From 69ce6980d6e4ebab73907a0a7094f28cf37f38bd Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Tue, 28 Feb 2023 19:35:43 +0100 Subject: [PATCH] Add number + sensor device class energy storage (#88310) * Add number + sensor device class energy storage * Format code * Update device automations --- homeassistant/components/number/const.py | 10 ++++++++++ homeassistant/components/sensor/const.py | 14 ++++++++++++++ .../components/sensor/device_condition.py | 1 + homeassistant/components/sensor/device_trigger.py | 1 + tests/components/sensor/test_device_condition.py | 2 ++ tests/components/sensor/test_device_trigger.py | 2 ++ 6 files changed, 30 insertions(+) diff --git a/homeassistant/components/number/const.py b/homeassistant/components/number/const.py index 91c1306c226..aa57bb2b716 100644 --- a/homeassistant/components/number/const.py +++ b/homeassistant/components/number/const.py @@ -127,6 +127,15 @@ class NumberDeviceClass(StrEnum): Unit of measurement: `Wh`, `kWh`, `MWh`, `MJ`, `GJ` """ + ENERGY_STORAGE = "energy_storage" + """Stored energy. + + Use this device class for sensors measuring stored energy, for example the amount + of electric energy currently stored in a battery or the capacity of a battery. + + Unit of measurement: `Wh`, `kWh`, `MWh`, `MJ`, `GJ` + """ + FREQUENCY = "frequency" """Frequency. @@ -365,6 +374,7 @@ DEVICE_CLASS_UNITS: dict[NumberDeviceClass, set[type[StrEnum] | str | None]] = { NumberDeviceClass.DATA_SIZE: set(UnitOfInformation), NumberDeviceClass.DISTANCE: set(UnitOfLength), NumberDeviceClass.ENERGY: set(UnitOfEnergy), + NumberDeviceClass.ENERGY_STORAGE: set(UnitOfEnergy), NumberDeviceClass.FREQUENCY: set(UnitOfFrequency), NumberDeviceClass.GAS: { UnitOfVolume.CENTUM_CUBIC_FEET, diff --git a/homeassistant/components/sensor/const.py b/homeassistant/components/sensor/const.py index 58cf985b09f..8ded1c304da 100644 --- a/homeassistant/components/sensor/const.py +++ b/homeassistant/components/sensor/const.py @@ -160,6 +160,17 @@ class SensorDeviceClass(StrEnum): ENERGY = "energy" """Energy. + Use this device class for sensors measuring energy consumption, for example + electric energy consumption. + Unit of measurement: `Wh`, `kWh`, `MWh`, `MJ`, `GJ` + """ + + ENERGY_STORAGE = "energy_storage" + """Stored energy. + + Use this device class for sensors measuring stored energy, for example the amount + of electric energy currently stored in a battery or the capacity of a battery. + Unit of measurement: `Wh`, `kWh`, `MWh`, `MJ`, `GJ` """ @@ -429,6 +440,7 @@ UNIT_CONVERTERS: dict[SensorDeviceClass | str | None, type[BaseUnitConverter]] = SensorDeviceClass.DATA_SIZE: InformationConverter, SensorDeviceClass.DISTANCE: DistanceConverter, SensorDeviceClass.ENERGY: EnergyConverter, + SensorDeviceClass.ENERGY_STORAGE: EnergyConverter, SensorDeviceClass.GAS: VolumeConverter, SensorDeviceClass.POWER: PowerConverter, SensorDeviceClass.POWER_FACTOR: UnitlessRatioConverter, @@ -462,6 +474,7 @@ DEVICE_CLASS_UNITS: dict[SensorDeviceClass, set[type[StrEnum] | str | None]] = { UnitOfTime.SECONDS, }, SensorDeviceClass.ENERGY: set(UnitOfEnergy), + SensorDeviceClass.ENERGY_STORAGE: set(UnitOfEnergy), SensorDeviceClass.FREQUENCY: set(UnitOfFrequency), SensorDeviceClass.GAS: { UnitOfVolume.CENTUM_CUBIC_FEET, @@ -526,6 +539,7 @@ DEVICE_CLASS_STATE_CLASSES: dict[SensorDeviceClass, set[SensorStateClass]] = { SensorStateClass.TOTAL, SensorStateClass.TOTAL_INCREASING, }, + SensorDeviceClass.ENERGY_STORAGE: {SensorStateClass.MEASUREMENT}, SensorDeviceClass.ENUM: set(), SensorDeviceClass.FREQUENCY: {SensorStateClass.MEASUREMENT}, SensorDeviceClass.GAS: {SensorStateClass.TOTAL, SensorStateClass.TOTAL_INCREASING}, diff --git a/homeassistant/components/sensor/device_condition.py b/homeassistant/components/sensor/device_condition.py index 5746b8b8e8c..6ed47cbf63e 100644 --- a/homeassistant/components/sensor/device_condition.py +++ b/homeassistant/components/sensor/device_condition.py @@ -89,6 +89,7 @@ ENTITY_CONDITIONS = { SensorDeviceClass.DISTANCE: [{CONF_TYPE: CONF_IS_DISTANCE}], SensorDeviceClass.DURATION: [{CONF_TYPE: CONF_IS_DURATION}], SensorDeviceClass.ENERGY: [{CONF_TYPE: CONF_IS_ENERGY}], + SensorDeviceClass.ENERGY_STORAGE: [{CONF_TYPE: CONF_IS_ENERGY}], SensorDeviceClass.FREQUENCY: [{CONF_TYPE: CONF_IS_FREQUENCY}], SensorDeviceClass.GAS: [{CONF_TYPE: CONF_IS_GAS}], SensorDeviceClass.HUMIDITY: [{CONF_TYPE: CONF_IS_HUMIDITY}], diff --git a/homeassistant/components/sensor/device_trigger.py b/homeassistant/components/sensor/device_trigger.py index dfd0a576d21..7e498321b3e 100644 --- a/homeassistant/components/sensor/device_trigger.py +++ b/homeassistant/components/sensor/device_trigger.py @@ -88,6 +88,7 @@ ENTITY_TRIGGERS = { SensorDeviceClass.DISTANCE: [{CONF_TYPE: CONF_DISTANCE}], SensorDeviceClass.DURATION: [{CONF_TYPE: CONF_DURATION}], SensorDeviceClass.ENERGY: [{CONF_TYPE: CONF_ENERGY}], + SensorDeviceClass.ENERGY_STORAGE: [{CONF_TYPE: CONF_ENERGY}], SensorDeviceClass.FREQUENCY: [{CONF_TYPE: CONF_FREQUENCY}], SensorDeviceClass.GAS: [{CONF_TYPE: CONF_GAS}], SensorDeviceClass.HUMIDITY: [{CONF_TYPE: CONF_HUMIDITY}], diff --git a/tests/components/sensor/test_device_condition.py b/tests/components/sensor/test_device_condition.py index 02b369b6a67..24d480e24b3 100644 --- a/tests/components/sensor/test_device_condition.py +++ b/tests/components/sensor/test_device_condition.py @@ -51,12 +51,14 @@ def test_matches_device_classes(device_class: SensorDeviceClass) -> None: SensorDeviceClass.BATTERY: "CONF_IS_BATTERY_LEVEL", SensorDeviceClass.CO: "CONF_IS_CO", SensorDeviceClass.CO2: "CONF_IS_CO2", + SensorDeviceClass.ENERGY_STORAGE: "CONF_IS_ENERGY", }.get(device_class, f"CONF_IS_{device_class.value.upper()}") assert hasattr(device_condition, constant_name), f"Missing constant {constant_name}" # Ensure it has correct value constant_value = { SensorDeviceClass.BATTERY: "is_battery_level", + SensorDeviceClass.ENERGY_STORAGE: "is_energy", }.get(device_class, f"is_{device_class.value}") assert getattr(device_condition, constant_name) == constant_value diff --git a/tests/components/sensor/test_device_trigger.py b/tests/components/sensor/test_device_trigger.py index 298aab2953a..34b5d6fb40f 100644 --- a/tests/components/sensor/test_device_trigger.py +++ b/tests/components/sensor/test_device_trigger.py @@ -55,12 +55,14 @@ def test_matches_device_classes(device_class: SensorDeviceClass) -> None: SensorDeviceClass.BATTERY: "CONF_BATTERY_LEVEL", SensorDeviceClass.CO: "CONF_CO", SensorDeviceClass.CO2: "CONF_CO2", + SensorDeviceClass.ENERGY_STORAGE: "CONF_ENERGY", }.get(device_class, f"CONF_{device_class.value.upper()}") assert hasattr(device_trigger, constant_name), f"Missing constant {constant_name}" # Ensure it has correct value constant_value = { SensorDeviceClass.BATTERY: "battery_level", + SensorDeviceClass.ENERGY_STORAGE: "energy", }.get(device_class, device_class.value) assert getattr(device_trigger, constant_name) == constant_value