Timer rule for MQTT lights Group

Hello,
I want to set a timer for a group of MQTT lights in Openhab.
If I turn the Fence lights ON after 5 hours it will turn off automatically.
Can anyone help me do that?
Thank you!

ITEMS:

Group All
Group Fence                 (All)

Group:Switch:OR(ON, OFF) 		Fence 		    "Outside Lights   [(%d)]" 		        (All)



Switch 			LightD27		 	"Fence1"	     	(Fence, CmdGroup ) 		["Lighting"] 	{mqtt=">[mosquitto:ST/LD27/cmd:command:*:default],<[mosquitto:ST/LD27/state:state:default:.*]", autoupdate="false"}
Switch 			LightD23		 	"Fence2"		    (Fence, CmdGroup ) 		["Lighting"] 	{mqtt=">[mosquitto:ST/LD23/cmd:command:*:default],<[mosquitto:ST/LD23/state:state:default:.*]", autoupdate="false"}
Switch 			LightD19		 	"Fence3"		    (Fence, CmdGroup ) 		["Lighting"] 	{mqtt=">[mosquitto:ST/LD19/cmd:command:*:default],<[mosquitto:ST/LD19/state:state:default:.*]", autoupdate="false"}
Switch 			LightD18		 	"Fence4"		    (Fence, CmdGroup ) 		["Lighting"] 	{mqtt=">[mosquitto:ST/LD18/cmd:command:*:default],<[mosquitto:ST/LD18/state:state:default:.*]", autoupdate="false"}
Switch 			LightD16		 	"Fence5"		    (Fence, CmdGroup ) 		["Lighting"] 	{mqtt=">[mosquitto:ST/LD16/cmd:command:*:default],<[mosquitto:ST/LD16/state:state:default:.*]", autoupdate="false"}
Switch 			LightD14		 	"Fence6"		    (Fence, CmdGroup ) 		["Lighting"] 	{mqtt=">[mosquitto:ST/LD14/cmd:command:*:default],<[mosquitto:ST/LD14/state:state:default:.*]", autoupdate="false"}
Switch 			LightD3		 	    "Fence7"		    (Fence, CmdGroup ) 		["Lighting"] 	{mqtt=">[mosquitto:ST/LD3/cmd:command:*:default],<[mosquitto:ST/LD3/state:state:default:.*]", autoupdate="false"}
Switch 			LightD11		 	"Fence8"		    (Fence, CmdGroup ) 		["Lighting"] 	{mqtt=">[mosquitto:ST/LD11/cmd:command:*:default],<[mosquitto:ST/LD11/state:state:default:.*]", autoupdate="false"}
Switch 			LightD24		 	"Fence9"		    (Fence, CmdGroup ) 		["Lighting"] 	{mqtt=">[mosquitto:ST/LD24/cmd:command:*:default],<[mosquitto:ST/LD24/state:state:default:.*]", autoupdate="false"}

SITEMAPS:

sitemap home label="MyHome"
{

    
	Frame label=""{
		Group item=Fence {
			
		Switch item=Fence label="  [%d]" mappings=[OFF="All Off", ON="All On"] icon="switch"
           
		 
		 Switch item=LightD27
		 Switch item=LightD23		 
         Switch item=LightD19		 	
         Switch item=LightD18		 	
         Switch item=LightD16		 	
         Switch item=LightD14		 	
         Switch item=LightD3		 	
		 Switch item=LightD11		 	
         Switch item=LightD24	
		}
	}
	
}	
rule "timer to turn lights off"
when
  Item Fence changed to ON
then
  createTimer(now.plusHours(5)) [| Fence.sendCommand(OFF) ]
end

Note that you have defined a Group nameed Fence twice; I think the second occurrence “wins”.

Thank you!
Could it be done so that the time can be adjusted from the user interface?

Sure. Create a Number Item and put in your UI with a setpoint or similar. Think about how you want to initialize that at system startup. Use its state in your rule - tip, you need the integer value for the plusHours()

Hello,
I tried this but it doesn’t work
.items:

Group All
Group Fence                 (All)


Group:Switch:OR(ON, OFF) 		Fence 		    "Outside Lights   [(%d)]" 		        (All)
Switch                          Fence           "my Auto-off Fence Light [%s]"
Number                          myHours         "my hours [%d]" 


Switch 			LightD27		 	"Fence1"	     	(Fence, CmdGroup ) 		["Lighting"] 	{mqtt=">[mosquitto:ST/LD27/cmd:command:*:default],<[mosquitto:ST/LD27/state:state:default:.*]", autoupdate="false"}
Switch 			LightD23		 	"Fence2"		    (Fence, CmdGroup ) 		["Lighting"] 	{mqtt=">[mosquitto:ST/LD23/cmd:command:*:default],<[mosquitto:ST/LD23/state:state:default:.*]", autoupdate="false"}
Switch 			LightD19		 	"Fence3"		    (Fence, CmdGroup ) 		["Lighting"] 	{mqtt=">[mosquitto:ST/LD19/cmd:command:*:default],<[mosquitto:ST/LD19/state:state:default:.*]", autoupdate="false"}
Switch 			LightD18		 	"Fence4"		    (Fence, CmdGroup ) 		["Lighting"] 	{mqtt=">[mosquitto:ST/LD18/cmd:command:*:default],<[mosquitto:ST/LD18/state:state:default:.*]", autoupdate="false"}
Switch 			LightD16		 	"Fence5"		    (Fence, CmdGroup ) 		["Lighting"] 	{mqtt=">[mosquitto:ST/LD16/cmd:command:*:default],<[mosquitto:ST/LD16/state:state:default:.*]", autoupdate="false"}
Switch 			LightD14		 	"Fence6"		    (Fence, CmdGroup ) 		["Lighting"] 	{mqtt=">[mosquitto:ST/LD14/cmd:command:*:default],<[mosquitto:ST/LD14/state:state:default:.*]", autoupdate="false"}
Switch 			LightD3		 	    "Fence7"		    (Fence, CmdGroup ) 		["Lighting"] 	{mqtt=">[mosquitto:ST/LD3/cmd:command:*:default],<[mosquitto:ST/LD3/state:state:default:.*]", autoupdate="false"}
Switch 			LightD11		 	"Fence8"		    (Fence, CmdGroup ) 		["Lighting"] 	{mqtt=">[mosquitto:ST/LD11/cmd:command:*:default],<[mosquitto:ST/LD11/state:state:default:.*]", autoupdate="false"}
Switch 			LightD24		 	"Fence9"		    (Fence, CmdGroup ) 		["Lighting"] 	{mqtt=">[mosquitto:ST/LD24/cmd:command:*:default],<[mosquitto:ST/LD24/state:state:default:.*]", autoupdate="false"}



.sitemaps:

sitemap home label="MyHome"
{

    
	Frame label=""{
		Group item=Fence {
			
		Switch item=Fence label="  [%d]" mappings=[OFF="All Off", ON="All On"] icon="switch"
        Setpoint item=myHours step=5 minValue=5 maxValue=120 icon="time"
		 
		         Switch item=LightD27
		         Switch item=LightD23		 
                 Switch item=LightD19		 	
                 Switch item=LightD18		 	
                 Switch item=LightD16		 	
                 Switch item=LightD14		 	
                 Switch item=LightD3		 	
	             Switch item=LightD11		 	
                 Switch item=LightD24	
		}
	}
	
}	

.rules:

import org.joda.time.DateTime

var Timer myTimer = null

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

you now have 3 Fence items with the same name in your items-file, which is incorrect:

Group Fence                 (All)
Group:Switch:OR(ON, OFF) 		Fence 		    "Outside Lights   [(%d)]" 		        (All)
Switch                          Fence           "my Auto-off Fence Light [%s]"

only keep the middle one, remove the top and bottom ones and try again

Come on, give us something to work with. What happens that you don’t expect, what doesn’t happen that you do?
When developing rules, always check openhab.log. If there’s nothing there, say so. If wondering if something happened or not, check events.log, tell us what you see.

Okay, so I gave a very old example because it was simple

remove this line from your rules, this was needed in OH1 but not wanted in OH2

I use Openhab2
13:56:19.269 [ERROR] [untime.internal.engine.RuleEngineImpl] - Rule ‘my auto off
rule’: cannot invoke method public void java.util.Timer.cancel() on null

It’s right you know; you can’t cancel a timer that doesn’t exist.
The rule tries to cancel the timer everytime the Item changes, even if no timer is null.

Tip - this sneaky small change will cancel the timer if it exists, but not complain if it doesn’t.

myTimer?.cancel

i remove the line import org.joda.time.DateTime
my rules:

var Timer myTimer = null

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

When i press the ON button i receive this:
14:28:39.294 [ERROR] [untime.internal.engine.RuleEngineImpl] - Rule ‘my auto off
rule’: An error occurred during the script execution: Could not invoke method:
org.joda.time.DateTime.plusSeconds(int) on instance: 2019-08-07T14:28:39.292+03:
00

When i press the OFF button i receive this:
14:28:41.974 [ERROR] [untime.internal.engine.RuleEngineImpl] - Rule ‘my auto off
rule’: cannot invoke method public void java.util.Timer.cancel() on null

Try to convert the myHours to int:

myTimer = createTimer(now.plusSeconds((myHours.state as DecimalType).intValue)) [|

Also applies to plusSeconds
The exact error and the fix is described in the old thread you copied

createTimer(now.plusSeconds( (myHours.state as DecimalType).intValue )

Thank you # [duiffie] & # [rossko57] !!! :slight_smile:

var Timer myTimer = null

rule "my auto off rule"
when
    Item Fence changed
then
    if (Fence.state==OFF) {
        myTimer?.cancel
        myTimer = null
    }
    else if (Fence.state==ON) {
        if (myTimer!=null) {
            myTimer.cancel
            myTimer = null
        }
        myTimer = createTimer(now.plusMinutes((myHours.state as DecimalType).intValue)) [| 
           Fence.sendCommand(OFF)
        ]
    }
end        

Does anyone help me with this suggestion?
“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.”

How do myHours keep their value even if openhab is reset?
Can you explain further to my meaning?
Thank you

Magic word is persistence, which stores values in a database. The function you are looking at is restoreOnStartup, which uses the database to repopulate selected Items at system boot. Mapdb is the simple one-value database for just this purpose.

Yes,
for me Persistence is a total fog
I need a knowledgeable guide to get to the destination.
I will open a new topic can someone help me