mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Migrate zwave_js entities to use new unique ID format (#46979)
* migrate zwave_js entities to use new unique ID format * remove extra param from helper * add comment to remove migration logic in the future * update comment * use instance attribute instead of calling functino on every state update
This commit is contained in:
parent
44293a3738
commit
424526db7e
@ -43,7 +43,7 @@ from .const import (
|
||||
ZWAVE_JS_EVENT,
|
||||
)
|
||||
from .discovery import async_discover_values
|
||||
from .helpers import get_device_id
|
||||
from .helpers import get_device_id, get_old_value_id, get_unique_id
|
||||
from .services import ZWaveServices
|
||||
|
||||
LOGGER = logging.getLogger(__package__)
|
||||
@ -83,6 +83,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Set up Z-Wave JS from a config entry."""
|
||||
client = ZwaveClient(entry.data[CONF_URL], async_get_clientsession(hass))
|
||||
dev_reg = await device_registry.async_get_registry(hass)
|
||||
ent_reg = entity_registry.async_get(hass)
|
||||
|
||||
@callback
|
||||
def async_on_node_ready(node: ZwaveNode) -> None:
|
||||
@ -95,6 +96,28 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
# run discovery on all node values and create/update entities
|
||||
for disc_info in async_discover_values(node):
|
||||
LOGGER.debug("Discovered entity: %s", disc_info)
|
||||
|
||||
# This migration logic was added in 2021.3 to handle breaking change to
|
||||
# value_id format. Some time in the future, this code block
|
||||
# (and get_old_value_id helper) can be removed.
|
||||
old_value_id = get_old_value_id(disc_info.primary_value)
|
||||
old_unique_id = get_unique_id(
|
||||
client.driver.controller.home_id, old_value_id
|
||||
)
|
||||
if entity_id := ent_reg.async_get_entity_id(
|
||||
disc_info.platform, DOMAIN, old_unique_id
|
||||
):
|
||||
LOGGER.debug(
|
||||
"Entity %s is using old unique ID, migrating to new one", entity_id
|
||||
)
|
||||
ent_reg.async_update_entity(
|
||||
entity_id,
|
||||
new_unique_id=get_unique_id(
|
||||
client.driver.controller.home_id,
|
||||
disc_info.primary_value.value_id,
|
||||
),
|
||||
)
|
||||
|
||||
async_dispatcher_send(
|
||||
hass, f"{DOMAIN}_{entry.entry_id}_add_{disc_info.platform}", disc_info
|
||||
)
|
||||
@ -193,7 +216,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
DATA_UNSUBSCRIBE: unsubscribe_callbacks,
|
||||
}
|
||||
|
||||
services = ZWaveServices(hass, entity_registry.async_get(hass))
|
||||
services = ZWaveServices(hass, ent_reg)
|
||||
services.async_register()
|
||||
|
||||
# Set up websocket API
|
||||
|
@ -13,7 +13,7 @@ from homeassistant.helpers.entity import Entity
|
||||
|
||||
from .const import DOMAIN
|
||||
from .discovery import ZwaveDiscoveryInfo
|
||||
from .helpers import get_device_id
|
||||
from .helpers import get_device_id, get_unique_id
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -31,6 +31,9 @@ class ZWaveBaseEntity(Entity):
|
||||
self.client = client
|
||||
self.info = info
|
||||
self._name = self.generate_name()
|
||||
self._unique_id = get_unique_id(
|
||||
self.client.driver.controller.home_id, self.info.value_id
|
||||
)
|
||||
# entities requiring additional values, can add extra ids to this list
|
||||
self.watched_value_ids = {self.info.primary_value.value_id}
|
||||
|
||||
@ -128,7 +131,7 @@ class ZWaveBaseEntity(Entity):
|
||||
@property
|
||||
def unique_id(self) -> str:
|
||||
"""Return the unique_id of the entity."""
|
||||
return f"{self.client.driver.controller.home_id}.{self.info.value_id}"
|
||||
return self._unique_id
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
|
@ -3,6 +3,7 @@ from typing import List, Tuple, cast
|
||||
|
||||
from zwave_js_server.client import Client as ZwaveClient
|
||||
from zwave_js_server.model.node import Node as ZwaveNode
|
||||
from zwave_js_server.model.value import Value as ZwaveValue
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
@ -12,6 +13,22 @@ from homeassistant.helpers.entity_registry import async_get as async_get_ent_reg
|
||||
from .const import DATA_CLIENT, DOMAIN
|
||||
|
||||
|
||||
@callback
|
||||
def get_old_value_id(value: ZwaveValue) -> str:
|
||||
"""Get old value ID so we can migrate entity unique ID."""
|
||||
command_class = value.command_class
|
||||
endpoint = value.endpoint or "00"
|
||||
property_ = value.property_
|
||||
property_key_name = value.property_key_name or "00"
|
||||
return f"{value.node.node_id}-{command_class}-{endpoint}-{property_}-{property_key_name}"
|
||||
|
||||
|
||||
@callback
|
||||
def get_unique_id(home_id: str, value_id: str) -> str:
|
||||
"""Get unique ID from home ID and value ID."""
|
||||
return f"{home_id}.{value_id}"
|
||||
|
||||
|
||||
@callback
|
||||
def get_device_id(client: ZwaveClient, node: ZwaveNode) -> Tuple[str, str]:
|
||||
"""Get device registry identifier for Z-Wave node."""
|
||||
|
@ -124,6 +124,37 @@ async def test_on_node_added_ready(
|
||||
)
|
||||
|
||||
|
||||
async def test_unique_id_migration(hass, multisensor_6_state, client, integration):
|
||||
"""Test unique ID is migrated from old format to new."""
|
||||
ent_reg = entity_registry.async_get(hass)
|
||||
entity_name = AIR_TEMPERATURE_SENSOR.split(".")[1]
|
||||
|
||||
# Create entity RegistryEntry using old unique ID format
|
||||
old_unique_id = f"{client.driver.controller.home_id}.52-49-00-Air temperature-00"
|
||||
entity_entry = ent_reg.async_get_or_create(
|
||||
"sensor",
|
||||
DOMAIN,
|
||||
old_unique_id,
|
||||
suggested_object_id=entity_name,
|
||||
config_entry=integration,
|
||||
original_name=entity_name,
|
||||
)
|
||||
assert entity_entry.entity_id == AIR_TEMPERATURE_SENSOR
|
||||
assert entity_entry.unique_id == old_unique_id
|
||||
|
||||
# Add a ready node, unique ID should be migrated
|
||||
node = Node(client, multisensor_6_state)
|
||||
event = {"node": node}
|
||||
|
||||
client.driver.controller.emit("node added", event)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Check that new RegistryEntry is using new unique ID format
|
||||
entity_entry = ent_reg.async_get(AIR_TEMPERATURE_SENSOR)
|
||||
new_unique_id = f"{client.driver.controller.home_id}.52-49-0-Air temperature-00-00"
|
||||
assert entity_entry.unique_id == new_unique_id
|
||||
|
||||
|
||||
async def test_on_node_added_not_ready(
|
||||
hass, multisensor_6_state, client, integration, device_registry
|
||||
):
|
||||
|
Loading…
x
Reference in New Issue
Block a user