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
}