93 lines
3.0 KiB
Python
93 lines
3.0 KiB
Python
"""Mixin class for handling harmony callback subscriptions."""
|
|
|
|
import asyncio
|
|
import logging
|
|
from typing import Any, Callable, NamedTuple, Optional
|
|
|
|
from homeassistant.core import callback
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
NoParamCallback = Optional[Callable[[object], Any]]
|
|
ActivityCallback = Optional[Callable[[object, tuple], Any]]
|
|
|
|
|
|
class HarmonyCallback(NamedTuple):
|
|
"""Callback type for Harmony Hub notifications."""
|
|
|
|
connected: NoParamCallback
|
|
disconnected: NoParamCallback
|
|
config_updated: NoParamCallback
|
|
activity_starting: ActivityCallback
|
|
activity_started: ActivityCallback
|
|
|
|
|
|
class HarmonySubscriberMixin:
|
|
"""Base implementation for a subscriber."""
|
|
|
|
def __init__(self, hass):
|
|
"""Initialize an subscriber."""
|
|
super().__init__()
|
|
self._hass = hass
|
|
self._subscriptions = []
|
|
self._activity_lock = asyncio.Lock()
|
|
|
|
async def async_lock_start_activity(self):
|
|
"""Acquire the lock."""
|
|
await self._activity_lock.acquire()
|
|
|
|
@callback
|
|
def async_unlock_start_activity(self):
|
|
"""Release the lock."""
|
|
if self._activity_lock.locked():
|
|
self._activity_lock.release()
|
|
|
|
@callback
|
|
def async_subscribe(self, update_callbacks: HarmonyCallback) -> Callable:
|
|
"""Add a callback subscriber."""
|
|
self._subscriptions.append(update_callbacks)
|
|
|
|
def _unsubscribe():
|
|
self.async_unsubscribe(update_callbacks)
|
|
|
|
return _unsubscribe
|
|
|
|
@callback
|
|
def async_unsubscribe(self, update_callback: HarmonyCallback):
|
|
"""Remove a callback subscriber."""
|
|
self._subscriptions.remove(update_callback)
|
|
|
|
def _config_updated(self, _=None) -> None:
|
|
_LOGGER.debug("config_updated")
|
|
self._call_callbacks("config_updated")
|
|
|
|
def _connected(self, _=None) -> None:
|
|
_LOGGER.debug("connected")
|
|
self.async_unlock_start_activity()
|
|
self._available = True
|
|
self._call_callbacks("connected")
|
|
|
|
def _disconnected(self, _=None) -> None:
|
|
_LOGGER.debug("disconnected")
|
|
self.async_unlock_start_activity()
|
|
self._available = False
|
|
self._call_callbacks("disconnected")
|
|
|
|
def _activity_starting(self, activity_info: tuple) -> None:
|
|
_LOGGER.debug("activity %s starting", activity_info)
|
|
self._call_callbacks("activity_starting", activity_info)
|
|
|
|
def _activity_started(self, activity_info: tuple) -> None:
|
|
_LOGGER.debug("activity %s started", activity_info)
|
|
self.async_unlock_start_activity()
|
|
self._call_callbacks("activity_started", activity_info)
|
|
|
|
def _call_callbacks(self, callback_func_name: str, argument: tuple = None):
|
|
for subscription in self._subscriptions:
|
|
current_callback = getattr(subscription, callback_func_name)
|
|
if current_callback:
|
|
if argument:
|
|
self._hass.async_run_job(current_callback, argument)
|
|
else:
|
|
self._hass.async_run_job(current_callback)
|