Skip to content

Commit 5eef6ed

Browse files
authored
Add mg/m³ as a valid UOM for sensor/number Carbon Monoxide device class (home-assistant#152456)
1 parent db72927 commit 5eef6ed

File tree

7 files changed

+56
-5
lines changed

7 files changed

+56
-5
lines changed

homeassistant/components/number/const.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class NumberDeviceClass(StrEnum):
124124
CO = "carbon_monoxide"
125125
"""Carbon Monoxide gas concentration.
126126
127-
Unit of measurement: `ppm` (parts per million)
127+
Unit of measurement: `ppm` (parts per million), mg/m³
128128
"""
129129

130130
CO2 = "carbon_dioxide"
@@ -469,7 +469,10 @@ class NumberDeviceClass(StrEnum):
469469
NumberDeviceClass.ATMOSPHERIC_PRESSURE: set(UnitOfPressure),
470470
NumberDeviceClass.BATTERY: {PERCENTAGE},
471471
NumberDeviceClass.BLOOD_GLUCOSE_CONCENTRATION: set(UnitOfBloodGlucoseConcentration),
472-
NumberDeviceClass.CO: {CONCENTRATION_PARTS_PER_MILLION},
472+
NumberDeviceClass.CO: {
473+
CONCENTRATION_PARTS_PER_MILLION,
474+
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
475+
},
473476
NumberDeviceClass.CO2: {CONCENTRATION_PARTS_PER_MILLION},
474477
NumberDeviceClass.CONDUCTIVITY: set(UnitOfConductivity),
475478
NumberDeviceClass.CURRENT: set(UnitOfElectricCurrent),

homeassistant/components/recorder/statistics.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
AreaConverter,
4747
BaseUnitConverter,
4848
BloodGlucoseConcentrationConverter,
49+
CarbonMonoxideConcentrationConverter,
4950
ConductivityConverter,
5051
DataRateConverter,
5152
DistanceConverter,
@@ -204,6 +205,10 @@ def query_circular_mean(table: type[StatisticsBase]) -> tuple[Label, Label]:
204205
**dict.fromkeys(
205206
MassVolumeConcentrationConverter.VALID_UNITS, MassVolumeConcentrationConverter
206207
),
208+
**dict.fromkeys(
209+
CarbonMonoxideConcentrationConverter.VALID_UNITS,
210+
CarbonMonoxideConcentrationConverter,
211+
),
207212
**dict.fromkeys(ConductivityConverter.VALID_UNITS, ConductivityConverter),
208213
**dict.fromkeys(DataRateConverter.VALID_UNITS, DataRateConverter),
209214
**dict.fromkeys(DistanceConverter.VALID_UNITS, DistanceConverter),

homeassistant/components/recorder/websocket_api.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
ApparentPowerConverter,
2020
AreaConverter,
2121
BloodGlucoseConcentrationConverter,
22+
CarbonMonoxideConcentrationConverter,
2223
ConductivityConverter,
2324
DataRateConverter,
2425
DistanceConverter,
@@ -66,6 +67,9 @@
6667
vol.Optional("blood_glucose_concentration"): vol.In(
6768
BloodGlucoseConcentrationConverter.VALID_UNITS
6869
),
70+
vol.Optional("carbon_monoxide"): vol.In(
71+
CarbonMonoxideConcentrationConverter.VALID_UNITS
72+
),
6973
vol.Optional("concentration"): vol.In(
7074
MassVolumeConcentrationConverter.VALID_UNITS
7175
),

homeassistant/components/sensor/const.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
AreaConverter,
5252
BaseUnitConverter,
5353
BloodGlucoseConcentrationConverter,
54+
CarbonMonoxideConcentrationConverter,
5455
ConductivityConverter,
5556
DataRateConverter,
5657
DistanceConverter,
@@ -156,7 +157,7 @@ class SensorDeviceClass(StrEnum):
156157
CO = "carbon_monoxide"
157158
"""Carbon Monoxide gas concentration.
158159
159-
Unit of measurement: `ppm` (parts per million)
160+
Unit of measurement: `ppm` (parts per million), `mg/m³`
160161
"""
161162

162163
CO2 = "carbon_dioxide"
@@ -537,6 +538,7 @@ class SensorStateClass(StrEnum):
537538
SensorDeviceClass.AREA: AreaConverter,
538539
SensorDeviceClass.ATMOSPHERIC_PRESSURE: PressureConverter,
539540
SensorDeviceClass.BLOOD_GLUCOSE_CONCENTRATION: BloodGlucoseConcentrationConverter,
541+
SensorDeviceClass.CO: CarbonMonoxideConcentrationConverter,
540542
SensorDeviceClass.CONDUCTIVITY: ConductivityConverter,
541543
SensorDeviceClass.CURRENT: ElectricCurrentConverter,
542544
SensorDeviceClass.DATA_RATE: DataRateConverter,
@@ -578,7 +580,10 @@ class SensorStateClass(StrEnum):
578580
SensorDeviceClass.ATMOSPHERIC_PRESSURE: set(UnitOfPressure),
579581
SensorDeviceClass.BATTERY: {PERCENTAGE},
580582
SensorDeviceClass.BLOOD_GLUCOSE_CONCENTRATION: set(UnitOfBloodGlucoseConcentration),
581-
SensorDeviceClass.CO: {CONCENTRATION_PARTS_PER_MILLION},
583+
SensorDeviceClass.CO: {
584+
CONCENTRATION_PARTS_PER_MILLION,
585+
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
586+
},
582587
SensorDeviceClass.CO2: {CONCENTRATION_PARTS_PER_MILLION},
583588
SensorDeviceClass.CONDUCTIVITY: set(UnitOfConductivity),
584589
SensorDeviceClass.CURRENT: set(UnitOfElectricCurrent),

homeassistant/util/unit_conversion.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,20 @@ def _are_unit_inverses(cls, from_unit: str | None, to_unit: str | None) -> bool:
168168
return (from_unit in cls._UNIT_INVERSES) != (to_unit in cls._UNIT_INVERSES)
169169

170170

171+
class CarbonMonoxideConcentrationConverter(BaseUnitConverter):
172+
"""Convert carbon monoxide ratio to mass per volume."""
173+
174+
UNIT_CLASS = "carbon_monoxide"
175+
_UNIT_CONVERSION: dict[str | None, float] = {
176+
CONCENTRATION_PARTS_PER_MILLION: 1,
177+
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER: 1.145609,
178+
}
179+
VALID_UNITS = {
180+
CONCENTRATION_PARTS_PER_MILLION,
181+
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
182+
}
183+
184+
171185
class DataRateConverter(BaseUnitConverter):
172186
"""Utility to convert data rate values."""
173187

tests/components/sensor/test_init.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3007,7 +3007,6 @@ def test_device_class_converters_are_complete() -> None:
30073007
no_converter_device_classes = {
30083008
SensorDeviceClass.AQI,
30093009
SensorDeviceClass.BATTERY,
3010-
SensorDeviceClass.CO,
30113010
SensorDeviceClass.CO2,
30123011
SensorDeviceClass.DATE,
30133012
SensorDeviceClass.ENUM,

tests/util/test_unit_conversion.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
AreaConverter,
4545
BaseUnitConverter,
4646
BloodGlucoseConcentrationConverter,
47+
CarbonMonoxideConcentrationConverter,
4748
ConductivityConverter,
4849
DataRateConverter,
4950
DistanceConverter,
@@ -78,6 +79,7 @@
7879
AreaConverter,
7980
BloodGlucoseConcentrationConverter,
8081
MassVolumeConcentrationConverter,
82+
CarbonMonoxideConcentrationConverter,
8183
ConductivityConverter,
8284
DataRateConverter,
8385
DistanceConverter,
@@ -114,6 +116,11 @@
114116
UnitOfBloodGlucoseConcentration.MILLIMOLE_PER_LITER,
115117
18,
116118
),
119+
CarbonMonoxideConcentrationConverter: (
120+
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
121+
CONCENTRATION_PARTS_PER_MILLION,
122+
1.145609,
123+
),
117124
ConductivityConverter: (
118125
UnitOfConductivity.MICROSIEMENS_PER_CM,
119126
UnitOfConductivity.MILLISIEMENS_PER_CM,
@@ -280,6 +287,20 @@
280287
UnitOfBloodGlucoseConcentration.MILLIGRAMS_PER_DECILITER,
281288
),
282289
],
290+
CarbonMonoxideConcentrationConverter: [
291+
(
292+
1,
293+
CONCENTRATION_PARTS_PER_MILLION,
294+
1.145609,
295+
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
296+
),
297+
(
298+
120,
299+
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
300+
104.74778,
301+
CONCENTRATION_PARTS_PER_MILLION,
302+
),
303+
],
283304
ConductivityConverter: [
284305
# Deprecated to deprecated
285306
(5, UnitOfConductivity.SIEMENS, 5e3, UnitOfConductivity.MILLISIEMENS),

0 commit comments

Comments
 (0)