124 files

This commit is contained in:
Home Assistant Version Control
2026-08-31 15:02:40 +00:00
parent 33de328a33
commit 9742f385a3
124 changed files with 13907 additions and 1376 deletions
@@ -1147,7 +1147,7 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
rotation tasks that were configured without an initial assignee — those
were invisible to every user filter until their first completion.
"""
if entry.version > 1 or entry.minor_version >= 5:
if entry.version > 1 or entry.minor_version >= 6:
return True
is_object_entry = entry.unique_id != GLOBAL_UNIQUE_ID
@@ -1225,7 +1225,28 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
shed_owned_devices(hass, own_entry_id=entry.entry_id, source_device_id=device_id)
minor = 5
hass.config_entries.async_update_entry(entry, data=data, minor_version=minor)
# 5 → 6 (#145): task rows show Complete / Skip as HA buttons instead of
# bare icons. An EXISTING install gets a one-time panel notice with a
# "back to icons" button (the flag lives in the hub entry's options and
# is cleared by that banner); a fresh install starts at minor 6 and
# never sees it.
new_options: dict[str, Any] | None = None
if minor < 6:
if not is_object_entry:
from .const import CONF_ROW_ACTION_NOTICE
# Older installs keep their settings in entry.data with EMPTY
# options (every reader uses `entry.options or entry.data`); the
# first options write must carry them over, or the flag alone
# would mask every setting.
base = dict(entry.options) if entry.options else dict(entry.data)
new_options = {**base, CONF_ROW_ACTION_NOTICE: True}
minor = 6
if new_options is not None:
hass.config_entries.async_update_entry(entry, data=data, options=new_options, minor_version=minor)
else:
hass.config_entries.async_update_entry(entry, data=data, minor_version=minor)
_LOGGER.info("Migrated entry %s to minor_version %s", entry.entry_id, minor)
return True
@@ -1445,6 +1466,33 @@ async def async_setup_entry(hass: HomeAssistant, entry: MaintenanceSupporterConf
entry.runtime_data = MaintenanceSupporterData(coordinator=coordinator, store=store)
await coordinator.async_config_entry_first_refresh()
# #148: a battery type that becomes known only after fleet setup (a
# Battery Notes note added later, a typed low-only Matter binary)
# never got its spare part — reconcile once per start, after the
# other integrations' entities exist. Also prunes the legacy
# untouched "UNKNOWN battery" part older versions minted. Registered
# AFTER runtime_data: on a running instance async_at_started fires
# immediately, and the reconcile needs the store for stock/prune.
if obj_data.get(BATTERY_FLEET_OBJECT_FLAG):
async def _fleet_parts_at_start(_hass: HomeAssistant) -> None:
from .helpers.battery_fleet_setup import reconcile_fleet_parts_at_start
from .helpers.i18n import normalize_language
try:
result = await reconcile_fleet_parts_at_start(hass, entry, normalize_language(hass))
except Exception:
_LOGGER.exception("Battery-fleet part reconcile at start failed")
return
if result["added"] or result["pruned"]:
_LOGGER.info(
"Battery-fleet parts reconciled at start: added %s, pruned legacy UNKNOWN: %s",
result["added"] or "none",
result["pruned"],
)
entry.async_on_unload(async_at_started(hass, _fleet_parts_at_start))
# v1.5.3 (#48): forward-sync obj fields → device_registry whenever the
# entry data changes (WS update OR config-flow re-edit). DeviceInfo
# only seeds these on first device creation; after that, dashboard