1 """Sensors for the weatherflow integration."""
3 from __future__
import annotations
5 from collections.abc
import Callable
6 from dataclasses
import dataclass, field
7 from datetime
import datetime
10 from pyweatherflowudp.const
import EVENT_RAPID_WIND
11 from pyweatherflowudp.device
import (
20 SensorEntityDescription,
28 SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
31 UnitOfElectricPotential,
34 UnitOfPrecipitationDepth,
47 from .const
import DOMAIN, LOGGER, format_dispatch_call
51 """Parse parse precipitation type."""
52 if raw_data.name.lower() ==
"unknown":
54 return raw_data.name.lower()
57 @dataclass(frozen=True, kw_only=True)
59 """Describes WeatherFlow sensor entity."""
61 raw_data_conv_fn: Callable[[WeatherFlowDevice], datetime | StateType]
63 event_subscriptions: list[str] = field(default_factory=
lambda: [EVENT_OBSERVATION])
64 imperial_suggested_unit: str |
None =
None
67 """Return the parsed sensor value."""
68 if (raw_sensor_data := getattr(device, self.
keykey))
is None:
73 SENSORS: tuple[WeatherFlowSensorEntityDescription, ...] = (
76 translation_key=
"air_density",
77 native_unit_of_measurement=
"kg/m³",
78 state_class=SensorStateClass.MEASUREMENT,
79 suggested_display_precision=5,
80 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
83 key=
"air_temperature",
84 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
85 device_class=SensorDeviceClass.TEMPERATURE,
86 state_class=SensorStateClass.MEASUREMENT,
87 suggested_display_precision=1,
88 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
91 key=
"dew_point_temperature",
92 translation_key=
"dew_point",
93 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
94 device_class=SensorDeviceClass.TEMPERATURE,
95 state_class=SensorStateClass.MEASUREMENT,
96 suggested_display_precision=1,
97 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
100 key=
"feels_like_temperature",
101 translation_key=
"feels_like",
102 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
103 device_class=SensorDeviceClass.TEMPERATURE,
104 state_class=SensorStateClass.MEASUREMENT,
105 suggested_display_precision=1,
106 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
109 key=
"wet_bulb_temperature",
110 translation_key=
"wet_bulb_temperature",
111 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
112 device_class=SensorDeviceClass.TEMPERATURE,
113 state_class=SensorStateClass.MEASUREMENT,
114 suggested_display_precision=1,
115 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
119 translation_key=
"battery_voltage",
120 native_unit_of_measurement=UnitOfElectricPotential.VOLT,
121 device_class=SensorDeviceClass.VOLTAGE,
122 entity_category=EntityCategory.DIAGNOSTIC,
123 state_class=SensorStateClass.MEASUREMENT,
124 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
128 native_unit_of_measurement=LIGHT_LUX,
129 device_class=SensorDeviceClass.ILLUMINANCE,
130 state_class=SensorStateClass.MEASUREMENT,
131 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
134 key=
"lightning_strike_average_distance",
135 state_class=SensorStateClass.MEASUREMENT,
136 device_class=SensorDeviceClass.DISTANCE,
137 native_unit_of_measurement=UnitOfLength.KILOMETERS,
138 translation_key=
"lightning_average_distance",
139 suggested_display_precision=2,
140 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
143 key=
"lightning_strike_count",
144 translation_key=
"lightning_count",
145 state_class=SensorStateClass.TOTAL,
146 raw_data_conv_fn=
lambda raw_data: raw_data,
149 key=
"precipitation_type",
150 translation_key=
"precipitation_type",
151 device_class=SensorDeviceClass.ENUM,
152 options=[
"none",
"rain",
"hail",
"rain_hail",
"unknown"],
153 raw_data_conv_fn=precipitation_raw_conversion_fn,
156 key=
"rain_accumulation_previous_minute",
157 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
158 state_class=SensorStateClass.TOTAL,
159 device_class=SensorDeviceClass.PRECIPITATION,
160 imperial_suggested_unit=UnitOfPrecipitationDepth.INCHES,
161 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
165 state_class=SensorStateClass.MEASUREMENT,
166 device_class=SensorDeviceClass.PRECIPITATION_INTENSITY,
167 native_unit_of_measurement=UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR,
168 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
171 key=
"relative_humidity",
172 native_unit_of_measurement=PERCENTAGE,
173 device_class=SensorDeviceClass.HUMIDITY,
174 state_class=SensorStateClass.MEASUREMENT,
175 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
179 native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
180 device_class=SensorDeviceClass.SIGNAL_STRENGTH,
181 entity_category=EntityCategory.DIAGNOSTIC,
182 state_class=SensorStateClass.MEASUREMENT,
183 entity_registry_enabled_default=
False,
184 event_subscriptions=[EVENT_STATUS_UPDATE],
185 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
188 key=
"station_pressure",
189 translation_key=
"station_pressure",
190 native_unit_of_measurement=UnitOfPressure.MBAR,
191 device_class=SensorDeviceClass.PRESSURE,
192 state_class=SensorStateClass.MEASUREMENT,
193 suggested_display_precision=5,
194 imperial_suggested_unit=UnitOfPressure.INHG,
195 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
198 key=
"solar_radiation",
199 native_unit_of_measurement=UnitOfIrradiance.WATTS_PER_SQUARE_METER,
200 device_class=SensorDeviceClass.IRRADIANCE,
201 state_class=SensorStateClass.MEASUREMENT,
202 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
206 translation_key=
"uptime",
207 device_class=SensorDeviceClass.TIMESTAMP,
208 entity_category=EntityCategory.DIAGNOSTIC,
209 entity_registry_enabled_default=
False,
210 event_subscriptions=[EVENT_STATUS_UPDATE],
211 raw_data_conv_fn=
lambda raw_data: raw_data,
215 translation_key=
"uv_index",
216 native_unit_of_measurement=UV_INDEX,
217 state_class=SensorStateClass.MEASUREMENT,
218 raw_data_conv_fn=
lambda raw_data: raw_data,
221 key=
"vapor_pressure",
222 translation_key=
"vapor_pressure",
223 native_unit_of_measurement=UnitOfPressure.MBAR,
224 device_class=SensorDeviceClass.PRESSURE,
225 state_class=SensorStateClass.MEASUREMENT,
226 imperial_suggested_unit=UnitOfPressure.INHG,
227 suggested_display_precision=5,
228 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
233 translation_key=
"wind_gust",
234 device_class=SensorDeviceClass.WIND_SPEED,
235 native_unit_of_measurement=UnitOfSpeed.METERS_PER_SECOND,
236 state_class=SensorStateClass.MEASUREMENT,
237 suggested_display_precision=2,
238 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
242 translation_key=
"wind_lull",
243 device_class=SensorDeviceClass.WIND_SPEED,
244 native_unit_of_measurement=UnitOfSpeed.METERS_PER_SECOND,
245 state_class=SensorStateClass.MEASUREMENT,
246 suggested_display_precision=2,
247 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
251 device_class=SensorDeviceClass.WIND_SPEED,
252 event_subscriptions=[EVENT_RAPID_WIND, EVENT_OBSERVATION],
253 native_unit_of_measurement=UnitOfSpeed.METERS_PER_SECOND,
254 state_class=SensorStateClass.MEASUREMENT,
255 suggested_display_precision=2,
256 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
260 translation_key=
"wind_speed_average",
261 device_class=SensorDeviceClass.WIND_SPEED,
262 native_unit_of_measurement=UnitOfSpeed.METERS_PER_SECOND,
263 state_class=SensorStateClass.MEASUREMENT,
264 suggested_display_precision=2,
265 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
268 key=
"wind_direction",
269 translation_key=
"wind_direction",
270 native_unit_of_measurement=DEGREE,
271 state_class=SensorStateClass.MEASUREMENT,
272 event_subscriptions=[EVENT_RAPID_WIND, EVENT_OBSERVATION],
273 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
276 key=
"wind_direction_average",
277 translation_key=
"wind_direction_average",
278 native_unit_of_measurement=DEGREE,
279 state_class=SensorStateClass.MEASUREMENT,
280 raw_data_conv_fn=
lambda raw_data: raw_data.magnitude,
287 config_entry: ConfigEntry,
288 async_add_entities: AddEntitiesCallback,
290 """Set up WeatherFlow sensors using config entry."""
293 def async_add_sensor(device: WeatherFlowDevice) ->
None:
294 """Add WeatherFlow sensor."""
295 LOGGER.debug(
"Adding sensors for %s", device)
297 sensors: list[WeatherFlowSensorEntity] = [
300 description=description,
301 is_metric=(hass.config.units == METRIC_SYSTEM),
303 for description
in SENSORS
304 if hasattr(device, description.key)
309 config_entry.async_on_unload(
319 """Defines a WeatherFlow sensor entity."""
321 entity_description: WeatherFlowSensorEntityDescription
322 _attr_should_poll =
False
323 _attr_has_entity_name =
True
327 device: WeatherFlowDevice,
328 description: WeatherFlowSensorEntityDescription,
329 is_metric: bool =
True,
331 """Initialize a WeatherFlow sensor entity."""
336 identifiers={(DOMAIN, device.serial_number)},
337 manufacturer=
"WeatherFlow",
339 name=device.serial_number,
340 sw_version=device.firmware_revision,
346 if description.imperial_suggested_unit
is not None and not is_metric:
348 description.imperial_suggested_unit
353 """Return the time when the sensor was last reset, if any."""
355 return self.
devicedevice.last_report
359 """Update entity state."""
366 """Subscribe to events."""
datetime|StateType get_native_value(self, WeatherFlowDevice device)
datetime|None last_reset(self)
None async_added_to_hass(self)
_attr_suggested_unit_of_measurement
None _async_update_state(self)
None __init__(self, WeatherFlowDevice device, WeatherFlowSensorEntityDescription description, bool is_metric=True)
None async_write_ha_state(self)
None async_on_remove(self, CALLBACK_TYPE func)
int|float|None get_native_value(data, IstaConsumptionType consumption_type, IstaValueType|None value_type=None)
str format_dispatch_call(ConfigEntry config_entry)
def precipitation_raw_conversion_fn(Enum raw_data)
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)