dzvents Light timer example  [Solved]

Easy to use, 100% Lua-based event scripting framework.

Moderator: leecollings

Post Reply
BakSeeDaa
Posts: 485
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi / ODroid
Domoticz version:

dzvents Light timer example

Post by BakSeeDaa »

I believe I have seen a dzvents Light timer script example somewhere but now I can't seem to find it.

Looking for a simple script to turn the light on in a room for a certain amount of time when the door gets opened. Except for the light device and the door switch, there is also a light switch involved. If the light is toggled on by the light switch, the light should not turn off automatically (or as an alternative, the lights should turn off after a much longer time).

Cheers!

EDIT: I made a script for this purpose. See my script in this post.
Last edited by BakSeeDaa on Friday 10 November 2017 13:15, edited 1 time in total.
User avatar
emme
Posts: 909
Joined: Monday 27 June 2016 11:02
Target OS: Raspberry Pi / ODroid
Domoticz version: latest
Location: Milano, Italy
Contact:

Re: dzvents Light timer example

Post by emme »

..mmh.. so...
here a sum of the rules:

- door open ==> light on by timer
- light button press ==> light on NOT by timer
- other switch ==> light on NOT by timer

correct?

I think you can do it only if the 2 switches are not directly connected to the light
...by my understanding this can be sone in this way:

Code: Select all


on = { devices = {'doorSwitch', 'switchLight1', 'switchLight2', 'timerSwitch'},
data = { switchPressed = { initial = false} },
execute = function(dz, devName)
    local lightTimer = 90     -- timer in secs
    local longDelay = 90    -- much longer delay
    local timerSwitch = dz.devices('timerSwitch')
    local roomLight = dz.devices('roomLight')
    
    if devName.name == 'doorSwitch' and devName.state == 'On' then
       roomlight.switchOn().checkFirst()
       timerswitch.switchOn().afterSec(lightTimer)
    elseIf ((devName.name == 'switchLight1') or (devName.name == 'switchLight2')) and devName.state == 'On' then
       dz.data.switchPressed = true
       roomlight.switchOn().checkFirst()
    elseif devName.name == 'timerSwitch' and devName.state == 'On' then
       if dz.data.switchPressed == true then --longer delay
           timerSwitch.switchOff().silent()
           timerSwitch.switchOn().afterSec(longDelay)
           dz.data.switchPressed = false
       else
           timerSwitch.switchOff().silent()
       end
    elseif ((devName.name == 'switchLight1') or (devName.name == 'switchLight2')) and devName.state == 'Off' then
       roomlight.switchOff().checkFirst()
       if dz.data.switchPressed == true then dz.data.switchPressed = false end 
    end
end

       
hope it will work with short corrections :P
MY intention is:
if door is open switch on for n secs...
if a key in pressed ON, do not consider anymore the timer and leave the light on
so, the light can be turned off ONLY by pressing one of the 2 switches
...for delaying the timer I had this idea: if one of the switches has been pressed I will delay the timer....

hope this would help... and work!!!! :lol: :lol: :lol: :lol:
The most dangerous phrase in any language is:
"We always done this way"
tlpeter
Posts: 191
Joined: Wednesday 26 November 2014 18:43
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Netherlands
Contact:

Re: dzvents Light timer example

Post by tlpeter »

I use .switchOff().afterMin(5)
User avatar
emme
Posts: 909
Joined: Monday 27 June 2016 11:02
Target OS: Raspberry Pi / ODroid
Domoticz version: latest
Location: Milano, Italy
Contact:

Re: dzvents Light timer example

Post by emme »

tlpeter wrote: Thursday 26 October 2017 17:06 I use .switchOff().afterMin(5)
that command cannot be deleted... so.. if you press the switch (that means that you do not want to switchoff the light automatically anymore) the light will go off anyway
I strongly hope one day we would be able to interact much better with Domoticz scheduler... :P :P
Last edited by emme on Thursday 26 October 2017 17:53, edited 1 time in total.
The most dangerous phrase in any language is:
"We always done this way"
tlpeter
Posts: 191
Joined: Wednesday 26 November 2014 18:43
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Netherlands
Contact:

Re: dzvents Light timer example

Post by tlpeter »

Aaah, i did not read well enough i see.
BakSeeDaa
Posts: 485
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi / ODroid
Domoticz version:

Re: dzvents Light timer example

Post by BakSeeDaa »

Thanks @emme for your script example.

Below is a script that I currently use. It keeps a table of the lights that you wish to control so it's easily to adopt to any number of lights, each with different values. Each light has a "Door Device", a door switch that typically turns the light on for a shorter period of time when the door gets opened. Each light also has a "Switch Device" which is a manual light switch that typically turns the light on for some longer time (or turns it off).

In my setup, I use a Fibaro Single Switch 2 (Z-wave). Then the name of the light is the same as the switch device as you can see below in the script.

The script is not supposed to work for every kind of setup. You can use it as an example, adopt it, change it and/or extend it and make it your own.

Prerequisites:
  • A Domoticz virtual text device always showing the ambient light level . The text must always be one of "Dark", "Bright" or "Shady". In the example below it's simply named "Ambient light level". My script doesn't take care of the logic behind this virtual text device. Note, it has nothing to do with the day state, e.g. if it's day or night.
  • dzVents version 2.3.0 or higher.
  • dzVents and Lua knowledge at least at an intermediate level. You need to understand what the script does, the code and how to debug it.
Each light that you wish to control has the following table elements that can be configured:
Table key .string. The Domoticz device name of the light device.
['enabled'] boolean. Whether this definition should be used or not.
['doorDevice'] string. The Domoticz device name of the lights door device as described above.
['switchDevice'] The Domoticz device name of the lights switch device as described above.
['minutesDoor'] = number. Number of minutes that the light shall be turned on after opening the door.
['minutesSwitch'] number. Number of minutes that the light shall be turned on after using the light switch manually.

Code: Select all

local lights = {
	['Bathroom lights'] = {['enabled'] = true, ['doorDevice'] = 'Bathroom Door', ['switchDevice'] = 'Bathroom lights', ['minutesDoor'] = 4,  ['minutesSwitch'] = 60},
	['External lights'] = {['enabled'] = true, ['doorDevice'] = 'Entrance Door', ['switchDevice'] = 'External lights', ['minutesDoor'] = 3,  ['minutesSwitch'] = 70},
}

local LIGHT_AMB_DEV = 'Ambient light level' -- Ambient light level virtual text device

local function getTriggerDevices()
	local tDevs = {}
	local tDevsIndexed = {}
	for lightDev, lightData in pairs(lights) do
		if lightData.enabled then
			tDevs[lightDev] = 1
			tDevs[lightData.doorDevice] = 1
			tDevs[lightData.switchDevice] = 1
		end
	end
	tDevs[LIGHT_AMB_DEV] = 1
	for k, _v in pairs(tDevs) do table.insert(tDevsIndexed, k) end
	return(tDevsIndexed)
end

local function getPData()
	local pData = {}
	for lightDev, lightData in pairs(lights) do
		if lightData.enabled then
			pData[lightDev] = {history = true, maxItems = 1}
		end
	end
	return(pData)
end

local triggerDevices = getTriggerDevices()
local pData = getPData()

return {
	active = true,
	logging = {
		level = domoticz.LOG_INFO, -- Select one of LOG_INFO, LOG_DEBUG, LOG_ERROR, LOG_FORCE to override system log level
		marker = "lightTimer"
	},
	on = {
		devices = triggerDevices,
		timer = {'every minute'}
	},
	data = pData,
	execute = function(domoticz, device, triggerInfo)
		local LIGHT_LEVEL_TEXT_DARK = 'Dark'
		local LIGHT_LEVEL_TEXT_BRIGHT = 'Bright'
		local LIGHT_LEVEL_TEXT_SHADY = 'Shady'

		for lightDevName, lightData in pairs(lights) do
			local pData = domoticz.data[lightDevName]
			if pData.size == 0 then pData.add('off') end -- Initialize data if necessary
			local hValue = pData.getLatest() -- Get the value for the latest history item

			-- Calculate the remaining time
			local remainingMinutes = (hValue.data == 'door')
				and (lightData.minutesDoor - hValue.time.minutesAgo)
				or (hValue.data == 'switch' and (lightData.minutesSwitch - hValue.time.minutesAgo) or 0)
			if remainingMinutes > 0 then domoticz.log(lightDevName..', '..hValue.data..': '..'remainingMinutes: '..remainingMinutes, domoticz.LOG_INFO) end

			if triggerInfo.type == domoticz.EVENT_TYPE_DEVICE then
	
				if device.name == lightData.doorDevice and device.active
				and (domoticz.devices(LIGHT_AMB_DEV).text ~= LIGHT_LEVEL_TEXT_BRIGHT) then
	
					if (remainingMinutes <= lightData.minutesDoor) then
						pData.add('door')
						-- Currently the checkFirst() option does not work combined with the .silent() option for all kind of devices
						if not domoticz.devices(lightDevName).active then
							domoticz.devices(lightDevName).switchOn().silent()
							domoticz.log(device.name .. ' opened. Switching on: '..lightDevName, domoticz.LOG_INFO)
						end
					end

				elseif device.name == lightData.switchDevice and device.active --then
				and domoticz.devices(lightData.doorDevice).lastUpdate.secondsAgo > 2 then 
					pData.add('switch')
					-- Currently the checkFirst() option does not work combined with the .silent() option for all kind of devices
					if domoticz.devices(lightDevName).active then
						domoticz.devices(lightDevName).switchOn().silent()
						domoticz.log(device.name .. ' switched. Switching on: '..domoticz.devices(lightDevName).name, domoticz.LOG_INFO)
					end

				elseif (device.name == lightData.switchDevice and not device.active)
				or (device.name == LIGHT_AMB_DEV and device.text == LIGHT_LEVEL_TEXT_BRIGHT and hValue.data == 'door') then
					pData.add('off')
				end

			elseif triggerInfo.type == domoticz.EVENT_TYPE_TIMER then
				if remainingMinutes <= 0 then
					if domoticz.devices(lightDevName).active then
						domoticz.devices(lightDevName).switchOff().silent()
						domoticz.log(lightDevName .. ', time came to an end. Turning off '..domoticz.devices(lightDevName).name, domoticz.LOG_INFO)
					end
				end
			end

		end

	end
}
Last edited by dannybloe on Wednesday 01 November 2017 14:16, edited 1 time in total.
Reason: Fixed dzVents version typo
stephanvdplas
Posts: 76
Joined: Wednesday 13 February 2019 18:09
Target OS: Windows
Domoticz version: 2023.1
Location: Netherlands
Contact:

Re: dzvents Light timer example

Post by stephanvdplas »

emme wrote: Thursday 26 October 2017 17:20
tlpeter wrote: Thursday 26 October 2017 17:06 I use .switchOff().afterMin(5)
that command cannot be deleted... so.. if you press the switch (that means that you do not want to switchoff the light automatically anymore) the light will go off anyway
I strongly hope one day we would be able to interact much better with Domoticz scheduler... :P :P
Since 2.4.0: cancelQueuedCommands(): Cancels queued commands. E.g. you switch on a device after 10 minutes: myDevice.switchOn().afterMin(10). Within those 10 minutes you can cancel that command by calling: myDevice.cancelQueuedCommands().
- Running LMS, Domoticz and Dashticz on a windows 11 laptop.
- LMS (11 players) / Hue (26 lights, 2 switches) / Z-wave (14 devices) / Toon (unrooted) / Chromecast
User avatar
emme
Posts: 909
Joined: Monday 27 June 2016 11:02
Target OS: Raspberry Pi / ODroid
Domoticz version: latest
Location: Milano, Italy
Contact:

Re: dzvents Light timer example  [Solved]

Post by emme »

I know, my post is dated 2017 while .cancelqueuedcommands is 2018 ;)
The most dangerous phrase in any language is:
"We always done this way"
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest