Skip to content

feat: keep charger devices in sync automatically - #78

Open
michaeln31 wants to merge 1 commit into
mainfrom
feat/g2-device-registry
Open

feat: keep charger devices in sync automatically#78
michaeln31 wants to merge 1 commit into
mainfrom
feat/g2-device-registry

Conversation

@michaeln31

Copy link
Copy Markdown
Contributor

What this does

Part of the Gold tier of the CI/CD to Platinum quality scale climb (item G2).

  • Standardizes device info on Home Assistant's typed DeviceInfo helper across the sensor and
    switch platforms (the lock platform already used it), and moves the duplicated "update model
    from device status" logic into one shared helper (entity.py) instead of five copies.
  • Devices are added automatically: if a new charger appears on your Andersen account, its
    entities now show up without needing to restart Home Assistant.
  • Devices are cleaned up automatically: if a charger is removed from your Andersen account,
    its device registry entry is now removed automatically instead of lingering.
  • Marks dynamic-devices and stale-devices as done in the quality scale checklist.

Testing

  • ./run-tests.ps1 --cov=custom_components/andersen_ev --cov-fail-under=95 locally in Docker:
    317 passed, 99.66% coverage (gate is 95%).
  • ruff check and ruff format clean on all changed files.
  • New tests cover the shared model-update helper, a device appearing mid-session on each
    platform, and a device disappearing (registry cleanup).

Manual test plan (before merge to main / after beta install)

  1. Install via HACS beta channel, restart Home Assistant.
  2. Settings > System > Logs, filter andersen_ev: confirm no errors on load.
  3. Confirm your existing charger's lock, sensors, and schedule switches all still show up under
    Settings > Devices & Services > Andersen EV, with correct model/name/serial number.
  4. Regression spot check: toggle the lock or a schedule switch and confirm it still works.
  5. This change only takes effect if a device is added to or removed from your Andersen account,
    which most users will not be able to trigger; the important thing is that nothing regresses
    for the single, unchanged device case above.

Standardizes device info across the sensor and switch platforms on Home
Assistant's typed DeviceInfo helper (lock already used it), and hoists the
duplicated model-update logic into a shared mixin (entity.py).

Adds two Gold-tier quality behaviors:
- dynamic-devices: if a new charger appears on the account, its entities
  are added automatically without needing a Home Assistant restart.
- stale-devices: if a charger is removed from the account, its device
  registry entry is cleaned up automatically.

quality_scale.yaml: mark dynamic-devices and stale-devices as done.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances the Andersen EV Home Assistant integration to keep the set of charger devices in sync at runtime (adding new devices without restart and cleaning up removed devices), while also standardizing entity device_info and consolidating duplicated “model-from-status” logic into a shared mixin.

Changes:

  • Add coordinator listeners in each platform to dynamically add entities for newly discovered devices.
  • Add an integration-level coordinator listener to remove stale device registry entries when devices disappear from the API.
  • Standardize DeviceInfo usage and centralize model-update logic in a shared AndersenEvDeviceInfoMixin, with new/updated tests and quality scale updates.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
custom_components/andersen_ev/init.py Registers a stale-device cleanup listener to remove device registry entries when devices disappear.
custom_components/andersen_ev/entity.py Introduces a shared mixin to update device model info from API/device status consistently.
custom_components/andersen_ev/lock.py Adds dynamic device entity creation via coordinator listener and adopts shared device-info mixin.
custom_components/andersen_ev/sensor.py Adds dynamic device entity creation via coordinator listener and adopts shared device-info mixin.
custom_components/andersen_ev/switch.py Refactors switch entity creation, adds dynamic device support, and adopts typed DeviceInfo + shared mixin.
custom_components/andersen_ev/tests/test_entity.py Adds unit tests for the shared model-update helper logic.
custom_components/andersen_ev/tests/test_init.py Adds tests for stale-device cleanup listener registration and behavior.
custom_components/andersen_ev/tests/test_lock.py Adds tests validating dynamic device entity creation for locks.
custom_components/andersen_ev/tests/test_sensor.py Adds tests validating dynamic device entity creation for sensors.
custom_components/andersen_ev/tests/test_switch.py Adds tests validating dynamic device entity creation for schedule switches (including async task scheduling).
custom_components/andersen_ev/quality_scale.yaml Marks dynamic-devices and stale-devices as done.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +31 to +34
def _entities_for_new_devices() -> list[AndersenEvLock]:
"""Build lock entities for any device not seen before."""
new_devices = [device for device in coordinator.data if device.device_id not in known_device_ids]
entities = []
Comment on lines +43 to +46
def _entities_for_new_devices() -> list[SensorEntity]:
"""Build sensor entities for any device not seen before."""
new_devices = [device for device in coordinator.data if device.device_id not in known_device_ids]
entities: list[SensorEntity] = []
Comment on lines +75 to +79
def _handle_coordinator_update() -> None:
"""Schedule switch creation for any device not seen before."""
new_devices = [device for device in coordinator.data if device.device_id not in known_device_ids]
if not new_devices:
return
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.

2 participants