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
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.
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:
leave it as it is and have a rule for each device with a lot of Item in the ‘when’ clause
add a group for every device, check for the group change
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 , 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.
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.
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