Bläddra i källkod

Expose per-service check results and services list via API status sensor

- Flatten checks dict into top-level state attributes on ApiStatusSensor
- Add services field to ApiStatusData; fetch from /services endpoint
- Fetch /status and /services in parallel via asyncio.gather in coordinator
ZiB 4 månader sedan
förälder
incheckning
3c4ee25845

+ 14 - 0
custom_components/room_cal_ha/backends/api.py

@@ -93,6 +93,20 @@ class RoomCalApiBackend(ReservationBackend):
       stale=stale,
       stale=stale,
     )
     )
 
 
+  async def async_fetch_services(self) -> dict[str, str]:
+    session = async_get_clientsession(self._hass)
+    url = f"{self._base_url()}/services"
+    try:
+      async with session.get(url, headers=self._headers()) as resp:
+        if resp.status in (401, 403):
+          return {}
+        resp.raise_for_status()
+        body = await resp.json()
+        return body if isinstance(body, dict) else {}
+    except Exception as exc:
+      _LOGGER.debug("Failed to fetch API services: %s", exc)
+      return {}
+
 
 
 def _parse_reservation(data: dict | None) -> ReservationData | None:
 def _parse_reservation(data: dict | None) -> ReservationData | None:
   if data is None:
   if data is None:

+ 6 - 1
custom_components/room_cal_ha/coordinator.py

@@ -1,5 +1,6 @@
 from __future__ import annotations
 from __future__ import annotations
 
 
+import asyncio
 import logging
 import logging
 from dataclasses import dataclass
 from dataclasses import dataclass
 from datetime import datetime, timedelta
 from datetime import datetime, timedelta
@@ -89,7 +90,11 @@ class RoomCalCoordinator(DataUpdateCoordinator[CoordinatorData]):
         raise UpdateFailed("API authorization failed; re-auth required")
         raise UpdateFailed("API authorization failed; re-auth required")
       except BackendConnectError as exc:
       except BackendConnectError as exc:
         _LOGGER.warning("API fetch failed, using cached data: %s", exc)
         _LOGGER.warning("API fetch failed, using cached data: %s", exc)
-      api_status = await api_backend.async_fetch_status()
+      api_status, services = await asyncio.gather(
+        api_backend.async_fetch_status(),
+        api_backend.async_fetch_services(),
+      )
+      api_status.services = services
 
 
     now = dt_util.utcnow()
     now = dt_util.utcnow()
 
 

+ 1 - 0
custom_components/room_cal_ha/models.py

@@ -11,6 +11,7 @@ class ApiStatusData:
   checks: dict = field(default_factory=dict)
   checks: dict = field(default_factory=dict)
   checked_at: datetime | None = None
   checked_at: datetime | None = None
   stale: bool = False
   stale: bool = False
+  services: dict = field(default_factory=dict)
 
 
 
 
 @dataclass
 @dataclass

+ 4 - 1
custom_components/room_cal_ha/sensor.py

@@ -233,9 +233,12 @@ class ApiStatusSensor(CoordinatorEntity[RoomCalCoordinator], SensorEntity):
     s = self._status()
     s = self._status()
     if s is None:
     if s is None:
       return None
       return None
-    attrs: dict = {"checks": s.checks, "stale": s.stale}
+    attrs: dict = {"stale": s.stale}
     if s.checked_at is not None:
     if s.checked_at is not None:
       attrs["checked_at"] = s.checked_at.isoformat()
       attrs["checked_at"] = s.checked_at.isoformat()
+    attrs.update(s.checks)
+    if s.services:
+      attrs["services"] = s.services
     return attrs
     return attrs