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.
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.
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.
// 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.