Skip to content
This repository has been archived by the owner on May 26, 2022. It is now read-only.

Commit

Permalink
zeroconf updates
Browse files Browse the repository at this point in the history
  • Loading branch information
maykar authored Sep 20, 2020
1 parent 2bdb96d commit 3697c39
Showing 1 changed file with 71 additions and 57 deletions.
128 changes: 71 additions & 57 deletions custom_components/plex_assistant/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@
https://github.com/maykar/plex_assistant
"""

from homeassistant.helpers.network import get_url
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.typing import HomeAssistantType
import voluptuous as vol

DOMAIN = "plex_assistant"
Expand All @@ -33,6 +31,7 @@

class PA:
""" Hold our libraries, devices, etc. """

plex = None
server = None
lib = {}
Expand All @@ -43,34 +42,29 @@ class PA:
client_sensor = []
alias_names = []
client_update = True
zeroconf = None


async def get_zeroconf_singleton(hass: HomeAssistantType):
try:
from homeassistant.components.zeroconf import async_get_instance
PA.zeroconf = await async_get_instance(hass)
except:
from zeroconf import Zeroconf
PA.zeroconf = Zeroconf()


def setup(hass, config):
async def async_setup(hass, config):
"""Called when Home Assistant is loading our component."""
import logging

import os
import logging

from gtts import gTTS
from plexapi.server import PlexServer
from pychromecast import get_chromecasts
from pychromecast.controllers.plex import PlexController

from .helpers import (cc_callback, find_media, fuzzy, get_libraries,
media_error, video_selection)
from homeassistant.helpers.network import get_url
from .localize import LOCALIZE
from .process_speech import process_speech

_LOGGER = logging.getLogger(__name__)
from .helpers import (
cc_callback,
find_media,
fuzzy,
get_libraries,
media_error,
video_selection,
)

conf = config[DOMAIN]
base_url = conf.get(CONF_URL)
Expand All @@ -80,34 +74,32 @@ def setup(hass, config):
tts_error = conf.get(CONF_TTS_ERROR)
aliases = conf.get(CONF_ALIASES)

localize = LOCALIZE[lang] if lang in LOCALIZE.keys() else LOCALIZE['en']
_LOGGER = logging.getLogger(__name__)

directory = hass.config.path() + '/www/plex_assist_tts/'
localize = LOCALIZE[lang] if lang in LOCALIZE.keys() else LOCALIZE["en"]
zc = None

try:
from homeassistant.components.zeroconf import async_get_instance
zc = await async_get_instance(hass)
except:
from zeroconf import Zeroconf
zc = Zeroconf()

directory = hass.config.path() + "/www/plex_assist_tts/"
if tts_error and not os.path.exists(directory):
os.makedirs(directory, mode=0o777)

get_chromecasts(blocking=False, callback=cc_callback,
zeroconf_instance=PA.zeroconf)
get_chromecasts(blocking=False, callback=cc_callback, zeroconf_instance=zc)

PA.server = PlexServer(base_url, token)
PA.plex = PA.server.library
PA.lib = get_libraries(PA.plex)
PA.alias_names = list(aliases.keys()) if aliases else []
def sync_io_server(base_url, token):
PA.server = PlexServer(base_url, token)
PA.plex = PA.server.library
PA.lib = get_libraries(PA.plex)

def update_sensor():
clients = [{client.title: {"ID": client.machineIdentifier,
"type": client.product}} for client in PA.clients]
devicelist = list(PA.devices.keys())
state = str(len(devicelist + clients)) + ' connected devices.'
attributes = {
"Connected Devices": {
'Cast Devices': devicelist or 'None',
'Plex Clients': clients or 'None'
},
"friendly_name": "Plex Assistant Devices",
}
sensor = "sensor.plex_assistant_devices"
hass.states.async_set(sensor, state, attributes)
await hass.async_add_executor_job(sync_io_server, base_url, token)

PA.alias_names = list(aliases.keys()) if aliases else []

def handle_input(call):
if not call.data.get("command").strip():
Expand All @@ -118,14 +110,14 @@ def handle_input(call):
_LOGGER.debug("Command: %s", command_string)

get_chromecasts(blocking=False, callback=cc_callback,
zeroconf_instance=PA.zeroconf)
zeroconf_instance=zc)

PA.clients = PA.server.clients()
PA.client_names = [client.title for client in PA.clients]
PA.client_ids = [client.machineIdentifier for client in PA.clients]

if localize["controls"]["update_sensor"] in command_string:
update_sensor()
update_sensor(hass)
return

cast = None
Expand All @@ -137,22 +129,25 @@ def handle_input(call):
PA.device_names = list(PA.devices.keys())

if not command["control"]:
_LOGGER.debug({i: command[i] for i in command if i != 'library'})
_LOGGER.debug({i: command[i] for i in command if i != "library"})

if PA.lib["updated"] < PA.plex.search(sort="addedAt:desc", limit=1)[0].addedAt:
PA.lib = get_libraries(PA.plex)

devices = PA.device_names + PA.client_names + PA.client_ids
device = fuzzy(command["device"] or default_cast, devices)

if aliases:
alias = fuzzy(command["device"] or default_cast, PA.alias_names)

if alias[1] < 60 and device[1] < 60:
_LOGGER.warning("{0} {1}: \"{2}\"".format(
localize["cast_device"].capitalize(),
localize["not_found"],
command["device"].title()
))
_LOGGER.warning(
'{0} {1}: "{2}"'.format(
localize["cast_device"].capitalize(),
localize["not_found"],
command["device"].title(),
)
)
_LOGGER.debug("Device Score: %s", device[1])
_LOGGER.debug("Devices: %s", str(devices))

Expand All @@ -164,9 +159,11 @@ def handle_input(call):
name = aliases[alias[0]] if alias[1] > device[1] else device[0]
cast = PA.devices[name] if name in PA.device_names else name
client = isinstance(cast, str)

if client:
client_device = next(
c for c in PA.clients if c.title == cast or c.machineIdentifier == cast)
c for c in PA.clients if c.title == cast or c.machineIdentifier == cast
)
cast = client_device

if command["control"]:
Expand All @@ -192,21 +189,20 @@ def handle_input(call):

try:
result = find_media(command, command["media"], PA.lib)
media = video_selection(command, result["media"],
result["library"])
media = video_selection(
command, result["media"], result["library"])
except Exception:
error = media_error(command, localize)
if tts_error:
tts = gTTS(error, lang=lang)
tts.save(directory + 'error.mp3')
tts.save(directory + "error.mp3")
speech_error = True
_LOGGER.warning(error)

if speech_error and not client:
cast.wait()
med_con = cast.media_controller
mp3 = get_url(hass) + "/local/plex_assist_tts/error.mp3"
med_con.play_media(mp3, 'audio/mpeg')
med_con.play_media(mp3, "audio/mpeg")
med_con.block_until_active()
return

Expand All @@ -224,7 +220,25 @@ def handle_input(call):
cast.wait()
plex_c.block_until_playing(media)

update_sensor()
update_sensor(hass)

hass.services.register(DOMAIN, "command", handle_input)
hass.services.async_register(DOMAIN, "command", handle_input)
return True


def update_sensor(hass):
clients = [
{client.title: {"ID": client.machineIdentifier, "type": client.product}}
for client in PA.clients
]
devicelist = list(PA.devices.keys())
state = str(len(devicelist + clients)) + " connected devices."
attributes = {
"Connected Devices": {
"Cast Devices": devicelist or "None",
"Plex Clients": clients or "None",
},
"friendly_name": "Plex Assistant Devices",
}
sensor = "sensor.plex_assistant_devices"
hass.states.async_set(sensor, state, attributes)

0 comments on commit 3697c39

Please sign in to comment.