Add WattWächter Plus integration#165238
Add WattWächter Plus integration#165238smartcircuits wants to merge 33 commits intohome-assistant:devfrom
Conversation
There was a problem hiding this comment.
Hi @tJpADUNCcs
It seems you haven't yet signed a CLA. Please do so here.
Once you do that we will be able to review and accept this pull request.
Thanks!
|
Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍 |
There was a problem hiding this comment.
Pull request overview
Adds a new core integration for WattWächter Plus energy monitoring devices (local polling + zeroconf discovery), including dynamic OBIS-based sensors, diagnostics support, and a firmware update entity.
Changes:
- Introduces the
wattwaechterintegration (config flow, coordinator, sensors, update entity, diagnostics, translations/icons/branding). - Registers the integration for zeroconf discovery and generated integration metadata.
- Adds a new test suite and CODEOWNERS entries for the integration.
Reviewed changes
Copilot reviewed 19 out of 25 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
homeassistant/components/wattwaechter/__init__.py |
Sets up the integration, creates client/coordinator, forwards platforms, handles options updates. |
homeassistant/components/wattwaechter/config_flow.py |
Implements user/zeroconf flows plus reauth/reconfigure and options flow. |
homeassistant/components/wattwaechter/const.py |
Defines domain/constants plus known OBIS and diagnostic sensor descriptions. |
homeassistant/components/wattwaechter/coordinator.py |
Polls meter/system data via DataUpdateCoordinator and maps auth/connection errors. |
homeassistant/components/wattwaechter/sensor.py |
Creates dynamic OBIS sensors + diagnostic sensors from coordinator data. |
homeassistant/components/wattwaechter/update.py |
Adds firmware update entity with OTA check/install and reboot detection. |
homeassistant/components/wattwaechter/entity.py |
Base entity providing device info (incl. configuration URL + MAC connection). |
homeassistant/components/wattwaechter/diagnostics.py |
Implements diagnostics payload with token/MAC redaction. |
homeassistant/components/wattwaechter/manifest.json |
Declares integration metadata, dependencies, requirements, and zeroconf type. |
homeassistant/components/wattwaechter/strings.json |
Adds config/options/error/exception and entity translations. |
homeassistant/components/wattwaechter/icons.json |
Adds entity icon translations. |
homeassistant/components/wattwaechter/quality_scale.yaml |
Declares quality scale status for the integration. |
homeassistant/components/wattwaechter/brand/icon.png |
Adds integration brand icon (256px). |
homeassistant/components/wattwaechter/brand/icon@2x.png |
Adds integration brand icon (512px). |
homeassistant/generated/zeroconf.py |
Registers _wattwaechter._tcp.local. zeroconf service mapping to the domain. |
homeassistant/generated/integrations.json |
Adds generated integration registry entry for wattwaechter. |
tests/components/wattwaechter/__init__.py |
Initializes the integration test package. |
tests/components/wattwaechter/conftest.py |
Adds fixtures and test data for the new integration tests. |
tests/components/wattwaechter/test_config_flow.py |
Tests config flow scenarios (user/zeroconf/reauth/reconfigure/options). |
tests/components/wattwaechter/test_init.py |
Tests setup/unload and setup retry behavior. |
tests/components/wattwaechter/test_sensor.py |
Tests OBIS sensor creation (known/unknown/minimal/no data) and diagnostics sensors. |
tests/components/wattwaechter/test_update.py |
Tests update entity (no update/update available/install + error paths + reboot detection). |
CODEOWNERS |
Adds codeowners for the new integration and its tests. |
You can also share your feedback on Copilot code review. Take the survey.
Add WattWächter Plus integration for local energy monitoring via SML/OBIS protocol.
0fef350 to
d19d94d
Compare
There was a problem hiding this comment.
It seems you haven't yet signed a CLA. Please do so here.
Once you do that we will be able to review and accept this pull request.
Thanks!
|
Addressed the Copilot feedback:
Regarding the automated "single platform" comment: this integration provides The tests currently use Companion docs PR: home-assistant/home-assistant.io#44004 |
|
Hi, just checking in on this PR — is there anything we need to adjust on our side? We noticed the CI workflows haven't run yet, presumably because of the first-time contributor approval? Let us know if there's anything we can do to move things along. |
| async def _async_update_data(self) -> MeterData: | ||
| """Fetch data from the WattWächter device.""" | ||
| try: | ||
| data = await self.client.meter_data() | ||
| except WattwaechterNoDataError as err: | ||
| raise UpdateFailed( | ||
| translation_domain=DOMAIN, | ||
| translation_key="no_meter_data", | ||
| translation_placeholders={"host": self.host}, | ||
| ) from err | ||
| except WattwaechterAuthenticationError as err: | ||
| raise ConfigEntryAuthFailed( | ||
| translation_domain=DOMAIN, | ||
| translation_key="auth_failed", | ||
| translation_placeholders={"error": str(err)}, | ||
| ) from err | ||
| except WattwaechterConnectionError as err: | ||
| raise UpdateFailed( | ||
| translation_domain=DOMAIN, | ||
| translation_key="update_failed", | ||
| translation_placeholders={"error": str(err)}, | ||
| ) from err | ||
|
|
||
| if data is None: | ||
| raise UpdateFailed( | ||
| translation_domain=DOMAIN, | ||
| translation_key="no_meter_data", | ||
| translation_placeholders={"host": self.host}, | ||
| ) |
There was a problem hiding this comment.
UpdateFailed (from homeassistant.helpers.update_coordinator) does not support the translation_domain/translation_key/translation_placeholders kwargs, which will raise a TypeError the first time one of these error paths occurs (breaking setup and retries). Use UpdateFailed(<string message>) for coordinator update failures, and keep translated exceptions for user-facing flows/errors where supported (e.g., ConfigEntryAuthFailed).
| return self.async_show_form( | ||
| step_id="zeroconf_confirm", | ||
| data_schema=vol.Schema( | ||
| { | ||
| vol.Required(CONF_TOKEN): str, | ||
| } | ||
| ), | ||
| description_placeholders={ | ||
| "model": self._model or "WattWächter Plus", | ||
| "firmware": self._fw_version or "unknown", | ||
| "host": self._host or "", | ||
| "device_id": self._device_id or "", | ||
| }, | ||
| ) |
There was a problem hiding this comment.
The zeroconf_confirm token form schema + description_placeholders block is duplicated in the same method for the error retry case (later in async_step_zeroconf_confirm). Consider extracting a small helper (e.g., _show_zeroconf_token_form(errors: dict[str, str] | None = None)) so future changes (new placeholders, validation, optional token behavior) don’t require updating multiple copies.
|
Hi @joostlek Thanks again for your review — really appreciate you taking the time! Sorry for the delayed response, I was on vacation. I've addressed all your feedback from the last round and also cleaned up a few additional things:
Looking forward to your next review whenever you get a chance. Thanks! |
Summary
Features
Quality
Follow-up PRs (planned)
Documentation
home-assistant/home-assistant.io#44004
Brands
home-assistant/brands#10065