Update: Version 0.9.6. Fixed a bug.
Update: Version 0.9.5 makes it almost trivial to make script schedules from code. Not only can you easily trigger time scripts per minute but now also all kinds of intervals, specific times, days of the week, sunset/rise etc. Check it out! http://www.domoticz.com/forum/viewtopic ... =20#p76871.
Update: The whole thing is simplified in v0.9.2, see post below. The idea is still the same but I made it much simpler. No need for special bindings file. Simply put your scripts in a subfolder and make it a Lua module (very easy)...
Old post:
======================================
Well, two actually.... bare with me
A lot of people complained a bit in the past about how long it takes for Domoticz to run all the event scripts each update cycle. I think this is mainly because it runs every script out there even when it is not needed (hence the notorious devicechanged checks everywhere) and that it fetches all device states in between over and over again. Some people suggested to create just one script and put all you logic in there.
So, I decided to make something just like and move it a step further and make it simple and generic so everybody can use it. I must say it works like a charm and fast (for me course). So here it goes:
There is only one script for timer events (runs every minute) and one script for device change events. These two scripts both read a file called event_bindings.lua. This file defines which scripts should be run every minute and which scripts should be run on specific device changes. The main scripts read the bindings and dispatch script execution to these event scripts but only if there is a need to. So, if there is binding for mySwitch, it only runs the script when mySwitch has actually changed! So no longer you need to check in every script if you device actually did change. Yay!
There are a couple of 'niceties':
- Each script that you bind to an event (device or timer) is a Lua module with a main function. See the example script. The main function receives the value of the changed device (just a convenience). Every script has access to all global tables created by Domoticz like devicechanged etc.
- Each script returns his part of the commandArray and an optional boolean value that can stop any further processing of scripts when set to false.
- Event bindings can use device ids instead of the device name since the name may change, the id stays the same. You need one of the newer versions of Domoticz for this because it uses the otherdevices_idx table. See the explanation in event_bindings.lua.
- In the logs you can see exactly what script runs and what the final list of commands is that is sent back to Domoticz
- Each cycle can define one or more preprocess and postprocess scripts. So, at the beginning of each cycle (e.g. device change) you can run a script that may do some checking. Perhaps make a switch 'Run scripts' that is checked and when active, the script returns false and execution of all scripts stop. Same for postprocess. It's optional but might be handy.
- You can bind multiple scripts to one event and use the same script for different events.
So, how does it work or better how can you use it?
- The zip contains 5 files: copy them over to the Lua script folder inside your Domoticz folder: e.g. /home/pi/domoticz/scripts/lua.
- The idea is that the two main scripts script_device_main.lua and script_time_main.lua, are the only scripts that are started by Domoticz event system. So you should rename all your other scripts to something with _demo in the name so that Domoticz ignores them. Or move them out of the way. Of course you can do this at a later stage. This system doesn't conflict with what you already have in place!
- Edit event_bindings.lua. This file is the glue between the event system and your event scripts. You have a section for timer events and for device events. The file contains lots of information and instructions but basically it is a list of timer scripts and device+script combinations. It looks like this:
Note that you do not have to add .lua to the script names.
Code: Select all
return { device = { preprocess = {'myPreprocessScript1', 'myPrepocessScript2'}, postprocess = {'doSomeStuffAtTheEnd'}, devices = { ['Kitchen light'] = {'handle_kitchen_lights', 'notify_me'}, ['125'] = {'calculate_energy_usage', 'notify_me'} } }, timer = { preprocess = {}, postprocess = {}, scripts = { 'control_bathroom_humidity', 'check_windows', 'another script' } } }
I have considered using XML or something like that but this is pure Lua and is always faster. All sections in this bindings file are optional. - Change your existing scripts into 'requireable' lua modules. This is very simple and you can use example_module.lua as the base. Basically you rename your script into something like 'handle_button_blabla.lua' and put some code around your existing code:
Code: Select all
return { main = function(value) local commandArray = {} -- your code here return commandArray, true -- return false if you want to stop further script processing end }
Maybe you can remove your devicechanged checks that you may have in your existing scripts because they are likely not needed anymore since script_device_main.lua does that for you.
Danny
Small update: I didn't include a script for variable changes and security changes. script_variable_xxx doesn't actually work on all user variable updates (only GUI changes) so I assume people don't use this feature anyway (but I could be wrong). And I think that people don't have many security scripts that have to be processed in sequence. But if that is required then I can add that quite easily.