Problem with DSL rule using previousState at startup

I have the following rule that works fine, but I get a start-up error that I have tried to filter out (unsuccessfuly) with a Null check in the rule.

rule "Poll with Main Setpoint change Cool"
    Item MainThermostat14_SetpointCooling changed
    var pollcount = Furnace_Poll_Count.state as Number
    var mainmode = MainThermostat14_ThermostatMode.state as Number
    var mainstate = MainThermostat14_ThermostatOperatingState.state as Number
    logWarn("events", "pre-if status new state{}, old state {}, mainstate {}", newState, previousState, mainstate)
    if(previousState == 'NULL' || previousState === null ) {
        logWarn("events", "Null found , new state {}, old state {}", newState, previousState)
    else {
        if ( mainmode == 2 && ((newState >= previousState && mainstate == 2) || (newState <= previousState && mainstate == 0))) {
            logWarn("events", "poll triggered new state{}, old state {}, mainstate {}", newState, previousState, mainstate)
            MainThermostat14_ThermostatOperatingState.sendCommand ("REFRESH")
            Furnace_Poll_Count.sendCommand (pollcount + 1)

The log items are;

2022-02-03 08:23:12.226 [WARN ] [] - pre-if status new state75 °F, old state NULL, mainstate 0
2022-02-03 08:23:16.804 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'refresh-1' failed: An error occurred during the script execution: Could not invoke method: org.openhab.core.model.script.lib.NumberExtensions.operator_greaterEqualsThan(org.openhab.core.types.Type,java.lang.Number) on instance: null in refresh

Any idea how to avoid getting to the >= operator, if the previousState is NULL (or null)?


Why not using a try & catch block?

I have never used try & catch (I’m kind of a novice). I’ll read up on it and see if that works. Thanks for the idea

Isn’t it

=== null

Mind the three equal signs

I wasn’t sure if I was looking for ‘NULL’ or null based on the two log entries, so tried for both in the rule.

Neither seemed to work.

Maybe log previousState first? See what it actually is. Try

logInfo("previous state", previousState.toString)

This can never happen. Either previousState will exist with a proper value (e.g. NULL) or it won’t exist at all.

The problem isn’t that the previous state is NULL. The problem is that newState and previousState are both State Objects. That’s the parent of all State type. The engine doesn’t know that they are Numbers and can be compared and can’t figure that out on it’s own. Unfortunately it reports that as “on instance null” because the result of trying to figure out a proper type to work with resulted in nothing being found.

You need to help it along.

(newState as Number >= previousState as Number)

Note that if either newState or previousState are in fact NULL or UNDEF a different exception will occur.

1 Like

So I’m trying to understand. Maybe I wasn’t clear or maybe I’m lost. This rule only springs an error on startup (works fine otherwise). I thought the sequence of events at S/U is that persistence is restoring values
09:55:17.347 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'MainThermostat14_SetpointCooling' changed from NULL to 75 °F

Then it seems like the rule engine goes does some rule check and the previous state was NULL. Do I want to compare 75 °F as Number >= NULL as Number (not really)? My naive thought was to try to prevent that part of the rule from trying to run on startup.


All I can say is that the problem is caused by the fact that one of the operands (either newState or previousState) cannot be coerced to something that can be compared.

Now that I look closer, previousState == 'NULL' will never be true. NULL isn’t a string. It’s not the word “NULL”. It is an enmeration. previousState == NULL. The same goes for ON, OFF, OPEN, CLOSED, INCREASE, etc.

Note you also need to watch out for UNDEF too.

1 Like

So you are saying this will trigger the IF statement on startup and bypass the comparison? (leave out the ‘quotes’)?

Well, NULL does not equal 'NULL'. They are not even remotely the same thing. So if the Item’s state is was NULL

previousState == NULL. // will return true
previousState == 'NULL' // will never return true

Got It. Second thing I learned this week. First was this whole idea of signed or unsigned integers.

I have a test system that I just restarted and NULL works.


I do appreciate all your work on the forum. I know it can be challenging between dumb users like myself and the developers pushing the envelope.


1 Like