Summary
The HA-DISCO publisher stops emitting numeric /state topics while continuing to send availability: online. Home Assistant entities therefore freeze at their last value and still render as available — they look like live readings. Restarting the container does not bring the numeric topics back.
This is the more dangerous half of the failure: a frozen-but-available sensor is indistinguishable from a working one, and automations built on it keep firing on stale data.
Setup
ruvnet/wifi-densepose:latest, 3 ESP32-S3 nodes, --mqtt --mqtt-tls --mqtt-port 8883 against a Mosquitto broker.
Observed
Subscribing directly at the broker while the server was running and receiving CSI normally:
homeassistant/binary_sensor/<object_id>/presence/state → streaming continuously
homeassistant/sensor/<object_id>/+/state → zero messages in 20 s
homeassistant/sensor/<object_id>/+/config and /availability online → still arriving
Meanwhile GET /api/v1/nodes showed all three nodes active with last_seen_ms of 14–15, and /api/v1/sensing/latest values changing normally. So the data existed; only the numeric MQTT path was silent.
Setting --mqtt-rate-vitals 1.0 made no difference — not rate limiting.
Home Assistant side: sensor.<...>_breathing_rate kept last_updated from ~40 minutes earlier, state unchanged, entity still available. Entities never went unavailable because the disconnect was clean, so LWT never fired.
Broker log at the moment it stopped:
Client <client-id> [<ip>:<port>] disconnected: connection closed by client.
and no reconnect afterwards.
Possibly related code
v2/crates/wifi-densepose-sensing-server/src/mqtt/publisher.rs:265-272 — on RecvError::Closed the publisher publishes offline for known nodes, calls client.disconnect() and returns. There is no restart path, so the publisher task is gone for the lifetime of the process. The availability publish is wrapped in let _ = …, so if it fails (client already down) the error is swallowed and HA never learns the entities went away.
That explains the permanent silence after the event, though not by itself why numeric topics stopped while presence kept flowing — those go through encoder.boolean vs the rl.allow(...)-gated loop at publisher.rs:336-352, so the two paths can diverge.
Suggested fix
Two independent things:
- Do not let the publisher terminate silently. If the broadcast channel closes, either restart the publisher or surface it as an error the operator can see (the current path leaves a live-looking but frozen integration).
- When numeric publishing stops for a node, stop its availability heartbeat too, so HA marks the entities
unavailable instead of showing stale values as current.
Summary
The HA-DISCO publisher stops emitting numeric
/statetopics while continuing to sendavailability: online. Home Assistant entities therefore freeze at their last value and still render as available — they look like live readings. Restarting the container does not bring the numeric topics back.This is the more dangerous half of the failure: a frozen-but-available sensor is indistinguishable from a working one, and automations built on it keep firing on stale data.
Setup
ruvnet/wifi-densepose:latest, 3 ESP32-S3 nodes,--mqtt --mqtt-tls --mqtt-port 8883against a Mosquitto broker.Observed
Subscribing directly at the broker while the server was running and receiving CSI normally:
homeassistant/binary_sensor/<object_id>/presence/state→ streaming continuouslyhomeassistant/sensor/<object_id>/+/state→ zero messages in 20 shomeassistant/sensor/<object_id>/+/configand/availability online→ still arrivingMeanwhile
GET /api/v1/nodesshowed all three nodesactivewithlast_seen_msof 14–15, and/api/v1/sensing/latestvalues changing normally. So the data existed; only the numeric MQTT path was silent.Setting
--mqtt-rate-vitals 1.0made no difference — not rate limiting.Home Assistant side:
sensor.<...>_breathing_ratekeptlast_updatedfrom ~40 minutes earlier, state unchanged, entity stillavailable. Entities never wentunavailablebecause the disconnect was clean, so LWT never fired.Broker log at the moment it stopped:
and no reconnect afterwards.
Possibly related code
v2/crates/wifi-densepose-sensing-server/src/mqtt/publisher.rs:265-272— onRecvError::Closedthe publisher publishesofflinefor known nodes, callsclient.disconnect()andreturns. There is no restart path, so the publisher task is gone for the lifetime of the process. The availability publish is wrapped inlet _ = …, so if it fails (client already down) the error is swallowed and HA never learns the entities went away.That explains the permanent silence after the event, though not by itself why numeric topics stopped while
presencekept flowing — those go throughencoder.booleanvs therl.allow(...)-gated loop atpublisher.rs:336-352, so the two paths can diverge.Suggested fix
Two independent things:
unavailableinstead of showing stale values as current.