Need help with rule to only execute on manual button press of device

Hey there guys, I Have an Insteon dimmer switch and motion sensor in my garage, I want the motion sensor to turn on the lights for a period of time then off (I have this part figured out). the next part is trickier, I want the motion sensor disabled if the switch is manually turned on, and then re-enabled when the switch is manually turned off. That way If I’m working on a project outside of the motion sensor I could have the lights stay on. Anyway I’ve been trying to figure this out for a few days now, and though I think my rules are heading in the right direction, I can’t seem to get it right.

so I’ll just layout what I’ve got so far, I’d really appreciate some help with this, Thanks in advance to anyone who can help.

Setup:
OH2 2.1.0-1 running on RPI2 (openhabian)
Items:

Dimmer garageLights "Garage Lights [%d %%]" (garage) {insteonplm="2B.DA.30:F00.00.01#dimmer"}
Contact GarageMotion "motion sensor [MAP(contact.map):%s]" (garage) {insteonplm="31.81.5E:0x00004A#contact"}
Switch grageMotionEnable "Garage Motion Enable"
Switch garageLightsTimer {expire="5m,command=OFF"}

Rules:

rule "Garage Motion"
	when
		Item GarageMotion received update
	then
		if (grageMotionEnable.state == ON){
			sendCommand(garageLightsTimer,ON)
			sendCommand(garageLights,100)
		}
end

rule "Turn Off Garage Lights"
	when
		Item garageLightsTimer received update OFF
	then
		if (grageMotionEnable.state == ON){
		sendCommand(garageLights,0)
		}
end

rule "Enable Garage Motion Sensor"
 when
 	Item garageLights received update 0
 then
 sendCommand(grageMotionEnable,ON)
end
 	
rule "Disable Garage Motion Sensor"
 when
 	Item garageLights received update 100
 then
 sendCommand(grageMotionEnable,OFF)
end

The “Enable Garage Motion Sensor” and “Disable Garage Motion Sensor” Rules is where My difficulties lie, I’d like those to only execute when I manually operate the switch, currently they execute whenever the state changes, Is even it possible to do this?

You have to get the manual switch state to openHAB. I don’t know insteon, so is this possible? of course you could define a marker, problem is, maybe the light went on through motion detection, but you want to switch it on manually, how to determine that? For preventing openHAB from disabling motion detection, I would change the rule like that:

rule "Disable Garage Motion Sensor"
when
    Item garageLights received update 100
then
    if(garageLightsTimer.state == OFF)
        grageMotionEnable.sendCommand(OFF)
end

It is challenging to be sure. The DP should give you some ideas. At a high level it sets a flag that is normally set to one value (i.e. MANUAL) but when a Rule executes it temporarily sets it to “RULE” (i.e. when you turn on/off the light from the motion sensor). When the Light changes state and the flag is set to MANUAL you know that the Light was manually triggered and you can set an override flag. If the flag is RULE you know the light changed because of the motion sensor and you would not set the override flag.

The above does depend on your switch reporting when it is toggled manually to OH or else there is no way for OH to know the light actually changed state.

1 Like

I think Openhab is aware when, I press a switch manually I get this in the logs whenever I press one of them:

2017-10-12 14:58:51.991 [INFO ] [onplm.internal.device.MessageHandler] - LightOnDimmerHandler: device 30.9C.4A was turned on REGULAR. Sending poll request to get actual level

But I’m not sure how to use that, or what to do with it.

I do think your example will work for my use case though, so I’ll give it a try and report back. Thank you so much.

Ok Code tested, and works but now I have another behavior(which after I took another look at the code, I would expect it). when the switch is pressed manually, it doesn’t disable the motion sensor, if it was already triggered from the motion sensor. any thoughts on that?

I’m Assuming I’m going to have to figure out how openhab can determine where the signal came from, as you had outlined in you first post?

If this helps, here is my rule block for garage lights for turning on / off by motion if dark… You could also just turn ON by motion and kick off a timer for a longer period to turn off (reset the time on new motion events)…

var Number glOnByMotion = 0
 
rule "GarageMotion"
when
	Item GarageMultiSensor_BinarySensor changed to ON
then
	logInfo("RuleMonitor", "AEON_Garage_Sensor changed to ON")
	if (GarageMultiSensor_SensorLuminance.state < 100 && GarageLights_Switch.state == OFF) {
		// set to 1 to indicate lights are on by motion
		glOnByMotion = 1
		sendCommand(GarageLights_Switch, ON)
		logInfo("RuleMonitor", "Garage Lights Triggered ON by Motion")
	}
end

rule "GarageNoMotion"
when
	Item GarageMultiSensor_BinarySensor changed to OFF
then
	logInfo("RuleMonitor", "AEON_Garage_Sensor changed to OFF")
	if (glOnByMotion == 1) {
		// set to 0 to indicate lights are off by motion
		glOnByMotion = 0
		sendCommand(GarageLights_Switch, OFF)	
		}
end

OH Thank you so much, that’s exactly what I needed.

1 Like

I just wanted to add to the conversation. This is my rule to accomplish this. It turns the lights on and will shut them off one minute after the last motion is detected, unless they were turned on by a switch. I also use a Daylight switch set by the Astro binding to only turn it on at night.

var Timer porch_timer = null

rule "Outside lights off"
when Item MotionSensor_BinarySensor changed from ON to OFF
then
if (porch_timer===null && Daylight.state == OFF && outside_Motion_detect == 1) {
// motion detected
logInfo(“Outside”,“Starting timer for turning off the lights”)
porch_timer = createTimer(now.plusSeconds(60)) [|
logInfo(“Outside”,“Turning lights off”)
sendCommand(porchLight, OFF)
porch_timer = null
outside_Motion_detect = null ]
} else if (porch_timer !== null && Daylight.state == OFF && outside_Motion_detect == 1) {
logInfo(“Outside”, “We have a timer already, rescheduling”)
porch_timer.reschedule(now.plusSeconds(60))
}
end

rule "Outside light motion On"
when
Item MotionSensor_BinarySensor changed from OFF to ON or Item MotionSensor_BinarySensor changed from NULL to ON
then
//if(porchLight.state == OFF && Daylight.state == OFF ) {
if(porchLight.state == OFF && Daylight.state == OFF ) {
outside_Motion_detect = 1
sendCommand(porchLight, ON)
porch_timer = null
}
end