257 files

This commit is contained in:
Home Assistant Version Control
2026-10-02 16:06:24 +00:00
parent 7c55603942
commit c29f5cc088
258 changed files with 24621 additions and 3136 deletions
@@ -40,6 +40,7 @@ from .entity.entity_base import MaintenanceEntity
from .entity.summary_coordinator import MaintenanceSummaryCoordinator
from .entity.triggers import BaseTrigger, create_triggers, normalize_entity_ids
from .helpers.aggregate import object_slug as aggregate_object_slug
from .helpers.coordinator_data import has_coordinator_data
from .helpers.dates import parse_hhmm
from .helpers.global_options import is_schedule_time_enabled
from .helpers.pause import is_task_inert
@@ -92,6 +93,13 @@ async def async_setup_entry(
# need replacing now — the aggregate that backs the single fleet task.
entities.append(BatteryFleetLowSensor(hass))
async_add_entities(entities)
# #191: maintenance cost per Home Assistant area (added as areas
# appear) — they follow the summary coordinator's refreshes.
if summary is not None:
from .entity.area_cost import AreaCostSensorManager
manager = AreaCostSensorManager(hass, entry.entry_id, async_add_entities)
entry.async_on_unload(manager.async_start(summary))
return
runtime_data = entry.runtime_data
@@ -288,6 +296,8 @@ class MaintenanceSensor(MaintenanceEntity, SensorEntity):
attrs["trigger_target_changes"] = trigger_config.get("trigger_target_changes")
elif ttype == "runtime":
attrs["trigger_runtime_hours"] = trigger_config.get("trigger_runtime_hours")
elif ttype == "due_date":
attrs["trigger_days_before"] = trigger_config.get("trigger_days_before", 0)
elif ttype == "compound":
attrs["compound_logic"] = trigger_config.get("compound_logic", "AND")
conditions = trigger_config.get("conditions", [])
@@ -334,11 +344,7 @@ class MaintenanceSensor(MaintenanceEntity, SensorEntity):
# Use merged data (static config + Store runtime) so that persisted
# trigger state (_trigger_state) survives HA restarts.
static_task = self.coordinator.entry.data.get(CONF_TASKS, {}).get(self._task_id, {})
store = self.coordinator._store
if store is not None:
task_data = store.merge_task_data(self._task_id, static_task)
else:
task_data = static_task
task_data = self.coordinator._store.merge_task_data(self._task_id, static_task)
trigger_config = task_data.get("trigger_config")
# Listen for task reset signals (completion/skip/reset) —
@@ -450,7 +456,7 @@ class MaintenanceSensor(MaintenanceEntity, SensorEntity):
"any" a sibling still holds the task, with "all" the task may never
have been triggered (bug audit 2026-09-26, SCH-5).
"""
if self.coordinator.data is None:
if not has_coordinator_data(self.coordinator):
# No read model yet: nothing to aggregate against — a deactivation
# keeps the historical per-entity meaning.
return not is_triggered