Get some status from my MQTT broker at startup

Hi folks,

An MQTT noob speaking here...

I have some Shellies that send a message to an MQTT topic, every time their relay status changes. Via an MQTT-In node I receive that status, so I can e.g. change the color of a ui-led to green or red to visualize the status of the relay.

However when I restart Node-RED, the status of the relay is of course gone. I could store the relay status in persistent context memory in Node-RED. But that seems a bit of a workaround to me, because the message is already persisted on the MQTT broker. So I was wondering if the last message could be replayed again into Node-RED at startup.

Although while writing this post now, I assume I am talking nononse... Because the Shelly does not only send relay status change messages, but also messages about its wifi connection status and so on.

Would appreciate if somebody could share me some best practises about MQTT for this.

Thanks!!!
Bart

You can use the dynamic subscription option and then just inject msg.action = subscribe and set msg.topic to required topic
See node help for further info

image

image

image

[{"id":"2c1581c91250dcf6","type":"mqtt in","z":"50aa70b641104f06","name":"","topic":"","qos":"2","datatype":"auto-detect","broker":"ad1faea18d26b2bf","nl":false,"rap":true,"rh":0,"inputs":1,"x":510,"y":180,"wires":[["e3f87b6e7823901e"]]},{"id":"e3f87b6e7823901e","type":"debug","z":"50aa70b641104f06","name":"debug 132","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":710,"y":180,"wires":[]},{"id":"40c716f11b71b278","type":"inject","z":"50aa70b641104f06","name":"","props":[{"p":"action","v":"subscribe","vt":"str"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"cheerlights","x":350,"y":180,"wires":[["2c1581c91250dcf6"]]},{"id":"ad1faea18d26b2bf","type":"mqtt-broker","name":"","broker":"mqtt.cheerlights.com","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closeRetain":"false","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willRetain":"false","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""}]
1 Like

Hi Simon,

Thanks for the tip!
Ok your proposal makes sense. But when I inject a message to start the subscription, nothing happens. I assume that only new messages will be received this way, and not the old existing messages? Because I need the last message(s) in order to know the current status of the Shelly switch...

It will pick up any retained topic
Can you set your Shelly to publish on a retained topic?

1 Like

Only the last message on a given topic is retained by the broker.

I found retained messages don't by themselves prevent dashboard/real world misalignment because sensors (etc) send their data and can then lose power.
You have to combine the retained message with Last Will and Testament Online/Offline messages (also retained).

2 Likes

Yes indeed it seems there is a "retain" flag in the Shelly switch user interface:
" The Retain flag is used to tell the broker to remember the last value until it gets a new one. Switches that don’t publish data very often would usually set the flag to true.

I will need to play with that in the next days. Thanks for the pointers!

1 Like

I don’t think you can be sure that the state value will be the last message (so potentially retained) on the topic.
The fallback can be to use the rest API of the Shellies. Fetching the state value through this API when nodered starts.

1 Like

Just remember, that a re-joining subscriber/client to a vbroker will only be re-supplied again with that topic data, when re-connecting with a different client-ID. That setting is in the broker config for the mqtt node (cleint-ID: leave empty for automatic generation).

I don't think that your suggestion would work, because maybe the message was sent whilst node-RED was connected, and therefore your client will have confirmed receipt of it, so why would it want to send it again?

You could always ask your shelly's for their current status, which may also be a more resilient option.

Try the attached flow, leaving the mqtt topics as they are, just update to your mqtt server.
If the inject node is changed to inject once on startup, then it should ask all connected shelly devices to report their statuses, and use that to update the colour of your ui_led's.

[{"id":"8b0af7dd77f5a07c","type":"inject","z":"f8cf7ea5344d6287","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"announce","payloadType":"str","x":120,"y":1350,"wires":[["3099f08e68b6c323"]]},{"id":"3099f08e68b6c323","type":"mqtt out","z":"f8cf7ea5344d6287","name":"","topic":"shellies/command","qos":"0","retain":"false","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"aa11e6d8.6cd088","x":300,"y":1350,"wires":[]},{"id":"9024984f2d995620","type":"mqtt in","z":"f8cf7ea5344d6287","name":"","topic":"shellies/+/info","qos":"0","datatype":"auto","broker":"aa11e6d8.6cd088","nl":false,"rap":true,"rh":0,"inputs":0,"x":105,"y":1300,"wires":[["e7898a73420c34c6"]]},{"id":"d99dacb4bba6148f","type":"debug","z":"f8cf7ea5344d6287","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":410,"y":1300,"wires":[]},{"id":"e7898a73420c34c6","type":"json","z":"f8cf7ea5344d6287","name":"","property":"payload","action":"","pretty":false,"x":260,"y":1300,"wires":[["d99dacb4bba6148f"]]},{"id":"aa11e6d8.6cd088","type":"mqtt-broker","name":"Local server","broker":"192.168.0.8","port":"1883","clientid":"Local node-RED","autoConnect":true,"usetls":false,"compatmode":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"admin","birthQos":"0","birthRetain":"false","birthPayload":"Hello from Local node-RED","birthMsg":{},"closeTopic":"admin","closeQos":"0","closeRetain":"false","closePayload":"Local node-RED is about to exit","closeMsg":{},"willTopic":"admin","willQos":"0","willRetain":"false","willPayload":"Local node-RED has now exited","willMsg":{},"sessionExpiry":""}]
1 Like

Did you resolve this @BartButenaers

If I can interpret for my understanding, you want the status/value of an old message but you want the broker to update your MQTT receive node with a particular old message on startup. Depending on the broker, there could be a way to access old messages. You need to know which one, of course. If the messages are stored on the broker log, or database. Otherwise the messages are flushed once the subscription is cleared. You will need to seek the information from your broker's user guide(s).

Hi Paul,
I will continue with this whenever I find time. But thanks to all the replies I have know an idea about the possibilities. Will post my feedback here when I continue with it...

1 Like

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.