Turn light off based on timer

Hi All,

Can someone give me an example on how to turn off lights base on timer variable?

I need to achive the following.

From the GUI when the light is turned on, I need to turn off the light after the number of hours mentioned in the GUI.

.items:

Switch myLight "my Auto-off Light [%s]" {...} // The light
Number myHours "my hours [%d]" // no binding needed

.sitemap:

    Setpoint item=myHours step=1 minValue=1 maxValue=12

.rules:

import org.joda.time.DateTime

var Timer myTimer = null

rule "my auto off rule"
when
    Item myLight changed
then
    if (myLight.state==OFF) {
        myTimer.cancel
        myTimer = null
    }
    else if (myLight.state==ON) {
        if (myTimer!=null) {
            myTimer.cancel
            myTimer = null
        }
        myTimer = createTimer(now.plusHours(myHours.state as DecimalType)) [| //use now.plusSeconds() for testing
            myLight.sendCommand(OFF)
        ]
    }
end        

For convenience, myHours should be persisted for example with mapdb (strategy = everyChange, restoreOnStartup) so if openHAB is restarted, myHours will be set to the last value.

1 Like

This give error as “Could not invoke method: org.joda.time.DateTime.plusSeconds(int) on instance:”

Got this fixed by adding .intValue.

Now I have another problem, How to make the same rule to work in minutes and hours both?

As I can’t access an openHAB Designer right now, I can only guess. Maybe
now.plusHours(h).plusMinutes(m)
would work. If not, you can use
now.plusMinutes(m + h*60)
:slight_smile:

Thanks @Udo_Hartmann this works fine.

Hi,

I am using Udo’s rule for a timer of a coffee maker. Obviously it seems, that the rule is working but not with the exact time to auto-off the coffee maker.

For example:

15:49:31.762 [INFO ] [marthome.event.ItemStateChangedEvent] - Wallplug1_Switch changed from OFF to ON
15:50:53.441 [INFO ] [marthome.event.ItemStateChangedEvent] - Wallplug1_Switch changed from ON to OFF

The timer was set to 2 minutes (now.plusMinutes).

Is there anything I have to consider?

The rule is:

var Timer myTimer_Kaffeemaschine = null

rule "Kaffeemaschine auto off"
when
    Item Wallplug1_Switch changed
then
    if (Wallplug1_Switch.state==OFF) {
        myTimer_Kaffeemaschine.cancel
        myTimer_Kaffeemaschine = null
    }
    else if (Wallplug1_Switch.state==ON) {
        if (myTimer_Kaffeemaschine!=null) {
            myTimer_Kaffeemaschine.cancel
            myTimer_Kaffeemaschine = null
        }
        myTimer_Kaffeemaschine = createTimer(now.plusMinutes(minutes_auto_off_kaffee.state as DecimalType)) [| //use now.plusSeconds() for testing
            Wallplug1_Switch.sendCommand(OFF)
        ]
    }
end

Can somebody point my to the right direction?

Thank you!

Greetings Johannes

I don’t see where you defined your val for the time off variable?

It’s a number item:

Number minutes_auto_off_kaffee "Auto-Off in Minuten [%d]" 

and under Habpanel I have a knob to define the value.

I would drop in a logInfo(“Kafffemschine”,"Timer: " + minutes_auto_off_kaffee.state) to double check your value is what you think it should be. You can also drop in a couple more earlier in your script to verify execution times of when it got the On state reported to it.

I have the same result with a fixed number insider the expression “now.plusMinutes(2)”, but I will check it.

The other item to be aware of is Timers keep running during rule reloads so you can end up with timer conflicts if it hasn’t been enough time for the first one to expire. Other then that, (and I’m not an expert) though I do see a missing comma in your createTimer statement before the [| that I normally see in the examples I’ve used as a basis for mine but you’d think that would break it entirely not cause a time shift.

createTimer(now.plusMinutes(minutes_auto_off_kaffee.state as DecimalType)) ,[|

This one?

yes. Like I said, a bit of a copy hack myself but did notice that variance. Not familiar enough with Java to know the purpose

Ok, Rule fired but know I get this error:

An error occured during the script execution: Could not invoke method: org.joda.time.DateTime.plusMinutes(int) on instance: 2017-02-28T19:27:55.957+01:00

My import at the beginning of the rule file:

import org.joda.time.DateTime

What is missing.

Thank you for your help!

What does the loginfo say, that you added to see what was passed to the timer?

I tested the logInfo output of the timer only with a fixed value (e.g. 2) inside the now.plusMinutes expression. I think the problem is the format of the number I will give into this expression. I used the expression from Udo:

Number myHours "my hours [%d]"

but changed to minutes. Could this be this expression for the formating

[%d]

problem?

I have checked: The timer don’t start, so I can not check the logInfo output.

Your plusMinutes error message is hinting that it wants to be supplied with an integer value.
Try (myHours.state as Number).intValue

The [%d] in the Item label is only about how you choose to display the number, in this case as a decimal.

Thank you, tomorrow I will give it a try.

Good night

Still no luck, this is the output:

Rule 'Kaffeemaschine auto off': An error occured during the script execution: The name '<XFeatureCallImplCustom>.state' cannot be resolved to an item or type.

and the smart home Designer says:

Type mismatch: cannot convert from Number to int

When I turn the coffee maker off the following log appears in karaf:

Rule 'Kaffeemaschine auto off': cannot invoke method public abstract boolean org.eclipse.smarthome.model.script.actions.Timer.cancel() on null

Thank you for any hint!