Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d19d94d
add wattwaechter integration
smartcircuits Mar 9, 2026
1d78171
fix _attr_in_progress: use None instead of False
smartcircuits Mar 10, 2026
0d9e034
fix codeowner to smartcircuits
smartcircuits Mar 10, 2026
1eee386
slim down PR per review: single platform, no diagnostics/reauth/recon…
smartcircuits Apr 1, 2026
d78059b
fix CI: bronze tier, mypy, pylint, test imports
smartcircuits Apr 1, 2026
9f98d10
fix CI: add quality_scale to manifest, requirements, ruff fixes
smartcircuits Apr 1, 2026
56a5a77
address review feedback from joostlek
smartcircuits Apr 2, 2026
50146b3
fix CI: ruff PERF401, generated file ordering, CODEOWNERS
smartcircuits Apr 2, 2026
22eb28e
Merge branch 'dev' into add-wattwaechter-integration
smartcircuits Apr 2, 2026
ce041e5
Merge branch 'dev' into add-wattwaechter-integration
smartcircuits Apr 2, 2026
dcc3f57
Merge branch 'dev' into add-wattwaechter-integration
smartcircuits Apr 2, 2026
10bb44d
fix ruff import order, prettier JSON sorting, integrations.json format
smartcircuits Apr 2, 2026
5c6e4b7
fix ruff formatting, import sorting, add mypy.ini entry
smartcircuits Apr 2, 2026
8c3a8b4
fix circular import: use TYPE_CHECKING for WattwaechterConfigEntry
smartcircuits Apr 2, 2026
3888be2
fix ruff: remove parentheses from multi-except (python 3.14)
smartcircuits Apr 2, 2026
feb385d
fix integrations.json field order to match hassfest generation
smartcircuits Apr 2, 2026
0c6a291
address second round of review feedback
smartcircuits Apr 2, 2026
bec90b2
Merge remote-tracking branch 'upstream/dev' into add-wattwaechter-int…
smartcircuits Apr 2, 2026
e8b5151
add return type annotations to test fixtures
smartcircuits Apr 2, 2026
39397c2
address third round of review feedback
smartcircuits Apr 11, 2026
a2d2b8f
fix except clause syntax for python 3.12 compatibility
smartcircuits Apr 11, 2026
20aac42
raise ConfigEntryNotReady when no meter data available on first poll
smartcircuits Apr 11, 2026
3b0fcf8
remove PARALLEL_UPDATES constant
smartcircuits Apr 11, 2026
1b817b0
import WattwaechterConfigEntry from coordinator instead of package root
smartcircuits Apr 11, 2026
27e6a0d
restore PARALLEL_UPDATES and add None guard for mypy
smartcircuits Apr 11, 2026
1597e2f
raise UpdateFailed on WattwaechterNoDataError to preserve last known …
smartcircuits Apr 11, 2026
e21b584
store empty string instead of None for device_name in config entry data
smartcircuits Apr 11, 2026
172231c
remove unused _LOGGER from sensor module
smartcircuits Apr 11, 2026
e700542
remove leftover wifi diagnostic sensor icons
smartcircuits Apr 11, 2026
33923f3
use entity registry unique_id lookups instead of hardcoded entity IDs…
smartcircuits Apr 11, 2026
d4c5a36
use unknown error instead of cannot_connect when device_id is missing
smartcircuits Apr 11, 2026
1a90ac9
add test for auth error during coordinator first refresh
smartcircuits Apr 11, 2026
6c78fd5
add missing tests for full codecov coverage
smartcircuits Apr 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CODEOWNERS

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

72 changes: 72 additions & 0 deletions homeassistant/components/wattwaechter/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""The WattWächter Plus integration."""
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

The PR description claims "MQTT conflict detection (prevents duplicate entities)" but there is no MQTT-related code in the integration. This feature is not implemented in the provided code.

Copilot uses AI. Check for mistakes.

from __future__ import annotations

import logging
from datetime import timedelta

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_SCAN_INTERVAL, CONF_TOKEN, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.aiohttp_client import async_get_clientsession

from aio_wattwaechter import Wattwaechter, WattwaechterConnectionError
from .const import DEFAULT_SCAN_INTERVAL, DOMAIN
from .coordinator import WattwaechterCoordinator

_LOGGER = logging.getLogger(__name__)

PLATFORMS = [Platform.SENSOR, Platform.UPDATE]

type WattwaechterConfigEntry = ConfigEntry[WattwaechterCoordinator]


async def async_setup_entry(
hass: HomeAssistant, entry: WattwaechterConfigEntry
) -> bool:
"""Set up WattWächter Plus from a config entry."""
host = entry.data[CONF_HOST]
token = entry.data.get(CONF_TOKEN)

session = async_get_clientsession(hass)
client = Wattwaechter(host, token=token, session=session)

# Verify device is reachable
try:
await client.alive()
except WattwaechterConnectionError as err:
raise ConfigEntryNotReady(
translation_domain=DOMAIN,
translation_key="cannot_connect",
translation_placeholders={"host": host},
) from err

coordinator = WattwaechterCoordinator(hass, entry, client)
await coordinator.async_config_entry_first_refresh()

entry.runtime_data = coordinator

await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

# Update listener for options changes (e.g. scan interval)
entry.async_on_unload(entry.add_update_listener(_async_update_listener))

return True


async def _async_update_listener(
hass: HomeAssistant, entry: WattwaechterConfigEntry
) -> None:
"""Handle options update - dynamically adjust coordinator interval."""
coordinator = entry.runtime_data
new_interval = entry.options.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
coordinator.update_interval = timedelta(seconds=new_interval)
await coordinator.async_request_refresh()


async def async_unload_entry(
hass: HomeAssistant, entry: WattwaechterConfigEntry
) -> bool:
"""Unload a WattWächter Plus config entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading