substitutions: # ----------------------- # Geräte-Identifikation # ----------------------- device_name: shys-heizungsbooster # Name des Geräts (z.B. "shys-heizungsbooster") device_friendly_name: SHYS Heizungsbooster # Anzeige-Name des Geräts (z.B. "SHYS Heizungsbooster") # ----------------------- # Sicherheit & Netzwerk # ----------------------- api_encryption_key: !secret api_encryption_key # API Encryption Key (z.B. "base64_encrypted_key_hier_eintragen==") ota_password: !secret ota_password # Passwort für den OTA Update (z.B. "InM2TlqVfJe4") ap_ssid: ${device_name}_AP # SSID für den Access Point (z.B. "shys-heizungsbooster_AP") ap_password: !secret ap_password # Passwort für den Access Point (z.B. "InM2TlqVfJe4") # ----------------------- # Lüfter Konfiguration # ----------------------- pin_fan: GPIO12 # Pin für Lüfter PWM Steuersignal fan_pwm_frequency: 25000 Hz # 4-Pol PC-Lüfter: 25000Hz // 3-Pol Lüfter mit Mosfet Schaltung: 1000Hz (bei Problemen 500-3000Hz testen) # --------------------------------- # Temperatur-Sensor Konfiguration # --------------------------------- pin_onewire_ds18b20: GPIO13 # Pin für One-Wire ds18b20_address_heizung: "0xd70122113b001828" # Adresse DS18B20 Heizung (aus ESPHome-Log auslesen) ds18b20_address_raum: "0xea0122113698f828" # Adresse DS18B20 Raumtemp (aus ESPHome-Log auslesen) raum_temp_entity: "sensor.raum_temperatur" # Raum Temperatur-Sensor in Home Assistant (wenn nicht gewünscht, dummy Eintrag stehen lassen!) # ---------------------- # Taster Konfiguration # ---------------------- pin_mode_button: GPIO14 # Pin für den Mode-Button (z.B. GPIO14) pin_set_button: GPIO16 # Pin für den Set-Button (z.B. GPIO16) pin_scl: GPIO5 # Pin für den SCL-Pin (z.B. GPIO5) pin_sda: GPIO4 # Pin für den SDA-Pin (z.B. GPIO4) pin_analog_in: ADC # Analoger Eingang für die Messung der Spannung am Lüfter (z.B. ADC1_0) # ----------------------- # Standardwerte (Initial Values) # ----------------------- initial_temp_threshold: "3.0" # Temperaturdifferenz zwischen Heizung und Raum, ab der der Lüfter eingeschaltet wird (z.B. 3°C) initial_min_heizung_temp: "30.0" # Mindesttemperatur der Heizung, unter der der Lüfter ausgeschaltet wird (z.B. 30°C) initial_max_heizung_temp: "50.0" # Maximale Heizungstemperatur, ab der der Lüfter mit 100% läuft (z.B. 50°C) initial_default_raum_temp: "21.0" # Fallback-Wert wenn kein Wert von HA oder DS18B20 verfügbar ist initial_manual_fan_speed: "50.0" # Manuelle Lüftergeschwindigkeit (für MANUAL-Modus) # ----------------------- # Timing # ----------------------- automatik_interval: 10s # Intervall für die automatische Steuerung (z.B. 10s) sensor_update_interval: 9s # Sollte etwas kürzer sein als automatik_interval # -------------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------------- # Konfiguration ENDE # -------------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------------- esphome: name: ${device_name} friendly_name: ${device_friendly_name} comment: Heizungsbooster zur besseren Wärmeverteilung im Raum. project: name: "smarthomeyourself.heizungsbooster" version: "1.0.0" esp8266: board: esp12e logger: api: encryption: key: ${api_encryption_key} ota: - platform: esphome password: ${ota_password} wifi: ssid: !secret wifi_ssid password: !secret wifi_password ap: ssid: ${ap_ssid} password: ${ap_password} captive_portal: one_wire: - platform: gpio pin: ${pin_onewire_ds18b20} output: - platform: esp8266_pwm pin: ${pin_fan} frequency: ${fan_pwm_frequency} id: pwm_output fan: - platform: speed output: pwm_output name: "Ventilator" id: heizung_luefter speed_count: 100 restore_mode: ALWAYS_OFF sensor: # Temperatur-Sensor Heizung (DS18B20 #1) - platform: dallas_temp name: "Heizkörper Temperatur (DS18B20 #1)" update_interval: ${sensor_update_interval} address: ${ds18b20_address_heizung} accuracy_decimals: 1 id: heizung_temp # Raumtemperatur-Sensor (DS18B20 #2) - Fallback wenn HA keinen Wert liefert - platform: dallas_temp name: "Raumtemperatur (DS18B20 #2)" update_interval: ${sensor_update_interval} address: ${ds18b20_address_raum} unit_of_measurement: "°C" accuracy_decimals: 1 id: raum_temp_ds18b20 # Raumtemperatur-Sensor aus HA - platform: homeassistant id: ha_raum_temp entity_id: ${raum_temp_entity} internal: true # Template Sensor: Raumtemperatur mit Priorität (HA > DS18B20 > Default) - platform: template name: "Raumtemperatur (Favorit)" id: raum_temp update_interval: ${sensor_update_interval} accuracy_decimals: 1 unit_of_measurement: "°C" lambda: |- // Priorität 1: Home Assistant Sensor if (id(ha_raum_temp).has_state()) { return id(ha_raum_temp).state; } // Priorität 2: DS18B20 Raumtemp-Sensor if (id(raum_temp_ds18b20).has_state()) { return id(raum_temp_ds18b20).state; } // Priorität 3: Default-Wert return id(default_raum_temp).state; number: # Threshold für Temperaturdifferenz (Heizung - Raum) zum Einschalten - platform: template name: "Temperatur-Schwellwert" id: temp_threshold min_value: 0.0 max_value: 10.0 step: 0.5 initial_value: ${initial_temp_threshold} optimistic: true restore_value: true # Minimale Heizungstemperatur (unter diesem Wert bleibt Lüfter aus) - platform: template name: "Minimale Heizungstemperatur" id: min_heizung_temp min_value: 20.0 max_value: 40.0 step: 1.0 initial_value: ${initial_min_heizung_temp} optimistic: true restore_value: true # Maximale Heizungstemperatur (ab diesem Wert läuft Lüfter mit 100%) - platform: template name: "Maximale Heizungstemperatur" id: max_heizung_temp min_value: 40.0 max_value: 80.0 step: 1.0 initial_value: ${initial_max_heizung_temp} optimistic: true restore_value: true # Default-Raumtemperatur (Fallback wenn weder HA noch DS18B20 verfügbar) - platform: template name: "Standard-Raumtemperatur" id: default_raum_temp min_value: 15.0 max_value: 30.0 step: 0.5 initial_value: ${initial_default_raum_temp} optimistic: true restore_value: true # Manuelle Lüftergeschwindigkeit (für MANUAL-Modus) - platform: template name: "Manuelle Lüftergeschwindigkeit" id: manual_fan_speed min_value: 0.0 max_value: 100.0 step: 10.0 initial_value: ${initial_manual_fan_speed} optimistic: true restore_value: true on_value: - script.execute: apply_manual_fan_speed select: # Interner Select für Betriebsmodus - platform: template id: fan_mode name: "Betriebsmodus" internal: false options: - "off" - "manual" - "auto" initial_option: "auto" optimistic: true restore_value: true on_value: - lambda: |- std::string mode = std::string(x); if (mode == "off") { // OFF: Lüfter ausschalten auto call = id(heizung_luefter).turn_off(); call.perform(); } else if (mode == "manual") { // MANUAL: Auf manuelle Geschwindigkeit setzen id(apply_manual_fan_speed).execute(); } else if (mode == "auto") { // AUTO: Automatik-Logik ausführen id(automatik_steuerung).execute(); } binary_sensor: # Mode-Button: Betriebsmodus wechseln (OFF -> MANUAL -> AUTO -> OFF) - platform: gpio pin: number: ${pin_mode_button} mode: INPUT_PULLUP inverted: true name: "Mode-Button" id: mode_button on_press: - script.execute: switch_mode # Set-Button: Geschwindigkeit im Manual-Modus ändern - platform: gpio pin: number: ${pin_set_button} inverted: true name: "Set-Button" id: set_button on_press: - script.execute: adjust_manual_speed interval: # Automatik-Steuerung - interval: ${automatik_interval} then: - script.execute: automatik_steuerung script: # Lüftergeschwindigkeit vom Number in den Fan übernehmen (nur im MANUAL-Modus) - id: apply_manual_fan_speed then: - lambda: |- // Nur im MANUAL-Modus anwenden std::string mode = id(fan_mode).current_option(); if (mode != "manual") { return; } int speed_value = (int)id(manual_fan_speed).state; if (speed_value < 1) { auto call = id(heizung_luefter).turn_off(); call.perform(); } else { auto call = id(heizung_luefter).turn_on(); call.set_speed(speed_value); call.perform(); } # Betriebsmodus wechseln: off -> manual -> auto -> off - id: switch_mode then: - lambda: |- std::string current_mode = id(fan_mode).current_option(); std::string new_mode; if (current_mode == "off") { new_mode = "manual"; } else if (current_mode == "manual") { new_mode = "auto"; } else { new_mode = "off"; } id(fan_mode).publish_state(new_mode); # Manuelle Geschwindigkeit in 25% Stufen ändern (0% -> 25% -> 50% -> 75% -> 100% -> 0%) - id: adjust_manual_speed then: - lambda: |- // Nur im MANUAL-Modus aktiv std::string mode = id(fan_mode).current_option(); if (mode != "manual") { return; } float current_speed = id(manual_fan_speed).state; float new_speed; if (current_speed < 12.5) { new_speed = 25.0; } else if (current_speed < 37.5) { new_speed = 50.0; } else if (current_speed < 62.5) { new_speed = 75.0; } else if (current_speed < 87.5) { new_speed = 100.0; } else { new_speed = 0.0; } id(manual_fan_speed).publish_state(new_speed); # Automatik-Steuerung: Lüfter basierend auf Temperaturdifferenz steuern - id: automatik_steuerung then: - lambda: |- // Nur im AUTO-Modus ausführen std::string mode = id(fan_mode).current_option(); if (mode != "auto") { return; } if (!id(heizung_temp).has_state() || !id(raum_temp).has_state()) { return; // Warten bis Sensoren Werte haben } float heizung = id(heizung_temp).state; float raum = id(raum_temp).state; float threshold = id(temp_threshold).state; float min_temp = id(min_heizung_temp).state; // Min-Temperatur Check: Heizung muss mindestens min_temp haben if (heizung < min_temp) { id(heizung_luefter).turn_off(); return; } float diff = heizung - raum; // Hysterese: 1.0°C zum Ausschalten, um Flackern zu vermeiden // Zwischen threshold_off und threshold: Zustand beibehalten (Hysterese) float threshold_off = threshold - 1.0; if (diff < threshold_off) { // Temperaturdifferenz zu gering -> Lüfter aus id(heizung_luefter).turn_off(); } else if (diff >= threshold) { // Temperaturdifferenz ausreichend -> Lüfter an // Stufenlose Geschwindigkeitssteuerung: min_temp = 0%, max_temp = 100% float max_temp = id(max_heizung_temp).state; float speed_percent; if (heizung < min_temp) { speed_percent = 0.0; } else if (heizung >= max_temp) { speed_percent = 100.0; } else { // Lineare Interpolation zwischen min_temp und max_temp speed_percent = ((heizung - min_temp) / (max_temp - min_temp)) * 100.0; } // Mindestens 25% Geschwindigkeit wenn eingeschaltet if (speed_percent < 25.0 && speed_percent > 0.0) { speed_percent = 25.0; } int speed_value = (int)speed_percent; auto call = id(heizung_luefter).turn_on(); call.set_speed(speed_value); call.perform(); }