Skip to content

Script examples

Jan Gabrielsson edited this page Aug 17, 2018 · 34 revisions

Examples

Running actions on specific times

local rule, define = Rule.eval, Util.defvar
define('lamp', 55)

rule("@10:00 => lamp:off") -- turn off lamp every day at 10
rule("@10:00 & lamp:isOn => lamp:off") -- turn off lamp every day at 10 if it is on
rule("@10:00 & wday('mon-fri') => lamp:off") -- turn off lamp weekdays at 10
rule("@10:00 & @15:00 => lamp:off") -- turn off lamp every day at 10 and 15
rule("@10:00 & $Presence=='away' => lamp:off") -- turn off lamp every day at 10 if fibaro global 'Presence' is set to 'away'
rule("@sunrise+00:15 => lamp:off") -- turn off lamp 15 min after sunrise every day
rule("@sunset-00:15 & wday('sat-sun') => lamp:on") -- turn on lamp 15 before sunset every weekend
rule("@12:00+rnd(-02:00,02:00) => lamp:on") -- turn on lamp randomly between 10:00 and 14:00 every day

rule("@@00:05 => log('Hello!')") -- logs Hello! every 5min
-- call waterFlowers function every 4th hour at weekends if Presence=='away'
rule("@@04:00 & wday('sat-sun') & $Presence=='away' => waterFlowers()") 

Running actions on triggers

local rule, define = Rule.eval, Util.defvar
define('lamp', 55)
define('lamp2', 57)
define('sensor', 56)

rule("sensor:isOn => lamp:on") -- turn on lamp when sensor breached
rule("sensor:isOn & 23:00..04:00 => lamp:on") -- turn on lamp when sensor breached between 23:00 and 04:00
rule("$Presence=='home' => lamp:on") -- turn on lamp when global 'Presence' is set to 'home'
rule("$Presence=='home' & sunset..23:00 => lamp:on") -- turn on lamp when global 'Presence' is set to 'home' between sunset and 23:00
rule("lamp:value => lamp2:value=lamp:value") -- set lamp2's value to whatever lamp is changed to.
rule("sensor:isOn & 20:00..00:00 => lamp:value=99") -- turn on lamp max when sensor breached
rule("sensor:isOn & 00:00..04:00 => lamp:value=30") -- turn on lamp dimmed when sensor breached

Action when conditions have been true for a period of time

local rule, define = Rule.eval, Util.defvar
define('lamp', 55)
define('door', 57)
define('sensor', 56)
define('floorSensor', {56,88,89})
define('floorSpots', {77,78,79})
define('phone', 201)

-- Send message to phone when door been open for 10min
rule("for(00:10,door:breached) => phone:msg='Door has been open 10min'")
-- Send message to phone when door been open for 10min, and repeat sending message very 10min until door closes
rule("for(00:10,door:breached) => phone:msg='Door has been open 10min'; repeat()")
-- Send message to phone when door been open for 10min, and repeat every 10min, for 5 times
rule("for(00:10,door:breached) => phone:msg='Door has been open 10min'; repeat(5)")

-- Turn off lamp when sensor been safe for 5min and lamp is on
rule("for(00:05,sensor:safe & lamp:isOn) => lamp:off")
-- Turn off lamp between 20:00 and 04:00 when sensor been safe for 5min and lamp is on
rule("for(00:05,sensor:safe & lamp:isOn) & 20:00..04:00 => lamp:off")
-- Turn off spots between 00:00 and 04:00 when all sensors are safe for 5min and some spots are on
rule("for(00:05,floorSensors:safe & floorSpots:isOn) & 00:00..04:00 => floorSpots:off")

Including Lua functions in scripts

local rule, define = Rule.eval, Util.defvar
define('phone',201)
define('test',function test(a,b) return a+b end)
rule("2+test(4,5)*2")
=> 20
define('api',api) -- include api.get,api.put,...
rule("@07:00 => phone:msg=log('Weather today is %s',api.get('/weather').WeatherCondition)") -- Send weather condition every morning to phone

Warning if door is open

This example checks if a door is open for 10min and then sends push messages every 10min for five times

Rule.eval("for(00:10,not(hall.door:safe)) => user.jan.phone:msg=log('Door open %s min',repeat(5)*10)")

-- Test open door warning logic
Rule.eval("wait(t/09:30); hall.door:value=1") -- open door
Rule.eval("wait(t/10:00); hall.door:value=0") -- close door

'for' takes a <time> that the second argument (condition) should be true. In this case not(hall.door:safe).
The first time that the rule triggers (because hall.door changes state), then if the conditions is true, for returns false but starts a timer that when expired runs the rule again. If true then for returns true and the action is run. The repeat function resets the timer for for so it will run again. In this case after 10min. repeat takes an argument for how many times it should repeat. Every time the timer expires, a counter is incremented and compared to the argument to repeat. repeat also returns the current counter value.


Auto-off spotlights

Turns offs spotlights if no sensor has been breached for 10 min

Rule.eval("downstairs_move={kitchen.sensor,hall.sensor,room.sensor}") -- sensors
Rule.eval("downstairs_spots={room.light,kitchen.light,hall.light}") -- spots
Rule.eval([[for(00:10,downstairs_move:safe & downstairs_spots:isOn) => 
    downstairs_spots:off; log('Turning off spots after 10min of inactivity downstairs')]])

-- Test auto-off spots logic
Rule.eval("downstairs_move:value=0") -- all sensor safe
Rule.eval("downstairs_spots:value=0") -- all spots off
Rule.eval("wait(t/11:00); hall.sensor:on") -- sensor triggered
Rule.eval("wait(t/11:00:45); hall.light:on") -- light turned on
Rule.eval("wait(t/11:05:10); hall.sensor:off") -- sensor safe, lights should turn off in 10min

Light auto-off in bathroom

The example below uses two sensor, one motion sensor and one door sensor. The rules turn on/off the light depending on the sensors. We use the door sensor to set a variable inBathroomto true when the door is closed and someone moves in the bathroom. In this way the light don't accidentally turn off if someone is still for a long time inside the bathroom... We also set the variable to true if someone close the door just after (< 3 secs) the movement sensor is breached. Typical case is to enter the bathroom (sensor breached) and then shortly after close the door...

Rule.eval("for(00:10,bathroom.sensor:safe &bathroom.door:value) => not(inBathroom)&bathroom.lamp:off")
Rule.eval("bathroom.sensor:breached => bathroom.door:safe & inBathroom=true ; bathroom.lamp:on")
Rule.eval("bathroom.door:breached => inBathroom=false")
Rule.eval("bathroom.door:safe & bathroom.sensor:breached & bathroom.sensor:last<=3 => inBathroom=true")

-- Test bathroom rules
Rule.eval("wait(t/15:30); bathroom.door:value=1") -- open door
Rule.eval("wait(t/15:31); bathroom.sensor:value=1") -- breach sensor
Rule.eval("wait(t/15:34); bathroom.door:value=0") -- close door
Rule.eval("wait(t/15:51); bathroom.sensor:value=0") -- sensor safe (20s)
Rule.eval("wait(t/16:01); bathroom.door:value=1") -- open door after 10min
Rule.eval("wait(t/16:05); bathroom.door:value=0") -- close door

First rule says that the movement sensor should be safe for 10min, and then if the inBathroom is false, turn off the lamp. We also include td.door:value in the for test, which makes that rule trigger when the door changes state.

Second rule turns on the light if the sensor is breached. It also sets inBathroom to true if the door is closed.

Third rule sets inBathroom to false if door is opened. We don't know if someone leaves.

Fourth rule sets inBathroom to true if door is closed within 3 seconds from sensor being breached.


Simple presence simulation

  local rule = Rule.eval
  rule("sensors={99,98,97}; door=88; home=true")
  rule("lamps={22,33,44,55}")
   
  rule("sensors:breached => || door:safe >> home=true; post(#home)")
  rule("door:breached => home=false; post(#home)")
  rule("for(00:30,sensors:safe & door:safe) => || home==false >> home=true; post(#away)")

  rule("#home => sim=false; log('Stopping presence simulation')")
  rule("#away => || !sim >> sim=true; post(#sim); log('Starting presence simulation')")

  rule("#sim => || sim >> lamp=lamps[rnd(1,4)]; lamp:toggle; post(#sim,ostime()+rnd(00:05,00:30))")
  
  -- Test Presence logic
  rule("wait(t/13:00); door:on") -- Door open
  rule("wait(t/13:01); door:off") -- Door close, simulation starts in 30min
  rule("wait(t/18:00); door:on")  -- Home again, simulation stopped
  rule("wait(t/18:00:30); 99:on") -- Sensor breached
  rule("wait(t/18:00:10); door:off") -- Door closed
  rule("wait(t/18:01); 99:off") -- Sensor safe

Turning off lights at Earth hour

Rule that schedules events 4 years into the future to turn off light at EarthHour...

    Rule.eval("lights={td.lamp_roof,lr.lamp_roof_sofa}",true)
    Rule.eval("earthDates={2019/3/30/20:30,2020/3/28/20:30,2021/3/27/20:30,2022/2/26/20:30}",true)
    Rule.eval("dolist(v,earthDates,post(#earthHour,v))",true)
    Rule.eval([[#earthHour{} =>
              states={};
              dolist(v,lights,add(states,{id=v,value=v:value}));
              off(lights);
              post(#earthHourOff,+/01:00)]])
    Rule.eval("#earthHourOff => dolist(v,states, v.id:value=v.value)")