mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
Fix invalid enocean unique_id (#74508)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
91384e07d0
commit
7141c36f8b
@ -5,12 +5,14 @@ from enocean.utils import combine_hex
|
|||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity
|
from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity
|
||||||
from homeassistant.const import CONF_ID, CONF_NAME
|
from homeassistant.const import CONF_ID, CONF_NAME, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import entity_registry
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
||||||
|
|
||||||
|
from .const import DOMAIN, LOGGER
|
||||||
from .device import EnOceanEntity
|
from .device import EnOceanEntity
|
||||||
|
|
||||||
CONF_CHANNEL = "channel"
|
CONF_CHANNEL = "channel"
|
||||||
@ -25,10 +27,40 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(
|
def generate_unique_id(dev_id: list[int], channel: int) -> str:
|
||||||
|
"""Generate a valid unique id."""
|
||||||
|
return f"{combine_hex(dev_id)}-{channel}"
|
||||||
|
|
||||||
|
|
||||||
|
def _migrate_to_new_unique_id(hass: HomeAssistant, dev_id, channel) -> None:
|
||||||
|
"""Migrate old unique ids to new unique ids."""
|
||||||
|
old_unique_id = f"{combine_hex(dev_id)}"
|
||||||
|
|
||||||
|
ent_reg = entity_registry.async_get(hass)
|
||||||
|
entity_id = ent_reg.async_get_entity_id(Platform.SWITCH, DOMAIN, old_unique_id)
|
||||||
|
|
||||||
|
if entity_id is not None:
|
||||||
|
new_unique_id = generate_unique_id(dev_id, channel)
|
||||||
|
try:
|
||||||
|
ent_reg.async_update_entity(entity_id, new_unique_id=new_unique_id)
|
||||||
|
except ValueError:
|
||||||
|
LOGGER.warning(
|
||||||
|
"Skip migration of id [%s] to [%s] because it already exists",
|
||||||
|
old_unique_id,
|
||||||
|
new_unique_id,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
LOGGER.debug(
|
||||||
|
"Migrating unique_id from [%s] to [%s]",
|
||||||
|
old_unique_id,
|
||||||
|
new_unique_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_platform(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
discovery_info: DiscoveryInfoType | None = None,
|
discovery_info: DiscoveryInfoType | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the EnOcean switch platform."""
|
"""Set up the EnOcean switch platform."""
|
||||||
@ -36,7 +68,8 @@ def setup_platform(
|
|||||||
dev_id = config.get(CONF_ID)
|
dev_id = config.get(CONF_ID)
|
||||||
dev_name = config.get(CONF_NAME)
|
dev_name = config.get(CONF_NAME)
|
||||||
|
|
||||||
add_entities([EnOceanSwitch(dev_id, dev_name, channel)])
|
_migrate_to_new_unique_id(hass, dev_id, channel)
|
||||||
|
async_add_entities([EnOceanSwitch(dev_id, dev_name, channel)])
|
||||||
|
|
||||||
|
|
||||||
class EnOceanSwitch(EnOceanEntity, SwitchEntity):
|
class EnOceanSwitch(EnOceanEntity, SwitchEntity):
|
||||||
@ -49,7 +82,7 @@ class EnOceanSwitch(EnOceanEntity, SwitchEntity):
|
|||||||
self._on_state = False
|
self._on_state = False
|
||||||
self._on_state2 = False
|
self._on_state2 = False
|
||||||
self.channel = channel
|
self.channel = channel
|
||||||
self._attr_unique_id = f"{combine_hex(dev_id)}"
|
self._attr_unique_id = generate_unique_id(dev_id, channel)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_on(self):
|
def is_on(self):
|
||||||
|
73
tests/components/enocean/test_switch.py
Normal file
73
tests/components/enocean/test_switch.py
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
"""Tests for the EnOcean switch platform."""
|
||||||
|
|
||||||
|
from enocean.utils import combine_hex
|
||||||
|
|
||||||
|
from homeassistant.components.enocean import DOMAIN as ENOCEAN_DOMAIN
|
||||||
|
from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry, assert_setup_component
|
||||||
|
|
||||||
|
SWITCH_CONFIG = {
|
||||||
|
"switch": [
|
||||||
|
{
|
||||||
|
"platform": ENOCEAN_DOMAIN,
|
||||||
|
"id": [0xDE, 0xAD, 0xBE, 0xEF],
|
||||||
|
"channel": 1,
|
||||||
|
"name": "room0",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async def test_unique_id_migration(hass: HomeAssistant) -> None:
|
||||||
|
"""Test EnOcean switch ID migration."""
|
||||||
|
|
||||||
|
entity_name = SWITCH_CONFIG["switch"][0]["name"]
|
||||||
|
switch_entity_id = f"{SWITCH_DOMAIN}.{entity_name}"
|
||||||
|
dev_id = SWITCH_CONFIG["switch"][0]["id"]
|
||||||
|
channel = SWITCH_CONFIG["switch"][0]["channel"]
|
||||||
|
|
||||||
|
ent_reg = er.async_get(hass)
|
||||||
|
|
||||||
|
old_unique_id = f"{combine_hex(dev_id)}"
|
||||||
|
|
||||||
|
entry = MockConfigEntry(domain=ENOCEAN_DOMAIN, data={"device": "/dev/null"})
|
||||||
|
|
||||||
|
entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
# Add a switch with an old unique_id to the entity registry
|
||||||
|
entity_entry = ent_reg.async_get_or_create(
|
||||||
|
SWITCH_DOMAIN,
|
||||||
|
ENOCEAN_DOMAIN,
|
||||||
|
old_unique_id,
|
||||||
|
suggested_object_id=entity_name,
|
||||||
|
config_entry=entry,
|
||||||
|
original_name=entity_name,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert entity_entry.entity_id == switch_entity_id
|
||||||
|
assert entity_entry.unique_id == old_unique_id
|
||||||
|
|
||||||
|
# Now add the sensor to check, whether the old unique_id is migrated
|
||||||
|
|
||||||
|
with assert_setup_component(1, SWITCH_DOMAIN):
|
||||||
|
assert await async_setup_component(
|
||||||
|
hass,
|
||||||
|
SWITCH_DOMAIN,
|
||||||
|
SWITCH_CONFIG,
|
||||||
|
)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
# Check that new entry has a new unique_id
|
||||||
|
entity_entry = ent_reg.async_get(switch_entity_id)
|
||||||
|
new_unique_id = f"{combine_hex(dev_id)}-{channel}"
|
||||||
|
|
||||||
|
assert entity_entry.unique_id == new_unique_id
|
||||||
|
assert (
|
||||||
|
ent_reg.async_get_entity_id(SWITCH_DOMAIN, ENOCEAN_DOMAIN, old_unique_id)
|
||||||
|
is None
|
||||||
|
)
|
Loading…
x
Reference in New Issue
Block a user