Merge branch 'feature/ha-adapter' into feature/ha-api-integration
This commit is contained in:
33
app/ha/client.py
Normal file
33
app/ha/client.py
Normal file
@@ -0,0 +1,33 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
|
||||
import requests
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class HaClientSettings:
|
||||
url: str
|
||||
token: str
|
||||
timeout_seconds: int = 10
|
||||
|
||||
|
||||
class HaClient:
|
||||
def __init__(self, settings: HaClientSettings) -> None:
|
||||
self._settings = settings
|
||||
self._session = requests.Session()
|
||||
self._session.headers.update({
|
||||
"Authorization": f"Bearer {settings.token}",
|
||||
"Content-Type": "application/json",
|
||||
})
|
||||
|
||||
def list_entities(self) -> list[dict[str, object]]:
|
||||
response = self._session.get(
|
||||
f"{self._settings.url}/api/states",
|
||||
timeout=self._settings.timeout_seconds,
|
||||
)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
19
app/ha/models.py
Normal file
19
app/ha/models.py
Normal file
@@ -0,0 +1,19 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class HaState(BaseModel):
|
||||
entity_id: str
|
||||
state: str
|
||||
attributes: dict[str, object] | None = None
|
||||
last_changed: str | None = None
|
||||
last_updated: str | None = None
|
||||
|
||||
|
||||
class HaEntitySummary(BaseModel):
|
||||
entity_id: str
|
||||
domain: str
|
||||
state_class: str | None = None
|
||||
device_class: str | None = None
|
||||
unit_of_measurement: str | None = None
|
||||
31
app/ha/reader.py
Normal file
31
app/ha/reader.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
from app.ha.client import HaClient
|
||||
from app.ha.models import HaEntitySummary, HaState
|
||||
|
||||
|
||||
class HaReader:
|
||||
def __init__(self, client: HaClient) -> None:
|
||||
self._client = client
|
||||
|
||||
def read_entities(self) -> Sequence[HaEntitySummary]:
|
||||
entities = self._client.list_entities()
|
||||
summaries: list[HaEntitySummary] = []
|
||||
for item in entities:
|
||||
entity_id = item.get("entity_id", "")
|
||||
if "." not in entity_id:
|
||||
continue
|
||||
domain = entity_id.split(".", 1)[0]
|
||||
attributes = item.get("attributes") or {}
|
||||
summaries.append(
|
||||
HaEntitySummary(
|
||||
entity_id=entity_id,
|
||||
domain=domain,
|
||||
state_class=str(attributes.get("state_class") or ""),
|
||||
device_class=str(attributes.get("device_class") or ""),
|
||||
unit_of_measurement=str(attributes.get("unit_of_measurement") or ""),
|
||||
)
|
||||
)
|
||||
return summaries
|
||||
Reference in New Issue
Block a user