Add reactive energy device class and units (#143941)

This commit is contained in:
alorente 2025-05-15 13:05:46 +02:00 committed by GitHub
parent 66ecc4d69d
commit 1d47dc41c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 96 additions and 2 deletions

View File

@ -33,6 +33,7 @@ from homeassistant.const import (
UnitOfPower, UnitOfPower,
UnitOfPrecipitationDepth, UnitOfPrecipitationDepth,
UnitOfPressure, UnitOfPressure,
UnitOfReactiveEnergy,
UnitOfReactivePower, UnitOfReactivePower,
UnitOfSoundPressure, UnitOfSoundPressure,
UnitOfSpeed, UnitOfSpeed,
@ -44,6 +45,7 @@ from homeassistant.const import (
) )
from homeassistant.util.unit_conversion import ( from homeassistant.util.unit_conversion import (
BaseUnitConverter, BaseUnitConverter,
ReactiveEnergyConverter,
TemperatureConverter, TemperatureConverter,
VolumeFlowRateConverter, VolumeFlowRateConverter,
) )
@ -320,6 +322,12 @@ class NumberDeviceClass(StrEnum):
- `psi` - `psi`
""" """
REACTIVE_ENERGY = "reactive_energy"
"""Reactive energy.
Unit of measurement: `varh`, `kvarh`
"""
REACTIVE_POWER = "reactive_power" REACTIVE_POWER = "reactive_power"
"""Reactive power. """Reactive power.
@ -498,6 +506,7 @@ DEVICE_CLASS_UNITS: dict[NumberDeviceClass, set[type[StrEnum] | str | None]] = {
NumberDeviceClass.PRECIPITATION: set(UnitOfPrecipitationDepth), NumberDeviceClass.PRECIPITATION: set(UnitOfPrecipitationDepth),
NumberDeviceClass.PRECIPITATION_INTENSITY: set(UnitOfVolumetricFlux), NumberDeviceClass.PRECIPITATION_INTENSITY: set(UnitOfVolumetricFlux),
NumberDeviceClass.PRESSURE: set(UnitOfPressure), NumberDeviceClass.PRESSURE: set(UnitOfPressure),
NumberDeviceClass.REACTIVE_ENERGY: set(UnitOfReactiveEnergy),
NumberDeviceClass.REACTIVE_POWER: set(UnitOfReactivePower), NumberDeviceClass.REACTIVE_POWER: set(UnitOfReactivePower),
NumberDeviceClass.SIGNAL_STRENGTH: { NumberDeviceClass.SIGNAL_STRENGTH: {
SIGNAL_STRENGTH_DECIBELS, SIGNAL_STRENGTH_DECIBELS,
@ -531,6 +540,7 @@ DEVICE_CLASS_UNITS: dict[NumberDeviceClass, set[type[StrEnum] | str | None]] = {
} }
UNIT_CONVERTERS: dict[NumberDeviceClass, type[BaseUnitConverter]] = { UNIT_CONVERTERS: dict[NumberDeviceClass, type[BaseUnitConverter]] = {
NumberDeviceClass.REACTIVE_ENERGY: ReactiveEnergyConverter,
NumberDeviceClass.TEMPERATURE: TemperatureConverter, NumberDeviceClass.TEMPERATURE: TemperatureConverter,
NumberDeviceClass.VOLUME_FLOW_RATE: VolumeFlowRateConverter, NumberDeviceClass.VOLUME_FLOW_RATE: VolumeFlowRateConverter,
} }

View File

@ -111,6 +111,9 @@
"pressure": { "pressure": {
"default": "mdi:gauge" "default": "mdi:gauge"
}, },
"reactive_energy": {
"default": "mdi:lightning-bolt"
},
"reactive_power": { "reactive_power": {
"default": "mdi:flash" "default": "mdi:flash"
}, },

View File

@ -130,6 +130,9 @@
"pressure": { "pressure": {
"name": "[%key:component::sensor::entity_component::pressure::name%]" "name": "[%key:component::sensor::entity_component::pressure::name%]"
}, },
"reactive_energy": {
"name": "[%key:component::sensor::entity_component::reactive_energy::name%]"
},
"reactive_power": { "reactive_power": {
"name": "[%key:component::sensor::entity_component::reactive_power::name%]" "name": "[%key:component::sensor::entity_component::reactive_power::name%]"
}, },

View File

@ -120,6 +120,7 @@
"precipitation": "[%key:component::sensor::entity_component::precipitation::name%]", "precipitation": "[%key:component::sensor::entity_component::precipitation::name%]",
"precipitation_intensity": "[%key:component::sensor::entity_component::precipitation_intensity::name%]", "precipitation_intensity": "[%key:component::sensor::entity_component::precipitation_intensity::name%]",
"pressure": "[%key:component::sensor::entity_component::pressure::name%]", "pressure": "[%key:component::sensor::entity_component::pressure::name%]",
"reactive_energy": "[%key:component::sensor::entity_component::reactive_energy::name%]",
"reactive_power": "[%key:component::sensor::entity_component::reactive_power::name%]", "reactive_power": "[%key:component::sensor::entity_component::reactive_power::name%]",
"signal_strength": "[%key:component::sensor::entity_component::signal_strength::name%]", "signal_strength": "[%key:component::sensor::entity_component::signal_strength::name%]",
"sound_pressure": "[%key:component::sensor::entity_component::sound_pressure::name%]", "sound_pressure": "[%key:component::sensor::entity_component::sound_pressure::name%]",

View File

@ -57,6 +57,7 @@ from homeassistant.util.unit_conversion import (
MassConverter, MassConverter,
PowerConverter, PowerConverter,
PressureConverter, PressureConverter,
ReactiveEnergyConverter,
SpeedConverter, SpeedConverter,
TemperatureConverter, TemperatureConverter,
UnitlessRatioConverter, UnitlessRatioConverter,
@ -208,6 +209,7 @@ STATISTIC_UNIT_TO_UNIT_CONVERTER: dict[str | None, type[BaseUnitConverter]] = {
**dict.fromkeys(MassConverter.VALID_UNITS, MassConverter), **dict.fromkeys(MassConverter.VALID_UNITS, MassConverter),
**dict.fromkeys(PowerConverter.VALID_UNITS, PowerConverter), **dict.fromkeys(PowerConverter.VALID_UNITS, PowerConverter),
**dict.fromkeys(PressureConverter.VALID_UNITS, PressureConverter), **dict.fromkeys(PressureConverter.VALID_UNITS, PressureConverter),
**dict.fromkeys(ReactiveEnergyConverter.VALID_UNITS, ReactiveEnergyConverter),
**dict.fromkeys(SpeedConverter.VALID_UNITS, SpeedConverter), **dict.fromkeys(SpeedConverter.VALID_UNITS, SpeedConverter),
**dict.fromkeys(TemperatureConverter.VALID_UNITS, TemperatureConverter), **dict.fromkeys(TemperatureConverter.VALID_UNITS, TemperatureConverter),
**dict.fromkeys(UnitlessRatioConverter.VALID_UNITS, UnitlessRatioConverter), **dict.fromkeys(UnitlessRatioConverter.VALID_UNITS, UnitlessRatioConverter),

View File

@ -33,6 +33,7 @@ from homeassistant.const import (
UnitOfPower, UnitOfPower,
UnitOfPrecipitationDepth, UnitOfPrecipitationDepth,
UnitOfPressure, UnitOfPressure,
UnitOfReactiveEnergy,
UnitOfReactivePower, UnitOfReactivePower,
UnitOfSoundPressure, UnitOfSoundPressure,
UnitOfSpeed, UnitOfSpeed,
@ -58,6 +59,7 @@ from homeassistant.util.unit_conversion import (
MassConverter, MassConverter,
PowerConverter, PowerConverter,
PressureConverter, PressureConverter,
ReactiveEnergyConverter,
SpeedConverter, SpeedConverter,
TemperatureConverter, TemperatureConverter,
UnitlessRatioConverter, UnitlessRatioConverter,
@ -349,6 +351,12 @@ class SensorDeviceClass(StrEnum):
- `psi` - `psi`
""" """
REACTIVE_ENERGY = "reactive_energy"
"""Reactive energy.
Unit of measurement: `varh`, `kvarh`
"""
REACTIVE_POWER = "reactive_power" REACTIVE_POWER = "reactive_power"
"""Reactive power. """Reactive power.
@ -529,6 +537,7 @@ UNIT_CONVERTERS: dict[SensorDeviceClass | str | None, type[BaseUnitConverter]] =
SensorDeviceClass.PRECIPITATION: DistanceConverter, SensorDeviceClass.PRECIPITATION: DistanceConverter,
SensorDeviceClass.PRECIPITATION_INTENSITY: SpeedConverter, SensorDeviceClass.PRECIPITATION_INTENSITY: SpeedConverter,
SensorDeviceClass.PRESSURE: PressureConverter, SensorDeviceClass.PRESSURE: PressureConverter,
SensorDeviceClass.REACTIVE_ENERGY: ReactiveEnergyConverter,
SensorDeviceClass.SPEED: SpeedConverter, SensorDeviceClass.SPEED: SpeedConverter,
SensorDeviceClass.TEMPERATURE: TemperatureConverter, SensorDeviceClass.TEMPERATURE: TemperatureConverter,
SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS_PARTS: UnitlessRatioConverter, SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS_PARTS: UnitlessRatioConverter,
@ -597,6 +606,7 @@ DEVICE_CLASS_UNITS: dict[SensorDeviceClass, set[type[StrEnum] | str | None]] = {
SensorDeviceClass.PRECIPITATION: set(UnitOfPrecipitationDepth), SensorDeviceClass.PRECIPITATION: set(UnitOfPrecipitationDepth),
SensorDeviceClass.PRECIPITATION_INTENSITY: set(UnitOfVolumetricFlux), SensorDeviceClass.PRECIPITATION_INTENSITY: set(UnitOfVolumetricFlux),
SensorDeviceClass.PRESSURE: set(UnitOfPressure), SensorDeviceClass.PRESSURE: set(UnitOfPressure),
SensorDeviceClass.REACTIVE_ENERGY: set(UnitOfReactiveEnergy),
SensorDeviceClass.REACTIVE_POWER: set(UnitOfReactivePower), SensorDeviceClass.REACTIVE_POWER: set(UnitOfReactivePower),
SensorDeviceClass.SIGNAL_STRENGTH: { SensorDeviceClass.SIGNAL_STRENGTH: {
SIGNAL_STRENGTH_DECIBELS, SIGNAL_STRENGTH_DECIBELS,
@ -672,6 +682,10 @@ DEVICE_CLASS_STATE_CLASSES: dict[SensorDeviceClass, set[SensorStateClass]] = {
SensorDeviceClass.PRECIPITATION: set(SensorStateClass), SensorDeviceClass.PRECIPITATION: set(SensorStateClass),
SensorDeviceClass.PRECIPITATION_INTENSITY: {SensorStateClass.MEASUREMENT}, SensorDeviceClass.PRECIPITATION_INTENSITY: {SensorStateClass.MEASUREMENT},
SensorDeviceClass.PRESSURE: {SensorStateClass.MEASUREMENT}, SensorDeviceClass.PRESSURE: {SensorStateClass.MEASUREMENT},
SensorDeviceClass.REACTIVE_ENERGY: {
SensorStateClass.TOTAL,
SensorStateClass.TOTAL_INCREASING,
},
SensorDeviceClass.REACTIVE_POWER: {SensorStateClass.MEASUREMENT}, SensorDeviceClass.REACTIVE_POWER: {SensorStateClass.MEASUREMENT},
SensorDeviceClass.SIGNAL_STRENGTH: {SensorStateClass.MEASUREMENT}, SensorDeviceClass.SIGNAL_STRENGTH: {SensorStateClass.MEASUREMENT},
SensorDeviceClass.SOUND_PRESSURE: {SensorStateClass.MEASUREMENT}, SensorDeviceClass.SOUND_PRESSURE: {SensorStateClass.MEASUREMENT},

View File

@ -70,6 +70,7 @@ CONF_IS_PRECIPITATION = "is_precipitation"
CONF_IS_PRECIPITATION_INTENSITY = "is_precipitation_intensity" CONF_IS_PRECIPITATION_INTENSITY = "is_precipitation_intensity"
CONF_IS_PRESSURE = "is_pressure" CONF_IS_PRESSURE = "is_pressure"
CONF_IS_SPEED = "is_speed" CONF_IS_SPEED = "is_speed"
CONF_IS_REACTIVE_ENERGY = "is_reactive_energy"
CONF_IS_REACTIVE_POWER = "is_reactive_power" CONF_IS_REACTIVE_POWER = "is_reactive_power"
CONF_IS_SIGNAL_STRENGTH = "is_signal_strength" CONF_IS_SIGNAL_STRENGTH = "is_signal_strength"
CONF_IS_SOUND_PRESSURE = "is_sound_pressure" CONF_IS_SOUND_PRESSURE = "is_sound_pressure"
@ -128,6 +129,7 @@ ENTITY_CONDITIONS = {
{CONF_TYPE: CONF_IS_PRECIPITATION_INTENSITY} {CONF_TYPE: CONF_IS_PRECIPITATION_INTENSITY}
], ],
SensorDeviceClass.PRESSURE: [{CONF_TYPE: CONF_IS_PRESSURE}], SensorDeviceClass.PRESSURE: [{CONF_TYPE: CONF_IS_PRESSURE}],
SensorDeviceClass.REACTIVE_ENERGY: [{CONF_TYPE: CONF_IS_REACTIVE_ENERGY}],
SensorDeviceClass.REACTIVE_POWER: [{CONF_TYPE: CONF_IS_REACTIVE_POWER}], SensorDeviceClass.REACTIVE_POWER: [{CONF_TYPE: CONF_IS_REACTIVE_POWER}],
SensorDeviceClass.SIGNAL_STRENGTH: [{CONF_TYPE: CONF_IS_SIGNAL_STRENGTH}], SensorDeviceClass.SIGNAL_STRENGTH: [{CONF_TYPE: CONF_IS_SIGNAL_STRENGTH}],
SensorDeviceClass.SOUND_PRESSURE: [{CONF_TYPE: CONF_IS_SOUND_PRESSURE}], SensorDeviceClass.SOUND_PRESSURE: [{CONF_TYPE: CONF_IS_SOUND_PRESSURE}],
@ -193,6 +195,7 @@ CONDITION_SCHEMA = vol.All(
CONF_IS_PRECIPITATION, CONF_IS_PRECIPITATION,
CONF_IS_PRECIPITATION_INTENSITY, CONF_IS_PRECIPITATION_INTENSITY,
CONF_IS_PRESSURE, CONF_IS_PRESSURE,
CONF_IS_REACTIVE_ENERGY,
CONF_IS_REACTIVE_POWER, CONF_IS_REACTIVE_POWER,
CONF_IS_SIGNAL_STRENGTH, CONF_IS_SIGNAL_STRENGTH,
CONF_IS_SOUND_PRESSURE, CONF_IS_SOUND_PRESSURE,

View File

@ -68,6 +68,7 @@ CONF_POWER_FACTOR = "power_factor"
CONF_PRECIPITATION = "precipitation" CONF_PRECIPITATION = "precipitation"
CONF_PRECIPITATION_INTENSITY = "precipitation_intensity" CONF_PRECIPITATION_INTENSITY = "precipitation_intensity"
CONF_PRESSURE = "pressure" CONF_PRESSURE = "pressure"
CONF_REACTIVE_ENERGY = "reactive_energy"
CONF_REACTIVE_POWER = "reactive_power" CONF_REACTIVE_POWER = "reactive_power"
CONF_SIGNAL_STRENGTH = "signal_strength" CONF_SIGNAL_STRENGTH = "signal_strength"
CONF_SOUND_PRESSURE = "sound_pressure" CONF_SOUND_PRESSURE = "sound_pressure"
@ -127,6 +128,7 @@ ENTITY_TRIGGERS = {
{CONF_TYPE: CONF_PRECIPITATION_INTENSITY} {CONF_TYPE: CONF_PRECIPITATION_INTENSITY}
], ],
SensorDeviceClass.PRESSURE: [{CONF_TYPE: CONF_PRESSURE}], SensorDeviceClass.PRESSURE: [{CONF_TYPE: CONF_PRESSURE}],
SensorDeviceClass.REACTIVE_ENERGY: [{CONF_TYPE: CONF_REACTIVE_ENERGY}],
SensorDeviceClass.REACTIVE_POWER: [{CONF_TYPE: CONF_REACTIVE_POWER}], SensorDeviceClass.REACTIVE_POWER: [{CONF_TYPE: CONF_REACTIVE_POWER}],
SensorDeviceClass.SIGNAL_STRENGTH: [{CONF_TYPE: CONF_SIGNAL_STRENGTH}], SensorDeviceClass.SIGNAL_STRENGTH: [{CONF_TYPE: CONF_SIGNAL_STRENGTH}],
SensorDeviceClass.SOUND_PRESSURE: [{CONF_TYPE: CONF_SOUND_PRESSURE}], SensorDeviceClass.SOUND_PRESSURE: [{CONF_TYPE: CONF_SOUND_PRESSURE}],
@ -193,6 +195,7 @@ TRIGGER_SCHEMA = vol.All(
CONF_PRECIPITATION, CONF_PRECIPITATION,
CONF_PRECIPITATION_INTENSITY, CONF_PRECIPITATION_INTENSITY,
CONF_PRESSURE, CONF_PRESSURE,
CONF_REACTIVE_ENERGY,
CONF_REACTIVE_POWER, CONF_REACTIVE_POWER,
CONF_SIGNAL_STRENGTH, CONF_SIGNAL_STRENGTH,
CONF_SOUND_PRESSURE, CONF_SOUND_PRESSURE,

View File

@ -114,6 +114,9 @@
"pressure": { "pressure": {
"default": "mdi:gauge" "default": "mdi:gauge"
}, },
"reactive_energy": {
"default": "mdi:lightning-bolt"
},
"reactive_power": { "reactive_power": {
"default": "mdi:flash" "default": "mdi:flash"
}, },

View File

@ -38,6 +38,7 @@
"is_precipitation": "Current {entity_name} precipitation", "is_precipitation": "Current {entity_name} precipitation",
"is_precipitation_intensity": "Current {entity_name} precipitation intensity", "is_precipitation_intensity": "Current {entity_name} precipitation intensity",
"is_pressure": "Current {entity_name} pressure", "is_pressure": "Current {entity_name} pressure",
"is_reactive_energy": "Current {entity_name} reactive energy",
"is_reactive_power": "Current {entity_name} reactive power", "is_reactive_power": "Current {entity_name} reactive power",
"is_signal_strength": "Current {entity_name} signal strength", "is_signal_strength": "Current {entity_name} signal strength",
"is_sound_pressure": "Current {entity_name} sound pressure", "is_sound_pressure": "Current {entity_name} sound pressure",
@ -92,6 +93,7 @@
"precipitation": "{entity_name} precipitation changes", "precipitation": "{entity_name} precipitation changes",
"precipitation_intensity": "{entity_name} precipitation intensity changes", "precipitation_intensity": "{entity_name} precipitation intensity changes",
"pressure": "{entity_name} pressure changes", "pressure": "{entity_name} pressure changes",
"reactive_energy": "{entity_name} reactive energy changes",
"reactive_power": "{entity_name} reactive power changes", "reactive_power": "{entity_name} reactive power changes",
"signal_strength": "{entity_name} signal strength changes", "signal_strength": "{entity_name} signal strength changes",
"sound_pressure": "{entity_name} sound pressure changes", "sound_pressure": "{entity_name} sound pressure changes",
@ -256,6 +258,9 @@
"pressure": { "pressure": {
"name": "Pressure" "name": "Pressure"
}, },
"reactive_energy": {
"name": "Reactive energy"
},
"reactive_power": { "reactive_power": {
"name": "Reactive power" "name": "Reactive power"
}, },

View File

@ -106,6 +106,7 @@
"precipitation": "[%key:component::sensor::entity_component::precipitation::name%]", "precipitation": "[%key:component::sensor::entity_component::precipitation::name%]",
"precipitation_intensity": "[%key:component::sensor::entity_component::precipitation_intensity::name%]", "precipitation_intensity": "[%key:component::sensor::entity_component::precipitation_intensity::name%]",
"pressure": "[%key:component::sensor::entity_component::pressure::name%]", "pressure": "[%key:component::sensor::entity_component::pressure::name%]",
"reactive_energy": "[%key:component::sensor::entity_component::reactive_energy::name%]",
"reactive_power": "[%key:component::sensor::entity_component::reactive_power::name%]", "reactive_power": "[%key:component::sensor::entity_component::reactive_power::name%]",
"signal_strength": "[%key:component::sensor::entity_component::signal_strength::name%]", "signal_strength": "[%key:component::sensor::entity_component::signal_strength::name%]",
"sound_pressure": "[%key:component::sensor::entity_component::sound_pressure::name%]", "sound_pressure": "[%key:component::sensor::entity_component::sound_pressure::name%]",

View File

@ -326,6 +326,7 @@
"precipitation": "[%key:component::sensor::entity_component::precipitation::name%]", "precipitation": "[%key:component::sensor::entity_component::precipitation::name%]",
"precipitation_intensity": "[%key:component::sensor::entity_component::precipitation_intensity::name%]", "precipitation_intensity": "[%key:component::sensor::entity_component::precipitation_intensity::name%]",
"pressure": "[%key:component::sensor::entity_component::pressure::name%]", "pressure": "[%key:component::sensor::entity_component::pressure::name%]",
"reactive_energy": "[%key:component::sensor::entity_component::reactive_energy::name%]",
"reactive_power": "[%key:component::sensor::entity_component::reactive_power::name%]", "reactive_power": "[%key:component::sensor::entity_component::reactive_power::name%]",
"signal_strength": "[%key:component::sensor::entity_component::signal_strength::name%]", "signal_strength": "[%key:component::sensor::entity_component::signal_strength::name%]",
"sound_pressure": "[%key:component::sensor::entity_component::sound_pressure::name%]", "sound_pressure": "[%key:component::sensor::entity_component::sound_pressure::name%]",

View File

@ -634,6 +634,14 @@ class UnitOfEnergy(StrEnum):
GIGA_CALORIE = "Gcal" GIGA_CALORIE = "Gcal"
# Reactive energy units
class UnitOfReactiveEnergy(StrEnum):
"""Reactive energy units."""
VOLT_AMPERE_REACTIVE_HOUR = "varh"
KILO_VOLT_AMPERE_REACTIVE_HOUR = "kvarh"
# Energy Distance units # Energy Distance units
class UnitOfEnergyDistance(StrEnum): class UnitOfEnergyDistance(StrEnum):
"""Energy Distance units.""" """Energy Distance units."""

View File

@ -24,6 +24,7 @@ from homeassistant.const import (
UnitOfMass, UnitOfMass,
UnitOfPower, UnitOfPower,
UnitOfPressure, UnitOfPressure,
UnitOfReactiveEnergy,
UnitOfSpeed, UnitOfSpeed,
UnitOfTemperature, UnitOfTemperature,
UnitOfTime, UnitOfTime,
@ -429,6 +430,17 @@ class PressureConverter(BaseUnitConverter):
} }
class ReactiveEnergyConverter(BaseUnitConverter):
"""Utility to convert reactive energy values."""
UNIT_CLASS = "energy"
_UNIT_CONVERSION: dict[str | None, float] = {
UnitOfReactiveEnergy.VOLT_AMPERE_REACTIVE_HOUR: 1,
UnitOfReactiveEnergy.KILO_VOLT_AMPERE_REACTIVE_HOUR: 1 / 1e3,
}
VALID_UNITS = set(UnitOfReactiveEnergy)
class SpeedConverter(BaseUnitConverter): class SpeedConverter(BaseUnitConverter):
"""Utility to convert speed values.""" """Utility to convert speed values."""

View File

@ -14,6 +14,7 @@ from homeassistant.const import (
UnitOfApparentPower, UnitOfApparentPower,
UnitOfFrequency, UnitOfFrequency,
UnitOfPressure, UnitOfPressure,
UnitOfReactiveEnergy,
UnitOfReactivePower, UnitOfReactivePower,
UnitOfVolume, UnitOfVolume,
) )
@ -44,6 +45,7 @@ UNITS_OF_MEASUREMENT = {
SensorDeviceClass.ENERGY: "kWh", # energy (Wh/kWh/MWh) SensorDeviceClass.ENERGY: "kWh", # energy (Wh/kWh/MWh)
SensorDeviceClass.FREQUENCY: UnitOfFrequency.GIGAHERTZ, # energy (Hz/kHz/MHz/GHz) SensorDeviceClass.FREQUENCY: UnitOfFrequency.GIGAHERTZ, # energy (Hz/kHz/MHz/GHz)
SensorDeviceClass.POWER_FACTOR: PERCENTAGE, # power factor (no unit, min: -1.0, max: 1.0) SensorDeviceClass.POWER_FACTOR: PERCENTAGE, # power factor (no unit, min: -1.0, max: 1.0)
SensorDeviceClass.REACTIVE_ENERGY: UnitOfReactiveEnergy.VOLT_AMPERE_REACTIVE_HOUR, # reactive energy (varh)
SensorDeviceClass.REACTIVE_POWER: UnitOfReactivePower.VOLT_AMPERE_REACTIVE, # reactive power (var) SensorDeviceClass.REACTIVE_POWER: UnitOfReactivePower.VOLT_AMPERE_REACTIVE, # reactive power (var)
SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, # µg/m³ of vocs SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, # µg/m³ of vocs
SensorDeviceClass.VOLTAGE: "V", # voltage (V) SensorDeviceClass.VOLTAGE: "V", # voltage (V)

View File

@ -119,7 +119,7 @@ async def test_get_conditions(
conditions = await async_get_device_automations( conditions = await async_get_device_automations(
hass, DeviceAutomationType.CONDITION, device_entry.id hass, DeviceAutomationType.CONDITION, device_entry.id
) )
assert len(conditions) == 27 assert len(conditions) == 28
assert conditions == unordered(expected_conditions) assert conditions == unordered(expected_conditions)

View File

@ -121,7 +121,7 @@ async def test_get_triggers(
triggers = await async_get_device_automations( triggers = await async_get_device_automations(
hass, DeviceAutomationType.TRIGGER, device_entry.id hass, DeviceAutomationType.TRIGGER, device_entry.id
) )
assert len(triggers) == 27 assert len(triggers) == 28
assert triggers == unordered(expected_triggers) assert triggers == unordered(expected_triggers)

View File

@ -1994,6 +1994,7 @@ async def test_non_numeric_device_class_with_unit_of_measurement(
SensorDeviceClass.PRECIPITATION_INTENSITY, SensorDeviceClass.PRECIPITATION_INTENSITY,
SensorDeviceClass.PRECIPITATION, SensorDeviceClass.PRECIPITATION,
SensorDeviceClass.PRESSURE, SensorDeviceClass.PRESSURE,
SensorDeviceClass.REACTIVE_ENERGY,
SensorDeviceClass.REACTIVE_POWER, SensorDeviceClass.REACTIVE_POWER,
SensorDeviceClass.SIGNAL_STRENGTH, SensorDeviceClass.SIGNAL_STRENGTH,
SensorDeviceClass.SOUND_PRESSURE, SensorDeviceClass.SOUND_PRESSURE,

View File

@ -24,6 +24,7 @@ from homeassistant.const import (
UnitOfMass, UnitOfMass,
UnitOfPower, UnitOfPower,
UnitOfPressure, UnitOfPressure,
UnitOfReactiveEnergy,
UnitOfSpeed, UnitOfSpeed,
UnitOfTemperature, UnitOfTemperature,
UnitOfTime, UnitOfTime,
@ -49,6 +50,7 @@ from homeassistant.util.unit_conversion import (
MassConverter, MassConverter,
PowerConverter, PowerConverter,
PressureConverter, PressureConverter,
ReactiveEnergyConverter,
SpeedConverter, SpeedConverter,
TemperatureConverter, TemperatureConverter,
UnitlessRatioConverter, UnitlessRatioConverter,
@ -78,6 +80,7 @@ _ALL_CONVERTERS: dict[type[BaseUnitConverter], list[str | None]] = {
MassConverter, MassConverter,
PowerConverter, PowerConverter,
PressureConverter, PressureConverter,
ReactiveEnergyConverter,
SpeedConverter, SpeedConverter,
TemperatureConverter, TemperatureConverter,
UnitlessRatioConverter, UnitlessRatioConverter,
@ -127,6 +130,11 @@ _GET_UNIT_RATIO: dict[type[BaseUnitConverter], tuple[str | None, str | None, flo
MassConverter: (UnitOfMass.STONES, UnitOfMass.KILOGRAMS, 0.157473), MassConverter: (UnitOfMass.STONES, UnitOfMass.KILOGRAMS, 0.157473),
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: (
UnitOfReactiveEnergy.VOLT_AMPERE_REACTIVE_HOUR,
UnitOfReactiveEnergy.KILO_VOLT_AMPERE_REACTIVE_HOUR,
1000,
),
SpeedConverter: ( SpeedConverter: (
UnitOfSpeed.KILOMETERS_PER_HOUR, UnitOfSpeed.KILOMETERS_PER_HOUR,
UnitOfSpeed.MILES_PER_HOUR, UnitOfSpeed.MILES_PER_HOUR,
@ -622,6 +630,20 @@ _CONVERTED_VALUE: dict[
(30, UnitOfPressure.MMHG, 1.181102, UnitOfPressure.INHG), (30, UnitOfPressure.MMHG, 1.181102, UnitOfPressure.INHG),
(5, UnitOfPressure.BAR, 72.51887, UnitOfPressure.PSI), (5, UnitOfPressure.BAR, 72.51887, UnitOfPressure.PSI),
], ],
ReactiveEnergyConverter: [
(
5,
UnitOfReactiveEnergy.KILO_VOLT_AMPERE_REACTIVE_HOUR,
5000,
UnitOfReactiveEnergy.VOLT_AMPERE_REACTIVE_HOUR,
),
(
5,
UnitOfReactiveEnergy.VOLT_AMPERE_REACTIVE_HOUR,
0.005,
UnitOfReactiveEnergy.KILO_VOLT_AMPERE_REACTIVE_HOUR,
),
],
SpeedConverter: [ SpeedConverter: [
# 5 km/h / 1.609 km/mi = 3.10686 mi/h # 5 km/h / 1.609 km/mi = 3.10686 mi/h
(5, UnitOfSpeed.KILOMETERS_PER_HOUR, 3.106856, UnitOfSpeed.MILES_PER_HOUR), (5, UnitOfSpeed.KILOMETERS_PER_HOUR, 3.106856, UnitOfSpeed.MILES_PER_HOUR),