Formulas for temperatures in rules

Tags: #<Tag:0x00007efecb8add30>

I’m trying to calculate dew point using a simple formula which gets the state from two items comming from the Nest thermostat binding: temperature and humidity.

var Number interiorHumidity
var Number interiorTemperature
var Number exteriorTemperature
var Number dewPoint

var auxVar = 20|°C

rule "Calcula pRocio"
when
   Time cron "0 0/1 * * * ?" or
then
    interiorHumidity = LivingRoomThermostatNest_Humidity.state as Number
    interiorTemperature = LivingRoomThermostatNest_Temperature.state as Number

    //Note: auxVar has been created just splitting the formula and having a clearer view of the problem.
    auxVar = ((100 - interiorHumidity * 100 ) / 5)
    dewPoint = interiorTemperature - auxVar


    logInfo("dew","interiorHumidity --> ",interiorHumidity)
    logInfo("dew","interiorTemperature --> ",interiorTemperature)
    logInfo("dew","dewPoint --> " + dewPoint)
    logInfo("dew","auxVar --> " + auxVar)
end

The rule works and the states are properly retrieved from the item.

This is the log I’m getting

interiorHumidity --> 55 %
interiorTemperature --> 21.5 ℃
auxVar --> 9.00000000
dewPoint --> 285.65000000

As you can see the result is not the one expected
dewPoint = interiorTemperature - auxVar => dewPoint = 21.5 ℃ - 9.00000000
and the result is 285.65000000

I guess that the problem is that interiorTemperature is a QuantityType and auxVar is Number and that creates the problem, however I could not find a way of fixing it.

Can someone propose a solution for this?

Thanks in advance

I created long time ago a lambda to calculate the dew point from Teperature and humdity. maybe this helps you

//  Lambda: getDewPoint
//
// 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 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) {
        a = 7.5
        b = 237.3
    } else {
        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))

]

The description is in germany, but with a little help (google) you will get it.

You answer is correct, it’s just in Kelvin, not C. If you subtract 273.15 (0C in Kelvin), you’ll get the number you want. But there must be a better solution, some sort of “var Number:Temperature” or similar? Hopefully someone else can chime in with the correct solution.

Thanks!
Let’s see if someone has a better solution and an explanation of why the temperature is converted automatically from Celsius to Kelvin.
As seen on the log, interiorTemperature and auxVar are Celsius but the result comes in Kelvin…

It makes sense that all temperature calculations are internally done as Kelvin. I’m guessing that your only issue is with displaying the value in C when it is all done.

The secrets of dimensioned openHAB Numbers are in here (somewhere)
https://www.eclipse.org/smarthome/blog/2018/02/22/units-of-measurement.html

This part looks relevant

Note that a QuantityType in scripts and rules must be written as <value>|"<unit>" . Some frequently used units and those which are valid identifiers can also ommit the quotation marks and can conveniently be written as <value>|<unit> (e.g. 20|°C )

I would suspect though that your simplified dewpoint calculation is missing something; it would normally be worked in K, and apply factors to convert to/from C

This will get the value as a vanilla NumberType

rule "Calcula pRocio"
when
   Time cron "0 0/1 * * * ?" or
then
    interiorHumidity = (LivingRoomThermostatNest_Humidity.state as QuantityType<Number>).doubleValue
    interiorTemperature = (LivingRoomThermostatNest_Temperature.state as QuantityType<Number>).doubleValue

I’m curious what the ‘native’ or ‘default’ raw value is for a Temperature item. Is it in K ? (that would make sense)

Yes it is

Even though K is probably what is wanted for dewpoint calculations, please could you show me an example of extracting a temperature value into a Number variable in C?
I find that UoM doc hard to grasp, I thnk it’s because forms like QuantityType<Number> in an explanatory LOOK like they require you to substitute text.

once the operation is performed, how do I generate a quantityType back?
adding |ºK is not working and neither is adding as as QuantityType
Thanks!

DewPointItem.postUpdate(dewPoint)
If your item is defined in C then you need to post a C value

My item is defined as

Number:Temperature      punt_Rosada     "Punt Rosada [%.1f %unit%]"         <Temperature>       (Weather, Temperatures_Graf)

If I use a hardcoded value it works
punt_Rosada.postUpdate(23|°C)

But if I use the result of my calculation it does not
punt_Rosada.postUpdate(tPuntoRocio|°C)

I can see in the log that tPuntoRocio has value.

In the log I get no viable alternative at input ‘°C’ referring to the postUpdate line in my rules file

Why I can’t use my variable with the calculation as a valid parameter?

This should work

punt_Rosada.postUpdate(tPuntoRocio)

It’s working now.
Thanks!

That may work with punt_Rosada.postUpdate(tPuntoRocio|"°C")

Hi,

In case you decide that you don’t want to maintain a rule for this, I’ve put together a binding that generates a bunch of derived weather values automatically. More information (along with a link to the latest version) can be found here:

Feel free to drop me a line if you have any questions!

Bill