## Fix feed-in price unit conversion, unify battery static price to ct/kWh - #286
Merged
Conversation
BatteryPriceHandler.pv_cost_euro_per_kwh expects €/kWh, but both the startup wiring in eos_connect.py and the hot-reload path in hot_reload.py passed the raw ct/kWh config value through unconverted. This inflated the PV opportunity-cost term, and therefore the computed battery price, by 100x whenever battery_price_include_feedin was enabled. Also removes the fixed-price EUR/ct auto-detection heuristic in FeedInPriceInterface: it silently guessed the unit based on a magnitude threshold (<0.1) and missed exactly this class of mistake for realistic ct/kWh values above that threshold. Fixes: #283
price.feed_in_price is ct/kWh everywhere in the schema and code, but two examples and one field description in the user guide showed or implied €/kWh — the same mix-up reported in #283. Also clarifies that feed_in_price is a price.* key, not a battery.* key, and that battery_price_include_feedin must be enabled for it to take effect.
battery.price_euro_per_wh_accu was the only price the user types directly into config that used €/Wh instead of ct/kWh, unlike every other price field in the app — and its name no longer matched its unit once switched. Renamed to battery.price_ct_kwh_accu and convert at the same boundary already used for price.feed_in_price, keeping the €/Wh-based internal engine and the EOS optimizer request payload untouched. Includes a one-time migration that moves and rescales any existing installation's stored value under the new key so already-configured prices survive the change.
ohAnd
force-pushed
the
283-fix-feedin-price-unit-conversion
branch
from
August 25, 2026 18:43
388b5a3 to
1b87544
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes: #283
Problem
price.feed_in_priceis ct/kWh, but both the startup wiring(
eos_connect.py) and the hot-reload path (hot_reload.py) passed itunconverted into
BatteryPriceHandler.pv_cost_euro_per_kwh, which expects€/kWh — inflating the PV opportunity cost, and the computed battery price,
by 100x whenever
battery_price_include_feedinwas enabled.battery.price_euro_per_wh_accuwas also the only user-facing price fieldusing €/Wh instead of ct/kWh.
Changes
price.feed_in_pricect/kWh → €/kWh at both boundaries.<0.1EUR/ct auto-detection heuristic inFeedInPriceInterface— it silently guessed the unit and missed exactly this class of bug.
battery.price_euro_per_wh_accu→battery.price_ct_kwh_accu(ct/kWh). Internal engine and the EOS optimizer payload keep €/Wh.
so configured prices survive the change.
currency_minor_unit).Testing
1186 passed(full suite, browser tests excluded)TestBatteryPriceUnitMigration: fresh install, zero value, rescale+move,runs-only-once
8.0 ct/kWh → 0.08 €/kWhBreaking / upgrade note
Config key rename is handled automatically by the migration; no manual action
needed. Users who worked around the 100x bug by entering a €/kWh-scaled
feed-in price should re-check
price.feed_in_price.