121 lines
3.9 KiB
Python
121 lines
3.9 KiB
Python
"""Entity class for Nest Protect."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from homeassistant.core import callback
|
|
from homeassistant.helpers import device_registry as dr
|
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
|
from homeassistant.helpers.entity import DeviceInfo, Entity, EntityDescription
|
|
|
|
from .const import ATTRIBUTION, DOMAIN
|
|
from .pynest.client import NestClient
|
|
from .pynest.models import Bucket
|
|
|
|
|
|
class NestEntity(Entity):
|
|
"""Class to describe an Nest entity and link it to a device."""
|
|
|
|
_attr_should_poll = False
|
|
|
|
def __init__(
|
|
self,
|
|
bucket: Bucket,
|
|
description: EntityDescription,
|
|
areas: dict[str, str],
|
|
client: NestClient,
|
|
):
|
|
"""Initialize."""
|
|
self.entity_description = description
|
|
self.bucket = bucket
|
|
self.client = client
|
|
self.area = areas.get(self.bucket.value["where_id"])
|
|
|
|
self._attr_unique_id = bucket.object_key
|
|
self._attr_attribution = ATTRIBUTION
|
|
self._attr_name = self.device_name()
|
|
self._attr_device_info = self.generate_device_info()
|
|
|
|
def device_name(self) -> str | None:
|
|
"""Generate device name."""
|
|
if label := self.bucket.value.get("description"):
|
|
name = label
|
|
elif self.area:
|
|
name = self.area
|
|
else:
|
|
name = ""
|
|
|
|
if self.bucket.object_key.startswith("topaz."):
|
|
return f"Nest Protect ({name})"
|
|
|
|
if self.bucket.object_key.startswith("kryptonite."):
|
|
return f"Nest Temperature Sensor ({name})"
|
|
|
|
return None
|
|
|
|
def generate_device_info(self) -> DeviceInfo | None:
|
|
"""Generate device info."""
|
|
|
|
if self.bucket.object_key.startswith("topaz."):
|
|
return DeviceInfo(
|
|
connections={
|
|
(dr.CONNECTION_NETWORK_MAC, self.bucket.value["wifi_mac_address"])
|
|
},
|
|
identifiers={(DOMAIN, self.bucket.value["serial_number"])},
|
|
name=self._attr_name,
|
|
manufacturer="Google",
|
|
model=self.bucket.value["model"],
|
|
sw_version=self.bucket.value["software_version"],
|
|
hw_version=(
|
|
"Wired" if self.bucket.value["wired_or_battery"] == 0 else "Battery"
|
|
),
|
|
suggested_area=self.area,
|
|
configuration_url="https://home.nest.com/protect/"
|
|
+ self.bucket.value["structure_id"], # TODO change url based on device
|
|
)
|
|
|
|
if self.bucket.object_key.startswith("kryptonite."):
|
|
identifier = (
|
|
self.bucket.value.get("serial_number") or self.bucket.object_key
|
|
)
|
|
|
|
return DeviceInfo(
|
|
identifiers={(DOMAIN, identifier)},
|
|
name=self._attr_name,
|
|
manufacturer="Google",
|
|
model=self.bucket.value.get("model"),
|
|
suggested_area=self.area,
|
|
)
|
|
|
|
return None
|
|
|
|
async def async_added_to_hass(self) -> None:
|
|
"""Run when entity is added to register update signal handler."""
|
|
self.async_on_remove(
|
|
async_dispatcher_connect(
|
|
self.hass, self.bucket.object_key, self.update_callback
|
|
)
|
|
)
|
|
|
|
@callback
|
|
def update_callback(self, bucket: Bucket):
|
|
"""Update the entities state."""
|
|
|
|
self.bucket = bucket
|
|
self.async_write_ha_state()
|
|
|
|
|
|
class NestDescriptiveEntity(NestEntity):
|
|
"""Class to describe an Nest entity which uses a Entity Description."""
|
|
|
|
def __init__(
|
|
self,
|
|
bucket: Bucket,
|
|
description: EntityDescription,
|
|
areas: dict[str, str],
|
|
client: NestClient,
|
|
) -> None:
|
|
"""Initialize the device."""
|
|
super().__init__(bucket, description, areas, client)
|
|
self._attr_name = f"{super().name} {self.entity_description.name}"
|
|
self._attr_unique_id = f"{super().unique_id}-{self.entity_description.key}"
|