Gasloos 2019 + WP Panasonic H-serie 7kW + 300 liter boilervat + PV 12.415Wp + Home Assistant + Hyundai Ioniq 6 First Edition + Zaptec laadpaal
Ik wil vandaag of morgen mijn setup met Marstek batterijen even beschrijven. Zal proberen ook de door jou gevraagde informatie erbij te zetten.
Zoals @Torch1969 ook al zei: het zit er (nog) niet in, maar ik zie (net als @Torch1969) wel een markt voor tweakers met een vast contract, waarbij of de kosten of de levering worden geminimaliseerd.vincent_1971 schreef op donderdag 7 mei 2026 @ 11:09:
Ben me er zelf hier aan het "inlezen" Waar ik nog niet echt uitkom is wat als je een vast contract hebt ( eneco 1 jaar )?
Is er een mogelijk om met vaste tarieven het een en ander in te stellen?
Heb zelf zonnepanelen, vloerverwarming, airco's en ook straks een warmtepompboiler.
Ik neem het mee als "gewenste" feature.
WP: Alpha Innotec MSW2-6S | PV: 20 x 300 Wp AEG | ACCU: 2x16x280Ah LiFePO4 3 x Multiplus II 48/3000 | DYN: Tibber | Gasloos | Day Ahead Optimizer
Ik heb het probleem van het schrijven van de berekende "feedin" richting de thuisbatterij als volgt opgelost:
DAO schrijft ieder kwartier de berekende feedin naar een eerste helper: input_number.dao_setpoint_feedin_ess
Ik heb een tweede helper gemaakt:
input_number.calculated_setpoint_feedin_ess
Zodra de eerste helper wijzigt (alleen door DAO meestal eens per kwartier) triggert die een automation die de waarde van helper 1 doorzet naar helper 2.
Als DAO dan ook nog "nul op de meter" wil (input_boolean.balanceer_grid) dan zet deze de pid-regelaar aan en die neemt als startwaarde de door DAO berekende feedin (van helper 1)
De output van de pid-regelaar gaat iedere seconde naar helper 2.
Ik heb ook nog twee beveiligingen draaien (boven op de beveiliging van mijn bms) die de feedin van mijn thuisbatterij beperkt als de thuisbatterij kritieke spanningsniveaus nadert. Die berekende beperkingen worden (nu nog) ook weggeschreven naar helper 2 omdat (nu nog) zowel pid als de beperkingen bijna nooit beide tegelijk actief zijn.
Ik ga dat voor 1 januari a.s. wel uitsplitsen omdat ik verwacht dat volgende jaar het systeem heel vaak NOM gaat draaien en dan ook in de buurt gaat komen van kritieke spanningsniveaus.
Over cycle-cost.
Die staan bij mij op 0.01 en die zijn veel lager dan mijn afschrijvingskosten (berekend over 5 jaar). Mijn batterij slijt nauwelijks omdat mijn laad-/ontlaadvermogen altijd minder is dan 0,2C en ik de batterij daarmee nauwelijks thermisch belast. Het spul draait nu 4 jaar en ik heb nog geen afname van capaciteit mogen constateren.
Maar ga je met laden en ontladen wel harder dan 0,2 C dan moet je misschien wel afschrijven op je batterij omdat je ze dan wel degelijk "flink aan de tand voelt".
WP: Alpha Innotec MSW2-6S | PV: 20 x 300 Wp AEG | ACCU: 2x16x280Ah LiFePO4 3 x Multiplus II 48/3000 | DYN: Tibber | Gasloos | Day Ahead Optimizer
Ik heb een Home Assistant package gemaakt waarin ik al mijn (generieke) helpers, automations en scripts heb gemaakt.
https://gist.github.com/fbloemhof/ded1c1dcfd797d11e4b61e66c101e4f0
Denk er aan dat je op regel 19 je eigen notify target invult en op regel 1170 het IP adres van DAO invult.
Ik heb hiernaast nog een andere file waarin ik wat persoonlijkere config heb, specifieker voor mijn setup.
In de DAO configuratie heb ik dan mijn battery als volgt geconfigureerd:
De keten is dan: DAO run past input_boolean.dao_battery_balance_mode en/of input_number.dao_battery_power_feedin aan, wat vervolgens automation.dao_marstek_battery_bridge zal triggeren. Die automation roept vervolgens script.marstek_control aan die de daadwerkelijke batterijen aanstuurt. Mijn batterijen hebben zelf een PID meter (in dit topic geleerd) en die kunnen daarmee prima zelf NOM aanhouden.JSON:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 "battery": [ { "name": "Marstek", "capacity": 10.4, "entity_actual_level": "sensor.dao_battery_soc_combined", "entity_set_power_feedin": "input_number.dao_battery_power_feedin", "entity_stop_inverter": "input_datetime.dao_battery_stop", "entity_set_operating_mode": "input_select.dao_battery_operating_mode", "entity_balance_switch": "input_boolean.dao_battery_balance_mode", "upper_limit": 100, "lower_limit": 11, "charge_stages": [ { "power": 0, "efficiency": 1.0 }, { "power": 200, "efficiency": 0.90 }, { "power": 1000, "efficiency": 0.95 }, { "power": 2400, "efficiency": 0.96 }, { "power": 3000, "efficiency": 0.94 } ], "discharge_stages": [ { "power": 0, "efficiency": 1.0 }, { "power": 200, "efficiency": 0.90 }, { "power": 1000, "efficiency": 0.95 }, { "power": 2400, "efficiency": 0.96 }, { "power": 3000, "efficiency": 0.94 } ], "minimum_power": 50, "dc_to_bat_efficiency": 0.93, "bat_to_dc_efficiency": 0.93, "cycle_cost": 0.025 } ],
Er zit, nu nog eens bekeken, toch wel wat specifieke dingen van mij in de package, ik houd bijvoorbeeld ook rekening met het laden van mijn EV. Ook heb ik momenteel wat gedonder met 1 van mijn 3 accu's, dus die is grotendeels uitgezonderd in de sensoren/automations.
Er zit ook allemaal voorbereiding in voor machines, die ik nog helemaal niet heb.
Ik begon hieraan met de ambitie een zo generiek mogelijke file te maken die mogelijk opgenomen kan worden in de DAO wiki, maar ik denk dat ik bij nader inzien dit beter in losse packages ("modules") kan gaan gieten zodat je kunt kiezen wat je wel/niet wilt hebben.
Ik heb zoveel mogelijk generieke naamgeving aangehouden (alles begint altijd met DAO) en ook opmaak en comments zo overzichtelijk mogelijk gehouden, maar het is een hoop avonduurtjes pielerij dus er sluipt ook wel eens wat luiheid doorheen.
[ Voor 3% gewijzigd door Beekforel op 08-05-2026 08:06 ]
ja is herkenbaar heBeekforel schreef op donderdag 7 mei 2026 @ 19:02:
Misschien wat minder ChatGPT gebruiken @hemertje, je eigen reacties beginnen ook aardig AI te lijken.
Ik wil vandaag of morgen mijn setup met Marstek batterijen even beschrijven. Zal proberen ook de door jou gevraagde informatie erbij te zetten.
ik gebruik Claude Code voor men reis door Home Assistant...
Gasloos 2019 + WP Panasonic H-serie 7kW + 300 liter boilervat + PV 12.415Wp + Home Assistant + Hyundai Ioniq 6 First Edition + Zaptec laadpaal
Hoi, dankjewel voor deze informatie!Beekforel schreef op donderdag 7 mei 2026 @ 21:41:
@hemertje bij deze.
Ik heb een Home Assistant package gemaakt waarin ik al mijn (generieke) helpers, automations en scripts heb gemaakt. https://gist.github.com/f...75396a57c84c1b2313f59626f
ik krijg een 404 foutmelding op je Github link
@Bravo ik lees in je handtekening dat ook jij in een prachtige EV mag rijden
hoe voorkom jij dat je wanneer je de EV laad je de kWh uit je thuisbatterijen haalt?
Gasloos 2019 + WP Panasonic H-serie 7kW + 300 liter boilervat + PV 12.415Wp + Home Assistant + Hyundai Ioniq 6 First Edition + Zaptec laadpaal
Oeps, heb delink gerepareerd.hemertje schreef op donderdag 7 mei 2026 @ 22:03:
[...]
Hoi, dankjewel voor deze informatie!
ik krijg een 404 foutmelding op je Github link
@Bravo ik lees in je handtekening dat ook jij in een prachtige EV mag rijden![]()
hoe voorkom jij dat je wanneer je de EV laad je de kWh uit je thuisbatterijen haalt?
Ik laad mijn EV overigens niet met DAO, dat laat ik over aan Tibber. Die knalt er dus wel doorheen maar DAO gaat daar goed mee om.
helaas nog steeds een 404 op https://gist.github.com/fbloemhof/ac5943a75396a57c84c1b2313f59626fBeekforel schreef op donderdag 7 mei 2026 @ 22:08:
[...]
Oeps, heb delink gerepareerd.
Ik laad mijn EV overigens niet met DAO, dat laat ik over aan Tibber. Die knalt er dus wel doorheen maar DAO gaat daar goed mee om.
Gasloos 2019 + WP Panasonic H-serie 7kW + 300 liter boilervat + PV 12.415Wp + Home Assistant + Hyundai Ioniq 6 First Edition + Zaptec laadpaal
Er zijn een aantal plooien gladgestreken.
Dit staat in de changelog:
- Updated for several python modules
- Corrected typos in DOCS.md
- Changed boiler heating_allowed_below to flex-setting (reported by @Impossibl3, pr from tomvanterve)
- Fixed error logging during execution of a run
- Fixed typo "Battery" -> Machine in machines.py
- Added x-help-text with 0 W stages
- Changed typo meteo-attemps -> meteo_attempts
- Changed timeout hassapi to 10 sec.
- Converted ev "entity stop laden" -> "entity_stop_charging" (reported by @Darkwings)
- Made boiler cooling_rate float and flexsetting (pr from tomvanterve)
Dus we horen graag jullie bevindingen.
WP: Alpha Innotec MSW2-6S | PV: 20 x 300 Wp AEG | ACCU: 2x16x280Ah LiFePO4 3 x Multiplus II 48/3000 | DYN: Tibber | Gasloos | Day Ahead Optimizer
Het lijkt erop dat hij op jouw HA-machine wel overweg kan met de oude zelf gecompileerde binaries maar niet met de binaries "off the shelf".eagle73 schreef op donderdag 7 mei 2026 @ 12:39:
[...]
Logisch inderdaad en gisteravond daar niet aandacht dat het beschibare tijdsvenster te klein is. Ik gebruik DAO momenteel voor het inplannen van apparatuur en op termijn zal er een keer een batterij komen. In de voorgaande versies van DAO kreeg ik ook een melding dat een apparaat niet ingepland kan worden maar het resulteerde wel in een uiteindelijk in de pagina met de verwachte solar opbrengst en de andere grafieken.
Ik heb nu alleen de vaatwasser in de machines laten staan er de rest weggehaald. DAO blijft nog steeds hangen in de MIP optimalisation. Dit levert de volgende output:
[...]
In 2026.3.2 heeft dit nog gewerkt en bij de stap naar 2026.4.4 blijft hij hangen in deze stap.
Wat je kunt doen: compileer binaries voor je eigen machine.
Hier staat hoe je dat moet doen:
https://github.com/cornee...ecompileerde-mip-binaries
WP: Alpha Innotec MSW2-6S | PV: 20 x 300 Wp AEG | ACCU: 2x16x280Ah LiFePO4 3 x Multiplus II 48/3000 | DYN: Tibber | Gasloos | Day Ahead Optimizer
wat ik lees:thomvh schreef op donderdag 7 mei 2026 @ 15:40:
Ook een vet project, wat eigenlijk op een soort gelijke basis als DAO de epex prijzen vooruit probeert te voorspellen: https://github.com/b3nn0/EpexPredictor
- NL regio ondersteund,
- gratis publieke API,
- self-hosting mogelijk via Docker Compose,
- ENTSO-E API key, verhoogt nauwkeurigheid
Gasloos 2019 + WP Panasonic H-serie 7kW + 300 liter boilervat + PV 12.415Wp + Home Assistant + Hyundai Ioniq 6 First Edition + Zaptec laadpaal
DAO werkt (nog) niet met voorspellingen van de day ahead prijzen. Alleen met vastgestelde prijzen.thomvh schreef op donderdag 7 mei 2026 @ 15:40:
Ook een vet project, wat eigenlijk op een soort gelijke basis als DAO de epex prijzen vooruit probeert te voorspellen: https://github.com/b3nn0/EpexPredictor
WP: Alpha Innotec MSW2-6S | PV: 20 x 300 Wp AEG | ACCU: 2x16x280Ah LiFePO4 3 x Multiplus II 48/3000 | DYN: Tibber | Gasloos | Day Ahead Optimizer
Excuses, ik bedoelde het ook niet als dat DAO hetzelfde doet. Ik bedoelde eigenlijk juist dat het een mooie toevoeging kan bieden. Merk dat DAO momenteel vaak ook na de nieuwe prijzen live gaan een andere tactiek gaat hanteren. Dus misschien wordt het dan wel interessant om dan met eventuele week voorspellingen te werken ofzo.KC27 schreef op vrijdag 8 mei 2026 @ 10:16:
[...]
DAO werkt (nog) niet met voorspellingen van de day ahead prijzen. Alleen met vastgestelde prijzen.
@KC27 . ik draai DAO in een separate docker container en niet als HA add-on. Is daar ook een mogelijkheid om de MIP binaries te compileren op een bepaalde manier?KC27 schreef op donderdag 7 mei 2026 @ 23:09:
[...]
Het lijkt erop dat hij op jouw HA-machine wel overweg kan met de oude zelf gecompileerde binaries maar niet met de binaries "off the shelf".
Wat je kunt doen: compileer binaries voor je eigen machine.
Hier staat hoe je dat moet doen:
https://github.com/cornee...ecompileerde-mip-binaries
In de docker container gedoken en daar staat een shell script "build_miplib.sh" en deze via
docker exec -it dao ./build_miplib.sh uitgevoerd waarbij "dao" de naam van je docker container is. Compilatie is gelukt en heb nu een extra folder in de config dir zitten genaamd "miplib" Wat de compliceerde versie is van MIP binaries voor mijn machine in staan.
Vervolgens de Dao docker container opnieuw starten en hij lijkt het weer te doen.
Wellicht goed om dit toe te voegen aan de wiki?
[ Voor 22% gewijzigd door eagle73 op 08-05-2026 15:13 ]
Tibber laat hetzelfde zien.
Maar ik heb toch sterk het gevoel dat er ergens in een systeem iets stuk is gegaan er er 0.00 euro wordt geretourneerd
Van daaruit een aantal Feature Requests welk naar mijn idee een toegevoegde waarde kan bieden aan DAO en hun eindgebruikers.
Een overzichtje met hulp van Claude... ik ben benieuwd naar jou en anderen hun visie en mening
DAO Feature Requests
Hieronder een aantal feature requests voor de Day Ahead Optimizer (DAO), opgesteld na vergelijkende analyse van een aantal vergelijkbare projecten: bvweerd/battery_controller (Dynamic Programming optimizer), Utini2000/Zendure-Solarflow-Local-HomeAssistant (productie-grade NoM controller) en b3nn0/EpexPredictor (LightGBM EPEX prijsvoorspelling). Aangevuld met eigen implementatie-ervaring op een Zendure 3× SolarFlow 2400 AC+ setup met SolarEdge 8kW omvormer.
---
FR-001 — entity pv switch in de solar-sectie (AC-omvormer) | Prioriteit: Hoog
DAO ondersteunt "entity pv switch" al in de battery/dc-sectie, maar niet in de solar (AC-omvormer) sectie. Bij negatieve EPEX-prijzen zetten AC-omvormers zoals SolarEdge, Fronius en SMA zichzelf automatisch uit via hun eigen app-logica. DAO weet dit niet en houdt rekening met PV-productie die er feitelijk niet is. Het gevolg: DAO verwacht PV-overschot en plant geen grid-import in, terwijl de werkelijkheid PV = 0W is. De accu laadt dan onnodig uit het grid tegen positieve prijs. De forecast-error loopt op tot 3-8 kWh per curtailment-dag.
Gewenste oplossing: voeg "entity pv switch" toe als optioneel veld in de solar (AC) sectie, identiek aan de bestaande implementatie in de dc/battery-sectie. Gedrag: als entity pv switch = off rekent DAO pv_forecast = 0 voor die installatie, en DAO mag de boolean zelf op off zetten bij negatieve terugleververgoeding.
1
2
3
4
5
6
7
8
9
| "solar": [
{
"name": "SolarEdge 8kW",
"entity pv switch": "input_boolean.dao_pv_solaredge_active",
"ml_prediction": "true",
"entities sensors": "sensor.solaredge_lifetime_energy",
"strings": [...]
}
] |
---
FR-002 — Pre-13:00 prijsfallback vóór Nordpool-publicatie | Prioriteit: Hoog
Nordpool NL publiceert dag-vooruit prijzen rond 13:00 CET. DAO draait zijn optimalisatie op vaste tijdstippen en gebruikt vóór 13:00 statische fallback-waarden (regular high / regular low) voor de volgende dag. Het gevolg: de ochtend-optimalisatie (bijv. 07:00) plant de volgende dag verkeerd in. Bij verwachte piekprijzen (Dunkelflaute) wordt de accu te vroeg leeggemaakt; bij verwachte negatieve prijzen wordt de accu niet maximaal geladen vóór de goedkope periode.
Gewenste oplossing optie A: integratie met EpexPredictor (https://github.com/b3nn0/EpexPredictor) als optionele prijsfallback-bron. Dit project gebruikt LightGBM op weerdata + ENTSO-E load + gasprijs en ondersteunt de NL regio. Nauwkeurigheid: nacht <0,5 ct/kWh, pieken 1-1,5 ct/kWh fout. Publieke API is gratis beschikbaar.
1
2
3
4
5
6
| "prices": {
"source_day_ahead": "nordpool",
"source_forecast_fallback": "epexpredictor",
"epexpredictor_url": "https://epexpredictor.batzill.com/prices_short",
"epexpredictor_region": "NL"
} |
---
FR-003 — Shadow price als horizon-eindconditie voor batterij | Prioriteit: Middel
DAO's batterij-optimalisatie gebruikt "entity min soc end opt" en "entity max soc end opt" als harde eindconditie. Deze waarden zijn statisch of handmatig ingesteld. De optimizer weet daardoor niet wat opgeslagen energie ná de planningshorizon waard is. Het gevolg: bij horizon-einde wordt de accu irrationeel leeg- of voorgepland, en gebruikers moeten dao_min_soc_einde_opt handmatig bijstellen op basis van verwachtingen voor de volgende dag.
Gewenste oplossing: een rolling shadow price als terminal condition. De shadow price is de marginale waarde van 1 kWh opgeslagen energie, afgeleid uit de vorige optimizer-run. Na ongeveer een week convergeert dit naar een stabiele waarde.
1
2
| terminal_value[s] = stored_kwh[s] x shadow_price shadow_price = afgeleid uit vorige optimizer-run (convergeert ~1 week) |
---
FR-004 — Oscillation filter (anti-micro-cyclus) | Prioriteit: Middel
DAO kan kwartieren plannen waarbij de accu afwisselend laadt en ontlaadt met een klein prijsverschil. Elke cyclus kost degradatie plus round-trip rendementsverlies. De minimaal winstgevende spread voor arbitrage is:
1
2
3
| min_spread = (2 x cycle_cost_per_kWh + min_price_spread) / sqrt(RTE)
= (2 x 0.015 + 0.005) / sqrt(0.93)
≈ 0.036 EUR/kWh |
---
FR-005 — Write-throttling / dispatch cooldown voor battery setpoint | Prioriteit: Laag
DAO schrijft naar "entity set power feedin" bij elke optimizer-tick, ook als de waarde identiek is aan de vorige. Dit genereert onnodig HA state-changes, database-writes en downstream REST-calls naar omvormers. Gewenste oplossing: schrijf alleen naar entity set power feedin als de waarde ≥ X Watt afwijkt van de vorige (configureerbaar, bijv. 25W), of als meer dan Y seconden verstreken zijn zonder write (heartbeat, bijv. 60s). Inspiratie: Utini2000/zendure_control.yaml gebruikt een vergelijkbaar dispatch-cooldown patroon met een mismatch-check en force-flag.
---
FR-006 — EpexPredictor configuratievoorbeeld in DOCS.md | Prioriteit: Laag
Verzoek om in DAO DOCS.md een officieel configuratievoorbeeld toe te voegen voor EpexPredictor als pre-13:00 prijsfallback sensor. Dit betreft alleen documentatie, geen code-wijziging.
1
2
3
4
5
6
7
8
9
10
11
12
| sensor:
- platform: rest
resource: "https://epexpredictor.batzill.com/prices_short?region=NL&surcharge=10.154&taxPercent=21&unit=EUR_PER_KWH&hours=48"
method: GET
unique_id: epex_price_prediction_nl
name: "EPEX Price Prediction NL"
unit_of_measurement: "EUR/kWh"
scan_interval: 3600
value_template: "{{ value_json.t[0] }}"
json_attributes:
- s
- t |
---
FR-007 — Native zero-export / balance controller met hysterese | Prioriteit: Hoog
DAO ondersteunt via "entity balance switch" al een balanceerstand, maar de daadwerkelijke regeling van het setpoint tijdens balanceren valt volledig buiten DAO. DAO schrijft dan geen waarden meer naar "entity set power feedin" en verwacht dat de omvormer zelf balanceert. Dit werkt goed voor hybride omvormers met ingebouwde zero-export logica (bijv. Victron ESS, SolarEdge StorEdge), maar niet voor AC-gekoppelde batterijsystemen zoals Zendure, SolarFlow, Enphase IQ Battery, of andere systemen die via een HA-helper worden aangestuurd. Voor die systemen moet de gebruiker zelf een volledige real-time regelaar bouwen.
Bewijs van de noodzaak: onze productie-implementatie
Testopstelling: Zendure 3x SolarFlow 2400 AC+ (24,48 kWh totaal, 3-fase, 1 unit per fase), SolarEdge 8kW AC-omvormer, Panasonic Aquarea 7kW warmtepomp, HomeWizard P1 meter (1s update), NL dynamische prijzen via Nordpool. Aansturing via @gielz en @gast777 proxy over zenSDK REST.
Omdat DAO tijdens balance-uren stopt met schrijven maar Zendure geen eigen zero-export logica heeft, was volledige import/export ongecontroleerd. Oplossing: een bang-bang controller met hysterese-timers gebouwd als HA-automatisering bovenop DAO. Gefaseerde implementatie:
Fase 1 — helpers (geen impact op bestaande DAO werking):
1
2
3
4
5
6
7
8
9
10
11
12
13
| input_number: dao_zendure_target_power: # actuator tussen DAO en omvormer, bereik -3000..+3000 W dao_nom_import_threshold: # default 80 W — drempel voor laden dao_nom_export_threshold: # default 200 W — drempel voor ontladen dao_nom_bias: # default 7 W — kleine offset richting export dao_nom_timer_seconds: # default 10 s — hysterese-timer, tunable 5-60s input_select: dao_nom_active_mode: # charge / discharge / idle timer: dao_nom_import_arm: # hysterese-timer import dao_nom_export_arm: # hysterese-timer export |
1
2
3
4
5
6
7
8
9
10
11
12
13
| # Logica (vereenvoudigd): # grid = P1_meting - bias # als grid > import_threshold: arm import_timer → na 10s: mode = discharge # als grid < -export_threshold: arm export_timer → na 10s: mode = charge # anders: cancel beide timers (dode zone) # # target binnen huidige mode: # discharge: target = -clamp(grid, 0, max_discharge_voor_SoC) # charge: target = +clamp(-grid, 0, max_charge_voor_SoC) # # SoC-aware limieten (pimNH-tabel, aangepast aan 3000W Zendure max): # laden: SoC<88% → 3000W, SoC<93% → 2000W, SoC<95% → 800W, SoC<98% → 300W, SoC<99% → 150W, anders 60W # ontladen: SoC>30% → 3000W, SoC>20% → 2000W, SoC>15% → 1500W, anders 300W |
1
2
3
4
5
6
| # Grid-overbelastings-clamp (safety, normale werking raakt dit nooit): # grid > 6000W → forceer max discharge | grid < -5000W → forceer max charge # EV-aware force-stop: # bij EV charge-start → target = 0, mode = idle # bij EV charge-einde → herstart init |
1
2
3
| # input_boolean.dao_pv_solaredge_active wordt gesynchroniseerd met # sensor.dao_pv_curtailment_active (all-in prijs < drempel). # Zolang FR-001 niet upstream beschikbaar is: handmatige sync via automation. |
Native ondersteuning voor een zero-export regelaar als optionele module binnen DAO, actief tijdens balance-uren. Minimale vereisten: configureerbare import/export drempels, hysterese-timer (anti-flapping), SoC-aware vermogensbegrenzing, en EV-pause logica. De regelaar schrijft naar "entity set power feedin" tijdens balance-uren in plaats van te stoppen met schrijven.
Dit voorkomt dat elke gebruiker met een AC-gekoppeld batterijsysteem zelf een volledige real-time regelaar moet bouwen. De Tweakers DAO-thread toont meerdere vergelijkbare implementaties (@pimNH , @KC27 , @Bravo , @Xom , @Beekforel ) — allemaal varianten van dezelfde ontbrekende DAO-functionaliteit.
Referenties: Utini2000/Zendure-Solarflow-Local-HomeAssistant (bewezen 1-15W precisie op productie), @pimNH bang-bang implementatie (Tweakers DAO-topic), @KC27 dubbele-helper patroon (Tweakers DAO-topic).
---
Samenvatting
FR-001 entity pv switch AC-omvormer — Hoog — Bugfix/Feature
FR-002 Pre-13:00 prijsfallback / EpexPredictor — Hoog — Feature
FR-003 Shadow price terminal condition — Middel — Algoritme
FR-004 Oscillation filter — Middel — Algoritme
FR-005 Write-throttling setpoint — Laag — Optimalisatie
FR-006 EpexPredictor documentatie — Laag — Docs
FR-007 Native zero-export / balance controller — Hoog — Feature
FR-001 en FR-007 hebben de meeste directe impact. FR-007 in het bijzonder omdat meerdere gebruikers in de Tweakers DAO-thread onafhankelijk van elkaar dezelfde workaround hebben gebouwd — een duidelijk signaal dat dit een structureel ontbrekende maar veel gewenste feature is.
Alvast bedankt voor de reacties!
Gasloos 2019 + WP Panasonic H-serie 7kW + 300 liter boilervat + PV 12.415Wp + Home Assistant + Hyundai Ioniq 6 First Edition + Zaptec laadpaal
FR-001 zit er gewoon in. FR-007 doen in 9 van de 10 gevallen de inverters zelf. Vandaar dat er waarschijnlijk de keus is gemaakt dat niet te integreren. E.g. de logica in Home Assistant te bakken.hemertje schreef op vrijdag 8 mei 2026 @ 18:38:
@KC27 @simnet @Beekforel @Bravo de laatste week met vriend Claude (Code) verder inhoudelijk in DAO, thuisbatterijen en NOM gedoken.
Van daaruit een aantal Feature Requests welk naar mijn idee een toegevoegde waarde kan bieden aan DAO en hun eindgebruikers.
Een overzichtje met hulp van Claude... ik ben benieuwd naar jou en anderen hun visie en mening
DAO Feature Requests
Hieronder een aantal feature requests voor de Day Ahead Optimizer (DAO), opgesteld na vergelijkende analyse van een aantal vergelijkbare projecten: bvweerd/battery_controller (Dynamic Programming optimizer), Utini2000/Zendure-Solarflow-Local-HomeAssistant (productie-grade NoM controller) en b3nn0/EpexPredictor (LightGBM EPEX prijsvoorspelling). Aangevuld met eigen implementatie-ervaring op een Zendure 3× SolarFlow 2400 AC+ setup met SolarEdge 8kW omvormer.
---
FR-001 — entity pv switch in de solar-sectie (AC-omvormer) | Prioriteit: Hoog
DAO ondersteunt "entity pv switch" al in de battery/dc-sectie, maar niet in de solar (AC-omvormer) sectie. Bij negatieve EPEX-prijzen zetten AC-omvormers zoals SolarEdge, Fronius en SMA zichzelf automatisch uit via hun eigen app-logica. DAO weet dit niet en houdt rekening met PV-productie die er feitelijk niet is. Het gevolg: DAO verwacht PV-overschot en plant geen grid-import in, terwijl de werkelijkheid PV = 0W is. De accu laadt dan onnodig uit het grid tegen positieve prijs. De forecast-error loopt op tot 3-8 kWh per curtailment-dag.
Gewenste oplossing: voeg "entity pv switch" toe als optioneel veld in de solar (AC) sectie, identiek aan de bestaande implementatie in de dc/battery-sectie. Gedrag: als entity pv switch = off rekent DAO pv_forecast = 0 voor die installatie, en DAO mag de boolean zelf op off zetten bij negatieve terugleververgoeding.code:Huidige workaround: input_boolean + automation die de curtailment-sensor synchroniseert. Werkt, maar is omslachtig en niet officieel ondersteund.
1 2 3 4 5 6 7 8 9"solar": [ { "name": "SolarEdge 8kW", "entity pv switch": "input_boolean.dao_pv_solaredge_active", "ml_prediction": "true", "entities sensors": "sensor.solaredge_lifetime_energy", "strings": [...] } ]
---
FR-002 — Pre-13:00 prijsfallback vóór Nordpool-publicatie | Prioriteit: Hoog
Nordpool NL publiceert dag-vooruit prijzen rond 13:00 CET. DAO draait zijn optimalisatie op vaste tijdstippen en gebruikt vóór 13:00 statische fallback-waarden (regular high / regular low) voor de volgende dag. Het gevolg: de ochtend-optimalisatie (bijv. 07:00) plant de volgende dag verkeerd in. Bij verwachte piekprijzen (Dunkelflaute) wordt de accu te vroeg leeggemaakt; bij verwachte negatieve prijzen wordt de accu niet maximaal geladen vóór de goedkope periode.
Gewenste oplossing optie A: integratie met EpexPredictor (https://github.com/b3nn0/EpexPredictor) als optionele prijsfallback-bron. Dit project gebruikt LightGBM op weerdata + ENTSO-E load + gasprijs en ondersteunt de NL regio. Nauwkeurigheid: nacht <0,5 ct/kWh, pieken 1-1,5 ct/kWh fout. Publieke API is gratis beschikbaar.code:Gewenste oplossing optie B: een "source_day_ahead_fallback" veld dat een HA-sensor accepteert met forecast-attributen, zodat gebruikers zelf een prijsmodel kunnen koppelen. Referentie: bvweerd/battery_controller ALGORITHM.md §9 en §14 voor een zelflerend historisch prijsmodel op basis van weerdata en recorder-data.
1 2 3 4 5 6"prices": { "source_day_ahead": "nordpool", "source_forecast_fallback": "epexpredictor", "epexpredictor_url": "https://epexpredictor.batzill.com/prices_short", "epexpredictor_region": "NL" }
---
FR-003 — Shadow price als horizon-eindconditie voor batterij | Prioriteit: Middel
DAO's batterij-optimalisatie gebruikt "entity min soc end opt" en "entity max soc end opt" als harde eindconditie. Deze waarden zijn statisch of handmatig ingesteld. De optimizer weet daardoor niet wat opgeslagen energie ná de planningshorizon waard is. Het gevolg: bij horizon-einde wordt de accu irrationeel leeg- of voorgepland, en gebruikers moeten dao_min_soc_einde_opt handmatig bijstellen op basis van verwachtingen voor de volgende dag.
Gewenste oplossing: een rolling shadow price als terminal condition. De shadow price is de marginale waarde van 1 kWh opgeslagen energie, afgeleid uit de vorige optimizer-run. Na ongeveer een week convergeert dit naar een stabiele waarde.code:Praktisch effect: de optimizer stopt met irrationeel ontladen vlak voor het horizon-einde en dao_min_soc_einde_opt hoeft niet meer handmatig bijgesteld te worden. Volledige wiskundige uitwerking in bvweerd/battery_controller ALGORITHM.md §5 en §9.
1 2 terminal_value[s] = stored_kwh[s] x shadow_price shadow_price = afgeleid uit vorige optimizer-run (convergeert ~1 week)
---
FR-004 — Oscillation filter (anti-micro-cyclus) | Prioriteit: Middel
DAO kan kwartieren plannen waarbij de accu afwisselend laadt en ontlaadt met een klein prijsverschil. Elke cyclus kost degradatie plus round-trip rendementsverlies. De minimaal winstgevende spread voor arbitrage is:code:Laden bij 0,10 €/kWh en ontladen bij 0,13 €/kWh geeft slechts 0,03 €/kWh spread, wat na degradatiekosten niet winstgevend is. Gewenste oplossing: een post-processing filter op de optimizer-output waarbij een laad→ontlaad of ontlaad→laad overgang die minder dan min_arbitrage_spread oplevert wordt vervangen door idle. Alternatief als config-parameter: "min_price_spread": 0.03 die de optimizer zelf meeneemt in de kostenfunctie. Referentie: bvweerd/battery_controller ALGORITHM.md §8.1 voor het iteratieve lookahead-algoritme.
1 2 3min_spread = (2 x cycle_cost_per_kWh + min_price_spread) / sqrt(RTE) = (2 x 0.015 + 0.005) / sqrt(0.93) ≈ 0.036 EUR/kWh
---
FR-005 — Write-throttling / dispatch cooldown voor battery setpoint | Prioriteit: Laag
DAO schrijft naar "entity set power feedin" bij elke optimizer-tick, ook als de waarde identiek is aan de vorige. Dit genereert onnodig HA state-changes, database-writes en downstream REST-calls naar omvormers. Gewenste oplossing: schrijf alleen naar entity set power feedin als de waarde ≥ X Watt afwijkt van de vorige (configureerbaar, bijv. 25W), of als meer dan Y seconden verstreken zijn zonder write (heartbeat, bijv. 60s). Inspiratie: Utini2000/zendure_control.yaml gebruikt een vergelijkbaar dispatch-cooldown patroon met een mismatch-check en force-flag.
---
FR-006 — EpexPredictor configuratievoorbeeld in DOCS.md | Prioriteit: Laag
Verzoek om in DAO DOCS.md een officieel configuratievoorbeeld toe te voegen voor EpexPredictor als pre-13:00 prijsfallback sensor. Dit betreft alleen documentatie, geen code-wijziging.code:Bron: https://github.com/b3nn0/EpexPredictor — NL regio ondersteund, gratis publieke API, self-hosting mogelijk via Docker Compose, ENTSO-E API key verhoogt nauwkeurigheid significant voor NL.
1 2 3 4 5 6 7 8 9 10 11 12sensor: - platform: rest resource: "https://epexpredictor.batzill.com/prices_short?region=NL&surcharge=10.154&taxPercent=21&unit=EUR_PER_KWH&hours=48" method: GET unique_id: epex_price_prediction_nl name: "EPEX Price Prediction NL" unit_of_measurement: "EUR/kWh" scan_interval: 3600 value_template: "{{ value_json.t[0] }}" json_attributes: - s - t
---
FR-007 — Native zero-export / balance controller met hysterese | Prioriteit: Hoog
DAO ondersteunt via "entity balance switch" al een balanceerstand, maar de daadwerkelijke regeling van het setpoint tijdens balanceren valt volledig buiten DAO. DAO schrijft dan geen waarden meer naar "entity set power feedin" en verwacht dat de omvormer zelf balanceert. Dit werkt goed voor hybride omvormers met ingebouwde zero-export logica (bijv. Victron ESS, SolarEdge StorEdge), maar niet voor AC-gekoppelde batterijsystemen zoals Zendure, SolarFlow, Enphase IQ Battery, of andere systemen die via een HA-helper worden aangestuurd. Voor die systemen moet de gebruiker zelf een volledige real-time regelaar bouwen.
Bewijs van de noodzaak: onze productie-implementatie
Testopstelling: Zendure 3x SolarFlow 2400 AC+ (24,48 kWh totaal, 3-fase, 1 unit per fase), SolarEdge 8kW AC-omvormer, Panasonic Aquarea 7kW warmtepomp, HomeWizard P1 meter (1s update), NL dynamische prijzen via Nordpool. Aansturing via @gielz en @gast777 proxy over zenSDK REST.
Omdat DAO tijdens balance-uren stopt met schrijven maar Zendure geen eigen zero-export logica heeft, was volledige import/export ongecontroleerd. Oplossing: een bang-bang controller met hysterese-timers gebouwd als HA-automatisering bovenop DAO. Gefaseerde implementatie:
Fase 1 — helpers (geen impact op bestaande DAO werking):code:Fase 2 — bang-bang controller (elke 6s tijdens balance, SoC-aware power limits):
1 2 3 4 5 6 7 8 9 10 11 12 13 input_number: dao_zendure_target_power: # actuator tussen DAO en omvormer, bereik -3000..+3000 W dao_nom_import_threshold: # default 80 W — drempel voor laden dao_nom_export_threshold: # default 200 W — drempel voor ontladen dao_nom_bias: # default 7 W — kleine offset richting export dao_nom_timer_seconds: # default 10 s — hysterese-timer, tunable 5-60s input_select: dao_nom_active_mode: # charge / discharge / idle timer: dao_nom_import_arm: # hysterese-timer import dao_nom_export_arm: # hysterese-timer exportcode:Fase 2.5 — uitbreidingen:
1 2 3 4 5 6 7 8 9 10 11 12 13 # Logica (vereenvoudigd): # grid = P1_meting - bias # als grid > import_threshold: arm import_timer → na 10s: mode = discharge # als grid < -export_threshold: arm export_timer → na 10s: mode = charge # anders: cancel beide timers (dode zone) # # target binnen huidige mode: # discharge: target = -clamp(grid, 0, max_discharge_voor_SoC) # charge: target = +clamp(-grid, 0, max_charge_voor_SoC) # # SoC-aware limieten (pimNH-tabel, aangepast aan 3000W Zendure max): # laden: SoC<88% → 3000W, SoC<93% → 2000W, SoC<95% → 800W, SoC<98% → 300W, SoC<99% → 150W, anders 60W # ontladen: SoC>30% → 3000W, SoC>20% → 2000W, SoC>15% → 1500W, anders 300Wcode:Fase 2.6 — PV-curtailment workaround (zie ook FR-001):
1 2 3 4 5 6 # Grid-overbelastings-clamp (safety, normale werking raakt dit nooit): # grid > 6000W → forceer max discharge | grid < -5000W → forceer max charge # EV-aware force-stop: # bij EV charge-start → target = 0, mode = idle # bij EV charge-einde → herstart initcode:Gevraagde DAO-feature
1 2 3 # input_boolean.dao_pv_solaredge_active wordt gesynchroniseerd met # sensor.dao_pv_curtailment_active (all-in prijs < drempel). # Zolang FR-001 niet upstream beschikbaar is: handmatige sync via automation.
Native ondersteuning voor een zero-export regelaar als optionele module binnen DAO, actief tijdens balance-uren. Minimale vereisten: configureerbare import/export drempels, hysterese-timer (anti-flapping), SoC-aware vermogensbegrenzing, en EV-pause logica. De regelaar schrijft naar "entity set power feedin" tijdens balance-uren in plaats van te stoppen met schrijven.
Dit voorkomt dat elke gebruiker met een AC-gekoppeld batterijsysteem zelf een volledige real-time regelaar moet bouwen. De Tweakers DAO-thread toont meerdere vergelijkbare implementaties (@pimNH , @KC27 , @Bravo , @Xom , @Beekforel ) — allemaal varianten van dezelfde ontbrekende DAO-functionaliteit.
Referenties: Utini2000/Zendure-Solarflow-Local-HomeAssistant (bewezen 1-15W precisie op productie), @pimNH bang-bang implementatie (Tweakers DAO-topic), @KC27 dubbele-helper patroon (Tweakers DAO-topic).
---
Samenvatting
FR-001 entity pv switch AC-omvormer — Hoog — Bugfix/Feature
FR-002 Pre-13:00 prijsfallback / EpexPredictor — Hoog — Feature
FR-003 Shadow price terminal condition — Middel — Algoritme
FR-004 Oscillation filter — Middel — Algoritme
FR-005 Write-throttling setpoint — Laag — Optimalisatie
FR-006 EpexPredictor documentatie — Laag — Docs
FR-007 Native zero-export / balance controller — Hoog — Feature
FR-001 en FR-007 hebben de meeste directe impact. FR-007 in het bijzonder omdat meerdere gebruikers in de Tweakers DAO-thread onafhankelijk van elkaar dezelfde workaround hebben gebouwd — een duidelijk signaal dat dit een structureel ontbrekende maar veel gewenste feature is.
Alvast bedankt voor de reacties!
![]()
FR2 - ik geloof dat ik dit niet snapt, DAO is na het binnen krijgen van de day ahead waardes ruim op tijd om hier slim mee om te gaan. Heel af en toe in de wintermaanden zou ik graag verder vooruit willen kijken.
FR3 - ik heb nog nooit handmatig de waardes moeten wijzigen. Zie ook FR2
FR4 - dit zit er toch gewoon in en kan je regelen met cycle Cost.
FR5 - dit lijkt mij een non issue. Dao schrijft enkele waardes, 2 of 3 en dat eens in het kwartier.
FR7 - Mijn omvormer kan heel goed zelf NOM houden, dus ik ben content met de balance switch.
Tot zover
AI is een prima tool om code te schrijven, maar het stellen van requirements vereist toch echt menselijk denken in plaats van interpretatie van een LLM.
Ik heb nu 6 weken ofzo de Zendure batterijen en in huis en gebruik DAO nu 3 weken, dit draadje volg ik al een half jaar ofzo.
Wat ik als eindgebruiker (en programmeerleek) mis is inderdaad de helpers en automations voor de verdere aansturingen van de verbruikers in huis. Ik snap HA, maar begrijp het niet altijd en code schrijven is niet mijn beroep of hobby, dus dan ga je hulp zoeken, en tegenwoordig is dat dan o.a. AI.
FR3, FR4, FR5 zijn inderdaad theoretisch van aard en niet gebaseerd op werkelijke problemen die ik in de praktijk ben tegengekomen met DAO. Die had ik niet moeten posten.
FR2 is wellicht te algemeen geformuleerd. Mijn specifieke situatie is dat ik 's ochtends vroeg al wil weten wat de volgende dag gaat doen, maar jullie hebben gelijk dat DAO hier in de meeste gevallen ruim op tijd bij is.
Over FR7 en de opmerking over de horizon:
Ik heb een Zendure SolarFlow setup waarbij de omvormer zelf geen NOM-logica heeft voor zover ik weet. DAO zet de balance switch en stopt dan met schrijven, wat voor mijn setup betekent dat ik zelf iets moet bouwen voor real-time bijsturing. Dat is inderdaad geen DAO-probleem maar een hardware-probleem aan mijn kant. De opmerking over de verkeerde horizon klopt — ik heb ten onrechte realtime control requirements in een setpoint-scheduler gegooid.
Wat wel interessant zou kunnen zijn: een wiki-pagina of voorbeeldpakket voor gebruikers met AC-gekoppelde systemen die geen eigen NOM-logica hebben. Ik zie in de thread dat @pimNH, @KC27 en anderen vergelijkbare oplossingen hebben gebouwd — als we dat samenvoegen in een community-voorbeeld in de wiki scheelt dat toekomstige gebruikers met hetzelfde hardware-profiel een hoop uitzoekwerk. Maar dat is iets om met de betrokkenen op te pakken, niet iets voor corneel27 om in DAO-core te bouwen.
Excuses voor de ruis in de thread.
Gasloos 2019 + WP Panasonic H-serie 7kW + 300 liter boilervat + PV 12.415Wp + Home Assistant + Hyundai Ioniq 6 First Edition + Zaptec laadpaal
| Smart Matching | Maintains constant zero import (-xx watt when charging and -xx watt when discharging). Charging can be fine-tuned via |
Dit heeft alles te maken met de merit-order systematiek waarmee de day-ahead prijzen tot stand komen.simnet schreef op vrijdag 8 mei 2026 @ 18:01:
Morgen tussen 10:00 en 16:00 (ongeveer) is de prijs een flatline op 0. Dat ziet er uit als een fout ergens...
Tibber laat hetzelfde zien.
Maar ik heb toch sterk het gevoel dat er ergens in een systeem iets stuk is gegaan er er 0.00 euro wordt geretourneerd
Veel producenten met zon- en windparken bieden hun (geplande) productie aan met een prijs van minimaal 0.00 euro (willen geen verlies maken). Zodra er meer dan de vraag wordt aangeboden tegen 0 euro wordt daarop de prijs bepaald.
De prijs zakt onder nul als er genoeg producenten zijn die ook bij negatieve prijzen gewoon blijven produceren en met die lagere prijzen aanbieden:
- energiebedrijven van consumenten met een vast contract moeten van hun overschot af
- producenten met een subsidie per geproduceerde kWh gaan door tot de subsidiegrens.
Als er dan ook nog genoeg vraag is (bij die negatieve prijs) zakt het evenwicht van vraag en aanbod alsnog "onder nul".
Hieronder een grafiek van een tool die de day-ahead prijs zes dagen vooruit voorspelt op basis van
- de verwachte consumptie in Nederland enerzijds en
- anderzijds geaccumuleerd: de productie van wind op land, wind op zee en zon.
Zondag wordt mogelijk weer een dag met day ahead prijzen onder nul (disclaimer: dit model heeft de neiging om pieken en dalen te overschatten).
WP: Alpha Innotec MSW2-6S | PV: 20 x 300 Wp AEG | ACCU: 2x16x280Ah LiFePO4 3 x Multiplus II 48/3000 | DYN: Tibber | Gasloos | Day Ahead Optimizer
Een tip van een mede Claude Code fan en iemand die nog wel zelf heeft leren programmeren; ga geen developers die hun hart en ziel nog in de pre-vibe code tijd hebben gestort op een hobby project, bombarderen met door AI gegenereerde feature requests. Als je niet zelf begrijpt wat de software doet en wat je wil, verdiep je er dan eerst in en vertel het in je eigen woorden.hemertje schreef op vrijdag 8 mei 2026 @ 18:38:
@KC27 @simnet @Beekforel @Bravo de laatste week met vriend Claude (Code) verder inhoudelijk in DAO, thuisbatterijen en NOM gedoken.
Wat ik je kan aanraden is om Claude te vragen je eigen HA integratie te bouwen die precies doet wat jij wilt. Ik heb het zelf ook in 3 avonden gedaan (https://gathering.tweakers.net/forum/view_message/85187270). Als developer die zelf heeft bijgedragen aan meerdere open source projecten (en ook aan deze) voelt het verdomd egoistisch om iets te bouwen wat perfect werkt voor mij maar voor niemand anders. Maar in ieder geval zadel ik niemand anders op met AI gegenereerde feature requests. En misschien leer je al doende ook nog iets.
Opzich snap ik dat principe, maar 4 uur lang exact nul, zonder enige variatie vind ik nog steeds een bijzondere situatie.KC27 schreef op vrijdag 8 mei 2026 @ 23:19:
[...]
Dit heeft alles te maken met de merit-order systematiek waarmee de day-ahead prijzen tot stand komen.
Veel producenten met zon- en windparken bieden hun (geplande) productie aan met een prijs van minimaal 0.00 euro (willen geen verlies maken). Zodra er meer dan de vraag wordt aangeboden tegen 0 euro wordt daarop de prijs bepaald.
Ik kan me niet herinneren dat ik eerder zo'n strakke horizontale prijs heb gezien over zo'n lange periode.
Meestal schommelt het wel met enkele centen.
Hier draait het, maar ik geloof niet dat ik gebruik maak van de delen die je verandert hebt. Wel blijft het lastig om te zien wanneer iets fout gaat. Ik heb de test versie normaal uit staan en test alleen wanneer je een nieuwe versie hebt. Dat betekent dat de meteo/epex/ml altijd achterlopen.KC27 schreef op donderdag 7 mei 2026 @ 22:54:
Er is een nieuwe test-versie gepubliceerd: 2026.5.0.rc1
Er zijn een aantal plooien gladgestreken.
Dit staat in de changelog:Omdat er nogal wat is veranderd komt eerst een testversie uit, zodat eventuele foutjes eerst gemeld en gefixed kunnen worden voordat we over een paar dagen een nieuwe stabiele versie publiceren.
- Updated for several python modules
- Corrected typos in DOCS.md
- Changed boiler heating_allowed_below to flex-setting (reported by @Impossibl3, pr from tomvanterve)
- Fixed error logging during execution of a run
- Fixed typo "Battery" -> Machine in machines.py
- Added x-help-text with 0 W stages
- Changed typo meteo-attemps -> meteo_attempts
- Changed timeout hassapi to 10 sec.
- Converted ev "entity stop laden" -> "entity_stop_charging" (reported by @Darkwings)
- Made boiler cooling_rate float and flexsetting (pr from tomvanterve)
Dus we horen graag jullie bevindingen.
Na run met debug komt er een groen vinkje maar geen resultaat, en ook geen duidelijke foutmelding. Hierdoor is het moeilijk achterhalen wat je moet doen om het aan de praat te krijgen. Ik weet intussen wat ik moet doen, maar het zou duidelijker kunnen.
===
na ophalen van prijzen krijg ik dit bij run:
===code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 552026-05-09 07:39:42 INFO: Loaded 6 secrets from ../data/secrets.json 2026-05-09 07:39:42 INFO: Validating configuration with ConfigurationV1 2026-05-09 07:39:42 info: Day Ahead Optimalisering versie: 2026.5.0.rc1 2026-05-09 07:39:42 info: Day Ahead Optimalisering gestart op: 09-05-2026 07:39:42 2026-05-09 07:39:42 info: Day Ahead Optimalisatie gestart: 09-05-2026 07:39:42 taak: calc_optimum_met_debug 2026-05-09 07:39:42 info: Debug = True 2026-05-09 07:39:42 fout: Er is een fout opgetreden, zie de fout-tracering Traceback (most recent call last): File "/root/dao/prog/da_base.py", line 694, in run_task_function getattr(self, run_task["function"])() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^ File "/root/dao/prog/da_base.py", line 538, in calc_optimum_met_debug dacalc.calc_optimum() ~~~~~~~~~~~~~~~~~~~^^ File "/root/dao/prog/day_ahead.py", line 118, in calc_optimum prog_data = self.db_da.get_prognose_data( start=start_hour, end=None, interval=self.interval ) File "/root/dao/lib/db_manager.py", line 471, in get_prognose_data fld_df = interpolate(fld_df, field, False) File "/root/dao/prog/utils.py", line 511, in interpolate result_df.index = pd.to_datetime(result_df["tijd"]) ~~~~~~~~~^^^^^^^^ File "/root/dao/venv/day_ahead/lib/python3.13/site-packages/pandas/core/frame.py", line 4378, in __getitem__ indexer = self.columns.get_loc(key) File "/root/dao/venv/day_ahead/lib/python3.13/site-packages/pandas/core/indexes/range.py", line 525, in get_loc raise KeyError(key) KeyError: 'tijd' Traceback (most recent call last): File "/root/dao/webserver/../prog/day_ahead.py", line 4712, in <module> main() ~~~~^^ File "/root/dao/webserver/../prog/day_ahead.py", line 4683, in main da_calc.run_task_function("calc_optimum_met_debug") ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/root/dao/prog/da_base.py", line 694, in run_task_function getattr(self, run_task["function"])() ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^ File "/root/dao/prog/da_base.py", line 538, in calc_optimum_met_debug dacalc.calc_optimum() ~~~~~~~~~~~~~~~~~~~^^ File "/root/dao/prog/day_ahead.py", line 118, in calc_optimum prog_data = self.db_da.get_prognose_data( start=start_hour, end=None, interval=self.interval ) File "/root/dao/lib/db_manager.py", line 471, in get_prognose_data fld_df = interpolate(fld_df, field, False) File "/root/dao/prog/utils.py", line 511, in interpolate result_df.index = pd.to_datetime(result_df["tijd"]) ~~~~~~~~~^^^^^^^^ File "/root/dao/venv/day_ahead/lib/python3.13/site-packages/pandas/core/frame.py", line 4378, in __getitem__ indexer = self.columns.get_loc(key) File "/root/dao/venv/day_ahead/lib/python3.13/site-packages/pandas/core/indexes/range.py", line 525, in get_loc raise KeyError(key) KeyError: 'tijd'
na ophalen meteo verdwijnt de foutmelding. Nu kan ik wel een debug run doen, met groen vinkje als resultaat. De eerste keer dat ik dan terug ga naar Home zag ik nog de niet geoptimaliseerde grafiek, na nog een run wel.
===
Uiteindelijk kon ik wel een ml training afstarten maar kwam ik op deze melding:
1
2
3
4
5
| <!doctype html> <html lang=en> <title>500 Internal Server Error</title> <h1>Internal Server Error</h1> <p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p> |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| [2026-05-09 07:50:05,126] ERROR in app: Exception on /log [GET]
Traceback (most recent call last):
File "/root/dao/venv/day_ahead/lib/python3.13/site-packages/flask/app.py", line 1511, in wsgi_app
response = self.full_dispatch_request()
File "/root/dao/venv/day_ahead/lib/python3.13/site-packages/flask/app.py", line 919, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/root/dao/venv/day_ahead/lib/python3.13/site-packages/flask/app.py", line 917, in full_dispatch_request
rv = self.dispatch_request()
File "/root/dao/venv/day_ahead/lib/python3.13/site-packages/flask/app.py", line 902, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
File "/root/dao/webserver/app/routes.py", line 652, in show_log
logfile = task_state["logfile"]
~~~~~~~~~~^^^^^^^^^^^
KeyError: 'logfile' |
Ik ben wel heel erg blij met DAO overigens! Petje af voor al het werk dat er verzet wordt door jou en de andere programmeurs.
[ Voor 64% gewijzigd door balk op 09-05-2026 07:54 ]
Hoi @hemertje ik heb respect voor je betrokkenheid en pogingen om input te geven en mee te denken in deze thread. Blijf dat vooral doen. Of een door AI gegenereerde post met daarna de vraag om reactie (wat eigenlijk neerkomt op: checken jullie de uitkomst even op juistheid?) betwijfel ik. Ik merkte dat ik er snel doorheen scrolde.hemertje schreef op vrijdag 8 mei 2026 @ 22:34:
@Dogooder @wmc jullie hebben gelijk en ik neem de kritiek ter harte.
Ik heb nu 6 weken ofzo de Zendure batterijen en in huis en gebruik DAO nu 3 weken, dit draadje volg ik al een half jaar ofzo.
Wat ik als eindgebruiker (en programmeerleek) mis is inderdaad de helpers en automations voor de verdere aansturingen van de verbruikers in huis. Ik snap HA, maar begrijp het niet altijd en code schrijven is niet mijn beroep of hobby, dus dan ga je hulp zoeken, en tegenwoordig is dat dan o.a. AI.
FR3, FR4, FR5 zijn inderdaad theoretisch van aard en niet gebaseerd op werkelijke problemen die ik in de praktijk ben tegengekomen met DAO. Die had ik niet moeten posten.
FR2 is wellicht te algemeen geformuleerd. Mijn specifieke situatie is dat ik 's ochtends vroeg al wil weten wat de volgende dag gaat doen, maar jullie hebben gelijk dat DAO hier in de meeste gevallen ruim op tijd bij is.
Over FR7 en de opmerking over de horizon:
Ik heb een Zendure SolarFlow setup waarbij de omvormer zelf geen NOM-logica heeft voor zover ik weet. DAO zet de balance switch en stopt dan met schrijven, wat voor mijn setup betekent dat ik zelf iets moet bouwen voor real-time bijsturing. Dat is inderdaad geen DAO-probleem maar een hardware-probleem aan mijn kant. De opmerking over de verkeerde horizon klopt — ik heb ten onrechte realtime control requirements in een setpoint-scheduler gegooid.
Wat wel interessant zou kunnen zijn: een wiki-pagina of voorbeeldpakket voor gebruikers met AC-gekoppelde systemen die geen eigen NOM-logica hebben. Ik zie in de thread dat @pimNH, @KC27 en anderen vergelijkbare oplossingen hebben gebouwd — als we dat samenvoegen in een community-voorbeeld in de wiki scheelt dat toekomstige gebruikers met hetzelfde hardware-profiel een hoop uitzoekwerk. Maar dat is iets om met de betrokkenen op te pakken, niet iets voor corneel27 om in DAO-core te bouwen.
Excuses voor de ruis in de thread.
Zoals @CopyCatz al aangeeft vergt het gebruik van HA en DAO echt wat leren en doen met dit soort tooling. Dáár kun je AI heel goed voor gebruiken, je laten inspireren om je gewenste functionaliteit op een bepaalde manier op te lossen.
Het opnemen van kant en klaar voorbeelden op de wiki gaat het niet oplossen. Elke situatie en elke hardware is net weer anders en vergt dan net weer wat aanpassingen. En die kunnen de mensen die dit soort voorbeelden dan klakkeloos copy en pasten, niet zelf bedenken. Dan moet je daar weer uitleg over geven in deze thread of op de wiki, en voordat je het weet moeten we een complete support afdeling oprichten….Een bepaalde vorm van zelfredzaamheid op het toepassen van dit soort tooling is gewoon nodig. En weet je, het puzzelen om iets werkend te krijgen is juist het grootste deel van de lol 😜
Is het een idee om je vraag over de NOM sturing te stellen in de Zendure topics hier op tweakers? (er is er zelfs één voor Zendure in HA). Er zijn vast meer mensen die de NOM sturing in HA hebben uitgewerkt of weten hoe je die moet aan en uit schakelen.
Voorbeeld (met name het stuk rond 15/16 uur):
:strip_exif()/f/image/IdyyvPp1UpOjBYRqArDzT0ZL.png?f=user_large)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| 2026-05-09 08:50:08 info: Inzet-factor laden BMW IX1 per stap uur 0.0A 6.0A 8.0A 10.0A 12.0A 14.0A 16.0A cons power 08:45 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 09:00 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 09:15 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 09:30 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 09:45 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 10:00 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 10:15 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 10:30 1.00(1.0) 0.00(0.0) 0.00(1.0) 0.00(0.0) -0.00(0.0) 0.00(0.0) -0.00(0.0) 0.000 5.520 10:45 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) -0.00(0.0) -0.000 0.000 11:00 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 11:15 0.96(1.0) 0.04(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.039 4.140 11:30 0.00(0.0) 0.00(0.0) 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 1.380 5.520 11:45 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 11.040 12:00 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 11.040 12:15 0.00(0.0) 0.00(0.0) 0.00(0.0) -0.00(0.0) -0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 11.040 12:30 0.00(0.0) 0.00(0.0) 0.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 16.560 12:45 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 11.040 13:00 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) -0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 11.040 13:15 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(1.0) 0.00(1.0) 1.00(1.0) 2.760 28.980 13:30 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(1.0) 1.00(1.0) 2.760 20.700 13:45 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 11.040 14:00 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(1.0) 1.00(1.0) 2.760 20.700 14:15 0.85(1.0) 0.00(0.0) 0.00(0.0) 0.15(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.267 6.900 14:30 0.43(1.0) 0.57(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) -0.00(0.0) 0.594 4.140 14:45 0.86(1.0) 0.00(0.0) 0.14(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.197 5.520 15:00 0.90(1.0) 0.00(0.0) 0.10(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.134 5.520 15:15 0.97(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.03(1.0) 0.086 11.040 15:30 0.98(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.02(1.0) 0.00(0.0) 0.00(0.0) 0.037 8.280 15:45 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) -0.00(0.0) -0.000 0.000 16:00 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 16:15 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 16:30 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 |
Mijn voorkeur zou daarom uitgaan naar één laadblok waarbij de hoeveelheid kWh per kwartier door de laadstroom geregeld wordt. Is er een manier om dit te bereiken?
Is dit nou ook al een sneaky preview naar een prognose feature 👀KC27 schreef op vrijdag 8 mei 2026 @ 23:19:
[...]
Dit heeft alles te maken met de merit-order systematiek waarmee de day-ahead prijzen tot stand komen.
Veel producenten met zon- en windparken bieden hun (geplande) productie aan met een prijs van minimaal 0.00 euro (willen geen verlies maken). Zodra er meer dan de vraag wordt aangeboden tegen 0 euro wordt daarop de prijs bepaald.
De prijs zakt onder nul als er genoeg producenten zijn die ook bij negatieve prijzen gewoon blijven produceren en met die lagere prijzen aanbieden:
- energiebedrijven van consumenten met een vast contract moeten van hun overschot af
- producenten met een subsidie per geproduceerde kWh gaan door tot de subsidiegrens.
Als er dan ook nog genoeg vraag is (bij die negatieve prijs) zakt het evenwicht van vraag en aanbod alsnog "onder nul".
Hieronder een grafiek van een tool die de day-ahead prijs zes dagen vooruit voorspelt op basis van
- de verwachte consumptie in Nederland enerzijds en
- anderzijds geaccumuleerd: de productie van wind op land, wind op zee en zon.
Zondag wordt mogelijk weer een dag met day ahead prijzen onder nul (disclaimer: dit model heeft de neiging om pieken en dalen te overschatten).
[Afbeelding]
Die zou mijn enige probleem waar ik nog geen oplossing voor heb oplossen... Auto moet morgen om 7 vol zijn. Maar hij gaat niet plannen omdat het buiten de berekenings horizon ligt.
[ Voor 5% gewijzigd door thomvh op 09-05-2026 10:50 ]
Super nuttige feedback! Wordt zeer gewaardeerd!balk schreef op zaterdag 9 mei 2026 @ 07:23:
[...]
Hier draait het, maar ik geloof niet dat ik gebruik maak van de delen die je verandert hebt. Wel blijft het lastig om te zien wanneer iets fout gaat. Ik heb de test versie normaal uit staan en test alleen wanneer je een nieuwe versie hebt. Dat betekent dat de meteo/epex/ml altijd achterlopen.
Na run met debug komt er een groen vinkje maar geen resultaat, en ook geen duidelijke foutmelding. Hierdoor is het moeilijk achterhalen wat je moet doen om het aan de praat te krijgen. Ik weet intussen wat ik moet doen, maar het zou duidelijker kunnen.
===
na ophalen van prijzen krijg ik dit bij run:
[...]
===
na ophalen meteo verdwijnt de foutmelding. Nu kan ik wel een debug run doen, met groen vinkje als resultaat. De eerste keer dat ik dan terug ga naar Home zag ik nog de niet geoptimaliseerde grafiek, na nog een run wel.
===
Uiteindelijk kon ik wel een ml training afstarten maar kwam ik op deze melding:code:en dit in de addon log in HA:
1 2 3 4 5 <!doctype html> <html lang=en> <title>500 Internal Server Error</title> <h1>Internal Server Error</h1> <p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>code:Ik weet dat ik dan de ML training met een scheduler moet starten, maar dit verdient wel wat polijsting
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15[2026-05-09 07:50:05,126] ERROR in app: Exception on /log [GET] Traceback (most recent call last): File "/root/dao/venv/day_ahead/lib/python3.13/site-packages/flask/app.py", line 1511, in wsgi_app response = self.full_dispatch_request() File "/root/dao/venv/day_ahead/lib/python3.13/site-packages/flask/app.py", line 919, in full_dispatch_request rv = self.handle_user_exception(e) File "/root/dao/venv/day_ahead/lib/python3.13/site-packages/flask/app.py", line 917, in full_dispatch_request rv = self.dispatch_request() File "/root/dao/venv/day_ahead/lib/python3.13/site-packages/flask/app.py", line 902, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ File "/root/dao/webserver/app/routes.py", line 652, in show_log logfile = task_state["logfile"] ~~~~~~~~~~^^^^^^^^^^^ KeyError: 'logfile'
Ik ben wel heel erg blij met DAO overigens! Petje af voor al het werk dat er verzet wordt door jou en de andere programmeurs.
Sterker nog, beide Zendure integraties die veel gebruikt worden bieden gewoon NOM modus mits ze toegang hebben tot een P1 meter.Torch1969 schreef op zaterdag 9 mei 2026 @ 09:27:
Is het een idee om je vraag over de NOM sturing te stellen in de Zendure topics hier op tweakers? (er is er zelfs één voor Zendure in HA). Er zijn vast meer mensen die de NOM sturing in HA hebben uitgewerkt of weten hoe je die moet aan en uit schakelen.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
| alias: Zendure Battery Control DAO v2
description: >
Controls Zendure battery operation mode based on balance switch and feed-in
power. Limits charging power so that P1 active power does not exceed 16000 W.
triggers:
- entity_id:
- input_boolean.dao_bat_balance_switch
- input_number.dao_bat_power_feedin
- sensor.p1_meter_3c39e7284ed6_active_power
trigger: state
conditions: []
actions:
- choose:
- conditions:
- condition: state
entity_id: input_boolean.dao_bat_balance_switch
state: "on"
sequence:
- target:
entity_id: select.zendure_manager_operation_2
data:
option: smart
action: select.select_option
- conditions:
- condition: state
entity_id: input_boolean.dao_bat_balance_switch
state: "off"
sequence:
- target:
entity_id: select.zendure_manager_operation_2
data:
option: manual
action: select.select_option
- conditions:
- condition: template
value_template: "{{ states('input_number.dao_bat_power_feedin') | float != 0 }}"
sequence:
- target:
entity_id: select.zendure_manager_operation_2
data:
option: manual
action: select.select_option
- target:
entity_id: number.zendure_manager_manual_power
action: number.set_value
data:
value: >
{% set desired = (states('input_number.dao_bat_power_feedin') | float) *
-1 %} {% set p1 = states('sensor.p1_meter_3c39e7284ed6_active_power') |
float(0) %} {% if desired > 0 %}
{# If charging, cap charging to avoid exceeding 16 kW grid draw #}
{{ [desired, [16000 - p1, 0] | max] | min }}
{% else %}
{# Discharging does not increase grid draw, keep it #}
{{ desired }}
{% endif %}
mode: single |
Ik begin mij steeds meer te irriteren aan die lappen AI poep.hemertje schreef op vrijdag 8 mei 2026 @ 18:38:
@KC27 @simnet @Beekforel @Bravo de laatste week met vriend Claude (Code) verder inhoudelijk in DAO, thuisbatterijen en NOM gedoken.
Van daaruit een aantal Feature Requests welk naar mijn idee een toegevoegde waarde kan bieden aan DAO en hun eindgebruikers.
Een overzichtje met hulp van Claude... ik ben benieuwd naar jou en anderen hun visie en mening
DAO Feature Requests
Hieronder een aantal feature requests voor de Day Ahead Optimizer (DAO), opgesteld na vergelijkende analyse van een aantal vergelijkbare projecten: bvweerd/battery_controller (Dynamic Programming optimizer), Utini2000/Zendure-Solarflow-Local-HomeAssistant (productie-grade NoM controller) en b3nn0/EpexPredictor (LightGBM EPEX prijsvoorspelling). Aangevuld met eigen implementatie-ervaring op een Zendure 3× SolarFlow 2400 AC+ setup met SolarEdge 8kW omvormer.
---
FR-001 — entity pv switch in de solar-sectie (AC-omvormer) | Prioriteit: Hoog
DAO ondersteunt "entity pv switch" al in de battery/dc-sectie, maar niet in de solar (AC-omvormer) sectie. Bij negatieve EPEX-prijzen zetten AC-omvormers zoals SolarEdge, Fronius en SMA zichzelf automatisch uit via hun eigen app-logica. DAO weet dit niet en houdt rekening met PV-productie die er feitelijk niet is. Het gevolg: DAO verwacht PV-overschot en plant geen grid-import in, terwijl de werkelijkheid PV = 0W is. De accu laadt dan onnodig uit het grid tegen positieve prijs. De forecast-error loopt op tot 3-8 kWh per curtailment-dag.
Gewenste oplossing: voeg "entity pv switch" toe als optioneel veld in de solar (AC) sectie, identiek aan de bestaande implementatie in de dc/battery-sectie. Gedrag: als entity pv switch = off rekent DAO pv_forecast = 0 voor die installatie, en DAO mag de boolean zelf op off zetten bij negatieve terugleververgoeding.code:Huidige workaround: input_boolean + automation die de curtailment-sensor synchroniseert. Werkt, maar is omslachtig en niet officieel ondersteund.
1 2 3 4 5 6 7 8 9"solar": [ { "name": "SolarEdge 8kW", "entity pv switch": "input_boolean.dao_pv_solaredge_active", "ml_prediction": "true", "entities sensors": "sensor.solaredge_lifetime_energy", "strings": [...] } ]
---
FR-002 — Pre-13:00 prijsfallback vóór Nordpool-publicatie | Prioriteit: Hoog
Nordpool NL publiceert dag-vooruit prijzen rond 13:00 CET. DAO draait zijn optimalisatie op vaste tijdstippen en gebruikt vóór 13:00 statische fallback-waarden (regular high / regular low) voor de volgende dag. Het gevolg: de ochtend-optimalisatie (bijv. 07:00) plant de volgende dag verkeerd in. Bij verwachte piekprijzen (Dunkelflaute) wordt de accu te vroeg leeggemaakt; bij verwachte negatieve prijzen wordt de accu niet maximaal geladen vóór de goedkope periode.
Gewenste oplossing optie A: integratie met EpexPredictor (https://github.com/b3nn0/EpexPredictor) als optionele prijsfallback-bron. Dit project gebruikt LightGBM op weerdata + ENTSO-E load + gasprijs en ondersteunt de NL regio. Nauwkeurigheid: nacht <0,5 ct/kWh, pieken 1-1,5 ct/kWh fout. Publieke API is gratis beschikbaar.code:Gewenste oplossing optie B: een "source_day_ahead_fallback" veld dat een HA-sensor accepteert met forecast-attributen, zodat gebruikers zelf een prijsmodel kunnen koppelen. Referentie: bvweerd/battery_controller ALGORITHM.md §9 en §14 voor een zelflerend historisch prijsmodel op basis van weerdata en recorder-data.
1 2 3 4 5 6"prices": { "source_day_ahead": "nordpool", "source_forecast_fallback": "epexpredictor", "epexpredictor_url": "https://epexpredictor.batzill.com/prices_short", "epexpredictor_region": "NL" }
---
FR-003 — Shadow price als horizon-eindconditie voor batterij | Prioriteit: Middel
DAO's batterij-optimalisatie gebruikt "entity min soc end opt" en "entity max soc end opt" als harde eindconditie. Deze waarden zijn statisch of handmatig ingesteld. De optimizer weet daardoor niet wat opgeslagen energie ná de planningshorizon waard is. Het gevolg: bij horizon-einde wordt de accu irrationeel leeg- of voorgepland, en gebruikers moeten dao_min_soc_einde_opt handmatig bijstellen op basis van verwachtingen voor de volgende dag.
Gewenste oplossing: een rolling shadow price als terminal condition. De shadow price is de marginale waarde van 1 kWh opgeslagen energie, afgeleid uit de vorige optimizer-run. Na ongeveer een week convergeert dit naar een stabiele waarde.code:Praktisch effect: de optimizer stopt met irrationeel ontladen vlak voor het horizon-einde en dao_min_soc_einde_opt hoeft niet meer handmatig bijgesteld te worden. Volledige wiskundige uitwerking in bvweerd/battery_controller ALGORITHM.md §5 en §9.
1 2 terminal_value[s] = stored_kwh[s] x shadow_price shadow_price = afgeleid uit vorige optimizer-run (convergeert ~1 week)
---
FR-004 — Oscillation filter (anti-micro-cyclus) | Prioriteit: Middel
DAO kan kwartieren plannen waarbij de accu afwisselend laadt en ontlaadt met een klein prijsverschil. Elke cyclus kost degradatie plus round-trip rendementsverlies. De minimaal winstgevende spread voor arbitrage is:code:Laden bij 0,10 €/kWh en ontladen bij 0,13 €/kWh geeft slechts 0,03 €/kWh spread, wat na degradatiekosten niet winstgevend is. Gewenste oplossing: een post-processing filter op de optimizer-output waarbij een laad→ontlaad of ontlaad→laad overgang die minder dan min_arbitrage_spread oplevert wordt vervangen door idle. Alternatief als config-parameter: "min_price_spread": 0.03 die de optimizer zelf meeneemt in de kostenfunctie. Referentie: bvweerd/battery_controller ALGORITHM.md §8.1 voor het iteratieve lookahead-algoritme.
1 2 3min_spread = (2 x cycle_cost_per_kWh + min_price_spread) / sqrt(RTE) = (2 x 0.015 + 0.005) / sqrt(0.93) ≈ 0.036 EUR/kWh
---
FR-005 — Write-throttling / dispatch cooldown voor battery setpoint | Prioriteit: Laag
DAO schrijft naar "entity set power feedin" bij elke optimizer-tick, ook als de waarde identiek is aan de vorige. Dit genereert onnodig HA state-changes, database-writes en downstream REST-calls naar omvormers. Gewenste oplossing: schrijf alleen naar entity set power feedin als de waarde ≥ X Watt afwijkt van de vorige (configureerbaar, bijv. 25W), of als meer dan Y seconden verstreken zijn zonder write (heartbeat, bijv. 60s). Inspiratie: Utini2000/zendure_control.yaml gebruikt een vergelijkbaar dispatch-cooldown patroon met een mismatch-check en force-flag.
---
FR-006 — EpexPredictor configuratievoorbeeld in DOCS.md | Prioriteit: Laag
Verzoek om in DAO DOCS.md een officieel configuratievoorbeeld toe te voegen voor EpexPredictor als pre-13:00 prijsfallback sensor. Dit betreft alleen documentatie, geen code-wijziging.code:Bron: https://github.com/b3nn0/EpexPredictor — NL regio ondersteund, gratis publieke API, self-hosting mogelijk via Docker Compose, ENTSO-E API key verhoogt nauwkeurigheid significant voor NL.
1 2 3 4 5 6 7 8 9 10 11 12sensor: - platform: rest resource: "https://epexpredictor.batzill.com/prices_short?region=NL&surcharge=10.154&taxPercent=21&unit=EUR_PER_KWH&hours=48" method: GET unique_id: epex_price_prediction_nl name: "EPEX Price Prediction NL" unit_of_measurement: "EUR/kWh" scan_interval: 3600 value_template: "{{ value_json.t[0] }}" json_attributes: - s - t
---
FR-007 — Native zero-export / balance controller met hysterese | Prioriteit: Hoog
DAO ondersteunt via "entity balance switch" al een balanceerstand, maar de daadwerkelijke regeling van het setpoint tijdens balanceren valt volledig buiten DAO. DAO schrijft dan geen waarden meer naar "entity set power feedin" en verwacht dat de omvormer zelf balanceert. Dit werkt goed voor hybride omvormers met ingebouwde zero-export logica (bijv. Victron ESS, SolarEdge StorEdge), maar niet voor AC-gekoppelde batterijsystemen zoals Zendure, SolarFlow, Enphase IQ Battery, of andere systemen die via een HA-helper worden aangestuurd. Voor die systemen moet de gebruiker zelf een volledige real-time regelaar bouwen.
Bewijs van de noodzaak: onze productie-implementatie
Testopstelling: Zendure 3x SolarFlow 2400 AC+ (24,48 kWh totaal, 3-fase, 1 unit per fase), SolarEdge 8kW AC-omvormer, Panasonic Aquarea 7kW warmtepomp, HomeWizard P1 meter (1s update), NL dynamische prijzen via Nordpool. Aansturing via @gielz en @gast777 proxy over zenSDK REST.
Omdat DAO tijdens balance-uren stopt met schrijven maar Zendure geen eigen zero-export logica heeft, was volledige import/export ongecontroleerd. Oplossing: een bang-bang controller met hysterese-timers gebouwd als HA-automatisering bovenop DAO. Gefaseerde implementatie:
Fase 1 — helpers (geen impact op bestaande DAO werking):code:Fase 2 — bang-bang controller (elke 6s tijdens balance, SoC-aware power limits):
1 2 3 4 5 6 7 8 9 10 11 12 13 input_number: dao_zendure_target_power: # actuator tussen DAO en omvormer, bereik -3000..+3000 W dao_nom_import_threshold: # default 80 W — drempel voor laden dao_nom_export_threshold: # default 200 W — drempel voor ontladen dao_nom_bias: # default 7 W — kleine offset richting export dao_nom_timer_seconds: # default 10 s — hysterese-timer, tunable 5-60s input_select: dao_nom_active_mode: # charge / discharge / idle timer: dao_nom_import_arm: # hysterese-timer import dao_nom_export_arm: # hysterese-timer exportcode:Fase 2.5 — uitbreidingen:
1 2 3 4 5 6 7 8 9 10 11 12 13 # Logica (vereenvoudigd): # grid = P1_meting - bias # als grid > import_threshold: arm import_timer → na 10s: mode = discharge # als grid < -export_threshold: arm export_timer → na 10s: mode = charge # anders: cancel beide timers (dode zone) # # target binnen huidige mode: # discharge: target = -clamp(grid, 0, max_discharge_voor_SoC) # charge: target = +clamp(-grid, 0, max_charge_voor_SoC) # # SoC-aware limieten (pimNH-tabel, aangepast aan 3000W Zendure max): # laden: SoC<88% → 3000W, SoC<93% → 2000W, SoC<95% → 800W, SoC<98% → 300W, SoC<99% → 150W, anders 60W # ontladen: SoC>30% → 3000W, SoC>20% → 2000W, SoC>15% → 1500W, anders 300Wcode:Fase 2.6 — PV-curtailment workaround (zie ook FR-001):
1 2 3 4 5 6 # Grid-overbelastings-clamp (safety, normale werking raakt dit nooit): # grid > 6000W → forceer max discharge | grid < -5000W → forceer max charge # EV-aware force-stop: # bij EV charge-start → target = 0, mode = idle # bij EV charge-einde → herstart initcode:Gevraagde DAO-feature
1 2 3 # input_boolean.dao_pv_solaredge_active wordt gesynchroniseerd met # sensor.dao_pv_curtailment_active (all-in prijs < drempel). # Zolang FR-001 niet upstream beschikbaar is: handmatige sync via automation.
Native ondersteuning voor een zero-export regelaar als optionele module binnen DAO, actief tijdens balance-uren. Minimale vereisten: configureerbare import/export drempels, hysterese-timer (anti-flapping), SoC-aware vermogensbegrenzing, en EV-pause logica. De regelaar schrijft naar "entity set power feedin" tijdens balance-uren in plaats van te stoppen met schrijven.
Dit voorkomt dat elke gebruiker met een AC-gekoppeld batterijsysteem zelf een volledige real-time regelaar moet bouwen. De Tweakers DAO-thread toont meerdere vergelijkbare implementaties (@pimNH , @KC27 , @Bravo , @Xom , @Beekforel ) — allemaal varianten van dezelfde ontbrekende DAO-functionaliteit.
Referenties: Utini2000/Zendure-Solarflow-Local-HomeAssistant (bewezen 1-15W precisie op productie), @pimNH bang-bang implementatie (Tweakers DAO-topic), @KC27 dubbele-helper patroon (Tweakers DAO-topic).
---
Samenvatting
FR-001 entity pv switch AC-omvormer — Hoog — Bugfix/Feature
FR-002 Pre-13:00 prijsfallback / EpexPredictor — Hoog — Feature
FR-003 Shadow price terminal condition — Middel — Algoritme
FR-004 Oscillation filter — Middel — Algoritme
FR-005 Write-throttling setpoint — Laag — Optimalisatie
FR-006 EpexPredictor documentatie — Laag — Docs
FR-007 Native zero-export / balance controller — Hoog — Feature
FR-001 en FR-007 hebben de meeste directe impact. FR-007 in het bijzonder omdat meerdere gebruikers in de Tweakers DAO-thread onafhankelijk van elkaar dezelfde workaround hebben gebouwd — een duidelijk signaal dat dit een structureel ontbrekende maar veel gewenste feature is.
Alvast bedankt voor de reacties!
![]()
En kun je niet gewoon GitHub gebruiken en issues aanmaken voor je feature requests?
edit: correctie, waarom neem je niet de moeite om GitHub issues aan te maken voor je feature requests??
en als toevoeging, lees aub even de huisregels rondom gebruik AI, oa.:
"Kunstmatige intelligentie (AI) mag als hulpmiddel worden gebruikt, maar grotendeels gegenereerde teksten zijn niet toegestaan. "
Misschien kun je het laden als apparaat configureren, verschillende programma's voor verschillende lengtes? Ik heb geen EV maar ik heb mijn boiler wel als apparaat geconfigureerd om zo af te dwingen dat hij iedere dag aan gaat.PcFer schreef op zaterdag 9 mei 2026 @ 10:03:
De komende tijd wil ik het inplannen van de EV door DAO wat meer onderzoeken. Tot nu toe merk ik dat de strategie "minimale kosten" vaak uitkomt op een situatie waarbij er niet aan één stuk geladen wordt, maar dat er zelfs delen van kwartieren wordt geladen.
Voorbeeld (met name het stuk rond 15/16 uur):
[Afbeelding]code:Ik begrijp dat het een resultaat is van een rekenkundige optimalisatie, maar dit pendelgedrag is in mijn ogen slechter voor de hardware en bovendien krijg je elk kwartier een melding van de auto app dat het laden gestart/gestopt is.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 2026-05-09 08:50:08 info: Inzet-factor laden BMW IX1 per stap uur 0.0A 6.0A 8.0A 10.0A 12.0A 14.0A 16.0A cons power 08:45 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 09:00 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 09:15 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 09:30 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 09:45 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 10:00 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 10:15 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 10:30 1.00(1.0) 0.00(0.0) 0.00(1.0) 0.00(0.0) -0.00(0.0) 0.00(0.0) -0.00(0.0) 0.000 5.520 10:45 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) -0.00(0.0) -0.000 0.000 11:00 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 11:15 0.96(1.0) 0.04(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.039 4.140 11:30 0.00(0.0) 0.00(0.0) 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 1.380 5.520 11:45 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 11.040 12:00 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 11.040 12:15 0.00(0.0) 0.00(0.0) 0.00(0.0) -0.00(0.0) -0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 11.040 12:30 0.00(0.0) 0.00(0.0) 0.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 16.560 12:45 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 11.040 13:00 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) -0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 11.040 13:15 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(1.0) 0.00(1.0) 1.00(1.0) 2.760 28.980 13:30 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(1.0) 1.00(1.0) 2.760 20.700 13:45 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 11.040 14:00 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(1.0) 1.00(1.0) 2.760 20.700 14:15 0.85(1.0) 0.00(0.0) 0.00(0.0) 0.15(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.267 6.900 14:30 0.43(1.0) 0.57(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) -0.00(0.0) 0.594 4.140 14:45 0.86(1.0) 0.00(0.0) 0.14(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.197 5.520 15:00 0.90(1.0) 0.00(0.0) 0.10(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.134 5.520 15:15 0.97(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.03(1.0) 0.086 11.040 15:30 0.98(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.02(1.0) 0.00(0.0) 0.00(0.0) 0.037 8.280 15:45 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) -0.00(0.0) -0.000 0.000 16:00 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 16:15 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 16:30 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000
Mijn voorkeur zou daarom uitgaan naar één laadblok waarbij de hoeveelheid kWh per kwartier door de laadstroom geregeld wordt. Is er een manier om dit te bereiken?
Ter informatie, een stukje geschiedenis en info over de laatste weken.
DAO draait hier nu een paar weken. Werkt prima voor het bepalen wanneer de accu moet laden/ontladen op basis van de prijzen. Maar ik ervaarde een probleem: zodra DAO de accu in "balance mode" zet voor nul op de meter, stopt DAO met het schrijven van setpoints. Mijn Zendure heeft geen eigen zero-export logica, dus dan gebeurde er niets meer. Import en export liepen ongecontroleerd.
Ik heb samen met Claude Code (AI programmeerassistent) een controller gebouwd die actief wordt tijdens die balance-uren. Die kijkt elke 6 seconden naar de P1 meter. Als we te veel stroom van het net halen (>80W) wacht hij 10 seconden. Blijft het zo? Dan gaat de accu ontladen om dat te compenseren. Omgekeerd bij terugleveren (>200W): dan gaat de accu laden.
Die wachttijd voorkomt dat hij heen en weer schakelt als de waterkoker even aangaat. En we hebben limieten ingebouwd afhankelijk van hoe vol de accu is. Bijna vol? Dan maar langzaam laden. Bijna leeg? Dan minder hard ontladen. Bij starten van de EV laadpaal forceert hij idle zodat er geen conflicten ontstaan.
Mijn SolarEdge zet zichzelf uit bij negatieve prijzen via de app. DAO wist dat niet, dus die rekende met PV opbrengst die er niet was. Met hulp van de AI heb ik een sensor gemaakt die checkt of de all-in prijs onder nul is, en die synct met een boolean in DAO. Daardoor weet DAO: panelen staan uit, reken met 0W PV.
Ik had eerst alle panelen op 0 graden gezet in DAO, maar dat klopte niet. Met de iPhone heb ik alles opgemeten: plat dak op 219 graden, zuidgevel 203 graden, etc. Samen met de AI omgezet naar DAO's coordinaten en nu staan alle 5 strings correct. ML model opnieuw getraind, Forecast.Solar devices geüpdatet. Totale capaciteit is 12.37 kWp.
Draait sinds vanavond. DAO denkt per kwartier na, onze oplossing per seconde. Eindelijk echt 24/7 nul op de meter.
Net live gezet. DAO op strategie (per kwartier), onze controller op tactiek (per seconde). De komende nacht de eerste test van écht 24/7 nul op de meter. Hoop ik dan
Alle code: github.com/hemertje/home-assistant-dao-zendure-nom-controller
Willen jullie eens meelezen , input is gewenst...
Gasloos 2019 + WP Panasonic H-serie 7kW + 300 liter boilervat + PV 12.415Wp + Home Assistant + Hyundai Ioniq 6 First Edition + Zaptec laadpaal
@wmc Bedankt voor het delen! Ik heb inmiddels een andere route gekozen met een custom bang-bang controller (inspiratie uit het DAO topic van @pimNH en @KC27).wmc schreef op zaterdag 9 mei 2026 @ 14:30:
Mijn automation voor de koppeling van DAO en de Zendure integratie. Hierbij zit ook een veiligheid zodat de hoofdzekering er niet uit klap als er door een ongeregeld apparaat ineens veel vermogen wordt getrokken (waterkoker, stofzuiger, tafel cirkelzaag etc)code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113alias: Zendure Battery Control DAO v2 description: > Controls Zendure battery operation mode based on balance switch and feed-in power. Limits charging power so that P1 active power does not exceed 16000 W. triggers: - entity_id: - input_boolean.dao_bat_balance_switch - input_number.dao_bat_power_feedin - sensor.p1_meter_3c39e7284ed6_active_power trigger: state conditions: [] actions: - choose: - conditions: - condition: state entity_id: input_boolean.dao_bat_balance_switch state: "on" sequence: - target: entity_id: select.zendure_manager_operation_2 data: option: smart action: select.select_option - conditions: - condition: state entity_id: input_boolean.dao_bat_balance_switch state: "off" sequence: - target: entity_id: select.zendure_manager_operation_2 data: option: manual action: select.select_option - conditions: - condition: template value_template: "{{ states('input_number.dao_bat_power_feedin') | float != 0 }}" sequence: - target: entity_id: select.zendure_manager_operation_2 data: option: manual action: select.select_option - target: entity_id: number.zendure_manager_manual_power action: number.set_value data: value: > {% set desired = (states('input_number.dao_bat_power_feedin') | float) * -1 %} {% set p1 = states('sensor.p1_meter_3c39e7284ed6_active_power') | float(0) %} {% if desired > 0 %} {# If charging, cap charging to avoid exceeding 16 kW grid draw #} {{ [desired, [16000 - p1, 0] | max] | min }} {% else %} {# Discharging does not increase grid draw, keep it #} {{ desired }} {% endif %} mode: single
Reageert per seconde met hysterese-timers. Werkt samen met Gielz + gast777.
Code en documentatie: zie de Github link hierboven
Iedereen die geïnteresseerd is: voel je vrij om te gebruiken/aan te passen!
Gasloos 2019 + WP Panasonic H-serie 7kW + 300 liter boilervat + PV 12.415Wp + Home Assistant + Hyundai Ioniq 6 First Edition + Zaptec laadpaal
geheugen geupdatethemertje schreef op dinsdag 5 mei 2026 @ 23:11:
[...]
ik zie wel dat mijn RAM op zijn Max loopt met 4GB intern
[Afbeelding]
eens op zoek naar een 16GB RAM module voor de HP t530 thin client
Gasloos 2019 + WP Panasonic H-serie 7kW + 300 liter boilervat + PV 12.415Wp + Home Assistant + Hyundai Ioniq 6 First Edition + Zaptec laadpaal
Ik denk dat jouw opmerking hout snijdt.PcFer schreef op zaterdag 9 mei 2026 @ 10:03:
De komende tijd wil ik het inplannen van de EV door DAO wat meer onderzoeken. Tot nu toe merk ik dat de strategie "minimale kosten" vaak uitkomt op een situatie waarbij er niet aan één stuk geladen wordt, maar dat er zelfs delen van kwartieren wordt geladen.
Voorbeeld (met name het stuk rond 15/16 uur):
[Afbeelding]code:Ik begrijp dat het een resultaat is van een rekenkundige optimalisatie, maar dit pendelgedrag is in mijn ogen slechter voor de hardware en bovendien krijg je elk kwartier een melding van de auto app dat het laden gestart/gestopt is.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 2026-05-09 08:50:08 info: Inzet-factor laden BMW IX1 per stap uur 0.0A 6.0A 8.0A 10.0A 12.0A 14.0A 16.0A cons power 08:45 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 09:00 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 09:15 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 09:30 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 09:45 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 10:00 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 10:15 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 10:30 1.00(1.0) 0.00(0.0) 0.00(1.0) 0.00(0.0) -0.00(0.0) 0.00(0.0) -0.00(0.0) 0.000 5.520 10:45 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) -0.00(0.0) -0.000 0.000 11:00 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 11:15 0.96(1.0) 0.04(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.039 4.140 11:30 0.00(0.0) 0.00(0.0) 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 1.380 5.520 11:45 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 11.040 12:00 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 11.040 12:15 0.00(0.0) 0.00(0.0) 0.00(0.0) -0.00(0.0) -0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 11.040 12:30 0.00(0.0) 0.00(0.0) 0.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 16.560 12:45 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 11.040 13:00 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) -0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 11.040 13:15 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(1.0) 0.00(1.0) 1.00(1.0) 2.760 28.980 13:30 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(1.0) 1.00(1.0) 2.760 20.700 13:45 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 1.00(1.0) 2.760 11.040 14:00 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(1.0) 1.00(1.0) 2.760 20.700 14:15 0.85(1.0) 0.00(0.0) 0.00(0.0) 0.15(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.267 6.900 14:30 0.43(1.0) 0.57(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) -0.00(0.0) 0.594 4.140 14:45 0.86(1.0) 0.00(0.0) 0.14(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.197 5.520 15:00 0.90(1.0) 0.00(0.0) 0.10(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.134 5.520 15:15 0.97(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.03(1.0) 0.086 11.040 15:30 0.98(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.02(1.0) 0.00(0.0) 0.00(0.0) 0.037 8.280 15:45 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) -0.00(0.0) -0.000 0.000 16:00 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 16:15 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000 16:30 1.00(1.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.00(0.0) 0.000 0.000
Mijn voorkeur zou daarom uitgaan naar één laadblok waarbij de hoeveelheid kWh per kwartier door de laadstroom geregeld wordt. Is er een manier om dit te bereiken?
Ik kan zelf niet overzien in hoeverre het aan/uit zetten van een lader slecht is.
Maar het met meer of minder vermogen laten laden lijkt me geen invloed hebben op de levensduur van de laadpaal en/of de boardlader.
Ik zou een optionele penalty kunnen introduceren die iedere tussentijdse start/stop actie een virtuele prijs aanrekent zodat dit alleen gebeurt als de daarmee bereikbare winst hoger is dan de penalty.
Lijkt dat wat?
WP: Alpha Innotec MSW2-6S | PV: 20 x 300 Wp AEG | ACCU: 2x16x280Ah LiFePO4 3 x Multiplus II 48/3000 | DYN: Tibber | Gasloos | Day Ahead Optimizer
Dank voor je testen en de terugkoppeling.balk schreef op zaterdag 9 mei 2026 @ 07:23:
[...]
Hier draait het, maar ik geloof niet dat ik gebruik maak van de delen die je verandert hebt. Wel blijft het lastig om te zien wanneer iets fout gaat. Ik heb de test versie normaal uit staan en test alleen wanneer je een nieuwe versie hebt. Dat betekent dat de meteo/epex/ml altijd achterlopen.
Na run met debug komt er een groen vinkje maar geen resultaat, en ook geen duidelijke foutmelding. Hierdoor is het moeilijk achterhalen wat je moet doen om het aan de praat te krijgen. Ik weet intussen wat ik moet doen, maar het zou duidelijker kunnen.
===
na ophalen van prijzen krijg ik dit bij run:
[...]
===
na ophalen meteo verdwijnt de foutmelding. Nu kan ik wel een debug run doen, met groen vinkje als resultaat. De eerste keer dat ik dan terug ga naar Home zag ik nog de niet geoptimaliseerde grafiek, na nog een run wel.
===
Uiteindelijk kon ik wel een ml training afstarten maar kwam ik op deze melding:code:en dit in de addon log in HA:
1 2 3 4 5 <!doctype html> <html lang=en> <title>500 Internal Server Error</title> <h1>Internal Server Error</h1> <p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>code:Ik weet dat ik dan de ML training met een scheduler moet starten, maar dit verdient wel wat polijsting
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15[2026-05-09 07:50:05,126] ERROR in app: Exception on /log [GET] Traceback (most recent call last): File "/root/dao/venv/day_ahead/lib/python3.13/site-packages/flask/app.py", line 1511, in wsgi_app response = self.full_dispatch_request() File "/root/dao/venv/day_ahead/lib/python3.13/site-packages/flask/app.py", line 919, in full_dispatch_request rv = self.handle_user_exception(e) File "/root/dao/venv/day_ahead/lib/python3.13/site-packages/flask/app.py", line 917, in full_dispatch_request rv = self.dispatch_request() File "/root/dao/venv/day_ahead/lib/python3.13/site-packages/flask/app.py", line 902, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^ File "/root/dao/webserver/app/routes.py", line 652, in show_log logfile = task_state["logfile"] ~~~~~~~~~~^^^^^^^^^^^ KeyError: 'logfile'
Ik ben wel heel erg blij met DAO overigens! Petje af voor al het werk dat er verzet wordt door jou en de andere programmeurs.
Ik ga kijken of en hoe ik deze fout-meldingen wat gebruikersvriendelijker kan maken zodat de gebruiker kan lezen wat ie moet doen!
WP: Alpha Innotec MSW2-6S | PV: 20 x 300 Wp AEG | ACCU: 2x16x280Ah LiFePO4 3 x Multiplus II 48/3000 | DYN: Tibber | Gasloos | Day Ahead Optimizer
Dat zou super zijn! Ik zat ook in de denkrichting van een configureerbare penalty voor het schakelen. Dat geeft volgens mij de mogelijkheid om één blok af te dwingen, maar ook om deze op te splitsen als er wel hele dure kwartieren tussendoor komen.KC27 schreef op zaterdag 9 mei 2026 @ 22:34:
[...]
Ik denk dat jouw opmerking hout snijdt.
Ik kan zelf niet overzien in hoeverre het aan/uit zetten van een lader slecht is.
Maar het met meer of minder vermogen laten laden lijkt me geen invloed hebben op de levensduur van de laadpaal en/of de boardlader.
Ik zou een optionele penalty kunnen introduceren die iedere tussentijdse start/stop actie een virtuele prijs aanrekent zodat dit alleen gebeurt als de daarmee bereikbare winst hoger is dan de penalty.
Lijkt dat wat?
Ik zie 2 redenen om te verkopen: als de prijs zeer goed is, en om de batterij leeg te maken als er een negatieve prijs aan komt.
En hoe kan je weten of DAO slim energie wilt aankopen?
Ik begrijp je vraag misschien niet zo goed, maar dit is toch de essentie van DAO? Met het setpoint dat je na iedere berekening krijgt zorg je dat je ESS zo gaat regelen dat dit getal gehaald wordt. Negatieve setpoint is dus ontladen en positieve setpoint is ladenUndertilted schreef op zondag 10 mei 2026 @ 18:47:
Hoe kan je weten of DAO slim energie wilt verkopen? Ik merk dat sommigen hier "entity balance switch" voor iets soortgelijk gebruiken: om tijdens "entity balance switch"==true de omvormer zelf load balancing te laten doen. Maar het is me niet duidelijk hoe dit te configureren.
Ik zie 2 redenen om te verkopen: als de prijs zeer goed is, en om de batterij leeg te maken als er een negatieve prijs aan komt.
En hoe kan je weten of DAO slim energie wilt aankopen?
Hoe ik het zie is dat er 3 modi zijn
- inkopen
- verkopen
- meter zo dicht mogelijk bij 0 om de batterij te gebruiken.
DAO was aan het ontladen terwijl de prijs quasi 0 was. Ontladen naar mijn huis, maar ook naar het net. Dit kan niet de bedoeling zijn: vanavond wordt het duur.
Als in de grafiek van na optimalisatie batterij uit met zo veel is als de verbruikers, dus het staafje naar boven is net zo lang als het staafje naar beneden, dan kiest DAO meestal voor NoM.
Wijkt het erg af met de werkelijkheid, dan moet je misschien ook eens naar je baseload kijken.
Zoals je hier ziet: prijs hoog == volle bak ontladen, prijs laag == volle bak opladen.In die situatie zet DAO de entity_balance_switch uit en zet de waarde in W die hij heeft bedacht naar entity_set_power_feedin.
Als mijn omvormer 5000 is, dan gaat die enkel aan 5000 laden/ontladen om "slim" te zijn, en alle andere waarden zijn om de meter op 0 te houden. Is dat zo dat ik het moet bekijken?Beekforel schreef op zondag 10 mei 2026 @ 20:39:
@Undertilted [Afbeelding] Zoals je hier ziet: prijs hoog == volle bak ontladen, prijs laag == volle bak opladen.
In die situatie zet DAO de entity_balance_switch uit en zet de waarde in W die hij heeft bedacht naar entity_set_power_feedin.
En dankjewel om de logica uit te leggen. Ik ga ermee aan de slag.
//edit: "uit" is toch "off" neem ik aan.
//edit2: is het niet omgekeerd? Moet die laden / ontladen vanuit het net niet juist "on" staan?
[ Voor 11% gewijzigd door Undertilted op 10-05-2026 21:11 ]
entity set power feedin: kan dit zowel negatief als positief zijn?
Kun je je grafieken en configuratie delen? Dan kunnen we zien waarom dit misschien zo is?Undertilted schreef op zondag 10 mei 2026 @ 21:18:
entity_balance_switch staat nu op off, DAO SP is 610W en de prijs is niks spectaculair.
entity set power feedin: kan dit zowel negatief als positief zijn?
De changelog van 2026.5.0 bevat de changelog van 2026.5.0.rc1:
- Updated several python modules
- Correct typos in DOCS.md
- Changed boiler heating_allowed_below to flex-setting (reported by @Impossibl3)
- Fixed error logging during execution of a run
- Fixed typo "Battery" -> Machine in machines.py
- Added x-help-text with 0 W stages
- Changed typo meteo-attemps -> meteo_attempts
- Changed timeout hassapi to 10 sec.
- Converted ev "entity stop laden" -> "entity_stop_charging" (reported by @Darkwings)
- made boiler cooling_rate float and flexsetting (pr from tomvanterve)
WP: Alpha Innotec MSW2-6S | PV: 20 x 300 Wp AEG | ACCU: 2x16x280Ah LiFePO4 3 x Multiplus II 48/3000 | DYN: Tibber | Gasloos | Day Ahead Optimizer
Het was eerder al een flex setting in de software maar met de strengere json controle was die weer vast geworden. Ik vermoed dat je nogsteeds een vaste waarde kan hanteren.wmc schreef op maandag 11 mei 2026 @ 08:36:
Nu heating_allowed_below een flex setting is geworden, betekent dat, dat hier een helper vooraangemaakt moet worden of mag dit een ingevuld getal blijven?
Voordeel is nu dat de legionellarun eerder ingepland kan wworden. Daarom is die er in gekomen.
[ Voor 10% gewijzigd door Impossibl3 op 11-05-2026 08:42 ]
PV 5.590 Wp Enphase, 2.700 Wp Growatt - Easee laadpaal - Itho Amber 95 WP
Als de EV laadt, laadt de thuisbatterij meestal ook, dus alle kWh's komen uit het net en/of PV. Wie dat regelt? DAO.hemertje schreef op donderdag 7 mei 2026 @ 22:03:
[...]
Hoi, dankjewel voor deze informatie!
ik krijg een 404 foutmelding op je Github link
@Bravo ik lees in je handtekening dat ook jij in een prachtige EV mag rijden![]()
hoe voorkom jij dat je wanneer je de EV laad je de kWh uit je thuisbatterijen haalt?
En ja, DAO stuurt allerlei helper entitities in HA aan die vervolgens met een automation worden doorgezet naar de verschillende integraties in HA die de daadwerkelijke sturing doen.
Battery setpoint -> automation -> setpoint batterij (Victron), indien NOM doet de batterij zelf NOM (default state). Stuurt HA niet actief, dan gaat de batterij na 15 seconden naar default state (fail safe)
Auto laden -> automation -> if 16A laden dan evcc: fast charge, if 6-15A laden dan evcc: Solar, else evcc: off (nog wel last van de bug die ik hier genoemd heb met wel A instellen, maar end time in het verleden)
PV is AC en wordt gewoon gestuurd vanuit DAO via de helpers pv
Het kost even tijd om te doorgronden en alles in je huis mee te laten werken, ik denk dat ik er meerdere maanden over heb gedaan om al deze apparaten te integreren in DAO. Pas vorige maand de PV helpers aangemaakt, omdat de prijzen echt ver onder 0 gingen.
Dit overzicht hierboven is leuk, maar daarmee ben je er nog niet. DAO regiseert, maar doet niet de daadwerkelijke uitvoering. Achter al deze (combinatie van) helpers zitten dus automations die via HA integraties de daadwerkelijke uitvoering doen. Allemaal op hun eigen wijze.
Voorbeeld: Vaatwasser wordt aangestuurd via Home Local (home connect van BSH, maar dan lokaal). Veranderd het tijdstip van VW DAO Start in een moment in het verleden ten opzichte van nu, dan wordt het programma ingesteld en vervolgens de vaatwasser gestart.
Wasmachine (ook BSH) is niet slim, dus die vul ik, kies een programma, zet de machine aan en zet vervolgens de tussenstekker (Ikea inspelning) handmatig uit. Veranderd het tijdstip van WM DOA Start in een moment in het verleden ten opzichte van nu, dan wordt de schakelaar weer ingeschakeld en gaat de wasmachine zijn ding doen.
[ Voor 19% gewijzigd door Bravo op 11-05-2026 09:04 ]
🚗 Ioniq 6 LR Lounge 20" 🔌⚡ Elli Pro gestuurd door evcc
🔋 Victron 6k5 + 16kWh | ☀️ 2700Wp SSW 30° @ SE2200 | ☀️ 1720Wp SSW 5° @ HM-1500
📷 Canon 6D | 🔭 17-40mm f/4 + 50mm f/1.8 II + 70-200mm f/4 | 💥 2x 430EX II | 🎛️ Sirui T005 + C10
Het woord flex setting zegt het (zoals ook @Impossibl3 zegt): het kan alle twee zowel direct met een getal in je config of via een entity in HA.wmc schreef op maandag 11 mei 2026 @ 08:36:
Nu heating_allowed_below een flex setting is geworden, betekent dat, dat hier een helper vooraangemaakt moet worden of mag dit een ingevuld getal blijven?
WP: Alpha Innotec MSW2-6S | PV: 20 x 300 Wp AEG | ACCU: 2x16x280Ah LiFePO4 3 x Multiplus II 48/3000 | DYN: Tibber | Gasloos | Day Ahead Optimizer
thomvh schreef op zondag 10 mei 2026 @ 22:54:
[...]
Kun je je grafieken en configuratie delen? Dan kunnen we zien waarom dit misschien zo is?
{
"homeassistant": {
"protocol api": "http",
"host": "192.168.178.46",
"ip port": 8123,
"token": "!secret ha_token"
},
"database ha": {
"engine": "sqlite",
"database": "home-assistant_v2.db",
"db_path": "/homeassistant"
},
"database da": {
"engine": "sqlite",
"db_path": "../data"
},
"country": "BE",
"meteoserver-key": "!secret meteoserver-key",
"meteoserver-model": "harmonie",
"meteoserver-attemps": 2,
"interval": "15min",
"prices": {
"source day ahead": "entsoe",
"entsoe-api-key": "!secret entsoe-api-key",
"regular high": 0.5,
"regular low": 0.4,
"switch to low": 23,
"energy taxes consumption": {
"2025-01-01": 0.1242
},
"energy taxes production": {
"2025-01-01": 0.1067733948
},
"cost supplier consumption": {
"2025-01-01": 0.0124554682
},
"cost supplier production": {
"2025-01-01": -0.01133
},
"vat consumption": {
"2022-04-01": -6
},
"vat production": {
"2022-04-01": 18.6352
},
"last invoice": "2026-01-01",
"tax refund": "False"
},
"logging level": "debug",
"use_calc_baseload": "False",
"baseload calc periode": 56,
"baseload": [
0.42,
1.14,
0.78,
1.26,
0.45,
0.36,
0.39,
0.45,
0.69,
0.78,
0.93,
0.96,
0.93,
0.69,
0.78,
0.63,
0.63,
1.62,
0.78,
0.78,
0.66,
0.57,
0.54,
0.48
],
"graphical backend": "",
"graphics": {
"style": "Solarize_Light2",
"show": "true",
"battery balance": "True",
"prices consumption": "True",
"prices production": "True",
"prices spot": "True",
"average consumption": "True"
},
"strategy": "minimize cost",
"notifications": {},
"grid": {
"max_power": 17
},
"history": {
"save days": 7
},
"dashboard": {
"port": 5000
},
"boiler": {
"boiler present": "False"
},
"heating": {
"heater present": "False",
"degree days factor": 3.6,
"stages": [
{
"max_power": 225,
"cop": 7.1
},
{
"max_power": 300,
"cop": 7.0
},
{
"max_power": 400,
"cop": 6.5
},
{
"max_power": 500,
"cop": 6.0
},
{
"max_power": 600,
"cop": 5.5
},
{
"max_power": 750,
"cop": 5.0
},
{
"max_power": 1000,
"cop": 4.5
},
{
"max_power": 1250,
"cop": 4.0
}
],
"entity adjust heating curve": "input_number.stooklijn_verschuiving_day_ahead",
"adjustment factor": 0.04
},
"battery": [
{
"name": "BYD",
"capacity": 9.0,
"entity actual level": "sensor.battery_state_of_charge",
"upper limit": 95,
"lower limit": 5,
"optimal lower level": 10,
"entity min soc end opt": "input_number.dao_min_soc_einde_opt",
"entity max soc end opt": "input_number.dao_max_soc_einde_opt",
"charge stages": [
{
"power": 0,
"efficiency": 1.0
},
{
"power": 300,
"efficiency": 0.88
},
{
"power": 1000,
"efficiency": 0.93
},
{
"power": 2000,
"efficiency": 0.95
},
{
"power": 3000,
"efficiency": 0.955
},
{
"power": 4000,
"efficiency": 0.95
},
{
"power": 5000,
"efficiency": 0.94
}
],
"discharge stages": [
{
"power": 0,
"efficiency": 1.0
},
{
"power": 300,
"efficiency": 0.9
},
{
"power": 1000,
"efficiency": 0.94
},
{
"power": 2000,
"efficiency": 0.955
},
{
"power": 3000,
"efficiency": 0.96
},
{
"power": 4000,
"efficiency": 0.955
},
{
"power": 5000,
"efficiency": 0.95
}
],
"reduced hours": {},
"minimum power": 200,
"dc_to_bat efficiency": 0.98,
"dc_to_bat max power": 5000,
"bat_to_dc efficiency": 0.99,
"bat_to_dc max power": 5000,
"cycle cost": 0.05,
"entity set power feedin": "input_number.dao_goodwe_feed_in_limit_w",
"entity balance switch": "input_boolean.dao_goodwe_balance_switch",
"entity from battery": "sensor.battery_power",
"entity from pv": "sensor.pv_power",
"entity from ac": "sensor.dao_grid_net_power",
"entity set power feedin": "input_number.dao_goodwe_feed_in_limit_w",
"solar": [
{
"name": "pv_roof_sw",
"entity pv switch": "input_boolean.dao_pv_roof_sw_enable",
"tilt": 5,
"orientation": 69,
"yield": 0.0085,
"capacity": 4.56
},
{
"name": "pv_roof_se",
"entity pv switch": "input_boolean.dao_pv_roof_se_enable",
"tilt": 15,
"orientation": -22,
"yield": 0.0063,
"capacity": 3.36
}
]
}
],
"solar": [],
"electric vehicle": [],
"machines": [],
"report": {
"entities grid consumption": [
"sensor.slimmelezer_energy_consumed_tariff_1",
"sensor.slimmelezer_energy_consumed_tariff_2"
],
"entities grid production": [
"sensor.slimmelezer_energy_produced_tariff_1",
"sensor.slimmelezer_energy_produced_tariff_2"
],
"entities solar production ac": [],
"entities solar production dc": [
"sensor.total_pv_generation"
],
"entities ev consumption": [],
"entities wp consumption": [],
"entities boiler consumption": [],
"entities machine consumption": [],
"entities battery consumption": [
"sensor.total_battery_charge"
],
"entities battery production": [
"sensor.total_battery_discharge"
]
},
"scheduler": {
"active": "true",
"0430": "get_meteo_data",
"1030": "get_meteo_data",
"1630": "get_meteo_data",
"2230": "get_meteo_data",
"1255": "get_day_ahead_prices",
"1355": "get_day_ahead_prices",
"1455": "get_day_ahead_prices",
"1554": "get_day_ahead_prices",
"1655": "get_day_ahead_prices",
"xx00": "calc_optimum",
"xx15": "calc_optimum",
"xx30": "calc_optimum",
"xx45": "calc_optimum",
"2359": "clean_data"
}
}
[sudo] password for
# =============================================================================
# DAO → GoodWe battery control package
# =============================================================================
# Plaatsing:
# Geactiveerd via configuration.yaml: dao_battery_control: !include dao_battery_control.yaml
# =============================================================================
###############################################################################
# 1) HELPERS
###############################################################################
input_boolean:
dao_master_enable:
name: DAO Master Enable
icon: mdi:shield-check
# Default UIT — bewust handmatig aanzetten na controle van de modusnamen
dao_goodwe_balance_switch:
name: DAO GoodWe balance switch
icon: mdi:scale-balance
# PV-string schakelaars die in options.json staan onder battery[0].solar•
dao_pv_roof_sw_enable:
name: DAO PV roof SW enable
icon: mdi:solar-panel
dao_pv_roof_se_enable:
name: DAO PV roof SE enable
icon: mdi:solar-panel
# Bestaande UI-helper dao_goodwe_cell_balance laten we ongemoeid
input_number:
dao_goodwe_feed_in_limit_w:
name: DAO GoodWe feed-in limit W
min: -5000
max: 5000
step: 10
unit_of_measurement: "W"
initial: 0
icon: mdi:transmission-tower
# SoC-targets die DAO leest (entity min/max soc end opt in options.json)
dao_min_soc_einde_opt:
name: DAO Min SoC einde optimum
min: 0
max: 100
step: 1
unit_of_measurement: "%"
initial: 10
icon: mdi:battery-low
dao_max_soc_einde_opt:
name: DAO Max SoC einde optimum
min: 0
max: 100
step: 1
unit_of_measurement: "%"
initial: 95
icon: mdi:battery-high
# Drempel waaronder DAO setpoint beschouwd wordt als "geen actie"
dao_idle_threshold_w:
name: DAO Idle threshold
min: 0
max: 1000
step: 50
unit_of_measurement: "W"
initial: 200
icon: mdi:sine-wave
dao_goodwe_feed_in_limit_w:
name: DAO GoodWe feed-in limit W
min: -5000
max: 5000
step: 1
unit_of_measurement: "W"
initial: 0
icon: mdi:transmission-tower
input_text:
dao_notificatie:
name: DAO notificatie
icon: mdi:message-text
max: 255
input_datetime:
laatste_activiteit:
name: Laatste DAO activiteit
icon: mdi:clock-time-eight
has_date: true
has_time: true
###############################################################################
# 2) TEMPLATE SENSORS (afgeleide status)
###############################################################################
template:
- sensor:
- name: "DAO derived battery mode"
unique_id: dao_derived_battery_mode
icon: mdi:battery-charging-medium
state: >-
{% set sp = states('input_number.dao_goodwe_feed_in_limit_w') | float(0) %}
{% set thr = states('input_number.dao_idle_threshold_w') | float(200) %}
{% if not is_state('input_boolean.dao_master_enable','on') %}
general
{% elif sp > thr %}
eco_charge
{% elif sp < -thr %}
eco_discharge
{% else %}
general
{% endif %}
- name: "DAO setpoint absolute"
unique_id: dao_setpoint_abs
unit_of_measurement: "W"
state_class: measurement
device_class: power
state: >-
{{ (states('input_number.dao_goodwe_feed_in_limit_w') | float(0)) | abs | round(0) }}
- name: "DAO setpoint percent"
unique_id: dao_setpoint_percent
unit_of_measurement: "%"
state: >-
{% set sp_w = states('input_number.dao_goodwe_feed_in_limit_w') | float(0) | abs %}
{% set max_w = 5000 %}
{{ ((sp_w / max_w) * 100) | round(0) | int }}
- name: "DAO action description"
unique_id: dao_action_description
icon: mdi:information-outline
state: >-
{% set sp = states('input_number.dao_goodwe_feed_in_limit_w') | float(0) %}
{% set master = is_state('input_boolean.dao_master_enable','on') %}
{% if not master %}
DAO uitgeschakeld — inverter in self-consumption
{% elif sp > states('input_number.dao_idle_threshold_w') | float(200) %}
Laden van net: {{ sp | round(0) }} W
{% elif sp < -1 * (states('input_number.dao_idle_threshold_w') | float(200)) %}
Ontladen naar net: {{ (sp | abs) | round(0) }} W
{% else %}
Self-consumption (geen sterk DAO-signaal)
{% endif %}
- name: "DAO grid net power"
unique_id: dao_grid_net_power
unit_of_measurement: "W"
device_class: power
state_class: measurement
state: >-
{{ (states('sensor.slimmelezer_power_consumed') | float(0)
- states('sensor.slimmelezer_power_produced') | float(0)) | round(0) }}
###############################################################################
# 2.1) COMMAND LINE SENSOR (DAO SQLite → setpoint in W)
###############################################################################
command_line:
- sensor:
name: "DAO battery setpoint from database"
unique_id: dao_battery_setpoint_from_database
command: >-
python3 -c "import sqlite3, time;
db='/opt/dao/data/dao_data/day_ahead.db';
con=sqlite3.connect(db);
cur=con.cursor();
now=int(time.time());
cur.execute(\"\"\"
WITH slot AS (
SELECT MAX(p.time) AS t
FROM prognoses p
JOIN variabel v ON v.id = p.variabel
WHERE v.code IN ('bat_in','bat_out')
AND p.time <= ?
),
next_slot AS (
SELECT MIN(p.time) AS nt
FROM prognoses p
JOIN variabel v ON v.id = p.variabel
WHERE v.code IN ('bat_in','bat_out')
AND p.time > (SELECT t FROM slot)
),
e AS (
SELECT
COALESCE(SUM(CASE WHEN v.code = 'bat_in' THEN p.value END), 0) AS bat_in_kwh,
COALESCE(SUM(CASE WHEN v.code = 'bat_out' THEN p.value END), 0) AS bat_out_kwh
FROM prognoses p
JOIN variabel v ON v.id = p.variabel
WHERE p.time = (SELECT t FROM slot)
AND v.code IN ('bat_in','bat_out')
)
SELECT ROUND((bat_in_kwh - bat_out_kwh) * 3600000.0 / COALESCE((SELECT nt - t FROM next_slot, slot), 900), 0)
FROM e;
\"\"\", (now,));
r=cur.fetchone();
print(0 if r is None or r[0] is None else r[0])"
unit_of_measurement: "W"
device_class: power
state_class: measurement
scan_interval: 60
value_template: "{{ value | float(0) | round(0) }}"
###############################################################################
# 3) AUTOMATIONS
###############################################################################
automation:
# ---------------------------------------------------------------------------
# 3.1) Hoofdautomation: DAO setpoint → GoodWe modus + eco power
# ---------------------------------------------------------------------------
- id: dao_apply_setpoint_to_goodwe
alias: "DAO → GoodWe — setpoint doorzetten"
description: >
Leest de DAO-setpoint en kill switch, en vertaalt dit naar de juiste
GoodWe-modus + eco_mode_power + eco_mode_soc-target.
mode: restart
trigger:
- platform: state
entity_id:
- input_number.dao_goodwe_feed_in_limit_w
- input_boolean.dao_master_enable
- input_number.dao_min_soc_einde_opt
- input_number.dao_max_soc_einde_opt
- platform: time_pattern
minutes: "/5"
variables:
sp: "{{ states('input_number.dao_goodwe_feed_in_limit_w') | float(0) }}"
thr: "{{ states('input_number.dao_idle_threshold_w') | float(200) }}"
max_w: 5000
power_pct: >-
{% set p = (((sp | abs) / max_w) * 100) | round(0) | int %}
{{ [[p, 100] | min, 1] | max }}
wanted_mode: >-
{% if not is_state('input_boolean.dao_master_enable','on') %}
general
{% elif sp > thr %}
eco_charge
{% elif sp < -1 * thr %}
eco_discharge
{% else %}
general
{% endif %}
wanted_soc: >-
{% if wanted_mode | trim == 'eco_charge' %}
{{ states('input_number.dao_max_soc_einde_opt') | int(95) }}
{% elif wanted_mode | trim == 'eco_discharge' %}
{{ states('input_number.dao_min_soc_einde_opt') | int(10) }}
{% else %}
10
{% endif %}
action:
- choose:
# === GEVAL 1: Kill switch UIT → forceer general (self-consumption) ===
- conditions:
- condition: template
value_template: "{{ wanted_mode | trim == 'general' }}"
sequence:
- service: select.select_option
target:
entity_id: select.goodwe_inverter_operation_mode
data:
option: "general"
# === GEVAL 2: DAO wil laden (positief, > drempel) → eco_charge ===
- conditions:
- condition: template
value_template: "{{ wanted_mode | trim == 'eco_charge' }}"
sequence:
- service: select.select_option
target:
entity_id: select.goodwe_inverter_operation_mode
data:
option: "eco_charge"
- delay: "00:00:02"
- service: number.set_value
continue_on_error: true
target:
entity_id: number.goodwe_eco_mode_power
data:
value: "{{ power_pct | int }}"
- service: number.set_value
continue_on_error: true
target:
entity_id: number.goodwe_eco_mode_soc
data:
value: "{{ wanted_soc | int }}"
- delay: "00:00:02"
- service: select.select_option
target:
entity_id: select.goodwe_inverter_operation_mode
data:
option: "eco_charge"
# === GEVAL 3: DAO wil ontladen (negatief, > drempel) → eco_discharge ===
- conditions:
- condition: template
value_template: "{{ wanted_mode | trim == 'eco_discharge' }}"
sequence:
- service: select.select_option
target:
entity_id: select.goodwe_inverter_operation_mode
data:
option: "eco_discharge"
- delay: "00:00:02"
- service: number.set_value
continue_on_error: true
target:
entity_id: number.goodwe_eco_mode_power
data:
value: "{{ power_pct | int }}"
- service: number.set_value
continue_on_error: true
target:
entity_id: number.goodwe_eco_mode_soc
data:
value: "{{ wanted_soc | int }}"
- delay: "00:00:02"
- service: select.select_option
target:
entity_id: select.goodwe_inverter_operation_mode
data:
option: "eco_discharge"
# === DEFAULT: setpoint dichtbij 0 of binnen idle-drempel → general ===
default:
- service: select.select_option
target:
entity_id: select.goodwe_inverter_operation_mode
data:
option: "general"
# Notitie van het laatste moment dat we iets doorgezet hebben
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.laatste_activiteit
data:
datetime: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
# ---------------------------------------------------------------------------
# 3.2) Veiligheid: nooit verder laden boven SoC max, nooit ontladen onder min
# ---------------------------------------------------------------------------
- id: dao_safety_soc_limits
alias: "DAO veiligheid SoC-grenzen"
description: >
Als de batterij boven max-SoC zit en DAO wil nog steeds laden, of onder
min-SoC en DAO wil nog ontladen, val terug op general om bot te dwingen.
mode: single
trigger:
- platform: time_pattern
minutes: "/1"
condition:
- condition: state
entity_id: input_boolean.dao_master_enable
state: "on"
action:
- choose:
- conditions:
- condition: template
value_template: >-
{{ (states('sensor.battery_state_of_charge') | float(50)) >=
(states('input_number.dao_max_soc_einde_opt') | float(95))
and states('input_number.dao_goodwe_feed_in_limit_w') | float(0) > 0 }}
sequence:
- service: select.select_option
target:
entity_id: select.goodwe_inverter_operation_mode
data:
option: "general"
- service: persistent_notification.create
data:
title: DAO veiligheid
message: "Batterij vol — laad-commando van DAO genegeerd."
- conditions:
- condition: template
value_template: >-
{{ (states('sensor.battery_state_of_charge') | float(50)) <=
(states('input_number.dao_min_soc_einde_opt') | float(10))
and states('input_number.dao_goodwe_feed_in_limit_w') | float(0) < 0 }}
sequence:
- service: select.select_option
target:
entity_id: select.goodwe_inverter_operation_mode
data:
option: "general"
- service: persistent_notification.create
data:
title: DAO veiligheid
message: "Batterij leeg — ontlaad-commando van DAO genegeerd."
# ---------------------------------------------------------------------------
# 3.3) Auto-reset: bij HA herstart kill switch op de laatst bekende waarde
# ---------------------------------------------------------------------------
- id: dao_master_enable_persist
alias: "DAO master enable log"
mode: single
trigger:
- platform: state
entity_id: input_boolean.dao_master_enable
action:
- service: persistent_notification.create
data:
title: "DAO {{ trigger.to_state.state | upper }}"
message: >-
DAO control is {{ 'AANGEZET — DAO bestuurt nu de batterij' if trigger.to_state.state == 'on'
else 'UITGEZET — inverter terug op general (self-consumption)' }}
# ---------------------------------------------------------------------------
# 3.4) DAO database setpoint → Home Assistant input_number
# ---------------------------------------------------------------------------
- id: dao_copy_database_setpoint_to_input_number
alias: "DAO database setpoint → input_number"
description: >
Kopieert het batterij-setpoint uit /opt/dao/data/dao_data/day_ahead.db
naar input_number.dao_goodwe_feed_in_limit_w.
Positief = laden van net. Negatief = ontladen naar net.
mode: restart
trigger:
- platform: state
entity_id: sensor.dao_battery_setpoint_from_database
- platform: time_pattern
seconds: "/15"
condition:
# - condition: state
# entity_id: input_boolean.dao_master_enable
# state: "on"
- condition: template
value_template: >-
{{ states('sensor.dao_battery_setpoint_from_database') not in ['unknown', 'unavailable', 'none', ''] }}
action:
- service: input_number.set_value
target:
entity_id: input_number.dao_goodwe_feed_in_limit_w
data:
value: >-
{% set raw = states('sensor.dao_battery_setpoint_from_database') | float(0) %}
{% set max_w = 5000 %}
{{ [[raw, max_w] | min, -1 * max_w] | max | round(0) }}
cartouche@cartouche-Macmini:/opt/dao/data/dao_data$ ^C
cartouche@cartouche-Macmini:/opt/dao/data/dao_data$ sudo cat /opt/homeassistant/config/dao_battery_control.yaml
# =============================================================================
# DAO → GoodWe battery control package
# =============================================================================
# Plaatsing: /home/cartouche/homeassistant/dao_battery_control.yaml
# Geactiveerd via configuration.yaml: dao_battery_control: !include dao_battery_control.yaml
# =============================================================================
###############################################################################
# 1) HELPERS
###############################################################################
input_boolean:
dao_master_enable:
name: DAO Master Enable
icon: mdi:shield-check
# Default UIT — bewust handmatig aanzetten na controle van de modusnamen
dao_goodwe_balance_switch:
name: DAO GoodWe balance switch
icon: mdi:scale-balance
# PV-string schakelaars die in options.json staan onder battery[0].solar•
dao_pv_roof_sw_enable:
name: DAO PV roof SW enable
icon: mdi:solar-panel
dao_pv_roof_se_enable:
name: DAO PV roof SE enable
icon: mdi:solar-panel
# Bestaande UI-helper dao_goodwe_cell_balance laten we ongemoeid
input_number:
dao_goodwe_feed_in_limit_w:
name: DAO GoodWe feed-in limit W
min: -5000
max: 5000
step: 10
unit_of_measurement: "W"
initial: 0
icon: mdi:transmission-tower
# SoC-targets die DAO leest (entity min/max soc end opt in options.json)
dao_min_soc_einde_opt:
name: DAO Min SoC einde optimum
min: 0
max: 100
step: 1
unit_of_measurement: "%"
initial: 10
icon: mdi:battery-low
dao_max_soc_einde_opt:
name: DAO Max SoC einde optimum
min: 0
max: 100
step: 1
unit_of_measurement: "%"
initial: 95
icon: mdi:battery-high
# Drempel waaronder DAO setpoint beschouwd wordt als "geen actie"
dao_idle_threshold_w:
name: DAO Idle threshold
min: 0
max: 1000
step: 50
unit_of_measurement: "W"
initial: 200
icon: mdi:sine-wave
dao_goodwe_feed_in_limit_w:
name: DAO GoodWe feed-in limit W
min: -5000
max: 5000
step: 1
unit_of_measurement: "W"
initial: 0
icon: mdi:transmission-tower
input_text:
dao_notificatie:
name: DAO notificatie
icon: mdi:message-text
max: 255
input_datetime:
laatste_activiteit:
name: Laatste DAO activiteit
icon: mdi:clock-time-eight
has_date: true
has_time: true
###############################################################################
# 2) TEMPLATE SENSORS (afgeleide status)
###############################################################################
template:
- sensor:
- name: "DAO derived battery mode"
unique_id: dao_derived_battery_mode
icon: mdi:battery-charging-medium
state: >-
{% set sp = states('input_number.dao_goodwe_feed_in_limit_w') | float(0) %}
{% set thr = states('input_number.dao_idle_threshold_w') | float(200) %}
{% if not is_state('input_boolean.dao_master_enable','on') %}
general
{% elif sp > thr %}
eco_charge
{% elif sp < -thr %}
eco_discharge
{% else %}
general
{% endif %}
- name: "DAO setpoint absolute"
unique_id: dao_setpoint_abs
unit_of_measurement: "W"
state_class: measurement
device_class: power
state: >-
{{ (states('input_number.dao_goodwe_feed_in_limit_w') | float(0)) | abs | round(0) }}
- name: "DAO setpoint percent"
unique_id: dao_setpoint_percent
unit_of_measurement: "%"
state: >-
{% set sp_w = states('input_number.dao_goodwe_feed_in_limit_w') | float(0) | abs %}
{% set max_w = 5000 %}
{{ ((sp_w / max_w) * 100) | round(0) | int }}
- name: "DAO action description"
unique_id: dao_action_description
icon: mdi:information-outline
state: >-
{% set sp = states('input_number.dao_goodwe_feed_in_limit_w') | float(0) %}
{% set master = is_state('input_boolean.dao_master_enable','on') %}
{% if not master %}
DAO uitgeschakeld — inverter in self-consumption
{% elif sp > states('input_number.dao_idle_threshold_w') | float(200) %}
Laden van net: {{ sp | round(0) }} W
{% elif sp < -1 * (states('input_number.dao_idle_threshold_w') | float(200)) %}
Ontladen naar net: {{ (sp | abs) | round(0) }} W
{% else %}
Self-consumption (geen sterk DAO-signaal)
{% endif %}
- name: "DAO grid net power"
unique_id: dao_grid_net_power
unit_of_measurement: "W"
device_class: power
state_class: measurement
state: >-
{{ (states('sensor.slimmelezer_power_consumed') | float(0)
- states('sensor.slimmelezer_power_produced') | float(0)) | round(0) }}
###############################################################################
# 2.1) COMMAND LINE SENSOR (DAO SQLite → setpoint in W)
###############################################################################
command_line:
- sensor:
name: "DAO battery setpoint from database"
unique_id: dao_battery_setpoint_from_database
command: >-
python3 -c "import sqlite3, time;
db='/opt/dao/data/dao_data/day_ahead.db';
con=sqlite3.connect(db);
cur=con.cursor();
now=int(time.time());
cur.execute(\"\"\"
WITH slot AS (
SELECT MAX(p.time) AS t
FROM prognoses p
JOIN variabel v ON v.id = p.variabel
WHERE v.code IN ('bat_in','bat_out')
AND p.time <= ?
),
next_slot AS (
SELECT MIN(p.time) AS nt
FROM prognoses p
JOIN variabel v ON v.id = p.variabel
WHERE v.code IN ('bat_in','bat_out')
AND p.time > (SELECT t FROM slot)
),
e AS (
SELECT
COALESCE(SUM(CASE WHEN v.code = 'bat_in' THEN p.value END), 0) AS bat_in_kwh,
COALESCE(SUM(CASE WHEN v.code = 'bat_out' THEN p.value END), 0) AS bat_out_kwh
FROM prognoses p
JOIN variabel v ON v.id = p.variabel
WHERE p.time = (SELECT t FROM slot)
AND v.code IN ('bat_in','bat_out')
)
SELECT ROUND((bat_in_kwh - bat_out_kwh) * 3600000.0 / COALESCE((SELECT nt - t FROM next_slot, slot), 900), 0)
FROM e;
\"\"\", (now,));
r=cur.fetchone();
print(0 if r is None or r[0] is None else r[0])"
unit_of_measurement: "W"
device_class: power
state_class: measurement
scan_interval: 60
value_template: "{{ value | float(0) | round(0) }}"
###############################################################################
# 3) AUTOMATIONS
###############################################################################
automation:
# ---------------------------------------------------------------------------
# 3.1) Hoofdautomation: DAO setpoint → GoodWe modus + eco power
# ---------------------------------------------------------------------------
- id: dao_apply_setpoint_to_goodwe
alias: "DAO → GoodWe — setpoint doorzetten"
description: >
Leest de DAO-setpoint en kill switch, en vertaalt dit naar de juiste
GoodWe-modus + eco_mode_power + eco_mode_soc-target.
mode: restart
trigger:
- platform: state
entity_id:
- input_number.dao_goodwe_feed_in_limit_w
- input_boolean.dao_master_enable
- input_number.dao_min_soc_einde_opt
- input_number.dao_max_soc_einde_opt
- platform: time_pattern
minutes: "/5"
variables:
sp: "{{ states('input_number.dao_goodwe_feed_in_limit_w') | float(0) }}"
thr: "{{ states('input_number.dao_idle_threshold_w') | float(200) }}"
max_w: 5000
power_pct: >-
{% set p = (((sp | abs) / max_w) * 100) | round(0) | int %}
{{ [[p, 100] | min, 1] | max }}
wanted_mode: >-
{% if not is_state('input_boolean.dao_master_enable','on') %}
general
{% elif sp > thr %}
eco_charge
{% elif sp < -1 * thr %}
eco_discharge
{% else %}
general
{% endif %}
wanted_soc: >-
{% if wanted_mode | trim == 'eco_charge' %}
{{ states('input_number.dao_max_soc_einde_opt') | int(95) }}
{% elif wanted_mode | trim == 'eco_discharge' %}
{{ states('input_number.dao_min_soc_einde_opt') | int(10) }}
{% else %}
10
{% endif %}
action:
- choose:
# === GEVAL 1: Kill switch UIT → forceer general (self-consumption) ===
- conditions:
- condition: template
value_template: "{{ wanted_mode | trim == 'general' }}"
sequence:
- service: select.select_option
target:
entity_id: select.goodwe_inverter_operation_mode
data:
option: "general"
# === GEVAL 2: DAO wil laden (positief, > drempel) → eco_charge ===
- conditions:
- condition: template
value_template: "{{ wanted_mode | trim == 'eco_charge' }}"
sequence:
- service: select.select_option
target:
entity_id: select.goodwe_inverter_operation_mode
data:
option: "eco_charge"
- delay: "00:00:02"
- service: number.set_value
continue_on_error: true
target:
entity_id: number.goodwe_eco_mode_power
data:
value: "{{ power_pct | int }}"
- service: number.set_value
continue_on_error: true
target:
entity_id: number.goodwe_eco_mode_soc
data:
value: "{{ wanted_soc | int }}"
- delay: "00:00:02"
- service: select.select_option
target:
entity_id: select.goodwe_inverter_operation_mode
data:
option: "eco_charge"
# === GEVAL 3: DAO wil ontladen (negatief, > drempel) → eco_discharge ===
- conditions:
- condition: template
value_template: "{{ wanted_mode | trim == 'eco_discharge' }}"
sequence:
- service: select.select_option
target:
entity_id: select.goodwe_inverter_operation_mode
data:
option: "eco_discharge"
- delay: "00:00:02"
- service: number.set_value
continue_on_error: true
target:
entity_id: number.goodwe_eco_mode_power
data:
value: "{{ power_pct | int }}"
- service: number.set_value
continue_on_error: true
target:
entity_id: number.goodwe_eco_mode_soc
data:
value: "{{ wanted_soc | int }}"
- delay: "00:00:02"
- service: select.select_option
target:
entity_id: select.goodwe_inverter_operation_mode
data:
option: "eco_discharge"
# === DEFAULT: setpoint dichtbij 0 of binnen idle-drempel → general ===
default:
- service: select.select_option
target:
entity_id: select.goodwe_inverter_operation_mode
data:
option: "general"
# Notitie van het laatste moment dat we iets doorgezet hebben
- service: input_datetime.set_datetime
target:
entity_id: input_datetime.laatste_activiteit
data:
datetime: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
# ---------------------------------------------------------------------------
# 3.2) Veiligheid: nooit verder laden boven SoC max, nooit ontladen onder min
# ---------------------------------------------------------------------------
- id: dao_safety_soc_limits
alias: "DAO veiligheid SoC-grenzen"
description: >
Als de batterij boven max-SoC zit en DAO wil nog steeds laden, of onder
min-SoC en DAO wil nog ontladen, val terug op general om bot te dwingen.
mode: single
trigger:
- platform: time_pattern
minutes: "/1"
condition:
- condition: state
entity_id: input_boolean.dao_master_enable
state: "on"
action:
- choose:
- conditions:
- condition: template
value_template: >-
{{ (states('sensor.battery_state_of_charge') | float(50)) >=
(states('input_number.dao_max_soc_einde_opt') | float(95))
and states('input_number.dao_goodwe_feed_in_limit_w') | float(0) > 0 }}
sequence:
- service: select.select_option
target:
entity_id: select.goodwe_inverter_operation_mode
data:
option: "general"
- service: persistent_notification.create
data:
title: DAO veiligheid
message: "Batterij vol — laad-commando van DAO genegeerd."
- conditions:
- condition: template
value_template: >-
{{ (states('sensor.battery_state_of_charge') | float(50)) <=
(states('input_number.dao_min_soc_einde_opt') | float(10))
and states('input_number.dao_goodwe_feed_in_limit_w') | float(0) < 0 }}
sequence:
- service: select.select_option
target:
entity_id: select.goodwe_inverter_operation_mode
data:
option: "general"
- service: persistent_notification.create
data:
title: DAO veiligheid
message: "Batterij leeg — ontlaad-commando van DAO genegeerd."
# ---------------------------------------------------------------------------
# 3.3) Auto-reset: bij HA herstart kill switch op de laatst bekende waarde
# ---------------------------------------------------------------------------
- id: dao_master_enable_persist
alias: "DAO master enable log"
mode: single
trigger:
- platform: state
entity_id: input_boolean.dao_master_enable
action:
- service: persistent_notification.create
data:
title: "DAO {{ trigger.to_state.state | upper }}"
message: >-
DAO control is {{ 'AANGEZET — DAO bestuurt nu de batterij' if trigger.to_state.state == 'on'
else 'UITGEZET — inverter terug op general (self-consumption)' }}
# ---------------------------------------------------------------------------
# 3.4) DAO database setpoint → Home Assistant input_number
# ---------------------------------------------------------------------------
- id: dao_copy_database_setpoint_to_input_number
alias: "DAO database setpoint → input_number"
description: >
Kopieert het batterij-setpoint uit /opt/dao/data/dao_data/day_ahead.db
naar input_number.dao_goodwe_feed_in_limit_w.
Positief = laden van net. Negatief = ontladen naar net.
mode: restart
trigger:
- platform: state
entity_id: sensor.dao_battery_setpoint_from_database
- platform: time_pattern
seconds: "/15"
condition:
# - condition: state
# entity_id: input_boolean.dao_master_enable
# state: "on"
- condition: template
value_template: >-
{{ states('sensor.dao_battery_setpoint_from_database') not in ['unknown', 'unavailable', 'none', ''] }}
action:
- service: input_number.set_value
target:
entity_id: input_number.dao_goodwe_feed_in_limit_w
data:
value: >-
{% set raw = states('sensor.dao_battery_setpoint_from_database') | float(0) %}
{% set max_w = 5000 %}
{{ [[raw, max_w] | min, -1 * max_w] | max | round(0) }}
[ Voor 166% gewijzigd door Undertilted op 11-05-2026 09:25 ]
thomvh schreef op zondag 10 mei 2026 @ 22:54:
[...]
Kun je je grafieken en configuratie delen? Dan kunnen we zien waarom dit misschien zo is?
Graag tussen quote-tagsUndertilted schreef op maandag 11 mei 2026 @ 09:22:
[...]code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289{ "homeassistant": { "protocol api": "http", "host": "192.168.178.46", "ip port": 8123, "token": "!secret ha_token" }, "database ha": { "engine": "sqlite", "database": "home-assistant_v2.db", "db_path": "/homeassistant" }, "database da": { "engine": "sqlite", "db_path": "../data" }, "country": "BE", "meteoserver-key": "!secret meteoserver-key", "meteoserver-model": "harmonie", "meteoserver-attemps": 2, "interval": "15min", "prices": { "source day ahead": "entsoe", "entsoe-api-key": "!secret entsoe-api-key", "regular high": 0.5, "regular low": 0.4, "switch to low": 23, "energy taxes consumption": { "2025-01-01": 0.1242 }, "energy taxes production": { "2025-01-01": 0.1067733948 }, "cost supplier consumption": { "2025-01-01": 0.0124554682 }, "cost supplier production": { "2025-01-01": -0.01133 }, "vat consumption": { "2022-04-01": -6 }, "vat production": { "2022-04-01": 18.6352 }, "last invoice": "2026-01-01", "tax refund": "False" }, "logging level": "debug", "use_calc_baseload": "False", "baseload calc periode": 56, "baseload": [ 0.42, 1.14, 0.78, 1.26, 0.45, 0.36, 0.39, 0.45, 0.69, 0.78, 0.93, 0.96, 0.93, 0.69, 0.78, 0.63, 0.63, 1.62, 0.78, 0.78, 0.66, 0.57, 0.54, 0.48 ], "graphical backend": "", "graphics": { "style": "Solarize_Light2", "show": "true", "battery balance": "True", "prices consumption": "True", "prices production": "True", "prices spot": "True", "average consumption": "True" }, "strategy": "minimize cost", "notifications": {}, "grid": { "max_power": 17 }, "history": { "save days": 7 }, "dashboard": { "port": 5000 }, "boiler": { "boiler present": "False" }, "heating": { "heater present": "False", "degree days factor": 3.6, "stages": [ { "max_power": 225, "cop": 7.1 }, { "max_power": 300, "cop": 7.0 }, { "max_power": 400, "cop": 6.5 }, { "max_power": 500, "cop": 6.0 }, { "max_power": 600, "cop": 5.5 }, { "max_power": 750, "cop": 5.0 }, { "max_power": 1000, "cop": 4.5 }, { "max_power": 1250, "cop": 4.0 } ], "entity adjust heating curve": "input_number.stooklijn_verschuiving_day_ahead", "adjustment factor": 0.04 }, "battery": [ { "name": "BYD", "capacity": 9.0, "entity actual level": "sensor.battery_state_of_charge", "upper limit": 95, "lower limit": 5, "optimal lower level": 10, "entity min soc end opt": "input_number.dao_min_soc_einde_opt", "entity max soc end opt": "input_number.dao_max_soc_einde_opt", "charge stages": [ { "power": 0, "efficiency": 1.0 }, { "power": 300, "efficiency": 0.88 }, { "power": 1000, "efficiency": 0.93 }, { "power": 2000, "efficiency": 0.95 }, { "power": 3000, "efficiency": 0.955 }, { "power": 4000, "efficiency": 0.95 }, { "power": 5000, "efficiency": 0.94 } ], "discharge stages": [ { "power": 0, "efficiency": 1.0 }, { "power": 300, "efficiency": 0.9 }, { "power": 1000, "efficiency": 0.94 }, { "power": 2000, "efficiency": 0.955 }, { "power": 3000, "efficiency": 0.96 }, { "power": 4000, "efficiency": 0.955 }, { "power": 5000, "efficiency": 0.95 } ], "reduced hours": {}, "minimum power": 200, "dc_to_bat efficiency": 0.98, "dc_to_bat max power": 5000, "bat_to_dc efficiency": 0.99, "bat_to_dc max power": 5000, "cycle cost": 0.05, "entity set power feedin": "input_number.dao_goodwe_feed_in_limit_w", "entity balance switch": "input_boolean.dao_goodwe_balance_switch", "entity from battery": "sensor.battery_power", "entity from pv": "sensor.pv_power", "entity from ac": "sensor.dao_grid_net_power", "entity set power feedin": "input_number.dao_goodwe_feed_in_limit_w", "solar": [ { "name": "pv_roof_sw", "entity pv switch": "input_boolean.dao_pv_roof_sw_enable", "tilt": 5, "orientation": 69, "yield": 0.0085, "capacity": 4.56 }, { "name": "pv_roof_se", "entity pv switch": "input_boolean.dao_pv_roof_se_enable", "tilt": 15, "orientation": -22, "yield": 0.0063, "capacity": 3.36 } ] } ], "solar": [], "electric vehicle": [], "machines": [], "report": { "entities grid consumption": [ "sensor.slimmelezer_energy_consumed_tariff_1", "sensor.slimmelezer_energy_consumed_tariff_2" ], "entities grid production": [ "sensor.slimmelezer_energy_produced_tariff_1", "sensor.slimmelezer_energy_produced_tariff_2" ], "entities solar production ac": [], "entities solar production dc": [ "sensor.total_pv_generation" ], "entities ev consumption": [], "entities wp consumption": [], "entities boiler consumption": [], "entities machine consumption": [], "entities battery consumption": [ "sensor.total_battery_charge" ], "entities battery production": [ "sensor.total_battery_discharge" ] }, "scheduler": { "active": "true", "0430": "get_meteo_data", "1030": "get_meteo_data", "1630": "get_meteo_data", "2230": "get_meteo_data", "1255": "get_day_ahead_prices", "1355": "get_day_ahead_prices", "1455": "get_day_ahead_prices", "1554": "get_day_ahead_prices", "1655": "get_day_ahead_prices", "xx00": "calc_optimum", "xx15": "calc_optimum", "xx30": "calc_optimum", "xx45": "calc_optimum", "2359": "clean_data" } }code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289{ "homeassistant": { "protocol api": "http", "host": "192.168.178.46", "ip port": 8123, "token": "!secret ha_token" }, "database ha": { "engine": "sqlite", "database": "home-assistant_v2.db", "db_path": "/homeassistant" }, "database da": { "engine": "sqlite", "db_path": "../data" }, "country": "BE", "meteoserver-key": "!secret meteoserver-key", "meteoserver-model": "harmonie", "meteoserver-attemps": 2, "interval": "15min", "prices": { "source day ahead": "entsoe", "entsoe-api-key": "!secret entsoe-api-key", "regular high": 0.5, "regular low": 0.4, "switch to low": 23, "energy taxes consumption": { "2025-01-01": 0.1242 }, "energy taxes production": { "2025-01-01": 0.1067733948 }, "cost supplier consumption": { "2025-01-01": 0.0124554682 }, "cost supplier production": { "2025-01-01": -0.01133 }, "vat consumption": { "2022-04-01": -6 }, "vat production": { "2022-04-01": 18.6352 }, "last invoice": "2026-01-01", "tax refund": "False" }, "logging level": "debug", "use_calc_baseload": "False", "baseload calc periode": 56, "baseload": [ 0.42, 1.14, 0.78, 1.26, 0.45, 0.36, 0.39, 0.45, 0.69, 0.78, 0.93, 0.96, 0.93, 0.69, 0.78, 0.63, 0.63, 1.62, 0.78, 0.78, 0.66, 0.57, 0.54, 0.48 ], "graphical backend": "", "graphics": { "style": "Solarize_Light2", "show": "true", "battery balance": "True", "prices consumption": "True", "prices production": "True", "prices spot": "True", "average consumption": "True" }, "strategy": "minimize cost", "notifications": {}, "grid": { "max_power": 17 }, "history": { "save days": 7 }, "dashboard": { "port": 5000 }, "boiler": { "boiler present": "False" }, "heating": { "heater present": "False", "degree days factor": 3.6, "stages": [ { "max_power": 225, "cop": 7.1 }, { "max_power": 300, "cop": 7.0 }, { "max_power": 400, "cop": 6.5 }, { "max_power": 500, "cop": 6.0 }, { "max_power": 600, "cop": 5.5 }, { "max_power": 750, "cop": 5.0 }, { "max_power": 1000, "cop": 4.5 }, { "max_power": 1250, "cop": 4.0 } ], "entity adjust heating curve": "input_number.stooklijn_verschuiving_day_ahead", "adjustment factor": 0.04 }, "battery": [ { "name": "BYD", "capacity": 9.0, "entity actual level": "sensor.battery_state_of_charge", "upper limit": 95, "lower limit": 5, "optimal lower level": 10, "entity min soc end opt": "input_number.dao_min_soc_einde_opt", "entity max soc end opt": "input_number.dao_max_soc_einde_opt", "charge stages": [ { "power": 0, "efficiency": 1.0 }, { "power": 300, "efficiency": 0.88 }, { "power": 1000, "efficiency": 0.93 }, { "power": 2000, "efficiency": 0.95 }, { "power": 3000, "efficiency": 0.955 }, { "power": 4000, "efficiency": 0.95 }, { "power": 5000, "efficiency": 0.94 } ], "discharge stages": [ { "power": 0, "efficiency": 1.0 }, { "power": 300, "efficiency": 0.9 }, { "power": 1000, "efficiency": 0.94 }, { "power": 2000, "efficiency": 0.955 }, { "power": 3000, "efficiency": 0.96 }, { "power": 4000, "efficiency": 0.955 }, { "power": 5000, "efficiency": 0.95 } ], "reduced hours": {}, "minimum power": 200, "dc_to_bat efficiency": 0.98, "dc_to_bat max power": 5000, "bat_to_dc efficiency": 0.99, "bat_to_dc max power": 5000, "cycle cost": 0.05, "entity set power feedin": "input_number.dao_goodwe_feed_in_limit_w", "entity balance switch": "input_boolean.dao_goodwe_balance_switch", "entity from battery": "sensor.battery_power", "entity from pv": "sensor.pv_power", "entity from ac": "sensor.dao_grid_net_power", "entity set power feedin": "input_number.dao_goodwe_feed_in_limit_w", "solar": [ { "name": "pv_roof_sw", "entity pv switch": "input_boolean.dao_pv_roof_sw_enable", "tilt": 5, "orientation": 69, "yield": 0.0085, "capacity": 4.56 }, { "name": "pv_roof_se", "entity pv switch": "input_boolean.dao_pv_roof_se_enable", "tilt": 15, "orientation": -22, "yield": 0.0063, "capacity": 3.36 } ] } ], "solar": [], "electric vehicle": [], "machines": [], "report": { "entities grid consumption": [ "sensor.slimmelezer_energy_consumed_tariff_1", "sensor.slimmelezer_energy_consumed_tariff_2" ], "entities grid production": [ "sensor.slimmelezer_energy_produced_tariff_1", "sensor.slimmelezer_energy_produced_tariff_2" ], "entities solar production ac": [], "entities solar production dc": [ "sensor.total_pv_generation" ], "entities ev consumption": [], "entities wp consumption": [], "entities boiler consumption": [], "entities machine consumption": [], "entities battery consumption": [ "sensor.total_battery_charge" ], "entities battery production": [ "sensor.total_battery_discharge" ] }, "scheduler": { "active": "true", "0430": "get_meteo_data", "1030": "get_meteo_data", "1630": "get_meteo_data", "2230": "get_meteo_data", "1255": "get_day_ahead_prices", "1355": "get_day_ahead_prices", "1455": "get_day_ahead_prices", "1554": "get_day_ahead_prices", "1655": "get_day_ahead_prices", "xx00": "calc_optimum", "xx15": "calc_optimum", "xx30": "calc_optimum", "xx45": "calc_optimum", "2359": "clean_data" } }
WP: Alpha Innotec MSW2-6S | PV: 20 x 300 Wp AEG | ACCU: 2x16x280Ah LiFePO4 3 x Multiplus II 48/3000 | DYN: Tibber | Gasloos | Day Ahead Optimizer
Ik heb het aangepast.
[ Voor 3% gewijzigd door Undertilted op 11-05-2026 09:34 ]
Ik kan me alleen bedenken dat de cycle cost relatief hoog staan op 0.05, je kunt eens proberen die omlaag te zetten naar 0.01, kijken wat er dan gebeurt. Anders zal het voornamelijk met de kosten te maken hebben. Want hij vind het blijkbaar interessanter om zonne stroom volledig aan het net te gaan leveren en niet zelf op te gebruiken.
Ik wil alleszinds meer de "general" mode van mijn omvormer gebruiken: die is veel nauwkeuriger dan wat DAO kan doen.
Daarom wil ik de entity_balance_switch gebruiken.
Wat me ook opvalt is dat DAO er van uitgaat dat ik rond deze tijd zonder DAO reeds begin terug te leveren. Dat klopt niet: mijn omvormer zal eerst de batterij volladen. Ik denk dat daar de fout zit.
Maar dat is dan toch niet de schuld van DAO?Undertilted schreef op maandag 11 mei 2026 @ 09:55:
Ik denk dat mijn verbruik nog niet goed gemoddeleerd is.
Ik wil alleszinds meer de "general" mode van mijn omvormer gebruiken: die is veel nauwkeuriger dan wat DAO kan doen.
Daarom wil ik de entity_balance_switch gebruiken.
Wat me ook opvalt is dat DAO er van uitgaat dat ik rond deze tijd zonder DAO reeds begin terug te leveren. Dat klopt niet: mijn omvormer zal eerst de batterij volladen. Ik denk dat daar de fout zit.
Als jouw omvormer op ''balance=on" staat omdat dat jou voorkeur heeft, dan heeft het voor DAO geen zin om te berekenen of wel/niet terugleveren handig is omdat je dat toch overruled. Als je al je gegevens correct instelt zal DAO zelf - afhankelijk van de door jou gekozen modus - doorgeven of het balanceren nodig is. Als dat op 'true' staat kan je via een automatisering jouw omvormer de opdracht geven de 0 te houden.
Buiten dat kan je via de andere helpers vanuit DAO ook krijgen wanneer het systeem vindt dat je moet opladen of ontladen. Ook dat kan je doorgeven aan je systeem middels een automatisering.
Het is niet de bedoeling om DAO elke seconde o.i.d. een getal uit te laten poepen waar je omvormer dan mee aan de slag gaat.
1x Venus-E v153 +LilyGo HA, CT003 V117 | 5040Wp ZO + 4200Wp NW | Zonneplan, 3x25A, Easee Charge Lite | EV 98kWh
DAO gaat er niet vanuit dat je dan teruglevert aan het net. DAO heeft berekend dat je zonne energie terugleveren op dat moment financieel gunstiger is dan in je batterij stoppen. Het is een advies van DAO aan jou.Undertilted schreef op maandag 11 mei 2026 @ 09:55:
Wat me ook opvalt is dat DAO er van uitgaat dat ik rond deze tijd zonder DAO reeds begin terug te leveren. Dat klopt niet: mijn omvormer zal eerst de batterij volladen. Ik denk dat daar de fout zit.
Als je DAO op minimize consumption zet dan komt er een ander beeld uit.
De grafiek die je deelt komt erg overeen met de grafiek die ik heb van dat tijdstip, dus ik denk dat het klopt.
DAO doet een advies. DAO doet zelf niet iets besturen. Dus DAO berekent bij jou dat het voordelig is om balance mode eigenlijk bijna altijd aan te hebben staan. Behalve wanneer de zon begint te schijnen dan is het beter om terug te gaan leveren aan het net om dat dat blijkbaar mee oplevert. Jij moet zelf de logica in Home Assistant bouwen om dit ook zo te laten zijn op je omvormer. Hierbij kan dat dus inhouden dat je omvormer gaat balanceren. Maar DAO doet het balanceren niet zelf. DAO zegt alleen ik wil dat je de komende 15 minuten Nul op de meter gaat draaien. Of ik wil dat je de komende 15 minuten met x vermogen gaat opladen/ontladen. Hoe jij dan zorgt dat je batterij dit ook gaat doen is aan jou.Undertilted schreef op maandag 11 mei 2026 @ 09:55:
Ik denk dat mijn verbruik nog niet goed gemoddeleerd is.
Ik wil alleszinds meer de "general" mode van mijn omvormer gebruiken: die is veel nauwkeuriger dan wat DAO kan doen.
Daarom wil ik de entity_balance_switch gebruiken.
Wat me ook opvalt is dat DAO er van uitgaat dat ik rond deze tijd zonder DAO reeds begin terug te leveren. Dat klopt niet: mijn omvormer zal eerst de batterij volladen. Ik denk dat daar de fout zit.
Wat jij zegt met de balance mode switch. Is een output van het advies van DAO. Dus DAO zegt ga balanceren dan zet het deze switch aan. Dat betekent niet dat DAO zelf het balanceren gaat regelen. Dat moet jij dan regelen door bijvoorbeeld je omvormer op de general mode te zetten zoals je beschrijft.
[ Voor 10% gewijzigd door thomvh op 11-05-2026 10:38 ]
Ik kreeg fout deze net ook bij het updaten.
Bij mij heb ik het opgelost door met de "Terminal & SSH" addon "ha supervisor repair" uit te voeren. Ik denk dat het fout is gegaan doordat ik zowel testing als productie tegelijkertijd probeerde te updaten.
Dat wil ik inderdaad bekomen. Maar dan moet ik de werking van input_boolean.dao_goodwe_balance_switch goed begrijpen.thomvh schreef op maandag 11 mei 2026 @ 10:36:
DAO zegt alleen ik wil dat je de komende 15 minuten Nul op de meter gaat draaien. Of ik wil dat je de komende 15 minuten met x vermogen gaat opladen/ontladen. Hoe jij dan zorgt dat je batterij dit ook gaat doen is aan jou.
Wat jij zegt met de balance mode switch. Is een output van het advies van DAO. Dus DAO zegt ga balanceren dan zet het deze switch aan. Dat betekent niet dat DAO zelf het balanceren gaat regelen. Dat moet jij dan regelen door bijvoorbeeld je omvormer op de general mode te zetten zoals je beschrijft.
De switch doet alleen aangeven dat het voor het komende interval nul op de meter moet doen. Hoe je dat dan inregelt is volledig aan jou. Ik heb het zo gedaan dat mijn inverter Zero export to CT gaat doen en het batterij nivea op mijn minimum komt te staan, maar dat heb ik in een Home Assistant Automation gedaan. Dan krijg ik een perfecte nul op de meter.Undertilted schreef op maandag 11 mei 2026 @ 10:47:
[...]
Dat wil ik inderdaad bekomen. Maar dan moet ik de werking van input_boolean.dao_goodwe_balance_switch goed begrijpen.
Hij rekent met de waardes die in jouw config staan. Want je hebt calc_baseload uit staan. Met die waardes en de stroomprijs bij jou vind DAO het het voordeligst om de batterij te gebruiken tot die leeg is. Hij gaat pas opladen wanneer het interessant is prijs technisch, met een cycle cost van 0.05 gaat dat pas gebeuren bij een grotere spread tussen de koop en verkoop prijs.Undertilted schreef op maandag 11 mei 2026 @ 10:45:
Hoe lang duurt het voor DAO het verbruik beter kan inschatten? Want op dit moment slaagt die de bal echt wel mis. [Afbeelding]
Ik zie hier nergens dat de accu wordt opgeladen.
Ik woon in Nederland dus mijn kosten zijn wat anders maar zo zien mijn grafiek er momenteel uit, het is gewoon geen denderende dag vandaag:
[ Voor 4% gewijzigd door thomvh op 11-05-2026 10:59 ]
prima plan en voorstel!wmc schreef op maandag 11 mei 2026 @ 10:39:
Is het een idee om een soort van bibliotheek op te gaan bouwen met voorbeelden van hoe DAO aan verschillende devices en automations gekoppeld is?
ik worstel er in ieder geval mee...
wat ik zie is dat er overdag veel zonnestroom overschot is maar dat die richting het net gaan ipv dat de batterijen gevuld worden, volgens mij kan je niet goedkoper je batterijen laden met gratis zonnestroom, dus waarom die dan naar het net gaat, ik heb geen idee....?
hier kan je mijn sturingen vinden:
https://github.com/hemertje/home-assistant-dao-zendure-nom-controller
Gasloos 2019 + WP Panasonic H-serie 7kW + 300 liter boilervat + PV 12.415Wp + Home Assistant + Hyundai Ioniq 6 First Edition + Zaptec laadpaal
Als je op moment x 20 cent per kWh krijgt voor het terugleveren van je overtollige zonnestroom en op moment y de accu kan laden tegen 5 cent (of uit overtollige zonnestroom die op dat moment maar 5 cent zou opleveren) dan kan je economisch gezien beter op moment x die stroom het net op sturen en op moment y laden.hemertje schreef op maandag 11 mei 2026 @ 21:19:
[...]
prima plan en voorstel!
ik worstel er in ieder geval mee...
wat ik zie is dat er overdag veel zonnestroom overschot is maar dat die richting het net gaan ipv dat de batterijen gevuld worden, volgens mij kan je niet goedkoper je batterijen laden met gratis zonnestroom, dus waarom die dan naar het net gaat, ik heb geen idee....?
hier kan je mijn sturingen vinden:
https://github.com/hemertje/home-assistant-dao-zendure-nom-controller
De vraag is dus wat DAO rekent als all-in terugleverprijs.
Als die hoger is dan de verwachte avondprijs minus cycle_cost, kiest DAO terecht voor terugleveren overdag.
Wat ik concreet zie:
overdag veel PV-overschot maar accu blijft laag, terwijl avondprijzen hoog zijn.
De spread zou groot genoeg moeten zijn.
Mijn vermoeden:
de PV-forecast van DAO was te laag — DAO wist niet dat er zoveel zon zou zijn, heeft de accu gepland voor laden op een ander moment, en het PV-overschot ging daardoor naar het net.
Geen bug, maar een forecast-accuraatheids probleem - zo lijkt het?
Volgende stap voor mij:
in HA Forecast.Solar deployen als referentie om te meten hoe groot de forecast-afwijking is...
[ Voor 90% gewijzigd door hemertje op 11-05-2026 21:50 ]
Gasloos 2019 + WP Panasonic H-serie 7kW + 300 liter boilervat + PV 12.415Wp + Home Assistant + Hyundai Ioniq 6 First Edition + Zaptec laadpaal
"charge_stages": [
{
"power": 0.0,
"efficiency": 1.0
},
{
"power": 100.0,
"efficiency": 0.5
},
{
"power": 300.0,
"efficiency": 0.75
},
{
"power": 500.0,
"efficiency": 0.85
},
{
"power": 800.0,
"efficiency": 0.89
},
{
"power": 1200.0,
"efficiency": 0.92
},
{
"power": 2000.0,
"efficiency": 0.94
},
{
"power": 4000.0,
"efficiency": 0.95
},
{
"power": 7000.0,
"efficiency": 0.955
},
{
"power": 11000.0,
"efficiency": 0.945
},
{
"power": 14000.0,
"efficiency": 0.93
},
{
"power": 17000.0,
"efficiency": 0.91
},
{
"power": 19500.0,
"efficiency": 0.89
}
],
"discharge_stages": [
{
"power": 0.0,
"efficiency": 1.0
},
{
"power": 100.0,
"efficiency": 0.45
},
{
"power": 300.0,
"efficiency": 0.7
},
{
"power": 500.0,
"efficiency": 0.82
},
{
"power": 800.0,
"efficiency": 0.88
},
{
"power": 1200.0,
"efficiency": 0.91
},
{
"power": 2000.0,
"efficiency": 0.93
},
{
"power": 4000.0,
"efficiency": 0.94
},
{
"power": 7000.0,
"efficiency": 0.945
},
{
"power": 11000.0,
"efficiency": 0.935
},
{
"power": 14000.0,
"efficiency": 0.92
},
{
"power": 17000.0,
"efficiency": 0.9
},
{
"power": 18000.0,
"efficiency": 0.89
}
Kun je grafieken van het gedrag laten zien? Dat kijkt wat makkelijker moet ik eerlijk bekennen om te begrijpen wat je gek gedrag vind. Daarbij ook in je hoofd houden. Door salderen is het relatief interessant om stroom te verkopen. Ook wanneer je overschot hebt.hemertje schreef op maandag 11 mei 2026 @ 21:43:
@Isdatzo klopt in theorie, maar mijn cycle_cost staat op 1,5 cent.
De vraag is dus wat DAO rekent als all-in terugleverprijs.
Als die hoger is dan de verwachte avondprijs minus cycle_cost, kiest DAO terecht voor terugleveren overdag.
Wat ik concreet zie:
overdag veel PV-overschot maar accu blijft laag, terwijl avondprijzen hoog zijn.
De spread zou groot genoeg moeten zijn.
Mijn vermoeden:
de PV-forecast van DAO was te laag — DAO wist niet dat er zoveel zon zou zijn, heeft de accu gepland voor laden op een ander moment, en het PV-overschot ging daardoor naar het net.
Geen bug, maar een forecast-accuraatheids probleem - zo lijkt het?
Volgende stap voor mij:
in HA Forecast.Solar deployen als referentie om te meten hoe groot de forecast-afwijking is...
[ Voor 5% gewijzigd door thomvh op 11-05-2026 22:53 ]
Ik heb de resources van mijn machine al gecontroleerd, maar ik zie niks bijzonders. Ram ok, CPU tijdens de berekening is ook laag 2% correctie 52% van 2 cpu, dus 1 cpu staat op 100% denk ik. Schijfruimte is ook ok.
Ook een restart van de docker gedaan, zonder resultaat.
max gap verhogen werkt ook niet.
Iemand een idee? Misschien is het morgen weer beter..
[ Voor 7% gewijzigd door Dogooder op 11-05-2026 23:31 ]
Mhh, je hebt bijna constant een negatieve baseload. Ben geen expert, maar dat kan natuurlijk de berekening de verkeerde kant op trekken.
Bij mij deed die vanochtend dit:
Ik snap ook nog niet helemaal waarom ik alles tussen 9 en 13 uur het net op gooi, voelt een beetje verspillend aan... Ik zou zelf ook denken de zonnestroom is goedkoper dan van het net aftrekken, want hij begint bij het dal pas te laden, en zeker omdat hij hem niet vol laad. Maar misschien dat iemand anders hier meer toelichting kan geven.
Als de prijzen dicht bij elkaar liggen (=weinig spreiding) gaat ie langer rekenen is mijn ervaring.Dogooder schreef op maandag 11 mei 2026 @ 23:11:
Ik draai nog versie 2026.4.4, maar ik heb sinds vandaag dat de rekentijden ineens zijn gaan toenemen. Vanochtend om 0600 uur ging een berekening nog binnen de seconde. Maar daarna is het ineens gaan toenemen en nu duurt het 360 tot 400 seconden. Nog even en het kwartier is voorbij voordat hij klaar is.
Ik heb de resources van mijn machine al gecontroleerd, maar ik zie niks bijzonders. Ram ok, CPU tijdens de berekening is ook laag 2% correctie 52% van 2 cpu, dus 1 cpu staat op 100% denk ik. Schijfruimte is ook ok.
Ook een restart van de docker gedaan, zonder resultaat.
Iemand een idee? Misschien is het morgen weer beter..
Ik heb max_gap verhoogd van 0.005 naar 0.1.
Dat maakt op (financiële) resultaat nauwelijks iets uit, maar de rekentijd daalt gigantisch.
Verder speelt het aantal "stages" van je batterij mee: hoe meer hoe trager.
Misschien kun je daarin kritisch grasduinen. Sinds afgelopen winter gaat DAO zelf tussen die stages interpoleren.
WP: Alpha Innotec MSW2-6S | PV: 20 x 300 Wp AEG | ACCU: 2x16x280Ah LiFePO4 3 x Multiplus II 48/3000 | DYN: Tibber | Gasloos | Day Ahead Optimizer
Dit is afhankelijk van je configuratie::thomvh schreef op maandag 11 mei 2026 @ 23:19:
[...]
Bij mij deed die vanochtend dit:
[...]
Ik snap ook nog niet helemaal waarom ik alles tussen 9 en 13 uur het net op gooi, voelt een beetje verspillend aan... Ik zou zelf ook denken de zonnestroom is goedkoper dan van het net aftrekken, want hij begint bij het dal pas te laden, en zeker omdat hij hem niet vol laad. Maar misschien dat iemand anders hier meer toelichting kan geven.
De inhoud van je batterij (in netto kWh) aan het einde wordt gewaardeerd tegen het gemiddelde inkoop tarief, maar als je cycle kosten hebt geconfigureerd en je hebt ook nog eens "opslag" verlies (efficiency) dan kan het netto net iets minder opleveren om op te slaan dan terug te leveren. Ik denk dat het vanmorgen "kantje boord" was.
Bij mij gebeurde er in die periode ook niks:
WP: Alpha Innotec MSW2-6S | PV: 20 x 300 Wp AEG | ACCU: 2x16x280Ah LiFePO4 3 x Multiplus II 48/3000 | DYN: Tibber | Gasloos | Day Ahead Optimizer
Thanks voor de uitleg! Zoals ik eerder al zei ben geen expert, dit is volgend jaar natuurlijk compleet verleden tijd want dan is het verschil tussen opslaan en verkopen natuurlijk tussen de 10 en 15 cent ergens. Waardoor opslaan eigenlijk altijd wel voordeliger zal zijn.KC27 schreef op maandag 11 mei 2026 @ 23:50:
[...]
Dit is afhankelijk van je configuratie::
De inhoud van je batterij (in netto kWh) aan het einde wordt gewaardeerd tegen het gemiddelde inkoop tarief, maar als je cycle kosten hebt geconfigureerd en je hebt ook nog eens "opslag" verlies (efficiency) dan kan het netto net iets minder opleveren om op te slaan dan terug te leveren. Ik denk dat het vanmorgen "kantje boord" was.
Bij mij gebeurde er in die periode ook niks:
[...]
ik had al Zendure thuisbatterijen staan voordat ik DAO installeerdethomvh schreef op maandag 11 mei 2026 @ 23:19:
[...]
Mhh, je hebt bijna constant een negatieve baseload. Ben geen expert, maar dat kan natuurlijk de berekening de verkeerde kant op trekken.
Bij mij deed die vanochtend dit:
[...]
Ik snap ook nog niet helemaal waarom ik alles tussen 9 en 13 uur het net op gooi, voelt een beetje verspillend aan... Ik zou zelf ook denken de zonnestroom is goedkoper dan van het net aftrekken, want hij begint bij het dal pas te laden, en zeker omdat hij hem niet vol laad. Maar misschien dat iemand anders hier meer toelichting kan geven.
deze beinvloeden dus de metingen van de P1 meter en de ML baseload learning naar mijn idee ?
Gasloos 2019 + WP Panasonic H-serie 7kW + 300 liter boilervat + PV 12.415Wp + Home Assistant + Hyundai Ioniq 6 First Edition + Zaptec laadpaal
De zelfvoorzienend van 78% bij 35 kWh opwek met 3× SolarFlow 2400 AC+ en bang-bang NoM controller: 22.6 kWh zelfverbruik, 6.7 kWh import, 12.5 kWh teruglevering. Dit is de baseline zonder EV vandaag.
Vragen die ik heb
PV forecast
Wie gebruikt Forecast.Solar of Solcast als externe bron naast de ML forecast?
Merken jullie significant verschil bij bewolkte/wisselvallige dagen?
Upper limit strategie
Zetten jullie upper limit bewust onder 100% om ruimte te houden voor onverwachte PV-pieken?
Of laten jullie DAO dat volledig bepalen? ik hanteer een bereik van 10-100%.
502 bij herstart
Herkennen jullie een 502 BadGateway na een HA herstart in 2026.5.0?
Of is dit specifiek voor mijn setup?
Gasloos 2019 + WP Panasonic H-serie 7kW + 300 liter boilervat + PV 12.415Wp + Home Assistant + Hyundai Ioniq 6 First Edition + Zaptec laadpaal
Je kunt wel je baseload statisch zetten en de pv yield gebruiken voor pv in plaats van de ml voorspellingen.
Daar zou ik beginnen. Baseload en pv data uit homeassistant halen zou ik pas gaan doen als alles correct werkt. Een ding tegelijk wijzigen.
De dynamische berekeningen werken natuurlijk alleen als de input goed is. Garbage in, garbage out principe.
[ Voor 12% gewijzigd door simnet op 12-05-2026 18:44 ]
Jouw baseline is best ver weg van je normale verbruik. Waardoor je misschien ook wel raar gedrag krijgt. Ik zou zoals andere zeggen even beginnen met manuele PV en Baseload settings.hemertje schreef op dinsdag 12 mei 2026 @ 18:23:
[...]
ik had al Zendure thuisbatterijen staan voordat ik DAO installeerde
deze beinvloeden dus de metingen van de P1 meter en de ML baseload learning naar mijn idee ?
nu las ik dat dao voor ml de laatste 3 jaar gebruikt aan data in home assistant, alleen heb ik iets minder dan 2 jaar geleden mijn pv verdubbeld van 6000wp naar 12000wp, en deze data zit in de zelfde sensor, zou hierdoor de ml te laag zijn?
Zou zeker kunnen. Als ik even bierviltjes rekenen doe. Kom jij op een gemiddelde van 10.000wp over 3 jaar uit. Wat 17 % minder dan je huidige is. Dus zou me persoonlijk niks verbazen.TheMystery schreef op dinsdag 12 mei 2026 @ 20:54:
Bij mij is de prognose van solar voor machine learning altijd erg laag, doa zit er dichter in de buurt maar meestal toch 10% ernaast.
nu las ik dat dao voor ml de laatste 3 jaar gebruikt aan data in home assistant, alleen heb ik iets minder dan 2 jaar geleden mijn pv verdubbeld van 6000wp naar 12000wp, en deze data zit in de zelfde sensor, zou hierdoor de ml te laag zijn?
En hier kan ik denk ik niets aan veranderen?, je zou eigenlijk een datum in de config moeten kunnen zetten zodat deze met juiste data kan rekenen.thomvh schreef op dinsdag 12 mei 2026 @ 20:59:
[...]
Zou zeker kunnen. Als ik even bierviltjes rekenen doe. Kom jij op een gemiddelde van 10.000wp over 3 jaar uit. Wat 17 % minder dan je huidige is. Dus zou me persoonlijk niks verbazen.
En voor het genoemde voorbeeld hierboven dat er al data van accu’s inzit een bepaalde juiste datum range.
edit: het verschil van de laatste 3 dagen tussen dao en ml is idd ongeveer 17%, maar welke waarde pakt dao nu?
[ Voor 8% gewijzigd door TheMystery op 12-05-2026 21:13 ]
Ja dat zou heel goed kunnen.TheMystery schreef op dinsdag 12 mei 2026 @ 20:54:
Bij mij is de prognose van solar voor machine learning altijd erg laag, doa zit er dichter in de buurt maar meestal toch 10% ernaast.
nu las ik dat dao voor ml de laatste 3 jaar gebruikt aan data in home assistant, alleen heb ik iets minder dan 2 jaar geleden mijn pv verdubbeld van 6000wp naar 12000wp, en deze data zit in de zelfde sensor, zou hierdoor de ml te laag zijn?
Kun je die oude data niet weggooien of verplaatsen naar een andere sensor (als je een beetje handig bent met sql)?
Eigenlijk moet je bij een flinke wijziging van je pv installatie in HA een nieuwe sensor aanmaken.
Dan kun je in HA (en eventueel ook in DAO) altijd nog sommeren.
[ Voor 14% gewijzigd door KC27 op 12-05-2026 21:31 ]
WP: Alpha Innotec MSW2-6S | PV: 20 x 300 Wp AEG | ACCU: 2x16x280Ah LiFePO4 3 x Multiplus II 48/3000 | DYN: Tibber | Gasloos | Day Ahead Optimizer
Om er zelf nog even in te duiken en ook om beter toe te lichten heb ik de rekentijden uit alle logs getrokken en in een grafiek geplot.Dogooder schreef op maandag 11 mei 2026 @ 23:11:
Ik draai nog versie 2026.4.4, maar ik heb sinds vandaag dat de rekentijden ineens zijn gaan toenemen. Vanochtend om 0600 uur ging een berekening nog binnen de seconde. Maar daarna is het ineens gaan toenemen en nu duurt het 360 tot 400 seconden. Nog even en het kwartier is voorbij voordat hij klaar is.
Ik heb de resources van mijn machine al gecontroleerd, maar ik zie niks bijzonders. Ram ok, CPU tijdens de berekening is ook laag 2% correctie 52% van 2 cpu, dus 1 cpu staat op 100% denk ik. Schijfruimte is ook ok.
Ook een restart van de docker gedaan, zonder resultaat.
max gap verhogen werkt ook niet.
Iemand een idee? Misschien is het morgen weer beter..
Voor 8 mei waren de rekentijden eigenlijk altijd onder de seconde. Je ziet mooi de rekentijd afnemen totdat de nieuwe prijzen zijn opgehaald. Maar sinds gisteren is zonder aanleiding het hek van de dam met rekentijden structureel meer dan 300 seconden.Ik heb nu de max-gap naar 0.1 bijgesteld, en dat zal vast wat helpen. Maar misschien ook wel verhullen wat hier fout gaat. Restart van de docker mocht ook niet echt baten. Ik draai 2026.4.4 al sinds 2026-04-25.
Zou het iets in de prijsdata of solardata kunnen zijn geweest?
Ik heb de data in ha zitten sinds het energy dashboard bestaat, en ik heb de data in 1 sensor anders is de hele historie in ha weg en die wil ik graag houden. Is er geen optie in te bouwen waar je de begin datum aan kan geven voor ml?KC27 schreef op dinsdag 12 mei 2026 @ 21:27:
[...]
Ja dat zou heel goed kunnen.
Kun je die oude data niet weggooien of verplaatsen naar een andere sensor (als je een beetje handig bent met sql)?
Eigenlijk moet je bij een flinke wijziging van je pv installatie in HA een nieuwe sensor aanmaken.
Dan kun je in HA (en eventueel ook in DAO) altijd nog sommeren.
of hoe lang duurt het voor dit recht getrokken wordt?
[ Voor 4% gewijzigd door TheMystery op 12-05-2026 22:10 ]
bijv.
2026-05-12 22:16:21 info: baseload voor weekdag 0 :
2026-05-12 22:16:21 info: 0.151 0.157 0.151 0.149 0.155 0.151 39.098 140.083 215.167 762.834 1239.375 388.981 198.054 822.686 1124.82 635.695 707.707 414.152 223.684 106.226 26.273 0.394 0.418 0.286
Zowel bij de solar ML prediction parameter als de report solar ac parameter gebruik ik dezelfde sensor.
Wat doe ik fout?
Ga ik even over nadenken ... als ik nou niks te doen hadTheMystery schreef op dinsdag 12 mei 2026 @ 22:08:
[...]
Ik heb de data in ha zitten sinds het energy dashboard bestaat, en ik heb de data in 1 sensor anders is de hele historie in ha weg en die wil ik graag houden. Is er geen optie in te bouwen waar je de begin datum aan kan geven voor ml?
Je mag altijd een PR indienen in Github.
DAO neemt nu standaard de solar-data van de laatste drie jaar.of hoe lang duurt het voor dit recht getrokken wordt?
Dus als je twee jaar geleden je pv-installatie hebt uitgebreid nog een jaar.
[ Voor 22% gewijzigd door KC27 op 12-05-2026 22:27 ]
WP: Alpha Innotec MSW2-6S | PV: 20 x 300 Wp AEG | ACCU: 2x16x280Ah LiFePO4 3 x Multiplus II 48/3000 | DYN: Tibber | Gasloos | Day Ahead Optimizer
Dit zou goed moeten gaan.atimmerman schreef op dinsdag 12 mei 2026 @ 22:20:
Wanneer ik DAO een balansrapport maak dan zie ik prima waarden voor de baseload. Daar worden ook de 2 verschillende AC solar systemen netjes gesommeerd. Wanneer ik echter een baseline laat berekenen, eerst even over een korte periode van 7 dagen, dan komen daar totaal foute waarden uit. Nu denk ik dat dat komt omdat de waarden van 1 solar systeem in Wh in HA terecht komt en daar netjes gescaled wordt. Kan/moet ik in DAO dan iets aan scaling doen?
bijv.
2026-05-12 22:16:21 info: baseload voor weekdag 0 :
2026-05-12 22:16:21 info: 0.151 0.157 0.151 0.149 0.155 0.151 39.098 140.083 215.167 762.834 1239.375 388.981 198.054 822.686 1124.82 635.695 707.707 414.152 223.684 106.226 26.273 0.394 0.418 0.286
Zowel bij de solar ML prediction parameter als de report solar ac parameter gebruik ik dezelfde sensor.
Wat doe ik fout?
Kun je de volgende rapportages berekeningen maken en de resultaten hier delen:
Via Reports, balans, gisteren: de hele tabel
Zet "baseload_calc_periode": 7
Via Run Bereken de baseload: de logging en/of de inhoud van het bestand baseload_0.json (dit is de baseload van maandag, staat in addon_config/xxxxx_dao_ahead_opt/dao_data).
WP: Alpha Innotec MSW2-6S | PV: 20 x 300 Wp AEG | ACCU: 2x16x280Ah LiFePO4 3 x Multiplus II 48/3000 | DYN: Tibber | Gasloos | Day Ahead Optimizer
Hoi @simnet , @thomvhsimnet schreef op dinsdag 12 mei 2026 @ 18:43:
Je data in homeassistant is duidelijk incorrect. Ik heb geen antwoord over joe je dat kunt fixen. Ik denk dat je daar niets aan kunt doen.
Je kunt wel je baseload statisch zetten en de pv yield gebruiken voor pv in plaats van de ml voorspellingen.
Daar zou ik beginnen. Baseload en pv data uit homeassistant halen zou ik pas gaan doen als alles correct werkt. Een ding tegelijk wijzigen.
De dynamische berekeningen werken natuurlijk alleen als de input goed is. Garbage in, garbage out principe.
dank voor je reactie.
Onlangs kwam ik hier op Tweakers het project van @Lasoul tegen: https://github.com/patric...istant-Import-Energy-Data
Ik zit sinds 2013 bij www.energiemanageronline.nl dus heb mijn data al meer dan 12 jaar beschikbaar.
Met de hulp van @Lasoul hebben we de 13 jaar data van energiemanageronline met hulp van zijn project in mijn HA ingelezen zodat DAO deze als input kan gebruiken...
HA zelf heb ik nu een 1,5 jaar draaien.
Een 14 maanden geleden is mijn PV-installatie uitgebreid jaar geleden
Een 6 weken geleden zijn de Zendure batterijen in huis gekomen
Een 3 weken geleden heb ik DAO geinstalleerd
@simnet Over welke data heb je het dan die incorrect is?
Hieronder mijn DAO config, wat dien ik aan te passen om te proberen de voorspellingen meer realistisch te krijgen?
code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820Home Run Reports Savings Solar Config options secrets JSON Editorupdate cancel { "config_version": 1, "homeassistant": { "ip_address": "supervisor", "protocol_api": "http" }, "database_ha": { "engine": "sqlite", "db_path": "/homeassistant", "database": "home-assistant_v2.db" }, "database_da": { "engine": "sqlite", "db_path": "../data", "database": "day_ahead.db" }, "meteoserver_key": "!secret meteoserver-key", "meteoserver_model": "harmonie", "meteoserver_attemps": 2, "prices": { "source_day_ahead": "nordpool", "energy_taxes_consumption": { "2022-01-01": 0.06729, "2023-01-01": 0.12599, "2024-01-01": 0.1088, "2025-01-01": 0.10154 }, "energy_taxes_production": { "2022-01-01": 0.06729, "2023-01-01": 0.12599, "2024-01-01": 0.1088, "2025-01-01": 0.10154 }, "cost_supplier_consumption": { "2022-01-01": 0.002, "2023-03-01": 0.018, "2024-04-01": 0.0175, "2024-08-01": 0.020496 }, "cost_supplier_production": { "2022-01-01": 0.002, "2023-03-01": 0.018, "2024-04-01": 0.0175, "2024-08-01": 0.020496, "2026-01-01": 0.0 }, "vat_consumption": { "2022-01-01": 21.0, "2022-07-01": 9.0, "2023-01-01": 21.0 }, "vat_production": { "2022-01-01": 21.0, "2022-07-01": 9.0, "2023-01-01": 21.0 }, "last_invoice": "2025-09-01", "tax_refund": true, "regular high": 0.5, "regular low": 0.4, "switch to low": 23 }, "logging_level": "info", "use_calc_baseload": true, "baseload_calc_periode": 56, "baseload": [ 0.14, 0.38, 0.26, 0.42, 0.15, 0.12, 0.13, 0.15, 0.23, 0.26, 0.31, 0.32, 0.31, 0.23, 0.26, 0.21, 0.21, 0.54, 0.26, 0.26, 0.22, 0.19, 0.18, 0.16 ], "graphical_backend": "", "graphics": { "style": "Solarize_Light2", "battery_balance": true, "prices_consumption": true, "prices_production": false, "prices_spot": true, "average_consumption": true, "show": "true" }, "interval": "15min", "strategy": "minimize cost", "max_gap": 0.005, "notifications": { "opstarten": false, "berekening": false }, "grid": { "max_power": 17.0 }, "history": { "save_days": 7 }, "dashboard": { "port": 5000 }, "battery": [ { "name": "Zendure 3x SolarFlow 2400 AC+", "entity_actual_level": "sensor.zendure_total_state_of_charge", "capacity": 24.48, "upper_limit": 100, "lower_limit": 10, "optimal_lower_level": 15, "penalty_low_soc": 0.0025, "entity_min_soc_end_opt": "input_number.dao_min_soc_einde_opt", "entity_max_soc_end_opt": "input_number.dao_max_soc_einde_opt", "charge_stages": [ { "power": 0.0, "efficiency": 1.0 }, { "power": 500.0, "efficiency": 0.88 }, { "power": 2400.0, "efficiency": 0.93 }, { "power": 3000.0, "efficiency": 0.92 } ], "discharge_stages": [ { "power": 0.0, "efficiency": 1.0 }, { "power": 500.0, "efficiency": 0.88 }, { "power": 2400.0, "efficiency": 0.93 }, { "power": 3000.0, "efficiency": 0.92 } ], "reduced_hours": {}, "reduce_power_low_soc": [], "reduce_power_high_soc": [], "minimum_power": 50, "dc_to_bat_efficiency": 0.97, "bat_to_dc_efficiency": 0.97, "cycle_cost": 0.015, "entity_set_power_feedin": "input_number.dao_set_power_feedin", "entity_set_operating_mode": "input_select.dao_set_operation_mode", "entity_set_operating_mode_on": "Aan", "entity_set_operating_mode_off": "Uit", "entity_stop_inverter": "input_datetime.dao_stop_inverter", "entity_balance_switch": "input_boolean.dao_balance_switch", "entity_from_battery": "input_number.dao_from_battery", "entity_from_ac": "input_number.dao_from_ac", "entity_calculated_soc": "input_number.dao_calculated_soc", "solar": [], "_comment_stages": "Max power gealigneerd met Gielz (3000 W). Pas naar 7200 aan wanneer hubs hard-wired op geschikte groep." } ], "solar": [ { "name": "SolarEdge_8kW", "entity_pv_switch": "input_boolean.dao_pv_solaredge_active", "strings": [ { "tilt": 15.0, "orientation": 39.0, "capacity": 4.8, "ml_prediction": false, "entities_sensors": [], "yield_factor": 0.0105, "_comment": "S1: Plat dak uitbouw 16×300W, Zuid-West" }, { "tilt": 90.0, "orientation": 23.0, "capacity": 0.86, "ml_prediction": false, "entities_sensors": [], "yield_factor": 0.0065, "_comment": "S2: Verticaal zuidgevel 2×430W" }, { "tilt": 37.0, "orientation": 23.0, "capacity": 3.0, "ml_prediction": false, "entities_sensors": [], "yield_factor": 0.01, "_comment": "S3: Hoofddak Zuid 10×300W" }, { "tilt": 32.0, "orientation": -63.0, "capacity": 1.66, "ml_prediction": false, "entities_sensors": [], "yield_factor": 0.0085, "_comment": "S4: Hoofddak Zuid-Oost 3×410W+1×430W" }, { "tilt": 32.0, "orientation": 108.0, "capacity": 2.05, "ml_prediction": false, "entities_sensors": [], "yield_factor": 0.0085, "_comment": "S5: Hoofddak West 5×410W" } ], "ml_prediction": true, "entities_sensors": [ "sensor.solaredge_lifetime_energy" ], "_comment_source": "Gebruikt sensor.solaredge_lifetime_energy (Wh) voor ML training - heeft jaren LTS historie. DAO traint op hourly deltas, absolute unit irrelevant voor patroonherkenning.", "_comment_pv_switch": "Fase 2.6: DAO zet deze boolean op off bij negatieve terugleververgoeding. Automation dao_sync_pv_switch synchroniseert met sensor.dao_pv_curtailment_active." } ], "electric_vehicle": [], "machines": [], "boiler": { "boiler_present": true, "entity_actual_temp": "sensor.panasonic_heat_pump_main_dhw_temp", "entity_setpoint": "input_number.dao_dhw_setpoint", "entity_hysterese": "input_number.dao_dhw_hysterese", "entity_enabled": "input_boolean.dao_dhw_enabled", "entity_instant_start": "input_boolean.dao_dhw_instant_start", "cop": 2.6, "cooling_rate": 0.4, "volume": 300.0, "heating_allowed_below": -10, "elec_power": 2000.0, "activate_service": "mqtt.publish", "boiler_heated_by_heatpump": true, "switch_entity": "input_boolean.dao_dhw_force_run" }, "heating": { "heater_present": true, "entity_hp_enabled": "input_boolean.dao_wp_enabled", "degree_days_factor": 3.6, "adjustment": "heating curve", "stages": [ { "max_power": 0.0, "cop": 8.0 }, { "max_power": 500.0, "cop": 6.0 }, { "max_power": 900.0, "cop": 4.5 }, { "max_power": 1400.0, "cop": 3.5 }, { "max_power": 1960.0, "cop": 2.8 }, { "max_power": 4590.0, "cop": 1.5 } ], "entity_adjust_heating_curve": "input_number.stooklijn_verschuiving_day_ahead", "adjustment_factor": 2.0, "min_run_length": 1, "entity_heat_produced": "sensor.panasonic_heat_pump_main_heat_power_production", "entity_hp_heat_demand": "sensor.panasonic_heat_pump_main_z1_heat_request_temp", "entity_avg_outside_temp": "sensor.knmi_temperatuur", "entity_hp_cop": "sensor.dao_wp_cop_template", "entity_hp_power": "sensor.panasonic_heat_pump_main_heat_power_consumption", "entity_hp_switch": "switch.panasonic_heat_pump_main_heatpump_state" }, "tibber": { "api_token": "!secret tibber_api_token", "api_url": "https://api.tibber.com/v1-beta/gql" }, "xgboost": { "tune_hyperparameters": true }, "report": { "entities_grid_consumption": [ "sensor.tibber_pulse_hemertje_last_meter_consumption" ], "entities_grid_production": [ "sensor.tibber_pulse_hemertje_last_meter_production" ], "entities_solar_production_ac": [ "sensor.solaredge_woning_ac_energy_kwh" ], "entities_solar_production_dc": [], "entities_ev_consumption": [ "sensor.laadpunt_total_energy" ], "entities_wp_consumption": [ "sensor.heishamon_wp_energy_kwh" ], "entities_boiler_consumption": [ "sensor.heishamon_backup_heater_energy_kwh" ], "entities_battery_consumption": [ "sensor.zendure_energy_import" ], "entities_battery_production": [ "sensor.zendure_energy_export" ], "entities_machine_consumption": [] }, "scheduler": { "active": true, "schedule": [ { "time": "0235", "action": "calc_baseloads" }, { "time": "0300", "action": "train_ml_predictions" }, { "time": "0435", "action": "get_meteo_data" }, { "time": "1035", "action": "get_meteo_data" }, { "time": "1635", "action": "get_meteo_data" }, { "time": "2235", "action": "get_meteo_data" }, { "time": "1335", "action": "get_day_ahead_prices" }, { "time": "1415", "action": "get_day_ahead_prices" }, { "time": "1515", "action": "get_day_ahead_prices" }, { "time": "1615", "action": "get_day_ahead_prices" }, { "time": "1715", "action": "get_day_ahead_prices" }, { "time": "xx00", "action": "calc_optimum" }, { "time": "xx15", "action": "calc_optimum" }, { "time": "xx30", "action": "calc_optimum" }, { "time": "xx45", "action": "calc_optimum" }, { "time": "2359", "action": "clean_data" } ] }, "meteoserver_attempts": 2 } { "config_version": 1, "homeassistant": { "ip_address": "supervisor", "protocol_api": "http" }, "database_ha": { "engine": "sqlite", "db_path": "/homeassistant", "database": "home-assistant_v2.db" }, "database_da": { "engine": "sqlite", "db_path": "../data", "database": "day_ahead.db" }, "meteoserver_key": "!secret meteoserver-key", "meteoserver_model": "harmonie", "meteoserver_attemps": 2, "prices": { "source_day_ahead": "nordpool", "energy_taxes_consumption": { "2022-01-01": 0.06729, "2023-01-01": 0.12599, "2024-01-01": 0.1088, "2025-01-01": 0.10154 }, "energy_taxes_production": { "2022-01-01": 0.06729, "2023-01-01": 0.12599, "2024-01-01": 0.1088, "2025-01-01": 0.10154 }, "cost_supplier_consumption": { "2022-01-01": 0.002, "2023-03-01": 0.018, "2024-04-01": 0.0175, "2024-08-01": 0.020496 }, "cost_supplier_production": { "2022-01-01": 0.002, "2023-03-01": 0.018, "2024-04-01": 0.0175, "2024-08-01": 0.020496, "2026-01-01": 0.0 }, "vat_consumption": { "2022-01-01": 21.0, "2022-07-01": 9.0, "2023-01-01": 21.0 }, "vat_production": { "2022-01-01": 21.0, "2022-07-01": 9.0, "2023-01-01": 21.0 }, "last_invoice": "2025-09-01", "tax_refund": true, "regular high": 0.5, "regular low": 0.4, "switch to low": 23 }, "logging_level": "info", "use_calc_baseload": true, "baseload_calc_periode": 56, "baseload": [ 0.14, 0.38, 0.26, 0.42, 0.15, 0.12, 0.13, 0.15, 0.23, 0.26, 0.31, 0.32, 0.31, 0.23, 0.26, 0.21, 0.21, 0.54, 0.26, 0.26, 0.22, 0.19, 0.18, 0.16 ], "graphical_backend": "", "graphics": { "style": "Solarize_Light2", "battery_balance": true, "prices_consumption": true, "prices_production": false, "prices_spot": true, "average_consumption": true, "show": "true" }, "interval": "15min", "strategy": "minimize cost", "max_gap": 0.005, "notifications": { "opstarten": false, "berekening": false }, "grid": { "max_power": 17.0 }, "history": { "save_days": 7 }, "dashboard": { "port": 5000 }, "battery": [ { "name": "Zendure 3x SolarFlow 2400 AC+", "entity_actual_level": "sensor.zendure_total_state_of_charge", "capacity": 24.48, "upper_limit": 100, "lower_limit": 10, "optimal_lower_level": 15, "penalty_low_soc": 0.0025, "entity_min_soc_end_opt": "input_number.dao_min_soc_einde_opt", "entity_max_soc_end_opt": "input_number.dao_max_soc_einde_opt", "charge_stages": [ { "power": 0.0, "efficiency": 1.0 }, { "power": 500.0, "efficiency": 0.88 }, { "power": 2400.0, "efficiency": 0.93 }, { "power": 3000.0, "efficiency": 0.92 } ], "discharge_stages": [ { "power": 0.0, "efficiency": 1.0 }, { "power": 500.0, "efficiency": 0.88 }, { "power": 2400.0, "efficiency": 0.93 }, { "power": 3000.0, "efficiency": 0.92 } ], "reduced_hours": {}, "reduce_power_low_soc": [], "reduce_power_high_soc": [], "minimum_power": 50, "dc_to_bat_efficiency": 0.97, "bat_to_dc_efficiency": 0.97, "cycle_cost": 0.015, "entity_set_power_feedin": "input_number.dao_set_power_feedin", "entity_set_operating_mode": "input_select.dao_set_operation_mode", "entity_set_operating_mode_on": "Aan", "entity_set_operating_mode_off": "Uit", "entity_stop_inverter": "input_datetime.dao_stop_inverter", "entity_balance_switch": "input_boolean.dao_balance_switch", "entity_from_battery": "input_number.dao_from_battery", "entity_from_ac": "input_number.dao_from_ac", "entity_calculated_soc": "input_number.dao_calculated_soc", "solar": [], "_comment_stages": "Max power gealigneerd met Gielz (3000 W). Pas naar 7200 aan wanneer hubs hard-wired op geschikte groep." } ], "solar": [ { "name": "SolarEdge_8kW", "entity_pv_switch": "input_boolean.dao_pv_solaredge_active", "strings": [ { "tilt": 15.0, "orientation": 39.0, "capacity": 4.8, "ml_prediction": false, "entities_sensors": [], "yield_factor": 0.0105, "_comment": "S1: Plat dak uitbouw 16×300W, Zuid-West" }, { "tilt": 90.0, "orientation": 23.0, "capacity": 0.86, "ml_prediction": false, "entities_sensors": [], "yield_factor": 0.0065, "_comment": "S2: Verticaal zuidgevel 2×430W" }, { "tilt": 37.0, "orientation": 23.0, "capacity": 3.0, "ml_prediction": false, "entities_sensors": [], "yield_factor": 0.01, "_comment": "S3: Hoofddak Zuid 10×300W" }, { "tilt": 32.0, "orientation": -63.0, "capacity": 1.66, "ml_prediction": false, "entities_sensors": [], "yield_factor": 0.0085, "_comment": "S4: Hoofddak Zuid-Oost 3×410W+1×430W" }, { "tilt": 32.0, "orientation": 108.0, "capacity": 2.05, "ml_prediction": false, "entities_sensors": [], "yield_factor": 0.0085, "_comment": "S5: Hoofddak West 5×410W" } ], "ml_prediction": true, "entities_sensors": [ "sensor.solaredge_lifetime_energy" ], "_comment_source": "Gebruikt sensor.solaredge_lifetime_energy (Wh) voor ML training - heeft jaren LTS historie. DAO traint op hourly deltas, absolute unit irrelevant voor patroonherkenning.", "_comment_pv_switch": "Fase 2.6: DAO zet deze boolean op off bij negatieve terugleververgoeding. Automation dao_sync_pv_switch synchroniseert met sensor.dao_pv_curtailment_active." } ], "electric_vehicle": [], "machines": [], "boiler": { "boiler_present": true, "entity_actual_temp": "sensor.panasonic_heat_pump_main_dhw_temp", "entity_setpoint": "input_number.dao_dhw_setpoint", "entity_hysterese": "input_number.dao_dhw_hysterese", "entity_enabled": "input_boolean.dao_dhw_enabled", "entity_instant_start": "input_boolean.dao_dhw_instant_start", "cop": 2.6, "cooling_rate": 0.4, "volume": 300.0, "heating_allowed_below": -10, "elec_power": 2000.0, "activate_service": "mqtt.publish", "boiler_heated_by_heatpump": true, "switch_entity": "input_boolean.dao_dhw_force_run" }, "heating": { "heater_present": true, "entity_hp_enabled": "input_boolean.dao_wp_enabled", "degree_days_factor": 3.6, "adjustment": "heating curve", "stages": [ { "max_power": 0.0, "cop": 8.0 }, { "max_power": 500.0, "cop": 6.0 }, { "max_power": 900.0, "cop": 4.5 }, { "max_power": 1400.0, "cop": 3.5 }, { "max_power": 1960.0, "cop": 2.8 }, { "max_power": 4590.0, "cop": 1.5 } ], "entity_adjust_heating_curve": "input_number.stooklijn_verschuiving_day_ahead", "adjustment_factor": 2.0, "min_run_length": 1, "entity_heat_produced": "sensor.panasonic_heat_pump_main_heat_power_production", "entity_hp_heat_demand": "sensor.panasonic_heat_pump_main_z1_heat_request_temp", "entity_avg_outside_temp": "sensor.knmi_temperatuur", "entity_hp_cop": "sensor.dao_wp_cop_template", "entity_hp_power": "sensor.panasonic_heat_pump_main_heat_power_consumption", "entity_hp_switch": "switch.panasonic_heat_pump_main_heatpump_state" }, "tibber": { "api_token": "!secret tibber_api_token", "api_url": "https://api.tibber.com/v1-beta/gql" }, "xgboost": { "tune_hyperparameters": true }, "report": { "entities_grid_consumption": [ "sensor.tibber_pulse_hemertje_last_meter_consumption" ], "entities_grid_production": [ "sensor.tibber_pulse_hemertje_last_meter_production" ], "entities_solar_production_ac": [ "sensor.solaredge_woning_ac_energy_kwh" ], "entities_solar_production_dc": [], "entities_ev_consumption": [ "sensor.laadpunt_total_energy" ], "entities_wp_consumption": [ "sensor.heishamon_wp_energy_kwh" ], "entities_boiler_consumption": [ "sensor.heishamon_backup_heater_energy_kwh" ], "entities_battery_consumption": [ "sensor.zendure_energy_import" ], "entities_battery_production": [ "sensor.zendure_energy_export" ], "entities_machine_consumption": [] }, "scheduler": { "active": true, "schedule": [ { "time": "0235", "action": "calc_baseloads" }, { "time": "0300", "action": "train_ml_predictions" }, { "time": "0435", "action": "get_meteo_data" }, { "time": "1035", "action": "get_meteo_data" }, { "time": "1635", "action": "get_meteo_data" }, { "time": "2235", "action": "get_meteo_data" }, { "time": "1335", "action": "get_day_ahead_prices" }, { "time": "1415", "action": "get_day_ahead_prices" }, { "time": "1515", "action": "get_day_ahead_prices" }, { "time": "1615", "action": "get_day_ahead_prices" }, { "time": "1715", "action": "get_day_ahead_prices" }, { "time": "xx00", "action": "calc_optimum" }, { "time": "xx15", "action": "calc_optimum" }, { "time": "xx30", "action": "calc_optimum" }, { "time": "xx45", "action": "calc_optimum" }, { "time": "2359", "action": "clean_data" } ] }, "meteoserver_attempts": 2 } © 2026: Apache 2.0 Day Ahead Optimizer version: 2026.5.0
Gasloos 2019 + WP Panasonic H-serie 7kW + 300 liter boilervat + PV 12.415Wp + Home Assistant + Hyundai Ioniq 6 First Edition + Zaptec laadpaal
Report,balans,gisterenKC27 schreef op dinsdag 12 mei 2026 @ 22:37:
[...]
Dit zou goed moeten gaan.
Kun je de volgende rapportages berekeningen maken en de resultaten hier delen:
Via Reports, balans, gisteren: de hele tabel
Zet "baseload_calc_periode": 7
Via Run Bereken de baseload: de logging en/of de inhoud van het bestand baseload_0.json (dit is de baseload van maandag, staat in addon_config/xxxxx_dao_ahead_opt/dao_data).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| Uur Verbruik Productie Accu_uit Accu in PV ac Elec. vehicle WP Boiler Machines Baseload kWh kWh kWh kWh kWh kWh kWh kWh kWh kWh 00:00 0.003 0.003 0.160 0.000 0.000 0.000 0.009 0.000 0.000 0.151 01:00 0.003 0.002 0.165 0.000 0.000 0.000 0.009 0.000 0.000 0.157 02:00 0.003 0.003 0.160 0.000 0.000 0.000 0.009 0.000 0.000 0.151 03:00 0.003 0.002 0.157 0.000 0.000 0.000 0.009 0.000 0.000 0.149 04:00 0.003 0.004 0.165 0.000 0.000 0.000 0.009 0.000 0.000 0.155 05:00 0.003 0.002 0.159 0.000 0.000 0.000 0.009 0.000 0.000 0.151 06:00 0.015 0.026 0.077 0.011 0.091 0.000 0.009 0.000 0.000 0.137 07:00 0.080 0.072 0.750 0.004 0.348 0.000 0.879 0.000 0.000 0.223 08:00 0.104 0.032 0.960 0.000 0.455 0.000 1.105 0.000 0.000 0.382 09:00 0.251 0.037 1.040 0.120 0.978 0.000 0.516 0.000 0.000 1.596 10:00 0.048 0.157 0.040 1.120 1.814 0.000 0.010 0.000 0.000 0.615 11:00 0.045 0.082 0.330 0.070 1.015 0.000 0.868 0.000 0.000 0.370 12:00 0.029 0.077 0.010 0.230 0.526 0.000 0.006 0.000 0.000 0.252 13:00 0.465 0.164 0.210 0.365 2.230 0.000 0.868 0.000 0.000 1.508 14:00 0.059 0.923 0.000 1.664 3.481 0.000 0.008 0.000 0.000 0.945 15:00 0.101 0.726 0.090 0.658 2.284 0.000 0.760 0.000 0.000 0.331 16:00 0.269 0.738 0.060 0.824 2.659 0.000 0.012 0.000 0.000 1.414 17:00 0.105 0.491 0.200 1.140 2.666 0.000 0.774 0.000 0.000 0.566 18:00 0.067 0.268 0.080 1.010 2.047 0.000 0.009 0.000 0.000 0.907 19:00 0.055 0.081 0.070 0.393 0.690 0.000 0.009 0.000 0.000 0.332 20:00 0.182 0.014 1.080 0.000 0.110 0.000 1.059 0.000 0.000 0.299 21:00 0.527 0.002 0.475 0.000 0.000 0.000 0.606 0.000 0.000 0.394 22:00 0.179 0.002 0.615 0.000 0.000 0.000 0.374 0.000 0.000 0.418 23:00 0.004 0.004 0.295 0.000 0.000 0.000 0.009 0.000 0.000 0.286 Totaal 2.603 3.912 7.348 7.609 21.394 0.000 7.934 0.000 0.000 11.890 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| [ 0.151, 0.157, 0.151, 0.149, 0.155, 0.151, 39.098, 140.083, 215.167, 762.834, 1239.375, 388.981, 198.054, 822.686, 1124.82, 635.695, 707.707, 414.152, 223.684, 106.226, 26.273, 0.394, 0.418, 0.286 ] |
Laat je balance report van gister eens zien.hemertje schreef op dinsdag 12 mei 2026 @ 22:44:
[...]
Hoi @simnet , @thomvh
dank voor je reactie.
Onlangs kwam ik hier op Tweakers het project van @Lasoul tegen: https://github.com/patric...istant-Import-Energy-Data
Ik zit sinds 2013 bij www.energiemanageronline.nl dus heb mijn data al meer dan 12 jaar beschikbaar.
Met de hulp van @Lasoul hebben we de 13 jaar data van energiemanageronline met hulp van zijn project in mijn HA ingelezen zodat DAO deze als input kan gebruiken...
HA zelf heb ik nu een 1,5 jaar draaien.
Een 14 maanden geleden is mijn PV-installatie uitgebreid jaar geleden
Een 6 weken geleden zijn de Zendure batterijen in huis gekomen
Een 3 weken geleden heb ik DAO geinstalleerd
@simnet Over welke data heb je het dan die incorrect is?
Hieronder mijn DAO config, wat dien ik aan te passen om te proberen de voorspellingen meer realistisch te krijgen?
[...]
Ik weet ook niet wat er bij jou aan de hand is. Bij mij gebeurde dit een paar weken terug en nu komen de oude snelle rekentijden weer terug.Dogooder schreef op dinsdag 12 mei 2026 @ 21:51:
[...]
Om er zelf nog even in te duiken en ook om beter toe te lichten heb ik de rekentijden uit alle logs getrokken en in een grafiek geplot.
[Afbeelding] Voor 8 mei waren de rekentijden eigenlijk altijd onder de seconde. Je ziet mooi de rekentijd afnemen totdat de nieuwe prijzen zijn opgehaald. Maar sinds gisteren is zonder aanleiding het hek van de dam met rekentijden structureel meer dan 300 seconden.
Ik heb nu de max-gap naar 0.1 bijgesteld, en dat zal vast wat helpen. Maar misschien ook wel verhullen wat hier fout gaat. Restart van de docker mocht ook niet echt baten. Ik draai 2026.4.4 al sinds 2026-04-25.
Zou het iets in de prijsdata of solardata kunnen zijn geweest?
Ik hoorde het ook van @tonvanboven (maar dat was "oude" hardware), dus je bent niet de enige.
Ik heb ook nog een suggestie van @tonvanboven op mijn to-do lijstje staan, om alle resultaten van de laatste berekening voor de volgende periode op te slaan in een bestand en deze waarden/settings bij het begin van die volgende periode (als de berekening wordt gestart) als "eerste orde benadering" naar HA te communiceren. Als dan de berekening twee minuten duurt is HA alvast begonnen en kan dit eventueel worden aangepast met de laatste resultaten.
Deze kan ook interessant zijn als we gaan rekenen met een of meer dagen voorspellingen van de day-ahead-prijzen, want dan zullen de rekentijden sowieso flink oplopen.
WP: Alpha Innotec MSW2-6S | PV: 20 x 300 Wp AEG | ACCU: 2x16x280Ah LiFePO4 3 x Multiplus II 48/3000 | DYN: Tibber | Gasloos | Day Ahead Optimizer
/f/image/ZQW22hC32PjhyoZxBoHasWUf.png?f=fotoalbum_large)
:strip_exif()/f/image/hrulFpdmFi7kBrHjztVPMSRc.png?f=user_large)
/f/image/vu1Sz7q2kkeAqL7uXFpt5o2d.png?f=fotoalbum_large)
/f/image/W4BrbUWt1RNK9DO94O0dDS5X.png?f=fotoalbum_large)
/f/image/s7JGOLViiPKWMqqNHq8CXDWu.png?f=fotoalbum_large)
/f/image/3HD1Cziopsv53ODz0l1VtnvR.png?f=fotoalbum_large)
/f/image/9XGGvGXxe7TjpF6gDNFwgSrG.png?f=fotoalbum_large)
/f/image/wVsZnYuW2R8nTWDX0mLMgqxr.png?f=fotoalbum_large)
:strip_exif()/f/image/1k1IsAMpQMPGdDbbTh72SDts.jpg?f=fotoalbum_large)
:strip_exif()/f/image/Qu35kfbJkPVjfLv323Tl5Qzj.jpg?f=fotoalbum_large)
:strip_exif()/f/image/pUhOOskVsSGe8SOxRJkSgOMu.jpg?f=fotoalbum_large)
:strip_exif()/f/image/7C9Hq0vd96uyAamVgdDJGqSc.jpg?f=fotoalbum_large)
:strip_exif()/f/image/FK3QZKXzQcUEazGbhmMXtYpi.jpg?f=fotoalbum_large)
/f/image/J0dVAuNrVt5P76TwwTKYRA8b.png?f=fotoalbum_large)