Skip to content

Commit

Permalink
Add some workaround logic to poll devices that are unavailable for a …
Browse files Browse the repository at this point in the history
…longer period of time (#359)

Co-authored-by: Martin Hjelmare <[email protected]>
  • Loading branch information
marcelveldt and MartinHjelmare committed Jul 12, 2023
1 parent e736c47 commit c5341f6
Showing 1 changed file with 19 additions and 3 deletions.
22 changes: 19 additions & 3 deletions matter_server/server/device_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@

LOGGER = logging.getLogger(__name__)
INTERVIEW_TASK_LIMIT = 5
MAX_POLL_INTERVAL = 600

# a list of attributes we should always watch on all nodes
DEFAULT_SUBSCRIBE_ATTRIBUTES: set[tuple[int | str, int | str, int | str]] = {
Expand Down Expand Up @@ -698,6 +699,18 @@ def resubscription_attempted(
if node.available:
node.available = False
self.server.signal_event(EventType.NODE_UPDATED, node)
if nextResubscribeIntervalMsec / 1000 > MAX_POLL_INTERVAL:
# workaround to handle devices that are unplugged
# from power for a longer period of time
# cancel subscription and add this node to our node polling job
# TODO: fix this once OerationalNodeDiscovery is available:
# https://github.com/project-chip/connectedhomeip/pull/26718
sub.Shutdown()
self._subscriptions.pop(node_id)
assert self.server.loop
self.server.loop.create_task(
self._check_interview_and_subscription(node_id, MAX_POLL_INTERVAL)
)

def resubscription_succeeded(
transaction: Attribute.SubscriptionTransaction,
Expand Down Expand Up @@ -757,8 +770,9 @@ def reschedule() -> None:
asyncio.create_task,
self._check_interview_and_subscription(
node_id,
# increase interval at each attempt with maximum of 10 minutes
min(reschedule_interval + 10, 600),
# increase interval at each attempt with maximum of
# MAX_POLL_INTERVAL seconds (= 10 minutes)
min(reschedule_interval + 10, MAX_POLL_INTERVAL),
),
)

Expand Down Expand Up @@ -794,6 +808,8 @@ def reschedule() -> None:
"will retry later in the background.",
node_id,
)
# TODO: fix this once OperationalNodeDiscovery is available:
# https://github.com/project-chip/connectedhomeip/pull/26718
reschedule()

@staticmethod
Expand Down Expand Up @@ -845,7 +861,7 @@ async def _resolve_node(self, node_id: int, retries: int = 3) -> None:
raise RuntimeError("Device Controller not initialized.")
try:
async with node_lock, self._resolve_lock:
LOGGER.info("Attempting to resolve node %s...", node_id)
LOGGER.debug("Attempting to resolve node %s...", node_id)
await self._call_sdk(
self.chip_controller.ResolveNode,
nodeid=node_id,
Expand Down

0 comments on commit c5341f6

Please sign in to comment.