Since my initial project to start with smart home devices at all was to dehumidify our 400 year old basement, I decided to post my current results on that project here.
The problem was, to start ventilators only when the air outside has the correct humidity/temperature condition in order to dry the air inside the basement. For us, this is to keep the humidity in the basement as low as possible. We also have a dehumidificator, but it uses about 450 W (the ventilators only around 40 W).
The devices I use:
- two Sonoff POW switches to control ventilators/dehumidificator and to have an overview of energy consumption.
- outsite I use several sensors to identify the outdoor dewpoint (homematic weather station, homematic outdoor sensor, netatmo modul).
- inside I use netatmo modul and a AM2301 Sensor connected to Sonoff TH16 running custom firmware
But you can use whatever type of sensors and switch. I post my code below to make it public. I may translate everything into englisch when I have the time. But my approach may help the one or other already. I wasn’t able to find a complete working system before, so have fun drying you basement in a low cost way:
My script to calculate the dewpoint:
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){ // 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*t)/(b+t))))
DD = (h/100.0*SDD)
v = Math::log10((DD/6.107))
return ((b*v)/(a-v))
]
rule "Taupunktberechnung Außenbereich" // calculation of outdoor dewpoint
when
Item Aussenbereich_Temperature received update or
Item Aussenbereich_Humidity received update or
System started
then
if ((Aussenbereich_Temperature.state != NULL) && (Aussenbereich_Humidity.state != NULL))
{
var t = (Aussenbereich_Temperature.state as DecimalType).doubleValue
var h = (Aussenbereich_Humidity.state as DecimalType).doubleValue
// OutsideThermometerCombined.sendCommand(String::format("%.1f°C / %.0f%%", t, h))
Aussenbereich_Taupunkt.postUpdate(getDewPoint.apply(t, h))
}
end
rule "Taupunktberechnung Keller" // calculation of basement dewpoint
when
Item Keller_Temperature received update or
Item Keller_Humidity received update or
System started
then
if ((Keller_Temperature.state != NULL) && (Keller_Humidity.state != NULL))
{
var t = (Keller_Temperature.state as DecimalType).doubleValue
var h = (Keller_Humidity.state as DecimalType).doubleValue
// OutsideThermometerCombined.sendCommand(String::format("%.1f°C / %.0f%%", t, h))
Keller_Taupunkt.postUpdate(getDewPoint.apply(t, h))
}
end
rule "Taupunktdifferenz berechnen" // for statistics: dewpoint difference
when
Item Keller_Taupunkt changed or
Item Aussenbereich_Taupunkt changed
then
var dewpoint_keller = (Keller_Taupunkt.state as DecimalType).doubleValue
var dewpoint_aussen = (Aussenbereich_Taupunkt.state as DecimalType).doubleValue
Taupunkt_Differenz.postUpdate(dewpoint_keller - dewpoint_aussen)
end
My script to control ventilation:
var Timer ventilation_timer = null
var Timer interval_timer = null
rule "Dehumidification" // this is to switch the dehumidificator when the inner humidity runs above a certain value
when
Item Keller_Humidity changed or
Item Keller_Dehumidification_Steady changed
then
var Number basement_humidity = Keller_Humidity.state as DecimalType
var Number dehumitification_bottom = Dehumitification_Bottom.state as DecimalType
var Number dehumitification_top = Dehumitification_Top.state as DecimalType
if(basement_humidity >= dehumitification_top) {
sendCommand(Keller_Entfeuchter_Steckdose, ON)
}
if(basement_humidity <= dehumitification_bottom) {
sendCommand(Keller_Entfeuchter_Steckdose, OFF)
}
end
// this is the core ventilation rule. I checks the surrounding parameters an starts the ventilators for 5 minutes and waits a certain time period to let the "fresh" air collecting the humidity from the inside.
rule "Ventilation"
when
Item Aussenbereich_Taupunkt changed or
Item Aussenbereich_Temperature changed or
Item Keller_Taupunkt changed or
Item Keller_Ventilation_Interval changed or
Item Keller_Temperatur_Min changed or
Item Keller_Temperature changed or
Item Keller_Ventilation_Steady changed or
Item Keller_Lueftung_Steckdose changed
then
var Number outdoor_dewpoint = Aussenbereich_Taupunkt.state as DecimalType
var Number basement_dewpoint = Keller_Taupunkt.state as DecimalType
var Number dewpoint_min_gap = Keller_Dewpoint_Gap_Min.state as DecimalType
var Number outdoor_temperature = Aussenbereich_Temperature.state as DecimalType
// Wenn Lüftung ständig an, dann Steckdose an!
if (Keller_Ventilation_Steady.state == ON) {
if (Keller_Lueftung_Steckdose.state == OFF) sendCommand(Keller_Lueftung_Steckdose, ON)
} else if (outdoor_temperature <= 0) {
if (Keller_Lueftung_Steckdose.state == ON) sendCommand(Keller_Lueftung_Steckdose, OFF)
}
// Wenn Taupunkt außen höher ist, als Taupunkt Keller, in jedem Fall ausschalten!
else if (outdoor_dewpoint > basement_dewpoint) {
sendCommand(Keller_Lueftung_Steckdose, OFF)
ventilation_timer = null
interval_timer = null
}
else if (basement_dewpoint - outdoor_dewpoint >= dewpoint_min_gap) {
var Number ventilation_interval = (Keller_Ventilation_Interval.state as DecimalType).intValue
if (ventilation_timer == null && interval_timer == null) {
if (Keller_Lueftung_Steckdose.state == OFF) sendCommand(Keller_Lueftung_Steckdose, ON)
// 5 Minuten Lüften
ventilation_timer = createTimer(now.plusMinutes(5)) [|
sendCommand(Keller_Lueftung_Steckdose, OFF)
ventilation_timer = null
// Pause gem. Keller_Ventilation_Interval
interval_timer = createTimer(now.plusMinutes(ventilation_interval)) [|
sendCommand(Keller_Lueftung_Steckdose, ON)
interval_timer = null
]
]
}
}
end
My items
/* **********************************************************************
* * Einstellung der Taupunktdifferenz (Kellertaupunkt - Außentaupunkt) *
* * 2°C bis 9°C, 1°-Schritte, Standardwert 5°C *
* **********************************************************************
* Eine Entfeuchtung erfolgt nach der eingestellten Taupunktdifferenz (effektive Feuchtigkeit).
* Der Standardwert liegt bei ca. 5°C Taupunktdifferenz. Dies ist ein Erfahrungswert um eine Entfeuchtung
* effektiv zu gewährleisten. Die Werten können zwischen 2°C und 9°C eingestellt werden. Wird die Differenz
* verkleinert, also gegen 2 gehen gelassen, wird öfter gelüftet, jedoch wesentlich weniger entfeuchtet.
*
*/
Number Keller_Dewpoint_Gap_Min
/* ************************************************************************************************
* * Einstellung des Lüftungsintervalls (Zeit zwischen 5-Minuten-Lüftungsphasen) *
* * 0 bis 90 Min., Entfeuchtung bei 0 Min., Erhaltungslüftung 10 bis 90 Min. in 10-Min.-Schitten *
* ************************************************************************************************
* Zur Entfeuchtung von Kellern wird hier ein automatisches Stoßlüften durchgeführt (Einstellung 0 Min.).
* Die Kellerluft wird dann durch die Querlüftung durch trockene Außenluft ausgetauscht, ohne dass sich
* die Wände abkühlen. Danach stoppt die Steuerung bei Taupunkt < 1°C) und wartet erneut auf die
* eingestellten Lüftungsbedingungen.
*/
Number Keller_Ventilation_Interval
/* **************************************************
* * Einstellung der Innenraumtemperatur *
* * 5°C bis 25°C in 1°-Schritten, Standardwert 8°C *
* **************************************************
*
* Mit diesem Wert wird die Absenkung der Innenraumtemperatur begrenzt.
*
*/
Number Keller_Temperatur_Min
/* ***********************************************************
* * Dauerlüftung *
* * Einschalten der Lüftung unabhängig von allen Parametern *
* ***********************************************************
*/
Switch Keller_Ventilation_Steady
// Entfeuchter-Variablen
Switch Keller_Dehumidification_Steady
Number Dehumitification_Bottom
Number Dehumitification_Top
// Berechnete Temperaturwerte (Durchschnittswerte)
Number Aussenbereich_Humidity "Luftfeuchtigkeit außen [%.2f %%]" <humidity> (Weather, Humidity)
Number Aussenbereich_Temperature "Temperatur außen [%.2f°C]" <temperature> (Weather, Temperature)
Number Keller_Humidity "Luftfeuchtigkeit Keller [%.2f %%]" <humidity> (Weather, Humidity)
Number Keller_Temperature "Temperatur Keller [%.2f°C]" <temperature> (Weather, Temperature)
// Berechnete Taupunktwerte (siehe dewpoint.rules)
Number Keller_Taupunkt "Taupunkt Keller [%.2f°C]" (Weather, Temperature)
Number Aussenbereich_Taupunkt "Taupunkt außen [%.2f°C]" (Weather, Temperature)
Number Taupunkt_Differenz "Taupunktdifferenz [%.2f°C]" (Weather, Temperature)
My sitemap
Frame label="Lüftungsprogramm" {
Setpoint item=Keller_Ventilation_Interval icon="clock" label="Lüftungsintervall [%.0f Min.]" step=10 minValue=0 maxValue=90
Setpoint item=Keller_Dewpoint_Gap_Min icon="water" label="Taupunktdifferenz (5°C) [%.1f°C]" step=1 minValue=2 maxValue=9
// Setpoint item=Keller_Temperatur_Min icon="temperature" label="Min. Temperatur (8°C) [%.1f°C]" step=1 minValue=5 maxValue=25
Switch item=Keller_Ventilation_Steady label="Dauerlüftung"
Switch item=Keller_Lueftung_Steckdose
Text item=Keller_Lueftung_Power {
Frame {
Text item=Keller_Lueftung_Power
Text item=Keller_Lueftung_Pow_Total
Text item=Keller_Lueftung_Pow_Yesterday
Text item=Keller_Lueftung_Pow_Today
}
}
Text item=Keller_Lueftung_RSSI
}
Frame label="Entfeuchtung" {
Setpoint item=Dehumitification_Bottom icon="rain" label="Entfeuchter aus [%.0f %%]" step=1 minValue=0 maxValue=90
Setpoint item=Dehumitification_Top icon="rain" label="Entfeuchter an [%.0f %%]" step=1 minValue=0 maxValue=90
Switch item=Keller_Entfeuchter_Steckdose
Text item=Keller_Entfeuchter_Power {
Frame {
Text item=Keller_Entfeuchter_Power
Text item=Keller_Entfeuchter_Pow_Total
Text item=Keller_Entfeuchter_Pow_Yesterday
Text item=Keller_Entfeuchter_Pow_Today
}
}
Text item=Keller_Entfeuchter_RSSI
}