Skip to content

Commit 1fcbb9f

Browse files
committed
Remove commissioning retries
More often than not commissioning retries are not needed. In fact they lead to worse UX performance as it takes longer for an attempt which is bound to fail (e.g. because the code is wrong or the device is not actually commissionable) to fail.
1 parent 1dc9af0 commit 1fcbb9f

File tree

1 file changed

+50
-77
lines changed

1 file changed

+50
-77
lines changed

matter_server/server/device_controller.py

+50-77
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@
7171
NODE_SUBSCRIPTION_CEILING_WIFI = 60
7272
NODE_SUBSCRIPTION_CEILING_THREAD = 60
7373
NODE_SUBSCRIPTION_CEILING_BATTERY_POWERED = 600
74-
MAX_COMMISSION_RETRIES = 3
7574
NODE_RESUBSCRIBE_ATTEMPTS_UNAVAILABLE = 3
7675
NODE_RESUBSCRIBE_TIMEOUT_OFFLINE = 30 * 60 * 1000
7776
NODE_PING_TIMEOUT = 10
@@ -260,41 +259,29 @@ async def commission_with_code(
260259
"""
261260
node_id = self._get_next_node_id()
262261

263-
attempts = 0
264-
# we retry commissioning a few times as we've seen devices in the wild
265-
# that are a bit unstable.
266-
# by retrying, we increase the chances of a successful commission
267-
while attempts <= MAX_COMMISSION_RETRIES:
268-
attempts += 1
269-
LOGGER.info(
270-
"Starting Matter commissioning with code using Node ID %s (attempt %s/%s).",
271-
node_id,
272-
attempts,
273-
MAX_COMMISSION_RETRIES,
274-
)
275-
try:
276-
commissioned_node_id: int = (
277-
await self._chip_device_controller.commission_with_code(
278-
node_id,
279-
code,
280-
DiscoveryType.DISCOVERY_NETWORK_ONLY
281-
if network_only
282-
else DiscoveryType.DISCOVERY_ALL,
283-
)
284-
)
285-
# We use SDK default behavior which always uses the commissioning Node ID in the
286-
# generated NOC. So this should be the same really.
287-
LOGGER.info(
288-
"Commissioned Node ID: %s vs %s", commissioned_node_id, node_id
262+
LOGGER.info(
263+
"Starting Matter commissioning with code using Node ID %s.",
264+
node_id,
265+
)
266+
try:
267+
commissioned_node_id: int = (
268+
await self._chip_device_controller.commission_with_code(
269+
node_id,
270+
code,
271+
DiscoveryType.DISCOVERY_NETWORK_ONLY
272+
if network_only
273+
else DiscoveryType.DISCOVERY_ALL,
289274
)
290-
assert commissioned_node_id == node_id
291-
break
292-
except ChipStackError as err:
293-
if attempts >= MAX_COMMISSION_RETRIES:
294-
raise NodeCommissionFailed(
295-
f"Commission with code failed for node {node_id}."
296-
) from err
297-
await asyncio.sleep(5)
275+
)
276+
# We use SDK default behavior which always uses the commissioning Node ID in the
277+
# generated NOC. So this should be the same really.
278+
LOGGER.info("Commissioned Node ID: %s vs %s", commissioned_node_id, node_id)
279+
if commissioned_node_id != node_id:
280+
raise RuntimeError("Returned Node ID must match requested Node ID")
281+
except ChipStackError as err:
282+
raise NodeCommissionFailed(
283+
f"Commission with code failed for node {node_id}."
284+
) from err
298285

299286
LOGGER.info("Matter commissioning of Node ID %s successful.", node_id)
300287

@@ -345,49 +332,35 @@ async def commission_on_network(
345332
if ip_addr is not None:
346333
ip_addr = self.server.scope_ipv6_lla(ip_addr)
347334

348-
attempts = 0
349-
# we retry commissioning a few times as we've seen devices in the wild
350-
# that are a bit unstable.
351-
# by retrying, we increase the chances of a successful commission
352-
while attempts <= MAX_COMMISSION_RETRIES:
353-
attempts += 1
354-
try:
355-
if ip_addr is None:
356-
# regular CommissionOnNetwork if no IP address provided
357-
LOGGER.info(
358-
"Starting Matter commissioning on network using Node ID %s (attempt %s/%s).",
359-
node_id,
360-
attempts,
361-
MAX_COMMISSION_RETRIES,
362-
)
363-
commissioned_node_id = (
364-
await self._chip_device_controller.commission_on_network(
365-
node_id, setup_pin_code, filter_type, filter
366-
)
367-
)
368-
else:
369-
LOGGER.info(
370-
"Starting Matter commissioning using Node ID %s and IP %s (attempt %s/%s).",
371-
node_id,
372-
ip_addr,
373-
attempts,
374-
MAX_COMMISSION_RETRIES,
375-
)
376-
commissioned_node_id = (
377-
await self._chip_device_controller.commission_ip(
378-
node_id, setup_pin_code, ip_addr
379-
)
335+
try:
336+
if ip_addr is None:
337+
# regular CommissionOnNetwork if no IP address provided
338+
LOGGER.info(
339+
"Starting Matter commissioning on network using Node ID %s.",
340+
node_id,
341+
)
342+
commissioned_node_id = (
343+
await self._chip_device_controller.commission_on_network(
344+
node_id, setup_pin_code, filter_type, filter
380345
)
381-
# We use SDK default behavior which always uses the commissioning Node ID in the
382-
# generated NOC. So this should be the same really.
383-
assert commissioned_node_id == node_id
384-
break
385-
except ChipStackError as err:
386-
if attempts >= MAX_COMMISSION_RETRIES:
387-
raise NodeCommissionFailed(
388-
f"Commissioning failed for node {node_id}."
389-
) from err
390-
await asyncio.sleep(5)
346+
)
347+
else:
348+
LOGGER.info(
349+
"Starting Matter commissioning using Node ID %s and IP %s.",
350+
node_id,
351+
ip_addr,
352+
)
353+
commissioned_node_id = await self._chip_device_controller.commission_ip(
354+
node_id, setup_pin_code, ip_addr
355+
)
356+
# We use SDK default behavior which always uses the commissioning Node ID in the
357+
# generated NOC. So this should be the same really.
358+
if commissioned_node_id != node_id:
359+
raise RuntimeError("Returned Node ID must match requested Node ID")
360+
except ChipStackError as err:
361+
raise NodeCommissionFailed(
362+
f"Commissioning failed for node {node_id}."
363+
) from err
391364

392365
LOGGER.info("Matter commissioning of Node ID %s successful.", node_id)
393366

0 commit comments

Comments
 (0)