Fix throttling issue in HomematicIP Cloud (#146683)

Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
hahn-th 2025-06-13 19:57:03 +02:00 committed by GitHub
parent 91bc56b15c
commit 761a0877e6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 41 additions and 41 deletions

View File

@ -128,6 +128,7 @@ class HomematicipHAP:
self.config_entry.data.get(HMIPC_AUTHTOKEN),
self.config_entry.data.get(HMIPC_NAME),
)
except HmipcConnectionError as err:
raise ConfigEntryNotReady from err
except Exception as err: # noqa: BLE001
@ -210,41 +211,13 @@ class HomematicipHAP:
for device in self.home.devices:
device.fire_update_event()
async def async_connect(self) -> None:
"""Start WebSocket connection."""
tries = 0
while True:
retry_delay = 2 ** min(tries, 8)
async def async_connect(self, home: AsyncHome) -> None:
"""Connect to HomematicIP Cloud Websocket."""
await home.enable_events()
try:
await self.home.get_current_state_async()
hmip_events = self.home.enable_events()
self.home.set_on_connected_handler(self.ws_connected_handler)
self.home.set_on_disconnected_handler(self.ws_disconnected_handler)
tries = 0
await hmip_events
except HmipConnectionError:
_LOGGER.error(
(
"Error connecting to HomematicIP with HAP %s. "
"Retrying in %d seconds"
),
self.config_entry.unique_id,
retry_delay,
)
if self._ws_close_requested:
break
self._ws_close_requested = False
tries += 1
try:
self._retry_task = self.hass.async_create_task(
asyncio.sleep(retry_delay)
)
await self._retry_task
except asyncio.CancelledError:
break
home.set_on_connected_handler(self.ws_connected_handler)
home.set_on_disconnected_handler(self.ws_disconnected_handler)
home.set_on_reconnect_handler(self.ws_reconnected_handler)
async def async_reset(self) -> bool:
"""Close the websocket connection."""
@ -272,14 +245,22 @@ class HomematicipHAP:
async def ws_connected_handler(self) -> None:
"""Handle websocket connected."""
_LOGGER.debug("WebSocket connection to HomematicIP established")
_LOGGER.info("Websocket connection to HomematicIP Cloud established")
if self._ws_connection_closed.is_set():
await self.get_state()
self._ws_connection_closed.clear()
async def ws_disconnected_handler(self) -> None:
"""Handle websocket disconnection."""
_LOGGER.warning("WebSocket connection to HomematicIP closed")
_LOGGER.warning("Websocket connection to HomematicIP Cloud closed")
self._ws_connection_closed.set()
async def ws_reconnected_handler(self, reason: str) -> None:
"""Handle websocket reconnection."""
_LOGGER.info(
"Websocket connection to HomematicIP Cloud re-established due to reason: %s",
reason,
)
self._ws_connection_closed.set()
async def get_hap(
@ -306,6 +287,6 @@ class HomematicipHAP:
home.on_update(self.async_update)
home.on_create(self.async_create_entity)
hass.loop.create_task(self.async_connect())
await self.async_connect(home)
return home

View File

@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/homematicip_cloud",
"iot_class": "cloud_push",
"loggers": ["homematicip"],
"requirements": ["homematicip==2.0.4"]
"requirements": ["homematicip==2.0.5"]
}

2
requirements_all.txt generated
View File

@ -1170,7 +1170,7 @@ home-assistant-frontend==20250531.3
home-assistant-intents==2025.6.10
# homeassistant.components.homematicip_cloud
homematicip==2.0.4
homematicip==2.0.5
# homeassistant.components.horizon
horimote==0.4.1

View File

@ -1016,7 +1016,7 @@ home-assistant-frontend==20250531.3
home-assistant-intents==2025.6.10
# homeassistant.components.homematicip_cloud
homematicip==2.0.4
homematicip==2.0.5
# homeassistant.components.remember_the_milk
httplib2==0.20.4

View File

@ -1,6 +1,6 @@
"""Test HomematicIP Cloud accesspoint."""
from unittest.mock import Mock, patch
from unittest.mock import AsyncMock, Mock, patch
from homematicip.auth import Auth
from homematicip.connection.connection_context import ConnectionContext
@ -16,6 +16,7 @@ from homeassistant.components.homematicip_cloud.const import (
)
from homeassistant.components.homematicip_cloud.errors import HmipcConnectionError
from homeassistant.components.homematicip_cloud.hap import (
AsyncHome,
HomematicipAuth,
HomematicipHAP,
)
@ -251,3 +252,21 @@ async def test_get_state_after_disconnect(
assert hap._ws_connection_closed.is_set()
await hap.ws_connected_handler()
mock_get_state.assert_called_once()
async def test_async_connect(
hass: HomeAssistant, hmip_config_entry: MockConfigEntry, simple_mock_home
) -> None:
"""Test async_connect."""
hass.config.components.add(DOMAIN)
hap = HomematicipHAP(hass, hmip_config_entry)
assert hap
simple_mock_home = AsyncMock(spec=AsyncHome, autospec=True)
await hap.async_connect(simple_mock_home)
simple_mock_home.set_on_connected_handler.assert_called_once()
simple_mock_home.set_on_disconnected_handler.assert_called_once()
simple_mock_home.set_on_reconnect_handler.assert_called_once()
simple_mock_home.enable_events.assert_called_once()