Add speed conversion function & add speed to units system (#53846)
* Add speed conversion function * Add test for speed utility functions * Update unit system tests * Fix incorrect unit conversions in tests * Fix some test errors * Calculate speed units from smaller set of constants * Fix typo in speed test * Use pytest.approx for checking floating point values * Change other instance of speeds needing to be pytest.approx * Revert changes to unit system * Fix oopsie in defining in/day and in/hr * Parametrize test * Add comments describing calculations & remove duplicate test
This commit is contained in:
parent
f46ba2b38b
commit
a102c425a9
9 changed files with 179 additions and 19 deletions
|
@ -37,6 +37,8 @@ from homeassistant.const import (
|
||||||
LENGTH_MILES,
|
LENGTH_MILES,
|
||||||
PRESSURE_HPA,
|
PRESSURE_HPA,
|
||||||
PRESSURE_INHG,
|
PRESSURE_INHG,
|
||||||
|
SPEED_KILOMETERS_PER_HOUR,
|
||||||
|
SPEED_MILES_PER_HOUR,
|
||||||
TEMP_FAHRENHEIT,
|
TEMP_FAHRENHEIT,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
@ -45,6 +47,7 @@ from homeassistant.helpers.sun import is_up
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
from homeassistant.util.distance import convert as distance_convert
|
from homeassistant.util.distance import convert as distance_convert
|
||||||
from homeassistant.util.pressure import convert as pressure_convert
|
from homeassistant.util.pressure import convert as pressure_convert
|
||||||
|
from homeassistant.util.speed import convert as speed_convert
|
||||||
|
|
||||||
from . import ClimaCellDataUpdateCoordinator, ClimaCellEntity
|
from . import ClimaCellDataUpdateCoordinator, ClimaCellEntity
|
||||||
from .const import (
|
from .const import (
|
||||||
|
@ -166,7 +169,10 @@ class BaseClimaCellWeatherEntity(ClimaCellEntity, WeatherEntity):
|
||||||
)
|
)
|
||||||
if wind_speed:
|
if wind_speed:
|
||||||
wind_speed = round(
|
wind_speed = round(
|
||||||
distance_convert(wind_speed, LENGTH_MILES, LENGTH_KILOMETERS), 4
|
speed_convert(
|
||||||
|
wind_speed, SPEED_MILES_PER_HOUR, SPEED_KILOMETERS_PER_HOUR
|
||||||
|
),
|
||||||
|
4,
|
||||||
)
|
)
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
|
@ -188,7 +194,10 @@ class BaseClimaCellWeatherEntity(ClimaCellEntity, WeatherEntity):
|
||||||
wind_gust = self.wind_gust
|
wind_gust = self.wind_gust
|
||||||
if wind_gust and self.hass.config.units.is_metric:
|
if wind_gust and self.hass.config.units.is_metric:
|
||||||
wind_gust = round(
|
wind_gust = round(
|
||||||
distance_convert(self.wind_gust, LENGTH_MILES, LENGTH_KILOMETERS), 4
|
speed_convert(
|
||||||
|
self.wind_gust, SPEED_MILES_PER_HOUR, SPEED_KILOMETERS_PER_HOUR
|
||||||
|
),
|
||||||
|
4,
|
||||||
)
|
)
|
||||||
cloud_cover = self.cloud_cover
|
cloud_cover = self.cloud_cover
|
||||||
return {
|
return {
|
||||||
|
@ -236,7 +245,10 @@ class BaseClimaCellWeatherEntity(ClimaCellEntity, WeatherEntity):
|
||||||
"""Return the wind speed."""
|
"""Return the wind speed."""
|
||||||
if self.hass.config.units.is_metric and self._wind_speed:
|
if self.hass.config.units.is_metric and self._wind_speed:
|
||||||
return round(
|
return round(
|
||||||
distance_convert(self._wind_speed, LENGTH_MILES, LENGTH_KILOMETERS), 4
|
speed_convert(
|
||||||
|
self._wind_speed, SPEED_MILES_PER_HOUR, SPEED_KILOMETERS_PER_HOUR
|
||||||
|
),
|
||||||
|
4,
|
||||||
)
|
)
|
||||||
return self._wind_speed
|
return self._wind_speed
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,11 @@ from homeassistant.const import (
|
||||||
CONF_LONGITUDE,
|
CONF_LONGITUDE,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
LENGTH_INCHES,
|
LENGTH_INCHES,
|
||||||
LENGTH_KILOMETERS,
|
|
||||||
LENGTH_MILES,
|
|
||||||
LENGTH_MILLIMETERS,
|
LENGTH_MILLIMETERS,
|
||||||
PRESSURE_HPA,
|
PRESSURE_HPA,
|
||||||
PRESSURE_INHG,
|
PRESSURE_INHG,
|
||||||
|
SPEED_KILOMETERS_PER_HOUR,
|
||||||
|
SPEED_MILES_PER_HOUR,
|
||||||
TEMP_CELSIUS,
|
TEMP_CELSIUS,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
@ -46,6 +46,7 @@ from homeassistant.helpers.update_coordinator import (
|
||||||
)
|
)
|
||||||
from homeassistant.util.distance import convert as convert_distance
|
from homeassistant.util.distance import convert as convert_distance
|
||||||
from homeassistant.util.pressure import convert as convert_pressure
|
from homeassistant.util.pressure import convert as convert_pressure
|
||||||
|
from homeassistant.util.speed import convert as convert_speed
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
ATTR_FORECAST_PRECIPITATION,
|
ATTR_FORECAST_PRECIPITATION,
|
||||||
|
@ -226,7 +227,9 @@ class MetWeather(CoordinatorEntity, WeatherEntity):
|
||||||
if self._is_metric or speed_km_h is None:
|
if self._is_metric or speed_km_h is None:
|
||||||
return speed_km_h
|
return speed_km_h
|
||||||
|
|
||||||
speed_mi_h = convert_distance(speed_km_h, LENGTH_KILOMETERS, LENGTH_MILES)
|
speed_mi_h = convert_speed(
|
||||||
|
speed_km_h, SPEED_KILOMETERS_PER_HOUR, SPEED_MILES_PER_HOUR
|
||||||
|
)
|
||||||
return int(round(speed_mi_h))
|
return int(round(speed_mi_h))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -13,11 +13,11 @@ from homeassistant.const import (
|
||||||
CONF_LONGITUDE,
|
CONF_LONGITUDE,
|
||||||
CONF_NAME,
|
CONF_NAME,
|
||||||
LENGTH_INCHES,
|
LENGTH_INCHES,
|
||||||
LENGTH_METERS,
|
|
||||||
LENGTH_MILES,
|
|
||||||
LENGTH_MILLIMETERS,
|
LENGTH_MILLIMETERS,
|
||||||
PRESSURE_HPA,
|
PRESSURE_HPA,
|
||||||
PRESSURE_INHG,
|
PRESSURE_INHG,
|
||||||
|
SPEED_METERS_PER_SECOND,
|
||||||
|
SPEED_MILES_PER_HOUR,
|
||||||
TEMP_CELSIUS,
|
TEMP_CELSIUS,
|
||||||
)
|
)
|
||||||
from homeassistant.helpers.entity import DeviceInfo
|
from homeassistant.helpers.entity import DeviceInfo
|
||||||
|
@ -25,6 +25,7 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
from homeassistant.util.distance import convert as convert_distance
|
from homeassistant.util.distance import convert as convert_distance
|
||||||
from homeassistant.util.pressure import convert as convert_pressure
|
from homeassistant.util.pressure import convert as convert_pressure
|
||||||
|
from homeassistant.util.speed import convert as convert_speed
|
||||||
|
|
||||||
from .const import ATTRIBUTION, CONDITION_MAP, DEFAULT_NAME, DOMAIN, FORECAST_MAP
|
from .const import ATTRIBUTION, CONDITION_MAP, DEFAULT_NAME, DOMAIN, FORECAST_MAP
|
||||||
|
|
||||||
|
@ -130,8 +131,9 @@ class MetEireannWeather(CoordinatorEntity, WeatherEntity):
|
||||||
if self._is_metric or speed_m_s is None:
|
if self._is_metric or speed_m_s is None:
|
||||||
return speed_m_s
|
return speed_m_s
|
||||||
|
|
||||||
speed_mi_s = convert_distance(speed_m_s, LENGTH_METERS, LENGTH_MILES)
|
speed_mi_h = convert_speed(
|
||||||
speed_mi_h = speed_mi_s / 3600.0
|
speed_m_s, SPEED_METERS_PER_SECOND, SPEED_MILES_PER_HOUR
|
||||||
|
)
|
||||||
return int(round(speed_mi_h))
|
return int(round(speed_mi_h))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -4,12 +4,12 @@ from homeassistant.const import (
|
||||||
ATTR_ATTRIBUTION,
|
ATTR_ATTRIBUTION,
|
||||||
CONF_LATITUDE,
|
CONF_LATITUDE,
|
||||||
CONF_LONGITUDE,
|
CONF_LONGITUDE,
|
||||||
LENGTH_KILOMETERS,
|
|
||||||
LENGTH_METERS,
|
LENGTH_METERS,
|
||||||
LENGTH_MILES,
|
LENGTH_MILES,
|
||||||
PERCENTAGE,
|
PERCENTAGE,
|
||||||
PRESSURE_INHG,
|
PRESSURE_INHG,
|
||||||
PRESSURE_PA,
|
PRESSURE_PA,
|
||||||
|
SPEED_KILOMETERS_PER_HOUR,
|
||||||
SPEED_MILES_PER_HOUR,
|
SPEED_MILES_PER_HOUR,
|
||||||
TEMP_CELSIUS,
|
TEMP_CELSIUS,
|
||||||
)
|
)
|
||||||
|
@ -19,6 +19,7 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
from homeassistant.util.distance import convert as convert_distance
|
from homeassistant.util.distance import convert as convert_distance
|
||||||
from homeassistant.util.dt import utcnow
|
from homeassistant.util.dt import utcnow
|
||||||
from homeassistant.util.pressure import convert as convert_pressure
|
from homeassistant.util.pressure import convert as convert_pressure
|
||||||
|
from homeassistant.util.speed import convert as convert_speed
|
||||||
|
|
||||||
from . import base_unique_id, device_info
|
from . import base_unique_id, device_info
|
||||||
from .const import (
|
from .const import (
|
||||||
|
@ -86,7 +87,9 @@ class NWSSensor(CoordinatorEntity, SensorEntity):
|
||||||
# Set alias to unit property -> prevent unnecessary hasattr calls
|
# Set alias to unit property -> prevent unnecessary hasattr calls
|
||||||
unit_of_measurement = self.native_unit_of_measurement
|
unit_of_measurement = self.native_unit_of_measurement
|
||||||
if unit_of_measurement == SPEED_MILES_PER_HOUR:
|
if unit_of_measurement == SPEED_MILES_PER_HOUR:
|
||||||
return round(convert_distance(value, LENGTH_KILOMETERS, LENGTH_MILES))
|
return round(
|
||||||
|
convert_speed(value, SPEED_KILOMETERS_PER_HOUR, SPEED_MILES_PER_HOUR)
|
||||||
|
)
|
||||||
if unit_of_measurement == LENGTH_MILES:
|
if unit_of_measurement == LENGTH_MILES:
|
||||||
return round(convert_distance(value, LENGTH_METERS, LENGTH_MILES))
|
return round(convert_distance(value, LENGTH_METERS, LENGTH_MILES))
|
||||||
if unit_of_measurement == PRESSURE_INHG:
|
if unit_of_measurement == PRESSURE_INHG:
|
||||||
|
|
|
@ -19,6 +19,8 @@ from homeassistant.const import (
|
||||||
PRESSURE_HPA,
|
PRESSURE_HPA,
|
||||||
PRESSURE_INHG,
|
PRESSURE_INHG,
|
||||||
PRESSURE_PA,
|
PRESSURE_PA,
|
||||||
|
SPEED_KILOMETERS_PER_HOUR,
|
||||||
|
SPEED_MILES_PER_HOUR,
|
||||||
TEMP_CELSIUS,
|
TEMP_CELSIUS,
|
||||||
TEMP_FAHRENHEIT,
|
TEMP_FAHRENHEIT,
|
||||||
)
|
)
|
||||||
|
@ -28,6 +30,7 @@ from homeassistant.helpers.typing import ConfigType
|
||||||
from homeassistant.util.distance import convert as convert_distance
|
from homeassistant.util.distance import convert as convert_distance
|
||||||
from homeassistant.util.dt import utcnow
|
from homeassistant.util.dt import utcnow
|
||||||
from homeassistant.util.pressure import convert as convert_pressure
|
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.temperature import convert as convert_temperature
|
||||||
|
|
||||||
from . import base_unique_id, device_info
|
from . import base_unique_id, device_info
|
||||||
|
@ -196,7 +199,9 @@ class NWSWeather(WeatherEntity):
|
||||||
if self.is_metric:
|
if self.is_metric:
|
||||||
wind = wind_km_hr
|
wind = wind_km_hr
|
||||||
else:
|
else:
|
||||||
wind = convert_distance(wind_km_hr, LENGTH_KILOMETERS, LENGTH_MILES)
|
wind = convert_speed(
|
||||||
|
wind_km_hr, SPEED_KILOMETERS_PER_HOUR, SPEED_MILES_PER_HOUR
|
||||||
|
)
|
||||||
return round(wind)
|
return round(wind)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -271,7 +276,9 @@ class NWSWeather(WeatherEntity):
|
||||||
if wind_speed is not None:
|
if wind_speed is not None:
|
||||||
if self.is_metric:
|
if self.is_metric:
|
||||||
data[ATTR_FORECAST_WIND_SPEED] = round(
|
data[ATTR_FORECAST_WIND_SPEED] = round(
|
||||||
convert_distance(wind_speed, LENGTH_MILES, LENGTH_KILOMETERS)
|
convert_speed(
|
||||||
|
wind_speed, SPEED_MILES_PER_HOUR, SPEED_KILOMETERS_PER_HOUR
|
||||||
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
data[ATTR_FORECAST_WIND_SPEED] = round(wind_speed)
|
data[ATTR_FORECAST_WIND_SPEED] = round(wind_speed)
|
||||||
|
|
|
@ -695,7 +695,7 @@ MASS: Final = "mass"
|
||||||
PRESSURE: Final = "pressure"
|
PRESSURE: Final = "pressure"
|
||||||
VOLUME: Final = "volume"
|
VOLUME: Final = "volume"
|
||||||
TEMPERATURE: Final = "temperature"
|
TEMPERATURE: Final = "temperature"
|
||||||
SPEED_MS: Final = "speed_ms"
|
SPEED: Final = "speed"
|
||||||
ILLUMINANCE: Final = "illuminance"
|
ILLUMINANCE: Final = "illuminance"
|
||||||
|
|
||||||
WEEKDAYS: Final[list[str]] = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]
|
WEEKDAYS: Final[list[str]] = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]
|
||||||
|
|
56
homeassistant/util/speed.py
Normal file
56
homeassistant/util/speed.py
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
"""Distance util functions."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from numbers import Number
|
||||||
|
|
||||||
|
from homeassistant.const import (
|
||||||
|
SPEED,
|
||||||
|
SPEED_INCHES_PER_DAY,
|
||||||
|
SPEED_INCHES_PER_HOUR,
|
||||||
|
SPEED_KILOMETERS_PER_HOUR,
|
||||||
|
SPEED_METERS_PER_SECOND,
|
||||||
|
SPEED_MILES_PER_HOUR,
|
||||||
|
SPEED_MILLIMETERS_PER_DAY,
|
||||||
|
UNIT_NOT_RECOGNIZED_TEMPLATE,
|
||||||
|
)
|
||||||
|
|
||||||
|
VALID_UNITS: tuple[str, ...] = (
|
||||||
|
SPEED_METERS_PER_SECOND,
|
||||||
|
SPEED_KILOMETERS_PER_HOUR,
|
||||||
|
SPEED_MILES_PER_HOUR,
|
||||||
|
SPEED_MILLIMETERS_PER_DAY,
|
||||||
|
SPEED_INCHES_PER_DAY,
|
||||||
|
SPEED_INCHES_PER_HOUR,
|
||||||
|
)
|
||||||
|
|
||||||
|
HRS_TO_SECS = 60 * 60 # 1 hr = 3600 seconds
|
||||||
|
KM_TO_M = 1000 # 1 km = 1000 m
|
||||||
|
KM_TO_MILE = 0.62137119 # 1 km = 0.62137119 mi
|
||||||
|
M_TO_IN = 39.3700787 # 1 m = 39.3700787 in
|
||||||
|
|
||||||
|
# Units in terms of m/s
|
||||||
|
UNIT_CONVERSION: dict[str, float] = {
|
||||||
|
SPEED_METERS_PER_SECOND: 1,
|
||||||
|
SPEED_KILOMETERS_PER_HOUR: HRS_TO_SECS / KM_TO_M,
|
||||||
|
SPEED_MILES_PER_HOUR: HRS_TO_SECS * KM_TO_MILE / KM_TO_M,
|
||||||
|
SPEED_MILLIMETERS_PER_DAY: (24 * HRS_TO_SECS) * 1000,
|
||||||
|
SPEED_INCHES_PER_DAY: (24 * HRS_TO_SECS) * M_TO_IN,
|
||||||
|
SPEED_INCHES_PER_HOUR: HRS_TO_SECS * M_TO_IN,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def convert(value: float, unit_1: str, unit_2: str) -> float:
|
||||||
|
"""Convert one unit of measurement to another."""
|
||||||
|
if unit_1 not in VALID_UNITS:
|
||||||
|
raise ValueError(UNIT_NOT_RECOGNIZED_TEMPLATE.format(unit_1, SPEED))
|
||||||
|
if unit_2 not in VALID_UNITS:
|
||||||
|
raise ValueError(UNIT_NOT_RECOGNIZED_TEMPLATE.format(unit_2, SPEED))
|
||||||
|
|
||||||
|
if not isinstance(value, Number):
|
||||||
|
raise TypeError(f"{value} is not of numeric type")
|
||||||
|
|
||||||
|
if unit_1 == unit_2:
|
||||||
|
return value
|
||||||
|
|
||||||
|
meters_per_second = value / UNIT_CONVERSION[unit_1]
|
||||||
|
return meters_per_second * UNIT_CONVERSION[unit_2]
|
|
@ -25,11 +25,14 @@ from homeassistant.const import (
|
||||||
PRESSURE_HPA,
|
PRESSURE_HPA,
|
||||||
PRESSURE_INHG,
|
PRESSURE_INHG,
|
||||||
PRESSURE_PA,
|
PRESSURE_PA,
|
||||||
|
SPEED_KILOMETERS_PER_HOUR,
|
||||||
|
SPEED_MILES_PER_HOUR,
|
||||||
TEMP_CELSIUS,
|
TEMP_CELSIUS,
|
||||||
TEMP_FAHRENHEIT,
|
TEMP_FAHRENHEIT,
|
||||||
)
|
)
|
||||||
from homeassistant.util.distance import convert as convert_distance
|
from homeassistant.util.distance import convert as convert_distance
|
||||||
from homeassistant.util.pressure import convert as convert_pressure
|
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.temperature import convert as convert_temperature
|
||||||
|
|
||||||
NWS_CONFIG = {
|
NWS_CONFIG = {
|
||||||
|
@ -80,8 +83,12 @@ SENSOR_EXPECTED_OBSERVATION_IMPERIAL = {
|
||||||
"windChill": str(round(convert_temperature(5, TEMP_CELSIUS, TEMP_FAHRENHEIT))),
|
"windChill": str(round(convert_temperature(5, TEMP_CELSIUS, TEMP_FAHRENHEIT))),
|
||||||
"heatIndex": str(round(convert_temperature(15, TEMP_CELSIUS, TEMP_FAHRENHEIT))),
|
"heatIndex": str(round(convert_temperature(15, TEMP_CELSIUS, TEMP_FAHRENHEIT))),
|
||||||
"relativeHumidity": "10",
|
"relativeHumidity": "10",
|
||||||
"windSpeed": str(round(convert_distance(10, LENGTH_KILOMETERS, LENGTH_MILES))),
|
"windSpeed": str(
|
||||||
"windGust": str(round(convert_distance(20, LENGTH_KILOMETERS, LENGTH_MILES))),
|
round(convert_speed(10, SPEED_KILOMETERS_PER_HOUR, SPEED_MILES_PER_HOUR))
|
||||||
|
),
|
||||||
|
"windGust": str(
|
||||||
|
round(convert_speed(20, SPEED_KILOMETERS_PER_HOUR, SPEED_MILES_PER_HOUR))
|
||||||
|
),
|
||||||
"windDirection": "180",
|
"windDirection": "180",
|
||||||
"barometricPressure": str(
|
"barometricPressure": str(
|
||||||
round(convert_pressure(100000, PRESSURE_PA, PRESSURE_INHG), 2)
|
round(convert_pressure(100000, PRESSURE_PA, PRESSURE_INHG), 2)
|
||||||
|
@ -98,7 +105,7 @@ WEATHER_EXPECTED_OBSERVATION_IMPERIAL = {
|
||||||
),
|
),
|
||||||
ATTR_WEATHER_WIND_BEARING: 180,
|
ATTR_WEATHER_WIND_BEARING: 180,
|
||||||
ATTR_WEATHER_WIND_SPEED: round(
|
ATTR_WEATHER_WIND_SPEED: round(
|
||||||
convert_distance(10, LENGTH_KILOMETERS, LENGTH_MILES)
|
convert_speed(10, SPEED_KILOMETERS_PER_HOUR, SPEED_MILES_PER_HOUR)
|
||||||
),
|
),
|
||||||
ATTR_WEATHER_PRESSURE: round(
|
ATTR_WEATHER_PRESSURE: round(
|
||||||
convert_pressure(100000, PRESSURE_PA, PRESSURE_INHG), 2
|
convert_pressure(100000, PRESSURE_PA, PRESSURE_INHG), 2
|
||||||
|
@ -152,7 +159,7 @@ EXPECTED_FORECAST_METRIC = {
|
||||||
ATTR_FORECAST_TIME: "2019-08-12T20:00:00-04:00",
|
ATTR_FORECAST_TIME: "2019-08-12T20:00:00-04:00",
|
||||||
ATTR_FORECAST_TEMP: round(convert_temperature(10, TEMP_FAHRENHEIT, TEMP_CELSIUS)),
|
ATTR_FORECAST_TEMP: round(convert_temperature(10, TEMP_FAHRENHEIT, TEMP_CELSIUS)),
|
||||||
ATTR_FORECAST_WIND_SPEED: round(
|
ATTR_FORECAST_WIND_SPEED: round(
|
||||||
convert_distance(10, LENGTH_MILES, LENGTH_KILOMETERS)
|
convert_speed(10, SPEED_MILES_PER_HOUR, SPEED_KILOMETERS_PER_HOUR)
|
||||||
),
|
),
|
||||||
ATTR_FORECAST_WIND_BEARING: 180,
|
ATTR_FORECAST_WIND_BEARING: 180,
|
||||||
ATTR_FORECAST_PRECIPITATION_PROBABILITY: 90,
|
ATTR_FORECAST_PRECIPITATION_PROBABILITY: 90,
|
||||||
|
|
70
tests/util/test_speed.py
Normal file
70
tests/util/test_speed.py
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
"""Test Home Assistant speed utility functions."""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from homeassistant.const import (
|
||||||
|
SPEED_INCHES_PER_DAY,
|
||||||
|
SPEED_INCHES_PER_HOUR,
|
||||||
|
SPEED_KILOMETERS_PER_HOUR,
|
||||||
|
SPEED_METERS_PER_SECOND,
|
||||||
|
SPEED_MILES_PER_HOUR,
|
||||||
|
SPEED_MILLIMETERS_PER_DAY,
|
||||||
|
)
|
||||||
|
import homeassistant.util.speed as speed_util
|
||||||
|
|
||||||
|
INVALID_SYMBOL = "bob"
|
||||||
|
VALID_SYMBOL = SPEED_KILOMETERS_PER_HOUR
|
||||||
|
|
||||||
|
|
||||||
|
def test_convert_same_unit():
|
||||||
|
"""Test conversion from any unit to same unit."""
|
||||||
|
assert speed_util.convert(2, SPEED_INCHES_PER_DAY, SPEED_INCHES_PER_DAY) == 2
|
||||||
|
assert speed_util.convert(3, SPEED_INCHES_PER_HOUR, SPEED_INCHES_PER_HOUR) == 3
|
||||||
|
assert (
|
||||||
|
speed_util.convert(4, SPEED_KILOMETERS_PER_HOUR, SPEED_KILOMETERS_PER_HOUR) == 4
|
||||||
|
)
|
||||||
|
assert speed_util.convert(5, SPEED_METERS_PER_SECOND, SPEED_METERS_PER_SECOND) == 5
|
||||||
|
assert speed_util.convert(6, SPEED_MILES_PER_HOUR, SPEED_MILES_PER_HOUR) == 6
|
||||||
|
assert (
|
||||||
|
speed_util.convert(7, SPEED_MILLIMETERS_PER_DAY, SPEED_MILLIMETERS_PER_DAY) == 7
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_convert_invalid_unit():
|
||||||
|
"""Test exception is thrown for invalid units."""
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
speed_util.convert(5, INVALID_SYMBOL, VALID_SYMBOL)
|
||||||
|
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
speed_util.convert(5, VALID_SYMBOL, INVALID_SYMBOL)
|
||||||
|
|
||||||
|
|
||||||
|
def test_convert_nonnumeric_value():
|
||||||
|
"""Test exception is thrown for nonnumeric type."""
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
speed_util.convert("a", SPEED_KILOMETERS_PER_HOUR, SPEED_MILES_PER_HOUR)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"from_value, from_unit, expected, to_unit",
|
||||||
|
[
|
||||||
|
# 5 km/h / 1.609 km/mi = 3.10686 mi/h
|
||||||
|
(5, SPEED_KILOMETERS_PER_HOUR, 3.10686, SPEED_MILES_PER_HOUR),
|
||||||
|
# 5 mi/h * 1.609 km/mi = 8.04672 km/h
|
||||||
|
(5, SPEED_MILES_PER_HOUR, 8.04672, SPEED_KILOMETERS_PER_HOUR),
|
||||||
|
# 5 in/day * 25.4 mm/in = 127 mm/day
|
||||||
|
(5, SPEED_INCHES_PER_DAY, 127, SPEED_MILLIMETERS_PER_DAY),
|
||||||
|
# 5 mm/day / 25.4 mm/in = 0.19685 in/day
|
||||||
|
(5, SPEED_MILLIMETERS_PER_DAY, 0.19685, SPEED_INCHES_PER_DAY),
|
||||||
|
# 5 in/hr * 24 hr/day = 3048 mm/day
|
||||||
|
(5, SPEED_INCHES_PER_HOUR, 3048, SPEED_MILLIMETERS_PER_DAY),
|
||||||
|
# 5 m/s * 39.3701 in/m * 3600 s/hr = 708661
|
||||||
|
(5, SPEED_METERS_PER_SECOND, 708661, SPEED_INCHES_PER_HOUR),
|
||||||
|
# 5000 in/hr / 39.3701 in/m / 3600 s/hr = 0.03528 m/s
|
||||||
|
(5000, SPEED_INCHES_PER_HOUR, 0.03528, SPEED_METERS_PER_SECOND),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_convert_different_units(from_value, from_unit, expected, to_unit):
|
||||||
|
"""Test conversion between units."""
|
||||||
|
assert speed_util.convert(from_value, from_unit, to_unit) == pytest.approx(
|
||||||
|
expected, rel=1e-4
|
||||||
|
)
|
Loading…
Add table
Add a link
Reference in a new issue