Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 51 additions & 14 deletions src/optimizer/explain.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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: `- **<name>**: <one sentence>`, 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.
Expand Down Expand Up @@ -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',
Expand Down
Loading