Ensure Shelly cleanups Bluetooth scanner data upon removal (#135472)

* Add bluetooth API to remove scanners that are no longer used

- Cleanup the advertisment history right away when a scanner is removed

In the future we will do some additional cleanup

* coverage

* finish tests

* Ensure Shelly cleanups Bluetooth scanner data upon removal

needs https://github.com/home-assistant/core/pull/135408
This commit is contained in:
J. Nick Koston 2025-01-12 17:41:21 -10:00 committed by GitHub
parent c9a7afe439
commit 2e5e2c50dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 1 deletions

View File

@ -15,6 +15,7 @@ from aioshelly.exceptions import (
from aioshelly.rpc_device import RpcDevice
import voluptuous as vol
from homeassistant.components.bluetooth import async_remove_scanner
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
@ -331,3 +332,11 @@ async def async_unload_entry(hass: HomeAssistant, entry: ShellyConfigEntry) -> b
return await hass.config_entries.async_unload_platforms(
entry, runtime_data.platforms
)
async def async_remove_entry(hass: HomeAssistant, entry: ShellyConfigEntry) -> None:
"""Remove a config entry."""
if get_device_entry_gen(entry) in RPC_GENERATIONS and (
mac_address := entry.unique_id
):
async_remove_scanner(hass, mac_address)

View File

@ -20,6 +20,7 @@ from aioshelly.exceptions import (
from aioshelly.rpc_device import RpcDevice, RpcUpdateType
from propcache import cached_property
from homeassistant.components.bluetooth import async_remove_scanner
from homeassistant.config_entries import ConfigEntry, ConfigEntryState
from homeassistant.const import (
ATTR_DEVICE_ID,
@ -30,7 +31,7 @@ from homeassistant.const import (
from homeassistant.core import CALLBACK_TYPE, Event, HomeAssistant, callback
from homeassistant.helpers import device_registry as dr, issue_registry as ir
from homeassistant.helpers.debounce import Debouncer
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, format_mac
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .bluetooth import async_connect_scanner
@ -697,6 +698,7 @@ class ShellyRpcCoordinator(ShellyCoordinatorBase[RpcDevice]):
)
if ble_scanner_mode == BLEScannerMode.DISABLED and self.connected:
await async_stop_scanner(self.device)
async_remove_scanner(self.hass, format_mac(self.mac).upper())
return
if await async_ensure_ble_enabled(self.device):
# BLE enable required a reboot, don't bother connecting

View File

@ -545,3 +545,22 @@ async def test_sleeping_block_device_wrong_sleep_period(
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert entry.data[CONF_SLEEP_PERIOD] == BLOCK_EXPECTED_SLEEP_PERIOD
async def test_bluetooth_cleanup_on_remove_entry(
hass: HomeAssistant,
mock_rpc_device: Mock,
) -> None:
"""Test bluetooth is cleaned up on entry removal."""
entry = await init_integration(hass, 2)
assert entry.state is ConfigEntryState.LOADED
await hass.config_entries.async_unload(entry.entry_id)
await hass.async_block_till_done()
with patch("homeassistant.components.shelly.async_remove_scanner") as remove_mock:
await hass.config_entries.async_remove(entry.entry_id)
await hass.async_block_till_done()
remove_mock.assert_called_once_with(hass, entry.unique_id.upper())