Rule which activates once based on conditionA || conditionB?

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 :slight_smile:

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.

1 Like