Energy distance units (#136933)
Co-authored-by: Abílio Costa <abmantis@users.noreply.github.com>pull/137792/head
parent
21ffcf853b
commit
84ae476b67
|
@ -23,6 +23,7 @@ from homeassistant.const import (
|
||||||
UnitOfElectricCurrent,
|
UnitOfElectricCurrent,
|
||||||
UnitOfElectricPotential,
|
UnitOfElectricPotential,
|
||||||
UnitOfEnergy,
|
UnitOfEnergy,
|
||||||
|
UnitOfEnergyDistance,
|
||||||
UnitOfFrequency,
|
UnitOfFrequency,
|
||||||
UnitOfInformation,
|
UnitOfInformation,
|
||||||
UnitOfIrradiance,
|
UnitOfIrradiance,
|
||||||
|
@ -166,6 +167,15 @@ class NumberDeviceClass(StrEnum):
|
||||||
Unit of measurement: `J`, `kJ`, `MJ`, `GJ`, `mWh`, `Wh`, `kWh`, `MWh`, `GWh`, `TWh`, `cal`, `kcal`, `Mcal`, `Gcal`
|
Unit of measurement: `J`, `kJ`, `MJ`, `GJ`, `mWh`, `Wh`, `kWh`, `MWh`, `GWh`, `TWh`, `cal`, `kcal`, `Mcal`, `Gcal`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
ENERGY_DISTANCE = "energy_distance"
|
||||||
|
"""Energy distance.
|
||||||
|
|
||||||
|
Use this device class for sensors measuring energy by distance, for example the amount
|
||||||
|
of electric energy consumed by an electric car.
|
||||||
|
|
||||||
|
Unit of measurement: `kWh/100km`, `mi/kWh`, `km/kWh`
|
||||||
|
"""
|
||||||
|
|
||||||
ENERGY_STORAGE = "energy_storage"
|
ENERGY_STORAGE = "energy_storage"
|
||||||
"""Stored energy.
|
"""Stored energy.
|
||||||
|
|
||||||
|
@ -447,6 +457,7 @@ DEVICE_CLASS_UNITS: dict[NumberDeviceClass, set[type[StrEnum] | str | None]] = {
|
||||||
UnitOfTime.MILLISECONDS,
|
UnitOfTime.MILLISECONDS,
|
||||||
},
|
},
|
||||||
NumberDeviceClass.ENERGY: set(UnitOfEnergy),
|
NumberDeviceClass.ENERGY: set(UnitOfEnergy),
|
||||||
|
NumberDeviceClass.ENERGY_DISTANCE: set(UnitOfEnergyDistance),
|
||||||
NumberDeviceClass.ENERGY_STORAGE: set(UnitOfEnergy),
|
NumberDeviceClass.ENERGY_STORAGE: set(UnitOfEnergy),
|
||||||
NumberDeviceClass.FREQUENCY: set(UnitOfFrequency),
|
NumberDeviceClass.FREQUENCY: set(UnitOfFrequency),
|
||||||
NumberDeviceClass.GAS: {
|
NumberDeviceClass.GAS: {
|
||||||
|
|
|
@ -38,6 +38,7 @@ from homeassistant.util.unit_conversion import (
|
||||||
ElectricCurrentConverter,
|
ElectricCurrentConverter,
|
||||||
ElectricPotentialConverter,
|
ElectricPotentialConverter,
|
||||||
EnergyConverter,
|
EnergyConverter,
|
||||||
|
EnergyDistanceConverter,
|
||||||
InformationConverter,
|
InformationConverter,
|
||||||
MassConverter,
|
MassConverter,
|
||||||
PowerConverter,
|
PowerConverter,
|
||||||
|
@ -147,6 +148,7 @@ STATISTIC_UNIT_TO_UNIT_CONVERTER: dict[str | None, type[BaseUnitConverter]] = {
|
||||||
for unit in ElectricPotentialConverter.VALID_UNITS
|
for unit in ElectricPotentialConverter.VALID_UNITS
|
||||||
},
|
},
|
||||||
**{unit: EnergyConverter for unit in EnergyConverter.VALID_UNITS},
|
**{unit: EnergyConverter for unit in EnergyConverter.VALID_UNITS},
|
||||||
|
**{unit: EnergyDistanceConverter for unit in EnergyDistanceConverter.VALID_UNITS},
|
||||||
**{unit: InformationConverter for unit in InformationConverter.VALID_UNITS},
|
**{unit: InformationConverter for unit in InformationConverter.VALID_UNITS},
|
||||||
**{unit: MassConverter for unit in MassConverter.VALID_UNITS},
|
**{unit: MassConverter for unit in MassConverter.VALID_UNITS},
|
||||||
**{unit: PowerConverter for unit in PowerConverter.VALID_UNITS},
|
**{unit: PowerConverter for unit in PowerConverter.VALID_UNITS},
|
||||||
|
|
|
@ -25,6 +25,7 @@ from homeassistant.util.unit_conversion import (
|
||||||
ElectricCurrentConverter,
|
ElectricCurrentConverter,
|
||||||
ElectricPotentialConverter,
|
ElectricPotentialConverter,
|
||||||
EnergyConverter,
|
EnergyConverter,
|
||||||
|
EnergyDistanceConverter,
|
||||||
InformationConverter,
|
InformationConverter,
|
||||||
MassConverter,
|
MassConverter,
|
||||||
PowerConverter,
|
PowerConverter,
|
||||||
|
@ -67,6 +68,7 @@ UNIT_SCHEMA = vol.Schema(
|
||||||
vol.Optional("electric_current"): vol.In(ElectricCurrentConverter.VALID_UNITS),
|
vol.Optional("electric_current"): vol.In(ElectricCurrentConverter.VALID_UNITS),
|
||||||
vol.Optional("voltage"): vol.In(ElectricPotentialConverter.VALID_UNITS),
|
vol.Optional("voltage"): vol.In(ElectricPotentialConverter.VALID_UNITS),
|
||||||
vol.Optional("energy"): vol.In(EnergyConverter.VALID_UNITS),
|
vol.Optional("energy"): vol.In(EnergyConverter.VALID_UNITS),
|
||||||
|
vol.Optional("energy_distance"): vol.In(EnergyDistanceConverter.VALID_UNITS),
|
||||||
vol.Optional("information"): vol.In(InformationConverter.VALID_UNITS),
|
vol.Optional("information"): vol.In(InformationConverter.VALID_UNITS),
|
||||||
vol.Optional("mass"): vol.In(MassConverter.VALID_UNITS),
|
vol.Optional("mass"): vol.In(MassConverter.VALID_UNITS),
|
||||||
vol.Optional("power"): vol.In(PowerConverter.VALID_UNITS),
|
vol.Optional("power"): vol.In(PowerConverter.VALID_UNITS),
|
||||||
|
|
|
@ -23,6 +23,7 @@ from homeassistant.const import (
|
||||||
UnitOfElectricCurrent,
|
UnitOfElectricCurrent,
|
||||||
UnitOfElectricPotential,
|
UnitOfElectricPotential,
|
||||||
UnitOfEnergy,
|
UnitOfEnergy,
|
||||||
|
UnitOfEnergyDistance,
|
||||||
UnitOfFrequency,
|
UnitOfFrequency,
|
||||||
UnitOfInformation,
|
UnitOfInformation,
|
||||||
UnitOfIrradiance,
|
UnitOfIrradiance,
|
||||||
|
@ -51,6 +52,7 @@ from homeassistant.util.unit_conversion import (
|
||||||
ElectricCurrentConverter,
|
ElectricCurrentConverter,
|
||||||
ElectricPotentialConverter,
|
ElectricPotentialConverter,
|
||||||
EnergyConverter,
|
EnergyConverter,
|
||||||
|
EnergyDistanceConverter,
|
||||||
InformationConverter,
|
InformationConverter,
|
||||||
MassConverter,
|
MassConverter,
|
||||||
PowerConverter,
|
PowerConverter,
|
||||||
|
@ -194,6 +196,15 @@ class SensorDeviceClass(StrEnum):
|
||||||
Unit of measurement: `J`, `kJ`, `MJ`, `GJ`, `mWh`, `Wh`, `kWh`, `MWh`, `GWh`, `TWh`, `cal`, `kcal`, `Mcal`, `Gcal`
|
Unit of measurement: `J`, `kJ`, `MJ`, `GJ`, `mWh`, `Wh`, `kWh`, `MWh`, `GWh`, `TWh`, `cal`, `kcal`, `Mcal`, `Gcal`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
ENERGY_DISTANCE = "energy_distance"
|
||||||
|
"""Energy distance.
|
||||||
|
|
||||||
|
Use this device class for sensors measuring energy by distance, for example the amount
|
||||||
|
of electric energy consumed by an electric car.
|
||||||
|
|
||||||
|
Unit of measurement: `kWh/100km`, `mi/kWh`, `km/kWh`
|
||||||
|
"""
|
||||||
|
|
||||||
ENERGY_STORAGE = "energy_storage"
|
ENERGY_STORAGE = "energy_storage"
|
||||||
"""Stored energy.
|
"""Stored energy.
|
||||||
|
|
||||||
|
@ -500,6 +511,7 @@ UNIT_CONVERTERS: dict[SensorDeviceClass | str | None, type[BaseUnitConverter]] =
|
||||||
SensorDeviceClass.DISTANCE: DistanceConverter,
|
SensorDeviceClass.DISTANCE: DistanceConverter,
|
||||||
SensorDeviceClass.DURATION: DurationConverter,
|
SensorDeviceClass.DURATION: DurationConverter,
|
||||||
SensorDeviceClass.ENERGY: EnergyConverter,
|
SensorDeviceClass.ENERGY: EnergyConverter,
|
||||||
|
SensorDeviceClass.ENERGY_DISTANCE: EnergyDistanceConverter,
|
||||||
SensorDeviceClass.ENERGY_STORAGE: EnergyConverter,
|
SensorDeviceClass.ENERGY_STORAGE: EnergyConverter,
|
||||||
SensorDeviceClass.GAS: VolumeConverter,
|
SensorDeviceClass.GAS: VolumeConverter,
|
||||||
SensorDeviceClass.POWER: PowerConverter,
|
SensorDeviceClass.POWER: PowerConverter,
|
||||||
|
@ -541,6 +553,7 @@ DEVICE_CLASS_UNITS: dict[SensorDeviceClass, set[type[StrEnum] | str | None]] = {
|
||||||
UnitOfTime.MILLISECONDS,
|
UnitOfTime.MILLISECONDS,
|
||||||
},
|
},
|
||||||
SensorDeviceClass.ENERGY: set(UnitOfEnergy),
|
SensorDeviceClass.ENERGY: set(UnitOfEnergy),
|
||||||
|
SensorDeviceClass.ENERGY_DISTANCE: set(UnitOfEnergyDistance),
|
||||||
SensorDeviceClass.ENERGY_STORAGE: set(UnitOfEnergy),
|
SensorDeviceClass.ENERGY_STORAGE: set(UnitOfEnergy),
|
||||||
SensorDeviceClass.FREQUENCY: set(UnitOfFrequency),
|
SensorDeviceClass.FREQUENCY: set(UnitOfFrequency),
|
||||||
SensorDeviceClass.GAS: {
|
SensorDeviceClass.GAS: {
|
||||||
|
@ -622,6 +635,7 @@ DEVICE_CLASS_STATE_CLASSES: dict[SensorDeviceClass, set[SensorStateClass]] = {
|
||||||
SensorStateClass.TOTAL,
|
SensorStateClass.TOTAL,
|
||||||
SensorStateClass.TOTAL_INCREASING,
|
SensorStateClass.TOTAL_INCREASING,
|
||||||
},
|
},
|
||||||
|
SensorDeviceClass.ENERGY_DISTANCE: {SensorStateClass.MEASUREMENT},
|
||||||
SensorDeviceClass.ENERGY_STORAGE: {SensorStateClass.MEASUREMENT},
|
SensorDeviceClass.ENERGY_STORAGE: {SensorStateClass.MEASUREMENT},
|
||||||
SensorDeviceClass.ENUM: set(),
|
SensorDeviceClass.ENUM: set(),
|
||||||
SensorDeviceClass.FREQUENCY: {SensorStateClass.MEASUREMENT},
|
SensorDeviceClass.FREQUENCY: {SensorStateClass.MEASUREMENT},
|
||||||
|
|
|
@ -48,6 +48,7 @@ CONF_IS_DATA_SIZE = "is_data_size"
|
||||||
CONF_IS_DISTANCE = "is_distance"
|
CONF_IS_DISTANCE = "is_distance"
|
||||||
CONF_IS_DURATION = "is_duration"
|
CONF_IS_DURATION = "is_duration"
|
||||||
CONF_IS_ENERGY = "is_energy"
|
CONF_IS_ENERGY = "is_energy"
|
||||||
|
CONF_IS_ENERGY_DISTANCE = "is_energy_distance"
|
||||||
CONF_IS_FREQUENCY = "is_frequency"
|
CONF_IS_FREQUENCY = "is_frequency"
|
||||||
CONF_IS_HUMIDITY = "is_humidity"
|
CONF_IS_HUMIDITY = "is_humidity"
|
||||||
CONF_IS_GAS = "is_gas"
|
CONF_IS_GAS = "is_gas"
|
||||||
|
@ -102,6 +103,7 @@ ENTITY_CONDITIONS = {
|
||||||
SensorDeviceClass.DISTANCE: [{CONF_TYPE: CONF_IS_DISTANCE}],
|
SensorDeviceClass.DISTANCE: [{CONF_TYPE: CONF_IS_DISTANCE}],
|
||||||
SensorDeviceClass.DURATION: [{CONF_TYPE: CONF_IS_DURATION}],
|
SensorDeviceClass.DURATION: [{CONF_TYPE: CONF_IS_DURATION}],
|
||||||
SensorDeviceClass.ENERGY: [{CONF_TYPE: CONF_IS_ENERGY}],
|
SensorDeviceClass.ENERGY: [{CONF_TYPE: CONF_IS_ENERGY}],
|
||||||
|
SensorDeviceClass.ENERGY_DISTANCE: [{CONF_TYPE: CONF_IS_ENERGY_DISTANCE}],
|
||||||
SensorDeviceClass.ENERGY_STORAGE: [{CONF_TYPE: CONF_IS_ENERGY}],
|
SensorDeviceClass.ENERGY_STORAGE: [{CONF_TYPE: CONF_IS_ENERGY}],
|
||||||
SensorDeviceClass.FREQUENCY: [{CONF_TYPE: CONF_IS_FREQUENCY}],
|
SensorDeviceClass.FREQUENCY: [{CONF_TYPE: CONF_IS_FREQUENCY}],
|
||||||
SensorDeviceClass.GAS: [{CONF_TYPE: CONF_IS_GAS}],
|
SensorDeviceClass.GAS: [{CONF_TYPE: CONF_IS_GAS}],
|
||||||
|
@ -168,6 +170,7 @@ CONDITION_SCHEMA = vol.All(
|
||||||
CONF_IS_DISTANCE,
|
CONF_IS_DISTANCE,
|
||||||
CONF_IS_DURATION,
|
CONF_IS_DURATION,
|
||||||
CONF_IS_ENERGY,
|
CONF_IS_ENERGY,
|
||||||
|
CONF_IS_ENERGY_DISTANCE,
|
||||||
CONF_IS_FREQUENCY,
|
CONF_IS_FREQUENCY,
|
||||||
CONF_IS_GAS,
|
CONF_IS_GAS,
|
||||||
CONF_IS_HUMIDITY,
|
CONF_IS_HUMIDITY,
|
||||||
|
|
|
@ -47,6 +47,7 @@ CONF_DATA_SIZE = "data_size"
|
||||||
CONF_DISTANCE = "distance"
|
CONF_DISTANCE = "distance"
|
||||||
CONF_DURATION = "duration"
|
CONF_DURATION = "duration"
|
||||||
CONF_ENERGY = "energy"
|
CONF_ENERGY = "energy"
|
||||||
|
CONF_ENERGY_DISTANCE = "energy_distance"
|
||||||
CONF_FREQUENCY = "frequency"
|
CONF_FREQUENCY = "frequency"
|
||||||
CONF_GAS = "gas"
|
CONF_GAS = "gas"
|
||||||
CONF_HUMIDITY = "humidity"
|
CONF_HUMIDITY = "humidity"
|
||||||
|
@ -101,6 +102,7 @@ ENTITY_TRIGGERS = {
|
||||||
SensorDeviceClass.DISTANCE: [{CONF_TYPE: CONF_DISTANCE}],
|
SensorDeviceClass.DISTANCE: [{CONF_TYPE: CONF_DISTANCE}],
|
||||||
SensorDeviceClass.DURATION: [{CONF_TYPE: CONF_DURATION}],
|
SensorDeviceClass.DURATION: [{CONF_TYPE: CONF_DURATION}],
|
||||||
SensorDeviceClass.ENERGY: [{CONF_TYPE: CONF_ENERGY}],
|
SensorDeviceClass.ENERGY: [{CONF_TYPE: CONF_ENERGY}],
|
||||||
|
SensorDeviceClass.ENERGY_DISTANCE: [{CONF_TYPE: CONF_ENERGY_DISTANCE}],
|
||||||
SensorDeviceClass.ENERGY_STORAGE: [{CONF_TYPE: CONF_ENERGY}],
|
SensorDeviceClass.ENERGY_STORAGE: [{CONF_TYPE: CONF_ENERGY}],
|
||||||
SensorDeviceClass.FREQUENCY: [{CONF_TYPE: CONF_FREQUENCY}],
|
SensorDeviceClass.FREQUENCY: [{CONF_TYPE: CONF_FREQUENCY}],
|
||||||
SensorDeviceClass.GAS: [{CONF_TYPE: CONF_GAS}],
|
SensorDeviceClass.GAS: [{CONF_TYPE: CONF_GAS}],
|
||||||
|
@ -168,6 +170,7 @@ TRIGGER_SCHEMA = vol.All(
|
||||||
CONF_DISTANCE,
|
CONF_DISTANCE,
|
||||||
CONF_DURATION,
|
CONF_DURATION,
|
||||||
CONF_ENERGY,
|
CONF_ENERGY,
|
||||||
|
CONF_ENERGY_DISTANCE,
|
||||||
CONF_FREQUENCY,
|
CONF_FREQUENCY,
|
||||||
CONF_GAS,
|
CONF_GAS,
|
||||||
CONF_HUMIDITY,
|
CONF_HUMIDITY,
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
"is_distance": "Current {entity_name} distance",
|
"is_distance": "Current {entity_name} distance",
|
||||||
"is_duration": "Current {entity_name} duration",
|
"is_duration": "Current {entity_name} duration",
|
||||||
"is_energy": "Current {entity_name} energy",
|
"is_energy": "Current {entity_name} energy",
|
||||||
|
"is_energy_distance": "Current {entity_name} energy per distance",
|
||||||
"is_frequency": "Current {entity_name} frequency",
|
"is_frequency": "Current {entity_name} frequency",
|
||||||
"is_gas": "Current {entity_name} gas",
|
"is_gas": "Current {entity_name} gas",
|
||||||
"is_humidity": "Current {entity_name} humidity",
|
"is_humidity": "Current {entity_name} humidity",
|
||||||
|
@ -69,6 +70,7 @@
|
||||||
"distance": "{entity_name} distance changes",
|
"distance": "{entity_name} distance changes",
|
||||||
"duration": "{entity_name} duration changes",
|
"duration": "{entity_name} duration changes",
|
||||||
"energy": "{entity_name} energy changes",
|
"energy": "{entity_name} energy changes",
|
||||||
|
"energy_distance": "{entity_name} energy per distance changes",
|
||||||
"frequency": "{entity_name} frequency changes",
|
"frequency": "{entity_name} frequency changes",
|
||||||
"gas": "{entity_name} gas changes",
|
"gas": "{entity_name} gas changes",
|
||||||
"humidity": "{entity_name} humidity changes",
|
"humidity": "{entity_name} humidity changes",
|
||||||
|
@ -183,6 +185,9 @@
|
||||||
"energy": {
|
"energy": {
|
||||||
"name": "Energy"
|
"name": "Energy"
|
||||||
},
|
},
|
||||||
|
"energy_distance": {
|
||||||
|
"name": "Energy per distance"
|
||||||
|
},
|
||||||
"energy_storage": {
|
"energy_storage": {
|
||||||
"name": "Stored energy"
|
"name": "Stored energy"
|
||||||
},
|
},
|
||||||
|
|
|
@ -632,6 +632,15 @@ class UnitOfEnergy(StrEnum):
|
||||||
GIGA_CALORIE = "Gcal"
|
GIGA_CALORIE = "Gcal"
|
||||||
|
|
||||||
|
|
||||||
|
# Energy Distance units
|
||||||
|
class UnitOfEnergyDistance(StrEnum):
|
||||||
|
"""Energy Distance units."""
|
||||||
|
|
||||||
|
KILO_WATT_HOUR_PER_100_KM = "kWh/100km"
|
||||||
|
MILES_PER_KILO_WATT_HOUR = "mi/kWh"
|
||||||
|
KM_PER_KILO_WATT_HOUR = "km/kWh"
|
||||||
|
|
||||||
|
|
||||||
# Electric_current units
|
# Electric_current units
|
||||||
class UnitOfElectricCurrent(StrEnum):
|
class UnitOfElectricCurrent(StrEnum):
|
||||||
"""Electric current units."""
|
"""Electric current units."""
|
||||||
|
|
|
@ -17,6 +17,7 @@ from homeassistant.const import (
|
||||||
UnitOfElectricCurrent,
|
UnitOfElectricCurrent,
|
||||||
UnitOfElectricPotential,
|
UnitOfElectricPotential,
|
||||||
UnitOfEnergy,
|
UnitOfEnergy,
|
||||||
|
UnitOfEnergyDistance,
|
||||||
UnitOfInformation,
|
UnitOfInformation,
|
||||||
UnitOfLength,
|
UnitOfLength,
|
||||||
UnitOfMass,
|
UnitOfMass,
|
||||||
|
@ -90,6 +91,7 @@ class BaseUnitConverter:
|
||||||
VALID_UNITS: set[str | None]
|
VALID_UNITS: set[str | None]
|
||||||
|
|
||||||
_UNIT_CONVERSION: dict[str | None, float]
|
_UNIT_CONVERSION: dict[str | None, float]
|
||||||
|
_UNIT_INVERSES: set[str] = set()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def convert(cls, value: float, from_unit: str | None, to_unit: str | None) -> float:
|
def convert(cls, value: float, from_unit: str | None, to_unit: str | None) -> float:
|
||||||
|
@ -105,6 +107,8 @@ class BaseUnitConverter:
|
||||||
if from_unit == to_unit:
|
if from_unit == to_unit:
|
||||||
return lambda value: value
|
return lambda value: value
|
||||||
from_ratio, to_ratio = cls._get_from_to_ratio(from_unit, to_unit)
|
from_ratio, to_ratio = cls._get_from_to_ratio(from_unit, to_unit)
|
||||||
|
if cls._are_unit_inverses(from_unit, to_unit):
|
||||||
|
return lambda val: to_ratio / (val / from_ratio)
|
||||||
return lambda val: (val / from_ratio) * to_ratio
|
return lambda val: (val / from_ratio) * to_ratio
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -129,6 +133,8 @@ class BaseUnitConverter:
|
||||||
if from_unit == to_unit:
|
if from_unit == to_unit:
|
||||||
return lambda value: value
|
return lambda value: value
|
||||||
from_ratio, to_ratio = cls._get_from_to_ratio(from_unit, to_unit)
|
from_ratio, to_ratio = cls._get_from_to_ratio(from_unit, to_unit)
|
||||||
|
if cls._are_unit_inverses(from_unit, to_unit):
|
||||||
|
return lambda val: None if val is None else to_ratio / (val / from_ratio)
|
||||||
return lambda val: None if val is None else (val / from_ratio) * to_ratio
|
return lambda val: None if val is None else (val / from_ratio) * to_ratio
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -138,6 +144,12 @@ class BaseUnitConverter:
|
||||||
from_ratio, to_ratio = cls._get_from_to_ratio(from_unit, to_unit)
|
from_ratio, to_ratio = cls._get_from_to_ratio(from_unit, to_unit)
|
||||||
return from_ratio / to_ratio
|
return from_ratio / to_ratio
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
@lru_cache
|
||||||
|
def _are_unit_inverses(cls, from_unit: str | None, to_unit: str | None) -> bool:
|
||||||
|
"""Return true if one unit is an inverse but not the other."""
|
||||||
|
return (from_unit in cls._UNIT_INVERSES) != (to_unit in cls._UNIT_INVERSES)
|
||||||
|
|
||||||
|
|
||||||
class DataRateConverter(BaseUnitConverter):
|
class DataRateConverter(BaseUnitConverter):
|
||||||
"""Utility to convert data rate values."""
|
"""Utility to convert data rate values."""
|
||||||
|
@ -284,6 +296,22 @@ class EnergyConverter(BaseUnitConverter):
|
||||||
VALID_UNITS = set(UnitOfEnergy)
|
VALID_UNITS = set(UnitOfEnergy)
|
||||||
|
|
||||||
|
|
||||||
|
class EnergyDistanceConverter(BaseUnitConverter):
|
||||||
|
"""Utility to convert vehicle energy consumption values."""
|
||||||
|
|
||||||
|
UNIT_CLASS = "energy_distance"
|
||||||
|
_UNIT_CONVERSION: dict[str | None, float] = {
|
||||||
|
UnitOfEnergyDistance.KILO_WATT_HOUR_PER_100_KM: 1,
|
||||||
|
UnitOfEnergyDistance.MILES_PER_KILO_WATT_HOUR: 100 * _KM_TO_M / _MILE_TO_M,
|
||||||
|
UnitOfEnergyDistance.KM_PER_KILO_WATT_HOUR: 100,
|
||||||
|
}
|
||||||
|
_UNIT_INVERSES: set[str] = {
|
||||||
|
UnitOfEnergyDistance.MILES_PER_KILO_WATT_HOUR,
|
||||||
|
UnitOfEnergyDistance.KM_PER_KILO_WATT_HOUR,
|
||||||
|
}
|
||||||
|
VALID_UNITS = set(UnitOfEnergyDistance)
|
||||||
|
|
||||||
|
|
||||||
class InformationConverter(BaseUnitConverter):
|
class InformationConverter(BaseUnitConverter):
|
||||||
"""Utility to convert information values."""
|
"""Utility to convert information values."""
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ from homeassistant.const import (
|
||||||
UnitOfElectricCurrent,
|
UnitOfElectricCurrent,
|
||||||
UnitOfElectricPotential,
|
UnitOfElectricPotential,
|
||||||
UnitOfEnergy,
|
UnitOfEnergy,
|
||||||
|
UnitOfEnergyDistance,
|
||||||
UnitOfInformation,
|
UnitOfInformation,
|
||||||
UnitOfLength,
|
UnitOfLength,
|
||||||
UnitOfMass,
|
UnitOfMass,
|
||||||
|
@ -43,6 +44,7 @@ from homeassistant.util.unit_conversion import (
|
||||||
ElectricCurrentConverter,
|
ElectricCurrentConverter,
|
||||||
ElectricPotentialConverter,
|
ElectricPotentialConverter,
|
||||||
EnergyConverter,
|
EnergyConverter,
|
||||||
|
EnergyDistanceConverter,
|
||||||
InformationConverter,
|
InformationConverter,
|
||||||
MassConverter,
|
MassConverter,
|
||||||
PowerConverter,
|
PowerConverter,
|
||||||
|
@ -79,6 +81,7 @@ _ALL_CONVERTERS: dict[type[BaseUnitConverter], list[str | None]] = {
|
||||||
SpeedConverter,
|
SpeedConverter,
|
||||||
TemperatureConverter,
|
TemperatureConverter,
|
||||||
UnitlessRatioConverter,
|
UnitlessRatioConverter,
|
||||||
|
EnergyDistanceConverter,
|
||||||
VolumeConverter,
|
VolumeConverter,
|
||||||
VolumeFlowRateConverter,
|
VolumeFlowRateConverter,
|
||||||
)
|
)
|
||||||
|
@ -115,6 +118,11 @@ _GET_UNIT_RATIO: dict[type[BaseUnitConverter], tuple[str | None, str | None, flo
|
||||||
1000,
|
1000,
|
||||||
),
|
),
|
||||||
EnergyConverter: (UnitOfEnergy.WATT_HOUR, UnitOfEnergy.KILO_WATT_HOUR, 1000),
|
EnergyConverter: (UnitOfEnergy.WATT_HOUR, UnitOfEnergy.KILO_WATT_HOUR, 1000),
|
||||||
|
EnergyDistanceConverter: (
|
||||||
|
UnitOfEnergyDistance.MILES_PER_KILO_WATT_HOUR,
|
||||||
|
UnitOfEnergyDistance.KM_PER_KILO_WATT_HOUR,
|
||||||
|
0.621371,
|
||||||
|
),
|
||||||
InformationConverter: (UnitOfInformation.BITS, UnitOfInformation.BYTES, 8),
|
InformationConverter: (UnitOfInformation.BITS, UnitOfInformation.BYTES, 8),
|
||||||
MassConverter: (UnitOfMass.STONES, UnitOfMass.KILOGRAMS, 0.157473),
|
MassConverter: (UnitOfMass.STONES, UnitOfMass.KILOGRAMS, 0.157473),
|
||||||
PowerConverter: (UnitOfPower.WATT, UnitOfPower.KILO_WATT, 1000),
|
PowerConverter: (UnitOfPower.WATT, UnitOfPower.KILO_WATT, 1000),
|
||||||
|
@ -486,6 +494,38 @@ _CONVERTED_VALUE: dict[
|
||||||
(10, UnitOfEnergy.GIGA_CALORIE, 10000, UnitOfEnergy.MEGA_CALORIE),
|
(10, UnitOfEnergy.GIGA_CALORIE, 10000, UnitOfEnergy.MEGA_CALORIE),
|
||||||
(10, UnitOfEnergy.GIGA_CALORIE, 11.622222, UnitOfEnergy.MEGA_WATT_HOUR),
|
(10, UnitOfEnergy.GIGA_CALORIE, 11.622222, UnitOfEnergy.MEGA_WATT_HOUR),
|
||||||
],
|
],
|
||||||
|
EnergyDistanceConverter: [
|
||||||
|
(
|
||||||
|
10,
|
||||||
|
UnitOfEnergyDistance.KILO_WATT_HOUR_PER_100_KM,
|
||||||
|
6.213712,
|
||||||
|
UnitOfEnergyDistance.MILES_PER_KILO_WATT_HOUR,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
25,
|
||||||
|
UnitOfEnergyDistance.KILO_WATT_HOUR_PER_100_KM,
|
||||||
|
4,
|
||||||
|
UnitOfEnergyDistance.KM_PER_KILO_WATT_HOUR,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
20,
|
||||||
|
UnitOfEnergyDistance.MILES_PER_KILO_WATT_HOUR,
|
||||||
|
3.106856,
|
||||||
|
UnitOfEnergyDistance.KILO_WATT_HOUR_PER_100_KM,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
10,
|
||||||
|
UnitOfEnergyDistance.MILES_PER_KILO_WATT_HOUR,
|
||||||
|
16.09344,
|
||||||
|
UnitOfEnergyDistance.KM_PER_KILO_WATT_HOUR,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
16.09344,
|
||||||
|
UnitOfEnergyDistance.KM_PER_KILO_WATT_HOUR,
|
||||||
|
10,
|
||||||
|
UnitOfEnergyDistance.MILES_PER_KILO_WATT_HOUR,
|
||||||
|
),
|
||||||
|
],
|
||||||
InformationConverter: [
|
InformationConverter: [
|
||||||
(8e3, UnitOfInformation.BITS, 8, UnitOfInformation.KILOBITS),
|
(8e3, UnitOfInformation.BITS, 8, UnitOfInformation.KILOBITS),
|
||||||
(8e6, UnitOfInformation.BITS, 8, UnitOfInformation.MEGABITS),
|
(8e6, UnitOfInformation.BITS, 8, UnitOfInformation.MEGABITS),
|
||||||
|
|
Loading…
Reference in New Issue