feat: event-basierte Vorhersage via HA-WebSocket\n\n- Entfernt periodisches Prediction-Intervall (60s)\n- Fügt WebSocket-Listener hinzu, der bei jedem State Change sofort evaluiert\n- BehaviorEngine.handle_state_change() identifiziert betroffene Aktoren und löst evaluate() aus\n- Fallback periodische Vorhersage bleibt als Backup\n- pyproject: websockets dependency\n- tests: test_main.py für Event-Listener\n\nCloses #39
This commit is contained in:
@@ -608,6 +608,35 @@ class BehaviorEngine:
|
||||
)
|
||||
return self._store.upsert(updated)
|
||||
|
||||
def handle_state_change(self, entity_id: str, new_state: dict[str, object] | None) -> None:
|
||||
"""Wird bei jedem HA-State-Change aufgerufen und löst sofortige Vorhersage aus.
|
||||
|
||||
- Wenn entity_id ein Aktor ist: evaluate() direkt.
|
||||
- Wenn entity_id ein Kontext-Entity ist: alle betroffenen Aktoren evaluieren.
|
||||
"""
|
||||
# Aktor direkt evaluieren
|
||||
for record in self._store.list():
|
||||
if record.actuator_entity_id == entity_id:
|
||||
try:
|
||||
self.evaluate(record.actuator_entity_id)
|
||||
except Exception:
|
||||
logger.exception("Event-basierte Vorhersage fehlgeschlagen für %s", record.actuator_entity_id)
|
||||
return
|
||||
# Kontext-Entity: alle Aktoren finden, die diesen Kontext nutzen
|
||||
affected_actuators = [
|
||||
record.actuator_entity_id
|
||||
for record in self._store.list()
|
||||
if (
|
||||
record.assignment.selected_numeric_entity_id == entity_id
|
||||
or entity_id in record.assignment.selected_context_entity_ids
|
||||
)
|
||||
]
|
||||
for actuator_entity_id in affected_actuators:
|
||||
try:
|
||||
self.evaluate(actuator_entity_id)
|
||||
except Exception:
|
||||
logger.exception("Event-basierte Vorhersage fehlgeschlagen für %s", actuator_entity_id)
|
||||
|
||||
|
||||
def predict_behavior(
|
||||
patterns: list[BehaviorPattern],
|
||||
|
||||
Reference in New Issue
Block a user