Bug in my light control script  [Solved]

Easy to use, 100% Lua-based event scripting framework.

Moderator: leecollings

Post Reply
User avatar
Domoberry
Posts: 126
Joined: Tuesday 30 May 2017 19:00
Target OS: Raspberry Pi / ODroid
Domoticz version: 2024.7
Contact:

Bug in my light control script

Post by Domoberry »

Hi Forum,
I have created a DzVents script that controls two lights based on two motion detectors: pass either motion detector, lights should go on for some time (happy flow). Problem is that in some cases (I still cannot reproduce), the lights do not turn off (unhappy flow). I did take into account the hint "Important note when using forXXX()" from the Wiki.
This evening, I captured the unhappy flow in the log and since I'm struggling with this for some time, as unexperienced programmer, decided to ask the forum for advice!
I'm afraid this is a lengthy post since one probably needs all related information (@moderator: feel free to remove and ask me to shorten if preferred)

There is a secondary issue, which could be related. See this post: https://www.domoticz.com/forum/viewtopi ... 24&t=29997. Whenever I trigger the light switch from the Domoticz UI, there are two corresponding 'On' or 'Off' entries in the light switch' log. I see the same double-entry phenomena when the script is controlling the switch. Current conclusion is that these double entries are a side effect of how the (ZWave FGS-223) switch is implemented in Domoticz / OpenZWave.

Here is related information related to this unhappy flow:
The 'Front door - Motion' device get triggered at 19:07:21 and for a while signals 'ON':

Code: Select all

Front door - Motion
2019-11-07 19:07:42	Off
2019-11-07 19:07:21	On
2019-11-07 16:48:09	Off 
2019-11-07 16:47:47	On 
...
At almost the same time, the 'Garage - Motion' detects me passing by as well:

Code: Select all

Garage - Motion
2019-11-07 19:07:31	Off
2019-11-07 19:07:21	On
2019-11-07 16:53:44	Off 
2019-11-07 16:53:23	On 
...
The script also depends on ambience light level; it only works when it is dark. The value of either of the dusk sensors does not change during the unhappy flow and remains 'On' (=dark)

Next is what I see in the log for the Light Outside House switch, where the lights were initially off (the other switch shows the same, I added the numbering):

Code: Select all

FGS-223 Outside House
2019-11-07 19:12:21	On 			(4)
2019-11-07 19:07:21	On			(3)
2019-11-07 19:07:21	On			(2)
2019-11-07 19:07:21	On			(1)
2019-11-07 07:06:21	Off 
2019-11-07 07:06:21	Off 
...
Where I loose track is at (3). (1) and (2) are the 'double' entries for 'On' (see note on double entries above). (3) I cannot really explain, if it was the other motion detector firing at almost the same time, I would have expected two entries again. With (4) things go wrong: this is 5 minutes later, where I would expect the lights to turn Off again. This indeed looks very much like the 'important note' from the wiki, yet, I took the suggested counter measure.

What could go wrong here?

Here is the (verbatim) script, so with all comments, remarks and logging statements included (if you would prefer, I can strip out all the bla bla and repost)

Code: Select all

-- "CB3 Outsight Light" Date: 190624, version 191105.6 
-- some variables/constants
local idxMotionFront = 77 -- Hue front door motion device switch; turns briefly 'on' if motion is detected
local idxDuskFront = 78 -- Hue front door motion device switch; 'on' if it is dark enough
local idxMotionGarage = 317 -- Hue garage door motion device switch; turns briefly 'on' if motion is detected
local idxDuskGarage = 318 -- Hue garage door motion device switch; 'on' if it is dark enough
local idxOutsideLightsSwitchHouse = 303 -- The Z-Wave Fibaro FGS-223 dual on/off relay/switch 1
local idxOutsideLightsSwitchGarage = 306 -- The Z-Wave Fibaro FGS-223 dual on/off relay/switch 2
local lightOnTimeHouse = 5 -- number of minutes the outside House lights should be on when triggered
local lightOnTimeGarage = 7 -- number of minutes the outside Garage lights should be on when triggered

return {
	-- trigger
	on = {
		-- device trigger on either of the motion detectors
		devices = { idxMotionFront, idxMotionGarage } -- Idx for both sensors
    },
    logging = {
        level = domoticz.LOG_DEBUG, -- use LOG_DEBUG if you want more logging, LOG_INFO as default is OK
        marker = 'Outside lights'
    },
	-- actual event code
	execute = function(domoticz, MotionDevice) -- MotionDevice gets the (device) object which triggered the script
	-- trigger could have been from either motion sensor, which one is not relevant for the script. 
        -- log the main input variables for the script
        domoticz.log("Scrip triggered by: " .. MotionDevice.name .. " (idx=" .. tostring(MotionDevice.idx) .. ")" , domoticz.LOG_DEBUG)
        domoticz.log("CB3 Front  Motion/Dusk = " .. tostring(domoticz.devices(idxMotionFront).active) .. " / " .. tostring(domoticz.devices(idxDuskFront).active) , domoticz.LOG_DEBUG)
        domoticz.log("CB3 Garage Motion/Dusk = " .. tostring(domoticz.devices(idxMotionGarage).active) .. " / " .. tostring(domoticz.devices(idxDuskGarage).active) , domoticz.LOG_DEBUG)
        -- note that a motion event triggers this script twice: when motion is 'on' and few seconds later when it goes 'off' again
        -- so, you need to check on the motion and dusk status:
        if ( (MotionDevice.active) and ( (domoticz.devices(idxDuskFront).active) or (domoticz.devices(idxDuskGarage).active) ) ) then 
            -- the motion sensor of the triggering device in 'on' AND it was dark enough on at least one of the dusk sensors
            -- so switch on (or restart the timer/retrigger) the outside lightswitches for the given number of minutes
            -- else do not do anything
            --
            -- do for the House lights
	        domoticz.log("CB3 activating or re-triggering House lights, Motion is ON and at least one Dusk is ON" , domoticz.LOG_DEBUG)
            --
            domoticz.devices(idxOutsideLightsSwitchHouse).switchOff().checkFirst().afterMin(lightOnTimeHouse)
            domoticz.log("Second line in 2 line SwitchHouse command is next" , domoticz.LOG_DEBUG)
            domoticz.devices(idxOutsideLightsSwitchHouse).switchOn().checkFirst().forMin(lightOnTimeHouse)
            --
            -- do the Garage lights
	        domoticz.log("CB3 activating or re-triggering Garage lights, Motion is ON and at least one Dusk is ON" , domoticz.LOG_DEBUG)
            --
            domoticz.devices(idxOutsideLightsSwitchGarage).switchOff().checkFirst().afterMin(lightOnTimeGarage)
            domoticz.log("Second line in 2 line SwitchGarage command is next" , domoticz.LOG_DEBUG)
            domoticz.devices(idxOutsideLightsSwitchGarage).switchOn().checkFirst().forMin(lightOnTimeGarage)
            --
	    else
            -- script was triggered by a state change of either one of the sensors, 
            -- but is was either motion from 'on' to 'off' or not dark enough, so no action needed
	        domoticz.log("CB3 Script triggered, but Motion is OFF and/or Dusk is OFF" , domoticz.LOG_DEBUG)
        end
	end
}
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: Bug in my light control script

Post by waaren »

Domoberry wrote: Thursday 07 November 2019 22:05 What could go wrong here?
My preference for these type of scripts is to leave out the forMin() completely and to work with cancelQueuedCommands(). Something like this.

Code: Select all

-- "CB3 Outsight Light" Date: 190624, version 191105.6 
-- some variables/constants
local idxMotionFront = 77 -- Hue front door motion device switch; turns briefly 'on' if motion is detected
local idxDuskFront = 78 -- Hue front door motion device switch; 'on' if it is dark enough
local idxMotionGarage = 317 -- Hue garage door motion device switch; turns briefly 'on' if motion is detected
local idxDuskGarage = 318 -- Hue garage door motion device switch; 'on' if it is dark enough
local idxOutsideLightsSwitchHouse = 303 -- The Z-Wave Fibaro FGS-223 dual on/off relay/switch 1
local idxOutsideLightsSwitchGarage = 306 -- The Z-Wave Fibaro FGS-223 dual on/off relay/switch 2
local lightOnTimeHouse = 5 -- number of minutes the outside House lights should be on when triggered
local lightOnTimeGarage = 7 -- number of minutes the outside Garage lights should be on when triggered

return {
    -- trigger
    on = {
        -- device trigger on either of the motion detectors
        devices = { idxMotionFront, idxMotionGarage } -- Idx for both sensors
    },
    logging = {
        level = domoticz.LOG_DEBUG, -- use LOG_DEBUG if you want more logging, LOG_INFO as default is OK
        marker = 'Outside lights'
    },
    -- actual event code
    execute = function(domoticz, MotionDevice) -- MotionDevice gets the (device) object which triggered the script
    -- trigger could have been from either motion sensor, which one is not relevant for the script. 
        -- log the main input variables for the script
        domoticz.log("Scrip triggered by: " .. MotionDevice.name .. " (idx=" .. tostring(MotionDevice.idx) .. ")" , domoticz.LOG_DEBUG)
        domoticz.log("CB3 Front  Motion/Dusk = " .. tostring(domoticz.devices(idxMotionFront).active) .. " / " .. tostring(domoticz.devices(idxDuskFront).active) , domoticz.LOG_DEBUG)
        domoticz.log("CB3 Garage Motion/Dusk = " .. tostring(domoticz.devices(idxMotionGarage).active) .. " / " .. tostring(domoticz.devices(idxDuskGarage).active) , domoticz.LOG_DEBUG)
        -- note that a motion event triggers this script twice: when motion is 'on' and few seconds later when it goes 'off' again
        -- so, you need to check on the motion and dusk status:
        if MotionDevice.active and ( domoticz.devices(idxDuskFront).active or domoticz.devices(idxDuskGarage).active ) then 
            -- the motion sensor of the triggering device in 'on' AND it was dark enough on at least one of the dusk sensors
            -- so switch on (or restart the timer/retrigger) the outside lightswitches for the given number of minutes
            -- else do not do anything
            --
            -- do for the House lights
            domoticz.log("CB3 activating or re-triggering House lights, Motion is ON and at least one Dusk is ON" , domoticz.LOG_DEBUG)
            domoticz.devices(idxOutsideLightsSwitchHouse).cancelQueuedCommands()
            domoticz.devices(idxOutsideLightsSwitchHouse).switchOn().checkFirst()
            domoticz.devices(idxOutsideLightsSwitchHouse).switchOff().afterMin(lightOnTimeHouse)
            
            --
            -- do the Garage lights
            domoticz.log("CB3 activating or re-triggering Garage lights, Motion is ON and at least one Dusk is ON" , domoticz.LOG_DEBUG)
            --
            domoticz.devices(idxOutsideLightsSwitchGarage).cancelQueuedCommands()
            domoticz.devices(idxOutsideLightsSwitchGarage).switchOn().checkFirst()
            domoticz.devices(idxOutsideLightsSwitchGarage).switchOff().afterMin(lightOnTimeGarage)
            domoticz.log("Second line in 2 line SwitchGarage command is next" , domoticz.LOG_DEBUG)
            
        else
            -- script was triggered by a state change of either one of the sensors, 
            -- but is was either motion from 'on' to 'off' or not dark enough, so no action needed
            domoticz.log("CB3 Script triggered, but Motion is OFF and/or Dusk is OFF" , domoticz.LOG_DEBUG)
        end
    end
}


Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
User avatar
Domoberry
Posts: 126
Joined: Tuesday 30 May 2017 19:00
Target OS: Raspberry Pi / ODroid
Domoticz version: 2024.7
Contact:

Re: Bug in my light control script  [Solved]

Post by Domoberry »

Hi Waaren,
Thanks for the tip! I implemented your suggestion in the script.
That would indeed remove the 'queued toggle' which could be toggling incorrectly.

Edit 2 days later:
So far the problem has not been seen anymore, and given the suggestion, I'm confident Waaren provided the solution!
Kudos for you!!
(should this be added to the dzVents wiki?)
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest