Move config and connections to Plex component (#26488)
* Move config and connections to component * Separate imports * Set a unique_id on sensor * Set a platforms const * Add SERVERS dict, hardcode to single server * Move to debug * Return false * More debug * Import at top to fix lint * Guard against legacy setup attempts * Refactor to add setup callback * Review comments * Log levels * Return result of callback * Store CONFIGURING in hass.data * Set up discovery if no config data * Use schema to set defaults * Remove media_player options to remove entities * Improve error handling
This commit is contained in:
parent
3c629db096
commit
30fb4ddc98
6 changed files with 238 additions and 231 deletions
|
@ -36,6 +36,7 @@ SERVICE_KONNECTED = "konnected"
|
|||
SERVICE_MOBILE_APP = "hass_mobile_app"
|
||||
SERVICE_NETGEAR = "netgear_router"
|
||||
SERVICE_OCTOPRINT = "octoprint"
|
||||
SERVICE_PLEX = "plex_mediaserver"
|
||||
SERVICE_ROKU = "roku"
|
||||
SERVICE_SABNZBD = "sabnzbd"
|
||||
SERVICE_SAMSUNG_PRINTER = "samsung_printer"
|
||||
|
@ -68,7 +69,7 @@ SERVICE_HANDLERS = {
|
|||
SERVICE_FREEBOX: ("freebox", None),
|
||||
SERVICE_YEELIGHT: ("yeelight", None),
|
||||
"panasonic_viera": ("media_player", "panasonic_viera"),
|
||||
"plex_mediaserver": ("media_player", "plex"),
|
||||
SERVICE_PLEX: ("plex", None),
|
||||
"yamaha": ("media_player", "yamaha"),
|
||||
"logitech_mediaserver": ("media_player", "squeezebox"),
|
||||
"directv": ("media_player", "directv"),
|
||||
|
|
|
@ -1 +1,201 @@
|
|||
"""The plex component."""
|
||||
"""Support to embed Plex."""
|
||||
import logging
|
||||
|
||||
import plexapi.exceptions
|
||||
import requests.exceptions
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.discovery import SERVICE_PLEX
|
||||
from homeassistant.components.media_player import DOMAIN as MP_DOMAIN
|
||||
from homeassistant.const import (
|
||||
CONF_HOST,
|
||||
CONF_PORT,
|
||||
CONF_SSL,
|
||||
CONF_TOKEN,
|
||||
CONF_URL,
|
||||
CONF_VERIFY_SSL,
|
||||
)
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers import discovery
|
||||
from homeassistant.util.json import load_json, save_json
|
||||
|
||||
from .const import (
|
||||
CONF_USE_EPISODE_ART,
|
||||
CONF_SHOW_ALL_CONTROLS,
|
||||
DEFAULT_HOST,
|
||||
DEFAULT_PORT,
|
||||
DEFAULT_SSL,
|
||||
DEFAULT_VERIFY_SSL,
|
||||
DOMAIN as PLEX_DOMAIN,
|
||||
PLATFORMS,
|
||||
PLEX_CONFIG_FILE,
|
||||
PLEX_MEDIA_PLAYER_OPTIONS,
|
||||
SERVERS,
|
||||
)
|
||||
from .server import PlexServer
|
||||
|
||||
MEDIA_PLAYER_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_USE_EPISODE_ART, default=False): cv.boolean,
|
||||
vol.Optional(CONF_SHOW_ALL_CONTROLS, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
|
||||
SERVER_CONFIG_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string,
|
||||
vol.Optional(CONF_TOKEN): cv.string,
|
||||
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
|
||||
vol.Optional(CONF_SSL, default=DEFAULT_SSL): cv.boolean,
|
||||
vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean,
|
||||
vol.Optional(MP_DOMAIN, default={}): MEDIA_PLAYER_SCHEMA,
|
||||
}
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({PLEX_DOMAIN: SERVER_CONFIG_SCHEMA}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
CONFIGURING = "configuring"
|
||||
_LOGGER = logging.getLogger(__package__)
|
||||
|
||||
|
||||
def setup(hass, config):
|
||||
"""Set up the Plex component."""
|
||||
|
||||
def server_discovered(service, info):
|
||||
"""Pass back discovered Plex server details."""
|
||||
if hass.data[PLEX_DOMAIN][SERVERS]:
|
||||
_LOGGER.debug("Plex server already configured, ignoring discovery.")
|
||||
return
|
||||
_LOGGER.debug("Discovered Plex server: %s:%s", info["host"], info["port"])
|
||||
setup_plex(discovery_info=info)
|
||||
|
||||
def setup_plex(config=None, discovery_info=None, configurator_info=None):
|
||||
"""Return assembled server_config dict."""
|
||||
json_file = hass.config.path(PLEX_CONFIG_FILE)
|
||||
file_config = load_json(json_file)
|
||||
|
||||
if config:
|
||||
server_config = config
|
||||
host_and_port = (
|
||||
f"{server_config.pop(CONF_HOST)}:{server_config.pop(CONF_PORT)}"
|
||||
)
|
||||
if MP_DOMAIN in server_config:
|
||||
hass.data[PLEX_MEDIA_PLAYER_OPTIONS] = server_config.pop(MP_DOMAIN)
|
||||
elif file_config:
|
||||
_LOGGER.debug("Loading config from %s", json_file)
|
||||
host_and_port, server_config = file_config.popitem()
|
||||
server_config[CONF_VERIFY_SSL] = server_config.pop("verify")
|
||||
elif discovery_info:
|
||||
server_config = {}
|
||||
host_and_port = f"{discovery_info[CONF_HOST]}:{discovery_info[CONF_PORT]}"
|
||||
elif configurator_info:
|
||||
server_config = configurator_info
|
||||
host_and_port = server_config["host_and_port"]
|
||||
else:
|
||||
discovery.listen(hass, SERVICE_PLEX, server_discovered)
|
||||
return True
|
||||
|
||||
use_ssl = server_config.get(CONF_SSL, DEFAULT_SSL)
|
||||
http_prefix = "https" if use_ssl else "http"
|
||||
server_config[CONF_URL] = f"{http_prefix}://{host_and_port}"
|
||||
|
||||
plex_server = PlexServer(server_config)
|
||||
try:
|
||||
plex_server.connect()
|
||||
except requests.exceptions.ConnectionError as error:
|
||||
_LOGGER.error(
|
||||
"Plex server could not be reached, please verify host and port: [%s]",
|
||||
error,
|
||||
)
|
||||
return False
|
||||
except (
|
||||
plexapi.exceptions.BadRequest,
|
||||
plexapi.exceptions.Unauthorized,
|
||||
plexapi.exceptions.NotFound,
|
||||
) as error:
|
||||
_LOGGER.error(
|
||||
"Connection to Plex server failed, please verify token and SSL settings: [%s]",
|
||||
error,
|
||||
)
|
||||
request_configuration(host_and_port)
|
||||
return False
|
||||
else:
|
||||
hass.data[PLEX_DOMAIN][SERVERS][
|
||||
plex_server.machine_identifier
|
||||
] = plex_server
|
||||
|
||||
if host_and_port in hass.data[PLEX_DOMAIN][CONFIGURING]:
|
||||
request_id = hass.data[PLEX_DOMAIN][CONFIGURING].pop(host_and_port)
|
||||
configurator = hass.components.configurator
|
||||
configurator.request_done(request_id)
|
||||
_LOGGER.debug("Discovery configuration done")
|
||||
if configurator_info:
|
||||
# Write plex.conf if created via discovery/configurator
|
||||
save_json(
|
||||
hass.config.path(PLEX_CONFIG_FILE),
|
||||
{
|
||||
host_and_port: {
|
||||
CONF_TOKEN: server_config[CONF_TOKEN],
|
||||
CONF_SSL: use_ssl,
|
||||
"verify": server_config[CONF_VERIFY_SSL],
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
if not hass.data.get(PLEX_MEDIA_PLAYER_OPTIONS):
|
||||
hass.data[PLEX_MEDIA_PLAYER_OPTIONS] = MEDIA_PLAYER_SCHEMA({})
|
||||
|
||||
for platform in PLATFORMS:
|
||||
hass.helpers.discovery.load_platform(
|
||||
platform, PLEX_DOMAIN, {}, original_config
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
def request_configuration(host_and_port):
|
||||
"""Request configuration steps from the user."""
|
||||
configurator = hass.components.configurator
|
||||
if host_and_port in hass.data[PLEX_DOMAIN][CONFIGURING]:
|
||||
configurator.notify_errors(
|
||||
hass.data[PLEX_DOMAIN][CONFIGURING][host_and_port],
|
||||
"Failed to register, please try again.",
|
||||
)
|
||||
return
|
||||
|
||||
def plex_configuration_callback(data):
|
||||
"""Handle configuration changes."""
|
||||
config = {
|
||||
"host_and_port": host_and_port,
|
||||
CONF_TOKEN: data.get("token"),
|
||||
CONF_SSL: cv.boolean(data.get("ssl")),
|
||||
CONF_VERIFY_SSL: cv.boolean(data.get("verify_ssl")),
|
||||
}
|
||||
setup_plex(configurator_info=config)
|
||||
|
||||
hass.data[PLEX_DOMAIN][CONFIGURING][
|
||||
host_and_port
|
||||
] = configurator.request_config(
|
||||
"Plex Media Server",
|
||||
plex_configuration_callback,
|
||||
description="Enter the X-Plex-Token",
|
||||
entity_picture="/static/images/logo_plex_mediaserver.png",
|
||||
submit_caption="Confirm",
|
||||
fields=[
|
||||
{"id": "token", "name": "X-Plex-Token", "type": ""},
|
||||
{"id": "ssl", "name": "Use SSL", "type": ""},
|
||||
{"id": "verify_ssl", "name": "Verify SSL", "type": ""},
|
||||
],
|
||||
)
|
||||
|
||||
# End of inner functions.
|
||||
|
||||
original_config = config
|
||||
|
||||
hass.data.setdefault(PLEX_DOMAIN, {SERVERS: {}, CONFIGURING: {}})
|
||||
|
||||
if hass.data[PLEX_DOMAIN][SERVERS]:
|
||||
_LOGGER.debug("Plex server already configured")
|
||||
return False
|
||||
|
||||
plex_config = config.get(PLEX_DOMAIN, {})
|
||||
return setup_plex(config=plex_config)
|
||||
|
|
|
@ -7,7 +7,11 @@ DEFAULT_PORT = 32400
|
|||
DEFAULT_SSL = False
|
||||
DEFAULT_VERIFY_SSL = True
|
||||
|
||||
PLATFORMS = ["media_player", "sensor"]
|
||||
SERVERS = "servers"
|
||||
|
||||
PLEX_CONFIG_FILE = "plex.conf"
|
||||
PLEX_MEDIA_PLAYER_OPTIONS = "plex_mp_options"
|
||||
PLEX_SERVER_CONFIG = "server_config"
|
||||
|
||||
CONF_USE_EPISODE_ART = "use_episode_art"
|
||||
|
|
|
@ -2,10 +2,13 @@
|
|||
from datetime import timedelta
|
||||
import json
|
||||
import logging
|
||||
import requests.exceptions
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.media_player import MediaPlayerDevice, PLATFORM_SCHEMA
|
||||
import plexapi.exceptions
|
||||
import plexapi.playlist
|
||||
import plexapi.playqueue
|
||||
import requests.exceptions
|
||||
|
||||
from homeassistant.components.media_player import MediaPlayerDevice
|
||||
from homeassistant.components.media_player.const import (
|
||||
MEDIA_TYPE_MOVIE,
|
||||
MEDIA_TYPE_MUSIC,
|
||||
|
@ -20,150 +23,37 @@ from homeassistant.components.media_player.const import (
|
|||
SUPPORT_VOLUME_SET,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
CONF_HOST,
|
||||
CONF_PORT,
|
||||
CONF_SSL,
|
||||
CONF_URL,
|
||||
CONF_TOKEN,
|
||||
CONF_VERIFY_SSL,
|
||||
DEVICE_DEFAULT_NAME,
|
||||
STATE_IDLE,
|
||||
STATE_OFF,
|
||||
STATE_PAUSED,
|
||||
STATE_PLAYING,
|
||||
)
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.event import track_time_interval
|
||||
from homeassistant.util import dt as dt_util
|
||||
from homeassistant.util.json import load_json, save_json
|
||||
|
||||
from .const import (
|
||||
CONF_USE_EPISODE_ART,
|
||||
CONF_SHOW_ALL_CONTROLS,
|
||||
CONF_REMOVE_UNAVAILABLE_CLIENTS,
|
||||
CONF_CLIENT_REMOVE_INTERVAL,
|
||||
DEFAULT_HOST,
|
||||
DEFAULT_PORT,
|
||||
DEFAULT_SSL,
|
||||
DEFAULT_VERIFY_SSL,
|
||||
DOMAIN as PLEX_DOMAIN,
|
||||
NAME_FORMAT,
|
||||
PLEX_CONFIG_FILE,
|
||||
PLEX_MEDIA_PLAYER_OPTIONS,
|
||||
SERVERS,
|
||||
)
|
||||
from .server import PlexServer
|
||||
|
||||
SERVER_SETUP = "server_setup"
|
||||
|
||||
_CONFIGURING = {}
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||
{
|
||||
vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string,
|
||||
vol.Optional(CONF_TOKEN): cv.string,
|
||||
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
|
||||
vol.Optional(CONF_SSL, default=DEFAULT_SSL): cv.boolean,
|
||||
vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean,
|
||||
vol.Optional(CONF_USE_EPISODE_ART, default=False): cv.boolean,
|
||||
vol.Optional(CONF_SHOW_ALL_CONTROLS, default=False): cv.boolean,
|
||||
vol.Optional(CONF_REMOVE_UNAVAILABLE_CLIENTS, default=True): cv.boolean,
|
||||
vol.Optional(
|
||||
CONF_CLIENT_REMOVE_INTERVAL, default=timedelta(seconds=600)
|
||||
): vol.All(cv.time_period, cv.positive_timedelta),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_entities_callback, discovery_info=None):
|
||||
"""Set up the Plex platform."""
|
||||
plex_data = hass.data.setdefault(PLEX_DOMAIN, {})
|
||||
server_setup = plex_data.setdefault(SERVER_SETUP, False)
|
||||
if server_setup:
|
||||
if discovery_info is None:
|
||||
return
|
||||
|
||||
# get config from plex.conf
|
||||
file_config = load_json(hass.config.path(PLEX_CONFIG_FILE))
|
||||
|
||||
if file_config:
|
||||
# Setup a configured PlexServer
|
||||
host, host_config = file_config.popitem()
|
||||
token = host_config["token"]
|
||||
try:
|
||||
has_ssl = host_config["ssl"]
|
||||
except KeyError:
|
||||
has_ssl = False
|
||||
try:
|
||||
verify_ssl = host_config["verify"]
|
||||
except KeyError:
|
||||
verify_ssl = True
|
||||
|
||||
# Via discovery
|
||||
elif discovery_info is not None:
|
||||
# Parse discovery data
|
||||
host = discovery_info.get("host")
|
||||
port = discovery_info.get("port")
|
||||
host = f"{host}:{port}"
|
||||
_LOGGER.info("Discovered PLEX server: %s", host)
|
||||
|
||||
if host in _CONFIGURING:
|
||||
return
|
||||
token = None
|
||||
has_ssl = False
|
||||
verify_ssl = True
|
||||
else:
|
||||
host = config[CONF_HOST]
|
||||
port = config[CONF_PORT]
|
||||
host = f"{host}:{port}"
|
||||
token = config.get(CONF_TOKEN)
|
||||
has_ssl = config[CONF_SSL]
|
||||
verify_ssl = config[CONF_VERIFY_SSL]
|
||||
|
||||
setup_plexserver(
|
||||
host, token, has_ssl, verify_ssl, hass, config, add_entities_callback
|
||||
)
|
||||
|
||||
|
||||
def setup_plexserver(
|
||||
host, token, has_ssl, verify_ssl, hass, config, add_entities_callback
|
||||
):
|
||||
"""Set up a plexserver based on host parameter."""
|
||||
import plexapi.exceptions
|
||||
|
||||
http_prefix = "https" if has_ssl else "http"
|
||||
|
||||
server_config = {
|
||||
CONF_URL: f"{http_prefix}://{host}",
|
||||
CONF_TOKEN: token,
|
||||
CONF_VERIFY_SSL: verify_ssl,
|
||||
}
|
||||
|
||||
try:
|
||||
plexserver = PlexServer(server_config)
|
||||
plexserver.connect()
|
||||
except (
|
||||
plexapi.exceptions.BadRequest,
|
||||
plexapi.exceptions.Unauthorized,
|
||||
plexapi.exceptions.NotFound,
|
||||
) as error:
|
||||
_LOGGER.info(error)
|
||||
# No token or wrong token
|
||||
request_configuration(host, hass, config, add_entities_callback)
|
||||
return
|
||||
else:
|
||||
hass.data[PLEX_DOMAIN][SERVER_SETUP] = True
|
||||
|
||||
# If we came here and configuring this host, mark as done
|
||||
if host in _CONFIGURING:
|
||||
request_id = _CONFIGURING.pop(host)
|
||||
configurator = hass.components.configurator
|
||||
configurator.request_done(request_id)
|
||||
_LOGGER.info("Discovery configuration done")
|
||||
|
||||
# Save config
|
||||
save_json(
|
||||
hass.config.path(PLEX_CONFIG_FILE),
|
||||
{host: {"token": token, "ssl": has_ssl, "verify": verify_ssl}},
|
||||
)
|
||||
plexserver = list(hass.data[PLEX_DOMAIN][SERVERS].values())[0]
|
||||
config = hass.data[PLEX_MEDIA_PLAYER_OPTIONS]
|
||||
|
||||
plex_clients = {}
|
||||
plex_sessions = {}
|
||||
|
@ -178,7 +68,9 @@ def setup_plexserver(
|
|||
return
|
||||
except requests.exceptions.RequestException as ex:
|
||||
_LOGGER.warning(
|
||||
"Could not connect to plex server at http://%s (%s)", host, ex
|
||||
"Could not connect to Plex server: %s (%s)",
|
||||
plexserver.friendly_name,
|
||||
ex,
|
||||
)
|
||||
return
|
||||
|
||||
|
@ -210,7 +102,9 @@ def setup_plexserver(
|
|||
return
|
||||
except requests.exceptions.RequestException as ex:
|
||||
_LOGGER.warning(
|
||||
"Could not connect to plex server at http://%s (%s)", host, ex
|
||||
"Could not connect to Plex server: %s (%s)",
|
||||
plexserver.friendly_name,
|
||||
ex,
|
||||
)
|
||||
return
|
||||
|
||||
|
@ -239,7 +133,6 @@ def setup_plexserver(
|
|||
_LOGGER.debug("Refreshing session: %s", machine_identifier)
|
||||
plex_clients[machine_identifier].refresh(None, session)
|
||||
|
||||
clients_to_remove = []
|
||||
for client in plex_clients.values():
|
||||
# force devices to idle that do not have a valid session
|
||||
if client.session is None:
|
||||
|
@ -253,59 +146,10 @@ def setup_plexserver(
|
|||
if client not in new_plex_clients:
|
||||
client.schedule_update_ha_state()
|
||||
|
||||
if not config.get(CONF_REMOVE_UNAVAILABLE_CLIENTS) or client.available:
|
||||
continue
|
||||
|
||||
if (dt_util.utcnow() - client.marked_unavailable) >= (
|
||||
config.get(CONF_CLIENT_REMOVE_INTERVAL)
|
||||
):
|
||||
hass.add_job(client.async_remove())
|
||||
clients_to_remove.append(client.machine_identifier)
|
||||
|
||||
while clients_to_remove:
|
||||
del plex_clients[clients_to_remove.pop()]
|
||||
|
||||
if new_plex_clients:
|
||||
add_entities_callback(new_plex_clients)
|
||||
|
||||
|
||||
def request_configuration(host, hass, config, add_entities_callback):
|
||||
"""Request configuration steps from the user."""
|
||||
configurator = hass.components.configurator
|
||||
# We got an error if this method is called while we are configuring
|
||||
if host in _CONFIGURING:
|
||||
configurator.notify_errors(
|
||||
_CONFIGURING[host], "Failed to register, please try again."
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
def plex_configuration_callback(data):
|
||||
"""Handle configuration changes."""
|
||||
setup_plexserver(
|
||||
host,
|
||||
data.get("token"),
|
||||
cv.boolean(data.get("has_ssl")),
|
||||
cv.boolean(data.get("do_not_verify_ssl")),
|
||||
hass,
|
||||
config,
|
||||
add_entities_callback,
|
||||
)
|
||||
|
||||
_CONFIGURING[host] = configurator.request_config(
|
||||
"Plex Media Server",
|
||||
plex_configuration_callback,
|
||||
description="Enter the X-Plex-Token",
|
||||
entity_picture="/static/images/logo_plex_mediaserver.png",
|
||||
submit_caption="Confirm",
|
||||
fields=[
|
||||
{"id": "token", "name": "X-Plex-Token", "type": ""},
|
||||
{"id": "has_ssl", "name": "Use SSL", "type": ""},
|
||||
{"id": "do_not_verify_ssl", "name": "Do not verify SSL", "type": ""},
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
class PlexClient(MediaPlayerDevice):
|
||||
"""Representation of a Plex device."""
|
||||
|
||||
|
@ -378,9 +222,6 @@ class PlexClient(MediaPlayerDevice):
|
|||
|
||||
def refresh(self, device, session):
|
||||
"""Refresh key device data."""
|
||||
import plexapi.exceptions
|
||||
|
||||
# new data refresh
|
||||
self._clear_media_details()
|
||||
|
||||
if session: # Not being triggered by Chrome or FireTablet Plex App
|
||||
|
@ -851,8 +692,6 @@ class PlexClient(MediaPlayerDevice):
|
|||
src["video_name"]
|
||||
)
|
||||
|
||||
import plexapi.playlist
|
||||
|
||||
if (
|
||||
media
|
||||
and media_type == "EPISODE"
|
||||
|
@ -918,8 +757,6 @@ class PlexClient(MediaPlayerDevice):
|
|||
_LOGGER.error("Client cannot play media: %s", self.entity_id)
|
||||
return
|
||||
|
||||
import plexapi.playqueue
|
||||
|
||||
playqueue = plexapi.playqueue.PlayQueue.create(
|
||||
self.device.server, media, **params
|
||||
)
|
||||
|
|
|
@ -1,87 +1,51 @@
|
|||
"""Support for Plex media server monitoring."""
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
|
||||
import plexapi.exceptions
|
||||
import requests.exceptions
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.switch import PLATFORM_SCHEMA
|
||||
from homeassistant.const import (
|
||||
CONF_NAME,
|
||||
CONF_HOST,
|
||||
CONF_PORT,
|
||||
CONF_TOKEN,
|
||||
CONF_SSL,
|
||||
CONF_URL,
|
||||
CONF_VERIFY_SSL,
|
||||
)
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.util import Throttle
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
from .const import DEFAULT_HOST, DEFAULT_PORT, DEFAULT_SSL, DEFAULT_VERIFY_SSL
|
||||
from .server import PlexServer
|
||||
from .const import DOMAIN as PLEX_DOMAIN, SERVERS
|
||||
|
||||
DEFAULT_NAME = "Plex"
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=1)
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||
{
|
||||
vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string,
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
vol.Optional(CONF_TOKEN): cv.string,
|
||||
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
|
||||
vol.Optional(CONF_SSL, default=DEFAULT_SSL): cv.boolean,
|
||||
vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
||||
"""Set up the Plex sensor."""
|
||||
name = config.get(CONF_NAME)
|
||||
plex_host = config.get(CONF_HOST)
|
||||
plex_port = config.get(CONF_PORT)
|
||||
plex_token = config.get(CONF_TOKEN)
|
||||
verify_ssl = config.get(CONF_VERIFY_SSL)
|
||||
|
||||
plex_url = "{}://{}:{}".format(
|
||||
"https" if config.get(CONF_SSL) else "http", plex_host, plex_port
|
||||
)
|
||||
|
||||
try:
|
||||
plex_server = PlexServer(
|
||||
{CONF_URL: plex_url, CONF_TOKEN: plex_token, CONF_VERIFY_SSL: verify_ssl}
|
||||
)
|
||||
plex_server.connect()
|
||||
except (
|
||||
plexapi.exceptions.BadRequest,
|
||||
plexapi.exceptions.Unauthorized,
|
||||
plexapi.exceptions.NotFound,
|
||||
) as error:
|
||||
_LOGGER.error(error)
|
||||
if discovery_info is None:
|
||||
return
|
||||
|
||||
add_entities([PlexSensor(name, plex_server)], True)
|
||||
plexserver = list(hass.data[PLEX_DOMAIN][SERVERS].values())[0]
|
||||
add_entities([PlexSensor(plexserver)], True)
|
||||
|
||||
|
||||
class PlexSensor(Entity):
|
||||
"""Representation of a Plex now playing sensor."""
|
||||
|
||||
def __init__(self, name, plex_server):
|
||||
def __init__(self, plex_server):
|
||||
"""Initialize the sensor."""
|
||||
self._name = name
|
||||
self._name = DEFAULT_NAME
|
||||
self._state = None
|
||||
self._now_playing = []
|
||||
self._server = plex_server
|
||||
self._unique_id = f"sensor-{plex_server.machine_identifier}"
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the sensor."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return the id of this plex client."""
|
||||
return self._unique_id
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the sensor."""
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
"""Shared class to maintain Plex server instances."""
|
||||
import logging
|
||||
|
||||
import plexapi.server
|
||||
from requests import Session
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue