Normalize deCONZ binary sensor unique IDs (#73657)

This commit is contained in:
Robert Svensson 2022-06-28 22:45:25 +02:00 committed by GitHub
parent a284ebe771
commit abf67c3153
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 16 deletions

View file

@ -27,8 +27,9 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback
import homeassistant.helpers.entity_registry as er
from .const import ATTR_DARK, ATTR_ON
from .const import ATTR_DARK, ATTR_ON, DOMAIN as DECONZ_DOMAIN
from .deconz_device import DeconzDevice
from .gateway import DeconzGateway, get_gateway_from_config_entry
@ -179,6 +180,27 @@ BINARY_SENSOR_DESCRIPTIONS = [
]
@callback
def async_update_unique_id(
hass: HomeAssistant, unique_id: str, description: DeconzBinarySensorDescription
) -> None:
"""Update unique ID to always have a suffix.
Introduced with release 2022.7.
"""
ent_reg = er.async_get(hass)
new_unique_id = f"{unique_id}-{description.key}"
if ent_reg.async_get_entity_id(DOMAIN, DECONZ_DOMAIN, new_unique_id):
return
if description.suffix:
unique_id = f'{unique_id.split("-", 1)[0]}-{description.suffix.lower()}'
if entity_id := ent_reg.async_get_entity_id(DOMAIN, DECONZ_DOMAIN, unique_id):
ent_reg.async_update_entity(entity_id, new_unique_id=new_unique_id)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
@ -205,6 +227,8 @@ async def async_setup_entry(
):
continue
async_update_unique_id(hass, sensor.unique_id, description)
async_add_entities([DeconzBinarySensor(sensor, gateway, description)])
gateway.register_platform_add_device_callback(
@ -255,9 +279,7 @@ class DeconzBinarySensor(DeconzDevice, BinarySensorEntity):
@property
def unique_id(self) -> str:
"""Return a unique identifier for this device."""
if self.entity_description.suffix:
return f"{self.serial}-{self.entity_description.suffix.lower()}"
return super().unique_id
return f"{super().unique_id}-{self.entity_description.key}"
@callback
def async_update_callback(self) -> None:

View file

@ -4,7 +4,7 @@ from unittest.mock import patch
import pytest
from homeassistant.components.binary_sensor import BinarySensorDeviceClass
from homeassistant.components.binary_sensor import DOMAIN, BinarySensorDeviceClass
from homeassistant.components.deconz.const import (
CONF_ALLOW_CLIP_SENSOR,
CONF_ALLOW_NEW_DEVICES,
@ -63,7 +63,8 @@ TEST_DATA = [
"entity_count": 3,
"device_count": 3,
"entity_id": "binary_sensor.alarm_10",
"unique_id": "00:15:8d:00:02:b5:d1:80-01-0500",
"unique_id": "00:15:8d:00:02:b5:d1:80-01-0500-alarm",
"old_unique_id": "00:15:8d:00:02:b5:d1:80-01-0500",
"state": STATE_OFF,
"entity_category": None,
"device_class": BinarySensorDeviceClass.SAFETY,
@ -104,7 +105,8 @@ TEST_DATA = [
"entity_count": 4,
"device_count": 3,
"entity_id": "binary_sensor.cave_co",
"unique_id": "00:15:8d:00:02:a5:21:24-01-0101",
"unique_id": "00:15:8d:00:02:a5:21:24-01-0101-carbon_monoxide",
"old_unique_id": "00:15:8d:00:02:a5:21:24-01-0101",
"state": STATE_OFF,
"entity_category": None,
"device_class": BinarySensorDeviceClass.CO,
@ -139,7 +141,8 @@ TEST_DATA = [
"entity_count": 2,
"device_count": 3,
"entity_id": "binary_sensor.sensor_kitchen_smoke",
"unique_id": "00:15:8d:00:01:d9:3e:7c-01-0500",
"unique_id": "00:15:8d:00:01:d9:3e:7c-01-0500-fire",
"old_unique_id": "00:15:8d:00:01:d9:3e:7c-01-0500",
"state": STATE_OFF,
"entity_category": None,
"device_class": BinarySensorDeviceClass.SMOKE,
@ -175,7 +178,8 @@ TEST_DATA = [
"entity_count": 2,
"device_count": 3,
"entity_id": "binary_sensor.sensor_kitchen_smoke_test_mode",
"unique_id": "00:15:8d:00:01:d9:3e:7c-test mode",
"unique_id": "00:15:8d:00:01:d9:3e:7c-01-0500-in_test_mode",
"old_unique_id": "00:15:8d:00:01:d9:3e:7c-test mode",
"state": STATE_OFF,
"entity_category": EntityCategory.DIAGNOSTIC,
"device_class": BinarySensorDeviceClass.SMOKE,
@ -207,7 +211,8 @@ TEST_DATA = [
"entity_count": 1,
"device_count": 2,
"entity_id": "binary_sensor.kitchen_switch",
"unique_id": "kitchen-switch",
"unique_id": "kitchen-switch-flag",
"old_unique_id": "kitchen-switch",
"state": STATE_ON,
"entity_category": None,
"device_class": None,
@ -244,7 +249,8 @@ TEST_DATA = [
"entity_count": 3,
"device_count": 3,
"entity_id": "binary_sensor.back_door",
"unique_id": "00:15:8d:00:02:2b:96:b4-01-0006",
"unique_id": "00:15:8d:00:02:2b:96:b4-01-0006-open",
"old_unique_id": "00:15:8d:00:02:2b:96:b4-01-0006",
"state": STATE_OFF,
"entity_category": None,
"device_class": BinarySensorDeviceClass.OPENING,
@ -290,7 +296,8 @@ TEST_DATA = [
"entity_count": 3,
"device_count": 3,
"entity_id": "binary_sensor.motion_sensor_4",
"unique_id": "00:17:88:01:03:28:8c:9b-02-0406",
"unique_id": "00:17:88:01:03:28:8c:9b-02-0406-presence",
"old_unique_id": "00:17:88:01:03:28:8c:9b-02-0406",
"state": STATE_OFF,
"entity_category": None,
"device_class": BinarySensorDeviceClass.MOTION,
@ -331,7 +338,8 @@ TEST_DATA = [
"entity_count": 5,
"device_count": 3,
"entity_id": "binary_sensor.water2",
"unique_id": "00:15:8d:00:02:2f:07:db-01-0500",
"unique_id": "00:15:8d:00:02:2f:07:db-01-0500-water",
"old_unique_id": "00:15:8d:00:02:2f:07:db-01-0500",
"state": STATE_OFF,
"entity_category": None,
"device_class": BinarySensorDeviceClass.MOISTURE,
@ -376,7 +384,8 @@ TEST_DATA = [
"entity_count": 3,
"device_count": 3,
"entity_id": "binary_sensor.vibration_1",
"unique_id": "00:15:8d:00:02:a5:21:24-01-0101",
"unique_id": "00:15:8d:00:02:a5:21:24-01-0101-vibration",
"old_unique_id": "00:15:8d:00:02:a5:21:24-01-0101",
"state": STATE_ON,
"entity_category": None,
"device_class": BinarySensorDeviceClass.VIBRATION,
@ -414,7 +423,8 @@ TEST_DATA = [
"entity_count": 4,
"device_count": 3,
"entity_id": "binary_sensor.presence_sensor_tampered",
"unique_id": "00:00:00:00:00:00:00:00-tampered",
"unique_id": "00:00:00:00:00:00:00:00-00-tampered",
"old_unique_id": "00:00:00:00:00:00:00:00-tampered",
"state": STATE_OFF,
"entity_category": EntityCategory.DIAGNOSTIC,
"device_class": BinarySensorDeviceClass.TAMPER,
@ -447,7 +457,8 @@ TEST_DATA = [
"entity_count": 4,
"device_count": 3,
"entity_id": "binary_sensor.presence_sensor_low_battery",
"unique_id": "00:00:00:00:00:00:00:00-low battery",
"unique_id": "00:00:00:00:00:00:00:00-00-low_battery",
"old_unique_id": "00:00:00:00:00:00:00:00-low battery",
"state": STATE_OFF,
"entity_category": EntityCategory.DIAGNOSTIC,
"device_class": BinarySensorDeviceClass.BATTERY,
@ -470,6 +481,14 @@ async def test_binary_sensors(
ent_reg = er.async_get(hass)
dev_reg = dr.async_get(hass)
# Create entity entry to migrate to new unique ID
ent_reg.async_get_or_create(
DOMAIN,
DECONZ_DOMAIN,
expected["old_unique_id"],
suggested_object_id=expected["entity_id"].replace(DOMAIN, ""),
)
with patch.dict(DECONZ_WEB_REQUEST, {"sensors": {"1": sensor_data}}):
config_entry = await setup_deconz_integration(
hass, aioclient_mock, options={CONF_ALLOW_CLIP_SENSOR: True}