Add Ombi integration (#26755)

* Add Ombi integration

* Black

* Remove trailing comma

* Change dict.get to dict[key] for known keys

* Remove monitored conditions from config

* Define SCAN_INTERVAL for default scan interval

* Adjust requests syntax and add music_requests

* Remove Ombi object initialization

* Move constants to const.py

* Fix imports

* Set pyombi requirement to version 0.1.3

* Add services.yaml

* Add config schema and setup for integration

* Set pyombi requirement to version 0.1.3

* Fix syntax for scan interval

* Fix datetime import

* Add all files from ombi component

* Move imports around

* Move imports around

* Move pyombi import to top of module

* Move scan_interval to sensor module

* Add custom validator for urlbase

* Add guard clause for discovery_info

* Add service validation schemas and constants

* Bump pyombi version

* Adjust urlbase validation

* Add exception warnings for irretrievable media

* Bump pyombi

* Change from .get to dict[key]

* Change schema and conf variable names

* Set return to return false

* Remove unneeded return
pull/26840/head
Tommy Larsson 2019-09-23 00:57:39 +02:00 committed by Martin Hjelmare
parent 5914475fe5
commit 60f0988435
8 changed files with 290 additions and 0 deletions

View File

@ -447,6 +447,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

View File

@ -198,6 +198,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

View File

@ -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

View File

@ -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"},
}

View File

@ -0,0 +1,8 @@
{
"domain": "ombi",
"name": "Ombi",
"documentation": "https://www.home-assistant.io/components/ombi/",
"dependencies": [],
"codeowners": ["@larssont"],
"requirements": ["pyombi==0.1.5"]
}

View File

@ -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 = []
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

View File

@ -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"

View File

@ -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