Bootstrap SillyHome Future v2 core
This commit is contained in:
93
tests/test_future_core.py
Normal file
93
tests/test_future_core.py
Normal file
@@ -0,0 +1,93 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from app.core.event_core import EventCore
|
||||
from app.core.handoff import HandoffMatrix
|
||||
from app.core.models import (
|
||||
BehaviorPatternV2,
|
||||
ControlProfile,
|
||||
EntityState,
|
||||
HandoffMode,
|
||||
LearningProfile,
|
||||
LearningState,
|
||||
RuntimeState,
|
||||
SafetyStage,
|
||||
StateEvent,
|
||||
)
|
||||
from app.core.stores import FutureStores
|
||||
|
||||
|
||||
def test_event_core_routes_state_event_to_decision(tmp_path: Path) -> None:
|
||||
stores = FutureStores(tmp_path)
|
||||
stores.save_runtime(
|
||||
RuntimeState(
|
||||
entities={
|
||||
"light.storage": EntityState(
|
||||
entity_id="light.storage",
|
||||
domain="light",
|
||||
state="off",
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
stores.save_learning(
|
||||
LearningState(
|
||||
profiles={
|
||||
"light.storage": LearningProfile(
|
||||
actuator_entity_id="light.storage",
|
||||
patterns=[
|
||||
BehaviorPatternV2(
|
||||
actuator_entity_id="light.storage",
|
||||
target_state="on",
|
||||
trigger_entity_id="binary_sensor.storage_door",
|
||||
trigger_state="on",
|
||||
support=3,
|
||||
confidence=0.95,
|
||||
)
|
||||
],
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
stores.save_control(
|
||||
stores.control().model_copy(
|
||||
update={
|
||||
"profiles": {
|
||||
"light.storage": ControlProfile(
|
||||
actuator_entity_id="light.storage",
|
||||
stage=SafetyStage.DRY_RUN,
|
||||
min_confidence=0.8,
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
core = EventCore(stores)
|
||||
|
||||
audit = core.process_state_event(
|
||||
StateEvent(entity_id="binary_sensor.storage_door", new_state="on")
|
||||
)
|
||||
|
||||
decisions = [item for item in audit if item.kind == "decision"]
|
||||
assert decisions
|
||||
assert decisions[0].decision is not None
|
||||
assert decisions[0].decision.target_state == "on"
|
||||
assert decisions[0].decision.allowed is True
|
||||
assert decisions[0].decision.dry_run is True
|
||||
|
||||
|
||||
def test_handoff_matrix_detects_conflict_and_rollback() -> None:
|
||||
matrix = HandoffMatrix()
|
||||
profile = ControlProfile(
|
||||
actuator_entity_id="light.storage",
|
||||
handoff_mode=HandoffMode.CONTROLLED,
|
||||
related_automation_ids=["automation.storage"],
|
||||
)
|
||||
|
||||
assert matrix.classify(profile) is HandoffMode.CONFLICT
|
||||
controlled = matrix.assume_control(profile)
|
||||
assert controlled.paused_automation_ids == ["automation.storage"]
|
||||
rolled_back = matrix.rollback(controlled)
|
||||
assert rolled_back.handoff_mode is HandoffMode.ROLLBACK
|
||||
assert rolled_back.paused_automation_ids == []
|
||||
Reference in New Issue
Block a user