mirror of
https://github.com/home-assistant/core.git
synced 2026-09-27 01:46:11 -04:00
Treat unknown homematicip_cloud device types as devices (#182394)
Co-authored-by: Markus Tuominen <3738613+Markus98@users.noreply.github.com>
This commit is contained in:
co-authored by
Markus Tuominen
parent
6f36091610
commit
620a329431
@@ -5,7 +5,7 @@ import logging
|
||||
from typing import TYPE_CHECKING, Any, override
|
||||
|
||||
from homematicip.base.functionalChannels import FunctionalChannel
|
||||
from homematicip.device import Device
|
||||
from homematicip.device import BaseDevice
|
||||
from homematicip.group import Group
|
||||
|
||||
from homeassistant.const import ATTR_ID
|
||||
@@ -133,7 +133,7 @@ class HomematicipGenericEntity(Entity):
|
||||
def device_info(self) -> DeviceInfo | None:
|
||||
"""Return device specific attributes."""
|
||||
# Only physical devices should be HA devices.
|
||||
if isinstance(self._device, Device):
|
||||
if isinstance(self._device, BaseDevice):
|
||||
device_id = str(self._device.id)
|
||||
home_id = str(self._device.homeId)
|
||||
|
||||
@@ -152,7 +152,7 @@ class HomematicipGenericEntity(Entity):
|
||||
# Serial numbers of Homematic IP device
|
||||
(DOMAIN, device_id)
|
||||
},
|
||||
manufacturer=self._device.oem,
|
||||
manufacturer=getattr(self._device, "oem", None),
|
||||
model=self._device.modelType,
|
||||
name=device_name,
|
||||
sw_version=self._device.firmwareVersion,
|
||||
@@ -325,13 +325,14 @@ class HomematicipGenericEntity(Entity):
|
||||
@override
|
||||
def available(self) -> bool:
|
||||
"""Return if entity is available."""
|
||||
return not self._device.unreach
|
||||
# BaseDevice, the fallback for an unknown device type, has no unreach.
|
||||
return not getattr(self._device, "unreach", False)
|
||||
|
||||
@property
|
||||
@override
|
||||
def unique_id(self) -> str:
|
||||
"""Return a unique ID."""
|
||||
if not isinstance(self._device, Device):
|
||||
if not isinstance(self._device, BaseDevice):
|
||||
return f"{self._device.id}_{self._feature_id}"
|
||||
channel_index = self.get_channel_index()
|
||||
return f"{self._device.id}_{channel_index}_{self._feature_id}"
|
||||
@@ -352,7 +353,7 @@ class HomematicipGenericEntity(Entity):
|
||||
"""Return the state attributes of the generic entity."""
|
||||
state_attr = {}
|
||||
|
||||
if isinstance(self._device, Device):
|
||||
if isinstance(self._device, BaseDevice):
|
||||
for attr, attr_key in DEVICE_ATTRIBUTES.items():
|
||||
if attr_value := getattr(self._device, attr, None):
|
||||
state_attr[attr_key] = attr_value
|
||||
|
||||
@@ -70,6 +70,53 @@ async def default_mock_hap_factory_fixture(
|
||||
return HomeFactory(hass, mock_connection, hmip_config_entry)
|
||||
|
||||
|
||||
@pytest.fixture(name="unknown_type_device_data")
|
||||
def unknown_type_device_data_fixture() -> dict[str, Any]:
|
||||
"""Return fixture data for a device whose type the library does not know.
|
||||
|
||||
The type is invented so that it stays unknown as devices get added.
|
||||
"""
|
||||
device_id = "3014F711000000000UNKNOWN"
|
||||
return {
|
||||
"connectionType": "HMIP_RF",
|
||||
"deviceArchetype": "HMIP",
|
||||
"firmwareVersion": "1.0.10",
|
||||
"functionalChannels": {
|
||||
"0": {
|
||||
"deviceId": device_id,
|
||||
"functionalChannelType": "DEVICE_BASE",
|
||||
"groupIndex": 0,
|
||||
"groups": [],
|
||||
"index": 0,
|
||||
"label": "",
|
||||
},
|
||||
"1": {
|
||||
"deviceId": device_id,
|
||||
"functionalChannelType": "SINGLE_KEY_CHANNEL",
|
||||
"groupIndex": 1,
|
||||
"groups": [],
|
||||
"index": 1,
|
||||
"label": "",
|
||||
},
|
||||
"2": {
|
||||
"deviceId": device_id,
|
||||
"functionalChannelType": "SINGLE_KEY_CHANNEL",
|
||||
"groupIndex": 2,
|
||||
"groups": [],
|
||||
"index": 2,
|
||||
"label": "",
|
||||
},
|
||||
},
|
||||
"homeId": "00000000-0000-0000-0000-000000000001",
|
||||
"id": device_id,
|
||||
"label": "Unknown Device",
|
||||
"lastStatusUpdate": 1614066137987,
|
||||
"modelType": "HmIP-UNKNOWN",
|
||||
"permanentlyReachable": True,
|
||||
"type": "SOME_FUTURE_DEVICE",
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture(name="full_flush_lock_controller_device_data")
|
||||
def full_flush_lock_controller_device_data_fixture() -> dict[str, Any]:
|
||||
"""Return fixture data for an HmIP-FLC device."""
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""Common tests for HomematicIP devices."""
|
||||
|
||||
from typing import Any
|
||||
from unittest.mock import patch
|
||||
|
||||
from homematicip.base.enums import EventType
|
||||
@@ -330,3 +331,36 @@ async def test_hmip_child_device_links_to_access_point(
|
||||
assert access_point_device is not None
|
||||
|
||||
assert child_device.via_device_id == access_point_device.id
|
||||
|
||||
|
||||
async def test_hmip_unknown_device_type(
|
||||
hass: HomeAssistant,
|
||||
entity_registry: er.EntityRegistry,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
default_mock_hap_factory: HomeFactory,
|
||||
unknown_type_device_data: dict[str, Any],
|
||||
) -> None:
|
||||
"""Test a device whose type the library does not know yet."""
|
||||
await default_mock_hap_factory.async_get_mock_hap(
|
||||
test_devices=["Unknown Device"], extra_devices=[unknown_type_device_data]
|
||||
)
|
||||
|
||||
entities = [
|
||||
entry
|
||||
for entry in entity_registry.entities.values()
|
||||
if entry.unique_id.startswith(unknown_type_device_data["id"])
|
||||
]
|
||||
assert sorted(entry.unique_id for entry in entities) == [
|
||||
"3014F711000000000UNKNOWN_1_button",
|
||||
"3014F711000000000UNKNOWN_2_button",
|
||||
]
|
||||
|
||||
device = device_registry.async_get(entities[0].device_id)
|
||||
assert device is not None
|
||||
assert (DOMAIN, unknown_type_device_data["id"]) in device.identifiers
|
||||
assert {entry.device_id for entry in entities} == {device.id}
|
||||
|
||||
for entry in entities:
|
||||
state = hass.states.get(entry.entity_id)
|
||||
assert state is not None
|
||||
assert state.state != STATE_UNAVAILABLE
|
||||
|
||||
Reference in New Issue
Block a user