From ec85c805a200df78eb13ea64433080b694032de0 Mon Sep 17 00:00:00 2001 From: Sam Geyskens Date: Sat, 18 Apr 2026 23:58:22 +0200 Subject: [PATCH] Add slimme_warmtebron_sturing.yaml --- slimme_warmtebron_sturing.yaml | 331 +++++++++++++++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 slimme_warmtebron_sturing.yaml diff --git a/slimme_warmtebron_sturing.yaml b/slimme_warmtebron_sturing.yaml new file mode 100644 index 0000000..97c49ef --- /dev/null +++ b/slimme_warmtebron_sturing.yaml @@ -0,0 +1,331 @@ +# blueprints/automation/slimme_warmtebron_sturing.yaml + +blueprint: + name: Slimme Warmtebron Sturing (Airco / Gas + Koeling) + description: > + Schakel automatisch tussen airco (warmtepomp) en gasverwarming op basis van + nettovermogen en een zelf te kiezen temperatuursensor. Ondersteunt verwarmen, + koelen én automatische seizoenswisseling. Inclusief hysterese. + domain: automation + input: + + # ── Bedrijfsmodus ────────────────────────────────────────────────────────── + operation_mode: + name: Bedrijfsmodus + description: > + Verwarmen: alleen verwarmingslogica actief. + Koelen: alleen koellogica actief. + Automatisch: verwarm als temp onder doel, koel als temp boven doel. + default: "auto" + selector: + select: + options: + - label: "🔥 Verwarmen" + value: "heating" + - label: "❄️ Koelen" + value: "cooling" + - label: "🔄 Automatisch" + value: "auto" + + # ── Vermogen ─────────────────────────────────────────────────────────────── + power_sensor: + name: Nettovermogen sensor + description: > + Sensor in Watt. Negatief = injectie naar net (zonne-overschot), + positief = afname van net. + selector: + entity: + domain: sensor + device_class: power + + solar_surplus_threshold: + name: Zonne-overschot drempel – verwarmen (W) + description: > + Minimale injectie (absoluut) vooraleer de airco als warmtebron gekozen + wordt boven gas. Bv. 500 = airco start bij ≥ 500 W injectie. + default: 500 + selector: + number: + min: 0 + max: 5000 + step: 50 + unit_of_measurement: "W" + mode: slider + + grid_threshold: + name: Netstroom drempel → gasverwarming (W) + description: > + Afname boven deze waarde schakelt over naar gas (goedkoper bij hoge + elektriciteitsprijs). Stem af op actuele gas/elektriciteitsverhouding. + default: 1000 + selector: + number: + min: 0 + max: 5000 + step: 50 + unit_of_measurement: "W" + mode: slider + + solar_surplus_threshold_cooling: + name: Zonne-overschot drempel – koelen (W) + description: > + Minimale injectie om de airco in koelmodus te starten. Zet lager dan + de verwarmingsdrempel want koelen verbruikt doorgaans minder. + Bv. 300 W. + default: 300 + selector: + number: + min: 0 + max: 5000 + step: 50 + unit_of_measurement: "W" + mode: slider + + cool_on_grid: + name: Koelen ook bij netstroom? + description: > + Er is geen alternatief voor de airco bij koeling. Als dit aan staat, + koelt de airco ook wanneer er stroom van het net wordt afgenomen. + Zet uit als je stroomkosten wilt vermijden en hitte verdraagbaar is. + default: true + selector: + boolean: + + cool_grid_threshold: + name: Max. netstroom bij koelen (W) + description: > + Enkel zichtbaar als "Koelen ook bij netstroom" aan staat. Boven deze + netstroom wordt koeling onderdrukt (piekuur-logica). 0 = geen limiet. + default: 2000 + selector: + number: + min: 0 + max: 6000 + step: 50 + unit_of_measurement: "W" + mode: slider + + # ── Temperatuur ──────────────────────────────────────────────────────────── + temperature_sensor: + name: Temperatuursensor (referentie) + description: > + Gebruik bij voorkeur de Tado wandthermostaat — de airco-sensor leest + doorgaans 1–2 °C hoger door stralingswarmte van de unit. + selector: + entity: + domain: sensor + device_class: temperature + + target_temperature: + name: Doeltemperatuur (°C) + default: 20 + selector: + number: + min: 10 + max: 30 + step: 0.5 + unit_of_measurement: "°C" + mode: slider + + hysteresis: + name: Hysterese (°C) + description: > + Marge rond de doeltemperatuur om pendelen te voorkomen. + Verwarming start onder (doel − hysterese), koeling boven (doel + hysterese). + default: 0.5 + selector: + number: + min: 0.1 + max: 3 + step: 0.1 + unit_of_measurement: "°C" + + # ── Klimaatentiteiten ────────────────────────────────────────────────────── + airco_climate: + name: Airco (climate entiteit) + selector: + entity: + domain: climate + + tado_climate: + name: Tado gasverwarming (climate entiteit) + selector: + entity: + domain: climate + + tado_off_temperature: + name: Tado rusttemperatuur (°C) + description: > + Temperatuur die Tado krijgt wanneer gas niet nodig is (vorstbeveiliging). + Tado gaat zelden echt "uit" — stel dit laag in (bv. 5 °C). + default: 5 + selector: + number: + min: 5 + max: 15 + step: 0.5 + unit_of_measurement: "°C" + +# ── Variabelen ───────────────────────────────────────────────────────────────── +variables: + _power_sensor: !input power_sensor + _temp_sensor: !input temperature_sensor + _solar_heat: !input solar_surplus_threshold + _grid_thresh: !input grid_threshold + _solar_cool: !input solar_surplus_threshold_cooling + _cool_on_grid: !input cool_on_grid + _cool_grid_max: !input cool_grid_threshold + _target: !input target_temperature + _hyst: !input hysteresis + _tado_off: !input tado_off_temperature + _mode: !input operation_mode + + current_power: "{{ states(_power_sensor) | float(0) }}" + current_temp: "{{ states(_temp_sensor) | float(0) }}" + + # Verwarmingslogica + needs_heat: "{{ current_temp < (_target | float - _hyst | float) }}" + solar_heat_ok: "{{ current_power <= (_solar_heat | float * -1) }}" + grid_high: "{{ current_power >= (_grid_thresh | float) }}" + + # Koelingslogica + needs_cool: "{{ current_temp > (_target | float + _hyst | float) }}" + solar_cool_ok: "{{ current_power <= (_solar_cool | float * -1) }}" + grid_cool_ok: > + {{ _cool_on_grid and + (_cool_grid_max == 0 or current_power < _cool_grid_max | float) }} + + # Gecombineerde modus checks + do_heat: > + {{ ((_mode == 'heating') or (_mode == 'auto' and needs_heat)) + and not needs_cool }} + do_cool: > + {{ ((_mode == 'cooling') or (_mode == 'auto' and needs_cool)) + and not needs_heat }} + at_target: > + {{ current_temp >= (_target | float - _hyst | float) and + current_temp <= (_target | float + _hyst | float) }} + +# ── Trigger ──────────────────────────────────────────────────────────────────── +trigger: + - platform: time_pattern + minutes: "/5" + - platform: state + entity_id: !input temperature_sensor + +mode: single +max_exceeded: silent + +# ── Acties ───────────────────────────────────────────────────────────────────── +action: + - choose: + + # ── VERWARMEN ───────────────────────────────────────────────────────────── + + # V1: Genoeg zonne-overschot → airco verwarmt, Tado op rust + - conditions: + - condition: template + value_template: "{{ do_heat and solar_heat_ok }}" + sequence: + - service: climate.set_hvac_mode + target: + entity_id: !input airco_climate + data: + hvac_mode: "heat" + - service: climate.set_temperature + target: + entity_id: !input airco_climate + data: + temperature: "{{ _target }}" + - service: climate.set_temperature + target: + entity_id: !input tado_climate + data: + temperature: "{{ _tado_off }}" + + # V2: Te veel netstroom → gas verwarmt, airco uit + - conditions: + - condition: template + value_template: "{{ do_heat and grid_high }}" + sequence: + - service: climate.set_hvac_mode + target: + entity_id: !input airco_climate + data: + hvac_mode: "off" + - service: climate.set_temperature + target: + entity_id: !input tado_climate + data: + temperature: "{{ _target }}" + + # ── KOELEN ──────────────────────────────────────────────────────────────── + + # K1: Koelen met zonne-overschot → airco koel modus + - conditions: + - condition: template + value_template: "{{ do_cool and solar_cool_ok }}" + sequence: + - service: climate.set_temperature + target: + entity_id: !input tado_climate + data: + temperature: "{{ _tado_off }}" + - service: climate.set_hvac_mode + target: + entity_id: !input airco_climate + data: + hvac_mode: "cool" + - service: climate.set_temperature + target: + entity_id: !input airco_climate + data: + temperature: "{{ _target }}" + + # K2: Koelen zonder overschot maar netstroom toegestaan + - conditions: + - condition: template + value_template: "{{ do_cool and not solar_cool_ok and grid_cool_ok }}" + sequence: + - service: climate.set_temperature + target: + entity_id: !input tado_climate + data: + temperature: "{{ _tado_off }}" + - service: climate.set_hvac_mode + target: + entity_id: !input airco_climate + data: + hvac_mode: "cool" + - service: climate.set_temperature + target: + entity_id: !input airco_climate + data: + temperature: "{{ _target }}" + + # K3: Koelen gewenst maar te duur / uitgeschakeld → airco uit, wachten + - conditions: + - condition: template + value_template: "{{ do_cool and not solar_cool_ok and not grid_cool_ok }}" + sequence: + - service: climate.set_hvac_mode + target: + entity_id: !input airco_climate + data: + hvac_mode: "off" + + # ── DOELTEMPERATUUR BEREIKT → alles op minimum ──────────────────────────── + - conditions: + - condition: template + value_template: "{{ at_target }}" + sequence: + - service: climate.set_hvac_mode + target: + entity_id: !input airco_climate + data: + hvac_mode: "off" + - service: climate.set_temperature + target: + entity_id: !input tado_climate + data: + temperature: "{{ _tado_off }}" \ No newline at end of file