mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 01:08:12 +00:00
Fix KNX unique_id (#49677)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
e96cbccc92
commit
78befcd3fd
@ -37,6 +37,7 @@ class KNXBinarySensor(KnxEntity, BinarySensorEntity):
|
||||
"""Initialize of KNX binary sensor."""
|
||||
self._device: XknxBinarySensor
|
||||
super().__init__(device)
|
||||
self._unique_id = f"{self._device.remote_value.group_address_state}"
|
||||
|
||||
@property
|
||||
def device_class(self) -> str | None:
|
||||
|
@ -6,6 +6,7 @@ from typing import Any, Callable
|
||||
|
||||
from xknx.devices import Climate as XknxClimate
|
||||
from xknx.dpt.dpt_hvac_mode import HVACControllerMode, HVACOperationMode
|
||||
from xknx.telegram.address import parse_device_group_address
|
||||
|
||||
from homeassistant.components.climate import ClimateEntity
|
||||
from homeassistant.components.climate.const import (
|
||||
@ -16,12 +17,14 @@ from homeassistant.components.climate.const import (
|
||||
SUPPORT_TARGET_TEMPERATURE,
|
||||
)
|
||||
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
|
||||
from .const import CONTROLLER_MODES, DOMAIN, PRESET_MODES
|
||||
from .knx_entity import KnxEntity
|
||||
from .schema import ClimateSchema
|
||||
|
||||
CONTROLLER_MODES_INV = {value: key for key, value in CONTROLLER_MODES.items()}
|
||||
PRESET_MODES_INV = {value: key for key, value in PRESET_MODES.items()}
|
||||
@ -34,6 +37,7 @@ async def async_setup_platform(
|
||||
discovery_info: DiscoveryInfoType | None = None,
|
||||
) -> None:
|
||||
"""Set up climate(s) for KNX platform."""
|
||||
_async_migrate_unique_id(hass, discovery_info)
|
||||
entities = []
|
||||
for device in hass.data[DOMAIN].xknx.devices:
|
||||
if isinstance(device, XknxClimate):
|
||||
@ -41,6 +45,33 @@ async def async_setup_platform(
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
@callback
|
||||
def _async_migrate_unique_id(
|
||||
hass: HomeAssistant, discovery_info: DiscoveryInfoType | None
|
||||
) -> None:
|
||||
"""Change unique_ids used in 2021.4 to include target_temperature GA."""
|
||||
entity_registry = er.async_get(hass)
|
||||
if not discovery_info or not discovery_info["platform_config"]:
|
||||
return
|
||||
|
||||
platform_config = discovery_info["platform_config"]
|
||||
for entity_config in platform_config:
|
||||
# normalize group address strings - ga_temperature_state was the old uid
|
||||
ga_temperature_state = parse_device_group_address(
|
||||
entity_config[ClimateSchema.CONF_TEMPERATURE_ADDRESS][0]
|
||||
)
|
||||
old_uid = str(ga_temperature_state)
|
||||
|
||||
entity_id = entity_registry.async_get_entity_id("climate", DOMAIN, old_uid)
|
||||
if entity_id is None:
|
||||
continue
|
||||
ga_target_temperature_state = parse_device_group_address(
|
||||
entity_config[ClimateSchema.CONF_TARGET_TEMPERATURE_STATE_ADDRESS][0]
|
||||
)
|
||||
new_uid = f"{ga_temperature_state}_{ga_target_temperature_state}"
|
||||
entity_registry.async_update_entity(entity_id, new_unique_id=new_uid)
|
||||
|
||||
|
||||
class KNXClimate(KnxEntity, ClimateEntity):
|
||||
"""Representation of a KNX climate device."""
|
||||
|
||||
@ -48,7 +79,10 @@ class KNXClimate(KnxEntity, ClimateEntity):
|
||||
"""Initialize of a KNX climate device."""
|
||||
self._device: XknxClimate
|
||||
super().__init__(device)
|
||||
|
||||
self._unique_id = (
|
||||
f"{device.temperature.group_address_state}_"
|
||||
f"{device.target_temperature.group_address_state}"
|
||||
)
|
||||
self._unit_of_measurement = TEMP_CELSIUS
|
||||
|
||||
@property
|
||||
|
@ -6,6 +6,7 @@ from datetime import datetime
|
||||
from typing import Any, Callable
|
||||
|
||||
from xknx.devices import Cover as XknxCover, Device as XknxDevice
|
||||
from xknx.telegram.address import parse_device_group_address
|
||||
|
||||
from homeassistant.components.cover import (
|
||||
ATTR_POSITION,
|
||||
@ -23,12 +24,14 @@ from homeassistant.components.cover import (
|
||||
CoverEntity,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.event import async_track_utc_time_change
|
||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||
|
||||
from .const import DOMAIN
|
||||
from .knx_entity import KnxEntity
|
||||
from .schema import CoverSchema
|
||||
|
||||
|
||||
async def async_setup_platform(
|
||||
@ -38,6 +41,7 @@ async def async_setup_platform(
|
||||
discovery_info: DiscoveryInfoType | None = None,
|
||||
) -> None:
|
||||
"""Set up cover(s) for KNX platform."""
|
||||
_async_migrate_unique_id(hass, discovery_info)
|
||||
entities = []
|
||||
for device in hass.data[DOMAIN].xknx.devices:
|
||||
if isinstance(device, XknxCover):
|
||||
@ -45,6 +49,37 @@ async def async_setup_platform(
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
@callback
|
||||
def _async_migrate_unique_id(
|
||||
hass: HomeAssistant, discovery_info: DiscoveryInfoType | None
|
||||
) -> None:
|
||||
"""Change unique_ids used in 2021.4 to include position_target GA."""
|
||||
entity_registry = er.async_get(hass)
|
||||
if not discovery_info or not discovery_info["platform_config"]:
|
||||
return
|
||||
|
||||
platform_config = discovery_info["platform_config"]
|
||||
for entity_config in platform_config:
|
||||
# normalize group address strings - ga_updown was the old uid but is optional
|
||||
updown_addresses = entity_config.get(CoverSchema.CONF_MOVE_LONG_ADDRESS)
|
||||
if updown_addresses is None:
|
||||
continue
|
||||
ga_updown = parse_device_group_address(updown_addresses[0])
|
||||
old_uid = str(ga_updown)
|
||||
|
||||
entity_id = entity_registry.async_get_entity_id("cover", DOMAIN, old_uid)
|
||||
if entity_id is None:
|
||||
continue
|
||||
position_target_addresses = entity_config.get(CoverSchema.CONF_POSITION_ADDRESS)
|
||||
ga_position_target = (
|
||||
parse_device_group_address(position_target_addresses[0])
|
||||
if position_target_addresses is not None
|
||||
else None
|
||||
)
|
||||
new_uid = f"{ga_updown}_{ga_position_target}"
|
||||
entity_registry.async_update_entity(entity_id, new_unique_id=new_uid)
|
||||
|
||||
|
||||
class KNXCover(KnxEntity, CoverEntity):
|
||||
"""Representation of a KNX cover."""
|
||||
|
||||
@ -52,7 +87,9 @@ class KNXCover(KnxEntity, CoverEntity):
|
||||
"""Initialize the cover."""
|
||||
self._device: XknxCover
|
||||
super().__init__(device)
|
||||
|
||||
self._unique_id = (
|
||||
f"{device.updown.group_address}_{device.position_target.group_address}"
|
||||
)
|
||||
self._unsubscribe_auto_updater: Callable[[], None] | None = None
|
||||
|
||||
@callback
|
||||
|
@ -44,7 +44,7 @@ class KNXFan(KnxEntity, FanEntity):
|
||||
"""Initialize of KNX fan."""
|
||||
self._device: XknxFan
|
||||
super().__init__(device)
|
||||
|
||||
self._unique_id = f"{self._device.speed.group_address}"
|
||||
self._step_range: tuple[int, int] | None = None
|
||||
if device.max_step:
|
||||
# FanSpeedMode.STEP:
|
||||
|
@ -17,6 +17,7 @@ class KnxEntity(Entity):
|
||||
def __init__(self, device: XknxDevice) -> None:
|
||||
"""Set up device."""
|
||||
self._device = device
|
||||
self._unique_id: str | None = None
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
@ -37,7 +38,7 @@ class KnxEntity(Entity):
|
||||
@property
|
||||
def unique_id(self) -> str | None:
|
||||
"""Return the unique id of the device."""
|
||||
return self._device.unique_id
|
||||
return self._unique_id
|
||||
|
||||
async def async_update(self) -> None:
|
||||
"""Request a state update from KNX bus."""
|
||||
|
@ -52,7 +52,7 @@ class KNXLight(KnxEntity, LightEntity):
|
||||
"""Initialize of KNX light."""
|
||||
self._device: XknxLight
|
||||
super().__init__(device)
|
||||
|
||||
self._unique_id = self._device_unique_id()
|
||||
self._min_kelvin = device.min_kelvin or LightSchema.DEFAULT_MIN_KELVIN
|
||||
self._max_kelvin = device.max_kelvin or LightSchema.DEFAULT_MAX_KELVIN
|
||||
self._min_mireds = color_util.color_temperature_kelvin_to_mired(
|
||||
@ -62,6 +62,17 @@ class KNXLight(KnxEntity, LightEntity):
|
||||
self._min_kelvin
|
||||
)
|
||||
|
||||
def _device_unique_id(self) -> str:
|
||||
"""Return unique id for this device."""
|
||||
if self._device.switch.group_address is not None:
|
||||
return f"{self._device.switch.group_address}"
|
||||
return (
|
||||
f"{self._device.red.switch.group_address}_"
|
||||
f"{self._device.green.switch.group_address}_"
|
||||
f"{self._device.blue.switch.group_address}_"
|
||||
f"{self._device.white.switch.group_address}"
|
||||
)
|
||||
|
||||
@property
|
||||
def brightness(self) -> int | None:
|
||||
"""Return the brightness of this light between 0..255."""
|
||||
|
@ -36,6 +36,9 @@ class KNXScene(KnxEntity, Scene):
|
||||
"""Init KNX scene."""
|
||||
self._device: XknxScene
|
||||
super().__init__(device)
|
||||
self._unique_id = (
|
||||
f"{self._device.scene_value.group_address}_{self._device.scene_number}"
|
||||
)
|
||||
|
||||
async def async_activate(self, **kwargs: Any) -> None:
|
||||
"""Activate the scene."""
|
||||
|
@ -37,6 +37,7 @@ class KNXSensor(KnxEntity, SensorEntity):
|
||||
"""Initialize of a KNX sensor."""
|
||||
self._device: XknxSensor
|
||||
super().__init__(device)
|
||||
self._unique_id = f"{self._device.sensor_value.group_address_state}"
|
||||
|
||||
@property
|
||||
def state(self) -> StateType:
|
||||
|
@ -53,6 +53,7 @@ class KNXSwitch(KnxEntity, SwitchEntity):
|
||||
invert=config[SwitchSchema.CONF_INVERT],
|
||||
)
|
||||
)
|
||||
self._unique_id = f"{self._device.switch.group_address}"
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
|
@ -37,6 +37,7 @@ class KNXWeather(KnxEntity, WeatherEntity):
|
||||
"""Initialize of a KNX sensor."""
|
||||
self._device: XknxWeather
|
||||
super().__init__(device)
|
||||
self._unique_id = f"{self._device._temperature.group_address_state}"
|
||||
|
||||
@property
|
||||
def temperature(self) -> float | None:
|
||||
|
Loading…
x
Reference in New Issue
Block a user