Plain Lua : commandArray MIMW

Moderator: leecollings

Post Reply
zicht
Posts: 300
Joined: Sunday 11 May 2014 11:09
Target OS: Windows
Domoticz version: 2023.1+
Location: NL
Contact:

Plain Lua : commandArray MIMW

Post by zicht »

Hi,

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
How to use :
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" 
place just before return commandArray --> handle_cArray() : This is mandatory and will fill commandArray at that moment with the real needed commands.

Code: Select all

handle_cArray(cArray)
return commandArray
Rpi & Win x64. Using : cam's,RFXCom, LaCrosse, RFY, HuE, google, standard Lua, Tasker, Waze traveltime, NLAlert&grip2+,curtains, vacuum, audioreceiver, smart-heating&cooling + many more (= automate all repetitive simple tasks)
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest