Remove connection state handling from Idasen Desk (#120242)
This commit is contained in:
parent
29da88d8f6
commit
480ffeda2c
6 changed files with 20 additions and 90 deletions
|
@ -68,7 +68,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
) -> None:
|
||||
"""Update from a Bluetooth callback to ensure that a new BLEDevice is fetched."""
|
||||
_LOGGER.debug("Bluetooth callback triggered")
|
||||
hass.async_create_task(coordinator.async_ensure_connection_state())
|
||||
hass.async_create_task(coordinator.async_connect_if_expected())
|
||||
|
||||
entry.async_on_unload(
|
||||
bluetooth.async_register_callback(
|
||||
|
|
|
@ -2,13 +2,12 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
from idasen_ha import Desk
|
||||
|
||||
from homeassistant.components import bluetooth
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -29,55 +28,29 @@ class IdasenDeskCoordinator(DataUpdateCoordinator[int | None]):
|
|||
super().__init__(hass, logger, name=name)
|
||||
self._address = address
|
||||
self._expected_connected = False
|
||||
self._connection_lost = False
|
||||
self._disconnect_lock = asyncio.Lock()
|
||||
|
||||
self.desk = Desk(self.async_set_updated_data)
|
||||
|
||||
async def async_connect(self) -> bool:
|
||||
"""Connect to desk."""
|
||||
_LOGGER.debug("Trying to connect %s", self._address)
|
||||
self._expected_connected = True
|
||||
ble_device = bluetooth.async_ble_device_from_address(
|
||||
self.hass, self._address, connectable=True
|
||||
)
|
||||
if ble_device is None:
|
||||
_LOGGER.debug("No BLEDevice for %s", self._address)
|
||||
return False
|
||||
self._expected_connected = True
|
||||
await self.desk.connect(ble_device)
|
||||
return True
|
||||
|
||||
async def async_disconnect(self) -> None:
|
||||
"""Disconnect from desk."""
|
||||
_LOGGER.debug("Disconnecting from %s", self._address)
|
||||
self._expected_connected = False
|
||||
self._connection_lost = False
|
||||
_LOGGER.debug("Disconnecting from %s", self._address)
|
||||
await self.desk.disconnect()
|
||||
|
||||
async def async_ensure_connection_state(self) -> None:
|
||||
"""Check if the expected connection state matches the current state.
|
||||
|
||||
If the expected and current state don't match, calls connect/disconnect
|
||||
as needed.
|
||||
"""
|
||||
async def async_connect_if_expected(self) -> None:
|
||||
"""Ensure that the desk is connected if that is the expected state."""
|
||||
if self._expected_connected:
|
||||
if not self.desk.is_connected:
|
||||
_LOGGER.debug("Desk disconnected. Reconnecting")
|
||||
self._connection_lost = True
|
||||
await self.async_connect()
|
||||
elif self._connection_lost:
|
||||
_LOGGER.info("Reconnected to desk")
|
||||
self._connection_lost = False
|
||||
elif self.desk.is_connected:
|
||||
if self._disconnect_lock.locked():
|
||||
_LOGGER.debug("Already disconnecting")
|
||||
return
|
||||
async with self._disconnect_lock:
|
||||
_LOGGER.debug("Desk is connected but should not be. Disconnecting")
|
||||
await self.desk.disconnect()
|
||||
|
||||
@callback
|
||||
def async_set_updated_data(self, data: int | None) -> None:
|
||||
"""Handle data update."""
|
||||
self.hass.async_create_task(self.async_ensure_connection_state())
|
||||
return super().async_set_updated_data(data)
|
||||
await self.async_connect()
|
||||
|
|
|
@ -12,5 +12,5 @@
|
|||
"documentation": "https://www.home-assistant.io/integrations/idasen_desk",
|
||||
"iot_class": "local_push",
|
||||
"quality_scale": "silver",
|
||||
"requirements": ["idasen-ha==2.5.3"]
|
||||
"requirements": ["idasen-ha==2.6.1"]
|
||||
}
|
||||
|
|
|
@ -1140,7 +1140,7 @@ ical==8.0.1
|
|||
icmplib==3.0
|
||||
|
||||
# homeassistant.components.idasen_desk
|
||||
idasen-ha==2.5.3
|
||||
idasen-ha==2.6.1
|
||||
|
||||
# homeassistant.components.network
|
||||
ifaddr==0.2.0
|
||||
|
|
|
@ -936,7 +936,7 @@ ical==8.0.1
|
|||
icmplib==3.0
|
||||
|
||||
# homeassistant.components.idasen_desk
|
||||
idasen-ha==2.5.3
|
||||
idasen-ha==2.6.1
|
||||
|
||||
# homeassistant.components.network
|
||||
ifaddr==0.2.0
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
"""Test the IKEA Idasen Desk init."""
|
||||
|
||||
import asyncio
|
||||
from unittest import mock
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
|
||||
|
@ -66,63 +65,21 @@ async def test_reconnect_on_bluetooth_callback(
|
|||
mock_desk_api.connect.assert_called_once()
|
||||
mock_register_callback.assert_called_once()
|
||||
|
||||
mock_desk_api.is_connected = False
|
||||
_, register_callback_args, _ = mock_register_callback.mock_calls[0]
|
||||
bt_callback = register_callback_args[1]
|
||||
|
||||
mock_desk_api.connect.reset_mock()
|
||||
bt_callback(None, None)
|
||||
await hass.async_block_till_done()
|
||||
assert mock_desk_api.connect.call_count == 2
|
||||
mock_desk_api.connect.assert_called_once()
|
||||
|
||||
|
||||
async def test_duplicated_disconnect_is_no_op(
|
||||
hass: HomeAssistant, mock_desk_api: MagicMock
|
||||
) -> None:
|
||||
"""Test that calling disconnect while disconnecting is a no-op."""
|
||||
await init_integration(hass)
|
||||
|
||||
await hass.services.async_call(
|
||||
"button", "press", {"entity_id": "button.test_disconnect"}, blocking=True
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
async def mock_disconnect():
|
||||
await asyncio.sleep(0)
|
||||
|
||||
mock_desk_api.disconnect.reset_mock()
|
||||
mock_desk_api.disconnect.side_effect = mock_disconnect
|
||||
|
||||
# Since the disconnect button was pressed but the desk indicates "connected",
|
||||
# any update event will call disconnect()
|
||||
mock_desk_api.is_connected = True
|
||||
mock_desk_api.trigger_update_callback(None)
|
||||
mock_desk_api.trigger_update_callback(None)
|
||||
mock_desk_api.trigger_update_callback(None)
|
||||
await hass.async_block_till_done()
|
||||
mock_desk_api.disconnect.assert_called_once()
|
||||
|
||||
|
||||
async def test_ensure_connection_state(
|
||||
hass: HomeAssistant, mock_desk_api: MagicMock
|
||||
) -> None:
|
||||
"""Test that the connection state is ensured."""
|
||||
await init_integration(hass)
|
||||
|
||||
mock_desk_api.connect.reset_mock()
|
||||
mock_desk_api.is_connected = False
|
||||
mock_desk_api.trigger_update_callback(None)
|
||||
await hass.async_block_till_done()
|
||||
mock_desk_api.connect.assert_called_once()
|
||||
|
||||
await hass.services.async_call(
|
||||
"button", "press", {"entity_id": "button.test_disconnect"}, blocking=True
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
mock_desk_api.disconnect.reset_mock()
|
||||
mock_desk_api.is_connected = True
|
||||
mock_desk_api.trigger_update_callback(None)
|
||||
await hass.async_block_till_done()
|
||||
mock_desk_api.disconnect.assert_called_once()
|
||||
mock_desk_api.connect.reset_mock()
|
||||
await hass.services.async_call(
|
||||
"button", "press", {"entity_id": "button.test_disconnect"}, blocking=True
|
||||
)
|
||||
bt_callback(None, None)
|
||||
await hass.async_block_till_done()
|
||||
assert mock_desk_api.connect.call_count == 0
|
||||
|
||||
|
||||
async def test_unload_entry(hass: HomeAssistant, mock_desk_api: MagicMock) -> None:
|
||||
|
|
Loading…
Add table
Reference in a new issue