My timer is working, or at least it was (based on the first Felix’s example).
I am trying to solve the other half of the script. So now the if is correctly syntaxed, but can you help here, how to **do nothing** in case of Item MagnetOknoDetska_OpenStatus changed to CLOSED?
rule "Mijia & Aqara Door/Window Sensor"
when
Item MagnetOknoDetska_OpenStatus changed to OPEN
then
logInfo("vetranie", "O chvilu pride notifikacia o dlhom vetrani")
Thread::sleep(15*1000*1) //60 Seconds, 1000 millis, 8 Minutes
if(Item MagnetOknoDetska_OpenStatus changed to CLOSED) {
**do nothing** //How this should be done/named correctly?
}
else
sendBroadcastNotification("Zavri okná a dvere, dlho vetráš", "flow")
end
I see… as Felix and Rich wrote before, the process is sleeping, means if something happends in those 6 minutes, it will not be registered.
I suppose that changing to received update will not save me: if(Item MagnetOknoDetska_OpenStatus received update CLOSED)
so I need it to be based on Felix second example of var Timer, right?
This is still looking for an event that would have to happen at the same nanosecond that your if(statement) ran.
Rich’s suggestion looks at the steady state, any time you like
What do you think an Item state is? It records the state of the Item. If it changes to CLOSED before the Timer runs, the Item’s state will be CLOSED when the Timer finally runs. That if statement will evaluate to false and since there is no else nothing happens. That’s why I test the Item’s state to see if it’s still open when the Timer goes off. If it is the broadcast is sent. If not it does nothing, just as you asked.
If you wanted to change your rule so that it cancels a timer when the Item changes to CLOSED you can certainly do that too. But not if you are using a Thread::sleep. Only if you use a Timer.
var Timer mytimer = null
rule "Mijia & Aqara Door/Window Sensor"
when
Item MagnetOknoDetska_OpenStatus changed
then
if(newState == OPEN){
mytimer = createTimer(now.plusSeconds(15), [ |
sendBroadcastNotification("Zavri okná a dvere, dlho vetráš", "flow")
mytimer = null
])
}
else {
mytimer?.cancel // the ? means only call cancel if mytimer isn't null
mytimer = null
}
end
OK, thanks, It is working now, even with custom xiaomi gateway sound
rule “Vetranie”
when
Item MagnetOknoDetska_OpenStatus changed to OPEN
then
logInfo("vetranie", "O chvilu pride notifikacia o dlhom vetrani")
Thread::sleep(15*1000*1) //60 Seconds, 1000 millis, 8 Minutes
if(MagnetOknoDetska_OpenStatus.state == OPEN) {
XiaomiGW_SoundVolume.sendCommand(3)
XiaomiGW_SoundSelector.sendCommand(10003)
Thread::sleep(4000) /* wait for 4 seconds */
XiaomiGW_SoundSelector.sendCommand(10000)
XiaomiGW_SoundVolume.sendCommand(6)
sendBroadcastNotification("Zavri okná a dvere, dlho vetráš")
}
end
Now I want to add extra condition - to run the command when Item MagnetOknoDetska_OpenStatus changed to OPEN
and the temperature outside is less than 18 degrees C: WeatherCompanyObservations_Temperature.state < 18
rule "Vetranie"
when
Item MagnetOknoDetska_OpenStatus changed to OPEN
then
logInfo("vetranie", "Rule vetranie spustene")
if(WeatherCompanyObservations_Temperature.state < 18) { //this does not work, but OH is not throwing any error
logInfo("vetranie", "O chvilu pride notifikacia o dlhom vetrani")
Thread::sleep(15*1000*1) //60 Seconds, 1000 millis, 8 Minutes
if(MagnetOknoDetska_OpenStatus.state == OPEN) {
XiaomiGW_SoundVolume.sendCommand(3)
XiaomiGW_SoundSelector.sendCommand(10003)
Thread::sleep(4000) /* wait for 4 seconds */
XiaomiGW_SoundSelector.sendCommand(10000)
XiaomiGW_SoundVolume.sendCommand(6)
sendBroadcastNotification("Zavri okná a dvere, dlho vetráš")
}
}
end
Should the line WeatherCompanyObservations_Temperature.state < 18 be defined somehow inbetween when and then too?
WeatherCompanyObservations_Temperature is an item with one channel:
Your Item is a Number:Temperature type, with units that are part of the value. You are comparing to 18 … 18 what, degrees K, metres, kWh?
You have to spell it out for openHAB - magic character pipe | is useful here with constant values. if (WeatherCompanyObservations_Temperature.state < 18|°C)
Hi. is it possible to create a stadaard “timer delay 10 seconds” script that can be used in other rules?
i have several infrared heaters and i want to switch them ON and OFF by the same condition but with a fixed delay of 10 seconds to prevent high voltage peeks on my home power grid.
i managed to switch tem On and OFF with the right conditions via this rule:
Have you considered that you can create in one rule a set of timers - one which issue a command to one device in 10secs time; and another timer that will issue a command to a different device in 20secs time; etc.
Thanks, i will look into the script part for the timer.
I find it difficult to choose between the script languages. I still have to learn this but which one will be future proof (for OH4, OH5, etc .) what can you advise for such a (simple) timer?
Just forget the Blockly, I can’t find any use for it. Just use the graphical interface, or now I am using (or trying to use) RulesDSL through VSCode - with OH plugin. Pretty neat!
Some people on this forum are really helpful (thanks!), documentation is also good. I like it a lot!
For best practices, is it necessary to cancel timers? For instance, a fan switch is changed and ON triggers timer. If the fan switch is manually turned off, what happens to the timer? Here is what I have, and it works fine, just wondering if second part (cancel) is necessary.
Definitely a nice addition since expiration timers don’t work great with zwave devices over long periods.
If you right click on the block you can see the help URLs that I added during the implementation which takes you in this case to Timer-Documentation. It says here
cancel: prevents the scheduled timer from executing. Most of the time cancel is used used in conjunction with setting the timer handler to null as a convenient indicator that some previously defined timer is now finished with. However setting the handler to null does not interact with the timer itself.