Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Support for Buienradar.nl weather service."""
2 
3 from __future__ import annotations
4 
5 import logging
6 
7 from buienradar.constants import (
8  ATTRIBUTION,
9  CONDCODE,
10  CONDITION,
11  DETAILED,
12  EXACT,
13  EXACTNL,
14  FORECAST,
15  IMAGE,
16  MEASURED,
17  PRECIPITATION_FORECAST,
18  STATIONNAME,
19  TIMEFRAME,
20  VISIBILITY,
21  WINDGUST,
22  WINDSPEED,
23 )
24 
26  SensorDeviceClass,
27  SensorEntity,
28  SensorEntityDescription,
29  SensorStateClass,
30 )
31 from homeassistant.const import (
32  ATTR_ATTRIBUTION,
33  CONF_LATITUDE,
34  CONF_LONGITUDE,
35  CONF_NAME,
36  DEGREE,
37  PERCENTAGE,
38  Platform,
39  UnitOfIrradiance,
40  UnitOfLength,
41  UnitOfPrecipitationDepth,
42  UnitOfPressure,
43  UnitOfSpeed,
44  UnitOfTemperature,
45  UnitOfVolumetricFlux,
46 )
47 from homeassistant.core import HomeAssistant, callback
48 from homeassistant.helpers.entity_platform import AddEntitiesCallback
49 from homeassistant.util import dt as dt_util
50 
51 from . import BuienRadarConfigEntry
52 from .const import (
53  CONF_TIMEFRAME,
54  DEFAULT_TIMEFRAME,
55  STATE_CONDITION_CODES,
56  STATE_CONDITIONS,
57  STATE_DETAILED_CONDITIONS,
58 )
59 from .util import BrData
60 
61 _LOGGER = logging.getLogger(__name__)
62 
63 MEASURED_LABEL = "Measured"
64 TIMEFRAME_LABEL = "Timeframe"
65 SYMBOL = "symbol"
66 
67 # Schedule next call after (minutes):
68 SCHEDULE_OK = 10
69 # When an error occurred, new call after (minutes):
70 SCHEDULE_NOK = 2
71 
72 STATIONNAME_LABEL = "Stationname"
73 
74 SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
76  key="stationname",
77  translation_key="stationname",
78  ),
79  # new in json api (>1.0.0):
81  key="barometerfc",
82  translation_key="barometerfc",
83  icon="mdi:gauge",
84  ),
85  # new in json api (>1.0.0):
87  key="barometerfcname",
88  translation_key="barometerfcname",
89  icon="mdi:gauge",
90  ),
91  # new in json api (>1.0.0):
93  key="barometerfcnamenl",
94  translation_key="barometerfcnamenl",
95  icon="mdi:gauge",
96  ),
98  key="condition",
99  translation_key="condition",
100  device_class=SensorDeviceClass.ENUM,
101  options=STATE_CONDITIONS,
102  ),
104  key="conditioncode",
105  translation_key="conditioncode",
106  device_class=SensorDeviceClass.ENUM,
107  options=STATE_CONDITION_CODES,
108  ),
110  key="conditiondetailed",
111  translation_key="conditiondetailed",
112  device_class=SensorDeviceClass.ENUM,
113  options=STATE_DETAILED_CONDITIONS,
114  ),
116  key="conditionexact",
117  translation_key="conditionexact",
118  ),
120  key="symbol",
121  translation_key="symbol",
122  ),
123  # new in json api (>1.0.0):
125  key="feeltemperature",
126  translation_key="feeltemperature",
127  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
128  device_class=SensorDeviceClass.TEMPERATURE,
129  ),
131  key="humidity",
132  device_class=SensorDeviceClass.HUMIDITY,
133  native_unit_of_measurement=PERCENTAGE,
134  icon="mdi:water-percent",
135  state_class=SensorStateClass.MEASUREMENT,
136  ),
138  key="temperature",
139  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
140  device_class=SensorDeviceClass.TEMPERATURE,
141  state_class=SensorStateClass.MEASUREMENT,
142  ),
144  key="groundtemperature",
145  translation_key="groundtemperature",
146  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
147  device_class=SensorDeviceClass.TEMPERATURE,
148  state_class=SensorStateClass.MEASUREMENT,
149  ),
151  key="windspeed",
152  native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
153  device_class=SensorDeviceClass.WIND_SPEED,
154  state_class=SensorStateClass.MEASUREMENT,
155  ),
157  key="windforce",
158  translation_key="windforce",
159  native_unit_of_measurement="Bft",
160  icon="mdi:weather-windy",
161  ),
163  key="winddirection",
164  translation_key="winddirection",
165  icon="mdi:compass-outline",
166  ),
168  key="windazimuth",
169  translation_key="windazimuth",
170  native_unit_of_measurement=DEGREE,
171  icon="mdi:compass-outline",
172  ),
174  key="pressure",
175  device_class=SensorDeviceClass.PRESSURE,
176  native_unit_of_measurement=UnitOfPressure.HPA,
177  icon="mdi:gauge",
178  state_class=SensorStateClass.MEASUREMENT,
179  ),
181  key="visibility",
182  translation_key="visibility",
183  native_unit_of_measurement=UnitOfLength.KILOMETERS,
184  device_class=SensorDeviceClass.DISTANCE,
185  state_class=SensorStateClass.MEASUREMENT,
186  ),
188  key="windgust",
189  translation_key="windgust",
190  native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
191  device_class=SensorDeviceClass.WIND_SPEED,
192  ),
194  key="precipitation",
195  native_unit_of_measurement=UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR,
196  state_class=SensorStateClass.MEASUREMENT,
197  device_class=SensorDeviceClass.PRECIPITATION_INTENSITY,
198  ),
200  key="irradiance",
201  device_class=SensorDeviceClass.IRRADIANCE,
202  native_unit_of_measurement=UnitOfIrradiance.WATTS_PER_SQUARE_METER,
203  state_class=SensorStateClass.MEASUREMENT,
204  ),
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,
210  ),
212  key="precipitation_forecast_total",
213  translation_key="precipitation_forecast_total",
214  native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
215  device_class=SensorDeviceClass.PRECIPITATION,
216  ),
217  # new in json api (>1.0.0):
219  key="rainlast24hour",
220  translation_key="rainlast24hour",
221  native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
222  device_class=SensorDeviceClass.PRECIPITATION,
223  ),
224  # new in json api (>1.0.0):
226  key="rainlasthour",
227  translation_key="rainlasthour",
228  native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
229  device_class=SensorDeviceClass.PRECIPITATION,
230  ),
232  key="temperature_1d",
233  translation_key="temperature_1d",
234  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
235  device_class=SensorDeviceClass.TEMPERATURE,
236  ),
238  key="temperature_2d",
239  translation_key="temperature_2d",
240  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
241  device_class=SensorDeviceClass.TEMPERATURE,
242  ),
244  key="temperature_3d",
245  translation_key="temperature_3d",
246  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
247  device_class=SensorDeviceClass.TEMPERATURE,
248  ),
250  key="temperature_4d",
251  translation_key="temperature_4d",
252  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
253  device_class=SensorDeviceClass.TEMPERATURE,
254  ),
256  key="temperature_5d",
257  translation_key="temperature_5d",
258  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
259  device_class=SensorDeviceClass.TEMPERATURE,
260  ),
262  key="mintemp_1d",
263  translation_key="mintemp_1d",
264  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
265  device_class=SensorDeviceClass.TEMPERATURE,
266  ),
268  key="mintemp_2d",
269  translation_key="mintemp_2d",
270  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
271  device_class=SensorDeviceClass.TEMPERATURE,
272  ),
274  key="mintemp_3d",
275  translation_key="mintemp_3d",
276  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
277  device_class=SensorDeviceClass.TEMPERATURE,
278  ),
280  key="mintemp_4d",
281  translation_key="mintemp_4d",
282  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
283  device_class=SensorDeviceClass.TEMPERATURE,
284  ),
286  key="mintemp_5d",
287  translation_key="mintemp_5d",
288  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
289  device_class=SensorDeviceClass.TEMPERATURE,
290  ),
292  key="rain_1d",
293  translation_key="rain_1d",
294  native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
295  device_class=SensorDeviceClass.PRECIPITATION,
296  ),
298  key="rain_2d",
299  translation_key="rain_2d",
300  native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
301  device_class=SensorDeviceClass.PRECIPITATION,
302  ),
304  key="rain_3d",
305  translation_key="rain_3d",
306  native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
307  device_class=SensorDeviceClass.PRECIPITATION,
308  ),
310  key="rain_4d",
311  translation_key="rain_4d",
312  native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
313  device_class=SensorDeviceClass.PRECIPITATION,
314  ),
316  key="rain_5d",
317  translation_key="rain_5d",
318  native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
319  device_class=SensorDeviceClass.PRECIPITATION,
320  ),
321  # new in json api (>1.0.0):
323  key="minrain_1d",
324  translation_key="minrain_1d",
325  native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
326  device_class=SensorDeviceClass.PRECIPITATION,
327  ),
329  key="minrain_2d",
330  translation_key="minrain_2d",
331  native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
332  device_class=SensorDeviceClass.PRECIPITATION,
333  ),
335  key="minrain_3d",
336  translation_key="minrain_3d",
337  native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
338  device_class=SensorDeviceClass.PRECIPITATION,
339  ),
341  key="minrain_4d",
342  translation_key="minrain_4d",
343  native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
344  device_class=SensorDeviceClass.PRECIPITATION,
345  ),
347  key="minrain_5d",
348  translation_key="minrain_5d",
349  native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
350  device_class=SensorDeviceClass.PRECIPITATION,
351  ),
352  # new in json api (>1.0.0):
354  key="maxrain_1d",
355  translation_key="maxrain_1d",
356  native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
357  device_class=SensorDeviceClass.PRECIPITATION,
358  ),
360  key="maxrain_2d",
361  translation_key="maxrain_2d",
362  native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
363  device_class=SensorDeviceClass.PRECIPITATION,
364  ),
366  key="maxrain_3d",
367  translation_key="maxrain_3d",
368  native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
369  device_class=SensorDeviceClass.PRECIPITATION,
370  ),
372  key="maxrain_4d",
373  translation_key="maxrain_4d",
374  native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
375  device_class=SensorDeviceClass.PRECIPITATION,
376  ),
378  key="maxrain_5d",
379  translation_key="maxrain_5d",
380  native_unit_of_measurement=UnitOfPrecipitationDepth.MILLIMETERS,
381  device_class=SensorDeviceClass.PRECIPITATION,
382  ),
384  key="rainchance_1d",
385  translation_key="rainchance_1d",
386  native_unit_of_measurement=PERCENTAGE,
387  icon="mdi:weather-pouring",
388  ),
390  key="rainchance_2d",
391  translation_key="rainchance_2d",
392  native_unit_of_measurement=PERCENTAGE,
393  icon="mdi:weather-pouring",
394  ),
396  key="rainchance_3d",
397  translation_key="rainchance_3d",
398  native_unit_of_measurement=PERCENTAGE,
399  icon="mdi:weather-pouring",
400  ),
402  key="rainchance_4d",
403  translation_key="rainchance_4d",
404  native_unit_of_measurement=PERCENTAGE,
405  icon="mdi:weather-pouring",
406  ),
408  key="rainchance_5d",
409  translation_key="rainchance_5d",
410  native_unit_of_measurement=PERCENTAGE,
411  icon="mdi:weather-pouring",
412  ),
414  key="sunchance_1d",
415  translation_key="sunchance_1d",
416  native_unit_of_measurement=PERCENTAGE,
417  icon="mdi:weather-partly-cloudy",
418  ),
420  key="sunchance_2d",
421  translation_key="sunchance_2d",
422  native_unit_of_measurement=PERCENTAGE,
423  icon="mdi:weather-partly-cloudy",
424  ),
426  key="sunchance_3d",
427  translation_key="sunchance_3d",
428  native_unit_of_measurement=PERCENTAGE,
429  icon="mdi:weather-partly-cloudy",
430  ),
432  key="sunchance_4d",
433  translation_key="sunchance_4d",
434  native_unit_of_measurement=PERCENTAGE,
435  icon="mdi:weather-partly-cloudy",
436  ),
438  key="sunchance_5d",
439  translation_key="sunchance_5d",
440  native_unit_of_measurement=PERCENTAGE,
441  icon="mdi:weather-partly-cloudy",
442  ),
444  key="windforce_1d",
445  translation_key="windforce_1d",
446  native_unit_of_measurement="Bft",
447  icon="mdi:weather-windy",
448  ),
450  key="windforce_2d",
451  translation_key="windforce_2d",
452  native_unit_of_measurement="Bft",
453  icon="mdi:weather-windy",
454  ),
456  key="windforce_3d",
457  translation_key="windforce_3d",
458  native_unit_of_measurement="Bft",
459  icon="mdi:weather-windy",
460  ),
462  key="windforce_4d",
463  translation_key="windforce_4d",
464  native_unit_of_measurement="Bft",
465  icon="mdi:weather-windy",
466  ),
468  key="windforce_5d",
469  translation_key="windforce_5d",
470  native_unit_of_measurement="Bft",
471  icon="mdi:weather-windy",
472  ),
474  key="windspeed_1d",
475  translation_key="windspeed_1d",
476  native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
477  device_class=SensorDeviceClass.WIND_SPEED,
478  ),
480  key="windspeed_2d",
481  translation_key="windspeed_2d",
482  native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
483  device_class=SensorDeviceClass.WIND_SPEED,
484  ),
486  key="windspeed_3d",
487  translation_key="windspeed_3d",
488  native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
489  device_class=SensorDeviceClass.WIND_SPEED,
490  ),
492  key="windspeed_4d",
493  translation_key="windspeed_4d",
494  native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
495  device_class=SensorDeviceClass.WIND_SPEED,
496  ),
498  key="windspeed_5d",
499  translation_key="windspeed_5d",
500  native_unit_of_measurement=UnitOfSpeed.KILOMETERS_PER_HOUR,
501  device_class=SensorDeviceClass.WIND_SPEED,
502  ),
504  key="winddirection_1d",
505  translation_key="winddirection_1d",
506  icon="mdi:compass-outline",
507  ),
509  key="winddirection_2d",
510  translation_key="winddirection_2d",
511  icon="mdi:compass-outline",
512  ),
514  key="winddirection_3d",
515  translation_key="winddirection_3d",
516  icon="mdi:compass-outline",
517  ),
519  key="winddirection_4d",
520  translation_key="winddirection_4d",
521  icon="mdi:compass-outline",
522  ),
524  key="winddirection_5d",
525  translation_key="winddirection_5d",
526  icon="mdi:compass-outline",
527  ),
529  key="windazimuth_1d",
530  translation_key="windazimuth_1d",
531  native_unit_of_measurement=DEGREE,
532  icon="mdi:compass-outline",
533  ),
535  key="windazimuth_2d",
536  translation_key="windazimuth_2d",
537  native_unit_of_measurement=DEGREE,
538  icon="mdi:compass-outline",
539  ),
541  key="windazimuth_3d",
542  translation_key="windazimuth_3d",
543  native_unit_of_measurement=DEGREE,
544  icon="mdi:compass-outline",
545  ),
547  key="windazimuth_4d",
548  translation_key="windazimuth_4d",
549  native_unit_of_measurement=DEGREE,
550  icon="mdi:compass-outline",
551  ),
553  key="windazimuth_5d",
554  translation_key="windazimuth_5d",
555  native_unit_of_measurement=DEGREE,
556  icon="mdi:compass-outline",
557  ),
559  key="condition_1d",
560  translation_key="condition_1d",
561  device_class=SensorDeviceClass.ENUM,
562  options=STATE_CONDITIONS,
563  ),
565  key="condition_2d",
566  translation_key="condition_2d",
567  device_class=SensorDeviceClass.ENUM,
568  options=STATE_CONDITIONS,
569  ),
571  key="condition_3d",
572  translation_key="condition_3d",
573  device_class=SensorDeviceClass.ENUM,
574  options=STATE_CONDITIONS,
575  ),
577  key="condition_4d",
578  translation_key="condition_4d",
579  device_class=SensorDeviceClass.ENUM,
580  options=STATE_CONDITIONS,
581  ),
583  key="condition_5d",
584  translation_key="condition_5d",
585  device_class=SensorDeviceClass.ENUM,
586  options=STATE_CONDITIONS,
587  ),
589  key="conditioncode_1d",
590  translation_key="conditioncode_1d",
591  device_class=SensorDeviceClass.ENUM,
592  options=STATE_CONDITION_CODES,
593  ),
595  key="conditioncode_2d",
596  translation_key="conditioncode_2d",
597  device_class=SensorDeviceClass.ENUM,
598  options=STATE_CONDITION_CODES,
599  ),
601  key="conditioncode_3d",
602  translation_key="conditioncode_3d",
603  device_class=SensorDeviceClass.ENUM,
604  options=STATE_CONDITION_CODES,
605  ),
607  key="conditioncode_4d",
608  translation_key="conditioncode_4d",
609  device_class=SensorDeviceClass.ENUM,
610  options=STATE_CONDITION_CODES,
611  ),
613  key="conditioncode_5d",
614  translation_key="conditioncode_5d",
615  device_class=SensorDeviceClass.ENUM,
616  options=STATE_CONDITION_CODES,
617  ),
619  key="conditiondetailed_1d",
620  translation_key="conditiondetailed_1d",
621  device_class=SensorDeviceClass.ENUM,
622  options=STATE_DETAILED_CONDITIONS,
623  ),
625  key="conditiondetailed_2d",
626  translation_key="conditiondetailed_2d",
627  device_class=SensorDeviceClass.ENUM,
628  options=STATE_DETAILED_CONDITIONS,
629  ),
631  key="conditiondetailed_3d",
632  translation_key="conditiondetailed_3d",
633  device_class=SensorDeviceClass.ENUM,
634  options=STATE_DETAILED_CONDITIONS,
635  ),
637  key="conditiondetailed_4d",
638  translation_key="conditiondetailed_4d",
639  device_class=SensorDeviceClass.ENUM,
640  options=STATE_DETAILED_CONDITIONS,
641  ),
643  key="conditiondetailed_5d",
644  translation_key="conditiondetailed_5d",
645  device_class=SensorDeviceClass.ENUM,
646  options=STATE_DETAILED_CONDITIONS,
647  ),
649  key="conditionexact_1d",
650  translation_key="conditionexact_1d",
651  ),
653  key="conditionexact_2d",
654  translation_key="conditionexact_2d",
655  ),
657  key="conditionexact_3d",
658  translation_key="conditionexact_3d",
659  ),
661  key="conditionexact_4d",
662  translation_key="conditionexact_4d",
663  ),
665  key="conditionexact_5d",
666  translation_key="conditionexact_5d",
667  ),
669  key="symbol_1d",
670  translation_key="symbol_1d",
671  ),
673  key="symbol_2d",
674  translation_key="symbol_2d",
675  ),
677  key="symbol_3d",
678  translation_key="symbol_3d",
679  ),
681  key="symbol_4d",
682  translation_key="symbol_4d",
683  ),
685  key="symbol_5d",
686  translation_key="symbol_5d",
687  ),
688 )
689 
690 
692  hass: HomeAssistant,
693  entry: BuienRadarConfigEntry,
694  async_add_entities: AddEntitiesCallback,
695 ) -> None:
696  """Create the buienradar sensor."""
697  config = entry.data
698  options = entry.options
699 
700  latitude = config.get(CONF_LATITUDE, hass.config.latitude)
701  longitude = config.get(CONF_LONGITUDE, hass.config.longitude)
702 
703  timeframe = options.get(
704  CONF_TIMEFRAME, config.get(CONF_TIMEFRAME, DEFAULT_TIMEFRAME)
705  )
706 
707  if None in (latitude, longitude):
708  _LOGGER.error("Latitude or longitude not set in Home Assistant config")
709  return
710 
711  coordinates = {CONF_LATITUDE: float(latitude), CONF_LONGITUDE: float(longitude)}
712 
713  _LOGGER.debug(
714  "Initializing buienradar sensor coordinate %s, timeframe %s",
715  coordinates,
716  timeframe,
717  )
718 
719  # create weather entities:
720  entities = [
721  BrSensor(config.get(CONF_NAME, "Buienradar"), coordinates, description)
722  for description in SENSOR_TYPES
723  ]
724 
725  # create weather data:
726  data = BrData(hass, coordinates, timeframe, entities)
727  entry.runtime_data[Platform.SENSOR] = data
728  await data.async_update()
729 
730  async_add_entities(entities)
731 
732 
734  """Representation of a Buienradar sensor."""
735 
736  _attr_entity_registry_enabled_default = False
737  _attr_should_poll = False
738  _attr_has_entity_name = True
739 
740  def __init__(
741  self, client_name, coordinates, description: SensorEntityDescription
742  ) -> None:
743  """Initialize the sensor."""
744  self.entity_descriptionentity_description = description
745  self._data_data: BrData | None = None
746  self._measured_measured = None
747  self._attr_unique_id_attr_unique_id = (
748  f"{coordinates[CONF_LATITUDE]:2.6f}{coordinates[CONF_LONGITUDE]:2.6f}"
749  f"{description.key}"
750  )
751 
752  # All continuous sensors should be forced to be updated
753  self._attr_force_update_attr_force_update = (
754  description.key != SYMBOL and not description.key.startswith(CONDITION)
755  )
756 
757  if description.key.startswith(PRECIPITATION_FORECAST):
758  self._timeframe_timeframe = None
759 
760  async def async_added_to_hass(self) -> None:
761  """Handle entity being added to hass."""
762  if self._data_data is None:
763  return
764  self._update_update()
765 
766  @callback
767  def data_updated(self, data: BrData):
768  """Handle data update."""
769  self._data_data = data
770  if not self.hasshass:
771  return
772  self._update_update()
773 
774  def _update(self):
775  """Update sensor data."""
776  _LOGGER.debug("Updating sensor %s", self.entity_identity_id)
777  if self._load_data_load_data(self._data_data.data):
778  self.async_write_ha_stateasync_write_ha_state()
779 
780  @callback
781  def _load_data(self, data): # noqa: C901
782  """Load the sensor with relevant data."""
783  # Check if we have a new measurement,
784  # otherwise we do not have to update the sensor
785  if self._measured_measured == data.get(MEASURED):
786  return False
787 
788  self._measured_measured = data.get(MEASURED)
789  sensor_type = self.entity_descriptionentity_description.key
790 
791  if sensor_type.endswith(("_1d", "_2d", "_3d", "_4d", "_5d")):
792  # update forecasting sensors:
793  fcday = 0
794  if sensor_type.endswith("_2d"):
795  fcday = 1
796  if sensor_type.endswith("_3d"):
797  fcday = 2
798  if sensor_type.endswith("_4d"):
799  fcday = 3
800  if sensor_type.endswith("_5d"):
801  fcday = 4
802 
803  # update weather symbol & status text
804  if sensor_type.startswith((SYMBOL, CONDITION)):
805  try:
806  condition = data.get(FORECAST)[fcday].get(CONDITION)
807  except IndexError:
808  _LOGGER.warning("No forecast for fcday=%s", fcday)
809  return False
810 
811  if condition:
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)
821 
822  img = condition.get(IMAGE)
823 
824  if new_state != self.statestatestate or img != self.entity_pictureentity_picture:
825  self._attr_native_value_attr_native_value = new_state
826  self._attr_entity_picture_attr_entity_picture = img
827  return True
828  return False
829 
830  if sensor_type.startswith(WINDSPEED):
831  # hass wants windspeeds in km/h not m/s, so convert:
832  try:
833  self._attr_native_value_attr_native_value = data.get(FORECAST)[fcday].get(
834  sensor_type[:-3]
835  )
836  except IndexError:
837  _LOGGER.warning("No forecast for fcday=%s", fcday)
838  return False
839 
840  if self.statestatestate is not None:
841  self._attr_native_value_attr_native_value = round(self.statestatestate * 3.6, 1)
842  return True
843 
844  # update all other sensors
845  try:
846  self._attr_native_value_attr_native_value = data.get(FORECAST)[fcday].get(
847  sensor_type[:-3]
848  )
849  except IndexError:
850  _LOGGER.warning("No forecast for fcday=%s", fcday)
851  return False
852  return True
853 
854  if sensor_type == SYMBOL or sensor_type.startswith(CONDITION):
855  # update weather symbol & status text
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)
867 
868  img = condition.get(IMAGE)
869 
870  if new_state != self.statestatestate or img != self.entity_pictureentity_picture:
871  self._attr_native_value_attr_native_value = new_state
872  self._attr_entity_picture_attr_entity_picture = img
873  return True
874 
875  return False
876 
877  if sensor_type.startswith(PRECIPITATION_FORECAST):
878  # update nested precipitation forecast sensors
879  nested = data.get(PRECIPITATION_FORECAST)
880  self._timeframe_timeframe = nested.get(TIMEFRAME)
881  self._attr_native_value_attr_native_value = nested.get(
882  sensor_type[len(PRECIPITATION_FORECAST) + 1 :]
883  )
884  return True
885 
886  if sensor_type in [WINDSPEED, WINDGUST]:
887  # hass wants windspeeds in km/h not m/s, so convert:
888  self._attr_native_value_attr_native_value = data.get(sensor_type)
889  if self.statestatestate is not None:
890  self._attr_native_value_attr_native_value = round(data.get(sensor_type) * 3.6, 1)
891  return True
892 
893  if sensor_type == VISIBILITY:
894  # hass wants visibility in km (not m), so convert:
895  self._attr_native_value_attr_native_value = data.get(sensor_type)
896  if self.statestatestate is not None:
897  self._attr_native_value_attr_native_value = round(self.statestatestate / 1000, 1)
898  return True
899 
900  # update all other sensors
901  self._attr_native_value_attr_native_value = data.get(sensor_type)
902  if sensor_type.startswith(PRECIPITATION_FORECAST):
903  result = {ATTR_ATTRIBUTION: data.get(ATTRIBUTION)}
904  if self._timeframe_timeframe is not None:
905  result[TIMEFRAME_LABEL] = f"{self._timeframe} min"
906 
907  self._attr_extra_state_attributes_attr_extra_state_attributes = result
908 
909  result = {
910  ATTR_ATTRIBUTION: data.get(ATTRIBUTION),
911  STATIONNAME_LABEL: data.get(STATIONNAME),
912  }
913  if self._measured_measured is not None:
914  # convert datetime (Europe/Amsterdam) into local datetime
915  local_dt = dt_util.as_local(self._measured_measured)
916  result[MEASURED_LABEL] = local_dt.strftime("%c")
917 
918  self._attr_extra_state_attributes_attr_extra_state_attributes = result
919  return True
None __init__(self, client_name, coordinates, SensorEntityDescription description)
Definition: sensor.py:742
None async_setup_entry(HomeAssistant hass, BuienRadarConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: sensor.py:695
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88