switch and sensor combination  [Solved]

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

Moderator: leecollings

abaratian
Posts: 22
Joined: Thursday 12 July 2018 20:19
Target OS: Windows
Domoticz version: 2021.1
Contact:

switch and sensor combination

Post by abaratian »

Hi,
The scenario is as follows:
a switch and a motion sensor are connected to a lamp.
I want:
1. when someone enters the room sensor should turn on lamp
2. when someone enters the room and presses the switch, the light should stay on no matter if there is presence or not. Pressing the switch again should turn off the light. in other words the switch should override sensor.

I can't figure out part 2. Can anyone help me?
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: switch and sensor combination

Post by waaren »

abaratian wrote: Sunday 20 October 2019 6:18 1. when someone enters the room sensor should turn on lamp
2. when someone enters the room and presses the switch, the light should stay on no matter if there is presence or not. Pressing the switch again should turn off the light. in other words the switch should override sensor.
Can you try this ?

Please note:
Control of lamp when motion detection is activated is by this dzVents script. The physical lamp should not be programmed to receive anything from motion detector.
Lamp and switch should be separate objects in domoticz

Code: Select all

--[[

    a switch and a motion sensor are connected to a lamp.
    1. when someone enters the room sensor should turn on lamp
    2. when someone enters the room and presses the switch, the light should stay on no matter if there is presence or not. 
        Pressing the switch again should turn off the light. In other words the switch should override sensor.

    !! Control of lamp by Motion detection is done by dzVents physical lamp should not be programmed to receive anything from motion detector.
    !! lamp and switch should be separate objects in domoticz 
]] --

-- Change these to reflect the names of your light, switch and motion detector

local lamp = 'lamp'
local motion = 'motion'
local switch = 'switch'

-- No changes below this line necessary

return 
{
    on =
    {   
        devices        = { motion, switch },
    }, 

    logging =   
    {   
        level =  domoticz.LOG_DEBUG,   
        marker =  "LightControl" 
    },    

    data =
    {   
        time = { initial = { 0 } },
    },
                            
    execute = function(dz, item)
        
        local lamp = dz.devices(lamp)
        local motion = dz.devices(motion)
        local switch = dz.devices(switch)
        
        local lampOnTime = 300 -- On time when switched by motion detector

        dz.log('state of lamp:     ' .. lamp.state,dz.LOG_DEBUG)
        dz.log('state of switch:   ' .. switch.state,dz.LOG_DEBUG)
        dz.log('state of motion:   ' .. motion.state,dz.LOG_DEBUG)
        
        if item == motion then
            if switch.active then 
                return -- no action needed when switch == 'On'
            elseif motion.active then
                lamp.cancelQueuedCommands()
                lamp.switchOn()
                lamp.switchOff().afterSec(lampOnTime)
            end
        else -- switch 
            lamp.cancelQueuedCommands()
            if switch.active then 
                lamp.switchOn()
            else
                lamp.switchOff()
            end    
        end
    end
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
abaratian
Posts: 22
Joined: Thursday 12 July 2018 20:19
Target OS: Windows
Domoticz version: 2021.1
Contact:

Re: switch and sensor combination

Post by abaratian »

waaren wrote: Sunday 20 October 2019 7:14
abaratian wrote: Sunday 20 October 2019 6:18 1. when someone enters the room sensor should turn on lamp
2. when someone enters the room and presses the switch, the light should stay on no matter if there is presence or not. Pressing the switch again should turn off the light. in other words the switch should override sensor.
Can you try this ?

Please note:
Control of lamp when motion detection is activated is by this dzVents script. The physical lamp should not be programmed to receive anything from motion detector.
Lamp and switch should be separate objects in domoticz

Code: Select all

--[[

    a switch and a motion sensor are connected to a lamp.
    1. when someone enters the room sensor should turn on lamp
    2. when someone enters the room and presses the switch, the light should stay on no matter if there is presence or not. 
        Pressing the switch again should turn off the light. In other words the switch should override sensor.

    !! Control of lamp by Motion detection is done by dzVents physical lamp should not be programmed to receive anything from motion detector.
    !! lamp and switch should be separate objects in domoticz 
]] --

-- Change these to reflect the names of your light, switch and motion detector

local lamp = 'lamp'
local motion = 'motion'
local switch = 'switch'

-- No changes below this line necessary

return 
{
    on =
    {   
        devices        = { motion, switch },
    }, 

    logging =   
    {   
        level =  domoticz.LOG_DEBUG,   
        marker =  "LightControl" 
    },    

    data =
    {   
        time = { initial = { 0 } },
    },
                            
    execute = function(dz, item)
        
        local lamp = dz.devices(lamp)
        local motion = dz.devices(motion)
        local switch = dz.devices(switch)
        
        local lampOnTime = 300 -- On time when switched by motion detector

        dz.log('state of lamp:     ' .. lamp.state,dz.LOG_DEBUG)
        dz.log('state of switch:   ' .. switch.state,dz.LOG_DEBUG)
        dz.log('state of motion:   ' .. motion.state,dz.LOG_DEBUG)
        
        if item == motion then
            if switch.active then 
                return -- no action needed when switch == 'On'
            elseif motion.active then
                lamp.cancelQueuedCommands()
                lamp.switchOn()
                lamp.switchOff().afterSec(lampOnTime)
            end
        else -- switch 
            lamp.cancelQueuedCommands()
            if switch.active then 
                lamp.switchOn()
            else
                lamp.switchOff()
            end    
        end
    end
}
Hi and thanks for the quick reply. sorry I wasn't clear enough about the situation. The lamp is not 'smart' and can't be controlled via domoticz. The switch is controlling the lamp. The load wire goes through the switch to the lamp and the sensor is wireless.
hestia
Posts: 357
Joined: Monday 25 December 2017 23:06
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.1
Location: Paris
Contact:

Re: switch and sensor combination

Post by hestia »

Hi
so you should have a smart device for you light like Qubino (Goap) ZMNHDD1 Flush Dimmer, Qubino (Goap) ZMNHADx Flush 1 Relay, FIBARO System FGD212, Dimmer 2+, Qubino (Goap) ZMNHBDx Flush 2 Relays+, Qubino (Goap) ZMNHSDx Din Dimmer+
If it is the case I did a script that do what you want but with several switches, lights, PIR and areas.
Perhaps you could look at it or use it with 1 item only in the array instead of several (I hope it works with 1 item only!).
A the present time the are some issues with z-waves like trigger even though in silent mode, that's why I had to had a workaround
https://www.domoticz.com/forum/viewtopi ... 99#p224799

Code: Select all

--[[
A dzVents Script to manage lights with switches and PIR.
For a place with several areas (a set of PIR, lights and switches).
Some use cases:
When the PIR is triggered if it is enough night, the lights are switch on, if not already on.
After if the switch is used (better if a push button),  the lights that were switch on by the PIR are switched off.
When the switch is used if it is enough night, the lights are switch on, if not already on.
During the day, if you switch on the lights, there are switched off

The lighs are switched off after a delay (different if on by PIR or switch)
You could have active and passive (for monitoring only) PIR: with active PIR the lights are switched on ; with passive PIR the switches are only switched off by button, by there are switched off after a delay
There is also a double-check to be sure the lights are really off


In French (pas la traduction exacte, un texte plus ancien)
Pour gérer l'éclairage d'un lieu comprenant plusieurs zones (ensemble de PIR, de lumières et de switches).
Selon les règles suivantes:
Lorsque un détecteur est activé et si c'est la nuit, on allume toutes les lumières qui ne sont pas déjà allumées.
Lorsque un interrupteur est activé on éteint les lumières qui viennent d'être allumés par un PIR et/ou, si c'est la nuit, on allume les lumières associées à cet interrupteurs
Les lumières sont éteintes au bout d'un temps défini selon que c'est un PIR ou un switche qui les a allumées, et à partir de la dernières fois qu'un PIR ou un switch les concernant a été activé
La nuit est déterminée par l'heure ou par la luminosité

V1: 20/10/2019
--]]

-- --[[

local DOMAIN = 'LumExtV4R1' -- For logging, as you like!
local ZONE_PIR= {{514, 620}, {659, 623}} -- PIR classified in zone (like the lights)
local ZONE_LIGHT= {{700, 453}, {142, 112}, {645}} -- lights classified in zone
local GROUP_LIGHT= {{700, 453}} -- group of lights (that work together)
local PIR_ALL = {620, 623} -- list of PIR that switch on all the lights - the others only switch on the lights of their zone
local PIR_MONITOR = {659} -- list of PIR that only check to switch off the lights
local DEOL = 270 -- dummy switch to pilot the on time
local DEVICES =  {DEOL, 453, 142, 112, 514, 620, 659, 623, 645} -- All the devices to trigger the script ; do not put the slaves (cf. GROUP_LIGHT)
local LUX = 305 -- idx device to get the illuminance
local LUX_MIN_PIR = 250 -- illuminance minimum in Lux to consider it's night enough to switch ON lights automatically; if nul night time is used
local LUX_MIN_SWITCH = 300 -- illuminance minimum in Lux to consider it's night enough to switch ON lights manualy ; if nul night time is used
local MAX_PIR = 100 -- 180 --  seconds ; time to keep on lights when switched on by PIR
local MAX_SWITCH = 3600 -- 300 -- 3600/12 -- seconds ; time to keep on lights when switched on by switch / bigger than MAX_PIR!
local TARGET_DIM_LEVEL = 80
local TIME_INTERVAL = 'every 30 minutes' -- Period to double-check if there is any light to switch off, in case of something went wrong

-- --]]

--[[

local DOMAIN = 'TestLum' -- For logging, as you like!
local ZONE_PIR= {{202}, {207}} -- PIR classified in zone (like the lights)
local ZONE_LIGHT= {{203, 204}, {205, 206, 214}, {460}} -- lights classified in zone
local GROUP_LIGHT= {{203, 204}, {206, 214}} -- group of lights (that work together)
local PIR_ALL = {202} -- list of PIR that switch on all the lights - the others only switch on the lights of their zone
local PIR_MONITOR = {207} -- list of PIR that only check to switch off the lights
local DEOL = 271 -- dummy switch to pilot the on time
local DEVICES =  {DEOL, 203, 204, 205, 206, 214, 202, 207, 460}-- All the devices to trigger the script
local LUX = 0 --305 -- idx device to get the illuminance
local LUX_MIN_PIR = 300 -- illuminance minimum in Lux to consider it's night enough to switch ON lights automatically; if nul night time is used
local LUX_MIN_SWITCH = 400 -- illuminance minimum in Lux to consider it's night enough to switch ON lights manualy ; if nul night time is used
local MAX_PIR = 20 --  seconds ; time keep on light on when switch on by PIR
local MAX_SWITCH = 40 -- 3600/12 -- seconds ; time keep on light on when switch on by switch / bigger than MAX_PIR
local TARGET_DIM_LEVEL = 60
local TIME_INTERVAL = 'every 10 minutes' -- Period to check if any light to switch off, in case of something wrong
local TEST_NIGHT = true
--]]

local CHECKOFF_SEC = 10 -- delay before checking if all light are off
local FALSETRIGGER_SEC = 6 -- delay to wait to avoid false trigger (in case of a bug on .silent)

return {
    active = true,
    logging = {
	level = domoticz.LOG_FORCE, -- Select one of LOG_DEBUG, LOG_INFO, LOG_ERROR, LOG_FORCE to override system log level -- normal = LOG_ERROR
	marker = DOMAIN
	},
    on = {
        devices = DEVICES,
        timer = {TIME_INTERVAL},
  	},
    data = {
		deviceOn = {initial={}},
		timeOn = {initial={}},
		checkOff = {initial=true},
	},
        
    execute = function(dz, the_device, triggerInfo)
        
    local LOG_LEVEL = dz.LOG_FORCE -- LOG_INFO, LOG_DEBUG, LOG_ERROR, LOG_FORCE  - normal = LOG_INFO
        
    local l_ForSec = 99999
    local Time = require('Time')
	local l_time = Time()
	local l_deviceOn = dz.data.deviceOn
	local l_timeOn = dz.data.timeOn
	
	local l_night_PIR=false
	local l_night_SWITCH=false 
    local l_day_night ='day'
    if LUX == 0 then
        --print ("N/D w time " .. tostring(isNightTime))
        if dz.time.isNightTime or TEST_NIGHT then
            l_night_PIR = true
            l_night_SWITCH = true
            l_day_night ='night'
        end
    else
        --print ("N/D w LUX idx: " .. LUX .. " Lux: " .. dz.devices(LUX).lux)
        if dz.devices(LUX).lux < LUX_MIN_SWITCH then
            l_night_SWITCH = true
            l_day_night ='night for switch only'
        
            if dz.devices(LUX).lux < LUX_MIN_PIR then
                l_night_PIR = true
                l_day_night ='night'
            end
        end
    end
   	dz.log('*** start ' .. triggerInfo.type .. ' ' .. l_time.raw .. ' ' ..  l_day_night, dz.LOG_FORCE)
  
--- FUNCTIONS BEG --------------------------------------------------------------


local function checkFalseTrigger (theItemId)
    -- to check if there is a false trigger due to .silent issue
    --print('function checkFalseTrigger ' .. theItemId)
    --print(l_deviceOn[theItemId])
    --if dz.devices(theDeviceId).active and l_deviceOn[theItemId]~= 'S' then -- 28/08/2019 -- to avoid false wrong trigger in case of switch off (13/09/2019) not after a switch on
        -- 01/10/2019 removed because it is possible to have z false switch off by the deviced
        local f_sec_delta = 0
        if l_timeOn[theItemId] ~= nil then -- and l_timeOn[theItemId] ~= 0 and l_timeOn[theItemId].raw ~= nil then
            --print ("time "  .. l_time.raw)
            --print("timeOn " .. l_timeOn[theItemId].raw)
            f_sec_delta = l_time.compare(l_timeOn[theItemId]).secs
            --if l_deviceOn[theItemId]== 'S' or l_deviceOn[theItemId]== 'P' then
                if f_sec_delta < FALSETRIGGER_SEC then
                    dz.log('! Wrong trigger - to stop the script ' .. dz.devices(theItemId).name .. ' ' .. dz.devices(theItemId).state .. ' ' .. l_deviceOn[theItemId] .. ' delta sec ' .. f_sec_delta,  dz.LOG_ERROR)
                    return true
                end
            --end
        end
    --end
    dz.log('Trigger OK - to continue the script ' .. dz.devices(theItemId).name .. ' ' .. dz.devices(theItemId).state,  dz.LOG_LEVEL)
    return false
end


local function theArray2Id (theArray, theItemId)
    -- find the sub array where the item is in the array (of 2 levels)
    local array2Id
   
    -- print('function theArray2Id')
    -- print('theItemId: ' .. theItemId)
    for i1, l1 in ipairs(theArray) do
        -- print('i1: ' .. i1)
        for i2, l2 in pairs(theArray[i1]) do
            --print('i2: '  .. i2)
            --print('l2: '  .. l2)
            if theItemId == l2 then
                --print 'OK'    
                --print("theItemId: " .. theItemId)
                --print('level1: ' .. i1)
                --print('level[]: ' .. l1[i2])
                --print('theArray[iz]: ' .. theArray[i1][i2])
                array2Id=i1
                break
            end
        end
        if array2Id ~= nill then break end
    end
    return array2Id
end


local function ifItemPresent2 (theArray, theItemId)
    -- find if the item is in the array (of 2 levels)
    local ItemPresent=false
    --print('function ifItemPresent2')
    --print('theItemId: ' .. theItemId)
    for i1, l1 in ipairs(theArray) do
        --print('i1: ' .. i1)
        for i2, l2 in pairs(theArray[i1]) do
            --print('i2: '  .. i2)
            --print('l2: '  .. l2)
            if theItemId == l2 then
                --print 'OK'    
                --print("theItemId: " .. theItemId)
                --print('level1: ' .. i1)
                --print('level[]: ' .. l1[i2])
                --print('theArray[iz]: ' .. theArray[i1][i2])
                ItemPresent=true
                break
            end
        end
        if ItemPresent then break end
    end
    return ItemPresent
end


local function ifItemPresent (theArray, theItemId)
    -- find if the item is in the array (of 1 level)
    local ItemPresent=false
    -- --print('function ifItemPresent')
    -- --print('theItemId: ' .. theItemId)
    for i1, l1 in ipairs(theArray) do
        --print('i1: ' .. i1)
        if theItemId == l1 then
            --print 'OK'    
            --print("theItemId: " .. theItemId)
            ItemPresent=true
            break
        end
       if ItemPresent then break end
    end
    return ItemPresent
end


local function switchOnLight (theDeviceId, PSX, Monitor)
    --switch on 1 light
    --print('function switchOnLight')
    --print('theDeviceId: ' .. theDeviceId)
    local deviceActive=true
    if dz.devices(theDeviceId).active then
        --if dz.devices(theDeviceId).switchType == 'Dimmer' then
           --if dz.devices(theDeviceId).level ~= TARGET_DIM_LEVEL then 
              --dz.devices(theDeviceId).dimTo(TARGET_DIM_LEVEL).silent()
           --end 
        --end
        --print('switchOnLight device active')
        dz.log(dz.devices(theDeviceId).name .. " " .. theDeviceId .. "  already active ", LOG_LEVEL)
    else
        if not Monitor then -- the PIR is to switch on a light or it is a switch
            deviceActive=false
            if dz.devices(theDeviceId).switchType == 'Dimmer' then
                --print('Dimmer')
                dz.devices(theDeviceId).dimTo(TARGET_DIM_LEVEL).silent()
            else
                --print('Not Dimmer')
                dz.devices(theDeviceId).switchOn().silent()
            end
            dz.log(dz.devices(theDeviceId).name .. " " .. theDeviceId .. " to On", LOG_LEVEL)
        end
    end
    if PSX == 'S' then  -- 05/08/2019
        l_deviceOn[theDeviceId]= 'S'
    elseif PSX == 'P' then
        if l_deviceOn[theDeviceId] ~= 'S' then
            l_deviceOn[theDeviceId]= 'P'
        end
    else
         dz.log('switchOnLight PSX error ' .. PSX, dz.LOG_ERROR)
    end 
    
    l_timeOn[theDeviceId] = l_time -- last 'on' time
    return deviceActive
end

local function switchOffLight (theDeviceId)
    --switch off 1 light
    -- print('function switchOffLight')
    -- print('theDeviceId: ' .. theDeviceId)
    -- print (l_time.raw)
    -- if (triggerInfo.type == 'device') then -- 12/08/2019 comments to avoid last seen update
        dz.devices(theDeviceId).switchOff().checkFirst().silent()
    --else -- timer, to check if some light could have been left on
        --dz.devices(theDeviceId).switchOff().silent() -- 09/08/2019 in case  dz don't have the right status
        --print('function switchOffLight: timer')
    --end
    
    l_deviceOn[theDeviceId]= 'X'
    l_timeOn[theDeviceId] = l_time -- last change state
    --local deviceActive=false
end


local function switchOnLightArray (theArray, PSX, Monitor)
    -- switch on all the lights of the array (1 level)
    --print('function switchOnLightArray')
    local deviceActive = false
    local allDeviceActive = true
    for i1, l1 in ipairs(theArray) do
        --print('Light: ' .. i1 .. ' ' .. l1)
        --if ItemIdToIgnore == l1 then
                --print ('ItemIdToIgnore: ' .. l1)
        --else 
            deviceActive=switchOnLight(l1, PSX, Monitor)
            if not deviceActive then
                allDeviceActive=false
            end
        --end
        --print('deviceActive: ' ..  tostring(deviceActive))
    end
    return allDeviceActive
end


local function switchOffLightArray (theArray, PSX)
    --switch off all the lights of the array (1 level)
    --print('function switchOffLightArray ' .. PSX)
    local l_sec_delta = 0
    local l_ForSecTmp = 0
    for i1, l1 in ipairs(theArray) do
        --print('light: ' .. i1 .. ' ' .. l1 .. ' PSX: ' .. PSX)
        if PSX == 'T' or PSX == 'XT' then -- to check if it is time to turn off the light
            --print ('MAX_SWITCH ' .. MAX_SWITCH)
            --print('MAX_PIR ' .. MAX_PIR)
            --print ("l1 " .. l1)
            
            if not l_timeOn[l1] then
              --l_timeOn[l1] = 0
              --l_sec_delta = 0
              l_sec_delta = MAX_SWITCH+1 -- 07/07/2019
            else
                l_sec_delta = l_time.compare(l_timeOn[l1]).secs
            end
            
            if not l_deviceOn[l1] then
              l_deviceOn[l1] = '?'
            end
            
            --print('l_sec_delta ' .. l_sec_delta)   -- :-( !!!! S éteint qd P éteint !!!!!!!!!!!
                if l_sec_delta > MAX_SWITCH
                or (l_deviceOn[l1] == 'P' and l_sec_delta > MAX_PIR)
                or (l_deviceOn[l1] == 'P' and PSX == 'XT')
                or l_deviceOn[l1] == 'X' then  -- 30/05/2019 removed / 07/07/2019 replaced!
                    switchOffLight(l1)
                    --print ('switchoff ' .. PSX)
                end

             -- calculate the time before triggering this script to switch off the next light
    	  
    	    if l_deviceOn[l1] == 'P' then
    	        l_ForSecTmp = MAX_PIR - l_sec_delta
    	        dz.log("switchOffLightArray: P l_ForSecTmp " .. l_ForSecTmp .. " l_sec_delta " .. l_sec_delta, LOG_LEVEL)
        	    if l_ForSec > l_ForSecTmp then 
        	        l_ForSec = l_ForSecTmp
        	         --dz.log("P !!!" .. l_ForSec, LOG_LEVEL)
    	        end
            elseif l_deviceOn[l1] == 'S' then
               l_ForSecTmp = MAX_SWITCH - l_sec_delta
	           dz.log("switchOffLightArray: S l_ForSecTmp " .. l_ForSecTmp .. " l_sec_delta " .. l_sec_delta, LOG_LEVEL)
    	       if l_ForSec > l_ForSecTmp then 
        	        l_ForSec = l_ForSecTmp
        	          --dz.log("S !!!" .. l_ForSec, LOG_LEVEL)
    	        end
    	    end
           
            --dz.log("l_ForSec " .. l_ForSec, LOG_LEVEL)
            if not l_timeOn[l1] then
                --print ("l1 => " .. l1)
                --print( dz.devices(l1).name)
                   --print( dz.devices(l1).state)
                   --print("devOn " .. l_deviceOn[l1])
                   --print("secdelta " .. l_sec_delta)
                dz.log(l1 .. '  ' .. dz.devices(l1).name .. ' ' .. dz.devices(l1).state .. ' ' .. l_deviceOn[l1] .. ' timeOn 0 delta sec ' .. l_sec_delta,  dz.LOG_FORCE)
            else 
                dz.log(l1 .. '  ' .. dz.devices(l1).name .. ' ' .. dz.devices(l1).state .. ' ' .. l_deviceOn[l1] .. ' timeOn ' .. l_timeOn[l1].raw .. ' delta sec ' .. l_sec_delta,  dz.LOG_FORCE)
            end
        else
            switchOffLight(l1)
        end
    end
    return allDeviceActive
end


local function switchOnLightArray2 (theArrayL1, theArrayL2, PSX)
    -- switch on all the lights of the array L2 (lights) regarding the zones of the array L1 (PIRs)
    local deviceActiveL1 = true
    local allDeviceActive = true
    --print('function switchOnLightArray2')
    for i1, l1 in ipairs(theArrayL1) do
        --print('i1: ' .. i1) 
        deviceActiveL1 = switchOnLightArray (theArrayL2[i1], PSX)
        if not deviceActiveL1 then
            allDeviceActive=false
        end
    end
    return allDeviceActive
end


local function switchOffLightArray2 (theArray, PSX)
    -- switch off all the lights of the array (of 2 levels) eventually filtered with PSX
    --print('function switchOffLightArray2')
    for i1, l1 in ipairs(theArray) do
        --print('i1: ' .. i1)
        deviceActiveL1 = switchOffLightArray (theArray[i1], PSX)
    end
end

local function checkLightActive2 (theArray)
    -- check if any light is already on in the array (of 2 levels)
    --print('function chechLightOn2')
    local anyActive=false
    for i1, l1 in ipairs(theArray) do
        --print('i1: ' .. i1)
        for i2, l2 in pairs(theArray[i1]) do
            --print('i2: '  .. i2)
            --print('l2: '  .. l2)
            if dz.devices(l2).active then
               anyActive=true
               --print('anyActive')
               return anyActive
            end
        end
    end
    return anyActive
end

--- FUNCTIONS END --------------------------------------------------------------
--------------------------------------------------------------------------------  

    local itemId = the_device.id
    local allDeviceActive = true
    local theDeviceOn = false
    local theSwitchOff = false
    local PIRMonitor = false
    local zoneMode=true
    
    if (triggerInfo.type == 'device') then
        if ifItemPresent2(ZONE_PIR, itemId) then -- this device is a PIR 
            dz.log('PIR: ' .. itemId .. ' ' ..  the_device.name.. ' ' ..  the_device.state,  LOG_LEVEL)
            if l_night_PIR then --at night
                --dz.log('PIR: ' .. itemId .. ' ' ..  the_device.name.. ' ' ..  the_device.state,  LOG_LEVEL)
            
                if not the_device.active then -- a switchOff signal from the PIR: used to check if some lights to switch off
                    --print('PIR not active')
                else
                    if ifItemPresent(PIR_MONITOR, itemId) then -- this PIR only check to swith off the lights
                        --print('PIR_MONITOR: ' .. itemId)
                        PIRMonitor = true
                    else
                        if ifItemPresent(PIR_ALL, itemId) then -- this PIR could switch on all light
                            --print('anyActive: ' ..  tostring(anyActive))
                            if not checkLightActive2 (ZONE_LIGHT) then -- if no light is already on
                                --print('All lights are off')
                                allDeviceActive = switchOnLightArray2 (ZONE_PIR, ZONE_LIGHT, 'P')
                                zoneMode=false -- if any light is on, only the lights in the PIR zone are switch on / light on all lights if no light is on
                            end
                        end
                    end
                    if zoneMode then -- 
                        --print('Lights on of the PIR zone')
                        local zoneId = theArray2Id(ZONE_PIR, itemId)
                        --print('zoneId: ' .. zoneId)
                        allDeviceActive = switchOnLightArray(ZONE_LIGHT[zoneId], 'P', PIRMonitor)
                    end
                end
            end
        elseif ifItemPresent2(ZONE_LIGHT, itemId) then -- this device is a switch
            dz.log('SWITCH: ' .. itemId .. ' ' .. the_device.name .. ' ' ..  the_device.state,  LOG_LEVEL)
            if l_night_SWITCH then -- at night
                local FalseTrigger=checkFalseTrigger(itemId)
                if FalseTrigger then
                    return -- it is a false trigger due to .silent issue
                end
                if the_device.active then
                    theDeviceOn = true
                    -- dz.log('l_theDeviceOn true' ,  LOG_LEVEL)
                else
                    theDeviceOn = false
                    theSwitchOff = true
                    -- dz.log('l_theDeviceOn false' ,  LOG_LEVEL)
                end
                local slaveId = theArray2Id(GROUP_LIGHT, itemId)
                if slaveId ~= nil then
                    --print('slaveId: ' .. slaveId)
                    --retreive the level to light the slave with the same level <= NOT MADE !!!
                    if theDeviceOn then
                        --print('go to switchOnLightArray')
                        allDeviceActive = switchOnLightArray(GROUP_LIGHT[slaveId], 'S') -- , itemId)  !!!!!!!!!!!!!!!!!!!!
                    else
                        --print('go to switchOffLightArray')
                        switchOffLightArray(GROUP_LIGHT[slaveId], 'X') 
                    end
                else -- no slaves
                    if theDeviceOn then
                        --print("switchOnLight " .. itemId)
                        switchOnLight (itemId, 'S')
                    else
                        --print("switchOffLight " .. itemId)
                        switchOffLight (itemId)
                    end 
                end
            else
                switchOffLight (itemId)
            end
        elseif itemId ~= DEOL then
            dz.log('Nor LIGHT, nethier PIR ?! ' .. itemId, dz.LOG_ERROR)
        else
            dz.log('DEOL: ' .. itemId .. ' ' .. the_device.name .. ' ' ..  the_device.state,  LOG_LEVEL)
        end
    end
-- [[  
    dz.log('*** end ' , dz.LOG_FORCE)
    if theSwitchOff then -- somebdy switchoff a light, if after a PIR, all light switch on by the PIR are switch off
        --print ('theSwitchOff')
        switchOffLightArray2(ZONE_LIGHT, 'XT')
    else
        switchOffLightArray2(ZONE_LIGHT, 'T') -- to check if it's time to switch off some lights
    end

    -- activate a dummy device to trigger the script to switch off the next lights
    if DEOL ~= nill then
        if l_ForSec < 9999 then -- a light to switch off in a while
            dz.data.checkOff = true
        else -- not a light to switch off
            if dz.data.checkOff then -- if first time, a 2nd round to secure the switch off
                l_ForSec = CHECKOFF_SEC -- number off seconds for the 2nd round
                if not checkLightActive2 (ZONE_LIGHT) then -- if any light is already on
                    dz.data.checkOff = false -- one more check
                end
                --print ('check in ' .. l_ForSec .. ' sec')
            end
        end 
        
        if l_ForSec < 9999 then
            dz.log('Next check in ' .. l_ForSec .. ' sec',  dz.LOG_FORCE)
            l_ForSec = l_ForSec + 3
            dz.devices(DEOL).cancelQueuedCommands()
            dz.devices(DEOL).switchOn().silent()
            dz.devices(DEOL).switchOff().afterSec(l_ForSec)
        else
            dz.log('All is switched off',  dz.LOG_FORCE)
            dz.devices(DEOL).cancelQueuedCommands()
            dz.devices(DEOL).switchOff().silent()
        end
    end
--]]
    dz.data.deviceOn = l_deviceOn
    dz.data.timeOn = l_timeOn

end}
Hope this help
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: switch and sensor combination

Post by waaren »

abaratian wrote: Sunday 20 October 2019 11:34 The lamp is not 'smart' and can't be controlled via domoticz. The switch is controlling the lamp. The load wire goes through the switch to the lamp and the sensor is wireless.
OK. Can you try this >

Code: Select all

--[[

    a switch connected to a lamp. Motion sensor should trigger switch
    1. when someone enters the room sensor should turn on lamp
    2. when someone enters the room and presses the switch, the light should stay on no matter if there is presence or not. 
        Pressing the switch again should turn off the light. In other words the switch should override sensor.

]] --

-- Change these to reflect the names of your light, switch and motion detector

local motion = 'motion'
local switch = 'switch'

-- No changes below this line necessary

return 
{
    on =
    {   
        devices        = { motion, switch },
    }, 

    logging =   
    {   
        level =  domoticz.LOG_DEBUG,   
        marker =  "LightControl" 
    },    
                            
    execute = function(dz, item)
        
        local motion = dz.devices(motion)
        local switch = dz.devices(switch)
        
        local lampOnTime = 300 -- On time when switched by motion detector

        dz.log('state of switch:   ' .. switch.state,dz.LOG_DEBUG)
        dz.log('state of motion:   ' .. motion.state,dz.LOG_DEBUG)
        
        if item == motion then
            if switch.active then 
                return -- no action needed when switch == 'On'
            elseif motion.active then
                switch.cancelQueuedCommands()
                switch.switchOn().silent()
                switch.switchOff().afterSec(lampOnTime).silent()
            end
        else -- switch 
            item.cancelQueuedCommands()
        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
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: switch and sensor combination

Post by waaren »

waaren wrote: Sunday 20 October 2019 22:08
abaratian wrote: Sunday 20 October 2019 11:34 The lamp is not 'smart' and can't be controlled via domoticz. The switch is controlling the lamp. The load wire goes through the switch to the lamp and the sensor is wireless.
OK. Can you try this ?

Code: Select all

--[[

    a switch connected to a lamp. Motion sensor should trigger switch
    1. when someone enters the room sensor should turn on lamp
    2. when someone enters the room and presses the switch, the light should stay on no matter if there is presence or not. 
        Pressing the switch again should turn off the light. In other words the switch should override sensor.

]] --

-- Change these to reflect the names of your light, switch and motion detector

local motion = 'motion'
local switch = 'switch'

-- No changes below this line necessary

return 
{
    on =
    {   
        devices        = { motion, switch },
    }, 

    logging =   
    {   
        level =  domoticz.LOG_DEBUG,   
        marker =  "LightControl" 
    },    
                            
    execute = function(dz, item)
        
        local motion = dz.devices(motion)
        local switch = dz.devices(switch)
        
        local lampOnTime = 300 -- On time when switched by motion detector

        dz.log('state of switch:   ' .. switch.state,dz.LOG_DEBUG)
        dz.log('state of motion:   ' .. motion.state,dz.LOG_DEBUG)
        
        if item == motion then
            if switch.active then 
                return -- no action needed when switch == 'On'
            elseif motion.active then
                switch.cancelQueuedCommands()
                switch.switchOn().silent()
                switch.switchOff().afterSec(lampOnTime).silent()
            end
        else -- switch 
            item.cancelQueuedCommands()
        end
    end
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
abaratian
Posts: 22
Joined: Thursday 12 July 2018 20:19
Target OS: Windows
Domoticz version: 2021.1
Contact:

Re: switch and sensor combination

Post by abaratian »

hestia wrote: Sunday 20 October 2019 19:15 Hi
so you should have a smart device for you light like Qubino (Goap) ZMNHDD1 Flush Dimmer, Qubino (Goap) ZMNHADx Flush 1 Relay, FIBARO System FGD212, Dimmer 2+, Qubino (Goap) ZMNHBDx Flush 2 Relays+, Qubino (Goap) ZMNHSDx Din Dimmer+
If it is the case I did a script that do what you want but with several switches, lights, PIR and areas.
Perhaps you could look at it or use it with 1 item only in the array instead of several (I hope it works with 1 item only!).
A the present time the are some issues with z-waves like trigger even though in silent mode, that's why I had to had a workaround
https://www.domoticz.com/forum/viewtopi ... 99#p224799

Code: Select all

--[[
A dzVents Script to manage lights with switches and PIR.
For a place with several areas (a set of PIR, lights and switches).
Some use cases:
When the PIR is triggered if it is enough night, the lights are switch on, if not already on.
After if the switch is used (better if a push button),  the lights that were switch on by the PIR are switched off.
When the switch is used if it is enough night, the lights are switch on, if not already on.
During the day, if you switch on the lights, there are switched off

The lighs are switched off after a delay (different if on by PIR or switch)
You could have active and passive (for monitoring only) PIR: with active PIR the lights are switched on ; with passive PIR the switches are only switched off by button, by there are switched off after a delay
There is also a double-check to be sure the lights are really off


In French (pas la traduction exacte, un texte plus ancien)
Pour gérer l'éclairage d'un lieu comprenant plusieurs zones (ensemble de PIR, de lumières et de switches).
Selon les règles suivantes:
Lorsque un détecteur est activé et si c'est la nuit, on allume toutes les lumières qui ne sont pas déjà allumées.
Lorsque un interrupteur est activé on éteint les lumières qui viennent d'être allumés par un PIR et/ou, si c'est la nuit, on allume les lumières associées à cet interrupteurs
Les lumières sont éteintes au bout d'un temps défini selon que c'est un PIR ou un switche qui les a allumées, et à partir de la dernières fois qu'un PIR ou un switch les concernant a été activé
La nuit est déterminée par l'heure ou par la luminosité

V1: 20/10/2019
--]]

-- --[[

local DOMAIN = 'LumExtV4R1' -- For logging, as you like!
local ZONE_PIR= {{514, 620}, {659, 623}} -- PIR classified in zone (like the lights)
local ZONE_LIGHT= {{700, 453}, {142, 112}, {645}} -- lights classified in zone
local GROUP_LIGHT= {{700, 453}} -- group of lights (that work together)
local PIR_ALL = {620, 623} -- list of PIR that switch on all the lights - the others only switch on the lights of their zone
local PIR_MONITOR = {659} -- list of PIR that only check to switch off the lights
local DEOL = 270 -- dummy switch to pilot the on time
local DEVICES =  {DEOL, 453, 142, 112, 514, 620, 659, 623, 645} -- All the devices to trigger the script ; do not put the slaves (cf. GROUP_LIGHT)
local LUX = 305 -- idx device to get the illuminance
local LUX_MIN_PIR = 250 -- illuminance minimum in Lux to consider it's night enough to switch ON lights automatically; if nul night time is used
local LUX_MIN_SWITCH = 300 -- illuminance minimum in Lux to consider it's night enough to switch ON lights manualy ; if nul night time is used
local MAX_PIR = 100 -- 180 --  seconds ; time to keep on lights when switched on by PIR
local MAX_SWITCH = 3600 -- 300 -- 3600/12 -- seconds ; time to keep on lights when switched on by switch / bigger than MAX_PIR!
local TARGET_DIM_LEVEL = 80
local TIME_INTERVAL = 'every 30 minutes' -- Period to double-check if there is any light to switch off, in case of something went wrong

-- --]]

--[[

local DOMAIN = 'TestLum' -- For logging, as you like!
local ZONE_PIR= {{202}, {207}} -- PIR classified in zone (like the lights)
local ZONE_LIGHT= {{203, 204}, {205, 206, 214}, {460}} -- lights classified in zone
local GROUP_LIGHT= {{203, 204}, {206, 214}} -- group of lights (that work together)
local PIR_ALL = {202} -- list of PIR that switch on all the lights - the others only switch on the lights of their zone
local PIR_MONITOR = {207} -- list of PIR that only check to switch off the lights
local DEOL = 271 -- dummy switch to pilot the on time
local DEVICES =  {DEOL, 203, 204, 205, 206, 214, 202, 207, 460}-- All the devices to trigger the script
local LUX = 0 --305 -- idx device to get the illuminance
local LUX_MIN_PIR = 300 -- illuminance minimum in Lux to consider it's night enough to switch ON lights automatically; if nul night time is used
local LUX_MIN_SWITCH = 400 -- illuminance minimum in Lux to consider it's night enough to switch ON lights manualy ; if nul night time is used
local MAX_PIR = 20 --  seconds ; time keep on light on when switch on by PIR
local MAX_SWITCH = 40 -- 3600/12 -- seconds ; time keep on light on when switch on by switch / bigger than MAX_PIR
local TARGET_DIM_LEVEL = 60
local TIME_INTERVAL = 'every 10 minutes' -- Period to check if any light to switch off, in case of something wrong
local TEST_NIGHT = true
--]]

local CHECKOFF_SEC = 10 -- delay before checking if all light are off
local FALSETRIGGER_SEC = 6 -- delay to wait to avoid false trigger (in case of a bug on .silent)

return {
    active = true,
    logging = {
	level = domoticz.LOG_FORCE, -- Select one of LOG_DEBUG, LOG_INFO, LOG_ERROR, LOG_FORCE to override system log level -- normal = LOG_ERROR
	marker = DOMAIN
	},
    on = {
        devices = DEVICES,
        timer = {TIME_INTERVAL},
  	},
    data = {
		deviceOn = {initial={}},
		timeOn = {initial={}},
		checkOff = {initial=true},
	},
        
    execute = function(dz, the_device, triggerInfo)
        
    local LOG_LEVEL = dz.LOG_FORCE -- LOG_INFO, LOG_DEBUG, LOG_ERROR, LOG_FORCE  - normal = LOG_INFO
        
    local l_ForSec = 99999
    local Time = require('Time')
	local l_time = Time()
	local l_deviceOn = dz.data.deviceOn
	local l_timeOn = dz.data.timeOn
	
	local l_night_PIR=false
	local l_night_SWITCH=false 
    local l_day_night ='day'
    if LUX == 0 then
        --print ("N/D w time " .. tostring(isNightTime))
        if dz.time.isNightTime or TEST_NIGHT then
            l_night_PIR = true
            l_night_SWITCH = true
            l_day_night ='night'
        end
    else
        --print ("N/D w LUX idx: " .. LUX .. " Lux: " .. dz.devices(LUX).lux)
        if dz.devices(LUX).lux < LUX_MIN_SWITCH then
            l_night_SWITCH = true
            l_day_night ='night for switch only'
        
            if dz.devices(LUX).lux < LUX_MIN_PIR then
                l_night_PIR = true
                l_day_night ='night'
            end
        end
    end
   	dz.log('*** start ' .. triggerInfo.type .. ' ' .. l_time.raw .. ' ' ..  l_day_night, dz.LOG_FORCE)
  
--- FUNCTIONS BEG --------------------------------------------------------------


local function checkFalseTrigger (theItemId)
    -- to check if there is a false trigger due to .silent issue
    --print('function checkFalseTrigger ' .. theItemId)
    --print(l_deviceOn[theItemId])
    --if dz.devices(theDeviceId).active and l_deviceOn[theItemId]~= 'S' then -- 28/08/2019 -- to avoid false wrong trigger in case of switch off (13/09/2019) not after a switch on
        -- 01/10/2019 removed because it is possible to have z false switch off by the deviced
        local f_sec_delta = 0
        if l_timeOn[theItemId] ~= nil then -- and l_timeOn[theItemId] ~= 0 and l_timeOn[theItemId].raw ~= nil then
            --print ("time "  .. l_time.raw)
            --print("timeOn " .. l_timeOn[theItemId].raw)
            f_sec_delta = l_time.compare(l_timeOn[theItemId]).secs
            --if l_deviceOn[theItemId]== 'S' or l_deviceOn[theItemId]== 'P' then
                if f_sec_delta < FALSETRIGGER_SEC then
                    dz.log('! Wrong trigger - to stop the script ' .. dz.devices(theItemId).name .. ' ' .. dz.devices(theItemId).state .. ' ' .. l_deviceOn[theItemId] .. ' delta sec ' .. f_sec_delta,  dz.LOG_ERROR)
                    return true
                end
            --end
        end
    --end
    dz.log('Trigger OK - to continue the script ' .. dz.devices(theItemId).name .. ' ' .. dz.devices(theItemId).state,  dz.LOG_LEVEL)
    return false
end


local function theArray2Id (theArray, theItemId)
    -- find the sub array where the item is in the array (of 2 levels)
    local array2Id
   
    -- print('function theArray2Id')
    -- print('theItemId: ' .. theItemId)
    for i1, l1 in ipairs(theArray) do
        -- print('i1: ' .. i1)
        for i2, l2 in pairs(theArray[i1]) do
            --print('i2: '  .. i2)
            --print('l2: '  .. l2)
            if theItemId == l2 then
                --print 'OK'    
                --print("theItemId: " .. theItemId)
                --print('level1: ' .. i1)
                --print('level[]: ' .. l1[i2])
                --print('theArray[iz]: ' .. theArray[i1][i2])
                array2Id=i1
                break
            end
        end
        if array2Id ~= nill then break end
    end
    return array2Id
end


local function ifItemPresent2 (theArray, theItemId)
    -- find if the item is in the array (of 2 levels)
    local ItemPresent=false
    --print('function ifItemPresent2')
    --print('theItemId: ' .. theItemId)
    for i1, l1 in ipairs(theArray) do
        --print('i1: ' .. i1)
        for i2, l2 in pairs(theArray[i1]) do
            --print('i2: '  .. i2)
            --print('l2: '  .. l2)
            if theItemId == l2 then
                --print 'OK'    
                --print("theItemId: " .. theItemId)
                --print('level1: ' .. i1)
                --print('level[]: ' .. l1[i2])
                --print('theArray[iz]: ' .. theArray[i1][i2])
                ItemPresent=true
                break
            end
        end
        if ItemPresent then break end
    end
    return ItemPresent
end


local function ifItemPresent (theArray, theItemId)
    -- find if the item is in the array (of 1 level)
    local ItemPresent=false
    -- --print('function ifItemPresent')
    -- --print('theItemId: ' .. theItemId)
    for i1, l1 in ipairs(theArray) do
        --print('i1: ' .. i1)
        if theItemId == l1 then
            --print 'OK'    
            --print("theItemId: " .. theItemId)
            ItemPresent=true
            break
        end
       if ItemPresent then break end
    end
    return ItemPresent
end


local function switchOnLight (theDeviceId, PSX, Monitor)
    --switch on 1 light
    --print('function switchOnLight')
    --print('theDeviceId: ' .. theDeviceId)
    local deviceActive=true
    if dz.devices(theDeviceId).active then
        --if dz.devices(theDeviceId).switchType == 'Dimmer' then
           --if dz.devices(theDeviceId).level ~= TARGET_DIM_LEVEL then 
              --dz.devices(theDeviceId).dimTo(TARGET_DIM_LEVEL).silent()
           --end 
        --end
        --print('switchOnLight device active')
        dz.log(dz.devices(theDeviceId).name .. " " .. theDeviceId .. "  already active ", LOG_LEVEL)
    else
        if not Monitor then -- the PIR is to switch on a light or it is a switch
            deviceActive=false
            if dz.devices(theDeviceId).switchType == 'Dimmer' then
                --print('Dimmer')
                dz.devices(theDeviceId).dimTo(TARGET_DIM_LEVEL).silent()
            else
                --print('Not Dimmer')
                dz.devices(theDeviceId).switchOn().silent()
            end
            dz.log(dz.devices(theDeviceId).name .. " " .. theDeviceId .. " to On", LOG_LEVEL)
        end
    end
    if PSX == 'S' then  -- 05/08/2019
        l_deviceOn[theDeviceId]= 'S'
    elseif PSX == 'P' then
        if l_deviceOn[theDeviceId] ~= 'S' then
            l_deviceOn[theDeviceId]= 'P'
        end
    else
         dz.log('switchOnLight PSX error ' .. PSX, dz.LOG_ERROR)
    end 
    
    l_timeOn[theDeviceId] = l_time -- last 'on' time
    return deviceActive
end

local function switchOffLight (theDeviceId)
    --switch off 1 light
    -- print('function switchOffLight')
    -- print('theDeviceId: ' .. theDeviceId)
    -- print (l_time.raw)
    -- if (triggerInfo.type == 'device') then -- 12/08/2019 comments to avoid last seen update
        dz.devices(theDeviceId).switchOff().checkFirst().silent()
    --else -- timer, to check if some light could have been left on
        --dz.devices(theDeviceId).switchOff().silent() -- 09/08/2019 in case  dz don't have the right status
        --print('function switchOffLight: timer')
    --end
    
    l_deviceOn[theDeviceId]= 'X'
    l_timeOn[theDeviceId] = l_time -- last change state
    --local deviceActive=false
end


local function switchOnLightArray (theArray, PSX, Monitor)
    -- switch on all the lights of the array (1 level)
    --print('function switchOnLightArray')
    local deviceActive = false
    local allDeviceActive = true
    for i1, l1 in ipairs(theArray) do
        --print('Light: ' .. i1 .. ' ' .. l1)
        --if ItemIdToIgnore == l1 then
                --print ('ItemIdToIgnore: ' .. l1)
        --else 
            deviceActive=switchOnLight(l1, PSX, Monitor)
            if not deviceActive then
                allDeviceActive=false
            end
        --end
        --print('deviceActive: ' ..  tostring(deviceActive))
    end
    return allDeviceActive
end


local function switchOffLightArray (theArray, PSX)
    --switch off all the lights of the array (1 level)
    --print('function switchOffLightArray ' .. PSX)
    local l_sec_delta = 0
    local l_ForSecTmp = 0
    for i1, l1 in ipairs(theArray) do
        --print('light: ' .. i1 .. ' ' .. l1 .. ' PSX: ' .. PSX)
        if PSX == 'T' or PSX == 'XT' then -- to check if it is time to turn off the light
            --print ('MAX_SWITCH ' .. MAX_SWITCH)
            --print('MAX_PIR ' .. MAX_PIR)
            --print ("l1 " .. l1)
            
            if not l_timeOn[l1] then
              --l_timeOn[l1] = 0
              --l_sec_delta = 0
              l_sec_delta = MAX_SWITCH+1 -- 07/07/2019
            else
                l_sec_delta = l_time.compare(l_timeOn[l1]).secs
            end
            
            if not l_deviceOn[l1] then
              l_deviceOn[l1] = '?'
            end
            
            --print('l_sec_delta ' .. l_sec_delta)   -- :-( !!!! S éteint qd P éteint !!!!!!!!!!!
                if l_sec_delta > MAX_SWITCH
                or (l_deviceOn[l1] == 'P' and l_sec_delta > MAX_PIR)
                or (l_deviceOn[l1] == 'P' and PSX == 'XT')
                or l_deviceOn[l1] == 'X' then  -- 30/05/2019 removed / 07/07/2019 replaced!
                    switchOffLight(l1)
                    --print ('switchoff ' .. PSX)
                end

             -- calculate the time before triggering this script to switch off the next light
    	  
    	    if l_deviceOn[l1] == 'P' then
    	        l_ForSecTmp = MAX_PIR - l_sec_delta
    	        dz.log("switchOffLightArray: P l_ForSecTmp " .. l_ForSecTmp .. " l_sec_delta " .. l_sec_delta, LOG_LEVEL)
        	    if l_ForSec > l_ForSecTmp then 
        	        l_ForSec = l_ForSecTmp
        	         --dz.log("P !!!" .. l_ForSec, LOG_LEVEL)
    	        end
            elseif l_deviceOn[l1] == 'S' then
               l_ForSecTmp = MAX_SWITCH - l_sec_delta
	           dz.log("switchOffLightArray: S l_ForSecTmp " .. l_ForSecTmp .. " l_sec_delta " .. l_sec_delta, LOG_LEVEL)
    	       if l_ForSec > l_ForSecTmp then 
        	        l_ForSec = l_ForSecTmp
        	          --dz.log("S !!!" .. l_ForSec, LOG_LEVEL)
    	        end
    	    end
           
            --dz.log("l_ForSec " .. l_ForSec, LOG_LEVEL)
            if not l_timeOn[l1] then
                --print ("l1 => " .. l1)
                --print( dz.devices(l1).name)
                   --print( dz.devices(l1).state)
                   --print("devOn " .. l_deviceOn[l1])
                   --print("secdelta " .. l_sec_delta)
                dz.log(l1 .. '  ' .. dz.devices(l1).name .. ' ' .. dz.devices(l1).state .. ' ' .. l_deviceOn[l1] .. ' timeOn 0 delta sec ' .. l_sec_delta,  dz.LOG_FORCE)
            else 
                dz.log(l1 .. '  ' .. dz.devices(l1).name .. ' ' .. dz.devices(l1).state .. ' ' .. l_deviceOn[l1] .. ' timeOn ' .. l_timeOn[l1].raw .. ' delta sec ' .. l_sec_delta,  dz.LOG_FORCE)
            end
        else
            switchOffLight(l1)
        end
    end
    return allDeviceActive
end


local function switchOnLightArray2 (theArrayL1, theArrayL2, PSX)
    -- switch on all the lights of the array L2 (lights) regarding the zones of the array L1 (PIRs)
    local deviceActiveL1 = true
    local allDeviceActive = true
    --print('function switchOnLightArray2')
    for i1, l1 in ipairs(theArrayL1) do
        --print('i1: ' .. i1) 
        deviceActiveL1 = switchOnLightArray (theArrayL2[i1], PSX)
        if not deviceActiveL1 then
            allDeviceActive=false
        end
    end
    return allDeviceActive
end


local function switchOffLightArray2 (theArray, PSX)
    -- switch off all the lights of the array (of 2 levels) eventually filtered with PSX
    --print('function switchOffLightArray2')
    for i1, l1 in ipairs(theArray) do
        --print('i1: ' .. i1)
        deviceActiveL1 = switchOffLightArray (theArray[i1], PSX)
    end
end

local function checkLightActive2 (theArray)
    -- check if any light is already on in the array (of 2 levels)
    --print('function chechLightOn2')
    local anyActive=false
    for i1, l1 in ipairs(theArray) do
        --print('i1: ' .. i1)
        for i2, l2 in pairs(theArray[i1]) do
            --print('i2: '  .. i2)
            --print('l2: '  .. l2)
            if dz.devices(l2).active then
               anyActive=true
               --print('anyActive')
               return anyActive
            end
        end
    end
    return anyActive
end

--- FUNCTIONS END --------------------------------------------------------------
--------------------------------------------------------------------------------  

    local itemId = the_device.id
    local allDeviceActive = true
    local theDeviceOn = false
    local theSwitchOff = false
    local PIRMonitor = false
    local zoneMode=true
    
    if (triggerInfo.type == 'device') then
        if ifItemPresent2(ZONE_PIR, itemId) then -- this device is a PIR 
            dz.log('PIR: ' .. itemId .. ' ' ..  the_device.name.. ' ' ..  the_device.state,  LOG_LEVEL)
            if l_night_PIR then --at night
                --dz.log('PIR: ' .. itemId .. ' ' ..  the_device.name.. ' ' ..  the_device.state,  LOG_LEVEL)
            
                if not the_device.active then -- a switchOff signal from the PIR: used to check if some lights to switch off
                    --print('PIR not active')
                else
                    if ifItemPresent(PIR_MONITOR, itemId) then -- this PIR only check to swith off the lights
                        --print('PIR_MONITOR: ' .. itemId)
                        PIRMonitor = true
                    else
                        if ifItemPresent(PIR_ALL, itemId) then -- this PIR could switch on all light
                            --print('anyActive: ' ..  tostring(anyActive))
                            if not checkLightActive2 (ZONE_LIGHT) then -- if no light is already on
                                --print('All lights are off')
                                allDeviceActive = switchOnLightArray2 (ZONE_PIR, ZONE_LIGHT, 'P')
                                zoneMode=false -- if any light is on, only the lights in the PIR zone are switch on / light on all lights if no light is on
                            end
                        end
                    end
                    if zoneMode then -- 
                        --print('Lights on of the PIR zone')
                        local zoneId = theArray2Id(ZONE_PIR, itemId)
                        --print('zoneId: ' .. zoneId)
                        allDeviceActive = switchOnLightArray(ZONE_LIGHT[zoneId], 'P', PIRMonitor)
                    end
                end
            end
        elseif ifItemPresent2(ZONE_LIGHT, itemId) then -- this device is a switch
            dz.log('SWITCH: ' .. itemId .. ' ' .. the_device.name .. ' ' ..  the_device.state,  LOG_LEVEL)
            if l_night_SWITCH then -- at night
                local FalseTrigger=checkFalseTrigger(itemId)
                if FalseTrigger then
                    return -- it is a false trigger due to .silent issue
                end
                if the_device.active then
                    theDeviceOn = true
                    -- dz.log('l_theDeviceOn true' ,  LOG_LEVEL)
                else
                    theDeviceOn = false
                    theSwitchOff = true
                    -- dz.log('l_theDeviceOn false' ,  LOG_LEVEL)
                end
                local slaveId = theArray2Id(GROUP_LIGHT, itemId)
                if slaveId ~= nil then
                    --print('slaveId: ' .. slaveId)
                    --retreive the level to light the slave with the same level <= NOT MADE !!!
                    if theDeviceOn then
                        --print('go to switchOnLightArray')
                        allDeviceActive = switchOnLightArray(GROUP_LIGHT[slaveId], 'S') -- , itemId)  !!!!!!!!!!!!!!!!!!!!
                    else
                        --print('go to switchOffLightArray')
                        switchOffLightArray(GROUP_LIGHT[slaveId], 'X') 
                    end
                else -- no slaves
                    if theDeviceOn then
                        --print("switchOnLight " .. itemId)
                        switchOnLight (itemId, 'S')
                    else
                        --print("switchOffLight " .. itemId)
                        switchOffLight (itemId)
                    end 
                end
            else
                switchOffLight (itemId)
            end
        elseif itemId ~= DEOL then
            dz.log('Nor LIGHT, nethier PIR ?! ' .. itemId, dz.LOG_ERROR)
        else
            dz.log('DEOL: ' .. itemId .. ' ' .. the_device.name .. ' ' ..  the_device.state,  LOG_LEVEL)
        end
    end
-- [[  
    dz.log('*** end ' , dz.LOG_FORCE)
    if theSwitchOff then -- somebdy switchoff a light, if after a PIR, all light switch on by the PIR are switch off
        --print ('theSwitchOff')
        switchOffLightArray2(ZONE_LIGHT, 'XT')
    else
        switchOffLightArray2(ZONE_LIGHT, 'T') -- to check if it's time to switch off some lights
    end

    -- activate a dummy device to trigger the script to switch off the next lights
    if DEOL ~= nill then
        if l_ForSec < 9999 then -- a light to switch off in a while
            dz.data.checkOff = true
        else -- not a light to switch off
            if dz.data.checkOff then -- if first time, a 2nd round to secure the switch off
                l_ForSec = CHECKOFF_SEC -- number off seconds for the 2nd round
                if not checkLightActive2 (ZONE_LIGHT) then -- if any light is already on
                    dz.data.checkOff = false -- one more check
                end
                --print ('check in ' .. l_ForSec .. ' sec')
            end
        end 
        
        if l_ForSec < 9999 then
            dz.log('Next check in ' .. l_ForSec .. ' sec',  dz.LOG_FORCE)
            l_ForSec = l_ForSec + 3
            dz.devices(DEOL).cancelQueuedCommands()
            dz.devices(DEOL).switchOn().silent()
            dz.devices(DEOL).switchOff().afterSec(l_ForSec)
        else
            dz.log('All is switched off',  dz.LOG_FORCE)
            dz.devices(DEOL).cancelQueuedCommands()
            dz.devices(DEOL).switchOff().silent()
        end
    end
--]]
    dz.data.deviceOn = l_deviceOn
    dz.data.timeOn = l_timeOn

end}
Hope this help
thanks for the reply. this is to complicated for my purpose right now.
abaratian
Posts: 22
Joined: Thursday 12 July 2018 20:19
Target OS: Windows
Domoticz version: 2021.1
Contact:

Re: switch and sensor combination

Post by abaratian »

waaren wrote: Sunday 20 October 2019 22:09
waaren wrote: Sunday 20 October 2019 22:08
abaratian wrote: Sunday 20 October 2019 11:34 The lamp is not 'smart' and can't be controlled via domoticz. The switch is controlling the lamp. The load wire goes through the switch to the lamp and the sensor is wireless.
OK. Can you try this ?

Code: Select all

--[[

    a switch connected to a lamp. Motion sensor should trigger switch
    1. when someone enters the room sensor should turn on lamp
    2. when someone enters the room and presses the switch, the light should stay on no matter if there is presence or not. 
        Pressing the switch again should turn off the light. In other words the switch should override sensor.

]] --

-- Change these to reflect the names of your light, switch and motion detector

local motion = 'motion'
local switch = 'switch'

-- No changes below this line necessary

return 
{
    on =
    {   
        devices        = { motion, switch },
    }, 

    logging =   
    {   
        level =  domoticz.LOG_DEBUG,   
        marker =  "LightControl" 
    },    
                            
    execute = function(dz, item)
        
        local motion = dz.devices(motion)
        local switch = dz.devices(switch)
        
        local lampOnTime = 300 -- On time when switched by motion detector

        dz.log('state of switch:   ' .. switch.state,dz.LOG_DEBUG)
        dz.log('state of motion:   ' .. motion.state,dz.LOG_DEBUG)
        
        if item == motion then
            if switch.active then 
                return -- no action needed when switch == 'On'
            elseif motion.active then
                switch.cancelQueuedCommands()
                switch.switchOn().silent()
                switch.switchOff().afterSec(lampOnTime).silent()
            end
        else -- switch 
            item.cancelQueuedCommands()
        end
    end
}
The light stays on for ever. this is the log

Code: Select all

 2019-10-21 22:57:54.073 Status: dzVents: Info: LightControl: ------ Start internal script: master_bathroom_sensor: Device: "Master Bathroom Motion (Xiaomi Gateway)", Index: 260
2019-10-21 22:57:54.073 Status: dzVents: Debug: LightControl: Processing device-adapter for Master Bathroom Night Light: Switch device adapter
2019-10-21 22:57:54.073 Status: dzVents: Debug: LightControl: state of switch: Off
2019-10-21 22:57:54.073 Status: dzVents: Debug: LightControl: state of motion: On
2019-10-21 22:57:54.073 Status: dzVents: Debug: LightControl: Constructed timed-command: On
2019-10-21 22:57:54.073 Status: dzVents: Debug: LightControl: Constructed timed-command: On NOTRIGGER
2019-10-21 22:57:54.073 Status: dzVents: Debug: LightControl: Constructed timed-command: Off
2019-10-21 22:57:54.073 Status: dzVents: Debug: LightControl: Constructed timed-command: Off AFTER 300 SECONDS
2019-10-21 22:57:54.073 Status: dzVents: Debug: LightControl: Constructed timed-command: Off AFTER 300 SECONDS NOTRIGGER
2019-10-21 22:57:54.073 Status: dzVents: Info: LightControl: ------ Finished master_bathroom_sensor
2019-10-21 22:57:55.291 Status: dzVents: Info: LightControl: ------ Start internal script: master_bathroom_sensor: Device: "Master Bathroom Night Light (Xiaomi Gateway)", Index: 257
2019-10-21 22:57:55.291 Status: dzVents: Debug: LightControl: Processing device-adapter for Master Bathroom Motion: Switch device adapter
2019-10-21 22:57:55.291 Status: dzVents: Debug: LightControl: state of switch: On
2019-10-21 22:57:55.291 Status: dzVents: Debug: LightControl: state of motion: On
2019-10-21 22:57:55.291 Status: dzVents: Info: LightControl: ------ Finished master_bathroom_sensor 
there should be only one "On NOTRIGGER" and one "Off AFTER 300 SECONDS NOTRIGGER"
I can't find out what are the other constructed commands. I have no other scripts for these devices.
adding checkFirst() doesn't help.
abaratian
Posts: 22
Joined: Thursday 12 July 2018 20:19
Target OS: Windows
Domoticz version: 2021.1
Contact:

Re: switch and sensor combination

Post by abaratian »

i got it working by replacing

Code: Select all

                switch.switchOn().silent()
                switch.switchOff().afterSec(lampOnTime).silent()
with

Code: Select all

                switch.switchOn().forSec(lampOnTime).silent().checkFirst()
and removing switch from trigger devices list.
thank you so much waaren
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: switch and sensor combination

Post by waaren »

abaratian wrote: Monday 21 October 2019 21:32 The light stays on for ever
there should be only one "On NOTRIGGER" and one "Off AFTER 300 SECONDS NOTRIGGER"
I can't find out what are the other constructed commands. I have no other scripts for these devices.
adding checkFirst() doesn't help.
You can ignore the additional constructed commands. This is normal when using silent() or afterSec.
More problamatic is that the silent() method does not work for your switch. What type of hardware is it connected to ?
And what is your domoticz version ?


You could try this script (I added an assumption that switch was triggered by motion detector if motion detector was updated within the 10 seconds before) If that does not work I would not now of how to solve this.

Code: Select all

--[[

    a switch connected to a lamp. Motion sensor should trigger switch
    1. when someone enters the room sensor should turn on lamp
    2. when someone enters the room and presses the switch, the light should stay on no matter if there is presence or not. 
        Pressing the switch again should turn off the light. In other words the switch should override sensor.

]] --

-- Change these to reflect the names of your light, switch and motion detector

local motion = 'motion'
local switch = 'switch'

-- No changes below this line necessary

return 
{
    on =
    {   
        devices        = { motion, switch },
    }, 

    logging =   
    {   
        level =  domoticz.LOG_DEBUG,   
        marker =  "LightControl" 
    },    
                            
    execute = function(dz, item)
        
        local motion = dz.devices(motion)
        local switch = dz.devices(switch)
        
        local lampOnTime = 300 -- On time when switched by motion detector

        dz.log('state of switch:   ' .. switch.state,dz.LOG_DEBUG)
        dz.log('state of motion:   ' .. motion.state,dz.LOG_DEBUG)
        
        if item == motion then
            if switch.active then 
                return -- no action needed when switch == 'On'
            elseif motion.active then
                switch.cancelQueuedCommands()
                switch.switchOn().silent()
                switch.switchOff().afterSec(lampOnTime).silent()
            end
        else -- switch 
            if motion.lastUpdated.secondsAgo < 10 then
                dz.log('Assume switch was operated by motion detector; no action now',dz.LOG_DEBUG)
            else
                item.cancelQueuedCommands()
            end    
        end
    end
}

Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
abaratian
Posts: 22
Joined: Thursday 12 July 2018 20:19
Target OS: Windows
Domoticz version: 2021.1
Contact:

Re: switch and sensor combination

Post by abaratian »

Thanks warren, I figured it out. See my above post. you've been so helpful. Thanks for your time and effort.
abaratian
Posts: 22
Joined: Thursday 12 July 2018 20:19
Target OS: Windows
Domoticz version: 2021.1
Contact:

Re: switch and sensor combination

Post by abaratian »

hi again,
I tested the script some more time. There is a problem, when the light is turned on by motion, it is turned off after the set time is passed even if there is constant motion in front of the sensor. Can you help with that?
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: switch and sensor combination

Post by waaren »

abaratian wrote: Monday 21 October 2019 23:23 hi again,
I tested the script some more time. There is a problem, when the light is turned on by motion, it is turned off after the set time is passed even if there is constant motion in front of the sensor. Can you help with that?
Is that with your version or my latest ?
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
abaratian
Posts: 22
Joined: Thursday 12 July 2018 20:19
Target OS: Windows
Domoticz version: 2021.1
Contact:

Re: switch and sensor combination  [Solved]

Post by abaratian »

waaren wrote: Tuesday 22 October 2019 1:03
abaratian wrote: Monday 21 October 2019 23:23 hi again,
I tested the script some more time. There is a problem, when the light is turned on by motion, it is turned off after the set time is passed even if there is constant motion in front of the sensor. Can you help with that?
Is that with your version or my latest ?
both
this is the final working version for anyone who is intrested
thanks to waaren for the help

Code: Select all

local motion = 'Main Bathroom Motion'
local switch = 'Main Bathroom Light'

-- No changes below this line necessary

return 
{
    on =
    {   
        devices        = { motion, switch },
    },
    data = {
        sensorTurnedOnLights = {initial=false}
    },

    logging =   
    {   
        level =  domoticz.LOG_DEBUG,   
        marker =  "LightControl" 
    },    
                            
    execute = function(dz, item)
        
        local lampOnTime = 150 -- On time when switched by motion detector
        local motion = dz.devices(motion)
        local switch = dz.devices(switch)

        if item == motion then
                if switch.active and motion.active then 
                    if dz.data.sensorTurnedOnLights then
                        switch.cancelQueuedCommands()
                        switch.switchOff().afterSec(lampOnTime).silent().checkFirst()
                    end
                elseif motion.active and not switch.active then
                    dz.data.sensorTurnedOnLights = true
                    switch.cancelQueuedCommands()
                    switch.switchOn().forSec(lampOnTime).silent().checkFirst()
                end
                
        else -- switch
            if switch.active and not motion.active then
                dz.data.sensorTurnedOnLights = false
            end
    end

    end
}
robbert1977
Posts: 15
Joined: Saturday 18 April 2020 22:12
Target OS: Raspberry Pi / ODroid
Domoticz version: 2020.2
Contact:

Re: switch and sensor combination

Post by robbert1977 »

Hey all,

I tried integrating above code into my (test) script.
However the global data doesn't seem to work?!
When I switch manually and then let activate the PIR the 60 seconds count down starts anyway...

When I try to log the value of the sensorTurnedOnLights (see below) it ignores the total sentence / rest of the script.. :
dz.log('sensorTurnedOnLights value: ' .. dz.data.sensorTurnedOnLights,dz.LOG_DEBUG)

It probably is something easy but I can't finid the mistake..
I changed "local motion = dz.devices(motion)" to local motion = dz.devices("PIR Test")
As it gave me otherwise an error.

I changed switch.active as it gave me an error and didn't work.

Code: Select all

local motion = 'PIR Test'
local switch = 'Lamp Gang'

return   {
    active = true,

    on =     {
      devices =   {
        motion,
        switch  }
    },

    data =     {
      sensorTurnedOnLights =       { initial= false  },
    },

            logging =  {
              level     =   domoticz.LOG_DEBUG,
              marker    =   "PIRTest"
            },

    execute = function(dz, item)
 --      local Lux        = dz.devices('PIR Gang Lux').lux
 --      local maxLux     = 150
 --      local Lights     = dz.devices("Lamp Gang")
       local maxSeconds = 60
       local motion = dz.devices("PIR Test")
       local switch = dz.devices("Lamp Gang")
 
       --DEBUG
       dz.log('state of switch:   ' .. switch.state,dz.LOG_DEBUG)
       dz.log('state of motion:   ' .. motion.state,dz.LOG_DEBUG)
       dz.log('name of item:   ' .. item.name,dz.LOG_DEBUG)

       if item == motion then
         if switch.state == "On" and motion.state == "On" then
           if dz.data.sensorTurnedOnLights then
             switch.cancelQueuedCommands()
             switch.switchOff().afterSec(maxSeconds).silent().checkFirst()
           end
         elseif motion.state == "On" and switch.state == "Off" then
           dz.data.sensorTurnedOnLights = true
           switch.cancelQueuedCommands()
           switch.switchOn().forSec(maxSeconds).silent().checkFirst()
         end
       else -- switch
         if switch.state == "On" and  motion.state == "Off" then
           dz.data.sensorTurnedOnLights = false
         end
       end
    end
}
My log after
1) switch
2) then PIR

Code: Select all

2020-05-24 17:32:56.577 Status: User: robbert initiated a switch command (122/Lamp Gang/On)
2020-05-24 17:33:04.792 Status: OpenZWave: Alarm received (Home Security: Motion Detected at Unknown Location), NodeID: 11 (0x0b)
2020-05-24 17:33:04.910 Status: dzVents: Info: Handling events for: "PIR Test", value: "Off"
2020-05-24 17:33:04.910 Status: dzVents: Info: PIRTest: ------ Start external script: test.lua: Device: "PIR Test (aeon z-wave)", Index: 160
2020-05-24 17:33:04.911 Status: dzVents: Debug: PIRTest: Processing device-adapter for Lamp Gang: Switch device adapter
2020-05-24 17:33:04.911 Status: dzVents: Debug: PIRTest: state of switch: On
2020-05-24 17:33:04.911 Status: dzVents: Debug: PIRTest: state of motion: Off
2020-05-24 17:33:04.911 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 17:33:04.912 Status: dzVents: Info: PIRTest: ------ Finished test.lua
2020-05-24 17:33:05.064 Status: dzVents: Info: Handling events for: "PIR Test", value: "On"
2020-05-24 17:33:05.064 Status: dzVents: Info: PIRTest: ------ Start external script: test.lua: Device: "PIR Test (aeon z-wave)", Index: 160
2020-05-24 17:33:05.065 Status: dzVents: Debug: PIRTest: Processing device-adapter for Lamp Gang: Switch device adapter
2020-05-24 17:33:05.065 Status: dzVents: Debug: PIRTest: state of switch: On
2020-05-24 17:33:05.066 Status: dzVents: Debug: PIRTest: state of motion: On
2020-05-24 17:33:05.066 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 17:33:05.066 Status: dzVents: Debug: PIRTest: Constructed timed-command: Off
2020-05-24 17:33:05.066 Status: dzVents: Debug: PIRTest: Constructed timed-command: Off AFTER 60 SECONDS
2020-05-24 17:33:05.066 Status: dzVents: Debug: PIRTest: Constructed timed-command: Off AFTER 60 SECONDS NOTRIGGER
2020-05-24 17:33:05.066 Status: dzVents: Debug: PIRTest: Constructed timed-command: Off AFTER 60 SECONDS NOTRIGGER
2020-05-24 17:33:05.067 Status: dzVents: Info: PIRTest: ------ Finished test.lua
2020-05-24 17:33:05.069 Status: EventSystem: Script event triggered: /home/robbert/domoticz/dzVents/runtime/dzVents.lua
2020-05-24 17:33:15.939 Status: OpenZWave: Alarm received (Home Security: Clear), NodeID: 11 (0x0b)
2020-05-24 17:33:16.098 Status: dzVents: Info: Handling events for: "PIR Test", value: "Off"
2020-05-24 17:33:16.098 Status: dzVents: Info: PIRTest: ------ Start external script: test.lua: Device: "PIR Test (aeon z-wave)", Index: 160
2020-05-24 17:33:16.099 Status: dzVents: Debug: PIRTest: Processing device-adapter for Lamp Gang: Switch device adapter
2020-05-24 17:33:16.099 Status: dzVents: Debug: PIRTest: state of switch: On
2020-05-24 17:33:16.099 Status: dzVents: Debug: PIRTest: state of motion: Off
2020-05-24 17:33:16.099 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 17:33:16.100 Status: dzVents: Info: PIRTest: ------ Finished test.lua
2020-05-24 17:33:16.207 Status: dzVents: Info: Handling events for: "PIR Test", value: "Off"
2020-05-24 17:33:16.207 Status: dzVents: Info: PIRTest: ------ Start external script: test.lua: Device: "PIR Test (aeon z-wave)", Index: 160
2020-05-24 17:33:16.208 Status: dzVents: Debug: PIRTest: Processing device-adapter for Lamp Gang: Switch device adapter
2020-05-24 17:33:16.208 Status: dzVents: Debug: PIRTest: state of switch: On
2020-05-24 17:33:16.208 Status: dzVents: Debug: PIRTest: state of motion: Off
2020-05-24 17:33:16.208 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 17:33:16.209 Status: dzVents: Info: PIRTest: ------ Finished test.lua
I hope someone can help me out here :)
Thanks from a newbie

kind regards robbert
Raspberry Pi 4
domoticzVersion: 2020.2
dzVentsVersion: 3.0.2
OpenZWave USB: 1.6-1033-g3661f170
RFXCOM - RFXtrx433 USB: Pro XL1/1043, Noise: 109 dB
Homebridge - Siri integration
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: switch and sensor combination

Post by waaren »

robbert1977 wrote: Sunday 24 May 2020 17:36 However the global data doesn't seem to work?!
There is no global data in the script. You probably mean persistent data?
I hope someone can help me out here :)
can you try this

Code: Select all

local motion = 'PIR Test'
local switch = 'Lamp Gang'

return
{
    active = true,

    on =
    {
      devices =
      {
        motion,
        switch,
        }
    },

    data =
    {
        sensorTurnedOnLights = { initial = false },
    },

    logging =
    {
        level =  domoticz.LOG_DEBUG,
        marker = 'PIRTest'
    },

    execute = function(dz, item)

--     local Lux        = dz.devices('PIR Gang Lux').lux
--     local maxLux     = 150
--     local Lights     = dz.devices('Lamp Gang')

        local maxSeconds = 60
        local motion = dz.devices('PIR Test')
        local switch = dz.devices('Lamp Gang')

        --DEBUG
        dz.log('state of switch:   ' .. switch.state,dz.LOG_DEBUG)
        dz.log('state of motion:   ' .. motion.state,dz.LOG_DEBUG)
        dz.log('name of item:   ' .. item.name,dz.LOG_DEBUG)
        dz.log('sensorTurnedOnLights value: ' .. tostring(dz.data.sensorTurnedOnLights),dz.LOG_DEBUG)

        if item == motion then
            if switch.state == 'On' and item.state == 'On' and dz.data.sensorTurnedOnLights then
                switch.cancelQueuedCommands()
                switch.switchOff().afterSec(maxSeconds).checkFirst().silent()
            elseif item.state == 'On' and switch.state == 'Off' then
                dz.data.sensorTurnedOnLights = true
                switch.cancelQueuedCommands()
                switch.switchOn().checkFirst().silent()
                switch.switchOff().afterSec(maxSeconds).silent()
            end
        elseif item.state == 'On' and  motion.state == 'Off' then
            dz.data.sensorTurnedOnLights = false
        end
    end
}
Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
robbert1977
Posts: 15
Joined: Saturday 18 April 2020 22:12
Target OS: Raspberry Pi / ODroid
Domoticz version: 2020.2
Contact:

Re: switch and sensor combination

Post by robbert1977 »

Waaren,

Thnx for your fast reply!
Thnx for the tostring... nice searched long for that :)

ok starting with a single motion, funny enough it starts with value Off:

Code: Select all

2020-05-24 21:30:23.868 Status: OpenZWave: Alarm received (Home Security: Motion Detected at Unknown Location), NodeID: 11 (0x0b)
2020-05-24 21:30:24.022 Status: dzVents: Info: Handling events for: "PIR Test", value: "Off"
2020-05-24 21:30:24.022 Status: dzVents: Info: PIRTest: ------ Start external script: test.lua: Device: "PIR Test (aeon z-wave)", Index: 160
2020-05-24 21:30:24.023 Status: dzVents: Debug: PIRTest: Processing device-adapter for Lamp Gang: Switch device adapter
2020-05-24 21:30:24.024 Status: dzVents: Debug: PIRTest: state of switch: Off
2020-05-24 21:30:24.024 Status: dzVents: Debug: PIRTest: state of motion: Off
2020-05-24 21:30:24.024 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 21:30:24.024 Status: dzVents: Debug: PIRTest: sensorTurnedOnLights value: true
2020-05-24 21:30:24.024 Status: dzVents: Info: PIRTest: ------ Finished test.lua
2020-05-24 21:30:24.184 Status: dzVents: Info: Handling events for: "PIR Test", value: "On"
2020-05-24 21:30:24.184 Status: dzVents: Info: PIRTest: ------ Start external script: test.lua: Device: "PIR Test (aeon z-wave)", Index: 160
2020-05-24 21:30:24.186 Status: dzVents: Debug: PIRTest: Processing device-adapter for Lamp Gang: Switch device adapter
2020-05-24 21:30:24.186 Status: dzVents: Debug: PIRTest: state of switch: Off
2020-05-24 21:30:24.186 Status: dzVents: Debug: PIRTest: state of motion: On
2020-05-24 21:30:24.186 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 21:30:24.186 Status: dzVents: Debug: PIRTest: sensorTurnedOnLights value: true
2020-05-24 21:30:24.186 Status: dzVents: Debug: PIRTest: Constructed timed-command: On
2020-05-24 21:30:24.186 Status: dzVents: Debug: PIRTest: Constructed timed-command: On
2020-05-24 21:30:24.186 Status: dzVents: Debug: PIRTest: Constructed timed-command: On NOTRIGGER
2020-05-24 21:30:24.187 Status: dzVents: Debug: PIRTest: Constructed timed-command: Off
2020-05-24 21:30:24.187 Status: dzVents: Debug: PIRTest: Constructed timed-command: Off AFTER 60 SECONDS
2020-05-24 21:30:24.187 Status: dzVents: Debug: PIRTest: Constructed timed-command: Off AFTER 60 SECONDS NOTRIGGER
2020-05-24 21:30:24.188 Status: dzVents: Info: PIRTest: ------ Finished test.lua
2020-05-24 21:30:24.192 Status: EventSystem: Script event triggered: /home/robbert/domoticz/dzVents/runtime/dzVents.lua
2020-05-24 21:30:35.015 Status: OpenZWave: Alarm received (Home Security: Clear), NodeID: 11 (0x0b)
2020-05-24 21:30:35.199 Status: dzVents: Info: Handling events for: "PIR Test", value: "Off"
2020-05-24 21:30:35.199 Status: dzVents: Info: PIRTest: ------ Start external script: test.lua: Device: "PIR Test (aeon z-wave)", Index: 160
2020-05-24 21:30:35.201 Status: dzVents: Debug: PIRTest: Processing device-adapter for Lamp Gang: Switch device adapter
2020-05-24 21:30:35.201 Status: dzVents: Debug: PIRTest: state of switch: On
2020-05-24 21:30:35.201 Status: dzVents: Debug: PIRTest: state of motion: Off
2020-05-24 21:30:35.201 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 21:30:35.201 Status: dzVents: Debug: PIRTest: sensorTurnedOnLights value: true
2020-05-24 21:30:35.203 Status: dzVents: Info: PIRTest: ------ Finished test.lua
2020-05-24 21:30:35.386 Status: dzVents: Info: Handling events for: "PIR Test", value: "Off"
2020-05-24 21:30:35.386 Status: dzVents: Info: PIRTest: ------ Start external script: test.lua: Device: "PIR Test (aeon z-wave)", Index: 160
2020-05-24 21:30:35.387 Status: dzVents: Debug: PIRTest: Processing device-adapter for Lamp Gang: Switch device adapter
2020-05-24 21:30:35.387 Status: dzVents: Debug: PIRTest: state of switch: On
2020-05-24 21:30:35.387 Status: dzVents: Debug: PIRTest: state of motion: Off
2020-05-24 21:30:35.387 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 21:30:35.387 Status: dzVents: Debug: PIRTest: sensorTurnedOnLights value: true
2020-05-24 21:30:35.388 Status: dzVents: Info: PIRTest: ------ Finished test.lua
Secondly I switched on and then activated motion (lights go out), but see below:
2020-05-24 21:30:35.201 Status: dzVents: Debug: PIRTest: state of switch: On
2020-05-24 21:30:35.201 Status: dzVents: Debug: PIRTest: state of motion: Off
2020-05-24 21:30:35.201 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 21:30:35.201 Status: dzVents: Debug: PIRTest: sensorTurnedOnLights value: true
that shouldn't happen..

Code: Select all

2020-05-24 21:30:35.015 Status: OpenZWave: Alarm received (Home Security: Clear), NodeID: 11 (0x0b)
2020-05-24 21:30:35.199 Status: dzVents: Info: Handling events for: "PIR Test", value: "Off"
2020-05-24 21:30:35.199 Status: dzVents: Info: PIRTest: ------ Start external script: test.lua: Device: "PIR Test (aeon z-wave)", Index: 160
2020-05-24 21:30:35.201 Status: dzVents: Debug: PIRTest: Processing device-adapter for Lamp Gang: Switch device adapter
2020-05-24 21:30:35.201 Status: dzVents: Debug: PIRTest: state of switch: On
2020-05-24 21:30:35.201 Status: dzVents: Debug: PIRTest: state of motion: Off
2020-05-24 21:30:35.201 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 21:30:35.201 Status: dzVents: Debug: PIRTest: sensorTurnedOnLights value: true
2020-05-24 21:30:35.203 Status: dzVents: Info: PIRTest: ------ Finished test.lua
2020-05-24 21:30:35.386 Status: dzVents: Info: Handling events for: "PIR Test", value: "Off"
2020-05-24 21:30:35.386 Status: dzVents: Info: PIRTest: ------ Start external script: test.lua: Device: "PIR Test (aeon z-wave)", Index: 160
2020-05-24 21:30:35.387 Status: dzVents: Debug: PIRTest: Processing device-adapter for Lamp Gang: Switch device adapter
2020-05-24 21:30:35.387 Status: dzVents: Debug: PIRTest: state of switch: On
2020-05-24 21:30:35.387 Status: dzVents: Debug: PIRTest: state of motion: Off
2020-05-24 21:30:35.387 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 21:30:35.387 Status: dzVents: Debug: PIRTest: sensorTurnedOnLights value: true
2020-05-24 21:30:35.388 Status: dzVents: Info: PIRTest: ------ Finished test.lua
2020-05-24 21:36:20.230 Status: User: robbert initiated a switch command (122/Lamp Gang/On)
2020-05-24 21:36:40.025 Status: OpenZWave: Alarm received (Home Security: Motion Detected at Unknown Location), NodeID: 11 (0x0b)
2020-05-24 21:36:40.183 Status: dzVents: Info: Handling events for: "PIR Test", value: "Off"
2020-05-24 21:36:40.183 Status: dzVents: Info: PIRTest: ------ Start external script: test.lua: Device: "PIR Test (aeon z-wave)", Index: 160
2020-05-24 21:36:40.184 Status: dzVents: Debug: PIRTest: Processing device-adapter for Lamp Gang: Switch device adapter
2020-05-24 21:36:40.184 Status: dzVents: Debug: PIRTest: state of switch: On
2020-05-24 21:36:40.184 Status: dzVents: Debug: PIRTest: state of motion: Off
2020-05-24 21:36:40.184 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 21:36:40.184 Status: dzVents: Debug: PIRTest: sensorTurnedOnLights value: true
2020-05-24 21:36:40.185 Status: dzVents: Info: PIRTest: ------ Finished test.lua
2020-05-24 21:36:40.376 Status: dzVents: Info: Handling events for: "PIR Test", value: "On"
2020-05-24 21:36:40.376 Status: dzVents: Info: PIRTest: ------ Start external script: test.lua: Device: "PIR Test (aeon z-wave)", Index: 160
2020-05-24 21:36:40.377 Status: dzVents: Debug: PIRTest: Processing device-adapter for Lamp Gang: Switch device adapter
2020-05-24 21:36:40.377 Status: dzVents: Debug: PIRTest: state of switch: On
2020-05-24 21:36:40.377 Status: dzVents: Debug: PIRTest: state of motion: On
2020-05-24 21:36:40.377 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 21:36:40.377 Status: dzVents: Debug: PIRTest: sensorTurnedOnLights value: true
2020-05-24 21:36:40.377 Status: dzVents: Debug: PIRTest: Constructed timed-command: Off
2020-05-24 21:36:40.377 Status: dzVents: Debug: PIRTest: Constructed timed-command: Off AFTER 60 SECONDS
2020-05-24 21:36:40.377 Status: dzVents: Debug: PIRTest: Constructed timed-command: Off AFTER 60 SECONDS
2020-05-24 21:36:40.377 Status: dzVents: Debug: PIRTest: Constructed timed-command: Off AFTER 60 SECONDS NOTRIGGER
2020-05-24 21:36:40.378 Status: dzVents: Info: PIRTest: ------ Finished test.lua
2020-05-24 21:36:40.380 Status: EventSystem: Script event triggered: /home/robbert/domoticz/dzVents/runtime/dzVents.lua
2020-05-24 21:36:51.175 Status: OpenZWave: Alarm received (Home Security: Clear), NodeID: 11 (0x0b)
2020-05-24 21:36:51.369 Status: dzVents: Info: Handling events for: "PIR Test", value: "Off"
2020-05-24 21:36:51.369 Status: dzVents: Info: PIRTest: ------ Start external script: test.lua: Device: "PIR Test (aeon z-wave)", Index: 160
2020-05-24 21:36:51.370 Status: dzVents: Debug: PIRTest: Processing device-adapter for Lamp Gang: Switch device adapter
2020-05-24 21:36:51.370 Status: dzVents: Debug: PIRTest: state of switch: On
2020-05-24 21:36:51.370 Status: dzVents: Debug: PIRTest: state of motion: Off
2020-05-24 21:36:51.370 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 21:36:51.370 Status: dzVents: Debug: PIRTest: sensorTurnedOnLights value: true
2020-05-24 21:36:51.371 Status: dzVents: Info: PIRTest: ------ Finished test.lua
2020-05-24 21:36:51.593 Status: dzVents: Info: Handling events for: "PIR Test", value: "Off"
2020-05-24 21:36:51.593 Status: dzVents: Info: PIRTest: ------ Start external script: test.lua: Device: "PIR Test (aeon z-wave)", Index: 160
2020-05-24 21:36:51.595 Status: dzVents: Debug: PIRTest: Processing device-adapter for Lamp Gang: Switch device adapter
2020-05-24 21:36:51.595 Status: dzVents: Debug: PIRTest: state of switch: On
2020-05-24 21:36:51.595 Status: dzVents: Debug: PIRTest: state of motion: Off
2020-05-24 21:36:51.595 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 21:36:51.595 Status: dzVents: Debug: PIRTest: sensorTurnedOnLights value: true
2020-05-24 21:36:51.596 Status: dzVents: Info: PIRTest: ------ Finished test.lua
Raspberry Pi 4
domoticzVersion: 2020.2
dzVentsVersion: 3.0.2
OpenZWave USB: 1.6-1033-g3661f170
RFXCOM - RFXtrx433 USB: Pro XL1/1043, Noise: 109 dB
Homebridge - Siri integration
robbert1977
Posts: 15
Joined: Saturday 18 April 2020 22:12
Target OS: Raspberry Pi / ODroid
Domoticz version: 2020.2
Contact:

Re: switch and sensor combination

Post by robbert1977 »

Maybe not the nicest way to trouble shoot but added lines with 000, 111 and 222 but helps me understand where I am :P

Code: Select all

if item == motion then
            if switch.state == 'On' and item.state == 'On' and dz.data.sensorTurnedOnLights then
        dz.log('00000000000000000000000000000000000000000:   ',dz.LOG_DEBUG)
                switch.cancelQueuedCommands()
                switch.switchOff().afterSec(maxSeconds).checkFirst().silent()
            elseif item.state == 'On' and switch.state == 'Off' then
        dz.log('11111111111111111111111111111111111111111:   ',dz.LOG_DEBUG)
                dz.data.sensorTurnedOnLights = true
                switch.cancelQueuedCommands()
                switch.switchOn().checkFirst().silent()
                switch.switchOff().afterSec(maxSeconds).silent()
            end
        --elseif item.state == 'On' and  motion.state == 'Off' then
        elseif switch.state == 'On' and  motion.state == 'Off' then
        dz.log('222222222222222222222222222222222222222   ',dz.LOG_DEBUG)
            dz.data.sensorTurnedOnLights = false
        end
Apparently in the first run it doesn't go to the elseif statement where item is not motion.
So the value "dz.data.sensorTurnedOnLights = false" was never set

Code: Select all

2020-05-24 21:50:05.400 Status: User: robbert initiated a switch command (122/Lamp Gang/On)
2020-05-24 21:50:10.212 Status: OpenZWave: Alarm received (Home Security: Motion Detected at Unknown Location), NodeID: 11 (0x0b)
2020-05-24 21:50:10.439 Status: dzVents: Info: Handling events for: "PIR Test", value: "Off"
2020-05-24 21:50:10.439 Status: dzVents: Info: PIRTest: ------ Start external script: test.lua: Device: "PIR Test (aeon z-wave)", Index: 160
2020-05-24 21:50:10.440 Status: dzVents: Debug: PIRTest: Processing device-adapter for Lamp Gang: Switch device adapter
2020-05-24 21:50:10.440 Status: dzVents: Debug: PIRTest: state of switch: On
2020-05-24 21:50:10.440 Status: dzVents: Debug: PIRTest: state of motion: Off
2020-05-24 21:50:10.440 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 21:50:10.440 Status: dzVents: Debug: PIRTest: sensorTurnedOnLights value: true
2020-05-24 21:50:10.441 Status: dzVents: Info: PIRTest: ------ Finished test.lua
2020-05-24 21:50:10.600 Status: dzVents: Info: Handling events for: "PIR Test", value: "On"
2020-05-24 21:50:10.600 Status: dzVents: Info: PIRTest: ------ Start external script: test.lua: Device: "PIR Test (aeon z-wave)", Index: 160
2020-05-24 21:50:10.601 Status: dzVents: Debug: PIRTest: Processing device-adapter for Lamp Gang: Switch device adapter
2020-05-24 21:50:10.601 Status: dzVents: Debug: PIRTest: state of switch: On
2020-05-24 21:50:10.601 Status: dzVents: Debug: PIRTest: state of motion: On
2020-05-24 21:50:10.601 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 21:50:10.601 Status: dzVents: Debug: PIRTest: sensorTurnedOnLights value: true
2020-05-24 21:50:10.601 Status: dzVents: Debug: PIRTest: 00000000000000000000000000000000000000000:
2020-05-24 21:50:10.602 Status: dzVents: Debug: PIRTest: Constructed timed-command: Off
2020-05-24 21:50:10.602 Status: dzVents: Debug: PIRTest: Constructed timed-command: Off AFTER 60 SECONDS
2020-05-24 21:50:10.602 Status: dzVents: Debug: PIRTest: Constructed timed-command: Off AFTER 60 SECONDS
2020-05-24 21:50:10.602 Status: dzVents: Debug: PIRTest: Constructed timed-command: Off AFTER 60 SECONDS NOTRIGGER
2020-05-24 21:50:10.602 Status: dzVents: Info: PIRTest: ------ Finished test.lua
2020-05-24 21:50:10.604 Status: EventSystem: Script event triggered: /home/robbert/domoticz/dzVents/runtime/dzVents.lua
2020-05-24 21:50:21.353 Status: OpenZWave: Alarm received (Home Security: Clear), NodeID: 11 (0x0b)
2020-05-24 21:50:21.636 Status: dzVents: Info: Handling events for: "PIR Test", value: "Off"
2020-05-24 21:50:21.637 Status: dzVents: Info: PIRTest: ------ Start external script: test.lua: Device: "PIR Test (aeon z-wave)", Index: 160
2020-05-24 21:50:21.639 Status: dzVents: Debug: PIRTest: Processing device-adapter for Lamp Gang: Switch device adapter
2020-05-24 21:50:21.639 Status: dzVents: Debug: PIRTest: state of switch: On
2020-05-24 21:50:21.639 Status: dzVents: Debug: PIRTest: state of motion: Off
2020-05-24 21:50:21.639 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 21:50:21.639 Status: dzVents: Debug: PIRTest: sensorTurnedOnLights value: true
2020-05-24 21:50:21.639 Status: dzVents: Info: PIRTest: ------ Finished test.lua
2020-05-24 21:50:21.801 Status: dzVents: Info: Handling events for: "PIR Test", value: "Off"
2020-05-24 21:50:21.801 Status: dzVents: Info: PIRTest: ------ Start external script: test.lua: Device: "PIR Test (aeon z-wave)", Index: 160
2020-05-24 21:50:21.802 Status: dzVents: Debug: PIRTest: Processing device-adapter for Lamp Gang: Switch device adapter
2020-05-24 21:50:21.802 Status: dzVents: Debug: PIRTest: state of switch: On
2020-05-24 21:50:21.802 Status: dzVents: Debug: PIRTest: state of motion: Off
2020-05-24 21:50:21.802 Status: dzVents: Debug: PIRTest: name of item: PIR Test
2020-05-24 21:50:21.802 Status: dzVents: Debug: PIRTest: sensorTurnedOnLights value: true
2020-05-24 21:50:21.803 Status: dzVents: Info: PIRTest: ------ Finished test.lua
Update.. it works :)
Don't really see any changes, as expected as well as item.state as switch.state woks in the elseif and even the lights stay on now..
I copy the code below for if anyone would like to see it .. now gonna add the lux parameter and try to fix that counter resets on motion (so on movement the lights stay on not go out)

Code: Select all

local motion = 'PIR Test'
local switch = 'Lamp Gang'

return
{
    active = true,

    on =
    {
      devices =
      {
        motion,
        switch,
        }
    },

    data =
    {
        sensorTurnedOnLights = { initial = false },
    },

    logging =
    {
        level =  domoticz.LOG_DEBUG,
        marker = 'PIRTest'
    },

    execute = function(dz, item)

--     local Lux        = dz.devices('PIR Gang Lux').lux
--     local maxLux     = 150
--     local Lights     = dz.devices('Lamp Gang')

        local maxSeconds = 60
        local motion = dz.devices('PIR Test')
        local switch = dz.devices('Lamp Gang')

        --DEBUG
        dz.log('state of switch:   ' .. switch.state,dz.LOG_DEBUG)
        dz.log('state of motion:   ' .. motion.state,dz.LOG_DEBUG)
        dz.log('name of item:   ' .. item.name,dz.LOG_DEBUG)
                dz.log('sensorTurnedOnLights value: ' .. tostring(dz.data.sensorTurnedOnLights),dz.LOG_DEBUG)

        if item == motion then
            if switch.state == 'On' and item.state == 'On' and dz.data.sensorTurnedOnLights then
        dz.log('00000000000000000000000000000000000000000:   ',dz.LOG_DEBUG)
                switch.cancelQueuedCommands()
                switch.switchOff().afterSec(maxSeconds).checkFirst().silent()
            elseif item.state == 'On' and switch.state == 'Off' then
        dz.log('11111111111111111111111111111111111111111:   ',dz.LOG_DEBUG)
                dz.data.sensorTurnedOnLights = true
                switch.cancelQueuedCommands()
                switch.switchOn().checkFirst().silent()
                switch.switchOff().afterSec(maxSeconds).silent()
            end
        --elseif item.state == 'On' and  motion.state == 'Off' then
        elseif switch.state == 'On' and  motion.state == 'Off' then
        dz.log('222222222222222222222222222222222222222   ',dz.LOG_DEBUG)
            dz.data.sensorTurnedOnLights = false
        end
    end
}
Last edited by robbert1977 on Sunday 24 May 2020 22:28, edited 1 time in total.
Raspberry Pi 4
domoticzVersion: 2020.2
dzVentsVersion: 3.0.2
OpenZWave USB: 1.6-1033-g3661f170
RFXCOM - RFXtrx433 USB: Pro XL1/1043, Noise: 109 dB
Homebridge - Siri integration
User avatar
waaren
Posts: 6028
Joined: Tuesday 03 January 2017 14:18
Target OS: Linux
Domoticz version: Beta
Location: Netherlands
Contact:

Re: switch and sensor combination

Post by waaren »

robbert1977 wrote: Sunday 24 May 2020 21:45 Apparently in the first run it doesn't go to the elseif statement where item is not motion.
So the value "dz.data.sensorTurnedOnLights = false" was never set
Sorry but this does not make sense to me.

item can only be motion or switch so if it is not motion it must be switch or the other way around. If you try again make sure you remove the existing persistent data file to prevent old values playing tricks on you. You can find the persistent data file at

<domoticz dir>/scripts/dzVents/data/__data_scriptName.lua

Maybe you could make it a bit les confusing by change it like:

Code: Select all

local motionName = 'PIR Test'
local switchName = 'Lamp Gang'

return
{
    active = true,

    on =
    {
      devices =
      {
        motionName,
        switchName,
        }
    },

    data =
    {
        sensorTurnedOnLights = { initial = false },
    },

    logging =
    {
        level =  domoticz.LOG_DEBUG,
        marker = 'PIRTest'
    },

    execute = function(dz, item)

--     local Lux        = dz.devices('PIR Gang Lux').lux
--     local maxLux     = 150
--     local Lights     = dz.devices('Lamp Gang')

        local maxSeconds = 60
        local motion = dz.devices(motionName)
        local switch = dz.devices(switchName)

        --DEBUG
        dz.log('state of switch:   ' .. switch.state,dz.LOG_DEBUG)
        dz.log('state of motion:   ' .. motion.state,dz.LOG_DEBUG)
        dz.log('name of item:   ' .. item.name,dz.LOG_DEBUG)
        dz.log('sensorTurnedOnLights value: ' .. tostring(dz.data.sensorTurnedOnLights),dz.LOG_DEBUG)

        if item == motion then
            dz.log('if item == motion',dz.LOG_DEBUG)
            if switch.state == 'On' and item.state == 'On' and dz.data.sensorTurnedOnLights then
                dz.log("switch.state == 'On' and item.state == 'On' and dz.data.sensorTurnedOnLights",dz.LOG_DEBUG)
                switch.cancelQueuedCommands()
                switch.switchOff().afterSec(maxSeconds).checkFirst().silent()
            elseif item.state == 'On' and switch.state == 'Off' then
                dz.log("item.state == 'On' and switch.state == 'Off'",dz.LOG_DEBUG)
                dz.data.sensorTurnedOnLights = true
                switch.cancelQueuedCommands()
                switch.switchOn().checkFirst().silent()
                switch.switchOff().afterSec(maxSeconds).silent()
            end
        elseif item.state == 'On' and  motion.state == 'Off' then
            dz.log("item.state == 'On' and  motion.state == 'Off'",dz.LOG_DEBUG)
            dz.data.sensorTurnedOnLights = false
        end
    end
}

Debian buster, bullseye on RPI-4, Intel NUC.
dz Beta, Z-Wave, RFLink, RFXtrx433e, P1, Youless, Hue, Yeelight, Xiaomi, MQTT
==>> dzVents wiki
robbert1977
Posts: 15
Joined: Saturday 18 April 2020 22:12
Target OS: Raspberry Pi / ODroid
Domoticz version: 2020.2
Contact:

Re: switch and sensor combination

Post by robbert1977 »

ur totally right dunno why it didn't work earlier..
Raspberry Pi 4
domoticzVersion: 2020.2
dzVentsVersion: 3.0.2
OpenZWave USB: 1.6-1033-g3661f170
RFXCOM - RFXtrx433 USB: Pro XL1/1043, Noise: 109 dB
Homebridge - Siri integration
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 1 guest