mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Add concentration conversion support for mg/m³ (#145325)
This commit is contained in:
parent
0c9b1b5c58
commit
bca4793c69
@ -9,6 +9,7 @@ import voluptuous as vol
|
|||||||
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
|
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
|
||||||
CONCENTRATION_PARTS_PER_BILLION,
|
CONCENTRATION_PARTS_PER_BILLION,
|
||||||
CONCENTRATION_PARTS_PER_MILLION,
|
CONCENTRATION_PARTS_PER_MILLION,
|
||||||
DEGREE,
|
DEGREE,
|
||||||
@ -370,7 +371,7 @@ class NumberDeviceClass(StrEnum):
|
|||||||
VOLATILE_ORGANIC_COMPOUNDS = "volatile_organic_compounds"
|
VOLATILE_ORGANIC_COMPOUNDS = "volatile_organic_compounds"
|
||||||
"""Amount of VOC.
|
"""Amount of VOC.
|
||||||
|
|
||||||
Unit of measurement: `µg/m³`
|
Unit of measurement: `µg/m³`, `mg/m³`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
VOLATILE_ORGANIC_COMPOUNDS_PARTS = "volatile_organic_compounds_parts"
|
VOLATILE_ORGANIC_COMPOUNDS_PARTS = "volatile_organic_compounds_parts"
|
||||||
@ -517,7 +518,8 @@ DEVICE_CLASS_UNITS: dict[NumberDeviceClass, set[type[StrEnum] | str | None]] = {
|
|||||||
NumberDeviceClass.SULPHUR_DIOXIDE: {CONCENTRATION_MICROGRAMS_PER_CUBIC_METER},
|
NumberDeviceClass.SULPHUR_DIOXIDE: {CONCENTRATION_MICROGRAMS_PER_CUBIC_METER},
|
||||||
NumberDeviceClass.TEMPERATURE: set(UnitOfTemperature),
|
NumberDeviceClass.TEMPERATURE: set(UnitOfTemperature),
|
||||||
NumberDeviceClass.VOLATILE_ORGANIC_COMPOUNDS: {
|
NumberDeviceClass.VOLATILE_ORGANIC_COMPOUNDS: {
|
||||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER
|
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
|
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
|
||||||
},
|
},
|
||||||
NumberDeviceClass.VOLATILE_ORGANIC_COMPOUNDS_PARTS: {
|
NumberDeviceClass.VOLATILE_ORGANIC_COMPOUNDS_PARTS: {
|
||||||
CONCENTRATION_PARTS_PER_BILLION,
|
CONCENTRATION_PARTS_PER_BILLION,
|
||||||
|
@ -55,6 +55,7 @@ from homeassistant.util.unit_conversion import (
|
|||||||
EnergyDistanceConverter,
|
EnergyDistanceConverter,
|
||||||
InformationConverter,
|
InformationConverter,
|
||||||
MassConverter,
|
MassConverter,
|
||||||
|
MassVolumeConcentrationConverter,
|
||||||
PowerConverter,
|
PowerConverter,
|
||||||
PressureConverter,
|
PressureConverter,
|
||||||
ReactiveEnergyConverter,
|
ReactiveEnergyConverter,
|
||||||
@ -197,6 +198,9 @@ STATISTIC_UNIT_TO_UNIT_CONVERTER: dict[str | None, type[BaseUnitConverter]] = {
|
|||||||
BloodGlucoseConcentrationConverter.VALID_UNITS,
|
BloodGlucoseConcentrationConverter.VALID_UNITS,
|
||||||
BloodGlucoseConcentrationConverter,
|
BloodGlucoseConcentrationConverter,
|
||||||
),
|
),
|
||||||
|
**dict.fromkeys(
|
||||||
|
MassVolumeConcentrationConverter.VALID_UNITS, MassVolumeConcentrationConverter
|
||||||
|
),
|
||||||
**dict.fromkeys(ConductivityConverter.VALID_UNITS, ConductivityConverter),
|
**dict.fromkeys(ConductivityConverter.VALID_UNITS, ConductivityConverter),
|
||||||
**dict.fromkeys(DataRateConverter.VALID_UNITS, DataRateConverter),
|
**dict.fromkeys(DataRateConverter.VALID_UNITS, DataRateConverter),
|
||||||
**dict.fromkeys(DistanceConverter.VALID_UNITS, DistanceConverter),
|
**dict.fromkeys(DistanceConverter.VALID_UNITS, DistanceConverter),
|
||||||
|
@ -28,6 +28,7 @@ from homeassistant.util.unit_conversion import (
|
|||||||
EnergyDistanceConverter,
|
EnergyDistanceConverter,
|
||||||
InformationConverter,
|
InformationConverter,
|
||||||
MassConverter,
|
MassConverter,
|
||||||
|
MassVolumeConcentrationConverter,
|
||||||
PowerConverter,
|
PowerConverter,
|
||||||
PressureConverter,
|
PressureConverter,
|
||||||
ReactiveEnergyConverter,
|
ReactiveEnergyConverter,
|
||||||
@ -62,6 +63,9 @@ UNIT_SCHEMA = vol.Schema(
|
|||||||
vol.Optional("blood_glucose_concentration"): vol.In(
|
vol.Optional("blood_glucose_concentration"): vol.In(
|
||||||
BloodGlucoseConcentrationConverter.VALID_UNITS
|
BloodGlucoseConcentrationConverter.VALID_UNITS
|
||||||
),
|
),
|
||||||
|
vol.Optional("concentration"): vol.In(
|
||||||
|
MassVolumeConcentrationConverter.VALID_UNITS
|
||||||
|
),
|
||||||
vol.Optional("conductivity"): vol.In(ConductivityConverter.VALID_UNITS),
|
vol.Optional("conductivity"): vol.In(ConductivityConverter.VALID_UNITS),
|
||||||
vol.Optional("data_rate"): vol.In(DataRateConverter.VALID_UNITS),
|
vol.Optional("data_rate"): vol.In(DataRateConverter.VALID_UNITS),
|
||||||
vol.Optional("distance"): vol.In(DistanceConverter.VALID_UNITS),
|
vol.Optional("distance"): vol.In(DistanceConverter.VALID_UNITS),
|
||||||
|
@ -9,6 +9,7 @@ import voluptuous as vol
|
|||||||
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
|
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
|
||||||
CONCENTRATION_PARTS_PER_BILLION,
|
CONCENTRATION_PARTS_PER_BILLION,
|
||||||
CONCENTRATION_PARTS_PER_MILLION,
|
CONCENTRATION_PARTS_PER_MILLION,
|
||||||
DEGREE,
|
DEGREE,
|
||||||
@ -57,6 +58,7 @@ from homeassistant.util.unit_conversion import (
|
|||||||
EnergyDistanceConverter,
|
EnergyDistanceConverter,
|
||||||
InformationConverter,
|
InformationConverter,
|
||||||
MassConverter,
|
MassConverter,
|
||||||
|
MassVolumeConcentrationConverter,
|
||||||
PowerConverter,
|
PowerConverter,
|
||||||
PressureConverter,
|
PressureConverter,
|
||||||
ReactiveEnergyConverter,
|
ReactiveEnergyConverter,
|
||||||
@ -400,7 +402,7 @@ class SensorDeviceClass(StrEnum):
|
|||||||
VOLATILE_ORGANIC_COMPOUNDS = "volatile_organic_compounds"
|
VOLATILE_ORGANIC_COMPOUNDS = "volatile_organic_compounds"
|
||||||
"""Amount of VOC.
|
"""Amount of VOC.
|
||||||
|
|
||||||
Unit of measurement: `µg/m³`
|
Unit of measurement: `µg/m³`, `mg/m³`
|
||||||
"""
|
"""
|
||||||
|
|
||||||
VOLATILE_ORGANIC_COMPOUNDS_PARTS = "volatile_organic_compounds_parts"
|
VOLATILE_ORGANIC_COMPOUNDS_PARTS = "volatile_organic_compounds_parts"
|
||||||
@ -540,6 +542,7 @@ UNIT_CONVERTERS: dict[SensorDeviceClass | str | None, type[BaseUnitConverter]] =
|
|||||||
SensorDeviceClass.REACTIVE_ENERGY: ReactiveEnergyConverter,
|
SensorDeviceClass.REACTIVE_ENERGY: ReactiveEnergyConverter,
|
||||||
SensorDeviceClass.SPEED: SpeedConverter,
|
SensorDeviceClass.SPEED: SpeedConverter,
|
||||||
SensorDeviceClass.TEMPERATURE: TemperatureConverter,
|
SensorDeviceClass.TEMPERATURE: TemperatureConverter,
|
||||||
|
SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS: MassVolumeConcentrationConverter,
|
||||||
SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS_PARTS: UnitlessRatioConverter,
|
SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS_PARTS: UnitlessRatioConverter,
|
||||||
SensorDeviceClass.VOLTAGE: ElectricPotentialConverter,
|
SensorDeviceClass.VOLTAGE: ElectricPotentialConverter,
|
||||||
SensorDeviceClass.VOLUME: VolumeConverter,
|
SensorDeviceClass.VOLUME: VolumeConverter,
|
||||||
@ -617,7 +620,8 @@ DEVICE_CLASS_UNITS: dict[SensorDeviceClass, set[type[StrEnum] | str | None]] = {
|
|||||||
SensorDeviceClass.SULPHUR_DIOXIDE: {CONCENTRATION_MICROGRAMS_PER_CUBIC_METER},
|
SensorDeviceClass.SULPHUR_DIOXIDE: {CONCENTRATION_MICROGRAMS_PER_CUBIC_METER},
|
||||||
SensorDeviceClass.TEMPERATURE: set(UnitOfTemperature),
|
SensorDeviceClass.TEMPERATURE: set(UnitOfTemperature),
|
||||||
SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS: {
|
SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS: {
|
||||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER
|
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
|
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
|
||||||
},
|
},
|
||||||
SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS_PARTS: {
|
SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS_PARTS: {
|
||||||
CONCENTRATION_PARTS_PER_BILLION,
|
CONCENTRATION_PARTS_PER_BILLION,
|
||||||
|
@ -7,6 +7,8 @@ from functools import lru_cache
|
|||||||
from math import floor, log10
|
from math import floor, log10
|
||||||
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
|
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
|
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
|
||||||
CONCENTRATION_PARTS_PER_BILLION,
|
CONCENTRATION_PARTS_PER_BILLION,
|
||||||
CONCENTRATION_PARTS_PER_MILLION,
|
CONCENTRATION_PARTS_PER_MILLION,
|
||||||
PERCENTAGE,
|
PERCENTAGE,
|
||||||
@ -686,6 +688,20 @@ class UnitlessRatioConverter(BaseUnitConverter):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class MassVolumeConcentrationConverter(BaseUnitConverter):
|
||||||
|
"""Utility to convert mass volume concentration values."""
|
||||||
|
|
||||||
|
UNIT_CLASS = "concentration"
|
||||||
|
_UNIT_CONVERSION: dict[str | None, float] = {
|
||||||
|
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER: 1000.0, # 1000 µg/m³ = 1 mg/m³
|
||||||
|
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER: 1.0,
|
||||||
|
}
|
||||||
|
VALID_UNITS = {
|
||||||
|
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
|
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class VolumeConverter(BaseUnitConverter):
|
class VolumeConverter(BaseUnitConverter):
|
||||||
"""Utility to convert volume values."""
|
"""Utility to convert volume values."""
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@ from itertools import chain
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
|
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
|
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
|
||||||
CONCENTRATION_PARTS_PER_BILLION,
|
CONCENTRATION_PARTS_PER_BILLION,
|
||||||
CONCENTRATION_PARTS_PER_MILLION,
|
CONCENTRATION_PARTS_PER_MILLION,
|
||||||
PERCENTAGE,
|
PERCENTAGE,
|
||||||
@ -48,6 +50,7 @@ from homeassistant.util.unit_conversion import (
|
|||||||
EnergyDistanceConverter,
|
EnergyDistanceConverter,
|
||||||
InformationConverter,
|
InformationConverter,
|
||||||
MassConverter,
|
MassConverter,
|
||||||
|
MassVolumeConcentrationConverter,
|
||||||
PowerConverter,
|
PowerConverter,
|
||||||
PressureConverter,
|
PressureConverter,
|
||||||
ReactiveEnergyConverter,
|
ReactiveEnergyConverter,
|
||||||
@ -69,6 +72,7 @@ _ALL_CONVERTERS: dict[type[BaseUnitConverter], list[str | None]] = {
|
|||||||
for converter in (
|
for converter in (
|
||||||
AreaConverter,
|
AreaConverter,
|
||||||
BloodGlucoseConcentrationConverter,
|
BloodGlucoseConcentrationConverter,
|
||||||
|
MassVolumeConcentrationConverter,
|
||||||
ConductivityConverter,
|
ConductivityConverter,
|
||||||
DataRateConverter,
|
DataRateConverter,
|
||||||
DistanceConverter,
|
DistanceConverter,
|
||||||
@ -128,6 +132,11 @@ _GET_UNIT_RATIO: dict[type[BaseUnitConverter], tuple[str | None, str | None, flo
|
|||||||
),
|
),
|
||||||
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),
|
||||||
|
MassVolumeConcentrationConverter: (
|
||||||
|
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
|
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
|
||||||
|
1000,
|
||||||
|
),
|
||||||
PowerConverter: (UnitOfPower.WATT, UnitOfPower.KILO_WATT, 1000),
|
PowerConverter: (UnitOfPower.WATT, UnitOfPower.KILO_WATT, 1000),
|
||||||
PressureConverter: (UnitOfPressure.HPA, UnitOfPressure.INHG, 33.86389),
|
PressureConverter: (UnitOfPressure.HPA, UnitOfPressure.INHG, 33.86389),
|
||||||
ReactiveEnergyConverter: (
|
ReactiveEnergyConverter: (
|
||||||
@ -738,6 +747,22 @@ _CONVERTED_VALUE: dict[
|
|||||||
(5, None, 5000000, CONCENTRATION_PARTS_PER_MILLION),
|
(5, None, 5000000, CONCENTRATION_PARTS_PER_MILLION),
|
||||||
(5, PERCENTAGE, 0.05, None),
|
(5, PERCENTAGE, 0.05, None),
|
||||||
],
|
],
|
||||||
|
MassVolumeConcentrationConverter: [
|
||||||
|
# 1000 µg/m³ = 1 mg/m³
|
||||||
|
(
|
||||||
|
1000,
|
||||||
|
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
|
1,
|
||||||
|
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
|
||||||
|
),
|
||||||
|
# 2 mg/m³ = 2000 µg/m³
|
||||||
|
(
|
||||||
|
2,
|
||||||
|
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
|
||||||
|
2000,
|
||||||
|
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||||
|
),
|
||||||
|
],
|
||||||
VolumeConverter: [
|
VolumeConverter: [
|
||||||
(5, UnitOfVolume.LITERS, 1.32086, UnitOfVolume.GALLONS),
|
(5, UnitOfVolume.LITERS, 1.32086, UnitOfVolume.GALLONS),
|
||||||
(5, UnitOfVolume.GALLONS, 18.92706, UnitOfVolume.LITERS),
|
(5, UnitOfVolume.GALLONS, 18.92706, UnitOfVolume.LITERS),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user