Skip to content

Commit

Permalink
Synchronize attribute reads and subscriptions on startup (#17)
Browse files Browse the repository at this point in the history
* Synchronize attribute reads and subscriptions on startup

Avoid multiple entities requesting reads and subscriptions of the same
node. Nodes seem to be overwhelmed and return a BUSY error code, which
isn't handled gracefully throughout the stack (it seems).

* Store Node Lock in the HA Adapter
  • Loading branch information
agners authored Jun 17, 2022
1 parent c15961b commit c6467d5
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 4 deletions.
6 changes: 6 additions & 0 deletions custom_components/matter_experimental/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None:
self._fallback_store = get_matter_fallback_store(hass, config_entry)
self.platform_handlers: dict[Platform, AddEntitiesCallback] = {}
self._platforms_set_up = asyncio.Event()
self._node_lock: dict[int, asyncio.Lock] = {}

def register_platform_handler(
self, platform: Platform, add_entities: AddEntitiesCallback
Expand Down Expand Up @@ -149,6 +150,11 @@ def get_server_url(self) -> str:
def get_client_session(self) -> aiohttp.ClientSession:
return async_get_clientsession(self.hass)

def get_node_lock(self, nodeid) -> asyncio.Lock:
if nodeid not in self._node_lock:
self._node_lock[nodeid] = asyncio.Lock()
return self._node_lock[nodeid]

async def setup_node(self, node: MatterNode) -> None:
"""Set up an node."""
await self._platforms_set_up.wait()
Expand Down
15 changes: 11 additions & 4 deletions custom_components/matter_experimental/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,8 @@ def device_info(self) -> entity.DeviceInfo | None:
"""Return device info for device registry."""
return {"identifiers": {(DOMAIN, self._device.node.unique_id)}}

async def async_added_to_hass(self) -> None:
"""Handle being added to Home Assistant."""
await super().async_added_to_hass()

async def init_matter_device(self) -> None:
"""Initialize and subscribe device attributes."""
device_name = (
device_registry.async_get(self.hass)
.async_get(self.registry_entry.device_id)
Expand Down Expand Up @@ -80,6 +78,15 @@ async def async_added_to_hass(self) -> None:

self._update_from_device()

async def async_added_to_hass(self) -> None:
"""Handle being added to Home Assistant."""
await super().async_added_to_hass()

async with self._device.node.matter.adapter.get_node_lock(
self._device.node.node_id
):
await self.init_matter_device()

async def async_will_remove_from_hass(self) -> None:
"""Run when entity will be removed from hass."""
if self._unsubscribe is not None:
Expand Down

0 comments on commit c6467d5

Please sign in to comment.