Strings in rules

I have the Alarm Decoder binding set up and I want to determine whether the alarm is armed. The Galant panel I have operates differently to the Vista, for which the Alarm Decoder was designed. None of the bits are set/unset when the panel is armed (except during the exit time) but what does happen is the display goes clear until the alarm is unset.

Therefore I am trying to use a simple rule to update a Number item to either 0 or 1 depending on whether the display is blank.

I have this rule but it doesn’t work:

rule AlarmArmed
when Item alarmPanelDisplay changed
then
if (alarmPanelDisplay == “” “”) {
postUpdate(alarmArmed,1)
}
else {
postUpdate(alarmArmed,0)
}
end

I have tried with and without the escaped quotes (the quotes are present when I view the string in either the REST API or the Classic UI).

I have also tried the string with only a single space (with and without quotes) because the string of 32 spaces appears to collapse to a single space when viewed in the REST API.

Whatever I do, the value of alarmArmed stays at 0.

I guess I’m doing the string comparison wrong but I can’t work out how. Any help please?

1 Like

Two issues:

You need to compare the state of alarmPanelDisplay.

if(alarmPanelDisplay.state.toString == "\"\"") {

The second is you should print out exactly what the string looks like, not just how it is encoded on a GUI somewhere. Add

logInfo("AlarmArmed", "alarmPanelDisplay is set to ---" + alarmPanelDisplay.state.toString + "--")

Whatever appears between the “—” in your log is what you need to compare against. If nothing appears (i.e. ------) then use == "". It must exactly match though. Same number of spaces, quotes (escaped as you are doing above) and all.

That worked brilliantly.

Thanks for your help.

I’m resurrecting this because it no longer works in OH3.

This is an extract from the log, showing what the alarm panel display string is:

2022-01-09 18:00:14.514 [WARN ] [.model.script.rules.NotArmedLongTest] - Alarm Panel Display ---  ACE Security  09-01-22   18:14---
2022-01-09 18:00:28.384 [WARN ] [.model.script.rules.NotArmedLongTest] - Alarm Panel Display ---NIGHT SETTING   Exit Now        ---
2022-01-09 18:01:02.735 [WARN ] [.model.script.rules.NotArmedLongTest] - Alarm Panel Display ---                                ---
2022-01-09 18:01:22.899 [WARN ] [.model.script.rules.NotArmedLongTest] - Alarm Panel Display ---  ACE Security  09-01-22   18:15---

So it appears that the “blank” display is 32 space characters.

When I try

when Item alarmPanelDisplay changed from "\"                                \""

as worked with the original alarmdecoder binding, the rule never triggers.

If I use

when Item alarmPanelDisplay changed from "                                "

as used to work with the v2 binding in OH2, the rule triggers on every change, not just when the previous state was blank.

Similarly if I use

when Item alarmPanelDisplay changed from ""

or

when Item alarmPanelDisplay changed from '                                '

it triggers on every change.

I could let the rule be triggered on every change and then evaluate the string within the rule but it seems inefficient to run the rule every 60 seconds when it used to only run when I unset the alarm.

Use code fences to prevent that just like you did with the logs.

Have you changed anything about your original implementation, for example rewrote it as a UI rule?

Does that really matter though? Your time is certainly more valuable than a fraction of a second worth of computer time every day.

They are fenced exactly the same way as the logs. I can see the spaces when I edit the text but I can see that they aren’t displayed to other readers, so I added the comment to avoid confusion.

No, the rule is still in the original file.

Part of the reason for working on my OpenHAB installation is for the fun of solving problems. Some people do crosswords or sudoku, I enjoy working on home automation. I could go for a suboptimal solution but where’s the fun in that?

They are not on their own line. They are embedded inside a sentence.

"                   "

Anyway, if it’s not in the UI I don’t have anything to offer. OH 3 changed the underlying rule engine when OH 3 was released and that may have changed how the trigger definitions are processed (e.g apply a trim to get rid of extra white space). In the browser I know for sure extra white space is trimmed.

Makes no difference.

Well, thanks anyway. Hopefully someone who knows the changes may be able to shed some light.

You are using the wrong quote. It needs to be aback quote.

`

not

'

Indeed. That’s the quote I am using; you can see it in the screenshot in my previous post. If I was using a single quote, it would show up as three single quotes and not appear in a different font with a highlighted background.

Then it’s because, like I said, it’s not on it’s own line. Code fences work like this:

```
code goes here
```

They done work like

The quick brown ```fox jumped``` over the lazy dog.

You can embed code in a sentence like that but you have to do it with a single quote:

The quick brown `fox jumped` over the lazy dog.

Which renders to

The quick brown fox jumped over the lazy dog.

OK, thanks; I have edited the original post. Note that using the single back quote and keeping the code within a sentence still removes additional spaces.

The quick brown `fox      jumped` over the lazy dog.

Renders to
The quick brown fox jumped over the lazy dog.

Anyway; what I came here to find out was how to trigger a rule on a string item state changing from 32 spaces. Hopefully someone will know.

As @rlkoshak has already said, it seems likely the parser for triggers is stripping spaces. I would expect that to affect simple “But only” too.

Trigger on any change, add a one-line scripted “But only if” looking for state of 32-spaces.

Wont’t the “but only if” act on the current state of the item? Changed from works on the previous state. I need to detect the change from otherwise I’ll create a race condition.

When the alarm is armed, the display is blank. When you unset it, the display shows the time etc. The old rule used “change from blank” to change the status item from set to unset. To replicate this, I could trigger on every change and if the display isn’t blank, change the status item to unset.

However, when you set the alarm, I use an “exit timer running” signal from the alarm to set the status item to “set”. At that point the display isn’t blank and changes during the exit cycle, which would trigger the rule and the display not being blank, would change the status item back to “unset”.

The changed from function worked brilliantly but it looks like I am going to have to write a load of code to set flags based on previous state and run the rule at least every 60 seconds to replace that functionality.

Why don’t we all find out what 's going on?

rule "investigate"
when
    Item alarmPanelDisplay changed
then
    logInfo("test", "Entry state X" + alarmPanelDisplay.state.toString + "X")
    logInfo("test", "Entry char count " + alarmPanelDisplay.state.toString.length)
    if (alarmPanelDisplay.state == “                                 ”) {
        alarmArmed.postUpdate(1)
    } else {
        alarmArmed.postUpdate(0)
    }
end

It’s probably all something silly like a newline character.

Not necessarily. You can create a Script Condition that acts on anything you can code, including previousState and newState or even the states of other Items.

No, just use previousState in Rules DSL which gets populated with the state the Item was in before it changed for changed triggered rules. Rules | openHAB

I modifed the code slightly so that it generate log entries:

rule investigate
when
    Item alarmPanelDisplay changed
then
    logInfo("test", "Entry state X" + alarmPanelDisplay.state.toString + "X")
    logInfo("test", "Entry char count " + alarmPanelDisplay.state.toString.length)
    if (alarmPanelDisplay.state == "                                 ") {
        logInfo("test", "Alarm display is blank")
    } else {
        logInfo("test", "Alarm display is not blank")
    }
end

This is what I get:

2022-01-14 19:49:53.113 [INFO ] [org.openhab.core.model.script.test  ] - Entry state X  ACE Security  14-01-22   20:04X
2022-01-14 19:49:53.117 [INFO ] [org.openhab.core.model.script.test  ] - Entry char count 32
2022-01-14 19:49:53.120 [INFO ] [org.openhab.core.model.script.test  ] - Alarm display is not blank
2022-01-14 19:50:19.011 [INFO ] [org.openhab.core.model.script.test  ] - Entry state XNIGHT SETTING   Exit Now        X
2022-01-14 19:50:19.015 [INFO ] [org.openhab.core.model.script.test  ] - Entry char count 32
2022-01-14 19:50:19.019 [INFO ] [org.openhab.core.model.script.test  ] - Alarm display is not blank
2022-01-14 19:50:53.089 [INFO ] [org.openhab.core.model.script.test  ] - Entry state X                                X
2022-01-14 19:50:53.092 [INFO ] [org.openhab.core.model.script.test  ] - Entry char count 32
2022-01-14 19:50:53.095 [INFO ] [org.openhab.core.model.script.test  ] - Alarm display is not blank
2022-01-14 19:50:59.696 [INFO ] [org.openhab.core.model.script.test  ] - Entry state X  ACE Security  14-01-22   20:05X
2022-01-14 19:50:59.700 [INFO ] [org.openhab.core.model.script.test  ] - Entry char count 32
2022-01-14 19:50:59.703 [INFO ] [org.openhab.core.model.script.test  ] - Alarm display is not blank

I’m getting a very odd effect.

I am logging what is going on with this rule:

rule NotArmedLong
when Item alarmPanelDisplay changed
then
    logInfo("test", "Entry state X" + alarmPanelDisplay.state.toString + "X")
    logInfo("test", "Entry char count " + alarmPanelDisplay.state.toString.length)
    logInfo("test", "Entry previous state X" + alarmPanelDisplay.previousState.state.toString + "X")
end

This is what is in the log:

2022-01-14 21:59:54.635 [INFO ] [org.openhab.core.model.script.test  ] - Entry state X  ACE Security  14-01-22   22:14X
2022-01-14 21:59:54.638 [INFO ] [org.openhab.core.model.script.test  ] - Entry char count 32
2022-01-14 21:59:54.671 [INFO ] [org.openhab.core.model.script.test  ] - Entry previous state X  ACE Security  23-05-21   18:40X
2022-01-14 22:00:54.941 [INFO ] [org.openhab.core.model.script.test  ] - Entry state X  ACE Security  14-01-22   22:15X
2022-01-14 22:00:54.946 [INFO ] [org.openhab.core.model.script.test  ] - Entry char count 32
2022-01-14 22:00:55.016 [INFO ] [org.openhab.core.model.script.test  ] - Entry previous state X  ACE Security  23-05-21   18:40X

So not only does the previousState not get updated with each item update; it looks like it was last updated on 23rd May 2021. My system has been rebooted many times since then and I don’t believe I’ve ever persisted the alarmPanelDisplay. Not sure what is going on!

Please click on and read the link I posted an my previous reply. I posted it for a reason.

Not ItemName.previousState> That pulls the previous state in persistence.

Just use literally previousState

logInfo("test", previousState)

I count 33 spaces there?

EDIT - Possible treasure … Java11 (some? all?) has a string .isBlank() method.

if (alarmPanelDisplay.state.toString.isBlank) {
    logInfo("test", "Entry state blank")
}
1 Like