MQTT Topics

The topic prefix defaults to eds and must match on both sides — lightd’s LIGHTD_TOPIC_PREFIX and the firmware’s LP_TOPIC_PREFIX.

TopicDirectionRetained
eds/lightstand/<id>/scenelightd → deviceyeswhat to render
eds/lightstand/<id>/statusdevice → brokeryes (LWT)online / offline
eds/lightstand/<id>/statedevice → brokeryeswhat it is rendering now
eds/lightd/statuslightd → brokeryes (LWT)the publisher’s presence
eds/console/statusconsole → brokeryes (LWT)the console’s presence; the only thing it publishes
eds/log/<id>device or agent Pi → brokernokey events, for the log store: the stand’s, the cover screen’s, the power beacon’s, and the now-playing agent’s (np-relay)
eds/nowplaying/source/<id>/…a driver → nowplaydyeswhat one player is doing; see Now Playing
eds/nowplaying/currentnowplayd → subscribersyesthe one current track
eds/nowplaying/current/artnowplayd → subscribersyesits cover, as image bytes; lightd lights the stand from it
eds/nowplaying/current/art/smallnowplayd → subscribersyesthe same cover at 240 pixels, as a baseline JPEG; the cover screen shows it
eds/nowplaying/commanda controller → nowplaydnevera button press, for whatever is current; see Now Playing
eds/nowplaying/source/<id>/commandnowplayd → a driverneverthe same press, passed to the current source; play_album to NP_ALBUM_SOURCE whatever is current (ADR-0040)
eds/voice/<device>/utterancedevice → voicedneverwhat followed the wake word: a WAV, 16 kHz 16-bit mono, at most 15 s (ADR-0042)
eds/voice/<device>/wokendevice → voicednever{"v":1}: the wake word was just heard, so the music is turned down (ADR-0044)
eds/voice/<device>/heardvoiced → device, consolenever{"v":1,"text","understood","artist","album","reason"}: what was made of the request
eds/voiced/statusvoiced → brokeryes (LWT)its presence
eds/screen/<id>/statusdevice → brokeryes (LWT)the cover screen’s presence
eds/beacon/<id>/statusdevice → brokeryes (LWT)whether the switch a beacon is on has power: online while it does, the will’s offline when it has not. nowplayd reads the one that speaks for the turntable (ADR-0023)
eds/nowplaying/current/looknowplayd → lightdyeswhether that cover’s album has a look of its own, by name; see Now Playing
eds/nowplaying/standconsole → nowplaydyes, as a settingwhich sources the stand is lit for: {"v":1,"sources":"records"}, the default, or "all" (ADR-0039)

The log topic

eds/log/<id> is not EdS’s own layout. <tenant>/log/<device> is the one topic under log/ Deevnet IoTaaS lets a device account publish, and its log bridge carries what arrives there into the tenant’s device log partition. The stand sends one JSON object per event — boot, network, scenes, health — at QoS 1 and not retained: a log line replayed to every new subscriber would be an event that never happened again.

The events and their fields are in the firmware’s README. Read them back with make logs in firmware/lp-stand, or on the LP Stand dashboard in the tenant’s Grafana organization.

Why the two status topics are separate

lightd publishes its own presence separately from the stands’ because a dark stand and a dead publisher look identical from the room. Without the distinction, the first diagnostic step is a guess.

Both use a last will, so the room learns a participant died rather than merely went quiet.

Quality of service

The stand subscribes to scene at QoS 1. A dropped scene means the stand shows the previous record’s colors until the next one — exactly the sort of quiet wrongness that is hard to notice and annoying to debug.

Watching the tree

mosquitto_sub -h <broker> -t 'eds/#' -v

Because gamma is applied on the device and not on the wire, what you see here is the color actually intended.