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

Note. The first ~2000 posts of this thread is mainly about EventRunner3 that is for the HC2. EventRunner3 is not developed further, but bugs are fixed as they are reported.

For HC3, the version is EventRunner4, and is a QuickApp,.

Please login or register to see this link.

 Its EventRunner5, link <

Please login or register to see this link.

>

Most of the 'Event Script" syntax and commands are still valid and old posts can be of use for new HC3 owners.

 

Link to

Please login or register to see this link.

for the HC2

 

There is a QA that is used to download and install the EventRunner4 QA to your HC3 (and update to new versions)

 

Here is an example of how to code in a "single instance / event" style. A style I'm using today for all of my scenes.

The idea is that instead of having to deal with a new instance being spawned with every scene trigger, all triggers are dealt with from within a single scene instance that is continuously running. It becomes something close to a traditional event loop model found in most modern GUI frameworks.  The advantages with coding scenes in this style are:

  • Scene can keep state in local lua variables between scene invocations/triggers
  • Easy to keep different rules/logic in the same scene without causing conflicts, e.g. combining continuous running loops/schedules with immediate reaction on incoming triggers
  • Easy to distribute different rules/logic between different scenes and allow them to communicate
  • Easy to schedule actions to do in the future - that can be easily cancelled if new information is gained.
  • Because the scene is continuously running it doesn't matter if there is a heavy initialisation when the scene starts up (parsing HomeTables etc.) as it is only done once...
  • The framework has extensive support to run and debug the scene offline on a PC/Mac to get things right before deploying the scene on the HC2 (

    Please login or register to see this link.

    ). Offline it is easy to simulate trigger/events to understand if the logic is correct, something that is not always easy to detect in a asynchronous environment.
  • It has publish/subscribe mechanism allowing scenes to exchange events without having to know each other's names or IDs or rely on global variables.
  • It has proven to be easy to integrate with external event/msg based systems like Node-red, where scenes can both send and receive events to node-red and thus extend functionality with Alexa, Google home, Hue etc etc.

 

Please login or register to see this attachment.

 

The framework is available in two version, a 'light' version and a full blow version with a lot of bells and whistles. The latter also supports writing rules in EventScript, a "simple", but very flexible and efficient approach to writing rules that need to trigger things at various times of the day, or trigger on sensors or switches changing states. The implementation of EventScript is built on-top of the single instance framework and the event model and would have been impossible to do in a traditional scene model. 

Ex of EventScript rules.

Please login or register to see this code.

More on EventScript and the full blown version is available in the posts listed below:

  • Please login or register to see this link.

    (works for EventRunnerLite too)
  • Please login or register to see this link.

    - a bare bone version of the framework
  • Please login or register to see this link.

    .
  • Please login or register to see this link.

  • Please login or register to see this link.

     (

    Please login or register to see this link.

    )
  • Please login or register to see this link.

  • Please login or register to see this link.

  • Please login or register to see this link.

  • Please login or register to see this link.

    - mapping of Hue devices to standards z-wave/fibaro:* calls
  • Please login or register to see this link.

    - sending/receiving events from node-red, with extendable, example flow.
    Gives support for Sonos TTS and Alexa input...Updated flow <

    Please login or register to see this link.

    >.  (and here is another thread,

    Please login or register to see this link.

    ,

    Please login or register to see this link.

    ,.)
  • Please login or register to see this link.

     used to debug EventRunner offline
  • Please login or register to see this link.

    and handle the VD logic with EventScript rules (

    Please login or register to see this link.

    )
  • There will also be some services based on the EventFramework posted
    • Please login or register to see this link.

      - a service that checks with iClod for people at places and sends events to other EventFramework services
    • Please login or register to see this link.

      - a service that fetches evens from Apple's iCloud calendar or Google calendar and post them to scenes. (latest 

      Please login or register to see this link.

      )
    • Please login or register to see this link.

      - part of Supervisor
    • Alarm service - TBD
    • Please login or register to see this link.

      - a UNIX like crontab service other scenes can register call-backs with
    • Please login or register to see this link.

       - A scene that pings EventRunner scenes and makes sure they stay alive.
  • Best practices rules - TBD
  • Implementation notes 
    • Please login or register to see this link.

    • Notes on the EventScript implementation - TBD
  • Please login or register to see this link.

 

The lastest version of the code is kept in my

Please login or register to see this link.

. The background of this framework and a thread discussing it can be found 

Please login or register to see this link.

, however the code has evolved a bit from when originally posted there.

 

If you are new to EventRunner I don't encourage you to read the posts in the thread chronological, as it contains a lot of outdated information.

 Instead, the best way to get an understanding of the capabilities of EventRunner is to browse the links in the list above.

 

 

Edited by jgab
  • Like 6
  • Thanks 4
Link to comment
Share on other sites

  • Topic Author
  • One way to to make the framework easier is to enhance the 'post' function. 'post' not only takes time in seconds from now that the event should be posted. It is also able to post the event at specific times of the day or next day .

    Below is a variant of 'post' we can do if the time parameter is a string:

    Please login or register to see this code.

    Post uses the 'toTime' function that converts a time string to seconds from now (it could be negative if a time in the past is specified).

    Having 'toTime' we can do some simple time math with sunset/sunrise, like 'post(event,"t/sunset+15")' that will post the event 15 min past sunset.

    The time schedule example in the first post can then be easier coded as:

    Please login or register to see this code.

    A more powerful 'post' function makes it much easier to deal with time.   

    One issue is that if you try to post something to happen at sunrise tomorrow, a 'post(event,"n/sunrise")' will post tomorrow, but at today's sunrise time. This is because when the post is made, sunrise returns today's sunrise. A way around this if doing a scheduler is to have a scheduling loop that make all the daily schedules at midnight. Then sunset/sunrise will return the correct values.

    Please login or register to see this code.

    The only snag is that in the startup we have to post events happening today, because the setup loop only run at midnight. Well, we can live with that.

    Edited by jgab
    • Like 3
    Link to comment
    Share on other sites

    Nice :) thank you very much for this!

     

    Do I understand that essentially it is a daily loop that 'posts' returning actions (although it is not really a 'daily loop' as a post triggers a repost) and that any device events (e.g. sceneactivation, value) results in posting additional triggers? 

     

    I do however not fully understand 1 thing:

    How are the additional triggers included? And how can you include multiple events from different devices? Is it as simple as including all of them in the header? But how (technically) are these then all combined in one scene instance?

     

    Small other thing: in case of failure / bug, will the scene autorestart?

     

    Thanks!

    Link to comment
    Share on other sites

  • Topic Author
  • Yes, device events arrives as posted events. You have to declare device properties/events/weather/globals triggers you want to receieve in the scene header. I've excluded the header part from my examples. The last version of the time scheduling is actually a daily loop that at midnight post the events for each day.

    Your question, yes you include them in the header and they will all arrive as calls to 'main(sourceTrigger)' in the same scene instance (thats the magic of the rest of the framework code). So for instance, the 'presence detection' example rely on that the sensors 99,199,201, and 301 are declared in the scene header. The code react on any of them being triggered and check if the others are also safe or breached. In theory we could keep a local bit-array with the status of the sensors to directly know if they are all safe or someone is breached without re-checking all the sensor as is done in the code. However, I wanted to keep the example simple.

     

    Second question, no it doesn't autorestart - that is a bit tricky. What I do is that in my scenes I implement a 'keep-alive' mechanism. In all scenes I have a

    Please login or register to see this code.

    and in some selected scene(s) watching the others, there is a 'pong' routine that pings the other scenes and if they don't respond with a pong within certain time they are restarted.

    Please login or register to see this code.

     

    Edited by jgab
    Added delay after receiving a 'pong' - otherwise we have a lot of ping-pong...
    • Like 1
    Link to comment
    Share on other sites

  • Topic Author
  • Another problem when coding loops with fibaro:sleep (or setTimeout for that matter) is time drift.

    Please login or register to see this code.

    The loop doesn't take 1 minute, but 1 minute + the time the stuff before the sleep requires to execute. So if you hoped to do everything on the minute things start to drift after a while. Sometimes that is not a problem but if you want thing to happen at specific times it is.

    Please login or register to see this code.

    This post the first "ding" at 15:00, and then the "ding" loop re-post the "ding" event 24 hour from now. Even though the 'printf' takes a very little time (ms), after a while it will start to drift and "dings" will start to happen 15:00:01, 15:00:02 etc.. The problem is of course that we do a relative post ("+/24:00"). One solution is to try to time how long it takes for the other stuff to execute and deduct that from the 24 hours. The easier solution here is to instead do a 'post("n/15:00")', that takes care to post at the time specified. This will run forever without drift (true for "t/..." too).

    If you want to run on a relative time advance, like every hour, you either schedule "n/00:00", "n/01:00", "n/02:00", ... etc or you need to do some calculation...

    However, the framework always do a post in a separate timer thread which kind of helps minimizing the drift. Just by doing the post(event,"+/01:00") as soon as possible, before we do the other stuff, it will minimize the drift. Even if, like in this case, the printf will take a long time...

    Please login or register to see this code.

     

     

    Link to comment
    Share on other sites

    Thanks @jgab! thinks are getting more clear!

    (Although I still do not understand technically what in the code ensures that only one scene instance is running :) )

     

    I have been able to create triggers, but not scheduled events.. Can you help me with the following?

    For some reason this code (as part of the main function):

    Please login or register to see this code.

    does yield a posting, but nothing happens 30 secs later.

     

    Weirdness seems to happen in the debug as the posting is scheduled for the same time as the post (11:47:15):

     

    Quote

     

    [DEBUG] 11:47:15: EventMgt - EventRunner v1.0
    [DEBUG] 11:47:15: Loading rules
    [DEBUG] 11:47:15: Posting {"type":"scheduler","event":{"type":"action","action":function: 0x9851628},"next":"+/00:00:30"} for Thu Aug 16 11:47:15
    [DEBUG] 11:47:15: Scene running
    [DEBUG] 11:47:15: Sunrise 06:24, Sunset 21:02

     

    Do you have any clue what is going wrong here?

    (FYI: it seems that the mailbox variable remains empty; plus in this case the posting happens before the code reports "scene running" but the latter does not seem to be the issue, because the same happens if the scheduled action is triggered by an event)

     

    Thanks!

    Edited by 3JL
    Link to comment
    Share on other sites

  • Topic Author
  • Ok,

    you are now using the full blown EventRunner framework, which is ok. In the 'Lite' version described above a 30s scheduled loop would look like this:

    Please login or register to see this code.

    In the EventRunner framework there are many ways to achieve this.

    First, the main() function becomes an initialization functions that runs before the scene starts - that's why you see the 'post' before the message that the scene has started, So inside main you do initialization stuff (read HomeTable, set up variables etc, and declare event handlers or script rules).

    What you do in your example is that you post an event but you have not declared any event handlers to do anything with it, so nothing happens. (the mailbox variable is only used for fibaro triggers coming in, internally posted events are handled more efficiently)

    I will come back with another post describing the syntax of the EventRunner framework better, but here are 3 ways to achieve a 30s loop:

    Please login or register to see this code.

    or because this is a very common pattern there is a Event.schedule function that creates a loop for us: (the action can be either an event or a lua function like in this case)

    Please login or register to see this code.

    or using the script rules:

    Please login or register to see this code.

     

    Edited by jgab
    • Like 1
    Link to comment
    Share on other sites

    Thanks! I got confused between Event.schedule and post({type=schedule,...})

    This works now!

     

    What would be the syntax for a single action within 30 secs, rather than repeated every 30 secs?

     

    edit: for e.g. the case to turn off a lamp again 30 secs after an event. My use case: I have several events that can turn on the ventilation for different periods, but they should not interfere (e.g. if it is turned on for 30 mins, and another trigger wants to turn in it on for 10 mins shortly thereafter, the 30 mins should prevail). Your framework seems excellent to manage this.  

    Edited by 3JL
    Link to comment
    Share on other sites

  • Topic Author
  • Well, then you just post something +30s and don't re-post the event.

    Please login or register to see this code.

    Assume that you have a switch with deviceID 33 and you want to do something 30s after the switch is turned on

    Please login or register to see this code.

    or with the scripts

    Please login or register to see this code.

     

    Edited by jgab
    • Like 1
    Link to comment
    Share on other sites

    @jgab i am testing your "bathroom" settings but i get this error when start scene. What have i miss?

    Please login or register to see this code.

     

    Link to comment
    Share on other sites

  • Topic Author
  • 6 minutes ago, jompa68 said:

    @jgab i am testing your "bathroom" settings but i get this error when start scene. What have i miss?

    Please login or register to see this code.

     

    Does the version in example_rules.lua work? It seems like it doesn't think that wc.door is defined which is strange. Can you send me the whole main() setup code?

     

    Link to comment
    Share on other sites

    1 hour ago, jgab said:

    t seems like it doesn't think that wc.door is defined which is strange

    Well, my own fault. Different name in "HomeTable" and code.

     

    Q2, code starts both lights in WC but does only turnOff 1 of them. Strange...

    Please login or register to see this code.

     

    Link to comment
    Share on other sites

  • Topic Author
  • well, the 

    Please login or register to see this code.

    is one statement, so the inBathrom only affect the "tak"

    Please login or register to see this code.

    is another that is always carried out if the door is open and the motion is safe for 10min

    I would write it as 

    Please login or register to see this code.

    then if inBathroom is true it will turn off both lights.

    or

    Please login or register to see this code.

    here we move the inBathroom test to the left side so if the 'for' is true, the inBathroom need to be true too for the right hand to execute. Keep it outside the 'for' expression though.

    or

    Please login or register to see this code.

    ||>> is a kind of if-then syntax, "|| <test> >> <expression> ; <expression> ; ..."

    Edited by jgab
    Link to comment
    Share on other sites

    @jgab in one of your examples you send notification every week at a specific day. Can your scene also handle odd or even week numbers?

    Link to comment
    Share on other sites

  • Topic Author
  • Ok, never thought about week numbers. 

    I have pushed a new version of EventRunner.lua to Github with week number support. The "constant" 'wnum' returns the current week number. (operator '%' is reminder)

    A rule could look like this then

    Please login or register to see this code.

     

    Link to comment
    Share on other sites

  • Topic Author
  • It makes sense to have % and wnum in the script language. However, it is quite easy to add functionality with lua functions.

    Please login or register to see this code.

    and its reasonable efficient. I just realized that os.date("%V") only works on Mac and HC2. On windows it's os.date("%W"). Need to add test in the code...

    Link to comment
    Share on other sites

    Hi @jgab, can 'rule.eval'-scheduled actions be cancelled / overruled?

    In the example you have provided above: the action should be performed only 30 seconds after last trigger of device 33 (assuming multiple triggers can happen within 30 seconds).

     

    On 8/16/2018 at 2:04 PM, jgab said:

     

    Please login or register to see this code.

     

     

    Link to comment
    Share on other sites

  • Topic Author
  • If the device is a switch and you want the switch to turn off when its been on for 30s one can use the "for" construct

    Please login or register to see this code.

    for(<time>,<expr>) monitors the <expr> and when it has been true for <time>  it returns true. In the example above if it turns off before 30s the timer is cancelled and started next time the device trigger on.

    if you want to monitor if a sensor has been safe for 30s and then do something it is similar

    Please login or register to see this code.

    Does that answer your question? If you have a specific case you like to share I can help you with suggestion how to express it.

    Link to comment
    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...