mirror of
https://github.com/home-assistant/core.git
synced 2025-07-15 09:17:10 +00:00
Rework Z-Wave.Me to group entities of one physical devices (#78553)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: Dmitry Vlasov <kerbalspacema@gmail.com>
This commit is contained in:
parent
93d74cafdc
commit
7af0f16f79
@ -8,6 +8,8 @@ from homeassistant.config_entries import ConfigEntry
|
|||||||
from homeassistant.const import CONF_TOKEN, CONF_URL
|
from homeassistant.const import CONF_TOKEN, CONF_URL
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.exceptions import ConfigEntryNotReady
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
|
from homeassistant.helpers import device_registry
|
||||||
|
from homeassistant.helpers.device_registry import DeviceRegistry
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect, dispatcher_send
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect, dispatcher_send
|
||||||
from homeassistant.helpers.entity import DeviceInfo, Entity
|
from homeassistant.helpers.entity import DeviceInfo, Entity
|
||||||
|
|
||||||
@ -23,6 +25,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
controller = hass.data[DOMAIN][entry.entry_id] = ZWaveMeController(hass, entry)
|
controller = hass.data[DOMAIN][entry.entry_id] = ZWaveMeController(hass, entry)
|
||||||
if await controller.async_establish_connection():
|
if await controller.async_establish_connection():
|
||||||
hass.async_create_task(async_setup_platforms(hass, entry, controller))
|
hass.async_create_task(async_setup_platforms(hass, entry, controller))
|
||||||
|
registry = device_registry.async_get(hass)
|
||||||
|
controller.remove_stale_devices(registry)
|
||||||
return True
|
return True
|
||||||
raise ConfigEntryNotReady()
|
raise ConfigEntryNotReady()
|
||||||
|
|
||||||
@ -62,24 +66,33 @@ class ZWaveMeController:
|
|||||||
|
|
||||||
def add_device(self, device: ZWaveMeData) -> None:
|
def add_device(self, device: ZWaveMeData) -> None:
|
||||||
"""Send signal to create device."""
|
"""Send signal to create device."""
|
||||||
if device.deviceType in ZWAVE_ME_PLATFORMS and self.platforms_inited:
|
if device.id in self.device_ids:
|
||||||
if device.id in self.device_ids:
|
dispatcher_send(self._hass, f"ZWAVE_ME_INFO_{device.id}", device)
|
||||||
dispatcher_send(self._hass, f"ZWAVE_ME_INFO_{device.id}", device)
|
else:
|
||||||
else:
|
dispatcher_send(
|
||||||
dispatcher_send(
|
self._hass, f"ZWAVE_ME_NEW_{device.deviceType.upper()}", device
|
||||||
self._hass, f"ZWAVE_ME_NEW_{device.deviceType.upper()}", device
|
)
|
||||||
)
|
self.device_ids.add(device.id)
|
||||||
self.device_ids.add(device.id)
|
|
||||||
|
|
||||||
def on_device_create(self, devices: list) -> None:
|
def on_device_create(self, devices: list[ZWaveMeData]) -> None:
|
||||||
"""Create multiple devices."""
|
"""Create multiple devices."""
|
||||||
for device in devices:
|
for device in devices:
|
||||||
self.add_device(device)
|
if device.deviceType in ZWAVE_ME_PLATFORMS and self.platforms_inited:
|
||||||
|
self.add_device(device)
|
||||||
|
|
||||||
def on_device_update(self, new_info: ZWaveMeData) -> None:
|
def on_device_update(self, new_info: ZWaveMeData) -> None:
|
||||||
"""Send signal to update device."""
|
"""Send signal to update device."""
|
||||||
dispatcher_send(self._hass, f"ZWAVE_ME_INFO_{new_info.id}", new_info)
|
dispatcher_send(self._hass, f"ZWAVE_ME_INFO_{new_info.id}", new_info)
|
||||||
|
|
||||||
|
def remove_stale_devices(self, registry: DeviceRegistry):
|
||||||
|
"""Remove old-format devices in the registry."""
|
||||||
|
for device_id in self.device_ids:
|
||||||
|
device = registry.async_get_device(
|
||||||
|
{(DOMAIN, f"{self.config.unique_id}-{device_id}")}
|
||||||
|
)
|
||||||
|
if device is not None:
|
||||||
|
registry.async_remove_device(device.id)
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platforms(
|
async def async_setup_platforms(
|
||||||
hass: HomeAssistant, entry: ConfigEntry, controller: ZWaveMeController
|
hass: HomeAssistant, entry: ConfigEntry, controller: ZWaveMeController
|
||||||
@ -113,7 +126,7 @@ class ZWaveMeEntity(Entity):
|
|||||||
def device_info(self) -> DeviceInfo:
|
def device_info(self) -> DeviceInfo:
|
||||||
"""Return device specific attributes."""
|
"""Return device specific attributes."""
|
||||||
return DeviceInfo(
|
return DeviceInfo(
|
||||||
identifiers={(DOMAIN, self._attr_unique_id)},
|
identifiers={(DOMAIN, self.device.deviceIdentifier)},
|
||||||
name=self._attr_name,
|
name=self._attr_name,
|
||||||
manufacturer=self.device.manufacturer,
|
manufacturer=self.device.manufacturer,
|
||||||
sw_version=self.device.firmware,
|
sw_version=self.device.firmware,
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "Z-Wave.Me",
|
"name": "Z-Wave.Me",
|
||||||
"documentation": "https://www.home-assistant.io/integrations/zwave_me",
|
"documentation": "https://www.home-assistant.io/integrations/zwave_me",
|
||||||
"iot_class": "local_push",
|
"iot_class": "local_push",
|
||||||
"requirements": ["zwave_me_ws==0.2.6", "url-normalize==1.4.3"],
|
"requirements": ["zwave_me_ws==0.3.0", "url-normalize==1.4.3"],
|
||||||
"after_dependencies": ["zeroconf"],
|
"after_dependencies": ["zeroconf"],
|
||||||
"zeroconf": [{ "type": "_hap._tcp.local.", "name": "*z.wave-me*" }],
|
"zeroconf": [{ "type": "_hap._tcp.local.", "name": "*z.wave-me*" }],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
|
@ -2640,4 +2640,4 @@ zm-py==0.5.2
|
|||||||
zwave-js-server-python==0.43.0
|
zwave-js-server-python==0.43.0
|
||||||
|
|
||||||
# homeassistant.components.zwave_me
|
# homeassistant.components.zwave_me
|
||||||
zwave_me_ws==0.2.6
|
zwave_me_ws==0.3.0
|
||||||
|
@ -1832,4 +1832,4 @@ zigpy==0.51.5
|
|||||||
zwave-js-server-python==0.43.0
|
zwave-js-server-python==0.43.0
|
||||||
|
|
||||||
# homeassistant.components.zwave_me
|
# homeassistant.components.zwave_me
|
||||||
zwave_me_ws==0.2.6
|
zwave_me_ws==0.3.0
|
||||||
|
74
tests/components/zwave_me/test_remove_stale_devices.py
Normal file
74
tests/components/zwave_me/test_remove_stale_devices.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
"""Test the zwave_me removal of stale devices."""
|
||||||
|
from unittest.mock import patch
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
import pytest as pytest
|
||||||
|
from zwave_me_ws import ZWaveMeData
|
||||||
|
|
||||||
|
from homeassistant.components.zwave_me import ZWaveMePlatform
|
||||||
|
from homeassistant.const import CONF_TOKEN, CONF_URL
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry, mock_device_registry
|
||||||
|
|
||||||
|
DEFAULT_DEVICE_INFO = ZWaveMeData(
|
||||||
|
id="DummyDevice",
|
||||||
|
deviceType=ZWaveMePlatform.BINARY_SENSOR,
|
||||||
|
title="DeviceDevice",
|
||||||
|
level=100,
|
||||||
|
deviceIdentifier="16-23",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def device_reg(hass):
|
||||||
|
"""Return an empty, loaded, registry."""
|
||||||
|
return mock_device_registry(hass)
|
||||||
|
|
||||||
|
|
||||||
|
async def mock_connection(controller):
|
||||||
|
"""Mock established connection and setting identifiers."""
|
||||||
|
controller.on_new_device(DEFAULT_DEVICE_INFO)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"identifier,should_exist",
|
||||||
|
[
|
||||||
|
(DEFAULT_DEVICE_INFO.id, False),
|
||||||
|
(DEFAULT_DEVICE_INFO.deviceIdentifier, True),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_remove_stale_devices(
|
||||||
|
hass: HomeAssistant, device_reg, identifier, should_exist
|
||||||
|
):
|
||||||
|
"""Test removing devices with old-format ids."""
|
||||||
|
|
||||||
|
config_entry = MockConfigEntry(
|
||||||
|
unique_id=uuid.uuid4(),
|
||||||
|
domain="zwave_me",
|
||||||
|
data={CONF_TOKEN: "test_token", CONF_URL: "http://test_test"},
|
||||||
|
)
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
device_reg.async_get_or_create(
|
||||||
|
config_entry_id=config_entry.entry_id,
|
||||||
|
connections={("mac", "12:34:56:AB:CD:EF")},
|
||||||
|
identifiers={("zwave_me", f"{config_entry.unique_id}-{identifier}")},
|
||||||
|
)
|
||||||
|
with patch("zwave_me_ws.ZWaveMe.get_connection", mock_connection,), patch(
|
||||||
|
"homeassistant.components.zwave_me.async_setup_platforms",
|
||||||
|
):
|
||||||
|
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
|
assert (
|
||||||
|
bool(
|
||||||
|
device_reg.async_get_device(
|
||||||
|
{
|
||||||
|
(
|
||||||
|
"zwave_me",
|
||||||
|
f"{config_entry.unique_id}-{identifier}",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
== should_exist
|
||||||
|
)
|
Loading…
x
Reference in New Issue
Block a user