Events

From Domoticz
Jump to navigation Jump to search

The Event System handles scripts/actions that are activated on triggers like device changes, security events, time, user variables etc

Domoticz will execute all time, variable and device triggers when the relevant trigger occurs, e.g. the device scripts are run when a device changes, the variable scripts are run when a variable changes, the time scripts will run every minute. Also scripts don't run in background. Domoticz will wait for the script to complete so don't use sleep() statements and get the script done as fast as possible. Also be aware of time consuming (external) actions like getting solar panel data from an internet portal that can block the throughput of other events in Domoticz.

The event system will have two options to create events:

Using script creation & editing functionality within Domoticz itself

You can find the interface here: Setup -> More options -> Events.

The Events page has 2 sections:

  1. My automation scripts. A list of all your scripts (enabled or disabled) stored in the database.
  2. Editor Here you can create and edit your scripts.It has minimal 2 tabs, when adding a script it will be added to the tabs
    1. Device current state list Here all your devices are listed with the current value so you do not have to switch to the device list in Setup-Devices. There is a Refresh button to update the statuses.
    2. Add script (+ sign). The Editor/Event Engine that will be used for the script. Drop down values:
      • Blockly
      • Python
      • Lua With drop down list for event type
      • dzVents With drop down list for event type
      • Event Type. Controls what events events will cause Domoticz to execute the script. Drop down values:
        1. All - Will run whenever anything happens that triggers the event system to run a script
        2. Device - Will run whenever ANY device state/value change
        3. Security - Will run whenever there is a security event
        4. Time - Will run once per minute. Scripts are executed one at a time.
        5. User Variable - Will run when User Variables are updated
        6. dzVents has more event types, see the documentation

Event scripts can be enabled or disabled using the "On/Off" checkbox. Disabled events are marked red in the events list.

Event scripts can be saved with the Save button and be deleted with the Delete button.

Scripts will be stored in the Domoticz database itself so do not need to be backed up separately.


Devices Current states Tab

In this Tab you can see the current state and values of all devices in the Domoticz environment.

With the button Refresh these states and values are refreshed.

The "Blockly" interface

For getting started with Blockly go to its wiki page Blockly.

Domoticz examples can be found in the forum: http://www.domoticz.com/forum/viewtopic.php?f=15&t=31

dzVents Interface

DzVents short for Domoticz Easy Events, brings Lua scripting in Domoticz to a whole new level. Writing scripts for Domoticz has never been so easy. Not only can you define triggers more easily, and have full control over timer-based scripts with extensive scheduling support, dzVents presents you with an easy to use API to all necessary information in Domoticz. No longer do you have to combine all kinds of information given to you by Domoticz in many different data tables. You don’t have to construct complex commandArrays anymore. dzVents encapsulates all the Domoticz peculiarities regarding controlling and querying your devices. And on top of that, script performance has increased a lot if you have many scripts because Domoticz will fetch all device information only once for all your device scripts and timer scripts.

By creating scripts inside Domoticz using the internal Domoticz event editor. To create a new dzVents script:

  1. Go to Setup > More Options > Events.
  2. Press the + button and choose dzVents.
  3. You must then choose a template on event type

They are there just for convenience during writing the script; the actual trigger for the script is determined by what you entered in the on = section. The internal event editor have a help button when writing dzVents scripts, next to Save and Delete. This button opens this wiki in a separate browser tab when clicked. Name your script to your liking but leave out the extension .lua

Check out DzVents: next generation Lua scripting for instructions how to use DzVents including extensive documentation.

Lua Interface

Lua events maintain through the editor work in the way that file based Lua scripts do and use the same 'commandArray' interface. There are samples and help on this Wiki. Currently Python is only an option if Domoticz is built from source with Python enabled.

The Lua editor is context sensitive and will prompt with auto-complete options and show common errors to help with debugging. The editor theme can be changed by pressing the control and comma keys at the same time. Domoticz will save the scheme when events are saved.

To create a new Lua event:

  1. Go to Setup > More Options > Events.
  2. Press the + button and choose Lua.
  3. You must then choose a template on event type

A template script will be shown that shows one way of processing that type of event.

The LUA_commands page has more information on the available commands that can be passed back to Domoticz.

Python Interface

Python events maintain through the editor work in the way that file based Lua scripts do and use the same 'commandArray' interface. This python event system has limited functionality, it can only switch devices On/Off, no other update parameters are available.

Currently Python is only an option if Domoticz is built from source with Python enabled (but enabled as default)

The Python editor is context sensitive and will prompt with auto-complete options and show common errors to help with debugging. The editor theme can be changed by pressing the control and comma keys at the same time. Domoticz will save the scheme when events are saved.

To create a new Python event:

  1. Go to Setup > More Options > Events.
  2. Press the + button and choose Python.
  3. You must then choose a template on event type

A template script will be shown that shows one way of processing that type of event.

The Python Events page has more information on the available commands that can be passed back to Domoticz.

User Variables

You can use User variables to store your custom values to be used in scripts.


Text Editor Default Keyboard Shortcuts

The build in Text Editor (ACE) has some handy short cuts. They are all listed here https://github.com/ajaxorg/ace/wiki/Default-Keyboard-Shortcuts

Some Examples:

Line Operations

Windows/Linux Mac Action
Ctrl-D Command-D Remove line
Alt-Shift-Down Command-Option-Down Copy lines down
Alt-Shift-Up Command-Option-Up Copy lines up
Alt-Down Option-Down Move lines down
Alt-Up Option-Up Move lines up
Alt-Delete Ctrl-K Remove to line end
Alt-Backspace Command-Backspace Remove to linestart
Ctrl-Backspace Option-Backspace, Ctrl-Option-Backspace Remove word left
Ctrl-Delete Option-Delete Remove word right
--- Ctrl-O Split line

Selection

Windows/Linux Mac Action
Ctrl-A Command-A Select all
Shift-Left Shift-Left Select left
Shift-Right Shift-Right Select right
Ctrl-Shift-Left Option-Shift-Left Select word left
Ctrl-Shift-Right Option-Shift-Right Select word right
Shift-Home Shift-Home Select line start
Shift-End Shift-End Select line end
Alt-Shift-Right Command-Shift-Right Select to line end
Alt-Shift-Left Command-Shift-Left Select to line start
Shift-Up Shift-Up Select up
Shift-Down Shift-Down Select down
Shift-PageUp Shift-PageUp Select page up
Shift-PageDown Shift-PageDown Select page down
Ctrl-Shift-Home Command-Shift-Up Select to start
Ctrl-Shift-End Command-Shift-Down Select to end
Ctrl-Shift-D Command-Shift-D Duplicate selection
Ctrl-Shift-P --- Select to matching bracket

Find/Replace

Windows/Linux Mac Action
Ctrl-F Command-F Find
Ctrl-H Command-Option-F Replace
Ctrl-K Command-G Find next
Ctrl-Shift-K Command-Shift-G Find previous


By adding your own scripts to the scripts/lua/ dir in your domoticz installation folder.

Note: The power of Domoticz and Lua can be generalised by writing Smart Lua Scripts, this method of combining a switch naming convention and a Lua script, allows a simple script to be used multiple times and simplifies both the addition and maintenance of further devices.


The lua scripts folder has two demo scripts that can serve as a starting point. The script filename has 3 components each sub-divided by an underscore : script_trigger_name.lua

Trigger can be 'time', 'device', 'variable' or 'security', name can be any string for your reference, script_device_MyOtherDeviceNameOnWhenMyDeviceNameOn.lua for instance.

Domoticz will execute all time, variable and device triggers when the relevant trigger occurs, e.g. the device scripts are run when a device changes, the variable scripts are run when a variable changes, the time scripts will run every minute. Also scripts don't run in background. Domoticz will wait for the script to complete so don't use sleep() statements and get the script done as fast as possible.

Domoticz ignores all scripts named "demo" and scripts without the .lua extension, so copy the examples and change the name.

Make sure that if you are using non-ansi characters you save the file in UTF-8 encoding, without a BOM header


LUA Scripts

The LUA_commands page has more information on the available commands that can be passed back to Domoticz.

Tables

Available in time triggered scripts
timeofday
uservariables
uservariables_lastupdate

globalvariables

otherdevices
otherdevices_idx
otherdevices_lastlevel
otherdevices_lastupdate
otherdevices_svalues

-- Below tables only when such devices exist on your system. (else nil)
otherdevices_barometer
otherdevices_dewpoint
otherdevices_humidity
otherdevices_rain
otherdevices_rain_lasthour
otherdevices_temperature
otherdevices_utility
otherdevices_weather
otherdevices_winddir
otherdevices_windgust
otherdevices_windspeed
otherdevices_zwavealarms

otherdevices_scenesgroups
otherdevices_scenesgroups_idx
Tables available in device triggered scripts

All of the tables available in device triggered scripts

devicechanged
devicechanged_ext
Tables available in variable triggered scripts

All of the tables available in variable triggered scripts

uservariablechanged
Use of Tables

The devicechanged table contains a devicename entry, indicating the new state for the device that triggered the device event:

 devicechanged['devicename']='Status', e.g. devicechanged['MyLamp']='On'

if the device that triggered a device-event measures temperature, humidity or barometric pressure, there will obviously not be a devicechanged['devicename']='Status' value because these values are analogue and not digital (on or off). Instead, the value type is appended (added) to the devicename and can be checked as follows:

 devicechanged['devicename_Temperature'] = value
 devicechanged['devicename_Humidity'] = value
 devicechanged['devicename_Barometer'] = value

The whole string (devicename + type) is case sensitive, value type should start with uppercase. If your thermometer is named "MyThermometer", check its incoming temperature value by stating something like "if devicechanged['MyThermometer_Temperature'] > 20 then". If you're not sure which values are coming in:

 for i, v in pairs(devicechanged) do print(i, v) end

The otherdevices table contains the status for all other devices, e.g.: otherdevices['yourotherdevicename']='On'. When a script is triggered by time, there will be no devicechanged value, so use otherdevices to access device states.

The otherdevices_lastupdate table contains the date + time of last update for all other devices, e.g.:

otherdevices_lastupdate['Door'] = '2013-07-10 18:14:32'

Temperature, humidity and barometer values for other devices can be found in otherdevices_temperature['yourdevice'],otherdevices_humidity['yourdevice'] and otherdevices_barometer['yourdevice'] tables.

The otherdevices_idx table contains the indexes for devices (which can be seen in 'Devices' tab, used in json sequests etc)

otherdevices_idx['Door'] = 42

To modify an otherdevice value, you should use commandArray['UpdateDevice']='idx|nValue|sValue' where idx is the device index, nValue and sValue the values to modify (see json page for details - Domoticz API/JSON URL's)

For using user variables in Lua scripts, there are three tables available: uservariables, uservariables_lastupdate and uservariablechanged. The uservariablechanged table (with only the variable that triggered the event) is only available in your event scripts (script_variable_name.lua), the other two are always available. Reference your variable by name, e.g. if uservariables["MyVar"] = ...

commandArray

Each script has to return a commandArray, which is filled based on succesful execution of your script. Commands in the commandArray will only be executed after the array has been returned back to Domoticz to be executed at the end of the script. This means that is is not possible to have one Lua script do multiple actions on the same device.

Using the 3 or 2 tables (depending on event type), build your own event logic, for instance:

 commandArray = {}
 if (devicechanged['MyDeviceName'] == 'On' and otherdevices['MyOtherDeviceName'] == 'Off') then
     commandArray['MyOtherDeviceName']='On'
 end
 return commandArray

Put device names and states between the square brackets exactly like they appear in Domoticz, the string is case sensitive and spaces need to be included e.g. devicechanged['Blue Light'].

When adding device states to the command array, choose the required command for your device, e.g. 'On', 'Off', 'Group On', etc. For dimmable devices, use command 'Set Level X' where X is a percentage (0-100) integer (do not put a percentage symbol after the value). There are three ways to set a device state. The most basic one is to just specify the new state (e.g. On/Off), which will set the new state immediately when the script logic evaluates to true.

It is also possible to change the state for a device for a fixed period of time; if the device only needs to be turned on for 10 minutes, use 'On FOR 10'.

To add a randomized timer to a device change, for instance to turn on a device somewhere in the next 30 minutes, use 'On RANDOM 30'. FOR and RANDOM are in minutes.

To change the state for a device after a fixed period of time; if the device only needs to be turned on after 10 seconds, use 'On AFTER 10'. AFTER is in seconds and accepts 3 seconds at least. ('On AFTER 2' doesn't work).

You can schedule severals commands. In this example , the testSwitch will go On after 5 seconds , and then goes On again 10 seconds after. (and not 15 seconds after ...)

   commandArray[#commandArray + 1] = {['testSwitch'] ='On AFTER 5' }
   commandArray[#commandArray + 1] = {['testSwitch'] ='On AFTER 15' }


The keywords FOR , RANDOM, AFTER must be written in CAPITAL LETTER.


To switch a scene or group, put prefix 'Scene:' or 'Group:' in front of the scene name. Note that it is not possible to check the state of a scene or group, since that is not its intended use. Check a (significant) single device from the scene/group table before switching scenes. Scenes can only be turned on, groups can be turned on and off. It is also possible to activate or deactivate a group or scene schedule by using 'Active' or 'Inactive'. This for instance enables the activation of presence simulation; when an alarm device is activated, also activate lighting schedules to simulate presence.

Notifications

Using the 'SendNotification' command a message can be sent to email or the notification system, whichever is set in Domoticz preferences.
Use a # to separate subject, message body, priority and sound (pushover only).

Priority values:

-2 Low (Not available on Pushover)
-1 Moderate (Prowl/NMA) Quiet (Pushover)
0 Normal
1 High (Prowl/NMA) bypasses quiet hours (Pushover)
2 Emergency (Prowl/NMA) requires confirmation (Pushover)

The Pushover system also supports different sounds. See [1]

CommandArray Examples

Using 'OpenURL' it is possible to trigger a url/api based on an event. The url will not retrieve/parse any data, use it for one way communication.

By prepending "Variable:" an existing variable can be updated.

Some valid examples:

 commandArray['Switch']='On'
 commandArray['Blinds']='Close'
 commandArray['Scene:Livingroom']='On'         -- remember, Scene cannot be turned Off!
 commandArray['Group:Kitchen']='Inactive'
 commandArray['Keyfob']='Group On'
 commandArray['DimmableDevice']='Set Level 50'
 commandArray['Selector']='Set Level: 50'
 commandArray['SendNotification']='subject#body#0'
 commandArray['SendEmail']='subject#body#[email protected]'
 commandArray['OpenURL']='www.yourdomain.com/api/movecamtopreset.cgi' 
 commandArray['Blinds']='Open RANDOM 30'
 commandArray['Porch Light']='On FOR 2'
 commandArray['Variable:MyVar']='Some value'
 commandArray['Variable:MyVar']='Some value AFTER 3'
 commandArray[textDeviceIdx] = { ['UpdateDevice'] = textDeviceIdx..'|0|'..'some text' }
 commandArray[tempDeviceIdx] = { ['UpdateDevice'] = tempDeviceIdx..'|0|'..temp }
 commandArray[tempHumDevIdx] = { ['UpdateDevice'] = tempHumDevIdx..'|0|'.. temp ..';'.. hum ..';'.. hum_stat }

-- ... (see json page Domoticz API/JSON URL's for exact number of arguments)

In device scripts, *always* do a check on the state of the changed device first. The device scripts are triggered fairly often, especially when you have a lot of thermometers and other measurement devices. If you just set the commandArray without any conditions, the script always just execute those commands at every device change, and those changes will trigger the scripts again and again resulting in a loop.

The same event will not fire unless the previous one completes. If an action is set using "Set FOR x minutes" or "RANDOM within x minutes", the same event will not schedule until the first one completes.


Using time conditions:

 time = os.date("*t")
 commandArray = {}
 if (devicechanged['MyDeviceName'] == 'On' and otherdevices['MyOtherDeviceName'] == 'Off' and time.hour >= 22) then
    commandArray['MyOtherDeviceName']='On'
 end
 return commandArray

For checking day- or nighttime use the timeofday array with boolean variables "Daytime" and "Nighttime":

 if (timeofday['Nighttime']) then
      print('its nighttime')
 end

If you want sunrise or sunset in a numeric value, use timeofday['SunriseInMinutes'] and timeofday['SunsetInMinutes']. So when sunrise is at 7:13, timeofday['SunriseInMinutes'] will be 433.


Note: start each "commandArray" line with a tab to indent it under the "if" statement. You can give multiple commands by specifying multiple command array entries:

 commandArray = {}
 if (devicechanged['MyDeviceName'] == 'On' and otherdevices['MyOtherDeviceName'] == 'Off') then
    commandArray['MyOtherDeviceName1']='On'
    commandArray['MyOtherDeviceName2']='On'
    commandArray['MyOtherDeviceName3']='Off'
    commandArray['Scene:MyScene']='On'
    commandArray['SendNotification']='subject#body#0'
    commandArray['OpenURL']='www.yourdomain.com/api/movecamtopreset.cgi' 
    commandArray['Variable:MyVar']='Some value'
 end
 return commandArray

The Lua print command will output its statements to the domoticz log, so you can use that to check on values or your logic. For instance, if you want to check the other device states that get passed into Lua, add line:

 for i, v in pairs(otherdevices) do print(i, v) end

Make sure to disable it after debugging as it clutters the log.

The commandArray also supports nested tables to send the same command type multiple times. To do this, give the command a numeric index (not alphanumeric with or without quotes!) and place the required action in a nested table:

 commandArray = {}
 commandArray[1]={['OpenURL']='www.cam1.com/api/movecamtopreset.cgi' }
 commandArray[2]={['OpenURL']='www.cam2.com/api/movecamtopreset.cgi' }
 commandArray[3]={['OpenURL']='www.cam3.com/api/movecamtopreset.cgi' }
 return commandArray

This will run three url commands with separate addresses. Always start the commandarray index at 1; Lua uses 1 based indexes, so commandArray[0] will not run.

Some examples (not meaningful, just to explain what will happen):

 commandArray = {}
 commandArray['Lamp']='On'
 commandArray[1]={['Lamp']='On'}
 commandArray[2]={['Lamp']='On'}
 commandArray[3]={['Lamp']='On'}
 commandArray['Lamp']='On'
 return commandArray

This will turn "Lamp" on 4 times (the last array item overwrites the first).

 commandArray = {}
 commandArray['Lamp']='On'
 commandArray[0]={['Lamp']='On'}
 commandArray[1]={['Lamp']='On'}
 commandArray[2]={['Lamp']='On'}
 commandArray['Lamp']='On'
 return commandArray

This will turn "Lamp" on 3 times (the last array item overwrites the first and the zero index is ignored).

Tips : Use this usefull form instead of counting the number of commands

commandArray[#commandArray + 1] = ...
commandArray[#commandArray + 1] = ...

Current state of the event system:

- Not all device states are correctly passed to Lua at the moment, but the most common ones like On/Off, Open/Closed are. - There is no check on the command in the commandArray. When you return commandArray['Kitchen light']="Up", we will not indicate that kitchen lights aren't meant to go up. Make sure you pass a valid command for the device.

Unfortunately, Domoticz doesn't report which device changed state thereby causing a script_device_xx.lua script to run. However the devicechanged table gives the game away. The following can be used to identify which device was the culprit so include it at the beginning of your device scripts:

 logging = true
 d = otherdevices
 device = ""
 for i, v in pairs(devicechanged) do
   if (#device == 0 or #i < #device) then device = i end
 end
 if (logging) then print("Triggered by " .. device .. " now " .. d[device]) end

Subsequently, you can use something like the following to decide what to do next:

 if (device == "PIR_1" or device == "PIR_2" or device == "PIR_3") then
   if (d[device] == "Motion" and not globalvariables["Security"] == "Disarmed" ) then
     whatever
   end
   return commandArray
 end
 
 if (device == "Keyfob" and d[device] == "On") then
   whatever
   return commandArray
 end

... and so on

The power of Domoticz and Lua can be generalised by writing Smart Lua Scripts, this method of combining a switch naming convention and a Lua script, allows a simple script to be used multiple times and simplifies both the addition and maintenance of further devices.

Post any issues here: <http://www.domoticz.com/forum/viewtopic.php?f=6&t=6>

Event Script Examples

Lua Example scripts here: Event script examples

Wiki page with examples: Scripts

Post Lua script examples and discussion here: <http://www.domoticz.com/forum/viewtopic.php?f=4&t=39>

Post your own Blockly examples in forum: <http://www.domoticz.com/forum/viewtopic.php?f=4&t=31>

Post your own DzVents examples in forum: <https://www.domoticz.com/forum/viewforum.php?f=72>