Tips wanted RE motion sensor behaviour

Topics (not sure which fora)
when not sure where to post, post here and mods will move it to right forum.

Moderators: leecollings, remb0

Post Reply
DanM
Posts: 79
Joined: Thursday 23 October 2014 22:41
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Tips wanted RE motion sensor behaviour

Post by DanM »

All,

I'm currently setting up a new home and so am trying to resolve all the quirks in my lua code so everything plays a little better. One of the issues I'm having is with motion sensors that just stay 'on' when motion is detected during the on period. So for example a Fibaro with a 3 minute on period will stay on indefinitely if you walk past every 2 minutes (and will not refresh the 'last seen').

This means that if the sensor is already 'on' as sunset, you cannot rely on a device change to trigger the lights. It seems if you want to account for both the on at sunset and off at sunset scenarios you have to duplicate code - one version to react to the initial on (a device script), but a second to react if its already on (a time script). I cant help be feel like I'm missing a obvious trick here to avoid the duplication*.

* I know I could just have the time script but that might mean waiting up to a minute for the lights to react if they are off and the motion is triggered post sunset.

Any and all help appreciated as always.

Thanks,

Dan
trixwood

Re: Tips wanted RE motion sensor behaviour

Post by trixwood »

it's not exactly clear what your scenario is... you mean something like this?

One 'all' or 'device' script:

Code: Select all

commandArray = {}
   -- if night
   if (devicechanged['motion sensor'] and time <= sunrise and time >= sunset) then
      -- use pir sensor to control lamp
      if (otherdevices_svalues['motion sensor'] == 'ON')  then commandarray['lamp'] = 'SET lamp ON' end
      if (otherdevices_svalues['motion sensor'] == 'OFF') then commandarray['lamp'] = 'SET lamp OFF' end
   end
   -- by day, if lamp is still on turn off 
   if (otherdevices['lamp'] == 'ON'  and time > sunrise and time < sunset) then commandarrays['lamp'] = 'SET lamp OFF' end
return commandArray
excuse the pseudo code :-)
DanM
Posts: 79
Joined: Thursday 23 October 2014 22:41
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Tips wanted RE motion sensor behaviour

Post by DanM »

This is similar to what I have and I'm afraid doesn't solve the problem (appreciate the response though - thanks). Its a little difficult to explain, let my try with an example:

Say sunset time is 18.00.

At 17.58 my wife walks into the room at triggers the device changed for the motion sensor. The lights determine that the sun has not set and so no action is taken. The motion sensor records a last seen time of 17.58 and is then set as on for three minutes. The motion sensor is however pointing at my wife who is now sat on the sofa, and so is continually reacting to her motion. In the case of the Fibaro this means it simply extends on the on time.

Fast forward to 18.30, the Fibaro is still 'on' from the initial 17.58 sensor. No further 'device changed' signals have been sent, nor has the last seen time changed (which would be my other thought as so how to track) and so the lights remain off despite sunset being 30 minutes ago. One route around this (and the one I currently have) is to have a second time script that checks if a sensor is on and reacts to it, this works fine.

The issue is my motion sensor scripts are complicated, lights become progressively more yellow over the evening and so rather than just a sunset time I have 6 or 7 times and lux levels that they react to each implementing a new scene. I'm hoping there might be a way to avoiding the duplicate time script in my new setup. It may just be a necessary evil.

Any clearer?
trixwood

Re: Tips wanted RE motion sensor behaviour

Post by trixwood »

Aha, I got it. Let me think about it.
trixwood

Re: Tips wanted RE motion sensor behaviour

Post by trixwood »

With a user variable that saves the state it was in the last time it ran.
Put the script on 'ALL' not time or device.

Code: Select all

commandArray = {}
   night = toNumber(uservariables["Night"])
   -- if night
   if ( time <= sunrise and time >= sunset) then
      -- if we come from day and there was motion switch lamp on)              
      if (otherdevices_svalues['motion sensor'] == 'ON' and night == 0)  then commandarray['lamp'] = 'ON' end
      night = 1 -- true
      commandArray['Variable:Night'] = tostring(night)
      -- motion is triggered
      if (devicechanged['motion sensor']) then
        -- use pir sensor to control lamp
        if (otherdevices_svalues['motion sensor'] == 'ON')  then commandarray['lamp'] = 'ON' end
        if (otherdevices_svalues['motion sensor'] == 'OFF') then commandarray['lamp'] = 'OFF' end
     else
       -- by day, if lamp is still on turn off 
       if (otherdevices['lamp'] == 'ON' ) then commandarrays['lamp'] = 'OFF' end
       night = 0 -- false
       commandArray['Variable:Night'] = tostring(night)
    end
return commandArray
I chose a number for night (maybe call it something else) such that you can expand from it to more night-time-zones.

Like for three... (still pseudo code -> see next post)

Ofcourse suggestions are welcome!
And uhm, you need to create a uservariable and give it the right value.
Last edited by trixwood on Thursday 28 July 2016 18:42, edited 6 times in total.
trixwood

Re: Tips wanted RE motion sensor behaviour

Post by trixwood »

Code: Select all

commandArray = {}
   -- get the twinight-zone
   nightzone = toNumber(uservariables["NightZone"])
   -- if night
   if (time <= sunrise and time >= sunset) then
        -- if we come from day and there was motion switch lamp on)       
        if (time < sunset + 1h)       
            if (otherdevices_svalues['motion sensor'] == 'ON' and nightzone != 1) then 
                commandarray['lamp'] = 'ON' 
                commandarray['lamp'] = '40%' 
            end
            nightzone = 1 -- dusk
        -- now we coming from dusk!
        elseif (time < sunset + 2h)
            if (otherdevices_svalues['motion sensor'] == 'ON' and nightzone != 2) then
                 commandarray['lamp'] = ON' 
                 commandarray['lamp'] = '50%' 
            end
            nightzone = 2 -- evening
        else
            if (otherdevices_svalues['motion sensor'] == 'ON' and nightzone != 3) then 
                commandarray['lamp'] = 'ON'
                commandarray['lamp'] = '70%' 
            end
            nightzone = 3 -- rest of the night
        end
        commandArray['Variable:NightZone'] = tostring(nightzone)
        -- motion is triggered
        if (devicechanged['motion sensor']) then
            -- use pir sensor to control lamp
            if (otherdevices_svalues['motion sensor'] == 'ON') then
                commandarray['lamp'] = 'ON' 
                if (time < sunset + 1h)  then commandarray['lamp'] = '40%' 
                elseif (time < sunset + 2h)  then commandarray['lamp'] = '50%' 
                else commandarray['lamp'] = '70%' end
            end
            if (otherdevices_svalues['motion sensor'] == 'OFF') then commandarray['lamp'] = 'OFF' end
        end
    else
        -- by day, if lamp is still on turn off 
        if (otherdevices['lamp'] == 'ON' ) then commandarrays['lamp'] = 'OFF' end
        nightzone = 0 -- day
        commandArray['Variable:NightZone'] = tostring(nightzone)
    end
return commandArray
Ok this should fix that power failure issue (for most part)... anyway you're the tester (still pseudo code, I am not that good with lua from head)

Still loss of state due to restart/offline/powerfailure will make that one zone could fail at it's commands if it's in the wrong state (and you still have to wait until the next nightzone for it auto-correct it's state...) ow well ;-) can not have it all... the likelihood that that happens is very very small ;-)

(ie: motion is on, light are off due to 24h power failure and the state is still from 24h ago namely nightzone = 1 and time < sunset + 1h is true well, then you still sit in the dark until the next twinightzone)...
Last edited by trixwood on Thursday 28 July 2016 19:03, edited 6 times in total.
DanM
Posts: 79
Joined: Thursday 23 October 2014 22:41
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Tips wanted RE motion sensor behaviour

Post by DanM »

Thank you, much appreciated.
trixwood

Re: Tips wanted RE motion sensor behaviour

Post by trixwood »

Let me know if it worked ;-) And post your code here :!: I probably made some errors (timedate function, you probably can't just type sunset+1hour :D , dimmer level :o
User avatar
wolph
Posts: 16
Joined: Sunday 13 September 2015 16:12
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Tips wanted RE motion sensor behaviour

Post by wolph »

I have a fairly similar setup and I've solved it using 1 timer script. 1 devices script and a user variable to keep track of the idle time.

http://www.domoticz.com/wiki/Event_script_examples
DanM
Posts: 79
Joined: Thursday 23 October 2014 22:41
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: Tips wanted RE motion sensor behaviour

Post by DanM »

Hi,

So the code has evolved quite a lot over the last few days and may not be that relevant to my initial question but I wanted to share it here just in case anyone else would like to use any of it. Feel free to ask any questions and suggest amendments (its a bit over engineered).

Broadly speaking the purpose of the code is to do three things:
1. Turn on the lights when motion is detected (setting a count down timer)
2. Allow for different scenes to be executed at different times of the day
3. Reduce the countdown timer of other rooms in the house (on the basis that if you are in the living room, you probably aren't in the conservatory) This bit probably needs a bit more thought and could be cleverer

In addition to this there are three general categories of activation:
1. Motion detected when we are out
2. Motion detected when we are in and its dark
3. Motion detected when we are in, its dark and nightmode is on (this is a dummy switch to indicate that we are in bed).

In situations 1 and 3 the activated scene is hard coded, in the 2 situation the scene is read from a variable. The additional benefit of the variable is that I'm able to stop the motion sensors adjusting the scenes by having a 'none' scene. This means that if I want to show off my hue lights to visitors from the phone app or make use of scenes not in domoticz I dont have domoticz fighting me.

In addition to the code below there are two other scripts - one that counts down the countdown variables, and one that chnages the scene variable depending on time of day.

Thanks again for your help.

Dan

Code: Select all

--**********************************************************************************
-- script_device_MotionTriggered
-- PURPOSE: Tell all motion sensors when to turn on. The countdown script turns them off. 
--**********************************************************************************

--**********************************************************************************
-- timedifference function
--**********************************************************************************
function timedifference (s)
  year = string.sub(s, 1, 4)
  month = string.sub(s, 6, 7)
  day = string.sub(s, 9, 10)
  hour = string.sub(s, 12, 13)
  minutes = string.sub(s, 15, 16)
  seconds = string.sub(s, 18, 19)
  t1 = os.time()
  t2 = os.time{year=year, month=month, day=day, hour=hour, min=minutes, sec=seconds}
  difference = os.difftime (t1, t2)
  return difference
end


--**********************************************************************************
--  Motion Function (applies to all rooms)
--**********************************************************************************

function motion (room_name, countdown_name)
	
		--set the full scene name by adding room name to the active_scene
		scene_with_room = "Scene:" .. room_name .. " Lights " .. active_scene
		
		--whatever the house status tell people motion was sensed. 
		print("script_device_MotionTriggered: " .. room_name .. " motion triggered/active")
				
--Nobody home (so basically someone has broken in)
if otherdevices['Someone Home'] == 'Off'  then 

		-- send a notification
		commandArray['SendNotification']='Motion#Motion in ' .. room_name .. ' when there should not be#0'
		
		--turn on the LimitLess LED hub (probably not off, but just in case)
		commandArray['Limitless Plug (LRF 1,01)']='On'
		
		--turn the lights on bright red 
		commandArray["Scene:" .. room_name .. " Lights Red"]='On'
		
		--set the off timer to 3 minutes
		commandArray["Variable:" .. countdown_name]= tostring(3)	
		
		--set the other lights timers to 3 minutes
		set_countdown(countdown_name, 3)		
		
--Somebody home, its dark, but nightmode is not active (normal evening use)
elseif otherdevices['Someone Home'] == 'On' and otherdevices['Night Mode'] == 'Off' and uservariables["day_night"] == 'night'  then
		
		--Log the action to be performed
		print('script_device_MotionTriggered: Activing ' .. scene_with_room)
		
		--turn on the lights
		commandArray[scene_with_room]='On'
		
		--set the livingroom off timer to 60 minutes
		commandArray["Variable:" .. countdown_name]= tostring(60)
		
		--set the other lights timers to 15 minutes
		set_countdown(countdown_name, 15)
		
			
--Someone home, its dark and nightmode is active
elseif otherdevices['Someone Home'] == 'On' and otherdevices['Night Mode'] == 'On' and uservariables["day_night"] == 'night'  then
	 	
		--turn the lights on in Nightlight mode
		commandArray["Scene:" .. room_name .. " Lights NightLight"]='On'
		
		--set the off timer to 3 minutes
		commandArray["Variable:" .. countdown_name]= tostring(3)
		
		--set the other lights timers to 3 minutes
		set_countdown(countdown_name, 3)
		
end

end


--**********************************************************************************
--COUNTDOWN REDUCTION FUNCTION
--when the motion sensor is triggered this not only means that we are entering a room, but also that we are leaving another one. We therefore reduce countdown timers for every other room
--**********************************************************************************

 function set_countdown(countdown_name,countdown)
 
	--start with a list of rooms/countdown variables
	rooms = {'livingroom_countdown', 'conservatory_countdown'}

	for i, room in ipairs(rooms) do
	  if room == countdown_name then
	  --This is the active room, we dont want to do anything
	  else
	  --This is not the active room, we want to reduce the countdown
		  print ("script_device_MotionTriggered: Setting " .. room .." to " .. countdown)
		  if ( uservariables[room] > countdown) then
			commandArray['Variable:'.. room]= tostring(countdown)
		  end
	  end 
	end
end

--**********************************************************************************
-- START UP CODE 
--**********************************************************************************

--Initilise a command array
commandArray={}

--Make a log entry to show the script is running
print('script_device_MotionTriggered: Script running')

--get the active scene from the variable house_scene. This is set eleswhere in a timer script. All the scenes in the house has the format room_name Lights active_scene
-- EG Living Room Lights Bright
active_scene = uservariables["house_scene"]


--**********************************************************************************
-- LIVING ROOM
--**********************************************************************************

if devicechanged['Living Room Motion Sensor']=='On' or devicechanged['Living Room Motion Sensor 2']=='On' or otherdevices['Living Room Motion Sensor']=='On' or otherdevices['Living Room Motion Sensor 2']=='On' then

		--set the room name
		room_name = 'Living Room'

		--set the coundown_variable
		countdown_name = 'livingroom_countdown'
		
		motion(room_name,countdown_name)

	
end

--**********************************************************************************
-- CONSERVATORY
--**********************************************************************************

if devicechanged['Conservatory Motion Sensor']=='On' or otherdevices['Conservatory Motion Sensor']=='On' then

		--set the room name
		room_name = 'Conservatory'

		--set the coundown_variable
		countdown_name = 'conservatory_countdown'
		
		motion(room_name,countdown_name)
	
end

--**********************************************************************************
-- SET NOBODY HOME AFTER A THE HOUSE HAS BEEN EMPTY 24 HOURS
--**********************************************************************************

 if timedifference(otherdevices_lastupdate['Living Room Motion Sensor']) >   86400 then
 
 print('script_device_MotionTriggered: The motion sensor was last triggered 24 hours ago, switching to someone out')
 
	if otherdevices['Someone Home'] == 'On' then
	commandArray['SendNotification']='Nobody Home#No movement for 24 hours - predicting that someone is out and adjusting the house appropriately#0'
	commandArray['Someone Home']='Off'
	end

end

return commandArray
Post Reply

Who is online

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