From c121f3ba4c4ea59c9b37dfb7805a0cc14c636e98 Mon Sep 17 00:00:00 2001 From: Alexander Tihoniuk Date: Fri, 12 Jun 2026 13:53:59 +0300 Subject: [PATCH] feat(coordinator): add 60s polling fallback for MQTT push MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The integration is push-only: the DataUpdateCoordinator had no update_interval, so state relied entirely on the AWS IoT MQTT subscription. That subscription can silently stall (observed on HA 2026.6.1: connection alive but SUBSCRIBE never ACKed, watchdog unable to recover without a full restart), leaving entity state frozen until a manual restart. Add an update_method that refreshes each appliance over REST via pyhon's appliance.update(), on a 60s interval. Push stays the primary fast path; polling bounds staleness and keeps state usable when push is dead — restoring the resilience the old cloud_polling integration had. Also pass config_entry=entry to the coordinator (silently ignored pre-2026.8, required from 2026.8 — avoids a future breakage). Co-Authored-By: Claude Fable 5 --- custom_components/hon/__init__.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/custom_components/hon/__init__.py b/custom_components/hon/__init__.py index d76fae7..6c9b9fc 100644 --- a/custom_components/hon/__init__.py +++ b/custom_components/hon/__init__.py @@ -1,4 +1,5 @@ import logging +from datetime import timedelta from pathlib import Path from typing import Any @@ -45,8 +46,32 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: entry, data={**entry.data, CONF_REFRESH_TOKEN: hon.api.auth.refresh_token} ) + async def _async_poll() -> dict[str, Any]: + """Periodic REST refresh as a fallback for MQTT push. + + pyhon delivers live state via AWS IoT MQTT push, but that + subscription can silently stall with no auto-recovery short of a + restart. Polling on an interval bounds staleness and keeps state + usable even while push is dead. + """ + for appliance in hon.appliances: + try: + await appliance.update() + except Exception as err: # noqa: BLE001 + _LOGGER.warning( + "Polling refresh failed for %s: %s", + getattr(appliance, "nick_name", appliance), + err, + ) + return {} + coordinator: DataUpdateCoordinator[dict[str, Any]] = DataUpdateCoordinator( - hass, _LOGGER, name=DOMAIN + hass, + _LOGGER, + config_entry=entry, + name=DOMAIN, + update_interval=timedelta(seconds=60), + update_method=_async_poll, ) @callback