diff --git a/CHANGELOG.md b/CHANGELOG.md index 41c83e7..497c972 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## [Unreleased] +## [1.6.0-beta.8] - 2026-05-24 + +Recovery service for the beta.7 cost-math fix. The beta.7 AEMO RRP-parser fix corrected the rate going forward, but the DWT provider's `_import_cost_today_c` accumulator carried the inflated value built up under the bug (the user's screenshot still showed `current_plan_cost_today=$66.78` on a real spend < $2). Adds a manual reset so users don't have to wait until midnight rollover. + +### Added + +- **`pricehawk.reset_today` service.** Zeros every registered provider's daily accumulators (`import_kwh_today`, `import_cost_today_c`, `export_kwh_today`, `export_earnings_today_c`) on every PriceHawk entry and persists the cleared state to the JSON Store. Use after any cost-math fix lands mid-day. Takes no parameters; resets all entries. Replaces the prior "wait until midnight" workaround. (`__init__.py:264-294`, `services.yaml`) + ## [1.6.0-beta.7] - 2026-05-24 🔴 **Critical cost-math bug fix.** AEMO dispatch parser was reading the wrong CSV row type — surfaced by live UAT 2026-05-24 when the user noticed today_cost claiming ~$66 on real consumption of ~12 kWh. diff --git a/custom_components/pricehawk/__init__.py b/custom_components/pricehawk/__init__.py index 262e913..6cdd125 100644 --- a/custom_components/pricehawk/__init__.py +++ b/custom_components/pricehawk/__init__.py @@ -261,11 +261,44 @@ async def handle_rank_alternatives(call: object) -> None: len(result), ) + async def handle_reset_today(call: object) -> None: + """Zero every registered provider's daily accumulators NOW. + + Use case: after a code-level cost-math bugfix lands mid-day, the + DWT provider's ``_import_cost_today_c`` still carries inflated + values accumulated under the prior bug. Without this service the + user has to wait until the midnight rollover to see clean data. + Live UAT 2026-05-24 — added after the AEMO RRP-row-type fix + (beta.7) left ``current_plan_cost_today=$66.78`` stuck on a real + spend of <$2. + """ + del call # Service takes no parameters; resets every entry. + for entry in hass.config_entries.async_entries(DOMAIN): + data: PriceHawkData | None = getattr(entry, "runtime_data", None) + if data is None: + continue + coord = data.coordinator + for provider in coord._providers.values(): + try: + provider.reset_daily() + except Exception as exc: # noqa: BLE001 — never sink the batch + _LOGGER.warning( + "reset_today: %s.reset_daily failed: %s", + getattr(provider, "id", "?"), exc, + ) + await coord.async_persist_state() + _LOGGER.info( + "reset_today: zeroed daily accumulators for %d provider(s) " + "on entry %s", + len(coord._providers), entry.entry_id, + ) + hass.services.async_register(DOMAIN, "analyze_csv", handle_analyze_csv) hass.services.async_register(DOMAIN, "backfill_history", handle_backfill) hass.services.async_register( DOMAIN, "rank_alternatives", handle_rank_alternatives ) + hass.services.async_register(DOMAIN, "reset_today", handle_reset_today) async def async_unload_entry(hass: HomeAssistant, entry: PriceHawkConfigEntry) -> bool: diff --git a/custom_components/pricehawk/manifest.json b/custom_components/pricehawk/manifest.json index e68c6b0..ac422a3 100644 --- a/custom_components/pricehawk/manifest.json +++ b/custom_components/pricehawk/manifest.json @@ -11,5 +11,5 @@ "issue_tracker": "https://github.com/Artic0din/ha-pricehawk/issues", "quality_scale": "silver", "requirements": ["openelectricity>=0.10.1,<0.11"], - "version": "1.6.0-beta.7" + "version": "1.6.0-beta.8" } diff --git a/custom_components/pricehawk/services.yaml b/custom_components/pricehawk/services.yaml index 3e0cadd..49b9f12 100644 --- a/custom_components/pricehawk/services.yaml +++ b/custom_components/pricehawk/services.yaml @@ -34,6 +34,14 @@ backfill_history: max: 90 mode: slider +reset_today: + name: Reset Today's Cost + description: >- + Zero every provider's daily accumulators (import_kwh_today, + import_cost_today_c, export_*_today, etc.) on every PriceHawk entry, + then persist state. Use after a code-level cost fix lands mid-day to + clear residual values without waiting for midnight rollover. + rank_alternatives: name: Rank Alternative Plans description: >- diff --git a/tests/test_silver_checklist.py b/tests/test_silver_checklist.py index 80e150f..f388330 100644 --- a/tests/test_silver_checklist.py +++ b/tests/test_silver_checklist.py @@ -92,8 +92,8 @@ def test_version_bumped(self): # Track the in-flight beta line. Bump this assertion when cutting # a new HACS-beta release. Hard-coded so a stray manifest edit # can't silently break HACS version pinning. - assert m["version"] == "1.6.0-beta.7", ( - f"manifest version should be 1.6.0-beta.7, got {m['version']}" + assert m["version"] == "1.6.0-beta.8", ( + f"manifest version should be 1.6.0-beta.8, got {m['version']}" ) def test_codeowner_present(self):