Skip to content

fix(costs): clear _last_soc_pct on midnight reset; wire reset_daily_accumulators (#899)#899

Open
jackmcintyre wants to merge 1 commit into
mainfrom
issue/899
Open

fix(costs): clear _last_soc_pct on midnight reset; wire reset_daily_accumulators (#899)#899
jackmcintyre wants to merge 1 commit into
mainfrom
issue/899

Conversation

@jackmcintyre

Copy link
Copy Markdown
Owner

Summary

Two related issues:

  1. CostTracker.reset_daily_accumulators was dead code (zero callers in custom_components/ — only tests exercised it). The midnight-reset path (tick_scheduler.handle_midnight_reset) inlined the same field-zeroing logic but did NOT clear _last_soc_pct.

  2. The omission corrupts grid_charge_efficiency: a grid charge spanning midnight leaves _last_soc_pct at the pre-midnight SOC. The first accumulate_costs after midnight computes soc_delta = current_soc - _last_soc_pct and attributes the entire overnight SOC gain to the new day's soc_gain_during_grid_charge_kwh_today, inflating the ratio.

Changes

  • utils/costs.py:reset_daily_accumulators: now also clears self._last_soc_pct = None so the first post-midnight grid-charge sample establishes a fresh baseline.
  • coordinator/tick_scheduler.py:handle_midnight_reset: delegates to cost_tracker.reset_daily_accumulators(data) (with a defensive inline fallback if cost_tracker is somehow None). Replaces the inline field-zeroing that was duplicating CostTracker's logic and missing the SOC baseline clear.

Validation

  • TDD: 2 failing tests in TestAccumulateEnergyKwh:
    • test_reset_daily_accumulators_clears_last_soc_pct_last_soc_pct must be None after reset (was 40.0).
    • test_no_phantom_soc_gain_after_midnight_reset — end-to-end: pre-midnight charge to SOC 50, reset, post-midnight sample at 81 must NOT attribute the 31-point delta (was 50.0, not None).
  • All 57 CostTracker + tick_scheduler tests pass.
  • Full suite: 3216 passed, 1 xfailed. Coverage: 95%.
  • uv run ruff check clean.

…ccumulators (#899)

Two related issues:

1. CostTracker.reset_daily_accumulators was dead code (zero callers in
   custom_components/ — only tests). The midnight-reset path inlined the same
   field-zeroing but did NOT clear _last_soc_pct. Result: a grid charge
   spanning midnight left _last_soc_pct at the pre-midnight SOC, so the first
   post-midnight accumulate_costs attributed the entire overnight SOC delta to
   the new day's soc_gain_during_grid_charge_kwh_today — corrupting
   grid_charge_efficiency.

2. reset_daily_accumulators now clears _last_soc_pct = None, and
   handle_midnight_reset delegates to it (with a defensive inline fallback if
   cost_tracker is somehow None).

TDD: 2 failing tests (assert _last_soc_pct is None after reset; end-to-end
no phantom SOC gain). 3216 pass, coverage 95%.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant