Using rules for updating item with last update time of several sensors

  • Platform information:
    • openHAB version: 2.5.8
  • Issue of the topic: I want to keep track of the last update / change time of a sensor as the reported battery percentage / voltage is unreliable

So hi there,

First I try to describe what i wanted to archive and why.
I have several Z-Wave Sensors/Actors and several selfmade sensors which all send their infos/status via Z-Wave or MQTT to Openhab.
So far so good.
But as the reported Batterylevel of several Z-Wave devices is highly unreliable i decided to keep track of when a device sends it last update / change.

Why are the Batterylevels unreliable? E.q. one Heiman Sensor reports 0% Batterylevel since at least 4 weeks, but still works. Other devices change their Battery level from 100% to something inbetwen to 0% and back up again faster than some singers change their clothes during a concert.

So what did i do?

  • For every Zwave Device i created a Thing in PaperUi with a Item for nearly every channel available
  • in a rule file for the “update” i added a Number variable last_changeItemDEVICENAME to track if the last update is at least old minute old (my C02 Sensor sends every C02 change via MQTT, which results in a update every second).
  • also I added for every device an Item DateTime Devicename_Update .... to safe the time and date of the last update and so that I can display it in a sitemap
  • and finally i created for every device a rule like the following
rule "Livingroom_small_heat"
when 
	 Item Livingroom_small_Thermo_AlarmPower changed or
	 Item Livingroom_small_Thermo_AlarmSystem changed or
	 Item Livingroom_small_Thermo_BasicDeprecated changed or
	 Item Livingroom_small_Thermo_BatteryLevel changed or
	 Item Livingroom_small_Thermo_CurrentTemperature changed or
	 Item Livingroom_small_Thermo_Dimmer changed or
	 Item Livingroom_small_Thermo_LocalDeviceProtection changed or
	 Item Livingroom_small_Thermo_SetpointEnergyHeat changed or
	 Item Livingroom_small_Thermo_SetpointHeat changed or
	 Item Livingroom_small_Thermo_ThermostatMode changed

then
	changedItemDummy = (now.millis - last_changeItemLivingSmallHeat)
	if (changedItemDummy < eineMinute) return; // last update was not even a minute ago
	last_changeItemLivingSmallHeat = now.millis
	Livingroom_small_Thermo_Update.postUpdate( new DateTimeType())
end

A possible solution could be to create a group for every device i have in my network and just look if a group member changed / received an update. Possible, but also no fun to add these groups in PaperUi or Habmin later on to existing Things.
Using the Thing as a trigger also won’t work, tested it already. The explanation is simple: the status of a thing is either ‘Offline’, ‘Online’ or something inbetween, but as far as i know there is not a way to get a simple rule, like the one above, to trigger if a chanel in the thing received a update.

If i forgot to add important informations to my question, please don’t hesitate and ask me.

But overall this is a lot of work for every device.
I wanted to discuss if there could be a better way, I think that maybe I think to complicated :frowning:

I’m using a rule to track the last update for my batteries sensors. I find it on forum, but I don’t remember where:

rules

    // This Rule triggers when any Item in the gRecordLastUpdate Group is updated, and
    // updates a virtual DateTime item with the same name as the Item but with _LUD as
    // a suffix, setting it to the current date and time.
    rule "Record Last Update"
    when
      Member of gRecordLastUpdate received update
    then
      // post an update to the item with the same name and _LUD suffix
      sendCommand( triggeringItem.name+"_LUD", now.toString)
    end

items

    Number  LivingRoom_DanfossSetpoint      "LivingRoom Danfoss Setpoint"
    Number  LivingRoom_DanfossBattery       "LivingRoom Danfoss Battery"    (gRecordLastUpdate)  
    DateTime LivingRoom_DanfossBattery_LUD   "Last Update [%1$tH:%1$tM:%1$tS]"

If i understood your code and rule correctly you just update on batterylevel change.
Which roughly translates to my “all items of one device in one group” possibility.

For youre case it will look something like this:

items

    Number      Livingroom_small_Thermo_AlarmPower          (gRecordLastUpdate)  
    Number      Livingroom_small_Thermo_AlarmSystem         (gRecordLastUpdate)  
    Number      Livingroom_small_Thermo_BasicDeprecated     (gRecordLastUpdate) 

    DateTime    Livingroom_small_Thermo_AlarmPower_LUD          "Last Update [%1$tH:%1$tM:%1$tS]"
    DateTime    Livingroom_small_Thermo_AlarmSystem_LUD         "Last Update [%1$tH:%1$tM:%1$tS]"
    DateTime    Livingroom_small_Thermo_BasicDeprecated_LUD     "Last Update [%1$tH:%1$tM:%1$tS]"

So you need to add every items you want to track in the gRecordLastUpdate group and you need to create a new item with the same name and ‘_LUD’ termination.

Yes, I only track one item per device. I use a lot of esp devices with temperature, humidity and atmo pressure sensor, for these I only track the temperature.

At least the DateTime Entries could be reduced greatly to one needed if you have a group for each device.
So at least from the feedback right now i have three options:

  1. leave it as it is and have a rule for each device with a lot of Item in the ‘when’ clause
  2. add a group for every device, check for the group change
  3. have one big group with every Item in there and add for every item a corresponding DateTime entry with e.q. ‘_LUD’ appended by the name and handle everything with only one rule

For solution two i don’t really see a benefit: Adding a group to each device in PaperUi will be a long and tiresome work and the yeah the rule itself will be a little bit easier, but that’s all.

For solution three the benefit is: One rule too rule them all :wink:, but with the downside to have a ton of ‘_LUD’ items. To Display these in a sitemap will need a lot of extra work again.

For info, you can store the last update time in an Item directly (no rules required) using Profiles. See this post for details:

Potentially not worth it in this case, because you need a rule for other things anyway, but just nice to know!

Over all the approach you eliminated as too much work is going to be the least amount of work. Create a Group to represent each device, add all the Items linked to the Channels for that device and trigger your rule with Member of triggers.

The DP linked above shows how to make your rule generic so you only need the one rule for all your devices. There is nothing that is going to be be easier or less work. If its PaperUI that is the problem, you might consider trying out OH 3 or moving to text configs for your Items.

Thank you for the hint with the DP.
I used the mean time and added the group for each device (which is still ongoing, lot of devices),
So far I can say two things:

  • Yeah it is easier than i thought and i don’t understand why some devices send their battery value not even once a day.
  • i have to rename some items, because my naming style for the items evolved as the number of devices has grown.

Overall it could work, some fiddling still for me to get the one-rule-to-rule-them-all approach really working, but it looks promising.

It consumes battery to report the battery status.

I agree with you that it consumes power, but interesting at least.
One of my sensors is a window sensor, the window itself is opended/closed at least two times a day, but the battery level is not send once from this device.
Than there are other devices, same company, same window sensor but other windows. They send their update at least 2 times a day. And yes i checked they have all the same config. Out of 10 of these sensors 4 don’t send a update. From the 10 sensors 6 still have 100% battery level.
So at least in my environment:
Using Battery Level Update as a hint that the device is still active is unreliable.

I think i got it with one rule, to rule them all.
Thanks to @rlkoshak and @LaurentiuB forthe inspirations!

It is not perfect but it works. So there is room for improvement in the future.

Here the rule in general, i shortended it a bit (removed all but 3 groups, you get the idea, i think)

rule "Zwave Update"
when 
    Member of FF_Livingroom_Door         received update or
    ...
    Member of GF_Office_Window           received update or
    Member of GF_Office_Power            received update

then
	// post an update to the item with the same name and _LUD suffix
    sendCommand( triggeringItem.groupNames.last+"_LUD", now.toString)
end

And here one example of an item:

DateTime    FF_Livingroom_Door_LUD                               "[Update Daten %1$td.%1$tm. %1$tH:%1$tM]"    (Last_Update_Sensor)