homelab-codex-ws/services/ha-diag-agent/src/ha_diag/checks/heartbeat.py
Oskar Kapala ab8895d28b feat(ha-diag-agent): scaffold service with HA REST client and event emitter
- new per-host service, follows node-agent pattern
- 7 new HA event types defined (routing in supervisor — Phase 5)
- HeartbeatCheck as pipeline validator (pings /api/, emits ha_websocket_dead)
- service.yaml + host configs for piha (ken) and chelsty-infra (chelsty)
- test scaffolding with aiohttp/aiosqlite mocks (15/15 passing)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 12:26:34 +02:00

48 lines
1.6 KiB
Python

from __future__ import annotations
from ..ha_client import HAClient
from ..models import CheckResult, HAEventType, Severity
from .base import Check
class HeartbeatCheck(Check):
"""Pings HA /api/ to verify the API is reachable.
Validates the end-to-end pipeline: HA client → check result → event emitter.
Real diagnostic checks (entity availability, system health, etc.) come in Phase 3.
"""
name = "heartbeat"
def __init__(self, ha_client: HAClient) -> None:
self._client = ha_client
async def run(self) -> CheckResult:
try:
async with self._client:
data = await self._client.get_api_status()
if isinstance(data, dict) and "message" in data:
return CheckResult(
healthy=True,
event_type=None,
severity=Severity.info,
message="HA API reachable",
payload={"response": data},
)
return CheckResult(
healthy=False,
event_type=HAEventType.ha_websocket_dead,
severity=Severity.error,
message=f"HA API returned unexpected response: {data!r}",
payload={"response": str(data)},
)
except Exception as exc:
return CheckResult(
healthy=False,
event_type=HAEventType.ha_websocket_dead,
severity=Severity.error,
message=f"HA API unreachable: {exc}",
payload={"error": str(exc)},
)