57 lines
1.7 KiB
Python
57 lines
1.7 KiB
Python
|
"""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]
|