How to find out if binding stopped working?

I have 50+ sensor in my home, and I get notifications if the battery is about to die. But recently I also had cases where the MQTT server stopped and a api key expired. This means that my rules would still work nicely since the sensors still has a valid value, it just hasn’t been updated for weeks!!

So can I add all my sensor to a group :
Group_Sensors
and every time a member of that group get a change I check
if now()-sensor.lastupdate>1h then send notification ?

Or do I need to create 50++ DateTime objects for each sensor and use @rlkoshak associated items to check this or is there a smarter way? Like using exec binding and check for errors in the log?

Possible option would be to use the expire binding. Have expire set to 0, “offline” or something that works for you for each of these items. That way if you stop getting updates regularly from your devices, OH will just set them to a this default which you can use a rule to trigger off of.

Totally use Expire binding as Moxified suggests. However, there is an edge case you will need to handle. If OH restarts or you reload a .items file after a device goes down but before the Expire binding triggers then that Item will never be reset to or whatever value you use to indicate it is not reporting.

Thankfully there is an easy way to handle this. Add every Item that has an Expire binding to a gResetExpire group and use the following Rule:

rule "Reset Expire Timers"
when
    System started
then
    Thread::sleep(1000) // may be required if your persistence routinely does not complete restoreOnStartup before this rule runs
    gResetExpire.members.forEach[i | i.postUpdate(i.state)]
end

Design Patterns: Generic Is Alive is another approach if you want to have a separate Item represent the online/offline state of the device. But in this case, I think the Expire binding is the best way to go.

2 Likes

Fantastic… Didn’t know this was an issue… fixing tonight!

I should also say that another approach that Thom D. advocates is to let your Items come up as NULL and do not use restoreOnStartup. In that case, the edge case is already handled because the dead items will remain NULL. To get an alert I would:

rule "Alert for Items that are still NULL 10 minutes after startup"
when
    System started
then
    createTimer(now.plusMinutes(10), [|
        if(gBatteries.members.filter[i | i.state == NULL].size > 0) {
            val alertMsg = new StringBuilder()
            alertMsg.append("The following Items are still NULL after 10 minutes:")
            gBatteries.members.filter[i | i.state == NULL].forEach[i | alertMsg.append(i.name + ", ")]
        }
    ])
end

Good point. I don’t restore these items on startup so I guess this wasn’t an issue for me. But, I haven’t implemented an alert on them yet so I have some ideas on where to start from.

Nice Idea!
My initial thought was to make a dictionary(does OH have this?) and as the key use the item name and for the value set the update time.

Then have a new item call sendNotification which uses the expire binding with a timeout of lets say 1h, so if presence is detected and time of day is between afternoon and night then we loop through the dictionary every hour to check last update time and see if this is longer ago then 1h.

But I like @Moxified and @rlkoshak idea, so I guess i will start redefining my items :slight_smile:

Also @ThomDietrich approach is great for checking if items is null, so I guess I will add all my items to a group called Group_AllItems(or is there such a group by default in OH?)

Yes, they are called Maps and the most commonly used version is HashMap

There is no all items group.

So I guess what I will do is this:

Number Miflora_Sensor4_Moisture "Sensor4 Soil Moisture [%d %%]" <text> (gMiflora, Group_Moisture,Group_Moisture_LivingRoom) {mqtt="<[mosquitto:miflora/sensor4:state:JSONPATH($.moisture)]", expire="1h,command=NULL" }

and then add them to the all group:

Group Group_Moisture "Mi Flora Soil Moisture elements" (Group_Allitems)

Finally make this rule:

rule "Alert for Items that are  NULL for more than 1 hour  "
when
   Item Presence_Home changed from OFF to ON
then
  
       if(Group_Allitems.members.filter[i | i.state == NULL].size > 0) {
           val alertMsg = new StringBuilder()
           alertMsg.append("The following Items are still NULL after 1 hour:")
           Group_Allitems.members.filter[i | i.state == NULL].forEach[i | alertMsg.append(i.name + ", ")]
           sendMail("skxxxxx@gmail.com","Sensor need to be checked",alertMsg.toString())
       }
   ])
end

Looks good to me. One thing I do is generate an alert when an item does go NULL and then I create a digest at 8 am every morning listing those other that are offline. So it isn’t too different from what you have here.

Though I have separate online switches which use expire to time out. They are all network binding, mqtt heartbeats, it zwave heart beats so it made the most sense to implement like that for me.

Not to pull this thread off topic but have you done any write-ups that would add some detail to this digest concept? I have limited myself to pushover thus far and it has some pros and cons. I like the sound of a digest.

My mind thinks up a rule that fires at 8 am and sends an email with a bunch of states it pulls from current and persistence maybe? Knowing you and your fancy ways, I suspect there has to be more :slight_smile:

It is basically the StringBuilder code above coupled with Design Pattern: Human Readable Names in Messages.

In fact the code in that DP is what I am referring to if you want a full example.

The digest is independent of how the message is delivered. I use Design Pattern: Separation of Behaviors for alerting and use a different service depending on the severity of the alerts (e.g. alerts go to all users, info only comes to me) and time of day (even alerts only come to me at night). So you can deliver it using any push notification or delivery you want.

I’m currently experimenting with a Google AIY Voice as be I’m going to implement a command where I can ask “Hey Google, what’s up” and I’ll get a report on the state of the home automation. For that I haven’t decided on an approach yet. I see two potential approaches:

  1. Send an MQTT message to generate the report and get the report back via MQTT.

  2. Maintain a String item with the report that is always kept up to date and use the REST api to pull it down.

I’m not sure what approach I want to take.

:blush:

I like solutions that are decoupled and flexible. My goal with the design patterns are to promote that sort of thinking.

2 Likes

I was just wondering what happens if i set the number items to null for one item in the group and then after take average of the group, will that value just be ignored? I hope so, because I use group based average to control my heat based on the average of 12 sensors… and if MQTT goes down while I am on holiday I still have 2 more sensors using other bindings so it should be no sleepless night then :slight_smile:

It seems like this does not get set to null, am I doing something wrong with the expire binding? No errors to be seen in VS or logs as far as I can see, sensor 9 should be null and not 0%

Are we sure expire supports setting to null? I don’t see much mention of it anywhere.

If its not supported then it is hard to make a generic rule or?

Don’t get me wrong. I don’t KNOW it isn’t supported. I’m just raising the question.

You could try turning trace on for the expire binding. That might throw an error or something if it isn’t supported.

Beyond that, I set my devices to “OFFLINE”. I like the look of a red colored “OFFLINE” on my sitemap so it made sense. You could then adapt your rule to look for “OFFLINE” instead of NULL. Should be able to just substitute:

i.state == "OFFLINE"

But I’m no coding genius. I’m more of a hack really. :slightly_frowning_face:

Ok, OFFLINE would work just fine, so OFFLINE is valid for all item types?

It doesn’t really make sense to send command NULL. What is the binding supposed to do with it?
Try using state=NULL.

If you don’t specify, expire will set your item to NULL or UNDEF depending on what the Item type is.

1 Like

No and a valid point. I’m using stings.

For a solid one size fits all, NULL or UNDEF would be best if it works. Try Rich’s recommendation and let us know. I’m curious as well.