DSMR hardening: restart-free config + decouple from telegram id
Config hot-reload (no restart): - MqttManager.unsubscribe(); apply_dsmr_subscription(settings) re-applies the DSMR subscription (subscribe/unsubscribe/topic-change, fresh snapshot so the sample interval also takes effect). - Called from lifespan AND PUT /api/config, so toggling DSMR ingest in the UI takes effect immediately without restarting the app. Decouple ingest from the DSMR telegram id (overflows / resets to zero): - Migration 20260624_12: drop UNIQUE(source_id), make recorded_at UNIQUE. - Idempotency now keys on recorded_at (telegram timestamp); the table's own autoincrement PK is the stable identity. source_id kept only as a reference. - Regression test: colliding telegram ids no longer drop new data.
This commit is contained in:
+5
-16
@@ -29,7 +29,7 @@ from app.config import get_settings
|
||||
from app.integrations.mqtt import mqtt_manager
|
||||
from app.services.auth import AuthBootstrapError, initialize_auth_schema
|
||||
from app.services.config_page import build_runtime_settings, seed_missing_config_from_bootstrap, sync_app_hostname_from_bootstrap
|
||||
from app.services.dsmr_ingest import handle_message as dsmr_handle_message
|
||||
from app.services.dsmr_ingest import apply_dsmr_subscription
|
||||
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
|
||||
@@ -246,21 +246,10 @@ async def lifespan(_: FastAPI):
|
||||
_startup_session.close()
|
||||
mqtt_manager.connect(_startup_runtime_settings)
|
||||
|
||||
# DSMR ingest: subscribe to the configured MQTT topic when enabled.
|
||||
# The handler captures a snapshot of the current runtime settings (for the
|
||||
# dsmr_sample_interval_s value). Runtime setting changes take effect after
|
||||
# a server restart or an explicit reconnect — consistent with other MQTT
|
||||
# configuration in this project.
|
||||
if _startup_runtime_settings.dsmr_ingest_enabled:
|
||||
_dsmr_topic = _startup_runtime_settings.dsmr_mqtt_topic
|
||||
_dsmr_settings_snapshot = _startup_runtime_settings
|
||||
mqtt_manager.subscribe(
|
||||
_dsmr_topic,
|
||||
lambda payload: dsmr_handle_message(payload, _dsmr_settings_snapshot),
|
||||
)
|
||||
logger.info("DSMR ingest enabled — subscribed to topic=%s.", _dsmr_topic)
|
||||
else:
|
||||
logger.debug("DSMR ingest disabled — not subscribing to DSMR topic.")
|
||||
# DSMR ingest: subscribe to the configured MQTT topic when enabled. The same
|
||||
# applier is called from PUT /api/config, so toggling DSMR via the UI takes
|
||||
# effect without an app restart.
|
||||
apply_dsmr_subscription(_startup_runtime_settings)
|
||||
|
||||
yield
|
||||
|
||||
|
||||
Reference in New Issue
Block a user