Help with simple Rule [motion dedector]

Hi,

I want do make a simple rule for Starting a pump triggered by motion and cron timer
Got the example from the forum but I allways get an error:
"error during the execution of rule … index 1 size 1"
The pump is starting but never going OFF.

var Timer timer = null
rule "Warmpaterpump ON"
when
        Time cron "0 30 6 ? * MON,TUE,WED,THU,FRI,SAT,SUN *" or
        Item BewEKue changed to OPEN or
        Item BewOGVR changed to OPEN
then
        if(timer==null) {
                sendCommand(Light_KG_Technikres, ON)
                timer = createTimer(now.plusSeconds(60)) [|
                                sendCommand(Light_KG_Technikres, OFF)
                        ]
                } 
       else {
                        timer.reschedule(now.plusSeconds(60))
        }
end

Also Im not sure if the else condition is ok or needed.

Add some logging to the rule to see which line it is failing on. I don’t see anything obviously wrong with this rule that would be causing that error.

In answer to your question about the else clause, what that will do it move the timer to turn off an additional minute into future if one of the triggering events occurs while the timer is still running.

There could be something wrong though. I say “could” because I’m not certain of the behavior of the reschedule method when called on an already triggered timer. I’m pretty sure that it fails and you have to recreate the Timer. You can easily make sure that happens by adding:

timer = null

right after sendCommand(Light_KG_Technikres, OFF).

I changed my code - without the else reschedule

var Timer timer = null

rule "Warmpaterpump ON"
when
        Time cron "0 30 6 ? * MON,TUE,WED,THU,FRI,SAT,SUN *" or
		Item BewEKue changed to OPEN or
		Item BewOGVR changed to OPEN
then
        if(timer==null) {
			sendCommand(Light_KG_Technikres, ON)
			logInfo("RuleInfo", "Warmwasserpumpe START")
			timer = createTimer(now.plusSeconds(60)) [|
				sendCommand(Light_KG_Technikres, OFF)
				logInfo("RuleInfo", "Warmwasserpumpe STOP")
				timer = null
                        ]
		} 
end

Now the Pump will be started and stopped --> sometimes I get an org.eclipse.jetty.io.EofException Error - but not sure if the error is coming from the rule or from somewhere else

BUT I would like to use the else for waiting a certain amount of time.

The items Bew* are Motiondedectors and when someone is in the room it will be triggered a couple of times.

should I use Thread::sleep(60000) before/or after timer = null ? I read somewhere that it isnt good memory managment using Thread::sleep.

Any exception is of concern, but I doubt that particular one is related to this particular rule.

Wait a certain amount of time before doing what? You are already waiting a certain amount of time with your timer. And if you have a timer (i.e timer != null) your rule does nothing so getting multiple events isn’t a problem.

The last thing you need to worry about is memory management with a rule like this. And besides, Timers and Thread::sleep have to different purposes and do two different things. Both have their place in rules.

1 Like

Thanks for the response.
The reason I was thinking about another timer(sleep thread) was that I didnt want the pump to run continuously when there is motion dedected the whole time.
Something more like run for one minute then wait 10 minutes and run again if there is motion.

For more explanation this is a circulation pump to circulate the warm water through the house. So that you dont need to wait a long time til warm water is coming out of the pipe. So I would like to start the pump in the morning or every time someone is near the kitchen or bath.

I have my OH2 running in a VM on a Intel NUC so memory managment shouldnt be a problem?

Hi Daham,
Just for fun, I did your scenario in Node-RED in just 5 minutes.

I simulated it, and it does all, what you need, including one run at 6:30, activation from two motion sensors for 60s and your last request to limit pump operation to maximum once per 10 minutes. If necessary I can throw you JSON code to try.
What you need is to setup MQTT binding, if you haven’t done this yet and install Node-Red. I guarantee it will work 100%.

Looks very cool and will try to set it up.

I dont have MQTT so short question - do I need to add a second item vor every information I want to transfer to node-red?

There are lots of ways you can do this. It is called the Latch Design Pattern. Below is a way to do it using a timestamp to see when the last time the pump was run and only run it if it has been longer than 10 minutes ago.

var Timer shutoffTimer= null
var DateTime lasRun = now.minusMinutes(10) // on a reboot run the pump on the first event

rule "Warmpaterpump ON"
when
        Time cron "0 30 6 ? * MON,TUE,WED,THU,FRI,SAT,SUN *" or
		Item BewEKue changed to OPEN or
		Item BewOGVR changed to OPEN
then
    if(lastRun.isBefore(now.minusMinutes(10)) {
        if(timer==null) {
	    sendCommand(Light_KG_Technikres, ON)
            lastRun = now
	    logInfo("RuleInfo", "Warmwasserpumpe START")
	    timer = createTimer(now.plusSeconds(60)) [|
                sendCommand(Light_KG_Technikres, OFF)
                logInfo("RuleInfo", "Warmwasserpumpe STOP")
		timer = null
            ]
        } 
    }
end

Thread::sleep won’t do what you want. It will mainly just make it so it takes ten minutes before the rule exits. It won’t prevent multiple instances of the rule from running.

Not necessarily. You can have multiple bindings applied to the same Item so when, for example, a Switch turns ON that gets sent out over MQTT.

1 Like

thx
var declaration lasRun = lastRun
but after changing that:

2016-10-05 16:53:43.076 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'warmwaterStart.rules'
2016-10-05 16:53:45.709 [ERROR] [.script.engine.ScriptExecutionThread] - Rule 'Warmpaterpump ON': An error occured during the script execution: The name '<XFeatureCallImplCustom>.isBefore(<XMemberFeatureCallImplCustom>)' cannot be resolved to an item or type.
2016-10-05 16:54:01.020 [WARN ] [jetty.server.handler.ResourceHandler] - org.eclipse.jetty.io.EofException
2016-10-05 16:55:01.290 [ERROR] [org.quartz.core.JobRunShell         ] - Job DEFAULT.2016-10-05T16:50:01.207+02:00: Proxy for org.eclipse.xtext.xbase.lib.Procedures$Procedure0: [ | {`..............

The method may be called before instead of isBefore. I don’t have access to my setup right now to double check.

No. It’s even simpler. You don’t have to change your items file at all. Once you install mqtt binding you should only setup Event Bus Binding in openhab.cfg by providing statePublishTopic and commandSubscribeTopic parameters there. This will automatically bind all your items to MQTT, so they will appear as topics on MQTT broker. This will look something like this (it’s a log from MQTT broker):

First string before space is item name, after space it is it’s value.
In Node-RED you just drag and drop MQTT In node and configure it to subscribe to relevant state topic


That’s it. This will be your input in Node-Red. With pump it will be the same, but in opposite direction. You will have to publish to command topic.