Rule optimization: Window OPEN reminder

Hm, obviously I didn‘t describe the problem precisely enough. That‘s my fault, sorry. Will try it again. So first here’s my rule.


var Map<String, Timer> timers = newHashMap

rule "Window state announcement"
when Member of alleFenster received update
then
val Number TimerLength = 10   // want to have Alexa triggering a window open message after 10 minutes

if((triggeringItem.state=="CLOSED") || (triggeringItem.state=="TILTED")) {
    if (timers.get(triggeringItem.name) !== null) {
    timers.get(triggeringItem.name).cancel();
    timers.remove(triggeringItem.name)
    logInfo("Test", transform("MAP", "windows.map", triggeringItem.name) + " is now closed!")
    return;
    }
} else {
    // Set the timer
    logInfo("Test", "New timer created for: " + transform("MAP", "windows.map", triggeringItem.name))
	var elapsedTime = 0
    timers.put(triggeringItem.name, createTimer(now.plusMinutes(TimerLength.intValue), [|
    	elapsedTime = elapsedTime + TimerLength
	val String longName = transform("MAP", "windowLongName.map", triggeringItem.name.toString)
	logInfo("Test", transform("MAP", "windows.map", triggeringItem.name) + " is open for " + elapsedTime + " minutes.")
	Echo_LivingRoom_TTS.sendCommand("The " + longName + " is open for " + elapsedTime + " minutes now.")
    timers.get(triggeringItem.name).reschedule(now.plusMinutes(5))  // reschedule timer for triggering next Alexa message
    ])) 
}
end

Let me describe an example with TimerLength = 10, Timer reschedule for triggering next Alexa message = 5.

Cycle 1:
elapsedTime = 0 + 10 = 10 —> Alexa message is triggered after 10 minutes with statement that window is opened for 10 minutes. All correct and fine.

Timer for triggering next Alexa message is rescheduled now with 5 minutes so next Alexa message will be given after next 5 minutes have expired…

Cycle 2:
elapsedTime = 10 + 10 = 20 —> Alexa message is correctly triggered after 15 minutes but with the wrong statement that window is opened for 20 minutes. Correct window opening time would be 15 minutes instead.

Hm… seems that my rule does not really fit here…

1 Like

The only problem is one of when addition takes place. So instead of initializing elapsedTime to 0, initialize it to 10. Then put the addition after the log and Alexa call and add 5 instead.

That was the trick. To initialize elapsedTime to 10 I have already tested before but still with the wrong result. To put the addition after the log and after the Alexa call was the easy solution I was not aware of. So Thanks a lot again for your support.

Will you show all your config for this rule ? there are missing som map`s maybe some Groups and so on

Hello together,

Since the migration to OH3, I just can not manage my existing rule.

Has anyone a finished rule. like a Blueprint.

For a window opening monitoring, outdoor temperature dependent rule?
Cherry on the cake: My old rule was able to tell which window was open, maybe it also works here.

It would be great if someone can share this.

1 Like

Would be keen to get it, too

Here is my DSL rule - works in OH3:

// Resend Window open msgs **********************************************************************************
rule "Resend/Retrigger Windows open msgs"
when
  Time cron "0 0/1 * * * ?"   // create a trigger that simply fires every 1 minutes
then
    if(Window_Terasse_Switch.state == OPEN)
    {
      // set item if undefined (after restart)
      if(Window_Terasse_Switch_Last_Open_time.state == NULL)  
        Window_Terasse_Switch_Last_Open_time.postUpdate(new DateTimeType())
      
      val dateTime = (Window_Terasse_Switch_Last_Open_time.state as DateTimeType).getZonedDateTime()
        
      // anfangen zu nerven: einmal nach x Minuten und dann jede Minute nach 2*x Minuten, aber nur, wenn Aussentemperatur < 20°C (Windows_Retrigger_Temperature_SetValue)
      if (((dateTime.plusMinutes(15).isBefore(now) && dateTime.plusSeconds(15*60+30).isAfter(now)) ||
          dateTime.plusMinutes(30).isBefore(now)) && 
          (Outdoor_Temperature.state as Number).floatValue < (Windows_Retrigger_Temperature_SetValue.state as Number).floatValue && 
          Window_Terasse_Send_retrigger_Msgs.state == ON
         )
      {
        // Set virtual item so we send "window close" message
        Window_Terasse_Switch_Last_Open_resend_active.postUpdate(ON)
        logInfo("Window_Terasse_Switch", "Terassentuer auf resend msg: noch auf seit " + String.format("%02d", dateTime.getHour) + ":" + String.format("%02d", dateTime.getMinute) + ":" + String.format("%02d", dateTime.getSecond))
        sendBroadcastNotification("Terassentür auf seit " + String.format("%02d", dateTime.getHour) + ":" + String.format("%02d", dateTime.getMinute) + ":" + String.format("%02d", dateTime.getSecond))
      }
    }

// Creates an item that sends notification if this item changes
rule "Records Terassentuer changed state"
when
  Item Window_Terasse_Switch changed
then
  if(SystemStarted_delayed.state == ON)
  {
    if(Window_Terasse_Switch.state==OPEN)
    {
      logInfo("Window_Terasse_Switch", "Terassentuer auf " + String.format("%02d", now.getHour) + ":" + String.format("%02d", now.getMinute))
      Window_Terasse_Switch_Last_Open_time.postUpdate(new DateTimeType())

    }
    else
    {
      if(Window_Terasse_Switch_Last_Open_resend_active.state == ON)
      {
        sendBroadcastNotification("Terassentür zu " + String.format("%02d", now.getHour) + ":" + String.format("%02d", now.getMinute) + ":" + String.format("%02d", now.getSecond)) // works
      }
      logInfo("Window_Terasse_Switch", "Terassentuer zu " + String.format("%02d", now.getHour) + ":" + String.format("%02d", now.getMinute))
    }

    // Clear virtual item so we do not send "window close" message
    Window_Terasse_Switch_Last_Open_resend_active.postUpdate(OFF)
  }
end

Items:

Contact   Window_Terasse_Switch   "Terassentür [MAP(de.map):%s]"                        <contact>    (gWindowContact)       
DateTime  Window_Terasse_Switch_Last_Open_time  "Offen seit [%1$td.%1$tm. %1$tH:%1$tM]"        <time>          // virtual item, mapdb persistence (reload at startup)
Switch    Window_Terasse_Switch_Last_Open_resend_active  "Terasse offen Resending [%s]"               // virtual item, to send close message only after open too long

Number:Temperature   Outdoor_Temperature               "Netatmo Aussentemperatur [%.1f %unit%]"                     <temperature> (gWeather_Chart)     { channel = "netatmo:NAModule1:home:outside:Temperature" }

Switch    Window_Terasse_Send_retrigger_Msgs      "Terassentür send Retrigger Msgs [%s]"            <settings> (gRetrigger) // virtual item, manual setting, mapdb persistence (reload at startup)
Number    Windows_Retrigger_Temperature_SetValue   "Fenster offen Temperaturschwelle [%.1f °C]"          <temperature>    //virtual item, manual setting, mapdb persistence (reload at startup)

You can switch on and off the retrigger via Window_Terasse_Send_retrigger_Msgs switch.
You can adapt the temperature low warn level via Windows_Retrigger_Temperature_SetValue.
The temperature itself is Outdoor_Temperature.

Hope that helps.

1 Like