Flow rate unit conversions and device class (#106077)

* Add volume flow rate conversions

* Add missing translations

* Adjust liter unit and add gallons per minute

* Adjust to min instead of m for minutes

* Add matching class for number

* Add some tests for number and sensor platform

* Add deprecated constants

* Add explicit list of flow rate for check

This reverts commit 105171af31.
This commit is contained in:
Joakim Plate 2024-01-30 15:01:08 +01:00 committed by GitHub
parent a8e3df7e50
commit cece117c93
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 180 additions and 3 deletions

View file

@ -34,6 +34,7 @@ from homeassistant.const import (
UnitOfTemperature, UnitOfTemperature,
UnitOfTime, UnitOfTime,
UnitOfVolume, UnitOfVolume,
UnitOfVolumeFlowRate,
UnitOfVolumetricFlux, UnitOfVolumetricFlux,
) )
from homeassistant.helpers.deprecation import ( from homeassistant.helpers.deprecation import (
@ -42,7 +43,11 @@ from homeassistant.helpers.deprecation import (
check_if_deprecated_constant, check_if_deprecated_constant,
dir_with_deprecated_constants, dir_with_deprecated_constants,
) )
from homeassistant.util.unit_conversion import BaseUnitConverter, TemperatureConverter from homeassistant.util.unit_conversion import (
BaseUnitConverter,
TemperatureConverter,
VolumeFlowRateConverter,
)
ATTR_VALUE = "value" ATTR_VALUE = "value"
ATTR_MIN = "min" ATTR_MIN = "min"
@ -372,6 +377,14 @@ class NumberDeviceClass(StrEnum):
USCS/imperial units are currently assumed to be US volumes) USCS/imperial units are currently assumed to be US volumes)
""" """
VOLUME_FLOW_RATE = "volume_flow_rate"
"""Generic flow rate
Unit of measurement: UnitOfVolumeFlowRate
- SI / metric: `/h`, `L/min`
- USCS / imperial: `ft³/min`, `gal/min`
"""
WATER = "water" WATER = "water"
"""Water. """Water.
@ -464,6 +477,7 @@ DEVICE_CLASS_UNITS: dict[NumberDeviceClass, set[type[StrEnum] | str | None]] = {
NumberDeviceClass.VOLTAGE: set(UnitOfElectricPotential), NumberDeviceClass.VOLTAGE: set(UnitOfElectricPotential),
NumberDeviceClass.VOLUME: set(UnitOfVolume), NumberDeviceClass.VOLUME: set(UnitOfVolume),
NumberDeviceClass.VOLUME_STORAGE: set(UnitOfVolume), NumberDeviceClass.VOLUME_STORAGE: set(UnitOfVolume),
NumberDeviceClass.VOLUME_FLOW_RATE: set(UnitOfVolumeFlowRate),
NumberDeviceClass.WATER: { NumberDeviceClass.WATER: {
UnitOfVolume.CENTUM_CUBIC_FEET, UnitOfVolume.CENTUM_CUBIC_FEET,
UnitOfVolume.CUBIC_FEET, UnitOfVolume.CUBIC_FEET,
@ -477,6 +491,7 @@ DEVICE_CLASS_UNITS: dict[NumberDeviceClass, set[type[StrEnum] | str | None]] = {
UNIT_CONVERTERS: dict[NumberDeviceClass, type[BaseUnitConverter]] = { UNIT_CONVERTERS: dict[NumberDeviceClass, type[BaseUnitConverter]] = {
NumberDeviceClass.TEMPERATURE: TemperatureConverter, NumberDeviceClass.TEMPERATURE: TemperatureConverter,
NumberDeviceClass.VOLUME_FLOW_RATE: VolumeFlowRateConverter,
} }
# These can be removed if no deprecated constant are in this module anymore # These can be removed if no deprecated constant are in this module anymore

View file

@ -148,6 +148,9 @@
"volume_storage": { "volume_storage": {
"name": "[%key:component::sensor::entity_component::volume_storage::name%]" "name": "[%key:component::sensor::entity_component::volume_storage::name%]"
}, },
"volume_flow_rate": {
"name": "[%key:component::sensor::entity_component::volume_flow_rate::name%]"
},
"water": { "water": {
"name": "[%key:component::sensor::entity_component::water::name%]" "name": "[%key:component::sensor::entity_component::water::name%]"
}, },

View file

@ -41,6 +41,7 @@ from homeassistant.util.unit_conversion import (
TemperatureConverter, TemperatureConverter,
UnitlessRatioConverter, UnitlessRatioConverter,
VolumeConverter, VolumeConverter,
VolumeFlowRateConverter,
) )
from .const import ( from .const import (
@ -139,6 +140,7 @@ STATISTIC_UNIT_TO_UNIT_CONVERTER: dict[str | None, type[BaseUnitConverter]] = {
**{unit: TemperatureConverter for unit in TemperatureConverter.VALID_UNITS}, **{unit: TemperatureConverter for unit in TemperatureConverter.VALID_UNITS},
**{unit: UnitlessRatioConverter for unit in UnitlessRatioConverter.VALID_UNITS}, **{unit: UnitlessRatioConverter for unit in UnitlessRatioConverter.VALID_UNITS},
**{unit: VolumeConverter for unit in VolumeConverter.VALID_UNITS}, **{unit: VolumeConverter for unit in VolumeConverter.VALID_UNITS},
**{unit: VolumeFlowRateConverter for unit in VolumeFlowRateConverter.VALID_UNITS},
} }
DATA_SHORT_TERM_STATISTICS_RUN_CACHE = "recorder_short_term_statistics_run_cache" DATA_SHORT_TERM_STATISTICS_RUN_CACHE = "recorder_short_term_statistics_run_cache"

View file

@ -28,6 +28,7 @@ from homeassistant.util.unit_conversion import (
TemperatureConverter, TemperatureConverter,
UnitlessRatioConverter, UnitlessRatioConverter,
VolumeConverter, VolumeConverter,
VolumeFlowRateConverter,
) )
from .models import StatisticPeriod from .models import StatisticPeriod
@ -67,6 +68,7 @@ UNIT_SCHEMA = vol.Schema(
vol.Optional("temperature"): vol.In(TemperatureConverter.VALID_UNITS), vol.Optional("temperature"): vol.In(TemperatureConverter.VALID_UNITS),
vol.Optional("unitless"): vol.In(UnitlessRatioConverter.VALID_UNITS), vol.Optional("unitless"): vol.In(UnitlessRatioConverter.VALID_UNITS),
vol.Optional("volume"): vol.In(VolumeConverter.VALID_UNITS), vol.Optional("volume"): vol.In(VolumeConverter.VALID_UNITS),
vol.Optional("volume_flow_rate"): vol.In(VolumeFlowRateConverter.VALID_UNITS),
} }
) )

View file

@ -34,6 +34,7 @@ from homeassistant.const import (
UnitOfTemperature, UnitOfTemperature,
UnitOfTime, UnitOfTime,
UnitOfVolume, UnitOfVolume,
UnitOfVolumeFlowRate,
UnitOfVolumetricFlux, UnitOfVolumetricFlux,
) )
from homeassistant.helpers.deprecation import ( from homeassistant.helpers.deprecation import (
@ -57,6 +58,7 @@ from homeassistant.util.unit_conversion import (
TemperatureConverter, TemperatureConverter,
UnitlessRatioConverter, UnitlessRatioConverter,
VolumeConverter, VolumeConverter,
VolumeFlowRateConverter,
) )
DOMAIN: Final = "sensor" DOMAIN: Final = "sensor"
@ -394,6 +396,14 @@ class SensorDeviceClass(StrEnum):
USCS/imperial units are currently assumed to be US volumes) USCS/imperial units are currently assumed to be US volumes)
""" """
VOLUME_FLOW_RATE = "volume_flow_rate"
"""Generic flow rate
Unit of measurement: UnitOfVolumeFlowRate
- SI / metric: `/h`, `L/min`
- USCS / imperial: `ft³/min`, `gal/min`
"""
WATER = "water" WATER = "water"
"""Water. """Water.
@ -489,6 +499,7 @@ UNIT_CONVERTERS: dict[SensorDeviceClass | str | None, type[BaseUnitConverter]] =
SensorDeviceClass.VOLTAGE: ElectricPotentialConverter, SensorDeviceClass.VOLTAGE: ElectricPotentialConverter,
SensorDeviceClass.VOLUME: VolumeConverter, SensorDeviceClass.VOLUME: VolumeConverter,
SensorDeviceClass.VOLUME_STORAGE: VolumeConverter, SensorDeviceClass.VOLUME_STORAGE: VolumeConverter,
SensorDeviceClass.VOLUME_FLOW_RATE: VolumeFlowRateConverter,
SensorDeviceClass.WATER: VolumeConverter, SensorDeviceClass.WATER: VolumeConverter,
SensorDeviceClass.WEIGHT: MassConverter, SensorDeviceClass.WEIGHT: MassConverter,
SensorDeviceClass.WIND_SPEED: SpeedConverter, SensorDeviceClass.WIND_SPEED: SpeedConverter,
@ -555,6 +566,7 @@ DEVICE_CLASS_UNITS: dict[SensorDeviceClass, set[type[StrEnum] | str | None]] = {
}, },
SensorDeviceClass.VOLTAGE: set(UnitOfElectricPotential), SensorDeviceClass.VOLTAGE: set(UnitOfElectricPotential),
SensorDeviceClass.VOLUME: set(UnitOfVolume), SensorDeviceClass.VOLUME: set(UnitOfVolume),
SensorDeviceClass.VOLUME_FLOW_RATE: set(UnitOfVolumeFlowRate),
SensorDeviceClass.VOLUME_STORAGE: set(UnitOfVolume), SensorDeviceClass.VOLUME_STORAGE: set(UnitOfVolume),
SensorDeviceClass.WATER: { SensorDeviceClass.WATER: {
UnitOfVolume.CENTUM_CUBIC_FEET, UnitOfVolume.CENTUM_CUBIC_FEET,
@ -621,6 +633,7 @@ DEVICE_CLASS_STATE_CLASSES: dict[SensorDeviceClass, set[SensorStateClass]] = {
SensorStateClass.TOTAL_INCREASING, SensorStateClass.TOTAL_INCREASING,
}, },
SensorDeviceClass.VOLUME_STORAGE: {SensorStateClass.MEASUREMENT}, SensorDeviceClass.VOLUME_STORAGE: {SensorStateClass.MEASUREMENT},
SensorDeviceClass.VOLUME_FLOW_RATE: {SensorStateClass.MEASUREMENT},
SensorDeviceClass.WATER: { SensorDeviceClass.WATER: {
SensorStateClass.TOTAL, SensorStateClass.TOTAL,
SensorStateClass.TOTAL_INCREASING, SensorStateClass.TOTAL_INCREASING,

View file

@ -77,6 +77,7 @@ CONF_IS_VOLATILE_ORGANIC_COMPOUNDS = "is_volatile_organic_compounds"
CONF_IS_VOLATILE_ORGANIC_COMPOUNDS_PARTS = "is_volatile_organic_compounds_parts" CONF_IS_VOLATILE_ORGANIC_COMPOUNDS_PARTS = "is_volatile_organic_compounds_parts"
CONF_IS_VOLTAGE = "is_voltage" CONF_IS_VOLTAGE = "is_voltage"
CONF_IS_VOLUME = "is_volume" CONF_IS_VOLUME = "is_volume"
CONF_IS_VOLUME_FLOW_RATE = "is_volume_flow_rate"
CONF_IS_WATER = "is_water" CONF_IS_WATER = "is_water"
CONF_IS_WEIGHT = "is_weight" CONF_IS_WEIGHT = "is_weight"
CONF_IS_WIND_SPEED = "is_wind_speed" CONF_IS_WIND_SPEED = "is_wind_speed"
@ -132,6 +133,7 @@ ENTITY_CONDITIONS = {
SensorDeviceClass.VOLTAGE: [{CONF_TYPE: CONF_IS_VOLTAGE}], SensorDeviceClass.VOLTAGE: [{CONF_TYPE: CONF_IS_VOLTAGE}],
SensorDeviceClass.VOLUME: [{CONF_TYPE: CONF_IS_VOLUME}], SensorDeviceClass.VOLUME: [{CONF_TYPE: CONF_IS_VOLUME}],
SensorDeviceClass.VOLUME_STORAGE: [{CONF_TYPE: CONF_IS_VOLUME}], SensorDeviceClass.VOLUME_STORAGE: [{CONF_TYPE: CONF_IS_VOLUME}],
SensorDeviceClass.VOLUME_FLOW_RATE: [{CONF_TYPE: CONF_IS_VOLUME_FLOW_RATE}],
SensorDeviceClass.WATER: [{CONF_TYPE: CONF_IS_WATER}], SensorDeviceClass.WATER: [{CONF_TYPE: CONF_IS_WATER}],
SensorDeviceClass.WEIGHT: [{CONF_TYPE: CONF_IS_WEIGHT}], SensorDeviceClass.WEIGHT: [{CONF_TYPE: CONF_IS_WEIGHT}],
SensorDeviceClass.WIND_SPEED: [{CONF_TYPE: CONF_IS_WIND_SPEED}], SensorDeviceClass.WIND_SPEED: [{CONF_TYPE: CONF_IS_WIND_SPEED}],
@ -186,6 +188,7 @@ CONDITION_SCHEMA = vol.All(
CONF_IS_VOLATILE_ORGANIC_COMPOUNDS_PARTS, CONF_IS_VOLATILE_ORGANIC_COMPOUNDS_PARTS,
CONF_IS_VOLTAGE, CONF_IS_VOLTAGE,
CONF_IS_VOLUME, CONF_IS_VOLUME,
CONF_IS_VOLUME_FLOW_RATE,
CONF_IS_WATER, CONF_IS_WATER,
CONF_IS_WEIGHT, CONF_IS_WEIGHT,
CONF_IS_WIND_SPEED, CONF_IS_WIND_SPEED,

View file

@ -76,6 +76,7 @@ CONF_VOLATILE_ORGANIC_COMPOUNDS = "volatile_organic_compounds"
CONF_VOLATILE_ORGANIC_COMPOUNDS_PARTS = "volatile_organic_compounds_parts" CONF_VOLATILE_ORGANIC_COMPOUNDS_PARTS = "volatile_organic_compounds_parts"
CONF_VOLTAGE = "voltage" CONF_VOLTAGE = "voltage"
CONF_VOLUME = "volume" CONF_VOLUME = "volume"
CONF_VOLUME_FLOW_RATE = "volume_flow_rate"
CONF_WATER = "water" CONF_WATER = "water"
CONF_WEIGHT = "weight" CONF_WEIGHT = "weight"
CONF_WIND_SPEED = "wind_speed" CONF_WIND_SPEED = "wind_speed"
@ -131,6 +132,7 @@ ENTITY_TRIGGERS = {
SensorDeviceClass.VOLTAGE: [{CONF_TYPE: CONF_VOLTAGE}], SensorDeviceClass.VOLTAGE: [{CONF_TYPE: CONF_VOLTAGE}],
SensorDeviceClass.VOLUME: [{CONF_TYPE: CONF_VOLUME}], SensorDeviceClass.VOLUME: [{CONF_TYPE: CONF_VOLUME}],
SensorDeviceClass.VOLUME_STORAGE: [{CONF_TYPE: CONF_VOLUME}], SensorDeviceClass.VOLUME_STORAGE: [{CONF_TYPE: CONF_VOLUME}],
SensorDeviceClass.VOLUME_FLOW_RATE: [{CONF_TYPE: CONF_VOLUME_FLOW_RATE}],
SensorDeviceClass.WATER: [{CONF_TYPE: CONF_WATER}], SensorDeviceClass.WATER: [{CONF_TYPE: CONF_WATER}],
SensorDeviceClass.WEIGHT: [{CONF_TYPE: CONF_WEIGHT}], SensorDeviceClass.WEIGHT: [{CONF_TYPE: CONF_WEIGHT}],
SensorDeviceClass.WIND_SPEED: [{CONF_TYPE: CONF_WIND_SPEED}], SensorDeviceClass.WIND_SPEED: [{CONF_TYPE: CONF_WIND_SPEED}],
@ -186,6 +188,7 @@ TRIGGER_SCHEMA = vol.All(
CONF_VOLATILE_ORGANIC_COMPOUNDS_PARTS, CONF_VOLATILE_ORGANIC_COMPOUNDS_PARTS,
CONF_VOLTAGE, CONF_VOLTAGE,
CONF_VOLUME, CONF_VOLUME,
CONF_VOLUME_FLOW_RATE,
CONF_WATER, CONF_WATER,
CONF_WEIGHT, CONF_WEIGHT,
CONF_WIND_SPEED, CONF_WIND_SPEED,

View file

@ -45,6 +45,7 @@
"is_volatile_organic_compounds_parts": "[%key:component::sensor::device_automation::condition_type::is_volatile_organic_compounds%]", "is_volatile_organic_compounds_parts": "[%key:component::sensor::device_automation::condition_type::is_volatile_organic_compounds%]",
"is_voltage": "Current {entity_name} voltage", "is_voltage": "Current {entity_name} voltage",
"is_volume": "Current {entity_name} volume", "is_volume": "Current {entity_name} volume",
"is_volume_flow_rate": "Current {entity_name} volume flow rate",
"is_water": "Current {entity_name} water", "is_water": "Current {entity_name} water",
"is_weight": "Current {entity_name} weight", "is_weight": "Current {entity_name} weight",
"is_wind_speed": "Current {entity_name} wind speed" "is_wind_speed": "Current {entity_name} wind speed"
@ -93,6 +94,7 @@
"volatile_organic_compounds_parts": "[%key:component::sensor::device_automation::trigger_type::volatile_organic_compounds%]", "volatile_organic_compounds_parts": "[%key:component::sensor::device_automation::trigger_type::volatile_organic_compounds%]",
"voltage": "{entity_name} voltage changes", "voltage": "{entity_name} voltage changes",
"volume": "{entity_name} volume changes", "volume": "{entity_name} volume changes",
"volume_flow_rate": "{entity_name} volume flow rate changes",
"water": "{entity_name} water changes", "water": "{entity_name} water changes",
"weight": "{entity_name} weight changes", "weight": "{entity_name} weight changes",
"wind_speed": "{entity_name} wind speed changes" "wind_speed": "{entity_name} wind speed changes"
@ -260,6 +262,9 @@
"volume": { "volume": {
"name": "Volume" "name": "Volume"
}, },
"volume_flow_rate": {
"name": "Volume flow rate"
},
"volume_storage": { "volume_storage": {
"name": "Stored volume" "name": "Stored volume"
}, },

View file

@ -1042,7 +1042,9 @@ class UnitOfVolumeFlowRate(StrEnum):
"""Volume flow rate units.""" """Volume flow rate units."""
CUBIC_METERS_PER_HOUR = "m³/h" CUBIC_METERS_PER_HOUR = "m³/h"
CUBIC_FEET_PER_MINUTE = "ft³/m" CUBIC_FEET_PER_MINUTE = "ft³/min"
LITERS_PER_MINUTE = "L/min"
GALLONS_PER_MINUTE = "gal/min"
_DEPRECATED_VOLUME_FLOW_RATE_CUBIC_METERS_PER_HOUR: Final = DeprecatedConstantEnum( _DEPRECATED_VOLUME_FLOW_RATE_CUBIC_METERS_PER_HOUR: Final = DeprecatedConstantEnum(

View file

@ -21,6 +21,7 @@ from homeassistant.const import (
UnitOfSpeed, UnitOfSpeed,
UnitOfTemperature, UnitOfTemperature,
UnitOfVolume, UnitOfVolume,
UnitOfVolumeFlowRate,
UnitOfVolumetricFlux, UnitOfVolumetricFlux,
) )
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
@ -39,6 +40,7 @@ _NAUTICAL_MILE_TO_M = 1852 # 1 nautical mile = 1852 m
# Duration conversion constants # Duration conversion constants
_HRS_TO_SECS = 60 * 60 # 1 hr = 3600 seconds _HRS_TO_SECS = 60 * 60 # 1 hr = 3600 seconds
_HRS_TO_MINUTES = 60 # 1 hr = 60 minutes
_DAYS_TO_SECS = 24 * _HRS_TO_SECS # 1 day = 24 hours = 86400 seconds _DAYS_TO_SECS = 24 * _HRS_TO_SECS # 1 day = 24 hours = 86400 seconds
# Mass conversion constants # Mass conversion constants
@ -516,3 +518,26 @@ class VolumeConverter(BaseUnitConverter):
UnitOfVolume.CUBIC_FEET, UnitOfVolume.CUBIC_FEET,
UnitOfVolume.CENTUM_CUBIC_FEET, UnitOfVolume.CENTUM_CUBIC_FEET,
} }
class VolumeFlowRateConverter(BaseUnitConverter):
"""Utility to convert volume values."""
UNIT_CLASS = "volume_flow_rate"
NORMALIZED_UNIT = UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR
# Units in terms of m³/h
_UNIT_CONVERSION: dict[str | None, float] = {
UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR: 1,
UnitOfVolumeFlowRate.CUBIC_FEET_PER_MINUTE: 1
/ (_HRS_TO_MINUTES * _CUBIC_FOOT_TO_CUBIC_METER),
UnitOfVolumeFlowRate.LITERS_PER_MINUTE: 1
/ (_HRS_TO_MINUTES * _L_TO_CUBIC_METER),
UnitOfVolumeFlowRate.GALLONS_PER_MINUTE: 1
/ (_HRS_TO_MINUTES * _GALLON_TO_CUBIC_METER),
}
VALID_UNITS = {
UnitOfVolumeFlowRate.CUBIC_FEET_PER_MINUTE,
UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
UnitOfVolumeFlowRate.GALLONS_PER_MINUTE,
}

View file

@ -32,6 +32,7 @@ from homeassistant.const import (
ATTR_UNIT_OF_MEASUREMENT, ATTR_UNIT_OF_MEASUREMENT,
CONF_PLATFORM, CONF_PLATFORM,
UnitOfTemperature, UnitOfTemperature,
UnitOfVolumeFlowRate,
) )
from homeassistant.core import HomeAssistant, State from homeassistant.core import HomeAssistant, State
from homeassistant.helpers import entity_registry as er from homeassistant.helpers import entity_registry as er
@ -686,6 +687,22 @@ async def test_restore_number_restore_state(
100, 100,
38.0, 38.0,
), ),
(
SensorDeviceClass.VOLUME_FLOW_RATE,
UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
UnitOfVolumeFlowRate.GALLONS_PER_MINUTE,
UnitOfVolumeFlowRate.GALLONS_PER_MINUTE,
50.0,
"13.2",
),
(
SensorDeviceClass.VOLUME_FLOW_RATE,
UnitOfVolumeFlowRate.GALLONS_PER_MINUTE,
UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
13.0,
"49.2",
),
], ],
) )
async def test_custom_unit( async def test_custom_unit(

View file

@ -36,6 +36,7 @@ from homeassistant.const import (
UnitOfSpeed, UnitOfSpeed,
UnitOfTemperature, UnitOfTemperature,
UnitOfVolume, UnitOfVolume,
UnitOfVolumeFlowRate,
UnitOfVolumetricFlux, UnitOfVolumetricFlux,
) )
from homeassistant.core import HomeAssistant, State from homeassistant.core import HomeAssistant, State
@ -580,6 +581,22 @@ async def test_restore_sensor_restore_state(
-0.00001, -0.00001,
"0", "0",
), ),
(
SensorDeviceClass.VOLUME_FLOW_RATE,
UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
UnitOfVolumeFlowRate.GALLONS_PER_MINUTE,
UnitOfVolumeFlowRate.GALLONS_PER_MINUTE,
50.0,
"13.2",
),
(
SensorDeviceClass.VOLUME_FLOW_RATE,
UnitOfVolumeFlowRate.GALLONS_PER_MINUTE,
UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
13.0,
"49.2",
),
], ],
) )
async def test_custom_unit( async def test_custom_unit(

View file

@ -103,7 +103,13 @@ def test_all() -> None:
], ],
"VOLUME_", "VOLUME_",
) )
+ _create_tuples(const.UnitOfVolumeFlowRate, "VOLUME_FLOW_RATE_") + _create_tuples(
[
const.UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
const.UnitOfVolumeFlowRate.CUBIC_FEET_PER_MINUTE,
],
"VOLUME_FLOW_RATE_",
)
+ _create_tuples( + _create_tuples(
[ [
const.UnitOfMass.GRAMS, const.UnitOfMass.GRAMS,

View file

@ -22,6 +22,7 @@ from homeassistant.const import (
UnitOfSpeed, UnitOfSpeed,
UnitOfTemperature, UnitOfTemperature,
UnitOfVolume, UnitOfVolume,
UnitOfVolumeFlowRate,
UnitOfVolumetricFlux, UnitOfVolumetricFlux,
) )
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
@ -41,6 +42,7 @@ from homeassistant.util.unit_conversion import (
TemperatureConverter, TemperatureConverter,
UnitlessRatioConverter, UnitlessRatioConverter,
VolumeConverter, VolumeConverter,
VolumeFlowRateConverter,
) )
INVALID_SYMBOL = "bob" INVALID_SYMBOL = "bob"
@ -65,6 +67,7 @@ _ALL_CONVERTERS: dict[type[BaseUnitConverter], list[str | None]] = {
TemperatureConverter, TemperatureConverter,
UnitlessRatioConverter, UnitlessRatioConverter,
VolumeConverter, VolumeConverter,
VolumeFlowRateConverter,
) )
} }
@ -103,6 +106,11 @@ _GET_UNIT_RATIO: dict[type[BaseUnitConverter], tuple[str | None, str | None, flo
), ),
UnitlessRatioConverter: (PERCENTAGE, None, 100), UnitlessRatioConverter: (PERCENTAGE, None, 100),
VolumeConverter: (UnitOfVolume.GALLONS, UnitOfVolume.LITERS, 0.264172), VolumeConverter: (UnitOfVolume.GALLONS, UnitOfVolume.LITERS, 0.264172),
VolumeFlowRateConverter: (
UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
0.06,
),
} }
# Dict containing a conversion test for every known unit. # Dict containing a conversion test for every known unit.
@ -413,6 +421,62 @@ _CONVERTED_VALUE: dict[
(5, UnitOfVolume.CENTUM_CUBIC_FEET, 3740.26, UnitOfVolume.GALLONS), (5, UnitOfVolume.CENTUM_CUBIC_FEET, 3740.26, UnitOfVolume.GALLONS),
(5, UnitOfVolume.CENTUM_CUBIC_FEET, 14158.42, UnitOfVolume.LITERS), (5, UnitOfVolume.CENTUM_CUBIC_FEET, 14158.42, UnitOfVolume.LITERS),
], ],
VolumeFlowRateConverter: [
(
1,
UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
16.6666667,
UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
),
(
1,
UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
0.58857777,
UnitOfVolumeFlowRate.CUBIC_FEET_PER_MINUTE,
),
(
1,
UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
4.40286754,
UnitOfVolumeFlowRate.GALLONS_PER_MINUTE,
),
(
1,
UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
0.06,
UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
),
(
1,
UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
0.03531466,
UnitOfVolumeFlowRate.CUBIC_FEET_PER_MINUTE,
),
(
1,
UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
0.264172052,
UnitOfVolumeFlowRate.GALLONS_PER_MINUTE,
),
(
1,
UnitOfVolumeFlowRate.CUBIC_FEET_PER_MINUTE,
1.69901079,
UnitOfVolumeFlowRate.CUBIC_METERS_PER_HOUR,
),
(
1,
UnitOfVolumeFlowRate.CUBIC_FEET_PER_MINUTE,
28.3168465,
UnitOfVolumeFlowRate.LITERS_PER_MINUTE,
),
(
1,
UnitOfVolumeFlowRate.CUBIC_FEET_PER_MINUTE,
7.48051948,
UnitOfVolumeFlowRate.GALLONS_PER_MINUTE,
),
],
} }