-
Notifications
You must be signed in to change notification settings - Fork 6
feat: fixing device migration #57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -9,10 +9,12 @@ | |||||||||||||
| from homeassistant.const import Platform | ||||||||||||||
| from homeassistant.core import HomeAssistant | ||||||||||||||
| from homeassistant.helpers import device_registry as dr | ||||||||||||||
| from homeassistant.helpers import entity_registry as er | ||||||||||||||
|
|
||||||||||||||
| from custom_components.inpost_air.coordinator import InPostAirDataCoordinator | ||||||||||||||
| from custom_components.inpost_air.models import ParcelLocker | ||||||||||||||
| from custom_components.inpost_air.utils import get_device_info, get_parcel_locker_url | ||||||||||||||
| from custom_components.inpost_air.const import DOMAIN | ||||||||||||||
|
|
||||||||||||||
| from .api import InPostAirPoint, InPostApi | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -29,12 +31,12 @@ class InPostAirData: | |||||||||||||
| coordinator: InPostAirDataCoordinator | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| type InPostAirConfiEntry = ConfigEntry[InPostAirData] | ||||||||||||||
| type InPostAirConfigEntry = ConfigEntry[InPostAirData] | ||||||||||||||
|
|
||||||||||||||
| PLATFORMS: list[Platform] = [Platform.SENSOR] | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| async def async_setup_entry(hass: HomeAssistant, entry: InPostAirConfiEntry) -> bool: | ||||||||||||||
| async def async_setup_entry(hass: HomeAssistant, entry: InPostAirConfigEntry) -> bool: | ||||||||||||||
| """Set up InPost Air from a config entry.""" | ||||||||||||||
| api_client = InPostApi(hass) | ||||||||||||||
| entry_data = entry.data.get("parcel_locker") | ||||||||||||||
|
|
@@ -71,30 +73,75 @@ async def async_setup_entry(hass: HomeAssistant, entry: InPostAirConfiEntry) -> | |||||||||||||
| return True | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| async def async_unload_entry(hass: HomeAssistant, entry: InPostAirConfiEntry) -> bool: | ||||||||||||||
| async def async_unload_entry(hass: HomeAssistant, entry: InPostAirConfigEntry) -> bool: | ||||||||||||||
| """Unload a config entry.""" | ||||||||||||||
| return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| async def async_migrate_entry(hass: HomeAssistant, config_entry: InPostAirConfiEntry): | ||||||||||||||
| """Migrate old entry.""" | ||||||||||||||
| _LOGGER.debug( | ||||||||||||||
| "Migrating %s from version %s", config_entry.title, config_entry.version | ||||||||||||||
| ) | ||||||||||||||
|
Comment on lines
-81
to
-83
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's keep that for debugging purposes |
||||||||||||||
| async def async_migrate_entry(hass: HomeAssistant, entry: InPostAirConfigEntry) -> bool: | ||||||||||||||
| """Remove legacy 3-tuple devices left by ≤ 1.4.x.""" | ||||||||||||||
|
||||||||||||||
| """Remove legacy 3-tuple devices left by ≤ 1.4.x.""" | |
| """Remove legacy 3-tuple devices left by ≤ 1.4.x.""" | |
| if entry.version == 2: | |
| return True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this method will be invoked each time we will bump config entry version, not just for 3-tuple ID change. we should revert old comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what happened to the original migration logic? VERSION 2 introduced storage of runtime data in config entry. I don't see logic that updates config_entry to handle that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
version 2 was introduced in 1.5.0
| if entry.version == 1: # 1.5.0 → 1.5.1 | |
| if entry.version == 1: # < 1.5.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wouldn't be easier to just find device with 3-tuple id in registry instead of iterating over all devices? (especially since async_migrate_entry will be invoked for each configured parcel locker).
If there is such device then update it's ID to new format, else delete it
Copilot
AI
Aug 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The string-to-enum conversion logic for disabled_by is duplicated for both old_disabled_by and new_disabled_by. Consider extracting this into a helper function to reduce code duplication.
| new_disabled_by = dr.DeviceEntryDisabler(new_disabled_by) | |
| def _normalize_disabled_by(value): | |
| return dr.DeviceEntryDisabler(value) if isinstance(value, str) else value | |
| old_disabled_by = _normalize_disabled_by(device.disabled_by) | |
| new_disabled_by = _normalize_disabled_by(new_dev.disabled_by) |
Copilot
AI
Aug 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using 'or' operator with DeviceEntryDisabler enums may not work as expected. If old_disabled_by is DeviceEntryDisabler.USER (which is truthy), it will be used correctly. However, if it's None, new_disabled_by will be used. But if old_disabled_by is a falsy enum value like DeviceEntryDisabler.INTEGRATION (if it exists), the logic might not behave as intended. Consider using explicit None checks instead.
| disabled_by=old_disabled_by or new_disabled_by, | |
| disabled_by=old_disabled_by if old_disabled_by is not None else new_disabled_by, |
Copilot
AI
Aug 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The migration function should check if entry.version > 2 and return False for unsupported downgrades, similar to the original implementation that was removed.
Uh oh!
There was an error while loading. Please reload this page.