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
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.
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
/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.