Skip to content
Merged
Show file tree
Hide file tree
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
11 changes: 11 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,17 @@ Fixed
``docs/reference/protocol/device_features.rst``, which documented the
wire spelling correctly all along.

- **``firmware_payload_capture.py`` captured almost nothing.** Its wildcards
covered ``cmd/{type}/{client_id}/res/#`` and the event topic, but the device
acknowledges control and query commands on
``cmd/{type}/navilink-{mac}/{client_id}/res`` - which neither pattern
matches - so the device status and device info responses were missed, along
with every request published on the device path. A capture run recorded 2
payloads where it should have recorded 11. It now also subscribes to
``cmd/{type}/navilink-{mac}/#``, which additionally picks up traffic from
other clients on the same device. Query results the device routes back to a
client-keyed topic, such as reservations and energy usage, were already
covered by the existing response wildcard.
Version 9.3.0 (2026-08-03)
==========================

Expand Down
17 changes: 15 additions & 2 deletions examples/advanced/firmware_payload_capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,17 +111,30 @@

# --- Wildcard subscriptions to catch everything ---

# All response messages back to this client
# Everything under the device's own command path. The device
# acknowledges control and query commands on
# cmd/{type}/navilink-{mac}/{client_id}/res, which is where the status
# and device-info responses arrive, so a capture without this
# subscription misses them entirely. It also picks up the published
# requests themselves and the traffic of other clients on the same
# device (a Home Assistant integration, the vendor app), which is
# exactly what a capture wants. Query results that the device routes
# back to a client-keyed topic - reservations, energy usage - arrive
# under res_wildcard below instead.
cmd_wildcard = MqttTopicBuilder.command_topic(device_type, mac, "#")
# Query results routed back to this client specifically
res_wildcard = MqttTopicBuilder.response_topic(device_type, client_id, "#")
# All event messages pushed by the device
evt_wildcard = MqttTopicBuilder.event_topic(device_type, mac, "#")

print(
f"\nSubscribing to:\n {redact_topic(res_wildcard)}\n"
f"\nSubscribing to:\n {redact_topic(cmd_wildcard)}\n"
f" {redact_topic(res_wildcard)}\n"
f" {redact_topic(evt_wildcard)}\n"

Check failure

Code scanning / CodeQL

Clear-text logging of sensitive information High

This expression logs
sensitive data (private)
as clear text.
This expression logs
sensitive data (private)
as clear text.
This expression logs
sensitive data (private)
as clear text.
This expression logs
sensitive data (private)
as clear text.
)
print("Captured topics:")

await mqtt_client.subscribe(cmd_wildcard, capture.record)
await mqtt_client.subscribe(res_wildcard, capture.record)
await mqtt_client.subscribe(evt_wildcard, capture.record)

Expand Down
Loading