Make device info a TypedDict (#49670)

This commit is contained in:
Ville Skyttä 2021-05-01 00:21:39 +03:00 committed by GitHub
parent 37e8571fe8
commit 59f32f7c9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 53 additions and 26 deletions

View File

@ -10,9 +10,8 @@ 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_NAME
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.entity import 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
from .const import DOMAIN from .const import DOMAIN
@ -65,18 +64,24 @@ class BondEntity(Entity):
return False return False
@property @property
def device_info(self) -> dict[str, Any] | None: 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 = { device_info: DeviceInfo = {
ATTR_NAME: self.name,
"manufacturer": self._hub.make, "manufacturer": self._hub.make,
"identifiers": {(DOMAIN, self._hub.bond_id, self._device.device_id)}, # type ignore: tuple items should not be Optional
"suggested_area": self._device.location, "identifiers": {(DOMAIN, self._hub.bond_id, self._device.device_id)}, # type: ignore[arg-type]
"via_device": (DOMAIN, self._hub.bond_id),
} }
if self.name is not None:
device_info["name"] = self.name
if self._hub.bond_id is not None:
device_info["via_device"] = (DOMAIN, self._hub.bond_id)
if self._device.location is not None:
device_info["suggested_area"] = self._device.location
if not self._hub.is_bridge: if not self._hub.is_bridge:
device_info["model"] = self._hub.model if self._hub.model is not None:
device_info["sw_version"] = self._hub.fw_ver device_info["model"] = self._hub.model
if self._hub.fw_ver is not None:
device_info["sw_version"] = self._hub.fw_ver
else: else:
model_data = [] model_data = []
if self._device.branding_profile: if self._device.branding_profile:

View File

@ -7,6 +7,7 @@ from homeassistant.components.sensor import SensorEntity
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import DEVICE_CLASS_TIMESTAMP from homeassistant.const import DEVICE_CLASS_TIMESTAMP
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
@ -32,7 +33,7 @@ async def async_setup_entry(
sensors = [] sensors = []
device_info = { device_info: DeviceInfo = {
"identifiers": {(DOMAIN, coordinator.data.serial)}, "identifiers": {(DOMAIN, coordinator.data.serial)},
"name": coordinator.data.model, "name": coordinator.data.model,
"manufacturer": ATTR_MANUFACTURER, "manufacturer": ATTR_MANUFACTURER,
@ -53,7 +54,7 @@ class BrotherPrinterSensor(CoordinatorEntity, SensorEntity):
self, self,
coordinator: BrotherDataUpdateCoordinator, coordinator: BrotherDataUpdateCoordinator,
kind: str, kind: str,
device_info: dict[str, Any], device_info: DeviceInfo,
) -> None: ) -> None:
"""Initialize.""" """Initialize."""
super().__init__(coordinator) super().__init__(coordinator)
@ -110,7 +111,7 @@ class BrotherPrinterSensor(CoordinatorEntity, SensorEntity):
return self._description["unit"] return self._description["unit"]
@property @property
def device_info(self) -> dict[str, Any]: def device_info(self) -> DeviceInfo:
"""Return the device info.""" """Return the device info."""
return self._device_info return self._device_info

View File

@ -31,6 +31,7 @@ from homeassistant.components.media_player.const import (
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import STATE_IDLE, STATE_PAUSED, STATE_PLAYING from homeassistant.const import STATE_IDLE, STATE_PAUSED, STATE_PLAYING
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.util.dt import utcnow from homeassistant.util.dt import utcnow
from .const import DATA_SOURCE_MANAGER, DOMAIN as HEOS_DOMAIN, SIGNAL_HEOS_UPDATED from .const import DATA_SOURCE_MANAGER, DOMAIN as HEOS_DOMAIN, SIGNAL_HEOS_UPDATED
@ -253,7 +254,7 @@ class HeosMediaPlayer(MediaPlayerEntity):
return self._player.available return self._player.available
@property @property
def device_info(self) -> dict: def device_info(self) -> DeviceInfo:
"""Get attributes about the device.""" """Get attributes about the device."""
return { return {
"identifiers": {(HEOS_DOMAIN, self._player.player_id)}, "identifiers": {(HEOS_DOMAIN, self._player.player_id)},

View File

@ -49,7 +49,7 @@ from homeassistant.helpers import (
discovery, discovery,
) )
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 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
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
@ -600,7 +600,7 @@ class HuaweiLteBaseEntity(Entity):
return False return False
@property @property
def device_info(self) -> dict[str, Any]: def device_info(self) -> DeviceInfo:
"""Get info for matching with parent router.""" """Get info for matching with parent router."""
return { return {
"identifiers": self.router.device_identifiers, "identifiers": self.router.device_identifiers,

View File

@ -24,6 +24,7 @@ from homeassistant.helpers.dispatcher import (
async_dispatcher_connect, async_dispatcher_connect,
async_dispatcher_send, async_dispatcher_send,
) )
from homeassistant.helpers.entity import DeviceInfo
import homeassistant.util.color as color_util import homeassistant.util.color as color_util
from . import ( from . import (
@ -234,7 +235,7 @@ class HyperionBaseLight(LightEntity):
return self._unique_id return self._unique_id
@property @property
def device_info(self) -> dict[str, Any] | None: def device_info(self) -> DeviceInfo:
"""Return device information.""" """Return device information."""
return { return {
"identifiers": {(DOMAIN, self._device_id)}, "identifiers": {(DOMAIN, self._device_id)},

View File

@ -31,6 +31,7 @@ from homeassistant.helpers.dispatcher import (
async_dispatcher_connect, async_dispatcher_connect,
async_dispatcher_send, async_dispatcher_send,
) )
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.util import slugify from homeassistant.util import slugify
from . import ( from . import (
@ -179,7 +180,7 @@ class HyperionComponentSwitch(SwitchEntity):
return bool(self._client.has_loaded_state) return bool(self._client.has_loaded_state)
@property @property
def device_info(self) -> dict[str, Any] | None: def device_info(self) -> DeviceInfo:
"""Return device information.""" """Return device information."""
return { return {
"identifiers": {(DOMAIN, self._device_id)}, "identifiers": {(DOMAIN, self._device_id)},

View File

@ -3,7 +3,6 @@ from __future__ import annotations
import asyncio import asyncio
import logging import logging
from typing import Any
from aiohttp import ClientError from aiohttp import ClientError
@ -14,6 +13,7 @@ from homeassistant.components.light import (
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import DeviceInfo
from .const import ( from .const import (
ATTR_HOST, ATTR_HOST,
@ -105,7 +105,7 @@ class TwinklyLight(LightEntity):
return "mdi:string-lights" return "mdi:string-lights"
@property @property
def device_info(self) -> dict[str, Any] | None: def device_info(self) -> DeviceInfo | None:
"""Get device specific attributes.""" """Get device specific attributes."""
return ( return (
{ {

View File

@ -4,7 +4,7 @@ from __future__ import annotations
from datetime import timedelta from datetime import timedelta
import logging import logging
import re import re
from typing import Any, Callable from typing import Callable
from WazeRouteCalculator import WazeRouteCalculator, WRCError from WazeRouteCalculator import WazeRouteCalculator, WRCError
import voluptuous as vol import voluptuous as vol
@ -23,6 +23,7 @@ from homeassistant.const import (
) )
from homeassistant.core import Config, CoreState, HomeAssistant from homeassistant.core import Config, CoreState, HomeAssistant
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import DeviceInfo
from .const import ( from .const import (
ATTR_DESTINATION, ATTR_DESTINATION,
@ -263,7 +264,7 @@ class WazeTravelTime(SensorEntity):
self._waze_data.update() self._waze_data.update()
@property @property
def device_info(self) -> dict[str, Any] | None: def device_info(self) -> DeviceInfo:
"""Return device specific attributes.""" """Return device specific attributes."""
return { return {
"name": "Waze", "name": "Waze",

View File

@ -9,7 +9,7 @@ from zwave_js_server.model.value import Value as ZwaveValue, get_value_id
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
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 DOMAIN from .const import DOMAIN
from .discovery import ZwaveDiscoveryInfo from .discovery import ZwaveDiscoveryInfo
@ -92,7 +92,7 @@ class ZWaveBaseEntity(Entity):
) )
@property @property
def device_info(self) -> dict: def device_info(self) -> DeviceInfo:
"""Return device information for the device registry.""" """Return device information for the device registry."""
# device is precreated in main handler # device is precreated in main handler
return { return {

View File

@ -10,7 +10,7 @@ import logging
import math import math
import sys import sys
from timeit import default_timer as timer from timeit import default_timer as timer
from typing import Any from typing import Any, TypedDict
from homeassistant.config import DATA_CUSTOMIZE from homeassistant.config import DATA_CUSTOMIZE
from homeassistant.const import ( from homeassistant.const import (
@ -110,6 +110,23 @@ def get_supported_features(hass: HomeAssistant, entity_id: str) -> int:
return entry.supported_features or 0 return entry.supported_features or 0
class DeviceInfo(TypedDict, total=False):
"""Entity device information for device registry."""
name: str
connections: set[tuple[str, str]]
identifiers: set[tuple[str, ...]]
manufacturer: str
model: str
suggested_area: str
sw_version: str
via_device: tuple[str, str]
entry_type: str | None
default_name: str
default_manufacturer: str
default_model: str
class Entity(ABC): class Entity(ABC):
"""An abstract class for Home Assistant entities.""" """An abstract class for Home Assistant entities."""
@ -214,7 +231,7 @@ class Entity(ABC):
return None return None
@property @property
def device_info(self) -> Mapping[str, Any] | None: def device_info(self) -> DeviceInfo | None:
"""Return device specific attributes. """Return device specific attributes.
Implemented by platform classes. Implemented by platform classes.