This page last changed on Jun 16, 2015 by ckbsmart.

Hello,

I have tried to make a group virtual switch for two lights to do the following:

  • when I press the virtual switch ON - turn on the two lights only if they are both off
    rule "scena lumini Buc all ON"
     salience -100
    when
     Event(source=="GVScene-lumini Bucatarie status", value=="ON")
     Event(source=="LED Bucatarie-OnOffSensor", value=="off")
     Event(source=="lumini Bucatarie-OnOffSensor", value=="off")
    then
      execute.command("lumini Bucatarie-On" );
      execute.command("LED Bucatarie-On" );
    end
    
  • when I press the virtual switch OFF - turn off both lights
    rule "scena lumini Buc all OFF"
    when
     Event(source=="GVScene-lumini Bucatarie status", value=="OFF")
    then
      execute.command("lumini Bucatarie-Off" );
      execute.command("LED Bucatarie-Off" );
    end
    
  • when I turn one of the lights ON - turn the virtual switch ON
    rule "scena lumini Buc status ON"
    when
    (OR
     Event(source=="LED Bucatarie-OnOffSensor", value=="on")
     Event(source=="lumini Bucatarie-OnOffSensor", value=="on")
    )
    then
      execute.command("Scene-lumini Bucatarie ON" );
    end
    
  • when I turn both of the lights OFF - turn the virtual switch OFF
    rule "scena lumini Buc status OFF"
     salience 100
    when
     Event(source=="LED Bucatarie-OnOffSensor", value=="off")
     Event(source=="lumini Bucatarie-OnOffSensor", value=="off")
    then
      execute.command("Scene-lumini Bucatarie OFF" );
    end
    

Event though from my point of view this is ok, the rules act strange.

  • when I turn off both lights the rule that has to turn off the virtual switch is not executed in time and instead of turning on the virtual switch the first rule gets executed and the lights get both turned on(or something like that). => to fix that I tried to add times to the rules and salience but I am not sure why it does not fix anything.

Thank you in advance.

Not sure it will work, but I would convert the light sensors to virtual switches and only use the virtual switches for the logic.

When
Event(source=="LED Bucatarie-OnOffSensor", value=="off")
Then
execute.command("LED Virtual off" );

When
Event(source=="lumini Bucatarie-OnOffSensor", value=="off")
Then
execute.command("lumini Bucatarie Virtual off" );

soooooo your first condition would then be:

rule "scena lumini Buc all ON"
salience -100
when
Event(source=="GVScene-lumini Bucatarie status", value=="ON")
Event(source=="LED Bucatarie-Virtual", value=="off")
Event(source=="lumini Bucatarie-Virtual", value=="off")
then
execute.command("lumini Bucatarie-On" );
execute.command("LED Bucatarie-On" );
end

Hopefully you don't have the sensors "outpacing" the virtual switches doing the above...Maybe!?

Posted by niedejb at Jun 17, 2015 02:21

Salience and/or timing should solve this. However, remember that there is a long time existing bug in the controller which causes that after each updating of the rules you must hard reboot the controller, otherwise new edited rules can be unpredictable after syncing.

Posted by aktur at Jun 17, 2015 06:41

Yes it was fixed with timing and a CONTROLLER HARDWARE RESTART ! I inserted a timer in the first rule that so that the rule that turns the virtual switch off has time to run before the first one is taken into consideration. Depending on how many devices are in the group I set the timer between 1 and 2 seconds.

Posted by ckbsmart at Jun 17, 2015 08:45

Side note, this is the best solution as far as you can get with the standard controller. Putting arbitrary delays to fix timing racing is not very robust. It will bite you some day as you are passing info from rules engine to openremote event processor and back to the rule engine and count on minimum performance. I've hit this flaw long time ago and the fundamental reason of this is that the openremote designers decided to use the rule engine in static (cloud mode - where info is passed as facts) instead of dynamic mode (stream mode - where info is passed as events). It is funny that what is called Event() is in fact casted to a fact instead of staying event.

Anyway, the real solution is:
1. change the Drools execution mode to stream - you have to recompile it or search the forum for version of the controller which I've posted while back. You cannot change it through parameters, which is pity, especially because you can change 100's of other, less important IMHO stuff.
2. redeclare Events back to events - this can you do by putting:

declare Event
  @role(event)
end

in the rules file.
3. Use correct timing conditions, for example if you require that something happens when you have something after one order of execution and something different with other:

rule "order 1"
when
  $s1: Event(source=="s1")
  Event(source=="s2", this after $s1)
then
  // s1 was before s2
end

rule "order 2"
when
  $s1: Event(source=="s1")
  Event(source=="s2", this before $s1)
then
  // s1 was after s2
end

Currently it is impossible to code efficiently these which makes any professional rules writing a nightmare.

Posted by aktur at Jun 17, 2015 09:47

I thought about it. I don't need it to run after the other one I just want them to execute fast enough so that it turns the virtual switch off. If the virtual switch is not turned off by the rule and all lights are off then the rule that says if all lights are off and the vs is on, turn on all lights gets executed. so instead of turning off lights i end up turning on all the lights in the house. it's a nightmare. if openremote is busy or vera does whatever the timer does not help at all ((

Is there a way in which i can change that rule that turns on the lights to something that says: if the VS is actual pressed(touched) then turn on all lights if all where off before.
And the rule that says that if one light is on: just change state of the VS to on but do not do anything else.

Thank you

Posted by ckbsmart at Jul 07, 2015 10:36

Is there a way in which i can change that rule that turns on the lights to something that says: if the VS is actual pressed(touched) then turn on all lights if all where off before.

Not with the default controller. But with a build with the Drools stram mode this would be:

declare Event
  @role(event)
end

rule "scena lumini Buc all ON"
 salience -100
when
 $e1: Event(source=="GVScene-lumini Bucatarie status", value=="ON")
 Event(source=="LED Bucatarie-OnOffSensor", value=="off", this before $e1)
 Event(source=="lumini Bucatarie-OnOffSensor", value=="off", this before $e1)
then
  execute.command("lumini Bucatarie-On" );
  execute.command("LED Bucatarie-On" );
end
Posted by aktur at Jul 07, 2015 11:57
Document generated by Confluence on Jun 05, 2016 09:33