78 lines
2.2 KiB
Python
78 lines
2.2 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime, timezone
|
|
|
|
from app.ha.client import HaClient, HaClientSettings
|
|
from app.ha.reader import HaReader
|
|
|
|
|
|
class FakeHaClient(HaClient):
|
|
def __init__(self) -> None:
|
|
super().__init__(HaClientSettings(url="http://test", token="token"))
|
|
|
|
def list_entities(self) -> list[dict[str, object]]:
|
|
return [
|
|
{
|
|
"entity_id": "sensor.temperature",
|
|
"state": "21.5",
|
|
"attributes": {
|
|
"state_class": "measurement",
|
|
"device_class": "temperature",
|
|
"unit_of_measurement": "°C",
|
|
},
|
|
},
|
|
{
|
|
"entity_id": "light.living_room",
|
|
"state": "on",
|
|
"attributes": {},
|
|
},
|
|
]
|
|
|
|
def get_history(
|
|
self,
|
|
entity_ids: list[str],
|
|
start_time: datetime,
|
|
end_time: datetime,
|
|
) -> list[object]:
|
|
return [
|
|
[
|
|
{
|
|
"entity_id": entity_ids[0],
|
|
"state": "21.5",
|
|
"last_changed": start_time.isoformat(),
|
|
}
|
|
]
|
|
]
|
|
|
|
|
|
def test_ha_reader_returns_summaries() -> None:
|
|
reader = HaReader(FakeHaClient())
|
|
summaries = reader.read_entities()
|
|
assert len(summaries) == 2
|
|
domains = {summary.domain for summary in summaries}
|
|
assert domains == {"sensor", "light"}
|
|
sensor = next(item for item in summaries if item.entity_id == "sensor.temperature")
|
|
assert sensor.unit_of_measurement == "°C"
|
|
|
|
|
|
def test_ha_reader_discovers_learnable_sensors() -> None:
|
|
reader = HaReader(FakeHaClient())
|
|
|
|
discovered = reader.discover(learnable=True)
|
|
|
|
assert [entity.entity_id for entity in discovered] == ["sensor.temperature"]
|
|
|
|
|
|
def test_ha_reader_normalizes_history() -> None:
|
|
reader = HaReader(FakeHaClient())
|
|
start = datetime(2026, 6, 1, tzinfo=timezone.utc)
|
|
|
|
history = reader.read_history(
|
|
["sensor.temperature"],
|
|
start,
|
|
datetime(2026, 6, 2, tzinfo=timezone.utc),
|
|
)
|
|
|
|
assert history[0].entity_id == "sensor.temperature"
|
|
assert history[0].points[0].value == 21.5
|