mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
Implement Apparent temperature in Weather entity component (#95070)
This commit is contained in:
parent
38614bc3f0
commit
6ad3b60adf
@ -30,6 +30,7 @@ from homeassistant.helpers.typing import ConfigType
|
||||
from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM
|
||||
|
||||
from .const import (
|
||||
ATTR_WEATHER_APPARENT_TEMPERATURE,
|
||||
ATTR_WEATHER_HUMIDITY,
|
||||
ATTR_WEATHER_OZONE,
|
||||
ATTR_WEATHER_PRECIPITATION_UNIT,
|
||||
@ -73,6 +74,8 @@ ATTR_FORECAST_PRECIPITATION: Final = "precipitation"
|
||||
ATTR_FORECAST_PRECIPITATION_PROBABILITY: Final = "precipitation_probability"
|
||||
ATTR_FORECAST_NATIVE_PRESSURE: Final = "native_pressure"
|
||||
ATTR_FORECAST_PRESSURE: Final = "pressure"
|
||||
ATTR_FORECAST_NATIVE_APPARENT_TEMP: Final = "native_apparent_temperature"
|
||||
ATTR_FORECAST_APPARENT_TEMP: Final = "apparent_temperature"
|
||||
ATTR_FORECAST_NATIVE_TEMP: Final = "native_temperature"
|
||||
ATTR_FORECAST_TEMP: Final = "temperature"
|
||||
ATTR_FORECAST_NATIVE_TEMP_LOW: Final = "native_templow"
|
||||
@ -199,6 +202,7 @@ class WeatherEntity(Entity):
|
||||
|
||||
_attr_native_pressure: float | None = None
|
||||
_attr_native_pressure_unit: str | None = None
|
||||
_attr_native_apparent_temperature: float | None = None
|
||||
_attr_native_temperature: float | None = None
|
||||
_attr_native_temperature_unit: str | None = None
|
||||
_attr_native_visibility: float | None = None
|
||||
@ -272,6 +276,11 @@ class WeatherEntity(Entity):
|
||||
return
|
||||
self.async_registry_entry_updated()
|
||||
|
||||
@property
|
||||
def native_apparent_temperature(self) -> float | None:
|
||||
"""Return the apparent temperature in native units."""
|
||||
return self._attr_native_temperature
|
||||
|
||||
@final
|
||||
@property
|
||||
def temperature(self) -> float | None:
|
||||
@ -600,6 +609,20 @@ class WeatherEntity(Entity):
|
||||
except (TypeError, ValueError):
|
||||
data[ATTR_WEATHER_TEMPERATURE] = temperature
|
||||
|
||||
if (apparent_temperature := self.native_apparent_temperature) is not None:
|
||||
from_unit = self.native_temperature_unit or self._default_temperature_unit
|
||||
to_unit = self._temperature_unit
|
||||
try:
|
||||
apparent_temperature_f = float(apparent_temperature)
|
||||
value_apparent_temp = UNIT_CONVERSIONS[ATTR_WEATHER_TEMPERATURE_UNIT](
|
||||
apparent_temperature_f, from_unit, to_unit
|
||||
)
|
||||
data[ATTR_WEATHER_APPARENT_TEMPERATURE] = round_temperature(
|
||||
value_apparent_temp, precision
|
||||
)
|
||||
except (TypeError, ValueError):
|
||||
data[ATTR_WEATHER_APPARENT_TEMPERATURE] = apparent_temperature
|
||||
|
||||
data[ATTR_WEATHER_TEMPERATURE_UNIT] = self._temperature_unit
|
||||
|
||||
if (humidity := self.humidity) is not None:
|
||||
@ -686,6 +709,26 @@ class WeatherEntity(Entity):
|
||||
value_temp, precision
|
||||
)
|
||||
|
||||
if (
|
||||
forecast_apparent_temp := forecast_entry.pop(
|
||||
ATTR_FORECAST_NATIVE_APPARENT_TEMP,
|
||||
forecast_entry.get(ATTR_FORECAST_NATIVE_APPARENT_TEMP),
|
||||
)
|
||||
) is not None:
|
||||
with suppress(TypeError, ValueError):
|
||||
forecast_apparent_temp = float(forecast_apparent_temp)
|
||||
value_apparent_temp = UNIT_CONVERSIONS[
|
||||
ATTR_WEATHER_TEMPERATURE_UNIT
|
||||
](
|
||||
forecast_apparent_temp,
|
||||
from_temp_unit,
|
||||
to_temp_unit,
|
||||
)
|
||||
|
||||
forecast_entry[ATTR_FORECAST_APPARENT_TEMP] = round_temperature(
|
||||
value_apparent_temp, precision
|
||||
)
|
||||
|
||||
if (
|
||||
forecast_temp_low := forecast_entry.pop(
|
||||
ATTR_FORECAST_NATIVE_TEMP_LOW,
|
||||
|
@ -22,6 +22,7 @@ ATTR_WEATHER_HUMIDITY = "humidity"
|
||||
ATTR_WEATHER_OZONE = "ozone"
|
||||
ATTR_WEATHER_PRESSURE = "pressure"
|
||||
ATTR_WEATHER_PRESSURE_UNIT = "pressure_unit"
|
||||
ATTR_WEATHER_APPARENT_TEMPERATURE = "apparent_temperature"
|
||||
ATTR_WEATHER_TEMPERATURE = "temperature"
|
||||
ATTR_WEATHER_TEMPERATURE_UNIT = "temperature_unit"
|
||||
ATTR_WEATHER_VISIBILITY = "visibility"
|
||||
|
@ -39,6 +39,9 @@
|
||||
"pressure_unit": {
|
||||
"name": "Pressure unit"
|
||||
},
|
||||
"apparent_temperature": {
|
||||
"name": "Apparent temperature"
|
||||
},
|
||||
"temperature": {
|
||||
"name": "Temperature"
|
||||
},
|
||||
|
@ -6,12 +6,14 @@ import pytest
|
||||
from homeassistant.components.weather import (
|
||||
ATTR_CONDITION_SUNNY,
|
||||
ATTR_FORECAST,
|
||||
ATTR_FORECAST_APPARENT_TEMP,
|
||||
ATTR_FORECAST_PRECIPITATION,
|
||||
ATTR_FORECAST_PRESSURE,
|
||||
ATTR_FORECAST_TEMP,
|
||||
ATTR_FORECAST_TEMP_LOW,
|
||||
ATTR_FORECAST_WIND_BEARING,
|
||||
ATTR_FORECAST_WIND_SPEED,
|
||||
ATTR_WEATHER_APPARENT_TEMPERATURE,
|
||||
ATTR_WEATHER_OZONE,
|
||||
ATTR_WEATHER_PRECIPITATION_UNIT,
|
||||
ATTR_WEATHER_PRESSURE,
|
||||
@ -63,6 +65,7 @@ class MockWeatherEntity(WeatherEntity):
|
||||
self._attr_native_pressure = 10
|
||||
self._attr_native_pressure_unit = UnitOfPressure.HPA
|
||||
self._attr_native_temperature = 20
|
||||
self._attr_native_apparent_temperature = 25
|
||||
self._attr_native_temperature_unit = UnitOfTemperature.CELSIUS
|
||||
self._attr_native_visibility = 30
|
||||
self._attr_native_visibility_unit = UnitOfLength.KILOMETERS
|
||||
@ -85,6 +88,7 @@ class MockWeatherEntityPrecision(WeatherEntity):
|
||||
super().__init__()
|
||||
self._attr_condition = ATTR_CONDITION_SUNNY
|
||||
self._attr_native_temperature = 20.3
|
||||
self._attr_native_apparent_temperature = 25.3
|
||||
self._attr_native_temperature_unit = UnitOfTemperature.CELSIUS
|
||||
self._attr_precision = PRECISION_HALVES
|
||||
|
||||
@ -153,21 +157,35 @@ async def test_temperature(
|
||||
"""Test temperature."""
|
||||
hass.config.units = unit_system
|
||||
native_value = 38
|
||||
apparent_native_value = 45
|
||||
state_value = TemperatureConverter.convert(native_value, native_unit, state_unit)
|
||||
apparent_state_value = TemperatureConverter.convert(
|
||||
apparent_native_value, native_unit, state_unit
|
||||
)
|
||||
|
||||
entity0 = await create_entity(
|
||||
hass, native_temperature=native_value, native_temperature_unit=native_unit
|
||||
hass,
|
||||
native_temperature=native_value,
|
||||
native_temperature_unit=native_unit,
|
||||
native_apparent_temperature=apparent_native_value,
|
||||
)
|
||||
|
||||
state = hass.states.get(entity0.entity_id)
|
||||
forecast = state.attributes[ATTR_FORECAST][0]
|
||||
|
||||
expected = state_value
|
||||
apparent_expected = apparent_state_value
|
||||
assert float(state.attributes[ATTR_WEATHER_TEMPERATURE]) == pytest.approx(
|
||||
expected, rel=0.1
|
||||
)
|
||||
assert float(state.attributes[ATTR_WEATHER_APPARENT_TEMPERATURE]) == pytest.approx(
|
||||
apparent_expected, rel=0.1
|
||||
)
|
||||
assert state.attributes[ATTR_WEATHER_TEMPERATURE_UNIT] == state_unit
|
||||
assert float(forecast[ATTR_FORECAST_TEMP]) == pytest.approx(expected, rel=0.1)
|
||||
assert float(forecast[ATTR_FORECAST_APPARENT_TEMP]) == pytest.approx(
|
||||
apparent_expected, rel=0.1
|
||||
)
|
||||
assert float(forecast[ATTR_FORECAST_TEMP_LOW]) == pytest.approx(expected, rel=0.1)
|
||||
|
||||
|
||||
|
@ -5,6 +5,7 @@ Call init before using it in your tests to ensure clean test data.
|
||||
from __future__ import annotations
|
||||
|
||||
from homeassistant.components.weather import (
|
||||
ATTR_FORECAST_NATIVE_APPARENT_TEMP,
|
||||
ATTR_FORECAST_NATIVE_PRECIPITATION,
|
||||
ATTR_FORECAST_NATIVE_PRESSURE,
|
||||
ATTR_FORECAST_NATIVE_TEMP,
|
||||
@ -46,6 +47,11 @@ class MockWeather(MockEntity, WeatherEntity):
|
||||
"""Return the platform temperature."""
|
||||
return self._handle("native_temperature")
|
||||
|
||||
@property
|
||||
def native_apparent_temperature(self) -> float | None:
|
||||
"""Return the platform apparent temperature."""
|
||||
return self._handle("native_apparent_temperature")
|
||||
|
||||
@property
|
||||
def native_temperature_unit(self) -> str | None:
|
||||
"""Return the unit of measurement for temperature."""
|
||||
@ -195,6 +201,7 @@ class MockWeatherMockForecast(MockWeather):
|
||||
return [
|
||||
{
|
||||
ATTR_FORECAST_NATIVE_TEMP: self.native_temperature,
|
||||
ATTR_FORECAST_NATIVE_APPARENT_TEMP: self.native_apparent_temperature,
|
||||
ATTR_FORECAST_NATIVE_TEMP_LOW: self.native_temperature,
|
||||
ATTR_FORECAST_NATIVE_PRESSURE: self.native_pressure,
|
||||
ATTR_FORECAST_NATIVE_WIND_SPEED: self.native_wind_speed,
|
||||
|
Loading…
x
Reference in New Issue
Block a user