Extend UnitOfReactivePower with 'mvar' (#150415)

This commit is contained in:
Ludovic BOUÉ
2025-08-14 11:46:06 +02:00
committed by GitHub
parent 7e28e3dcd3
commit cc4b9e0eca
8 changed files with 73 additions and 16 deletions

View File

@@ -338,7 +338,7 @@ class NumberDeviceClass(StrEnum):
REACTIVE_POWER = "reactive_power"
"""Reactive power.
Unit of measurement: `var`, `kvar`
Unit of measurement: `mvar`, `var`, `kvar`
"""
SIGNAL_STRENGTH = "signal_strength"

View File

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

View File

@@ -33,6 +33,7 @@ from homeassistant.util.unit_conversion import (
PowerConverter,
PressureConverter,
ReactiveEnergyConverter,
ReactivePowerConverter,
SpeedConverter,
TemperatureConverter,
UnitlessRatioConverter,
@@ -81,6 +82,7 @@ UNIT_SCHEMA = vol.Schema(
vol.Optional("power"): vol.In(PowerConverter.VALID_UNITS),
vol.Optional("pressure"): vol.In(PressureConverter.VALID_UNITS),
vol.Optional("reactive_energy"): vol.In(ReactiveEnergyConverter.VALID_UNITS),
vol.Optional("reactive_power"): vol.In(ReactivePowerConverter.VALID_UNITS),
vol.Optional("speed"): vol.In(SpeedConverter.VALID_UNITS),
vol.Optional("temperature"): vol.In(TemperatureConverter.VALID_UNITS),
vol.Optional("unitless"): vol.In(UnitlessRatioConverter.VALID_UNITS),

View File

@@ -64,6 +64,7 @@ from homeassistant.util.unit_conversion import (
PowerConverter,
PressureConverter,
ReactiveEnergyConverter,
ReactivePowerConverter,
SpeedConverter,
TemperatureConverter,
UnitlessRatioConverter,
@@ -370,7 +371,7 @@ class SensorDeviceClass(StrEnum):
REACTIVE_POWER = "reactive_power"
"""Reactive power.
Unit of measurement: `var`, `kvar`
Unit of measurement: `mvar`, `var`, `kvar`
"""
SIGNAL_STRENGTH = "signal_strength"
@@ -550,6 +551,7 @@ UNIT_CONVERTERS: dict[SensorDeviceClass | str | None, type[BaseUnitConverter]] =
SensorDeviceClass.PRECIPITATION_INTENSITY: SpeedConverter,
SensorDeviceClass.PRESSURE: PressureConverter,
SensorDeviceClass.REACTIVE_ENERGY: ReactiveEnergyConverter,
SensorDeviceClass.REACTIVE_POWER: ReactivePowerConverter,
SensorDeviceClass.SPEED: SpeedConverter,
SensorDeviceClass.TEMPERATURE: TemperatureConverter,
SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS: MassVolumeConcentrationConverter,

View File

@@ -609,6 +609,7 @@ class UnitOfPower(StrEnum):
class UnitOfReactivePower(StrEnum):
"""Reactive power units."""
MILLIVOLT_AMPERE_REACTIVE = "mvar"
VOLT_AMPERE_REACTIVE = "var"
KILO_VOLT_AMPERE_REACTIVE = "kvar"

View File

@@ -29,6 +29,7 @@ from homeassistant.const import (
UnitOfPower,
UnitOfPressure,
UnitOfReactiveEnergy,
UnitOfReactivePower,
UnitOfSpeed,
UnitOfTemperature,
UnitOfTime,
@@ -460,6 +461,22 @@ class ReactiveEnergyConverter(BaseUnitConverter):
VALID_UNITS = set(UnitOfReactiveEnergy)
class ReactivePowerConverter(BaseUnitConverter):
"""Utility to convert reactive power values."""
UNIT_CLASS = "reactive_power"
_UNIT_CONVERSION: dict[str | None, float] = {
UnitOfReactivePower.MILLIVOLT_AMPERE_REACTIVE: 1 * 1000,
UnitOfReactivePower.VOLT_AMPERE_REACTIVE: 1,
UnitOfReactivePower.KILO_VOLT_AMPERE_REACTIVE: 1 / 1000,
}
VALID_UNITS = {
UnitOfReactivePower.MILLIVOLT_AMPERE_REACTIVE,
UnitOfReactivePower.VOLT_AMPERE_REACTIVE,
UnitOfReactivePower.KILO_VOLT_AMPERE_REACTIVE,
}
class SpeedConverter(BaseUnitConverter):
"""Utility to convert speed values."""

View File

@@ -2978,7 +2978,6 @@ def test_device_class_converters_are_complete() -> None:
SensorDeviceClass.PM1,
SensorDeviceClass.PM10,
SensorDeviceClass.PM25,
SensorDeviceClass.REACTIVE_POWER,
SensorDeviceClass.SIGNAL_STRENGTH,
SensorDeviceClass.SOUND_PRESSURE,
SensorDeviceClass.SULPHUR_DIOXIDE,

View File

@@ -29,6 +29,7 @@ from homeassistant.const import (
UnitOfPower,
UnitOfPressure,
UnitOfReactiveEnergy,
UnitOfReactivePower,
UnitOfSpeed,
UnitOfTemperature,
UnitOfTime,
@@ -57,6 +58,7 @@ from homeassistant.util.unit_conversion import (
PowerConverter,
PressureConverter,
ReactiveEnergyConverter,
ReactivePowerConverter,
SpeedConverter,
TemperatureConverter,
UnitlessRatioConverter,
@@ -89,6 +91,7 @@ _ALL_CONVERTERS: dict[type[BaseUnitConverter], list[str | None]] = {
PowerConverter,
PressureConverter,
ReactiveEnergyConverter,
ReactivePowerConverter,
SpeedConverter,
TemperatureConverter,
UnitlessRatioConverter,
@@ -100,6 +103,11 @@ _ALL_CONVERTERS: dict[type[BaseUnitConverter], list[str | None]] = {
# Dict containing all converters with a corresponding unit ratio.
_GET_UNIT_RATIO: dict[type[BaseUnitConverter], tuple[str | None, str | None, float]] = {
ApparentPowerConverter: (
UnitOfApparentPower.MILLIVOLT_AMPERE,
UnitOfApparentPower.VOLT_AMPERE,
1000,
),
AreaConverter: (UnitOfArea.SQUARE_KILOMETERS, UnitOfArea.SQUARE_METERS, 0.000001),
BloodGlucoseConcentrationConverter: (
UnitOfBloodGlucoseConcentration.MILLIGRAMS_PER_DECILITER,
@@ -141,11 +149,6 @@ _GET_UNIT_RATIO: dict[type[BaseUnitConverter], tuple[str | None, str | None, flo
CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER,
1000,
),
ApparentPowerConverter: (
UnitOfApparentPower.MILLIVOLT_AMPERE,
UnitOfApparentPower.VOLT_AMPERE,
1000,
),
PowerConverter: (UnitOfPower.WATT, UnitOfPower.KILO_WATT, 1000),
PressureConverter: (UnitOfPressure.HPA, UnitOfPressure.INHG, 33.86389),
ReactiveEnergyConverter: (
@@ -153,6 +156,11 @@ _GET_UNIT_RATIO: dict[type[BaseUnitConverter], tuple[str | None, str | None, flo
UnitOfReactiveEnergy.KILO_VOLT_AMPERE_REACTIVE_HOUR,
1000,
),
ReactivePowerConverter: (
UnitOfReactivePower.MILLIVOLT_AMPERE_REACTIVE,
UnitOfReactivePower.VOLT_AMPERE_REACTIVE,
1000,
),
SpeedConverter: (
UnitOfSpeed.KILOMETERS_PER_HOUR,
UnitOfSpeed.MILES_PER_HOUR,
@@ -176,6 +184,14 @@ _GET_UNIT_RATIO: dict[type[BaseUnitConverter], tuple[str | None, str | None, flo
_CONVERTED_VALUE: dict[
type[BaseUnitConverter], list[tuple[float, str | None, float, str | None]]
] = {
ApparentPowerConverter: [
(
10,
UnitOfApparentPower.MILLIVOLT_AMPERE,
0.01,
UnitOfApparentPower.VOLT_AMPERE,
),
],
AreaConverter: [
# Square Meters to other units
(5, UnitOfArea.SQUARE_METERS, 50000, UnitOfArea.SQUARE_CENTIMETERS),
@@ -623,14 +639,6 @@ _CONVERTED_VALUE: dict[
(1, UnitOfMass.STONES, 14, UnitOfMass.POUNDS),
(1, UnitOfMass.STONES, 224, UnitOfMass.OUNCES),
],
ApparentPowerConverter: [
(
10,
UnitOfApparentPower.MILLIVOLT_AMPERE,
0.01,
UnitOfApparentPower.VOLT_AMPERE,
),
],
PowerConverter: [
(10, UnitOfPower.KILO_WATT, 10000, UnitOfPower.WATT),
(10, UnitOfPower.MEGA_WATT, 10e6, UnitOfPower.WATT),
@@ -682,6 +690,32 @@ _CONVERTED_VALUE: dict[
UnitOfReactiveEnergy.KILO_VOLT_AMPERE_REACTIVE_HOUR,
),
],
ReactivePowerConverter: [
(
10,
UnitOfReactivePower.KILO_VOLT_AMPERE_REACTIVE,
10000,
UnitOfReactivePower.VOLT_AMPERE_REACTIVE,
),
(
10,
UnitOfReactivePower.VOLT_AMPERE_REACTIVE,
0.01,
UnitOfReactivePower.KILO_VOLT_AMPERE_REACTIVE,
),
(
10,
UnitOfReactivePower.MILLIVOLT_AMPERE_REACTIVE,
0.01,
UnitOfReactivePower.VOLT_AMPERE_REACTIVE,
),
(
10,
UnitOfReactivePower.MILLIVOLT_AMPERE_REACTIVE,
0.00001,
UnitOfReactivePower.KILO_VOLT_AMPERE_REACTIVE,
),
],
SpeedConverter: [
# 5 km/h / 1.609 km/mi = 3.10686 mi/h
(5, UnitOfSpeed.KILOMETERS_PER_HOUR, 3.106856, UnitOfSpeed.MILES_PER_HOUR),