core/homeassistant/components/livisi/binary_sensor.py

112 lines
3.7 KiB
Python

"""Code to handle a Livisi Binary Sensor."""
from __future__ import annotations
from typing import Any
from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass,
BinarySensorEntity,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN, LIVISI_STATE_CHANGE, LOGGER, WDS_DEVICE_TYPE
from .coordinator import LivisiDataUpdateCoordinator
from .entity import LivisiEntity
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up binary_sensor device."""
coordinator: LivisiDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
known_devices = set()
@callback
def handle_coordinator_update() -> None:
"""Add Window Sensor."""
shc_devices: list[dict[str, Any]] = coordinator.data
entities: list[BinarySensorEntity] = []
for device in shc_devices:
if device["id"] not in known_devices and device["type"] == WDS_DEVICE_TYPE:
livisi_binary: BinarySensorEntity = LivisiWindowDoorSensor(
config_entry, coordinator, device
)
LOGGER.debug("Include device type: %s", device["type"])
coordinator.devices.add(device["id"])
known_devices.add(device["id"])
entities.append(livisi_binary)
async_add_entities(entities)
config_entry.async_on_unload(
coordinator.async_add_listener(handle_coordinator_update)
)
class LivisiBinarySensor(LivisiEntity, BinarySensorEntity):
"""Represents a Livisi Binary Sensor."""
def __init__(
self,
config_entry: ConfigEntry,
coordinator: LivisiDataUpdateCoordinator,
device: dict[str, Any],
capability_name: str,
) -> None:
"""Initialize the Livisi sensor."""
super().__init__(config_entry, coordinator, device)
self._capability_id = self.capabilities[capability_name]
async def async_added_to_hass(self) -> None:
"""Register callbacks."""
await super().async_added_to_hass()
self.async_on_remove(
async_dispatcher_connect(
self.hass,
f"{LIVISI_STATE_CHANGE}_{self._capability_id}",
self.update_states,
)
)
@callback
def update_states(self, state: bool) -> None:
"""Update the state of the device."""
self._attr_is_on = state
self.async_write_ha_state()
class LivisiWindowDoorSensor(LivisiBinarySensor):
"""Represents a Livisi Window/Door Sensor as a Binary Sensor Entity."""
def __init__(
self,
config_entry: ConfigEntry,
coordinator: LivisiDataUpdateCoordinator,
device: dict[str, Any],
) -> None:
"""Initialize the Livisi window/door sensor."""
super().__init__(config_entry, coordinator, device, "WindowDoorSensor")
self._attr_device_class = (
BinarySensorDeviceClass.DOOR
if (device.get("tags", {}).get("typeCategory") == "TCDoorId")
else BinarySensorDeviceClass.WINDOW
)
async def async_added_to_hass(self) -> None:
"""Get current state."""
await super().async_added_to_hass()
response = await self.coordinator.async_get_device_state(
self._capability_id, "isOpen"
)
if response is None:
self._attr_available = False
else:
self._attr_is_on = response