Apparent temperature

Hi

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.

Thanks for your help.

@manswiss

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.

3 Likes

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.

Thanks for you code. But your code is for dewpoint and not for “feel temperature”.
PS: I speak also German.

I pointed that out, didn’t I.
You are expected to do the ‘transfer’ work and contribute the missing part back to this community.

That’s why I included the German comments.

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

I have now the solution. Thanks for your help:

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

@manswiss

Glad you found the solution

I was looking for dew point calculation. Thanks for posting this.

Just look at the third posting @mstormi, posted the calculation.

I was also in search of a solution for the dew point calculation and found three similar sources:

Solution A, Solution B and this as Solution C.

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?

This is programming, many ways lead to the same target.
Avoid .doubleValue if you can but ultimately just do what works for you.