How to detect missing MQTT messages within a timeout

Hi,

I’m using SolarAssistant via it’s MQTT bridge to communicate with my OpenHAB (4.1.1) instance. Everything is working great in both directions for monitoring the batteries and inverters and controlling some inverter settings.
One of the items for each inverter is the current runtime mode which may be like “Solar/Battery”, “Grid”, “Power on”, “Standby” and “Fault”. Unfortunately there is no “Power off” mode.

Now I want to implement an OH rule to detect the “Power off” situation. In case the inverters are running in one of the known modes, Solar Assistant is sending every 15 seconds messages with inverter data. In case when the inverter is switched off there will be no more messages send via MQTT which I want to use as a trigger to detect “Power off”. I think about a cron rule which is checking every 15 seconds if new MQTT messages has been arrived.

One of the possible solutions would be to sub to subscribe directly inside an OH DSL rule to an MQTT topic even if the topic is already used in the MQTT binding with everything configured. The receiving of any message may reset a timestamp and the parallel cron rule may check this timestamp every 15 seconds to detect missing messges.

Maybe better solutions are possible?

Addon:
I’m running the influxdb.persist configuration with strategy “everyChange” to save storage. So a solution with using the historic item API will not work in this case (Solar Assistant is sending the data every 15 seconds, even they have not changed since the last sending).

If the device is really powered off may be you can use the Network binding? See network:pingdevice in the docs.

Solar Assistant is communicating via MODBUS with each of the inverters and batteries. The inverters (and batteries) itself don’t have network/WiFi (and no IP address). I can therefore only access data in OH that Solar Assistant provides via MQTT. Solar Assistant is like a proxy and protocol translator between all inverters/batteries and OH.

Hi @fmeili1

Could you not use an expire on the item you defined with the MQTT property, so that when it hasn’t been updated for a certain time it will be set too OFF.

This is what I am doing with other MQTT properties when they have been offline for a while.

I’m not sure if this may work. It’s possible that Solar Assistant is sending out the same values every 15 seconds for a longer period of time and because there are changes for the values, it will be ignored in OH (because of my persistence configuration “everyChange”). I assume, that the “expire” item configuration will only be triggered if the item value changed, which is not the case here.

… if the item receives an update or command

:wink:

So on the item itself it should be fine even with updates of the same value for a while.

Thanks, I’ll give it a try. Until now I’ve never used the “expire” feature for Items and I need to understand a bit better how it works.

if it’s clearly so, that Solar Assistant does not send updates, you should use the expire-functionality as Hans already wrote on your “runtime mode”-item and reset it to “Power Off” (or whatever you set for that) for that item:

directly in code for UI - I used 30secs and “POWEROFF” as state:

value: 0h0m30s,POWEROFF
config: {}

I think I need to combine it within a rule because the Item which I need to watch, if it’s updated every 15 seconds to detect the “power off” situation, is not the Item which I need to change it’s state to “Power off”.

e.g. I have an Number:ElectricPotential Item called “inverter1OutputVoltage” where I may implement the “expire” to detect the power off situation but I don’t want to change the value of this item itself. Instead I want the change the state of a second String Item called “inverter1Mode” from it’s current value to “Power off”.

The String item which represents the running mode is not one of the messages which will be sent every 15 seconds!

I also do that with some devices, using a different MQTT property item solely for registering the offline state to then do in a rule whatever you need, without actually affecting the property you are charting.

Could even be just the name or any other static property received.

do you built the item only via rules in openHAB or does Solar Assistant sent that information? Sorry, I understood, that Solar Assistant sends the mode already.

If you build the item values from a rule already, then you can apply the “expire” on the string item as explained, because:

  1. if Solar Assisstant stops sending values=>
  2. your rule does not fire
  3. if the rule does not fire
  4. the string item is not updated for a time
  5. you can simply use the expire-metainformation

=> no need for a rule logic for that.

I’ve made a mistake.
I’ve just realized, that the mode item is really an item which is also send out also every 15 seconds (it’s not built by myself via rules). So the simple “expire” on the inverters mode String item’s like you’ve suggested is working:

… {channel=“…”, expire=“30s,Power off”}

Sorry about the confusion!

The only drawback is, that the value “Power off” gets not persistent. In case of an OH restart (or re-loading the item file), I’ll see for about 30 seconds it’s last value which was sent via Solar Assistant (e.g. “Standby”) before it again changing via “expire” definition to “Power off”.

Is the inverter’s mode Stringitem persisted, with restoreOnStartup?

Yes, all my items are persisted (with everyChange configuration). With every OH reload of the items file, I see for 30 seconds the last value which was sent by MQTT (I have not really done an OH restart, just triggered an item file reload via change in the file).

That’s interesting. A real OH restart shows the “Power off” state which was generated via the “expire” state change (restoreOnStartup is set), so it’s persisted. But any further reload of the items file still behaves like it’s not persisted and show the last (old) value received via MQTT until the “expire” property change it again to “Power off”. I don’t have an explanation about this.

Now, after waiting a couple of minutes, any further changes in the item file (and reloaded by OH) works as expected. I don’t know why it behaved so strange at the beginning, but it’s working now.
Thanks again for your help.

The message to the MQTT topic that is published by SolarAssistant is retained. What’s most likely happening is the Item gets loaded, populated by restoreOnStartup (note I assume you are not using rrd4j for this as rrd4j does not work with string Items) but then when the Thing comes online, all retained messages are processed and the Item is updated with that message.

That’s a real good explanation for this behavior! So I just need to be aware that, after a restart (and maybe a reload of the item file, also), the retained messages are processed with the previous (old) values before the “expire” property resets them again. I need to think about this especially in rules which depends on the current inverter mode!

I can think of a couple options there.

One would be to disable the persistence on the mqtt message if you have the ability to change those settings on the publisher side. Of course, you’d have to determine whether not saving the last messages on the mqtt broker would have other consequences and if that’s okay with your setup or not.

Another possibility is for you to use a rule and publish from openhab to the mqtt power topic, giving it a value of power off. That way the next time you restart openhab it is still reading the topic for the message that was last published, but the value is correct because you explicitly sent the Off value.

You could also turn on the mapdb persistence option for either the specific string item in question or for all items. Mapdb is able to persist strings so restoreOnStartup would work.

The tricky part for all of this is that the mqtt topic has the wrong value if it’s saving the last message but never sends an off value. When I’m using mqtt, I tend to try to avoid having persistence on topics that would actually put my system in the wrong state if I read them. IMO turning mqtt persistence off in this case is preferable since none of your values would actually need to be updated if the system is off, so reading any persisted values from the mqtt bus for the solar equipment is not useful.

The restored value will still get overwritten by the retained MQTT message.

The latest message retrieved from the topic will always take precedence over the restored state from persistence. OH has no way to know that the message it received was retained or not, it just knows it received a message.

If the solar inverter is smart enough to use the retained flag, it’s probably smart enough to use a LWT.

I’m not certain how OH handles this but I would not be surprised if the Thing were configured to go OFFLINE if the LWT message indicates the device is OFFLINE, it will ignore any messages from that device. I also wouldn’t be surprised if the opposite is true so that needs to be tested.

If the Thing being OFFLINE doesn’t cause the messages to be ignored, the LWT message could be used in other ways. For example, a rule could update all the Items to UNDEF or something like that when the Thing goes OFFLINE. I used to do that sort of thing all the time.