1 """Support for Buienradar.nl weather service."""
3 from __future__
import annotations
7 from buienradar.constants
import (
17 PRECIPITATION_FORECAST,
28 SensorEntityDescription,
41 UnitOfPrecipitationDepth,
51 from .
import BuienRadarConfigEntry
55 STATE_CONDITION_CODES,
57 STATE_DETAILED_CONDITIONS,
59 from .util
import BrData
61 _LOGGER = logging.getLogger(__name__)
63 MEASURED_LABEL =
"Measured"
64 TIMEFRAME_LABEL =
"Timeframe"
72 STATIONNAME_LABEL =
"Stationname"
74 SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
77 translation_key=
"stationname",
82 translation_key=
"barometerfc",
87 key=
"barometerfcname",
88 translation_key=
"barometerfcname",
93 key=
"barometerfcnamenl",
94 translation_key=
"barometerfcnamenl",
99 translation_key=
"condition",
100 device_class=SensorDeviceClass.ENUM,
101 options=STATE_CONDITIONS,
105 translation_key=
"conditioncode",
106 device_class=SensorDeviceClass.ENUM,
107 options=STATE_CONDITION_CODES,
110 key=
"conditiondetailed",
111 translation_key=
"conditiondetailed",
112 device_class=SensorDeviceClass.ENUM,
113 options=STATE_DETAILED_CONDITIONS,
116 key=
"conditionexact",
117 translation_key=
"conditionexact",
121 translation_key=
"symbol",
125 key=
"feeltemperature",
126 translation_key=
"feeltemperature",
127 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
128 device_class=SensorDeviceClass.TEMPERATURE,
132 device_class=SensorDeviceClass.HUMIDITY,
133 native_unit_of_measurement=PERCENTAGE,
134 icon=
"mdi:water-percent",
135 state_class=SensorStateClass.MEASUREMENT,
139 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
140 device_class=SensorDeviceClass.TEMPERATURE,
141 state_class=SensorStateClass.MEASUREMENT,
144 key=
"groundtemperature",
145 translation_key=
"groundtemperature",
146 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
147 device_class=SensorDeviceClass.TEMPERATURE,
148 state_class=SensorStateClass.MEASUREMENT,
152 native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
153 device_class=SensorDeviceClass.WIND_SPEED,
154 state_class=SensorStateClass.MEASUREMENT,
158 translation_key=
"windforce",
159 native_unit_of_measurement=
"Bft",
160 icon=
"mdi:weather-windy",
164 translation_key=
"winddirection",
165 icon=
"mdi:compass-outline",
169 translation_key=
"windazimuth",
170 native_unit_of_measurement=DEGREE,
171 icon=
"mdi:compass-outline",
175 device_class=SensorDeviceClass.PRESSURE,
176 native_unit_of_measurement=UnitOfPressure.HPA,
178 state_class=SensorStateClass.MEASUREMENT,
182 translation_key=
"visibility",
183 native_unit_of_measurement=UnitOfLength.KILOMETERS,
184 device_class=SensorDeviceClass.DISTANCE,
185 state_class=SensorStateClass.MEASUREMENT,
189 translation_key=
"windgust",
190 native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
191 device_class=SensorDeviceClass.WIND_SPEED,
195 native_unit_of_measurement=UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR,
196 state_class=SensorStateClass.MEASUREMENT,
197 device_class=SensorDeviceClass.PRECIPITATION_INTENSITY,
201 device_class=SensorDeviceClass.IRRADIANCE,
202 native_unit_of_measurement=UnitOfIrradiance.WATTS_PER_SQUARE_METER,
203 state_class=SensorStateClass.MEASUREMENT,
206 key=
"precipitation_forecast_average",
207 translation_key=
"precipitation_forecast_average",
208 native_unit_of_measurement=UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR,
209 device_class=SensorDeviceClass.PRECIPITATION_INTENSITY,
212 key=
"precipitation_forecast_total",
213 translation_key=
"precipitation_forecast_total",
214 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
215 device_class=SensorDeviceClass.PRECIPITATION,
219 key=
"rainlast24hour",
220 translation_key=
"rainlast24hour",
221 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
222 device_class=SensorDeviceClass.PRECIPITATION,
227 translation_key=
"rainlasthour",
228 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
229 device_class=SensorDeviceClass.PRECIPITATION,
232 key=
"temperature_1d",
233 translation_key=
"temperature_1d",
234 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
235 device_class=SensorDeviceClass.TEMPERATURE,
238 key=
"temperature_2d",
239 translation_key=
"temperature_2d",
240 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
241 device_class=SensorDeviceClass.TEMPERATURE,
244 key=
"temperature_3d",
245 translation_key=
"temperature_3d",
246 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
247 device_class=SensorDeviceClass.TEMPERATURE,
250 key=
"temperature_4d",
251 translation_key=
"temperature_4d",
252 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
253 device_class=SensorDeviceClass.TEMPERATURE,
256 key=
"temperature_5d",
257 translation_key=
"temperature_5d",
258 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
259 device_class=SensorDeviceClass.TEMPERATURE,
263 translation_key=
"mintemp_1d",
264 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
265 device_class=SensorDeviceClass.TEMPERATURE,
269 translation_key=
"mintemp_2d",
270 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
271 device_class=SensorDeviceClass.TEMPERATURE,
275 translation_key=
"mintemp_3d",
276 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
277 device_class=SensorDeviceClass.TEMPERATURE,
281 translation_key=
"mintemp_4d",
282 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
283 device_class=SensorDeviceClass.TEMPERATURE,
287 translation_key=
"mintemp_5d",
288 native_unit_of_measurement=UnitOfTemperature.CELSIUS,
289 device_class=SensorDeviceClass.TEMPERATURE,
293 translation_key=
"rain_1d",
294 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
295 device_class=SensorDeviceClass.PRECIPITATION,
299 translation_key=
"rain_2d",
300 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
301 device_class=SensorDeviceClass.PRECIPITATION,
305 translation_key=
"rain_3d",
306 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
307 device_class=SensorDeviceClass.PRECIPITATION,
311 translation_key=
"rain_4d",
312 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
313 device_class=SensorDeviceClass.PRECIPITATION,
317 translation_key=
"rain_5d",
318 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
319 device_class=SensorDeviceClass.PRECIPITATION,
324 translation_key=
"minrain_1d",
325 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
326 device_class=SensorDeviceClass.PRECIPITATION,
330 translation_key=
"minrain_2d",
331 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
332 device_class=SensorDeviceClass.PRECIPITATION,
336 translation_key=
"minrain_3d",
337 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
338 device_class=SensorDeviceClass.PRECIPITATION,
342 translation_key=
"minrain_4d",
343 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
344 device_class=SensorDeviceClass.PRECIPITATION,
348 translation_key=
"minrain_5d",
349 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
350 device_class=SensorDeviceClass.PRECIPITATION,
355 translation_key=
"maxrain_1d",
356 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
357 device_class=SensorDeviceClass.PRECIPITATION,
361 translation_key=
"maxrain_2d",
362 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
363 device_class=SensorDeviceClass.PRECIPITATION,
367 translation_key=
"maxrain_3d",
368 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
369 device_class=SensorDeviceClass.PRECIPITATION,
373 translation_key=
"maxrain_4d",
374 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
375 device_class=SensorDeviceClass.PRECIPITATION,
379 translation_key=
"maxrain_5d",
380 native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
381 device_class=SensorDeviceClass.PRECIPITATION,
385 translation_key=
"rainchance_1d",
386 native_unit_of_measurement=PERCENTAGE,
387 icon=
"mdi:weather-pouring",
391 translation_key=
"rainchance_2d",
392 native_unit_of_measurement=PERCENTAGE,
393 icon=
"mdi:weather-pouring",
397 translation_key=
"rainchance_3d",
398 native_unit_of_measurement=PERCENTAGE,
399 icon=
"mdi:weather-pouring",
403 translation_key=
"rainchance_4d",
404 native_unit_of_measurement=PERCENTAGE,
405 icon=
"mdi:weather-pouring",
409 translation_key=
"rainchance_5d",
410 native_unit_of_measurement=PERCENTAGE,
411 icon=
"mdi:weather-pouring",
415 translation_key=
"sunchance_1d",
416 native_unit_of_measurement=PERCENTAGE,
417 icon=
"mdi:weather-partly-cloudy",
421 translation_key=
"sunchance_2d",
422 native_unit_of_measurement=PERCENTAGE,
423 icon=
"mdi:weather-partly-cloudy",
427 translation_key=
"sunchance_3d",
428 native_unit_of_measurement=PERCENTAGE,
429 icon=
"mdi:weather-partly-cloudy",
433 translation_key=
"sunchance_4d",
434 native_unit_of_measurement=PERCENTAGE,
435 icon=
"mdi:weather-partly-cloudy",
439 translation_key=
"sunchance_5d",
440 native_unit_of_measurement=PERCENTAGE,
441 icon=
"mdi:weather-partly-cloudy",
445 translation_key=
"windforce_1d",
446 native_unit_of_measurement=
"Bft",
447 icon=
"mdi:weather-windy",
451 translation_key=
"windforce_2d",
452 native_unit_of_measurement=
"Bft",
453 icon=
"mdi:weather-windy",
457 translation_key=
"windforce_3d",
458 native_unit_of_measurement=
"Bft",
459 icon=
"mdi:weather-windy",
463 translation_key=
"windforce_4d",
464 native_unit_of_measurement=
"Bft",
465 icon=
"mdi:weather-windy",
469 translation_key=
"windforce_5d",
470 native_unit_of_measurement=
"Bft",
471 icon=
"mdi:weather-windy",
475 translation_key=
"windspeed_1d",
476 native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
477 device_class=SensorDeviceClass.WIND_SPEED,
481 translation_key=
"windspeed_2d",
482 native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
483 device_class=SensorDeviceClass.WIND_SPEED,
487 translation_key=
"windspeed_3d",
488 native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
489 device_class=SensorDeviceClass.WIND_SPEED,
493 translation_key=
"windspeed_4d",
494 native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
495 device_class=SensorDeviceClass.WIND_SPEED,
499 translation_key=
"windspeed_5d",
500 native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
501 device_class=SensorDeviceClass.WIND_SPEED,
504 key=
"winddirection_1d",
505 translation_key=
"winddirection_1d",
506 icon=
"mdi:compass-outline",
509 key=
"winddirection_2d",
510 translation_key=
"winddirection_2d",
511 icon=
"mdi:compass-outline",
514 key=
"winddirection_3d",
515 translation_key=
"winddirection_3d",
516 icon=
"mdi:compass-outline",
519 key=
"winddirection_4d",
520 translation_key=
"winddirection_4d",
521 icon=
"mdi:compass-outline",
524 key=
"winddirection_5d",
525 translation_key=
"winddirection_5d",
526 icon=
"mdi:compass-outline",
529 key=
"windazimuth_1d",
530 translation_key=
"windazimuth_1d",
531 native_unit_of_measurement=DEGREE,
532 icon=
"mdi:compass-outline",
535 key=
"windazimuth_2d",
536 translation_key=
"windazimuth_2d",
537 native_unit_of_measurement=DEGREE,
538 icon=
"mdi:compass-outline",
541 key=
"windazimuth_3d",
542 translation_key=
"windazimuth_3d",
543 native_unit_of_measurement=DEGREE,
544 icon=
"mdi:compass-outline",
547 key=
"windazimuth_4d",
548 translation_key=
"windazimuth_4d",
549 native_unit_of_measurement=DEGREE,
550 icon=
"mdi:compass-outline",
553 key=
"windazimuth_5d",
554 translation_key=
"windazimuth_5d",
555 native_unit_of_measurement=DEGREE,
556 icon=
"mdi:compass-outline",
560 translation_key=
"condition_1d",
561 device_class=SensorDeviceClass.ENUM,
562 options=STATE_CONDITIONS,
566 translation_key=
"condition_2d",
567 device_class=SensorDeviceClass.ENUM,
568 options=STATE_CONDITIONS,
572 translation_key=
"condition_3d",
573 device_class=SensorDeviceClass.ENUM,
574 options=STATE_CONDITIONS,
578 translation_key=
"condition_4d",
579 device_class=SensorDeviceClass.ENUM,
580 options=STATE_CONDITIONS,
584 translation_key=
"condition_5d",
585 device_class=SensorDeviceClass.ENUM,
586 options=STATE_CONDITIONS,
589 key=
"conditioncode_1d",
590 translation_key=
"conditioncode_1d",
591 device_class=SensorDeviceClass.ENUM,
592 options=STATE_CONDITION_CODES,
595 key=
"conditioncode_2d",
596 translation_key=
"conditioncode_2d",
597 device_class=SensorDeviceClass.ENUM,
598 options=STATE_CONDITION_CODES,
601 key=
"conditioncode_3d",
602 translation_key=
"conditioncode_3d",
603 device_class=SensorDeviceClass.ENUM,
604 options=STATE_CONDITION_CODES,
607 key=
"conditioncode_4d",
608 translation_key=
"conditioncode_4d",
609 device_class=SensorDeviceClass.ENUM,
610 options=STATE_CONDITION_CODES,
613 key=
"conditioncode_5d",
614 translation_key=
"conditioncode_5d",
615 device_class=SensorDeviceClass.ENUM,
616 options=STATE_CONDITION_CODES,
619 key=
"conditiondetailed_1d",
620 translation_key=
"conditiondetailed_1d",
621 device_class=SensorDeviceClass.ENUM,
622 options=STATE_DETAILED_CONDITIONS,
625 key=
"conditiondetailed_2d",
626 translation_key=
"conditiondetailed_2d",
627 device_class=SensorDeviceClass.ENUM,
628 options=STATE_DETAILED_CONDITIONS,
631 key=
"conditiondetailed_3d",
632 translation_key=
"conditiondetailed_3d",
633 device_class=SensorDeviceClass.ENUM,
634 options=STATE_DETAILED_CONDITIONS,
637 key=
"conditiondetailed_4d",
638 translation_key=
"conditiondetailed_4d",
639 device_class=SensorDeviceClass.ENUM,
640 options=STATE_DETAILED_CONDITIONS,
643 key=
"conditiondetailed_5d",
644 translation_key=
"conditiondetailed_5d",
645 device_class=SensorDeviceClass.ENUM,
646 options=STATE_DETAILED_CONDITIONS,
649 key=
"conditionexact_1d",
650 translation_key=
"conditionexact_1d",
653 key=
"conditionexact_2d",
654 translation_key=
"conditionexact_2d",
657 key=
"conditionexact_3d",
658 translation_key=
"conditionexact_3d",
661 key=
"conditionexact_4d",
662 translation_key=
"conditionexact_4d",
665 key=
"conditionexact_5d",
666 translation_key=
"conditionexact_5d",
670 translation_key=
"symbol_1d",
674 translation_key=
"symbol_2d",
678 translation_key=
"symbol_3d",
682 translation_key=
"symbol_4d",
686 translation_key=
"symbol_5d",
693 entry: BuienRadarConfigEntry,
694 async_add_entities: AddEntitiesCallback,
696 """Create the buienradar sensor."""
698 options = entry.options
700 latitude = config.get(CONF_LATITUDE, hass.config.latitude)
701 longitude = config.get(CONF_LONGITUDE, hass.config.longitude)
703 timeframe = options.get(
704 CONF_TIMEFRAME, config.get(CONF_TIMEFRAME, DEFAULT_TIMEFRAME)
707 if None in (latitude, longitude):
708 _LOGGER.error(
"Latitude or longitude not set in Home Assistant config")
711 coordinates = {CONF_LATITUDE:
float(latitude), CONF_LONGITUDE:
float(longitude)}
714 "Initializing buienradar sensor coordinate %s, timeframe %s",
721 BrSensor(config.get(CONF_NAME,
"Buienradar"), coordinates, description)
722 for description
in SENSOR_TYPES
726 data =
BrData(hass, coordinates, timeframe, entities)
727 entry.runtime_data[Platform.SENSOR] = data
728 await data.async_update()
734 """Representation of a Buienradar sensor."""
736 _attr_entity_registry_enabled_default =
False
737 _attr_should_poll =
False
738 _attr_has_entity_name =
True
741 self, client_name, coordinates, description: SensorEntityDescription
743 """Initialize the sensor."""
745 self.
_data_data: BrData |
None =
None
748 f
"{coordinates[CONF_LATITUDE]:2.6f}{coordinates[CONF_LONGITUDE]:2.6f}"
754 description.key != SYMBOL
and not description.key.startswith(CONDITION)
757 if description.key.startswith(PRECIPITATION_FORECAST):
761 """Handle entity being added to hass."""
762 if self.
_data_data
is None:
768 """Handle data update."""
770 if not self.
hasshass:
775 """Update sensor data."""
776 _LOGGER.debug(
"Updating sensor %s", self.
entity_identity_id)
782 """Load the sensor with relevant data."""
785 if self.
_measured_measured == data.get(MEASURED):
788 self.
_measured_measured = data.get(MEASURED)
791 if sensor_type.endswith((
"_1d",
"_2d",
"_3d",
"_4d",
"_5d")):
794 if sensor_type.endswith(
"_2d"):
796 if sensor_type.endswith(
"_3d"):
798 if sensor_type.endswith(
"_4d"):
800 if sensor_type.endswith(
"_5d"):
804 if sensor_type.startswith((SYMBOL, CONDITION)):
806 condition = data.get(FORECAST)[fcday].
get(CONDITION)
808 _LOGGER.warning(
"No forecast for fcday=%s", fcday)
812 new_state = condition.get(CONDITION)
813 if sensor_type.startswith(SYMBOL):
814 new_state = condition.get(EXACTNL)
815 if sensor_type.startswith(
"conditioncode"):
816 new_state = condition.get(CONDCODE)
817 if sensor_type.startswith(
"conditiondetailed"):
818 new_state = condition.get(DETAILED)
819 if sensor_type.startswith(
"conditionexact"):
820 new_state = condition.get(EXACT)
822 img = condition.get(IMAGE)
830 if sensor_type.startswith(WINDSPEED):
837 _LOGGER.warning(
"No forecast for fcday=%s", fcday)
850 _LOGGER.warning(
"No forecast for fcday=%s", fcday)
854 if sensor_type == SYMBOL
or sensor_type.startswith(CONDITION):
856 if condition := data.get(CONDITION):
857 if sensor_type == SYMBOL:
858 new_state = condition.get(EXACTNL)
859 if sensor_type == CONDITION:
860 new_state = condition.get(CONDITION)
861 if sensor_type ==
"conditioncode":
862 new_state = condition.get(CONDCODE)
863 if sensor_type ==
"conditiondetailed":
864 new_state = condition.get(DETAILED)
865 if sensor_type ==
"conditionexact":
866 new_state = condition.get(EXACT)
868 img = condition.get(IMAGE)
877 if sensor_type.startswith(PRECIPITATION_FORECAST):
879 nested = data.get(PRECIPITATION_FORECAST)
880 self.
_timeframe_timeframe = nested.get(TIMEFRAME)
882 sensor_type[len(PRECIPITATION_FORECAST) + 1 :]
886 if sensor_type
in [WINDSPEED, WINDGUST]:
893 if sensor_type == VISIBILITY:
902 if sensor_type.startswith(PRECIPITATION_FORECAST):
903 result = {ATTR_ATTRIBUTION: data.get(ATTRIBUTION)}
905 result[TIMEFRAME_LABEL] = f
"{self._timeframe} min"
910 ATTR_ATTRIBUTION: data.get(ATTRIBUTION),
911 STATIONNAME_LABEL: data.get(STATIONNAME),
915 local_dt = dt_util.as_local(self.
_measured_measured)
916 result[MEASURED_LABEL] = local_dt.strftime(
"%c")
None async_added_to_hass(self)
def _load_data(self, data)
_attr_extra_state_attributes
def data_updated(self, BrData data)
None __init__(self, client_name, coordinates, SensorEntityDescription description)
str|None entity_picture(self)
None async_write_ha_state(self)
None async_setup_entry(HomeAssistant hass, BuienRadarConfigEntry entry, AddEntitiesCallback async_add_entities)
web.Response get(self, web.Request request, str config_key)