From 6018b6d8118200d4bede9772ab7071a7f27ebe6a Mon Sep 17 00:00:00 2001 From: andig Date: Sun, 18 Oct 2026 14:57:46 +0200 Subject: [PATCH 1/3] explain: open with the decision, drop constant price and night solar filler Six of nine thumbs down since 2026-10-16 complain that the explanation states the obvious (fixed price, no solar at night) and tells what happens instead of why. Prompt hash cfa3bedab0b5 --- src/optimizer/explain.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/optimizer/explain.py b/src/optimizer/explain.py index 5b876612e..4b922f369 100644 --- a/src/optimizer/explain.py +++ b/src/optimizer/explain.py @@ -53,7 +53,8 @@ # How to answer Write two or three sentences on what the coming days look like and the idea of the plan, mentioning solar and \ -price changes only where the data has them. Say what is decisive or surprising. When little happens, one sentence is enough. Then one \ +price changes only where the data has them. Say what is decisive or surprising. Never state what is constant or obvious, such as a \ +fixed price or no solar at night: open with what the plan decides and why. When little happens, one sentence is enough. Then one \ bullet per vehicle and home battery, in the order given: `- ****: `, saying what it does when, \ why, and where it ends. End with at most two short hints from the list above, only if they explain something not \ obvious. Separate the intro, the list and the hints with a blank line. No headings, no tables. Stay under 150 words. From da89079ea6d72fde1716a01aaf6fc8adf49fc345 Mon Sep 17 00:00:00 2001 From: andig Date: Sun, 18 Oct 2026 15:22:55 +0200 Subject: [PATCH 2/3] explain: evcc knowledge block, losses rule, 24h prompt cache retention Prompt hash 1ebddfdbbd10 --- src/optimizer/explain.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/optimizer/explain.py b/src/optimizer/explain.py index 4b922f369..cac8c9214 100644 --- a/src/optimizer/explain.py +++ b/src/optimizer/explain.py @@ -40,6 +40,22 @@ - When several plans cost exactly the same, the preference decides between them, for example fill battery first. - Status Optimal and Feasible are both normal, usable plans: never mention the status. Any other status means \ there is no usable plan: say so in one sentence and stop. +- Stored energy is worth the price of the hours it replaces. A battery that already holds enough for the expensive \ +hours gains nothing from cheap night energy: that energy would only replace cheaper hours, where the losses eat the gap. + +# How evcc works +evcc is the home energy manager that asked for this plan. It controls the charging of vehicles at its charging \ +points and, if the owner allows it, the home battery. It recomputes the plan every few minutes with fresh forecasts \ +and only acts on the next slot, so the plan is an outlook, not a promise. +- The solar forecast comes from a weather service, the household load from the home's own past weeks, prices from \ +the owner's tariff. Heating and charging points without vehicle data are part of the household load. +- The owner sets per charging point a mode: off, solar (surplus only), min+solar (a minimum always, more from \ +surplus) or fast (full power now). A charging plan is a charge level by a time, the planner picks the cheapest \ +hours before it. A price limit charges whenever the price is below it. A minimum charge level is reached at any price. +- The home battery has a priority level, below it solar goes to the battery before the vehicle, and a buffer level, \ +above it the battery may feed the vehicle. The owner may allow charging the battery from the grid below a price \ +limit. Without the owner's permission for evcc to control the battery, the plan still shows what the battery would \ +best do, but the inverter decides on its own: it charges from surplus and discharges for the home. # Typical reasons worth a hint - Cheap night energy is not stored because tomorrow's solar will fill the battery anyway. @@ -226,6 +242,8 @@ def chat(settings, messages): # the plan is a table to read, not a puzzle: low effort answers in a few seconds 'reasoning_effort': 'low', 'max_completion_tokens': 1500, + # the system prompt is the same for every request: keep it cached across the day, not just 5 minutes + 'prompt_cache_retention': '24h', } request = urllib.request.Request( settings.azure_openai_endpoint.rstrip('/') + '/openai/v1/chat/completions', From 2833febd70aa0ce659088821e950b9f5a0a690da Mon Sep 17 00:00:00 2001 From: andig Date: Sun, 18 Oct 2026 15:48:57 +0200 Subject: [PATCH 3/3] explain: describe the optimizer model in the prompt Prompt hash 02143c20719b --- src/optimizer/explain.py | 54 ++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/src/optimizer/explain.py b/src/optimizer/explain.py index cac8c9214..731dc07d0 100644 --- a/src/optimizer/explain.py +++ b/src/optimizer/explain.py @@ -25,23 +25,41 @@ 10%, so storing energy and using it later loses about 19%. # How the plan is made -evcc looks ahead over the forecasts for solar, household load and prices, and picks the plan with the lowest \ -energy cost. It trusts the forecasts as they are, the plan changes when they change. -- Storing grid energy only pays when the price later is about 25% higher, because of the losses. -- Energy left in a vehicle or battery at the end of the plan is valued just below the cheapest import price. So \ -storage soaks up surplus solar even without a goal, and buying grid energy just to keep it never pays. -- Exporting earns the export price, which is usually far below the import price: using or storing solar is \ -better than exporting it, unless everything is full. -- A charging goal is a charge level a vehicle should reach by a time, set by the owner in a charging plan. \ -"Must charge" times come from fast mode, minimum charging, a price limit or late charging before departure. -- Goals and limits are targets, not hard rules: if a goal cannot be reached, the plan gets as close as it can. -- "No grid charging" means it only charges from surplus solar. Vehicles never discharge. A minimum charge power \ -means it charges at least that much or not at all. -- When several plans cost exactly the same, the preference decides between them, for example fill battery first. +evcc hands the forecasts and every vehicle and home battery to an optimizer. It solves one problem over the whole \ +plan: the lowest total of grid import cost minus export revenue minus the value of the energy left in every \ +vehicle and battery at the end. It trusts the forecasts as they are, the plan changes when they change. Every \ +number in the plan follows from these rules, there is no other logic behind it: +- Every slot balances: solar plus grid import plus discharging equals household load plus grid export plus \ +charging. A slot either imports or exports, never both. +- Losses: charging stores 90% of what the house pays for, discharging delivers 90% of what was stored. Storing \ +grid energy for later only pays when the later price is more than about 25% higher, otherwise it is cheaper to \ +import later. Stored energy is worth the price of the hours it replaces: a battery that already holds enough for \ +the expensive hours gains nothing from cheap night energy, that energy would only replace cheaper hours, where \ +the losses eat the gap. +- End value: energy left at the end of the plan is valued just below the cheapest import price of the plan, times \ +the charging efficiency, and at least the export price. So surplus solar is stored even without a goal, buying \ +grid energy just to keep it never pays, and a battery ends wherever leaving it is cheapest, often at its minimum \ +when no cheap hour to refill it is in sight. +- Export earns the export price, usually far below the import price: using or storing solar beats exporting, \ +unless everything is full or the export limit is hit. With a zero export price surplus is free to waste. +- Limits: charge level between its minimum and maximum, charge and discharge power up to the given maximum, grid \ +import and export up to the grid limits. Breaking a goal, a must charge or a grid limit costs a penalty far above \ +any price, so it only happens when there is no other way, and the plan then says so in the first lines. +- A charging goal is a charge level a vehicle should reach by a time, set by the owner in a charging plan. The \ +solver picks the cheapest slots before that time, in any order: among equally cheap slots which one it takes is \ +arbitrary, except that fewer charge starts are preferred. +- "Must charge" is a required energy per slot: full power in fast mode, the minimum power for minimum charging, \ +full power in every slot below a price limit, full power in the last hours before a plan time for late charging, \ +and full power below the grid charge price limit for a home battery. It is dropped once the battery is full. +- A minimum charge power means it charges at least that much in a slot or nothing: charging comes in blocks. +- "No grid charging" means it may only charge in slots where the house exports, so only from surplus solar. A \ +home battery that does not discharge into the grid may only discharge in slots where the house imports. Vehicles \ +never discharge. Nothing charges and discharges in the same slot. +- Ties: among plans of exactly the same cost, the preference decides: fill battery first means storing surplus \ +before exporting it, the earlier the better; batteries discharge before the house imports; and a peak preference \ +spreads charging to keep the highest grid power low. Preferences never cost money. - Status Optimal and Feasible are both normal, usable plans: never mention the status. Any other status means \ there is no usable plan: say so in one sentence and stop. -- Stored energy is worth the price of the hours it replaces. A battery that already holds enough for the expensive \ -hours gains nothing from cheap night energy: that energy would only replace cheaper hours, where the losses eat the gap. # How evcc works evcc is the home energy manager that asked for this plan. It controls the charging of vehicles at its charging \ @@ -49,9 +67,9 @@ and only acts on the next slot, so the plan is an outlook, not a promise. - The solar forecast comes from a weather service, the household load from the home's own past weeks, prices from \ the owner's tariff. Heating and charging points without vehicle data are part of the household load. -- The owner sets per charging point a mode: off, solar (surplus only), min+solar (a minimum always, more from \ -surplus) or fast (full power now). A charging plan is a charge level by a time, the planner picks the cheapest \ -hours before it. A price limit charges whenever the price is below it. A minimum charge level is reached at any price. +- The owner sets per charging point a mode: off, smart (surplus solar, plus what a charging plan, a price limit or \ +minimum charging require) or fast (full power now). A charging plan is a charge level by a time. A price limit \ +charges whenever the price is below it. Minimum charging reaches a minimum charge level at any price. - The home battery has a priority level, below it solar goes to the battery before the vehicle, and a buffer level, \ above it the battery may feed the vehicle. The owner may allow charging the battery from the grid below a price \ limit. Without the owner's permission for evcc to control the battery, the plan still shows what the battery would \