Use DeviceInfo on components with via_device (#58222)
Co-authored-by: epenet <epenet@users.noreply.github.com>
This commit is contained in:
parent
fc3e7f5b7e
commit
51a10f88de
7 changed files with 81 additions and 62 deletions
|
@ -10,6 +10,7 @@ from typing import Any
|
||||||
from aiohttp import ClientError
|
from aiohttp import ClientError
|
||||||
from bond_api import BPUPSubscriptions
|
from bond_api import BPUPSubscriptions
|
||||||
|
|
||||||
|
from homeassistant.const import ATTR_MODEL, ATTR_NAME, ATTR_SW_VERSION, ATTR_VIA_DEVICE
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers.entity import DeviceInfo, Entity
|
from homeassistant.helpers.entity import DeviceInfo, Entity
|
||||||
from homeassistant.helpers.event import async_track_time_interval
|
from homeassistant.helpers.event import async_track_time_interval
|
||||||
|
@ -54,22 +55,22 @@ class BondEntity(Entity):
|
||||||
@property
|
@property
|
||||||
def device_info(self) -> DeviceInfo:
|
def device_info(self) -> DeviceInfo:
|
||||||
"""Get a an HA device representing this Bond controlled device."""
|
"""Get a an HA device representing this Bond controlled device."""
|
||||||
device_info: DeviceInfo = {
|
device_info = DeviceInfo(
|
||||||
"manufacturer": self._hub.make,
|
manufacturer=self._hub.make,
|
||||||
# type ignore: tuple items should not be Optional
|
# type ignore: tuple items should not be Optional
|
||||||
"identifiers": {(DOMAIN, self._hub.bond_id, self._device.device_id)}, # type: ignore[arg-type]
|
identifiers={(DOMAIN, self._hub.bond_id, self._device.device_id)}, # type: ignore[arg-type]
|
||||||
}
|
)
|
||||||
if self.name is not None:
|
if self.name is not None:
|
||||||
device_info["name"] = self.name
|
device_info[ATTR_NAME] = self.name
|
||||||
if self._hub.bond_id is not None:
|
if self._hub.bond_id is not None:
|
||||||
device_info["via_device"] = (DOMAIN, self._hub.bond_id)
|
device_info[ATTR_VIA_DEVICE] = (DOMAIN, self._hub.bond_id)
|
||||||
if self._device.location is not None:
|
if self._device.location is not None:
|
||||||
device_info["suggested_area"] = self._device.location
|
device_info["suggested_area"] = self._device.location
|
||||||
if not self._hub.is_bridge:
|
if not self._hub.is_bridge:
|
||||||
if self._hub.model is not None:
|
if self._hub.model is not None:
|
||||||
device_info["model"] = self._hub.model
|
device_info[ATTR_MODEL] = self._hub.model
|
||||||
if self._hub.fw_ver is not None:
|
if self._hub.fw_ver is not None:
|
||||||
device_info["sw_version"] = self._hub.fw_ver
|
device_info[ATTR_SW_VERSION] = self._hub.fw_ver
|
||||||
else:
|
else:
|
||||||
model_data = []
|
model_data = []
|
||||||
if self._device.branding_profile:
|
if self._device.branding_profile:
|
||||||
|
@ -77,7 +78,7 @@ class BondEntity(Entity):
|
||||||
if self._device.template:
|
if self._device.template:
|
||||||
model_data.append(self._device.template)
|
model_data.append(self._device.template)
|
||||||
if model_data:
|
if model_data:
|
||||||
device_info["model"] = " ".join(model_data)
|
device_info[ATTR_MODEL] = " ".join(model_data)
|
||||||
|
|
||||||
return device_info
|
return device_info
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,9 @@ from aiohomekit.model.characteristics import (
|
||||||
from aiohomekit.model.services import Service, ServicesTypes
|
from aiohomekit.model.services import Service, ServicesTypes
|
||||||
|
|
||||||
from homeassistant.components import zeroconf
|
from homeassistant.components import zeroconf
|
||||||
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
|
from homeassistant.const import ATTR_VIA_DEVICE, EVENT_HOMEASSISTANT_STOP
|
||||||
from homeassistant.exceptions import ConfigEntryNotReady
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import DeviceInfo, Entity
|
||||||
|
|
||||||
from .config_flow import normalize_hkid
|
from .config_flow import normalize_hkid
|
||||||
from .connection import HKDevice
|
from .connection import HKDevice
|
||||||
|
@ -145,24 +145,24 @@ class HomeKitEntity(Entity):
|
||||||
return self._accessory.available and self.service.available
|
return self._accessory.available and self.service.available
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_info(self):
|
def device_info(self) -> DeviceInfo:
|
||||||
"""Return the device info."""
|
"""Return the device info."""
|
||||||
info = self.accessory_info
|
info = self.accessory_info
|
||||||
accessory_serial = info.value(CharacteristicsTypes.SERIAL_NUMBER)
|
accessory_serial = info.value(CharacteristicsTypes.SERIAL_NUMBER)
|
||||||
|
|
||||||
device_info = {
|
device_info = DeviceInfo(
|
||||||
"identifiers": {(DOMAIN, "serial-number", accessory_serial)},
|
identifiers={(DOMAIN, "serial-number", accessory_serial)},
|
||||||
"name": info.value(CharacteristicsTypes.NAME),
|
name=info.value(CharacteristicsTypes.NAME),
|
||||||
"manufacturer": info.value(CharacteristicsTypes.MANUFACTURER, ""),
|
manufacturer=info.value(CharacteristicsTypes.MANUFACTURER, ""),
|
||||||
"model": info.value(CharacteristicsTypes.MODEL, ""),
|
model=info.value(CharacteristicsTypes.MODEL, ""),
|
||||||
"sw_version": info.value(CharacteristicsTypes.FIRMWARE_REVISION, ""),
|
sw_version=info.value(CharacteristicsTypes.FIRMWARE_REVISION, ""),
|
||||||
}
|
)
|
||||||
|
|
||||||
# Some devices only have a single accessory - we don't add a
|
# Some devices only have a single accessory - we don't add a
|
||||||
# via_device otherwise it would be self referential.
|
# via_device otherwise it would be self referential.
|
||||||
bridge_serial = self._accessory.connection_info["serial-number"]
|
bridge_serial = self._accessory.connection_info["serial-number"]
|
||||||
if accessory_serial != bridge_serial:
|
if accessory_serial != bridge_serial:
|
||||||
device_info["via_device"] = (DOMAIN, "serial-number", bridge_serial)
|
device_info[ATTR_VIA_DEVICE] = (DOMAIN, "serial-number", bridge_serial)
|
||||||
|
|
||||||
return device_info
|
return device_info
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,10 @@ from aiohomekit.model import Accessories
|
||||||
from aiohomekit.model.characteristics import CharacteristicsTypes
|
from aiohomekit.model.characteristics import CharacteristicsTypes
|
||||||
from aiohomekit.model.services import ServicesTypes
|
from aiohomekit.model.services import ServicesTypes
|
||||||
|
|
||||||
|
from homeassistant.const import ATTR_IDENTIFIERS, ATTR_VIA_DEVICE
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers import device_registry as dr
|
from homeassistant.helpers import device_registry as dr
|
||||||
|
from homeassistant.helpers.entity import DeviceInfo
|
||||||
from homeassistant.helpers.event import async_track_time_interval
|
from homeassistant.helpers.event import async_track_time_interval
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
|
@ -205,29 +207,31 @@ class HKDevice:
|
||||||
service_type=ServicesTypes.ACCESSORY_INFORMATION,
|
service_type=ServicesTypes.ACCESSORY_INFORMATION,
|
||||||
)
|
)
|
||||||
|
|
||||||
device_info = {
|
device_info = DeviceInfo(
|
||||||
"identifiers": {
|
identifiers={
|
||||||
(
|
(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
"serial-number",
|
"serial-number",
|
||||||
info.value(CharacteristicsTypes.SERIAL_NUMBER),
|
info.value(CharacteristicsTypes.SERIAL_NUMBER),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
"name": info.value(CharacteristicsTypes.NAME),
|
name=info.value(CharacteristicsTypes.NAME),
|
||||||
"manufacturer": info.value(CharacteristicsTypes.MANUFACTURER, ""),
|
manufacturer=info.value(CharacteristicsTypes.MANUFACTURER, ""),
|
||||||
"model": info.value(CharacteristicsTypes.MODEL, ""),
|
model=info.value(CharacteristicsTypes.MODEL, ""),
|
||||||
"sw_version": info.value(CharacteristicsTypes.FIRMWARE_REVISION, ""),
|
sw_version=info.value(CharacteristicsTypes.FIRMWARE_REVISION, ""),
|
||||||
}
|
)
|
||||||
|
|
||||||
if accessory.aid == 1:
|
if accessory.aid == 1:
|
||||||
# Accessory 1 is the root device (sometimes the only device, sometimes a bridge)
|
# Accessory 1 is the root device (sometimes the only device, sometimes a bridge)
|
||||||
# Link the root device to the pairing id for the connection.
|
# Link the root device to the pairing id for the connection.
|
||||||
device_info["identifiers"].add((DOMAIN, "accessory-id", self.unique_id))
|
device_info[ATTR_IDENTIFIERS].add(
|
||||||
|
(DOMAIN, "accessory-id", self.unique_id)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# Every pairing has an accessory 1
|
# Every pairing has an accessory 1
|
||||||
# It *doesn't* have a via_device, as it is the device we are connecting to
|
# It *doesn't* have a via_device, as it is the device we are connecting to
|
||||||
# Every other accessory should use it as its via device.
|
# Every other accessory should use it as its via device.
|
||||||
device_info["via_device"] = (
|
device_info[ATTR_VIA_DEVICE] = (
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
"serial-number",
|
"serial-number",
|
||||||
self.connection_info["serial-number"],
|
self.connection_info["serial-number"],
|
||||||
|
|
|
@ -13,10 +13,16 @@ from pymyq.device import MyQDevice
|
||||||
from pymyq.errors import InvalidCredentialsError, MyQError
|
from pymyq.errors import InvalidCredentialsError, MyQError
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
from homeassistant.const import (
|
||||||
|
ATTR_MODEL,
|
||||||
|
ATTR_VIA_DEVICE,
|
||||||
|
CONF_PASSWORD,
|
||||||
|
CONF_USERNAME,
|
||||||
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||||
from homeassistant.helpers import aiohttp_client
|
from homeassistant.helpers import aiohttp_client
|
||||||
|
from homeassistant.helpers.entity import DeviceInfo
|
||||||
from homeassistant.helpers.update_coordinator import (
|
from homeassistant.helpers.update_coordinator import (
|
||||||
CoordinatorEntity,
|
CoordinatorEntity,
|
||||||
DataUpdateCoordinator,
|
DataUpdateCoordinator,
|
||||||
|
@ -91,23 +97,23 @@ class MyQEntity(CoordinatorEntity):
|
||||||
return self._device.name
|
return self._device.name
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_info(self):
|
def device_info(self) -> DeviceInfo:
|
||||||
"""Return the device_info of the device."""
|
"""Return the device_info of the device."""
|
||||||
device_info = {
|
device_info = DeviceInfo(
|
||||||
"identifiers": {(DOMAIN, self._device.device_id)},
|
identifiers={(DOMAIN, self._device.device_id)},
|
||||||
"name": self._device.name,
|
name=self._device.name,
|
||||||
"manufacturer": MANUFACTURER,
|
manufacturer=MANUFACTURER,
|
||||||
"sw_version": self._device.firmware_version,
|
sw_version=self._device.firmware_version,
|
||||||
}
|
)
|
||||||
model = (
|
model = (
|
||||||
KNOWN_MODELS.get(self._device.device_id[2:4])
|
KNOWN_MODELS.get(self._device.device_id[2:4])
|
||||||
if self._device.device_id is not None
|
if self._device.device_id is not None
|
||||||
else None
|
else None
|
||||||
)
|
)
|
||||||
if model:
|
if model:
|
||||||
device_info["model"] = model
|
device_info[ATTR_MODEL] = model
|
||||||
if self._device.parent_device_id:
|
if self._device.parent_device_id:
|
||||||
device_info["via_device"] = (DOMAIN, self._device.parent_device_id)
|
device_info[ATTR_VIA_DEVICE] = (DOMAIN, self._device.parent_device_id)
|
||||||
return device_info
|
return device_info
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -14,6 +14,7 @@ from homeassistant.const import (
|
||||||
ATTR_MANUFACTURER,
|
ATTR_MANUFACTURER,
|
||||||
ATTR_MODEL,
|
ATTR_MODEL,
|
||||||
ATTR_NAME,
|
ATTR_NAME,
|
||||||
|
ATTR_VIA_DEVICE,
|
||||||
CONF_HOST,
|
CONF_HOST,
|
||||||
CONF_PORT,
|
CONF_PORT,
|
||||||
CONF_TYPE,
|
CONF_TYPE,
|
||||||
|
@ -87,7 +88,7 @@ class OneWireHub:
|
||||||
manufacturer=device_info[ATTR_MANUFACTURER],
|
manufacturer=device_info[ATTR_MANUFACTURER],
|
||||||
model=device_info[ATTR_MODEL],
|
model=device_info[ATTR_MODEL],
|
||||||
name=device_info[ATTR_NAME],
|
name=device_info[ATTR_NAME],
|
||||||
via_device=device_info.get("via_device"),
|
via_device=device_info.get(ATTR_VIA_DEVICE),
|
||||||
)
|
)
|
||||||
|
|
||||||
async def discover_devices(self) -> None:
|
async def discover_devices(self) -> None:
|
||||||
|
@ -141,7 +142,7 @@ class OneWireHub:
|
||||||
ATTR_NAME: device_id,
|
ATTR_NAME: device_id,
|
||||||
}
|
}
|
||||||
if parent_id:
|
if parent_id:
|
||||||
device_info["via_device"] = (DOMAIN, parent_id)
|
device_info[ATTR_VIA_DEVICE] = (DOMAIN, parent_id)
|
||||||
device = OWServerDeviceDescription(
|
device = OWServerDeviceDescription(
|
||||||
device_info=device_info,
|
device_info=device_info,
|
||||||
id=device_id,
|
id=device_id,
|
||||||
|
|
|
@ -13,12 +13,13 @@ from openzwavemqtt.const import (
|
||||||
from openzwavemqtt.models.node import OZWNode
|
from openzwavemqtt.models.node import OZWNode
|
||||||
from openzwavemqtt.models.value import OZWValue
|
from openzwavemqtt.models.value import OZWValue
|
||||||
|
|
||||||
|
from homeassistant.const import ATTR_NAME, ATTR_SW_VERSION, ATTR_VIA_DEVICE
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers.dispatcher import (
|
from homeassistant.helpers.dispatcher import (
|
||||||
async_dispatcher_connect,
|
async_dispatcher_connect,
|
||||||
async_dispatcher_send,
|
async_dispatcher_send,
|
||||||
)
|
)
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import DeviceInfo, Entity
|
||||||
|
|
||||||
from . import const
|
from . import const
|
||||||
from .const import DOMAIN, PLATFORMS
|
from .const import DOMAIN, PLATFORMS
|
||||||
|
@ -184,7 +185,7 @@ class ZWaveDeviceEntity(Entity):
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_info(self):
|
def device_info(self) -> DeviceInfo:
|
||||||
"""Return device information for the device registry."""
|
"""Return device information for the device registry."""
|
||||||
node = self.values.primary.node
|
node = self.values.primary.node
|
||||||
node_instance = self.values.primary.instance
|
node_instance = self.values.primary.instance
|
||||||
|
@ -192,20 +193,20 @@ class ZWaveDeviceEntity(Entity):
|
||||||
node_firmware = node.get_value(
|
node_firmware = node.get_value(
|
||||||
CommandClass.VERSION, ValueIndex.VERSION_APPLICATION
|
CommandClass.VERSION, ValueIndex.VERSION_APPLICATION
|
||||||
)
|
)
|
||||||
device_info = {
|
device_info = DeviceInfo(
|
||||||
"identifiers": {(DOMAIN, dev_id)},
|
identifiers={(DOMAIN, dev_id)},
|
||||||
"name": create_device_name(node),
|
name=create_device_name(node),
|
||||||
"manufacturer": node.node_manufacturer_name,
|
manufacturer=node.node_manufacturer_name,
|
||||||
"model": node.node_product_name,
|
model=node.node_product_name,
|
||||||
}
|
)
|
||||||
if node_firmware is not None:
|
if node_firmware is not None:
|
||||||
device_info["sw_version"] = node_firmware.value
|
device_info[ATTR_SW_VERSION] = node_firmware.value
|
||||||
|
|
||||||
# device with multiple instances is split up into virtual devices for each instance
|
# device with multiple instances is split up into virtual devices for each instance
|
||||||
if node_instance > 1:
|
if node_instance > 1:
|
||||||
parent_dev_id = create_device_id(node)
|
parent_dev_id = create_device_id(node)
|
||||||
device_info["name"] += f" - Instance {node_instance}"
|
device_info[ATTR_NAME] += f" - Instance {node_instance}"
|
||||||
device_info["via_device"] = (DOMAIN, parent_dev_id)
|
device_info[ATTR_VIA_DEVICE] = (DOMAIN, parent_dev_id)
|
||||||
return device_info
|
return device_info
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -4,10 +4,16 @@ import logging
|
||||||
|
|
||||||
from tellduslive import BATTERY_LOW, BATTERY_OK, BATTERY_UNKNOWN
|
from tellduslive import BATTERY_LOW, BATTERY_OK, BATTERY_UNKNOWN
|
||||||
|
|
||||||
from homeassistant.const import ATTR_BATTERY_LEVEL, DEVICE_DEFAULT_NAME
|
from homeassistant.const import (
|
||||||
|
ATTR_BATTERY_LEVEL,
|
||||||
|
ATTR_MANUFACTURER,
|
||||||
|
ATTR_MODEL,
|
||||||
|
ATTR_VIA_DEVICE,
|
||||||
|
DEVICE_DEFAULT_NAME,
|
||||||
|
)
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import DeviceInfo, Entity
|
||||||
|
|
||||||
from .const import SIGNAL_UPDATE_ENTITY
|
from .const import SIGNAL_UPDATE_ENTITY
|
||||||
|
|
||||||
|
@ -116,17 +122,17 @@ class TelldusLiveEntity(Entity):
|
||||||
return self._id
|
return self._id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def device_info(self):
|
def device_info(self) -> DeviceInfo:
|
||||||
"""Return device info."""
|
"""Return device info."""
|
||||||
device = self._client.device_info(self.device.device_id)
|
device = self._client.device_info(self.device.device_id)
|
||||||
device_info = {
|
device_info = DeviceInfo(
|
||||||
"identifiers": {("tellduslive", self.device.device_id)},
|
identifiers={("tellduslive", self.device.device_id)},
|
||||||
"name": self.device.name,
|
name=self.device.name,
|
||||||
}
|
)
|
||||||
if (model := device.get("model")) is not None:
|
if (model := device.get("model")) is not None:
|
||||||
device_info["model"] = model.title()
|
device_info[ATTR_MODEL] = model.title()
|
||||||
if (protocol := device.get("protocol")) is not None:
|
if (protocol := device.get("protocol")) is not None:
|
||||||
device_info["manufacturer"] = protocol.title()
|
device_info[ATTR_MANUFACTURER] = protocol.title()
|
||||||
if (client := device.get("client")) is not None:
|
if (client := device.get("client")) is not None:
|
||||||
device_info["via_device"] = ("tellduslive", client)
|
device_info[ATTR_VIA_DEVICE] = ("tellduslive", client)
|
||||||
return device_info
|
return device_info
|
||||||
|
|
Loading…
Add table
Reference in a new issue