i have running a MIMW for commandArray for a long time now and maybe i can help someone with it.
It does never write a same value into any device or uservar, it checks and if the same it discarts the command.
1. it is a failsafe to reduce endles repetitions (LOOP!) if i make a scripting mistake.
2. it reduces the need to check before set in script ( although i keep doing that as a good behavior)
3. it removes all unneeded commandArray --> speed-up when having 100+ events/minute
Lua if very efficient and the script cause no noticable delay ( typical device script runs <0.02s what is mostly the base time to load the lua engine for the script)
Code: Select all
cArray={}
function handle_cArray()
for device, newState in pairs(cArray) do
local currentState = otherdevices[device] or ""
local done = false
if device ~= nil and newState ~= nil then
--------------------------------------------------------------------
-- 1. SPECIAL COMMANDS (never state-filtered)
--------------------------------------------------------------------
local isSpecial =
device:sub(1,6) == "Scene:" or
device:sub(1,6) == "Group:" or
device == "OpenURL" or
device == "SendNotification" or
device == "SendEmail" or
device == "TriggerIFTTT" or
device:sub(1,12) == "SendCamera:" or
device == "UpdateDevice"
if isSpecial then
commandArray[device] = newState
print("Special done: ".. device .." "..currentState.."->"..newState)
done = true
end
--------------------------------------------------------------------
-- 2. USER VARIABLE (strict-mode correct)
--------------------------------------------------------------------
if not done and device:sub(1,9) == "Variable:" then
local varName = device:sub(10)
local currentValue = uservariables[varName] or ""
if tostring(currentValue) ~= tostring(newState) then
commandArray[device] = newState
--print("uservariable done: ".. device .." "..currentValue.."->"..newState)
done = true
end
-- Uservars NEVER fall into NORMAL device logic
goto continue
end
--------------------------------------------------------------------
-- 3. TIMING MODIFIERS (AFTER optimization)
--------------------------------------------------------------------
local hasTiming =
newState:match("%sFOR%s") or
newState:match("%sRANDOM%s") or
newState:match("%sREPEAT%s") or
newState:match("%sINTERVAL%s")
if not done and newState:match("%sAFTER%s") and not hasTiming then
local _, n = string.gsub(newState, " ", "")
local findstate = string.find(newState, " ", 1)
local RealnewState = string.sub(newState, 1, findstate - 1)
local cur = otherdevices[device] or ""
if cur == RealnewState and n == 2 then
done = true -- AFTER optimization skip
end
end
--------------------------------------------------------------------
-- 4. SELECTOR SWITCH (Set Level xx)
-- Correct detection: selector = NOT On/Off/Open/Closed
--------------------------------------------------------------------
if not done and newState:match("^Set Level") then
local textState = otherdevices[device] or ""
local isSelector =
textState ~= "" and
textState ~= "On" and
textState ~= "Off" and
textState ~= "Open" and
textState ~= "Closed"
if isSelector then
local newLevel = newState:match("Set Level%s+(%d+)")
local currentLevel = otherdevices_svalues[device]
if tostring(currentLevel) ~= tostring(newLevel) then
commandArray[device] = newState
print("Selector_sw done: ".. device .." "..currentState.."->"..newState)
done = true
end
goto continue
end
end
--------------------------------------------------------------------
-- 5. THERMOSTAT SETPOINT (SetSetPoint:idx)
--------------------------------------------------------------------
if not done and device:sub(1,12) == "SetSetPoint:" then
local idx = device:sub(13)
local current = otherdevices_svalues[idx]
if tostring(current) ~= tostring(newState) then
commandArray[device] = newState
print("Setpoint done: ".. device .." "..currentState.."->"..newState)
done = true
end
end
--------------------------------------------------------------------
-- 7. NORMAL DEVICE STATE (dimmers, switches, bulbs)
--------------------------------------------------------------------
if not done then
if tostring(currentState) ~= tostring(newState) then
commandArray[device] = newState
--print("Normal done: ".. device .." "..currentState.."->"..newState)
done = true
end
end
end
::continue::
-- Strict mode: show all skipped actions except uservars
if not done and device:sub(1,9) ~= "Variable:" then
--if not done then
print("Not done: ".. device .." "..currentState.."->"..newState)
end
end
end
Place the script at top of yours (or user require/load mechanism.)
Replace all commandArray with cArray
Code: Select all
cArray['Plafon spots keuken'] = "On FOR 30" Code: Select all
handle_cArray(cArray)
return commandArray