-
Notifications
You must be signed in to change notification settings - Fork 40
8. Voorbeelden
- DAO leest de config, haalt, indien van toepassing, variabele "input" waarden uit HA en start de optimalisatieberekening.
- Na een geslaagde optimalisatie (in webinterface "Tabel" log file staat "Het programma heeft een optimale oplossing gevonden"), schrijft DAO de resultaten voor de eerstvolgende periode, in de HA "set" helpers.
- Om de DAO planning ook echt voor de komende periode uit te kunnen voeren zijn een of meerdere HA automations nodig die reageren op wijzingen in de "set" waarden b.v. start EV laden.
- Pas de DAO configuratie aan via DAO webinterface: Config -> JSON Editor; doe dit stap voor stap. Laat in het begin de scheduler uit.
- Eerst alleen met het ophalen van meteo en prijs gegevens --> test met debug run
Run Debug zet geen waardes door naar Home Assistant, "zonder debug" doet dat wel
- Voeg panelen toe --> test met debug run
- Voeg een machine of accu toe --> test met debug run
- etc. Zet de scheduler pas aan wanneer alles goed draait
- Eerst alleen met het ophalen van meteo en prijs gegevens --> test met debug run
- Maak de benodigde "input" en "set" helpers aan in Home Assistant (HA) (Settings -> Devices & Services -> Helpers -> + Create helper) en zorg ervoor dat ze een juiste waarde hebben
- Run DAO optimalisatieberekening met debug vanaf de DAO webinterface; dit valideert de "input" helpers. Controleer op eventuele fouten mbv de DAO Webpagina: Tabel view
- Run DAO optimalisatieberekening zonder debug vanaf de DAO webinterface; dit valideert de "set" of "output" helpers. Controleer de log file op eventuele fouten mbv de DAO webinterface: Tabel view
- Maak de benodigde automations aan in HA en test ze handmatig (Test Conditions & Run Actions). Let op, er moeten vaak niet alleen een actie worden gestart maar ook weer gestopt.
- Controleer of alles stabiel (blijft) draaien als de DAO optimalisatieberekeningen elke periode opnieuw worden gestart mbv de DAO scheduler
- Een of meerdere thuisbatterijen of gesimuleerde thuisbatterijen zoals https://github.com/hif2k1/battery_sim. Dit basis voorbeeld gebruikt een enkele 5.2 kWh Sessy batterij. https://www.sessy.nl/product/sessy/
- Een HA integratie voor de thuisbatterij zodat HA ermee kan communiceren om de DAO planning ook echt uit te voeren. Dit voorbeeld gebruikt https://github.com/PimDoos/ha-sessy/
- Let op: de gebruikte "efficiency" en "cycle cost" waarden zijn slechts initiele startwaarden.
De DAO configuratie gebruikt een enkele "input" HA sensor van de integratie:
- sensor.sessy_1_state_of_charge: Geeft de actuele SoC van de batterij door als input aan DAO
De DAO configuratie gebruikt 3 "set" HA helpers waarin DAO de planningsresultaten voor de volgende periode schrijft:
- input_select.dao_battery_set_operating_mode: DAO zet de waarde op "Aan" of "Uit"
- input_number.dao_battery_set_power_feedin: DAO schrijft met welk vermogen de Batterij moet laden (positief) of ontladen (negatief)
- input_boolean.dao_battery_set_balance_switch: DAO zet deze helper op "On" om "nul op de meter"/"NoM" mode in te schakelen; anders "Off"
βοΈ Click to expand DAO configuration details
"grid": { "max_power": 17.0, "entity_balance_switch": "input_boolean.dao_battery_set_balance_switch" }, "battery": [ { "name": "Sessy", "capacity": 5.2, "entity_actual_level": "sensor.sessy_1_state_of_charge", "lower_limit": 0.0, "upper_limit": 100.0, "charge_stages": [ { "power": 0.0, "efficiency": 1.0 }, { "power": 2200.0, "efficiency": 0.875 } ], "discharge_stages": [ { "power": 0.0, "efficiency": 1.0 }, { "power": 1700.0, "efficiency": 0.875 } ], "minimum_power": 500, "dc_to_bat_efficiency": 0.975, "bat_to_dc_efficiency": 0.975, "cycle_cost": 0.0, "entity_set_power_feedin": "input_number.dao_battery_set_power_feedin", "entity_set_operating_mode": "input_select.dao_battery_set_operating_mode", "reduce_power_low_soc": [], "reduce_power_high_soc": [], "solar": [] } ],
Dit zijn de drie "set" helpers die in HA moeten worden aangemaakt:
[η»ε:Image]Voor de "operating mode" kan het beste een input_select (Dropdown) helper worden gebruikt. Met de HA user interface kunnen eenvoudig de toegestane waarden voor deze helper (in dit geval de default opties "Aan" en "Uit") worden gedefinieerd.
[η»ε:Image]Een enkele automation volstaat in dit geval. Dit is, in pseudo code, wat er tenminste moet gebeuren:
- Als DAO Operating Mode = "Uit" dan zet Battery mode => Idle
- Als DAO Balance Switch = On dan zet Battery mode => NoM (de batterij past zelf elke paar seconden het setpoint aan afhankelijk van het actuele tekort of overschot aan vermogen)
- Als DAO Operating Mode = "Aan" en DAO Balance Switch = Off dan zet Battery mode => Api en het Battery Setpoint op de power feedin zoals door DAO berekend.
De automation gebruikt twee sensoren van de HA Battery integratie:
- select.sessy_1_power_strategy: Voor de keuze van de Idle, Nom of Api power mode
- number.sessy_1_power_setpoint: Voor het zetten van het (ont)laadvermogen Let op, Sessy gebruikt een negatief setpoint om te laden en een positief setpoint om te ontladen; dus wordt het door DAO berekende vermogen hier met -1 vermenigvuldigd.
π» Click to expand YAML Automation
alias: DAO_Battery_set_charge_discharge description: "" triggers: - trigger: state entity_id: - input_boolean.dao_battery_set_balance_switch - input_select.dao_battery_set_operating_mode - input_number.dao_battery_set_power_feedin conditions: [] actions: - if: - condition: state entity_id: input_select.dao_battery_set_operating_mode state: - Uit - condition: state entity_id: input_boolean.dao_battery_set_balance_switch state: - "off" then: - action: select.select_option metadata: {} target: entity_id: select.sessy_1_power_strategy data: option: idle - if: - condition: state entity_id: input_boolean.dao_battery_set_balance_switch state: - "on" then: - action: select.select_option metadata: {} target: entity_id: select.sessy_1_power_strategy data: option: nom - if: - condition: state entity_id: input_select.dao_battery_set_operating_mode state: - Aan - condition: state entity_id: input_boolean.dao_battery_set_balance_switch state: - "off" then: - action: select.select_option metadata: {} target: entity_id: select.sessy_1_power_strategy data: option: api - action: number.set_value metadata: {} data: value: "{{ -1.0 * (states('input_number.dao_battery_set_power_feedin') | float) }}" target: entity_id: number.sessy_1_power_setpoint mode: single
Dit is een basis dashboard om de voortgang van het laden/ontladen te kunnen volgen:
[η»ε:Image]Mocht het nodig zijn dan kan de HA gebruiker hier een of meerdere "set" waarden aanpassen en zo de resultaten van de DAO optimalisatieberekening tijdelijk overrulen.
| Strategie = "minimize cost" | Strategie = "minimize consumption" |
|---|---|
| [η»ε:Image] | [η»ε:Image] |
- Gebruik een Flex setting voor zowel de lower als de upper limit van de configuratie. Op deze manier kunnen deze waarden eenvoudig vanuit HA worden aangepast (handmatig via een dashboard of via een automation). De eerstvolgende DAO optimalisatieberekening zal dan deze gewijzigde waarden gebruiken zonder dat de DAO configuratie hoeft te worden aangepast. Wijzig hiervoor eenmalig de DAO configuratie en vervang:
βοΈ Click to expand DAO configuration details
... "lower_limit": 0.0, "upper_limit": 100.0, ...
βοΈ Click to expand DAO configuration details
... "lower_limit": "input_number.dao_battery_lower_limit", "upper_limit": "input_number.dao_battery_upper_limit", ...
En voeg deze nieuwe input helpers toe aan de inputs binnen het dashboard:
- Combineer meerdere identieke batterijen voor DAO in een enkele virtuele batterij. Dit vereenvoudigt de configuratie, minimaliseert het aantal benodigde HA helpers en automations en reduceert de rekentijden. Hier als voorbeeld een situatie met drie 5.2 kWh Sessy's. Wijzig hiervoor de DAO configuratie en vervang:
βοΈ Click to expand DAO configuration details
... "capacity": 5.2, "entity_actual_level": "sensor.sessy_1_state_of_charge", "charge_stages": [ { "power": 0.0, "efficiency": 1.0 }, { "power": 2200.0, "efficiency": 0.875 } ], "discharge_stages": [ { "power": 0.0, "efficiency": 1.0 }, { "power": 1700.0, "efficiency": 0.875 } ], ...
βοΈ Click to expand DAO configuration details
... "capacity": 15.6, "entity_actual_level": "sensor.sessy_COMBINED_state_of_charge", "charge_stages": [ { "power": 0.0, "efficiency": 1.0 }, { "power": 6600.0, // 3 * 2200 W "efficiency": 0.875 } ], "discharge_stages": [ { "power": 0.0, "efficiency": 1.0 }, { "power": 5100.0, // 3 * 1700 W "efficiency": 0.875 } ], ...
π Click to expand Jinja2 template
{% set soc1 = states('sensor.sessy_1_state_of_charge') | float %} {% set soc2 = states('sensor.sessy_2_state_of_charge') | float %} {% set soc3 = states('sensor.sessy_3_state_of_charge') | float %} {{ (soc1 + soc2 + soc3)/3 }}
π» Click to expand YAML Automation
... - action: select.select_option metadata: {} target: entity_id: - select.sessy_1_power_strategy - select.sessy_2_power_strategy - select.sessy_3_power_strategy data: option: api ...
π» Click to expand YAML Automation
... - action: number.set_value metadata: {} data: value: "{{ -1.0/3.0 * (states('input_number.dao_battery_set_power_feedin') | float) }}" target: entity_id: - number.sessy_1_power_setpoint - number.sessy_2_power_setpoint - number.sessy_3_power_setpoint ...
- Een HA integratie voor Zendure zodat HA ermee kan communiceren om de DAO planning ook echt uit te voeren. Voor 1 enkele batterij unit volstaat "Gielz" https://github.com/Gielz1986/Zendure-HA-zenSDK.
- Indien meerdere batterij units aanwezig zijn dan kan de "gast777-proxy" gebruikt worden om de verschillende units als 1 logische batterij te behandelen https://github.com/gast777/Zendure-zenSDK-proxy
| DAO "battery" | Sessy (5 kWh) | Zendure AC2400 |
|---|---|---|
| name | Sessy (3 x) | Zendure ( 3 x) |
| capacity | 15.6 | 24.0 |
| entity_actual_level | sensor.sessy_1_state_of_charge | sensor.zendure_total_state_of_charge |
| charge_status - power | 6600 | 7200 |
| discharge_status - power | 5100 | 7200 |
DAO zet de planning voor de eerst volgende periode in deze 3 HA "set" entiteiten:
- input_boolean.dao_battery_set_balance_switch (Modus)
- input_select.dao_battery_set_operating_mode (Modus)
- input_number.dao_battery_set_power_feedin (Setpoint)
De HA "DAO_Battery_set_charge_discharge" automation communiceert met de specifieke batterij integratie en zet de juiste waarden voor "Modus" en "Setpoint". In de actions van de automation moeten de Sessy entiteiten en opties voor Modus & Setpoint vervangen worden door de corresponderende Zendure entiteiten en opties.
| HA - Automation | Sessy | Zendure |
|---|---|---|
| Modus | select.sessy_1_power_strategy API Net Zero Idle
|
input_select.zendure_operation_mode Manual Smart Matching Standby
|
| Setpoint | number.sessy_1_power_setpoint (+) laden (-) is ontladen
|
input_number.zendure_manual_power (+) laden (-) is ontladen
|
| Sessy (deel van de automation yaml ) | Zendure (deel van de automation yaml) |
|---|---|
actions: - if: - condition: state entity_id: input_select.dao_battery_set_operating_mode state: - Uit - condition: state entity_id: input_boolean.dao_battery_set_balance_switch state: - "off" then: - action: select.select_option metadata: {} target: β
entity_id: select.sessy_1_power_strategy data: β
option: idle |
actions: - if: - condition: state entity_id: input_select.dao_battery_set_operating_mode state: - Uit - condition: state entity_id: input_boolean.dao_battery_set_balance_switch state: - "off" then: - action: select.select_option metadata: {} target: π entity_id: input_select.zendure_operation_mode data: π option: Standby |
- Een of meerdere Electrische Auto's. Dit basis voorbeeld gebruikt een enkel voertuig met een 80 kWh accu.
- Een laadpaal met een HA integratie zodat HA ermee kan communiceren om de DAO planning ook echt uit te voeren. Dit voorbeeld gebruikt EVCC https://evcc.io/en/ samen met de HA integration voor EVCC https://github.com/marq24/ha-evcc omdat het een groot aantal laadpalen direct en op een uniforme manier ondersteunt. De EVCC functionaliteit is enorm gegroeid in de afgelopen jaren. In dit voorbeeld wordt slechts een klein deel van deze functionaliteit gebruikt.
- Let op: de gebruikte "efficiency" waarden in de DAO configuratie zijn slechts initiele startwaarden.
De DAO configuratie gebruikt twee sensoren van de "laadpaal" integratie (laadpaal is hier ook de naam van de charger in de EVCC configuratie) en drie "input" HA helpers:
- binary_sensor.evcc_laadpaal_connected: "On" als de auto met de laadpaal is verbonden; anders "Off"
- sensor.evcc_laadpaal_vehicle_soc: Hiermee geeft de laadpaal de actuele SoC van de auto door als input aan DAO
- input_text.dao_ev_position_at_home: Vaste "home" waarde.
- input_number.dao_ev_charge_target_soc: Tot welk SoC percentage moet de auto geladen worden (het laaddoel)
- input_datetime.dao_ev_charge_ready_datetime: Op welk tijdstip moet dit laaddoel bereikt zijn
De DAO configuratie gebruikt 2 "set" HA helpers waarin DAO de planningsresultaten voor de volgende periode schrijft:
- input_number.dao_ev_set_charging_ampere: DAO schrijft hierin met hoeveel ampere de auto geladen moet worden
- input_boolean.dao_ev_charge_active_switch: DAO zet deze helper op "On" als de laadpaal ingeschakeld moet worden, anders "Off"
βοΈ Click to expand DAO configuration details
"electric_vehicle": [ { "name": "My EV", "capacity": 80.0, "entity_position": "input_text.dao_ev_position_at_home", "entity_actual_level": "sensor.evcc_laadpaal_vehicle_soc", "entity_plugged_in": "binary_sensor.evcc_laadpaal_connected", "charge_stages": [ { "ampere": 6.0, "efficiency": 0.90 }, { "ampere": 8.0, "efficiency": 0.90 }, { "ampere": 10.0, "efficiency": 0.90 }, { "ampere": 12.0, "efficiency": 0.90 }, { "ampere": 14.0, "efficiency": 0.90 }, { "ampere": 16.0, "efficiency": 0.90 } ], "charge_three_phase": true, "charge_scheduler": { "entity_set_level": "input_number.dao_ev_charge_target_soc", "level_margin": 0, "entity_ready_datetime": "input_datetime.dao_ev_charge_ready_datetime" }, "entity_set_charging_ampere": "input_number.dao_ev_set_charging_ampere", "charge_switch": "input_boolean.dao_ev_charge_active_switch" } ],
Dit zijn de drie "input" helpers die in HA moeten worden aangemaakt:
[η»ε:Image]In dit voorbeeld is voor "entity_position" een HA helper aangemaakt van het type input_text met de vaste waarde "home". Een input_select HA helper met de waarden "home" en "away" is in dit geval niet echt nodig. DAO gaat het laden pas inplannen als zowel "entity_position" = "home" als ook "entity_plugged_in" = "On". Door entity_position altijd op "home" te zetten gaat DAO het laden direct bij het volgende interval inplannen als de auto aan de laadpaal wordt gekoppeld.
Dit zijn de twee "set" helpers die in HA moeten worden aangemaakt:
[η»ε:Image]Een enkele automation, getriggerd door een wijziging van "dao_ev_charge_active_switch" of "dao_ev_set_charging_ampere", volstaat in dit geval. In pseudo code, is dit wat er tenminste moet gebeuren:
- Als "dao_ev_charge_active_switch" = "Off" dan zet Mode van de laadpaal ("select.evcc_laadpaal_mode") => "Off"
- Als "dao_ev_charge_active_switch" = "On" en "dao_ev_set_charging_ampere" tussen 6A & 16A dan zet Mode van de laadpaal ("select.evcc_laadpaal_mode") => "Fast" en de laadstroom op de bijbehorende waarde. De EVCC integratie voor de laadstroom biedt twee entiteiten: "select.evcc_laadpaal_min_current" en "select.evcc_laadpaal_max_current" met een lange lijst van text waarden waaronder 6A, 8A, 10A, 12A, 14A en 16A (helaas biedt EVCC dus geen mogelijkheid om direct een getalwaarde te gebruiken). Dit zorgt voor een fors aantal IF statements in de automatisering.
In dit voorbeeld wordt nog geen gebruik gemaakt van de EVCC mogelijkheid om te laden met een overschot aan zonneenergie ("select.evcc_laadpaal_mode" = "Solar" of "select.evcc_laadpaal_mode" = "Min+Solar").
De automation gebruikt 4 sensoren van de EVCC integratie:
- select.evcc_laadpaal_mode ("Off" of "Fast")
- number.evcc_laadpaal_limit_soc (krijgt de input waarde van "input_number.dao_ev_charge_target_soc"). Dit zorgt ervoor dat EVCC stopt met laden als het laaddoel is bereikt (vooral belangrijk in combinatie met mode "Solar" en "Min+Solar")
- select.evcc_laadpaal_min_current (wordt altijd op "6A" gezet)
- select.evcc_laadpaal_max_current (wordt afhankelijk van DAO planning op "6A", "8A", "10A", "12A", "14A" of "16A gezet)
| EVCC Modus | EVCC Max Current |
|---|---|
| [η»ε:Image] | [η»ε:Image] |
π» Click to expand YAML "DAO_MyEV_set_charge_on_off_and_ampere" Automation
alias: DAO_MyEV_set_charge_on_off_and_ampere description: "" triggers: - trigger: state entity_id: - input_boolean.dao_ev_charge_active_switch - trigger: state entity_id: - input_number.dao_ev_set_charging_ampere conditions: [] actions: - action: number.set_value metadata: {} target: entity_id: - number.evcc_laadpaal_limit_soc data: value: " {{ states('input_number.dao_ev_charge_target_soc')|float }}" - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_min_current data: option: "6" - if: - condition: state entity_id: input_boolean.dao_ev_charge_active_switch state: - "off" then: - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_mode data: option: "off" enabled: true - if: - condition: state entity_id: input_boolean.dao_ev_charge_active_switch state: - "on" - condition: numeric_state entity_id: input_number.dao_ev_set_charging_ampere below: 6.1 above: 0 then: - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_mode data: option: now - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_max_current data: option: "6" enabled: true - if: - condition: state entity_id: input_boolean.dao_ev_charge_active_switch state: - "on" - condition: numeric_state entity_id: input_number.dao_ev_set_charging_ampere below: 8.1 above: 6 then: - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_mode data: option: now - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_max_current data: option: "8" enabled: true - if: - condition: state entity_id: input_boolean.dao_ev_charge_active_switch state: - "on" - condition: numeric_state entity_id: input_number.dao_ev_set_charging_ampere below: 10.1 above: 8 then: - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_mode data: option: now - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_max_current data: option: "10" enabled: true - if: - condition: state entity_id: input_boolean.dao_ev_charge_active_switch state: - "on" - condition: numeric_state entity_id: input_number.dao_ev_set_charging_ampere below: 12.1 above: 10 then: - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_mode data: option: now - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_max_current data: option: "12" enabled: true - if: - condition: state entity_id: input_boolean.dao_ev_charge_active_switch state: - "on" - condition: numeric_state entity_id: input_number.dao_ev_set_charging_ampere below: 14.1 above: 12 then: - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_mode data: option: now - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_max_current data: option: "14" enabled: true - if: - condition: state entity_id: input_boolean.dao_ev_charge_active_switch state: - "on" - condition: numeric_state entity_id: input_number.dao_ev_set_charging_ampere above: 14 then: - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_mode data: option: now - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_max_current data: option: "16" enabled: true mode: single
Dit is een basis dashboard om de laadinstellingen en de planningsresultaten te kunnen volgen:
[η»ε:Image]Mocht het nodig zijn dan kan de HA gebruiker hier een of meerdere "set" waarden aanpassen en zo de resultaten van de DAO optimalisatieberekening tijdelijk overrulen.
| Strategie = "minimize cost" | Strategie = "minimize consumption" |
|---|---|
| [η»ε:Image] | [η»ε:Image] |
Laaddoel moet op dag+1 voor 19:00 bereikt zijn.
- minimize cost: het laden gebeurt met vol vermogen (16A) op de goedkoopste momenten
- minimize consumption: het laden gebeurt, voor zover mogelijk, met het verwachte PV overschot en aanvullend met maximaal vermogen op de goedkoopste momenten
Laden met overschot zonnestroom in combinatie met de "minimize consumption" optimization strategy
- DAO maakt weliswaar een mooie planning op basis van o.a. de voorspelde zonne-energie maar de realiteit is toch vaak net even anders; denk b.v. aan overdrijvende wolkenvelden.
- EVCC biedt de mogelijkheid om de laadstroom bijna continue (elke 30 seconden) aan te passen aan het actueel beschikbare OVERSCHOT aan (zonne)energie.
- Hiermee kan, gedurende een planningsinterval, energieteruglevering worden voorkomen bij extra zon en netgebruik worden voorkomen bij minder zon dan verwacht (NoM).
- Bij een voorbeeld PV installatie met een maximaal vermogen van ongeveer 7 kW kan maximaal 10A (zonne)laadstroom aan de EV worden geleverd als er geen andere stroomgebruikers actief zijn.
- Bij een door DAO geplande stroomvraag tot 10A kan EVCC nu dus in "Min+Solar" of "Solar" mode worden gebruikt. Bij een stroomvraag hoger dan 10A wordt dan nog steeds "Fast" mode + "Max Current" gebruikt (zie eerder). Bij mode = "Solar" kan het voorkomen dat het laden volledig wordt gestopt als het overschot aan zonne-energie onder de 4 kW komt. Bij mode = "Min+Solar" wordt er altijd met tenminste 4 kW / 6A geladen. Dit voorbeeld kiest voor mode = "Min+Solar".
- Bij de volgende optimalisatie zal DAO reageren op wat er feitelijk in de EV is geladen (via "entity_actual_level").
- Dit alles is vooral relevant na de afschaffing van de salderingsregeling en bij gebruik van de "minimize consumption" strategie.
π» Click to expand YAML "DAO_MyEV_set_charge_and_min+solar_where_applicable" Automation
alias: DAO_MyEV_set_charge_and_min+solar_where_applicable description: "" triggers: - trigger: state entity_id: - input_boolean.dao_ev_charge_active_switch - trigger: state entity_id: - input_number.dao_ev_set_charging_ampere conditions: [] actions: - action: number.set_value metadata: {} target: entity_id: - number.evcc_laadpaal_limit_soc data: value: " {{ states('input_number.dao_ev_charge_target_soc')|float }}" - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_min_current data: option: "6" - if: - condition: state entity_id: input_boolean.dao_ev_charge_active_switch state: - "off" then: - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_mode data: option: "off" enabled: true - if: - condition: state entity_id: input_boolean.dao_ev_charge_active_switch state: - "on" - condition: numeric_state entity_id: input_number.dao_ev_set_charging_ampere below: 6.1 above: 0 then: - if: - condition: state entity_id: input_select.dao_optimization_strategy state: - minimize cost then: - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_mode data: option: now - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_max_current data: option: "6" else: - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_mode data: option: minpv enabled: true - if: - condition: state entity_id: input_boolean.dao_ev_charge_active_switch state: - "on" - condition: numeric_state entity_id: input_number.dao_ev_set_charging_ampere below: 8.1 above: 6 then: - if: - condition: state entity_id: input_select.dao_optimization_strategy state: - minimize cost then: - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_mode data: option: now - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_max_current data: option: "8" else: - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_mode data: option: minpv enabled: true - if: - condition: state entity_id: input_boolean.dao_ev_charge_active_switch state: - "on" - condition: numeric_state entity_id: input_number.dao_ev_set_charging_ampere below: 10.1 above: 8 then: - if: - condition: state entity_id: input_select.dao_optimization_strategy state: - minimize cost then: - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_mode data: option: now - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_max_current data: option: "10" else: - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_mode data: option: minpv enabled: true - if: - condition: state entity_id: input_boolean.dao_ev_charge_active_switch state: - "on" - condition: numeric_state entity_id: input_number.dao_ev_set_charging_ampere below: 12.1 above: 10 then: - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_mode data: option: now - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_max_current data: option: "12" enabled: true - if: - condition: state entity_id: input_boolean.dao_ev_charge_active_switch state: - "on" - condition: numeric_state entity_id: input_number.dao_ev_set_charging_ampere below: 14.1 above: 12 then: - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_mode data: option: now - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_max_current data: option: "14" enabled: true - if: - condition: state entity_id: input_boolean.dao_ev_charge_active_switch state: - "on" - condition: numeric_state entity_id: input_number.dao_ev_set_charging_ampere above: 14 then: - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_mode data: option: now - action: select.select_option metadata: {} target: entity_id: - select.evcc_laadpaal_max_current data: option: "16" enabled: true mode: single
Bij een deel van de DAO gebruikers wordt OF het laden/ontladen van de Battery, OF het laden van de EV, door derden buiten DAO om gepland en uitgevoerd. Een paar voorbeelden:
- EV laden b.v. door Tibber-GridRewards,
- Battery laden/ontladen b.v. door FrankEnergy-Powerplay
- Etc.
Als derde partijen beide apparaten aansturen dan moet DAO dat natuurlijk niet ook nog doen. Het is in zo'n situatie zinvol om deze apparaten uit de DAO configuratie te halen en enkel de DAO reporting te gebruiken (gebruik eigen sensoren ipv de voorbeeld hieronder).
βοΈ Click to expand DAO configuration details
... "battery":[], ... "electric_vehicle": [], ... "report": { "entities_ev_consumption": [sensor.<EV_charged_energy>], "entities_battery_consumption": [sensor.<Battery_1_charged_energy>,sensor.<Battery_2_charged_energy>,...], "entities_battery_production": [sensor.<Battery_1_discharged_energy>,sensor.<Battery_2_discharged_energy>,...], }, ...
Als slechts 1 van beide apparaten door een derde partij wordt aangestuurd dan is het zinvol extra automatisering(en) toe te voegen om eventuele conflicten te voorkomen. Omdat DAO geen volledig beeld heeft van de situatie is het onduidelijk of beide apparaten tegelijk actief zijn. Hierbij een paar mogelijke voorbeeldsituaties waarbij het uitgangspunt is dat DAO de Battery aanstuurt en een derde partij de EV (omgekeerd kan natuurlijk net zo goed):
- Derde partij start/stopt met EV laden; wat te doen als Battery actief is?
- Battery start/stopt met laden/ontladen; wat te doen als EV actief is?
De keuze in dit voorbeeld is dat de Battery alleen tegelijk met de EV mag laden (b.v. omdat lokaal load balancing aanwezig is). Een eenvoudig plaatje laat zien welke STOP/START/RESTART situaties in zo'n situatie afgevangen moeten worden.
Er zijn verschillende mogelijkheden om binnen HA de laadstatus van een EV te achterhalen:
- via de EV integratie (Audi, BMW, Kia, ...)
- via de laadpaal integratie (EVCC, Zaptec, ...)
- via een aparte integratie met de derde partij (bv Tibber GridRewards) (https://github.com/JohNan/homeassistant-tibber_grid_rewards.git).
In dit voorbeeld is er vanuit gegaan dat, mbv de gekozen integratie, een zelf gedefinieerde "binary_sensor.EV_charging_state" op "On" /"Off" wordt gezet.
Uitbreiding (#1): Als EV laden extern wordt gestart, dan moet Battery ontladen worden gestopt. Voeg een nieuwe automatisering toe (naamgeving prefix "Guard" + "Battery" ipv "DAO" om duidelijk te maken dat deze automation tot doel heeft om de Battery te beschermen en niet door DAO wordt ge-triggerd:
π» Click to expand YAML "Guard_Battery_stop_discharge_when_EV_starts_charging" Automation
alias: Guard_Battery_stop_discharge_when_EV_starts_charging description: "" triggers: - trigger: state entity_id: - binary_sensor.ev_charging_state to: - "on" conditions: - condition: state entity_id: binary_sensor.guard_battery_ev_overlap_conflict state: - "on" actions: - action: input_select.select_option metadata: {} target: entity_id: input_select.dao_battery_set_operating_mode data: option: Uit - action: input_boolean.turn_off metadata: {} target: entity_id: input_boolean.dao_battery_balance_switch2 data: {} mode: single
Uitbreiding (#2): Als EV laden stopt, moet Battery aansturing opnieuw worden ge-triggered. Voeg een tweede "Guard" automation toe die de bestaande DAO automation aanroept (op deze manier blijven de automations zo veel mogelijk onafhankelijk van elkaar).
π» Click to expand YAML "Guard_Battery_restart_discharging_when_EV_stops_charging" Automation
alias: Guard_Battery_restart_discharging_when_EV_stops_charging description: "" triggers: - trigger: state entity_id: - binary_sensor.ev_charging_state to: - "off" conditions: [] actions: - action: automation.trigger metadata: {} target: entity_id: - automation.dao_sessy_set_charge_discharge data: skip_condition: false mode: single
Uitbreiding (#3): Battery ontladen mag niet worden gestart als EV laden actief is.
In dit voorbeeld is er voor gekozen om een enkele binary template sensor (binary_sensor.guard_battery_ev_overlap_conflict) te definiΓ«ren met daarin de (mogelijk vrij complexe) logica die bepaalt of er wel of niet een conflict is. In de automation(s) hoeft dan slechts 1 conditie (wel of geen conflict) toegevoegd te worden.
Guard_battery_ev_overlap_conflict template sensor:
π Click to expand Jinja2 template
{% set ev_charging = states('binary_sensor.ev_charging_state') %} {% if ev_charging in ["unavailable"] %} {% set ev_charging = "off" %} {% endif %} {% set balancing = states('input_boolean.dao_battery_balance_switch') %} {% if balancing in ["unavailable"] %} {% set balancing = "off" %} {% endif %} {% set battery_mode = states('input_select.dao_battery_set_operating_mode') %} {% if battery_mode in ["unavailable"] %} {% set battery_active = "off" %} {% else %} {% set battery_active = (battery_mode in ["Aan"]) %} {% endif %} {% set infeed = states('input_number.dao_battery_set_power_feedin') %} {% if infeed in ["unavailable"] %} {% set battery_discharging = false %} {% else %} {% set battery_discharging = (infeed|float) < -100 %} {% endif %} {% if (ev_charging|bool) and (balancing|bool) %} {{ true }} {% elif (ev_charging|bool) and (battery_active|bool) and (battery_discharging|bool) %} {{ true }} {% else %} {{ false }} {% endif %}
Aan de bestaande DAO automation hoeft dan slechts een conditie te worden toegevoegd:
π» Click to expand YAML Automation
... conditions: - condition: state entity_id: binary_sensor.guard_battery_ev_overlap_conflict state: - "off" ...
βοΈ Click to expand DAO configuration details
... "interval": "15min", "strategy": "input_select.dao_optimization_strategy", "max_gap": 0.005, "notifications": { "notification_entity": "input_text.dao_notification_message", "opstarten": true, "berekening": true, "last_activity_entity": "input_datetime.dao_optimization_last_activity" }, ...
Mocht er incidenteel een keer iets fout gaan in de DAO berekening dan helpt het als je daarover een notificatie op je telefoon krijgt of, indien mogelijk, HA daar direct op kan laten reageren. DAO schrijf meldingen in de HA "notification_entity" helper als de bijhorende opties in de configuratie zijn aangezet (zie configuration details hierboven). Enkele voorbeelden (niet uitputtend) van zulke meldingen:
- DAO calc afgerond 30-07-2026 13:15:25
- fout: Er is een fout opgetreden, zie de fout-tracering
- waarschuwing: Geen oplossing voor: minimize consumption
Als voorbeeld volgt hier een eerste automation die een notificatie stuurt naar een telefoon indien de melding een fout of waarschuwing (alles andere dan "calc afgerond") bevat:
π» Click to expand YAML "DAO_Calculation_error" Automation
alias: DAO_Calculation_error description: "" triggers: - trigger: template value_template: |- {% set dao_message = states('input_text.dao_notification_message') %} {% set words = dao_message.split(' ') %} {% if words[1] in ["calc"] and words[2] in ["afgerond"] %} {{ 'false' }} {% else %} {{ 'true' }} {% endif %} conditions: [] actions: - action: notify.send_message metadata: {} target: entity_id: notify.my_notifications_group data: message: "\"{{ states('input_text.dao_notification_automation') }}\"" title: DAO Notification mode: single
Hierbij is my_notifications_group een HA helper van het type (Group -> Notify group) met daarin een lijst van alle devices (telefoon(s), tablet(s), PCs, ...) die gebruik maken van de HA Mobile App en waar de notificatie naar toe moet worden gestuurd. Het gebruik van de group maakt het eenvoudig om devices toe te voegen (of weg te halen) zonder een groot aantal automations te moeten wijzigen.
Als je als strategy primair kiest voor "minimize consumption" komt het soms voor dat DAO geen oplossing vindt. Je krijgt dan een notificatie met een waarschuwing. Als je daar een automation aanhangt kun je je strategy omzetten naar "minimize cost" en via een rest-commando de berekening opnieuw uit laten voeren. Natuurlijk kan er ook nog een melding worden gestuurd naar de telefoon zodat het gebrurik van deze alternatieve strategy als "backup" niet onopgemerkt blijft.
π» Click to expand YAML "DAO_notification_no_solution_for_minimize_consumption" Automation
alias: DAO_notification_no_solution_for_minimize_consumption description: "" triggers: - trigger: template value_template: "{% set dao_message = states('input_text.dao_notification_message') %}\n{% set words = dao_message.split(' ') %}\n{% if words[1] in [\"Geen\"] and words[2] in [\"oplossing\"] and words[4] in [\"minimize\"] and words[5] in [\"consumption\"] %}\n\t {{ 'false' }}\n\t{% else %}\n\t {{ 'true' }}\n\t{% endif %}" conditions: [] actions: - action: input_select.select_option metadata: {} target: entity_id: input_select.dao_optimization_strategy data: option: minimize cost - action: rest_command.start_dao_calc metadata: {} data: {} mode: single
Hiervoor moet wel eerst het "start_dao_calc" rest_command in de configuration.yaml file van HA worden gedefinieerd; uiteraard met de juiste DAO URL (IP address en port nummer)
rest_command: start_dao_calc: url: http://192.168.1.1:5000/api/run/calc_zonder_debug verify_ssl: false
Incidenteel kan het gebeuren dat een DAO run volledig faalt en zelfs geen notificatie meldingen geeft. Dit hoeft helemaal niet door DAO veroorzaakt te worden. Toch is ook in zo'n geval een melding op de telefoon van grote waarde. Een simpele manier om zo'n situatie te detecteren is door gebruik te maken van een HA timer helper (hier: timer.dao_last_activity_timer) met een duur van 20 minuten (ruim langer dan het "15min" interval en de optie "Restore date and time when HA starts" actief). Hierbij worden twee HA automations gebruikt. De eerste om de timer steeds opnieuw te starten nadat DAO een berekening succesvol heeft afgerond, en de tweede om een melding op de telefoon te geven als de timer afloopt (geen succesvolle berekening binnen 20 minuten).
π» Click to expand YAML "DAO_Reset_timer_after_successful_calculation" Automation
alias: DAO_Reset_timer_after_successful_calculation description: "" triggers: - trigger: state entity_id: - input_datetime.dao_optimization_last_activity conditions: [] actions: - action: timer.start metadata: {} target: entity_id: timer.dao_last_activity_timer data: {} mode: single
π» Click to expand YAML "DAO_Last_activity_timer_ran_out" Automation
alias: DAO_Last_activity_timer_ran_out description: "" triggers: - trigger: time_pattern minutes: /15 conditions: - condition: state entity_id: timer.dao_last_activity_timer state: - idle actions: - action: notify.send_message metadata: {} target: entity_id: notify.my_notifications_group data: title: DAO Notification message: Last calculation more than 20 minutes ago mode: single
Tenslotte nog een laatste notificatie voor de situatie waarin DAO het opladen van de EV (nog) niet heeft ingepland omdat het opgegeven eindtijdstip voorbij de planningshorizon ligt omdat er nog prijzen ontbreken. DAO geeft hiervoor zelf enkel een melding in de log file maar schrijft dit niet in de HA helper. Toch is deze situatie relatief eenvoudig te detecteren. Deze automation die elke 15 minuten wordt getrigger-ed gebruikt een DAO rest-commando om het laatste tijdstip te bepalen waarvoor DAO nog day ahead prijzen heeft en checkt vervolgens of dit voor het tijdstip is waarop de EV klaar moet zijn met laden. Als dat het geval is wordt een melding naar de telefoon gestuurd (een andere mogelijkheid is om het "EV klaar met laden" tijdstip eventueel naar voren te trekken). De extra conditie die checkt of de EV aan de laadpaal hangt is enkel toegevoegd voor de performance en dient om het aantal onnodige API calls te beperken.
π» Click to expand YAML "DAO_EV_notification_on_missing_spot_prices" Automation
alias: DAO_EV_notification_on_missing_spot_prices description: "" triggers: - trigger: time_pattern minutes: /15 conditions: - condition: state entity_id: binary_sensor.dao_ev_vehicle_connected state: - "on" actions: - action: rest_command.query_dao_da_vandaag_en_morgen metadata: {} data: {} response_variable: da_prices - if: - condition: template value_template: >- {% set list_length = da_prices.content.data | list | length %} {% set horizon_end_time = da_prices.content.data[list_length-1].time | as_datetime | as_local %} {% set charge_end_time = states('input_datetime.dao_ev_ready_datetime') | as_datetime | as_local %} {% if horizon_end_time < charge_end_time %} {{ 'true' }} {% else %} {{ 'false' }} {% endif %} then: - action: notify.send_message metadata: {} target: entity_id: notify.my_notifications_group data: message: EV planning is on hold due to missing spot prices title: DAO Notification mode: single
Ook hiervoor moet wel eerst het "query_dao_da_vandaag_en_morgen" rest_command in de configuration.yaml file van HA worden gedefinieerd; wederom met de juiste DAO URL (IP address en port nummer)
rest_command: query_dao_da_vandaag_en_morgen: url: http://192.168.1.1:5000/api/report/da/vandaag_en_morgen verify_ssl: false