Initial Commit

This commit is contained in:
2026-06-11 11:50:50 -04:00
commit d4a69c41be
2748 changed files with 80489 additions and 0 deletions
@@ -0,0 +1,204 @@
"""Binary sensor platform for Nest Protect."""
from __future__ import annotations
from collections.abc import Callable
from dataclasses import dataclass
from typing import Any
from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
BinarySensorEntityDescription,
)
from homeassistant.helpers.entity import EntityCategory
from . import HomeAssistantNestProtectData
from .const import DOMAIN
from .entity import NestDescriptiveEntity
@dataclass
class NestProtectBinarySensorDescriptionMixin:
"""Define an entity description mixin for binary sensor entities."""
value_fn: Callable[[Any], bool]
@dataclass
class NestProtectBinarySensorDescription(
BinarySensorEntityDescription, NestProtectBinarySensorDescriptionMixin
):
"""Class to describe a Nest Protect binary sensor."""
wired_only: bool = False
BINARY_SENSOR_DESCRIPTIONS: list[BinarySensorEntityDescription] = [
NestProtectBinarySensorDescription(
key="co_status",
name="CO Status",
device_class=BinarySensorDeviceClass.CO,
value_fn=lambda state: state != 0,
),
NestProtectBinarySensorDescription(
key="smoke_status",
name="Smoke Status",
device_class=BinarySensorDeviceClass.SMOKE,
value_fn=lambda state: state != 0,
),
NestProtectBinarySensorDescription(
key="heat_status",
name="Heat Status",
device_class=BinarySensorDeviceClass.HEAT,
value_fn=lambda state: state != 0,
),
NestProtectBinarySensorDescription(
key="component_speaker_test_passed",
name="Speaker Test",
device_class=BinarySensorDeviceClass.PROBLEM,
entity_category=EntityCategory.DIAGNOSTIC,
icon="mdi:speaker-wireless",
value_fn=lambda state: not state,
),
NestProtectBinarySensorDescription(
key="battery_health_state",
name="Battery Health",
device_class=BinarySensorDeviceClass.BATTERY,
entity_category=EntityCategory.DIAGNOSTIC,
value_fn=lambda state: state,
),
NestProtectBinarySensorDescription(
key="is_online",
name="Online",
device_class=BinarySensorDeviceClass.CONNECTIVITY,
entity_category=EntityCategory.DIAGNOSTIC,
value_fn=lambda state: state,
),
NestProtectBinarySensorDescription(
key="component_smoke_test_passed",
name="Smoke Test",
device_class=BinarySensorDeviceClass.PROBLEM,
entity_category=EntityCategory.DIAGNOSTIC,
icon="mdi:smoke",
value_fn=lambda state: not state,
),
NestProtectBinarySensorDescription(
key="component_co_test_passed",
name="CO Test",
device_class=BinarySensorDeviceClass.PROBLEM,
entity_category=EntityCategory.DIAGNOSTIC,
icon="mdi:molecule-co",
value_fn=lambda state: not state,
),
NestProtectBinarySensorDescription(
key="component_wifi_test_passed",
name="WiFi Test",
device_class=BinarySensorDeviceClass.PROBLEM,
entity_category=EntityCategory.DIAGNOSTIC,
icon="mdi:wifi",
value_fn=lambda state: not state,
),
NestProtectBinarySensorDescription(
key="component_led_test_passed",
name="LED Test",
device_class=BinarySensorDeviceClass.PROBLEM,
entity_category=EntityCategory.DIAGNOSTIC,
icon="mdi:led-off",
value_fn=lambda state: not state,
),
NestProtectBinarySensorDescription(
key="component_pir_test_passed",
name="PIR Test",
device_class=BinarySensorDeviceClass.PROBLEM,
entity_category=EntityCategory.DIAGNOSTIC,
icon="mdi:run",
value_fn=lambda state: not state,
),
NestProtectBinarySensorDescription(
key="component_buzzer_test_passed",
name="Buzzer Test",
device_class=BinarySensorDeviceClass.PROBLEM,
entity_category=EntityCategory.DIAGNOSTIC,
icon="mdi:alarm-bell",
value_fn=lambda state: not state,
),
# Disabled for now, since it seems like this state is not valid
# NestProtectBinarySensorDescription(
# key="component_heat_test_passed",
# name="Heat Test",
# device_class=BinarySensorDeviceClass.PROBLEM,
# entity_category=EntityCategory.DIAGNOSTIC,
# icon="mdi:fire",
# value_fn=lambda state: not state
# ),
NestProtectBinarySensorDescription(
key="component_hum_test_passed",
name="Humidity Test",
device_class=BinarySensorDeviceClass.PROBLEM,
entity_category=EntityCategory.DIAGNOSTIC,
icon="mdi:water-percent",
value_fn=lambda state: not state,
),
NestProtectBinarySensorDescription(
key="removed_from_base",
name="Removed from Base",
device_class=BinarySensorDeviceClass.PROBLEM,
entity_category=EntityCategory.DIAGNOSTIC,
icon="mdi:tray-remove",
value_fn=lambda state: state,
),
NestProtectBinarySensorDescription(
key="auto_away",
name="Occupancy",
device_class=BinarySensorDeviceClass.OCCUPANCY,
wired_only=True,
value_fn=lambda state: not state,
),
NestProtectBinarySensorDescription(
key="line_power_present",
name="Line Power",
device_class=BinarySensorDeviceClass.POWER,
entity_category=EntityCategory.DIAGNOSTIC,
wired_only=True,
value_fn=lambda state: state,
),
]
async def async_setup_entry(hass, entry, async_add_devices):
"""Set up the Nest Protect binary sensors from a config entry."""
data: HomeAssistantNestProtectData = hass.data[DOMAIN][entry.entry_id]
entities: list[NestProtectBinarySensor] = []
supported_keys: dict[str, NestProtectBinarySensorDescription] = {
description.key: description for description in BINARY_SENSOR_DESCRIPTIONS
}
for device in data.devices.values():
for key in device.value:
if description := supported_keys.get(key):
# Not all entities are useful for battery powered Nest Protect devices
if description.wired_only and device.value["wired_or_battery"] != 0:
continue
entities.append(
NestProtectBinarySensor(
device, description, data.areas, data.client
)
)
async_add_devices(entities)
class NestProtectBinarySensor(NestDescriptiveEntity, BinarySensorEntity):
"""Representation of a Nest Protect Binary Sensor."""
entity_description: NestProtectBinarySensorDescription
@property
def is_on(self) -> bool:
"""Return the state of the sensor."""
state = self.bucket.value.get(self.entity_description.key)
return self.entity_description.value_fn(state)