184 files
This commit is contained in:
1 parent
7b47edbf8d
commit
0c64e47969
184 files changed
+9608
-11572
No files matched your search
@@ -492,6 +492,35 @@ async def _reconcile_fleet_task(hass: HomeAssistant, entry: ConfigEntry, lang: s
|
||||
return True
|
||||
|
||||
|
||||
def _heal_fleet_trigger_recovery_flag(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""#156: fleet tasks minted before ``auto_complete_on_recovery`` joined
|
||||
the canonical trigger keep showing Triggered after the batteries were
|
||||
swapped — the low count drops to 0 but nothing records the completion,
|
||||
and ``fleet_task_trigger_ok`` (type+entity only) never repairs it. Add
|
||||
the missing flag, and ONLY the flag: a deliberately edited threshold or
|
||||
entity list stays untouched. Runs at every start, so restored backups
|
||||
from old exports heal too.
|
||||
"""
|
||||
found = find_fleet_task(entry)
|
||||
if found is None:
|
||||
return False
|
||||
task_id, task_data = found
|
||||
tc = task_data.get("trigger_config") or {}
|
||||
eids = tc.get("entity_ids") or ([tc["entity_id"]] if tc.get("entity_id") else [])
|
||||
if tc.get("type") != "threshold" or LOW_COUNT_ENTITY_ID not in eids:
|
||||
return False
|
||||
if tc.get("auto_complete_on_recovery"):
|
||||
return False
|
||||
new_task = dict(task_data)
|
||||
new_task["trigger_config"] = {**tc, "auto_complete_on_recovery": True}
|
||||
new_data = dict(entry.data)
|
||||
new_tasks = dict(new_data.get(CONF_TASKS, {}))
|
||||
new_tasks[task_id] = new_task
|
||||
new_data[CONF_TASKS] = new_tasks
|
||||
hass.config_entries.async_update_entry(entry, data=new_data)
|
||||
return True
|
||||
|
||||
|
||||
async def reconcile_fleet_parts_at_start(hass: HomeAssistant, entry: ConfigEntry, lang: str) -> dict[str, Any]:
|
||||
"""Boot-time reconcile of the fleet's type-parts (issue #148).
|
||||
|
||||
@@ -505,6 +534,8 @@ async def reconcile_fleet_parts_at_start(hass: HomeAssistant, entry: ConfigEntry
|
||||
product/vendor data, auto-buy off); the moment a user touched it, it
|
||||
is theirs and stays.
|
||||
"""
|
||||
trigger_healed = _heal_fleet_trigger_recovery_flag(hass, entry)
|
||||
|
||||
types = discover_battery_types(hass)
|
||||
added = _reconcile_type_parts(hass, entry, types, lang)
|
||||
|
||||
@@ -530,12 +561,34 @@ async def reconcile_fleet_parts_at_start(hass: HomeAssistant, entry: ConfigEntry
|
||||
new_data[CONF_PARTS] = parts
|
||||
hass.config_entries.async_update_entry(entry, data=new_data)
|
||||
pruned = True
|
||||
if store is not None:
|
||||
store.remove_part("batt_unknown")
|
||||
|
||||
# #148 follow-up (v2.70.0 aftermath): the prune must not leave the
|
||||
# part's stock sensor behind as an unavailable orphan in the entity
|
||||
# registry — the official ws_delete_part removes that entry, the v2.70.0
|
||||
# prune did not, and HA greys out Delete while the integration still
|
||||
# claims the entity. Sweep every part-stock registry entry whose part no
|
||||
# longer exists; this also heals installs where the v2.70.0 prune
|
||||
# already ran (the part is gone, only the registry corpse remains).
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
ent_reg = er.async_get(hass)
|
||||
orphans_removed = 0
|
||||
for reg_entry in er.async_entries_for_config_entry(ent_reg, entry.entry_id):
|
||||
uid = reg_entry.unique_id or ""
|
||||
if "_part_" not in uid:
|
||||
continue
|
||||
pid = uid.split("_part_", 1)[1]
|
||||
if pid and pid not in parts:
|
||||
ent_reg.async_remove(reg_entry.entity_id)
|
||||
orphans_removed += 1
|
||||
|
||||
if store is not None and (added or pruned):
|
||||
for pid in added:
|
||||
store.set_part_stock(pid, 0)
|
||||
await store.async_save()
|
||||
return {"added": added, "pruned": pruned}
|
||||
return {"added": added, "pruned": pruned, "orphans_removed": orphans_removed, "trigger_healed": trigger_healed}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user