feat: v4.4.0 — balance rounding fix, desired range persistence, Tessie resync, Forecast to EV Capture Factor sensor - #51
Conversation
Co-authored-by: Patrick1610 <6585375+Patrick1610@users.noreply.github.com>
|
Regarding the question "Wat heb je verder nodig?" (What else do you need?) for the analysis — here is the data that would be most useful alongside the energy dashboard CSV and history CSV exports: From the Energy Dashboard export: From the History export (all entities used in the integration setup): Additional context that would help: |
|
Tessie charge current can get out of sync, sometimes an external source sets the A one step back within 10s of a new setting. The app does not resync after this resulting in an offset in stable conditions |
|
On reload the range sensors calculate based on 100km (or maybe the setting during setup) for a moment. Make sure the desired range is not an input during setup and is persistent until the desired range sensor is available. |
|
Implement a new diagnostic + forecasting-oriented sensor named: Forecast to EV Capture Factor GoalAdd a new sensor that answers this question as simply and reliably as possible: “What fraction of the remaining solar forecast today is likely still usable for EV charging?” This sensor must be designed specifically for forecast-to-EV estimation. Important: ReasonThe current Solar-to-EV Ratio is conceptually too broad for forecast estimation because it represents solar energy that reached the EV versus total produced solar energy, which dilutes the value with many periods that are not EV-relevant (vehicle away, battery already high, cable disconnected, etc.). For forecast estimation we want a different question: “Of the solar opportunity that existed while the EV was actually in a position to benefit, what fraction was historically captured by the EV?” That is the value we want to multiply against Remaining Forecast Today. Required design principlesPrioritize:
Do NOT introduce a complex predictive model. Use existing configured integration inputsUse the entities/concepts already configured in the integration, by their integration meaning, not by hardcoded user-specific entity IDs:
New sensor meaningThe new sensor must represent: historical EV capture factor under EV-relevant solar opportunity conditions This is NOT:
This IS:
Recommended implementationImplement this as a ratio of two cumulative internal energy counters.
Solar opportunity sourceFor the denominator, prefer the most EV-relevant internal source available: Preferred:
Fallback:
If a surplus-style internal source exists and is reliable, use that. In all cases:
Output sensor behaviorExpose: Forecast to EV Capture Factor State:
Examples:
This should be a cumulative/stable historical factor, not a rapidly oscillating real-time percentage. Optional supporting diagnostic sensorIf useful for debugging, also expose: Forecast to EV Opportunity Energy Only add this if it materially improves transparency/debuggability. Intended useThis new sensor should become the preferred multiplier for estimating remaining forecast usable by the EV. Conceptual usage: Optionally, downstream logic may additionally gate this by simple real-time availability conditions such as:
But the capture factor itself should remain a historical stable factor. What NOT to do
Backward compatibility / UX
Implementation preferenceUse the simplest implementation that fits the current architecture:
Final priorityThe most important requirement is semantic quality and reliability. This sensor must give us full control over a trustworthy forecast-oriented output. |
|
de version bump van 4.3.7 moet naar 4.4.0, niet 4.8.0 |
|
Implement a full simplification/rebuild of the charging overhead and charged-energy model. Main objectiveReplace the current mixed / partially session-based overhead logic with a simpler, more explicit and more reliable model based on:
This change should also make the EV Charge Energy Added Sensor obsolete in setup and implementation. The result should be:
Core design decisionThe integration must no longer treat EV Charge Energy Added Sensor as a required or primary source. Remove EV Charge Energy Added Sensor from the config/setup flow. Charging overhead and charged-energy reporting should instead be based on:
If EV Battery Energy Sensor is not configured, allow a fallback based on:
But the preferred and primary model must be battery-kWh based. Semantic definitionRedefine Charging Overhead as: the difference between:
Everything between those two is overhead. This explicitly includes:
Do NOT try to separate these categories. FormulaUse: overhead_factor = 1 - (battery_delta_kwh / wall_energy_kwh) Where:
Clamp nonsensical results safely where appropriate. Qualified charging sessionA charging session must only start when charging is genuinely happening under the integration’s own control logic. This is required to exclude situations like:
Create a clear internal condition similar to: qualified_charging_active =
Session start snapshotWhen qualified_charging_active transitions from false to true, create a session snapshot:
This snapshot must be robust and deterministic. Session wall energyInternally integrate EV Power Sensor into wall energy kWh. Do this inside the integration, not by relying on an external HA Integral helper. This should become the canonical source of charger-delivered session energy. Suggested internal behavior:
This internal wall-energy kWh should then become the primary source for:
Battery energy source priorityUse this source priority for battery-side energy:
Important: EV Charge Energy Added Sensor removalRemove EV Charge Energy Added Sensor from setup/configuration. This sensor should no longer be selectable in the integration options/config flow. Also remove any logic where charging overhead, charged energy, capacity estimation, diagnostics, or session math depend primarily on EV Charge Energy Added Sensor. If there is any remaining use that is still valuable for diagnostics, it may remain only as a low-priority optional internal auxiliary source, but it must not shape the main semantics anymore. Preferred outcome:
Charged energy sensor rebuildRebuild the integration’s “charged energy” output so that it is based on the new internal wall-energy kWh accumulator derived from EV Power Sensor. This means:
In other words: This creates one coherent foundation:
Session vs historical overheadSeparate session and historical concepts clearly.
Historical overhead should be the stable main value used by the integration for planning and calculations. Session overhead may exist as a diagnostic/live sensor, but it should not be the main truth used everywhere. Session finalizationAt end of a qualified charging session, finalize:
Use finalized session totals to build the historical overhead value. This is preferred over continuously blending partial session data into one mixed overhead value. Quality / robustness rules
Recommended diagnosticsAdd or preserve diagnostics that make the system auditable:
Charging Overhead Source should clearly indicate for example:
Optional: Naming / semanticsUse names/descriptions that make the distinction obvious:
The wording should make it impossible to confuse:
What NOT to do
IntentWe want one clean and trustworthy energy model:
Final priorityFavor semantic clarity and reliability over cleverness. It is better to have a simple, explicit and internally consistent wall-kWh vs battery-kWh model than a more complicated model that depends on ambiguous or resetting vehicle-reported “energy added” values. |
|
@copilot PR Plan — Alleen verwerkt uit de 7 meegegeven PR-commentsBronnen voor dit plan (exact deze comments):
Alles hieronder is direct afgeleid van bovenstaande comments. Geen extra roadmap-items. 1) Scope (alleen deze commentpunten)
2) Uitwerking per commentpuntA) Versioning
B) Forecast to EV Capture Factor (nieuw)Doelvraag: Rekenpad (dedicated, simpel, robuust):
EV-relevante condities voor noemer-accumulatie:
Bron van opportunity:
Niet doen (expliciet):
C) Overhead + charged-energy simplificatieCanonieke semantiek:
Sessie vs historisch scheiden:
Session finalization:
Bron/fallback transparantie:
D) Balanced mode rounding + decision correctness
E) Tessie sync/resync
F) Reload & desired range persistentie
3) Prioriteit en volgorde in deze PR
Reden: eerst correctness/regressierisico, daarna modelwijziging, dan nieuwe forecast-sensor bovenop stabiele basis. 4) Acceptatiecriteria (alleen op basis van comments)
5) Strikte out-of-scope regelAlles wat niet direct herleidbaar is naar deze 7 comment-ID’s valt buiten dit plan. |
…e resync, Forecast to EV Capture Factor sensor, remove EV Energy Added from setup Co-authored-by: Patrick1610 <6585375+Patrick1610@users.noreply.github.com>
Version corrected to
Fixed in commit 4896593. The root cause was
Same root cause as the screenshot at 10:53 — the spurious 5A→6A jump was caused by the forced
Implemented in commit 4896593 via
Fixed in commit 4896593. Added
Implemented in commit 4896593. New Opportunity energy accumulates only when: vehicle present, battery <90%, cable connected (if configured), priority ≠ Usage:
The current charging overhead model already uses EV Power Sensor for wall energy and EV Battery Energy Sensor for battery delta — the core semantics requested are already implemented. For this commit (4896593) I removed
... All items from the plan implemented in commit 4896593:
|
|
@copilot Top, dank! Wil je deze PR nu afmaken/polishen richting merge met onderstaande punten als leidraad? DoelMaak PR #51 merge-klaar op v4.4.0, met de fixes/features die er al in zitten, plus de laatste review-aanpassingen. Must-fix (voor merge)
Should-fix (polish)
Merge-advies (expliciet)
Oplevering gevraagd
|
…ed diagnostic clarification, scenario tests, v4.4.0 changelog Co-authored-by: Patrick1610 <6585375+Patrick1610@users.noreply.github.com>
... All must-fix and polish items done in commit Must-fix 1 — EV Energy Added diagnostic-only: Added explicit Must-fix 2 — Tessie resync tighter: Replaced the single 3-tick threshold with a two-tier system:
Logging consolidated via a local Must-fix 3 — Scenario tests: Added Should-fix 4 — README changelog: Added complete Should-fix 5 — manifest: |
|
@copilot Super werk. Kun je deze PR in één laatste pass merge-ready maken met onderstaande concrete checklist? DoelPR #51 afronden voor merge op v4.4.0 met heldere semantiek, minder false positives bij resync, en strakke tests/docs. 1) EV Energy Added: semantiek consistent afmaken (must)We hebben de setup-input al verwijderd. Maak nu runtime/diagnostics ook consistent:
Voorkeur in deze PR: volledig verwijderen uit coordinator data dict + relevante sensor attributes, tenzij dat bestaande users breekt.
2) Tessie/externe override resync: false positives beperken (must)Huidige resync op EMA mismatch is goed, maar voeg guard toe:
3) Tests aanvullen op echte flow (must)Naast mirror-tests, voeg 1–2 coordinator-flow tests toe die runtimegedrag afdekken:
4) PR polish + release notes (should)
5) Output verwachtLever in je laatste update:
Dank! Zet dit als laatste polish-commit(s), zodat we hierna kunnen mergen en een aparte analyse/optimalisatie-PR starten op 4.4.0. |
… data dict and sensor attributes Co-authored-by: Patrick1610 <6585375+Patrick1610@users.noreply.github.com>
... Final pass done in commit Item 1 — EV Energy Added fully removed: Items 2–5 were already completed in the previous commit
780 tests, all passing. CodeQL: 0 alerts. |
|
@copilot Nog 1 kleine polish vóór merge graag:
Daarna is deze PR voor mij merge-ready op 4.4.0. |
…son and translations/en.json Co-authored-by: Patrick1610 <6585375+Patrick1610@users.noreply.github.com>
Done in commit Item 1 — EV Energy Added semantic consistency: Already fully removed from runtime in Item 2 — UI strings cleaned up: Removed the orphaned Item 3 — PR description confirmed: 780 tests, all passing. |


Version bump to
4.4.0with several bug fixes, a new diagnostic sensor, and merge-readiness polish based on review feedback.Breaking / Behavior Notes
balancepriority no longer forces a minimum +1A step on upward modulation. A step only occurs when the EMA actually rounds to a higher integer (EMA ≥ 5.5A to step from 5A → 6A). Same clean-up applied tozero_prefer_export(floor) andzero_prefer_import(ceil).desired_rangeis persisted in.storage/adaptive_chargeand restored before the first tick, eliminating the momentary 100 km glitch on reload.CONF_EV_ENERGY_ADDED_SENSORis retained inconst.pyonly for silent backward-compat deserialization of existing config entries — the value is never read or used.0.0until sufficient history exists (denominator = 0). Storage keysforecast_capture_solar_whandforecast_capture_opportunity_whare new (default0.0, merged on load from older stores). Utility meters remain coupled to Energy Charged / Battery Delta — not to this factor.Changes
manifest.json4.3.7→4.4.0Balance mode rounding fix (
coordinator.py)max(current_int + 1, quantized)minimum step in_commit_currentformodulate_upround()quantization: EMA=5.27A with committed=5A correctly stays at 5A instead of spuriously jumping to 6Azero_prefer_export(floor) andzero_prefer_import(ceil) modesDesired range reload persistence (
coordinator.py,storage.py)desired_range_kmto the persistent storeRestoreEntityhook runsset_desired_range()andasync_service_set_desired_range()now persist the valueTessie / external current resync (
coordinator.py)_detect_external_current_override()with a two-tier detection strategy:_RESYNC_POST_COMMIT_WINDOW_S): 3 stable ticks required — covers Tessie overriding within seconds of our command_reset(reason)helper; debug logging at every mismatch tick explains tick count, diff, and window state_committed_currentto the EMA-implied value, correcting the permanent 1A offsetNew sensor: Forecast to EV Capture Factor (
sensor.py,coordinator.py,storage.py)ForecastToEvCaptureFactorSensorwith entity keyforecast_to_ev_capture_factor(measurement factor, range 0.0–1.0)forecast_capture_solar_wh(numerator) andforecast_capture_opportunity_wh(denominator)PRIORITY_EXPORTsurplus_w(solar available to EV, clamped ≥ 0), falling back tosolar_wremaining_forecast_today_kwh × forecast_to_ev_capture_factorEV Charge Energy Added Sensor (
coordinator.py,sensor.py,config_flow.py,strings.json,translations/en.json)CONF_EV_ENERGY_ADDED_SENSORfrom both the initial setup flow and the options/reconfigure flowev_energy_added_kwhis no longer read at runtime, no longer included in the coordinator data dict, and no longer exposed in any sensor attributesev_energy_added_sensorlabel and description strings fromstrings.jsonandtranslations/en.json— setup UI, runtime, and docs now consistently reflect the removalself._ev_energy_added_sensorandCONF_EV_ENERGY_ADDED_SENSORare retained silently only to avoid breaking existing config entries on load — the value is never usedTests (
tests/test_coordinator.py,tests/test_storage.py)TestExternalResyncScenario(multi-tick Tessie override → resync → no lasting offset) andTestForecastCaptureAccumulationScenario(tick-flow accumulation with EV-relevant gating, including denominator=0 → 0.0 and clamp 0..1)TestBuildDataDictBatteryFieldsto reflect removal ofev_energy_added_kwhfrom the data dictDocumentation (
README.md)### v4.4.0changelog section with behavior notes, feature description, and migration notes💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.