Use the common unique_id schema in the Shelly button platform (#152707)

This commit is contained in:
Maciej Bieniek
2025-09-21 19:34:50 +02:00
committed by GitHub
parent 2b6a125927
commit 1e14fb6dab
5 changed files with 71 additions and 16 deletions

View File

@@ -9,6 +9,7 @@ from typing import TYPE_CHECKING, Any, Final
from aioshelly.const import BLU_TRV_IDENTIFIER, MODEL_BLU_GATEWAY_G3, RPC_GENERATIONS
from aioshelly.exceptions import DeviceConnectionError, InvalidAuthError, RpcCallError
from aioshelly.rpc_device import RpcDevice
from homeassistant.components.button import (
DOMAIN as BUTTON_PLATFORM,
@@ -22,13 +23,13 @@ from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from homeassistant.util import slugify
from .const import DOMAIN, LOGGER, SHELLY_GAS_MODELS
from .coordinator import ShellyBlockCoordinator, ShellyConfigEntry, ShellyRpcCoordinator
from .entity import get_entity_block_device_info, get_entity_rpc_device_info
from .utils import (
async_remove_orphaned_entities,
format_ble_addr,
get_blu_trv_device_info,
get_device_entry_gen,
get_rpc_entity_name,
@@ -112,12 +113,10 @@ def async_migrate_unique_ids(
if not entity_entry.entity_id.startswith("button"):
return None
device_name = slugify(coordinator.device.name)
for key in ("reboot", "self_test", "mute", "unmute"):
old_unique_id = f"{device_name}_{key}"
old_unique_id = f"{coordinator.mac}_{key}"
if entity_entry.unique_id == old_unique_id:
new_unique_id = f"{coordinator.mac}_{key}"
new_unique_id = f"{coordinator.mac}-{key}"
LOGGER.debug(
"Migrating unique_id for %s entity from [%s] to [%s]",
entity_entry.entity_id,
@@ -130,6 +129,26 @@ def async_migrate_unique_ids(
)
}
if blutrv_key_ids := get_rpc_key_ids(coordinator.device.status, BLU_TRV_IDENTIFIER):
assert isinstance(coordinator.device, RpcDevice)
for _id in blutrv_key_ids:
key = f"{BLU_TRV_IDENTIFIER}:{_id}"
ble_addr: str = coordinator.device.config[key]["addr"]
old_unique_id = f"{ble_addr}_calibrate"
if entity_entry.unique_id == old_unique_id:
new_unique_id = f"{format_ble_addr(ble_addr)}-{key}-calibrate"
LOGGER.debug(
"Migrating unique_id for %s entity from [%s] to [%s]",
entity_entry.entity_id,
old_unique_id,
new_unique_id,
)
return {
"new_unique_id": entity_entry.unique_id.replace(
old_unique_id, new_unique_id
)
}
return None
@@ -264,7 +283,7 @@ class ShellyButton(ShellyBaseButton):
"""Initialize Shelly button."""
super().__init__(coordinator, description)
self._attr_unique_id = f"{coordinator.mac}_{description.key}"
self._attr_unique_id = f"{coordinator.mac}-{description.key}"
if isinstance(coordinator, ShellyBlockCoordinator):
self._attr_device_info = get_entity_block_device_info(coordinator)
else:
@@ -297,7 +316,7 @@ class ShellyBluTrvButton(ShellyBaseButton):
ble_addr: str = config["addr"]
fw_ver = coordinator.device.status[key].get("fw_ver")
self._attr_unique_id = f"{ble_addr}_{description.key}"
self._attr_unique_id = f"{format_ble_addr(ble_addr)}-{key}-{description.key}"
self._attr_device_info = get_blu_trv_device_info(
config, ble_addr, coordinator.mac, fw_ver
)

View File

@@ -918,3 +918,8 @@ def remove_empty_sub_devices(hass: HomeAssistant, entry: ConfigEntry) -> None:
dev_reg.async_update_device(
device.id, remove_config_entry_id=entry.entry_id
)
def format_ble_addr(ble_addr: str) -> str:
"""Format BLE address to use in unique_id."""
return ble_addr.replace(":", "").upper()

View File

@@ -30,7 +30,7 @@
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'calibrate',
'unique_id': 'f8:44:77:25:f0:dd_calibrate',
'unique_id': 'F8447725F0DD-blutrv:200-calibrate',
'unit_of_measurement': None,
})
# ---
@@ -78,7 +78,7 @@
'suggested_object_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': '123456789ABC_reboot',
'unique_id': '123456789ABC-reboot',
'unit_of_measurement': None,
})
# ---

View File

@@ -422,7 +422,7 @@
'suggested_object_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': '123456789ABC_reboot',
'unique_id': '123456789ABC-reboot',
'unit_of_measurement': None,
})
# ---
@@ -1672,7 +1672,7 @@
'suggested_object_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': '123456789ABC_reboot',
'unique_id': '123456789ABC-reboot',
'unit_of_measurement': None,
})
# ---
@@ -2935,7 +2935,7 @@
'suggested_object_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': '123456789ABC_reboot',
'unique_id': '123456789ABC-reboot',
'unit_of_measurement': None,
})
# ---

View File

@@ -33,7 +33,7 @@ async def test_block_button(
assert state.state == STATE_UNKNOWN
assert (entry := entity_registry.async_get(entity_id))
assert entry.unique_id == "123456789ABC_reboot"
assert entry.unique_id == "123456789ABC-reboot"
await hass.services.async_call(
BUTTON_DOMAIN,
@@ -136,9 +136,9 @@ async def test_rpc_button_reauth_error(
@pytest.mark.parametrize(
("gen", "old_unique_id", "new_unique_id", "migration"),
[
(2, "test_name_reboot", "123456789ABC_reboot", True),
(1, "test_name_reboot", "123456789ABC_reboot", True),
(2, "123456789ABC_reboot", "123456789ABC_reboot", False),
(2, "123456789ABC_reboot", "123456789ABC-reboot", True),
(1, "123456789ABC_reboot", "123456789ABC-reboot", True),
(2, "123456789ABC-reboot", "123456789ABC-reboot", False),
],
)
async def test_migrate_unique_id(
@@ -379,3 +379,34 @@ async def test_wall_display_virtual_button(
blocking=True,
)
mock_rpc_device.button_trigger.assert_called_once_with(200, "single_push")
async def test_migrate_unique_id_blu_trv(
hass: HomeAssistant,
mock_blu_trv: Mock,
entity_registry: EntityRegistry,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test migration of unique_id for BLU TRV button."""
entry = await init_integration(hass, 3, model=MODEL_BLU_GATEWAY_G3, skip_setup=True)
old_unique_id = "f8:44:77:25:f0:dd_calibrate"
entity = entity_registry.async_get_or_create(
suggested_object_id="trv_name_calibrate",
disabled_by=None,
domain=BUTTON_DOMAIN,
platform=DOMAIN,
unique_id=old_unique_id,
config_entry=entry,
)
assert entity.unique_id == old_unique_id
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
entity_entry = entity_registry.async_get("button.trv_name_calibrate")
assert entity_entry
assert entity_entry.unique_id == "F8447725F0DD-blutrv:200-calibrate"
assert "Migrating unique_id for button.trv_name_calibrate" in caplog.text