From 0dd5391cd79b0a519725332d1762d8fdcc47a69d Mon Sep 17 00:00:00 2001 From: dontinelli <73341522+dontinelli@users.noreply.github.com> Date: Fri, 21 Jun 2024 11:10:15 +0200 Subject: [PATCH] Add Siemes and Millisiemens as additional units of conductivity and enable conversion between conductivity units (#118728) --- homeassistant/components/fyta/sensor.py | 10 +++++++-- homeassistant/components/mysensors/sensor.py | 4 ++-- homeassistant/components/number/const.py | 8 +++++++ homeassistant/components/plant/__init__.py | 4 ++-- .../components/recorder/statistics.py | 4 +++- .../components/recorder/websocket_api.py | 1 + homeassistant/components/sensor/const.py | 11 ++++++++++ .../components/sensor/device_condition.py | 3 +++ .../components/sensor/device_trigger.py | 3 +++ homeassistant/components/sensor/strings.json | 5 +++++ homeassistant/components/xiaomi_ble/sensor.py | 4 ++-- homeassistant/const.py | 15 ++++++++++++- homeassistant/util/unit_conversion.py | 14 ++++++++++++ tests/components/plant/test_init.py | 22 ++++++++++++++----- .../sensor/test_device_condition.py | 2 ++ .../components/sensor/test_device_trigger.py | 2 ++ tests/util/test_unit_conversion.py | 16 ++++++++++++++ 17 files changed, 112 insertions(+), 16 deletions(-) diff --git a/homeassistant/components/fyta/sensor.py b/homeassistant/components/fyta/sensor.py index 3c7ed35746a1..574b4e7b18e1 100644 --- a/homeassistant/components/fyta/sensor.py +++ b/homeassistant/components/fyta/sensor.py @@ -16,7 +16,12 @@ from homeassistant.components.sensor import ( SensorStateClass, ) from homeassistant.config_entries import ConfigEntry -from homeassistant.const import PERCENTAGE, EntityCategory, UnitOfTemperature +from homeassistant.const import ( + PERCENTAGE, + EntityCategory, + UnitOfConductivity, + UnitOfTemperature, +) from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback @@ -105,7 +110,8 @@ SENSORS: Final[list[FytaSensorEntityDescription]] = [ FytaSensorEntityDescription( key="salinity", translation_key="salinity", - native_unit_of_measurement="mS/cm", + native_unit_of_measurement=UnitOfConductivity.MILLISIEMENS, + device_class=SensorDeviceClass.CONDUCTIVITY, state_class=SensorStateClass.MEASUREMENT, ), FytaSensorEntityDescription( diff --git a/homeassistant/components/mysensors/sensor.py b/homeassistant/components/mysensors/sensor.py index 537bf575af0b..a6a91c12a814 100644 --- a/homeassistant/components/mysensors/sensor.py +++ b/homeassistant/components/mysensors/sensor.py @@ -15,12 +15,12 @@ from homeassistant.components.sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( - CONDUCTIVITY, DEGREE, LIGHT_LUX, PERCENTAGE, Platform, UnitOfApparentPower, + UnitOfConductivity, UnitOfElectricCurrent, UnitOfElectricPotential, UnitOfEnergy, @@ -191,7 +191,7 @@ SENSORS: dict[str, SensorEntityDescription] = { ), "V_EC": SensorEntityDescription( key="V_EC", - native_unit_of_measurement=CONDUCTIVITY, + native_unit_of_measurement=UnitOfConductivity.MICROSIEMENS, ), "V_VAR": SensorEntityDescription( key="V_VAR", diff --git a/homeassistant/components/number/const.py b/homeassistant/components/number/const.py index f279ffb72a83..6343c3a599f0 100644 --- a/homeassistant/components/number/const.py +++ b/homeassistant/components/number/const.py @@ -18,6 +18,7 @@ from homeassistant.const import ( SIGNAL_STRENGTH_DECIBELS, SIGNAL_STRENGTH_DECIBELS_MILLIWATT, UnitOfApparentPower, + UnitOfConductivity, UnitOfDataRate, UnitOfElectricCurrent, UnitOfElectricPotential, @@ -120,6 +121,12 @@ class NumberDeviceClass(StrEnum): Unit of measurement: `ppm` (parts per million) """ + CONDUCTIVITY = "conductivity" + """Conductivity. + + Unit of measurement: `S/cm`, `mS/cm`, `µS/cm` + """ + CURRENT = "current" """Current. @@ -424,6 +431,7 @@ DEVICE_CLASS_UNITS: dict[NumberDeviceClass, set[type[StrEnum] | str | None]] = { NumberDeviceClass.BATTERY: {PERCENTAGE}, NumberDeviceClass.CO: {CONCENTRATION_PARTS_PER_MILLION}, NumberDeviceClass.CO2: {CONCENTRATION_PARTS_PER_MILLION}, + NumberDeviceClass.CONDUCTIVITY: set(UnitOfConductivity), NumberDeviceClass.CURRENT: set(UnitOfElectricCurrent), NumberDeviceClass.DATA_RATE: set(UnitOfDataRate), NumberDeviceClass.DATA_SIZE: set(UnitOfInformation), diff --git a/homeassistant/components/plant/__init__.py b/homeassistant/components/plant/__init__.py index afce1207add9..b549dee28871 100644 --- a/homeassistant/components/plant/__init__.py +++ b/homeassistant/components/plant/__init__.py @@ -10,7 +10,6 @@ import voluptuous as vol from homeassistant.components.recorder import get_instance, history from homeassistant.const import ( ATTR_UNIT_OF_MEASUREMENT, - CONDUCTIVITY, CONF_SENSORS, LIGHT_LUX, PERCENTAGE, @@ -18,6 +17,7 @@ from homeassistant.const import ( STATE_PROBLEM, STATE_UNAVAILABLE, STATE_UNKNOWN, + UnitOfConductivity, UnitOfTemperature, ) from homeassistant.core import ( @@ -148,7 +148,7 @@ class Plant(Entity): "max": CONF_MAX_MOISTURE, }, READING_CONDUCTIVITY: { - ATTR_UNIT_OF_MEASUREMENT: CONDUCTIVITY, + ATTR_UNIT_OF_MEASUREMENT: UnitOfConductivity.MICROSIEMENS, "min": CONF_MIN_CONDUCTIVITY, "max": CONF_MAX_CONDUCTIVITY, }, diff --git a/homeassistant/components/recorder/statistics.py b/homeassistant/components/recorder/statistics.py index e1178dea2a9b..aeeb30816d72 100644 --- a/homeassistant/components/recorder/statistics.py +++ b/homeassistant/components/recorder/statistics.py @@ -28,6 +28,7 @@ from homeassistant.helpers.typing import UNDEFINED, UndefinedType from homeassistant.util import dt as dt_util from homeassistant.util.unit_conversion import ( BaseUnitConverter, + ConductivityConverter, DataRateConverter, DistanceConverter, DurationConverter, @@ -126,6 +127,7 @@ QUERY_STATISTICS_SUMMARY_SUM = ( STATISTIC_UNIT_TO_UNIT_CONVERTER: dict[str | None, type[BaseUnitConverter]] = { + **{unit: ConductivityConverter for unit in ConductivityConverter.VALID_UNITS}, **{unit: DataRateConverter for unit in DataRateConverter.VALID_UNITS}, **{unit: DistanceConverter for unit in DistanceConverter.VALID_UNITS}, **{unit: DurationConverter for unit in DurationConverter.VALID_UNITS}, @@ -154,7 +156,7 @@ def mean(values: list[float]) -> float | None: This is a very simple version that only works with a non-empty list of floats. The built-in - statistics.mean is more robust but is is almost + statistics.mean is more robust but is almost an order of magnitude slower. """ return sum(values) / len(values) diff --git a/homeassistant/components/recorder/websocket_api.py b/homeassistant/components/recorder/websocket_api.py index b091343e5a46..195d3d3efb07 100644 --- a/homeassistant/components/recorder/websocket_api.py +++ b/homeassistant/components/recorder/websocket_api.py @@ -48,6 +48,7 @@ from .util import PERIOD_SCHEMA, get_instance, resolve_period UNIT_SCHEMA = vol.Schema( { + vol.Optional("conductivity"): vol.In(DataRateConverter.VALID_UNITS), vol.Optional("data_rate"): vol.In(DataRateConverter.VALID_UNITS), vol.Optional("distance"): vol.In(DistanceConverter.VALID_UNITS), vol.Optional("duration"): vol.In(DurationConverter.VALID_UNITS), diff --git a/homeassistant/components/sensor/const.py b/homeassistant/components/sensor/const.py index cc89908f00d6..5acf2ecef238 100644 --- a/homeassistant/components/sensor/const.py +++ b/homeassistant/components/sensor/const.py @@ -18,6 +18,7 @@ from homeassistant.const import ( SIGNAL_STRENGTH_DECIBELS, SIGNAL_STRENGTH_DECIBELS_MILLIWATT, UnitOfApparentPower, + UnitOfConductivity, UnitOfDataRate, UnitOfElectricCurrent, UnitOfElectricPotential, @@ -46,6 +47,7 @@ from homeassistant.helpers.deprecation import ( ) from homeassistant.util.unit_conversion import ( BaseUnitConverter, + ConductivityConverter, DataRateConverter, DistanceConverter, DurationConverter, @@ -137,6 +139,12 @@ class SensorDeviceClass(StrEnum): Unit of measurement: `ppm` (parts per million) """ + CONDUCTIVITY = "conductivity" + """Conductivity. + + Unit of measurement: `S/cm`, `mS/cm`, `µS/cm` + """ + CURRENT = "current" """Current. @@ -485,6 +493,7 @@ STATE_CLASSES: Final[list[str]] = [cls.value for cls in SensorStateClass] UNIT_CONVERTERS: dict[SensorDeviceClass | str | None, type[BaseUnitConverter]] = { SensorDeviceClass.ATMOSPHERIC_PRESSURE: PressureConverter, + SensorDeviceClass.CONDUCTIVITY: ConductivityConverter, SensorDeviceClass.CURRENT: ElectricCurrentConverter, SensorDeviceClass.DATA_RATE: DataRateConverter, SensorDeviceClass.DATA_SIZE: InformationConverter, @@ -517,6 +526,7 @@ DEVICE_CLASS_UNITS: dict[SensorDeviceClass, set[type[StrEnum] | str | None]] = { SensorDeviceClass.BATTERY: {PERCENTAGE}, SensorDeviceClass.CO: {CONCENTRATION_PARTS_PER_MILLION}, SensorDeviceClass.CO2: {CONCENTRATION_PARTS_PER_MILLION}, + SensorDeviceClass.CONDUCTIVITY: set(UnitOfConductivity), SensorDeviceClass.CURRENT: set(UnitOfElectricCurrent), SensorDeviceClass.DATA_RATE: set(UnitOfDataRate), SensorDeviceClass.DATA_SIZE: set(UnitOfInformation), @@ -591,6 +601,7 @@ DEVICE_CLASS_STATE_CLASSES: dict[SensorDeviceClass, set[SensorStateClass]] = { SensorDeviceClass.BATTERY: {SensorStateClass.MEASUREMENT}, SensorDeviceClass.CO: {SensorStateClass.MEASUREMENT}, SensorDeviceClass.CO2: {SensorStateClass.MEASUREMENT}, + SensorDeviceClass.CONDUCTIVITY: {SensorStateClass.MEASUREMENT}, SensorDeviceClass.CURRENT: {SensorStateClass.MEASUREMENT}, SensorDeviceClass.DATA_RATE: {SensorStateClass.MEASUREMENT}, SensorDeviceClass.DATA_SIZE: set(SensorStateClass), diff --git a/homeassistant/components/sensor/device_condition.py b/homeassistant/components/sensor/device_condition.py index fb605d9419cf..21258db2ac58 100644 --- a/homeassistant/components/sensor/device_condition.py +++ b/homeassistant/components/sensor/device_condition.py @@ -41,6 +41,7 @@ CONF_IS_ATMOSPHERIC_PRESSURE = "is_atmospheric_pressure" CONF_IS_BATTERY_LEVEL = "is_battery_level" CONF_IS_CO = "is_carbon_monoxide" CONF_IS_CO2 = "is_carbon_dioxide" +CONF_IS_CONDUCTIVITY = "is_conductivity" CONF_IS_CURRENT = "is_current" CONF_IS_DATA_RATE = "is_data_rate" CONF_IS_DATA_SIZE = "is_data_size" @@ -90,6 +91,7 @@ ENTITY_CONDITIONS = { SensorDeviceClass.BATTERY: [{CONF_TYPE: CONF_IS_BATTERY_LEVEL}], SensorDeviceClass.CO: [{CONF_TYPE: CONF_IS_CO}], SensorDeviceClass.CO2: [{CONF_TYPE: CONF_IS_CO2}], + SensorDeviceClass.CONDUCTIVITY: [{CONF_TYPE: CONF_IS_CONDUCTIVITY}], SensorDeviceClass.CURRENT: [{CONF_TYPE: CONF_IS_CURRENT}], SensorDeviceClass.DATA_RATE: [{CONF_TYPE: CONF_IS_DATA_RATE}], SensorDeviceClass.DATA_SIZE: [{CONF_TYPE: CONF_IS_DATA_SIZE}], @@ -153,6 +155,7 @@ CONDITION_SCHEMA = vol.All( CONF_IS_BATTERY_LEVEL, CONF_IS_CO, CONF_IS_CO2, + CONF_IS_CONDUCTIVITY, CONF_IS_CURRENT, CONF_IS_DATA_RATE, CONF_IS_DATA_SIZE, diff --git a/homeassistant/components/sensor/device_trigger.py b/homeassistant/components/sensor/device_trigger.py index b46f62602855..0ffc42127bc8 100644 --- a/homeassistant/components/sensor/device_trigger.py +++ b/homeassistant/components/sensor/device_trigger.py @@ -40,6 +40,7 @@ CONF_ATMOSPHERIC_PRESSURE = "atmospheric_pressure" CONF_BATTERY_LEVEL = "battery_level" CONF_CO = "carbon_monoxide" CONF_CO2 = "carbon_dioxide" +CONF_CONDUCTIVITY = "conductivity" CONF_CURRENT = "current" CONF_DATA_RATE = "data_rate" CONF_DATA_SIZE = "data_size" @@ -89,6 +90,7 @@ ENTITY_TRIGGERS = { SensorDeviceClass.BATTERY: [{CONF_TYPE: CONF_BATTERY_LEVEL}], SensorDeviceClass.CO: [{CONF_TYPE: CONF_CO}], SensorDeviceClass.CO2: [{CONF_TYPE: CONF_CO2}], + SensorDeviceClass.CONDUCTIVITY: [{CONF_TYPE: CONF_CONDUCTIVITY}], SensorDeviceClass.CURRENT: [{CONF_TYPE: CONF_CURRENT}], SensorDeviceClass.DATA_RATE: [{CONF_TYPE: CONF_DATA_RATE}], SensorDeviceClass.DATA_SIZE: [{CONF_TYPE: CONF_DATA_SIZE}], @@ -153,6 +155,7 @@ TRIGGER_SCHEMA = vol.All( CONF_BATTERY_LEVEL, CONF_CO, CONF_CO2, + CONF_CONDUCTIVITY, CONF_CURRENT, CONF_DATA_RATE, CONF_DATA_SIZE, diff --git a/homeassistant/components/sensor/strings.json b/homeassistant/components/sensor/strings.json index 101b32f373fe..fc85f4b05a91 100644 --- a/homeassistant/components/sensor/strings.json +++ b/homeassistant/components/sensor/strings.json @@ -8,6 +8,7 @@ "is_battery_level": "Current {entity_name} battery level", "is_carbon_monoxide": "Current {entity_name} carbon monoxide concentration level", "is_carbon_dioxide": "Current {entity_name} carbon dioxide concentration level", + "is_conductivity": "Current {entity_name} conductivity", "is_current": "Current {entity_name} current", "is_data_rate": "Current {entity_name} data rate", "is_data_size": "Current {entity_name} data size", @@ -57,6 +58,7 @@ "battery_level": "{entity_name} battery level changes", "carbon_monoxide": "{entity_name} carbon monoxide concentration changes", "carbon_dioxide": "{entity_name} carbon dioxide concentration changes", + "conductivity": "{entity_name} conductivity changes", "current": "{entity_name} current changes", "data_rate": "{entity_name} data rate changes", "data_size": "{entity_name} data size changes", @@ -153,6 +155,9 @@ "carbon_dioxide": { "name": "Carbon dioxide" }, + "conductivity": { + "name": "Conductivity" + }, "current": { "name": "Current" }, diff --git a/homeassistant/components/xiaomi_ble/sensor.py b/homeassistant/components/xiaomi_ble/sensor.py index d107af8ef1ba..65b33c3c559d 100644 --- a/homeassistant/components/xiaomi_ble/sensor.py +++ b/homeassistant/components/xiaomi_ble/sensor.py @@ -20,11 +20,11 @@ from homeassistant.components.sensor import ( ) from homeassistant.const import ( CONCENTRATION_MILLIGRAMS_PER_CUBIC_METER, - CONDUCTIVITY, LIGHT_LUX, PERCENTAGE, SIGNAL_STRENGTH_DECIBELS_MILLIWATT, EntityCategory, + UnitOfConductivity, UnitOfElectricPotential, UnitOfMass, UnitOfPressure, @@ -53,7 +53,7 @@ SENSOR_DESCRIPTIONS = { (DeviceClass.CONDUCTIVITY, Units.CONDUCTIVITY): SensorEntityDescription( key=str(Units.CONDUCTIVITY), device_class=None, - native_unit_of_measurement=CONDUCTIVITY, + native_unit_of_measurement=UnitOfConductivity.MICROSIEMENS, state_class=SensorStateClass.MEASUREMENT, ), ( diff --git a/homeassistant/const.py b/homeassistant/const.py index da059d4230d8..577e8df6f39d 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -1129,8 +1129,21 @@ _DEPRECATED_MASS_POUNDS: Final = DeprecatedConstantEnum( ) """Deprecated: please use UnitOfMass.POUNDS""" + # Conductivity units -CONDUCTIVITY: Final = "µS/cm" +class UnitOfConductivity(StrEnum): + """Conductivity units.""" + + SIEMENS = "S/cm" + MICROSIEMENS = "µS/cm" + MILLISIEMENS = "mS/cm" + + +_DEPRECATED_CONDUCTIVITY: Final = DeprecatedConstantEnum( + UnitOfConductivity.MICROSIEMENS, + "2025.6", +) +"""Deprecated: please use UnitOfConductivity.MICROSIEMENS""" # Light units LIGHT_LUX: Final = "lx" diff --git a/homeassistant/util/unit_conversion.py b/homeassistant/util/unit_conversion.py index 04ce0715192e..2b9f73afab7e 100644 --- a/homeassistant/util/unit_conversion.py +++ b/homeassistant/util/unit_conversion.py @@ -10,6 +10,7 @@ from homeassistant.const import ( CONCENTRATION_PARTS_PER_MILLION, PERCENTAGE, UNIT_NOT_RECOGNIZED_TEMPLATE, + UnitOfConductivity, UnitOfDataRate, UnitOfElectricCurrent, UnitOfElectricPotential, @@ -169,6 +170,19 @@ class DistanceConverter(BaseUnitConverter): } +class ConductivityConverter(BaseUnitConverter): + """Utility to convert electric current values.""" + + UNIT_CLASS = "conductivity" + NORMALIZED_UNIT = UnitOfConductivity.MICROSIEMENS + _UNIT_CONVERSION: dict[str | None, float] = { + UnitOfConductivity.MICROSIEMENS: 1, + UnitOfConductivity.MILLISIEMENS: 1e-3, + UnitOfConductivity.SIEMENS: 1e-6, + } + VALID_UNITS = set(UnitOfConductivity) + + class ElectricCurrentConverter(BaseUnitConverter): """Utility to convert electric current values.""" diff --git a/tests/components/plant/test_init.py b/tests/components/plant/test_init.py index 97286a28cdec..122ac3b75d1f 100644 --- a/tests/components/plant/test_init.py +++ b/tests/components/plant/test_init.py @@ -6,11 +6,11 @@ from homeassistant.components import plant from homeassistant.components.recorder import Recorder from homeassistant.const import ( ATTR_UNIT_OF_MEASUREMENT, - CONDUCTIVITY, LIGHT_LUX, STATE_OK, STATE_PROBLEM, STATE_UNAVAILABLE, + UnitOfConductivity, ) from homeassistant.core import HomeAssistant, State from homeassistant.setup import async_setup_component @@ -79,7 +79,9 @@ async def test_low_battery(hass: HomeAssistant) -> None: async def test_initial_states(hass: HomeAssistant) -> None: """Test plant initialises attributes if sensor already exists.""" - hass.states.async_set(MOISTURE_ENTITY, 5, {ATTR_UNIT_OF_MEASUREMENT: CONDUCTIVITY}) + hass.states.async_set( + MOISTURE_ENTITY, 5, {ATTR_UNIT_OF_MEASUREMENT: UnitOfConductivity.MICROSIEMENS} + ) plant_name = "some_plant" assert await async_setup_component( hass, plant.DOMAIN, {plant.DOMAIN: {plant_name: GOOD_CONFIG}} @@ -98,7 +100,9 @@ async def test_update_states(hass: HomeAssistant) -> None: assert await async_setup_component( hass, plant.DOMAIN, {plant.DOMAIN: {plant_name: GOOD_CONFIG}} ) - hass.states.async_set(MOISTURE_ENTITY, 5, {ATTR_UNIT_OF_MEASUREMENT: CONDUCTIVITY}) + hass.states.async_set( + MOISTURE_ENTITY, 5, {ATTR_UNIT_OF_MEASUREMENT: UnitOfConductivity.MICROSIEMENS} + ) await hass.async_block_till_done() state = hass.states.get(f"plant.{plant_name}") assert state.state == STATE_PROBLEM @@ -115,7 +119,9 @@ async def test_unavailable_state(hass: HomeAssistant) -> None: hass, plant.DOMAIN, {plant.DOMAIN: {plant_name: GOOD_CONFIG}} ) hass.states.async_set( - MOISTURE_ENTITY, STATE_UNAVAILABLE, {ATTR_UNIT_OF_MEASUREMENT: CONDUCTIVITY} + MOISTURE_ENTITY, + STATE_UNAVAILABLE, + {ATTR_UNIT_OF_MEASUREMENT: UnitOfConductivity.MICROSIEMENS}, ) await hass.async_block_till_done() state = hass.states.get(f"plant.{plant_name}") @@ -132,13 +138,17 @@ async def test_state_problem_if_unavailable(hass: HomeAssistant) -> None: assert await async_setup_component( hass, plant.DOMAIN, {plant.DOMAIN: {plant_name: GOOD_CONFIG}} ) - hass.states.async_set(MOISTURE_ENTITY, 42, {ATTR_UNIT_OF_MEASUREMENT: CONDUCTIVITY}) + hass.states.async_set( + MOISTURE_ENTITY, 42, {ATTR_UNIT_OF_MEASUREMENT: UnitOfConductivity.MICROSIEMENS} + ) await hass.async_block_till_done() state = hass.states.get(f"plant.{plant_name}") assert state.state == STATE_OK assert state.attributes[plant.READING_MOISTURE] == 42 hass.states.async_set( - MOISTURE_ENTITY, STATE_UNAVAILABLE, {ATTR_UNIT_OF_MEASUREMENT: CONDUCTIVITY} + MOISTURE_ENTITY, + STATE_UNAVAILABLE, + {ATTR_UNIT_OF_MEASUREMENT: UnitOfConductivity.MICROSIEMENS}, ) await hass.async_block_till_done() state = hass.states.get(f"plant.{plant_name}") diff --git a/tests/components/sensor/test_device_condition.py b/tests/components/sensor/test_device_condition.py index 5f0646db8db5..3bc9a660e93e 100644 --- a/tests/components/sensor/test_device_condition.py +++ b/tests/components/sensor/test_device_condition.py @@ -58,6 +58,7 @@ 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.CONDUCTIVITY: "CONF_IS_CONDUCTIVITY", SensorDeviceClass.ENERGY_STORAGE: "CONF_IS_ENERGY", SensorDeviceClass.VOLUME_STORAGE: "CONF_IS_VOLUME", }.get(device_class, f"CONF_IS_{device_class.value.upper()}") @@ -66,6 +67,7 @@ def test_matches_device_classes(device_class: SensorDeviceClass) -> None: # Ensure it has correct value constant_value = { SensorDeviceClass.BATTERY: "is_battery_level", + SensorDeviceClass.CONDUCTIVITY: "is_conductivity", SensorDeviceClass.ENERGY_STORAGE: "is_energy", SensorDeviceClass.VOLUME_STORAGE: "is_volume", }.get(device_class, f"is_{device_class.value}") diff --git a/tests/components/sensor/test_device_trigger.py b/tests/components/sensor/test_device_trigger.py index 71c844e428aa..87a6d9929c30 100644 --- a/tests/components/sensor/test_device_trigger.py +++ b/tests/components/sensor/test_device_trigger.py @@ -62,6 +62,7 @@ def test_matches_device_classes(device_class: SensorDeviceClass) -> None: SensorDeviceClass.BATTERY: "CONF_BATTERY_LEVEL", SensorDeviceClass.CO: "CONF_CO", SensorDeviceClass.CO2: "CONF_CO2", + SensorDeviceClass.CONDUCTIVITY: "CONF_CONDUCTIVITY", SensorDeviceClass.ENERGY_STORAGE: "CONF_ENERGY", SensorDeviceClass.VOLUME_STORAGE: "CONF_VOLUME", }.get(device_class, f"CONF_{device_class.value.upper()}") @@ -70,6 +71,7 @@ def test_matches_device_classes(device_class: SensorDeviceClass) -> None: # Ensure it has correct value constant_value = { SensorDeviceClass.BATTERY: "battery_level", + SensorDeviceClass.CONDUCTIVITY: "conductivity", SensorDeviceClass.ENERGY_STORAGE: "energy", SensorDeviceClass.VOLUME_STORAGE: "volume", }.get(device_class, device_class.value) diff --git a/tests/util/test_unit_conversion.py b/tests/util/test_unit_conversion.py index efac252aa5f0..98a6a1da5a66 100644 --- a/tests/util/test_unit_conversion.py +++ b/tests/util/test_unit_conversion.py @@ -11,6 +11,7 @@ from homeassistant.const import ( CONCENTRATION_PARTS_PER_BILLION, CONCENTRATION_PARTS_PER_MILLION, PERCENTAGE, + UnitOfConductivity, UnitOfDataRate, UnitOfElectricCurrent, UnitOfElectricPotential, @@ -31,6 +32,7 @@ from homeassistant.exceptions import HomeAssistantError from homeassistant.util import unit_conversion from homeassistant.util.unit_conversion import ( BaseUnitConverter, + ConductivityConverter, DataRateConverter, DistanceConverter, DurationConverter, @@ -57,6 +59,7 @@ INVALID_SYMBOL = "bob" _ALL_CONVERTERS: dict[type[BaseUnitConverter], list[str | None]] = { converter: sorted(converter.VALID_UNITS, key=lambda x: (x is None, x)) for converter in ( + ConductivityConverter, DataRateConverter, DistanceConverter, DurationConverter, @@ -77,6 +80,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]] = { + ConductivityConverter: ( + UnitOfConductivity.MICROSIEMENS, + UnitOfConductivity.MILLISIEMENS, + 1000, + ), DataRateConverter: ( UnitOfDataRate.BITS_PER_SECOND, UnitOfDataRate.BYTES_PER_SECOND, @@ -122,6 +130,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]] ] = { + ConductivityConverter: [ + (5, UnitOfConductivity.SIEMENS, 5e3, UnitOfConductivity.MILLISIEMENS), + (5, UnitOfConductivity.SIEMENS, 5e6, UnitOfConductivity.MICROSIEMENS), + (5, UnitOfConductivity.MILLISIEMENS, 5e3, UnitOfConductivity.MICROSIEMENS), + (5, UnitOfConductivity.MILLISIEMENS, 5e-3, UnitOfConductivity.SIEMENS), + (5e6, UnitOfConductivity.MICROSIEMENS, 5e3, UnitOfConductivity.MILLISIEMENS), + (5e6, UnitOfConductivity.MICROSIEMENS, 5, UnitOfConductivity.SIEMENS), + ], DataRateConverter: [ (8e3, UnitOfDataRate.BITS_PER_SECOND, 8, UnitOfDataRate.KILOBITS_PER_SECOND), (8e6, UnitOfDataRate.BITS_PER_SECOND, 8, UnitOfDataRate.MEGABITS_PER_SECOND),