Dewpoint controlled dehumidification/ventilation

Tags: #<Tag:0x00007f2fb135cef0> #<Tag:0x00007f2fb135cd60> #<Tag:0x00007f2fb135cbd0>

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

	Item Aussenbereich_Temperature received update or
	Item Aussenbereich_Humidity received update or
	System started


	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))


rule "Taupunktberechnung Keller" // calculation of basement dewpoint

	Item Keller_Temperature received update or
	Item Keller_Humidity received update or
	System started


	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))


rule "Taupunktdifferenz berechnen" // for statistics: dewpoint difference
	Item Keller_Taupunkt changed or
	Item Aussenbereich_Taupunkt changed
	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)

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
	Item Keller_Humidity changed or
	Item Keller_Dehumidification_Steady changed
	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)

// 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"
	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
	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


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

Thank you for sharing this with us ! It is always great to see what problems and solutions other have found.

Do you happen to have any before/after data ? (Power consumption, humidity, ÔÇŽ ?)

Sorry for reviving this old thread but I would like to thank @kisseler very much for this excellent tutorial! I am currently using it as a very helpful starting point for my own basement ventilation. In my new home, I found out that the basement is quite wet, too. An approach like this looks very promising!

Just as @Spottyq I would be glad to hear something about your experiences with this topic. Maybe you have refined your ideas and may share them with the community? Thanks a lot!

1 Like