1 """Provides a sensor for Home Connect."""
4 from dataclasses
import dataclass
5 from datetime
import datetime, timedelta
7 from typing
import cast
9 from homeconnect.api
import HomeConnectError
14 SensorEntityDescription,
23 from .
import HomeConnectConfigEntry
28 BSH_OPERATION_STATE_FINISHED,
29 BSH_OPERATION_STATE_PAUSE,
30 BSH_OPERATION_STATE_RUN,
31 COFFEE_EVENT_BEAN_CONTAINER_EMPTY,
32 COFFEE_EVENT_DRIP_TRAY_FULL,
33 COFFEE_EVENT_WATER_TANK_EMPTY,
34 DISHWASHER_EVENT_RINSE_AID_NEARLY_EMPTY,
35 DISHWASHER_EVENT_SALT_NEARLY_EMPTY,
36 REFRIGERATION_EVENT_DOOR_ALARM_FREEZER,
37 REFRIGERATION_EVENT_DOOR_ALARM_REFRIGERATOR,
38 REFRIGERATION_EVENT_TEMP_ALARM_FREEZER,
40 from .entity
import HomeConnectEntity
42 _LOGGER = logging.getLogger(__name__)
45 EVENT_OPTIONS = [
"confirmed",
"off",
"present"]
48 @dataclass(frozen=True, kw_only=True)
50 """Entity Description class for sensors."""
52 default_value: str |
None =
None
53 appliance_types: tuple[str, ...] |
None =
None
57 BSH_PROGRAM_SENSORS = (
59 key=
"BSH.Common.Option.RemainingProgramTime",
60 device_class=SensorDeviceClass.TIMESTAMP,
62 translation_key=
"program_finish_time",
65 key=
"BSH.Common.Option.Duration",
66 device_class=SensorDeviceClass.DURATION,
67 native_unit_of_measurement=UnitOfTime.SECONDS,
71 key=
"BSH.Common.Option.ProgramProgress",
72 native_unit_of_measurement=PERCENTAGE,
74 translation_key=
"program_progress",
80 key=BSH_OPERATION_STATE,
81 device_class=SensorDeviceClass.ENUM,
93 translation_key=
"operation_state",
97 device_class=SensorDeviceClass.ENUM,
103 translation_key=
"door",
106 key=
"ConsumerProducts.CoffeeMaker.Status.BeverageCounterCoffee",
107 state_class=SensorStateClass.TOTAL_INCREASING,
108 translation_key=
"coffee_counter",
111 key=
"ConsumerProducts.CoffeeMaker.Status.BeverageCounterPowderCoffee",
112 state_class=SensorStateClass.TOTAL_INCREASING,
113 translation_key=
"powder_coffee_counter",
116 key=
"ConsumerProducts.CoffeeMaker.Status.BeverageCounterHotWater",
117 native_unit_of_measurement=UnitOfVolume.MILLILITERS,
118 device_class=SensorDeviceClass.VOLUME,
119 state_class=SensorStateClass.TOTAL_INCREASING,
120 translation_key=
"hot_water_counter",
123 key=
"ConsumerProducts.CoffeeMaker.Status.BeverageCounterHotWaterCups",
124 state_class=SensorStateClass.TOTAL_INCREASING,
125 translation_key=
"hot_water_cups_counter",
128 key=
"ConsumerProducts.CoffeeMaker.Status.BeverageCounterHotMilk",
129 state_class=SensorStateClass.TOTAL_INCREASING,
130 translation_key=
"hot_milk_counter",
133 key=
"ConsumerProducts.CoffeeMaker.Status.BeverageCounterFrothyMilk",
134 state_class=SensorStateClass.TOTAL_INCREASING,
135 translation_key=
"frothy_milk_counter",
138 key=
"ConsumerProducts.CoffeeMaker.Status.BeverageCounterMilk",
139 state_class=SensorStateClass.TOTAL_INCREASING,
140 translation_key=
"milk_counter",
143 key=
"ConsumerProducts.CoffeeMaker.Status.BeverageCounterCoffeeAndMilk",
144 state_class=SensorStateClass.TOTAL_INCREASING,
145 translation_key=
"coffee_and_milk_counter",
148 key=
"ConsumerProducts.CoffeeMaker.Status.BeverageCounterRistrettoEspresso",
149 state_class=SensorStateClass.TOTAL_INCREASING,
150 translation_key=
"ristretto_espresso_counter",
153 key=
"BSH.Common.Status.BatteryLevel",
154 device_class=SensorDeviceClass.BATTERY,
155 translation_key=
"battery_level",
158 key=
"BSH.Common.Status.Video.CameraState",
159 device_class=SensorDeviceClass.ENUM,
166 "streaminglocalancloud",
169 translation_key=
"camera_state",
172 key=
"ConsumerProducts.CleaningRobot.Status.LastSelectedMap",
173 device_class=SensorDeviceClass.ENUM,
180 translation_key=
"last_selected_map",
186 key=REFRIGERATION_EVENT_DOOR_ALARM_FREEZER,
187 device_class=SensorDeviceClass.ENUM,
188 options=EVENT_OPTIONS,
190 translation_key=
"freezer_door_alarm",
191 appliance_types=(
"FridgeFreezer",
"Freezer"),
194 key=REFRIGERATION_EVENT_DOOR_ALARM_REFRIGERATOR,
195 device_class=SensorDeviceClass.ENUM,
196 options=EVENT_OPTIONS,
198 translation_key=
"refrigerator_door_alarm",
199 appliance_types=(
"FridgeFreezer",
"Refrigerator"),
202 key=REFRIGERATION_EVENT_TEMP_ALARM_FREEZER,
203 device_class=SensorDeviceClass.ENUM,
204 options=EVENT_OPTIONS,
206 translation_key=
"freezer_temperature_alarm",
207 appliance_types=(
"FridgeFreezer",
"Freezer"),
210 key=COFFEE_EVENT_BEAN_CONTAINER_EMPTY,
211 device_class=SensorDeviceClass.ENUM,
212 options=EVENT_OPTIONS,
214 translation_key=
"bean_container_empty",
215 appliance_types=(
"CoffeeMaker",),
218 key=COFFEE_EVENT_WATER_TANK_EMPTY,
219 device_class=SensorDeviceClass.ENUM,
220 options=EVENT_OPTIONS,
222 translation_key=
"water_tank_empty",
223 appliance_types=(
"CoffeeMaker",),
226 key=COFFEE_EVENT_DRIP_TRAY_FULL,
227 device_class=SensorDeviceClass.ENUM,
228 options=EVENT_OPTIONS,
230 translation_key=
"drip_tray_full",
231 appliance_types=(
"CoffeeMaker",),
234 key=DISHWASHER_EVENT_SALT_NEARLY_EMPTY,
235 device_class=SensorDeviceClass.ENUM,
236 options=EVENT_OPTIONS,
238 translation_key=
"salt_nearly_empty",
239 appliance_types=(
"Dishwasher",),
242 key=DISHWASHER_EVENT_RINSE_AID_NEARLY_EMPTY,
243 device_class=SensorDeviceClass.ENUM,
244 options=EVENT_OPTIONS,
246 translation_key=
"rinse_aid_nearly_empty",
247 appliance_types=(
"Dishwasher",),
254 entry: HomeConnectConfigEntry,
255 async_add_entities: AddEntitiesCallback,
257 """Set up the Home Connect sensor."""
260 """Get a list of entities."""
261 entities: list[SensorEntity] = []
262 for device
in entry.runtime_data.devices:
268 for description
in EVENT_SENSORS
269 if description.appliance_types
270 and device.appliance.type
in description.appliance_types
272 with contextlib.suppress(HomeConnectError):
273 if device.appliance.get_programs_available():
279 for description
in SENSORS
280 if description.key
in device.appliance.status
288 """Sensor class for Home Connect."""
290 entity_description: HomeConnectSensorEntityDescription
294 """Return true if the sensor is available."""
298 """Update the sensor's status."""
299 appliance_status = self.
devicedevice.appliance.status
301 self.
bsh_keybsh_key
not in appliance_status
302 or ATTR_VALUE
not in appliance_status[self.
bsh_keybsh_key]
307 status = appliance_status[self.
bsh_keybsh_key]
309 case SensorDeviceClass.TIMESTAMP:
310 if ATTR_VALUE
not in status:
323 in (appliance_status := self.
devicedevice.appliance.status)
324 and ATTR_VALUE
in appliance_status[BSH_OPERATION_STATE]
325 and appliance_status[BSH_OPERATION_STATE][ATTR_VALUE]
327 BSH_OPERATION_STATE_RUN,
328 BSH_OPERATION_STATE_PAUSE,
329 BSH_OPERATION_STATE_FINISHED,
338 case SensorDeviceClass.ENUM:
343 cast(str, status.get(ATTR_VALUE)).split(
".")[-1]
SensorDeviceClass|None device_class(self)
str|None device_class(self)
None async_setup_entry(HomeAssistant hass, HomeConnectConfigEntry entry, AddEntitiesCallback async_add_entities)
list[OneWireSensor] get_entities(OneWireHub onewire_hub, MappingProxyType[str, Any] options)