[SOLVED] Problem with casting 7.52 °C into DecimalType

Tags: #<Tag:0x00007fc3e9484658>

I am running into a problem when calculating the Dew Point using an example from here.

The following error I see in my log files:

2019-04-03 21:13:17.919 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Compute DewPoint': Could not cast 7.5 °C to org.eclipse.smarthome.core.library.types.DecimalType; line 9, column 12, length 44

The item file looks like the following:

Number:Temperature Weather_Temp_Dewpoint        "Computed Dewpoint"
DateTime localLastMeasurement "Timestamp of last measurement [%1$tY-%1$tm-%1$tdT%1$tH:%1$tM:%1$tS]" <time> (Weather) { channel="openweathermap:weather-and-forecast:api:local:current#time-stamp" }
String localCurrentCondition "Current condition [%s]" <sun_clouds> (Weather) { channel="openweathermap:weather-and-forecast:api:local:current#condition" }
Image localCurrentConditionIcon "Icon" (Weather) { channel="openweathermap:weather-and-forecast:api:local:current#icon" }
Number:Temperature localCurrentTemperature "Current temperature [%.1f %unit%]" <temperature> (Weather) { channel="openweathermap:weather-and-forecast:api:local:current#temperature" }
Number:Pressure localCurrentPressure "Current barometric pressure [%.1f %unit%]" <pressure> { channel="openweathermap:weather-and-forecast:api:local:current#pressure" }
Number:Dimensionless localCurrentHumidity "Current atmospheric humidity [%d %unit%]" <humidity> { channel="openweathermap:weather-and-forecast:api:local:current#humidity" }

weather.rules looks like the following:

rule "Compute DewPoint"
when
        Item localCurrentTemperature changed or
        Item localCurrentHumidity changed or
        System started
then
        if ((localCurrentTemperature.state != NULL) && (localCurrentHumidity.state != NULL))
        {
                var t = (localCurrentTemperature.state as DecimalType).doubleValue
                var h = (localCurrentHumidity.state as DecimalType).doubleValue
        
                postUpdate(Weather_Temp_Dewpoint,getDewPoint.apply(t, h))
        }
end

weather.script looks like the following:

val org.eclipse.xtext.xbase.lib.Functions$Function2<Double, Double, Double> getDewPoint = [
        
        Double Temperature, 
        Double Humidity 
        
        |

        var Double a
        var Double b
        var Double SDD
        var Double DD
        var Double v
        var Double t = Temperature
        var Double h = Humidity
        
        if (t >= 0.0){ // T >= 0 °C
                a = 7.5
                b = 237.3
        } else { // T < 0 °C über Wasser
                a = 7.6
                b = 240.7
        }
        SDD=(6.1078 * Math::pow(10.0, ((a*t)/(b+t))))
        DD = (h/100.0*SDD)
        v = Math::log10((DD/6.107))
        return ((b*v)/(a-v))

]

I do not remember anymore but I believe this rule worked before the upgrade to OpenHAB 2.4.

1 Like

Many thanks, @rossko57, this worked for me. The code does now look like the following:

rule "Compute DewPoint"
when
        Item localCurrentTemperature changed or
        Item localCurrentHumidity changed or
        System started
then
        if ((localCurrentTemperature.state != NULL) && (localCurrentHumidity.state != NULL))
        {
                var Number t = (localCurrentTemperature.state as QuantityType<Number>).doubleValue
                var Number h = (localCurrentHumidity.state as QuantityType<Number>).doubleValue
        
                postUpdate(Weather_Temp_Dewpoint,getDewPoint.apply(t, h))
        }
end

I get the following error in my openhab.log now:

2019-04-04 09:15:12.184 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Compute DewPoint': The name 'getDewPoint' cannot be resolved to an item or type; line 13, column 36, length 11

May I not call getDewPoint the way I am currently doing it? How do I need to call that script within postUpdate to do my calculation?

Don’t know if that helps, but I have a very similar function in my setup that calculates the absolute humidity. Wanted to post it here for reference. This definitely works/worked in 2.4 and 2.5.0.M1.

import org.eclipse.smarthome.core.library.dimension
import javax.measure.quantity
import java.lang.Math
import java.math.BigDecimal
import java.text.DecimalFormat
import org.eclipse.xtext.xbase.lib.Functions

/*
 * Calculates absolute humidity
 */
val Functions$Function2<Number, QuantityType<Temperature>, Double> absHum = [ relHum, t |
    // constants
    val GAS_CONST = 8314.3
    val MOL = 18.016

    var a = 0d
    var b = 0d
    if (t >= 0|°C) {
        // water
        a = 7.5
        b = 237.3
    } else {
        // ice
        a = 7.6
        b = 240.7  
    }

    /*
     * formulas
     * saturated vapor pressure:	svp = 6.1078 * 10^((a * temp) / (b + temp))
     * vapor pressure:		vp = relHum * 100 / svp
     * absolute humidity:		absHum = 10^5 * MOL / GAS_CONST * vp / (temp + 273.15)
     */

    // absolute humidity inside
    val svp = 6.1078 * Math::pow(10, (a * t) / (b + t))
    val BigDecimal vp = relHum / 100 * svp
    val absHum = Math::pow(10, 5) * MOL / GAS_CONST * vp / (t + 273.15|°C)
	
    return absHum
]

VSCode will mark a few spots as invalid (current limitation of units of measurement & language server), but the code works.

Some friendly advice:

  • Since you are working with units of measurements anyway, try not to lose those on the way (e.g. when handing them over to functions).
  • You do not need to specify the type of the method arguments (after [ and before |) because the compiler will infer those from the types in the function declaration
  • There used to be a bug in openHAB where it was necessary to insert a blank (space) directly after the opening square brackets [. I still have this in my functions. Not sure if it is still necessary. But I believe the bug made it appear as if the Function didn’t exist
  • If you import the org.eclipse.xtext.xbase.lib.Functions package you can use the much shorter Function declaration
  • Instead of calling postUpdate (or sendCommand) with the item as the first parameter you should call the postUpdate method of the item. This will make your code more readable and is more suitable to object oriented nature of xtext. (But the way you are calling the function in your example is valid!)
rule "Some Rule"
when
  System started
then
    MyItem.postUpdate(
        myFunction.apply(arg0, argn)
    )
end

Cheers,
Jens

2 Likes

You need to have your function in the same xxx.rules file as the rules that call it, to be in scope.

Thank you for this information, as this was not clear to me. I thought scripts need to go into scripts/XXX.script.

Functions must be written in rules syntax DSL and are included in rules files.

Scripts go in individual files in /scripts. Never found them much use. as you cannot pass parameters.

1 Like

Thanks to @rossko57 and @jewesta, the issue is resolved now.

/var/log/openhab2/events.log:2019-04-04 20:46:56.866 [vent.ItemStateChangedEvent] - Weather_Temp_Dewpoint changed from 4.783841456696462 °C to 4.636296257761859 °C
/var/log/openhab2/events.log:2019-04-04 20:56:58.261 [vent.ItemStateChangedEvent] - Weather_Temp_Dewpoint changed from 4.636296257761859 °C to 4.587114193574739 °C
/var/log/openhab2/events.log:2019-04-04 21:07:00.003 [vent.ItemStateChangedEvent] - Weather_Temp_Dewpoint changed from 4.587114193574739 °C to 4.547768422988867 °C
/var/log/openhab2/events.log:2019-04-04 21:17:01.505 [vent.ItemStateChangedEvent] - Weather_Temp_Dewpoint changed from 4.547768422988867 °C to 5.255543237607681 °C
/var/log/openhab2/events.log:2019-04-04 21:27:03.091 [vent.ItemStateChangedEvent] - Weather_Temp_Dewpoint changed from 5.255543237607681 °C to 5.235714366532568 °C
/var/log/openhab2/events.log:2019-04-04 21:37:04.489 [vent.ItemStateChangedEvent] - Weather_Temp_Dewpoint changed from 5.235714366532568 °C to 5.047339395047797 °C
/var/log/openhab2/events.log:2019-04-04 21:47:05.957 [vent.ItemStateChangedEvent] - Weather_Temp_Dewpoint changed from 5.047339395047797 °C to 4.78956107656496 °C
/var/log/openhab2/events.log:2019-04-04 21:57:07.186 [vent.ItemStateChangedEvent] - Weather_Temp_Dewpoint changed from 4.78956107656496 °C to 4.730073437246145 °C
/var/log/openhab2/events.log:2019-04-04 22:07:08.700 [vent.ItemStateChangedEvent] - Weather_Temp_Dewpoint changed from 4.730073437246145 °C to 4.670585672281414 °C

@jewesta now that I got the code working, I will work on the cleanups you suggested earlier today.

1 Like