Fix HomematicIP entity recovery after access point cloud reconnect (#162575)

This commit is contained in:
Christian Lackas
2026-02-14 12:23:16 +01:00
committed by GitHub
parent 30e484c292
commit 3b3f4066c3
2 changed files with 45 additions and 0 deletions

View File

@@ -161,6 +161,11 @@ class HomematicipHAP:
_LOGGER.error("HMIP access point has lost connection with the cloud")
self._ws_connection_closed.set()
self.set_all_to_unavailable()
elif self._ws_connection_closed.is_set():
_LOGGER.info("HMIP access point has reconnected to the cloud")
self._get_state_task = self.hass.async_create_task(self._try_get_state())
self._get_state_task.add_done_callback(self.get_state_finished)
self._ws_connection_closed.clear()
@callback
def async_create_entity(self, *args, **kwargs) -> None:

View File

@@ -269,6 +269,46 @@ async def test_get_state_after_disconnect(
mock_sleep.assert_awaited_with(2)
async def test_get_state_after_ap_reconnect(
hass: HomeAssistant, hmip_config_entry: MockConfigEntry, simple_mock_home
) -> None:
"""Test state recovery after access point reconnects to cloud.
When the access point loses its cloud connection, async_update sets all
devices to unavailable. When the access point reconnects (home.connected
becomes True), async_update should trigger a state refresh to restore
entity availability.
"""
hass.config.components.add(DOMAIN)
hap = HomematicipHAP(hass, hmip_config_entry)
assert hap
simple_mock_home = MagicMock(spec=AsyncHome)
simple_mock_home.devices = []
simple_mock_home.websocket_is_connected = Mock(return_value=True)
hap.home = simple_mock_home
with patch.object(hap, "get_state") as mock_get_state:
# Initially not disconnected
assert not hap._ws_connection_closed.is_set()
# Access point loses cloud connection
hap.home.connected = False
hap.async_update()
assert hap._ws_connection_closed.is_set()
mock_get_state.assert_not_called()
# Access point reconnects to cloud
hap.home.connected = True
hap.async_update()
# Let _try_get_state run
await hass.async_block_till_done()
mock_get_state.assert_called_once()
assert not hap._ws_connection_closed.is_set()
async def test_try_get_state_exponential_backoff() -> None:
"""Test _try_get_state waits for websocket connection."""