OH3 rule, check in a rule if item was "ON" in past 30 minutes

Thanks for your reply. The sequence is:

When MotionSensorBath turns ON
Then Turn pseudo switch Zirkulation_5min ON

Turning on that switch will result in the corresponding rule to be triggered, which is supposed to check if the pump (the actual switch for it is called Zirkulationspumpe) is OFF, and if that’s the case, it should check if the pump has already been turned ON in the past 25 minutes. If that is the case, it should not do anything. If it wasn’t turned on, it should turn it on for 5 minutes and turn it off after those 5 minutes.

You say "of course it did: Yea, it did, so why does the rule not jump into the first if part when it is called the second time, in that 25 minute timespan? All I do in there is a logInfo entry, nothing else.

if (Zirkulationspumpe.changedSince(now.minusMinutes(25), "influxdb")) {
            logInfo("Zirkulation", "Pumpe war innerhalb der letzten 25 Minuten angeschaltet. Ignoriere 5-Minuten-Befehl.")
        } else {

Instead it always goes into the else branch, which turns on the pump.

I was thinking more of actual entries in your events.log that will show the interplay of the various Items involved.

I haven’t worked out if it is related, because I can’t see how you trigger it, but note that your rule triggers on
received update ON
and will trigger even if the Item is already ON and gets another ON (it’s not the same as changed to ON)

if (Zirkulationspumpe.changedSince(now.minusMinutes(25), "influxdb"))

Have you seen anything to suggest that is working for you at all? It will of course return false if there’s no data in that db etc.
So, things to check -
Have you an influxdb service installed, is it called “influxdb”?
REST API interactive tool is helpful to find out.
Is there any data related to your Item recorded in your db?
Again, REST API can help.
Or you can put a crude test in your rule -

logInfo("test", (Zirkulationspumpe.historicState(now.minusMinutes(25), "influxdb").state.toString)

The datetime handling, including the “now”, has changed in OH3, but I think now.minusMinutes(nn) works as in OH2.

Yea, I have influxdb installed and openHAB persists quite a few items to it:

The blue “spikes” are from the Zirkulationspumpe item. At around 13h (1 pm) you can see quite a bit of turning off/on of the pump as I was testing…

So I guess there is data there. Maybe something did change in OH3, would be nice to find out if so and what did change.

The fact that the rule might get triggered more often that it should should not really matter in this case, even though it’s a valid point. Or should it?

I agree.

Having established you’ve got data, I think you should be looking at if you can access it from your rule. OH3 is still pre-release, there have been changes in both persistence methods and time variable handling.

Tried debugging a little bit:

rule "test historic states..."
when
    Time cron "0 0/1 * * * ?"
then
    logInfo("Zirkulationspumpe.historicState(now.minusMinutes(10))", Zirkulationspumpe.historicState(now.minusMinutes(10), "influxdb").state.toString)
    logInfo("Zirkulationspumpe.historicState(now.minusMinutes(5))", Zirkulationspumpe.historicState(now.minusMinutes(5), "influxdb").state.toString)
    logInfo("Zirkulationspumpe.historicState(now.minusMinutes(3))", Zirkulationspumpe.historicState(now.minusMinutes(3), "influxdb").state.toString)
    logInfo("Zirkulationspumpe.historicState(now.minusMinutes(1))", Zirkulationspumpe.historicState(now.minusMinutes(1), "influxdb").state.toString)
    logInfo("now.minusMinutes(10)", now.minusMinutes(10).toString)
end

This is what I get, even though the “Zirkulationspumpe” was turned on for the past ~5 minutes:

2020-12-21 10:24:00.493 [INFO ] [.historicState(now.minusMinutes(10))] - OFF
2020-12-21 10:24:00.505 [INFO ] [e.historicState(now.minusMinutes(5))] - OFF
2020-12-21 10:24:00.522 [INFO ] [e.historicState(now.minusMinutes(3))] - OFF
2020-12-21 10:24:00.538 [INFO ] [e.historicState(now.minusMinutes(1))] - OFF
2020-12-21 10:24:00.543 [INFO ] [re.model.script.now.minusMinutes(10)] - 2020-12-21T10:14:00.541416+01:00[Europe/Berlin]

At least now.minutesMinutes(…) seems to be working, so I still don’t know why the historicState is always OFF. :frowning:

1 Like

Oh, but I do get regular errors in the log, but not each time the rule gets called, as far as it looks:

    2020-12-21 10:30:53.072 [ERROR] [xt.ide.server.concurrent.ReadRequest] - Error during request:
java.lang.RuntimeException: Cannot create a resource for 'java:/Objects/org.openhab.core.persistence.HistoricItem'; a registered resource factory is needed
        at org.eclipse.xtext.resource.XtextResourceSet.getResource(XtextResourceSet.java:263) ~[bundleFile:?]
        at org.eclipse.xtext.ide.server.ProjectManager.getResource(ProjectManager.java:169) ~[bundleFile:?]
        at org.eclipse.xtext.ide.server.WorkspaceManager.doRead(WorkspaceManager.java:436) ~[bundleFile:?]
        at org.eclipse.xtext.ide.server.findReferences.WorkspaceResourceAccess.readOnly(WorkspaceResourceAccess.java:36) ~[bundleFile:?]
        at org.eclipse.xtext.ide.server.symbol.DocumentSymbolService.doRead(DocumentSymbolService.java:332) ~[bundleFile:?]
        at org.eclipse.xtext.ide.server.symbol.DocumentSymbolService.getDefinitions(DocumentSymbolService.java:112) ~[bundleFile:?]
        at org.eclipse.xtext.ide.server.symbol.DocumentSymbolService.getDefinitions(DocumentSymbolService.java:99) ~[bundleFile:?]
        at org.eclipse.xtext.ide.server.LanguageServerImpl.lambda$definition$24(LanguageServerImpl.java:603) ~[bundleFile:?]
        at org.eclipse.xtext.ide.server.WorkspaceManager.doRead(WorkspaceManager.java:438) ~[bundleFile:?]
        at org.eclipse.xtext.ide.server.LanguageServerImpl.definition(LanguageServerImpl.java:602) ~[bundleFile:?]
        at org.eclipse.xtext.ide.server.LanguageServerImpl.definition(LanguageServerImpl.java:590) ~[bundleFile:?]
        at org.eclipse.xtext.ide.server.LanguageServerImpl.lambda$definition$23(LanguageServerImpl.java:581) ~[bundleFile:?]
        at org.eclipse.xtext.ide.server.concurrent.ReadRequest.lambda$doRun$0(ReadRequest.java:66) [bundleFile:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
        at java.lang.Thread.run(Thread.java:834) [?:?]
2020-12-21 10:30:54.246 [ERROR] [t.ide.server.concurrent.WriteRequest] - Error during request:
java.util.concurrent.CompletionException: java.lang.RuntimeException: Cannot create a resource for 'java:/Objects/org.openhab.core.persistence.HistoricItem'; a registered resource factory is needed
        at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:331) ~[?:?]
        at java.util.concurrent.CompletableFuture.andTree(CompletableFuture.java:1452) ~[?:?]
        at java.util.concurrent.CompletableFuture.andTree(CompletableFuture.java:1444) ~[?:?]
        at java.util.concurrent.CompletableFuture.andTree(CompletableFuture.java:1444) ~[?:?]
        at java.util.concurrent.CompletableFuture.allOf(CompletableFuture.java:2337) ~[?:?]
        at org.eclipse.xtext.ide.server.concurrent.RequestManager.cancel(RequestManager.java:114) ~[?:?]
        at org.eclipse.xtext.ide.server.concurrent.RequestManager.runWrite(RequestManager.java:80) ~[?:?]
        at org.eclipse.xtext.ide.server.LanguageServerImpl.runBuildable(LanguageServerImpl.java:453) ~[?:?]
        at org.eclipse.xtext.ide.server.LanguageServerImpl.didChange(LanguageServerImpl.java:393) ~[?:?]
        at jdk.internal.reflect.GeneratedMethodAccessor295.invoke(Unknown Source) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
        at org.eclipse.lsp4j.jsonrpc.services.GenericEndpoint.lambda$null$0(GenericEndpoint.java:65) ~[?:?]
        at org.eclipse.lsp4j.jsonrpc.services.GenericEndpoint.notify(GenericEndpoint.java:152) ~[?:?]
        at org.eclipse.lsp4j.jsonrpc.RemoteEndpoint.handleNotification(RemoteEndpoint.java:220) ~[?:?]
        at org.eclipse.lsp4j.jsonrpc.RemoteEndpoint.consume(RemoteEndpoint.java:187) ~[?:?]
        at org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer.handleMessage(StreamMessageProducer.java:194) ~[?:?]
        at org.eclipse.lsp4j.jsonrpc.json.StreamMessageProducer.listen(StreamMessageProducer.java:94) ~[?:?]
        at org.eclipse.lsp4j.jsonrpc.json.ConcurrentMessageProcessor.run(ConcurrentMessageProcessor.java:113) ~[?:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
        at java.lang.Thread.run(Thread.java:834) [?:?]
Caused by: java.lang.RuntimeException: Cannot create a resource for 'java:/Objects/org.openhab.core.persistence.HistoricItem'; a registered resource factory is needed
        at org.eclipse.xtext.resource.XtextResourceSet.getResource(XtextResourceSet.java:263) ~[?:?]
        at org.eclipse.xtext.ide.server.ProjectManager.getResource(ProjectManager.java:169) ~[?:?]
        at org.eclipse.xtext.ide.server.WorkspaceManager.doRead(WorkspaceManager.java:436) ~[?:?]
        at org.eclipse.xtext.ide.server.findReferences.WorkspaceResourceAccess.readOnly(WorkspaceResourceAccess.java:36) ~[?:?]
        at org.eclipse.xtext.ide.server.symbol.DocumentSymbolService.doRead(DocumentSymbolService.java:332) ~[?:?]
        at org.eclipse.xtext.ide.server.symbol.DocumentSymbolService.getDefinitions(DocumentSymbolService.java:112) ~[?:?]
        at org.eclipse.xtext.ide.server.symbol.DocumentSymbolService.getDefinitions(DocumentSymbolService.java:99) ~[?:?]
        at org.eclipse.xtext.ide.server.LanguageServerImpl.lambda$definition$24(LanguageServerImpl.java:603) ~[?:?]
        at org.eclipse.xtext.ide.server.WorkspaceManager.doRead(WorkspaceManager.java:438) ~[?:?]
        at org.eclipse.xtext.ide.server.LanguageServerImpl.definition(LanguageServerImpl.java:602) ~[?:?]
        at org.eclipse.xtext.ide.server.LanguageServerImpl.definition(LanguageServerImpl.java:590) ~[?:?]
        at org.eclipse.xtext.ide.server.LanguageServerImpl.lambda$definition$23(LanguageServerImpl.java:581) ~[?:?]
        at org.eclipse.xtext.ide.server.concurrent.ReadRequest.lambda$doRun$0(ReadRequest.java:66) ~[?:?]
        ... 5 more

I think I just found out what’s wrong. In InfluxDB, the timestamps for the data are one hour behind. I’m not sure why that is, but at least Grafana displays the data with my correct time.

grafik

This is the current data for Zirkulationspumpe in InfluxDB (it’s 10:42 right now).

Grafana shows:

grafik

What’s going on? Is openHAB not doing some kind of timezone adaptation that it should be doing? I can’t seem to find where Grafana is configured to adapt the timezone…

Ok, sorry for the spam, but that might not have been the problem either. Even if I set historicState to now.minutesMinutes(65), for example, to a time where the measurement in influxdb is 1 / ON, I still get OFF from the historicState…

Well, it is a step forward, basic function appears to work. Worth remembering what historicState() gives you - it’s the newest data recorded in the db from just before the target time. There will never be data for the exact instant you target, so it gives the previous known data on the assumption it is still true at the instant.
So it could in fact be data from weeks ago.

It’s probably worth examining the timestamp of the data you get, to help understand;

logInfo("Zirkulationspumpe.historicState(now.minusMinutes(10))", Zirkulationspumpe.historicState(now.minusMinutes(10), "influxdb").state.toString)
logInfo("Zirkulationspumpe.historicState(now.minusMinutes(10))", Zirkulationspumpe.historicState(now.minusMinutes(10), "influxdb").getTimestamp.toString)

Now then,

2020-12-21 10:30:53.072 [ERROR] [xt.ide.server.concurrent.ReadRequest] - Error during request:
java.lang.RuntimeException: Cannot create a resource for 'java:/Objects/org.openhab.core.persistence.HistoricItem'; a registered resource factory is needed

This looks pretty serious and broken … but f it is, why isn’t the rule blowing up instead of returning (possibly fake) data?
I don’t know. This looks like buggy persistence service. Let’s see if you get a sensible timestamp, or 1-1-1900
[ Maybe the error originates from attempting to write to db (because you’ve updated pump thingy) rather than from the rule. ] - nah not that, it says historicItem in the error.

It’s probably a red herring, times can get confusing in persistence. There’s no reason a db cannot store everything with UTC timestamps, and it’s the job of OH persistence services to hide that from you and work with local timezones. It just gets confusing when you probe deeply.

Are you using jdbc as storage?
Maybe its related to:

Looks like the timestamps are fine (the pump has been turned on after the first timestamp in this example of the log):

2020-12-21 14:54:00.900 [INFO ] [ricState(now.minusMinutes(10)) state] - OFF
2020-12-21 14:54:00.911 [INFO ] [tate(now.minusMinutes(10)) timestamp] - 2020-12-21T14:44:00.279+01:00[Europe/Berlin]
2020-12-21 14:54:00.915 [INFO ] [re.model.script.now.minusMinutes(10)] - 2020-12-21T14:44:00.914030+01:00[Europe/Berlin]
2020-12-21 14:55:00.902 [INFO ] [ricState(now.minusMinutes(10)) state] - OFF
2020-12-21 14:55:00.918 [INFO ] [tate(now.minusMinutes(10)) timestamp] - 2020-12-21T14:45:00.288+01:00[Europe/Berlin]
2020-12-21 14:55:00.922 [INFO ] [re.model.script.now.minusMinutes(10)] - 2020-12-21T14:45:00.921093+01:00[Europe/Berlin]
2020-12-21 14:55:27.993 [INFO ] [g.openhab.core.model.script.Presence] - All presence sensors off, starting Present_Timer
2020-12-21 14:56:00.902 [INFO ] [ricState(now.minusMinutes(10)) state] - OFF
2020-12-21 14:56:00.914 [INFO ] [tate(now.minusMinutes(10)) timestamp] - 2020-12-21T14:46:00.296+01:00[Europe/Berlin]
2020-12-21 14:56:00.919 [INFO ] [re.model.script.now.minusMinutes(10)] - 2020-12-21T14:46:00.918019+01:00[Europe/Berlin]

Somehow I don’t get the errors anymore, no clue why.

Not sure, I set up InfluxDB and Grafana via openHABian configuration. Not sure what is used “inside”; but I didn’t set up JDBC manually or anything…

Ok, looks like I’m not the only one having the problem:

Hi Mario,
Sorry I miss your post during my research.
I am convinced our problem comes from influxdb persistence binding. Do you also have an influxdb v1 database?

Hi Olivier,

yea, I do have an influxdb v1 database. What to do now? :slight_smile:

Have you tried a different persistence service to make sure that it’s caused by the influx persistence service?

I think we shall open an issue against influxdb persistence binding.

Persistence of switch items works fine with rrd4j. It seems also to work fine with influxdb v2 but I didn’t try since migration from v1 to v2 seems not straightforward with docker.

Alright, I’m not sure what you expect to see but that looks like good data from an “everyminute” strategy.

We should bear in mind here that at the moment your rule runs, the current state of your Item may not yet be written to db, that’s a process that takes time.

There certainly are long-standing doubts about changedSince() effectiveness with Influxdb

I wonder if part of it is ambiguity over what it’s supposed to do - tell you if it’s different ‘now’ compared with ‘then’, or to tell you if it changed (and maybe changed back again) between ‘then’ and ‘now’.

A possible workaround -
Use an everyChange strategy (only)
Use updatedSince() rule method (if that works)

Completely different approach, abandoning persistence -
Rule to start or re-start half-hour timer every time pump runs.
(Work out if you want to time from pump-start or pump-stop)
Timer self destructs on expiry.
Other rule checks to see if timer running before doing XX.

That’s not a problem. All I want to know is if the pump was on at all in the past x minutes. It doesn’t really matter if it was turned on a few seconds ago.

I was thinking about using rules to accomplish this, but thought that it would be overkill to write rules for it if I could just use changedSince.

Now as it looks the influxdb persistence service might be broken in OH3, so changedSince might not work at all because of that (also, restoreOnStartup does not work). So I might wait for this problem to fixed before writing rules for what I want to do.

Thanks for your help!

Ok, have you done that before and know where to do that? I can help or comment on it if needed.

The issue is opened :

Please feel free to add any relevant information.

3 Likes

Thank you! Unfortunately my OH3 is broken after trying to upgrade from RC2 to the stable release… so I can’t do anything at the moment. But you said everything in the issue anyway. :slight_smile:

The issue was fixed. I built and the latest version of the InfluxDB binding and now historicState and changedSince seem to be working.

But as was stated in the issue, it might take a while (3.1 or later) until it reaches openHAB stable.

1 Like