Jump to content

Welcome to Smart Home Forum by FIBARO

Dear Guest,

 

as you can notice parts of Smart Home Forum by FIBARO is not available for you. You have to register in order to view all content and post in our community. Don't worry! Registration is a simple free process that requires minimal information for you to sign up. Become a part of of Smart Home Forum by FIBARO by creating an account.

 

As a member you can:

  •     Start new topics and reply to others
  •     Follow topics and users to get email updates
  •     Get your own profile page and make new friends
  •     Send personal messages
  •     ... and learn a lot about our system!

 

Regards,

Smart Home Forum by FIBARO Team


Recommended Posts

Posted
49 minutes ago, fastvd said:

everything is correct...that's why I use the post command, in the role of a marker\tag, so to speak...
and I don't understand why the 2nd rule works in parallel, if there is no marker yet!

but here it's not about the marker via POST... I already created a global variable... and similarly tried to switch it and make the rule work ONLY with a specific global variable! I've tried everything and can't figure out why!

rule("spotKab:isOn & $count_spot_Kab=='1'  =>  $count_spot_Kab='2' ;log('Spot lighting in the office is turned on for the 1st time ')")
rule("spotKab:isOn & $count_spot_Kab=='2'  => $count_spot_Kab='3'; log('Spot lighting is included in office 2 again')")
rule("spotKab:isOn & $count_spot_Kab=='3'  => log('Spot lighting is included in office 3 again')")

 

 

Please login or register to see this attachment.

Posted

I wrote the 3rd version of counting the number of rule activations and everything goes smoothly ALL 3 rules SIMULTANEOUSLY!!! Why is the Count_spotKab variable not taken into account?
Here are my rules:
Util.defTriggerVar("Count_spotKab",1)
 Util.defTriggerVar("diyly_spotKab",false)
  rule([[spotKab:isOn & !diyly_spotKab => post(#post1)]])
  rule([[#post1 & Count_spotKab==1 => Count_spotKab=2; log('Light turned on %s times',Count_spotKab)]])
  rule([[#post1 & Count_spotKab==2 => Count_spotKab+=1; log('Light turned on %s times',Count_spotKab)]])
  rule([[#post1 & Count_spotKab==3 => ;diyly_spotKab=true;Count_spotKab=1; log('Light turned on %s times',Count_spotKab)]])

Please login or register to see this attachment.

Posted (edited)
 
I found the reason and the solution.
The reason why all 3 rules become TRUE at the same time is because they actually run on the chain at the same time!
And the solution: we need to stop this chain, and the easiest thing I could think of is to change the Count_spotKab variable not when the light is turned on, but when it is turned off!
But I had to enter one more variable, since the shutdown process also goes along the chain, and here the OnOff_spotKab variable came in handy.
Well, if the rule is repeated 3 times, the Diyly_spotKab variable will become FALSE to stop the cycle! And at midnight at 00:01, our variables will be ready to count again!
 
Util.defTriggerVar("Count_spotKab",1)
 Util.defTriggerVar("Diyly_spotKab",false)
 Util.defTriggerVar("OnOff_spotKab",false)
 rule([[@ {catch, 00:01} => diyly_spotKab=false;
 OnOff_spotKab=false;
        log('Resetting the variable ')
        ]])
  ------------------
  rule([[spotKab:isOn  & !Diyly_spotKab  => post(#postON)]])
  rule([[spotKab:isOff  & !Diyly_spotKab  => post(#postOFF)]])
  -------------------
  rule([[#postON & Count_spotKab==1 => log('Light turned on 1 times')]])
  rule([[#postOFF & Count_spotKab==1 & !OnOff => Count_spotKab=2;log('Light turned OFF 1 times')]]) 
  -------------------
  rule([[#postON & Count_spotKab==2 =>OnOff=true; log('Light turned on 2 times')]])
  rule([[#postOFF & Count_spotKab==2 & OnOff => Count_spotKab=3; log('Light turned OFF 2 times')]]) 
  -------------------
  rule([[#postON & Count_spotKab==3 => Diyly_spotKab=true;Count_spotKab=1; log('Light turned on 3 times',Count_spotKab)]])
Edited by fastvd
  • Topic Author
  • Posted
    On 9/22/2022 at 5:43 PM, fastvd said:
     
    I found the reason and the solution.
    The reason why all 3 rules become TRUE at the same time is because they actually run on the chain at the same time!
    And the solution: we need to stop this chain, and the easiest thing I could think of is to change the Count_spotKab variable not when the light is turned on, but when it is turned off!
    But I had to enter one more variable, since the shutdown process also goes along the chain, and here the OnOff_spotKab variable came in handy.
    Well, if the rule is repeated 3 times, the Diyly_spotKab variable will become FALSE to stop the cycle! And at midnight at 00:01, our variables will be ready to count again!
     
    Util.defTriggerVar("Count_spotKab",1)
     Util.defTriggerVar("Diyly_spotKab",false)
     Util.defTriggerVar("OnOff_spotKab",false)
     rule([[@ {catch, 00:01} => diyly_spotKab=false;
     OnOff_spotKab=false;
            log('Resetting the variable ')
            ]])
      ------------------
      rule([[spotKab:isOn  & !Diyly_spotKab  => post(#postON)]])
      rule([[spotKab:isOff  & !Diyly_spotKab  => post(#postOFF)]])
      -------------------
      rule([[#postON & Count_spotKab==1 => log('Light turned on 1 times')]])
      rule([[#postOFF & Count_spotKab==1 & !OnOff => Count_spotKab=2;log('Light turned OFF 1 times')]]) 
      -------------------
      rule([[#postON & Count_spotKab==2 =>OnOff=true; log('Light turned on 2 times')]])
      rule([[#postOFF & Count_spotKab==2 & OnOff => Count_spotKab=3; log('Light turned OFF 2 times')]]) 
      -------------------
      rule([[#postON & Count_spotKab==3 => Diyly_spotKab=true;Count_spotKab=1; log('Light turned on 3 times',Count_spotKab)]])

    Hi, been sick last week, a bit better now but the energy level is not really back to normal yet. Anyway, will try to answer some questions.

     

    First, yes all rules that matches the incoming trigger will run. So if you have

    Please login or register to see this code.

    They will all run when device 88 is turned on. The rules are invoked top to bottom (first defined to last defined).

    Normally rules are designed to be exclusive and only run one. However, it can be a useful way to split up long and complex rules.

    Ex. If we want to turn on a light when a sensor is breached and also log it, we can keep the log in a separate rule

    Please login or register to see this code.

    instead we can do

    Please login or register to see this code.

    Why would we do that? Well we could keep all the logging rules in a separate section of the file and we could more easily turn on/off the logging. However, it's a matter of taste.

    There is a way to stop the invocation of rules.

    Please login or register to see this code.

    'EM' stands for 'EventManager'. If we return fibaro.EM.BREAK as the last value from a rule it will stop executing matching rules that come after.

    In some special cases this is useful construct.

     

    Another point. If you trigger on events '#event' then the rule will only be executed when that event is posted.

    Please login or register to see this code.

    This rule will be triggered either when a #foo event is posted or when device 88 changes state.

    However, the action will only be carried out it's triggering on #foo being posted (and 88 is on))

    When device 88 changes state the rule triggers, but there is no #foo event available. There is no memory that events have been posted in the past

    so this rule can never be true unless #foo is posted and available for the rule.

     

    In this case the 88:isOn works as an extra 'guard' for the rule. #foo is posted AND device 88 is on then log 'A'....

    So when your rules triggers on #events, then all other test in the head of the rule works as extra guards.

     

    So, back to your rules. If I understod things I guess you could simplify it a bit.

    Please login or register to see this code.

    I don't think your 'OnOff' variable is needed as the spotKab:isOn and spotKab:isOff will never post the same #postOn/Off event twice.

    You also don't need to make Count_spotKab a triggerVar as it only serves as an extra condition (and combined with something like #postON it can never make a rule true as discussed in the beginning of the post)

     

    In general, a rule that should only work ex 5 times a day would be

    Please login or register to see this code.

     

    Posted (edited)

    Good morning Jan,

    I hope you are feeling better.

    This I don't understand direct after restart I see in Debug

    Please login or register to see this code.

    trace>arming is off as all above statements are true

    Debug it will execute #alarmInbrekerSignalen

    I figured out it comes from:

    Please login or register to see this code.

    What I am doing wrong?

    Edited by Sjakie
  • Topic Author
  • Posted

    1 minute and 1 second after restart it will post #alarmInbrekerSignalen

    Please login or register to see this code.

    So what you are doing wrong depends on what you want to do?

    Posted (edited)

    This I had in mind but not an activation at restart.

     

    Please login or register to see this code.

     

    Edited by Sjakie
  • Topic Author
  • Posted
    45 minutes ago, Sjakie said:

    This I had in mind but not an activation at restart.

     

    Please login or register to see this code.

     

    This rule only runs when appPhone.beveiligenAppartement changes state to off. It will not run if it is already off when you restart.

    To do that you can add .start()

    Please login or register to see this code.

     

    Posted

    Thanks, simple and effective!

    Posted
    On 9/24/2022 at 11:15 AM, jgab said:

    Hi, been sick last week, a bit better now but the energy level is not really back to normal yet. Anyway, will try to answer some questions.

     

    First, yes all rules that matches the incoming trigger will run. So if you have

    Please login or register to see this code.

    They will all run when device 88 is turned on. The rules are invoked top to bottom (first defined to last defined).

    Normally rules are designed to be exclusive and only run one. However, it can be a useful way to split up long and complex rules.

    Ex. If we want to turn on a light when a sensor is breached and also log it, we can keep the log in a separate rule

    Please login or register to see this code.

    instead we can do

    Please login or register to see this code.

    Why would we do that? Well we could keep all the logging rules in a separate section of the file and we could more easily turn on/off the logging. However, it's a matter of taste.

    There is a way to stop the invocation of rules.

    Please login or register to see this code.

    'EM' stands for 'EventManager'. If we return fibaro.EM.BREAK as the last value from a rule it will stop executing matching rules that come after.

    In some special cases this is useful construct.

     

    Another point. If you trigger on events '#event' then the rule will only be executed when that event is posted.

    Please login or register to see this code.

    This rule will be triggered either when a #foo event is posted or when device 88 changes state.

    However, the action will only be carried out it's triggering on #foo being posted (and 88 is on))

    When device 88 changes state the rule triggers, but there is no #foo event available. There is no memory that events have been posted in the past

    so this rule can never be true unless #foo is posted and available for the rule.

     

    In this case the 88:isOn works as an extra 'guard' for the rule. #foo is posted AND device 88 is on then log 'A'....

    So when your rules triggers on #events, then all other test in the head of the rule works as extra guards.

     

    So, back to your rules. If I understod things I guess you could simplify it a bit.

    Please login or register to see this code.

    I don't think your 'OnOff' variable is needed as the spotKab:isOn and spotKab:isOff will never post the same #postOn/Off event twice.

    You also don't need to make Count_spotKab a triggerVar as it only serves as an extra condition (and combined with something like #postON it can never make a rule true as discussed in the beginning of the post)

     

    In general, a rule that should only work ex 5 times a day would be

    Please login or register to see this code.

     

     

    With this declaration of a variable - I have an error!

    Please login or register to see this image.

    /monthly_2022_09/image.png.84459000955072f4a372d454376b691a.png" />

     

     

    Please login or register to see this attachment.

    Posted (edited)

    oh these brackets)

    and yes, the rule works and it's easier! thank you!

    Please login or register to see this image.

    /monthly_2022_09/image.png.6c6559deadc8f1ac5779759d0df23887.png" />

    then explain the main difference between Util.defTriggerVar and Util.defvar ?

    P.S.: and quick recovery of strength and energy! )))

    Edited by fastvd
  • Topic Author
  • Posted
    13 minutes ago, fastvd said:

    oh these brackets)

    and yes, the rule works and it's easier! thank you!

    Please login or register to see this link.

    then explain the main difference between Util.defTriggerVar and Util.defvar ?

    P.S.: and quick recovery of strength and energy! )))

     

    First a recap of how ER rules work.

    A ER rule consist of 

    Please login or register to see this code.

    If there is no arrow, =>, it's just considered an expression that is executed when we restart ER.

    Ex.

    Please login or register to see this code.

    only runs when we start/restart ER. No rule is created. These expression can be good for setting up ER variables etc.

     

    If it's a rule (e.g. having an =>) the rule is compiled into an efficient format to run and stored away in a rule database.

    In particular the <test> part is inspected for any type of trigger.

    Please login or register to see this code.

    This rule contains 2 triggers, device 77 changing value and global variable 'DayT' changing value.

    The ER engine will setup up a link from those trigger to running the rule.

    So if 77 changes value it will run the rule, the rule will test if 77:isOn and if the global 'DayT' is equal to 'Night'. If so, the actions will be run.

    The advantage with this setup is that we only run the rule when something that can possibly make the rule true is happening.

    Many other home automation rule systems run all rules continuously in a loop to see if any rule has been true. This way ER is more efficient.

     

    Ok, ER variables comes in 6 flavours.

     

    1.

    Please login or register to see this code.

    This will create a ER internal variable only accessible within other ER rules. We can do the same with

    Please login or register to see this code.

    They are not accessible outside of rules from i.e. Lua

     

    2. We can have rule local variables

    Please login or register to see this code.

    These variables are temporary when a rule is run and disappears after that.

     

    3. We can use Lua global variables within rules

    Please login or register to see this code.

    These are a little bit slower to use because ER first checks if 'a' in this case is an internal ER variable, and when not found tries the Lua global version.

     

    4. We can use HC3 global variables with $<globalName>

     

    5. We can use QuickAppVariables stored in the ER QA with $$<quickAppVariableName> 

     

    6. ...and we have triggerVars. These are ER internal variables declared with

    Please login or register to see this code.

     

    If we would do

    Please login or register to see this code.

    We would get an error that there is no trigger for the rule. When the compiler inspects the test (a == 7) there is no device or global or event that can

    trigger this rule. Just an internal ER variable and they don't trigger rules when they change value.

    However, we can make it a trigger by declaring it with

    Please login or register to see this code.

    The compiler will know that a is a trigger variable now and allow it. Whenever we assign 'a' a value, the ER engine will check if the value is a new value and if so it

    will generate an event that will trigger all rules that the variable is part of the tests.

     

    • Like 1
    Posted

    @jgab perfect summary, thanks

     

    In ER4 I have only issue with starting values (as was discused in different topics/time)

     

    It could be super to have possibility to generate starting events based on real value of devices/parameters - something like:

     

    fakeEvent(deviceID) // this will read Value from deviceID an generate event as standard change of value in this deviceID 

    fakeEvent(deviceID,"temperature") // with parameter it will read real value of temperature parameter from device ID and generate event with for this parameter and value

     

    any other rules will react on these events and also same will be possible in other situations where we need to read default values ...

     

    What do you think about it?

     

     

     

  • Topic Author
  • Posted

    Please login or register to see this code.

     

    This function would work but there are some general problems.

    First, events/triggers are only emitted when something actually changes value.

    In this case we send old value, which can be interpreted as duplicates.

    In the example from @fastvd in the previous posts my rule solution depended on that

    spotKab:isOn is never called twice in a row, without spotKab:isOff being called.

     

    If you need it just to kick-off some rules when ER (re)starts, you can usually use the .start()

    method added to the rule(...).start() definition. That will run the rule at startup and if the test is ok, run the actions.

    It works with all device and globals etc. that has a current state.

    It doesn't work with home made events.

    Ex.

    Please login or register to see this code.

    will not work as there is no #foo event available when checking the test.

    Please login or register to see this code.

    will works, as we can check 88:isOn in the test of the rule.

     

    You could collect all startup rules in a table

    Please login or register to see this code.

     

    and then do

    Please login or register to see this code.

    Then you have that table if you would like to trigger them all again later when you are running.

     

    You could also use a triggerVar to kick-off some rules at startup or anytime.

    Please login or register to see this code.

     

    The disadvantage is that you need to add the T test in the beginning.

    You could create your own rule function that adds the T.

    Please login or register to see this code.

     

    Posted
    10 hours ago, jgab said:

    Please login or register to see this code.

     

    This function would work but there are some general problems.

    First, events/triggers are only emitted when something actually changes value.

    In this case we send old value, which can be interpreted as duplicates.

    In the example from @fastvd in the previous posts my rule solution depended on that

    spotKab:isOn is never called twice in a row, without spotKab:isOff being called.

     

    thanks, this function will solve all my problems :)

    what is usually value for type?
     

     

  • Topic Author
  • Posted
    17 minutes ago, petrkl12 said:

    thanks, this function will solve all my problems :)

    what is usually value for type?
     

     

    ‘device’

    Posted (edited)

    ER4 was updated to 0.87, and here I see a lot of unnecessary logs in the console, namely, I see all the triggers... once in the 0.5 version, I was just at the top of the main tab, I did this:
    _debugFlags.trigger=false -- log incoming triggers
     and when I needed triggers, I did true...
     and in this version, several versions of the log appeared, as if I put false , but everything still gives me all the trigger logs!
    How to turn it off?


    debugFlags.trigger = false -- log incoming triggers
    _debugFlags.trigger2 = false -- log incoming triggers
    _debugFlags.sourceTrigger = false
    _debugFlags.fcall=true -- log fibaro.call
    _debugFlags.post = true -- log internal posts
    _debugFlags.rule=true -- log rules being invoked (true or false)
    _debugFlags.ruleTrue=true -- log only rules that are true
    _debugFlags.pubsub=true -- log only rules that are true
    _debugFlags.extendedErrors=true

    Edited by fastvd
    Posted (edited)

    Hello. Jan, here I finished my heating, where depending on whether a window is open in our bedrooms, the heating of the entire floor + logging is turned off/on. And just in logging in, I don't know how to describe it so that it tells us WHICH ONE is open, and not just SOME!
    Here are my 2 rules: first, we change the variable if ALL windows are closed, and the other is the other way around: if at least one window is open, then we change the variable and give a log...and here we would like to have a clear understanding of which window is open?

     

    --2) If all windows of the 2nd floor are closed, then the variable Windows_F2=TRUE and vice versa
      rule("windowBedr:safe & windowChil:safe & windowAbabina:safe & windowKab:safe => Windows_F2=true;log('ALL windows on the 2nd floor are closed')")
      rule("windowBedr:breached | windowChil:breached | windowAbabina:breached | windowKab:breached => Windows_F2=false;log('Some window is open')")
      

    PS: if someone is interested in ALL the logic of the climate control rules depending on the state of the windows, I can give you the complete code) Just tell me!

    Edited by fastvd
    Posted

    back to your question, how do you know which window is open! I understand that we can use a separate rule to see which window is opened by an elementary rule:
    rule("windowBedr:breached=> log('bedroom window is Open')")

    rule("windowChild:breached=> log('children window is Open')")
    Similarly for other 2 windows.

    here's the question: is it possible to put a label on the opening of a specific window, so that later, when the rule with all windows works, you can select which window to open based on this label?

    rule("windowBedr:breached | windowChil:breached | windowAbabina:breached | windowKab:breached => Windows_F2=false;log('HOW TO DESCRIBE A SPECIFIC WINDOW HERE?')")

  • Topic Author
  • Posted

    Please login or register to see this code.

     

    • Like 1

    Join the conversation

    You can post now and register later. If you have an account, sign in now to post with your account.

    Guest
    Reply to this topic...

    ×   Pasted as rich text.   Paste as plain text instead

      Only 75 emoji are allowed.

    ×   Your link has been automatically embedded.   Display as a link instead

    ×   Your previous content has been restored.   Clear editor

    ×   You cannot paste images directly. Upload or insert images from URL.

    ×
    ×
    • Create New...