Best Way to Determine Count of State Changes Over Last X Minutes


I have some LIFX lights that if you power cycle them several times, they hard reset themselves. These are on a scene that is highly complex and in very rare scenarios, timing issues can cause a loop. I would like to build a quick check into the scene trigger to determine if the state of a Number item has changed state more than X times in the the last Y minutes. I can think of a few ways to do this using cron-based rules or counters, but it seems to me there must be a way to do more easily using the persistence history I have on all of my items.

Can anyone suggest the best way to count the number of the last Item state changes over a specified period?



There are, I believe a lot of “depends” here and many more specifics would be required for more specific help: the values of your number item, the persistence db you have configured, etc. However, the .sumSince persistence method might do what you are looking for if your number item is alternating between 0 and some other known value.

That’s actually quite difficult over a rolling minute, knowing when to drop old events from the count.
openHAB persistence has no “count” features, but as @JustinG says you can simulate that with a binary 0/1 Item and sumSince.
Probably easiest to have a rule working the item-to-count.

I agree with what has been said thus far. There are a lot of details needed to provide specifics.

Two approaches are to use persistence and sumSince as JustinG recommends. Depending on what persistence you use, a Switch or a Contact Item gets saved as a 0 for OFF/CLOSED and 1 for ON/OPEN so sumSince would give you the number of ON events in the past minute. But that only gives you at best half of the events and it takes a little additional logic to determine the total number of events as you have to check to see if the Switch was ON before the minute started and ON now and adjust the total count as necessary. You also have make sure that you are storing updates and not just changes if the device can send the same event more than once in a row.

Another approach would be to use Timers. When an event occurs add 1 to a count variable or Item. Create a Timer to subtract one after a minute has passed.

In Python that would look something like:

from core.rules import rule
from core.triggers import when
from core.actions import ScriptExecution
from org.joda.time import DateTime

event_count = 0

@rule("Count events in the last minute")
@when("Item MyItem received update")
def count_event(event):
    global event_count
    event_count += 1
    ScriptExecution.createTimer(DateTime().now().plusMinutes(1), lambda: event_count -= 1)

In Rules DSL it would look something like:

var event_count = 0

rule "Count events in the last minute"
    Item MyItem received update
    event_count = event_count + 1
    createTimer(now.plusMinutes(1), [ | event_count = event_count - 1 ]

Note, if the events occur really close together the above could become all mixed up and fail. This is more likely to occur in Rules DSL than the Python version as the Python version prevents the rule from running more than once at a time while Rules DSL will allow the rule to run multiple times concurrently.