diff --git a/homeassistant/components/zwave_js/discovery_data_template.py b/homeassistant/components/zwave_js/discovery_data_template.py index ea05005deae..2d8e895d9df 100644 --- a/homeassistant/components/zwave_js/discovery_data_template.py +++ b/homeassistant/components/zwave_js/discovery_data_template.py @@ -11,6 +11,13 @@ from zwave_js_server.const.command_class.meter import ( ENERGY_TOTAL_INCREASING_METER_TYPES, POWER_FACTOR_METER_TYPES, POWER_METER_TYPES, + UNIT_AMPERE as METER_UNIT_AMPERE, + UNIT_CUBIC_FEET, + UNIT_CUBIC_METER as METER_UNIT_CUBIC_METER, + UNIT_KILOWATT_HOUR, + UNIT_US_GALLON, + UNIT_VOLT as METER_UNIT_VOLT, + UNIT_WATT as METER_UNIT_WATT, VOLTAGE_METER_TYPES, ElectricScale, MeterScaleType, @@ -26,16 +33,97 @@ from zwave_js_server.const.command_class.multilevel_sensor import ( PRESSURE_SENSORS, SIGNAL_STRENGTH_SENSORS, TEMPERATURE_SENSORS, + UNIT_AMPERE as SENSOR_UNIT_AMPERE, + UNIT_BTU_H, + UNIT_CELSIUS, + UNIT_CENTIMETER, + UNIT_CUBIC_FEET_PER_MINUTE, + UNIT_CUBIC_METER as SENSOR_UNIT_CUBIC_METER, + UNIT_CUBIC_METER_PER_HOUR, + UNIT_DECIBEL, + UNIT_DEGREES, + UNIT_DENSITY, + UNIT_FAHRENHEIT, + UNIT_FEET, + UNIT_GALLONS, + UNIT_HERTZ, + UNIT_INCHES_OF_MERCURY, + UNIT_INCHES_PER_HOUR, + UNIT_KILOGRAM, + UNIT_KILOHERTZ, + UNIT_LITER, + UNIT_LUX, + UNIT_M_S, + UNIT_METER, + UNIT_MICROGRAM_PER_CUBIC_METER, + UNIT_MILLIAMPERE, + UNIT_MILLIMETER_HOUR, + UNIT_MILLIVOLT, + UNIT_MPH, + UNIT_PARTS_MILLION, + UNIT_PERCENTAGE_VALUE, + UNIT_POUND_PER_SQUARE_INCH, + UNIT_POUNDS, + UNIT_POWER_LEVEL, + UNIT_RSSI, + UNIT_SECOND, + UNIT_SYSTOLIC, + UNIT_VOLT as SENSOR_UNIT_VOLT, + UNIT_WATT as SENSOR_UNIT_WATT, + UNIT_WATT_PER_SQUARE_METER, VOLTAGE_SENSORS, + MultilevelSensorScaleType, MultilevelSensorType, ) from zwave_js_server.model.node import Node as ZwaveNode from zwave_js_server.model.value import Value as ZwaveValue, get_value_id from zwave_js_server.util.command_class.meter import get_meter_scale_type from zwave_js_server.util.command_class.multilevel_sensor import ( + get_multilevel_sensor_scale_type, get_multilevel_sensor_type, ) +from homeassistant.const import ( + CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, + CONCENTRATION_PARTS_PER_MILLION, + DEGREE, + ELECTRIC_CURRENT_AMPERE, + ELECTRIC_CURRENT_MILLIAMPERE, + ELECTRIC_POTENTIAL_MILLIVOLT, + ELECTRIC_POTENTIAL_VOLT, + ENERGY_KILO_WATT_HOUR, + FREQUENCY_HERTZ, + FREQUENCY_KILOHERTZ, + IRRADIATION_WATTS_PER_SQUARE_METER, + LENGTH_CENTIMETERS, + LENGTH_FEET, + LENGTH_METERS, + LIGHT_LUX, + MASS_KILOGRAMS, + MASS_POUNDS, + PERCENTAGE, + POWER_BTU_PER_HOUR, + POWER_WATT, + PRECIPITATION_INCHES_PER_HOUR, + PRECIPITATION_MILLIMETERS_PER_HOUR, + PRESSURE_INHG, + PRESSURE_MMHG, + PRESSURE_PSI, + SIGNAL_STRENGTH_DECIBELS, + SIGNAL_STRENGTH_DECIBELS_MILLIWATT, + SPEED_METERS_PER_SECOND, + SPEED_MILES_PER_HOUR, + TEMP_CELSIUS, + TEMP_FAHRENHEIT, + TIME_SECONDS, + VOLUME_CUBIC_FEET, + VOLUME_CUBIC_METERS, + VOLUME_FLOW_RATE_CUBIC_FEET_PER_MINUTE, + VOLUME_FLOW_RATE_CUBIC_METERS_PER_HOUR, + VOLUME_GALLONS, + VOLUME_LITERS, +) + from .const import ( ENTITY_DESC_KEY_BATTERY, ENTITY_DESC_KEY_CO, @@ -78,6 +166,58 @@ MULTILEVEL_SENSOR_DEVICE_CLASS_MAP: dict[str, set[MultilevelSensorType]] = { ENTITY_DESC_KEY_VOLTAGE: VOLTAGE_SENSORS, } +METER_UNIT_MAP: dict[str, set[MeterScaleType]] = { + ELECTRIC_CURRENT_AMPERE: METER_UNIT_AMPERE, + VOLUME_CUBIC_FEET: UNIT_CUBIC_FEET, + VOLUME_CUBIC_METERS: METER_UNIT_CUBIC_METER, + VOLUME_GALLONS: UNIT_US_GALLON, + ENERGY_KILO_WATT_HOUR: UNIT_KILOWATT_HOUR, + ELECTRIC_POTENTIAL_VOLT: METER_UNIT_VOLT, + POWER_WATT: METER_UNIT_WATT, +} + +MULTILEVEL_SENSOR_UNIT_MAP: dict[str, set[MultilevelSensorScaleType]] = { + ELECTRIC_CURRENT_AMPERE: SENSOR_UNIT_AMPERE, + POWER_BTU_PER_HOUR: UNIT_BTU_H, + TEMP_CELSIUS: UNIT_CELSIUS, + LENGTH_CENTIMETERS: UNIT_CENTIMETER, + VOLUME_FLOW_RATE_CUBIC_FEET_PER_MINUTE: UNIT_CUBIC_FEET_PER_MINUTE, + VOLUME_CUBIC_METERS: SENSOR_UNIT_CUBIC_METER, + VOLUME_FLOW_RATE_CUBIC_METERS_PER_HOUR: UNIT_CUBIC_METER_PER_HOUR, + SIGNAL_STRENGTH_DECIBELS: UNIT_DECIBEL, + DEGREE: UNIT_DEGREES, + CONCENTRATION_MICROGRAMS_PER_CUBIC_METER: { + *UNIT_DENSITY, + *UNIT_MICROGRAM_PER_CUBIC_METER, + }, + TEMP_FAHRENHEIT: UNIT_FAHRENHEIT, + LENGTH_FEET: UNIT_FEET, + VOLUME_GALLONS: UNIT_GALLONS, + FREQUENCY_HERTZ: UNIT_HERTZ, + PRESSURE_INHG: UNIT_INCHES_OF_MERCURY, + PRECIPITATION_INCHES_PER_HOUR: UNIT_INCHES_PER_HOUR, + MASS_KILOGRAMS: UNIT_KILOGRAM, + FREQUENCY_KILOHERTZ: UNIT_KILOHERTZ, + VOLUME_LITERS: UNIT_LITER, + LIGHT_LUX: UNIT_LUX, + LENGTH_METERS: UNIT_METER, + ELECTRIC_CURRENT_MILLIAMPERE: UNIT_MILLIAMPERE, + PRECIPITATION_MILLIMETERS_PER_HOUR: UNIT_MILLIMETER_HOUR, + ELECTRIC_POTENTIAL_MILLIVOLT: UNIT_MILLIVOLT, + SPEED_MILES_PER_HOUR: UNIT_MPH, + SPEED_METERS_PER_SECOND: UNIT_M_S, + CONCENTRATION_PARTS_PER_MILLION: UNIT_PARTS_MILLION, + PERCENTAGE: {*UNIT_PERCENTAGE_VALUE, *UNIT_RSSI}, + MASS_POUNDS: UNIT_POUNDS, + PRESSURE_PSI: UNIT_POUND_PER_SQUARE_INCH, + SIGNAL_STRENGTH_DECIBELS_MILLIWATT: UNIT_POWER_LEVEL, + TIME_SECONDS: UNIT_SECOND, + PRESSURE_MMHG: UNIT_SYSTOLIC, + ELECTRIC_POTENTIAL_VOLT: SENSOR_UNIT_VOLT, + POWER_WATT: SENSOR_UNIT_WATT, + IRRADIATION_WATTS_PER_SQUARE_METER: UNIT_WATT_PER_SQUARE_METER, +} + @dataclass class ZwaveValueID: @@ -154,10 +294,8 @@ class DynamicCurrentTempClimateDataTemplate(BaseDiscoverySchemaDataTemplate): value.node, self.dependent_value ), } - for key in self.lookup_table: - data["lookup_table"][key] = self._get_value_from_id( - value.node, self.lookup_table[key] - ) + for key, value_id in self.lookup_table.items(): + data["lookup_table"][key] = self._get_value_from_id(value.node, value_id) return data @@ -183,17 +321,45 @@ class DynamicCurrentTempClimateDataTemplate(BaseDiscoverySchemaDataTemplate): return None +@dataclass +class NumericSensorDataTemplateData: + """Class to represent returned data from NumericSensorDataTemplate.""" + + entity_description_key: str | None = None + unit_of_measurement: str | None = None + + class NumericSensorDataTemplate(BaseDiscoverySchemaDataTemplate): """Data template class for Z-Wave Sensor entities.""" - def resolve_data(self, value: ZwaveValue) -> str | None: + @staticmethod + def find_key_from_matching_set( + enum_value: MultilevelSensorType | MultilevelSensorScaleType | MeterScaleType, + set_map: dict[ + str, set[MultilevelSensorType | MultilevelSensorScaleType | MeterScaleType] + ], + ) -> str | None: + """Find a key in a set map that matches a given enum value.""" + for key, value_set in set_map.items(): + for value_in_set in value_set: + # Since these are IntEnums and the different classes reuse the same + # values, we need to match the class as well + if ( + value_in_set.__class__ == enum_value.__class__ + and value_in_set == enum_value + ): + return key + return None + + def resolve_data(self, value: ZwaveValue) -> NumericSensorDataTemplateData: """Resolve helper class data for a discovered value.""" if value.command_class == CommandClass.BATTERY: - return ENTITY_DESC_KEY_BATTERY + return NumericSensorDataTemplateData(ENTITY_DESC_KEY_BATTERY, PERCENTAGE) if value.command_class == CommandClass.METER: scale_type = get_meter_scale_type(value) + unit = self.find_key_from_matching_set(scale_type, METER_UNIT_MAP) # We do this because even though these are energy scales, they don't meet # the unit requirements for the energy device class. if scale_type in ( @@ -201,28 +367,36 @@ class NumericSensorDataTemplate(BaseDiscoverySchemaDataTemplate): ElectricScale.KILOVOLT_AMPERE_HOUR, ElectricScale.KILOVOLT_AMPERE_REACTIVE_HOUR, ): - return ENTITY_DESC_KEY_TOTAL_INCREASING + return NumericSensorDataTemplateData( + ENTITY_DESC_KEY_TOTAL_INCREASING, unit + ) # We do this because even though these are power scales, they don't meet # the unit requirements for the power device class. if scale_type == ElectricScale.KILOVOLT_AMPERE_REACTIVE: - return ENTITY_DESC_KEY_MEASUREMENT + return NumericSensorDataTemplateData(ENTITY_DESC_KEY_MEASUREMENT, unit) - for key, scale_type_set in METER_DEVICE_CLASS_MAP.items(): - if scale_type in scale_type_set: - return key + return NumericSensorDataTemplateData( + self.find_key_from_matching_set(scale_type, METER_DEVICE_CLASS_MAP), + unit, + ) if value.command_class == CommandClass.SENSOR_MULTILEVEL: sensor_type = get_multilevel_sensor_type(value) + scale_type = get_multilevel_sensor_scale_type(value) + unit = self.find_key_from_matching_set( + scale_type, MULTILEVEL_SENSOR_UNIT_MAP + ) if sensor_type == MultilevelSensorType.TARGET_TEMPERATURE: - return ENTITY_DESC_KEY_TARGET_TEMPERATURE - for ( - key, - sensor_type_set, - ) in MULTILEVEL_SENSOR_DEVICE_CLASS_MAP.items(): - if sensor_type in sensor_type_set: - return key + return NumericSensorDataTemplateData( + ENTITY_DESC_KEY_TARGET_TEMPERATURE, unit + ) + key = self.find_key_from_matching_set( + sensor_type, MULTILEVEL_SENSOR_DEVICE_CLASS_MAP + ) + if key: + return NumericSensorDataTemplateData(key, unit) - return None + return NumericSensorDataTemplateData() @dataclass diff --git a/homeassistant/components/zwave_js/sensor.py b/homeassistant/components/zwave_js/sensor.py index b8b8cb4b978..549df9f6264 100644 --- a/homeassistant/components/zwave_js/sensor.py +++ b/homeassistant/components/zwave_js/sensor.py @@ -2,7 +2,6 @@ from __future__ import annotations from collections.abc import Mapping -from dataclasses import dataclass import logging from typing import cast @@ -25,6 +24,9 @@ from homeassistant.components.sensor import ( SensorEntity, SensorEntityDescription, ) +from homeassistant.components.zwave_js.discovery_data_template import ( + NumericSensorDataTemplateData, +) from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( DEVICE_CLASS_BATTERY, @@ -40,8 +42,6 @@ from homeassistant.const import ( DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_VOLTAGE, ENTITY_CATEGORY_DIAGNOSTIC, - TEMP_CELSIUS, - TEMP_FAHRENHEIT, ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_platform @@ -89,98 +89,91 @@ STATUS_ICON: dict[NodeStatus, str] = { } -@dataclass -class ZwaveSensorEntityDescription(SensorEntityDescription): - """Base description of a Zwave Sensor entity.""" - - info: ZwaveDiscoveryInfo | None = None - - -ENTITY_DESCRIPTION_KEY_MAP: dict[str, ZwaveSensorEntityDescription] = { - ENTITY_DESC_KEY_BATTERY: ZwaveSensorEntityDescription( +ENTITY_DESCRIPTION_KEY_MAP: dict[str, SensorEntityDescription] = { + ENTITY_DESC_KEY_BATTERY: SensorEntityDescription( ENTITY_DESC_KEY_BATTERY, device_class=DEVICE_CLASS_BATTERY, entity_category=ENTITY_CATEGORY_DIAGNOSTIC, state_class=STATE_CLASS_MEASUREMENT, ), - ENTITY_DESC_KEY_CURRENT: ZwaveSensorEntityDescription( + ENTITY_DESC_KEY_CURRENT: SensorEntityDescription( ENTITY_DESC_KEY_CURRENT, device_class=DEVICE_CLASS_CURRENT, state_class=STATE_CLASS_MEASUREMENT, ), - ENTITY_DESC_KEY_VOLTAGE: ZwaveSensorEntityDescription( + ENTITY_DESC_KEY_VOLTAGE: SensorEntityDescription( ENTITY_DESC_KEY_VOLTAGE, device_class=DEVICE_CLASS_VOLTAGE, state_class=STATE_CLASS_MEASUREMENT, ), - ENTITY_DESC_KEY_ENERGY_MEASUREMENT: ZwaveSensorEntityDescription( + ENTITY_DESC_KEY_ENERGY_MEASUREMENT: SensorEntityDescription( ENTITY_DESC_KEY_ENERGY_MEASUREMENT, device_class=DEVICE_CLASS_ENERGY, state_class=STATE_CLASS_MEASUREMENT, ), - ENTITY_DESC_KEY_ENERGY_TOTAL_INCREASING: ZwaveSensorEntityDescription( + ENTITY_DESC_KEY_ENERGY_TOTAL_INCREASING: SensorEntityDescription( ENTITY_DESC_KEY_ENERGY_TOTAL_INCREASING, device_class=DEVICE_CLASS_ENERGY, state_class=STATE_CLASS_TOTAL_INCREASING, ), - ENTITY_DESC_KEY_POWER: ZwaveSensorEntityDescription( + ENTITY_DESC_KEY_POWER: SensorEntityDescription( ENTITY_DESC_KEY_POWER, device_class=DEVICE_CLASS_POWER, state_class=STATE_CLASS_MEASUREMENT, ), - ENTITY_DESC_KEY_POWER_FACTOR: ZwaveSensorEntityDescription( + ENTITY_DESC_KEY_POWER_FACTOR: SensorEntityDescription( ENTITY_DESC_KEY_POWER_FACTOR, device_class=DEVICE_CLASS_POWER_FACTOR, state_class=STATE_CLASS_MEASUREMENT, ), - ENTITY_DESC_KEY_CO: ZwaveSensorEntityDescription( + ENTITY_DESC_KEY_CO: SensorEntityDescription( ENTITY_DESC_KEY_CO, device_class=DEVICE_CLASS_CO, state_class=STATE_CLASS_MEASUREMENT, ), - ENTITY_DESC_KEY_CO2: ZwaveSensorEntityDescription( + ENTITY_DESC_KEY_CO2: SensorEntityDescription( ENTITY_DESC_KEY_CO2, device_class=DEVICE_CLASS_CO2, state_class=STATE_CLASS_MEASUREMENT, ), - ENTITY_DESC_KEY_HUMIDITY: ZwaveSensorEntityDescription( + ENTITY_DESC_KEY_HUMIDITY: SensorEntityDescription( ENTITY_DESC_KEY_HUMIDITY, device_class=DEVICE_CLASS_HUMIDITY, state_class=STATE_CLASS_MEASUREMENT, ), - ENTITY_DESC_KEY_ILLUMINANCE: ZwaveSensorEntityDescription( + ENTITY_DESC_KEY_ILLUMINANCE: SensorEntityDescription( ENTITY_DESC_KEY_ILLUMINANCE, device_class=DEVICE_CLASS_ILLUMINANCE, state_class=STATE_CLASS_MEASUREMENT, ), - ENTITY_DESC_KEY_PRESSURE: ZwaveSensorEntityDescription( + ENTITY_DESC_KEY_PRESSURE: SensorEntityDescription( ENTITY_DESC_KEY_PRESSURE, device_class=DEVICE_CLASS_PRESSURE, state_class=STATE_CLASS_MEASUREMENT, ), - ENTITY_DESC_KEY_SIGNAL_STRENGTH: ZwaveSensorEntityDescription( + ENTITY_DESC_KEY_SIGNAL_STRENGTH: SensorEntityDescription( ENTITY_DESC_KEY_SIGNAL_STRENGTH, device_class=DEVICE_CLASS_SIGNAL_STRENGTH, entity_category=ENTITY_CATEGORY_DIAGNOSTIC, entity_registry_enabled_default=False, state_class=STATE_CLASS_MEASUREMENT, ), - ENTITY_DESC_KEY_TEMPERATURE: ZwaveSensorEntityDescription( + ENTITY_DESC_KEY_TEMPERATURE: SensorEntityDescription( ENTITY_DESC_KEY_TEMPERATURE, device_class=DEVICE_CLASS_TEMPERATURE, state_class=STATE_CLASS_MEASUREMENT, ), - ENTITY_DESC_KEY_TARGET_TEMPERATURE: ZwaveSensorEntityDescription( + ENTITY_DESC_KEY_TARGET_TEMPERATURE: SensorEntityDescription( ENTITY_DESC_KEY_TARGET_TEMPERATURE, device_class=DEVICE_CLASS_TEMPERATURE, state_class=None, ), - ENTITY_DESC_KEY_MEASUREMENT: ZwaveSensorEntityDescription( + ENTITY_DESC_KEY_MEASUREMENT: SensorEntityDescription( ENTITY_DESC_KEY_MEASUREMENT, device_class=None, state_class=STATE_CLASS_MEASUREMENT, ), - ENTITY_DESC_KEY_TOTAL_INCREASING: ZwaveSensorEntityDescription( + ENTITY_DESC_KEY_TOTAL_INCREASING: SensorEntityDescription( ENTITY_DESC_KEY_TOTAL_INCREASING, device_class=None, state_class=STATE_CLASS_TOTAL_INCREASING, @@ -201,25 +194,42 @@ async def async_setup_entry( """Add Z-Wave Sensor.""" entities: list[ZWaveBaseEntity] = [] + if info.platform_data: + data: NumericSensorDataTemplateData = info.platform_data + else: + data = NumericSensorDataTemplateData() entity_description = ENTITY_DESCRIPTION_KEY_MAP.get( - info.platform_data - ) or ZwaveSensorEntityDescription("base_sensor") - entity_description.info = info + data.entity_description_key or "", SensorEntityDescription("base_sensor") + ) if info.platform_hint == "string_sensor": - entities.append(ZWaveStringSensor(config_entry, client, entity_description)) + entities.append( + ZWaveStringSensor(config_entry, client, info, entity_description) + ) elif info.platform_hint == "numeric_sensor": entities.append( - ZWaveNumericSensor(config_entry, client, entity_description) + ZWaveNumericSensor( + config_entry, + client, + info, + entity_description, + data.unit_of_measurement, + ) ) elif info.platform_hint == "list_sensor": - entities.append(ZWaveListSensor(config_entry, client, entity_description)) + entities.append( + ZWaveListSensor(config_entry, client, info, entity_description) + ) elif info.platform_hint == "config_parameter": entities.append( - ZWaveConfigParameterSensor(config_entry, client, entity_description) + ZWaveConfigParameterSensor( + config_entry, client, info, entity_description + ) ) elif info.platform_hint == "meter": - entities.append(ZWaveMeterSensor(config_entry, client, entity_description)) + entities.append( + ZWaveMeterSensor(config_entry, client, info, entity_description) + ) else: LOGGER.warning( "Sensor not implemented for %s/%s", @@ -269,12 +279,14 @@ class ZwaveSensorBase(ZWaveBaseEntity, SensorEntity): self, config_entry: ConfigEntry, client: ZwaveClient, - entity_description: ZwaveSensorEntityDescription, + info: ZwaveDiscoveryInfo, + entity_description: SensorEntityDescription, + unit_of_measurement: str | None = None, ) -> None: """Initialize a ZWaveSensorBase entity.""" - assert entity_description.info - super().__init__(config_entry, client, entity_description.info) + super().__init__(config_entry, client, info) self.entity_description = entity_description + self._attr_native_unit_of_measurement = unit_of_measurement # Entity class attributes self._attr_force_update = True @@ -312,12 +324,10 @@ class ZWaveNumericSensor(ZwaveSensorBase): @property def native_unit_of_measurement(self) -> str | None: """Return unit of measurement the value is expressed in.""" + if self._attr_native_unit_of_measurement is not None: + return self._attr_native_unit_of_measurement if self.info.primary_value.metadata.unit is None: return None - if self.info.primary_value.metadata.unit == "C": - return TEMP_CELSIUS - if self.info.primary_value.metadata.unit == "F": - return TEMP_FAHRENHEIT return str(self.info.primary_value.metadata.unit) @@ -365,10 +375,14 @@ class ZWaveListSensor(ZwaveSensorBase): self, config_entry: ConfigEntry, client: ZwaveClient, - entity_description: ZwaveSensorEntityDescription, + info: ZwaveDiscoveryInfo, + entity_description: SensorEntityDescription, + unit_of_measurement: str | None = None, ) -> None: """Initialize a ZWaveListSensor entity.""" - super().__init__(config_entry, client, entity_description) + super().__init__( + config_entry, client, info, entity_description, unit_of_measurement + ) # Entity class attributes self._attr_name = self.generate_name( @@ -405,10 +419,14 @@ class ZWaveConfigParameterSensor(ZwaveSensorBase): self, config_entry: ConfigEntry, client: ZwaveClient, - entity_description: ZwaveSensorEntityDescription, + info: ZwaveDiscoveryInfo, + entity_description: SensorEntityDescription, + unit_of_measurement: str | None = None, ) -> None: """Initialize a ZWaveConfigParameterSensor entity.""" - super().__init__(config_entry, client, entity_description) + super().__init__( + config_entry, client, info, entity_description, unit_of_measurement + ) self._primary_value = cast(ConfigurationValue, self.info.primary_value) # Entity class attributes diff --git a/homeassistant/const.py b/homeassistant/const.py index 6c808ffd3b3..43e07036cb8 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -421,6 +421,7 @@ ATTR_TEMPERATURE: Final = "temperature" POWER_WATT: Final = "W" POWER_KILO_WATT: Final = "kW" POWER_VOLT_AMPERE: Final = "VA" +POWER_BTU_PER_HOUR: Final = "BTU/h" # Energy units ENERGY_WATT_HOUR: Final = "Wh" @@ -472,6 +473,7 @@ LENGTH_MILES: Final = "mi" # Frequency units FREQUENCY_HERTZ: Final = "Hz" +FREQUENCY_KILOHERTZ: Final = "kHz" FREQUENCY_MEGAHERTZ: Final = "MHz" FREQUENCY_GIGAHERTZ: Final = "GHz" @@ -482,6 +484,7 @@ PRESSURE_KPA: Final = "kPa" PRESSURE_BAR: Final = "bar" PRESSURE_CBAR: Final = "cbar" PRESSURE_MBAR: Final = "mbar" +PRESSURE_MMHG: Final = "mmHg" PRESSURE_INHG: Final = "inHg" PRESSURE_PSI: Final = "psi"