 Expected Indoor Humidity from Outside Condition

Hi Openhabians,

as winter is approaching (at least in the northern hemisphere), I always struggle to keep the indoor humidity at a good level. Usually it keeps getting too dry and only a humidifier will help.
But sometimes, it will also help to open the windows at the right time and I thought it would be nice to know when.

So here is a rule, that will calculate the expected indoor humidity based on the outside conditions - but at indoor temperature. So If you’d open your windows, let the outside air in and then heat it up to your current indoor temperature - you will know what humidity to expect.

With this, you can do some stuff like:

• Open automated bathroom windows if there’s a possibility to decrease humidity (expected humidity lower than current indoor bathroom humidity).
• Advise to open window to increase/decrease humidity
• Monitor absolute outdoor humidity (rho_D)
• Warn if windows are open too long and expected humidity will be low etc.

What you’ll need:

• Outdoor temperature and humidity sensor
• Indoor temperature sensor (and for comparisons also an indoor humidity sensor)

Items:

• Outdoor Temperature: Outdoor_Temp in °C
• Indoor Temperature: Indoor_Temp in °C
• Outdoor Humidity: Outdoor_Humidity in Percent
• Expected Humidity: Humidity_Expected

You probably want to change the items according to the names you already use.
Here is the rule code (It might not be the most elaborate use of openhab code, but I was struggling with unit conversions here and there…)

rule "Expected Humidity"
when
Item Outdoor_Temp changed or
Item Outdoor_Humidity changed
then
var Number e_sat_w
var Number e_sat_w_in
var Number e_par
var Number e_par_in
var Number rho_D
var Number humidity_ex
val Number t_out = (Outdoor_Temp.state as Number)
val Number t_in = (Indoor_Temp.state as Number)
logInfo("math.rules","T out is " + t_out)
logInfo("math.rules","T in is " + t_in)

e_sat_w = 611.2 * Math.exp((17.62*t_out)/(243.12+t_out))
logInfo("math.rules","Saturation vapor pressure ambient: " + e_sat_w)

e_sat_w_in = 611.2 * Math.exp((17.62*t_in)/(243.12+t_in))
logInfo("math.rules","Saturation vapor pressure indoors: " + e_sat_w_in)

e_par = (Outdoor_Humidity.state as Number) / 100 * e_sat_w
logInfo("math.rules","Partial water vapor pressure: " + e_par)

rho_D = e_par / (461.51 * (t_out + 273.15))
logInfo("math.rules","Absolute humidity in kg/m^3 " + rho_D)

e_par_in = rho_D * (461.51 *(t_in + 273.15))
humidity_ex = 100 * e_par_in / e_sat_w_in
logInfo("math.rules","Expected indoor humidity: " + humidity_ex)
Humidity_Expected.postUpdate(humidity_ex)

end

So maybe someone will find it useful, I’m also open for some improvement hints on my sloppy unit conversion!

2 Likes

I do something like this, in the reverse context;
Calculate dewpoint for storage container internal air to see if it will cause condensation on steel (or glass) walls at outside temperature. (If so run an extractor fan - low temperature is less problem than condensation for many storage purposes)

1 Like

Me, too, to vent my basement where the washing is.

Shamelessly stolen from @Dibbler42 . I kept the explanation (sorry, German only) :

import java.lang.Math

/* -----------------------------------------------------------------------------------------------------
-
*
* 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 |
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
]
2 Likes

I would think about triggering the rule also, when the indoor temperature changes, because that has impact on the expected indoor humidity also.

I use a similar rule. I calculate the absolute humidity for inside and outdoor and compare these values to update a string that tells me, if opening a window increases or decreases the indoor humidity. But knowing a more are less exact number isn’t that bad. So thanks for sharing!

To supplement the rule collection for humidity calculation (I think, i found and copied it here):

rule "Calculate absolute humidity (g h2o / m3 air) and dew point"
when
Item temp1 changed or
Item hum1 changed
then
var temp = temp1.state as DecimalType
var hum = hum1.state as DecimalType

var t1 = (17.271*temp.floatValue) / (237.7+temp.floatValue) + Math::log(hum.floatValue*0.01)
var dew = (237.7 * t1) / (17.271 - t1)
var Number c1 = ((17.67*temp.floatValue)/(temp.floatValue+243.5))
var abs = (Math::pow(Math::E,c1.doubleValue)*6.112*2.1674*hum.floatValue) /(273.15+temp.floatValue)

Dewpoint1.postUpdate(dew)
AbsHum1.postUpdate(abs)
end
2 Likes