Detecting offline Things in a less stupid way

@fullmoonguru I used the trigger to catch a new custom event and added every received event to a linked queue to be processed (because usually you receive more than one event if a thing goes offline…)

rule “Event log management”
when
Channel “logreader:reader:b211c4e3:newCustomEvent” triggered
then
if (logEvents.peek === null && evento.state.toString == “ON”)
evento.postUpdate (OFF)
logEvents.add(receivedEvent.toString())
if(timer === null && evento.state.toString != “ON”) {
timer = createTimer(now.plusSeconds(5), [ |
if (evento.state.toString != “ON”) {
evento.sendCommand(ON)
timer = null
}
])
}
end

I put in patterns for the logreader thing “to ONLINE|to OFFLINE” and filtered out ItemStateChangedEvent to avoid the loop.

1 Like

@Rickytr I’m pretty new at this. When you say:

I put in patterns for the logreader thing “to ONLINE|to OFFLINE” and filtered out ItemStateChangedEvent to avoid the loop.

How did you do that?

Then in the script, I’m not clear what it’s doing. It looks like it’s posting an event (a virtual switch you created?) as OFF if something is offline and ON if nothing is offline. Not clear what teh timer is doing.

Sorry for my noob questions & thanks for your help.

You’ll want to read up on

@fullmoonguru I use the switch to start another piece of code that parse every event in the linked queue. I decided to use the timer to start parsing after some seconds because in this way I can manage better when I receive several offline errors together, for example when Hue hub goes offline with every connected light.

@rossko57 thanks for replying I DID read up on this before trying it. Here’s what I tried:

First I did:

Rule ID = Device_Offline_Alert

When > Thing Event > Log Reader > A Trigger Channel Fired > Channel > New Error Event > Event = COMMUNICATION_ERROR

Then > Execute a script (my email script)

That didn’t work so then I tried:

When > Thing Event > Log Reader > Trigger Channel Fires > Channel: newCustomEvent > Event = COMMUNICATION_ERROR

No luck there either.

I also tried Status change to OFFLINE and Status updated to OFFLINE, in the Logreader thing which didn’t work (I assume that’s because it’s referring to the Logreader thing itself).

I can see the alerts in the logfile so I know that’s working, and I know the email is working because I can get successful results by making the trigger an offline alert from a specific Thing.

@rossko57 do you have any ideas why this isn’t working for me?

is difficult to diagnose. Did the rule run, is it your email that doesn’t work? It’s up to you to find out. You could add a log at the start of your rule to say when it’s triggered.

Do you see that in your events.log ? May we see? Does it match your rule trigger? May we see that? ('code’if you are using UI rules)

Are there any new options in OH3 to support “monitoring a group of things”
a) thing status changed
b) certain channels are triggered

This should be based on groups. I just started to implement a rule monitoring my Shellys in an alarm is triggered. After the 15h “Chanel xxx triggered oir” I stopped and looking for other options. For me it doesn’t make sense that I need to list every channel and hard code the thing uid. Why is it not possible to build a group of channels?
or could I

  • build a group of things (possible with the OH3 model)
  • have a periodic rule (once a minute)
  • iterate on the group, get thing status and check for OFFLINE

That would be ok for checking the thing status, but even doesn’t cover the aspect that things raise an alarm by triggering a channel.

As with pretty much all “why” questions in openHAB, the answer is because no one has implemented it. Adding support for something like this will require changes to the core API and rule engine triggers since the ThingRegistry doesn’t have any way to get all Things or all Things with a given tag or anything like that.

Not possible, The model is just a way to organize your Items.

This is very much possible.

Given you can’t use the ThingRegistry to get the list of all Things and you can’t create a Group of Things about the only remaining thing you can do is to query the REST API for all the Things and parse through the returned JSON. You could put that into a once a minute triggered rule or the like.

@rossko57 I had a logfile running and could see the Thing drop. I just never saw the rule trigger. The email is the same script I use for other alerts and I also manually triggered the rule and got the email. I am working on some other issues right now but I’ll get back on this and try to give more detailed info. I appreciate the help.

@rossko57 OK, back on this. This is the log entry I get when a device drops.

2021-05-10 15:41:11.368 [INFO ] [ab.event.ThingStatusInfoChangedEvent] - Thing 'zwave:device:Z-Wave_Serial_Controller:node4' changed from ONLINE to OFFLINE (COMMUNICATION_ERROR): Node is not communicating with controller

I’m not sure if flagging an error alert doesn’t work because this is an info alert? How would you use Log Reader to trigger from something in this log?

No idea. How have you configured your log reader?

I wouldn’t. Personal choice, I would trigger a rule from Thing xxx:xxx changed

Thank you for this piece of code. I was looking for a way to check the status of things in HABApp because Homematic stuff needs some time after booting to initialize. HABApp is to fast. Is there also a way to come from an OpenHAB item to the linked thing to get the status?

What do you mean by that? The startup of HABApp?
It should work non the less!

You can read the item definition from OpenHAB and then get the link and use that to get the thing.
However, the thing uuid is static, so I would just copy paste that from the gui.
Is there any reason this does not work for you?

I have created a complex class for controling the rollershutters for a room. The constructor gets as parameter the room name and then collects the objects for the rollershutters, the alarm contacts, light,… in the room.
Then, base on a rule engine, actions are triggered on events. I use the same class for all the rooms in my house. So I can’t hard code the gui’s per room.
When booting up my Raspberry Pi OpenHAB and HabAPP starts. HabAPP has the config option wait_for_openhab. This works quite well. So HabAPP wait until OpenHAB comes up. Then the HabAPP engine starts loading the Python scripts. I can see in the log the rules are started. At the same time I see in OpenHAB the Homematic bridge thing (the CCU) is initializing. All the other things are in state “error bridge”. After the bridge is online, the other Homematic things start initializing and then became online.
At that point the rollershutter in HabAPP is already running the rule engine and the objects are in strange states. For now I fixed this by checking every item value if it’s None, then I wait until it becames a number.
But I hope there is a more elegant way to do this. My idea is to lookup the things of the items and then check the status of this thing and wait until they become online.

Can you use the -wos switch to wait a little longer after a reboot?
Imho that would be the most simple solution.

Yes, this would be an option. I will try this. Thank you.
But for the future it would be nice to include this in the object model of HabAPP. Somethink like a method get_all_items() in HABApp.openhab.items.Thing class or get_thing() in the OpenhabItem class.

The whole idea of Items is to abstract and hide implementation machinery.
Having said that, of course they usually have links.
Note that there may be multiple links - so you cannot have “a parent Thing”, you must have a list, and it may be empty.
An actual implementation is more likely to give you a list of channels, and leave you to work out what Things they belong to.

There is the get_item function on the oh interface that will return the whole item definition from openhab. The links are always named after the thing so it should be pretty easy to get it.

However I strongly agree with @rossko57 .
Items are there to hide the underlaying technical implementation and all you seem to be trying is to fix an initialization issue.
I’d rather tackle the issue through one of these different mechanisms:

  • mapdb that restores item states on startup
  • post update to the used items when the rule is loaded with sensible defaults
  • create the item listener only when the thing is online
    (just pass the thing uuid to the rule as an additional parameter)
  • use the wos switch and wait until all items have a proper state

I just use a timer if a response isnt received from the item then shows as offline.
Use ping for wifi
Updates from motion sensors/thermometers relies on the device providing an update - if it doesnt timer runs out and it shows as off line.
Im sure there are other ways but I have found that sufficient.