mirror of
https://github.com/home-assistant/core.git
synced 2025-07-17 18:27:09 +00:00
Add native unit types for weather entities (#59533)
* Add native unit types for weather entities * Update weatherentity and change precision in climacell test * Move weather test to demo tests * Add weather test for temperature conversion * Add more unit conversion tests * Remove extra native_ methods * Remove extra properties and save precision change for another PR * Remove visibility_unit from metoffice component The vibility values given by metoffice are formatted into strings, which means they can't automatically be converted. * Improve docstrings and convert pressures in forecast * Add precipitation and wind speed units * Clean up tests * Round converted weather values * Round weather values to 2 decimal places * Move number of rounding decimal places to constant * Docstring and styles
This commit is contained in:
parent
5a97db6685
commit
09af85c6a4
@ -8,7 +8,7 @@ from homeassistant.components.weather import (
|
|||||||
ATTR_FORECAST_WIND_SPEED,
|
ATTR_FORECAST_WIND_SPEED,
|
||||||
WeatherEntity,
|
WeatherEntity,
|
||||||
)
|
)
|
||||||
from homeassistant.const import LENGTH_KILOMETERS, TEMP_CELSIUS
|
from homeassistant.const import TEMP_CELSIUS
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
@ -117,11 +117,6 @@ class MetOfficeWeather(CoordinatorEntity, WeatherEntity):
|
|||||||
_visibility = f"{visibility_class} - {visibility_distance}"
|
_visibility = f"{visibility_class} - {visibility_distance}"
|
||||||
return _visibility
|
return _visibility
|
||||||
|
|
||||||
@property
|
|
||||||
def visibility_unit(self):
|
|
||||||
"""Return the unit of measurement."""
|
|
||||||
return LENGTH_KILOMETERS
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def pressure(self):
|
def pressure(self):
|
||||||
"""Return the mean sea-level pressure."""
|
"""Return the mean sea-level pressure."""
|
||||||
|
@ -61,6 +61,8 @@ ENTITY_ID_FORMAT = DOMAIN + ".{}"
|
|||||||
|
|
||||||
SCAN_INTERVAL = timedelta(seconds=30)
|
SCAN_INTERVAL = timedelta(seconds=30)
|
||||||
|
|
||||||
|
ROUNDING_PRECISION = 2
|
||||||
|
|
||||||
|
|
||||||
class Forecast(TypedDict, total=False):
|
class Forecast(TypedDict, total=False):
|
||||||
"""Typed weather forecast dict."""
|
"""Typed weather forecast dict."""
|
||||||
@ -112,38 +114,52 @@ class WeatherEntity(Entity):
|
|||||||
_attr_ozone: float | None = None
|
_attr_ozone: float | None = None
|
||||||
_attr_precision: float
|
_attr_precision: float
|
||||||
_attr_pressure: float | None = None
|
_attr_pressure: float | None = None
|
||||||
|
_attr_pressure_unit: str | None = None
|
||||||
_attr_state: None = None
|
_attr_state: None = None
|
||||||
_attr_temperature_unit: str
|
_attr_temperature_unit: str
|
||||||
_attr_temperature: float | None
|
_attr_temperature: float | None
|
||||||
_attr_visibility: float | None = None
|
_attr_visibility: float | None = None
|
||||||
|
_attr_visibility_unit: str | None = None
|
||||||
|
_attr_precipitation_unit: str | None = None
|
||||||
_attr_wind_bearing: float | str | None = None
|
_attr_wind_bearing: float | str | None = None
|
||||||
_attr_wind_speed: float | None = None
|
_attr_wind_speed: float | None = None
|
||||||
|
_attr_wind_speed_unit: str | None = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def temperature(self) -> float | None:
|
def temperature(self) -> float | None:
|
||||||
"""Return the platform temperature."""
|
"""Return the platform temperature in native units (i.e. not converted)."""
|
||||||
return self._attr_temperature
|
return self._attr_temperature
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def temperature_unit(self) -> str:
|
def temperature_unit(self) -> str:
|
||||||
"""Return the unit of measurement."""
|
"""Return the native unit of measurement for temperature."""
|
||||||
return self._attr_temperature_unit
|
return self._attr_temperature_unit
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def pressure(self) -> float | None:
|
def pressure(self) -> float | None:
|
||||||
"""Return the pressure."""
|
"""Return the pressure in native units."""
|
||||||
return self._attr_pressure
|
return self._attr_pressure
|
||||||
|
|
||||||
|
@property
|
||||||
|
def pressure_unit(self) -> str | None:
|
||||||
|
"""Return the native unit of measurement for pressure."""
|
||||||
|
return self._attr_pressure_unit
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def humidity(self) -> float | None:
|
def humidity(self) -> float | None:
|
||||||
"""Return the humidity."""
|
"""Return the humidity in native units."""
|
||||||
return self._attr_humidity
|
return self._attr_humidity
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def wind_speed(self) -> float | None:
|
def wind_speed(self) -> float | None:
|
||||||
"""Return the wind speed."""
|
"""Return the wind speed in native units."""
|
||||||
return self._attr_wind_speed
|
return self._attr_wind_speed
|
||||||
|
|
||||||
|
@property
|
||||||
|
def wind_speed_unit(self) -> str | None:
|
||||||
|
"""Return the native unit of measurement for wind speed."""
|
||||||
|
return self._attr_wind_speed_unit
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def wind_bearing(self) -> float | str | None:
|
def wind_bearing(self) -> float | str | None:
|
||||||
"""Return the wind bearing."""
|
"""Return the wind bearing."""
|
||||||
@ -156,17 +172,27 @@ class WeatherEntity(Entity):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def visibility(self) -> float | None:
|
def visibility(self) -> float | None:
|
||||||
"""Return the visibility."""
|
"""Return the visibility in native units."""
|
||||||
return self._attr_visibility
|
return self._attr_visibility
|
||||||
|
|
||||||
|
@property
|
||||||
|
def visibility_unit(self) -> str | None:
|
||||||
|
"""Return the native unit of measurement for visibility."""
|
||||||
|
return self._attr_visibility_unit
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def forecast(self) -> list[Forecast] | None:
|
def forecast(self) -> list[Forecast] | None:
|
||||||
"""Return the forecast."""
|
"""Return the forecast in native units."""
|
||||||
return self._attr_forecast
|
return self._attr_forecast
|
||||||
|
|
||||||
|
@property
|
||||||
|
def precipitation_unit(self) -> str | None:
|
||||||
|
"""Return the native unit of measurement for accumulated precipitation."""
|
||||||
|
return self._attr_precipitation_unit
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def precision(self) -> float:
|
def precision(self) -> float:
|
||||||
"""Return the precision of the temperature value."""
|
"""Return the precision of the temperature value, after unit conversion."""
|
||||||
if hasattr(self, "_attr_precision"):
|
if hasattr(self, "_attr_precision"):
|
||||||
return self._attr_precision
|
return self._attr_precision
|
||||||
return (
|
return (
|
||||||
@ -178,11 +204,14 @@ class WeatherEntity(Entity):
|
|||||||
@final
|
@final
|
||||||
@property
|
@property
|
||||||
def state_attributes(self):
|
def state_attributes(self):
|
||||||
"""Return the state attributes."""
|
"""Return the state attributes, converted from native units to user-configured units."""
|
||||||
data = {}
|
data = {}
|
||||||
if self.temperature is not None:
|
if self.temperature is not None:
|
||||||
data[ATTR_WEATHER_TEMPERATURE] = show_temp(
|
data[ATTR_WEATHER_TEMPERATURE] = show_temp(
|
||||||
self.hass, self.temperature, self.temperature_unit, self.precision
|
self.hass,
|
||||||
|
self.temperature,
|
||||||
|
self.temperature_unit,
|
||||||
|
self.precision,
|
||||||
)
|
)
|
||||||
|
|
||||||
if (humidity := self.humidity) is not None:
|
if (humidity := self.humidity) is not None:
|
||||||
@ -192,15 +221,28 @@ class WeatherEntity(Entity):
|
|||||||
data[ATTR_WEATHER_OZONE] = ozone
|
data[ATTR_WEATHER_OZONE] = ozone
|
||||||
|
|
||||||
if (pressure := self.pressure) is not None:
|
if (pressure := self.pressure) is not None:
|
||||||
|
if (unit := self.pressure_unit) is not None:
|
||||||
|
pressure = round(
|
||||||
|
self.hass.config.units.pressure(pressure, unit), ROUNDING_PRECISION
|
||||||
|
)
|
||||||
data[ATTR_WEATHER_PRESSURE] = pressure
|
data[ATTR_WEATHER_PRESSURE] = pressure
|
||||||
|
|
||||||
if (wind_bearing := self.wind_bearing) is not None:
|
if (wind_bearing := self.wind_bearing) is not None:
|
||||||
data[ATTR_WEATHER_WIND_BEARING] = wind_bearing
|
data[ATTR_WEATHER_WIND_BEARING] = wind_bearing
|
||||||
|
|
||||||
if (wind_speed := self.wind_speed) is not None:
|
if (wind_speed := self.wind_speed) is not None:
|
||||||
|
if (unit := self.wind_speed_unit) is not None:
|
||||||
|
wind_speed = round(
|
||||||
|
self.hass.config.units.wind_speed(wind_speed, unit),
|
||||||
|
ROUNDING_PRECISION,
|
||||||
|
)
|
||||||
data[ATTR_WEATHER_WIND_SPEED] = wind_speed
|
data[ATTR_WEATHER_WIND_SPEED] = wind_speed
|
||||||
|
|
||||||
if (visibility := self.visibility) is not None:
|
if (visibility := self.visibility) is not None:
|
||||||
|
if (unit := self.visibility_unit) is not None:
|
||||||
|
visibility = round(
|
||||||
|
self.hass.config.units.length(visibility, unit), ROUNDING_PRECISION
|
||||||
|
)
|
||||||
data[ATTR_WEATHER_VISIBILITY] = visibility
|
data[ATTR_WEATHER_VISIBILITY] = visibility
|
||||||
|
|
||||||
if self.forecast is not None:
|
if self.forecast is not None:
|
||||||
@ -220,6 +262,34 @@ class WeatherEntity(Entity):
|
|||||||
self.temperature_unit,
|
self.temperature_unit,
|
||||||
self.precision,
|
self.precision,
|
||||||
)
|
)
|
||||||
|
if ATTR_FORECAST_PRESSURE in forecast_entry:
|
||||||
|
if (unit := self.pressure_unit) is not None:
|
||||||
|
pressure = round(
|
||||||
|
self.hass.config.units.pressure(
|
||||||
|
forecast_entry[ATTR_FORECAST_PRESSURE], unit
|
||||||
|
),
|
||||||
|
ROUNDING_PRECISION,
|
||||||
|
)
|
||||||
|
forecast_entry[ATTR_FORECAST_PRESSURE] = pressure
|
||||||
|
if ATTR_FORECAST_WIND_SPEED in forecast_entry:
|
||||||
|
if (unit := self.wind_speed_unit) is not None:
|
||||||
|
wind_speed = round(
|
||||||
|
self.hass.config.units.wind_speed(
|
||||||
|
forecast_entry[ATTR_FORECAST_WIND_SPEED], unit
|
||||||
|
),
|
||||||
|
ROUNDING_PRECISION,
|
||||||
|
)
|
||||||
|
forecast_entry[ATTR_FORECAST_WIND_SPEED] = wind_speed
|
||||||
|
if ATTR_FORECAST_PRECIPITATION in forecast_entry:
|
||||||
|
if (unit := self.precipitation_unit) is not None:
|
||||||
|
precipitation = round(
|
||||||
|
self.hass.config.units.accumulated_precipitation(
|
||||||
|
forecast_entry[ATTR_FORECAST_PRECIPITATION], unit
|
||||||
|
),
|
||||||
|
ROUNDING_PRECISION,
|
||||||
|
)
|
||||||
|
forecast_entry[ATTR_FORECAST_PRECIPITATION] = precipitation
|
||||||
|
|
||||||
forecast.append(forecast_entry)
|
forecast.append(forecast_entry)
|
||||||
|
|
||||||
data[ATTR_FORECAST] = forecast
|
data[ATTR_FORECAST] = forecast
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
"""The tests for the Weather component."""
|
"""The tests for the demo weather component."""
|
||||||
from homeassistant.components import weather
|
from homeassistant.components import weather
|
||||||
from homeassistant.components.weather import (
|
from homeassistant.components.weather import (
|
||||||
ATTR_FORECAST,
|
ATTR_FORECAST,
|
170
tests/components/weather/test_init.py
Normal file
170
tests/components/weather/test_init.py
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
"""The test for weather entity."""
|
||||||
|
import pytest
|
||||||
|
from pytest import approx
|
||||||
|
|
||||||
|
from homeassistant.components.weather import (
|
||||||
|
ATTR_CONDITION_SUNNY,
|
||||||
|
ATTR_FORECAST,
|
||||||
|
ATTR_FORECAST_PRECIPITATION,
|
||||||
|
ATTR_FORECAST_PRESSURE,
|
||||||
|
ATTR_FORECAST_TEMP,
|
||||||
|
ATTR_FORECAST_TEMP_LOW,
|
||||||
|
ATTR_FORECAST_WIND_SPEED,
|
||||||
|
ATTR_WEATHER_PRESSURE,
|
||||||
|
ATTR_WEATHER_TEMPERATURE,
|
||||||
|
ATTR_WEATHER_VISIBILITY,
|
||||||
|
ATTR_WEATHER_WIND_SPEED,
|
||||||
|
)
|
||||||
|
from homeassistant.const import (
|
||||||
|
LENGTH_MILES,
|
||||||
|
LENGTH_MILLIMETERS,
|
||||||
|
PRESSURE_INHG,
|
||||||
|
SPEED_METERS_PER_SECOND,
|
||||||
|
TEMP_FAHRENHEIT,
|
||||||
|
)
|
||||||
|
from homeassistant.setup import async_setup_component
|
||||||
|
from homeassistant.util.distance import convert as convert_distance
|
||||||
|
from homeassistant.util.pressure import convert as convert_pressure
|
||||||
|
from homeassistant.util.speed import convert as convert_speed
|
||||||
|
from homeassistant.util.temperature import convert as convert_temperature
|
||||||
|
from homeassistant.util.unit_system import IMPERIAL_SYSTEM, METRIC_SYSTEM
|
||||||
|
|
||||||
|
|
||||||
|
async def create_entity(hass, **kwargs):
|
||||||
|
"""Create the weather entity to run tests on."""
|
||||||
|
kwargs = {"temperature": None, "temperature_unit": None, **kwargs}
|
||||||
|
platform = getattr(hass.components, "test.weather")
|
||||||
|
platform.init(empty=True)
|
||||||
|
platform.ENTITIES.append(
|
||||||
|
platform.MockWeatherMockForecast(
|
||||||
|
name="Test", condition=ATTR_CONDITION_SUNNY, **kwargs
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
entity0 = platform.ENTITIES[0]
|
||||||
|
assert await async_setup_component(
|
||||||
|
hass, "weather", {"weather": {"platform": "test"}}
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
return entity0
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("unit_system", [IMPERIAL_SYSTEM, METRIC_SYSTEM])
|
||||||
|
async def test_temperature_conversion(
|
||||||
|
hass,
|
||||||
|
enable_custom_integrations,
|
||||||
|
unit_system,
|
||||||
|
):
|
||||||
|
"""Test temperature conversion."""
|
||||||
|
hass.config.units = unit_system
|
||||||
|
native_value = 38
|
||||||
|
native_unit = TEMP_FAHRENHEIT
|
||||||
|
|
||||||
|
entity0 = await create_entity(
|
||||||
|
hass, temperature=native_value, temperature_unit=native_unit
|
||||||
|
)
|
||||||
|
|
||||||
|
state = hass.states.get(entity0.entity_id)
|
||||||
|
forecast = state.attributes[ATTR_FORECAST][0]
|
||||||
|
|
||||||
|
expected = convert_temperature(
|
||||||
|
native_value, native_unit, unit_system.temperature_unit
|
||||||
|
)
|
||||||
|
assert float(state.attributes[ATTR_WEATHER_TEMPERATURE]) == approx(
|
||||||
|
expected, rel=0.1
|
||||||
|
)
|
||||||
|
assert float(forecast[ATTR_FORECAST_TEMP]) == approx(expected, rel=0.1)
|
||||||
|
assert float(forecast[ATTR_FORECAST_TEMP_LOW]) == approx(expected, rel=0.1)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("unit_system", [IMPERIAL_SYSTEM, METRIC_SYSTEM])
|
||||||
|
async def test_pressure_conversion(
|
||||||
|
hass,
|
||||||
|
enable_custom_integrations,
|
||||||
|
unit_system,
|
||||||
|
):
|
||||||
|
"""Test pressure conversion."""
|
||||||
|
hass.config.units = unit_system
|
||||||
|
native_value = 30
|
||||||
|
native_unit = PRESSURE_INHG
|
||||||
|
|
||||||
|
entity0 = await create_entity(
|
||||||
|
hass, pressure=native_value, pressure_unit=native_unit
|
||||||
|
)
|
||||||
|
state = hass.states.get(entity0.entity_id)
|
||||||
|
forecast = state.attributes[ATTR_FORECAST][0]
|
||||||
|
|
||||||
|
expected = convert_pressure(native_value, native_unit, unit_system.pressure_unit)
|
||||||
|
assert float(state.attributes[ATTR_WEATHER_PRESSURE]) == approx(expected, rel=1e-2)
|
||||||
|
assert float(forecast[ATTR_FORECAST_PRESSURE]) == approx(expected, rel=1e-2)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("unit_system", [IMPERIAL_SYSTEM, METRIC_SYSTEM])
|
||||||
|
async def test_wind_speed_conversion(
|
||||||
|
hass,
|
||||||
|
enable_custom_integrations,
|
||||||
|
unit_system,
|
||||||
|
):
|
||||||
|
"""Test wind speed conversion."""
|
||||||
|
hass.config.units = unit_system
|
||||||
|
native_value = 10
|
||||||
|
native_unit = SPEED_METERS_PER_SECOND
|
||||||
|
|
||||||
|
entity0 = await create_entity(
|
||||||
|
hass, wind_speed=native_value, wind_speed_unit=native_unit
|
||||||
|
)
|
||||||
|
|
||||||
|
state = hass.states.get(entity0.entity_id)
|
||||||
|
forecast = state.attributes[ATTR_FORECAST][0]
|
||||||
|
|
||||||
|
expected = convert_speed(native_value, native_unit, unit_system.wind_speed_unit)
|
||||||
|
assert float(state.attributes[ATTR_WEATHER_WIND_SPEED]) == approx(
|
||||||
|
expected, rel=1e-2
|
||||||
|
)
|
||||||
|
assert float(forecast[ATTR_FORECAST_WIND_SPEED]) == approx(expected, rel=1e-2)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("unit_system", [IMPERIAL_SYSTEM, METRIC_SYSTEM])
|
||||||
|
async def test_visibility_conversion(
|
||||||
|
hass,
|
||||||
|
enable_custom_integrations,
|
||||||
|
unit_system,
|
||||||
|
):
|
||||||
|
"""Test visibility conversion."""
|
||||||
|
hass.config.units = unit_system
|
||||||
|
native_value = 10
|
||||||
|
native_unit = LENGTH_MILES
|
||||||
|
|
||||||
|
entity0 = await create_entity(
|
||||||
|
hass, visibility=native_value, visibility_unit=native_unit
|
||||||
|
)
|
||||||
|
|
||||||
|
state = hass.states.get(entity0.entity_id)
|
||||||
|
expected = convert_distance(native_value, native_unit, unit_system.length_unit)
|
||||||
|
assert float(state.attributes[ATTR_WEATHER_VISIBILITY]) == approx(
|
||||||
|
expected, rel=1e-2
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("unit_system", [IMPERIAL_SYSTEM, METRIC_SYSTEM])
|
||||||
|
async def test_precipitation_conversion(
|
||||||
|
hass,
|
||||||
|
enable_custom_integrations,
|
||||||
|
unit_system,
|
||||||
|
):
|
||||||
|
"""Test precipitation conversion."""
|
||||||
|
hass.config.units = unit_system
|
||||||
|
native_value = 30
|
||||||
|
native_unit = LENGTH_MILLIMETERS
|
||||||
|
|
||||||
|
entity0 = await create_entity(
|
||||||
|
hass, precipitation=native_value, precipitation_unit=native_unit
|
||||||
|
)
|
||||||
|
|
||||||
|
state = hass.states.get(entity0.entity_id)
|
||||||
|
forecast = state.attributes[ATTR_FORECAST][0]
|
||||||
|
|
||||||
|
expected = convert_distance(
|
||||||
|
native_value, native_unit, unit_system.accumulated_precipitation_unit
|
||||||
|
)
|
||||||
|
assert float(forecast[ATTR_FORECAST_PRECIPITATION]) == approx(expected, rel=1e-2)
|
126
tests/testing_config/custom_components/test/weather.py
Normal file
126
tests/testing_config/custom_components/test/weather.py
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
"""
|
||||||
|
Provide a mock weather platform.
|
||||||
|
|
||||||
|
Call init before using it in your tests to ensure clean test data.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from homeassistant.components.weather import (
|
||||||
|
ATTR_FORECAST_PRECIPITATION,
|
||||||
|
ATTR_FORECAST_PRESSURE,
|
||||||
|
ATTR_FORECAST_TEMP,
|
||||||
|
ATTR_FORECAST_TEMP_LOW,
|
||||||
|
ATTR_FORECAST_WIND_BEARING,
|
||||||
|
ATTR_FORECAST_WIND_SPEED,
|
||||||
|
Forecast,
|
||||||
|
WeatherEntity,
|
||||||
|
)
|
||||||
|
|
||||||
|
from tests.common import MockEntity
|
||||||
|
|
||||||
|
ENTITIES = []
|
||||||
|
|
||||||
|
|
||||||
|
def init(empty=False):
|
||||||
|
"""Initialize the platform with entities."""
|
||||||
|
global ENTITIES
|
||||||
|
ENTITIES = [] if empty else [MockWeather()]
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_platform(
|
||||||
|
hass, config, async_add_entities_callback, discovery_info=None
|
||||||
|
):
|
||||||
|
"""Return mock entities."""
|
||||||
|
async_add_entities_callback(ENTITIES)
|
||||||
|
|
||||||
|
|
||||||
|
class MockWeather(MockEntity, WeatherEntity):
|
||||||
|
"""Mock weather class."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def temperature(self) -> float | None:
|
||||||
|
"""Return the platform temperature."""
|
||||||
|
return self._handle("temperature")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def temperature_unit(self) -> str | None:
|
||||||
|
"""Return the unit of measurement for temperature."""
|
||||||
|
return self._handle("temperature_unit")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def pressure(self) -> float | None:
|
||||||
|
"""Return the pressure."""
|
||||||
|
return self._handle("pressure")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def pressure_unit(self) -> str | None:
|
||||||
|
"""Return the unit of measurement for pressure."""
|
||||||
|
return self._handle("pressure_unit")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def humidity(self) -> float | None:
|
||||||
|
"""Return the humidity."""
|
||||||
|
return self._handle("humidity")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def wind_speed(self) -> float | None:
|
||||||
|
"""Return the wind speed."""
|
||||||
|
return self._handle("wind_speed")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def wind_speed_unit(self) -> str | None:
|
||||||
|
"""Return the unit of measurement for wind speed."""
|
||||||
|
return self._handle("wind_speed_unit")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def wind_bearing(self) -> float | str | None:
|
||||||
|
"""Return the wind bearing."""
|
||||||
|
return self._handle("wind_bearing")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def ozone(self) -> float | None:
|
||||||
|
"""Return the ozone level."""
|
||||||
|
return self._handle("ozone")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def visibility(self) -> float | None:
|
||||||
|
"""Return the visibility."""
|
||||||
|
return self._handle("visibility")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def visibility_unit(self) -> str | None:
|
||||||
|
"""Return the unit of measurement for visibility."""
|
||||||
|
return self._handle("visibility_unit")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def forecast(self) -> list[Forecast] | None:
|
||||||
|
"""Return the forecast."""
|
||||||
|
return self._handle("forecast")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def precipitation_unit(self) -> str | None:
|
||||||
|
"""Return the native unit of measurement for accumulated precipitation."""
|
||||||
|
return self._handle("precipitation_unit")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def condition(self) -> str | None:
|
||||||
|
"""Return the current condition."""
|
||||||
|
return self._handle("condition")
|
||||||
|
|
||||||
|
|
||||||
|
class MockWeatherMockForecast(MockWeather):
|
||||||
|
"""Mock weather class with mocked forecast."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def forecast(self) -> list[Forecast] | None:
|
||||||
|
"""Return the forecast."""
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
ATTR_FORECAST_TEMP: self.temperature,
|
||||||
|
ATTR_FORECAST_TEMP_LOW: self.temperature,
|
||||||
|
ATTR_FORECAST_PRESSURE: self.pressure,
|
||||||
|
ATTR_FORECAST_WIND_SPEED: self.wind_speed,
|
||||||
|
ATTR_FORECAST_WIND_BEARING: self.wind_bearing,
|
||||||
|
ATTR_FORECAST_PRECIPITATION: self._values.get("precipitation"),
|
||||||
|
}
|
||||||
|
]
|
Loading…
x
Reference in New Issue
Block a user