mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 15:17:35 +00:00
Fix throttling issue in HomematicIP Cloud (#146683)
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
parent
91bc56b15c
commit
761a0877e6
@ -128,6 +128,7 @@ class HomematicipHAP:
|
|||||||
self.config_entry.data.get(HMIPC_AUTHTOKEN),
|
self.config_entry.data.get(HMIPC_AUTHTOKEN),
|
||||||
self.config_entry.data.get(HMIPC_NAME),
|
self.config_entry.data.get(HMIPC_NAME),
|
||||||
)
|
)
|
||||||
|
|
||||||
except HmipcConnectionError as err:
|
except HmipcConnectionError as err:
|
||||||
raise ConfigEntryNotReady from err
|
raise ConfigEntryNotReady from err
|
||||||
except Exception as err: # noqa: BLE001
|
except Exception as err: # noqa: BLE001
|
||||||
@ -210,41 +211,13 @@ class HomematicipHAP:
|
|||||||
for device in self.home.devices:
|
for device in self.home.devices:
|
||||||
device.fire_update_event()
|
device.fire_update_event()
|
||||||
|
|
||||||
async def async_connect(self) -> None:
|
async def async_connect(self, home: AsyncHome) -> None:
|
||||||
"""Start WebSocket connection."""
|
"""Connect to HomematicIP Cloud Websocket."""
|
||||||
tries = 0
|
await home.enable_events()
|
||||||
while True:
|
|
||||||
retry_delay = 2 ** min(tries, 8)
|
|
||||||
|
|
||||||
try:
|
home.set_on_connected_handler(self.ws_connected_handler)
|
||||||
await self.home.get_current_state_async()
|
home.set_on_disconnected_handler(self.ws_disconnected_handler)
|
||||||
hmip_events = self.home.enable_events()
|
home.set_on_reconnect_handler(self.ws_reconnected_handler)
|
||||||
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
|
|
||||||
|
|
||||||
async def async_reset(self) -> bool:
|
async def async_reset(self) -> bool:
|
||||||
"""Close the websocket connection."""
|
"""Close the websocket connection."""
|
||||||
@ -272,14 +245,22 @@ class HomematicipHAP:
|
|||||||
|
|
||||||
async def ws_connected_handler(self) -> None:
|
async def ws_connected_handler(self) -> None:
|
||||||
"""Handle websocket connected."""
|
"""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():
|
if self._ws_connection_closed.is_set():
|
||||||
await self.get_state()
|
await self.get_state()
|
||||||
self._ws_connection_closed.clear()
|
self._ws_connection_closed.clear()
|
||||||
|
|
||||||
async def ws_disconnected_handler(self) -> None:
|
async def ws_disconnected_handler(self) -> None:
|
||||||
"""Handle websocket disconnection."""
|
"""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()
|
self._ws_connection_closed.set()
|
||||||
|
|
||||||
async def get_hap(
|
async def get_hap(
|
||||||
@ -306,6 +287,6 @@ class HomematicipHAP:
|
|||||||
home.on_update(self.async_update)
|
home.on_update(self.async_update)
|
||||||
home.on_create(self.async_create_entity)
|
home.on_create(self.async_create_entity)
|
||||||
|
|
||||||
hass.loop.create_task(self.async_connect())
|
await self.async_connect(home)
|
||||||
|
|
||||||
return home
|
return home
|
||||||
|
@ -6,5 +6,5 @@
|
|||||||
"documentation": "https://www.home-assistant.io/integrations/homematicip_cloud",
|
"documentation": "https://www.home-assistant.io/integrations/homematicip_cloud",
|
||||||
"iot_class": "cloud_push",
|
"iot_class": "cloud_push",
|
||||||
"loggers": ["homematicip"],
|
"loggers": ["homematicip"],
|
||||||
"requirements": ["homematicip==2.0.4"]
|
"requirements": ["homematicip==2.0.5"]
|
||||||
}
|
}
|
||||||
|
2
requirements_all.txt
generated
2
requirements_all.txt
generated
@ -1170,7 +1170,7 @@ home-assistant-frontend==20250531.3
|
|||||||
home-assistant-intents==2025.6.10
|
home-assistant-intents==2025.6.10
|
||||||
|
|
||||||
# homeassistant.components.homematicip_cloud
|
# homeassistant.components.homematicip_cloud
|
||||||
homematicip==2.0.4
|
homematicip==2.0.5
|
||||||
|
|
||||||
# homeassistant.components.horizon
|
# homeassistant.components.horizon
|
||||||
horimote==0.4.1
|
horimote==0.4.1
|
||||||
|
2
requirements_test_all.txt
generated
2
requirements_test_all.txt
generated
@ -1016,7 +1016,7 @@ home-assistant-frontend==20250531.3
|
|||||||
home-assistant-intents==2025.6.10
|
home-assistant-intents==2025.6.10
|
||||||
|
|
||||||
# homeassistant.components.homematicip_cloud
|
# homeassistant.components.homematicip_cloud
|
||||||
homematicip==2.0.4
|
homematicip==2.0.5
|
||||||
|
|
||||||
# homeassistant.components.remember_the_milk
|
# homeassistant.components.remember_the_milk
|
||||||
httplib2==0.20.4
|
httplib2==0.20.4
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
"""Test HomematicIP Cloud accesspoint."""
|
"""Test HomematicIP Cloud accesspoint."""
|
||||||
|
|
||||||
from unittest.mock import Mock, patch
|
from unittest.mock import AsyncMock, Mock, patch
|
||||||
|
|
||||||
from homematicip.auth import Auth
|
from homematicip.auth import Auth
|
||||||
from homematicip.connection.connection_context import ConnectionContext
|
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.errors import HmipcConnectionError
|
||||||
from homeassistant.components.homematicip_cloud.hap import (
|
from homeassistant.components.homematicip_cloud.hap import (
|
||||||
|
AsyncHome,
|
||||||
HomematicipAuth,
|
HomematicipAuth,
|
||||||
HomematicipHAP,
|
HomematicipHAP,
|
||||||
)
|
)
|
||||||
@ -251,3 +252,21 @@ async def test_get_state_after_disconnect(
|
|||||||
assert hap._ws_connection_closed.is_set()
|
assert hap._ws_connection_closed.is_set()
|
||||||
await hap.ws_connected_handler()
|
await hap.ws_connected_handler()
|
||||||
mock_get_state.assert_called_once()
|
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()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user