Skip to content

Commit 959c3a8

Browse files
allenporterfrenck
authored andcommitted
Fix a bug in rainbird device migration that results in additional devices (home-assistant#149078)
1 parent 254ccca commit 959c3a8

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

homeassistant/components/rainbird/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,9 @@ def _async_fix_device_id(
218218
for device_entry in device_entries:
219219
unique_id = str(next(iter(device_entry.identifiers))[1])
220220
device_entry_map[unique_id] = device_entry
221+
if unique_id.startswith(mac_address):
222+
# Already in the correct format
223+
continue
221224
if (suffix := unique_id.removeprefix(str(serial_number))) != unique_id:
222225
migrations[unique_id] = f"{mac_address}{suffix}"
223226

tests/components/rainbird/test_init.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,3 +449,75 @@ async def test_fix_duplicate_device_ids(
449449
assert device_entry.identifiers == {(DOMAIN, MAC_ADDRESS_UNIQUE_ID)}
450450
assert device_entry.name_by_user == expected_device_name
451451
assert device_entry.disabled_by == expected_disabled_by
452+
453+
454+
async def test_reload_migration_with_leading_zero_mac(
455+
hass: HomeAssistant,
456+
device_registry: dr.DeviceRegistry,
457+
entity_registry: er.EntityRegistry,
458+
) -> None:
459+
"""Test migration and reload of a device with a mac address with a leading zero."""
460+
mac_address = "01:02:03:04:05:06"
461+
mac_address_unique_id = dr.format_mac(mac_address)
462+
serial_number = "0"
463+
464+
# Setup the config entry to be in a pre-migrated state
465+
config_entry = MockConfigEntry(
466+
domain=DOMAIN,
467+
unique_id=serial_number,
468+
data={
469+
"host": "127.0.0.1",
470+
"password": "password",
471+
CONF_MAC: mac_address,
472+
"serial_number": serial_number,
473+
},
474+
)
475+
config_entry.add_to_hass(hass)
476+
477+
# Create a device and entity with the old unique id format
478+
device_entry = device_registry.async_get_or_create(
479+
config_entry_id=config_entry.entry_id,
480+
identifiers={(DOMAIN, f"{serial_number}-1")},
481+
)
482+
entity_entry = entity_registry.async_get_or_create(
483+
"switch",
484+
DOMAIN,
485+
f"{serial_number}-1-zone1",
486+
suggested_object_id="zone1",
487+
config_entry=config_entry,
488+
device_id=device_entry.id,
489+
)
490+
491+
# Setup the integration, which will migrate the unique ids
492+
await hass.config_entries.async_setup(config_entry.entry_id)
493+
await hass.async_block_till_done()
494+
495+
# Verify the device and entity were migrated to the new format
496+
migrated_device_entry = device_registry.async_get_device(
497+
identifiers={(DOMAIN, f"{mac_address_unique_id}-1")}
498+
)
499+
assert migrated_device_entry is not None
500+
migrated_entity_entry = entity_registry.async_get(entity_entry.entity_id)
501+
assert migrated_entity_entry is not None
502+
assert migrated_entity_entry.unique_id == f"{mac_address_unique_id}-1-zone1"
503+
504+
# Reload the integration
505+
await hass.config_entries.async_reload(config_entry.entry_id)
506+
await hass.async_block_till_done()
507+
508+
# Verify the device and entity still have the correct identifiers and were not duplicated
509+
reloaded_device_entry = device_registry.async_get(migrated_device_entry.id)
510+
assert reloaded_device_entry is not None
511+
assert reloaded_device_entry.identifiers == {(DOMAIN, f"{mac_address_unique_id}-1")}
512+
reloaded_entity_entry = entity_registry.async_get(entity_entry.entity_id)
513+
assert reloaded_entity_entry is not None
514+
assert reloaded_entity_entry.unique_id == f"{mac_address_unique_id}-1-zone1"
515+
516+
assert (
517+
len(dr.async_entries_for_config_entry(device_registry, config_entry.entry_id))
518+
== 1
519+
)
520+
assert (
521+
len(er.async_entries_for_config_entry(entity_registry, config_entry.entry_id))
522+
== 1
523+
)

0 commit comments

Comments
 (0)