[SOLVED] Extend rule to determine if

Hi all,

I started to implement a rule, sending me a Telegram message when e.g. a window is open for more than 15 minutes.
This works fine so far, however, I need a hand in extending the rule to stop the timer, when it’s closed again.

rule "Notify if window in guest toilet is open for too long"
when
    Item fenster_gaestewc changed to OPEN
then
    if (stopAlarmTimer === null)
    {
        stopAlarmTimer = createTimer(now.plusSeconds(900)) [|
            stopAlarmTimer.cancel()
            stopAlarmTimer = null
            sendTelegram("bot2", "Das Fenster im Gäste-WC ist seit 15 Minuten offen!")
        ]
    }
end

rule "Notify if frontdoor  is open for too long"
when
    Item hausflur_haustuer changed to OPEN
then
    if (stopAlarmTimer === null)
    {
        stopAlarmTimer = createTimer(now.plusSeconds(900)) [|
            stopAlarmTimer.cancel()
            stopAlarmTimer = null
            sendTelegram("bot2", "Die Haustür ist seit 15 Minuten offen!")
        ]
    }
end

I altered the rule as follows, but that results in no notification being sent at all, also LogInfo isn’t working:

var Timer gaestewc_Timer = null
var Timer haustuer_Timer = null

rule "Notify if window in guest toilet is open for too long"
when
    Item fenster_gaestewc changed
then
    if (fenster_gaestewc===CLOSED)
    {
                        (gaestewc_Timer !==null)
                        {
                                logInfo("timer","[Timer] Fenster Gäste-WC geschlossen. Timer wird abgebrochen...")
                                gaestewc_Timer.cancel
                                gaestewc_Timer=null
                        }
    }
        else if (fenster_gaestewc===OPEN)
        {
                if (gaestewc_Timer===null)
                {
                        gaestewc_Timer=createTimer(now.plusMinutes(15))
                        [|
                                logInfo("timer","[Timer] Fenster Gäste-WC über 15 Minuten offen. Sende Notification...")
                                sendTelegram("bot2", "Das Fenster im Gäste-WC ist seit 15 Minuten offen!")
                        ]
                }
        }

end




rule "Notify if frontdoor  is open for too long"
when
    Item hausflur_haustuer changed
then
    if (hausflur_haustuer===CLOSED)
    {
                        (haustuer_Timer !==null)
                        {
                                logInfo("timer","[Timer] Haustür geschlossen. Timer wird abgebrochen...")
                                haustuer_Timer.cancel
                                haustuer_Timer=null
                        }
    }
        else if (hausflur_haustuer===OPEN)
        {
                if (haustuer_Timer===null)
                {
                        loginfo("timer","[Timer] Haustür geöffnet. Starte Timer...")
                        haustuer_Timer=createTimer(now.plusMinutes(15))
                        [|
                                logInfo("timer","[Timer] Haustür über 15 Minuten offen. Sende Notification...")
                                sendTelegram("bot2", "Die Haustür ist seit 15 Minuten offen!")
                        ]
                }
        }

end

What would need to be added to not send a notification in case it gets closed in the timeframe of 15 minutes?

Cheers,

Ben

You mustn’t check for ===CLOSED or OPEN, use === only ever if testing against null use == instead.

1 Like

Thanks a bunch for your reply, could you elaborate? I went for === due to messages complaining in log, now completely lost how it would be correct.

=== null
but
== CLOSED
and
== NULL

Altered it as follows:

var Timer gaestewc_Timer = null
var Timer haustuer_Timer = null

rule "Notify if window in guest toilet is open for too long"
when
    Item fenster_gaestewc changed
then
    if (fenster_gaestewc==CLOSED)
    {
                        (gaestewc_Timer !==null)
                        {
                                logInfo("timer","[Timer] Fenster Gäste-WC geschlossen. Timer wird abgebrochen...")
                                gaestewc_Timer.cancel
                                gaestewc_Timer=null
                        }
    }
        else if (fenster_gaestewc==OPEN)
        {
                if (gaestewc_Timer==NULL)
                {
                        gaestewc_Timer=createTimer(now.plusMinutes(15))
                        [|
                                logInfo("timer","[Timer] Fenster Gäste-WC über 15 Minuten offen. Sende Notification...")
                                sendTelegram("bot2", "Das Fenster im Gäste-WC ist seit 15 Minuten offen!")
                        ]
                }
        }

end




rule "Notify if frontdoor  is open for too long"
when
    Item hausflur_haustuer changed
then
    if (hausflur_haustuer==CLOSED)
    {
                        (haustuer_Timer !==null)
                        {
                                logInfo("timer","[Timer] Haustür geschlossen. Timer wird abgebrochen...")
                                haustuer_Timer.cancel
                                haustuer_Timer=null
                        }
    }
        else if (hausflur_haustuer==OPEN)
        {
                if (haustuer_Timer==NULL)
                {
                        loginfo("timer","[Timer] Haustür geöffnet. Starte Timer...")
                        haustuer_Timer=createTimer(now.plusMinutes(15))
                        [|
                                logInfo("timer","[Timer] Haustür über 15 Minuten offen. Sende Notification...")
                                sendTelegram("bot2", "Die Haustür ist seit 15 Minuten offen!")
                        ]
                }
        }

end

Resulting in:

2019-03-26 09:36:30.165 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'doors_windows_open.rules', using it anyway:
This expression is not allowed in this context, since it doesn't cause any side effects.
This expression is not allowed in this context, since it doesn't cause any side effects.
2019-03-26 09:36:30.167 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'doors_windows_open.rules'
2019-03-26 09:36:31.337 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'doors_windows_open.rules', using it anyway:
This expression is not allowed in this context, since it doesn't cause any side effects.
This expression is not allowed in this context, since it doesn't cause any side effects.
2019-03-26 09:36:31.345 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model 'doors_windows_open.rules'

You mustn’t check the timer variable against NULL but against null, that was correct in your 1st version.
See also [SOLVED] Unexpected results with Val math operators and NULL | UNDEF | null | uninitialized

var Timer gaestewc_Timer = null
var Timer haustuer_Timer = null

rule "Notify if window in guest toilet is open for too long"
when
    Item fenster_gaestewc changed
then
    if (fenster_gaestewc==CLOSED)
    {
                        (gaestewc_Timer !==null)
                        {
                                logInfo("timer","[Timer] Fenster Gäste-WC geschlossen. Timer wird abgebrochen...")
                                gaestewc_Timer.cancel
                                gaestewc_Timer=null
                        }
    }
        else if (fenster_gaestewc==OPEN)
        {
                if (gaestewc_Timer==null)
                {
                        gaestewc_Timer=createTimer(now.plusMinutes(15))
                        [|
                                logInfo("timer","[Timer] Fenster Gäste-WC über 15 Minuten offen. Sende Notification...")
                                sendTelegram("bot2", "Das Fenster im Gäste-WC ist seit 15 Minuten offen!")
                        ]
                }
        }

end




rule "Notify if frontdoor  is open for too long"
when
    Item hausflur_haustuer changed
then
    if (hausflur_haustuer==CLOSED)
    {
                        (haustuer_Timer !==null)
                        {
                                logInfo("timer","[Timer] Haustür geschlossen. Timer wird abgebrochen...")
                                haustuer_Timer.cancel
                                haustuer_Timer=null
                        }
    }
        else if (hausflur_haustuer==OPEN)
        {
                if (haustuer_Timer==null)
                {
                        loginfo("timer","[Timer] Haustür geöffnet. Starte Timer...")
                        haustuer_Timer=createTimer(now.plusMinutes(15))
                        [|
                                logInfo("timer","[Timer] Haustür über 15 Minuten offen. Sende Notification...")
                                sendTelegram("bot2", "Die Haustür ist seit 15 Minuten offen!")
                        ]
                }
        }

end

results in:

==> /var/log/openhab2/openhab.log <==
2019-03-26 10:07:08.899 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model ‘doors_windows_open.rules’, using it anyway:
This expression is not allowed in this context, since it doesn’t cause any side effects.
The operator ‘==’ should be replaced by ‘===’ when null is one of the arguments.
This expression is not allowed in this context, since it doesn’t cause any side effects.
The operator ‘==’ should be replaced by ‘===’ when null is one of the arguments.
2019-03-26 10:07:08.900 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model ‘doors_windows_open.rules’
2019-03-26 10:07:10.137 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model ‘doors_windows_open.rules’, using it anyway:
This expression is not allowed in this context, since it doesn’t cause any side effects.
The operator ‘==’ should be replaced by ‘===’ when null is one of the arguments.
This expression is not allowed in this context, since it doesn’t cause any side effects.
The operator ‘==’ should be replaced by ‘===’ when null is one of the arguments.
2019-03-26 10:07:10.162 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model ‘doors_windows_open.rules’

because again you tested ==null which I told you you mustn’t.

Come on it’s not that difficult.

Sorry Markus to be such a pain in the back but I don’t get my head around it.
Above you said to not check against NULL but against null, that’s why I did it like that.

I seem lost…

Correct.
But I also said that to test against null you need to use === (not ==)

OK, altered it like that:

var Timer gaestewc_Timer = null
var Timer haustuer_Timer = null

rule "Notify if window in guest toilet is open for too long"
when
    Item fenster_gaestewc changed
then
    if (fenster_gaestewc==CLOSED)
    {
                        (gaestewc_Timer !==null)
                        {
                                logInfo("timer","[Timer] Fenster Gäste-WC geschlossen. Timer wird abgebrochen...")
                                gaestewc_Timer.cancel
                                gaestewc_Timer=null
                        }
    }
        else if (fenster_gaestewc==OPEN)
        {
                if (gaestewc_Timer===null)
                {
                        gaestewc_Timer=createTimer(now.plusMinutes(15))
                        [|
                                logInfo("timer","[Timer] Fenster Gäste-WC über 15 Minuten offen. Sende Notification...")
                                sendTelegram("bot2", "Das Fenster im Gäste-WC ist seit 15 Minuten offen!")
                        ]
                }
        }

end




rule "Notify if frontdoor  is open for too long"
when
    Item hausflur_haustuer changed
then
    if (hausflur_haustuer==CLOSED)
    {
                        (haustuer_Timer !==null)
                        {
                                logInfo("timer","[Timer] Haustür geschlossen. Timer wird abgebrochen...")
                                haustuer_Timer.cancel
                                haustuer_Timer=null
                        }
    }
        else if (hausflur_haustuer==OPEN)
        {
                if (haustuer_Timer===null)
                {
                        loginfo("timer","[Timer] Haustür geöffnet. Starte Timer...")
                        haustuer_Timer=createTimer(now.plusMinutes(15))
                        [|
                                logInfo("timer","[Timer] Haustür über 15 Minuten offen. Sende Notification...")
                                sendTelegram("bot2", "Die Haustür ist seit 15 Minuten offen!")
                        ]
                }
        }

end

(hope I got you right this time).

Resulting in:

2019-03-26 10:21:28.482 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model ‘doors_windows_open.rules’, using it anyway:
This expression is not allowed in this context, since it doesn’t cause any side effects.
This expression is not allowed in this context, since it doesn’t cause any side effects.
2019-03-26 10:21:28.484 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model ‘doors_windows_open.rules’
2019-03-26 10:21:29.647 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model ‘doors_windows_open.rules’, using it anyway:
This expression is not allowed in this context, since it doesn’t cause any side effects.
This expression is not allowed in this context, since it doesn’t cause any side effects.
2019-03-26 10:21:29.659 [INFO ] [el.core.internal.ModelRepositoryImpl] - Refreshing model ‘doors_windows_open.rules’

Also logInfo is not kicking in

You are missing the “if” in front of “(gaestewc_Timer !==null)”

Thanks. That removed the messages in logfile. However, loginfo isn’t logging anything so not sure if that solved everything.

The part

and

should use the state of the item and not the item itself…

so just add “.state” to fenster_gaestewc

Andreas

PS: The same for the door…

1 Like

That brought me further, thank you Andreas.
I now at least saw 1 LogInfo when haustuer changes to open and when it changes to close and none for fenster_gaestewc, neither for OPEN nor for CLOSED.

Currentl rule:

var Timer gaestewc_Timer = null
var Timer haustuer_Timer = null

rule "Notify if window in guest toilet is open for too long"
when
    Item fenster_gaestewc changed
then
    if (fenster_gaestewc.state==CLOSED)
    {
                        if (gaestewc_Timer !==null)
                        {
                                logInfo("timer","[Timer] Fenster Gäste-WC geschlossen. Timer wird abgebrochen...")
                                gaestewc_Timer.cancel
                                gaestewc_Timer=null
                        }
    }
        else if (fenster_gaestewc.state==OPEN)
        {
                if (gaestewc_Timer===null)
                {
                        gaestewc_Timer=createTimer(now.plusMinutes(15))
                        [|
                                logInfo("timer","[Timer] Fenster Gäste-WC über 15 Minuten offen. Sende Notification...")
                                sendTelegram("bot2", "Das Fenster im Gäste-WC ist seit 15 Minuten offen!")
                        ]
                }
        }

end




rule "Notify if frontdoor  is open for too long"
when
    Item hausflur_haustuer changed
then
    if (hausflur_haustuer.state==CLOSED)
    {
                        if (haustuer_Timer !==null)
                        {
                                logInfo("timer","[Timer] Haustür geschlossen. Timer wird abgebrochen...")
                                haustuer_Timer.cancel
                                haustuer_Timer=null
                        }
    }
        else if (hausflur_haustuer.state==OPEN)
        {
                if (haustuer_Timer===null)
                {
                        logInfo("timer","[Timer] Haustür geöffnet. Starte Timer...")
                        haustuer_Timer=createTimer(now.plusMinutes(15))
                        [|
                                logInfo("timer","[Timer] Haustür über 15 Minuten offen. Sende Notification...")
                                sendTelegram("bot2", "Die Haustür ist seit 15 Minuten offen!")
                        ]
                }
        }

end

Add logging (almost every other line if necessary) so you can tell what is being executed and what states your Items are in.

It would help us read the code as well if you used consistent indentation. Usually one indent should be one tab or four spaces.

If fenster_gaestewc closes and there is not Timer you will not get a log statement.
If fenster_gaestewc opens and there is a Timer you will not get a log statement

1 Like

I tried to achieve logging by way of LogInfo.
In each state it now seems to work but not when fenster_gaestewc opens (no LogInfo executed)

You need to log out for ALL possible states so you can figure out what states your Items are and what parts of your code are executing. You currently only log out when the code works as you expect which tells you nothing when the code doesn’t work as you expect. You need to understand what your code is doing and for that you need MORE logging.

I didn’t dear asking but I’ll do it now:

I’d know how to do it in bash, powershell but not how I would do it in OpenHab (rules). Therefore I only used logInfo as this was the only thing I could think of

Yes. Use logInfo. You need MORE logInfo statement. You already know how to do it. You already have two log statements in that Rule already. You need a lot more.