M5-T11: add HA discovery and state publishing wired to polling

This commit is contained in:
2026-06-22 15:32:43 +02:00
parent 9d05f5ea62
commit 35b95f5c88
7 changed files with 1657 additions and 23 deletions
+36
View File
@@ -28,6 +28,7 @@ from app.services.auth import AuthBootstrapError, initialize_auth_schema
from app.services.config_page import seed_missing_config_from_bootstrap, sync_app_hostname_from_bootstrap
from app.services.public_ip import check_public_ipv4_and_notify
from app.services.modbus_poll import poll_all_enabled_devices, BASE_POLL_TICK_SECONDS
from app.services.ha_discovery import publish_discovery, publish_states
from scripts.app_db_adopt import AppDatabaseAdoptionError, validate_app_runtime_db
logger = logging.getLogger(__name__)
@@ -60,6 +61,30 @@ def _run_scheduled_modbus_poll() -> None:
session.close()
def _run_scheduled_ha_state_publish() -> None:
"""Periodic job: publish discovery configs + state + availability for all enabled exposed entities.
Runs every 60 seconds. When the MQTT broker is connected:
- Publishes (or re-publishes) all HA Discovery configs (retained, idempotent).
- Publishes the current state / availability for all enabled entities.
This also serves as the reliable "publish discovery after connect" mechanism:
because paho connects asynchronously, a synchronous call immediately after
``mqtt_manager.connect()`` would fire before the TCP handshake completes and
be a no-op. Instead, this periodic job picks it up within 60 seconds of the
broker becoming available — retained payloads make repeated publishes harmless.
"""
session_local = get_session_local()
session: Session = session_local()
try:
publish_discovery(session)
publish_states(session)
except Exception:
logger.exception("_run_scheduled_ha_state_publish: unexpected error")
finally:
session.close()
def ensure_auth_db_ready() -> None:
session_local = get_session_local()
session: Session = session_local()
@@ -103,9 +128,20 @@ async def lifespan(_: FastAPI):
max_instances=1,
coalesce=True,
)
# Periodic HA state / availability publish (60-second fallback sweep).
scheduler.add_job(
_run_scheduled_ha_state_publish,
trigger=IntervalTrigger(seconds=60),
id="ha-state-publish",
replace_existing=True,
max_instances=1,
coalesce=True,
)
scheduler.start()
# MQTT: connect if configured.
# Discovery will be published by the first run of _run_scheduled_ha_state_publish
# (within 60 s of startup), after the async paho handshake completes.
mqtt_manager.connect(get_settings())
yield