OH3: how to identify the error source / reason encountered in a rule (DSL)?

  • OH3 openHABian on rPi4 with 4GB
2023-07-30 10:26:41.167 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'weather-1' failed: Index 2 out of bounds for length 1 in weather

This is the weather-1 rule:

rule "Weather: Ambient light last reboot"
    when
        Item al_KDL_Notification received update
    then
        if (al_KDL_Notification.state.toString == "AmbientLight_01|INFO|has rebooted")
        {
            logInfo(LOG_PREFIX + "01.01", "--> Shed ambient light has rebooted :(")
            al_KDL_LastReboot.postUpdate(new DateTimeType())

            // logging controller reboots to file
			val String ERROR_MESSAGE = LocalDateTime.now().toString + " " +
                "Shed ambient light has rebooted"
			val String CLI_RETURN_CODE = executeCommandLine(Duration.ofSeconds(3),
                "/bin/sh", "-c", "echo " + ERROR_MESSAGE +
                " >> /etc/openhab/html/AmbientLight_01.txt; echo -n $?")
			logInfo(LOG_PREFIX + "01.02", "AmbientLight_01 error logged to file")

            if (Integer::parseInt(CLI_RETURN_CODE) != 0)
            {
    			logInfo(LOG_PREFIX + "01.03", "Return code: {}", CLI_RETURN_CODE)
            }
        }
        else if (al_KDL_Notification.toString.contains("|INFO|"))
        {
            var STRING_TO_SPLIT = al_KDL_Notification.state.toString
            var STRING_ARRAY = STRING_TO_SPLIT.split("\\|")
            var NUM_ARRAY_ELEMENTS = STRING_ARRAY.length()

            //logInfo(LOG_PREFIX + "01.04", "STRING_ARRAY............: {}", STRING_ARRAY)
            //logInfo(LOG_PREFIX + "01.05", "NUM_ARRAY_ELEMENTS........: {}", NUM_ARRAY_ELEMENTS)

            if (NUM_ARRAY_ELEMENTS == 3)
            {
                al_KDL_Notification.postUpdate(al_KDL_Notification.state.toString.split("\\|").get(2))
            }
        }
end

What maybe weird with this rule is that `al_KDL_Notification’ receives a MQTT string, which is then subsequently updated with a reduced version of said string… which mostly does not re-trigger the rule, but when it does causes the error.
Maybe I need to add a proxy item and updated that with the reduced string?!

I may be wrong, But as far as i know, it should be

var NUM_ARRAY_ELEMENTS = STRING_ARRAY.size()

Too lazy to test it here, though. :slight_smile:

1 Like

Thanks, no worries…
I changed it and will report back how it went. :slight_smile:

[edit] Changed to size(), which is the correct one.
Error still occurred; added more logging.

OK, the error helps narrow down to the line pretty specifically. There’s only one line of code that gets element 2 from a List.

al_KDL_Notification.postUpdate(al_KDL_Notification.state.toString.split("\\|").get(2))

For some reason, when the rule runs that split fails to generate three elements.

First of all, the fact that an Item is updating itself which will trigger the rule to run again is a big code smell. This whole rule looks like an elaborate work around a problem which should probably solved in other ways.

But just focusing on the else if, don’t throw away work you’ve already done.

al_KDL_Notification.postUpdate(STRING_ARRAY.get(2))

Maybe the Item’s state has already updated to something else between the first split and the second split?

In fact, you shouldn’t be using al_KDL_Notification’s state in this rule directly at all. Use newState instead. That’s the state that caused the rule to trigger and it’s guaranteed not to change while the rule is running.

1 Like

Thank; You’re right, I shouldn’t update an item that triggered a rule in that rule.

Have corrected this by introducing a proxy item that gets updated with the ‘massaged’ string.