1 """Support for Xiaomi Miio binary sensors."""
3 from __future__
import annotations
5 from collections.abc
import Callable, Iterable
6 from dataclasses
import dataclass
10 BinarySensorDeviceClass,
12 BinarySensorEntityDescription,
19 from .
import VacuumCoordinatorDataAttributes
28 MODELS_HUMIDIFIER_MIIO,
29 MODELS_HUMIDIFIER_MIOT,
30 MODELS_HUMIDIFIER_MJJSQ,
32 MODELS_VACUUM_WITH_MOP,
33 MODELS_VACUUM_WITH_SEPARATE_MOP,
35 from .entity
import XiaomiCoordinatedMiioEntity
37 _LOGGER = logging.getLogger(__name__)
39 ATTR_NO_WATER =
"no_water"
40 ATTR_PTC_STATUS =
"ptc_status"
41 ATTR_POWERSUPPLY_ATTACHED =
"powersupply_attached"
42 ATTR_WATER_TANK_DETACHED =
"water_tank_detached"
43 ATTR_MOP_ATTACHED =
"is_water_box_carriage_attached"
44 ATTR_WATER_BOX_ATTACHED =
"is_water_box_attached"
45 ATTR_WATER_SHORTAGE =
"is_water_shortage"
48 @dataclass(frozen=True)
50 """A class that describes binary sensor entities."""
52 value: Callable |
None =
None
53 parent_key: str |
None =
None
56 BINARY_SENSOR_TYPES = (
59 translation_key=ATTR_NO_WATER,
60 icon=
"mdi:water-off-outline",
61 entity_category=EntityCategory.DIAGNOSTIC,
64 key=ATTR_WATER_TANK_DETACHED,
65 translation_key=ATTR_WATER_TANK_DETACHED,
66 icon=
"mdi:car-coolant-level",
67 device_class=BinarySensorDeviceClass.CONNECTIVITY,
68 value=
lambda value:
not value,
69 entity_category=EntityCategory.DIAGNOSTIC,
73 translation_key=ATTR_PTC_STATUS,
74 device_class=BinarySensorDeviceClass.POWER,
75 entity_category=EntityCategory.DIAGNOSTIC,
78 key=ATTR_POWERSUPPLY_ATTACHED,
79 translation_key=ATTR_POWERSUPPLY_ATTACHED,
80 device_class=BinarySensorDeviceClass.PLUG,
81 entity_category=EntityCategory.DIAGNOSTIC,
85 AIRFRESH_A1_BINARY_SENSORS = (ATTR_PTC_STATUS,)
86 FAN_ZA5_BINARY_SENSORS = (ATTR_POWERSUPPLY_ATTACHED,)
90 key=ATTR_WATER_BOX_ATTACHED,
91 translation_key=ATTR_WATER_BOX_ATTACHED,
92 icon=
"mdi:square-rounded",
93 parent_key=VacuumCoordinatorDataAttributes.status,
94 entity_registry_enabled_default=
True,
95 device_class=BinarySensorDeviceClass.CONNECTIVITY,
96 entity_category=EntityCategory.DIAGNOSTIC,
99 key=ATTR_WATER_BOX_ATTACHED,
100 translation_key=ATTR_WATER_BOX_ATTACHED,
102 parent_key=VacuumCoordinatorDataAttributes.status,
103 entity_registry_enabled_default=
True,
104 device_class=BinarySensorDeviceClass.CONNECTIVITY,
105 entity_category=EntityCategory.DIAGNOSTIC,
108 key=ATTR_WATER_SHORTAGE,
109 translation_key=ATTR_WATER_SHORTAGE,
111 parent_key=VacuumCoordinatorDataAttributes.status,
112 entity_registry_enabled_default=
True,
113 device_class=BinarySensorDeviceClass.PROBLEM,
114 entity_category=EntityCategory.DIAGNOSTIC,
118 VACUUM_SENSORS_SEPARATE_MOP = {
121 key=ATTR_MOP_ATTACHED,
122 translation_key=ATTR_MOP_ATTACHED,
123 icon=
"mdi:square-rounded",
124 parent_key=VacuumCoordinatorDataAttributes.status,
125 entity_registry_enabled_default=
True,
126 device_class=BinarySensorDeviceClass.CONNECTIVITY,
127 entity_category=EntityCategory.DIAGNOSTIC,
131 HUMIDIFIER_MIIO_BINARY_SENSORS = (ATTR_WATER_TANK_DETACHED,)
132 HUMIDIFIER_MIOT_BINARY_SENSORS = (ATTR_WATER_TANK_DETACHED,)
133 HUMIDIFIER_MJJSQ_BINARY_SENSORS = (ATTR_NO_WATER, ATTR_WATER_TANK_DETACHED)
137 """Only vacuums with mop should have binary sensor registered."""
138 if config_entry.data[CONF_MODEL]
not in MODELS_VACUUM_WITH_MOP:
141 device = hass.data[DOMAIN][config_entry.entry_id].
get(KEY_DEVICE)
142 coordinator = hass.data[DOMAIN][config_entry.entry_id][KEY_COORDINATOR]
144 sensors = VACUUM_SENSORS
146 if config_entry.data[CONF_MODEL]
in MODELS_VACUUM_WITH_SEPARATE_MOP:
147 sensors = VACUUM_SENSORS_SEPARATE_MOP
149 for sensor, description
in sensors.items():
150 parent_key_data = getattr(coordinator.data, description.parent_key)
151 if getattr(parent_key_data, description.key,
None)
is None:
153 "It seems the %s does not support the %s as the initial value is None",
154 config_entry.data[CONF_MODEL],
162 f
"{sensor}_{config_entry.unique_id}",
173 config_entry: ConfigEntry,
174 async_add_entities: AddEntitiesCallback,
176 """Set up the Xiaomi sensor from a config entry."""
179 if config_entry.data[CONF_FLOW_TYPE] == CONF_DEVICE:
180 model = config_entry.data[CONF_MODEL]
181 sensors: Iterable[str] = []
182 if model
in MODEL_AIRFRESH_A1
or model
in MODEL_AIRFRESH_T2017:
183 sensors = AIRFRESH_A1_BINARY_SENSORS
184 elif model
in MODEL_FAN_ZA5:
185 sensors = FAN_ZA5_BINARY_SENSORS
186 elif model
in MODELS_HUMIDIFIER_MIIO:
187 sensors = HUMIDIFIER_MIIO_BINARY_SENSORS
188 elif model
in MODELS_HUMIDIFIER_MIOT:
189 sensors = HUMIDIFIER_MIOT_BINARY_SENSORS
190 elif model
in MODELS_HUMIDIFIER_MJJSQ:
191 sensors = HUMIDIFIER_MJJSQ_BINARY_SENSORS
192 elif model
in MODELS_VACUUM:
196 for description
in BINARY_SENSOR_TYPES:
197 if description.key
not in sensors:
201 hass.data[DOMAIN][config_entry.entry_id][KEY_DEVICE],
203 f
"{description.key}_{config_entry.unique_id}",
204 hass.data[DOMAIN][config_entry.entry_id][KEY_COORDINATOR],
213 """Representation of a Xiaomi Humidifier binary sensor."""
215 entity_description: XiaomiMiioBinarySensorDescription
217 def __init__(self, device, entry, unique_id, coordinator, description):
218 """Initialize the entity."""
219 super().
__init__(device, entry, unique_id, coordinator)
223 description.entity_registry_enabled_default
234 """Determine native value."""
236 return self._extract_value_from_attribute(
241 state = self._extract_value_from_attribute(
def __init__(self, device, entry, unique_id, coordinator, description)
def _determine_native_value(self)
_attr_entity_registry_enabled_default
None _handle_coordinator_update(self)
web.Response get(self, web.Request request, str config_key)
def _setup_vacuum_sensors(hass, config_entry, async_add_entities)
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)