UpdatedSince in Light rules

Hi all,

I’m trying to use the UpdatedSince function to determine if a Light status has (manually) been changed and if so, then not to turn off the lights after motion detection expires.

The usecase for this is, that if someone’s in our kitchen, the lights go on automatically at a given percentage of the dimmer and depending on the time of the day, light strenght, etc… If someone feels the light is too dim or bright, and adjusts it to her/his own convenience, then the light should stay on and not turn off upon end of the timer.

Here’s the full rule:

var Timer waitTimerKitchen = null


rule "Bewegung Küche"
when


	Item GF_Kitchen_Sensor_MotionEvent changed from OFF to ON

then    


val KitMot = (GF_Kitchen_Sensor_Licht.state as DecimalType).intValue
logInfo("Bewegung Küche","GF_Kitchen_Sensor_Licht: {}", KitMot)

if((KitMot <= 45) || (Nacht.state == ON)) {
logInfo("Bewegung Küche","GF_Kitchen_Sensor_Licht: {}", KitMot,Tag +" ist der Tag")


      if (waitTimerKitchen !== null) {
      logInfo("Bewegung Küche","Hoppala, ein Timer ist schon da -> mach ma nochmal 2 Minuten")
      waitTimerKitchen.reschedule(now.plusMinutes(2))
      
      } else {
	
      
      if (now.getHourOfDay() >= 6 && now.getHourOfDay() < 10) {      
	logInfo("Bewegung Küche FRÜH", "Jetzt geht das Licht an Licht1: {} Licht2 {}",GF_Kitchen_Light1,GF_Kitchen_Light2 + "% ist die Dimmung")
	GF_Kitchen_Light1.sendCommand(100) //Kaffeemaschine
      GF_Kitchen_Light2.sendCommand(100)} //Küche

      if (now.getHourOfDay() >= 10 && now.getHourOfDay() < 21) {      
	logInfo("Bewegung Küche TAG", "Jetzt geht das Licht an Licht1: {} Licht2 {}",GF_Kitchen_Light1,GF_Kitchen_Light2 + "% ist die Dimmung")
	GF_Kitchen_Light1.sendCommand(75) //Kaffeemaschine
      GF_Kitchen_Light2.sendCommand(60)} //Küche

      if (now.getHourOfDay() >= 21 && GF_LivingDining_Power4.state == ON || Heimkino.state == ON)  {      
	logInfo("Bewegung Küche NACHT KINO", "Jetzt geht das Licht an Licht1: {} Licht2 {}",GF_Kitchen_Light1,GF_Kitchen_Light2 + "% ist die Dimmung")
	GF_Kitchen_Light1.sendCommand(0) //Kaffeemaschine
      GF_Kitchen_Light2.sendCommand(9)} //Küche

      if (now.getHourOfDay() >= 21 && GF_LivingDining_Power4.state == OFF || Heimkino.state == OFF)  {      
	logInfo("Bewegung Küche NACHT", "Jetzt geht das Licht an Licht1: {} Licht2 {}",GF_Kitchen_Light1,GF_Kitchen_Light2 + "% ist die Dimmung")
	GF_Kitchen_Light1.sendCommand(32) //Kaffeemaschine
      GF_Kitchen_Light2.sendCommand(50)} //Küche


      logInfo("Bewegung Küche", "Jetzt mach ich einen 2 Minuten Timer")
      waitTimerKitchen = createTimer(now.plusMinutes(2))[|


            logInfo("Bewegung Küche", "Ich checke ob Bewegung erkannt: " + 
            GF_Kitchen_Sensor_MotionEvent.state + " ist der Status, so schauts aus")
            if (GF_Kitchen_Sensor_MotionEvent.state ==  ON) {
            logInfo("Bewegung Küche","Weil Bewegung erkannt, Timer neu setzen")
            waitTimerKitchen.reschedule(now.plusMinutes(2))

            if (now.getHourOfDay() >= 6 && now.getHourOfDay() < 10 && 
            GF_LivingDining_Sensor_MotionEvent.state == ON) {
            logInfo("Bewegung WZ MORGEN","Weil Bewegung erkannt, Timer neu setzen")
            waitTimerKitchen.reschedule(now.plusMinutes(7))}



      } else {
            
            logInfo("Bewegung Küche", "Check ob Lichtstärke verändert wurde")
            if (GF_Kitchen_Light1.updatedSince(now.minusSeconds(119)) || 
            GF_Kitchen_Light2.updatedSince(now.minusSeconds(119))) {
            KKL.sendCommand(ON)
            
            } else {

                  logInfo("Bewegung Küche", "Jetzt geht das Licht aus Licht1: {} Licht2 {}",GF_Kitchen_Light1,GF_Kitchen_Light2 + "% ist die Dimmung")
                  GF_Kitchen_Light1.sendCommand(0)
                  GF_Kitchen_Light2.sendCommand(0)

                  logInfo("Bewegung Küche", "Ende der Regel -> Timer aus")
                  waitTimerKitchen = null
                  }
            }               
            
      ]
}
}
end

all is working fine, except this part:

      } else {
            
            logInfo("Bewegung Küche", "Check ob Lichtstärke verändert wurde")
            if (GF_Kitchen_Light1.updatedSince(now.minusSeconds(119)) || 
            GF_Kitchen_Light2.updatedSince(now.minusSeconds(119))) {
            KKL.sendCommand(ON)
            
            } else {

which never seems to really be triggered. Do I need to connect it somehow to my persistance? I’ve rrd4j and an influx running (the later one since some time only, to tap into this DB and experiment a bit with Grafana).

For lack of creativity, I’ve decided to send an ON command to the KKL item. This is a groupswitch of both lights.

Any help & guidance on how to use the updatedSince function correctly, would be appreciated.

thanks,
Kurt

1 Like

Thanks for the hint.
After updating the persistence to everyMinute, I now have the opposite effect: The part of the rule in question seems now to be executed all the time, irrespectively of an actual update :face_with_raised_eyebrow: .

I wonder what am I doing wrong…

Kurt

The rule only runs, if there is a change from OFF to ON. Please check the log or post the part.:grinning:

2 Likes

The rule only runs, if there is a change from OFF to ON. Please check the log and post the part.

2 Likes

Hi,

Indeed, the rule itself gets triggered if my Motion Sensor gets triggered from OFF to ON – that’s working.
What is not working, is the ELSE part of the rule with the updatedSince function.
Thanks for hinting me to the persistence issue - this helped me to solve 2 bugs (timer cancelation in that same else part).

However, now it is the case, that the ELSE part in question gets executed all the time, independent if the item is actually updated.
Here are the logs:

2018-03-16 15:41:20.773 [vent.ItemStateChangedEvent] - GF_Kitchen_Sensor_MotionEvent changed from OFF to ON

2018-03-16 15:41:24.111 [INFO ] [home.model.script.Bewegung Küche TAG] - Jetzt geht das Licht an Licht1: GF_Kitchen_Light1 (Type=DimmerItem, State=0, Label=Deckenlampe Kaffemaschine, Category=overheadlights, Groups=[GF_Kitchen, Lights, KKL]) Licht2 GF_Kitchen_Light2 (Type=DimmerItem, State=0, Label=Deckenlampe Küche, Category=overheadlights, Groups=[GF_Kitchen, Lights, KKL])% ist die Dimmung
2018-03-16 15:41:24.117 [ome.event.ItemCommandEvent] - Item 'GF_Kitchen_Light1' received command 75
2018-03-16 15:41:24.123 [ome.event.ItemCommandEvent] - Item 'GF_Kitchen_Light2' received command 60
2018-03-16 15:41:24.135 [INFO ] [marthome.model.script.Bewegung Küche] - Jetzt mach ich einen 2 Minuten Timer
2018-03-16 15:41:24.138 [GroupItemStateChangedEvent] - KKL changed from OFF to ON through GF_Kitchen_Light1
2018-03-16 15:41:24.335 [vent.ItemStateChangedEvent] - GF_Kitchen_Sensor_MotionEvent changed from ON to OFF
2018-03-16 15:43:24.153 [INFO ] [marthome.model.script.Bewegung Küche] - Ich checke ob Bewegung erkannt: OFF ist der Status, so schauts aus
2018-03-16 15:43:24.167 [INFO ] [marthome.model.script.Bewegung Küche] - Check ob Lichtstärke verändert wurde
2018-03-16 15:43:24.215 [ome.event.ItemCommandEvent] - Item 'KKL' received command ON
2018-03-16 15:43:24.225 [ome.event.ItemCommandEvent] - Item 'GF_Kitchen_Light2' received command ON
2018-03-16 15:43:24.238 [ome.event.ItemCommandEvent] - Item 'GF_Kitchen_Light1' received command ON
2018-03-16 15:43:24.263 [vent.ItemStateChangedEvent] - GF_Kitchen_Light1 changed from 75 to 100
2018-03-16 15:43:24.267 [vent.ItemStateChangedEvent] - GF_Kitchen_Light2 changed from 60 to 100

What I would like to achieve is that if there is no update, the timer get canceled and light turns off.
Now, openhab seems to ignore all updatedSince events and the light actually never turns off again.

:grimacing:

I hope I’m being more clear - thanks for your help upfront!

Kurt

Maybe ist a problem with rrd4j and the 1 minute intervall updatedSince leads to wrong results

It’s a logic error.
One of the 4 time of day ifs will always be executed and you update the lights
Therefore the updateSince will be true

Hi Vincent,

I think you’re right - there must be a logic error somewhere in my rule.

I’m not sure however if it is the error you’re pointing to: Indeed, one of the four options per day will always update the lights, but then I’m creating a 2min Timer.
The updatedSince checks for updates <119 Sec.
I was of the opinion, that this should bridge the time between the light got last updated automatically and the check if the light got updated (manually) within 119Sec was sufficient.
Even if I’m checking updatedSince <10sec, the ELSE part of the rule in question would still get triggered, besides there is no update of the LightItem in the logs to allow it to do wo

am I making a mistake in this thinking?

Kurt

I am struggling a bit to read your your rule
Could you modify the indents, please?

Tidy up you logic test:
Put each test in bracket, for example:

	    if ((now.getHourOfDay() >= 6) && (now.getHourOfDay() < 10)) {

There are a lot of these and you may get unpredictable results. It also makes it easier to read

OK,
I could be a persistence problem
I have tidied up your code and it seems correct (Just make sure you have logic tests in brackets)
Can you show me your rdj4.persist and you influxdb.persist

Hi,

thanks so much for your effort and also for the hints with putting logic tests inside brackets.

Here’s my rrd4j.persist:

Strategies {
 everyMinute : "0 * * * * ?"
 everyHour : "0 0 * * * ?"
 everyDay : "0 0 0 * * ?"
 every15min : "*/15 * * * * ?"
 default = everyChange
}

Items {

GF_Kitchen_Light1 : strategy = everyMinute
GF_Kitchen_Light2 : strategy = everyMinute

}

influxDB is installed, but not persisting the Items above.
Default persistence service in PaperUI is set to rrd4j.

Kurt

updatedSince with rrd4j is every update (not every change)

That’s your problem
Rd4j only persists numbers.
In influx.persist add your items with everyUpdate as a strategy.

1 Like

is a number, but I agree, take a other persictence

My bad.
Then add everyUpdate as a strategy in rrd4j

The strategy everyMinute must be used, otherwise no data will be persisted (stored).https://docs.openhab.org/addons/persistence/rrd4j/readme.html#example

Hi Harry & Vincent,

thanks a lot for all your help!!

using everyUpdate as a persistence strategy for the updatedSince makes sense :slight_smile:

As a conclusion however, this means if one wants to use updatedSince in rules, rrjd4 cannot be used at all. Using influxDB with everyUpdate makes the rule run smoothly.

Kurt

1 Like