♻️ Move site rate ×100 scalar into the sensor #45

Merged
mat merged 1 commit from refactor/site-rate-scalar-in-sensor into main 2026-07-10 15:05:31 +00:00
Owner

Why

#19 duplicated the "is this a rate?" knowledge in two places that can silently drift apart:

  • coordinator.py_RATE_KEYS decided the ×100
  • sensor.pySITE_METRICS decided the PERCENTAGE unit

Add a rate key to one set and forget the other → a ×100 value surfaced in Wh, or a raw 0-1 ratio surfaced in %. No test caught that direction.

Change

  • The coordinator now stores the raw 0-1 ratio for rates; _RATE_KEYS is deleted.
  • The sensor applies ×100 when its native_unit_of_measurement == PERCENTAGE — the single source of truth, next to the unit it already owns.

Behavior

Unchanged at the entity level: test_auto_production_rate_reads_latest_value (0.42 → 42.0) and test_site_metrics_expose_every_known_key (0.75 → 75.0) still pass as-is. Re-adding ×100 to the coordinator would double-scale and make 0.42 → 4200, so the existing tests lock the new contract.

Test plan

  • pytest — 32 passed
  • ruff + mypy clean
## Why `#19` duplicated the "is this a rate?" knowledge in two places that can silently drift apart: - `coordinator.py` → `_RATE_KEYS` decided the ×100 - `sensor.py` → `SITE_METRICS` decided the `PERCENTAGE` unit Add a rate key to one set and forget the other → a ×100 value surfaced in Wh, or a raw 0-1 ratio surfaced in %. No test caught that direction. ## Change - The coordinator now stores the **raw 0-1 ratio** for rates; `_RATE_KEYS` is deleted. - The sensor applies ×100 when its `native_unit_of_measurement == PERCENTAGE` — the single source of truth, next to the unit it already owns. ## Behavior Unchanged at the entity level: `test_auto_production_rate_reads_latest_value` (`0.42 → 42.0`) and `test_site_metrics_expose_every_known_key` (`0.75 → 75.0`) still pass as-is. Re-adding ×100 to the coordinator would double-scale and make `0.42 → 4200`, so the existing tests lock the new contract. ## Test plan - [x] pytest — 32 passed - [x] ruff + mypy clean
♻️ Move site rate ×100 scalar into the sensor
Some checks are pending
Validate / lint-ruff (push) Waiting to run
Validate / test-pytest (push) Waiting to run
Validate / type-check-mypy (push) Waiting to run
Validate / lint-ruff (pull_request) Waiting to run
Validate / test-pytest (pull_request) Waiting to run
Validate / type-check-mypy (pull_request) Waiting to run
0dcacd6320
The 'is this a rate' knowledge was duplicated: _RATE_KEYS in the
coordinator (decided ×100) and SITE_METRICS in the sensor (decided the
PERCENTAGE unit). Adding a rate to one set and forgetting the other would
silently surface a ×100 value in Wh (or vice-versa).

The coordinator now stores the raw 0-1 ratio; the sensor applies ×100
when its unit is PERCENTAGE — the single source of truth. Behavior is
unchanged at the entity level (existing rate tests still pass).
mat changed target branch from feat/40-site-metrics to main 2026-07-10 14:59:01 +00:00
mat force-pushed refactor/site-rate-scalar-in-sensor from 0dcacd6320
Some checks are pending
Validate / lint-ruff (push) Waiting to run
Validate / test-pytest (push) Waiting to run
Validate / type-check-mypy (push) Waiting to run
Validate / lint-ruff (pull_request) Waiting to run
Validate / test-pytest (pull_request) Waiting to run
Validate / type-check-mypy (pull_request) Waiting to run
to 5a0a145552
All checks were successful
Validate / lint-ruff (push) Successful in 7s
Validate / test-pytest (push) Successful in 3m0s
Validate / type-check-mypy (push) Successful in 3m8s
Validate / lint-ruff (pull_request) Successful in 7s
Validate / test-pytest (pull_request) Successful in 3m0s
Validate / type-check-mypy (pull_request) Successful in 3m8s
2026-07-10 15:03:08 +00:00
Compare
mat merged commit 7d7bb6b096 into main 2026-07-10 15:05:31 +00:00
mat deleted branch refactor/site-rate-scalar-in-sensor 2026-07-10 15:05:31 +00:00
mat referenced this pull request from a commit 2026-07-10 18:06:30 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
mat/homeassistant-comwatt!45
No description provided.