Destroy old discovery topics when the radio key changes

This commit is contained in:
Jack Kingsman
2026-04-12 14:59:41 -07:00
parent d2d009ae79
commit c24e291017
2 changed files with 55 additions and 1 deletions

View File

@@ -519,12 +519,16 @@ class MqttHaModule(FanoutModule):
if key_changed:
old_key = self._radio_key
old_topics = list(self._discovery_topics)
if old_topics:
await self._clear_retained_topics(old_topics)
self._discovery_topics.clear()
self._radio_key = pub_key
self._radio_name = new_name
# Remove stale discovery entries from the old identity (e.g.
# "unknown" placeholder from before the radio key was known),
# then re-publish with the real identity.
if old_key is not None:
if old_key is not None and not old_topics:
await self._clear_retained_topics(
[t for t, _ in _radio_discovery_configs(self._prefix, old_key, "")]
)

View File

@@ -286,6 +286,56 @@ class TestMqttHaHealth:
assert mod._radio_key == "aabbccddeeff"
assert mod._radio_name == "MyRadio"
@pytest.mark.asyncio
async def test_on_health_key_change_clears_all_existing_discovery_topics(self):
mod = MqttHaModule("test", _base_config())
mod._publisher = MagicMock()
mod._publisher.connected = True
mod._publisher.publish = AsyncMock()
mod._radio_key = "aabbccddeeff"
mod._radio_name = "OldRadio"
mod._discovery_topics = [
"homeassistant/sensor/meshcore_aabbccddeeff/noise_floor/config",
"homeassistant/event/meshcore_aabbccddeeff/messages/config",
"homeassistant/device_tracker/meshcore_ccdd11223344/config",
"homeassistant/sensor/meshcore_eeff11223344/battery_voltage/config",
]
mod._clear_retained_topics = AsyncMock()
async def publish_discovery_side_effect():
assert mod._discovery_topics == []
mod._discovery_topics = [
"homeassistant/sensor/meshcore_112233445566/noise_floor/config",
"homeassistant/event/meshcore_112233445566/messages/config",
]
mod._publish_discovery = AsyncMock(side_effect=publish_discovery_side_effect)
await mod.on_health(
{
"connected": True,
"public_key": "112233445566",
"name": "NewRadio",
}
)
mod._clear_retained_topics.assert_awaited_once_with(
[
"homeassistant/sensor/meshcore_aabbccddeeff/noise_floor/config",
"homeassistant/event/meshcore_aabbccddeeff/messages/config",
"homeassistant/device_tracker/meshcore_ccdd11223344/config",
"homeassistant/sensor/meshcore_eeff11223344/battery_voltage/config",
]
)
mod._publish_discovery.assert_awaited_once()
assert mod._radio_key == "112233445566"
assert mod._radio_name == "NewRadio"
assert mod._discovery_topics == [
"homeassistant/sensor/meshcore_112233445566/noise_floor/config",
"homeassistant/event/meshcore_112233445566/messages/config",
]
class TestMqttHaLifecycle:
@pytest.mark.asyncio