Set homekit controller available state at startup (#51013)

This commit is contained in:
J. Nick Koston 2021-05-25 11:47:28 -05:00 committed by GitHub
parent 1e86818f85
commit 98535c9e6c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 16 deletions

View file

@ -27,6 +27,7 @@ from .device_trigger import async_fire_triggers, async_setup_triggers_for_entry
DEFAULT_SCAN_INTERVAL = datetime.timedelta(seconds=60) DEFAULT_SCAN_INTERVAL = datetime.timedelta(seconds=60)
RETRY_INTERVAL = 60 # seconds RETRY_INTERVAL = 60 # seconds
MAX_POLL_FAILURES_TO_DECLARE_UNAVAILABLE = 3
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -107,7 +108,7 @@ class HKDevice:
# Useful when routing events to triggers # Useful when routing events to triggers
self.devices = {} self.devices = {}
self.available = True self.available = False
self.signal_state_updated = "_".join((DOMAIN, self.unique_id, "state_updated")) self.signal_state_updated = "_".join((DOMAIN, self.unique_id, "state_updated"))
@ -124,6 +125,7 @@ class HKDevice:
# Never allow concurrent polling of the same accessory or bridge # Never allow concurrent polling of the same accessory or bridge
self._polling_lock = asyncio.Lock() self._polling_lock = asyncio.Lock()
self._polling_lock_warned = False self._polling_lock_warned = False
self._poll_failures = 0
self.watchable_characteristics = [] self.watchable_characteristics = []
@ -151,9 +153,14 @@ class HKDevice:
] ]
@callback @callback
def async_set_unavailable(self): def async_set_available_state(self, available):
"""Mark state of all entities on this connection as unavailable.""" """Mark state of all entities on this connection when it becomes available or unavailable."""
self.available = False _LOGGER.debug(
"Called async_set_available_state with %s for %s", available, self.unique_id
)
if self.available == available:
return
self.available = available
self.hass.helpers.dispatcher.async_dispatcher_send(self.signal_state_updated) self.hass.helpers.dispatcher.async_dispatcher_send(self.signal_state_updated)
async def async_setup(self): async def async_setup(self):
@ -259,6 +266,8 @@ class HKDevice:
if self.watchable_characteristics: if self.watchable_characteristics:
await self.pairing.subscribe(self.watchable_characteristics) await self.pairing.subscribe(self.watchable_characteristics)
if not self.pairing.connection.is_connected:
return
await self.async_update() await self.async_update()
@ -386,25 +395,30 @@ class HKDevice:
async def async_update(self, now=None): async def async_update(self, now=None):
"""Poll state of all entities attached to this bridge/accessory.""" """Poll state of all entities attached to this bridge/accessory."""
if not self.pollable_characteristics: if not self.pollable_characteristics:
_LOGGER.debug("HomeKit connection not polling any characteristics") self.async_set_available_state(self.pairing.connection.is_connected)
_LOGGER.debug(
"HomeKit connection not polling any characteristics: %s", self.unique_id
)
return return
if self._polling_lock.locked(): if self._polling_lock.locked():
if not self._polling_lock_warned: if not self._polling_lock_warned:
_LOGGER.warning( _LOGGER.warning(
"HomeKit controller update skipped as previous poll still in flight" "HomeKit controller update skipped as previous poll still in flight: %s",
self.unique_id,
) )
self._polling_lock_warned = True self._polling_lock_warned = True
return return
if self._polling_lock_warned: if self._polling_lock_warned:
_LOGGER.info( _LOGGER.info(
"HomeKit controller no longer detecting back pressure - not skipping poll" "HomeKit controller no longer detecting back pressure - not skipping poll: %s",
self.unique_id,
) )
self._polling_lock_warned = False self._polling_lock_warned = False
async with self._polling_lock: async with self._polling_lock:
_LOGGER.debug("Starting HomeKit controller update") _LOGGER.debug("Starting HomeKit controller update: %s", self.unique_id)
try: try:
new_values_dict = await self.get_characteristics( new_values_dict = await self.get_characteristics(
@ -413,20 +427,24 @@ class HKDevice:
except AccessoryNotFoundError: except AccessoryNotFoundError:
# Not only did the connection fail, but also the accessory is not # Not only did the connection fail, but also the accessory is not
# visible on the network. # visible on the network.
self.async_set_unavailable() self.async_set_available_state(False)
return return
except (AccessoryDisconnectedError, EncryptionError): except (AccessoryDisconnectedError, EncryptionError):
# Temporary connection failure. Device is still available but our # Temporary connection failure. Device may still available but our
# connection was dropped. # connection was dropped or we are reconnecting
self._poll_failures += 1
if self._poll_failures >= MAX_POLL_FAILURES_TO_DECLARE_UNAVAILABLE:
self.async_set_available_state(False)
return return
self._poll_failures = 0
self.process_new_events(new_values_dict) self.process_new_events(new_values_dict)
_LOGGER.debug("Finished HomeKit controller update") _LOGGER.debug("Finished HomeKit controller update: %s", self.unique_id)
def process_new_events(self, new_values_dict): def process_new_events(self, new_values_dict):
"""Process events from accessory into HA state.""" """Process events from accessory into HA state."""
self.available = True self.async_set_available_state(True)
# Process any stateless events (via device_triggers) # Process any stateless events (via device_triggers)
async_fire_triggers(self, new_values_dict) async_fire_triggers(self, new_values_dict)

View file

@ -3,7 +3,7 @@
"name": "HomeKit Controller", "name": "HomeKit Controller",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/homekit_controller", "documentation": "https://www.home-assistant.io/integrations/homekit_controller",
"requirements": ["aiohomekit==0.2.64"], "requirements": ["aiohomekit==0.2.65"],
"zeroconf": ["_hap._tcp.local."], "zeroconf": ["_hap._tcp.local."],
"after_dependencies": ["zeroconf"], "after_dependencies": ["zeroconf"],
"codeowners": ["@Jc2k", "@bdraco"], "codeowners": ["@Jc2k", "@bdraco"],

View file

@ -175,7 +175,7 @@ aioguardian==1.0.4
aioharmony==0.2.7 aioharmony==0.2.7
# homeassistant.components.homekit_controller # homeassistant.components.homekit_controller
aiohomekit==0.2.64 aiohomekit==0.2.65
# homeassistant.components.emulated_hue # homeassistant.components.emulated_hue
# homeassistant.components.http # homeassistant.components.http

View file

@ -112,7 +112,7 @@ aioguardian==1.0.4
aioharmony==0.2.7 aioharmony==0.2.7
# homeassistant.components.homekit_controller # homeassistant.components.homekit_controller
aiohomekit==0.2.64 aiohomekit==0.2.65
# homeassistant.components.emulated_hue # homeassistant.components.emulated_hue
# homeassistant.components.http # homeassistant.components.http