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

  • Topic Author
  • 14 hours ago, 3JL said:

    Hi @jgab, another question :)

    Is it possible to identify manual overrides? E.g. events take place, under the condition that a lamp has not changed manually recently?

    J

    Hi, there is some experimental code for that, however it's not well tested. Get the latestversion from Github.

    "ID:manual" returns the number of seconds since the id was last manually changed, or -1 if it was done from the script.

    So, if ID:manual>=0 then it was changed manually. 

    The rule below turns on the lamp if the sensor is breached, but only if the last manual change was at least 10min ago.

    Please login or register to see this code.

    This rule only turns on lamp2 if lamp1 was turned on manually

    Please login or register to see this code.

    I think it only works for dimmable switches at the moment (where fibaro:call(ID,'turnOn') sets the value to 99). If you need it for non dimmable switches, where 'turnOn' sets the value to 1, use ID:value=1 instead if ID:on...

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • To my understanding, knowing if a trigger was done manually is always a guess. If one calls fibaro:call(lamp,'turnOn') then you will get an {type='property', deviceID=lamp, propertyName='value'} event back from the HC2. What I do is that I intercept all fibaro:call's in the framework, and if I get an event back within 1sec I conclude that it was not a manual event. In rare cases when you toggle a switch manually at the same time as the script changes the same switch you may get a false negative...

    Edit: Ok, have pushed a new version that should work with non dimmable switches (with value 0 and 1). Still a heuristic though.

    Edited by jgab

    Share this post


    Link to post
    Share on other sites
    22 hours ago, jgab said:

    Hi, there is some experimental code for that, however it's not well tested. Get the latestversion from Github.

    "ID:manual" returns the number of seconds since the id was last manually changed, or -1 if it was done from the script.

    So, if ID:manual>=0 then it was changed manually. 

    The rule below turns on the lamp if the sensor is breached, but only if the last manual change was at least 10min ago.

    Please login or register to see this code.

    This rule only turns on lamp2 if lamp1 was turned on manually

    Please login or register to see this code.

    I think it only works for dimmable switches at the moment (where fibaro:call(ID,'turnOn') sets the value to 99). If you need it for non dimmable switches, where 'turnOn' sets the value to 1, use ID:value=1 instead if ID:on...

     

    Works like a charm :) Thanks!!

    Share this post


    Link to post
    Share on other sites

    Hi,

     

    how to start scene with parametres in your script e.g. 

    fibaro:startScene(jT.scene.HueCollorEffect,{"1", "192.168.1.245", jT.hue.HueUserZahrada, "colorloop", 254, 2}) 

     

    I have found in your wiki:

    :start. Start scene. Ex. 66:start = fibaro:startScene(66)

    but I don't know where I should place parametres {a,b,c}

     

    Thanks

     

    My script - but it doesn't work:

      Rule.eval("everyHourRun = {00:00,01:00,02:00,03:00,04:00,05:00,06:00,07:00,08:00,09:00,10:00,11:00,12:00,13:00,14:00,15:00,16:00,17:00,18:00,19:00,20:00,21:00,22:00,23:00})")
      Rule.eval("@everyHourRun & label(Zahrada.Osvetlenizahrady,'sldBrightness')~=0 => log('Run Garden Light Effect');fibaro:startScene(scene.HueCollorEffect,{'1', '192.168.1.245', hue.HueUserZahrada, 'colorloop', 254, 2})")

    Edited by petrkl12

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • No, you can't include calls to fibaro:... like that in the script. Well, in fact you can but then you have to write

    "...=> log('Run Garden Light Effect');fibaro.startScene(fibaro,scene.HueCollorEffect,{'1', '192.168.1.245', hue.HueUserZahrada, 'colorloop', 254, 2})")

     

    The reason is that fibaro:fun(x) is Lua's attempt to object oriented programming and is translated to fibaro.fun(fibaro,x), and I don't support the ':' calling convention in the script (I use ':' for other stuff)

    The script syntax for starting a scene with args is SCENEID:start=ARGS. i.e.

    "...=> log('Run Garden Light Effect');scene.HueCollorEffect:start={'1', '192.168.1.245', hue.HueUserZahrada, 'colorloop', 254, 2}")

    Edited by jgab
    • Like 1

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • In a

    Please login or register to see this link.

    we described how to write scheduling rules (daily) rules using the script language. Those rules were invoked at specified times and we could add extra conditions if their actions should be carried out or not.

     

    However, we also want rules that react immidiatly to devices being triggered or any other event that the HC2 scenes support (and that is declared in the header of the scene).

    Please login or register to see this code.

    This is pretty simple examples. Events need to be declared in the scene header (or the EventRunner scene will never be informed about the events). After that, rules reacting on events can be written straight forward in the script syntax supported.

    A trigger rule has the syntax

    <expression involving scene triggers> => <actions>

     

    When the script is "compiled" we look through the left-hand expression looking for any device/global or other event and register the rule to be called whenever those devices/globals or other events arrive.

     

    So when 'myLightSensor's value changes in the above example, the scene is triggered and the EventRunner framework make sure to call the right rule(s). The left-hand side is then evaluated, 'myLightSensor:lux > 200', and if it returns true the right-hand side is evaluated which turns on 'myLight1'.

    The last rule is an event 'AccessControlEvent' that the framework currently hasn't special syntax support for. However, we can still match against  the incoming event (sourceTrigger) and write our rule. In the future we may add script syntax to deal with these event more conveniently.

      

    The left-hand side can contain expressions involving several triggers, and the rule is called whenever any changes state

    Please login or register to see this code.

    This rule is called whenever ‘myDoorSensor’ changes state or fibaro global 'Home' change value. The left is evaluated so the sensor must be breached and the global set to 'AWAY' for the expression to be true and the light turned on.

    This can be quite useful. Assume we have a set of fibaro motion and light sensors 

    Please login or register to see this code.

    The first rule is called whenever a sensor changes state. ':breached' called on a set of devices will return true if any of the devices in the set is breached. The sourceTrigger that caused the rule to be triggered is available in the script variable 'env.event'. We pick out the deviceID that caused the trigger and assign it to a script variable 'd'. Then we apply the ':msg' operator on the set of phone IDs we want to send a message to. The message is created with the 'log()' function that writes the message to the log but also return the message string to the ':msg' operator so that it is sent to the phone devices. There are ':name' and ':roomName' operator we can use on a device to get the device name and room name.

     

    The second rule is also called whenever a sensor changes state and but here we take out the max value from the set of lux values returned. If that max lux value is lower than 200 we turn on the light.

     

    The third rule is similar but a more complex expression that sums the lux values and divide with the number of sensors to get an average lux value to check against. 

    In reality you may want to turn on and off the value depending on the lux value, but not toggling the light like crazy if the lux value is varying around the break point. Then the below can work.

    Please login or register to see this code.

     

    The EventRunner framework calls rules immediately when an event comes in (it doesn't poll every x seconds) so it is suitable for writing rules that need to react quickly, like turning on lights when sensors are breached. Rules can also share local variables and states as they run in the same scene instance which further helps in writing rules.

    Please login or register to see this code.

     Here, whenever all sensors are safe and also the door sensor is safe we set a local script variable 'away' to true.

    The we have a schedule rule that runs at random intervals between 5 and 20min toggling lights, but only if away is true. A real presence simulation rule would not set 'away' until the sensors been safe for a period of time. For that it is possible to use the 'for' function described later in this post.

     

    It is easy to limit rules to time intervals using the '..' operator

    Please login or register to see this code.

     Assuming we have a text2speech() function, if the sensor is breached and the time is between 06:00 and 08:00, the message plays.

    This rule is called whenever the sensor changes state but also at 06:00 and 08:01. The reason is that the sensor can be breached at 05:59, which would make the left-hand side condition false and the action not invoked. However, at 06:00 the sensor is still breached but not changing state, so the rule would not be run. Therefore, rules containing '..' intervals are called at entry and exit of the intervals.

     

    Of course, all kinds of tests can be added to a trigger rule, like day of week, month, week number etc. but they don't trigger the rule.

    Please login or register to see this code.

    This will trigger on sensor and time interval, but the wday test also needs to be true too for the action to be invoked.

     

    In the example above, if the intention is to play the message once in the morning, the problem is that it will play every time the sensor is breached between 06:00 and 08:00. We could solve that with setting a flag first time the sensor is breached and clear it outside the intervall, However, it is easier with the 'once' function.

    Please login or register to see this code.

    'once' takes an expression and return true if the expression returns true. However, the expression needs to return false and then return true before 'once' will return true again. In this case it will return true the first time we are between 06:00 and 08:00 but then it will not be true until we exit the interval and enter it the next time, e.g. the next day. So, 'once' keeps state, similar to what we would have done with a flag and it would have been difficult to implement without rules running in the same scene instance.

     

    Another useful function is 'for' that allow us to write tests that need to be true for a period of time.

    Please login or register to see this code.

    The 'for' function always return false the first time it is called, but if the expression is true it starts a timer for the time specified and if the expression is still true then it returns true and continue with the rule. If the expression turns false during the time the timer will be cleared.

    The result is that we can easily write rules that check if something is true for a certain time, like windows left open etc.

    Please login or register to see this code.

    If any window is open for more than 10min a message is sent to the phones (during winter months)

     

    Like 'once', 'for' will not re-trigger before the expression has turned false. In the above example, someone have to close all windows and then open one before the rule will trigger again. However, with 'repeat()' we can re-trigger the 'for' expression.

    Please login or register to see this code.

     

    This will make the rule trigger, and messages sent, every 10min the windows continue to be open. i.e. keep reminding us.

    'repeat' can take an argument being the number of times the 'for' should be re-triggered. 'repeat' also return how many times it has currently repeated, e.g. re-triggered.

    Please login or register to see this code.

     This will remind us 5 times that the windows are open, '...open for 10min', to '...open for 50min',

     

    Rules can also trigger on events.

    Please login or register to see this code.

    This rule trigger on a {type='property', deviceID=88, propertyName='value'} event and in addition checks that the value filed is larger than 0. This is equivalent to write

    Please login or register to see this code.

    ...so for standard fibaro events it's seldom necessary. However it's useful for own defined events.

    Please login or register to see this code.

    Triggers for CentralSceneEvent or AccessControlEvent can be written using the ':central' and ':access' properties

    Please login or register to see this code.

    Here, myKeyFob:central will trigger a CentralSceneEvent for the device with ID myKeyFob. ':central' will return the data part of the event so that we can continue to test if the result '.keyId' equals 4. If that's true we execute the right hand side and turn myLight1.

    A problem is that a ':property' applied to a table of IDs will return a table of results. I.e. {66,77}:value is the same as {66:value, 77:value}, i.e. a table.

    This is a problem because if we want to test if any of 2 keyFobs (id 101 and 103) has the '4' key pressed, we can't write

     Rule.eval("{101, 103}:central.keyId==4 => myLight1:on")    

    The reason is that it will return a table of keyId values for 101 and 103 and a table will not be equal to '4'. What we want to do is apply ':central' to the ID that triggered the rule.

    ':dID' will return the id that caused the event, so we can write like this

    Please login or register to see this code.

    ':dID' returns the ID that triggered the event and then we apply ':central' on that to get the data part, and then we pick out the keyId key and can do our test.

     

    Edited by jgab
    • Like 2

    Share this post


    Link to post
    Share on other sites

    @jgab your framework is absolutely number ONE. There is possible to do a lot of things without programming and move home automation to next level!

     

    I have question about overall logic:

     

    - What is your recommendation about number of EventRunner scenes? Should I put every rules into one scene or divide them based on i.e. rules for one room or functions i.e. lights?

     

    - Are there any limits ie. number of triggered devices in header for one scene?

     

    Thanks

     

     

     

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • On 10/17/2018 at 7:44 AM, petrkl12 said:

    @jgab your framework is absolutely number ONE. There is possible to do a lot of things without programming and move home automation to next level!

     

    I have question about overall logic:

     

    - What is your recommendation about number of EventRunner scenes? Should I put every rules into one scene or divide them based on i.e. rules for one room or functions i.e. lights?

     

    - Are there any limits ie. number of triggered devices in header for one scene?

     

    Thanks

     

     

     

    Thanks @3JL and @petrkl12

    I'm planning to address this in another post. In short, because it's easy to send events between scenes it's quite easy to distribute the logic between scenes.

    Number of rules in one scene can be a lot - I try to be clever to find and call rules effectively. However, number of triggers in the header can of course go out of hand. If it's light switches and other devices that send triggers with some time in-between it's not that problematic. However, Ive seen power triggers coming rapidly (not sure if mine was broken) and that can be problematic. Because Fibaro only allows max 10 simultaneous  instances of a scene that's kind of a limit (actually 1 continuously running main EventRunner scene + 9 trigger instances).

    So if you get 10 triggers within 200ms you may lose a trigger.

     

    For that reason it can be tactical to divide up logic between more than one scene. I would divide them up on function, not room.

    -I have one lightning scene with 'daily' rules and sensor triggers and sceneActivation triggers and keyFob actions to control all lightning in the house and never had an issue. Its 20+ lights and 10+ sensors so it's not huge - maybe divide it up in floors if you have a massive installation.

    -I have a scene continuously calling Apple iCloud Find friends and posting events when family members come and go (I will post that scene later)

    -I have a scene looking at sensors and the listening to the iCloud services to determine if people are at home or elsewhere to send an away/home event to other scenes

    -I have a "house protection" scene that reacts on the away event and barks a dog if anyone opens the front door or ring the bell. It also pushes messages if fire is detected and can be disabled by the key fob.

    -I have a "master scene" that pings the other scenes and restarts them if they don't answer. It's also responsible for restarting scenes that asks for it (some scenes wants to be restarted if the HomeTable changes)

    -I have a power scene that looks at power usage from dishing, washing, and drying machines and sends messages when they are finished. 

     

    I'm planning to do some kind of logging service and some kind of VD to be able to set debug flags while the scene runs on the HC2 and also inject events to test the scene on the HC2 (but I really recommend developing scenes off-line)

     

    I'm kind of thinking about support for rooms and floors, but even though automatically creating lists of sensors and lights belonging to rooms is easy I still think that explicitly making such lists in in the 'HomeTable' is better as not all lights/sensors always should be included, and arbitrary zones with sensors from neighbouring rooms can be defined.

     

    Anyway, I'm happy that you want to try out the code and please let me know if you are missing something or something is difficult to achieve, and let's see if we can fix it.

    Edited by jgab

    Share this post


    Link to post
    Share on other sites

    Anyone that have a working setArmed event?

     

    This does not work

    Please login or register to see this code.

    This does not give error in ZeroBraneStudio but i don't see that it actually do setArmed.

    Please login or register to see this code.

     

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • 1 hour ago, jompa68 said:

    Anyone that have a working setArmed event?

     

    This does not work

    Please login or register to see this code.

    This does not give error in ZeroBraneStudio but i don't see that it actually do setArmed.

    Please login or register to see this code.

     

     

    Assigning values to properties have syntax "ID:property=value".

    Try Rule.eval("@sunset => arm:sensors:armed=1;log('Armed')")

    P.S will look into 'catchup' for @daily rules

    Share this post


    Link to post
    Share on other sites

    Please login or register to see this code.

    This rule gives this on my iOS device

    Please login or register to see this attachment.

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • 1 hour ago, jompa68 said:

    Please login or register to see this code.

    This rule gives this on my iOS device

    Please login or register to see this attachment.

    Sorry for that ;) will fix it this evening and push a new version.

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • Ok, pushed a new version (v1.2) of EventRunner - need to download new version of EventRunnnerDebug too.

    Please login or register to see this code.

    will run the action once if it's after 10:00, and then schedule it for 10:00 the next day. The trick is the keyword 'catch' in the list of times.

    Note that

    Please login or register to see this code.

    will run the action once if it is after 10:00 but before 13:00. Will also run it once if it is after 13:00.

     

    Oh. v1.2 has some changes when it comes to debugging. Logging fibaro calls work at HC2 now.

    Oh Oh. Pushed a new version with separate _debugFlags.fibaroSet for fibaro:setGlobal. Lot's of annoying debug messages from the framework otherwise. Turned off by default.

    Edited by jgab

    Share this post


    Link to post
    Share on other sites

    Did you remember to change layout of push message?

    my eventrunner is growing day by day, 50 rules now, and starting to get hang of it ;)

     

    Impressiv scene and great support @jgab

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • Yes, push messages are fixed

    10 minutes ago, jompa68 said:

    Did you remember to change layout of push message?

    my eventrunner is growing day by day, 50 rules now, and starting to get hang of it ;)

     

    Impressiv scene and great support @jgab

    Thanks for helping me debug it :)

    Share this post


    Link to post
    Share on other sites

    Can i use OR somehow in the actions? Like my example below?

     

    Please login or register to see this code.

     

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • 5 minutes ago, jompa68 said:

    Can i use OR somehow in the actions? Like my example below?

     

    Please login or register to see this code.

     

    Yep, OR is '|'

    Please login or register to see this code.

     

    Share this post


    Link to post
    Share on other sites

    Get some error and it is perhaps my fault because i setup triggers wrong...

     

    Please login or register to see this code.

    When i did go to sleep last night an error did occur in debug and this morning the 4th Rule.eval did not run.

     

    Please login or register to see this code.

    UPDATE

    Found why the 4th Rule.eval did not run. Should be this, perhaps the error from last night is gone also now.

     

    Please login or register to see this code.

     

    Edited by jompa68

    Share this post


    Link to post
    Share on other sites

    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...