M8-T10: add WarmteLink serial worker manager

This commit is contained in:
2026-08-23 21:22:06 +02:00
parent afe653bafa
commit 4884a19e3d
6 changed files with 721 additions and 11 deletions
+21 -10
View File
@@ -38,6 +38,7 @@ from app.services.modbus_poll import poll_all_enabled_devices, BASE_POLL_TICK_SE
from app.services.ha_discovery import publish_discovery, publish_states
from app.services.tibber_prices import refresh_prices
from app.services.energy_cost import compute_closed_periods
from app.services.warmtelink_worker import warmtelink_worker_manager
from app.services.timezone import local_tz
from scripts.app_db_adopt import AppDatabaseAdoptionError, validate_app_runtime_db
@@ -273,18 +274,28 @@ async def lifespan(_: FastAPI):
_startup_runtime_settings = build_runtime_settings(_startup_session, get_settings())
finally:
_startup_session.close()
mqtt_manager.connect(_startup_runtime_settings)
serial_started = False
try:
mqtt_manager.connect(_startup_runtime_settings)
# DSMR sources carry their own runtime configuration and are reconciled
# after the MQTT manager is connected.
apply_dsmr_subscription()
# DSMR sources carry their own runtime configuration and are reconciled
# after the MQTT manager is connected.
apply_dsmr_subscription()
# Mark it before reconcile: a partial reconcile can already own a fd or
# a non-daemon thread and must receive the same orderly shutdown.
serial_started = True
warmtelink_worker_manager.start()
yield
# MQTT: clean shutdown before the process exits.
mqtt_manager.disconnect()
scheduler.shutdown(wait=False)
yield
finally:
# Serial descriptors/workers must be handled first on every exit path.
if serial_started:
try:
warmtelink_worker_manager.shutdown()
except Exception:
logger.exception("WarmteLink shutdown failed")
mqtt_manager.disconnect()
scheduler.shutdown(wait=False)
def create_app() -> FastAPI: