Rule to Check LastWakeUp on ZWave battery devices

I would like to write a rule to check if the LastWakeUp property of a ZWave battery device is older than a certain period of time. i.e. to check if it has been lost. => Does anyone have ideas about how to access a Thing’s properties in a Rule?

You could use the REST API to get the thing, then use JSONPATH to extract the value of the zwave_lastwakeup property. Note that the things API endpoint now requires authentication.

@mhilbush many thanks; great idea.

Isn’t that a bit weird. The Rule would be running inside the OH Server (i.e making a REST call to localhost) so IMHO authentication should not really be necessary.

I have chosen a different approach. I put the battery items in a group called ZWOGUP and create an additional item for each battery item for the last update timestamp. This DateTime item hast the same name as the battery item but ends with the suffix _LUP (for LastUPdate):

Number 	 BA_KOCH_WS  "BA_KOCH_WS (OG186) [%d %%]"  <battery> (zwogup) {channel="remoteopenhab:server:ZWOG:node186_battery_level"}
DateTime BA_KOCH_WS_LCH	"LCH Bat.Terr.tür Süd [%1$ta %1$td.%1$tm.%1$ty %1$tT]"	<clock>
DateTime BA_KOCH_WS_LUP	"LUP Bat.Terr.tür Süd [%1$ta %1$td.%1$tm.%1$ty %1$tT]"	<clock>

Then I have a rule that is triggered when a member item of the group ZWOGUP receives an update. In the rule I post the actual timestamp to the _LUP-item:

rule "MemberUpdatezwogup"
when
    Member of zwogup received update
then
    postUpdate(triggeringItem.name+"_LUP", new DateTimeType().toString)
end

So I have a timestamp for all my battery items and I slo grouped them on one page in my BasicUI sitemap:

@vossivossi thank you; that is a really cool suggestion. I do just wonder whether ‘received update’ is always only triggered when the actual device physically checks in; or is there a chance that ‘received update’ might be triggered internally inside OH, leading to a wrong assumption that the device is Ok? What is your experience?

From my experience this works really good and update timestamps are reliable. I persist the items and in my persistence strategy I restore them on startup.

Perfect! Many thanks.

There is a difference between last update and last wake up. Ideally, a z-wave device wakes up periodically to grep updates from the controller and send/update status updates if they occur. This can be less than a month or nearly never in case it is a leak sensor. But it wakes up up every day (or hour or every 10 days etc. )

As far as I know there is no way to access the LastWakeUp in Rules DSL but in NGRE.
This is the Jython Rule I use (I think I found it in this forum):

from core.rules import rule
from core.triggers import when
from core.metadata import get_value
from core.log import logging, LOG_PREFIX
from org.eclipse.smarthome.core.thing import ThingUID
LOG = logging.getLogger("{}.ZWaveLastWakeup".format(LOG_PREFIX))

@rule("Update ZWave LastWakeup Values on Battery Operated Devices")
@when("Time cron 0 0/5 * 1/1 * ? *")
def zwave_last_wakeup(event):
    for i in ir.getItem("zwaveLastWakeup").members:
        LOG.debug("ItemName=[{}]".format(i.name))
        name = get_value(i.name, "name")
        LOG.debug("ThingUID=[{}]".format(name))
        thing = things.get(ThingUID(name))
        last_wakeup = thing.properties.get("zwave_lastwakeup")
        events.postUpdate(i.name, last_wakeup)

It is not perfect and not event driven, but works well.

This is my Item:

DateTime FloodWaterSensor_LastWakeup "Last Wakeup [%1$td.%1$tm.%1$tY %1$tH:%1$tM:%1$tS]" <calendar> (zwaveLastWakeup) {name="zwave:device:32303136-3131-3033-3030-303032383733:node51"}

Before, I used this Item definition using http binding:

DateTime FloodSensorFloodWaterSensor_LastWakeup  <calendar>  {http="<[http://127.0.0.1:8080/rest/things/zwave%3Adevice%3A32303136-3131-3033-3030-303032383733%3Anode51:600000:JSONPATH($.properties.zwave_lastwakeup)]"}

This all is for OH 2.5…

@danil thank you for your insight. I guess that I am indeed looking for ‘last wake up’ rather than ‘last wake update’. :slight_smile:

@danil, I am interested to know why you changed?

Just to learn the new jython and helper libraries :wink:
Also metadata on item and accessing it.
Both variants are/was stable (I use only 10 battery powers devices)

Edit: ahh, I remember. It was too eliminate oh1 bindings.

Bad news: they eliminated HTTP from OH2
Good news: they added it back to OH3.

So probably I will use the latter. :slight_smile:

@danil
I actually would like to use that jython script in OH3 …
seems like I did not understand the fundamentals there however.

I added the automation and tried to first put a thisrule.py in OH-Conf/automation/js223
there it already was not recognized. I further tested the helloworld example from the docs. Aswell that script does not show up in the log.

So next try: via UI … added the code from above … there I have a run now option but it seems like the when definiton from the script is being ignored?
should when adding the script via UI only the script part being added and the schedule being set via “schedule” from the menu or is this either or…? confused

That script requires:

The code above won’t work unless both steps have been performed correctly. The Helloworld example is a way to test that everything is set up correctly. If that doesn’t work, nothing is going to work.

You cannot just copy a text based rule from a forum post and put it into a Script verbatim. Ui rules are constructed differently.

hello world works. however the part with helper libs was not in the doc that I looked at.
I tried first to add the text based rule in the automation folder which did not work … missing those libs.
I thought all libs from that rule are part of the jython install when adding that automatcion.

In the meanwhile I stumbled over the thready describing everything with that helper libs.
I might try but it feels a little “manual”.

since the helper stuff is just abstracting things the same (read zwave wakeup from thing props) should be feasible just with a script + schedule via UI - correct?`

Best

For now, the helper libraries are not part of the openHAB project and there is no add-on yet to install them.

Yes but:

  • you’ll want to look at the helper libraries to see how to do the stuff imported from core

  • if you want it to trigger based.on an event you’ll need to create a Rule, not a Script. The @rule, @when parts of the rule are defined through the UI, not as part of the code part of the rule

  • you can’t have “global” variables. All you can do is what is inside the function…

Here is an example of how to access the Lastwakeup property in DSL (OH3.2):

var headers = newHashMap("Authorization" -> "Bearer oh.resttoken.7cQ9rLkGhU3gUlzR2vJpVy7WwvUT0T1S8HgBcREsrij4L5FZixrbkcnpxS96HniUiCyGMcYRFac3AjrChQnF67", "WWW-Authenticate" -> "Basic")
var String url = "http://mypi:8080/rest/things/zwave%3Adevice%3A183a957ea8%3Anode3"          
var String json = sendHttpGetRequest(url, headers, 10000)
var String lastwakeupStr = transform("JSONPATH", "$.properties.zwave_lastwakeup", json)  // filter the lastwakeup property
var DateTimeType lastwakeupDTT = DateTimeType.valueOf(lastwakeupStr)                     // convert string to DateTimeType 
zWave003Lastwakeup.postUpdate(lastwakeupDTT)

The token in the first line can be obtained by clicking on the admin user (bottom left). There you can generate a token.

I execute the rule once a day. To display the date nicely, I add a pattern %1$td-%1$tm-%1$tY to the stateDescription metadata of the item.

I also raise an alarm if the wakeup time is longer than 2 days:

var wakeup = "OK"
if (now >lastwakeupDTT.getZonedDateTime.plusDays(2))  
{
  wakeup = "NOK"
}
zWave003LastwakeupStatus.postUpdate(wakeup)
2 Likes

I edited and simplified the code above according to this post:
https://community.openhab.org/t/datetime-conversion-openhab-3-x/107197
from @anfaenger
It is a good explanation of the possible DateTime conversions.

I used JustingG’s simple solution wich works great: