Rules to only fire when its :00 or :30

rule “PVisland Voltage below 23V Alert - Notification”
when
   Time cron "0 0,30 * ? * * *" or
   Item PVislandVolt received update
then
   ...

Harry, Thanks…

are you sure OR…because i want to trigger if its 0 or 30mins of the hour + an update has taken place. I do not want to trigger the rule if only its 0 or 30 but in addition an update has happened…

or will this not work in sync as the updates come per minute (if sensor is online) … but is not exaclty at x:30:00.

Not sure if you get what I mean. rule should not trigger just due to the fact that its 0 or 30…but in combination with 0/30 + an update comes in…only i’m not sure if this comes only true when its :0:0 or 30:0.
or it triggers for a whole minute of e.g. 30:00 to 30:59…this way it would definitely cover an update as it has to happen some time within this single minute.

no

than you have to use

rule “PVisland Voltage below 23V Alert - Notification”
when
   Time cron "0 0,30 * ? * * *"
then
   // check here if the values has changed
   // do
   // store the actual values for the next check
end

I found and issue in the code I posted. It’s been updated. If you would like repeated alerts, here are some options 1) make a timer that will keep bugging you every 30 min, 2) use a timestamp instead of a boolean for the flag and check that 30 min has passed. Neither of these use a cron trigger.

OK thanks.

Harry, but if i trigger on 0 and 30mins per hour…than it would trigger exactly at zero second i guess…but if the update comes in at 25sec or 45sec or whatever sec within this minute it would not do the if part at all.

Could this somehow be turned arround … so if an update comes in the if part checks if current time is 0 or 30mins…this would definitely work from being in sync between the update and actual time…

You can’t use a AND-condition in the WHEN-Part, only OR.
The rule uses the actuel value of the item. If it runs every 30 min. is’t not importent, if the value is from 29:xx or form 30:xx.

I agree, but think about a situation where the PVisland system goes offline and no updated values are sent…if the latest value is as low that it would trigger…it will trigger every 30mins as the value does not change anymore even if no updated values come in…

or maybe i do understand this wrong…

How would this be coded in the if part: // check here if the values has changed

I presume PVislandVolt is a number-Item.

var Number lastValue = 0

rule "PVisland Voltage below 23V Alert - Notification"
when
   Time cron "0 0,30 * ? * * *"
then
    logInfo("___",lastValue.toString +" "+ PVislandVolt.state.toString)
    if (PVislandVolt.state < 23 && lastValue != PVislandVolt.state) {
       logInfo("___","changed")
//     sendMail(“xxxxxxxxxxxxxxxxxx”, “PVisland | Battery Voltage Level Alert | " + PVislandVolt.state + " V”, “—EoM—”)
       lastValue = PVislandVolt.state}
end

If you take away the requirement that the alert come exactly at 00 and 30 and make your requirement that it only report every 30 minutes it is below the threshold it becomes much simpler. I’ll use Design Pattern: Expire Binding Based Timers and Design Pattern: Separation of Behaviors.

rule "PVisland Voltage below 23V Alert - Notification"
when
    Item PVislandVolt changed
then
    // NULL isn't a value we can use in this rule
    if(PVislandVolt.state == NULL) return;

    // If the Timer is already running we have nothing to do
    if(PVislandVolt_Timer.state == ON) return;

    // Voltage is low, alert
    if(PVislandVolt.state < 23) {
        aAlert.sendCommand("PVisland | Battery Voltage Level Alert | " + PVislandVolt.state + "V", "--EOM--")
        PVislandVolt_Timer.sendCommand(ON)
    }

    // Voltage is back above threshold, cancel alerts
    else {
        PVislandVolt_Timer.postUpdate(OFF)
    }
end

rule "PVislandVol timer expired"
when
    Item PVislandVolt_Timer received command OFF
then
    // No more alerts if the voltage goes above the threshold
    if(PVislandVolt.state == NULL || PVislandVolt.state >= 23) return;

    // alert and reschedule the Timer for another 30 minutes while it remains below threshold
    aAlert.sendCommand("PVisland | Battery Voltage Level Alert | " + PVislandVolt.state + "V", "--EOM--")
    PVislandVolt_Timer.sendCommand(ON)
end

If you only want the one alert when it first goes below the threshold and not get repeats, which you stated is your ultimate goal, then Scott already provided that answer in post 4.

As you can see, minor changes in your requirements can result in drastically different solutions. And all things considered, implementing your ultimate goal is actually far easier than your stated compromise solution.

1 Like

@rlkoshak sorry for the delay. recently tried your rules above including a switch item for the timer. It works great to only allow a first threshold go-below but if voltage goes up again it seems to not reset at all. So until i reboot openhab machine i do not see any warnings anymore…even if it goes above 23V and later again below 23V.

Can you have a quick look what could be wrong or maybe i forgot to implement beneath these scripts.
Thanks Norbert

Add logging to the Rule to see when it is triggering and what it is doing.

OK, will try to add some logging information. But what should that show us except from what I already see from the dummy-switch state i already see in the event logs?
There i see that the switch goes ON but never OFF.

btw. why did you use postupdate instead of sendcommand for the OFF? Regards/Thanks Norbert

    pi@SmartPi:~ $ cat /var/log/openhab2/events.log.5 |grep PVislandVolt_
2018-10-30 06:01:07.331 [ome.event.ItemCommandEvent] - Item 'PVislandVolt_Timer' received command ON
2018-10-30 06:01:07.338 [vent.ItemStateChangedEvent] - PVislandVolt_Timer changed from NULL to ON
pi@SmartPi:~ $ cat /var/log/openhab2/events.log.6 |grep PVislandVolt_
2018-11-02 06:01:07.507 [ome.event.ItemCommandEvent] - Item 'PVislandVolt_Timer' received command ON
2018-11-02 06:01:07.516 [vent.ItemStateChangedEvent] - PVislandVolt_Timer changed from NULL to ON
pi@SmartPi:~ $ cat /var/log/openhab2/events.log.5 |grep PVislandVolt_
2018-10-30 06:01:07.331 [ome.event.ItemCommandEvent] - Item 'PVislandVolt_Timer' received command ON
2018-10-30 06:01:07.338 [vent.ItemStateChangedEvent] - PVislandVolt_Timer changed from NULL to ON
pi@SmartPi:~ $ cat /var/log/openhab2/events.log.4 |grep PVislandVolt_
2018-10-26 09:51:28.618 [ome.event.ItemCommandEvent] - Item 'PVislandVolt_Timer' received command ON
2018-10-26 09:51:28.623 [vent.ItemStateChangedEvent] - PVislandVolt_Timer changed from NULL to ON
pi@SmartPi:~ $ cat /var/log/openhab2/events.log.3 |grep PVislandVolt_
pi@SmartPi:~ $ cat /var/log/openhab2/events.log.2 |grep PVislandVolt_
2018-10-21 09:32:10.349 [ome.event.ItemCommandEvent] - Item 'PVislandVolt_Timer' received command ON
2018-10-21 09:32:10.353 [vent.ItemStateChangedEvent] - PVislandVolt_Timer changed from NULL to ON
pi@SmartPi:~ $ cat /var/log/openhab2/events.log.1 |grep PVislandVolt_

It’s the rule running at all?

Are they right if statements of the rule running when PVislandVolt is in its various states?

When something doesn’t work as expected you need to gather information to figure out why. Otherwise you are just guessing.

As I documented in the Expire Binding Based Timers DP I linked above, to cancel the Timer you use postUpdate. If you use sendCommand, the second rule will run and that rule should only run when the timer expires, not when it is cancelled.

Thanks for your feedback…
What i found out now is a suspicious line in the openhab.log file…but i cannot see anything wrong.

2018-10-21 09:30:04.097 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'PVisland Voltage below 23V Alert - Notification': The name 'PVislandVolt_Timer' cannot be resolved to an item or type; line 59, column 8, length 18

However I have a Switch item integrated in the default items file…I marked the line that is mentioned with ** **

Switch PVislandVolt_Timer

// ***************************************************************************************************
rule "PVisland Voltage below 23V Alert - Notification"
when
    Item PVislandVolt changed
then
    if(PVislandVolt.state == NULL) return;
    **if(PVislandVolt_Timer.state == ON) return;**
    if(PVislandVolt.state < 23) {
        sendMail("norasdfasfdasfdm", "PVisland | Battery Voltage Level Alert | " + PVislandVolt.state + " V", "---EoM---")
        PVislandVolt_Timer.sendCommand(ON)
    }
    else {
        PVislandVolt_Timer.postUpdate(OFF)
    }
end

rule "PVislandVolt timer expired"
when
    Item PVislandVolt_Timer received command OFF
then
    if(PVislandVolt.state == NULL || PVislandVolt.state >= 23) return;
    PVislandVolt_Timer.sendCommand(ON)
end

Do you see this every time the rule runs or only when oh first starts?

hi @rlkoshak,
i now spent some time testing the behaviour of your rules code…but it seems that after it goes below 23V and setting the _timer switch to ON in never again goes OFF after Volt go higher than the threshold…so its dead-locked after the first email-notification (forever). From the code i understand that the behaviour has to be like this but i’m no that good to change it myself accordingly that after a Voltage higher 23V again the notification is reset so if later it goes bleow 23 again the notification would be sent…as i guess its expected to work.

2018-11-18 22:03:43.187 [ome.event.ItemCommandEvent] - Item 'PVislandVolt' received command 24.45
2018-11-18 22:03:43.197 [vent.ItemStateChangedEvent] - PVislandVolt changed from NULL to 24.45
2018-11-18 22:03:43.231 [vent.ItemStateChangedEvent] - PVislandVolt_Timer changed from NULL to OFF
2018-11-18 22:24:49.961 [ome.event.ItemCommandEvent] - Item 'PVislandVolt' received command 22.45
2018-11-18 22:24:49.995 [vent.ItemStateChangedEvent] - PVislandVolt changed from 24.45 to 22.45
2018-11-18 22:24:52.318 [ome.event.ItemCommandEvent] - Item 'PVislandVolt_Timer' received command ON
2018-11-18 22:24:52.324 [vent.ItemStateChangedEvent] - PVislandVolt_Timer changed from OFF to ON
2018-11-18 22:25:25.909 [ome.event.ItemCommandEvent] - Item 'PVislandVolt' received command 23.45
2018-11-18 22:25:25.929 [vent.ItemStateChangedEvent] - PVislandVolt changed from 22.45 to 23.45

hi @rlkoshak,
i now adapted your rule set to a more simplified version that seems to work. Can you please please have a check and let me know if this would be a stable rule set or if something is missing or should be more like yours… from above you can see that the pure rich-ruleset does never go back to normal state…maybe you can check this as well as yours looks more pro-level.

//***************************************************************************************************
rule “PVisland Voltage below 23V Alert - Notification”
when
Item PVislandVolt changed
then
if (PVislandVolt.state == NULL) return;
if (PVislandVolt_Timer.state == ON) return;
if (PVislandVolt.state < 23) {
sendMail(“norbert.jasdfasdfase.com”, "PVisland | Battery Voltage Level Alert | " + PVislandVolt.state + “V”, “—EoM—”)
PVislandVolt_Timer.sendCommand(ON)
}
end

rule “PVisland Voltage below 23V Alert - Return to Normal”
when
Item PVislandVolt changed
then
if (PVislandVolt.state == NULL) return;
if (PVislandVolt_Timer.state == OFF) return;
if (PVislandVolt.state > 23) {
PVislandVolt_Timer.sendCommand(OFF) }
end

OK, there is a logic error in the original but it should be easy enough to fix.

We need to move the line where we turn the timer off further up the Rule and send it when the volt state is over 23 and then only send the alert message if there isn’t a timer running.

rule "PVisland Voltage below 23V Alert - Notification"
when
    Item PVislandVolt changed
then
    if(PVislandVolt.state == NULL) return;
    if(PVislandVolt.state >= 24) PVislandVolt_Timer.postUpdate(OFF)
    else if(PVislandVolt_Timer.state == OFF) {
        sendMail("norasdfasfdasfdm", "PVisland | Battery Voltage Level Alert | " + PVislandVolt.state + " V", "---EoM---")
        PVislandVolt_Timer.sendCommand(ON)
    }
end

Thanks…so this new rule replaces both rules from above i guess?

Is there a chance to change the rule so OFF is not always set when new values come in.
Something like:

if((PVislandVolt.state >= 24) && (xxxTimer==ON)) PVislandVolt_Timer.postUpdate(OFF)

No, the second Rule gets run when the Timer expires. You still need that one.

As for the OFF, that is a typo. It should be PVislandVolt_Timer.postUpdate(OFF), not sendCommand(OFF). Then the second rule (from my post) will not execute every time.