MQTT messages created by rule

Dear All,
I’m perplex by some MQTT problem and reaching out to you for some help.
I have 10’s of custom sensors that are subscribed to the OH commands, but sometimes, usualy after 2-3 week will stop listening. A PITA to troubleshoot as it happens rare.

I have came with an idea to create OH item with a heartbeat counter that would be sent over MQTT so the sensors logic (python script) would know they lost connection

So my question is what is the proper way to do it so the OH would originate the messages.
Is simple .postUpdate to the heartbeat item enough to send out message to all the subscribed MQTT clients?

I would define a Thing:

Thing topic OH_master "OH_master" {
Channels:
   Type number : heartbeat "heartbeat" [ stateTopic="OH_master/heartbeat" , commandTopic="OH_master/heartbeat"]
}

And matching Item

Number Sensor_Heartbeat "Sensor Heartbeat #: [%d]" <settings>{channel="mqtt:topic:eui:OH_master:heartbeat" }

And then just increment once a minute it in a Rule

rule "HEARTBEAT "
when
Time cron "0 * * 1/1 * ? *"
then
Sensor_Heartbeat.postUpdate((Sensor_Heartbeat.state as Number) + 1)
end

Shoud that work? Or I’m missing something

There is a nuance here. Do the sensors stop responding to messages or do they lose their connection to the broker? If the latter, or if the software crashes or freezes up or the like than you can use the LWT to get a message published from the broker to tell you exactly when it goes offline/get’s stuck.

MQTT implements a heartbeat for you and when you configure a LWT topic and message, the broker will publish the LWT message when the client doesn’t respond to the heartbeat. So you might not need to implement anything at all here except something to subscribe to the LWT messages.

It would be very unusual to have a program that still answers to the MQTT heartbeat but does not respond to other MQTT messages.

It depends on how you configure your MQTT Thing and the MQTT topic structure, but you would use sendCommand and not postUpdate. That looks like it might work as you describe but I strongly recommend researching LWT as the MQTT technology itself has this built in.

1 Like

So the story is the that I use python script running as a service on RPI as a client. paho.mqtt library and I subscribe in a very simple manner.

client = mqttClient.Client(sensor_name)
client.on_connect = on_connect
client.on_message = on_message
client.connect(OH_IP, port=1883)
client.loop_start()
client.subscribe(sensor_name + '/relay_0')
client.subscribe(sensor_name + '/relay_1')

After 2 weeks I find a script running fine, logging data. It still publishes some values over MQTT, but the on_message callback stops executing, as if the messages stopped arriving. I have some other networks where the same script structure has uptime of 6 month and it is fine.


I did some reading about LWT but I looks for me it will be sent also when the sensor just drops from the WiFi and that can happen. Would I then need to re-subscribe to the topic? From my experience it doesn’t look like I need to do that with QoS 0 the client should continue to receive the messages.

How are you recovering these sensors at present? If your script stops responding to incoming MQTT directives, what can you do?

That is only MQTT listener failing, the host are still pingable in the network
As they are RPI zero W based I can just ssh to them and restart the script.
But I also did implement on them saltstack that is a real marvel of IoT host management so from the main server I just issue a salt command to all minions (seriously they call like that in saltstack) to excecute

sudo salt '*' cmd.run "sudo systemctl restart sensor.service"

I just finished implementing the heartbeat on them, will see if that is a workaround. but still need to make more research what is causing the problem, but that is a python/paho/mqtt problem not OH.


Needed to change PostUpdate (does not generate a MQTT message) to SendCommand

I realize this is an older topic, but if this is still an issue for you or anyone else maybe this will help.

I have written a Python program to allow remote access to GPIO pins, sensors, and other hardware on Raspberry PI’s and other SBCs via MQTT. It has a heartbeat setting where it will publish all values at a set interval, even if they have not changed. This can be used, along with the LWT that Rich was explaining, to determine if a device is still online and whether it disconnected intentionally or not. You can find MQTTany on Github.