mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 02:37:08 +00:00
Delete removed device(s) at runtime in Plugwise (#120296)
This commit is contained in:
parent
55101fcc45
commit
32c07180f6
@ -16,11 +16,12 @@ from homeassistant.config_entries import ConfigEntry
|
|||||||
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_USERNAME
|
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT, CONF_USERNAME
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import ConfigEntryError
|
from homeassistant.exceptions import ConfigEntryError
|
||||||
|
from homeassistant.helpers import device_registry as dr
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
from homeassistant.helpers.debounce import Debouncer
|
from homeassistant.helpers.debounce import Debouncer
|
||||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
|
|
||||||
from .const import DEFAULT_PORT, DEFAULT_USERNAME, DOMAIN, LOGGER
|
from .const import DEFAULT_PORT, DEFAULT_USERNAME, DOMAIN, GATEWAY_ID, LOGGER
|
||||||
|
|
||||||
|
|
||||||
class PlugwiseDataUpdateCoordinator(DataUpdateCoordinator[PlugwiseData]):
|
class PlugwiseDataUpdateCoordinator(DataUpdateCoordinator[PlugwiseData]):
|
||||||
@ -83,7 +84,46 @@ class PlugwiseDataUpdateCoordinator(DataUpdateCoordinator[PlugwiseData]):
|
|||||||
except UnsupportedDeviceError as err:
|
except UnsupportedDeviceError as err:
|
||||||
raise ConfigEntryError("Device with unsupported firmware") from err
|
raise ConfigEntryError("Device with unsupported firmware") from err
|
||||||
else:
|
else:
|
||||||
self.new_devices = set(data.devices) - self._current_devices
|
self._async_add_remove_devices(data, self.config_entry)
|
||||||
self._current_devices = set(data.devices)
|
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def _async_add_remove_devices(self, data: PlugwiseData, entry: ConfigEntry) -> None:
|
||||||
|
"""Add new Plugwise devices, remove non-existing devices."""
|
||||||
|
# Check for new or removed devices
|
||||||
|
self.new_devices = set(data.devices) - self._current_devices
|
||||||
|
removed_devices = self._current_devices - set(data.devices)
|
||||||
|
self._current_devices = set(data.devices)
|
||||||
|
|
||||||
|
if removed_devices:
|
||||||
|
self._async_remove_devices(data, entry)
|
||||||
|
|
||||||
|
def _async_remove_devices(self, data: PlugwiseData, entry: ConfigEntry) -> None:
|
||||||
|
"""Clean registries when removed devices found."""
|
||||||
|
device_reg = dr.async_get(self.hass)
|
||||||
|
device_list = dr.async_entries_for_config_entry(
|
||||||
|
device_reg, self.config_entry.entry_id
|
||||||
|
)
|
||||||
|
# via_device cannot be None, this will result in the deletion
|
||||||
|
# of other Plugwise Gateways when present!
|
||||||
|
via_device: str = ""
|
||||||
|
for device_entry in device_list:
|
||||||
|
if device_entry.identifiers:
|
||||||
|
item = list(list(device_entry.identifiers)[0])
|
||||||
|
if item[0] == DOMAIN:
|
||||||
|
# First find the Plugwise via_device, this is always the first device
|
||||||
|
if item[1] == data.gateway[GATEWAY_ID]:
|
||||||
|
via_device = device_entry.id
|
||||||
|
elif ( # then remove the connected orphaned device(s)
|
||||||
|
device_entry.via_device_id == via_device
|
||||||
|
and item[1] not in data.devices
|
||||||
|
):
|
||||||
|
device_reg.async_update_device(
|
||||||
|
device_entry.id, remove_config_entry_id=entry.entry_id
|
||||||
|
)
|
||||||
|
LOGGER.debug(
|
||||||
|
"Removed %s device %s %s from device_registry",
|
||||||
|
DOMAIN,
|
||||||
|
device_entry.model,
|
||||||
|
item[1],
|
||||||
|
)
|
||||||
|
@ -39,7 +39,7 @@ TOM = {
|
|||||||
"hardware": "1",
|
"hardware": "1",
|
||||||
"location": "f871b8c4d63549319221e294e4f88074",
|
"location": "f871b8c4d63549319221e294e4f88074",
|
||||||
"model": "Tom/Floor",
|
"model": "Tom/Floor",
|
||||||
"name": "Tom Badkamer",
|
"name": "Tom Zolder",
|
||||||
"sensors": {
|
"sensors": {
|
||||||
"battery": 99,
|
"battery": 99,
|
||||||
"temperature": 18.6,
|
"temperature": 18.6,
|
||||||
@ -258,3 +258,30 @@ async def test_update_device(
|
|||||||
for device_entry in list(device_registry.devices.values()):
|
for device_entry in list(device_registry.devices.values()):
|
||||||
item_list.extend(x[1] for x in device_entry.identifiers)
|
item_list.extend(x[1] for x in device_entry.identifiers)
|
||||||
assert "01234567890abcdefghijklmnopqrstu" in item_list
|
assert "01234567890abcdefghijklmnopqrstu" in item_list
|
||||||
|
|
||||||
|
# Remove the existing Tom/Floor
|
||||||
|
data.devices.pop("1772a4ea304041adb83f357b751341ff")
|
||||||
|
with patch(HA_PLUGWISE_SMILE_ASYNC_UPDATE, return_value=data):
|
||||||
|
async_fire_time_changed(hass, utcnow + timedelta(minutes=1))
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert (
|
||||||
|
len(
|
||||||
|
er.async_entries_for_config_entry(
|
||||||
|
entity_registry, mock_config_entry.entry_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
== 29
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
len(
|
||||||
|
dr.async_entries_for_config_entry(
|
||||||
|
device_registry, mock_config_entry.entry_id
|
||||||
|
)
|
||||||
|
)
|
||||||
|
== 6
|
||||||
|
)
|
||||||
|
item_list: list[str] = []
|
||||||
|
for device_entry in list(device_registry.devices.values()):
|
||||||
|
item_list.extend(x[1] for x in device_entry.identifiers)
|
||||||
|
assert "1772a4ea304041adb83f357b751341ff" not in item_list
|
||||||
|
Loading…
x
Reference in New Issue
Block a user