Repository navigation
Description
Summary
In my setup the MQTT topic of one V1 device (Saros 10R) silently stops getting messages after some hours. The MQTT connection itself stays up: pings work, there is no disconnect or reconnect, and messages for a second device (A01 F25 Ultra) on the same session keep arriving. From then on every cloud RPC to the Saros times out (in Home Assistant: the map never refreshes), until the integration is reloaded.
HealthManager should catch this, since it restarts the session after 3 consecutive MQTT timeouts. But since #672 one HealthManager instance is shared across all MQTT channels of the session. The A01 device is polled over MQTT about every 60 s and always succeeds, and each success calls on_success(), which resets the counter. The V1 device times out about every 40 s, so the counter never gets past 2 and the session is never restarted.
#672 meant this on purpose ("Any successful RPCs by other devices will reset the counter"), to keep one inactive device from restarting the whole session. This report is the case that design misses: the session is healthy for one topic and broken for another, and only a fresh session (new SUBSCRIBE) fixes it.
Environment
- Home Assistant 2026.10.4 (HA OS), core
roborockintegration python-roborock7.12.0 (as pinned by HA).roborock/mqtt/,health_manager.py, and theon_success/on_timeoutcalls inv1_channel.py/a01_channel.pyare unchanged on 7.15.2.- Devices on the account:
- Saros 10R,
roborock.vacuum.a144, pv 1.0, fw 02.52.86. Normally uses the local channel, so its MQTT topic is idle most of the time. Map requests (GET_MULTI_MAPS_LIST,GET_MAP_V1) always go over MQTT. - F25 Ultra,
roborock.wdv.a194, pv A01, fw 01.03.38. Polled over MQTT about every 60 s.
- Saros 10R,
What happens
- HA starts at 22:38 and the session connects. The last MQTT message from the Saros topic arrives at 22:43.
- Next day 17:02 the robot starts cleaning and HA asks for the map over MQTT. Every request times out after 10 s, 46 in a row over 30 minutes. In that time:
- no
Received PUBLISHarrives on the Saros topic. On an earlier day, while working, the same topic got about 600 messages/hour during cleaning. - no CONNECT, DISCONNECT, SUBSCRIBE, or UNSUBSCRIBE is sent on the wire.
subscribe()just finds the topic in_client_subscribed_topicsand logsUnsubscribing topic …, still have active callbacksafterwards. - PINGREQ/PINGRESP every 45 s, and the F25 Ultra's query/response over MQTT every minute, both keep working.
Restarting MQTT session after …is never logged.
- no
- Reloading the HA integration makes a new session (
Starting MQTT session, CONNACK,Sending SUBSCRIBEfor the Saros topic). Map requests succeed at once, and messages from the Saros topic flow again.
I have seen this on two days in a row. Things I ruled out on purpose: rebooting the robot (msgSeq reset, its messages kept coming on a fresh session) and opening the Roborock app while HA was running. Neither breaks the subscription. I don't know why the broker stops delivering for that topic. This report is only about the recovery not happening.
Log excerpt
Topic parts redacted, payloads left out. …7qvtt = Saros 10R (V1), …KZgzu = F25 Ultra (A01).
17:02:46.210 [aiomqtt] Received PUBLISH (d0, q0, r0, m0), 'rr/m/o/<rriot_u>/<user>/<duid…KZgzu>', ... (103 bytes) <- A01 success -> counter = 0
17:02:51.984 [roborock_session] Subscribing to topic rr/m/o/<rriot_u>/<user>/<duid…7qvtt>
17:02:51.985 [aiomqtt] Sending PUBLISH (d0, q0, r0, m1089), 'rr/m/i/<rriot_u>/<user>/<duid…7qvtt>', ... (215 bytes)
17:02:55.328 [aiomqtt] Sending PINGREQ
17:02:55.352 [aiomqtt] Received PINGRESP
17:03:01.988 [roborock_session] Unsubscribing topic rr/m/o/<rriot_u>/<user>/<duid…7qvtt>, still have active callbacks
17:03:01.989 [homeassistant.components.roborock.coordinator] Failed to update map: Something went wrong creating the map <- V1 timeout -> counter = 1
17:03:16.982 [roborock_session] Subscribing to topic rr/m/o/<rriot_u>/<user>/<duid…7qvtt>
17:03:16.982 [aiomqtt] Sending PUBLISH (d0, q0, r0, m1090), 'rr/m/i/<rriot_u>/<user>/<duid…7qvtt>', ... (215 bytes)
17:03:26.985 [roborock_session] Unsubscribing topic rr/m/o/<rriot_u>/<user>/<duid…7qvtt>, still have active callbacks
17:03:26.985 [homeassistant.components.roborock.coordinator] Failed to update map: Something went wrong creating the map <- V1 timeout -> counter = 2
17:03:46.481 [aiomqtt] Sending PUBLISH (d0, q0, r0, m1091), 'rr/m/i/<rriot_u>/<user>/<duid…KZgzu>', ... (103 bytes)
17:03:48.144 [aiomqtt] Received PUBLISH (d0, q0, r0, m0), 'rr/m/o/<rriot_u>/<user>/<duid…KZgzu>', ... (103 bytes) <- A01 success -> counter = 0
17:03:57.011 [aiomqtt] Sending PUBLISH (d0, q0, r0, m1092), 'rr/m/i/<rriot_u>/<user>/<duid…7qvtt>', ... (215 bytes)
17:04:07.015 [homeassistant.components.roborock.coordinator] Failed to update map: Something went wrong creating the map <- counter = 1
17:04:36.984 [aiomqtt] Sending PUBLISH (d0, q0, r0, m1093), 'rr/m/i/<rriot_u>/<user>/<duid…7qvtt>', ... (215 bytes)
17:04:46.986 [homeassistant.components.roborock.coordinator] Failed to update map: Something went wrong creating the map <- counter = 2
17:04:49.250 [aiomqtt] Received PUBLISH (d0, q0, r0, m0), 'rr/m/o/<rriot_u>/<user>/<duid…KZgzu>', ... (103 bytes) <- A01 success -> counter = 0
... same pattern until 17:32, 46 map timeouts in total, no session restart
Over the whole log (about 19 h, 46 V1 timeouts plus 3 more at 03:38), the longest run of V1 timeouts without an A01 success in between is 2. TIMEOUT_THRESHOLD is 3.
Before this window, the last message on the Saros topic was the day before:
2026-11-03 22:43:22.141 [aiomqtt] Received PUBLISH (d0, q0, r0, m0), 'rr/m/o/<rriot_u>/<user>/<duid…7qvtt>', ... (71 bytes)
Relevant code (7.12.0, same on main)
roborock/mqtt/roborock_session.py: oneHealthManager(self.restart)per session, used by everyMqttChannel.roborock/mqtt/health_manager.py:on_success()sets_consecutive_timeouts = 0, andon_timeout()restarts atTIMEOUT_THRESHOLD = 3.roborock/devices/rpc/a01_channel.py:on_success()after every A01 query.roborock/devices/rpc/v1_channel.py(RpcChannel._send_raw, MQTT strategy):on_timeout()/on_success().
Possible fixes
Just ideas, you know the tradeoffs better:
- Count timeouts per device/topic. Keep the session-wide counter but also track consecutive timeouts per device. When one device crosses the threshold and nothing has come in on its topic in that time, recover that device instead of ignoring it.
- Resubscribe the topic instead of restarting the session. For a per-device failure, send
UNSUBSCRIBE+SUBSCRIBEfor that topic only, so devices that still work aren't touched. (Not sure this alone helps if the broker-side state is stale. A full session restart is proven to help.) - Only let a success reset the counter for the topic it came from, e.g. track successes per topic and restart when any topic with recent traffic attempts has N timeouts in a row, still under
RESTART_COOLDOWN.
The 30-minute RESTART_COOLDOWN already limits restart churn, so per-device detection shouldn't cause flapping.
Workaround
Reload the Roborock config entry (e.g. with an automation when cleaning starts). That creates a new session and recovers the map right away.
Full debug logs and diagnostics are available on request.
Activity
infy1995 commentedon Nov 9, 2026
I'm working on a fix for this and currently testing it on my Home Assistant setup, so there's no need for anyone else to pick it up.
What the fix does
HealthManagerstill counts consecutive timeouts for the whole session, but now also per device, so a success from one device no longer resets another device's timeouts. Three consecutive timeouts on one device restart the session, still limited by the existing 30-minute cooldown.mqtt_healthsection (timeouts, successes, consecutive timeouts, restarts triggered, last success/timeout, session restarts), so this kind of failure is visible in the Home Assistant diagnostics download.Status
Branch: https://github.com/infy1995/python-roborock/tree/fix/mqtt-device-health
The library tests pass. Home Assistant 2026.11.0's Roborock integration tests also pass against it (304 of 305). The one failure is
test_diagnostics, because newer library versions redactrawName, which is unrelated to this change.It's now running on my Home Assistant with the Saros 10R and F25 Ultra. I'm waiting for the topic to go silent again to confirm that the restart actually recovers the map, and I'll follow up here with the result.
fix: restart the MQTT session when one device stops receiving messages
fix: restart the MQTT session when one device stops receiving messages
infy1995 commentedon Nov 13, 2026
Follow-up: the fix is in draft PR #1044. I'm running the final version on my Home Assistant for another day or two before marking it ready.
Confirmed: a session restart recovers the map every time. The device answers on the first request over the new connection. Over several days it recovered the Saros on its own after every failure, without reloading the integration.
Changed since my last comment:
mqtt_healthdiagnostics are smaller:failing_since, last success and timeout, counts, and the last 10 events.Ruled out:
Observed:
The PR description has the full list of what was tested, what didn't work, and what was ruled out.
fix: restart the MQTT session when one device stops receiving messages