Add new unit types for better type checking (#53124)

* Add new unit types
* Update helper functions
* Update components
* Update lcn climate
This commit is contained in:
Marc Mueller 2021-07-18 14:43:47 +02:00 committed by GitHub
parent 78f4a49b73
commit 71a8ae3016
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 254 additions and 152 deletions

View file

@ -18,6 +18,7 @@ from homeassistant.const import (
STATE_OFF,
STATE_ON,
TEMP_CELSIUS,
UnitTemperatureT,
)
from homeassistant.core import HomeAssistant, ServiceCall
import homeassistant.helpers.config_validation as cv
@ -195,7 +196,7 @@ class ClimateEntity(Entity):
_attr_target_temperature_low: float | None
_attr_target_temperature_step: float | None = None
_attr_target_temperature: float | None = None
_attr_temperature_unit: str
_attr_temperature_unit: UnitTemperatureT
@property
def state(self) -> str:
@ -303,7 +304,7 @@ class ClimateEntity(Entity):
return data
@property
def temperature_unit(self) -> str:
def temperature_unit(self) -> UnitTemperatureT:
"""Return the unit of measurement used by the platform."""
return self._attr_temperature_unit

View file

@ -19,6 +19,7 @@ from homeassistant.const import (
CONF_PLATFORM,
CONF_TYPE,
PERCENTAGE,
UnitT,
)
from homeassistant.core import CALLBACK_TYPE, HomeAssistant
from homeassistant.helpers import config_validation as cv, entity_registry
@ -172,6 +173,7 @@ async def async_get_trigger_capabilities(hass: HomeAssistant, config):
)
}
unit_of_measurement: UnitT
if trigger_type == "current_temperature_changed":
unit_of_measurement = hass.config.units.temperature_unit
else:

View file

@ -11,7 +11,7 @@ from homeassistant.components.climate import (
ClimateEntity,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import PRECISION_HALVES, PRECISION_TENTHS
from homeassistant.const import PRECISION_HALVES, PRECISION_TENTHS, UnitTemperatureT
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -105,7 +105,7 @@ class DevoloClimateDeviceEntity(DevoloMultiLevelSwitchDeviceEntity, ClimateEntit
return SUPPORT_TARGET_TEMPERATURE
@property
def temperature_unit(self) -> str:
def temperature_unit(self) -> UnitTemperatureT:
"""Return the supported unit of temperature."""
return TEMP_CELSIUS

View file

@ -65,6 +65,7 @@ from homeassistant.const import (
PRECISION_TENTHS,
PRECISION_WHOLE,
TEMP_CELSIUS,
UnitTemperatureT,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -166,7 +167,7 @@ class EsphomeClimateEntity(EsphomeEntity[ClimateInfo, ClimateState], ClimateEnti
return PRECISION_TENTHS
@property
def temperature_unit(self) -> str:
def temperature_unit(self) -> UnitTemperatureT:
"""Return the unit of measurement used by the platform."""
return TEMP_CELSIUS

View file

@ -23,6 +23,7 @@ from homeassistant.const import (
ATTR_UNIT_OF_MEASUREMENT,
PRECISION_HALVES,
TEMP_CELSIUS,
UnitTemperatureT,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -97,7 +98,7 @@ class FritzboxThermostat(FritzBoxEntity, ClimateEntity):
return self.device.present # type: ignore [no-any-return]
@property
def temperature_unit(self) -> str:
def temperature_unit(self) -> UnitTemperatureT:
"""Return the unit of measurement that is used."""
return TEMP_CELSIUS

View file

@ -18,6 +18,9 @@ from homeassistant.const import (
CONF_ENTITIES,
CONF_SOURCE,
CONF_UNIT_OF_MEASUREMENT,
TEMP_CELSIUS,
TEMP_FAHRENHEIT,
UnitTemperatureT,
)
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, HomeAssistantType
@ -107,9 +110,12 @@ class LcnClimate(LcnEntity, ClimateEntity):
return const.SUPPORT_TARGET_TEMPERATURE
@property
def temperature_unit(self) -> str:
def temperature_unit(self) -> UnitTemperatureT:
"""Return the unit of measurement."""
return cast(str, self.unit.value)
# Config schema only allows for: TEMP_CELSIUS and TEMP_FAHRENHEIT
if self.unit == pypck.lcn_defs.VarUnit.FAHRENHEIT:
return TEMP_FAHRENHEIT
return TEMP_CELSIUS
@property
def current_temperature(self) -> float | None:

View file

@ -19,7 +19,12 @@ from homeassistant.components.climate.const import (
)
from homeassistant.components.mysensors.const import MYSENSORS_DISCOVERY, DiscoveryInfo
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS, TEMP_FAHRENHEIT
from homeassistant.const import (
ATTR_TEMPERATURE,
TEMP_CELSIUS,
TEMP_FAHRENHEIT,
UnitTemperatureT,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -91,7 +96,7 @@ class MySensorsHVAC(mysensors.device.MySensorsEntity, ClimateEntity):
return features
@property
def temperature_unit(self) -> str:
def temperature_unit(self) -> UnitTemperatureT:
"""Return the unit of measurement."""
return TEMP_CELSIUS if self.hass.config.units.is_metric else TEMP_FAHRENHEIT

View file

@ -53,6 +53,7 @@ from homeassistant.const import (
PRECISION_TENTHS,
TEMP_CELSIUS,
TEMP_FAHRENHEIT,
UnitTemperatureT,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
@ -248,7 +249,7 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity):
return THERMOSTAT_MODE_SETPOINT_MAP.get(int(self._current_mode.value), []) # type: ignore
@property
def temperature_unit(self) -> str:
def temperature_unit(self) -> UnitTemperatureT:
"""Return the unit of measurement used by the platform."""
if (
self._unit_value

View file

@ -1,7 +1,7 @@
"""Constants used by Home Assistant components."""
from __future__ import annotations
from typing import Final
from typing import Final, NewType
MAJOR_VERSION: Final = 2021
MINOR_VERSION: Final = 8
@ -393,166 +393,212 @@ ATTR_DEVICE_CLASS: Final = "device_class"
# Temperature attribute
ATTR_TEMPERATURE: Final = "temperature"
# #### UNITS OF MEASUREMENT ####
UnitT = NewType("UnitT", str)
# Power units
POWER_WATT: Final = "W"
POWER_KILO_WATT: Final = "kW"
UnitPowerT = NewType("UnitPowerT", UnitT)
POWER_WATT: Final[UnitPowerT] = UnitPowerT(UnitT("W"))
POWER_KILO_WATT: Final[UnitPowerT] = UnitPowerT(UnitT("kW"))
# Voltage units
VOLT: Final = "V"
VOLT: Final[UnitT] = UnitT("V")
# Energy units
ENERGY_WATT_HOUR: Final = "Wh"
ENERGY_KILO_WATT_HOUR: Final = "kWh"
UnitEnergyT = NewType("UnitEnergyT", UnitT)
ENERGY_WATT_HOUR: Final[UnitEnergyT] = UnitEnergyT(UnitT("Wh"))
ENERGY_KILO_WATT_HOUR: Final[UnitEnergyT] = UnitEnergyT(UnitT("kWh"))
# Electrical units
ELECTRICAL_CURRENT_AMPERE: Final = "A"
ELECTRICAL_VOLT_AMPERE: Final = "VA"
ELECTRICAL_CURRENT_AMPERE: Final[UnitT] = UnitT("A")
ELECTRICAL_VOLT_AMPERE: Final[UnitT] = UnitT("VA")
# Degree units
DEGREE: Final = "°"
DEGREE: Final[UnitT] = UnitT("°")
# Currency units
CURRENCY_EURO: Final = ""
CURRENCY_DOLLAR: Final = "$"
CURRENCY_CENT: Final = "¢"
UnitCurrencyT = NewType("UnitCurrencyT", UnitT)
CURRENCY_EURO: Final[UnitCurrencyT] = UnitCurrencyT(UnitT(""))
CURRENCY_DOLLAR: Final[UnitCurrencyT] = UnitCurrencyT(UnitT("$"))
CURRENCY_CENT: Final[UnitCurrencyT] = UnitCurrencyT(UnitT("¢"))
# Temperature units
TEMP_CELSIUS: Final = "°C"
TEMP_FAHRENHEIT: Final = "°F"
TEMP_KELVIN: Final = "K"
UnitTemperatureT = NewType("UnitTemperatureT", UnitT)
TEMP_CELSIUS: Final[UnitTemperatureT] = UnitTemperatureT(UnitT("°C"))
TEMP_FAHRENHEIT: Final[UnitTemperatureT] = UnitTemperatureT(UnitT("°F"))
TEMP_KELVIN: Final[UnitTemperatureT] = UnitTemperatureT(UnitT("K"))
# Time units
TIME_MICROSECONDS: Final = "μs"
TIME_MILLISECONDS: Final = "ms"
TIME_SECONDS: Final = "s"
TIME_MINUTES: Final = "min"
TIME_HOURS: Final = "h"
TIME_DAYS: Final = "d"
TIME_WEEKS: Final = "w"
TIME_MONTHS: Final = "m"
TIME_YEARS: Final = "y"
UnitTimeT = NewType("UnitTimeT", UnitT)
TIME_MICROSECONDS: Final[UnitTimeT] = UnitTimeT(UnitT("μs"))
TIME_MILLISECONDS: Final[UnitTimeT] = UnitTimeT(UnitT("ms"))
TIME_SECONDS: Final[UnitTimeT] = UnitTimeT(UnitT("s"))
TIME_MINUTES: Final[UnitTimeT] = UnitTimeT(UnitT("min"))
TIME_HOURS: Final[UnitTimeT] = UnitTimeT(UnitT("h"))
TIME_DAYS: Final[UnitTimeT] = UnitTimeT(UnitT("d"))
TIME_WEEKS: Final[UnitTimeT] = UnitTimeT(UnitT("w"))
TIME_MONTHS: Final[UnitTimeT] = UnitTimeT(UnitT("m"))
TIME_YEARS: Final[UnitTimeT] = UnitTimeT(UnitT("y"))
# Length units
LENGTH_MILLIMETERS: Final = "mm"
LENGTH_CENTIMETERS: Final = "cm"
LENGTH_METERS: Final = "m"
LENGTH_KILOMETERS: Final = "km"
UnitLengthT = NewType("UnitLengthT", UnitT)
LENGTH_MILLIMETERS: Final[UnitLengthT] = UnitLengthT(UnitT("mm"))
LENGTH_CENTIMETERS: Final[UnitLengthT] = UnitLengthT(UnitT("cm"))
LENGTH_METERS: Final[UnitLengthT] = UnitLengthT(UnitT("m"))
LENGTH_KILOMETERS: Final[UnitLengthT] = UnitLengthT(UnitT("km"))
LENGTH_INCHES: Final = "in"
LENGTH_FEET: Final = "ft"
LENGTH_YARD: Final = "yd"
LENGTH_MILES: Final = "mi"
LENGTH_INCHES: Final[UnitLengthT] = UnitLengthT(UnitT("in"))
LENGTH_FEET: Final[UnitLengthT] = UnitLengthT(UnitT("ft"))
LENGTH_YARD: Final[UnitLengthT] = UnitLengthT(UnitT("yd"))
LENGTH_MILES: Final[UnitLengthT] = UnitLengthT(UnitT("mi"))
# Frequency units
FREQUENCY_HERTZ: Final = "Hz"
FREQUENCY_GIGAHERTZ: Final = "GHz"
UnitFrequencyT = NewType("UnitFrequencyT", UnitT)
FREQUENCY_HERTZ: Final[UnitFrequencyT] = UnitFrequencyT(UnitT("Hz"))
FREQUENCY_GIGAHERTZ: Final[UnitFrequencyT] = UnitFrequencyT(UnitT("GHz"))
# Pressure units
PRESSURE_PA: Final = "Pa"
PRESSURE_HPA: Final = "hPa"
PRESSURE_BAR: Final = "bar"
PRESSURE_MBAR: Final = "mbar"
PRESSURE_INHG: Final = "inHg"
PRESSURE_PSI: Final = "psi"
UnitPressureT = NewType("UnitPressureT", UnitT)
PRESSURE_PA: Final[UnitPressureT] = UnitPressureT(UnitT("Pa"))
PRESSURE_HPA: Final[UnitPressureT] = UnitPressureT(UnitT("hPa"))
PRESSURE_BAR: Final[UnitPressureT] = UnitPressureT(UnitT("bar"))
PRESSURE_MBAR: Final[UnitPressureT] = UnitPressureT(UnitT("mbar"))
PRESSURE_INHG: Final[UnitPressureT] = UnitPressureT(UnitT("inHg"))
PRESSURE_PSI: Final[UnitPressureT] = UnitPressureT(UnitT("psi"))
# Volume units
VOLUME_LITERS: Final = "L"
VOLUME_MILLILITERS: Final = "mL"
VOLUME_CUBIC_METERS: Final = ""
VOLUME_CUBIC_FEET: Final = "ft³"
UnitVolumeT = NewType("UnitVolumeT", UnitT)
VOLUME_LITERS: Final[UnitVolumeT] = UnitVolumeT(UnitT("L"))
VOLUME_MILLILITERS: Final[UnitVolumeT] = UnitVolumeT(UnitT("mL"))
VOLUME_CUBIC_METERS: Final[UnitVolumeT] = UnitVolumeT(UnitT(""))
VOLUME_CUBIC_FEET: Final[UnitVolumeT] = UnitVolumeT(UnitT("ft³"))
VOLUME_GALLONS: Final = "gal"
VOLUME_FLUID_OUNCE: Final = "fl. oz."
VOLUME_GALLONS: Final[UnitVolumeT] = UnitVolumeT(UnitT("gal"))
VOLUME_FLUID_OUNCE: Final[UnitVolumeT] = UnitVolumeT(UnitT("fl. oz."))
# Volume Flow Rate units
VOLUME_FLOW_RATE_CUBIC_METERS_PER_HOUR: Final = "m³/h"
VOLUME_FLOW_RATE_CUBIC_FEET_PER_MINUTE: Final = "ft³/m"
UnitVolumeFlowT = NewType("UnitVolumeFlowT", UnitT)
VOLUME_FLOW_RATE_CUBIC_METERS_PER_HOUR: Final[UnitVolumeFlowT] = UnitVolumeFlowT(
UnitT("m³/h")
)
VOLUME_FLOW_RATE_CUBIC_FEET_PER_MINUTE: Final[UnitVolumeFlowT] = UnitVolumeFlowT(
UnitT("ft³/m")
)
# Area units
AREA_SQUARE_METERS: Final = ""
UnitAreaT = NewType("UnitAreaT", UnitT)
AREA_SQUARE_METERS: Final[UnitAreaT] = UnitAreaT(UnitT(""))
# Mass units
MASS_GRAMS: Final = "g"
MASS_KILOGRAMS: Final = "kg"
MASS_MILLIGRAMS: Final = "mg"
MASS_MICROGRAMS: Final = "µg"
UnitMassT = NewType("UnitMassT", UnitT)
MASS_GRAMS: Final[UnitMassT] = UnitMassT(UnitT("g"))
MASS_KILOGRAMS: Final[UnitMassT] = UnitMassT(UnitT("kg"))
MASS_MILLIGRAMS: Final[UnitMassT] = UnitMassT(UnitT("mg"))
MASS_MICROGRAMS: Final[UnitMassT] = UnitMassT(UnitT("µg"))
MASS_OUNCES: Final = "oz"
MASS_POUNDS: Final = "lb"
MASS_OUNCES: Final[UnitMassT] = UnitMassT(UnitT("oz"))
MASS_POUNDS: Final[UnitMassT] = UnitMassT(UnitT("lb"))
# Conductivity units
CONDUCTIVITY: Final = "µS/cm"
CONDUCTIVITY: Final[UnitT] = UnitT("µS/cm")
# Light units
LIGHT_LUX: Final = "lx"
LIGHT_LUX: Final[UnitT] = UnitT("lx")
# UV Index units
UV_INDEX: Final = "UV index"
UV_INDEX: Final[UnitT] = UnitT("UV index")
# Percentage units
PERCENTAGE: Final = "%"
PERCENTAGE: Final[UnitT] = UnitT("%")
# Irradiation units
IRRADIATION_WATTS_PER_SQUARE_METER: Final = "W/m²"
IRRADIATION_BTUS_PER_HOUR_SQUARE_FOOT: Final = "BTU/(h×ft²)"
UnitIrradiationT = NewType("UnitIrradiationT", UnitT)
IRRADIATION_WATTS_PER_SQUARE_METER: Final[UnitIrradiationT] = UnitIrradiationT(
UnitT("W/m²")
)
IRRADIATION_BTUS_PER_HOUR_SQUARE_FOOT: Final[UnitIrradiationT] = UnitIrradiationT(
UnitT("BTU/(h×ft²)")
)
# Precipitation units
PRECIPITATION_MILLIMETERS_PER_HOUR: Final = "mm/h"
PRECIPITATION_MILLIMETERS_PER_HOUR: Final[UnitT] = UnitT("mm/h")
# Concentration units
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER: Final = "µg/m³"
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER: Final = "mg/m³"
CONCENTRATION_MICROGRAMS_PER_CUBIC_FOOT: Final = "μg/ft³"
CONCENTRATION_PARTS_PER_CUBIC_METER: Final = "p/m³"
CONCENTRATION_PARTS_PER_MILLION: Final = "ppm"
CONCENTRATION_PARTS_PER_BILLION: Final = "ppb"
UnitConcentrationT = NewType("UnitConcentrationT", UnitT)
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER: Final[
UnitConcentrationT
] = UnitConcentrationT(UnitT("µg/m³"))
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER: Final[
UnitConcentrationT
] = UnitConcentrationT(UnitT("mg/m³"))
CONCENTRATION_MICROGRAMS_PER_CUBIC_FOOT: Final[UnitConcentrationT] = UnitConcentrationT(
UnitT("μg/ft³")
)
CONCENTRATION_PARTS_PER_CUBIC_METER: Final[UnitConcentrationT] = UnitConcentrationT(
UnitT("p/m³")
)
CONCENTRATION_PARTS_PER_MILLION: Final[UnitConcentrationT] = UnitConcentrationT(
UnitT("ppm")
)
CONCENTRATION_PARTS_PER_BILLION: Final[UnitConcentrationT] = UnitConcentrationT(
UnitT("ppb")
)
# Speed units
SPEED_MILLIMETERS_PER_DAY: Final = "mm/d"
SPEED_INCHES_PER_DAY: Final = "in/d"
SPEED_METERS_PER_SECOND: Final = "m/s"
SPEED_INCHES_PER_HOUR: Final = "in/h"
SPEED_KILOMETERS_PER_HOUR: Final = "km/h"
SPEED_MILES_PER_HOUR: Final = "mph"
UnitSpeedT = NewType("UnitSpeedT", UnitT)
SPEED_MILLIMETERS_PER_DAY: Final[UnitSpeedT] = UnitSpeedT(UnitT("mm/d"))
SPEED_INCHES_PER_DAY: Final[UnitSpeedT] = UnitSpeedT(UnitT("in/d"))
SPEED_METERS_PER_SECOND: Final[UnitSpeedT] = UnitSpeedT(UnitT("m/s"))
SPEED_INCHES_PER_HOUR: Final[UnitSpeedT] = UnitSpeedT(UnitT("in/h"))
SPEED_KILOMETERS_PER_HOUR: Final[UnitSpeedT] = UnitSpeedT(UnitT("km/h"))
SPEED_MILES_PER_HOUR: Final[UnitSpeedT] = UnitSpeedT(UnitT("mph"))
# Signal_strength units
SIGNAL_STRENGTH_DECIBELS: Final = "dB"
SIGNAL_STRENGTH_DECIBELS_MILLIWATT: Final = "dBm"
UnitSignalStrengthT = NewType("UnitSignalStrengthT", UnitT)
SIGNAL_STRENGTH_DECIBELS: Final[UnitSignalStrengthT] = UnitSignalStrengthT(UnitT("dB"))
SIGNAL_STRENGTH_DECIBELS_MILLIWATT: Final[UnitSignalStrengthT] = UnitSignalStrengthT(
UnitT("dBm")
)
# Data units
DATA_BITS: Final = "bit"
DATA_KILOBITS: Final = "kbit"
DATA_MEGABITS: Final = "Mbit"
DATA_GIGABITS: Final = "Gbit"
DATA_BYTES: Final = "B"
DATA_KILOBYTES: Final = "kB"
DATA_MEGABYTES: Final = "MB"
DATA_GIGABYTES: Final = "GB"
DATA_TERABYTES: Final = "TB"
DATA_PETABYTES: Final = "PB"
DATA_EXABYTES: Final = "EB"
DATA_ZETTABYTES: Final = "ZB"
DATA_YOTTABYTES: Final = "YB"
DATA_KIBIBYTES: Final = "KiB"
DATA_MEBIBYTES: Final = "MiB"
DATA_GIBIBYTES: Final = "GiB"
DATA_TEBIBYTES: Final = "TiB"
DATA_PEBIBYTES: Final = "PiB"
DATA_EXBIBYTES: Final = "EiB"
DATA_ZEBIBYTES: Final = "ZiB"
DATA_YOBIBYTES: Final = "YiB"
DATA_RATE_BITS_PER_SECOND: Final = "bit/s"
DATA_RATE_KILOBITS_PER_SECOND: Final = "kbit/s"
DATA_RATE_MEGABITS_PER_SECOND: Final = "Mbit/s"
DATA_RATE_GIGABITS_PER_SECOND: Final = "Gbit/s"
DATA_RATE_BYTES_PER_SECOND: Final = "B/s"
DATA_RATE_KILOBYTES_PER_SECOND: Final = "kB/s"
DATA_RATE_MEGABYTES_PER_SECOND: Final = "MB/s"
DATA_RATE_GIGABYTES_PER_SECOND: Final = "GB/s"
DATA_RATE_KIBIBYTES_PER_SECOND: Final = "KiB/s"
DATA_RATE_MEBIBYTES_PER_SECOND: Final = "MiB/s"
DATA_RATE_GIBIBYTES_PER_SECOND: Final = "GiB/s"
UnitDataT = NewType("UnitDataT", UnitT)
DATA_BITS: Final[UnitDataT] = UnitDataT(UnitT("bit"))
DATA_KILOBITS: Final[UnitDataT] = UnitDataT(UnitT("kbit"))
DATA_MEGABITS: Final[UnitDataT] = UnitDataT(UnitT("Mbit"))
DATA_GIGABITS: Final[UnitDataT] = UnitDataT(UnitT("Gbit"))
DATA_BYTES: Final[UnitDataT] = UnitDataT(UnitT("B"))
DATA_KILOBYTES: Final[UnitDataT] = UnitDataT(UnitT("kB"))
DATA_MEGABYTES: Final[UnitDataT] = UnitDataT(UnitT("MB"))
DATA_GIGABYTES: Final[UnitDataT] = UnitDataT(UnitT("GB"))
DATA_TERABYTES: Final[UnitDataT] = UnitDataT(UnitT("TB"))
DATA_PETABYTES: Final[UnitDataT] = UnitDataT(UnitT("PB"))
DATA_EXABYTES: Final[UnitDataT] = UnitDataT(UnitT("EB"))
DATA_ZETTABYTES: Final[UnitDataT] = UnitDataT(UnitT("ZB"))
DATA_YOTTABYTES: Final[UnitDataT] = UnitDataT(UnitT("YB"))
DATA_KIBIBYTES: Final[UnitDataT] = UnitDataT(UnitT("KiB"))
DATA_MEBIBYTES: Final[UnitDataT] = UnitDataT(UnitT("MiB"))
DATA_GIBIBYTES: Final[UnitDataT] = UnitDataT(UnitT("GiB"))
DATA_TEBIBYTES: Final[UnitDataT] = UnitDataT(UnitT("TiB"))
DATA_PEBIBYTES: Final[UnitDataT] = UnitDataT(UnitT("PiB"))
DATA_EXBIBYTES: Final[UnitDataT] = UnitDataT(UnitT("EiB"))
DATA_ZEBIBYTES: Final[UnitDataT] = UnitDataT(UnitT("ZiB"))
DATA_YOBIBYTES: Final[UnitDataT] = UnitDataT(UnitT("YiB"))
# Data_rate units
UnitDataRateT = NewType("UnitDataRateT", UnitT)
DATA_RATE_BITS_PER_SECOND: Final[UnitDataRateT] = UnitDataRateT(UnitT("bit/s"))
DATA_RATE_KILOBITS_PER_SECOND: Final[UnitDataRateT] = UnitDataRateT(UnitT("kbit/s"))
DATA_RATE_MEGABITS_PER_SECOND: Final[UnitDataRateT] = UnitDataRateT(UnitT("Mbit/s"))
DATA_RATE_GIGABITS_PER_SECOND: Final[UnitDataRateT] = UnitDataRateT(UnitT("Gbit/s"))
DATA_RATE_BYTES_PER_SECOND: Final[UnitDataRateT] = UnitDataRateT(UnitT("B/s"))
DATA_RATE_KILOBYTES_PER_SECOND: Final[UnitDataRateT] = UnitDataRateT(UnitT("kB/s"))
DATA_RATE_MEGABYTES_PER_SECOND: Final[UnitDataRateT] = UnitDataRateT(UnitT("MB/s"))
DATA_RATE_GIGABYTES_PER_SECOND: Final[UnitDataRateT] = UnitDataRateT(UnitT("GB/s"))
DATA_RATE_KIBIBYTES_PER_SECOND: Final[UnitDataRateT] = UnitDataRateT(UnitT("KiB/s"))
DATA_RATE_MEBIBYTES_PER_SECOND: Final[UnitDataRateT] = UnitDataRateT(UnitT("MiB/s"))
DATA_RATE_GIBIBYTES_PER_SECOND: Final[UnitDataRateT] = UnitDataRateT(UnitT("GiB/s"))
# #### SERVICES ####
SERVICE_HOMEASSISTANT_STOP: Final = "stop"
@ -653,13 +699,14 @@ RESTART_EXIT_CODE: Final = 100
UNIT_NOT_RECOGNIZED_TEMPLATE: Final = "{} is not a recognized {} unit."
LENGTH: Final = "length"
MASS: Final = "mass"
PRESSURE: Final = "pressure"
VOLUME: Final = "volume"
TEMPERATURE: Final = "temperature"
SPEED_MS: Final = "speed_ms"
ILLUMINANCE: Final = "illuminance"
UnitTypeT = NewType("UnitTypeT", str)
LENGTH: Final[UnitTypeT] = UnitTypeT("length")
MASS: Final[UnitTypeT] = UnitTypeT("mass")
PRESSURE: Final[UnitTypeT] = UnitTypeT("pressure")
VOLUME: Final[UnitTypeT] = UnitTypeT("volume")
TEMPERATURE: Final[UnitTypeT] = UnitTypeT("temperature")
SPEED_MS: Final[UnitTypeT] = UnitTypeT("speed_ms")
ILLUMINANCE: Final[UnitTypeT] = UnitTypeT("illuminance")
WEEKDAYS: Final[list[str]] = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]

View file

@ -3,13 +3,16 @@ from __future__ import annotations
from numbers import Number
from homeassistant.const import PRECISION_HALVES, PRECISION_TENTHS
from homeassistant.const import PRECISION_HALVES, PRECISION_TENTHS, UnitTemperatureT
from homeassistant.core import HomeAssistant
from homeassistant.util.temperature import convert as convert_temperature
def display_temp(
hass: HomeAssistant, temperature: float | None, unit: str, precision: float
hass: HomeAssistant,
temperature: float | None,
unit: UnitTemperatureT,
precision: float,
) -> float | None:
"""Convert temperature into preferred units/precision for display."""
temperature_unit = unit

View file

@ -15,9 +15,10 @@ from homeassistant.const import (
LENGTH_MILLIMETERS,
LENGTH_YARD,
UNIT_NOT_RECOGNIZED_TEMPLATE,
UnitLengthT,
)
VALID_UNITS = [
VALID_UNITS: tuple[UnitLengthT, ...] = (
LENGTH_KILOMETERS,
LENGTH_MILES,
LENGTH_FEET,
@ -26,9 +27,9 @@ VALID_UNITS = [
LENGTH_MILLIMETERS,
LENGTH_INCHES,
LENGTH_YARD,
]
)
TO_METERS: dict[str, Callable[[float], float]] = {
TO_METERS: dict[UnitLengthT, Callable[[float], float]] = {
LENGTH_METERS: lambda meters: meters,
LENGTH_MILES: lambda miles: miles * 1609.344,
LENGTH_YARD: lambda yards: yards * 0.9144,
@ -39,7 +40,7 @@ TO_METERS: dict[str, Callable[[float], float]] = {
LENGTH_MILLIMETERS: lambda millimeters: millimeters * 0.001,
}
METERS_TO: dict[str, Callable[[float], float]] = {
METERS_TO: dict[UnitLengthT, Callable[[float], float]] = {
LENGTH_METERS: lambda meters: meters,
LENGTH_MILES: lambda meters: meters * 0.000621371,
LENGTH_YARD: lambda meters: meters * 1.09361,
@ -51,7 +52,7 @@ METERS_TO: dict[str, Callable[[float], float]] = {
}
def convert(value: float, unit_1: str, unit_2: str) -> float:
def convert(value: float, unit_1: UnitLengthT, unit_2: UnitLengthT) -> float:
"""Convert one unit of measurement to another."""
if unit_1 not in VALID_UNITS:
raise ValueError(UNIT_NOT_RECOGNIZED_TEMPLATE.format(unit_1, LENGTH))

View file

@ -1,4 +1,6 @@
"""Pressure util functions."""
from __future__ import annotations
from numbers import Number
from homeassistant.const import (
@ -9,11 +11,18 @@ from homeassistant.const import (
PRESSURE_PA,
PRESSURE_PSI,
UNIT_NOT_RECOGNIZED_TEMPLATE,
UnitPressureT,
)
VALID_UNITS = [PRESSURE_PA, PRESSURE_HPA, PRESSURE_MBAR, PRESSURE_INHG, PRESSURE_PSI]
VALID_UNITS: tuple[UnitPressureT, ...] = (
PRESSURE_PA,
PRESSURE_HPA,
PRESSURE_MBAR,
PRESSURE_INHG,
PRESSURE_PSI,
)
UNIT_CONVERSION = {
UNIT_CONVERSION: dict[UnitPressureT, float] = {
PRESSURE_PA: 1,
PRESSURE_HPA: 1 / 100,
PRESSURE_MBAR: 1 / 100,
@ -22,7 +31,7 @@ UNIT_CONVERSION = {
}
def convert(value: float, unit_1: str, unit_2: str) -> float:
def convert(value: float, unit_1: UnitPressureT, unit_2: UnitPressureT) -> float:
"""Convert one unit of measurement to another."""
if unit_1 not in VALID_UNITS:
raise ValueError(UNIT_NOT_RECOGNIZED_TEMPLATE.format(unit_1, PRESSURE))

View file

@ -5,6 +5,7 @@ from homeassistant.const import (
TEMP_KELVIN,
TEMPERATURE,
UNIT_NOT_RECOGNIZED_TEMPLATE,
UnitTemperatureT,
)
@ -37,7 +38,10 @@ def celsius_to_kelvin(celsius: float, interval: bool = False) -> float:
def convert(
temperature: float, from_unit: str, to_unit: str, interval: bool = False
temperature: float,
from_unit: UnitTemperatureT,
to_unit: UnitTemperatureT,
interval: bool = False,
) -> float:
"""Convert a temperature from one unit to another."""
if from_unit not in (TEMP_CELSIUS, TEMP_FAHRENHEIT, TEMP_KELVIN):

View file

@ -24,6 +24,13 @@ from homeassistant.const import (
VOLUME,
VOLUME_GALLONS,
VOLUME_LITERS,
UnitLengthT,
UnitMassT,
UnitPressureT,
UnitT,
UnitTemperatureT,
UnitTypeT,
UnitVolumeT,
)
from homeassistant.util import (
distance as distance_util,
@ -36,17 +43,23 @@ from homeassistant.util import (
LENGTH_UNITS = distance_util.VALID_UNITS
MASS_UNITS = [MASS_POUNDS, MASS_OUNCES, MASS_KILOGRAMS, MASS_GRAMS]
MASS_UNITS: tuple[UnitMassT, ...] = (
MASS_POUNDS,
MASS_OUNCES,
MASS_KILOGRAMS,
MASS_GRAMS,
)
PRESSURE_UNITS = pressure_util.VALID_UNITS
VOLUME_UNITS = volume_util.VALID_UNITS
TEMPERATURE_UNITS = [TEMP_FAHRENHEIT, TEMP_CELSIUS]
TEMPERATURE_UNITS: tuple[UnitTemperatureT, ...] = (TEMP_FAHRENHEIT, TEMP_CELSIUS)
def is_valid_unit(unit: str, unit_type: str) -> bool:
def is_valid_unit(unit: UnitT, unit_type: UnitTypeT) -> bool:
"""Check if the unit is valid for it's type."""
units: tuple[UnitT, ...]
if unit_type == LENGTH:
units = LENGTH_UNITS
elif unit_type == TEMPERATURE:
@ -69,11 +82,11 @@ class UnitSystem:
def __init__(
self,
name: str,
temperature: str,
length: str,
volume: str,
mass: str,
pressure: str,
temperature: UnitTemperatureT,
length: UnitLengthT,
volume: UnitVolumeT,
mass: UnitMassT,
pressure: UnitPressureT,
) -> None:
"""Initialize the unit system object."""
errors: str = ", ".join(
@ -103,14 +116,14 @@ class UnitSystem:
"""Determine if this is the metric unit system."""
return self.name == CONF_UNIT_SYSTEM_METRIC
def temperature(self, temperature: float, from_unit: str) -> float:
def temperature(self, temperature: float, from_unit: UnitTemperatureT) -> float:
"""Convert the given temperature to this unit system."""
if not isinstance(temperature, Number):
raise TypeError(f"{temperature!s} is not a numeric value.")
return temperature_util.convert(temperature, from_unit, self.temperature_unit)
def length(self, length: float | None, from_unit: str) -> float:
def length(self, length: float | None, from_unit: UnitLengthT) -> float:
"""Convert the given length to this unit system."""
if not isinstance(length, Number):
raise TypeError(f"{length!s} is not a numeric value.")
@ -120,7 +133,7 @@ class UnitSystem:
length, from_unit, self.length_unit
)
def pressure(self, pressure: float | None, from_unit: str) -> float:
def pressure(self, pressure: float | None, from_unit: UnitPressureT) -> float:
"""Convert the given pressure to this unit system."""
if not isinstance(pressure, Number):
raise TypeError(f"{pressure!s} is not a numeric value.")
@ -130,7 +143,7 @@ class UnitSystem:
pressure, from_unit, self.pressure_unit
)
def volume(self, volume: float | None, from_unit: str) -> float:
def volume(self, volume: float | None, from_unit: UnitVolumeT) -> float:
"""Convert the given volume to this unit system."""
if not isinstance(volume, Number):
raise TypeError(f"{volume!s} is not a numeric value.")
@ -138,7 +151,7 @@ class UnitSystem:
# type ignore: https://github.com/python/mypy/issues/7207
return volume_util.convert(volume, from_unit, self.volume_unit) # type: ignore
def as_dict(self) -> dict[str, str]:
def as_dict(self) -> dict[str, UnitT]:
"""Convert the unit system to a dictionary."""
return {
LENGTH: self.length_unit,

View file

@ -1,4 +1,6 @@
"""Volume conversion util functions."""
from __future__ import annotations
from numbers import Number
from homeassistant.const import (
@ -8,9 +10,15 @@ from homeassistant.const import (
VOLUME_GALLONS,
VOLUME_LITERS,
VOLUME_MILLILITERS,
UnitVolumeT,
)
VALID_UNITS = [VOLUME_LITERS, VOLUME_MILLILITERS, VOLUME_GALLONS, VOLUME_FLUID_OUNCE]
VALID_UNITS: tuple[UnitVolumeT, ...] = (
VOLUME_LITERS,
VOLUME_MILLILITERS,
VOLUME_GALLONS,
VOLUME_FLUID_OUNCE,
)
def __liter_to_gallon(liter: float) -> float:
@ -23,7 +31,7 @@ def __gallon_to_liter(gallon: float) -> float:
return gallon * 3.785
def convert(volume: float, from_unit: str, to_unit: str) -> float:
def convert(volume: float, from_unit: UnitVolumeT, to_unit: UnitVolumeT) -> float:
"""Convert a temperature from one unit to another."""
if from_unit not in VALID_UNITS:
raise ValueError(UNIT_NOT_RECOGNIZED_TEMPLATE.format(from_unit, VOLUME))