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:
@@ -107,6 +107,36 @@ def test_subscribe_when_connected_calls_paho_subscribe_immediately() -> None:
|
||||
mock_client.subscribe.assert_called_once_with("dsmr/json")
|
||||
|
||||
|
||||
def test_unsubscribe_removes_handler_from_registry() -> None:
|
||||
"""unsubscribe() must drop the handler so it is not re-subscribed on reconnect."""
|
||||
manager = MqttManager()
|
||||
manager.subscribe("dsmr/json", MagicMock())
|
||||
|
||||
manager.unsubscribe("dsmr/json")
|
||||
|
||||
assert "dsmr/json" not in manager._subscriptions
|
||||
|
||||
|
||||
def test_unsubscribe_when_connected_calls_paho_unsubscribe() -> None:
|
||||
"""unsubscribe() while connected must call client.unsubscribe(topic)."""
|
||||
manager = MqttManager()
|
||||
mock_client = MagicMock()
|
||||
manager._client = mock_client
|
||||
manager._connected = True
|
||||
manager.subscribe("dsmr/json", MagicMock())
|
||||
|
||||
manager.unsubscribe("dsmr/json")
|
||||
|
||||
mock_client.unsubscribe.assert_called_once_with("dsmr/json")
|
||||
|
||||
|
||||
def test_unsubscribe_unknown_topic_is_noop() -> None:
|
||||
"""unsubscribe() on a topic that was never registered must not raise."""
|
||||
manager = MqttManager()
|
||||
manager.unsubscribe("never/registered") # must not raise
|
||||
assert "never/registered" not in manager._subscriptions
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# on_message dispatch
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user