Motion based lightcontrol

Hello,
I would like that light before the timer ends after 2min the light dims 30sec before it stops. I’ve tried different things but with timers I can’t go any further. It does not work in all conditions.

  1. light on with a single movement
  2. light on with renewed movement
  3. light on during continuous movement and then leave the area.

I found this function and modified it a bit.
PS: it should work like philips hue motionsensor rule.
Thanks for your help

val Map<String, Timer> LightingTimers = newHashMap //used for motion detection timers

val Functions$Function4<GenericItem, Number, Number, Map<String, Timer>, Boolean> MakeLightTimer = [ //function (lambda) to create/reschedule/cancel timer (call with time set to 0 to cancel)
item,
level,
time,
timers |

var String timerKey = item.name
var String timerKey2 = item.name + "-2"
if (timers.containsKey(timerKey)) {
    var Timer timerTmp = timers.get(timerKey)
    var Timer timerTmp2 = timers.get(timerKey)
    if(time == 0) {
        timerTmp.cancel()
        timers.remove(timerKey)
        timerTmp2.cancel()
        timers.remove(timerKey2)
        logInfo("Light Timer Function", timerKey + " Timer cancelled" )
    }
    else {
    	timerTmp.reschedule(now.plusSeconds(time))
    	if(timerTmp2 != null)
        	timerTmp2.reschedule(now.plusSeconds(time).minusSeconds(30))
        else{
        	timers.put(timerKey2, createTimer(now.plusSeconds(time).minusSeconds(30)) [|
            logInfo("Dimming Light Timer Function", timerKey2 + " Motion over, Light turning OFF" )
            sendCommand(item, 30)
            timers.remove(timerKey2)]) 
        }
        	
        logInfo("Light Timer Function", timerKey + " Motion detected, Timer recheduled for " + time + " more seconds" )
        sendCommand(item, level.intValue)
        }
    }
else {
    if(time != 0) {
        if(level == 0)        sendCommand(item, OFF)
        else if(level == 100) sendCommand(item, ON)
        else                  sendCommand(item, level.intValue)
        logInfo("Light Timer Function", timerKey + " Motion detected, Light set to: " + level)
        timers.put(timerKey2, createTimer(now.plusSeconds(time).minusSeconds(30)) [|
            logInfo("Dimming Light Timer Function", timerKey2 + " Motion over, Light turning OFF" )
            sendCommand(item, 30)
            timers.remove(timerKey2)])   
        }
        
        timers.put(timerKey, createTimer(now.plusSeconds(time)) [|
            logInfo("Light Timer Function", timerKey + " Motion over, Light turning OFF" )
            sendCommand(item, OFF)
            timers.remove(timerKey)])
           logInfo("","ENDS OF FUNTION" ) 
         
    }
true
]

rule "Flur OG Licht"
when
Item Flur_Hue_Motion2_motion changed to ON
then

MakeLightTimer.apply(diBrightness,80,60,LightingTimers)

end

Is the motion Item declared as a Switch? Normally they are Contact Items in which case you’d need to be looking for OPEN not ON

Also do you keep receiving ON messages for continued motion or does it just remain ON? Different devices operate in different ways so you need to test and understand how your device works. My PIR will go OPEN on first detection, so I turn on the light, but the next message I receive will only be CLOSED I wont get any more OPEN messages for continued presence/motion. So my rule creates a timer to turn the lights OFF when I receive the CLOSED message, the OPEN checks for and cancels the timer in case someone comes back in that time period. My PIR will go CLOSED after about 60 seconds of no motion so I take that in to account when I create my timers but again that can vary from device to device and often can be controlled on the device.

You’ve not provided any logs but I’m guessing that’s because you’re not really getting any at the moment. I would add a logInfo to the entry point of the rule as well to make sure the rule is firing.

Although this wont fix the basics you really need to make the lambda function thread safe. This post shows the basics of how to do that for a rule with a timer just apply the principles to your lambda and timers rather than the calling rule. You’ll need to add a 5 parameter to the lambda so you can pass in the global Lock:

Hi
thanks for replay
i use the philips hue motion sensors. i retrive actions via json from hue bridge.
i get a ON Command for Motion and OFF after a few sec. During motion its still ON

I don’t use them and don’t know anything about them. I could spend an hour researching them just to help with your issue or it would be easier for me if you directly answered the question. Is the motion Item declared as a Switch? Fair enough if you don’t know but you can tell me that as well.

Did you add a logInfo entry to your Rule? Assuming you did, did it appear in the openhab.log?