Count number of times a door got opened

I would like to count how often a door (contact) got opened. In my case I receieve this contact trough MQTT - adjust to your setup.
Group GP_Persist_Restore is configured to restore Item state at startup through persistence service.

items/door.items

Contact Door_Status "Door [%s]" <door> (GP_Persist_Restore) { channel="mqtt:topic:myTopic:door_status"}
Number:Dimensionless Door_Counter "Door Counter [%d]" <door> (GP_Persist_Restore)

So I just need a “simple” rule to count when the status of the door changes to open - handling all the type conversions and taking into account that the number is NULL in the beginning.

rules/door.rules

rule "door counter"
    when
        Item Door_Status changed to OPEN
    then
    if(Door_Counter.state != NULL) {
        Door_Counter.postUpdate((Door_Counter.state as Number) + 1)
    } else {
        Door_Counter.postUpdate(1)
    }
end
1 Like

This doesn’t mean what you think. Number:Dimensionless is for “proportions”, i.e a percentage or ratio or dB. “1” means 100% or 1:1

For counting, you just want a plain Number type.

You’ll need to decide how long a period to count for - eternity, since midnight, etc. - and maybe add another rule or a UI button to reset your counter.

I respectfully don’t agree. Dimensionless means exactly that without dimension. A plain number Type and a Dimensionless number are more or less the same.
The fact that bindings provide percentage value under this type is because that’s the only one that fits.

I agree with that, you’ll have to decide a period of counting. Maybe reset the couter every night, week, month…
A button to reset the counter is also a good idea.

Thanks for your notes!
Yeah, for a productive use an automatic reset would be great, but I wanted to keep the example simple - mainly showing the necessary unit conversion, because it wasn’t just Door_Counter.postUpdate(Door_Counter.state + 1) as I first expected.

It’s not a unit conversion, it’s a type conversion.
Item.state is a state type that needs to be further converted to a number with as Number or a string(for example) with .toString

Does that make sense? I’m on the phone and can’t highlight the syntaxes.

postUpdate and sendCommand commands accept many types as arguments depending on the item type as the conversions to a valid state are done in the background.

A simple way to add that time dimension to this would be to use persistence. Persist the Door_Status Item which should save OPEN as 1 and CLOSED as 0. Then run a Rule periodically, lets say every 5 minutes you have a simple one line Rule:

rule "door counter"
when
    Time "cron 0 */5 * * * * ? *" // I probably got this wrong
then
    Door_Counter.postUpdate(Door_Status.sumSince(now.minusDays(1)))
end

How to persist a Door status as 1 or 0 instead of OPEN and CLOSED ?

Use a proxy item and a rule. A contact Item can only be OPEN or CLOSED (and NULL and UNDEF…)

I confirm that influxDB persists an ON as a 1 and a OFF as a 0

Note that doesn’t always help when using openHAB persistence methods; the persistence layer knows it’s supposed to be a Switch type Item and converts retrieved 0/1 back to ON/OFF e.g. myItem.previousState()

For some external service doing it’s own fetches from influxdb, like Grafana, you’d get 0/1 of course.