1 """The Meater Temperature Probe integration."""
3 from __future__
import annotations
5 from collections.abc
import Callable
6 from dataclasses
import dataclass
7 from datetime
import datetime, timedelta
9 from meater.MeaterApi
import MeaterProbe
14 SensorEntityDescription,
24 DataUpdateCoordinator,
28 from .const
import DOMAIN
31 @dataclass(frozen=True, kw_only=True)
33 """Describes meater sensor entity."""
35 available: Callable[[MeaterProbe |
None], bool]
36 value: Callable[[MeaterProbe], datetime | float | str |
None]
40 """Convert elapsed time to timestamp."""
41 if not probe.cook
or not hasattr(probe.cook,
"time_elapsed"):
43 return dt_util.utcnow() -
timedelta(seconds=probe.cook.time_elapsed)
47 """Convert remaining time to timestamp."""
50 or not hasattr(probe.cook,
"time_remaining")
51 or probe.cook.time_remaining < 0
54 return dt_util.utcnow() +
timedelta(seconds=probe.cook.time_remaining)
61 translation_key=
"ambient",
62 device_class=SensorDeviceClass.TEMPERATURE,
63 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
64 state_class=SensorStateClass.MEASUREMENT,
65 available=
lambda probe: probe
is not None,
66 value=
lambda probe: probe.ambient_temperature,
71 translation_key=
"internal",
72 device_class=SensorDeviceClass.TEMPERATURE,
73 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
74 state_class=SensorStateClass.MEASUREMENT,
75 available=
lambda probe: probe
is not None,
76 value=
lambda probe: probe.internal_temperature,
81 translation_key=
"cook_name",
82 available=
lambda probe: probe
is not None and probe.cook
is not None,
83 value=
lambda probe: probe.cook.name
if probe.cook
else None,
89 translation_key=
"cook_state",
90 available=
lambda probe: probe
is not None and probe.cook
is not None,
91 value=
lambda probe: probe.cook.state
if probe.cook
else None,
95 key=
"cook_target_temp",
96 translation_key=
"cook_target_temp",
97 device_class=SensorDeviceClass.TEMPERATURE,
98 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
99 state_class=SensorStateClass.MEASUREMENT,
100 available=
lambda probe: probe
is not None and probe.cook
is not None,
101 value=
lambda probe: probe.cook.target_temperature
102 if probe.cook
and hasattr(probe.cook,
"target_temperature")
107 key=
"cook_peak_temp",
108 translation_key=
"cook_peak_temp",
109 device_class=SensorDeviceClass.TEMPERATURE,
110 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
111 state_class=SensorStateClass.MEASUREMENT,
112 available=
lambda probe: probe
is not None and probe.cook
is not None,
113 value=
lambda probe: probe.cook.peak_temperature
114 if probe.cook
and hasattr(probe.cook,
"peak_temperature")
120 key=
"cook_time_remaining",
121 translation_key=
"cook_time_remaining",
122 device_class=SensorDeviceClass.TIMESTAMP,
123 available=
lambda probe: probe
is not None and probe.cook
is not None,
124 value=_remaining_time_to_timestamp,
129 key=
"cook_time_elapsed",
130 translation_key=
"cook_time_elapsed",
131 device_class=SensorDeviceClass.TIMESTAMP,
132 available=
lambda probe: probe
is not None and probe.cook
is not None,
133 value=_elapsed_time_to_timestamp,
139 hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
141 """Set up the entry."""
142 coordinator: DataUpdateCoordinator[dict[str, MeaterProbe]] = hass.data[DOMAIN][
147 def async_update_data():
148 """Handle updated data from the API endpoint."""
149 if not coordinator.last_update_success:
152 devices = coordinator.data
154 known_probes: set = hass.data[DOMAIN][
"known_probes"]
157 for device_id
in devices:
158 if device_id
in known_probes:
164 for sensor_description
in SENSOR_TYPES
167 known_probes.add(device_id)
174 coordinator.async_add_listener(async_update_data)
178 SensorEntity, CoordinatorEntity[DataUpdateCoordinator[dict[str, MeaterProbe]]]
180 """Meater Temperature Sensor Entity."""
182 entity_description: MeaterSensorEntityDescription
185 self, coordinator, device_id, description: MeaterSensorEntityDescription
187 """Initialise the sensor."""
194 manufacturer=
"Apption Labs",
195 model=
"Meater Probe",
196 name=f
"Meater Probe {device_id}",
205 """Return the temperature of the probe."""
206 if not (device := self.coordinator.data.get(self.
device_iddevice_id)):
213 """Return if entity is available."""
216 self.coordinator.last_update_success
218 self.coordinator.data.get(self.
device_iddevice_id)
None __init__(self, coordinator, device_id, MeaterSensorEntityDescription description)
datetime|None _elapsed_time_to_timestamp(MeaterProbe probe)
datetime|None _remaining_time_to_timestamp(MeaterProbe probe)
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)