Keep API responsive under HA events

This commit is contained in:
2026-06-18 12:57:01 +02:00
parent 38a85fce74
commit 149f11a18e
6 changed files with 23 additions and 16 deletions

View File

@@ -2,7 +2,7 @@ FROM python:3.13-slim
WORKDIR /app
ARG SILLYHOME_FUTURE_REF=v2.0.0-alpha.5
ARG SILLYHOME_FUTURE_REF=v2.0.0-alpha.6
RUN python -m pip install --no-cache-dir \
"http://192.168.6.31:3000/Otto/sillyhome-future/archive/${SILLYHOME_FUTURE_REF}.tar.gz"

View File

@@ -1,5 +1,5 @@
name: SillyHome Future
version: "2.0.0-alpha.5"
version: "2.0.0-alpha.6"
slug: sillyhome_future
description: Event-first SillyHome v2 test controller
url: http://192.168.6.31:3000/Otto/sillyhome-future

View File

@@ -49,7 +49,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.5",
version="2.0.0-alpha.6",
lifespan=lifespan,
)
@@ -189,24 +189,31 @@ def _load_initial_ha_states(client: FutureHaClient) -> None:
async def _ha_listener_loop(client: FutureHaClient) -> None:
while True:
runtime = stores.runtime()
runtime.websocket_status = "connecting"
stores.save_runtime(runtime)
await asyncio.to_thread(_set_websocket_status, "connecting")
try:
async for event in client.listen_state_events():
runtime = stores.runtime()
runtime.websocket_status = "connected"
stores.save_runtime(runtime)
event_core.process_state_event(event, execute=_execute_ha_decision)
await asyncio.to_thread(_set_websocket_status, "connected")
await asyncio.to_thread(
event_core.process_state_event,
event,
execute=_execute_ha_decision,
)
await asyncio.sleep(0)
except asyncio.CancelledError:
raise
except Exception as exc:
runtime = stores.runtime()
runtime.websocket_status = f"reconnecting: {exc}"
stores.save_runtime(runtime)
await asyncio.to_thread(_set_websocket_status, f"reconnecting: {exc}")
await asyncio.sleep(2)
def _set_websocket_status(status: str) -> None:
runtime = stores.runtime()
if runtime.websocket_status == status:
return
runtime.websocket_status = status
stores.save_runtime(runtime)
def _execute_ha_decision(decision: object) -> bool:
if ha_client is None or not hasattr(decision, "actuator_entity_id"):
return False

View File

@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "sillyhome-future"
version = "2.0.0-alpha.5"
version = "2.0.0-alpha.6"
description = "SillyHome v2 event-core prototype"
requires-python = ">=3.11"
dependencies = [

View File

@@ -9,7 +9,7 @@ def test_addon_config_declares_future_addon() -> None:
config = yaml.safe_load(Path("addon/config.yaml").read_text(encoding="utf-8"))
assert config["slug"] == "sillyhome_future"
assert config["version"] == "2.0.0-alpha.5"
assert config["version"] == "2.0.0-alpha.6"
assert config["ingress"] is True
assert config["ingress_port"] == 8099
assert config["homeassistant_api"] is True

View File

@@ -15,7 +15,7 @@ def test_health_and_backup_roundtrip(tmp_path, monkeypatch) -> None: # type: ig
assert stores is not None
assert health.status_code == 200
assert health.json()["version"] == "2.0.0-alpha.5"
assert health.json()["version"] == "2.0.0-alpha.6"
assert backup.status_code == 200
assert restore.status_code == 200
assert restore.json() == {"status": "restored"}