M8-R15: fix HA discovery identities and thermal totals
frontend / frontend (push) Successful in 47s
pytest / test (push) Successful in 4m1s
docker-image / build-and-push (push) Successful in 1m38s

This commit is contained in:
2026-08-28 01:20:52 +02:00
parent 8180082f90
commit 018f13d73d
13 changed files with 1284 additions and 136 deletions
+84
View File
@@ -111,3 +111,87 @@ def test_homeassistant_client_raises_on_invalid_arguments() -> None:
with pytest.raises(ValueError, match="webhook_id"):
client.trigger_webhook(webhook_id="", body={})
def test_discovery_registry_bindings_reads_entity_and_device_registry(monkeypatch: pytest.MonkeyPatch) -> None:
"""The repair confirmation reads HA's authoritative registry bindings."""
sent: list[dict] = []
class _Socket:
replies = iter((
'{"type":"auth_required"}',
'{"type":"auth_ok"}',
'{"id":1,"success":true,"result":[{"platform":"mqtt","unique_id":"u1","device_id":"d1"}]}',
'{"id":2,"success":true,"result":[{"id":"d1","identifiers":[["mqtt","home-automation:meter:m1"]]}]}',
))
def __enter__(self):
return self
def __exit__(self, *_args):
return None
def recv(self, *, timeout=None):
assert timeout is not None
assert timeout <= 1.5
return next(self.replies)
def send(self, payload):
sent.append(json.loads(payload))
monkeypatch.setattr("app.integrations.homeassistant.connect", lambda *_args, **_kwargs: _Socket())
bindings = HomeAssistantClient(_configured_settings()).discovery_registry_bindings({"u1", "missing"})
assert bindings == {"u1": {"home-automation:meter:m1"}}
assert [message.get("type") for message in sent] == [
"auth", "config/entity_registry/list", "config/device_registry/list"
]
def test_discovery_registry_bindings_uses_one_deadline_and_ignores_non_mqtt_identifiers(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""Only official ["mqtt", value] pairs participate in repair matching."""
received_timeouts: list[float] = []
class _Socket:
replies = iter((
'{"type":"auth_required"}',
'{"type":"auth_ok"}',
'{"id":1,"success":true,"result":['
'{"platform":"mqtt","unique_id":"u1","device_id":"d1"},'
'{"platform":"mqtt","unique_id":"u2","device_id":"d2"},'
'{"platform":"mqtt","unique_id":"u3","device_id":"d3"}]}',
'{"id":2,"success":true,"result":['
'{"id":"d1","identifiers":[["mqtt","expected"],["esphome","aux"]]},'
'{"id":"d2","identifiers":[["esphome","expected"],"expected",["mqtt",3],[]]},'
'{"id":"d3","identifiers":[["mqtt","expected"],["mqtt","old"]]}]}',
))
def __enter__(self): return self
def __exit__(self, *_args): return None
def send(self, _payload): return None
def recv(self, *, timeout=None):
received_timeouts.append(timeout)
return next(self.replies)
monkeypatch.setattr("app.integrations.homeassistant.connect", lambda *_args, **_kwargs: _Socket())
bindings = HomeAssistantClient(_configured_settings()).discovery_registry_bindings({"u1", "u2", "u3"})
assert bindings == {"u1": {"expected"}, "u2": set(), "u3": {"expected", "old"}}
assert len(received_timeouts) == 4
assert all(timeout is not None and 0 < timeout <= 1.5 for timeout in received_timeouts)
def test_discovery_registry_bindings_silent_socket_times_out(monkeypatch: pytest.MonkeyPatch) -> None:
class _Socket:
def __enter__(self): return self
def __exit__(self, *_args): return None
def send(self, _payload): return None
def recv(self, *, timeout=None):
assert timeout is not None and timeout > 0
raise TimeoutError("silent")
monkeypatch.setattr("app.integrations.homeassistant.connect", lambda *_args, **_kwargs: _Socket())
with pytest.raises(HomeAssistantRequestError, match="registry query failed"):
HomeAssistantClient(_configured_settings()).discovery_registry_bindings({"u1"})