Fix harmony failing to switch activities when a switch is in progress (#47212)

Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
This commit is contained in:
J. Nick Koston 2021-03-01 18:56:42 -06:00 committed by GitHub
parent cb99969845
commit d02218ff30
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 11 deletions

View file

@ -22,17 +22,8 @@ class HarmonyData(HarmonySubscriberMixin):
self._name = name self._name = name
self._unique_id = unique_id self._unique_id = unique_id
self._available = False self._available = False
self._client = None
callbacks = { self._address = address
"config_updated": self._config_updated,
"connect": self._connected,
"disconnect": self._disconnected,
"new_activity_starting": self._activity_starting,
"new_activity": self._activity_started,
}
self._client = HarmonyClient(
ip_address=address, callbacks=ClientCallbackType(**callbacks)
)
@property @property
def activities(self): def activities(self):
@ -105,6 +96,18 @@ class HarmonyData(HarmonySubscriberMixin):
async def connect(self) -> bool: async def connect(self) -> bool:
"""Connect to the Harmony Hub.""" """Connect to the Harmony Hub."""
_LOGGER.debug("%s: Connecting", self._name) _LOGGER.debug("%s: Connecting", self._name)
callbacks = {
"config_updated": self._config_updated,
"connect": self._connected,
"disconnect": self._disconnected,
"new_activity_starting": self._activity_starting,
"new_activity": self._activity_started,
}
self._client = HarmonyClient(
ip_address=self._address, callbacks=ClientCallbackType(**callbacks)
)
try: try:
if not await self._client.connect(): if not await self._client.connect():
_LOGGER.warning("%s: Unable to connect to HUB", self._name) _LOGGER.warning("%s: Unable to connect to HUB", self._name)
@ -113,6 +116,7 @@ class HarmonyData(HarmonySubscriberMixin):
except aioexc.TimeOut: except aioexc.TimeOut:
_LOGGER.warning("%s: Connection timed-out", self._name) _LOGGER.warning("%s: Connection timed-out", self._name)
return False return False
return True return True
async def shutdown(self): async def shutdown(self):
@ -159,10 +163,12 @@ class HarmonyData(HarmonySubscriberMixin):
) )
return return
await self.async_lock_start_activity()
try: try:
await self._client.start_activity(activity_id) await self._client.start_activity(activity_id)
except aioexc.TimeOut: except aioexc.TimeOut:
_LOGGER.error("%s: Starting activity %s timed-out", self.name, activity) _LOGGER.error("%s: Starting activity %s timed-out", self.name, activity)
self.async_unlock_start_activity()
async def async_power_off(self): async def async_power_off(self):
"""Start the PowerOff activity.""" """Start the PowerOff activity."""

View file

@ -1,5 +1,6 @@
"""Mixin class for handling harmony callback subscriptions.""" """Mixin class for handling harmony callback subscriptions."""
import asyncio
import logging import logging
from typing import Any, Callable, NamedTuple, Optional from typing import Any, Callable, NamedTuple, Optional
@ -29,6 +30,17 @@ class HarmonySubscriberMixin:
super().__init__() super().__init__()
self._hass = hass self._hass = hass
self._subscriptions = [] 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 @callback
def async_subscribe(self, update_callbacks: HarmonyCallback) -> Callable: def async_subscribe(self, update_callbacks: HarmonyCallback) -> Callable:
@ -51,11 +63,13 @@ class HarmonySubscriberMixin:
def _connected(self, _=None) -> None: def _connected(self, _=None) -> None:
_LOGGER.debug("connected") _LOGGER.debug("connected")
self.async_unlock_start_activity()
self._available = True self._available = True
self._call_callbacks("connected") self._call_callbacks("connected")
def _disconnected(self, _=None) -> None: def _disconnected(self, _=None) -> None:
_LOGGER.debug("disconnected") _LOGGER.debug("disconnected")
self.async_unlock_start_activity()
self._available = False self._available = False
self._call_callbacks("disconnected") self._call_callbacks("disconnected")
@ -65,6 +79,7 @@ class HarmonySubscriberMixin:
def _activity_started(self, activity_info: tuple) -> None: def _activity_started(self, activity_info: tuple) -> None:
_LOGGER.debug("activity %s started", activity_info) _LOGGER.debug("activity %s started", activity_info)
self.async_unlock_start_activity()
self._call_callbacks("activity_started", activity_info) self._call_callbacks("activity_started", activity_info)
def _call_callbacks(self, callback_func_name: str, argument: tuple = None): def _call_callbacks(self, callback_func_name: str, argument: tuple = None):