Add consumption-weighted average price sensors ("your own average") - #108
Draft
enoch85 wants to merge 3 commits into
Draft
Add consumption-weighted average price sensors ("your own average")#108enoch85 wants to merge 3 commits into
enoch85 wants to merge 3 commits into
Conversation
Lets users see whether they beat the market average by weighting each interval's spot price by the energy they actually consumed. Opt-in: two sensors per area (today + this month) are created only when a cumulative kWh energy sensor is selected in the options. - New pure WeightedAverageAccumulator (sensor/consumption.py): cost/energy and simple-benchmark accumulation, period reset, meter-reset handling. - ConsumptionWeightedAverageSensor (RestoreEntity): tracks the meter via state-change events, samples the elapsed-interval simple average as the benchmark, persists across restarts with a config fingerprint, resets at local midnight (daily) / month start (monthly). - Options: optional energy-sensor EntitySelector (domain sensor, device_class energy) + translations (en/de/nl/strings). - Attributes: simple_average, savings_vs_average, beating_average, consumed_energy, accumulated_cost, period, period_start. - Tests: pure accumulator math incl. a simulated month, and the sensor adapter (opt-in gating, restore/fingerprint, attributes, availability).
Sorts next to the market Average Price sensor in entity pickers and reads naturally: what you paid vs what the market averaged. - sensor_type: consumption_weighted_average_today/month -> average_price_paid_today/month - Names: "Your Average Price Today/This Month" -> "Average Price Paid Today/This Month" Unreleased (draft PR), so renamed directly without aliases.
If the energy meter entity was still unavailable when the sensor was added (startup race), the baseline seed found no numeric state and the first meter increment was swallowed as a baseline reading, losing that consumption. Seed from the state-change event's old_state instead so the delta books. Caught by the live week-long verification (a run right after boot booked 0 kWh while the independent reference booked 2 kWh).
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.
What & why
Today you can see the market Average Price but not whether your own usage beat it. Beating the average means using more electricity during below-average-price intervals — only measurable by weighting each interval's price by the energy you actually consumed.
This adds an opt-in consumption-weighted average: two sensors per area — Average Price Paid Today and Average Price Paid This Month — created only when you pick a cumulative kWh energy sensor in the integration options.
How it works
Δkwhis priced at the current interval's all-in price:cost += Δkwh × price,energy += Δkwh; the sensor state iscost / energy(same unit as Average Price).savings_vs_averageandbeating_averageattributes.RestoreEntitywith a config fingerprint (unit/VAT/currency/meter change → clean restart). The meter baseline re-seeds on startup so downtime isn't mispriced; meter resets/replacements are handled.Files
sensor/consumption.py— pure, hass-freeWeightedAverageAccumulator(the testable core)sensor/price.py—ConsumptionWeightedAverageSensor(RestoreEntity adapter)sensor/electricity.py— opt-in wiringconfig_flow/schemas.py+const/+translations/— the energy-sensor optiontests/pytest/unit/— accumulator math (incl. a simulated month) + sensor adapterTesting
Draft: opening for review of the approach/naming before finalizing.