- Mirror source to Destination
Toggle source to Destination
Turn destination on when source is turned on
Turn destination off when source is turned off
Mirror Dimmer switches or Sets Dimmer to a set value
Hide switches
Update user variables
Use third switch for conditional Access if true or false switch
The script requires a string user variable to be created called ST-Setting. This variable is then populated with the switch IDx numbers and the commands required. Multiple switches can be added to the user variable to create "ripple effects" . Warning there is only limited syntax checking so creating a switch loop is possible.
The script contains the syntax required to link source and destination switches together
Create a new LUA device event called Switch-Link-1.8 and cut and paste the following
Code: Select all
-- This program links two switches together so the actions of the one switch effects the other
--
--These commands can trigger the switches or just effect the Domoticz switches without triggering the action of the switches
--
--
--
-- The program relies on a user string variable to be created in Domoticz interface with the name ST-Setting
-- Use the following syntax for the string value
--
-- IDx|(1)(2)(T)(F)(IDx)|IDx|Command|IDx|(T)(F)(IDx)|IDx|Commands etc
--
-- Where IDx is the source IDx number of virtual switch (obtain the IDx value from the Device list)
-- (T)(F)(IDx)* Only trigger destination if test switch is on (T) or Off (F).
-- (1)(2) (1) way switch source affects destination (2) way switch souce and destination effects each other
-- IDx is the destination IDx number of virtual switch to be linked to the source switch
--
-- Commands
--
-- D Duplicated. ( Source will force the destination switch to match
-- T Toggled ( Source will toggle the destination switch to be the opposite )
-- p on ( source will change the destination switch to be on)
-- M Off ( source will change the destination switch to be off)
-- Fnn* Fixed ( source Dim value will mirror the Destination if dim value set to 00 or change value to nn)
-- H Hide ( Source will Hide destination switch. h will un-dide hidden switch )
--
--
-- Uccc.. UVariable ( Source will trigger IDx of User Variable (string only) to be replaced with
-- charactors specified. @t@ will insert time, @d@ date, @i@ Idx,
-- @n@ name @v@ value @l@ last update)
--
-- Example 120|1|123|T
--
-- Using lowercase letters for the above will change the switch in Domoticz without triggering the action. Usful for resetting
-- switches
--
-- *There is bug in Domoticz. Dim Slider will not match value using fnn . Fnn works correctly but will trigger action
-- see https://www.domoticz.com/forum/viewtopic.php?t=14935
--
--
-- Ver 1.0
--
-- Initial program
--
-- Ver 1.1
--
-- Bug in Command array only actioned last switch action. Updaded to create comand array index
--
-- Ver 1.2
--
-- Change switch test from on and off to off and not off , to allow switch link to work with non-similer switches.
--
-- Ver 1.3
--
-- Added Dimmer switch mirror. Changed commands names to be more logic
--
-- Vesion 1.4
--
-- Added trigger by log
--
-- Version 1.5
--
-- Added Hide and unhide switches and set uservariables
--
-- Version 1.6
--
-- Changed User variables switch to use iDX number of User variable rather than name
--
-- Version 1.7
--
-- Updated to allow Conditional switching. Major change now 4 varibles per switch
--
-- Version 1.8
--
-- Added two way switching ( to reduce ST-Setting length and complexity) and error checking
--
commandArray = {}
-- functions
function split(pString, pPattern)
local Table = {}
local fpat = "(.-)" .. pPattern
local last_end = 1
local s, e, cap = pString:find(fpat, 1)
while s do
if s ~= 1 or cap ~= "" then
table.insert(Table,cap)
end
last_end = e+1
s, e, cap = pString:find(fpat, last_end)
end
if last_end <= #pString then
cap = pString:sub(last_end)
table.insert(Table, cap)
end
return Table
end
function idxname(deviceIDX)
local idx = tonumber(deviceIDX)
for i, v in pairs(otherdevices_idx) do
if v == idx then
return i
end
end
return 0
end
function idxvars(uridx)
urlcall=assert(io.popen("curl 'http://127.0.0.1:8080/json.htm?type=command¶m=getuservariable&idx=" .. uridx .. "'" ))
local urlreply = urlcall:read('*all')
urlcall:close()
local urlsplit = split(urlreply,",")
local urlname = string.gsub(urlsplit[2], '"', "")
urlname = string.sub(urlname,7)
urlname = string.sub(urlname,12)
return urlname
end
-- variables
id=0
cmd=0
Vars = {}
Vars=split(uservariables["ST-Setting"], "|")
Dname = ""
Dname1 = ""
Dname2 = ""
runflag = "T"
s=0
e=0
etime = os.clock()
-- start program
print ("Switch Link started")
-- ensue ST-Settings conatin info
if string.len(uservariables["ST-Setting"]) < 1 then
print ("No ST-Setting Exit script")
print ("Switch link completed in " .. os.clock()-etime)
return commandArray
end
if #Vars % 4 ~= 0 then
print ("ST-Setting invalid Exit script")
print ("Switch link completed in " .. os.clock()-etime)
return commandArray
end
-- check for two way switch. Add revese of switch in Table. Test if valid commands for 1 and 2 way switch
for i=1, #Vars,4 do
if Vars[i+1] == "2" then
if string.match("DTPMFHUch",Vars[i+3]) then
print (Vars[i] .. "|" .. Vars[i+1] .. "|" .. Vars[i+2] .. "|" .. Vars[i+3] .. " invalid two way Switch")
print ("Switch link completed in " .. os.clock()-etime)
return commandArray
end
c= #Vars + 1
Vars[c] = Vars[i+2]
Vars[c+1] = "1"
Vars[c+2] = Vars[i]
Vars[c+3] = Vars[i+3]
end
if Vars[i+1] == "1" then
if Vars[i] == Vars[i+2] then
if string.match("DTPMFHU",Vars[i+3]) then
print (Vars[i] .. "|" .. Vars[i+1] .. "|" .. Vars[i+2] .. "|" .. Vars[i+3] .. " invalid Switch loop")
print ("Switch link completed in " .. os.clock()-etime)
return commandArray
end
end
end
end
-- loop through all the devices
for DomDevice,DeviceValue in pairs(devicechanged) do
-- get IDx number of device
if q == null then
print ("Switch Link triggered by " .. DomDevice)
q = 1
end
id = tostring(otherdevices_idx[DomDevice])
--loop through all variables parsed from ST-Setting
for i=1,#Vars,4 do
-- if device found action command
if (Vars[i] == id) then
-- setup counter for number of commandArray updates
cmd=cmd+1
-- setup fixed variables for device name and action to perform
action = string.sub(Vars[i+3],1,1)
Dname = idxname(Vars[i])
Dname1 = idxname(Vars[i+2])
if Dname1 == 0 then
Dname1 = idxvars(Vars[i+2])
end
-- test for conditinal result
if string.len(Vars[i+1]) > 0 then
Dname2 = idxname(string.sub(Vars[i+1], 2))
flag = string.sub(Vars[i+1], 1, 1)
if otherdevices[Dname2] ~= "On" and flag == "T" then
rint("If option triggered result is " .. runflag)
runflag = "F"
end
if otherdevices[Dname2] == "On" and flag == "F" then
runflag = "F"
rint("If option triggered result is " .. runflag)
end
end
-- duplicate switch
if action == "D" and runflag == "T" then
commandArray[cmd]={[Dname1] = DeviceValue}
print (Dname1 .. " Match " .. Dname)
end
-- duplicate swith in Domoticz only
if action == "d" and runflag == "T" then
if DeviceValue ~="Off" then
Dvalue = Vars[i+2] .. "|1|on"
commandArray[cmd]={["UpdateDevice"] = Dvalue}
end
if DeviceValue == "Off" then
Dvalue = Vars[i+2] .. "|0|off"
commandArray[cmd]={["UpdateDevice"] = Dvalue}
end
print (Dname1 .. " Domoticz switch match " .. Dname)
end
-- Toggle destination switch
if action == "T" and runflag == "T" then
if DeviceValue ~="Off" then
Dvalue = idxname(Vars[i+2])
commandArray[cmd]={[Dname1] = "Off"}
print (Dname1 .. " Off " .. Dname .. " On")
end
if DeviceValue == "Off" then
commandArray[cmd]={[Dname1] = "On"}
print (Dname1 .. " On " .. Dname .. " Off")
end
end
-- turn destination switch on as long as source not off
if action == "P" and runflag == "T" then
if DeviceValue ~="Off" then
commandArray[cmd]={[Dname1] = "On"}
print (Dname1 .. " turn on the same as " .. Dname)
end
end
-- turn destination switch off as long as source not on
if action == "M" and runflag == "T" then
commandArray[cmd]={[Dname1] = "Off"}
print (Dname1 .. " turn off the same as " .. Dname)
end
-- turn destination switch off as long as source is off
if action == "m" and runflag == "T" then
Dvalue = Vars[i+2] .. "|0|off"
commandArray[cmd]={["UpdateDevice"] = Dvalue}
print (Dname1 .. " Domoticz switch off the same as " .. Dname)
end
-- Mirror Dim value to destination
if action == "F" and runflag == "T" then
if string.sub(Vars[i+3], 2, 3) == "00" then
commandArray[cmd]={[Dname1] = (DeviceValue .. " AFTER 1")}
print (Dname1 .. " dimmed to the same as " .. Dname)
else
dimvalue = ("Set Level:" .. string.sub(Vars[i+2], 2, 3) .. "*")
commandArray[cmd]={[Dname1] = dimvalue}
print (Dname1 .. " dimmed to " .. string.sub(Vars[i+2], 2, 3))
end
end
-- Hides destination switch
if action == "H" and runflag == "T" then
Dname1 = ("$" .. Dname1)
url = ("http://127.0.0.1:8080/json.htm?type=command¶m=renamedevice&idx=" .. Vars[i+2] .. "&name=" .. Dname1)
commandArray[cmd]={["OpenURL"] = url}
end
if action == "U" and runflag == "T" then
d = tostring(os.date("%x"))
t = tostring(os.date("%X"))
l = otherdevices_lastupdate[Dname]
v = otherdevices_svalues[Dname]
uvar = string.sub(Vars[i+3],2)
uvar = string.gsub(uvar, "@d@", d)
uvar = string.gsub(uvar, "@t@", t)
uvar = string.gsub(uvar, "@i@", Vars[i])
uvar = string.gsub(uvar, "@n@", Dname)
uvar = string.gsub(uvar, "@l@", l)
uvar = string.gsub(uvar, "@v@", v)
uvar = string.gsub(uvar, " ", "%%20")
url = ("http://127.0.0.1:8080/json.htm?param=updateuservariable&type=command&vname=" .. Dname1 .."&vtype=2&vvalue=" .. uvar )
print ("User Variable " .. Dname1 .. " triggered with " .. uvar)
commandArray[cmd]={["OpenURL"] = url}
end
-- Toggle destination switch on in Domoticz
if action == "t" and runflag == "T" then
if DeviceValue ~="Off" then
Dvalue = Vars[i+2] .. "|0|off"
commandArray[cmd]={["UpdateDevice"] = Dvalue}
print (Dname1 .. " Domoticz switch off " .. Dname .. " On")
end
if DeviceValue == "Off" then
Dvalue = Vars[i+2] .. "|1|on"
commandArray[cmd]={["UpdateDevice"] = Dvalue}
print (Dname1 .. " Domoticz switch on " .. Dname .. " Off")
end
end
-- Mirror Dim value to destination
if action == "f" and runflag == "T" then
if string.sub(Vars[i+3], 2, 3) == "00" then
Dvalue = Vars[i+2] .. "|2|" .. string.sub(DeviceValue, 12, 14)
commandArray[cmd]={["UpdateDevice"] = Dvalue}
print (Dname1 .. " dimmed to the same as " .. Dname)
else
Dvalue = Vars[i+1] .. "|2|" .. string.sub(Vars[i+3], 2, 3)
commandArray[cmd]={["UpdateDevice"] = Dvalue}
print (Dname1 .. " dimmed to " .. string.sub(Vars[i+3], 2, 3))
end
end
-- turn destination switch in Domoticz on as long as source not off
if action == "p" and runflag == "T" then
if DeviceValue ~="Off" then
Dvalue = Vars[i+2] .. "|1|On"
commandArray[cmd]={["UpdateDevice"] = Dvalue}
print (Dname1 .. " Domoticz switch on the same as " .. Dname)
end
end
-- Shows destination switch
if action == "h" and runflag == "T" then
url = ("http://127.0.0.1:8080/json.htm?type=command¶m=renamedevice&idx=" .. Vars[i+2] .. "&name=" .. Dname1)
commandArray[cmd]={["OpenURL"] = url}
end
if action == "u" and runflag == "T" then
d = tostring(os.date("%x"))
t = tostring(os.date("%X"))
l = otherdevices_lastupdate[Dname]
v = otherdevices_svalues[Dname]
uvar = string.sub(Vars[i+3],2)
uvar = string.gsub(uvar, "@d@", d)
uvar = string.gsub(uvar, "@t@", t)
uvar = string.gsub(uvar, "@i@", Vars[i])
uvar = string.gsub(uvar, "@n@", Dname)
uvar = string.gsub(uvar, "@l@", l)
uvar = string.gsub(uvar, "@v@", v)
Dname1 = ("Variable:" .. Dname1)
print ("User Variable " .. Dname1 .. " updated with " .. uvar)
commandArray[cmd]={[Dname1] = uvar}
end
end
end
end
print ("Switch link completed in " .. os.clock()-etime)
return commandArray