OH2.5 - float eval

  • Platform information:
    • Hardware: RPI 4
    • OS: Openhab docker container
    • openHAB version: 2.5.11
  • Issue of the topic: I’m trying to evaluate a float number,

I’ve tried ‘as Number’ and as doubleValue, etc as well but cannot get this to evaluate as expected…

Rule:

rule "wiiscale check"
when
        Item wiiscaleweight_state changed
then
        var float wiiweight = wiiscaleweight_state.state 
        if ( wiiweight >= 23.85 ) {
          sendTelegram("House_bot", "Weight now: " + wiiweight.toString)
          }
end

State change log:

2021-01-12 11:24:32.343 [vent.ItemStateChangedEvent] - wiiscaleweight_state changed from 23.51208 to 23.50928

Rule error log:

2021-01-12 11:24:32.345 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'wiiscale check': An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.FloatExtensions.operator_greaterEqualsThan(float,double) on instance: null

Tips appreciated!

First, don’t force variables to be a primitive if you have any other choice. Doing so can add minutes to the amount of time that it takes to load and parse .rules files.

Assuming that wiiscaleweight_state is a Number Item (not Number:Dimensionless or the like) than it’s carrying on of the following three states:

  • NULL - the Item has never been initialized since OH started
  • UNDEF - the binding determined that it can’t know what state the device is in
  • DecimalType - an openHAB state representing a numerical value

So first you need to make sure that the Item’s state isn’t NULL or UNDEF. You can’t cast either of those states to a Number. The error implies that the type of the state isn’t a Number which means it’s one of these.

If you’ve confirmed that it’s not one of those, then often you can just use it as a number.

if(wiiscaleweight_state.state >= 23.85) {

If that doesn’t work, you can cast it to Number.

var wiiweight = wiiscaleweight_state.state as Number

Then you can use wiiweight in any mathematical comparisons and calculations.

Thanks for that Rich!

It is a number item indeed - so I changed the rule to:

rule "wiiscale check"
when
        Item wiiscaleweight_state changed
then
        logInfo("wiiscale", "Value of wiiscaleweight_state.state.toString is: " + wiiscaleweight_state.state.toString)
        if ( wiiscaleweight_state.state > 2 ) {
             logInfo("wiiscale", "scale value inside the if statement")
          }
end

Oddly it appears the evaluation is not working as in my logs I only see:

2021-01-12 22:32:28.388 [vent.ItemStateChangedEvent] - wiiscaleweight_state changed from 3.11844 to 3.43964
2021-01-12 22:32:28.788 [INFO ] [ipse.smarthome.model.script.wiiscale] - Value of wiiscaleweight_state.state.toString is: 3.43964

So it never gets to the logInfo line inside the If statement.

In contrast, if I cast it (the Number) to a Number as per your var example, I get:

2021-01-12 22:38:30.730 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'wiiscale check': Could not cast 3.44412 to java.lang.Number; line 7, column 21, length 36

Thanks!

Double check that the Item is really a Number Item. The only reason to get that error I can think of is if Item is a String Item.

Hi,

Thanks -and you are right indeed - I was convinced however yes, the Item was a String.

Problem is, the Item needs to stay a String as it is using the exec channel and it will not execute if it is a Number.

So I’m back to trying to make the String a Number, when using this:

rule "wiiscale check"
when
        Item wiiscaleweight_state changed
then
        var wiiweight = wiiscaleweight_state.state as Number
        logInfo("wiiscale", "Value of wiiscaleweight_state.state.toString is: " + wiiscaleweight_state.state.toString)
        if ( wiiweight > 2 ) {
          logInfo("wiiscale", "scale value inside the if statement")
          }
end

I get:

2021-01-12 23:35:38.817 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'wiiscale check': Could not cast 3.53892 to java.lang.Number; line 7, column 21, length 36

Line 7 being the var line.

Thanks

Assuming there is no whitespace or other stray characters you can parse it.

var wiiweight = Float::parseFloat(wiiscaleweight_state.state.toString)

Thanks a ton Rich, that did it!