Logic operators precedence

Hi.
Can’t seem to find any obvious answer to this so I have to ask: What are the reules for precedence between logic operators in openHAB rules? I have the following in a rule:

if(ZWaveMultiSensor_SensorTemperature.state == null ||
    TellstickTemperature1_ActualTemperature.state < ZWaveMultiSensor_SensorTemperature.state) {
    Utetemperatur.postUpdate(TellstickTemperature1_ActualTemperature.state)
}

I think the logic should be that if the first expression in the if evaluates to true (ie the state of the sensor is null) then the second expression should never need to be evaluated at all, but the result I get is that if ZWaveMultiSensor_SensorTemperature is null I get the following in my log:

20:16:53.515 [ERROR] [.script.engine.ScriptExecutionThread] - Rule 'Tellstick tempsensor updated': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.lib.NumberExtensions.operator_lessThan(org.eclipse.smarthome.core.types.Type,java.lang.Number) on instance: null

How is this possible?

You need to check for NULL (and not null).

Ref. http://docs.openhab.org/tutorials/migration#rules:

To test for Items with an Undefined state replace if(MyItem.state == Undefined) with if(MyItem.state == NULL). Case matters. NULL is only valid when testing an Item’s state to see if it is undefined. null is used pretty much everywhere else to mean “no value” and usually indicates no result or an error.

Ok, that’s just pure non-logic. We use null everywhere but when comparing, where we use NULL. Guess I’ll simply have to get used to that one though. Thanks a lot!

I agree that it is not very intuitive, and easy to get mixed up. I think the reason for this situation, however, is that rules language is “sort of Java” where testing for null is valid. NULL on the other hand is probably something introduced by openHAB as a way to test for an item that has not received an initial state update yet. I guess choosing some other “name” than NULL would have been a bit less confusing…

I guess that explains it. It’s simply not really null.

Just for the record, what I do is when it hasn’t been updated in x minutes, I “manually” set it to null (or whatever we should call it) in another rule using the following code that I’ve also failed to make in a more intuitive way:

var nullValue = new NumberItem("dummy").state
ZWaveMultiSensor_SensorTemperature.postUpdate(nullValue)

The Rules DSL follows the standard Java order of operations and || should be succeed fast (i.e. if the first argument is true then the rest of the comparisons are skipped). Similarly, && should be fail fast (i.e. if the first argument is false the rest of the comparisons are skipped.

There is a special State Object called NULL and this is what you are comparing the Item’s state to. This special state used to be called Undefined and the change to NULL is one of the changes introduced in 2.0. I, like you, feel NULL is more confusing than enlightening and would have rather it stayed named Undefined.

Have you looked into the Expire binding? You can configure your Item to automatically be set to NULL (or any other state via an update or command) after it hasn’t been updated for x minutes. For example:

Number ZWaveMultiSensor_SensorTemperature ... { ..., expire="Xm" }

Replace “X” with your minutes. After that amount of time without an update to the Item it will be set to NULL. No need for a rule.

Beyond that you can just use:

ZWaveMultiSensor_SensorTemperature.postUpdate(NULL)

in your existing rule.

See the second example in the Generic Is Alive Deisgn Pattern for a more fully implemented example.

Yes, it’s has been suggested to me many times. I have all my Items set up via GUI (paperUI) though so it can’t be easily done. I wish there was support for the Expire binding without having to set up Items the old fashioned way…

I have to admit I didn’t test postUpdate(NULL). Searched in the forum and found multiple answers suggesting to use the strange workaround that I’m using now so then I searched no further :slight_smile: