Add WattWächter Plus integration#165238
Add WattWächter Plus integration#165238smartcircuits wants to merge 3 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.
| "WattWächter device did not come back online after firmware update" | ||
| ) | ||
| finally: | ||
| self._attr_in_progress = False |
There was a problem hiding this comment.
_attr_in_progress is used as a progress percentage for UpdateEntityFeature.PROGRESS (typically int | None). Setting it to False in the finally block leaves it as a boolean (and effectively 0), which can make the update appear perpetually “in progress” at 0%. Set it to None when the install is complete (and consider resetting to None on early failures too).
| self._attr_in_progress = False | |
| self._attr_in_progress = None |
| from pytest_homeassistant_custom_component.common import MockConfigEntry | ||
|
|
||
| from aio_wattwaechter.models import ( | ||
| AliveResponse, | ||
| InfoEntry, | ||
| MeterData, | ||
| ObisValue, | ||
| OtaCheckResponse, | ||
| OtaData, | ||
| SystemInfo, | ||
| ) | ||
|
|
||
| from custom_components.wattwaechter.const import ( | ||
| CONF_DEVICE_ID, | ||
| CONF_DEVICE_NAME, | ||
| CONF_FW_VERSION, | ||
| CONF_MAC, | ||
| CONF_MODEL, | ||
| DOMAIN, | ||
| ) |
There was a problem hiding this comment.
These tests are importing/patching custom_components.wattwaechter.* and using pytest_homeassistant_custom_component fixtures, but this integration is implemented under homeassistant.components.wattwaechter. In core, tests should import from/patch homeassistant.components.wattwaechter.* and use tests.common.MockConfigEntry (and core fixtures) instead, otherwise the test suite won’t exercise the code under test.
| from custom_components.wattwaechter.const import ( | ||
| CONF_DEVICE_ID, | ||
| CONF_DEVICE_NAME, | ||
| CONF_FW_VERSION, | ||
| CONF_MAC, | ||
| CONF_MODEL, | ||
| DOMAIN, | ||
| ) |
There was a problem hiding this comment.
This test module imports custom_components.wattwaechter.* and patches custom_components.wattwaechter.config_flow.Wattwaechter, which won’t affect the real integration code at homeassistant.components.wattwaechter. Update imports/patch targets to homeassistant.components.wattwaechter.* so the tests actually cover the core integration.
| from custom_components.wattwaechter.coordinator import WattwaechterCoordinator | ||
|
|
||
| from .conftest import MOCK_ALIVE_RESPONSE, MOCK_METER_DATA, MOCK_SYSTEM_INFO | ||
|
|
||
|
|
||
| async def test_setup_entry(hass: HomeAssistant, mock_config_entry) -> None: | ||
| """Test successful integration setup.""" | ||
| with patch( | ||
| "custom_components.wattwaechter.Wattwaechter" | ||
| ) as mock_cls: | ||
| client = mock_cls.return_value |
There was a problem hiding this comment.
This test patches custom_components.wattwaechter.Wattwaechter and imports the coordinator from custom_components.*, but the integration lives in homeassistant.components.wattwaechter. The patch target/imports should be updated to homeassistant.components.wattwaechter.* so the test suite is validating the actual core integration code.
| from custom_components.wattwaechter.const import DOMAIN | ||
|
|
||
| from .conftest import ( | ||
| MOCK_ALIVE_RESPONSE, | ||
| MOCK_METER_DATA, | ||
| MOCK_METER_DATA_MINIMAL, | ||
| MOCK_METER_DATA_WITH_UNKNOWN, | ||
| MOCK_OTA_CHECK_NO_UPDATE, | ||
| MOCK_SYSTEM_INFO, | ||
| ) | ||
|
|
||
|
|
||
| async def _setup_integration(hass: HomeAssistant, mock_config_entry, meter_data): | ||
| """Set up the integration with given meter data.""" | ||
| with patch( | ||
| "custom_components.wattwaechter.Wattwaechter" | ||
| ) as mock_cls: | ||
| client = mock_cls.return_value | ||
| client.alive = AsyncMock(return_value=MOCK_ALIVE_RESPONSE) | ||
| client.meter_data = AsyncMock(return_value=meter_data) | ||
| client.system_info = AsyncMock(return_value=MOCK_SYSTEM_INFO) | ||
| client.ota_check = AsyncMock(return_value=MOCK_OTA_CHECK_NO_UPDATE) | ||
| client.host = "192.168.1.100" |
There was a problem hiding this comment.
This test imports DOMAIN from custom_components.wattwaechter.const and patches custom_components.wattwaechter.Wattwaechter. Since the integration is under homeassistant.components.wattwaechter, these imports/patches won’t target the code being shipped in core. Switch to homeassistant.components.wattwaechter.* throughout.
| with patch( | ||
| "custom_components.wattwaechter.Wattwaechter" | ||
| ) as mock_cls: |
There was a problem hiding this comment.
This test patches custom_components.wattwaechter.* (including custom_components.wattwaechter.update.asyncio.sleep), but the integration is implemented at homeassistant.components.wattwaechter. Update the patch targets to homeassistant.components.wattwaechter.* so the test exercises the correct module and avoids false positives.
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 |
Summary
Features
Quality
Documentation
home-assistant/home-assistant.io#44004