diff --git a/homeassistant/components/number/const.py b/homeassistant/components/number/const.py index c36f1ba3d05..1d82d4a5a96 100644 --- a/homeassistant/components/number/const.py +++ b/homeassistant/components/number/const.py @@ -47,10 +47,35 @@ from homeassistant.const import ( UnitOfVolumetricFlux, ) from homeassistant.util.unit_conversion import ( + ApparentPowerConverter, + AreaConverter, BaseUnitConverter, + BloodGlucoseConcentrationConverter, + CarbonMonoxideConcentrationConverter, + ConductivityConverter, + DataRateConverter, + DistanceConverter, + DurationConverter, + ElectricCurrentConverter, + ElectricPotentialConverter, + EnergyConverter, + EnergyDistanceConverter, + InformationConverter, + MassConverter, + MassVolumeConcentrationConverter, + NitrogenDioxideConcentrationConverter, + NitrogenMonoxideConcentrationConverter, + OzoneConcentrationConverter, + PowerConverter, + PressureConverter, ReactiveEnergyConverter, + ReactivePowerConverter, + SpeedConverter, + SulphurDioxideConcentrationConverter, TemperatureConverter, TemperatureDeltaConverter, + UnitlessRatioConverter, + VolumeConverter, VolumeFlowRateConverter, ) @@ -587,10 +612,45 @@ DEVICE_CLASS_UNITS: dict[NumberDeviceClass, set[type[StrEnum] | str | None]] = { } UNIT_CONVERTERS: dict[NumberDeviceClass, type[BaseUnitConverter]] = { + NumberDeviceClass.APPARENT_POWER: ApparentPowerConverter, + NumberDeviceClass.ABSOLUTE_HUMIDITY: MassVolumeConcentrationConverter, + NumberDeviceClass.AREA: AreaConverter, + NumberDeviceClass.ATMOSPHERIC_PRESSURE: PressureConverter, + NumberDeviceClass.BLOOD_GLUCOSE_CONCENTRATION: BloodGlucoseConcentrationConverter, + NumberDeviceClass.CO: CarbonMonoxideConcentrationConverter, + NumberDeviceClass.CONDUCTIVITY: ConductivityConverter, + NumberDeviceClass.CURRENT: ElectricCurrentConverter, + NumberDeviceClass.DATA_RATE: DataRateConverter, + NumberDeviceClass.DATA_SIZE: InformationConverter, + NumberDeviceClass.DISTANCE: DistanceConverter, + NumberDeviceClass.DURATION: DurationConverter, + NumberDeviceClass.ENERGY: EnergyConverter, + NumberDeviceClass.ENERGY_DISTANCE: EnergyDistanceConverter, + NumberDeviceClass.ENERGY_STORAGE: EnergyConverter, + NumberDeviceClass.GAS: VolumeConverter, + NumberDeviceClass.NITROGEN_DIOXIDE: NitrogenDioxideConcentrationConverter, + NumberDeviceClass.NITROGEN_MONOXIDE: NitrogenMonoxideConcentrationConverter, + NumberDeviceClass.OZONE: OzoneConcentrationConverter, + NumberDeviceClass.POWER: PowerConverter, + NumberDeviceClass.POWER_FACTOR: UnitlessRatioConverter, + NumberDeviceClass.PRECIPITATION: DistanceConverter, + NumberDeviceClass.PRECIPITATION_INTENSITY: SpeedConverter, + NumberDeviceClass.PRESSURE: PressureConverter, NumberDeviceClass.REACTIVE_ENERGY: ReactiveEnergyConverter, + NumberDeviceClass.REACTIVE_POWER: ReactivePowerConverter, + NumberDeviceClass.SULPHUR_DIOXIDE: SulphurDioxideConcentrationConverter, + NumberDeviceClass.SPEED: SpeedConverter, NumberDeviceClass.TEMPERATURE: TemperatureConverter, NumberDeviceClass.TEMPERATURE_DELTA: TemperatureDeltaConverter, + NumberDeviceClass.VOLATILE_ORGANIC_COMPOUNDS: MassVolumeConcentrationConverter, + NumberDeviceClass.VOLATILE_ORGANIC_COMPOUNDS_PARTS: UnitlessRatioConverter, + NumberDeviceClass.VOLTAGE: ElectricPotentialConverter, + NumberDeviceClass.VOLUME: VolumeConverter, + NumberDeviceClass.VOLUME_STORAGE: VolumeConverter, NumberDeviceClass.VOLUME_FLOW_RATE: VolumeFlowRateConverter, + NumberDeviceClass.WATER: VolumeConverter, + NumberDeviceClass.WEIGHT: MassConverter, + NumberDeviceClass.WIND_SPEED: SpeedConverter, } # We translate units that were using using the legacy coding of μ \u00b5 diff --git a/tests/components/number/test_websocket_api.py b/tests/components/number/test_websocket_api.py index 8fbc79f2c1f..fdc2d090842 100644 --- a/tests/components/number/test_websocket_api.py +++ b/tests/components/number/test_websocket_api.py @@ -37,17 +37,6 @@ async def test_device_class_units( assert msg["success"] assert msg["result"] == {"units": ["K", "°C", "°F"]} - # Device class with units which number doesn't allow customizing & converting - await client.send_json_auto_id( - { - "type": "number/device_class_convertible_units", - "device_class": "energy", - } - ) - msg = await client.receive_json() - assert msg["success"] - assert msg["result"] == {"units": []} - # Unknown device class await client.send_json_auto_id( { diff --git a/tests/components/sensor/test_init.py b/tests/components/sensor/test_init.py index cdebaa4eeb8..cdaec70afbd 100644 --- a/tests/components/sensor/test_init.py +++ b/tests/components/sensor/test_init.py @@ -14,6 +14,7 @@ import pytest from homeassistant.components import sensor from homeassistant.components.number import ( AMBIGUOUS_UNITS as NUMBER_AMBIGUOUS_UNITS, + UNIT_CONVERTERS as NUMBER_UNIT_CONVERTERS, NumberDeviceClass, ) from homeassistant.components.sensor import ( @@ -2118,6 +2119,16 @@ def test_device_classes_aligned() -> None: assert getattr(SensorDeviceClass, device_class.name).value == device_class.value +def test_unit_converters_aligned() -> None: + """Make sure all number unit converters are also available in sensor converters.""" + + assert len(NUMBER_UNIT_CONVERTERS) == len(UNIT_CONVERTERS) + + for device_class, converter in NUMBER_UNIT_CONVERTERS.items(): + assert device_class.value in UNIT_CONVERTERS + assert UNIT_CONVERTERS[device_class.value] == converter + + async def test_value_unknown_in_enumeration( hass: HomeAssistant, caplog: pytest.LogCaptureFixture,