I’d like to create a rule like this:
when
Item A received command or
Item B received command
then
[do something]
end
That triggers only once when Items A and B receive a command simultaneously. Any way to accomplish this?
I’d like to create a rule like this:
when
Item A received command or
Item B received command
then
[do something]
end
That triggers only once when Items A and B receive a command simultaneously. Any way to accomplish this?
Rules are event based. It is impossible for both A and B to receive a command at the same time. So the behavior you are describing is impossible.
Using or just like you have above will trigger the rule if either A or B receive a command, just as you are after. If it isn’t then something else is going wrong and we need to look to the logs for errors and add logInfo statements to see what is actually happening.
To add to the answer by @rlkoshak: As said it is not possible for two events to occur simultaneously. This is not a restriction of openHAB but of the real world
If you want to do something in the event of A and with B in a certain state, this should be your approach:
rule "myrule"
when
Item A received command
then
if (B.state == ON) {
...
}
end
If you are in fact talking about two events happening at (almost) the same time, please describe your usecase show your code.
Btw. in your title you stated “conditionA || conditionB” which is OR not AND
You both make excellent points about the impossibility of true simultaneous events!
Here’s the usecase Trigger Rule when Thing initializes?
There may be another solution that doesn’t involve this conditionA || conditionB question, but I’m curious (to learn) how this could be accomplished anyway.
I suppose what I really want is for the rule to fire once within a short amount of time based on either conditionA or conditionB happening.
So, maybe the solution is something like (pseudocode)
var eventXTime = [current time]
when
Item A received command or
Item B received command
then
if ([current time] > [event time].[add 1 second]) {
eventXTime = [current time]
[do something]
}
end
OK, I think I understand what you are asking. You want to limit how frequently a rule will trigger no matter how fast the events come in, correct?
Assuming all you want to do is run the code if two events from either Item occur within one second, what you have in your pseudo code will work.
Assuming OH 2 (you need some import statements in 1.8.3)
var lastExTime = null
rule "Two events to trigger rule"
when
Item A received command or
Item B received command
then
if(now == null || now.isAfter(lastEvent.plusSeconds(1)){
lastExTime = now
// do stuff
}
end
You could do it with a timer
var Timer ruleTimeout = null
rule "Two events to trigger rule"
when
Item A received command or
Item B received command
then
if(ruleTimeout == null || ruleTimeout.hasTerminated) {
ruleTimeout = createTimer(now.plusSeconds(1), [| ruleTimeout = null]
// do stuff
}
// If the timer is running the event is ignored
end
or you could do it with a lock
import java.util.concurrent.locks.ReentrantLock
val ReentrantLock lock new ReentrantLock
rule "Two events to trigger rule"
when
Item A received command or
Item B received command
then
if(!lock.isLocked){
try {
lock.lock
// do stuff
} catch(Throwable t) {}
finally {
lock.unlock
}
}
// Any rule that triggers while the lock is locked gets ignored
end
The above are three implementations of the Latch Design Pattern.
However, I’m not entirely certain how it applies to your use case.
Perhaps if you explain a little bit more about how the events occur when you power on the lights from the switch it will be more clear and we can offer a full solution. When I read that initial thread I thought it was asking whether or not the binding generates an event when the bulbs turn on, not that the events are occurring and you just need to figure out based on timing that the turn on has occurred.