Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
17a2a41
Add Ombi integration
Sep 20, 2019
37e19f2
Black
Sep 20, 2019
7072f5c
Remove trailing comma
Sep 20, 2019
56ee0ed
Change dict.get to dict[key] for known keys
Sep 20, 2019
9fce49e
Remove monitored conditions from config
Sep 20, 2019
ffa27ac
Define SCAN_INTERVAL for default scan interval
Sep 20, 2019
9a9668d
Adjust requests syntax and add music_requests
Sep 21, 2019
a87f473
Remove Ombi object initialization
Sep 21, 2019
a9dd25d
Move constants to const.py
Sep 21, 2019
e4f9fab
Fix imports
Sep 21, 2019
1c2df49
Set pyombi requirement to version 0.1.3
Sep 21, 2019
1c1ba5c
Add services.yaml
Sep 21, 2019
0dbe480
Add config schema and setup for integration
Sep 21, 2019
458db12
Set pyombi requirement to version 0.1.3
Sep 21, 2019
3e75ac1
Fix syntax for scan interval
Sep 22, 2019
0da03f2
Fix datetime import
Sep 22, 2019
41b64a8
Add all files from ombi component
Sep 22, 2019
dbaf247
Move imports around
Sep 22, 2019
856c3d9
Move imports around
Sep 22, 2019
e085f77
Move pyombi import to top of module
Sep 22, 2019
55281a9
Move scan_interval to sensor module
Sep 22, 2019
258f6dc
Add custom validator for urlbase
Sep 22, 2019
7cc2ae6
Add guard clause for discovery_info
Sep 22, 2019
3f825d5
Add service validation schemas and constants
Sep 22, 2019
fa05b6f
Bump pyombi version
Sep 22, 2019
de75d7a
Adjust urlbase validation
Sep 22, 2019
32f4710
Add exception warnings for irretrievable media
Sep 22, 2019
c7de8fe
Bump pyombi
Sep 22, 2019
6af3d4c
Change from .get to dict[key]
Sep 22, 2019
8fb96a2
Change schema and conf variable names
Sep 22, 2019
bed2108
Set return to return false
Sep 22, 2019
4e6c85a
Remove unneeded return
Sep 22, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ omit =
homeassistant/components/oem/climate.py
homeassistant/components/oasa_telematics/sensor.py
homeassistant/components/ohmconnect/sensor.py
homeassistant/components/ombi/*
homeassistant/components/onewire/sensor.py
homeassistant/components/onkyo/media_player.py
homeassistant/components/onvif/camera.py
Expand Down
1 change: 1 addition & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ homeassistant/components/nws/* @MatthewFlamm
homeassistant/components/nzbget/* @chriscla
homeassistant/components/obihai/* @dshokouhi
homeassistant/components/ohmconnect/* @robbiet480
homeassistant/components/ombi/* @larssont
homeassistant/components/onboarding/* @home-assistant/core
homeassistant/components/opentherm_gw/* @mvn23
homeassistant/components/openuv/* @bachya
Expand Down
149 changes: 149 additions & 0 deletions homeassistant/components/ombi/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
"""Support for Ombi."""
import logging

import pyombi
import voluptuous as vol

from homeassistant.const import (
CONF_API_KEY,
CONF_HOST,
CONF_PORT,
CONF_SSL,
CONF_USERNAME,
)
import homeassistant.helpers.config_validation as cv

from .const import (
ATTR_NAME,
ATTR_SEASON,
CONF_URLBASE,
DEFAULT_PORT,
DEFAULT_SEASON,
DEFAULT_SSL,
DEFAULT_URLBASE,
DOMAIN,
SERVICE_MOVIE_REQUEST,
SERVICE_MUSIC_REQUEST,
SERVICE_TV_REQUEST,
)

_LOGGER = logging.getLogger(__name__)


def urlbase(value) -> str:
"""Validate and transform urlbase."""
if value is None:
raise vol.Invalid("string value is None")
value = str(value).strip("/")
if not value:
return value
return value + "/"


SUBMIT_MOVIE_REQUEST_SERVICE_SCHEMA = vol.Schema({vol.Required(ATTR_NAME): cv.string})

SUBMIT_MUSIC_REQUEST_SERVICE_SCHEMA = vol.Schema({vol.Required(ATTR_NAME): cv.string})

SUBMIT_TV_REQUEST_SERVICE_SCHEMA = vol.Schema(
{
vol.Required(ATTR_NAME): cv.string,
vol.Optional(ATTR_SEASON, default=DEFAULT_SEASON): vol.In(
["first", "latest", "all"]
),
}
)

CONFIG_SCHEMA = vol.Schema(
{
DOMAIN: vol.Schema(
{
vol.Required(CONF_API_KEY): cv.string,
vol.Required(CONF_HOST): cv.string,
vol.Required(CONF_USERNAME): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_URLBASE, default=DEFAULT_URLBASE): urlbase,
vol.Optional(CONF_SSL, default=DEFAULT_SSL): cv.boolean,
}
)
},
extra=vol.ALLOW_EXTRA,
)


def setup(hass, config):
"""Set up the Ombi component platform."""

ombi = pyombi.Ombi(
ssl=config[DOMAIN][CONF_SSL],
host=config[DOMAIN][CONF_HOST],
port=config[DOMAIN][CONF_PORT],
api_key=config[DOMAIN][CONF_API_KEY],
username=config[DOMAIN][CONF_USERNAME],
urlbase=config[DOMAIN][CONF_URLBASE],
)

try:
ombi.test_connection()
except pyombi.OmbiError as err:
_LOGGER.warning("Unable to setup Ombi: %s", err)
return False

hass.data[DOMAIN] = {"instance": ombi}

def submit_movie_request(call):
"""Submit request for movie."""
name = call.data[ATTR_NAME]
movies = ombi.search_movie(name)
if movies:
movie = movies[0]
ombi.request_movie(movie["theMovieDbId"])
else:
raise Warning("No movie found.")

def submit_tv_request(call):
"""Submit request for TV show."""
name = call.data[ATTR_NAME]
tv_shows = ombi.search_tv(name)

if tv_shows:
season = call.data[ATTR_SEASON]
show = tv_shows[0]["id"]
if season == "first":
ombi.request_tv(show, request_first=True)
elif season == "latest":
ombi.request_tv(show, request_latest=True)
elif season == "all":
ombi.request_tv(show, request_all=True)
else:
raise Warning("No TV show found.")

def submit_music_request(call):
"""Submit request for music album."""
name = call.data[ATTR_NAME]
music = ombi.search_music_album(name)
if music:
ombi.request_music(music[0]["foreignAlbumId"])
else:
raise Warning("No music album found.")

hass.services.register(
DOMAIN,
SERVICE_MOVIE_REQUEST,
submit_movie_request,
schema=SUBMIT_MOVIE_REQUEST_SERVICE_SCHEMA,
)
hass.services.register(
DOMAIN,
SERVICE_MUSIC_REQUEST,
submit_music_request,
schema=SUBMIT_MUSIC_REQUEST_SERVICE_SCHEMA,
)
hass.services.register(
DOMAIN,
SERVICE_TV_REQUEST,
submit_tv_request,
schema=SUBMIT_TV_REQUEST_SERVICE_SCHEMA,
)
hass.helpers.discovery.load_platform("sensor", DOMAIN, {}, config)

return True
24 changes: 24 additions & 0 deletions homeassistant/components/ombi/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""Support for Ombi."""
ATTR_NAME = "name"
ATTR_SEASON = "season"

CONF_URLBASE = "urlbase"

DEFAULT_NAME = DOMAIN = "ombi"
DEFAULT_PORT = 5000
DEFAULT_SEASON = "latest"
DEFAULT_SSL = False
DEFAULT_URLBASE = ""

SERVICE_MOVIE_REQUEST = "submit_movie_request"
SERVICE_MUSIC_REQUEST = "submit_music_request"
SERVICE_TV_REQUEST = "submit_tv_request"

SENSOR_TYPES = {
"movies": {"type": "Movie requests", "icon": "mdi:movie"},
"tv": {"type": "TV show requests", "icon": "mdi:television-classic"},
"music": {"type": "Music album requests", "icon": "mdi:album"},
"pending": {"type": "Pending requests", "icon": "mdi:clock-alert-outline"},
"approved": {"type": "Approved requests", "icon": "mdi:check"},
"available": {"type": "Available requests", "icon": "mdi:download"},
}
8 changes: 8 additions & 0 deletions homeassistant/components/ombi/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"domain": "ombi",
"name": "Ombi",
"documentation": "https://www.home-assistant.io/components/ombi/",
"dependencies": [],
"codeowners": ["@larssont"],
"requirements": ["pyombi==0.1.5"]
}
77 changes: 77 additions & 0 deletions homeassistant/components/ombi/sensor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
"""Support for Ombi."""
from datetime import timedelta
import logging

from pyombi import OmbiError

from homeassistant.helpers.entity import Entity

from .const import DOMAIN, SENSOR_TYPES

_LOGGER = logging.getLogger(__name__)

SCAN_INTERVAL = timedelta(seconds=60)


def setup_platform(hass, config, add_entities, discovery_info=None):
"""Set up the Ombi sensor platform."""
if discovery_info is None:
return

sensors = []
Comment thread
MartinHjelmare marked this conversation as resolved.

ombi = hass.data[DOMAIN]["instance"]

for sensor in SENSOR_TYPES:
sensor_label = sensor
sensor_type = SENSOR_TYPES[sensor]["type"]
sensor_icon = SENSOR_TYPES[sensor]["icon"]
sensors.append(OmbiSensor(sensor_label, sensor_type, ombi, sensor_icon))

add_entities(sensors, True)


class OmbiSensor(Entity):
"""Representation of an Ombi sensor."""

def __init__(self, label, sensor_type, ombi, icon):
"""Initialize the sensor."""
self._state = None
self._label = label
self._type = sensor_type
self._ombi = ombi
self._icon = icon

@property
def name(self):
"""Return the name of the sensor."""
return f"Ombi {self._type}"

@property
def icon(self):
"""Return the icon to use in the frontend."""
return self._icon

@property
def state(self):
"""Return the state of the sensor."""
return self._state

def update(self):
"""Update the sensor."""
try:
if self._label == "movies":
self._state = self._ombi.movie_requests
elif self._label == "tv":
self._state = self._ombi.tv_requests
elif self._label == "music":
self._state = self._ombi.music_requests
elif self._label == "pending":
self._state = self._ombi.total_requests["pending"]
elif self._label == "approved":
self._state = self._ombi.total_requests["approved"]
elif self._label == "available":
self._state = self._ombi.total_requests["available"]
except OmbiError as err:
_LOGGER.warning("Unable to update Ombi sensor: %s", err)
self._state = None
27 changes: 27 additions & 0 deletions homeassistant/components/ombi/services.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Ombi services.yaml entries

submit_movie_request:
description: Searches for a movie and requests the first result.
fields:
name:
description: Search parameter
example: "beverly hills cop"


submit_tv_request:
description: Searches for a TV show and requests the first result.
fields:
name:
description: Search parameter
example: "breaking bad"
season:
description: Which season(s) to request (first, latest or all)
example: "latest"


submit_music_request:
description: Searches for a music album and requests the first result.
fields:
name:
description: Search parameter
example: "nevermind"
3 changes: 3 additions & 0 deletions requirements_all.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1353,6 +1353,9 @@ pynzbgetapi==0.2.0
# homeassistant.components.obihai
pyobihai==1.1.0

# homeassistant.components.ombi
pyombi==0.1.5

# homeassistant.components.openuv
pyopenuv==1.0.9

Expand Down