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:
@@ -187,6 +187,28 @@ def test_put_config_with_csrf_header_updates_app_name(
|
||||
assert app_name_field["value"] == "Updated via API"
|
||||
|
||||
|
||||
def test_put_config_reapplies_dsmr_subscription(
|
||||
client: TestClient, test_database_urls
|
||||
) -> None:
|
||||
"""Saving config must re-apply the DSMR subscription so enabling DSMR ingest
|
||||
takes effect without an app restart (the route calls apply_dsmr_subscription
|
||||
with the refreshed settings)."""
|
||||
_login(client)
|
||||
|
||||
payload = _full_config_payload({"DSMR_INGEST_ENABLED": "true"})
|
||||
with patch("app.services.dsmr_ingest.apply_dsmr_subscription") as spy:
|
||||
response = client.put(
|
||||
"/api/config",
|
||||
json={"updates": payload},
|
||||
headers={"X-CSRF-Token": "any-non-empty-value"},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
spy.assert_called_once()
|
||||
applied_settings = spy.call_args.args[0]
|
||||
assert applied_settings.dsmr_ingest_enabled is True
|
||||
|
||||
|
||||
def test_put_config_blank_secret_keeps_existing_value(
|
||||
client: TestClient, test_database_urls
|
||||
) -> None:
|
||||
|
||||
Reference in New Issue
Block a user