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
  • Some clarification on how Fibaro triggers of type {property='event', event=...} is handled in the Framework.

    First, only two types of events is currently handled; AccessControlEvent and CentralSceneEvent. These are the only two types I have seen so far. If you have other types of events please let me know as it is easy to add new types.

     

    The framework detects these events (if you have declared them in the header --[[ %% events ... --]])

    and re-posts them as events of the format {type='property', propertyName='AccessControlEvent', value=<data part of event>}

    and similar for CentralSceneEvent.

    This is to harmonise the format to the more traditional fibaro triggers format - it also allows me to reuse code in the framework.

    Please login or register to see this code.

    However, these events are now also possible to trigger on and access with the ':property' format which makes it shorter to write.

    AccessControlEvent is 'ID:access' and CentralSceneEvent is 'ID:central'

    Please login or register to see this code.

    we save away the result of lockID:access in the variable 'e' so we can access the fields in the 'data' structure easier in the right-hand side of the rules.

    The last rule can be written in other ways to get similar results 

    Please login or register to see this code.

    If you have several locks it can be handled like this

    Please login or register to see this code.

    Here we don't know what id triggered, so we pick up the <data> part from the env.event.value that is the <data> part of the lock that triggered.

    Edited by jgab

    Share this post


    Link to post
    Share on other sites

    @jgab

     

    it looks there is still problem with that rule on GitHub:

     

      define('KeyFobs', {251, 252})
      rule([[key=KeyFobs:central => log('Tlacitko na ovladaci KeyFob v aute: key=%s %s',key.keyId,key.keyAttribute)]])

     

    Error: "bad argument #2 to '_format' (no value)

     

    Thanks for correction

     

    Edited by petrkl12

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • 9 minutes ago, petrkl12 said:

    @jgab

     

    it looks there is still problem with that rule on GitHub:

     

      define('KeyFobs', {251, 252})
      rule([[key=KeyFobs:central => log('Tlacitko na ovladaci KeyFob v aute: key=%s %s',key.keyId,key.keyAttribute)]])

     

    Error: "bad argument #2 to '_format' (no value)

     

    Thanks for correction

     

    Ok, that doesn't work. KeyFobs:central will return a table of the <data> parts of both 251 and 252. The same ways as {8,9}:value return {99,99} if both 8 and 9 is on.

    The way to do this is to pick up the event that triggered the rule..

    Please login or register to see this code.

    Unfortunately "events" are a bit special and maybe ":central" and ":access" is not the perfect syntax...

    For lights and sensors it's enough to know ID:isOn.

    For events one typically need to look further into the event.

    89:central.keyId=="1" works, but {87,89}:central.keyId doesn't because of what I described above.

    Maybe I could order the <data> parts that {id1,id2,..}:central return in time order, with the latest first. Then this would work

    Please login or register to see this code.

    Would that be understandable?

    Share this post


    Link to post
    Share on other sites

    Need some help, again

    Have this in zerobrane and testing

    Please login or register to see this code.

    Please login or register to see this code.

    and debug window gives this

    Please login or register to see this code.

    Goal is to run different post if any door/window is open or close when set house into SleepMode

    Share this post


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

    Need some help, again

    Have this in zerobrane and testing

    Please login or register to see this code.

    Please login or register to see this code.

    and debug window gives this

    Please login or register to see this code.

    Goal is to run different post if any door/window is open or close when set house into SleepMode

    arm_sensors:value will return a table with the values of the sensors, and a table is never == to 0. One could do max(arm_sensors:value)==0 that will return 0 if the maximum value of the table is 0. However, it is better to do arm_sensors:safe that will return true if ALL sensor are safe.

    arms_sensors:breached will return true if ANY sensor is breached. In fact, :safe is an alias for :isOff and :breached is an alias for :isOn that behave the same way.

    Please login or register to see this code.

     

    Having said that, I'm unsure why you get the error

    Please login or register to see this code.

    Edited by jgab

    Share this post


    Link to post
    Share on other sites

    Thanks, works perfect!

     

    another question about #<event> 

    Please login or register to see this code.

    I cannot use event & expression together?

    Like this

    Please login or register to see this code.

     

    Share this post


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

    Thanks, works perfect!

     

    another question about #<event> 

    Please login or register to see this code.

    I cannot use event & expression together?

    Like this

    Please login or register to see this code.

     

    No, an event has to appear alone on the left hand side of a rule (this may be something I will change in a future release). For now you can move the additional test to the right hand side.

    Please login or register to see this code.

     

    Share this post


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

    oh! found an error in iosLocator scene

     

    Please login or register to see this code.

     

    I have never got to the nextStage code with my devices. Anyway, it seemed like Apple changed the protocol some time ago. I think I have fixed it now and pushed a new version of iOSLocator.

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • Here is another "style" of coding when using the EventRunner framework.

    @julesmartens needed help to code an alarm system. It's a bit complicated because he needs "full" and "ring" protection during night etc.

    ...so it makes an interesting use-case.

     

    Alarm systems are a bit tricky to code because there are typically several implicit states that the system can be in (armed, disarmed, fully armed, ring armed, alarm running etc) and there are many events that can happen during each state that should transition the system to another state.  When coding this, it's easy to miss some combination of possible state/transition and event the system needs to handle.

     

    One common way is to code these kind of systems as state-machines. 

     

    The advantage is that we can structure the code in possible events and all states - and how the system should react in each situation. In that way we can convince ourselves that the system will do the right thing in each situation (and what the right thing should be). For instance, when coding this example I discovered some state transitions that was not explicitly described in the original problem.

    We code it using the EventScript rules. Rules trigger on incoming events and depending on what state we are in, we transition to a new state - sometimes given extra conditions. If we don't handle a state in a rule it just means that nothing happens. It is important to understand/agree that "nothing should happen" i these cases and it can be good to explicitly log that "we don't do anything for this event in this state". In the example below I have left out those "do nothing" for brevity.

    The framework also makes it easy for us to post "fake" events so we can see that the system reacts in the way we anticipate.

    (we don't implement the RGB requirement in the original use-case but it should be easy to add)

    Please login or register to see this code.

    Here we just temporarily breach the system at night and we can see that it goes back to a normal "ring" arming afterwards.

    Please login or register to see this code.

     

    Edited by jgab
    • Like 3

    Share this post


    Link to post
    Share on other sites

    Hi Jgab, 

     

    Thanks for pointing out this method of coding, very interesting and I had never seen this option before!

    Some part of the code is readable to me however I have some fundamental questions.

    Do I understand correctly that I should create a master scene that contains the eventrunner light?

    Next to this I have to create other master scenes with eventdebugger?

     

    For each scene for a function (like alarm) I should declare/link to the eventrunner scene to make this code work ?

    In the example at page 1 of this thread, I see that you listed 55 value. What is this / to what scene should I refer to?

     

    I guess I should use the latest version of eventrunner light from your github page. 

    I loaded it in a scene and got errors. What to change in this scene? 

     

    In the example alarm code you provided here (thank you for that), you do not use global variables.

    In my alarm code I would like to keep to use some globals, for example, 'presentstate' and 'darkness'.

    I want to prevent that breached PIRs trigger the alarm while I am at home.

    And I prefer to not hardcode "sleepstate" based on a fixed timeslot but use global sleepstate instead.

     

     

    Hope your feedback can get me moving forward with this. Looks really nice!

     

    Regards

    Jules

     

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • This is a note on installing the EventRunner framework.

     

    First, I really recommend setting up an IDE off-line on a PC/Mac to test and debug scenes created with the framework before deploying them on the HC2.

    I recommend ZeroBrane Studio. It's free and cross platform. I guess that any other IDE with support for Lua would work.

     

    • Download 

      Please login or register to see this link.

      (free for Windows, MacOS, Linux)
    • Install ZeroBrane and open it.
    • Download 

      Please login or register to see this link.

       (that is the Emulator). Put the file in a directory you want to use for scene development (or use what ZeroBrane suggests)
    • Download 

      Please login or register to see this link.

       (that is the Framework). Put the file in the same directory as HC2.lua
    • Open EventRunner.lua in ZeroBrane and run it  it with the F5 or [>] button.
    • (There is also an optional

      Please login or register to see this link.

      file with some examples that can be included to test more rules (see end of main() function)

     

    Please see this video on how to use the "Emulator" HC2. It demonstrates with a simple scene but the principle is the same for EventRunner.lua

     

     

    There are a few variables in the beginning of the 'EventRunner.lua' file that affect the execution.

    •   _sceneName = "AutoLight". Set to the name of your scene, ex "AutoLight". It's printed as a part of the start-up message.
    •   _deviceTable = "devicemap". Not mandatory, but good practice to give a name to your HomeTable global. Allows you to code like HT = json.decode(fibaro:getGlobalValue(_deviceTable))

     

    There is also a _debugFlags table where logging of various subsystems in the framework can be turned on

    Please login or register to see this code.

     

    EventRunner.lua, when run off-line, calls HC2.lua in the beginning and from there, HC2.lua takes over and run EventRunner.lua. HC2.lua is a HC2 emulator that allows us to run the scene, use fibaro:* calls, call the real HC2 if we want and also run multiple scenes etc etc.

    When we move EventRunner.lua to the real HC2, it will not try to include HC2.lua, and just run as is.

    Usually when EventRunner.lua runs without bugs on the emulator it will run on the HC2 without problem too.

     

    The default EventRunner scene will have the below structure (for EventRunner.lua, EventRunnerLite is slightly different)

    Please login or register to see this code.

     

    Typically, you want to read in some configuration data stored in a fibaro global when starting up. Like a

    Please login or register to see this link.

     containing deviceID definitions as described by @AutoFrank.

    They way to do that is to copy the globals and other data from the real HC2. In the instruction video linked to above the steps to create the HC2.data file are shown (adding HC2 credentials to the HC2.lua file and pressing a button in the Web GUI)

     

    Calling 'Util.defvars' will make the table definitions available for EventScript rules, and 'Util.reverseMapDef' makes the debug output nicer when printing deviceIDs.

    Please login or register to see this code.

     

    When running off-line, the variable _EMULATED is set to true. This allows you to run code off-line that should not run when moving the scene to the real HC2.

    Especially there are commands starting with _System.* that is available when emulated but not on the real HC2.

    Please login or register to see this code.

    _System.speed(true) starts to run the emulator faster than realtime. Perfect when debugging scenes that do things once a day...

    _System.setRemote(<resource>,<device>) sets a resource to be used on the real HC2.

    Normally all calls to devices or globals etc are emulated when running off-line (by the HC2.lua emulator).

    Please login or register to see this code.

    will result in a log message that the device turns on and the state will be saved so a fibaro:getValue will return the right value.

    However, if we set it to remote it will log but also make a call to the real device on the HC2 to turn on the light.

    Be aware that this can be an issue if you run _System.speed(true) as everything goes fast so lamps will just flicker...

    Note, that it is not possible to speed timers on the HC2.

     

    Also, even if you are not using the EventRunner framework with Lua event handlers or EventScript rules, it is still a very convenient to use HC2.lua to code standard scenes. All fibaro functions are available, fibaro:sleep(), HTTPClient, setTimeout works etc... and it it's possible to run faster than realtime, set breakpoints etc. Often when I try to help others in the forum with standard lua scenes I can quickly code and test with HC2.lua emulator to make sure that my code is correct...

     

    So, debug the rules on a PC/Mac and when they behave as expected copy the the whole framework/scene to the HC2 and it should run correct! :-) .
     

    Edited by jgab
    • Like 1

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • 6 hours ago, julesmartens said:

    Hi Jgab, 

     

    Thanks for pointing out this method of coding, very interesting and I had never seen this option before!

    Some part of the code is readable to me however I have some fundamental questions.

    Do I understand correctly that I should create a master scene that contains the eventrunner light?

    Next to this I have to create other master scenes with eventdebugger?

    I just added a post on how to setup the framework <

    Please login or register to see this link.

    >. Also linked from post #1.

    The alarm example is based on the full EventRunner.lua framework as it uses the

    Please login or register to see this link.

    feature, that is not available the EventRunnerLite.lua framework

     

    I would really really really recommend that you setup a development environment on a PC or Mac (using the free ZeroBrane app mentioned in the setup post). It will save you a lot of time to test out the scene there before deploying on the HC2. Literally saves you time as the framework, when off-line, as default run the rules faster than realtime, so you can speed through weeks in seconds but the logs still prints the correct time/date so you understand when things happened (the 'speeding' can be turned off)

     

     

    6 hours ago, julesmartens said:

    For each scene for a function (like alarm) I should declare/link to the eventrunner scene to make this code work ?

    In the example at page 1 of this thread, I see that you listed 55 value. What is this / to what scene should I refer to?

    55 is just an example for that post of a device trigger, and need to be changed for a real deviceID if running on the HC2.

    You take a copy of the EventRunner.lua file and replace the "function main() ... end"  in the beginning of the file with the code in the alarm example I posted above and run it on a PC/Mac as described in the setup post. Then, you could try to replace the deviceIDs with your real deviceIDs and try it on the HC2. Note that you also have to declare the door and window sensors and the keyfob in the header of the scene, like all HC2 scenes usually do. Otherwise the framework will not get notified if a sensor changes state.

    In my example the header would look like

    Please login or register to see this code.

    In the EvenRunnerDebug.lua file (that is only used when running off-line) you can set the _REMOTE variable as described in the setup post. You also need to add your HC2 credentials in that file. Having done that, while running off-line, rules will call the real fibaro function on your HC2 and turing on sirens and flashlights etc. That is great for debugging. However, you won't get triggers from sensors then. The way to do that is to create rules that turn ono sensors at specific times (that is possible when running off-line but not when running on the HC2)

    Ex.

    Please login or register to see this code.

    The above example defines a rule that logs a message when a sensor is breached. The last rule waits until 15:30 and sets the sensor to on (i.e. breached the sensor) and the first rule will trigger. Once again, only works off-line, but is a great way to "play back" events in a predetermined order to test the logic of the scene. The other nice thing is that the rules runs faster than realtime so we don't have to wait until 15:30....

     

    6 hours ago, julesmartens said:

    I guess I should use the latest version of eventrunner light from your github page. 

    I loaded it in a scene and got errors. What to change in this scene? 

    Follow the above setup post.

     

    6 hours ago, julesmartens said:

     

    In the example alarm code you provided here (thank you for that), you do not use global variables.

    In my alarm code I would like to keep to use some globals, for example, 'presentstate' and 'darkness'.

    I want to prevent that breached PIRs trigger the alarm while I am at home.

    And I prefer to not hardcode "sleepstate" based on a fixed timeslot but use global sleepstate instead.

    The setup post explains how to bring in a "HomeTable". In 'EventScript' rules it is easy to use (set and get) fibaro globals.

    If the state is not in 'armedFull' or 'armedRing' the alarm will not trigger on a pir breach as there is no such state transition. In the example it automatically turns off in the morning (06:00) but it could be turned off the first time someone moves in the morning. 

    Myself, I have rules that turn on the alarm on weekdays if there has been no movement for a while after 08:00 as family members leave for work and school. And then I use the

    Please login or register to see this link.

    scene to disable the alarm when family members approaches the house in the evening.

    Please login or register to see this code.

    Have a look at the EventScript tutorials linked in post #1.

     

    6 hours ago, julesmartens said:

     

    Hope your feedback can get me moving forward with this. Looks really nice!

     

    If you are new to programming and new to the HC2 this is going to be a bit daunting (and you didn't choose the easiest use-case), but first see if you get the example up and running off-line on a PC / Mac and we can take it from there...

     

     

    Share this post


    Link to post
    Share on other sites

    HI I

     

    short headsup. I just installed zerobrane and the libs as instructed.

     

    I ran test code

    require("FibaroSceneAPI")
    hc2_user = "X"
    hc2_pwd = "Y"
    hc2_ip = "192.168.1.200"  

     

    local data = fibaro:getGlobal("Darkness")
    print(data)
     

    With the feeback 

    Program starting as '"C:\Program Files (x86)\ZeroBrane\bin\lua.exe" -e "io.stdout:setvbuf('no')" "C:\Users\JMartens\Downloads\ZeroBraneStudio\myprograms\testfile1.lua"'.
    Program 'lua.exe' started in 'C:\Users\JMartens\Downloads\ZeroBraneStudio\myprograms' (pid: 22108).
    1
    Program completed in 0.17 seconds (pid: 22108).

     

    So I had "1" as feedback which is OK for that global. ;-)

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • New version, 1.4, is uploaded.

    I have rewritten the EventScript trigger logic. It is much cleaner now and I can sleep better at the nights.

    Everything should work as before, but because it's an extensive rewrite bugs can have sneaked in - let me know and I fix it.

     

    A new feature is that logic expressions in left-hand of rules for event triggers is now allowed

    Please login or register to see this code.

    In fact, expressions like this works

    Please login or register to see this code.

     So, open coded event expression in the left hand will be used as trigger (event handlers). Note that this rule will never trigger

    Please login or register to see this code.

    ..as a rule can never be triggered by 2 events at the same time.
      There is a new function Util.printRule(rule) that will list the event handlers (triggers) of a rule

    Please login or register to see this code.

     ...and we can see that it creates trigger for the 'bar' and 'foo' event, and for the deviceID 55.

    This is a good way to see what rules will react to. 
     

    I have started to clean up the error handling too. Still many unclear error messages but the logic is there now to improve it.
    Many small bugs fixed; local vars could not be set to 'false' etc.

    Files changed:

    EvenRunner.lua

    EventRunnerDebug.lua

    example_rules.lua

    (haven't updated iOSLocator.lua yet)

    Edited by jgab

    Share this post


    Link to post
    Share on other sites

    Hi @jgab,

    can you help me understand what this does? 

    Please login or register to see this code.

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • 6 minutes ago, 3JL said:

    Hi @jgab,

    can you help me understand what this does? 

    Please login or register to see this code.

    #foo{val='a'} is a short form for typing {type='foo', val='a'}

    This is because all events are tables with a 'type' field.

    #foo would be the same as just {type='foo'}.

    In the example above I match against #foo{val='$a'}, which means that the script variable 'a' will be set to the value of the 'value' field, and the variable 'a' is then usable in the rest of the rule expression. Here we write it out with 'log'.

    Edited by jgab

    Share this post


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

    New version, 1.4, is uploaded.

     

     

    Thanks for new version.

     

    Here is my findings:

     

    1. Error in following rule

    'Switches:central => d=env.event.deviceID; RoomActions(d,'switchesT'); log('Vypinace pohyb id=%s',d)': /opt/fibaro/scenes/227.lua:1229: /opt/fibaro/scenes/227.lua:997: invalid order function for sorting

    Please login or register to see this code.

     2. This rule doesn't work at all (changes  in label in virtual devices). Triggers are coming into scene ...

    Please login or register to see this code.

     

    Share this post


    Link to post
    Share on other sites
  • Topic Author
  • 42 minutes ago, petrkl12 said:

     

    Thanks for new version.

     

    Here is my findings:

     

    1. Error in following rule

    'Switches:central => d=env.event.deviceID; RoomActions(d,'switchesT'); log('Vypinace pohyb id=%s',d)': /opt/fibaro/scenes/227.lua:1229: /opt/fibaro/scenes/227.lua:997: invalid order function for sorting

    Please login or register to see this code.

     2. This rule doesn't work at all (changes  in label in virtual devices). Triggers are coming into scene ...

    Please login or register to see this code.

     

    Thanks!,

    the first issue I can't reproduce. If you run

    Please login or register to see this code.

    do you still get that error?

     

    The second issue, the feature of having a list of deviceIDs in an event "disappeared' in the new version. I will fix it tonight.

    However, now it's also possible to do like below, but I admit it's not as convenient...

    Please login or register to see this code.

     

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