Hi there,
I’ve just upgraded to Home Assistant 2025.7 and thanks to new integration UI, I noticed that inpost-air 1.5.0 now registers two devices for every parcel locker:
-
Old device – created by versions ≤ 1.4.x
Identifiers: ('inpost_air', locker_code, locker_id) (single 3-tuple)
-
New device – created by 1.5.0
Identifiers: {('inpost_air', locker_code), ('inpost_air', locker_id)} (two 2-tuples)
Here is related code snippet:
1e4db35#diff-def8c2bbe017571a9f34d2df0740883182a7d0af8a59d9cd00b16a061f635429L2-L46
Because HA compares devices by individual tuples, none of the new tuples match the old one, so core thinks it’s a brand-new device. All entities migrate to the new device, leaving the original entry orphaned and visible in the UI.
Suggested fix: one-off migration
I don't think, we need to keep the legacy 3-tuple identifier, so the simplest migration is to delete any empty devices that still carry it and (optionally) copy user metadata to the correct device.:
# custom_components/inpost_air/__init__.py
# Untested and generated by ChatGPT
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr
DOMAIN = "inpost_air"
async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Remove legacy 3-tuple devices left by ≤ 1.4.x."""
if entry.version == 1: # 1.5.0 → 1.5.1
dev_reg = dr.async_get(hass)
for device in list(dev_reg.devices.values()):
if entry.entry_id not in device.config_entries:
continue
# Detect an old device with a single 3-element identifier
old_id = next(
(i for i in device.identifiers
if len(i) == 3 and i[0] == DOMAIN),
None,
)
if not old_id:
continue
# Skip if it still has entities (unexpected edge-case)
if device.entities:
hass.logger.warning(
"Legacy device %s still has entities; skipping cleanup", device.id
)
continue
# Optionally carry over area/name/disabled flags to the new device
_, code, _ = old_id
new_dev = next(
(d for d in dev_reg.devices.values()
if (DOMAIN, code) in d.identifiers
and entry.entry_id in d.config_entries
and d.id != device.id),
None,
)
if new_dev:
dev_reg.async_update_device(
new_dev.id,
area_id=device.area_id or new_dev.area_id,
name_by_user=device.name_by_user or new_dev.name_by_user,
disabled_by=device.disabled_by or new_dev.disabled_by,
)
# Remove the orphaned 3-tuple device
dev_reg.async_remove_device(device.id)
entry.version = 2 # mark migration complete
return True
This runs once on upgrade, leaves users with a single clean device per locker, and preserves their area or custom name settings.
I’m not planning a PR myself, but feel free to copy the code snippet.
Thanks for maintaining the integration!
Hi there,
I’ve just upgraded to Home Assistant 2025.7 and thanks to new integration UI, I noticed that inpost-air 1.5.0 now registers two devices for every parcel locker:
Old device – created by versions ≤ 1.4.x
Identifiers:
('inpost_air', locker_code, locker_id)(single 3-tuple)New device – created by 1.5.0
Identifiers:
{('inpost_air', locker_code), ('inpost_air', locker_id)}(two 2-tuples)Here is related code snippet:
1e4db35#diff-def8c2bbe017571a9f34d2df0740883182a7d0af8a59d9cd00b16a061f635429L2-L46
Because HA compares devices by individual tuples, none of the new tuples match the old one, so core thinks it’s a brand-new device. All entities migrate to the new device, leaving the original entry orphaned and visible in the UI.
Suggested fix: one-off migration
I don't think, we need to keep the legacy 3-tuple identifier, so the simplest migration is to delete any empty devices that still carry it and (optionally) copy user metadata to the correct device.:
This runs once on upgrade, leaves users with a single clean device per locker, and preserves their area or custom name settings.
I’m not planning a PR myself, but feel free to copy the code snippet.
Thanks for maintaining the integration!