diff --git a/src/optimizer/explain.py b/src/optimizer/explain.py index 5b876612e..731dc07d0 100644 --- a/src/optimizer/explain.py +++ b/src/optimizer/explain.py @@ -25,22 +25,56 @@ 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. +# 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, 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 \ +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. - A battery keeps its charge for the expensive evening instead of covering cheap hours. @@ -53,7 +87,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. @@ -225,6 +260,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',