OH3 how to create simple pir light with reschedule timer

Hello,
many of uf first of later will try to implement a PIR based light for his home.

With openhab 3 enviromet rule engine is quite simple…
you decide the triggers elements, the conditions of trigghering and a very little script like the following to execute:

sendCommand(Light_Power, ON)
createTimer(now.plusSeconds(200)) [|
	sendCommand(Light_Power, OFF) ]

this works quite well,but after 200 sec i need to re-trigger because i’m missing a very important feature…

how to reschedule timer if the PIR triggers again before the end of the rule?
I’m not able to run the same rule as previous openhab 2.

Many thanks in advance!!!

I’m not a le to understand how to work with rules without global variable like timers. Any help?

Thanks a lot

I would use expire binding on a textual item in OH2 and is included in OH 3 as a metadata variable

something like

expire=“200ms,command=OFF”

on an OH2 item

add as metadata in OH3 - click Add Metadata - choose expiration timer

This way once the time is up it will do the command eg off. If it is triggered again it starts the timer again.
This also gets round the numbers of timers you can have (2 in OH2 - no idea about in 3).
Timers have their uses but expire is better here.

Hello,
Ok, but is also possible to expire with timer only after certain hour of the day?
Maybe did not understand well the feature. If I add metadata expire to a switch it will switch off after some time right?

Hello Muplex,

I know what you mean. I used this feature very often in OH2. I had a special switch for this. Example: Kids wake up in the night. Then I make ligth on for 30 minutes, all go to bed. OH will switch it off. But on the evening I don’t want it.

For OH3 I have no solution at the moment too.

Exactly
Proliferation of “dummy switches” is not smart and efficient at all as rule management in my opinion.
I hope OH staff take in consider these big laks and will implement something in next release… My rule now is not the same as before without global and timer variable…

Thanks for reply

What is it you were trying to do?

You can still run text file rules in OH3. Then you can use you global timers.

1 Like

But I have to copy only the “body” inside a script like these
1)

Or copying the same rule of OH2 and paste here ?
2)

That :point_up_2:t2:
You can use the same folders as OH2.

I’m trying from days to run a one with these method… no luck
I adapt getHourofDay to getHour but no luck and other adaptation/migration stuff find in the forum but the rule with globals var does not trigger at all

Can you post your OH2 rule?

Yes sure. and many thank you foy your help :star_struck:

It is basically an energy monitor for may fotovoltaic + normal energy system.
timers it to prevent alexa trigget continously the High consumption warning.

//Global Varibles
var Timer Timer_Pow = null

rule "Energymonitor"
when
    Item MQTTEnergymonitor_EnelPotenzaReale received update or
    Item MQTTEnergymonitor_PannelliPotenzaReale received update
then 
	if (MQTTEnergymonitor_EnelPotenzaReale.state > 0 && MQTTEnergymonitor_PannelliPotenzaReale.state > 0) 
	{
		Ist_Consumo.postUpdate(MQTTEnergymonitor_PannelliPotenzaReale.state as Number + MQTTEnergymonitor_EnelPotenzaReale.state as Number)
		Ist_Prelievo.postUpdate(MQTTEnergymonitor_EnelPotenzaReale.state)
		Ist_Immissione.postUpdate(0)
		Ist_Autoconsumo.postUpdate(MQTTEnergymonitor_PannelliPotenzaReale.state)
		Ist_Produzione.postUpdate(MQTTEnergymonitor_PannelliPotenzaReale.state)
	}
	
	if (MQTTEnergymonitor_EnelPotenzaReale.state < 0) 
	{
		Ist_Consumo.postUpdate(MQTTEnergymonitor_PannelliPotenzaReale.state as Number + MQTTEnergymonitor_EnelPotenzaReale.state as Number )
		Ist_Prelievo.postUpdate(0)
		Ist_Immissione.postUpdate(-MQTTEnergymonitor_EnelPotenzaReale.state as Number)
		Ist_Autoconsumo.postUpdate(MQTTEnergymonitor_PannelliPotenzaReale.state as Number + MQTTEnergymonitor_EnelPotenzaReale.state as Number)
		Ist_Produzione.postUpdate(MQTTEnergymonitor_PannelliPotenzaReale.state)
	}
	
	if (MQTTEnergymonitor_PannelliPotenzaReale.state < 0) 
	{
		Ist_Consumo.postUpdate(-MQTTEnergymonitor_PannelliPotenzaReale.state as Number + MQTTEnergymonitor_EnelPotenzaReale.state as Number)
		Ist_Prelievo.postUpdate(MQTTEnergymonitor_EnelPotenzaReale.state)
		Ist_Immissione.postUpdate(0)
		Ist_Autoconsumo.postUpdate(0)
		Ist_Produzione.postUpdate(MQTTEnergymonitor_PannelliPotenzaReale.state)
	}


	Emon_Summary.postUpdate(String::format("Consumo: %s W - Produco: %s W",(Ist_Consumo.state as Number).intValue,(Ist_Produzione.state as Number).intValue))
	
	
	if (MQTTEnergymonitor_EnelPotenzaReale.state >= 5000 && (now.getHour() >= 8 && now.getHour() < 24) && Timer_Pow === null) {
		Timer_Pow = createTimer(now.plusSeconds(20)) [|
			Alexa_Speak.sendCommand("WARNING . CONSUMPTION TO HIGH.")
	        Timer_Pow.cancel
	        Timer_Pow = null
		]
	}
end

if copy paste, nether the first data update part, before alexa speack if, is executed

Or the PIR example as the topic title sais. not work neither too. the concept is the same for reschedule the timer…

// Imports

// Global Variables
var Timer Timer_1 = null

rule "PIR Soggiorno"
when
    Item PIR1_Soggiorno changed from OFF to ON or
    Item PIR2_Soggiorno changed from OFF to ON
then 
	 if ((now.isAfter(now.withTimeAtStartOfDay.plusHours(20)) || now.isBefore(now.withTimeAtStartOfDay.plusHours(7))) && Timer_1 === null && Scenario.state == 0 && Luminosita_Int_Soggiorno.state < 5 && (LIFX1_Int_Soggiorno_Accendi.state < 5 || LIFX1_Int_Soggiorno.state == OFF) && (RGBW_Int_Soggiorno_Accendi.state == OFF || RGBW_Strip.state == OFF) && (Sonoff_S1_Int_Cucina_Accendi.state == OFF || Sonoff_S1_Presence.state == OFF) && (Sonoff_S2_Int_Salotto_Accendi.state == OFF || Sonoff_S2_Presence.state == OFF)) 
	 {
	    sendCommand(RGBW_Int_Soggiorno_Accendi, ON)
	    Timer_1 = createTimer(now.plusMillis(800)) [|
	    	if (now.isAfter(now.withTimeAtStartOfDay.plusHours(20)) && now.isBefore(now.withTimeAtStartOfDay.plusHours(23))) 
	    	{
	        	RGBW_Int_Soggiorno_Colore.sendCommand("200,30,90")
	        	sendCommand(LIFX1_Int_Soggiorno_Accendi, 25)
	    	}
	    	else if (now.isAfter(now.withTimeAtStartOfDay.plusHours(23)) && now.isBefore(now.withTimeAtStartOfDay.plusHours(1))) 
	    	{
	        	RGBW_Int_Soggiorno_Colore.sendCommand("50,30,50")
	        	sendCommand(LIFX1_Int_Soggiorno_Accendi, 15)
	    	}
	    	else if (now.isAfter(now.withTimeAtStartOfDay.plusHours(1)) && now.isBefore(now.withTimeAtStartOfDay.plusHours(7))) 
	    	{
	        	RGBW_Int_Soggiorno_Colore.sendCommand("50,30,20")
	        	sendCommand(LIFX1_Int_Soggiorno_Accendi, 10)
	    	}
	    ]
	    Timer_1 = createTimer(now.plusSeconds(180)) [|
	        Timer_1.cancel
	        Timer_1 = null
	        sendCommand(LIFX1_Int_Soggiorno_Accendi, OFF)
	        sendCommand(RGBW_Int_Soggiorno_Accendi, OFF)
	    ]
	}
  	else if (Timer_1 !== null) {
    	Timer_1.reschedule(now.plusSeconds(300))
  	}
end

I think it will not work for you also
Openhab 3 known issue

Joda timers has been remove from oh3

Correct, that’s why you must change the withTimeAtStartOfDay.plusHours(20) with a javatime varations.
I can’t help you at this moment with all the changes. But you can have a look here, all the methods of javatime: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/ZonedDateTime.html

for example the now.isAfter(now.withTimeAtStartOfDay.plusHours(20)) will be now.isAfter(now.withHour(20).withMinute(0).withSecond(0))

after many and many try on spare script I found what do not work.

I dont know why but sometimes the item.state value must decleared as Number.

here the first modified rule that seems to working.
I’m looking at the PIR exaple to fix it

//Global Varibles
var Timer Timer_Pow = null

rule "Energy Monitor"
when
    Item MQTTEnergymonitor_EnelPotenzaReale received update or
    Item MQTTEnergymonitor_PannelliPotenzaReale received update
then 
	if (MQTTEnergymonitor_EnelPotenzaReale.state as Number > 0 && MQTTEnergymonitor_PannelliPotenzaReale.state as Number > 0) 
	{
		Ist_Consumo.postUpdate(MQTTEnergymonitor_PannelliPotenzaReale.state as Number + MQTTEnergymonitor_EnelPotenzaReale.state as Number)
		Ist_Prelievo.postUpdate(MQTTEnergymonitor_EnelPotenzaReale.state)
		Ist_Immissione.postUpdate(0)
		Ist_Autoconsumo.postUpdate(MQTTEnergymonitor_PannelliPotenzaReale.state as Number)
		Ist_Produzione.postUpdate(MQTTEnergymonitor_PannelliPotenzaReale.state as Number)
	}
	
	if (MQTTEnergymonitor_EnelPotenzaReale.state <= 0) 
	{
		Ist_Consumo.postUpdate(MQTTEnergymonitor_PannelliPotenzaReale.state as Number + MQTTEnergymonitor_EnelPotenzaReale.state as Number )
		Ist_Prelievo.postUpdate(0)
		Ist_Immissione.postUpdate(-MQTTEnergymonitor_EnelPotenzaReale.state as Number)
		Ist_Autoconsumo.postUpdate(MQTTEnergymonitor_PannelliPotenzaReale.state as Number + MQTTEnergymonitor_EnelPotenzaReale.state as Number)
		Ist_Produzione.postUpdate(MQTTEnergymonitor_PannelliPotenzaReale.state as Number)
	}
	
	if (MQTTEnergymonitor_PannelliPotenzaReale.state <= 0) 
	{
		Ist_Consumo.postUpdate(-MQTTEnergymonitor_PannelliPotenzaReale.state as Number + MQTTEnergymonitor_EnelPotenzaReale.state as Number)
		Ist_Prelievo.postUpdate(MQTTEnergymonitor_EnelPotenzaReale.state as Number)
		Ist_Immissione.postUpdate(0)
		Ist_Autoconsumo.postUpdate(0)
		Ist_Produzione.postUpdate(MQTTEnergymonitor_PannelliPotenzaReale.state as Number)
	}


	Emon_Summary.postUpdate(String::format("Consumo: %s W - Produco: %s W",(Ist_Consumo.state as Number).intValue,(Ist_Produzione.state as Number).intValue))
	
	
	if (MQTTEnergymonitor_EnelPotenzaReale.state as Number >= 5000 && (now.getHour() >= 8 && now.getHour() < 24) && Timer_Pow === null) {
		Timer_Pow = createTimer(now.plusSeconds(20)) [|
			Alexa_Speak.sendCommand("WARNING! CONSUMPTION TOO HIGH!")
	        Timer_Pow.cancel
	        Timer_Pow = null
		]
	}
end

Edit:

here the PIR exaple working for OH3 :slight_smile:

 // Global Variables
var Timer Timer_PIR = null

rule "PIR Soggiorno"
when
    Item MQTTESP_PirSoggiorno changed from OFF to ON or
    Item MQTTESP_PirCucina changed from OFF to ON
then 
	 if ((now.getHour > 20 || now.getHour < 7) && Timer_PIR === null && Scenario.state == 0 && MQTTESP_LuminositaSoggiorno.state < 5 && (Lifx_Brightness.state < 5 || LifxSoggiorno_Online.state == OFF) && (RGBWStrip_Power.state == OFF || RGBWStripCucina_Online.state == OFF) && (MQTTSonoff_LuceCucina.state == OFF || SonoffCucina_Online.state == OFF) && (MQTTSonoff_LuceSalotto.state == OFF || SonoffSoggiorno_Online.state == OFF)) 
	 {
	    sendCommand(RGBWStrip_Power, ON)
	    Timer_PIR = createTimer(now.plusSeconds(1)) [|
	    	if (now.getHour > 20 && now.getHour < 23) 
	    	{
	        	RGBWStrip_Color.sendCommand("200,30,90")
	        	sendCommand(Lifx_Brightness, 25)
	    	}
	    	else if (now.getHour > 23 && now.getHour < 1) 
	    	{
	        	RGBWStrip_Color.sendCommand("50,30,50")
	        	sendCommand(Lifx_Brightness, 15)
	    	}
	    	else if (now.getHour > 1 && now.getHour < 7) 
	    	{
	        	RGBWStrip_Color.sendCommand("50,30,20")
	        	sendCommand(Lifx_Brightness, 10)
	    	}
	    ]
	    Timer_PIR = createTimer(now.plusSeconds(180)) [|
	        Timer_PIR.cancel
	        Timer_PIR = null
	        sendCommand(Lifx_Brightness, OFF)
	        sendCommand(RGBWStrip_Power, OFF)
	    ]
	}
  	else if (Timer_PIR !== null) {
    	Timer_PIR.reschedule(now.plusSeconds(300))
  	}
end

OH3 has an “expiration timer” metadata element in the items. You can set the timeout for your light there. Everytime the item is send the ON command from the PIR or motion sensor, the timer will reset.

I had a scenario, where I want to be able to switch the lights on without triggering the timer. So I created a virtual on/off switch item with the timer. My motion sensor triggers this virtual switch instead.

I have then created rules, that tell my light to be switched on (and off), when my virtual switch is switched on (and off).

No scripting needed. I hope this helps.

/M

Meant to do a video on adding the motion sensor, but was waiting, until I had it all figured out.

Might be of interest to others.

/M

Hi all,
we would like to share with community our solution for HC-SR501 PIR sensor to control light for OpenHAB 3. It is usable with any other PIR sensors. You can activate/deactivate light controlling with button and also change a timer as you want. Rescheduling works as expected. In case of Away Home we get a motion notification from each zone by email or telegram push. Detailed tutorial you can find here:
https://opentux.eu/blog/pihome/advanced-pir-sensors-features-in-openhab