mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 08:47:57 +00:00
Implement Wind Gust speed in Weather entity component (#95065)
* Weather wind gust speed * strings * No compat
This commit is contained in:
parent
d811fa0e74
commit
5d365ecb6b
@ -43,6 +43,7 @@ from .const import (
|
||||
ATTR_WEATHER_VISIBILITY,
|
||||
ATTR_WEATHER_VISIBILITY_UNIT,
|
||||
ATTR_WEATHER_WIND_BEARING,
|
||||
ATTR_WEATHER_WIND_GUST_SPEED,
|
||||
ATTR_WEATHER_WIND_SPEED,
|
||||
ATTR_WEATHER_WIND_SPEED_UNIT,
|
||||
DOMAIN,
|
||||
@ -85,6 +86,8 @@ ATTR_FORECAST_NATIVE_TEMP_LOW: Final = "native_templow"
|
||||
ATTR_FORECAST_TEMP_LOW: Final = "templow"
|
||||
ATTR_FORECAST_TIME: Final = "datetime"
|
||||
ATTR_FORECAST_WIND_BEARING: Final = "wind_bearing"
|
||||
ATTR_FORECAST_NATIVE_WIND_GUST_SPEED: Final = "native_wind_gust_speed"
|
||||
ATTR_FORECAST_WIND_GUST_SPEED: Final = "wind_gust_speed"
|
||||
ATTR_FORECAST_NATIVE_WIND_SPEED: Final = "native_wind_speed"
|
||||
ATTR_FORECAST_WIND_SPEED: Final = "wind_speed"
|
||||
ATTR_FORECAST_NATIVE_DEW_POINT: Final = "native_dew_point"
|
||||
@ -138,6 +141,7 @@ class Forecast(TypedDict, total=False):
|
||||
native_templow: float | None
|
||||
templow: None
|
||||
wind_bearing: float | str | None
|
||||
native_wind_gust_speed: float | None
|
||||
native_wind_speed: float | None
|
||||
wind_speed: None
|
||||
native_dew_point: float | None
|
||||
@ -218,6 +222,7 @@ class WeatherEntity(Entity):
|
||||
_attr_native_visibility: float | None = None
|
||||
_attr_native_visibility_unit: str | None = None
|
||||
_attr_native_precipitation_unit: str | None = None
|
||||
_attr_native_wind_gust_speed: float | None = None
|
||||
_attr_native_wind_speed: float | None = None
|
||||
_attr_native_wind_speed_unit: str | None = None
|
||||
_attr_native_dew_point: float | None = None
|
||||
@ -418,6 +423,11 @@ class WeatherEntity(Entity):
|
||||
"""Return the humidity in native units."""
|
||||
return self._attr_humidity
|
||||
|
||||
@property
|
||||
def native_wind_gust_speed(self) -> float | None:
|
||||
"""Return the wind gust speed in native units."""
|
||||
return self._attr_native_wind_gust_speed
|
||||
|
||||
@final
|
||||
@property
|
||||
def wind_speed(self) -> float | None:
|
||||
@ -686,6 +696,20 @@ class WeatherEntity(Entity):
|
||||
if (wind_bearing := self.wind_bearing) is not None:
|
||||
data[ATTR_WEATHER_WIND_BEARING] = wind_bearing
|
||||
|
||||
if (wind_gust_speed := self.native_wind_gust_speed) is not None:
|
||||
from_unit = self.native_wind_speed_unit or self._default_wind_speed_unit
|
||||
to_unit = self._wind_speed_unit
|
||||
try:
|
||||
wind_gust_speed_f = float(wind_gust_speed)
|
||||
value_wind_gust_speed = UNIT_CONVERSIONS[ATTR_WEATHER_WIND_SPEED_UNIT](
|
||||
wind_gust_speed_f, from_unit, to_unit
|
||||
)
|
||||
data[ATTR_WEATHER_WIND_GUST_SPEED] = round(
|
||||
value_wind_gust_speed, ROUNDING_PRECISION
|
||||
)
|
||||
except (TypeError, ValueError):
|
||||
data[ATTR_WEATHER_WIND_GUST_SPEED] = wind_gust_speed
|
||||
|
||||
if (wind_speed := self.native_wind_speed) is not None:
|
||||
from_unit = self.native_wind_speed_unit or self._default_wind_speed_unit
|
||||
to_unit = self._wind_speed_unit
|
||||
@ -828,6 +852,27 @@ class WeatherEntity(Entity):
|
||||
ROUNDING_PRECISION,
|
||||
)
|
||||
|
||||
if (
|
||||
forecast_wind_gust_speed := forecast_entry.pop(
|
||||
ATTR_FORECAST_NATIVE_WIND_GUST_SPEED,
|
||||
None,
|
||||
)
|
||||
) is not None:
|
||||
from_wind_speed_unit = (
|
||||
self.native_wind_speed_unit or self._default_wind_speed_unit
|
||||
)
|
||||
to_wind_speed_unit = self._wind_speed_unit
|
||||
with suppress(TypeError, ValueError):
|
||||
forecast_wind_gust_speed_f = float(forecast_wind_gust_speed)
|
||||
forecast_entry[ATTR_FORECAST_WIND_GUST_SPEED] = round(
|
||||
UNIT_CONVERSIONS[ATTR_WEATHER_WIND_SPEED_UNIT](
|
||||
forecast_wind_gust_speed_f,
|
||||
from_wind_speed_unit,
|
||||
to_wind_speed_unit,
|
||||
),
|
||||
ROUNDING_PRECISION,
|
||||
)
|
||||
|
||||
if (
|
||||
forecast_wind_speed := forecast_entry.pop(
|
||||
ATTR_FORECAST_NATIVE_WIND_SPEED,
|
||||
|
@ -29,6 +29,7 @@ ATTR_WEATHER_TEMPERATURE_UNIT = "temperature_unit"
|
||||
ATTR_WEATHER_VISIBILITY = "visibility"
|
||||
ATTR_WEATHER_VISIBILITY_UNIT = "visibility_unit"
|
||||
ATTR_WEATHER_WIND_BEARING = "wind_bearing"
|
||||
ATTR_WEATHER_WIND_GUST_SPEED = "wind_gust_speed"
|
||||
ATTR_WEATHER_WIND_SPEED = "wind_speed"
|
||||
ATTR_WEATHER_WIND_SPEED_UNIT = "wind_speed_unit"
|
||||
ATTR_WEATHER_PRECIPITATION_UNIT = "precipitation_unit"
|
||||
|
@ -63,6 +63,9 @@
|
||||
"wind_bearing": {
|
||||
"name": "Wind bearing"
|
||||
},
|
||||
"wind_gust_speed": {
|
||||
"name": "Wind gust speed"
|
||||
},
|
||||
"wind_speed": {
|
||||
"name": "Wind speed"
|
||||
},
|
||||
|
@ -14,6 +14,7 @@ from homeassistant.components.weather import (
|
||||
ATTR_FORECAST_TEMP,
|
||||
ATTR_FORECAST_TEMP_LOW,
|
||||
ATTR_FORECAST_WIND_BEARING,
|
||||
ATTR_FORECAST_WIND_GUST_SPEED,
|
||||
ATTR_FORECAST_WIND_SPEED,
|
||||
ATTR_WEATHER_APPARENT_TEMPERATURE,
|
||||
ATTR_WEATHER_OZONE,
|
||||
@ -25,6 +26,7 @@ from homeassistant.components.weather import (
|
||||
ATTR_WEATHER_VISIBILITY,
|
||||
ATTR_WEATHER_VISIBILITY_UNIT,
|
||||
ATTR_WEATHER_WIND_BEARING,
|
||||
ATTR_WEATHER_WIND_GUST_SPEED,
|
||||
ATTR_WEATHER_WIND_SPEED,
|
||||
ATTR_WEATHER_WIND_SPEED_UNIT,
|
||||
ROUNDING_PRECISION,
|
||||
@ -77,6 +79,7 @@ class MockWeatherEntity(WeatherEntity):
|
||||
self._attr_native_temperature_unit = UnitOfTemperature.CELSIUS
|
||||
self._attr_native_visibility = 30
|
||||
self._attr_native_visibility_unit = UnitOfLength.KILOMETERS
|
||||
self._attr_native_wind_gust_speed = 10
|
||||
self._attr_native_wind_speed = 3
|
||||
self._attr_native_wind_speed_unit = UnitOfSpeed.METERS_PER_SECOND
|
||||
self._attr_forecast = [
|
||||
@ -373,6 +376,49 @@ async def test_wind_speed(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"native_unit",
|
||||
(
|
||||
UnitOfSpeed.MILES_PER_HOUR,
|
||||
UnitOfSpeed.KILOMETERS_PER_HOUR,
|
||||
UnitOfSpeed.METERS_PER_SECOND,
|
||||
),
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
("state_unit", "unit_system"),
|
||||
(
|
||||
(UnitOfSpeed.KILOMETERS_PER_HOUR, METRIC_SYSTEM),
|
||||
(UnitOfSpeed.MILES_PER_HOUR, US_CUSTOMARY_SYSTEM),
|
||||
),
|
||||
)
|
||||
async def test_wind_gust_speed(
|
||||
hass: HomeAssistant,
|
||||
enable_custom_integrations: None,
|
||||
native_unit: str,
|
||||
state_unit: str,
|
||||
unit_system,
|
||||
) -> None:
|
||||
"""Test wind speed."""
|
||||
hass.config.units = unit_system
|
||||
native_value = 10
|
||||
state_value = SpeedConverter.convert(native_value, native_unit, state_unit)
|
||||
|
||||
entity0 = await create_entity(
|
||||
hass, native_wind_gust_speed=native_value, native_wind_speed_unit=native_unit
|
||||
)
|
||||
|
||||
state = hass.states.get(entity0.entity_id)
|
||||
forecast = state.attributes[ATTR_FORECAST][0]
|
||||
|
||||
expected = state_value
|
||||
assert float(state.attributes[ATTR_WEATHER_WIND_GUST_SPEED]) == pytest.approx(
|
||||
expected, rel=1e-2
|
||||
)
|
||||
assert float(forecast[ATTR_FORECAST_WIND_GUST_SPEED]) == pytest.approx(
|
||||
expected, rel=1e-2
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("native_unit", (None,))
|
||||
@pytest.mark.parametrize(
|
||||
("state_unit", "unit_system"),
|
||||
|
@ -13,6 +13,7 @@ from homeassistant.components.weather import (
|
||||
ATTR_FORECAST_NATIVE_PRESSURE,
|
||||
ATTR_FORECAST_NATIVE_TEMP,
|
||||
ATTR_FORECAST_NATIVE_TEMP_LOW,
|
||||
ATTR_FORECAST_NATIVE_WIND_GUST_SPEED,
|
||||
ATTR_FORECAST_NATIVE_WIND_SPEED,
|
||||
ATTR_FORECAST_PRECIPITATION,
|
||||
ATTR_FORECAST_PRESSURE,
|
||||
@ -80,6 +81,11 @@ class MockWeather(MockEntity, WeatherEntity):
|
||||
"""Return the humidity."""
|
||||
return self._handle("humidity")
|
||||
|
||||
@property
|
||||
def native_wind_gust_speed(self) -> float | None:
|
||||
"""Return the wind speed."""
|
||||
return self._handle("native_wind_gust_speed")
|
||||
|
||||
@property
|
||||
def native_wind_speed(self) -> float | None:
|
||||
"""Return the wind speed."""
|
||||
@ -219,6 +225,7 @@ class MockWeatherMockForecast(MockWeather):
|
||||
ATTR_FORECAST_NATIVE_DEW_POINT: self.native_dew_point,
|
||||
ATTR_FORECAST_CLOUD_COVERAGE: self.cloud_coverage,
|
||||
ATTR_FORECAST_NATIVE_PRESSURE: self.native_pressure,
|
||||
ATTR_FORECAST_NATIVE_WIND_GUST_SPEED: self.native_wind_gust_speed,
|
||||
ATTR_FORECAST_NATIVE_WIND_SPEED: self.native_wind_speed,
|
||||
ATTR_FORECAST_WIND_BEARING: self.wind_bearing,
|
||||
ATTR_FORECAST_NATIVE_PRECIPITATION: self._values.get(
|
||||
|
Loading…
x
Reference in New Issue
Block a user