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
Question
jgab 1,921
This framework has been superseded by the
Please login or register to see this link.
. The basic principle is the same but features and code has evolved.'So this is for Lua coders out there...
Part of the reason for me owning a HC2 is to play around with programming, to some frustration for the other inhabitants
Anyway, I have some understanding why Fibaro have chosen the model they have. However, I have been trying a "programming model" of funneling all fibaro events into the same running scene instance (
Please login or register to see this link.
).Normally there is a scene instance started up when the scene autostarts and/or additional sene instances started when events declared in the scene header is received. This implies the need to use fibaro's global variables to sync between scenes instances etc... an issue when combining long running scenes like schedulers with triggers of incoming events.
With the model in this example the "autostart" instance is the "main" scene and additional scenes started by triggered events "post" their source trigger back to the "main" scene/instance and exits. (Simplified logic below. In reality a bit more elaborate to avoid race conditions etc)
Please login or register to see this attachment.
(
Please login or register to see this link.
)I'm currently using it in a json based scheduler but it can be quite interesting to use as a general model for coding scenes.
In particular this lends itself to a model based on matching and posting events. Two main functions are provided in this example code;
Please login or register to see this code.
Event:event(pattern,function) declares a handler for 'incoming' events.
'pattern' is any Lua key/value table matched against incoming events. The event needs at least a 'type' key, something that all Fibaro events (source triggers) have. 'function' is the handler called if the event matches.
Ex.
Please login or register to see this code.
This prints "Hello!" when a value property event for device id 310 is recieved (given that it is declared in the scene header)
Patterns can be a bit more elaborate and may contain variables to be matched against.
Ex.
Please login or register to see this code.
Variables start with a '$' char and matched variables are available in the env.p parameter sent to the handler.
For incoming events, keys that are not part of the standard (Fibaro) event can be matched against anyway, given that the key name corresponds to a property of that device id (it's a hack but quite useful).
Ex.
Please login or register to see this code.
(The key 'last' is also allowed and returns the last modification time - works for globals and devices)
So this allows you to handle events, so what? Well always running in the same instance makes stuff like this work
Please login or register to see this code.
'a' is just a local Lua variable keeping its value between, in this case 3, event invocations....
'env.last' is the time in seconds since the event was last invoked.
Recieving events is all good, but being able to post your own events makes things even more interestings, and actually turns it into a programming model...
Please login or register to see this code.
'event' is a Lua key/value table (with at least the mandatory 'type' key). Time is a either an absolute time, number, seconds since 1970 e.g. 'os.time()' or a string;
"10:00" representing 10.00 today
"+10:00" representing 10 hours from now.
"n10:00" representing the next 10.00 o'clock. Called after 10.00, it becomes 10.00 the next day.
"Sunset" represents sunset hour. "Sunset+10" and "Sunset-10" allowed, likewise for "Sunrise"
Specifying delays like this allows for scheduling events to happen in the future, the base for 'loops' and schedulers...
If time is omitted the event is posted immediatly.
Ex. an event that does something every hour.
Please login or register to see this code.
To run the above every hour we just need to start it with
Please login or register to see this code.
The event matched is available in 'env.event' and is just reposted at the current time + 1 hour.
So, in the same "programming model' incoming fibaro events can be mixed with own events and 'loops'.
A lot of nice to have functions can be built using this model. A more general "scheduler" could look like this.
Please login or register to see this code.
Please login or register to see this code.
This will post an event {type='quarter'} every 15min, that can be acted upon by some other event handler...
Please login or register to see this code.
Will reuse the same event declaration for something that reschedules every 30min..
To be able to schedule Lua functions to be invoked, an 'action' handler can be declared.
Please login or register to see this code.
Then we can do
Please login or register to see this code.
The scheduler wil post the 'action' event every 15min, and the 'action' handler will call the function...
There are some more code in the attached example to showcase other variants of schedulers based on this.
The code is setup to be able to run offline and simulate time to see the action (see variables in the beginning of file)
It is of course possible to Event:post your own Fibaro events for simulation and debugging.
It is possible to use FibaroSceneAPI. I do most of my development in ZeroBraneStudio on a Mac.
Still better optimisation, error handling needs to be implemented, but it runs as is...
A setup that is quite convenient for a scene is to have a handler that runs every
midnight and initializes upcoming events for the day, like sunsets/sunrises,
stuff from calendars etc. (More examples in the included code...)
Please login or register to see this code.
Please login or register to see this code.
In the attached code there is a more 'full' example of a 'startup handler.
Will play around with this a bit more and post some more use cases...
ZEvent_030.lua - First version
ZEvent_031.lua - Fixed better time representation
ZEvent_032.lua - Small fixes and a simple emulation of net.HTTPClient to use when running offline
ZEvent_033.lua - More efficient pattern matching with variables, and the beginning of CEP...
Please login or register to see this attachment.
- Fixed bug (lesson, never redefine json.encode). Support for inter-scene eventsPlease login or register to see this attachment.
- Lots of new functions, see later postPlease login or register to see this attachment.
- Bug fix, copy&paste miss in 035Please login or register to see this attachment.
- Better performance, better error handling, less bugs... and the unavoidable intro of a script representation... :-/Please login or register to see this attachment.
- Refactored code. Separate Event_utils file with function to run/emulate offline. Bug fixes. Event:ping/pongPlease login or register to see this attachment.
- Utilities for running offline Edited by jgabLink to comment
Share on other sites
18 answers to this question
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.