I’ve got sensors reading temperature and humidity. How can I calculate the apparent temperature in a rule?
I have found the following link: https://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml
But do not manage to turn this into a rule.
It is quite hard to properly calculate the Heatindex.
Based on the formula from the url you gave it, should be possible to do something like this.
val T = temperature.state as Number
val RH = humidity.state as Number
val HI = -42.379 + 2.04901523*T + 10.14333127*RH - .22475541*T*RH - .00683783*T*T - .05481717*RH*RH + .00122874*T*T*RH + .00085282*T*RH*RH - .00000199*T*T*RH*RH
I didn’t test it, but the calculation should work.
I’m calculating the dewpoint as follows.
Different value with a different formula but should get you the idea.
Example to call (can be simplified, just passing the states will do, too): TPaussen = calculateDewPoint.apply((Garten_Auge2_Temp.state as Number).doubleValue, (Garten_Auge_Feuchte.state as Number).doubleValue) as Double
/* ------------------------------------------------------------------------------------------------------
*
* Berechnung des Taupunktes für eine gegebene Temperatur und Luftfeuchtigkeit
*
* Beschreibung:
* Die Luft ist ein Gemisch verschiedener Gase. Eines dieser Gase ist der Wasserdampf. Die Menge an
* Wasserdampf, die in der Luft enthalten sein kann, ist allerdings begrenzt. Je wärmer die Luft ist,
* desto mehr Wasserdampf kann in ihr enthalten sein.
*
* Die relative Luftfeuchtigkeit gibt an, wie viel Prozent des maximalen Wasserdampfgehaltes die Luft
* im Augenblick enthält. Da der maximale Wasserdampfgehalt mit steigender Temperatur ansteigt,
* fällt die relative Luftfeuchtigkeit mit steigender Temperatur (und umgekehrt).
*
* Die Taupunkttemperatur ist definiert als die Temperatur, bei der der aktuelle Wasserdampfgehalt in
* der Luft der maximale (100% relative Luftfeuchtigkeit) ist. Die Taupunkttemperatur ist damit eine von
* der aktuellen Temperatur unabhängige Größe. Eine Möglichkeit die Taupunkttemperatur zu messen
* ist das Abkühlen von Metall bis sich die Oberfläche mit Wasserdampf beschlägt. Dann ist die
* Temperatur des Metalls die Taupunkttemperatur.
*
* Es gibt keine exakte Formel zur Umrechnung der Taupunkttemperatur in die relative Luftfeuchtigkeit.
* Zur Erstellung des Taupunktrechners habe ich eine einfache Näherungsformel benutzt. Eine exakte
* Umrechnung ist nur mit experimentell ermittelten Tabellen möglich.
*
* Aus Temperatur und relativer Luftfeuchte bzw. Temperatur und Taupunkt lässt sich auch der
* absolute Feuchtegehalt der Luft in Gramm Wasserdampf pro Kubikmeter ausrechnen.
*
* Formeln:
* Die Grundlage der Berechnungen ist die Näherungsformel für den Sättigungsdampfdruck ( Gleichung 1 ),
* die sogenannte Magnusformel. Die relative Luftfeuchtigkeit ist definiert als das Verhältnis vom
* augenblicklichen Dampfdruck zum Sättigungsdampfdruck (umgeformte Gleichung 2). Bei der
* Taupunkttemperatur ist definitionsgemäß der Sättigungsdampfdruck gleich dem aktuellen Dampfdruck.
* Aus diesen beiden Definitionen folgt unmittelbar Gleichung 3, die Formel zur Berechnung der
* relativen Luftfeuchtigkeit aus der Taupunkttemperatur. Die 4. Gleichung beschreibt umgekehrt die
* Berechnung der Taupunkttemperatur aus der relativen Luftfeuchtigkeit und der aktuellen Temperatur.
* Diese 4. Gleichung ist im Grunde nichts anderes als die nach T aufgelöste 1. Gleichung , wobei für
* den Sättigungsdampfdruck der aktuelle Dampfdruck (und nicht der aktuelle Sättigungsdampfdruck)
* eingesetzt wird, so dass die Taupunkttemperatur und nicht die normale Temperatur als Ergebnis
* herauskommt. Aus der allgemeinen Gasgleichung ergibt sich die 5. Gleichung .
*
* Bezeichnungen:
* r = relative Luftfeuchte
* T = Temperatur in °C
* TK = Temperatur in Kelvin (TK = T + 273.15)
* TD = Taupunkttemperatur in °C
* DD = Dampfdruck in hPa
* SDD = Sättigungsdampfdruck in hPa
*
* Parameter:
* a = 7.5, b = 237.3 für T >= 0
* a = 7.6, b = 240.7 für T < 0 über Wasser (Taupunkt)
* a = 9.5, b = 265.5 für T < 0 über Eis (Frostpunkt)
*
* R* = 8314.3 J/(kmol*K) (universelle Gaskonstante)
* mw = 18.016 kg/kmol (Molekulargewicht des Wasserdampfes)
* AF = absolute Feuchte in g Wasserdampf pro m3 Luft
*
* Formeln:
* SDD(T) = 6.1078 * 10^((a*T)/(b+T))
* DD(r,T) = r/100 * SDD(T)
* r(T,TD) = 100 * SDD(TD) / SDD(T)
* TD(r,T) = b*v/(a-v) mit v(r,T) = log10(DD(r,T)/6.1078)
* AF(r,TK) = 10^5 * mw/R* * DD(r,T)/TK; AF(TD,TK) = 10^5 * mw/R* * SDD(TD)/TK
*
* Quelle: http://www.wetterochs.de/wetter/feuchte.html
*
* Danke an Stefan Ochs von www.wetterochs.de
*
* ------------------------------------------------------------------------------------------------------ */
val Functions$Function2 <Number,Number,Number> calculateDewPoint = [ temperature, humidity |
//val Functions$Function2 <double,double,double> calculateDewPoint = [ temperature, humidity |
var double a
var double b
var double SDD
var double DD
var double v
var double TD
if (temperature >= 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*temperature)/(b+temperature))))
DD = (humidity/100*SDD).doubleValue
v = Math::log10((DD/6.107))
TD = ((b*v)/(a-v))
// Return Value is TD
TD
]
Print your function here please when you’ve gotten it to work.
Thanks for you answer. This part is OK, but on my link it has many adjustments, because by lower values it is not correct. But maybe somebody has a better code written for that.
Based on the calculation in the url we could extend
val T = temperature.state as Number
val RH = humidity.state as Number
val HI = -42.379 + 2.04901523*T + 10.14333127*RH - .22475541*T*RH - .00683783*T*T - .05481717*RH*RH + .00122874*T*T*RH + .00085282*T*RH*RH - .00000199*T*T*RH*RH
if (RH< 13 && T>= 80 && T<=110) {
// ADJUSTMENT = [(13-RH)/4]*SQRT{[17-ABS(T-95.)]/17}
var adjust = ((13-RH)/4) * Math.sqrt(17-Math.abs(T-95.)/17)
HI -= adjust
} else if (RH>85 && T>80 && T<87) {
// ADJUSTMENT = [(RH-85)/10] * [(87-T)/5]
var adjust = ((RH-85)/10) * ((87-T)/5)
HI += adjust
} else if (T<80){
// HI = 0.5 * {T + 61.0 + [(T-68.0)*1.2] + (RH*0.094)}
HI = 0.5 * (T + 61.0 + ((T-68.0)*1.2) + (RH*0.094))
}
// remember it is in F in Germany you would prefer to use C
// C to F = T(°F) = T(°C) × 9/5 + 32
// F to C = T(°C) = (T(°F) - 32) × 5/9
rule "set Outdoor_FeelTemp"
when
Item Outdoor_Temp changed or
Item Outdoor_Feuchte changed
then
var Number Temp = Outdoor_Temp.state as DecimalType
var Number Humity = Outdoor_Feuchte.state as DecimalType
var Number T = Temp * 9/5 + 32
var Number RH = Humity
var Number HI = 0;
if(T <= 40.0) {
HI = T
} else {
HI = -42.379 + 2.04901523*T + 10.14333127*RH - 0.22475541*T*RH - 0.00683783*T*T - 0.05481717*RH*RH + 0.00122874*T*T*RH + 0.00085282*T*RH*RH - 0.00000199*T*T*RH*RH
if (RH < 13 && T >= 80 && T <= 112) {
var adjust = ((13-RH)/4) * Math.sqrt(17-Math.abs(T-95)/17)
HI -= adjust
} else if (RH > 85 && T >= 80 && T <= 87) {
var adjust = ((RH-85)/10) * ((87-T)/5)
HI += adjust
} else if (T < 80){
HI = 0.5 * (T + 61.0 + ((T-68.0)*1.2) + (RH*0.094))
}
}
var Number FeelTemp = (HI - 32) * 5/9
postUpdate(Outdoor_FeelTemp,FeelTemp)
end
When comparing them, some smaller differences are not clear. In particular with the development status of openHAB 3.4.1.
Are the import command from Solution A necessary or can they be omitted?
Solution B and Markus uses <…, …, …> behind Function2, but with Number or Double. Markus has commented a version with Double out. Why?
Markus uses only once a .doubleValue statement when DD is calculated. Solution A in every calculation and solution B not at all.
Solution B uses a “return” statement, the others not. What is best practice?
And last question to understand the syntax. Why searching for Function2 I found this. But here is the function described as Function.Function2. Why is a $ used in the rule instead of the point from the documentation?