Calculation of Switch duty cycle and/or activation time in rules

Hi all,

my question does not relate to a specific setup. I’m using OH3 with rules in text files.

For my analysis I would like to calculate the total activation time and/or ED for a couple of persisted switch items. I can display the state (ON or OFF) in grafana but I would like to have something like: ED(switch.item({last 365 days})) = 0.40 or ActivationTime(switch.item({last 7 days})) = 64.4 hours.

Any ideas to solve this ?

Not sure about that. Did you try .averageSince()? (should be ED)

You’re right - didn’t think of the most obvious :grimacing: - thanks

Unchecked the solution because it doesn’t seem to work as expected. I persist on change only, this always leads to EDs between 49 and 51 %. Probably this will only work if the switch value is persisted at least every minute. Any other ideas ?

averageSince is time-weighted. It shouldn’t require every minute persistence.

If you’re not getting the value you expect, are you sure the function is referencing the correct persistence service? If you have multiple persistence services the function will use the default service unless specified. This might not be the service you are expecting.

This is not the only persisted value I am using. Other values, such like temperatures, work apparently fine. I just checked another switch value, which should provide an ED of estimated 1 %. It also shows a value between 49 and 51 % (0.4974689978572280).


sorry if this sounds stupid but what is „ED“?

1 Like

But you’re not giving us much to work with. Which persistence service are you using? This can influence resuklts, e.g MapDB would be hopeless, rrd4j approximate, etc. May we see the query that produces unexpected results?

Ah, sorry. I mean duty cycle.

Ok, I’m using influx & grafana for visual representation. So grafana shows the correct graphs. What do you mean by query ?

I tried the following:

    EDtemp = szTorWarten.averageSince(now.minusHours(24)) as Number
    EDperc = szTorWarten.averageSince(now.minusHours(24), "influxdb") as Number 
    logInfo('rules','ED TorWarten {}, {}', EDtemp, EDperc)

And this is, what grafana does:

That’s exactly what I meant by “query”, yes.
May we see the log output? I’m prying at what you see because there is talk of %, I would not expect to see literal %.
Could you retrieve a .historicState for the same time target and log that, for a baseline record?

I doubt applying “as Number” has any effect here, but try without just in case.
(You cannot “as Number” raw historicState anyway)

That’s what I got:

2022-12-16 16:40:30.814 [INFO ] [org.openhab.core.model.script.rules ] - ED TorWarten 0.4993328383237941, 0.4993328323404844
2022-12-16 16:45:30.814 [INFO ] [org.openhab.core.model.script.rules ] - ED TorWarten 0.4975442748695697, 0.4975442689290464
2022-12-16 16:50:30.815 [INFO ] [org.openhab.core.model.script.rules ] - ED TorWarten 0.4957684786179370, 0.4957684668215491

Sure, no percent signs - that’s just formatting. For me 50% = 0.5.

EDtemp = szTorWarten.averageSince(now.minusHours(24)) 
EDperc = szTorWarten.averageSince(now.minusHours(24), "influxdb") 
EDhist = szTorWarten.historicState(now.minusHours(24)).state
EDhist2 = szTorWarten.historicState(now.minusHours(24), "influxdb").state
logInfo('rules','ED TorWarten {}, {}, {}, {}', EDtemp, EDperc, EDhist, EDhist2)

gives two additional "OFF"s in the log.

And, hopefully, a timestamp in the right area?

Assuming yes, that all looks sensible and I would say the averageSince function is broken for Switch (it is a special case after all).

Your openHAB version becomes of interest now.

That’s OH 3.30 release build, running on debian x86. Uname -r gives 4.19.0-20-amd64.

Java is:
openjdk 11.0.17 2022-10-18 LTS OpenJDK Runtime Environment Zulu11.60+19-CA (build 11.0.17+8-LTS) OpenJDK 64-Bit Server VM Zulu11.60+19-CA (build 11.0.17+8-LTS, mixed mode)

Well, since we’re talking about averageSince: I found another unexpected result while taking a 24h average value for brightness. The brightness (green) goes down to 0 at night which means that there are no updates in the database. This is what grafana makes out of it:


I am not able to explain why the 24h average value (yellow) makes a jump at 4pm. I was expecting a smooth curve like there is for temperatures.

As a potential source of surprises, just make sure everyone is on the same timezone - the important ones here would be Java (not openHAB) as revealed by log stamping, and the reported timestamp from historicState (that we haven’t seen yet). And that of your influx.

Well, how can I check that ?

Well, you can see the date/time stamp of the entries in your openhab.log when you run your test rule. Are they correct? This tells about the Jave sub-system timekeeping.

And the unseen response to historicState should inclufe a date/timestamp as well as a state, which relates to the record retrieved. Does that correspond to -24hrs or whatever you asked for (plus a bit to reach next-ojdest)?

Influxdb I don’t know about; databases keeping time series records need to know the time, so there’s probably a timezone setting.
But if the historicState is functioning correctly that is probably good enough.

I’ve been back at the problem. The easiest solution is to have a numerical copy of the switch state persisted (something like 1.0 for ON and 0.0 for OFF). On these values the averageSince seems to work correctly. On the switch data it definitely doesn’t, at least not with influx.

Thanks for all posts helping me to find a proper solution.

Again back to start. It only seemed to work correctly in the beginning but it definitely didn’t last. So I’m beginning to doubt that the averageSince function works at all - at least it doesn’t do its time compensated job with influx.

Now I track and persist the operating hours of the switch. I then take the difference of the operating hours for the last 24 hours and divide it by 24 to get the duty cycle. This seems to work …