Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tweak subscription ceiling based on routing role #619

Merged
merged 2 commits into from
Mar 6, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 18 additions & 22 deletions matter_server/server/device_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,15 @@
DATA_KEY_LAST_NODE_ID = "last_node_id"

LOGGER = logging.getLogger(__name__)
MIN_NODE_SUBSCRIPTION_CEILING = 30
MAX_NODE_SUBSCRIPTION_CEILING = 300
MIN_NODE_SUBSCRIPTION_CEILING_BATTERY_POWERED = 300
MAX_NODE_SUBSCRIPTION_CEILING_BATTERY_POWERED = 1800
NODE_SUBSCRIPTION_CEILING_WIFI = 30
NODE_SUBSCRIPTION_CEILING_THREAD = 60
NODE_SUBSCRIPTION_CEILING_BATTERY_POWERED = 600
MAX_COMMISSION_RETRIES = 3
NODE_RESUBSCRIBE_ATTEMPTS_UNAVAILABLE = 3
NODE_RESUBSCRIBE_TIMEOUT_OFFLINE = 30 * 60 * 1000
NODE_PING_TIMEOUT = 10
NODE_PING_TIMEOUT_BATTERY_POWERED = 60
NODE_MDNS_BACKOFF = 300
NODE_MDNS_BACKOFF = 610 # must be higher than (highest) sub ceiling
FALLBACK_NODE_SCANNER_INTERVAL = 1800

MDNS_TYPE_OPERATIONAL_NODE = "_matter._tcp.local."
Expand Down Expand Up @@ -842,13 +841,6 @@ async def _subscribe_node(self, node_id: int) -> None:
await self._call_sdk(prev_sub.Shutdown)
del self._subscriptions[node_id]

# determine if node is battery powered sleeping device
# Endpoint 0, ThreadNetworkDiagnostics Cluster, routingRole attribute
battery_powered = (
node.attributes.get(ROUTING_ROLE_ATTRIBUTE_PATH, 0)
== Clusters.ThreadNetworkDiagnostics.Enums.RoutingRoleEnum.kSleepyEndDevice
)

loop = cast(asyncio.AbstractEventLoop, self.server.loop)

# set-up the actual subscription
Expand Down Expand Up @@ -927,6 +919,7 @@ def event_callback(
node_logger.debug(
"Received node event: %s - transaction: %s", data, transaction
)
self._node_last_seen[node_id] = time.time()
node_event = MatterNodeEvent(
node_id=node_id,
endpoint_id=data.Header.EndpointId,
Expand Down Expand Up @@ -994,16 +987,19 @@ def resubscription_succeeded(

node_logger.info("Setting up attributes and events subscription.")
interval_floor = 0
interval_ceiling = (
randint( # noqa: S311
MIN_NODE_SUBSCRIPTION_CEILING_BATTERY_POWERED,
MAX_NODE_SUBSCRIPTION_CEILING_BATTERY_POWERED,
)
if battery_powered
else randint( # noqa: S311
MIN_NODE_SUBSCRIPTION_CEILING, MAX_NODE_SUBSCRIPTION_CEILING
)
)
# determine subscription ceiling based on routing role
# Endpoint 0, ThreadNetworkDiagnostics Cluster, routingRole attribute
# for WiFi devices, this cluster doesn't exist.
routing_role = node.attributes.get(ROUTING_ROLE_ATTRIBUTE_PATH)
if routing_role is None:
interval_ceiling = NODE_SUBSCRIPTION_CEILING_WIFI
elif (
routing_role
== Clusters.ThreadNetworkDiagnostics.Enums.RoutingRoleEnum.kSleepyEndDevice
):
interval_ceiling = NODE_SUBSCRIPTION_CEILING_BATTERY_POWERED
else:
interval_ceiling = NODE_SUBSCRIPTION_CEILING_THREAD
self._last_subscription_attempt[node_id] = 0
sub: Attribute.SubscriptionTransaction = await self.chip_controller.Read(
node_id,
Expand Down