Filter autopilot actuator candidates

This commit is contained in:
2026-06-18 18:43:53 +02:00
parent 8057751c11
commit bf832b49f4
6 changed files with 46 additions and 9 deletions

View File

@@ -155,7 +155,7 @@ async def lifespan(app: FastAPI) -> AsyncIterator[None]:
app = FastAPI(
title="SillyHome Future API",
description="SillyHome v2 event-core side project.",
version="2.0.0-alpha.14",
version="2.0.0-alpha.15",
lifespan=lifespan,
)
@@ -199,7 +199,7 @@ def dashboard_data() -> dict[str, object]:
actuator_entities = [
entity
for entity in runtime.entities.values()
if entity.domain in {"light", "switch", "fan", "cover", "humidifier"}
if _is_good_actuator(entity.entity_id, entity.friendly_name)
]
return {
"websocket_status": runtime.websocket_status,
@@ -954,7 +954,8 @@ def _run_autopilot_once() -> AutopilotRunResult:
learning.candidates = {
candidate_id: candidate
for candidate_id, candidate in learning.candidates.items()
if _is_good_trigger_id(candidate.trigger_entity_id)
if _is_good_actuator(candidate.actuator_entity_id, None)
and _is_good_trigger_id(candidate.trigger_entity_id)
}
candidates = _generate_candidates(settings)
for candidate in candidates:
@@ -974,7 +975,7 @@ def _generate_candidates(settings: AutopilotSettings) -> list[CandidateRecommend
actuators = [
entity
for entity in runtime.entities.values()
if entity.domain in {"light", "switch", "fan", "cover", "humidifier"}
if _is_good_actuator(entity.entity_id, entity.friendly_name)
][:150]
triggers = [
entity
@@ -1056,6 +1057,32 @@ def _is_good_trigger_id(entity_id: str) -> bool:
return not any(token in raw for token in bad) and any(token in raw for token in good)
def _is_good_actuator(entity_id: str, friendly_name: str | None) -> bool:
domain = entity_id.split(".", 1)[0]
if domain not in {"light", "switch", "fan", "cover", "humidifier"}:
return False
if domain != "switch":
return True
raw = f"{entity_id} {friendly_name or ''}".lower()
bad = {
"alarm",
"battery",
"batterie",
"detection",
"linkquality",
"low",
"motion",
"occupancy",
"people",
"presence",
"problem",
"tamper",
"trigger",
"update",
}
return not any(token in raw for token in bad)
def _entity_tokens(entity: EntityState) -> set[str]:
raw = f"{entity.entity_id} {entity.friendly_name or ''}".lower()
return {part for part in raw.replace(".", "_").split("_") if len(part) >= 4}