HELP: Door contact rule

I’ve installed a recessed Z Wave sensor into my down stairs toilet door. The aim is to control the Hue light in my down stairs toilet. The easy part is getting the light to switch on and off when the sensor reports as open and then closed again.

What I need help with is how I put some logic into the rule so that the light doesn’t turn off straight away. Such as, you open the door to enter the toilet and then close the door after you the light needs to stay on until to open and then close the door again.

Any suggestion on how I’d get that into a rule?

This should give you a good start:

I’ve made some progress on getting my rule working. This is what I have so far. As I’m sure you can see, I need to close the door twice to turn the light off. Generally this works fine, however we use the toilet as a cloak room. This means that when getting a coat or putting one away we only open and close the door once. How can I add a calculation to work out the difference between opening and close, my idea is to switch the light off if the difference is 60 seconds or less.

rule "Toilet Door Open"
when
	Item Hallway_Toilet_Door_Sensor received update OPEN
then
	if (Hallway_Toilet_Occupied.state != "Yes") {
		Hallway_Toilet_Light.sendCommand(100)
		postUpdate(Hallway_Toilet_Occupied, "Yes")
	} else {
		postUpdate(Hallway_Toilet_Occupied, "No")
	}
end

rule "Toilet Door Closed"
when
	Item Hallway_Toilet_Door_Sensor received update CLOSED
then
	if(Hallway_Toilet_Occupied.state == "No") {
		Hallway_Toilet_Light.sendCommand(0)
	}
end

Thanks for your help.

Regards,

Garry

Keep a timestamp as a global var. Set the timestamp to now when the door opens. When the door closes check the timestamp with if(timestamp.isBefore(now.minusMinutes(1))

What have I got wrong with this? It’s trowing an exception and not working.

import org.openhab.core.library.types.*
import org.eclipse.xtext.xbase.lib.*
import org.openhab.core.library.types.DateTimeType
var DateTime timestamp = null

rule "Hallway Motion Sensor Activation"
when
	Item Hallway_Motion_Sensor changed from CLOSED to OPEN
then
	postUpdate(Hallway_Motion_Sensor_Last_Activation, new DateTimeType())
	if(TimeOfDay.state == "Evening") {
		Dining_Area_Bloom_Light.sendCommand(0)
	} else if (TimeOfDay.state == "Night") {
		Dining_Area_Bloom_Light.sendCommand(0)
	}
end

rule "Toilet Door Open"
when
	Item Hallway_Toilet_Door_Sensor received update OPEN
then
	var DateTime timestamp = now
	if (Hallway_Toilet_Occupied.state != "Yes") {
		Hallway_Toilet_Light.sendCommand(100)
		postUpdate(Hallway_Toilet_Occupied, "Yes")
	} else {
		postUpdate(Hallway_Toilet_Occupied, "No")
	}
end

rule "Toilet Door Closed"
when
	Item Hallway_Toilet_Door_Sensor received update CLOSED
then
	if(Hallway_Toilet_Occupied.state == "No") {
		Hallway_Toilet_Light.sendCommand(0)
	} else if(timestamp.isBefore(now.minusMinutes(1)) {
		postUpdate(Hallway_Toilet_Occupied, "No")
		Hallway_Toilet_Light.sendCommand(0)
	}
end

Here’s the error;
2016-11-28 20:54:46.295 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule ‘Toilet Door Closed’: The name ‘.isBefore()’ cannot be resolved to an item or type.

Since you are running OH 1.8 (apparently from the imports), you need to import org.joda.time.* so you are using the same class as now.

You may need to force timestamp to be a joda DateTime as well:

var org.joda.time.DateTime timestamp = null

Now getting this error; 2016-11-28 21:11:14.445 [ERROR] [o.o.c.s.ScriptExecutionThread ] - Error during the execution of rule ‘Toilet Door Closed’: cannot invoke method public boolean org.joda.time.base.AbstractInstant.isBefore(org.joda.time.ReadableInstant) on null

Better error.

You are recreating the timestamp in “Toilet Door Open” rather than saving the timesatmp to the global.

Change the first line of that rule to

timestamp = now

:slight_smile: Getting closer now. No longer getting the error, but the rule still isn’t working as I expect it to. Oh so close I feel.

Thanks for all your help Rich, hopefully it’s just something else that’s very simple.

Seems that the if statement is being ignored

if(timestamp.isBefore(now.minusMinutes(1))

Well, that is actually a complicated if/else/if statement. It isn’t ignoring the timestamp if, it is simply evaluating to true, or false (you haven’t actually said in what ways it isn’t working).

Add some logging statements so you can see the states of Hallway_Toilet_Occupied.state, timestamp, now, and now.minusMinutes(1) to see what state everything is in when you run.

As written, the else if clause will on run if Hallway_Toilet_Occupied.state equals something other than “No” and timestamp was taken more than a minute ago. The entire Rule only runs when Hallway_Toilet_Door_Sensor receives a CLOSED.

Make sure you are not receiving any extraneous OPEN updates on Hallway_Toilet_Occupied which would mess up your timestamp. If you are you can fix that by changing your rule trigger to Item Hallway_Toilet_Door_Sensor changed to OPEN