2016-07-31 17:20:56 +00:00
|
|
|
"""Distance util functions."""
|
2021-03-17 20:46:07 +00:00
|
|
|
from __future__ import annotations
|
|
|
|
|
2016-07-31 17:20:56 +00:00
|
|
|
from numbers import Number
|
2021-03-17 20:46:07 +00:00
|
|
|
from typing import Callable
|
2016-07-31 17:20:56 +00:00
|
|
|
|
2016-07-31 20:24:49 +00:00
|
|
|
from homeassistant.const import (
|
2019-12-09 15:42:10 +00:00
|
|
|
LENGTH,
|
2020-11-09 10:38:15 +00:00
|
|
|
LENGTH_CENTIMETERS,
|
2016-07-31 20:24:49 +00:00
|
|
|
LENGTH_FEET,
|
2020-11-09 10:38:15 +00:00
|
|
|
LENGTH_INCHES,
|
2019-12-09 15:42:10 +00:00
|
|
|
LENGTH_KILOMETERS,
|
2016-07-31 20:24:49 +00:00
|
|
|
LENGTH_METERS,
|
2019-12-09 15:42:10 +00:00
|
|
|
LENGTH_MILES,
|
2020-11-09 10:38:15 +00:00
|
|
|
LENGTH_MILLIMETERS,
|
|
|
|
LENGTH_YARD,
|
2016-07-31 20:24:49 +00:00
|
|
|
UNIT_NOT_RECOGNIZED_TEMPLATE,
|
|
|
|
)
|
2016-07-31 17:20:56 +00:00
|
|
|
|
2021-07-20 12:13:51 +00:00
|
|
|
VALID_UNITS: tuple[str, ...] = (
|
2020-11-09 10:38:15 +00:00
|
|
|
LENGTH_KILOMETERS,
|
|
|
|
LENGTH_MILES,
|
|
|
|
LENGTH_FEET,
|
|
|
|
LENGTH_METERS,
|
|
|
|
LENGTH_CENTIMETERS,
|
|
|
|
LENGTH_MILLIMETERS,
|
|
|
|
LENGTH_INCHES,
|
|
|
|
LENGTH_YARD,
|
2021-07-18 12:43:47 +00:00
|
|
|
)
|
2016-07-31 17:20:56 +00:00
|
|
|
|
2021-07-20 12:13:51 +00:00
|
|
|
TO_METERS: dict[str, Callable[[float], float]] = {
|
2020-11-11 19:10:17 +00:00
|
|
|
LENGTH_METERS: lambda meters: meters,
|
|
|
|
LENGTH_MILES: lambda miles: miles * 1609.344,
|
|
|
|
LENGTH_YARD: lambda yards: yards * 0.9144,
|
|
|
|
LENGTH_FEET: lambda feet: feet * 0.3048,
|
|
|
|
LENGTH_INCHES: lambda inches: inches * 0.0254,
|
|
|
|
LENGTH_KILOMETERS: lambda kilometers: kilometers * 1000,
|
|
|
|
LENGTH_CENTIMETERS: lambda centimeters: centimeters * 0.01,
|
|
|
|
LENGTH_MILLIMETERS: lambda millimeters: millimeters * 0.001,
|
|
|
|
}
|
|
|
|
|
2021-07-20 12:13:51 +00:00
|
|
|
METERS_TO: dict[str, Callable[[float], float]] = {
|
2020-11-11 19:10:17 +00:00
|
|
|
LENGTH_METERS: lambda meters: meters,
|
|
|
|
LENGTH_MILES: lambda meters: meters * 0.000621371,
|
|
|
|
LENGTH_YARD: lambda meters: meters * 1.09361,
|
|
|
|
LENGTH_FEET: lambda meters: meters * 3.28084,
|
|
|
|
LENGTH_INCHES: lambda meters: meters * 39.3701,
|
|
|
|
LENGTH_KILOMETERS: lambda meters: meters * 0.001,
|
|
|
|
LENGTH_CENTIMETERS: lambda meters: meters * 100,
|
|
|
|
LENGTH_MILLIMETERS: lambda meters: meters * 1000,
|
|
|
|
}
|
|
|
|
|
2016-07-31 17:20:56 +00:00
|
|
|
|
2021-07-20 12:13:51 +00:00
|
|
|
def convert(value: float, unit_1: str, unit_2: str) -> float:
|
2016-07-31 17:20:56 +00:00
|
|
|
"""Convert one unit of measurement to another."""
|
2016-07-31 20:24:49 +00:00
|
|
|
if unit_1 not in VALID_UNITS:
|
2019-07-31 19:25:30 +00:00
|
|
|
raise ValueError(UNIT_NOT_RECOGNIZED_TEMPLATE.format(unit_1, LENGTH))
|
2016-07-31 20:24:49 +00:00
|
|
|
if unit_2 not in VALID_UNITS:
|
2019-07-31 19:25:30 +00:00
|
|
|
raise ValueError(UNIT_NOT_RECOGNIZED_TEMPLATE.format(unit_2, LENGTH))
|
2016-07-31 20:24:49 +00:00
|
|
|
|
2016-07-31 17:20:56 +00:00
|
|
|
if not isinstance(value, Number):
|
2019-08-23 16:53:33 +00:00
|
|
|
raise TypeError(f"{value} is not of numeric type")
|
2016-07-31 17:20:56 +00:00
|
|
|
|
2020-03-12 10:52:20 +00:00
|
|
|
if unit_1 == unit_2 or unit_1 not in VALID_UNITS:
|
2016-07-31 17:20:56 +00:00
|
|
|
return value
|
|
|
|
|
2020-11-11 19:10:17 +00:00
|
|
|
meters: float = TO_METERS[unit_1](value)
|
2020-11-09 10:38:15 +00:00
|
|
|
|
2020-11-11 19:10:17 +00:00
|
|
|
return METERS_TO[unit_2](meters)
|