Thank you!
Function to calculate heat Index, i use for heating instead of temperature as Feel Temperature
val Functions$Function2< Number, Number, Number> heatIndex = [
T, H |
var Number c1 = -8.78469475556
var Number c2 = 1.61139411
var Number c3 = 2.33854883889
var Number c4 = -0.14611605
var Number c5 = -0.012308094
var Number c6 = -0.0164248277778
var Number c7 = 0.002211732
var Number c8 = 0.00072546
var Number c9 = -0.000003582
var Number HI = c1 + c2*T + c3*H + c4*T*H + c5*(T*T) + c6*(H*H) + c7*((T*T)*H) + c8*(T*(H*H)) + c9*((T*T)*(H*H))
HI
]
var roomHI = heatIndex.apply(roomTemp, roomHum)
Don’t use this syntax for defining lambdas. It’s long, ugly and inflexible.
A related point is in general don’t specify the types of variables unless you are first assigning it to null. It’s unnecessary and in this particular case this one lambda forcing the types like this could add minutes to the amount of time it takes OH to load and parse these few lines of code. Instead let Rules DSL figure out the types on its own at runtime.
Constants (like c1-c9) should be declared as val.
Finally, when defining a lambda in this way, the last line will determine the type and the value returned by the lambda. If the last line of the lambda returns void the lambda will be defined as a procedure. But this also means you don’t need to save a variable for your calculation. Just make the calculation be the last line.
val heatIndex = [ Number T, Number H |
val c1 = -8.78469475556
val c2 = 1.61139411
val c3 = 2.33854883889
val c4 = -0.14611605
val c5 = -0.012308094
val c6 = -0.0164248277778
val c7 = 0.002211732
val c8 = 0.00072546
val c9 = -0.000003582
c1 + c2*T + c3*H + c4*T*H + c5*(T*T) + c6*(H*H) + c7*((T*T)*H) + c8*(T*(H*H)) + c9*((T*T)*(H*H))
]
Not only will that do exactly the same as the original, it will load and parse way faster and in most cases work better at runtime too.
@rlkoshak Hi! I’m stuck.
Found more relevant formula here.
But if it used as lambda, i received wrong result or no result at all.
val heatIndex = [ Number numT, Number numH |
val Double T = numT.doubleValue * 9/5 + 32
val Double H = numH.doubleValue
var Double HI = 0.0
if (T <= 40.0) {
HI = T
} else {
HI = -42.379 + 2.04901523*T + 10.14333127*H - 0.22475541*T*H - 0.00683783*T*T - 0.05481717*H*H + 0.00122874*T*T*H + 0.00085282*T*H*H - 0.00000199*T*T*H*H
if (H < 13 && T >= 80 && T <= 112) {
HI = HI - ((13-H)/4) * Math.sqrt(17-Math.abs(T.doubleValue-95)/17)
} else if (H > 85 && T >= 80 && T <= 87) {
HI = HI + ((H-85)/10) * ((87-T)/5)
} else if (T < 80){
HI = 0.5 * (T + 61.0 + ((T-68.0)*1.2) + (H*0.094))
}
}
Math.round(((HI - 32) * 5/9).floatValue*10.0)/10.0
]
-----------
roomSens_FeelsLikeTemp.postUpdate(heatIndex.apply(roomSens_InWallTemp.state, roomSens_InWallHum.state as Number))
bedSens_FeelsLikeTemp.postUpdate(heatIndex.apply(bedSens_InWallTemp.state, bedSens_InWallHum.state as Number))
kidSens_FeelsLikeTemp.postUpdate(heatIndex.apply(kidSens_InWallTemp.state, kidSens_InWallHum.state as Number))
Well, I’m no expert on these formulas. If it’s producing a wrong answer then it’s doing exactly what you are telling it to do. So you need to figure out what you’re telling it to do. Use lots of logging to log out each step of the calculation. Double check the values used with the value calculated by the function. Somewhere you’ll find a discrepancy and that will tell you which calculation is wrong.
If there’s no result at all what does that really mean? It returns null? It throws an exception?
The only think I notice, besides the return to specifying variable’s types unnecessarily, is that you cast the Item’s state to Number for the second argument but not the first when you call the lambda.
That doesn’t change anything in how to debug the problem. If it’s not caused by the failure to cast the first argument to Number then there is something wrong with the calculations, or the order of the arguments. In either case logging will tell you what is going on.