Jython script - best method to disable faulty Motion sensors

Running openhabian on Pi4
openHAB 3.4.0 Build #3029
jython rules

Occasionally I find some of my zigbee motion sensors become “Chatty” (my term) when the battery is running low. I have solved this issue in many sensors by modifying them to be hard-wired to a dongle. However, others still have this issue (and not convenient to hardwire)

When a motion sensor becomes Chatty, it repeatably sends ON then OFF in a fairly rapid succession (i.e. every few seconds without the typical 20 second delay, for these sensors) This can trigger undesirable results, especially my Security System rules.

I have Jython code that watches for Battery issue in order to let me know when a battery needs replacement. I use a combination of Temperature reports, Battery Voltage and Battery Level - depending on the type of device and features. And, I also monitor for this “Chatty” condition and then mark the Sensor as such until it returns to “Normal”

So, the question: I am considering various methods for ignoring sensors that are “Chatty” including:

  1. Creating a string Item that contains a list of Chatty sensors
  2. Updating some Meta Data to reflect Chatty or not
  3. Adding and removing Members from a Chatty Group (using the REST api)
  4. Disabling the sensor Thing when Chatty

Perhaps there are other methods I am not considering… basically in the Rules that trigger on the Motion Sensor, I would test if it is Chatty, then ignore the sensor.

Which method is the most efficient in terms of processing since I’d rather not add more delay to the normal sensor processing.

Ideas?

Unless you are running on an underpowered machine, which in this case a RPi 4 is not underpowered, this doesn’t matter. Or at most it matters far less than human readability and long term maintainability.

I too have some chatty sensors, only they are wired and it’s mostly a problem when it’s cold. There’s probably a loose wire somewhere or a short.

Anyway, I solved the problem with a Debounce. Set a timer and only count the new state when the Item stays in that new state for long enough. See Debounce [3.2.0;3.4.9] for a rule template you can just install and use or at least to see some code you can reimplement from. I’ve an old Jython version of it at GitHub - rkoshak/openhab-rules-tools at before-npm but this is old a no longer maintained. You’ll likely need to adjust it to get it to work on recent OH 3 instances.

This would work but I think it would require a lot of book keeping to add/remove sensors.

This would be less work since the information is kept in the Item’s metadata. Setting and reading the metadata is pretty straight forward.

You can do this through the Item Objects themselves. No need to make REST API calls.

If a Debounce won’t work, this is what I would do. There’s no point in an erroring Thing to load up your system with bad events. Better to cut them off as close to the source as possible. Again, this can be done through the ThingRegistry and Thing Objects, no need for the REST API. And with this approach you wouldn’t need to run rules just to know whether or not you need to ignore the event. Just prevent the events in the first place.

1 Like

Thanks Rich for some good suggestions.

Yes I could do this, but the biggest issue is that when I am away, my Security System would think someone is in the house (I already have logic to limit how a security intrusion is handled) … so a debounce would only reduce how often it happened.

I spent a while trying to find an Item Method to do this … does that exist?

The problem with this approach is that I want to know when the Sensor has returned to Normal. For instance, I watch for big increases in Battery Voltage to mark the Battery as “New”. I also watch for the device to become “Non-Chatty” - I use some long period of time of no sensor triggers. I also want to continue to monitor the Temperature reports which I use to definitively mark the device as Dead.

I am using Meta Data for other various things so that approach seems to be a good one. And I agree the performance issue is negligible compared to human perception time. :slight_smile:

It depends. Does the sensor eventually settle on a valid value or not. In my sensor’s case, eventually it will stop bouncing at a “true” sensor reading. So all I lose is a little increase in latency before the proxy Item updates (if it updates at all because it won’t update if the proxy is already in the same state).

From the Item: GenericItem (openHAB Core 4.2.0-SNAPSHOT API)

From the Group Item: GroupItem (openHAB Core 4.2.0-SNAPSHOT API)

1 Like

No. In my case it flaps ON then a few seconds later OFF, then repeats until the Battery finally completely dies.

Well that’s embarrassing … I did find that earlier and even tested it … lol … I need more sleep.

Now I see my confusion … I originally was trying this code:

    items["Chatty_Motion"].addMember("BackDen_Motion")

which generated the error:

AttributeError: 'org.openhab.core.types.UnDefType' object has no attribute 'addMember'

I then assumed it didn’t exist :upside_down_face: and tried the REST api and it worked.

After you said it works … I went back and realized two issues:

  1. I can’t use:
    items["group"].addMember(item)
    … I must use
    ir.getItem("group").addMember(item)

  2. Also, I need to give it the item object ir.getItem(item) so … instead I used:

    ir.getItem("Chatty_Motion").addMember(ir.getItem("BackDen_Motion"))

Which works fine.

TBH … I obviously don’t understand the difference with the construct items[“item_name”] and ir.getItem(“item_name”) … I thought they were the same. Obvioously not. :slight_smile:

ir is also available as itemRegistry. As the name implied, that’s a reference to the place where all the Items are stored. When you call getItem() on the ir, you get back the actual Java Item Object.

items is a dictionary of Item Name/State pairs. Thus items['MyItem'] is the current state of MyItem and is equivalent to ir.getItem('MyItem').state.

Yes, the items dict is uses the Item name as the key and the current state as the value. It’s not the actual Item Object (but it’s really super convenient).

Yes, I had found that I was using both methods in my code (~50 .py files) … so I started to converting them to the more convenient items["MyItem"] and made the wrong assumption :slight_smile:

Anyway, thanks for the education!