I want to share some Dzvents/lua implementation in order to be able to trigger an "All Off" action by double clicking a "2 button" wall switch location without the use of zwave scene functioanlity.
This script might be useful in case you use z-wave modules which don't support scenes(e.g. Qubino) or another reason why you cannot create an 'all off' functionality with scenes.
I shared my implementation in its entirety(so with my personal house situation an), this in the idea it would make it more clear how to use the script.>
My personal situation contains 3 "all off by double click" locations:
1)keukendeur[/list]
2)Voordeur[/list]
3)Zolder-trap[/list]
Hope it might be useful for you as well, if not, no problem, at least you gave it a try


Code: Select all
-----------------------------------------------------------
-- script description
----------------------------------------------------------
--This script will switch off all active nodes when we performed 2 times a 'double tab'* on predefined switch locations
-- the z-wave nodes cannot detect this 'dubble tab' so we have to 'simulate' this in domoticz by compairing switch event timings.
-- This script might be usefull in case you use z-wave modules which don't support scenes(e.g. Qubino) or another reason why you cannot create an 'all off' functionality with scenes
--
-- The definition of a 'double tab' is:
-- 1) press the 2 buttons of your switch simultaneously
-- 2) press the 2 buttons of your switch quickly after each other.
--
-- More details about the script AND how to configure it can be check inline the code via comments.
-- All places in the code where you can or should make script configuration start with the [TODO] prefix followed by an explanation on why and how to do it.
---------------------------------------------------------
----------------------------------------------------------
-- define global functions here
----------------------------------------------------------
function CheckTableContains(table, val)
for i=1,#table do
--if table[i] == val then
if string.find(val, table[i]) then
return true
end
end
return false
end
function GetSwitchesLastUpdateTime(domoticz,Switch,Switch1Name, Switch2Name)
local Switch1
local Switch2
Switch1 = domoticz.devices(Switch1Name)
Switch2 = domoticz.devices(Switch2Name)
-- remark from dzvents wiki page:
---------------------------------------
--The lastUpdate for devices that triggered this script is in fact the previousUpdate time.
-- The real lastUpdate time for these “script triggering” devices is the current time.
-- below if statement is to assign the current time to the right Switch
if (Switch.name == Switch1Name) then
Switch1_updateTime = domoticz.time.makeTime() --create time object for current time
Switch2_updateTime = Switch2.lastUpdate --create time object for lastupdate time of switch
else
Switch1_updateTime = Switch1.lastUpdate --create time object for lastupdate time of switch
Switch2_updateTime = domoticz.time.makeTime() --create time object for current time
end
return Switch1, Switch2
end
----------------------------------------------------------
return
{
--Script Triggers
on =
{
--[TODO] define here all swiches that are used in the script to trigger the "all off by double tab" script
devices = { "L_0_Vide_Plafond", "L_0_Vide_Muur", "L_1_TrapPlafond", "L_1_Zolder", "L_0_Inkom_Schakelaar", "L_0_Gevel"}
},
-- persistent data(varname start with higher case)
data = {
-- variable to use as a placeholder to store the FirstDoubleTabDetected datim.
--Remark: we cannot instantiate the 'FirstDoubleTabDetected' variable as a 'time' object in the persistent data section above.
-- so therefor on the first time this script will run, the 'FirstDoubleTabDetected' is still a 'nil' object and is set inside the code.
FirstDoubleTabDetected={},
--[TODO] with below variable gives the max time that domoticz should take into account between the moment that the 2 swichtes are pushed to simulate the "doubltab"
--remark :we take 5 seconds(3sec+2 secs buffer) since thr Qubino Dimmers(Keukendeur) takes on average 2-3 seconds before domoticz handles these switch events for both switches.
-- The Fibaro switches(Voordeur,Zolder-trap) is handeld much faster by Domoticz(within second)
-- So it's usefull to define here a maxtime that works well with all zwave devises(fast &slow).
-- This way you can always rely on a correctly working script, if required you can overrule this Maxtime in the customizable function required per location(check below)
MaxTime_BetweenDoubleTabSwitches ={ initial = 5 },
--[TODO] with below variable gives the max time that domoticz should take into account between the first and the second 'doubleTab' action
--Remark: We take 15 seconds since the Qubino Dimmers(Keukendeur) takes on average 5-6 seconds before domoticz handles the second 'doubleTab'
-- The Fibaro switches(Voordeur,Zolder-trap) is handeld much faster by Domoticz(within second)
-- So it's usefull to define here a maxtime that works well with all zwave devises(fast &slow).
-- This way you can always rely on a correctly working script, if required you can overrule this Maxtime in the customizable function required per location(check below)
MaxTime_BetweenFirstSecondDoubeTab ={ initial = 15 },
--[TODO] with below variables you indicate how you want to switch off the devices.
-- you have 2 options:
-- 1) SwitchOff_ActiveDevices: switch off only the "active*" Light/Switch devices (* active according domoticz)
-- This option is the fastest option so swicht of your active devices(= limited device list) since only for those a swich off command is send
-- 2) SwitchOff_AllDevices: swith off all Light/Switch devices independent from their domoticz state
-- -> this is the most rubuust option to switch off the devices since it will also switch off the devices for which their active status is not updated for whatever reason in Domoticz(happens once in a while )
-- This option is the slowest(=takes a while before all active devices will be swichted off) since it had to go trought the complete device list in an alphabetical order.
-- remark: you can combine option 1) and 2) since it will combine best of both wordls:
-- a)the active devices will be swichted off as quick as possible
-- b) if for whatever reason the active status of a certain device is not updated correclty in, you can be sure it will switch off
-- Therefor both options are active by default but you can change it to your own preferences.
SwitchOff_ActiveDevices = { initial = 1},
SwitchOff_AllDevices = { initial = 1},
--[TODO] time to indicate flash duration
FlashTime = { initial = 2}
},
-- custom logging level for this script
logging = {
level = domoticz.LOG_INFO,
marker = "template"
},
-- the actual script logic
-- the second parameter is depending on the trigger
-- when it is a device change, the second parameter is the device object
execute = function(domoticz, Switch,info)
local timeCompaire_DoubleTabSwitches
local timeCompaire_FirstDoubleTabDetected
local firstDoubleTabRegisterdNotificationLight
local Switch1
local Switch2
local Switch1Name
local Switch2Name
local DevicesToExcludeAllOff
print("Script-DoubleTab:-----------------START---------------------")
-- always re-initialize below persitent timers so we always apply the most recent value on each script run after it was manually updated.
-- without this re-initialize, we would not use te values saved in the 'data' setiona above and system will keep using the 'old' value
domoticz.data.initialize('MaxTime_BetweenDoubleTabSwitches')
domoticz.data.initialize('MaxTime_BetweenFirstSecondDoubeTab')
domoticz.data.initialize('SwitchOff_ActiveDevices')
domoticz.data.initialize('SwitchOff_AllDevices')
domoticz.data.initialize('FlashTime')
print("Script-DoubleTab:MaxTime_BetweenFirstSecondDoubeTab=".. tostring(domoticz.data.MaxTime_BetweenFirstSecondDoubeTab))
print("Script-DoubleTab:MaxTime_BetweenDoubleTabSwitches=".. tostring(domoticz.data.MaxTime_BetweenDoubleTabSwitches))
print("Script-DoubleTab:SwitchOff_ActiveDevices=".. tostring(domoticz.data.SwitchOff_ActiveDevices))
print("Script-DoubleTab:SwitchOff_AllDevices=".. tostring(domoticz.data.SwitchOff_AllDevices))
print("Script-DoubleTab:FlashTime=".. tostring(domoticz.data.FlashTime))
-- we cannot instantiate the 'FirstDoubleTabDetected' variable as a 'time' object in the persistent data section above.
-- so the first time this script will run, the 'FirstDoubleTabDetected' is still a 'nil' object.
-- below if statement is to overcome this 'initial' problem, after the first run this is not a problem anymore
if (domoticz.data.FirstDoubleTabDetected == nil) then
print("Script-DoubleTab:domoticz.data.FirstDoubleTabDetected == nil")
domoticz.data.FirstDoubleTabDetected=domoticz.time
end
--------------------------------------------------------------------------------------------------------------------------------------------------
-- BEGIN section to define all "AllOffByDoubleTab" location of your choise -> below your customization is needed!!!!!
--------------------------------------------------------------------------------------------------------------------------------------------------
--###########################################################
-- START Copy/paste section (make a copy of this complete section for all the different "AllOffByDoubleTab" location you want and configure it accordingly )
--
-- 1) 'AllOffByDoubleTab location : keukendeur'
----------------------------------------------------------
--[TODO] defind below the 2 Switch names which will be used for this AllOffByDoubleTab location
Switch1Name= "L_0_Vide_Plafond"
Switch2Name= "L_0_Vide_Muur"
--[TODO] Overrule the default MaxTime in case you want to have better response time for quicker z-wave devies(e.g. Fibaro)
-- So If needed uncomment below 2 MaxTime lines and define appropriate value
--MaxTime_BetweenDoubleTabSwitches = 2
--MaxTime_BetweenFirstSecondDoubeTab = 5
if (Switch.name == Switch1Name) or (Switch.name == Switch2Name) then
-- [TODO] define below the message that you want to log when this location is selected
print ("Script-DoubleTab:AllOffByDoubleTab location 1: keukendeur'")
--[TODO] define below the light name that will be used to indicate(flash) when the first double tab action is registerd by the system
firstDoubleTabRegisterdNotificationLight = domoticz.devices("L_0_Keuken_Plafond")
--[TODO] Define below the list of devices to exclude or switch on for this AllOffByDoubleTab location
-- syntax remarks:
-- 1)provide full switch name (e.g. "L_0_Gevel") or part of it (e.g. "Gevel")
-- 2)list is capital sensitive!
DevicesToExcludeAllOff={'Plug_0_Living_Tv',"Buiten", "RegenwaterPomp",'Gevel','L_0_TerrasTuin',"Blinds","VR"}
--DevicesToSwitchOn={"Blinds_0"}
DevicesToSwitchOn={}
Switch1, Switch2 = GetSwitchesLastUpdateTime(domoticz,Switch,Switch1Name,Switch2Name)
end
----------------------------------------------------------
-- STOP START Copy/paste section section
--###########################################################
--###########################################################
-- START Copy/paste section (make a copy of this complete section for all the different "AllOffByDoubleTab" location you want and configure it accordingly )
--
-- 2) 'AllOffByDoubleTab location : Voordeur'
----------------------------------------------------------
--[TODO] defind below the 2 Switch names which will be used for this AllOffByDoubleTab location
Switch1Name= "L_0_Inkom_Schakelaar"
Switch2Name= "L_0_Gevel"
--[TODO] Overrule the default MaxTime in case you want to have better response time for quicker z-wave devies(e.g. Fibaro)
-- So If needed uncomment below 2 MaxTime lines and define appropriate value
MaxTime_BetweenDoubleTabSwitches = 2
MaxTime_BetweenFirstSecondDoubeTab = 5
if (Switch.name == Switch1Name) or (Switch.name == Switch2Name) then
-- [TODO] define below the message that you want to log when this location is selected
print("Script-DoubleTab:AllOffByDoubleTab location 2: Voordeur'")
--[TODO] define below the light name that will be used to indicate(flash) when the first double tab action is registerd by the system
firstDoubleTabRegisterdNotificationLight = domoticz.devices("L_0_Keuken_Plafond")
--[TODO] Define below the list of devices to exclude or switch on for this AllOffByDoubleTab location
-- syntax remarks:
-- 1)provide full switch name (e.g. "L_0_Gevel") or part of it (e.g. "Gevel")
-- 2)list is capital sensitive!
DevicesToExcludeAllOff={'Plug_0_Living_Tv',"Buiten", "RegenwaterPomp",'Gevel','L_0_TerrasTuin',"Blinds","VR"}
--DevicesToSwitchOn={"Blinds_0"}
DevicesToSwitchOn={}
Switch1, Switch2 = GetSwitchesLastUpdateTime(domoticz,Switch,Switch1Name,Switch2Name)
end
----------------------------------------------------------
-- STOP START Copy/paste section section
--###########################################################
--###########################################################
-- START Copy/paste section (make a copy of this complete section for all the different "AllOffByDoubleTab" location you want and configure it accordingly )
--
-- 3) 'AllOffByDoubleTab location: Zolder-trap'
----------------------------------------------------------
--[TODO] defind below the 2 Switch names which will be used for this AllOffByDoubleTab location
Switch1Name= "L_1_TrapPlafond"
Switch2Name= "L_1_Zolder"
--[TODO] Overrule the default MaxTime in case you want to have better response time for quicker z-wave devies(e.g. Fibaro)
-- So If needed uncomment below 2 MaxTime lines and define appropriate value
MaxTime_BetweenDoubleTabSwitches = 2
MaxTime_BetweenFirstSecondDoubeTab = 5
if (Switch.name == Switch1Name) or (Switch.name == Switch2Name) then
-- [TODO] define below the message that you want to log when this location is selected
print("Script-DoubleTab:AllOffByDoubleTab location 3: Zolder-trap")
--[TODO] define below the light name that will be used to indicate(flash) when the first double tab action is registerd by the system
firstDoubleTabRegisterdNotificationLight = domoticz.devices("L_1_Passerelle")
--[TODO] Define below the list of devices to exclude or switch on for this AllOffByDoubleTab location
-- syntax remarks:
-- 1)provide full switch name (e.g. "L_0_Gevel") or part of it (e.g. "Gevel")
-- 2)list is capital sensitive!
DevicesToExcludeAllOff = {'Plug_0_Living_Tv', 'L_1_WC1' ,'Ventilatie', "RegenwaterPomp","L_1_SlpMamaPapa_Plafond","Blinds","VR","L_1_SlpkMamaPapa"}
--DevicesToSwitchOn={"Blinds_0"}
DevicesToSwitchOn={}
Switch1, Switch2 = GetSwitchesLastUpdateTime(domoticz,Switch,Switch1Name,Switch2Name)
end
----------------------------------------------------------
-- STOP START Copy/paste section section
--###########################################################
--------------------------------------------------------------------------------------------------------------------------------------------------
-- END section to define all AllOffByDoubleTab location of your choise -> below any customization is NOT needed anymore!!!!!
--------------------------------------------------------------------------------------------------------------------------------------------------
print("Script-DoubleTab:Switch1.name=" .. Switch1.name)
print("Script-DoubleTab:Switch1_updateTime=" .. Switch1_updateTime.raw)
print("Script-DoubleTab:Switch2.name=" .. Switch2.name)
print("Script-DoubleTab:Switch2_updateTime=" .. Switch2_updateTime.raw)
timeCompaire_DoubleTabSwitches = Switch1_updateTime.compare(Switch2_updateTime).secs
timeCompaire_FirstDoubleTabDetected = domoticz.time.compare(domoticz.data.FirstDoubleTabDetected).secs
print ("Script-DoubleTab:FirstDoubleTabDetected datim=" .. domoticz.data.FirstDoubleTabDetected.raw)
print("Script-DoubleTab:timeCompaire_DoubleTabSwitches=" .. timeCompaire_DoubleTabSwitches)
print("Script-DoubleTab:timeCompaire_FirstDoubleTabDetected=" .. timeCompaire_FirstDoubleTabDetected)
-- a 'double tab' event is recognized if the 2 switches are toggled within 3 seconds from each other.
-- remark 1: although you pushed both switches simultaneously, Domoticz will not process both toggle events all together but separately.
-- This means that the second detected switch event triggers the actual timeCompaire_DoubleTabSwitches<=3 condition
print("Script-DoubleTab:'double tab' event happend? -> timeCompaire_DoubleTabSwitches<=domoticz.data.MaxTime_BetweenDoubleTabSwitches:" .. timeCompaire_DoubleTabSwitches .. "<=" .. domoticz.data.MaxTime_BetweenDoubleTabSwitches .. "?")
if (timeCompaire_DoubleTabSwitches<=domoticz.data.MaxTime_BetweenDoubleTabSwitches) then
--check if we are dealing with the first or second 'double tab':
-- the first is regonized if the last 'double' tab happend longer than 10 seconds ago e.g. 2 hours
print("Script-DoubleTab:first double tab event? -> timeCompaire_FirstDoubleTabDetected>domoticz.data.MaxTime_BetweenFirstSecondDoubeTab:" .. timeCompaire_FirstDoubleTabDetected .. ">" .. domoticz.data.MaxTime_BetweenFirstSecondDoubeTab .. "?")
if (timeCompaire_FirstDoubleTabDetected>domoticz.data.MaxTime_BetweenFirstSecondDoubeTab) then
-------------------------------------------------
-- 1) first double tab -> flash lamp
-------------------------------------------------
domoticz.log("Script-DoubleTab:------------------------------------------------")
domoticz.log("Script-DoubleTab:-- first double tab detected -> flash lamp --")
domoticz.log("Script-DoubleTab:------------------------------------------------")
domoticz.data.FirstDoubleTabDetected= domoticz.time
--flash 1 second light to indicate the first 'double tab' was registered by Domoticz so user can perform second 'double tab'
if (firstDoubleTabRegisterdNotificationLight.state == 'On') then
firstDoubleTabRegisterdNotificationLight.switchOff().forSec(domoticz.data.FlashTime).silent()
else
firstDoubleTabRegisterdNotificationLight.switchOn().forSec(domoticz.data.FlashTime).silent()
end
-- the second 'double tab' is regonized when the last 'double' tab happend within 10 seconds after the first 'double tab'.
else
-------------------------------------------------
-- 2) second double tab -> switch off devices
-------------------------------------------------
domoticz.log("Script-DoubleTab:--------------------------------------------------------------")
domoticz.log("Script-DoubleTab:-- second double tab detected -> switch off devices --")
domoticz.log("Script-DoubleTab:--------------------------------------------------------------")
if (domoticz.data.SwitchOff_ActiveDevices == 1) then
--swich off all ACTIVE devices or switch ON selected ones (lamp,ventilation,plugs)
--------------------------------------------------------
domoticz.log("Script-DoubleTab:switch OFF all ACTIVE devices or swich ON selected Devices")
domoticz.log("Script-DoubleTab:-----------------------------")
domoticz.devices().forEach(function(device)
--select only "Light/Switch" since the 'devices()' method contains all 'devices' so it includes also e.g. current watt/volt meters,...
if (device.deviceType == "Light/Switch" ) then
--if (device.state ~= 'Off') and not(CheckTableContains (DevicesToExcludeAllOff, device.name)) and not(CheckTableContains (DevicesToSwitchOn, device.name)) then
if (device.state ~= 'Off') and not(CheckTableContains (DevicesToExcludeAllOff, device.name)) then
device.switchOff().silent()
print ("Script-DoubleTab:device name=" .. device.name .. " is switched OFF.")
end
if (CheckTableContains (DevicesToSwitchOn, device.name)) then
device.switchOn().silent()
print ("Script-DoubleTab:device name=" .. device.name .. " is switched ON.")
end
end
end) --end statement of "foreach"
end
if (domoticz.data.SwitchOff_AllDevices == 1) then
--swich off all ALL devices as a fall back in case domoticz was not updated correclty with 'on' status
------------------------------------------------------------------------------------------------------
domoticz.log("Script-DoubleTab:switch off ALL devices")
domoticz.log("Script-DoubleTab:----------------------")
domoticz.devices().forEach(function(device)
--select only "Light/Switch" since the 'devices()' method contains all 'devices' so it includes also e.g. current watt/volt meters,...
if (device.deviceType == "Light/Switch" ) then
if not(CheckTableContains (DevicesToExcludeAllOff, device.name)) then
device.switchOff().silent()
--print ("Script-DoubleTab:device name=" .. device.name .. " is switched off.")
end
end
end) --end statement of "foreach"
end
end
end
print("Script-DoubleTab:-----------------END---------------------")
end
}