Add the remaining site-level metrics as sensors #19

Open
mat wants to merge 1 commit from feat/40-site-metrics into main
Owner

Summary

Closes MateoGreil/homeassistant-comwatt#40.

The Comwatt site time-series API returns ten metric keys but only autoproductionRates was surfaced. Expose all ten: production, consumption, injection, withdrawal, charge, discharge, and their rate counterparts (auto-production / auto-consumption / injection / withdrawal).

Design

  • Coordinator extracts every known key into sites_data[site_id] via a single _extract_site_metrics helper. Rates are multiplied by 100 in one place.
  • Sensor platform replaces the bespoke ComwattAutoProductionRateSensor with a generic ComwattSiteMetricSensor driven by a ComwattSiteMetricDescription. Adding a new metric is a one-line addition to SITE_METRICS.
  • Backward compatible: unique_id of the existing sensor unchanged (site_{site_id}_auto_production_rate). No registry churn for current users.

Notes on units and state classes

  • Rate sensors: PERCENTAGE + MEASUREMENT (as before).
  • Delta sensors (production/consumption/injection/withdrawal/charge/discharge): UnitOfEnergy.WATT_HOUR + MEASUREMENT. Intentionally no device_class=ENERGY — each reading is a per-hour delta, not a cumulative counter, and HA rejects ENERGY + MEASUREMENT. Users wanting Energy-dashboard-quality cumulative figures should use the existing {device}_total_energy entity or the new comwatt:{device}_total_energy external statistic from #18.

Test plan

  • Updated topology tests to match the full expected unique_id set.
  • New test_site_metrics_expose_every_known_key round-trips every API key to an entity state with the right unit.
  • pytest tests/ — 25 passed; ruff + mypy clean.
  • Hands-on: after deploy, look for 9 new sensors under your Comwatt site device in HA. Values should match what you see in the Comwatt app for the last hour.
## Summary Closes [MateoGreil/homeassistant-comwatt#40](https://github.com/MateoGreil/homeassistant-comwatt/issues/40). The Comwatt site time-series API returns ten metric keys but only `autoproductionRates` was surfaced. Expose all ten: production, consumption, injection, withdrawal, charge, discharge, and their rate counterparts (auto-production / auto-consumption / injection / withdrawal). ## Design - Coordinator extracts every known key into `sites_data[site_id]` via a single `_extract_site_metrics` helper. Rates are multiplied by 100 in one place. - Sensor platform replaces the bespoke `ComwattAutoProductionRateSensor` with a generic `ComwattSiteMetricSensor` driven by a `ComwattSiteMetricDescription`. Adding a new metric is a one-line addition to `SITE_METRICS`. - **Backward compatible**: unique_id of the existing sensor unchanged (`site_{site_id}_auto_production_rate`). No registry churn for current users. ## Notes on units and state classes - Rate sensors: `PERCENTAGE` + `MEASUREMENT` (as before). - Delta sensors (production/consumption/injection/withdrawal/charge/discharge): `UnitOfEnergy.WATT_HOUR` + `MEASUREMENT`. Intentionally **no** `device_class=ENERGY` — each reading is a per-hour delta, not a cumulative counter, and HA rejects `ENERGY + MEASUREMENT`. Users wanting Energy-dashboard-quality cumulative figures should use the existing `{device}_total_energy` entity or the new `comwatt:{device}_total_energy` external statistic from [#18](https://git.greil.fr/mat/homeassistant-comwatt/pulls/18). ## Test plan - [x] Updated topology tests to match the full expected unique_id set. - [x] New `test_site_metrics_expose_every_known_key` round-trips every API key to an entity state with the right unit. - [x] `pytest tests/` — 25 passed; `ruff` + `mypy` clean. - [ ] Hands-on: after deploy, look for 9 new sensors under your Comwatt site device in HA. Values should match what you see in the Comwatt app for the last hour.
Add the remaining site-level metrics as sensors
All checks were successful
Validate / validate-hacs (push) Has been skipped
Validate / validate-hassfest (push) Has been skipped
Validate / lint-ruff (push) Successful in 7s
Validate / test-pytest (push) Successful in 1m45s
Validate / type-check-mypy (push) Successful in 1m49s
Validate / validate-hacs (pull_request) Has been skipped
Validate / validate-hassfest (pull_request) Has been skipped
Validate / lint-ruff (pull_request) Successful in 7s
Validate / test-pytest (pull_request) Successful in 1m45s
Validate / type-check-mypy (pull_request) Successful in 1m49s
b1dc5f4c60
Closes #40.

The Comwatt site time-series API returns ten keys under
`get_site_networks_ts_time_ago`:

    productions, consumptions, injections, withdrawals,
    charges, discharges,
    autoproductionRates, autoconsumptionRates,
    injectionRates, withdrawalRates

Previously only `autoproductionRates` was surfaced. Expose all ten.

Structure:

- Coordinator: extract every known key into `sites_data[site_id]`, with
  a single helper (`_extract_site_metrics`). Rates are multiplied by
  100 once, in one place.
- Sensor platform: replace the bespoke `ComwattAutoProductionRateSensor`
  class with a generic `ComwattSiteMetricSensor` driven by a
  `ComwattSiteMetricDescription` (frozen dataclass). Each metric is a
  tuple entry in `SITE_METRICS`. Adding a new one is a one-line change.
- Backwards compatibility: the existing sensor keeps its unique_id
  (`site_{site_id}_auto_production_rate`) because that's the
  description's `key` — existing users see no registry churn.

Energy delta sensors (production/consumption/etc.) are declared with
unit Wh and `SensorStateClass.MEASUREMENT` but intentionally **no**
`device_class=ENERGY`: each reading is the last hourly bucket's delta
rather than a cumulative counter, and HA rejects the MEASUREMENT +
ENERGY combination. Users wanting Energy-dashboard-quality cumulative
figures should pick the existing `{device}_total_energy` entity or the
external `comwatt:{device}_total_energy` statistic (see PR #18).

## Tests

- `test_simple_device_creates_site_and_device_sensors` and the parent
  variant: updated expected unique_ids to match the new set.
- `test_site_metrics_expose_every_known_key`: verifies every API key
  round-trips to the expected sensor state (rate × 100, delta as-is),
  with correct units.
mat force-pushed feat/40-site-metrics from b1dc5f4c60
All checks were successful
Validate / validate-hacs (push) Has been skipped
Validate / validate-hassfest (push) Has been skipped
Validate / lint-ruff (push) Successful in 7s
Validate / test-pytest (push) Successful in 1m45s
Validate / type-check-mypy (push) Successful in 1m49s
Validate / validate-hacs (pull_request) Has been skipped
Validate / validate-hassfest (pull_request) Has been skipped
Validate / lint-ruff (pull_request) Successful in 7s
Validate / test-pytest (pull_request) Successful in 1m45s
Validate / type-check-mypy (pull_request) Successful in 1m49s
to 9348329645
All checks were successful
Validate / validate-hacs (pull_request) Has been skipped
Validate / validate-hassfest (pull_request) Has been skipped
Validate / lint-ruff (pull_request) Successful in 7s
Validate / test-pytest (pull_request) Successful in 1m46s
Validate / type-check-mypy (pull_request) Successful in 1m48s
Validate / validate-hacs (push) Has been skipped
Validate / validate-hassfest (push) Has been skipped
Validate / lint-ruff (push) Successful in 7s
Validate / test-pytest (push) Successful in 1m45s
Validate / type-check-mypy (push) Successful in 1m48s
2026-04-24 21:53:03 +00:00
Compare
All checks were successful
Validate / validate-hacs (pull_request) Has been skipped
Validate / validate-hassfest (pull_request) Has been skipped
Validate / lint-ruff (pull_request) Successful in 7s
Validate / test-pytest (pull_request) Successful in 1m46s
Validate / type-check-mypy (pull_request) Successful in 1m48s
Validate / validate-hacs (push) Has been skipped
Validate / validate-hassfest (push) Has been skipped
Validate / lint-ruff (push) Successful in 7s
Validate / test-pytest (push) Successful in 1m45s
Validate / type-check-mypy (push) Successful in 1m48s
This pull request can be merged automatically.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feat/40-site-metrics:feat/40-site-metrics
git switch feat/40-site-metrics

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff feat/40-site-metrics
git switch feat/40-site-metrics
git rebase main
git switch main
git merge --ff-only feat/40-site-metrics
git switch feat/40-site-metrics
git rebase main
git switch main
git merge --no-ff feat/40-site-metrics
git switch main
git merge --squash feat/40-site-metrics
git switch main
git merge --ff-only feat/40-site-metrics
git switch main
git merge feat/40-site-metrics
git push origin main
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!19
No description provided.