Timer with alert for open window

Hi guys,

I want to create a rule that starts a 5 min timer, when a window opens and send an alert via a notification, when the window is still open after 5 minutes. Can anyone point me towards an example with javascript in a rule?

Thanks

Why not create it with Blockly and study the code it produces ?

1 Like

Trying it in Blockly and looking at the code is an excellent suggestion. In addition:

1 Like

…and the generated code:

if (cache.private.exists('MyWindowTimer') === false || cache.private.get('MyWindowTimer').hasTerminated()) {
  cache.private.put('MyWindowTimer', actions.ScriptExecution.createTimer('MyWindowTimer', time.ZonedDateTime.now().plusMinutes(5), function (timer_context) {
    if (items.getItem('OfficeWindowSensorState').state == 'OPEN') {
      actions.notificationBuilder('The window is open.').send()
    }
    }, undefined));
};

This will only give you one notification, but you can can retrigger, or cancel if need be.

1 Like

Thanks! I need to get into this Blockly tool.

var WindowTime = now

var Integer WindowCounter = 0

rule “Alarm Offene Fenster/Türen”

when

Time cron "0 \* \* \* \* ?"

then

val OTempLimit = (OpenWindows_Temp.state as QuantityType<Number>).toUnit("°C").floatValue

val OTempOut = (Weather_Temperature.state as QuantityType<Number>).toUnit("°C").floatValue

// OpenWindows_Temp is Number:Temperature-Item where Temperature is state

// Weather_Temperatureis Number:Temperature-Item with Outdoor-Temperature

if ((System_Start.state == ON) && (Toggle_OpenWindows.state == ON) && (OTempOut < OTempLimit)) {

    if (now.isAfter(WindowTime.plusHours(1))) {

        WindowCounter = 0

    }

    var String WindowsMsg = ""

    var Boolean WindowsMsgTrue = false

    val WindowsDuration = (OpenWindows_Duration.state as QuantityType<Number>).toUnit("min").intValue



    // Fenster/Türen und Sensoren in einer Liste speichern

    val OWitems = newLinkedHashMap(

        "Fenster1" -> newArrayList(OpenWindows_Fenster1, Sensor_Fenster1, Sensor_Fenster1_Last), 

        "Fenster2" -> newArrayList(OpenWindows_Fenster2, Sensor_Fenster2, Sensor_Fenster2_Last)

    )

    // OpenWindows\_\* is Switch holding Information, if Item should be included

    // Sensor\_\* is Sensor Open/Closed

    // Sensor\_\*\_Last is DateTimeItem and is updated everytime Sensor is changing from CLOSED to OPEN

    for (OWentry : OWitems.entrySet) {

        val OWlabel = OWentry.key

        val openWindowItem = OWentry.value.get(0)

        val OWsensorItem = OWentry.value.get(1)

        val OWlastsensorItem = OWentry.value.get(2)



        if ((openWindowItem.state == ON) && (OWsensorItem.state == OPEN) && (OWlastsensorItem.state != NULL) && (now.minusMinutes(WindowsDuration).isAfter((OWlastsensorItem.state as DateTimeType).getZonedDateTime(ZoneId.systemDefault())))) {

            WindowsMsg = WindowsMsg + OWlabel + " "

            WindowsMsgTrue = true

        }

    }

    if (WindowsMsgTrue && now.isAfter(WindowTime.plusSeconds(170)) && (WindowCounter < (OpenWindows_Counter.state as DecimalType).intValue)) {

        WindowsMsg = WindowsMsg + "länger als " + WindowsDuration.toString + " Minuten geöffnet" 

        if (Switch_Alarm.state == OFF) {

            Echo_Esszimmer_Speak.sendCommand(WindowsMsg)

        }

        val mailActionsO = getActions("mail", "mail:smtp:e73692a76f")

        mailActionsO.sendMail("receiver@email.com", "Offene Fenster", WindowsMsg)

        logInfo("Offene Fenster:", WindowsMsg)

        WindowTime = now

        WindowCounter = WindowCounter + 1

    }

}

end

your code goes here

Thank you all for your support! I got this rule now going and it works quite well:

configuration: {}
triggers:

  • id: “2”
    configuration:
    groupName: ChangedSecurityItems
    state: OPEN
    type: core.GroupStateUpdateTrigger
    conditions:

  • inputs: {}
    id: “3”
    configuration:
    itemName: Weather_and_Forecast_Aussentemperatur
    state: = (items.Room_Climate_Control_Flur_OG_Zieltemperatur.state - 4)
    operator: <
    type: core.ItemStateCondition
    actions:

  • inputs: {}
    id: “1”
    configuration:
    type: application/javascript
    script: >-
    var OpenItem; var OpenItemName; var OpenItemLabel; var TempNotify;

    OpenItem = items.getItem(event.ItemName).semantics.equipment;
    
    OpenItemName = items.getItem(event.ItemName).name;
    
    OpenItemLabel = OpenItem.label;
    
    TempNotify = (OpenItemLabel + ' zu lange offen!');
    
    if (cache.private.exists(OpenItemName) === false ||
    cache.private.get(OpenItemName).hasTerminated()) {
      cache.private.put(OpenItemName, actions.ScriptExecution.createTimer(OpenItemName, time.ZonedDateTime.now().plusSeconds(300), function (timer_context) {
        if (items.getItem(OpenItemName).state == 'OPEN') {
          actions.notificationBuilder(TempNotify).send();
          items.getItem('temp_alert').sendCommand('ON')
        }
        }, undefined));
    };
    

    type: script.ScriptAction

jruby can make your script simpler

after 300.seconds, id: event.item, reschedule: false do
  if event.item.open?
    msg = "#{event.item.equipment.label} zu lange offen!"
    Notification.send(msg)
    temp_alert.on
  end
end

I’ve been using the expire in items ever since. you can set a notify_window_open switch to ON when you open the window. And in a rule check if the switch changes to OFF and then do your notification.

If you open or close the window in between, it is automatically reset and starts over. Expire works directly in items. IMHO better and easier to work with than with timers