Letzter täglicher Build · 2 YAML-Konfigurationen
Build erfolgreich
Zuletzt gebaut: 26.09.2026, 15:15
Dieses Projekt enthält 1 weitere Datei
Nutze den Download-Button oben, um das komplette Projekt herunterzuladen und alle Dateien einzusehen.

3ddruck-parts1.png
572.8 KB

3ddruck-parts2.png
1086.1 KB
1substitutions:
2 # -----------------------
3 # Geräte-Identifikation
4 # -----------------------
5 device_name: shys-heizungsbooster # Name des Geräts (z.B. "shys-heizungsbooster")
6 device_friendly_name: SHYS Heizungsbooster # Anzeige-Name des Geräts (z.B. "SHYS Heizungsbooster")
7
8 # -----------------------
9 # Sicherheit & Netzwerk
10 # -----------------------
11 api_encryption_key: !secret api_encryption_key # API Encryption Key (z.B. "base64_encrypted_key_hier_eintragen==")
12 ota_password: !secret ota_password # Passwort für den OTA Update (z.B. "InM2TlqVfJe4")
13 ap_ssid: ${device_name}_AP # SSID für den Access Point (z.B. "shys-heizungsbooster_AP")
14 ap_password: !secret ap_password # Passwort für den Access Point (z.B. "InM2TlqVfJe4")
15
16 # -----------------------
17 # Lüfter Konfiguration
18 # -----------------------
19 pin_fan: GPIO12 # Pin für Lüfter PWM Steuersignal
20 fan_pwm_frequency: 25000 Hz # 4-Pol PC-Lüfter: 25000Hz // 3-Pol Lüfter mit Mosfet Schaltung: 1000Hz (bei Problemen 500-3000Hz testen)
21
22 # ---------------------------------
23 # Temperatur-Sensor Konfiguration
24 # ---------------------------------
25 pin_onewire_ds18b20: GPIO13 # Pin für One-Wire
26 ds18b20_address_heizung: "0xd70122113b001828" # Adresse DS18B20 Heizung (aus ESPHome-Log auslesen)
27 ds18b20_address_raum: "0xea0122113698f828" # Adresse DS18B20 Raumtemp (aus ESPHome-Log auslesen)
28
29 raum_temp_entity: "sensor.raum_temperatur" # Raum Temperatur-Sensor in Home Assistant (wenn nicht gewünscht, dummy Eintrag stehen lassen!)
30
31 # ----------------------
32 # Taster Konfiguration
33 # ----------------------
34 pin_mode_button: GPIO14 # Pin für den Mode-Button (z.B. GPIO14)
35 pin_set_button: GPIO16 # Pin für den Set-Button (z.B. GPIO16)
36
37 pin_scl: GPIO5 # Pin für den SCL-Pin (z.B. GPIO5)
38 pin_sda: GPIO4 # Pin für den SDA-Pin (z.B. GPIO4)
39 pin_analog_in: ADC # Analoger Eingang für die Messung der Spannung am Lüfter (z.B. ADC1_0)
40
41 # -----------------------
42 # Standardwerte (Initial Values)
43 # -----------------------
44 initial_temp_threshold: "3.0" # Temperaturdifferenz zwischen Heizung und Raum, ab der der Lüfter eingeschaltet wird (z.B. 3°C)
45 initial_min_heizung_temp: "30.0" # Mindesttemperatur der Heizung, unter der der Lüfter ausgeschaltet wird (z.B. 30°C)
46 initial_max_heizung_temp: "50.0" # Maximale Heizungstemperatur, ab der der Lüfter mit 100% läuft (z.B. 50°C)
47 initial_default_raum_temp: "21.0" # Fallback-Wert wenn kein Wert von HA oder DS18B20 verfügbar ist
48 initial_manual_fan_speed: "50.0" # Manuelle Lüftergeschwindigkeit (für MANUAL-Modus)
49
50 # -----------------------
51 # Timing
52 # -----------------------
53 automatik_interval: 10s # Intervall für die automatische Steuerung (z.B. 10s)
54 sensor_update_interval: 9s # Sollte etwas kürzer sein als automatik_interval
55
56
57
58 # --------------------------------------------------------------------------------------------
59 # --------------------------------------------------------------------------------------------
60 # Konfiguration ENDE
61 # --------------------------------------------------------------------------------------------
62 # --------------------------------------------------------------------------------------------
63
64
65esphome:
66 name: ${device_name}
67 friendly_name: ${device_friendly_name}
68
69 comment: Heizungsbooster zur besseren Wärmeverteilung im Raum.
70 project:
71 name: "smarthomeyourself.heizungsbooster"
72 version: "1.0.0"
73
74esp8266:
75 board: esp12e
76
77logger:
78
79api:
80 encryption:
81 key: ${api_encryption_key}
82
83ota:
84 - platform: esphome
85 password: ${ota_password}
86
87wifi:
88 ssid: !secret wifi_ssid
89 password: !secret wifi_password
90
91 ap:
92 ssid: ${ap_ssid}
93 password: ${ap_password}
94
95captive_portal:
96
97one_wire:
98 - platform: gpio
99 pin: ${pin_onewire_ds18b20}
100
101output:
102 - platform: esp8266_pwm
103 pin: ${pin_fan}
104 frequency: ${fan_pwm_frequency}
105 id: pwm_output
106
107fan:
108 - platform: speed
109 output: pwm_output
110 name: "Ventilator"
111 id: heizung_luefter
112 speed_count: 100
113 restore_mode: ALWAYS_OFF
114
115sensor:
116 # Temperatur-Sensor Heizung (DS18B20 #1)
117 - platform: dallas_temp
118 name: "Heizkörper Temperatur (DS18B20 #1)"
119 update_interval: ${sensor_update_interval}
120 address: ${ds18b20_address_heizung}
121 accuracy_decimals: 1
122 id: heizung_temp
123
124 # Raumtemperatur-Sensor (DS18B20 #2) - Fallback wenn HA keinen Wert liefert
125 - platform: dallas_temp
126 name: "Raumtemperatur (DS18B20 #2)"
127 update_interval: ${sensor_update_interval}
128 address: ${ds18b20_address_raum}
129 unit_of_measurement: "°C"
130 accuracy_decimals: 1
131 id: raum_temp_ds18b20
132
133 # Raumtemperatur-Sensor aus HA
134 - platform: homeassistant
135 id: ha_raum_temp
136 entity_id: ${raum_temp_entity}
137 internal: true
138
139 # Template Sensor: Raumtemperatur mit Priorität (HA > DS18B20 > Default)
140 - platform: template
141 name: "Raumtemperatur (Favorit)"
142 id: raum_temp
143 update_interval: ${sensor_update_interval}
144 accuracy_decimals: 1
145 unit_of_measurement: "°C"
146 lambda: |-
147 // Priorität 1: Home Assistant Sensor
148 if (id(ha_raum_temp).has_state()) {
149 return id(ha_raum_temp).state;
150 }
151 // Priorität 2: DS18B20 Raumtemp-Sensor
152 if (id(raum_temp_ds18b20).has_state()) {
153 return id(raum_temp_ds18b20).state;
154 }
155 // Priorität 3: Default-Wert
156 return id(default_raum_temp).state;
157
158number:
159 # Threshold für Temperaturdifferenz (Heizung - Raum) zum Einschalten
160 - platform: template
161 name: "Temperatur-Schwellwert"
162 id: temp_threshold
163 min_value: 0.0
164 max_value: 10.0
165 step: 0.5
166 initial_value: ${initial_temp_threshold}
167 optimistic: true
168 restore_value: true
169
170 # Minimale Heizungstemperatur (unter diesem Wert bleibt Lüfter aus)
171 - platform: template
172 name: "Minimale Heizungstemperatur"
173 id: min_heizung_temp
174 min_value: 20.0
175 max_value: 40.0
176 step: 1.0
177 initial_value: ${initial_min_heizung_temp}
178 optimistic: true
179 restore_value: true
180
181 # Maximale Heizungstemperatur (ab diesem Wert läuft Lüfter mit 100%)
182 - platform: template
183 name: "Maximale Heizungstemperatur"
184 id: max_heizung_temp
185 min_value: 40.0
186 max_value: 80.0
187 step: 1.0
188 initial_value: ${initial_max_heizung_temp}
189 optimistic: true
190 restore_value: true
191
192 # Default-Raumtemperatur (Fallback wenn weder HA noch DS18B20 verfügbar)
193 - platform: template
194 name: "Standard-Raumtemperatur"
195 id: default_raum_temp
196 min_value: 15.0
197 max_value: 30.0
198 step: 0.5
199 initial_value: ${initial_default_raum_temp}
200 optimistic: true
201 restore_value: true
202
203 # Manuelle Lüftergeschwindigkeit (für MANUAL-Modus)
204 - platform: template
205 name: "Manuelle Lüftergeschwindigkeit"
206 id: manual_fan_speed
207 min_value: 0.0
208 max_value: 100.0
209 step: 10.0
210 initial_value: ${initial_manual_fan_speed}
211 optimistic: true
212 restore_value: true
213 on_value:
214 - script.execute: apply_manual_fan_speed
215
216select:
217 # Interner Select für Betriebsmodus
218 - platform: template
219 id: fan_mode
220 name: "Betriebsmodus"
221 internal: false
222 options:
223 - "off"
224 - "manual"
225 - "auto"
226 initial_option: "auto"
227 optimistic: true
228 restore_value: true
229 on_value:
230 - lambda: |-
231 std::string mode = std::string(x);
232
233 if (mode == "off") {
234 // OFF: Lüfter ausschalten
235 auto call = id(heizung_luefter).turn_off();
236 call.perform();
237
238 } else if (mode == "manual") {
239 // MANUAL: Auf manuelle Geschwindigkeit setzen
240 id(apply_manual_fan_speed).execute();
241
242 } else if (mode == "auto") {
243 // AUTO: Automatik-Logik ausführen
244 id(automatik_steuerung).execute();
245 }
246
247binary_sensor:
248 # Mode-Button: Betriebsmodus wechseln (OFF -> MANUAL -> AUTO -> OFF)
249 - platform: gpio
250 pin:
251 number: ${pin_mode_button}
252 mode: INPUT_PULLUP
253 inverted: true
254 name: "Mode-Button"
255 id: mode_button
256 on_press:
257 - script.execute: switch_mode
258
259 # Set-Button: Geschwindigkeit im Manual-Modus ändern
260 - platform: gpio
261 pin:
262 number: ${pin_set_button}
263 inverted: true
264 name: "Set-Button"
265 id: set_button
266 on_press:
267 - script.execute: adjust_manual_speed
268
269
270interval:
271 # Automatik-Steuerung
272 - interval: ${automatik_interval}
273 then:
274 - script.execute: automatik_steuerung
275
276
277script:
278 # Lüftergeschwindigkeit vom Number in den Fan übernehmen (nur im MANUAL-Modus)
279 - id: apply_manual_fan_speed
280 then:
281 - lambda: |-
282 // Nur im MANUAL-Modus anwenden
283 std::string mode = id(fan_mode).current_option();
284 if (mode != "manual") {
285 return;
286 }
287
288 int speed_value = (int)id(manual_fan_speed).state;
289
290 if (speed_value < 1) {
291 auto call = id(heizung_luefter).turn_off();
292 call.perform();
293
294 } else {
295 auto call = id(heizung_luefter).turn_on();
296 call.set_speed(speed_value);
297 call.perform();
298 }
299
300 # Betriebsmodus wechseln: off -> manual -> auto -> off
301 - id: switch_mode
302 then:
303 - lambda: |-
304 std::string current_mode = id(fan_mode).current_option();
305 std::string new_mode;
306
307 if (current_mode == "off") {
308 new_mode = "manual";
309
310 } else if (current_mode == "manual") {
311 new_mode = "auto";
312
313 } else {
314 new_mode = "off";
315 }
316
317 id(fan_mode).publish_state(new_mode);
318
319 # Manuelle Geschwindigkeit in 25% Stufen ändern (0% -> 25% -> 50% -> 75% -> 100% -> 0%)
320 - id: adjust_manual_speed
321 then:
322 - lambda: |-
323 // Nur im MANUAL-Modus aktiv
324 std::string mode = id(fan_mode).current_option();
325 if (mode != "manual") {
326 return;
327 }
328
329 float current_speed = id(manual_fan_speed).state;
330 float new_speed;
331
332 if (current_speed < 12.5) {
333 new_speed = 25.0;
334
335 } else if (current_speed < 37.5) {
336 new_speed = 50.0;
337
338 } else if (current_speed < 62.5) {
339 new_speed = 75.0;
340
341 } else if (current_speed < 87.5) {
342 new_speed = 100.0;
343
344 } else {
345 new_speed = 0.0;
346 }
347
348 id(manual_fan_speed).publish_state(new_speed);
349
350 # Automatik-Steuerung: Lüfter basierend auf Temperaturdifferenz steuern
351 - id: automatik_steuerung
352 then:
353 - lambda: |-
354 // Nur im AUTO-Modus ausführen
355 std::string mode = id(fan_mode).current_option();
356 if (mode != "auto") {
357 return;
358 }
359
360 if (!id(heizung_temp).has_state() || !id(raum_temp).has_state()) {
361 return; // Warten bis Sensoren Werte haben
362 }
363
364 float heizung = id(heizung_temp).state;
365 float raum = id(raum_temp).state;
366 float threshold = id(temp_threshold).state;
367 float min_temp = id(min_heizung_temp).state;
368
369 // Min-Temperatur Check: Heizung muss mindestens min_temp haben
370 if (heizung < min_temp) {
371 id(heizung_luefter).turn_off();
372 return;
373 }
374
375 float diff = heizung - raum;
376
377 // Hysterese: 1.0°C zum Ausschalten, um Flackern zu vermeiden
378 // Zwischen threshold_off und threshold: Zustand beibehalten (Hysterese)
379 float threshold_off = threshold - 1.0;
380
381 if (diff < threshold_off) {
382 // Temperaturdifferenz zu gering -> Lüfter aus
383 id(heizung_luefter).turn_off();
384
385 } else if (diff >= threshold) {
386 // Temperaturdifferenz ausreichend -> Lüfter an
387 // Stufenlose Geschwindigkeitssteuerung: min_temp = 0%, max_temp = 100%
388 float max_temp = id(max_heizung_temp).state;
389 float speed_percent;
390
391 if (heizung < min_temp) {
392 speed_percent = 0.0;
393
394 } else if (heizung >= max_temp) {
395 speed_percent = 100.0;
396
397 } else {
398 // Lineare Interpolation zwischen min_temp und max_temp
399 speed_percent = ((heizung - min_temp) / (max_temp - min_temp)) * 100.0;
400 }
401
402 // Mindestens 25% Geschwindigkeit wenn eingeschaltet
403 if (speed_percent < 25.0 && speed_percent > 0.0) {
404 speed_percent = 25.0;
405 }
406
407 int speed_value = (int)speed_percent;
408 auto call = id(heizung_luefter).turn_on();
409 call.set_speed(speed_value);
410 call.perform();
411 }
3ddruck-parts3.png
1657.6 KB

heizungsbooster-pcb-back.jpg
831.5 KB

heizungsbooster-pcb.jpg
824.2 KB

im_gehaeuse_v2.jpg
393.7 KB

schaltplan.png
144.6 KB
thumb.png
155.7 KB