Compare commits

..

1 Commits

Author SHA1 Message Date
787516ac67 Avoid per-request discovery classification in dashboard
Some checks failed
quality / test (3.11) (push) Has been cancelled
quality / test (3.13) (push) Has been cancelled
2026-06-17 01:19:59 +02:00

View File

@@ -208,7 +208,11 @@ def context_options(
@router.get("/summary", response_model=list[ActuatorSummary])
def list_configured_summary(request: Request) -> list[ActuatorSummary]:
entity_map = {entity.entity_id: entity for entity in _load_cached_entities(request)}
records = _service(request).list_configured()
entity_map = _load_cached_entity_map(
request,
{record.actuator_entity_id for record in records},
)
return [
ActuatorSummary(
actuator_entity_id=record.actuator_entity_id,
@@ -247,7 +251,7 @@ def list_configured_summary(request: Request) -> list[ActuatorSummary]:
),
updated_at=record.updated_at.isoformat(),
)
for record in _service(request).list_configured()
for record in records
]
@@ -259,16 +263,12 @@ def dashboard_overview(request: Request) -> DashboardOverview:
raw_entities = []
raw_updated_at = cache_payload.get("updated_at")
updated_at = raw_updated_at if isinstance(raw_updated_at, str) else None
cached_entities = [
HaEntitySummary.model_validate(entity)
for entity in raw_entities
if isinstance(entity, dict)
]
discovered = discover_entities(cached_entities) if cached_entities else []
group_counts: dict[tuple[str, str], int] = {}
for entity in discovered:
key = (entity.category, entity.role.value)
group_counts[key] = group_counts.get(key, 0) + 1
raw_groups = cache_payload.get("discovery_groups", [])
cached_groups = [
DashboardDiscoveryGroup.model_validate(group)
for group in raw_groups
if isinstance(group, dict)
] if isinstance(raw_groups, list) else []
reconciliation = _reconciliation_state_or_default(request)
ws_status = getattr(request.app.state, "ws_status", None)
actuators = list_configured_summary(request)
@@ -286,15 +286,12 @@ def dashboard_overview(request: Request) -> DashboardOverview:
review_required=reconciliation.review_required,
),
cache=EntityCacheStatus(
available=bool(cached_entities),
available=bool(raw_entities),
updated_at=updated_at,
entity_count=len(cached_entities),
entity_count=len(raw_entities),
),
actuators=actuators,
discovery_groups=[
DashboardDiscoveryGroup(category=category, role=role, count=count)
for (category, role), count in sorted(group_counts.items())
],
discovery_groups=cached_groups,
)
@@ -521,6 +518,30 @@ def _load_cached_entities(request: Request) -> list[HaEntitySummary]:
return []
def _load_cached_entity_map(
request: Request,
entity_ids: set[str],
) -> dict[str, HaEntitySummary]:
if not entity_ids:
return {}
payload = _load_entity_cache_payload(request)
raw_entities = payload.get("entities", [])
if not isinstance(raw_entities, list):
return {}
result: dict[str, HaEntitySummary] = {}
for raw_entity in raw_entities:
if not isinstance(raw_entity, dict):
continue
entity_id = raw_entity.get("entity_id")
if not isinstance(entity_id, str) or entity_id not in entity_ids:
continue
try:
result[entity_id] = HaEntitySummary.model_validate(raw_entity)
except ValueError:
continue
return result
def _load_entity_cache_payload(request: Request) -> dict[str, object]:
path = _entity_cache_path(request)
if not path.exists():
@@ -535,8 +556,16 @@ def _load_entity_cache_payload(request: Request) -> dict[str, object]:
def _save_cached_entities(request: Request, entities: list[HaEntitySummary]) -> None:
path = _entity_cache_path(request)
path.parent.mkdir(parents=True, exist_ok=True)
group_counts: dict[tuple[str, str], int] = {}
for entity in discover_entities(entities):
key = (entity.category, entity.role.value)
group_counts[key] = group_counts.get(key, 0) + 1
payload = {
"updated_at": datetime.now(timezone.utc).isoformat(),
"discovery_groups": [
{"category": category, "role": role, "count": count}
for (category, role), count in sorted(group_counts.items())
],
"entities": [entity.model_dump(mode="json") for entity in entities],
}
temporary = path.with_suffix(".json.tmp")