Event script examples

From Domoticz
Jump to navigation Jump to search

Send a warning when the garage door has been open for more than 10 minutes

Using time difference in seconds between time that script runs (t1) and the time the door status was last seen. 600 seconds for 10 minutes, one notification is enough so make sure to put in an end value as well (<700) otherwise a notification will be sent every minute when the script is evaluated.

-- script_time_garagedoor.lua
t1 = os.time()
s = otherdevices_lastupdate['Garagedeur']
-- returns a date time like 2013-07-11 17:23:12

year = string.sub(s, 1, 4)
month = string.sub(s, 6, 7)
day = string.sub(s, 9, 10)
hour = string.sub(s, 12, 13)
minutes = string.sub(s, 15, 16)
seconds = string.sub(s, 18, 19)

commandArray = {}

t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
difference = (os.difftime (t1, t2))
if (otherdevices['Garagedeur'] == 'Open' and difference > 600 and difference < 700) then
   commandArray['SendNotification']='Garage door alert#The garage door has been open for more than 10 minutes!'
end 
 
return commandArray

Simple security

Using a kaku/coco keyfob named "Surveillance mode". Note that it goes to "Group On" when on! My motion sensors are X10, check the motion status on your pirs using: for i, v in pairs(devicechanged) do print(i, v) end

commandArray = {}
 if ((otherdevices['Surveillance mode'] == 'Group On') and (devicechanged['PIR 1'] == 'Motion' or devicechanged['PIR 1'] == 'Motion')) then
    commandArray['SendNotification']='Alert#Motion detected while in surveillance mode!'
 end
return commandArray

Have Domoticz execute Operating System commands

Lua supports execution of operating system executables and scripts, actual executing syntax will depend on your operating system.

This simple script sends a "wake on lan" event to a predefined host using the command "etherwake" on linux. the argument to etherwake is the mac address of the computer to be woken. the purpose of: commandArray['wakeup-server'] = 'Off' is to make sure that the wake on lan event only gets triggered once, since the script lacks any state checking capability

commandArray = {}
  if (otherdevices['wakeup-server'] == 'On') then
    os.execute('/usr/sbin/etherwake 00:1e:d0:31:e0:21')
    commandArray['wakeup-server'] = 'Off'
    print('wol event sent')
  end
return commandArray

Presence detection using two motion sensors

This is a script is used to determine if anyone is still upstairs, it is a time based script that runs every minute and it uses two motion detectors to determine if there is any movement upstairs, and which direction (up or down) the last person was heading, if there is no motion upstairs, and the last person was heading downstairs it turns off all lights in the group "scene:lights_upstairs" when 30 minutes have passed.

One motion sensor is located on the top floor, and the other one in the staircase and the timedifference between their lastupdated timestamps determines direction.

there is also a manual switch downstairs that turns on the ceiling light on the top floor, and to allow time for someone to make it up the stairs I never turn off the lights if the ceiling light was switched on within the last two minutes (120s), if you turn on the ceiling light upstairs, but never go up, it will automatically turn off the next time the script runs after two minutes.

 function timedifference (s)
   year = string.sub(s, 1, 4)
   month = string.sub(s, 6, 7)
   day = string.sub(s, 9, 10)
   hour = string.sub(s, 12, 13)
   minutes = string.sub(s, 15, 16)
   seconds = string.sub(s, 18, 19)
   t1 = os.time()
   t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
   difference = os.difftime (t1, t2)
   return difference
 end
 commandArray = {}
 print('evaluating if someone is upstairs')
 if (otherdevices['topfloor_motion'] == 'Off') and (timedifference(otherdevices_lastupdate['topfloor_ceiling_lamp']) > 120) then
   if (timedifference(otherdevices_lastupdate['topfloor_motion']) > 1800) then
      if timedifference(otherdevices_lastupdate['top_stairs_motion']) <    timedifference(otherdevices_lastupdate['topfloor_motion']) then
         commandArray['Scene:topfloor_lights']='Off'
         print('turning off, no movement upstairs for more than 30m')
      end
   end
 end

Using Ping command to check the status of a network device

This Lua time script will run every minute (if named script_time_ping.lua) and checks the status of a device by sending one IP ping command to its IP address. The result is reported to Domoticz through a (dummy) switch called Ping in the example.

commandArray = {}

 ping_success=os.execute('ping -c1 192.168.1.156')
 if ping_success then
   print("ping success")
   commandArray['Ping']='On'
 else
   print("ping fail")
   commandArray['Ping']='Off'	
 end

return commandArray

When running Domoticz on a windows platform use:

 ping_success=os.execute('ping 192.168.1.156 -n 1 -w 100>nul')

Should the device not respond to the first ping -c1 could be changed to -c3 to have it send three pings. However this will "hold up" the script for 3 seconds. Should the test be performed more often then once a minute a shell script can be used which can be found here. Source

Using Ping & Bluetooth to check the status of a network device

This Lua script checks the presence of a device by using the ping command. If you want it can also check by Bluetooth. You don't need to pair your device. It neither has to be detectable. The script runs every minute if you name the script "script_time_name.lua" and put it in domoticz/scripts/lua.

Setup:

1. For every device create a dummy switch in Domoticz

2. For every device create a user variable in Domoticz (set value to 1)

3. Use your own settings in this code:

ping[1]={'192.168.1.1', 'Device 1', 'Teller 1', 'nil', 5}

192.168.1.1 = ip-address

Device 1 = Name of dummy switch

Teller 1 = Name of User Variable

nil = if you just want to use the ping command. Fill in the MAC-address (Bluetooth!) if you also want to use Bluetooth detection

5 = the delay in minutes (in this case if the device doesn't response 5 times in a row the switch is turned off)

This code has 3 devices but you can expand with as many as you want. Just add more lines.

-- Title: script_time_ping.lua
-- Date:  14-07-2015

commandArray={}

debug=false

prefixe="(PING) "

local ping={}
local ping_success
local bt_success

ping[1]={'192.168.1.1', 'Device 1', 'Teller 1', 'nil', 5}                 -- android
ping[2]={'192.168.1.2', 'Device 2', 'Teller 2', 'aa:bb:cc:dd:ee:ff', 5}   -- iphone
ping[3]={'192.168.1.3', 'Device 3', 'Teller 3', 'nil', 5}                 -- android

for ip = 1, #ping do
  if ping[ip][4] == 'nil' then
    bt_success=false
    ping_success=os.execute('ping -c 1 -w 1 '..ping[ip][1])
  else
    f = assert (io.popen ("hcitool names "..ping[ip][4]))
    bt = f:read()
    if bt==nil then
      bt_success=false
    else
      bt_success=true
    end
    f:close()
  end
  if ping_success or bt_success then
    if (debug==true) then
      print(prefixe.."ping success "..ping[ip][2])
    end
    if (otherdevices[ping[ip][2]]=='Off') then
      commandArray[ping[ip][2]]='On'
    end
    if (uservariables[ping[ip][3]]) ~= 1 then
      commandArray['Variable:'..ping[ip][3]]= tostring(1)
    end
  else
    if (debug==true) then
      print(prefixe.."ping fail "..ping[ip][2])
    end
    if (otherdevices[ping[ip][2]]=='On') then
      if (uservariables[ping[ip][3]])==ping[ip][5] then
        commandArray[ping[ip][2]]='Off'
      else
        commandArray['Variable:'..ping[ip][3]]= tostring((uservariables[ping[ip][3]]) + 1)
      end
    end
  end
end

return commandArray

--RasPi2 21:49, 28 June 2015 (CEST)

Motion detector 30 minute time-out (presence detection)

I created a script that looks at the status of a motion sensor (Z-Wave) to detect presence. The motion sensor itself will switch back to 'Off' when no motion is detected anymore after 4 minutes. This is a bit short, i would like to extend it to a longer period. With the script, Domoticz looks if the motion sensor stays in the 'Off' status for more than 30 minutes.
If this is the case, it will turn the 'SomeoneHome' switch to off. When there is motion within the 30 minute period (configurable), the timer is reset and nothing will happen (lights will stay on).

-- script_time_nomotion.lua

local motion_switch = 'Motion'
local nomotion_uservar = 'nomotionCounter'
local status_switch = 'SomeoneHome'

commandArray = {}

no_motion_minutes = tonumber(uservariables[nomotion_uservar])

if (otherdevices[motion_switch] == 'Off') then
	no_motion_minutes = no_motion_minutes + 1
	--print('<font color="red">No motion has been detected for: ' ..no_motion_minutes.. ' minutes</font>')
else 
	no_motion_minutes = 0	
end 

commandArray['Variable:' .. nomotion_uservar] = tostring(no_motion_minutes)

if otherdevices[status_switch] == 'On' and no_motion_minutes > 30 then --change the 30 to the amount of minutes you prefer
 	commandArray[status_switch]='Off'
end

return commandArray

The script above needs a uservariable called 'nomotionCounter', type 'Integer' and value '0' (zero).
The script is only for turning off the 'SomeoneHome' switch (which i base other events on). For turning that switch on (and letting Domoticz know that someone got home), use the script below:

-- script_device_motion.lua
local motion_switch = 'Motion'
local status_switch = 'SomeoneHome'

commandArray = {}

if devicechanged[motion_switch] then
	if otherdevices[motion_switch] == 'On' and otherdevices[status_switch] == 'Off' then
 	commandArray[status_switch]='On'
 	end
end
return commandArray

--ThinkPad (talk) 19:33, 23 October 2015 (CEST)

Advanced motion detection with multiple detectors, switches and configurable timeouts

To create a more advanced motion detection system this script allows you to combine multiple detectors with multiple switches. Example use-cases are turning on the lights in specific parts of the hallway depending on motion detectors and door magnet sensors.

First, create a user variable per group you wish to control simultaneously.

1. Go to: setup -> more options -> user variables

2. Variable name: the name of the group, I would recommend letters, numbers and underscores only

3. Variable type: integer

4. Variable value: 0

Second, create a timer script to increment the no-activity counter (the variables above) every minute

1. Go to: setup -> more options -> events

2. Fill in any name you wish

3. Instead of "Blockly" select "Lua"

4. Instead of "All" set "Time"

5. Paste the following script but modify the variables at the top:

commandArray = {}

local switches = {
    -- The hallway_floor_0 is the variable name chosen earlier
    hallway_level_0={
        -- The detectors below can be anything that turns "On" when there's activity
        detectors={
            'door front',
            'motion staircase level 0'
        },
        switches={
            'light level 0',
            'light level 1'
        },
        timeout=2
    },
    hallway_level_1={
        detectors={
            'motion staircase level 1'
        },
        switches={
            'light level 1'
        }
    }
}

for variable,devices in pairs(switches) do
    -- Increase the no motion counter
    local no_motion_minutes = tonumber(uservariables[variable]) + 1
    local timeout = tonumber(devices['timeout'] or 5)
    
    -- Store the no motion counter in the variable again
    commandArray['Variable:' .. variable] = tostring(no_motion_minutes)
    
    -- If we have reached the timeout, disable the linked switches
    if(timeout <= no_motion_minutes) then
        for i, switch in ipairs(devices['switches']) do
            if(otherdevices[switch] ~= 'Off') then
                commandArray[switch] = 'Off'
            end
        end
    end
end

return commandArray


Third, create a device script to turn the lights on and reset the counters when needed

1. Go to: setup -> more options -> events

2. Fill in any name you wish

3. Instead of "Blockly" select "Lua"

4. Instead of "All" set "Device"

5. Paste the following script but modify the variables at the top:

commandArray = {}

local switches = {
    -- The hallway_floor_0 is the variable name chosen earlier
    hallway_level_0={
        -- The detectors below can be anything that turns "On" when there's activity
        detectors={
            'door front',
            'motion staircase level 0'
        },
        switches={
            'light level 0',
            'light level 1'
        },
        timeout=2
    },
    hallway_level_1={
        detectors={
            'motion staircase level 1'
        },
        switches={
            'light level 1'
        }
    }
}

-- Loop through all the changed devices sent by the trigger
for deviceName,deviceValue in pairs(devicechanged) do
    
    for variable,devices in pairs(switches) do
        local status = 0
    
        for i, detector in ipairs(devices['detectors']) do
            -- Check if it is one of the detectors and is set to "On"
            if detector == deviceName and deviceValue == 'On' then
                status = 1
                break
            end
        end

        -- If one of the sensors was turned on, enable the light and reset the no motion variable
        if status == 1 then
            commandArray['Variable:' .. variable] = tostring(0)
            for i, switch in ipairs(devices['switches']) do
                if(otherdevices[switch] == 'Off') then
                    commandArray[switch] = 'On'
                end
            end
        end
    end
end
        
return commandArray

--User:Wolph 2016-07-04 16:23:56 (CEST)

Where to Find More Examples

Many other examples of the use of Lua can be found by searching for Lua on the discussion forum and other pages on the wiki for specific situations (i.e. Setup MQTT support, Interacting with Google Calendar, Smart Lua Scripts)