Skip to content

Commit 50047f0

Browse files
authored
Add new device class for absolute humidity (home-assistant#148567)
1 parent 21b1122 commit 50047f0

File tree

14 files changed

+62
-4
lines changed

14 files changed

+62
-4
lines changed

homeassistant/components/number/const.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import voluptuous as vol
99

1010
from homeassistant.const import (
11+
CONCENTRATION_GRAMS_PER_CUBIC_METER,
1112
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
1213
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
1314
CONCENTRATION_PARTS_PER_BILLION,
@@ -78,6 +79,11 @@ class NumberDeviceClass(StrEnum):
7879
"""Device class for numbers."""
7980

8081
# NumberDeviceClass should be aligned with SensorDeviceClass
82+
ABSOLUTE_HUMIDITY = "absolute_humidity"
83+
"""Absolute humidity.
84+
85+
Unit of measurement: `g/m³`, `mg/m³`
86+
"""
8187

8288
APPARENT_POWER = "apparent_power"
8389
"""Apparent power.
@@ -452,6 +458,10 @@ class NumberDeviceClass(StrEnum):
452458

453459
DEVICE_CLASSES_SCHEMA: Final = vol.All(vol.Lower, vol.Coerce(NumberDeviceClass))
454460
DEVICE_CLASS_UNITS: dict[NumberDeviceClass, set[type[StrEnum] | str | None]] = {
461+
NumberDeviceClass.ABSOLUTE_HUMIDITY: {
462+
CONCENTRATION_GRAMS_PER_CUBIC_METER,
463+
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
464+
},
455465
NumberDeviceClass.APPARENT_POWER: set(UnitOfApparentPower),
456466
NumberDeviceClass.AQI: {None},
457467
NumberDeviceClass.AREA: set(UnitOfArea),

homeassistant/components/number/icons.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
"_": {
44
"default": "mdi:ray-vertex"
55
},
6+
"absolute_humidity": {
7+
"default": "mdi:water-opacity"
8+
},
69
"apparent_power": {
710
"default": "mdi:flash"
811
},

homeassistant/components/number/strings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
}
3232
}
3333
},
34+
"absolute_humidity": {
35+
"name": "[%key:component::sensor::entity_component::absolute_humidity::name%]"
36+
},
3437
"apparent_power": {
3538
"name": "[%key:component::sensor::entity_component::apparent_power::name%]"
3639
},

homeassistant/components/sensor/const.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import voluptuous as vol
99

1010
from homeassistant.const import (
11+
CONCENTRATION_GRAMS_PER_CUBIC_METER,
1112
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
1213
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
1314
CONCENTRATION_PARTS_PER_BILLION,
@@ -107,6 +108,12 @@ class SensorDeviceClass(StrEnum):
107108
"""
108109

109110
# Numerical device classes, these should be aligned with NumberDeviceClass
111+
ABSOLUTE_HUMIDITY = "absolute_humidity"
112+
"""Absolute humidity.
113+
114+
Unit of measurement: `g/m³`, `mg/m³`
115+
"""
116+
110117
APPARENT_POWER = "apparent_power"
111118
"""Apparent power.
112119
@@ -521,6 +528,7 @@ class SensorStateClass(StrEnum):
521528
STATE_CLASSES: Final[list[str]] = [cls.value for cls in SensorStateClass]
522529

523530
UNIT_CONVERTERS: dict[SensorDeviceClass | str | None, type[BaseUnitConverter]] = {
531+
SensorDeviceClass.ABSOLUTE_HUMIDITY: MassVolumeConcentrationConverter,
524532
SensorDeviceClass.AREA: AreaConverter,
525533
SensorDeviceClass.ATMOSPHERIC_PRESSURE: PressureConverter,
526534
SensorDeviceClass.BLOOD_GLUCOSE_CONCENTRATION: BloodGlucoseConcentrationConverter,
@@ -554,6 +562,10 @@ class SensorStateClass(StrEnum):
554562
}
555563

556564
DEVICE_CLASS_UNITS: dict[SensorDeviceClass, set[type[StrEnum] | str | None]] = {
565+
SensorDeviceClass.ABSOLUTE_HUMIDITY: {
566+
CONCENTRATION_GRAMS_PER_CUBIC_METER,
567+
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
568+
},
557569
SensorDeviceClass.APPARENT_POWER: set(UnitOfApparentPower),
558570
SensorDeviceClass.AQI: {None},
559571
SensorDeviceClass.AREA: set(UnitOfArea),
@@ -651,6 +663,7 @@ class SensorStateClass(StrEnum):
651663
# have 0 decimals, that one should be used and not mW, even though mW also should have
652664
# 0 decimals. Otherwise the smaller units will have more decimals than expected.
653665
UNITS_PRECISION = {
666+
SensorDeviceClass.ABSOLUTE_HUMIDITY: (CONCENTRATION_GRAMS_PER_CUBIC_METER, 1),
654667
SensorDeviceClass.APPARENT_POWER: (UnitOfApparentPower.VOLT_AMPERE, 0),
655668
SensorDeviceClass.AREA: (UnitOfArea.SQUARE_CENTIMETERS, 0),
656669
SensorDeviceClass.ATMOSPHERIC_PRESSURE: (UnitOfPressure.PA, 0),
@@ -691,6 +704,7 @@ class SensorStateClass(StrEnum):
691704
}
692705

693706
DEVICE_CLASS_STATE_CLASSES: dict[SensorDeviceClass, set[SensorStateClass]] = {
707+
SensorDeviceClass.ABSOLUTE_HUMIDITY: {SensorStateClass.MEASUREMENT},
694708
SensorDeviceClass.APPARENT_POWER: {SensorStateClass.MEASUREMENT},
695709
SensorDeviceClass.AQI: {SensorStateClass.MEASUREMENT},
696710
SensorDeviceClass.AREA: set(SensorStateClass),

homeassistant/components/sensor/device_condition.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
DEVICE_CLASS_NONE = "none"
3535

36+
CONF_IS_ABSOLUTE_HUMIDITY = "is_absolute_humidity"
3637
CONF_IS_APPARENT_POWER = "is_apparent_power"
3738
CONF_IS_AQI = "is_aqi"
3839
CONF_IS_AREA = "is_area"
@@ -88,6 +89,7 @@
8889
CONF_IS_WIND_SPEED = "is_wind_speed"
8990

9091
ENTITY_CONDITIONS = {
92+
SensorDeviceClass.ABSOLUTE_HUMIDITY: [{CONF_TYPE: CONF_IS_ABSOLUTE_HUMIDITY}],
9193
SensorDeviceClass.APPARENT_POWER: [{CONF_TYPE: CONF_IS_APPARENT_POWER}],
9294
SensorDeviceClass.AQI: [{CONF_TYPE: CONF_IS_AQI}],
9395
SensorDeviceClass.AREA: [{CONF_TYPE: CONF_IS_AREA}],
@@ -159,6 +161,7 @@
159161
vol.Required(CONF_ENTITY_ID): cv.entity_id_or_uuid,
160162
vol.Required(CONF_TYPE): vol.In(
161163
[
164+
CONF_IS_ABSOLUTE_HUMIDITY,
162165
CONF_IS_APPARENT_POWER,
163166
CONF_IS_AQI,
164167
CONF_IS_AREA,

homeassistant/components/sensor/device_trigger.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
DEVICE_CLASS_NONE = "none"
3434

35+
CONF_ABSOLUTE_HUMIDITY = "absolute_humidity"
3536
CONF_APPARENT_POWER = "apparent_power"
3637
CONF_AQI = "aqi"
3738
CONF_AREA = "area"
@@ -87,6 +88,7 @@
8788
CONF_WIND_SPEED = "wind_speed"
8889

8990
ENTITY_TRIGGERS = {
91+
SensorDeviceClass.ABSOLUTE_HUMIDITY: [{CONF_TYPE: CONF_ABSOLUTE_HUMIDITY}],
9092
SensorDeviceClass.APPARENT_POWER: [{CONF_TYPE: CONF_APPARENT_POWER}],
9193
SensorDeviceClass.AQI: [{CONF_TYPE: CONF_AQI}],
9294
SensorDeviceClass.AREA: [{CONF_TYPE: CONF_AREA}],
@@ -159,6 +161,7 @@
159161
vol.Required(CONF_ENTITY_ID): cv.entity_id_or_uuid,
160162
vol.Required(CONF_TYPE): vol.In(
161163
[
164+
CONF_ABSOLUTE_HUMIDITY,
162165
CONF_APPARENT_POWER,
163166
CONF_AQI,
164167
CONF_AREA,

homeassistant/components/sensor/icons.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
"_": {
44
"default": "mdi:eye"
55
},
6+
"absolute_humidity": {
7+
"default": "mdi:water-opacity"
8+
},
69
"apparent_power": {
710
"default": "mdi:flash"
811
},

homeassistant/components/sensor/strings.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"title": "Sensor",
33
"device_automation": {
44
"condition_type": {
5+
"is_absolute_humidity": "Current {entity_name} absolute humidity",
56
"is_apparent_power": "Current {entity_name} apparent power",
67
"is_aqi": "Current {entity_name} air quality index",
78
"is_area": "Current {entity_name} area",
@@ -57,6 +58,7 @@
5758
"is_wind_speed": "Current {entity_name} wind speed"
5859
},
5960
"trigger_type": {
61+
"absolute_humidity": "{entity_name} absolute humidity changes",
6062
"apparent_power": "{entity_name} apparent power changes",
6163
"aqi": "{entity_name} air quality index changes",
6264
"area": "{entity_name} area changes",
@@ -148,6 +150,9 @@
148150
"duration": {
149151
"name": "Duration"
150152
},
153+
"absolute_humidity": {
154+
"name": "Absolute humidity"
155+
},
151156
"apparent_power": {
152157
"name": "Apparent power"
153158
},

homeassistant/const.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,7 @@ class UnitOfPrecipitationDepth(StrEnum):
910910

911911

912912
# Concentration units
913+
CONCENTRATION_GRAMS_PER_CUBIC_METER: Final = "g/m³"
913914
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER: Final = "µg/m³"
914915
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER: Final = "mg/m³"
915916
CONCENTRATION_MICROGRAMS_PER_CUBIC_FOOT: Final = "μg/ft³"

homeassistant/util/unit_conversion.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from math import floor, log10
88

99
from homeassistant.const import (
10+
CONCENTRATION_GRAMS_PER_CUBIC_METER,
1011
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
1112
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
1213
CONCENTRATION_PARTS_PER_BILLION,
@@ -693,12 +694,14 @@ class MassVolumeConcentrationConverter(BaseUnitConverter):
693694

694695
UNIT_CLASS = "concentration"
695696
_UNIT_CONVERSION: dict[str | None, float] = {
696-
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER: 1000.0, # 1000 µg/m³ = 1 mg/m³
697-
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER: 1.0,
697+
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER: 1000000.0, # 1000 µg/m³ = 1 mg/m³
698+
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER: 1000.0, # 1000 mg/m³ = 1 g/m³
699+
CONCENTRATION_GRAMS_PER_CUBIC_METER: 1.0,
698700
}
699701
VALID_UNITS = {
700702
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
701703
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
704+
CONCENTRATION_GRAMS_PER_CUBIC_METER,
702705
}
703706

704707

0 commit comments

Comments
 (0)