HI ! My tv take 15 sec to open … when I send a power on command from openhab my tv start opening. if i send an off command from openhab during this time my tv does not shut off but openhab think it’s off. I would like to write a rule that wait 15 sec while i could hit off when i first turn on my tv …
this is what i got so far … ( Doesn’t work)
(TV is a virtual switch and harmonyTV is the actual object that control my tv)
var Number i = 0
var Number Y = 0
rule “TV OFF counter”
when
Item TV received command OFF
if(y==0) {
postUpdate(TV, OFF)
while (y<11){
postUpdate(TV, OFF)
Thread::sleep(1000)
postUpdate(TV, OFF)
y=y+1
}
}
end
rule "TV ON counter"
when
Item TV received command ON
if(i==0) {
postUpdate(TV, ON)
while (i<16){
Thread::sleep(1000)
postUpdate(TV, ON)
i=i+1
}
}
end
rule "TV ON"
when
Item TV received command ON
if(y==10) {
harmonyTV.sendCommand(ON)
y=0
}
end
rule "TV OFF"
when
Item TV received command OFF
if(i==15) {
harmonyTV.sendCommand(OFF)
i=0
Have you considered a different approach, using a “busy flag” - an item to show the TV cannot be used.
Send TV the ON command - AND set the “busy” flag true. Start a timer off that will unset the busy flag in 15 secs.
For the rule that issues the OFF, have it check the busy flag. If it isn’t set, send OFF now. If it is set, start a timer to send OFF in 15 seconds.
Or do something more complicated if you need to minimize the dalay.
yeah ! could work actually ! but in a best case scenario my virtual switch didn’t change status when i click on it if the busy flag is true… how could i do that
I suppose, if your switch item has default autoupdate, you could also send OFF during the busy period - ignored by TV but should change the sitemap icon
You will achieve this by using Thread::sleep like you already did, but you also need to place a ReentrantLock. By acquiring the lock for each action, you stop parallelism. This means you can send the OFF command, but it will only be run, if the sleep time passed and after the lock was released from the previous thread that acquired it.
I did exactly your use-case on my TV as well. My lock time was even longer, because I needed to wait until the TV connected via WiFi.
It looks like this:
import java.util.concurrent.locks.ReentrantLock
var java.util.concurrent.locks.ReentrantLock lock = new java.util.concurrent.locks.ReentrantLock()
rule tv_turn_on
when
Item tv_power received command ON
then
lock.lock()
try {
// do stuff to turn it on
Thread::sleep(30000) // This is the time the TV needs to turn on and be available
} finally{
lock.unlock()
}
end
rule tv_turn_off
when
Item tv_power received command OFF
then
lock.lock() // OpenHAB will wait here if anything else has this lock open and continue afterwards
try {
// do stuff to turn it off.
} finally{
lock.unlock()
}
end
As soon as your rule hits a .lock() it will wait until the lock is free again. Let’s assume the following:
Rule turn tv on acquires the lock, turns on TV and waits 10 seconds to ensue it is ready.
Rule turn tv off acquires the lock and turns the TV off, without any sleep.
If you now press turn tv on once and immediately afterwards press turn tv off 5 times, this will happen:
lock is locked
TV turns ON
Thread sleeps 10 seconds
lock is unlocked
lock is locked
TV turns OFF
lock is released
lock is locked
TV turns OFF
lock is released
lock is locked
TV turns OFF
lock is released
lock is locked
TV turns OFF
lock is released
lock is locked
TV turns OFF
lock is released
being more abstract and only writing down what you as used will experience:
TV turns ON
10 seconds of sleep
TV turns OFF
This is how a user wants to experience this. If your TV also has a time until it accepts commands after turning off (likely about 2-4 seconds), you should also put a sleep into the turn tv off rule.
You basically should always measure the time of actions and put the rule thread to sleep until it can continue again. So you will never miss anything.