This commit is contained in:
Flavien Haas 2025-04-27 18:02:15 +02:00
parent 9203a0562a
commit 2e259892bf
5 changed files with 43 additions and 35 deletions

3
bolt.svg Normal file
View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M7 2v11h3v9l7-12h-4l4-8z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 119 B

View File

@ -6,7 +6,6 @@ import voluptuous as vol
from homeassistant import config_entries
from homeassistant.core import callback
from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers import device_registry as dr
from .const import (
@ -18,13 +17,18 @@ from .const import (
_LOGGER = logging.getLogger(__name__)
async def async_get_devices(hass):
async def async_get_zha_devices(hass):
"""Get ZHA devices."""
device_registry = dr.async_get(hass)
if "zha" not in hass.data:
return []
zha_gateway = hass.data["zha"].get("zha_gateway")
if not zha_gateway:
return []
return [
entry
for entry in device_registry.devices.values()
if entry.via_device_id is not None and "zha" in entry.via_device_id
(str(device.ieee), f"{device.name} ({device.ieee})")
for device in zha_gateway.devices.values()
]
class LinkyTariffConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
@ -35,7 +39,7 @@ class LinkyTariffConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
async def async_step_user(self, user_input=None):
"""Handle the initial step."""
errors = {}
devices = await async_get_devices(self.hass)
devices = await async_get_zha_devices(self.hass)
if not devices:
return self.async_abort(reason="no_zha_devices")
@ -45,15 +49,10 @@ class LinkyTariffConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
self._abort_if_unique_id_configured()
return self.async_create_entry(title="Linky Tariff", data=user_input)
device_options = {
device.id: f"{device.name_by_user or device.name} ({device.id})"
for device in devices
}
return self.async_show_form(
step_id="user",
data_schema=vol.Schema({
vol.Required(CONF_IEEE): vol.In(device_options),
vol.Required(CONF_IEEE): vol.In(dict(devices)),
vol.Optional(
CONF_POLL_INTERVAL,
default=DEFAULT_POLL_INTERVAL

BIN
icon.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

48
init.py
View File

@ -5,8 +5,9 @@ import logging
from typing import Any
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_IEEE, CONF_SCAN_INTERVAL
from homeassistant.const import CONF_IEEE
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from .const import (
@ -63,31 +64,36 @@ class LinkyTariffCoordinator(DataUpdateCoordinator):
update_interval=poll_interval,
)
self.ieee = ieee
self._attr = None
async def _async_update_data(self) -> dict[str, Any]:
"""Fetch data from ZHA device."""
try:
result = await self.hass.services.async_call(
"zha_toolkit",
"attr_read",
{
"ieee": self.ieee,
"endpoint_id": ENDPOINT_ID,
"cluster_id": CLUSTER_ID,
"attribute_id": ATTRIBUTE_ID,
"manufacturer": None,
},
blocking=True,
return_response=True,
)
if "zha" not in self.hass.data:
raise ValueError("ZHA integration not loaded")
zha_gateway = self.hass.data["zha"].get("zha_gateway")
if not zha_gateway:
raise ValueError("ZHA gateway not available")
zha_device = zha_gateway.devices.get(self.ieee)
if not zha_device:
raise ValueError(f"Device {self.ieee} not found in ZHA")
endpoint = zha_device.endpoints.get(ENDPOINT_ID)
if not endpoint:
raise ValueError(f"Endpoint {ENDPOINT_ID} not found")
cluster = endpoint.in_clusters.get(CLUSTER_ID)
if not cluster:
raise ValueError(f"Cluster {CLUSTER_ID} not found")
result = await cluster.read_attributes([ATTRIBUTE_ID])
value = result.get(ATTRIBUTE_ID, "unknown")
if result and "value" in result:
return {
"value": result["value"],
"last_update": self.hass.config.time_utc(),
}
return {"value": "unknown", "last_update": self.hass.config.time_utc()}
return {
"value": value,
"last_update": self.hass.config.time_utc(),
}
except Exception as ex:
_LOGGER.error("Error reading Linky tariff: %s", ex)

View File

@ -7,6 +7,6 @@
"codeowners": ["@flavien"],
"requirements": [],
"iot_class": "local_polling",
"loggers": ["zha_toolkit"],
"dependencies": ["zha"],
"integration_type": "device"
}