mirror of
https://github.com/home-assistant/core.git
synced 2025-07-13 16:27:08 +00:00
Implement Cloud coverage in Weather entity component (#95068)
This commit is contained in:
parent
b8de7df609
commit
eafddaae83
@ -31,6 +31,7 @@ from homeassistant.util.unit_system import US_CUSTOMARY_SYSTEM
|
|||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ATTR_WEATHER_APPARENT_TEMPERATURE,
|
ATTR_WEATHER_APPARENT_TEMPERATURE,
|
||||||
|
ATTR_WEATHER_CLOUD_COVERAGE,
|
||||||
ATTR_WEATHER_DEW_POINT,
|
ATTR_WEATHER_DEW_POINT,
|
||||||
ATTR_WEATHER_HUMIDITY,
|
ATTR_WEATHER_HUMIDITY,
|
||||||
ATTR_WEATHER_OZONE,
|
ATTR_WEATHER_OZONE,
|
||||||
@ -87,6 +88,7 @@ ATTR_FORECAST_NATIVE_WIND_SPEED: Final = "native_wind_speed"
|
|||||||
ATTR_FORECAST_WIND_SPEED: Final = "wind_speed"
|
ATTR_FORECAST_WIND_SPEED: Final = "wind_speed"
|
||||||
ATTR_FORECAST_NATIVE_DEW_POINT: Final = "native_dew_point"
|
ATTR_FORECAST_NATIVE_DEW_POINT: Final = "native_dew_point"
|
||||||
ATTR_FORECAST_DEW_POINT: Final = "dew_point"
|
ATTR_FORECAST_DEW_POINT: Final = "dew_point"
|
||||||
|
ATTR_FORECAST_CLOUD_COVERAGE: Final = "cloud_coverage"
|
||||||
|
|
||||||
ENTITY_ID_FORMAT = DOMAIN + ".{}"
|
ENTITY_ID_FORMAT = DOMAIN + ".{}"
|
||||||
|
|
||||||
@ -124,6 +126,7 @@ class Forecast(TypedDict, total=False):
|
|||||||
condition: str | None
|
condition: str | None
|
||||||
datetime: Required[str]
|
datetime: Required[str]
|
||||||
precipitation_probability: int | None
|
precipitation_probability: int | None
|
||||||
|
cloud_coverage: int | None
|
||||||
native_precipitation: float | None
|
native_precipitation: float | None
|
||||||
precipitation: None
|
precipitation: None
|
||||||
native_pressure: float | None
|
native_pressure: float | None
|
||||||
@ -173,6 +176,7 @@ class WeatherEntity(Entity):
|
|||||||
_attr_forecast: list[Forecast] | None = None
|
_attr_forecast: list[Forecast] | None = None
|
||||||
_attr_humidity: float | None = None
|
_attr_humidity: float | None = None
|
||||||
_attr_ozone: float | None = None
|
_attr_ozone: float | None = None
|
||||||
|
_attr_cloud_coverage: int | None = None
|
||||||
_attr_precision: float
|
_attr_precision: float
|
||||||
_attr_pressure: None = (
|
_attr_pressure: None = (
|
||||||
None # Provide backwards compatibility. Use _attr_native_pressure
|
None # Provide backwards compatibility. Use _attr_native_pressure
|
||||||
@ -481,6 +485,11 @@ class WeatherEntity(Entity):
|
|||||||
"""Return the ozone level."""
|
"""Return the ozone level."""
|
||||||
return self._attr_ozone
|
return self._attr_ozone
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cloud_coverage(self) -> float | None:
|
||||||
|
"""Return the Cloud coverage in %."""
|
||||||
|
return self._attr_cloud_coverage
|
||||||
|
|
||||||
@final
|
@final
|
||||||
@property
|
@property
|
||||||
def visibility(self) -> float | None:
|
def visibility(self) -> float | None:
|
||||||
@ -596,7 +605,7 @@ class WeatherEntity(Entity):
|
|||||||
|
|
||||||
@final
|
@final
|
||||||
@property
|
@property
|
||||||
def state_attributes(self) -> dict[str, Any]:
|
def state_attributes(self) -> dict[str, Any]: # noqa: C901
|
||||||
"""Return the state attributes, converted.
|
"""Return the state attributes, converted.
|
||||||
|
|
||||||
Attributes are configured from native units to user-configured units.
|
Attributes are configured from native units to user-configured units.
|
||||||
@ -655,6 +664,9 @@ class WeatherEntity(Entity):
|
|||||||
if (ozone := self.ozone) is not None:
|
if (ozone := self.ozone) is not None:
|
||||||
data[ATTR_WEATHER_OZONE] = ozone
|
data[ATTR_WEATHER_OZONE] = ozone
|
||||||
|
|
||||||
|
if (cloud_coverage := self.cloud_coverage) is not None:
|
||||||
|
data[ATTR_WEATHER_CLOUD_COVERAGE] = cloud_coverage
|
||||||
|
|
||||||
if (pressure := self.native_pressure) is not None:
|
if (pressure := self.native_pressure) is not None:
|
||||||
from_unit = self.native_pressure_unit or self._default_pressure_unit
|
from_unit = self.native_pressure_unit or self._default_pressure_unit
|
||||||
to_unit = self._pressure_unit
|
to_unit = self._pressure_unit
|
||||||
|
@ -32,6 +32,7 @@ ATTR_WEATHER_WIND_BEARING = "wind_bearing"
|
|||||||
ATTR_WEATHER_WIND_SPEED = "wind_speed"
|
ATTR_WEATHER_WIND_SPEED = "wind_speed"
|
||||||
ATTR_WEATHER_WIND_SPEED_UNIT = "wind_speed_unit"
|
ATTR_WEATHER_WIND_SPEED_UNIT = "wind_speed_unit"
|
||||||
ATTR_WEATHER_PRECIPITATION_UNIT = "precipitation_unit"
|
ATTR_WEATHER_PRECIPITATION_UNIT = "precipitation_unit"
|
||||||
|
ATTR_WEATHER_CLOUD_COVERAGE = "cloud_coverage"
|
||||||
|
|
||||||
DOMAIN: Final = "weather"
|
DOMAIN: Final = "weather"
|
||||||
|
|
||||||
|
@ -30,6 +30,9 @@
|
|||||||
"ozone": {
|
"ozone": {
|
||||||
"name": "Ozone"
|
"name": "Ozone"
|
||||||
},
|
},
|
||||||
|
"cloud_coverage": {
|
||||||
|
"name": "Cloud coverage"
|
||||||
|
},
|
||||||
"precipitation_unit": {
|
"precipitation_unit": {
|
||||||
"name": "Precipitation unit"
|
"name": "Precipitation unit"
|
||||||
},
|
},
|
||||||
|
@ -31,7 +31,10 @@ from homeassistant.components.weather import (
|
|||||||
WeatherEntity,
|
WeatherEntity,
|
||||||
round_temperature,
|
round_temperature,
|
||||||
)
|
)
|
||||||
from homeassistant.components.weather.const import ATTR_WEATHER_DEW_POINT
|
from homeassistant.components.weather.const import (
|
||||||
|
ATTR_WEATHER_CLOUD_COVERAGE,
|
||||||
|
ATTR_WEATHER_DEW_POINT,
|
||||||
|
)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_FRIENDLY_NAME,
|
ATTR_FRIENDLY_NAME,
|
||||||
PRECISION_HALVES,
|
PRECISION_HALVES,
|
||||||
@ -522,21 +525,26 @@ async def test_precipitation_no_unit(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_wind_bearing_and_ozone(
|
async def test_wind_bearing_ozone_and_cloud_coverage(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
enable_custom_integrations: None,
|
enable_custom_integrations: None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test wind bearing."""
|
"""Test wind bearing, ozone and cloud coverage."""
|
||||||
wind_bearing_value = 180
|
wind_bearing_value = 180
|
||||||
ozone_value = 10
|
ozone_value = 10
|
||||||
|
cloud_coverage = 75
|
||||||
|
|
||||||
entity0 = await create_entity(
|
entity0 = await create_entity(
|
||||||
hass, wind_bearing=wind_bearing_value, ozone=ozone_value
|
hass,
|
||||||
|
wind_bearing=wind_bearing_value,
|
||||||
|
ozone=ozone_value,
|
||||||
|
cloud_coverage=cloud_coverage,
|
||||||
)
|
)
|
||||||
|
|
||||||
state = hass.states.get(entity0.entity_id)
|
state = hass.states.get(entity0.entity_id)
|
||||||
assert float(state.attributes[ATTR_WEATHER_WIND_BEARING]) == 180
|
assert float(state.attributes[ATTR_WEATHER_WIND_BEARING]) == 180
|
||||||
assert float(state.attributes[ATTR_WEATHER_OZONE]) == 10
|
assert float(state.attributes[ATTR_WEATHER_OZONE]) == 10
|
||||||
|
assert float(state.attributes[ATTR_WEATHER_CLOUD_COVERAGE]) == 75
|
||||||
|
|
||||||
|
|
||||||
async def test_none_forecast(
|
async def test_none_forecast(
|
||||||
|
@ -5,6 +5,7 @@ Call init before using it in your tests to ensure clean test data.
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from homeassistant.components.weather import (
|
from homeassistant.components.weather import (
|
||||||
|
ATTR_FORECAST_CLOUD_COVERAGE,
|
||||||
ATTR_FORECAST_NATIVE_APPARENT_TEMP,
|
ATTR_FORECAST_NATIVE_APPARENT_TEMP,
|
||||||
ATTR_FORECAST_NATIVE_DEW_POINT,
|
ATTR_FORECAST_NATIVE_DEW_POINT,
|
||||||
ATTR_FORECAST_NATIVE_PRECIPITATION,
|
ATTR_FORECAST_NATIVE_PRECIPITATION,
|
||||||
@ -98,6 +99,11 @@ class MockWeather(MockEntity, WeatherEntity):
|
|||||||
"""Return the ozone level."""
|
"""Return the ozone level."""
|
||||||
return self._handle("ozone")
|
return self._handle("ozone")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def cloud_coverage(self) -> float | None:
|
||||||
|
"""Return the cloud coverage in %."""
|
||||||
|
return self._handle("cloud_coverage")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_visibility(self) -> float | None:
|
def native_visibility(self) -> float | None:
|
||||||
"""Return the visibility."""
|
"""Return the visibility."""
|
||||||
@ -210,6 +216,7 @@ class MockWeatherMockForecast(MockWeather):
|
|||||||
ATTR_FORECAST_NATIVE_APPARENT_TEMP: self.native_apparent_temperature,
|
ATTR_FORECAST_NATIVE_APPARENT_TEMP: self.native_apparent_temperature,
|
||||||
ATTR_FORECAST_NATIVE_TEMP_LOW: self.native_temperature,
|
ATTR_FORECAST_NATIVE_TEMP_LOW: self.native_temperature,
|
||||||
ATTR_FORECAST_NATIVE_DEW_POINT: self.native_dew_point,
|
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_PRESSURE: self.native_pressure,
|
||||||
ATTR_FORECAST_NATIVE_WIND_SPEED: self.native_wind_speed,
|
ATTR_FORECAST_NATIVE_WIND_SPEED: self.native_wind_speed,
|
||||||
ATTR_FORECAST_WIND_BEARING: self.wind_bearing,
|
ATTR_FORECAST_WIND_BEARING: self.wind_bearing,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user