Script examples (Lua)

Moderator: leecollings

thorbj
Posts: 113
Joined: Thursday 20 November 2014 22:11
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Norway
Contact:

Re: Script examples (Lua)

Post by thorbj »

I made these two scripts to turn on the lights in the livingroom based on motion and lumen values in the room, and to turn off the lights if the lumen-values are high.
So far tests are great, so I hope it works for everyone else who wants to try it to.


TURN ON LIGHTS:

Code: Select all

-- ~/domoticz/scripts/lua/script_device_livingroomon.lua
-- When entering room, script reads current light level
-- and turns on the lights in the room based on given options.
-- If it's between 8AM and 8PM it chooses a scenery for day-lights,
-- and otherwise for evening/night-lights. It also measures the
-- lumen-values and decides if it is to bright in the room to
-- turn on the lights.
commandArray = {}

-- SETTINGS --
a = 'Lux sensor' -- name of the lux sensor
b = 'Motion Sensor' -- name of the motion sensor
c = 'Lamp 1' -- name of a lamp that this script should depend on

d = 500 -- maximum lumen value
-- END SETTINGS --

-- Define hours for day and evening lights
h = tonumber((os.date('%H')))
if     (h >= 8 and h < 20)
   then
   x = 'Scene:Livingroom ON day'
   else
   x = 'Scene:Livingroom ON night'
end

-- Get values from Lux sensor
V = otherdevices_svalues[a]

-- Remove charachters from datastring
function stripchars(str, chrs)
   local s = str:gsub("["..chrs.."]", '')
   return s end

-- Remove " Lux" from V
w = stripchars( V, " Lux" )

-- Issue command "x" if lux is below 500 (d) and motion is detected and dimmer is off
if    (tonumber(w) <= d and devicechanged[b] == 'On' and otherdevices[c] == 'Off') then   
   commandArray[x]='On'
   print(x)
end
return commandArray
TURN OFF LIGHTS:

Code: Select all

-- ~/domoticz/scripts/lua/script_device_livingroomoff.lua
-- This script reads the current lumen-values from a lux sensor and
-- turns off the lights if the values is above a given number.
commandArray = {}

-- SETTINGS --
a = 'Lux sensor' -- name of the lux sensor
b = 'Lamp 1' -- name of a lamp that this script should depend on
c = 'Lamp 2' -- name of an eventual second lamp that this script should depend on

d = 500 -- maximum lumen value

e = 'Scene:Livingroom OFF' -- name of scenario to be initiated

p = 'Lights in the livingroom has been turned off due to high lumen-values' -- text to be printed in log
-- END SETTINGS --

-- Get values from the Lux sensor
V = otherdevices_svalues[a]

-- Function to strip charachters
function
 stripchars(str, chrs)
 local s = str:gsub("["..chrs.."]", '')
 return s
end

-- Strip " Lux" from V
w = stripchars( V, " Lux" )

-- Turn off lights if dimmer is on and Lux is higher than 500 (d)
if     (tonumber(w) > d and otherdevices[b] == 'On' or tonumber(w) > d and otherdevices[c] == 'On') then   
 commandArray[e]='Off'
 print(p)
end
return commandArray
Cheers!
2xRaspberry Pi Model 2 w/RaZberry z-wave chip (master/slave)|Fibaro Wall Plug|Fibaro Universal Dimmer 500W|Aeon Labs Multisensor|RFXtrx433E|Nexa WMR-1000|Nexa Pe-3|Nexa Remote|Nexa LGDR3500|Lightify Gateway|Lightify RGBW bulb
rom44
Posts: 1
Joined: Thursday 12 February 2015 23:11
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Script examples (Lua)

Post by rom44 »

I would like to share you my script for heating regulation.The principle is to set ON a switch (relay of electric radiator or pilot wire) for X minutes every 10 minutes.
The time X minutes is calculated according PI regulation.
I haven't tested it with my electric radiators but it should work. Of course you have to adapt the PI_K and PI_I coefficients according your house and heating system.

I'm opened for your suggestions ! ;)

To make it work, you need :
5 decimal user variables named : "Previous_setpoint", "PI_K", "PI_I", "Integral_limit" and "Integral"
2 switches named : "Chauffage" (to start/stop the heating system and the regulation) and "Fil pilote" (it's the output of the regulation)
1 set-point named : "Consigne" (you can change the value with the planning function or manually)
And of course the script enclosed, named script_time_chauffage.lua:

Code: Select all

-- Script for heating regulation
-- Regulation based on PI regulator
-- The script set ON a switch for 0 to 10 minutes every 10 minutes
-- Useful for electric radiators with or without pilot wire

local Temp_salon=otherdevices_svalues['Salon'] -- Get room temperature
local Setpoint=otherdevices_svalues['Consigne'] -- Get room temperature set-point
local Previous_setpoint=uservariables['Previous_setpoint'] -- Get previous room temperature set-point
local PI_K=uservariables['PI_K'] -- Get K coefficient of PI regulation
local PI_I=uservariables['PI_I'] -- Get I coefficient of PI regulation
local Integral=uservariables['Integral'] -- Get current value of Integral
local Integral_limit=uservariables['Integral_limit'] -- Get limit for Integral
local PI_periode -- Output of regulator, time between 0 and 10 minutes
local Diff_setpoint -- Difference between set-point and room temp

commandArray = {}
-- If Heating switch is ON, active regulation
if otherdevices['Chauffage'] == 'On' then

	print('Salon temperature: '..Temp_salon)
	print('Setpoint: '..Setpoint)
	
	-- Calc temperature error
	Diff_setpoint = Setpoint-Temp_salon
	print('Error: '..Diff_setpoint)
	
	-- Reset Integral if set-point changed, conversion to number to avoid decimal problem with string comparison
	if tonumber(Setpoint) ~= tonumber(Previous_setpoint) then
		Integral=0
		print('Set-point changed, Integral reseted')
	end
	
	-- Update Previous_setpoint
	commandArray['Variable:Previous_setpoint']=Setpoint
	
	-- Update Integral
	Integral = Integral+Diff_setpoint*PI_I
	
	-- Limit Integral to +/- Integral_limit
	if Integral >= Integral_limit then
		Integral = Integral_limit
	elseif Integral <= -Integral_limit then
		Integral = -Integral_limit
	end
	
	-- Set user variable "Integral"
	commandArray['Variable:Integral']=tostring(Integral)
	print('Integral: '..Integral)
	
	-- Calc regulator output, rounded to have full minutes
	PI_periode=math.floor(Diff_setpoint*PI_K+Integral+0.5)
	
	-- Limit output between 0 and 10 minutes
	if PI_periode<0 then
		PI_periode=0
	end
	if PI_periode>10 then
		PI_periode=10
	end

	print('Output: '..PI_periode)
	
	-- Get system time
	time = os.date("*t")

	-- Every 10 minutes
	if((time.min % 10)==0)then
		if PI_periode>=0 then
			-- Set switch "Fil pilote" ON for X minutes
			commandArray['Fil pilote']='On FOR '..PI_periode
			print('Fil pilote ON for '..PI_periode..' minutes')
		else
			print('Fil pilote OFF')
		end
	else
		print('Waiting timer')
	end
	
-- If Heating switch is OFF, do nothing
else
	print('Chauffage OFF')
	commandArray['Variable:Integral']=0
end

return commandArray
User avatar
nayr
Posts: 354
Joined: Tuesday 11 November 2014 18:42
Target OS: Linux
Domoticz version: github
Location: Denver, CO - USA
Contact:

Re: Script examples (Lua)

Post by nayr »

I live in a high altitude desert, we get nice mild spring days in high 60's and up.. but it still gets really cold at night (under 40F). We have a habit of opening the backdoor for fresh air during the day, turning down the heater and then spacing it out and leaving the heater off, not realizing it until we wake up the next morning and the house is freezing. Since I use an evap cooler for cooling and it dont care if the backdoor is open this script only changes the heater setpoint.

This simple script turns the thermostat down to 60F after the backdoor has been left open for more than 5mins, turns it back up to 70F after its been closed for 10mins. If thermostat programing tries to change the temp and the door is still open it will over-ride the change.
You'll need to change the bold in these lines to match the ID of your heating setpoint: commandArray['UpdateDevice']='24|0|60'

Code: Select all

-- Automatically adjust heating setpoint to 60F when back door is left open.

t1 = os.time()
s = otherdevices_lastupdate['Back Door']
heater = otherdevices_svalues['Heater Setpoint']

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['Back Door'] == 'Open' and difference > 299 and difference < 360) then
        commandArray['SendNotification']='Perimeter Warning#The back door has been open for more than 5 mins..'
        commandArray['UpdateDevice']='24|0|60'
        print("Back door left open, adjusting heater setpoint to 60F")
elseif (otherdevices['Back Door'] == 'Open' and difference > 361 and heater ~= '15.56') then
        commandArray['UpdateDevice']='24|0|60'
        print("Back door left open, adjusting heater setpoint to 60F")
elseif (otherdevices['Back Door'] == 'Closed' and difference > 599 and difference < 660 and heater == '15.56') then
        commandArray['UpdateDevice']='24|0|70'
        print("Back door finally closed, adjusting heater setpoint to 70F")
end

return commandArray
Debian Jessie: CuBox-i4 (Primary) w/Static Routed IP and x509 / BeagleBone with OpenSprinkler / BeagleBone Planted Aquarium / 3x Raspbery Pi2b GPIO Slaves
Elemental Theme - node-domoticz-mqtt - Home Theatre Controller - AndroidTV Simple OSD Remote - x509 TLS Auth
roblom
Posts: 402
Joined: Wednesday 26 February 2014 15:28
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: the Netherlands
Contact:

Re: Script examples (Lua)

Post by roblom »

CopyCatz wrote:Made a time script that determines whether the living room is empty, if there's no movement for an hour switch on dummy device "Huiskamer leeg" (livingroom empty).

Code: Select all

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 = {}

if (otherdevices['Bewegingsmelder voor'] == 'No Motion' and otherdevices['Bewegingsmelder achter'] == 'No Motion' and otherdevices['Bewegingsmelder zithoek'] == 'Off') then
	if (timedifference(otherdevices_lastupdate['Bewegingsmelder voor']) > 3600 and timedifference(otherdevices_lastupdate['Bewegingsmelder achter']) > 3600 and timedifference(otherdevices_lastupdate['Bewegingsmelder zithoek']) > 3600) then
		if (otherdevices['Huiskamer leeg'] == 'Off') then
			commandArray['Huiskamer leeg']='On'
		end
	end	
end

return commandArray
After which I can run other stuff based on the fact that the room is empty.
Am I wrong or is the switch "Huiskamer Leeg" only switched On and never Off?
User avatar
CopyCatz
Developer
Posts: 123
Joined: Thursday 11 July 2013 17:28
Target OS: -
Domoticz version:
Location: Outer Heaven
Contact:

Re: Script examples (Lua)

Post by CopyCatz »

I had a separate script that decided when the room was empty and someone entered, it would send me a notification and then reset the situation (i.e. "huiskamer leeg" = off). That's why you dont see it in this script.
ThinkPad
Posts: 890
Joined: Tuesday 30 September 2014 8:49
Target OS: Linux
Domoticz version: beta
Location: The Netherlands
Contact:

Re: Script examples (Lua)

Post by ThinkPad »

I have put all my Domoticz scripts on Bitbucket: here.
Might be useful for someone :)
I am not active on this forum anymore.
NietGiftig
Posts: 121
Joined: Sunday 11 October 2015 8:50
Target OS: Raspberry Pi / ODroid
Domoticz version: V3.6224
Location: Holland
Contact:

Re: Script examples (Lua)

Post by NietGiftig »

ThinkPad wrote:Might be useful for someone :)
Sure is, thanks
RPI-2 + SSD / ESPEasy Sensors & Switches / Sonoff / RFLink / Action Switches / TP-Link switch / Node-Red / Reacticz
RoyT
Posts: 16
Joined: Wednesday 02 December 2015 19:30
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Contact:

Re: Script examples (Lua)

Post by RoyT »

I just created my very first Lua script for turning on/off my subwoofer. The problem is that the subwoofer consumes 15Watt when in use, and a whopping 10Watt in standby mode. This script checks the power consumption of the receiver (1.5W standby, 120W when in use) and switches the subwoofer on when the receiver consumes > 10W (else turn it off). This is based on values from a Greenwave PowerNode (6 ports; I have multiple hence the naming "1.3" = "PowerNode_1.Socket_3").

Code: Select all

commandArray = {}

sensor = 'Usage PN 1.3 (receiver)'
subwoofer = 'PN 1.5 (subwoofer)'
values = otherdevices_svalues[sensor]

watt, kwh = values:match("([^;]+);([^;]+)")

if (tonumber(watt) > 10 and otherdevices[subwoofer] == 'Off') then
  commandArray[subwoofer] = 'On'
elseif (tonumber(watt) < 10 and otherdevices[subwoofer] == 'On') then
  commandArray[subwoofer] = 'Off'
end

return commandArray
trollmar
Posts: 16
Joined: Friday 24 April 2015 9:27
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Script examples (Lua)

Post by trollmar »

ThinkPad wrote:I have put all my Domoticz scripts on Bitbucket: here.
Might be useful for someone :)
Thx for sharing.
I try to use your script "script_time_nomotion.lua"

Code: Select all

-- script_time_nomotion.lua
-- This script flips a switch when no motion has been detected for more than 30 minutes 

--Change the values below to reflect to your own setup
local motion_switch 		= 'Motion_Sensor_Wohnzimmer-Küche'
local nomotion_uservar 		= 'nomotionCounter'
local status_switch 		= 'Wohnzimmer_anwesenheit'
local nomotion_timeout		= 30	--Amount of minutes that no motion should be detected to assume nobody is home anymore


commandArray = {}

no_motion_minutes = tonumber(uservariables[nomotion_uservar])
remaining = nomotion_timeout - no_motion_minutes

if (otherdevices[motion_switch] == 'Off') then
	no_motion_minutes = no_motion_minutes + 1
	print('<font color="red">Al ' ..tonumber(no_motion_minutes).. ' minuten geen beweging gedetecteerd, over ' ..tonumber(remaining).. ' minuten gaat het licht uit!</font>')	
else 
	no_motion_minutes = 0
	--print('<font color="red">Beweging gedetecteerd, teller gereset naar ' ..tonumber(no_motion_minutes).. '</font>')
end 

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

--if otherdevices[status_switch] == 'On' and no_motion_minutes > 30 then
if otherdevices[status_switch] == 'On' and no_motion_minutes > tonumber(nomotion_timeout) then
 	commandArray[status_switch]='Off'
	print('<font color="red">Al ' ..tonumber(no_motion_minutes).. ' minuten geen beweging gedetecteerd, niemand meer thuis</font>')	
end

return commandArray
It counts....but instead of minutes it counts every "system second".



Any idear how i can change it to run only once any minute??




Here is a screenshot
Attachments
log.jpg
log.jpg (212 KiB) Viewed 24473 times
ThinkPad
Posts: 890
Joined: Tuesday 30 September 2014 8:49
Target OS: Linux
Domoticz version: beta
Location: The Netherlands
Contact:

Re: Script examples (Lua)

Post by ThinkPad »

You probably have it called script_device.... instead of script_time
I am not active on this forum anymore.
User avatar
Dnpwwo
Posts: 819
Joined: Sunday 23 March 2014 9:00
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Melbourne, Australia
Contact:

Re: Script examples (Lua)

Post by Dnpwwo »

I have something similar to this where I check the status of all devices that have names that end in 'PIR' to determine the last movement detected in the house. I then take actions at various thresholds.

I do use a time based script for this but I don't use a user variable because I run my database on an SD card and minimise updates to prolong its life. Instead I compare the device's last updated time against 'now'.

There is a routine to do that comparison on the wiki that you should be able to use: http://www.domoticz.com/wiki/Event_scri ... 10_minutes.
The reasonable man adapts himself to the world; the unreasonable one persists to adapt the world to himself. Therefore all progress depends on the unreasonable man. George Bernard Shaw
Rydin
Posts: 4
Joined: Friday 05 February 2016 23:21
Target OS: Windows
Domoticz version:
Contact:

Re: Script examples (Lua)

Post by Rydin »

My first attempt on writing a lua script.
This gets the gas prices from petrol stations in Norway called st1 (http://www.st1.no/3dpriser/)
The best virtual device i found was percentage. Not perfect on the dashboard, but works fine on my frontpage on a tablet.
bensindiesel.PNG
bensindiesel.PNG (19.38 KiB) Viewed 24112 times
diesel.PNG
diesel.PNG (2.46 KiB) Viewed 24112 times

Code: Select all

--domoticz/scripts/lua/script_time_st1.lua

--import JSON addin (download from http://regex.info/code/JSON.lua)
json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()

------------- Begin local variables -------------

--These are the avaiable ST1 stations
-- 46146 = St1 Arendal
-- 46124 = St1 Asker
-- 46101 = St1 Askim
-- 46141 = St1 Oslo Biltilsynet
-- 46139 = St1 Oslo Breivollveien
-- 46109 = St1 Drammen Holmensgt
-- 46119 = St1 Drammen Tollbugata
-- 46118 = St1 Fredrikstad
-- 46148 = St1 Kongsberg
-- 46135 = St1 Gjelleråsen
-- 46140 = St1 Gjøvik
-- 46133 = St1 Hamar
-- 46145 = St1 Herøya
-- 46130 = St1 Holmestrand
-- 46121 = St1 Horten
-- 46114 = St1 Hønefoss
-- 46136 = St1 Høvik
-- 46137 = St1 Oslo Jerikoveien
-- 46147 = St1 Jessheim
-- 46128 = St1 Oslo Kirkeveien
-- 46113 = St1 Kløfta
-- 46106 = St1 Larvik  Nansetgata
-- 46138 = St1 Larvik  Tjøllingvn
-- 46105 = St1 Mosseporten
-- 46112 = St1 Varnaveien
-- 46110 = St1 Nittedal
-- 46122 = St1 Notodden
-- 46125 = St1 Oppegård
-- 46116 = St1 Vallermyrvn
-- 46104 = St1 Rakkestad
-- 46143 = St1 Regnbuen
-- 46103 = St1 Rolvsøy
-- 46142 = St1 Rortunet
-- 46131 = St1 Sandefjord
-- 46129 = St1 Skien
-- 46120 = St1 Oslo Sporveisgata
-- 46123 = St1 Tønsberg
-- 46127 = St1 Åshaugveien, Ås
-- 46111 = St1 Vestby

--Change variable to match station
local myStation 	= '46111'

--idx and name of virtual devices for displaying fuel price (ex Percentage). Put false if not in use
local virtualB95 	= 'Bensin'
local idxB95 		= false
local virtualDiesel = 'Diesel'
local idxDiesel 	= 80

------------- End local variables -------------


------------- Begin code -------------
	
commandArray = {}
	
	--get prices.js from ST1--
	local st1=assert(io.popen('curl "http://st1.notch.no/prices.js"'))
	local pricesvar = st1:read('*all')
	st1:close()
	
	--remove var = prices from file
	local prices = string.sub(pricesvar, 15, -3)
	--make a readable table
	local jsonPrices = json:decode(prices)
	
	--get prices from correct station
	for i,v in pairs(jsonPrices['stations']) do		
		if jsonPrices['stations'][i]['stationId'] == myStation then
			priceB95 = jsonPrices['stations'][i]['b95']
			priceDiesel = jsonPrices['stations'][i]['diesel']
			--priceTime = jsonPrices['stations'][i]['time']
		end
	end
	
	--Replace "," with "."
	priceB95 = string.gsub(priceB95, ",", ".", 1)
	priceDiesel = string.gsub(priceDiesel, ",", ".", 1)
	
	--update the virtual devices if the price has changed
	if idxDiesel ~= false then
		if priceDiesel ~= otherdevices_svalues[virtualDiesel] then
			print('Diesel new price: ' ..priceDiesel)
			commandArray[1] = {['UpdateDevice'] = idxDiesel .. '|0|' .. priceDiesel}
		end
	end
	
	if idxB95 ~= false then
		if priceB95 ~= otherdevices_svalues[virtualB95] then
			print('B95 new price: ' ..priceB95)
			commandArray[2] = {['UpdateDevice'] = idxB95 .. '|0|' .. priceB95}
		end
	end
------------- End code -------------

return commandArray
bellison
Posts: 3
Joined: Friday 06 January 2017 23:20
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Script examples (Lua)

Post by bellison »

Hi,

This is my first lua script in 13 years, so there might be things in this script that might be done in an ugly way.

The dimming speed is a exponential curve so it will slowly increase the dimmers in the beginning and quickly in the end (i figure that it is probably the best way to wake up)

I wanted a wake up light. And all i found was some examples that i didn't understand and that required editing the script it self to work. and that was difficult on my smart phone in the evenings.

I have create a script that utilizes a few user variables.

WakeUpLightEnabled* -- a number value if the wake up light is enabled or not 1 = enabled 0 = disabled, this should be a integer value
WakeUpTime* -- the time you want to wake up (when the lights reach maximum level), this should be a time value
WakeUpPeriodLenght* -- for how many minutes the light should be running from start to end, this should be a integer value
WakeUpLightRunning* -- just a variable keeping track of for how many minutes the wakeup light has been running, this should be a integer value
WakeUpLightAppliences* -- a comma separated list of the dimmers you want to turn on eg. dimmer1,dimmer2 , this should be a string value
WakeUpStartDimLevel -- start level in % for the dimming (this is not needed, default value is set to 5), this should be a integer value
WakeUpEndDimLevel -- end level in % for the dimming (this is not needed, default value is set to 100), this should be a integer value
userVars.JPG
userVars.JPG (30.44 KiB) Viewed 21575 times

Code: Select all

commandArray = {}

function main()
    
    iWakeUpLightRunning = tonumber(uservariables['WakeUpLightRunning'])
    tWakeUpTime = Split(uservariables['WakeUpTime'], ":")
    iWakeUpPeriodLenght = tonumber(uservariables['WakeUpPeriodLenght'])
    iWakeUpStartDimLevel = tonumber(uservariables['WakeUpStartDimLevel'])
    --print ("iWakeUpStartDimLevel = " .. iWakeUpStartDimLevel .. " uservariables['WakeUpStartDimLevel'] = " .. uservariables['WakeUpStartDimLevel'])
    iWakeUpEndDimLevel = tonumber(uservariables['WakeUpEndDimLevel'])
    
    --print ("WakeUpPeriodLenght " .. iWakeUpPeriodLenght)
    
    CurrentTime = os.date("%H:%M")
    
    tTime = os.date("*t")
    tTime["min"] = tWakeUpTime[2] - iWakeUpPeriodLenght
    tTime["hour"] = tWakeUpTime[1]
    sStartTime = os.date("%H:%M", os.time(tTime))
    
    ln20 = math.log( iWakeUpEndDimLevel / iWakeUpStartDimLevel)
    k = ln20 / iWakeUpPeriodLenght
    iDimValue = math.ceil ( iWakeUpStartDimLevel * math.exp( (k * iWakeUpLightRunning) ))
    
    --print ( "iDimValue = " .. iDimValue .. " k = " .. k .. " ln20 = " .. ln20 )
    
    if iWakeUpLightRunning == 0 and CurrentTime ~= sStartTime then
    	--do nothing
    	return
    elseif iWakeUpLightRunning == 0 and CurrentTime == sStartTime then
    	iWakeUpLightRunning = 1
    --print("first try")
    elseif iDimValue < 100 then
    	iWakeUpLightRunning = iWakeUpLightRunning + 1
    else
    	if iDimValue > 100 then
    		iDimValue = 100
           --print("setting to 100")
    	end
    	iWakeUpLightRunning = 0
    	bRunLastTime = true
		--rint("resetting to 0")
    end
    
    iDimLevel = 0
    
    commandArray['Variable:WakeUpLightRunning'] = tostring(iWakeUpLightRunning)
    if iWakeUpLightRunning > 0 or bRunLastTime then
        for k,v in pairs(tAppliences) do
            --print("for " .. v .. " Set Level " .. iDimValue.." %")
            iCurrentDimLevel = tonumber(string.match(otherdevices[v], "Set Level: (%d+) %%"))
            --print ("Dim level for " .. v .. " = " .. otherdevices[v] .. " is " .. (iCurrentDimLevel or "") .. " target level " .. iDimValue)
            if (iCurrentDimLevel and iCurrentDimLevel == 100 ) or otherdevices[v] == "On" then
                -- the dimmer is already on or 100%. just leave it alone
            elseif ((iCurrentDimLevel and iCurrentDimLevel == 0) or otherdevices[v] == "Off") and (iWakeUpLightRunning > 1 or (bRunLastTime and iWakeUpPeriodLenght > 1)) then
                -- the dimmer has been turned off after the wakeup light started don't turn on again.
            elseif iCurrentDimLevel and iCurrentDimLevel < iDimValue and iWakeUpEndDimLevel >= iDimValue then
                -- increase the dim-level for the wakeup light dimmers
               -- print ("Dim level for " .. v .. " = " .. otherdevices[v] .. " is " .. (iCurrentDimLevel or "") .. " setting level to " .. iDimValue)
                commandArray[v] = "Set Level " .. iDimValue .. "%"
            elseif iWakeUpEndDimLevel <= iDimValue then
                -- the dimmer has reached the max-value this should be the last run
               -- print ("Reached the iWakeUpEndDimLevel of " .. iWakeUpEndDimLevel .. " for " .. v)
                commandArray[v] = "Set Level " .. iWakeUpEndDimLevel .. "%"
            elseif otherdevices[v] == "Off" then
                -- first run set the inital value
                commandArray[v] = "Set Level " .. iDimValue .."%"
                --iDimLevel = math.ceil ( iDimValue * 16 / 100 )
                --commandArray[v] = "Set Level " .. iDimLevel
                print ( 'fist try, ' .. "commandArray['" .. v .. "'] = " .. commandArray[v] ) 
            end
        end
    end
end

function checkIfAllUserVariablesExists()
   
    if uservariables['WakeUpLightEnabled'] == nil then
        uservariables['WakeUpLightEnabled'] = 0
        commandArray["Variable:WakeUpLightEnabled"] = uservariables['WakeUpLightEnabled']
    end
    if uservariables['WakeUpLightAppliences'] == nil then
        uservariables['WakeUpLightAppliences'] = ""
        commandArray["Variable:WakeUpLightAppliences"] = uservariables['WakeUpLightAppliences']
    end
    if uservariables['WakeUpLightRunning'] == nil then
        uservariables['WakeUpLightRunning'] = 0
        commandArray["Variable:WakeUpLightRunning"] = uservariables['WakeUpLightRunning']
    end
    if uservariables['WakeUpTime'] == nil then
        uservariables['WakeUpTime'] = "07:00"
        commandArray["Variable:WakeUpTime"] = uservariables['WakeUpTime']
    end
    if uservariables['WakeUpPeriodLenght'] == nil then
        uservariables['WakeUpPeriodLenght'] = "15"
        commandArray["Variable:WakeUpPeriodLenght"] = uservariables['WakeUpPeriodLenght']
    end
    if uservariables['WakeUpStartDimLevel'] == nil then
        uservariables['WakeUpStartDimLevel'] = "5"
        commandArray["Variable:WakeUpStartDimLevel"] = uservariables['WakeUpStartDimLevel']
    end
    if uservariables['WakeUpEndDimLevel'] == nil then
        uservariables['WakeUpEndDimLevel'] = "100"
        commandArray["Variable:WakeUpEndDimLevel"] = uservariables['WakeUpEndDimLevel']
    end 
end

function Split(str, delim, maxNb)
    -- Eliminate bad cases...
    if string.find(str, delim) == nil then
        return { str }
    end
    if maxNb == nil or maxNb < 1 then
        maxNb = 0    -- No limit
    end
    local result = {}
    local pat = "(.-)" .. delim .. "()"
    local nb = 0
    local lastPos
    for part, pos in string.gmatch(str, pat) do
        nb = nb + 1
        result[nb] = part
        lastPos = pos
        if nb == maxNb then break end
    end
    -- Handle the last field
    if nb ~= maxNb then
        result[nb + 1] = string.sub(str, lastPos)
    end
    return result
end

checkIfAllUserVariablesExists()

tAppliences = Split(uservariables['WakeUpLightAppliences'], ",")
if tAppliences == nil or uservariables['WakeUpLightEnabled'] == nil or uservariables['WakeUpLightEnabled'] == 0 then 
    -- no list with dimmers that should wake up, end it here
    if uservariables['WakeUpLightEnabled'] ~= 0 then
        commandArray['Variable:WakeUpLightRunning']=""..0
    end
    return commandArray
end

main()
return commandArray;
hope you enoy it.
Why don't we create a script library on the wiki?
Last edited by bellison on Monday 23 January 2017 10:01, edited 1 time in total.
Kaspervm
Posts: 1
Joined: Wednesday 11 January 2017 3:10
Target OS: NAS (Synology & others)
Domoticz version:
Contact:

Re: Script examples (Lua)

Post by Kaspervm »

bellison wrote:Hi,

This is my first lua script in 13 years, so there might be things in this script that might be done in an ugly way.

The dimming speed is a exponential curve so it will slowly increase the dimmers in the beginning and quickly in the end (i figure that it is probably the best way to wake up)

I wanted a wake up light. And all i found was some examples that i didn't understand and that required editing the script it self to work. and that was difficult on my smart phone in the evenings.

I have create a script that utilizes a few user variables.

WakeUpLightEnabled* -- a number value if the wake up light is enabled or not 1 = enabled 0 = disabled, this should be a integer value
WakeUpTime* -- the time you want to wake up (when the lights reach maximum level), this should be a time value
WakeUpPeriodLenght* -- for how many minutes the light should be running from start to end, this should be a integer value
WakeUpLightRunning* -- just a variable keeping track of for how many minutes the wakeup light has been running, this should be a integer value
WakeUpLightAppliences* -- a comma separated list of the dimmers you want to turn on eg. dimmer1,dimmer2 , this should be a string value
WakeUpStartDimLevel -- start level in % for the dimming (this is not needed, default value is set to 5), this should be a integer value
WakeUpEndDimLevel -- end level in % for the dimming (this is not needed, default value is set to 100), this should be a integer value

userVars.JPG

Code: Select all

commandArray = {}

function main()
    
    iWakeUpLightRunning = tonumber(uservariables['WakeUpLightRunning'])
    tWakeUpTime = Split(uservariables['WakeUpTime'], ":")
    iWakeUpPeriodLenght = tonumber(uservariables['WakeUpPeriodLenght'])
    iWakeUpStartDimLevel = tonumber(uservariables['WakeUpStartDimLevel'])
    iWakeUpEndDimLevel = tonumber(uservariables['WakeUpEndDimLevel'])
    
    --print ("WakeUpPeriodLenght " .. iWakeUpPeriodLenght)
    
    CurrentTime = os.date("%H:%M")
    
    tTime = os.date("*t")
    tTime["min"] = tWakeUpTime[2] - iWakeUpPeriodLenght
    tTime["hour"] = tWakeUpTime[1]
    sStartTime = os.date("%H:%M", os.time(tTime))
    
    ln20 = math.log( iWakeUpEndDimLevel / iWakeUpStartDimLevel)
    k = ln20 / iWakeUpPeriodLenght
    iDimValue = math.ceil ( 5 * math.exp( (k * iWakeUpLightRunning) ))
    
    --print ( "iDimValue = " .. iDimValue .. " k = " .. k .. " ln20 = " .. ln20 )
    
    if iWakeUpLightRunning == 0 and CurrentTime ~= sStartTime then
    	--do nothing
    	return
    elseif iWakeUpLightRunning == 0 and CurrentTime == sStartTime then
    	iWakeUpLightRunning = 1
    --	print("first try")
    elseif iDimValue < 100 then
    	iWakeUpLightRunning = iWakeUpLightRunning + 1
    else
    	if iDimValue > 100 then
    		iDimValue = 100
           -- print("setting to 100")
    	end
    	iWakeUpLightRunning = 0
    	bRunLastTime = true
    --	print("resetting to 0")
    end
    
    commandArray['Variable:WakeUpLightRunning']=""..iWakeUpLightRunning
    if iWakeUpLightRunning > 0 or bRunLastTime then
        for k,v in pairs(tAppliences) do
            --print("for " .. v .. " Set Level " .. iDimValue.." %")
            iCurrentDimLevel = tonumber(string.match(otherdevices[v], "Set Level: (%d+) %%"))
            print ("Dim level for " .. v .. " = " .. otherdevices[v] .. " is " .. (iCurrentDimLevel or "") .. " target level " .. iDimValue)
            if (iCurrentDimLevel and iCurrentDimLevel == 100 ) or otherdevices[v] == "On" then
                -- the dimmer is already on or 100%. just leave it alone
            elseif ((iCurrentDimLevel and iCurrentDimLevel == 0) or otherdevices[v] == "Off") and (iWakeUpLightRunning > 1 or (bRunLastTime and iWakeUpPeriodLenght > 1)) then
                -- the dimmer has been turned off after the wakeup light started don't turn on again.
            elseif iCurrentDimLevel and iCurrentDimLevel < iDimValue and iWakeUpEndDimLevel >= iDimValue then
                -- increase the dim-level for the wakeup light dimmers
                print ("Dim level for " .. v .. " = " .. otherdevices[v] .. " is " .. (iCurrentDimLevel or "") .. " setting level to " .. iDimValue)
                commandArray[v] = "Set Level " .. iDimValue .. " %"
            elseif iWakeUpEndDimLevel <= iDimValue then
                -- the dimmer has reached the max-value this should be the last run
                print ("Reached the iWakeUpEndDimLevel of " .. iWakeUpEndDimLevel .. " for " .. v)
                commandArray[v] = "Set Level " .. iWakeUpEndDimLevel .. " %"
            elseif otherdevices[v] == "Off" then
                -- first run set the inital value
                commandArray[v] = "Set Level " .. iDimValue.." %"
            end
        end
    end
end

function checkIfAllUserVariablesExists()
   
    if uservariables['WakeUpLightEnabled'] == nil then
        uservariables['WakeUpLightEnabled'] = 0
        commandArray["Variable:WakeUpLightEnabled"] = uservariables['WakeUpLightEnabled']
    end
    if uservariables['WakeUpLightAppliences'] == nil then
        uservariables['WakeUpLightAppliences'] = ""
        commandArray["Variable:WakeUpLightAppliences"] = uservariables['WakeUpLightAppliences']
    end
    if uservariables['WakeUpLightRunning'] == nil then
        uservariables['WakeUpLightRunning'] = 0
        commandArray["Variable:WakeUpLightRunning"] = uservariables['WakeUpLightRunning']
    end
    if uservariables['WakeUpTime'] == nil then
        uservariables['WakeUpTime'] = "07:00"
        commandArray["Variable:WakeUpTime"] = uservariables['WakeUpTime']
    end
    if uservariables['WakeUpPeriodLenght'] == nil then
        uservariables['WakeUpPeriodLenght'] = "15"
        commandArray["Variable:WakeUpPeriodLenght"] = uservariables['WakeUpPeriodLenght']
    end
    if uservariables['WakeUpStartDimLevel'] == nil then
        uservariables['WakeUpStartDimLevel'] = "5"
        commandArray["Variable:WakeUpStartDimLevel"] = uservariables['WakeUpStartDimLevel']
    end
    if uservariables['WakeUpEndDimLevel'] == nil then
        uservariables['WakeUpEndDimLevel'] = "100"
        commandArray["Variable:WakeUpEndDimLevel"] = uservariables['WakeUpEndDimLevel']
    end 
end

function Split(str, delim, maxNb)
    -- Eliminate bad cases...
    if string.find(str, delim) == nil then
        return { str }
    end
    if maxNb == nil or maxNb < 1 then
        maxNb = 0    -- No limit
    end
    local result = {}
    local pat = "(.-)" .. delim .. "()"
    local nb = 0
    local lastPos
    for part, pos in string.gmatch(str, pat) do
        nb = nb + 1
        result[nb] = part
        lastPos = pos
        if nb == maxNb then break end
    end
    -- Handle the last field
    if nb ~= maxNb then
        result[nb + 1] = string.sub(str, lastPos)
    end
    return result
end

checkIfAllUserVariablesExists()

tAppliences = Split(uservariables['WakeUpLightAppliences'], ",")
if tAppliences == nil or uservariables['WakeUpLightEnabled'] == nil or uservariables['WakeUpLightEnabled'] == 0 then 
    -- no list with dimmers that should wake up, end it here
    commandArray['Variable:WakeUpLightRunning']=""..0
    return commandArray
end

main()

return commandArray
hope you enoy it.
Why don't we create a script library on the wiki?
Wow!

I am totally new with all this stuff but i think this is what i've been looking for..

I need to do a sunrise and sundown on certain times everyday on my aquarium LED light.

So actually i just need to activate a RGBW controller to start from 9 to 10 o'clock with "sunrise" with dimming from 0-100 - and the "sunset" from 22 to 23 o'clock with dimming 100-0.

Maybe i could kindly ask you to edit your script so it fits my needs? :)
I would really like to know and see how a script/code would look like and then i can work my way through the rest of the gadgets i am planning to buy :P

/ Kasper
korneel
Posts: 6
Joined: Tuesday 17 January 2017 15:22
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Script examples (Lua)

Post by korneel »

Interestingly I just finished up a wakeup light too, but I wanted to take my next alarm time automatically set via my phone because I'm lazy.
This is a script I originally made with blocky, but that didn't really work for some reason. Also I wanted it to be flexible, taking the date and time in consideration. So if my next alarm is set for monday, it won't start on sunday when I want to sleep in.

This script uses three variables, which you'll find at the top of the script.

wakeupspan - The time you want the light to take to become fully lit
steps - the number of iterations you want your light to take (I use ten, it's OK, no fancy algorythm like bellison)
switch - the name of the switch you want to use - for easy implementation

Some thoughts

This doesn't work very well if you don't have Tasker as it is tied to a date, see below how to set that up.
It's a lot faster than adding a 'wait' or sleep in your script and should finish within a second or so. But the downside of this is that if you turn the light on or off during the timespan, the light will fall back to the scheduled commands, so if you decide to sleep in, it will come back with a vengeance ;-)
You might want to insert a 'Holiday Mode' check or whether you're home at all.

Why two user variables? Well, it's only one extra line in Tasker, but a whole lot more annoying to parse in Lua if I were to use one date-time or string.

So here's the code:

Code: Select all

-- Script to wake up on a set time
-- set the time in a uservariable so you can set it using tasker with AutoAlarm to read your alarm.
-- only issue: you can't turn the light off in during the time it comes on as it will keep falling back to the script
-- custom variables set to influence the flow
wakeupspan = 300 -- time in seconds
steps = 10 --number of iterations
switch = 'Kamer' --name of the switch

commandArray = {}
-- helper function to parse the date and time strings from the uservar
function mysplit(inputstr, sep)
        if sep == nil then
                sep = "%s"
        end
        local t={} ; i=1
        for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
                t[i] = str
                i = i + 1
        end
        return t
end


print('Wake Up Light')
-- now some logic!
-- first process the date and time to a time object
dateTable = mysplit(uservariables["WakeUpDate"], '/')
timeTable = mysplit(uservariables['WakeUpTime'], ':')

-- now set the times
currentTime = os.time()
wakeupsies = os.time{year=dateTable[3],month=dateTable[2],day=dateTable[1],hour=timeTable[1],min=timeTable[2]}

print('Alarm set for :'..os.date('%c',wakeupsies))
print('Wakeup starts at:'..os.date('%c',wakeupsies-wakeupspan))
print('Current time:'..os.date('%c',currentTime))
--only if the device is not already on
-- on the right time. We'll try within the span
loops = wakeupspan/steps
if os.time() > (wakeupsies-wakeupspan) then
        if os.time() < wakeupsies then
                if otherdevices[switch]=='Off' then
--                      table.insert(commandArray, {[switch] = 'Set Level 1'})
                        for i=1,steps,1 do
                                print('Set Level '..(i*steps)..' AFTER '..(loops*i)..' seconds')
                                cmd = 'Set Level '..(i*steps)..' AFTER '..(loops*i)
                                table.insert(commandArray,{ [switch] = cmd })
                        end
                else
                        print(switch..' already on')
                end
        end
else
        print('out of time span')
end
To use

Don't forget to set two user variables 'WakeUpTime' and 'WakeUpDate'.

I use Tasker and AutoAlarm to read my next alarm at around 3am and send it to my Raspberry Pi.
First in the Tasker Event is AutoAlarm and then two simple http get commands:

Code: Select all

http://192.168.0.8:8080/json.htm?type=command&param=updateuservariable&vname=WakeUpTime&vtype=4&vvalue=%hour:%minute
and

Code: Select all

http://192.168.0.8:8080/json.htm?type=command&param=updateuservariable&vname=WakeUpDate&vtype=3&vvalue=%year/%month/%day
(repace the IP address with your own)
User avatar
Brutus
Posts: 249
Joined: Friday 26 September 2014 9:33
Target OS: Windows
Domoticz version:
Location: Netherlands
Contact:

Re: Script examples (Lua)

Post by Brutus »

I had a simple script to turn on my hall light when I am walking through the Fibaro Motion Sensor at nighttime.
But I noticed that when you only use the "Nighttime" of the day the lights are still off when its almost sunset or just after Sunrise.
So I needed to add some time. After some looking at the forum I couldn't find the proper way to do this. But after some testing this is the result:

Code: Select all


--------------------------------------------------------------------------------------------------
-- Data:

time    = os.date("*t")
minutes = time.min + time.hour * 60

Sensor      = devicechanged['Bewegingsmelder Gang']
SensorUit   = otherdevices['Bewegingsmelder Uitschakelen']

commandArray = {}

---------------------------------------------------------------------------------------------------
-- Verlichting Gang Aan:

if (minutes < (timeofday['SunriseInMinutes']+15)) or (minutes > (timeofday['SunsetInMinutes']-15))then
    
    if Sensor == 'On' and SensorUit == 'Off' then
        commandArray['Gang'] = 'On'
        print ('<font color="teal">Verlichting gang aan!</font>')
    end
    
---------------------------------------------------------------------------------------------------
-- Verlichting Gang Uit:

    if Sensor == 'Off' and SensorUit == 'Off' then
        commandArray['Gang'] = 'Off'
        print ('<font color="teal">Verlichting gang uit!</font>')
    end   

end

return commandArray
1x Intel NUC8i5BEK (Windows 10 x64) Domoticz on Virtualbox with DietPi.
1x Aeon Labs USB Z-Stick S2
1x P1 Smart Meter USB
28x Fibaro Modules
SMA Solar System
Daikin Airco / Heating
Denon DHT-S716H & DSW-1H
PSYCHOTIC
Posts: 20
Joined: Saturday 21 February 2015 16:32
Target OS: Windows
Domoticz version:
Location: Netherlands
Contact:

Re: Script examples (Lua)

Post by PSYCHOTIC »

Ive got a pondtemperature device wich is giving me wrong readings from time 2 time.
Ive created a lua script that corrects these temp glitches.

Maybee helpfull for others.

commandArray = {}
if (devicechanged['Vijver Temperatuur Errored']) then
print('Vijver Temperatuur Errored = ' .. devicechanged['Vijver Temperatuur Errored'])
TempErrored = devicechanged['Vijver Temperatuur Errored']
print('Vijver Temperatuur OK = ' .. otherdevices['Vijver Temperatuur'])
TempCor = otherdevices['Vijver Temperatuur']
TempDiff = devicechanged['Vijver Temperatuur Errored'] - otherdevices['Vijver Temperatuur']
print('Vijver Temperatuur Diff = ' .. TempDiff )
if TempDiff > -3 and TempDiff < 0 then
commandArray['UpdateDevice'] = "4146|0|" .. tostring(TempErrored)
print('Vijver Temperatuur Diff Approved' )



elseif TempDiff < 3 and TempDiff > 0 then
commandArray['UpdateDevice'] = "4146|0|" .. tostring(TempErrored)
print('Vijver Temperatuur Diff Approved' )


else
print('Vijver Temperatuur Diff DisApproved' )
end
end
return commandArray
ToneStrife
Posts: 20
Joined: Sunday 16 April 2017 17:02
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Script examples (Lua)

Post by ToneStrife »

Hi everyone,
I have configured 2 dummy sensors for me and my wife to detect if we are at home or not (On/Off) and I have also made one called Familia (family) to be turned On if both are at home but is not working and spaming the log. Any help?

Code: Select all

commandArray = {}

if (devicechanged['Gala']) or (devicechanged['Carlos']) and (otherdevices['Carlos'] == 'On') and (otherdevices['Gala'] == 'On') then
    
    commandArray['Familia']='On'
end

if (devicechanged['Gala']) or (devicechanged['Carlos']) and (otherdevices['Carlos'] == 'Off') or (otherdevices['Gala'] == 'Off') then
    
    commandArray['Familia']='Off'
    
end
I edit myslef, I have to select that is a Device Event not All. Anywhere I can find which should I select there?
tozzke
Posts: 135
Joined: Friday 02 January 2015 9:22
Target OS: Raspberry Pi / ODroid
Domoticz version: Stable
Location: Netherlands
Contact:

Re: Script examples (Lua)

Post by tozzke »

try changing it to:

Code: Select all

commandArray = {}
if (otherdevices['Gala'] == 'On' or otherdevices['Carlos'] == 'On') and otherdevices['Familia'] == 'Off' then
    commandArray['Familia'] = 'On'

elseif otherdevices['Gala'] == 'Off' and otherdevices['Carlos'] == 'Off' and otherdevices['Familia'] == 'On' then
    commandArray['Familia'] = 'Off'
end
return commandArray
Nautilus
Posts: 722
Joined: Friday 02 October 2015 12:12
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: Finland
Contact:

Re: Script examples (Lua)

Post by Nautilus »

ToneStrife wrote: I edit myslef, I have to select that is a Device Event not All. Anywhere I can find which should I select there?
Choose device script if you have a "devicechanged" trigger on the script ( = you wan the script to run on each device change) and select time script if you only have "otherdevices" conditions ("devicechanged is not available in time scripts) and you want to run the script once a minute. I see no reason to select "All" option in any circumstance but probably there is some special cases...:)
tozzke wrote:try changing it to:

Code: Select all

commandArray = {}
if (otherdevices['Gala'] == 'On' or otherdevices['Carlos'] == 'On') and otherdevices['Familia'] == 'Off' then
    commandArray['Familia'] = 'On'

elseif otherdevices['Gala'] == 'Off' and otherdevices['Carlos'] == 'Off' and otherdevices['Familia'] == 'On' then
    commandArray['Familia'] = 'Off'
end
return commandArray
This is a good option (except I think the first condition needs to be otherdevices['Gala'] == 'On' and otherdevices['Carlos'] == 'On' and second (otherdevices['Gala'] == 'Off' or otherdevices['Carlos'] == 'Off) => requirement for "Familia" was that both are home) if it is enough that "Familia" switch is updated with up to one minute delay. The above would need to be defined as time script. But I think the original should work as well as long as it is defined as device script...
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest