Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Support for the OpenWeatherMap (OWM) service."""
2 
3 from __future__ import annotations
4 
6  SensorDeviceClass,
7  SensorEntity,
8  SensorEntityDescription,
9  SensorStateClass,
10 )
11 from homeassistant.const import (
12  DEGREE,
13  PERCENTAGE,
14  UV_INDEX,
15  UnitOfLength,
16  UnitOfPressure,
17  UnitOfSpeed,
18  UnitOfTemperature,
19  UnitOfVolumetricFlux,
20 )
21 from homeassistant.core import HomeAssistant
22 from homeassistant.helpers import entity_registry as er
23 from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
24 from homeassistant.helpers.entity_platform import AddEntitiesCallback
25 from homeassistant.helpers.typing import StateType
26 from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
27 
28 from . import OpenweathermapConfigEntry
29 from .const import (
30  ATTR_API_CLOUDS,
31  ATTR_API_CONDITION,
32  ATTR_API_CURRENT,
33  ATTR_API_DEW_POINT,
34  ATTR_API_FEELS_LIKE_TEMPERATURE,
35  ATTR_API_HUMIDITY,
36  ATTR_API_PRECIPITATION_KIND,
37  ATTR_API_PRESSURE,
38  ATTR_API_RAIN,
39  ATTR_API_SNOW,
40  ATTR_API_TEMPERATURE,
41  ATTR_API_UV_INDEX,
42  ATTR_API_VISIBILITY_DISTANCE,
43  ATTR_API_WEATHER,
44  ATTR_API_WEATHER_CODE,
45  ATTR_API_WIND_BEARING,
46  ATTR_API_WIND_SPEED,
47  ATTRIBUTION,
48  DEFAULT_NAME,
49  DOMAIN,
50  MANUFACTURER,
51  OWM_MODE_FREE_FORECAST,
52 )
53 from .coordinator import WeatherUpdateCoordinator
54 
55 WEATHER_SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
57  key=ATTR_API_WEATHER,
58  name="Weather",
59  ),
61  key=ATTR_API_DEW_POINT,
62  name="Dew Point",
63  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
64  device_class=SensorDeviceClass.TEMPERATURE,
65  state_class=SensorStateClass.MEASUREMENT,
66  ),
68  key=ATTR_API_TEMPERATURE,
69  name="Temperature",
70  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
71  device_class=SensorDeviceClass.TEMPERATURE,
72  state_class=SensorStateClass.MEASUREMENT,
73  ),
75  key=ATTR_API_FEELS_LIKE_TEMPERATURE,
76  name="Feels like temperature",
77  native_unit_of_measurement=UnitOfTemperature.CELSIUS,
78  device_class=SensorDeviceClass.TEMPERATURE,
79  state_class=SensorStateClass.MEASUREMENT,
80  ),
82  key=ATTR_API_WIND_SPEED,
83  name="Wind speed",
84  native_unit_of_measurement=UnitOfSpeed.METERS_PER_SECOND,
85  device_class=SensorDeviceClass.WIND_SPEED,
86  state_class=SensorStateClass.MEASUREMENT,
87  ),
89  key=ATTR_API_WIND_BEARING,
90  name="Wind bearing",
91  native_unit_of_measurement=DEGREE,
92  state_class=SensorStateClass.MEASUREMENT,
93  ),
95  key=ATTR_API_HUMIDITY,
96  name="Humidity",
97  native_unit_of_measurement=PERCENTAGE,
98  device_class=SensorDeviceClass.HUMIDITY,
99  state_class=SensorStateClass.MEASUREMENT,
100  ),
102  key=ATTR_API_PRESSURE,
103  name="Pressure",
104  native_unit_of_measurement=UnitOfPressure.HPA,
105  device_class=SensorDeviceClass.PRESSURE,
106  state_class=SensorStateClass.MEASUREMENT,
107  ),
109  key=ATTR_API_CLOUDS,
110  name="Cloud coverage",
111  native_unit_of_measurement=PERCENTAGE,
112  state_class=SensorStateClass.MEASUREMENT,
113  ),
115  key=ATTR_API_RAIN,
116  name="Rain",
117  native_unit_of_measurement=UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR,
118  device_class=SensorDeviceClass.PRECIPITATION_INTENSITY,
119  state_class=SensorStateClass.MEASUREMENT,
120  ),
122  key=ATTR_API_SNOW,
123  name="Snow",
124  native_unit_of_measurement=UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR,
125  device_class=SensorDeviceClass.PRECIPITATION_INTENSITY,
126  state_class=SensorStateClass.MEASUREMENT,
127  ),
129  key=ATTR_API_PRECIPITATION_KIND,
130  name="Precipitation kind",
131  ),
133  key=ATTR_API_UV_INDEX,
134  name="UV Index",
135  native_unit_of_measurement=UV_INDEX,
136  state_class=SensorStateClass.MEASUREMENT,
137  ),
139  key=ATTR_API_VISIBILITY_DISTANCE,
140  name="Visibility",
141  native_unit_of_measurement=UnitOfLength.METERS,
142  device_class=SensorDeviceClass.DISTANCE,
143  state_class=SensorStateClass.MEASUREMENT,
144  ),
146  key=ATTR_API_CONDITION,
147  name="Condition",
148  ),
150  key=ATTR_API_WEATHER_CODE,
151  name="Weather Code",
152  ),
153 )
154 
155 
157  hass: HomeAssistant,
158  config_entry: OpenweathermapConfigEntry,
159  async_add_entities: AddEntitiesCallback,
160 ) -> None:
161  """Set up OpenWeatherMap sensor entities based on a config entry."""
162  domain_data = config_entry.runtime_data
163  name = domain_data.name
164  weather_coordinator = domain_data.coordinator
165 
166  if domain_data.mode == OWM_MODE_FREE_FORECAST:
167  entity_registry = er.async_get(hass)
168  entries = er.async_entries_for_config_entry(
169  entity_registry, config_entry.entry_id
170  )
171  for entry in entries:
172  entity_registry.async_remove(entry.entity_id)
173  else:
176  name,
177  f"{config_entry.unique_id}-{description.key}",
178  description,
179  weather_coordinator,
180  )
181  for description in WEATHER_SENSOR_TYPES
182  )
183 
184 
186  """Abstract class for an OpenWeatherMap sensor."""
187 
188  _attr_should_poll = False
189  _attr_attribution = ATTRIBUTION
190 
191  def __init__(
192  self,
193  name: str,
194  unique_id: str,
195  description: SensorEntityDescription,
196  coordinator: DataUpdateCoordinator,
197  ) -> None:
198  """Initialize the sensor."""
199  self.entity_descriptionentity_description = description
200  self._coordinator_coordinator = coordinator
201 
202  self._attr_name_attr_name = f"{name} {description.name}"
203  self._attr_unique_id_attr_unique_id = unique_id
204  split_unique_id = unique_id.split("-")
205  self._attr_device_info_attr_device_info = DeviceInfo(
206  entry_type=DeviceEntryType.SERVICE,
207  identifiers={(DOMAIN, f"{split_unique_id[0]}-{split_unique_id[1]}")},
208  manufacturer=MANUFACTURER,
209  name=DEFAULT_NAME,
210  )
211 
212  @property
213  def available(self) -> bool:
214  """Return True if entity is available."""
215  return self._coordinator_coordinator.last_update_success
216 
217  async def async_added_to_hass(self) -> None:
218  """Connect to dispatcher listening for entity data notifications."""
219  self.async_on_removeasync_on_remove(
220  self._coordinator_coordinator.async_add_listener(self.async_write_ha_stateasync_write_ha_state)
221  )
222 
223  async def async_update(self) -> None:
224  """Get the latest data from OWM and updates the states."""
225  await self._coordinator_coordinator.async_request_refresh()
226 
227 
229  """Implementation of an OpenWeatherMap sensor."""
230 
231  def __init__(
232  self,
233  name: str,
234  unique_id: str,
235  description: SensorEntityDescription,
236  weather_coordinator: WeatherUpdateCoordinator,
237  ) -> None:
238  """Initialize the sensor."""
239  super().__init__(name, unique_id, description, weather_coordinator)
240  self._weather_coordinator_weather_coordinator = weather_coordinator
241 
242  @property
243  def native_value(self) -> StateType:
244  """Return the state of the device."""
245  return self._weather_coordinator_weather_coordinator.data[ATTR_API_CURRENT].get(
246  self.entity_descriptionentity_description.key
247  )
None __init__(self, str name, str unique_id, SensorEntityDescription description, DataUpdateCoordinator coordinator)
Definition: sensor.py:197
None __init__(self, str name, str unique_id, SensorEntityDescription description, WeatherUpdateCoordinator weather_coordinator)
Definition: sensor.py:237
None async_on_remove(self, CALLBACK_TYPE func)
Definition: entity.py:1331
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88
None async_add_listener(HomeAssistant hass, Callable[[], None] listener)
Definition: __init__.py:82
None async_setup_entry(HomeAssistant hass, OpenweathermapConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: sensor.py:160