From 4459d8674abc07d5c0f8c84d3af23dc9d1eabd74 Mon Sep 17 00:00:00 2001 From: Maciej Bieniek Date: Mon, 9 Aug 2021 23:56:33 +0200 Subject: [PATCH] Add `binary_sensor` platform for Xiaomi Miio integration (#54096) --- .coveragerc | 1 + .../components/xiaomi_miio/__init__.py | 9 +- .../components/xiaomi_miio/binary_sensor.py | 87 +++++++++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 homeassistant/components/xiaomi_miio/binary_sensor.py diff --git a/.coveragerc b/.coveragerc index 839bd34f6e5..5d9c5e9c5c8 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1202,6 +1202,7 @@ omit = homeassistant/components/xiaomi_miio/__init__.py homeassistant/components/xiaomi_miio/air_quality.py homeassistant/components/xiaomi_miio/alarm_control_panel.py + homeassistant/components/xiaomi_miio/binary_sensor.py homeassistant/components/xiaomi_miio/device.py homeassistant/components/xiaomi_miio/device_tracker.py homeassistant/components/xiaomi_miio/fan.py diff --git a/homeassistant/components/xiaomi_miio/__init__.py b/homeassistant/components/xiaomi_miio/__init__.py index 89355ae309e..bd9e69bd12d 100644 --- a/homeassistant/components/xiaomi_miio/__init__.py +++ b/homeassistant/components/xiaomi_miio/__init__.py @@ -37,7 +37,14 @@ _LOGGER = logging.getLogger(__name__) GATEWAY_PLATFORMS = ["alarm_control_panel", "light", "sensor", "switch"] SWITCH_PLATFORMS = ["switch"] FAN_PLATFORMS = ["fan"] -HUMIDIFIER_PLATFORMS = ["humidifier", "number", "select", "sensor", "switch"] +HUMIDIFIER_PLATFORMS = [ + "binary_sensor", + "humidifier", + "number", + "select", + "sensor", + "switch", +] LIGHT_PLATFORMS = ["light"] VACUUM_PLATFORMS = ["vacuum"] AIR_MONITOR_PLATFORMS = ["air_quality", "sensor"] diff --git a/homeassistant/components/xiaomi_miio/binary_sensor.py b/homeassistant/components/xiaomi_miio/binary_sensor.py new file mode 100644 index 00000000000..c2f14b17d22 --- /dev/null +++ b/homeassistant/components/xiaomi_miio/binary_sensor.py @@ -0,0 +1,87 @@ +"""Support for Xiaomi Miio binary sensors.""" +from enum import Enum + +from homeassistant.components.binary_sensor import ( + BinarySensorEntity, + BinarySensorEntityDescription, +) + +from .const import ( + CONF_DEVICE, + CONF_FLOW_TYPE, + CONF_MODEL, + DOMAIN, + KEY_COORDINATOR, + KEY_DEVICE, + MODELS_HUMIDIFIER_MJJSQ, +) +from .device import XiaomiCoordinatedMiioEntity + +ATTR_NO_WATER = "no_water" +ATTR_WATER_TANK_DETACHED = "water_tank_detached" + +BINARY_SENSOR_TYPES = ( + BinarySensorEntityDescription( + key=ATTR_NO_WATER, + name="Water Tank Empty", + icon="mdi:water-off-outline", + ), + BinarySensorEntityDescription( + key=ATTR_WATER_TANK_DETACHED, + name="Water Tank Detached", + icon="mdi:flask-empty-off-outline", + ), +) + +HUMIDIFIER_MJJSQ_BINARY_SENSORS = (ATTR_NO_WATER, ATTR_WATER_TANK_DETACHED) + + +async def async_setup_entry(hass, config_entry, async_add_entities): + """Set up the Xiaomi sensor from a config entry.""" + entities = [] + + if config_entry.data[CONF_FLOW_TYPE] == CONF_DEVICE: + model = config_entry.data[CONF_MODEL] + sensors = [] + if model in MODELS_HUMIDIFIER_MJJSQ: + sensors = HUMIDIFIER_MJJSQ_BINARY_SENSORS + for description in BINARY_SENSOR_TYPES: + if description.key not in sensors: + continue + entities.append( + XiaomiGenericBinarySensor( + f"{config_entry.title} {description.name}", + hass.data[DOMAIN][config_entry.entry_id][KEY_DEVICE], + config_entry, + f"{description.key}_{config_entry.unique_id}", + hass.data[DOMAIN][config_entry.entry_id][KEY_COORDINATOR], + description, + ) + ) + + async_add_entities(entities) + + +class XiaomiGenericBinarySensor(XiaomiCoordinatedMiioEntity, BinarySensorEntity): + """Representation of a Xiaomi Humidifier binary sensor.""" + + def __init__(self, name, device, entry, unique_id, coordinator, description): + """Initialize the entity.""" + super().__init__(name, device, entry, unique_id, coordinator) + + self.entity_description = description + + @property + def is_on(self): + """Return true if the binary sensor is on.""" + return self._extract_value_from_attribute( + self.coordinator.data, self.entity_description.key + ) + + @staticmethod + def _extract_value_from_attribute(state, attribute): + value = getattr(state, attribute) + if isinstance(value, Enum): + return value.value + + return value