Meter Reading [3.3.0;3.4.9)

logo

This is a simple rule that works with an accumulating sensor reading that can be reset unpredictably. For example, a sensor that keeps track of the total kWh used but resets back to zero when the sensor loses power.

The rule will add the delta from the previous reading to the current reading to the Item holding the total. However, when the sensor Item get’s reset the rule treats the current reading as the delta. Therefore this rule only works for an accumulating sensor where the reported reading is always increasing.

If the total Item is NULL or UNDEF, it’s initialized to 0 and the delta becomes the first value.

Managing the total Item (e.g. resetting it once a day, adding up the sum for the week or month, etc.) are not handled by this rule.

Language: JavaScript Scripting

Dependencies:
JavaScript Scripting add-on installed with the default configuration

Changelog

Version 0.1

  • initial release

Resources

https://raw.githubusercontent.com/rkoshak/openhab-rules-tools/main/rule-templates/counting/counting.yaml

2 Likes

Hi Rich

just wanted to say thank you. It works an is absolutly perfect for the shelly devices which lose the sum value all the time.

BR
Daniel

1 Like

Hi Rick

Today I seem to have run into a problem with the rule. It will probably be my setup, but I would like to understand it.
I have the regular energy item from the meter and the sum item that I write the sum into. For some reason my system crashed yesterday and I rebooted today. Now the total counter value was added at startup. So it looks like the counter was reset, which didn’t happen.
Value meter about 2150kWh
Value sum yesterday about 2150kWh
Value meter after reboot 2160kWh
Value sum after reboot 4310kWh

Both items are saved on every change in rrd4j and restore on startup is enabled.

Thanks
Daniel

It’s possible that the restoreOnStartup failed so when the rule ran the sum Item was still NULL.

It’s also possible that the rule was triggered before the restoreOnStartup happened, though that’s less likely.

If it happens consistently, I’ll need some more logs, including the events.log. If it only occurred this one time after the crash, we probably won’t ever know exactly what happened.

There isn’t a whole lot that we can do inside the rule to deal with this. The rule can’t know the difference between the Item just not having been restored or just having been initialized.

If you happen to configure using openhabian, you may have ZRAM in use for your persistence services. In the event of an unexpected crash or power failure, persistence data since last controlled reboot may be lost forever. Restore-on-startup may then pull up data from long ago.

1 Like

thank you. Yes U use openhabian so this may be the reason.

If it happens again I’ll post the events log.

Thank you

BR

I have a question to this line:

var lastReading = (event.oldItemState.toString() == 'NULL' || event.oldItemState.toString() == 'UNDEF') ? 0 : event.oldItemState.floatValue();        

When can event.oldItemState be NULL/UNDEF? I think only at startup. I’m not sure if it makes sense to set lastReading to 0, because this might result in a big delta value. I would rather skip before getting a wrong delta. What is your opinion?

It’s up to the binding, rules, and anything else that updates the state of the Item. The Item is definitely NULL when OH first loads the Item. Some bindings will set an Item to UNDEF when it cannot communicate with the actual device.

The beauty of rule templates is if you want to tweak it or do something different, you can modify the code of the rule that was created from the template. You are not stuck with what’s here. You are able and encouraged to use this template as a starting point and update it as needed to meet your needs.

That’s what this basically does. If the Item state is NULL or UNDEF, the delta becomes 0 meaning the previous sum gets used. The total doesn’t suddenly drop to 0. In effect, the NULL/UNDEF is just ignored.

I think the delta doesn’t become 0, but lastReading.
If the latest meter reading is e.g. 50.000kWh, the delta would be 50.000kWh as lastReading=0 (delta = 50000 - 0).

var delta = (reading < lastReading) ? reading : (reading - lastReading);

You would sum the full 50.000kWh to totalItem. This is what I don’t unterstand.

If that’s what’s happening, it’s a bug. My intent was to just float the last reading forward and effectively ignoring the NULL/UNDEF state.

That line of code does look wrong.

I don’t actually use this template in production so it’ll take me a bit to test what’s going on and fix it. If you don’t want to wait, I’m happy to accept a fix. :wink: