Rules time cron triggers are working but value assign in rules not right

Cyclic “rule” processing irregular

How can I ensure that rules are processed correctly cyclically. or values are correctly adopted
I have the following “rules”

rule "zylisch0"
when 
Time cron  "0 */5 * ? * *"
then
AEwert.postUpdate (0.0)
AFwert.postUpdate (0.0)
AGwert.postUpdate (0.0)
end



rule "zylisch1"
when 
Time cron  "0 * * * * ?"
then
AEwert.postUpdate (AEwert.state as Number + 1.0)
AAwert.postUpdate (ENBW_Bezogen.state as Number - ACwert.state as Number)
ABwert.postUpdate (ENBW_Geliefert.state as Number- ADwert.state as Number)
ACwert.postUpdate (ENBW_Bezogen.state as Number)
ADwert.postUpdate (ENBW_Geliefert.state as Number)
AFwert.postUpdate (AFwert.state as Number + AAwert.state as Number )
AGwert.postUpdate (AGwert.state as Number + ABwert.state as Number )
end

And that’s the protocol for that. Rules are run through but apparently the values are not adopted although they are logged.
Every case is different! Timestamp ok but not the value!

2020-10-25 17:07:00.025 [vent.ItemStateChangedEvent] - AEwert changed from 1.0 to 2.0
2020-10-25 17:08:00.023 [vent.ItemStateChangedEvent] - AEwert changed from 2.0 to 3.0
2020-10-25 17:09:00.021 [vent.ItemStateChangedEvent] - AEwert changed from 3.0 to 4.0
2020-10-25 17:10:00.019 [vent.ItemStateChangedEvent] - AEwert changed from 4.0 to 0.0
2020-10-25 17:10:00.059 [vent.ItemStateChangedEvent] - AEwert changed from 0.0 to 1.0
2020-10-25 17:11:00.020 [vent.ItemStateChangedEvent] - AEwert changed from 1.0 to 2.0
2020-10-25 17:12:00.016 [vent.ItemStateChangedEvent] - AEwert changed from 2.0 to 3.0
2020-10-25 17:13:00.021 [vent.ItemStateChangedEvent] - AEwert changed from 3.0 to 4.0
2020-10-25 17:14:00.023 [vent.ItemStateChangedEvent] - AEwert changed from 4.0 to 5.0
2020-10-25 17:15:00.025 [vent.ItemStateChangedEvent] - AEwert changed from 5.0 to 0.0
2020-10-25 17:15:00.042 [vent.ItemStateChangedEvent] - AEwert changed from 0.0 to 6.0
2020-10-25 17:16:00.025 [vent.ItemStateChangedEvent] - AEwert changed from 6.0 to 7.0
2020-10-25 17:17:00.019 [vent.ItemStateChangedEvent] - AEwert changed from 7.0 to 8.0
2020-10-25 17:18:00.016 [vent.ItemStateChangedEvent] - AEwert changed from 8.0 to 9.0
2020-10-25 17:19:00.026 [vent.ItemStateChangedEvent] - AEwert changed from 9.0 to 10.0
2020-10-25 17:20:00.018 [vent.ItemStateChangedEvent] - AEwert changed from 10.0 to 0.0
2020-10-25 17:20:00.061 [vent.ItemStateChangedEvent] - AEwert changed from 0.0 to 1.0
2020-10-25 17:21:00.023 [vent.ItemStateChangedEvent] - AEwert changed from 1.0 to 2.0
2020-10-25 17:22:00.019 [vent.ItemStateChangedEvent] - AEwert changed from 2.0 to 3.0

IMHO your two rules are running a race at every 5 minutes, your zylisch1 is using the .state of AEwert when posting an update to it, the update done by zylisch0 might have happened before or not.
Additionally, using a .state of an item which has received an .postUpdate in that same rule will produce the same problems since it is done in a seperate thread and might not be performed already.

Doing this in one rule is doomed to failure.

postUpdate is asynchronous.
Meaning it posts an update to OH event bus, which gets distributed to any rules, bindings, etc. that might be listening. Eventually (well after a few milliseconds) the actual Item is updated.
Important - the rule does not stop and wait for that to happen, processing continues.
So if you read that same Item state later in the rule, you might get the “old” state or you might get the “new” state. It’s indeterminate.

In your rule excerpt above, AAwert.state is indeterminate in the second line.

If you need to update AFwert when AAwert is actually updated, that’s fine, trigger a rule from AAwert receiving update to do that. Don’t be frightened of many small rules.

If you must do it in the same rule, that’s fine too. You know what you posted to AAwert - so remember that and use that

var x = some calculation
AAwert.postUpdate(x)
...
AFwert.postUpdate (AFwert.state as Number + x )
1 Like

Hello rossko57
Thank you for response I mean your recommendation is working fine but
It means there ist no way for data acquisition with a safe cycle time

I would use one rule like this:

rule "zylisch"
when 
Time cron  "0 * * * * ?"
then
if (AEwert.state as Number==4) {
   AEwert.postUpdate (0.0)
   AFwert.postUpdate (0.0)
   AGwert.postUpdate (0.0)} 
else {
   AEwert.postUpdate (AEwert.state as Number + 1.0)
   AAwert.postUpdate (ENBW_Bezogen.state as Number - ACwert.state as Number)
   ABwert.postUpdate (ENBW_Geliefert.state as Number- ADwert.state as Number)
   ACwert.postUpdate (ENBW_Bezogen.state as Number)
   ADwert.postUpdate (ENBW_Geliefert.state as Number)
   AFwert.postUpdate (AFwert.state as Number + ENBW_Bezogen.state as Number - ACwert.state as Number )
   AGwert.postUpdate (AGwert.state as Number + ENBW_Geliefert.state as Number- ADwert.state as Number ) }
end

What is not covered is the starting condition. Thinking…

[Edit:] Maybe changing the
if (AEwert.state as Number==4) {
to something like

Pseudo-code: if (actualMinute mod 5 ==0) {

I don’t know what means. Acquisition of what, from where? Cycle of what? What would be unsafe?

I would like to process values with a precise cycle time, which means that a calculation should be carried out exactly every 10 minutes.

I would like to process values with a precise cycle time, which means that a calculation should be carried out exactly every 10 minutes.

Okeydoke, see @opus one-rule solution.

openHAB is not a real time system and it is simply incapable of being one. If you need that precise of timing openHAB is never going to a satisfactory solution.

You need to define precise. Do you need within half a nanosecond, or within half a second?

Ooookay, what problem do you identify with running one rule every ten minutes? The various calculations and updates it makes to Items will be sequenced in time by a few milliseconds, that’s the way almost any scripting system works.

Hallo rossko57 thank you for answer

I know the specifics of script based systems. What I did not know was that the value assignments are not executed synchronously in openhab and that rules are not processed in the order in which they are stored in the file.
With this knowledge, I can formulate my rules as I want.

Basically, I still need information on how I can better coordinate the processing. I would like a fixed order and (within limits) defined start times. Where can I read information about this.

openHAB is an event driven system. Those rule triggers (the then clause) defines which events will cause the rule to run. If you want to use Time cron based triggers and you need the rules to run in a sequence, you have to define the cron triggers in sequence. For example:

Time cron "0 * * * * ?"
Time cron "1 * * * * ?"
Time cron "2 * * * * ?"

and so on.

Of course this means that the rules will execute one second apart (plus or minus some milliseconds.

If you need shorter times in the sequence you can use a single rule and use a Timer to delay the execution of the code that needs to be run later.

rule " Sequence"
when
    Time cron "0 * * * * ?"
then
    // do some stuff
    createTimer(now.plusMillis(250), [ |
        // do some more stuff
    ])
    createTimer(now.plusMillis(500), [ | 
        // do yet more stuff
    ])
end

That will “do some stuff”, and schedule “do some more stuff” to run in a quarter of a second and “do yet more stuff” to execute in 500 milliseconds.

If the times are short enough (< about 300 msec over all) you can use a sleep to add pauses.

rule " Sequence"
when
    Time cron "0 * * * * ?"
then
    // do some stuff
    Thread::sleep(100)
    // do some more stuff
    Thread::sleep(100)
    // do yet more stuff
end

This last approach is somewhat dangerous as there is a limited number of rules execution threads and when you run out no rules will be able to run until a rule exits. That is why it’s better to have rules that run as fast as possible rather than waiting around doing nothing.

Having said all of that, it is almost always better to structure rules to trigger based on events from Items: updated, change state, or receive command. This almost always results in a better set of rules than polling with a cron trigger.

That is a consequence of their event driven nature, that Rich points out.
If you happen to define two rules to start at the same instant, say by cron schedule or by other shared trigger event, it’s indeterminate which one will do what first. Rules are multithreaded and do not wait on each other.

Hello
Thanks for the really detailed and really helpful explanation. Great.
In this context, how can I check or how can I be sure that an assignment that I assigned to an item with item.postUpdate (x) has been carried out.
So that I can process this item in the second rule.

Using sleep this is unsure to me. If no action is taken, the initialization will be carried out too late and therefore the calculation is not correct after midnight.

rule „rule1“
when
   System started or 
   Time is midnight
then 
   ........
    A__Test1.postUpdate(0.0)
   ........
end

rule „rule2“
when
   Time cron  "0 * * * * ?" 
then 
   ........
   A__Test1.postUpdate(A__Test1.state as Number + xy)
   ........
end

Don’t use a cron, it’s dumb.

when
   Item A__Test1 received update

EDIT - well that’s bit blunt, but what I really mean is that you are asking the wrong question. “How do I use bolts to join two pieces of rubber?”, instead of “How do I join these two pieces of rubber?”

Go back and look at what you are trying to achieve.
You’ve not described that, but it looks like -
Increment a counter style thingy every minute, at 00 seconds.
At midnight, reset the counter.

You have a decision to make. Because your counter is also scheduled to increment at exactly midnight, would you prefer to reset it before or after midnight? Because at exactly midnight it cannot be schrodinger’s counter, both reset and incremented.

That’s a hint that the simplest solution to the problem given is probably
Time cron "59 59 23 * * ?"
but it depends on the desired outcome, not the available tools. There’s about four possible outcomes just juggling the crons a little.

You can’t. At least not directly inside the rule. But you can trigger the second rule by Item item received update. The update itself generates an event that can be used to trigger a rule. As has been said, OH is event driven. You want to write rules that respond to events. If your second rule will always run after your first rule, why not put them into the same rule?

Than move the resetting of the Item to rule2 and do the reset when it’s around midnight. Or trigger rule2 when the Item changes state instead of on a fixed time.

Remember, the “H” in openHAB stands for “Home”. This isn’t an industrial control system. You are not going to get the sorts of precision and control over timing, transactions, etc. as you would find (and require) with a real-time industrial control system.