diff --git a/homeassistant/components/nam/const.py b/homeassistant/components/nam/const.py index f60d03eea78..85472deba06 100644 --- a/homeassistant/components/nam/const.py +++ b/homeassistant/components/nam/const.py @@ -4,10 +4,11 @@ from __future__ import annotations from datetime import timedelta from typing import Final -from homeassistant.components.sensor import ATTR_STATE_CLASS, STATE_CLASS_MEASUREMENT +from homeassistant.components.sensor import ( + STATE_CLASS_MEASUREMENT, + SensorEntityDescription, +) from homeassistant.const import ( - ATTR_DEVICE_CLASS, - ATTR_ICON, CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, CONCENTRATION_PARTS_PER_MILLION, DEVICE_CLASS_CO2, @@ -22,8 +23,6 @@ from homeassistant.const import ( TEMP_CELSIUS, ) -from .model import SensorDescription - SUFFIX_P0: Final = "_p0" SUFFIX_P1: Final = "_p1" SUFFIX_P2: Final = "_p2" @@ -52,10 +51,6 @@ ATTR_SPS30_P2: Final = f"{ATTR_SPS30}{SUFFIX_P2}" ATTR_SPS30_P4: Final = f"{ATTR_SPS30}{SUFFIX_P4}" ATTR_UPTIME: Final = "uptime" -ATTR_ENABLED: Final = "enabled" -ATTR_LABEL: Final = "label" -ATTR_UNIT: Final = "unit" - DEFAULT_NAME: Final = "Nettigo Air Monitor" DEFAULT_UPDATE_INTERVAL: Final = timedelta(minutes=6) DOMAIN: Final = "nam" @@ -66,165 +61,145 @@ MIGRATION_SENSORS: Final = [ ("humidity", ATTR_DHT22_HUMIDITY), ] -SENSORS: Final[dict[str, SensorDescription]] = { - ATTR_BME280_HUMIDITY: { - ATTR_LABEL: f"{DEFAULT_NAME} BME280 Humidity", - ATTR_UNIT: PERCENTAGE, - ATTR_DEVICE_CLASS: DEVICE_CLASS_HUMIDITY, - ATTR_ICON: None, - ATTR_ENABLED: True, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_BME280_PRESSURE: { - ATTR_LABEL: f"{DEFAULT_NAME} BME280 Pressure", - ATTR_UNIT: PRESSURE_HPA, - ATTR_DEVICE_CLASS: DEVICE_CLASS_PRESSURE, - ATTR_ICON: None, - ATTR_ENABLED: True, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_BME280_TEMPERATURE: { - ATTR_LABEL: f"{DEFAULT_NAME} BME280 Temperature", - ATTR_UNIT: TEMP_CELSIUS, - ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, - ATTR_ICON: None, - ATTR_ENABLED: True, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_BMP280_PRESSURE: { - ATTR_LABEL: f"{DEFAULT_NAME} BMP280 Pressure", - ATTR_UNIT: PRESSURE_HPA, - ATTR_DEVICE_CLASS: DEVICE_CLASS_PRESSURE, - ATTR_ICON: None, - ATTR_ENABLED: True, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_BMP280_TEMPERATURE: { - ATTR_LABEL: f"{DEFAULT_NAME} BMP280 Temperature", - ATTR_UNIT: TEMP_CELSIUS, - ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, - ATTR_ICON: None, - ATTR_ENABLED: True, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_HECA_HUMIDITY: { - ATTR_LABEL: f"{DEFAULT_NAME} HECA Humidity", - ATTR_UNIT: PERCENTAGE, - ATTR_DEVICE_CLASS: DEVICE_CLASS_HUMIDITY, - ATTR_ICON: None, - ATTR_ENABLED: True, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_HECA_TEMPERATURE: { - ATTR_LABEL: f"{DEFAULT_NAME} HECA Temperature", - ATTR_UNIT: TEMP_CELSIUS, - ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, - ATTR_ICON: None, - ATTR_ENABLED: True, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_MHZ14A_CARBON_DIOXIDE: { - ATTR_LABEL: f"{DEFAULT_NAME} MH-Z14A Carbon Dioxide", - ATTR_UNIT: CONCENTRATION_PARTS_PER_MILLION, - ATTR_DEVICE_CLASS: DEVICE_CLASS_CO2, - ATTR_ICON: None, - ATTR_ENABLED: True, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_SDS011_P1: { - ATTR_LABEL: f"{DEFAULT_NAME} SDS011 Particulate Matter 10", - ATTR_UNIT: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, - ATTR_DEVICE_CLASS: None, - ATTR_ICON: "mdi:blur", - ATTR_ENABLED: True, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_SDS011_P2: { - ATTR_LABEL: f"{DEFAULT_NAME} SDS011 Particulate Matter 2.5", - ATTR_UNIT: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, - ATTR_DEVICE_CLASS: None, - ATTR_ICON: "mdi:blur", - ATTR_ENABLED: True, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_SHT3X_HUMIDITY: { - ATTR_LABEL: f"{DEFAULT_NAME} SHT3X Humidity", - ATTR_UNIT: PERCENTAGE, - ATTR_DEVICE_CLASS: DEVICE_CLASS_HUMIDITY, - ATTR_ICON: None, - ATTR_ENABLED: True, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_SHT3X_TEMPERATURE: { - ATTR_LABEL: f"{DEFAULT_NAME} SHT3X Temperature", - ATTR_UNIT: TEMP_CELSIUS, - ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, - ATTR_ICON: None, - ATTR_ENABLED: True, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_SPS30_P0: { - ATTR_LABEL: f"{DEFAULT_NAME} SPS30 Particulate Matter 1.0", - ATTR_UNIT: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, - ATTR_DEVICE_CLASS: None, - ATTR_ICON: "mdi:blur", - ATTR_ENABLED: True, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_SPS30_P1: { - ATTR_LABEL: f"{DEFAULT_NAME} SPS30 Particulate Matter 10", - ATTR_UNIT: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, - ATTR_DEVICE_CLASS: None, - ATTR_ICON: "mdi:blur", - ATTR_ENABLED: True, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_SPS30_P2: { - ATTR_LABEL: f"{DEFAULT_NAME} SPS30 Particulate Matter 2.5", - ATTR_UNIT: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, - ATTR_DEVICE_CLASS: None, - ATTR_ICON: "mdi:blur", - ATTR_ENABLED: True, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_SPS30_P4: { - ATTR_LABEL: f"{DEFAULT_NAME} SPS30 Particulate Matter 4.0", - ATTR_UNIT: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, - ATTR_DEVICE_CLASS: None, - ATTR_ICON: "mdi:blur", - ATTR_ENABLED: True, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_DHT22_HUMIDITY: { - ATTR_LABEL: f"{DEFAULT_NAME} DHT22 Humidity", - ATTR_UNIT: PERCENTAGE, - ATTR_DEVICE_CLASS: DEVICE_CLASS_HUMIDITY, - ATTR_ICON: None, - ATTR_ENABLED: True, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_DHT22_TEMPERATURE: { - ATTR_LABEL: f"{DEFAULT_NAME} DHT22 Temperature", - ATTR_UNIT: TEMP_CELSIUS, - ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE, - ATTR_ICON: None, - ATTR_ENABLED: True, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_SIGNAL_STRENGTH: { - ATTR_LABEL: f"{DEFAULT_NAME} Signal Strength", - ATTR_UNIT: SIGNAL_STRENGTH_DECIBELS_MILLIWATT, - ATTR_DEVICE_CLASS: DEVICE_CLASS_SIGNAL_STRENGTH, - ATTR_ICON: None, - ATTR_ENABLED: False, - ATTR_STATE_CLASS: STATE_CLASS_MEASUREMENT, - }, - ATTR_UPTIME: { - ATTR_LABEL: f"{DEFAULT_NAME} Uptime", - ATTR_UNIT: None, - ATTR_DEVICE_CLASS: DEVICE_CLASS_TIMESTAMP, - ATTR_ICON: None, - ATTR_ENABLED: False, - ATTR_STATE_CLASS: None, - }, -} +SENSORS: Final[tuple[SensorEntityDescription, ...]] = ( + SensorEntityDescription( + key=ATTR_BME280_HUMIDITY, + name=f"{DEFAULT_NAME} BME280 Humidity", + unit_of_measurement=PERCENTAGE, + device_class=DEVICE_CLASS_HUMIDITY, + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_BME280_PRESSURE, + name=f"{DEFAULT_NAME} BME280 Pressure", + unit_of_measurement=PRESSURE_HPA, + device_class=DEVICE_CLASS_PRESSURE, + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_BME280_TEMPERATURE, + name=f"{DEFAULT_NAME} BME280 Temperature", + unit_of_measurement=TEMP_CELSIUS, + device_class=DEVICE_CLASS_TEMPERATURE, + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_BMP280_PRESSURE, + name=f"{DEFAULT_NAME} BMP280 Pressure", + unit_of_measurement=PRESSURE_HPA, + device_class=DEVICE_CLASS_PRESSURE, + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_BMP280_TEMPERATURE, + name=f"{DEFAULT_NAME} BMP280 Temperature", + unit_of_measurement=TEMP_CELSIUS, + device_class=DEVICE_CLASS_TEMPERATURE, + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_HECA_HUMIDITY, + name=f"{DEFAULT_NAME} HECA Humidity", + unit_of_measurement=PERCENTAGE, + device_class=DEVICE_CLASS_HUMIDITY, + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_HECA_TEMPERATURE, + name=f"{DEFAULT_NAME} HECA Temperature", + unit_of_measurement=TEMP_CELSIUS, + device_class=DEVICE_CLASS_TEMPERATURE, + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_MHZ14A_CARBON_DIOXIDE, + name=f"{DEFAULT_NAME} MH-Z14A Carbon Dioxide", + unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION, + device_class=DEVICE_CLASS_CO2, + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_SDS011_P1, + name=f"{DEFAULT_NAME} SDS011 Particulate Matter 10", + unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, + icon="mdi:blur", + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_SDS011_P2, + name=f"{DEFAULT_NAME} SDS011 Particulate Matter 2.5", + unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, + icon="mdi:blur", + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_SHT3X_HUMIDITY, + name=f"{DEFAULT_NAME} SHT3X Humidity", + unit_of_measurement=PERCENTAGE, + device_class=DEVICE_CLASS_HUMIDITY, + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_SHT3X_TEMPERATURE, + name=f"{DEFAULT_NAME} SHT3X Temperature", + unit_of_measurement=TEMP_CELSIUS, + device_class=DEVICE_CLASS_TEMPERATURE, + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_SPS30_P0, + name=f"{DEFAULT_NAME} SPS30 Particulate Matter 1.0", + unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, + icon="mdi:blur", + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_SPS30_P1, + name=f"{DEFAULT_NAME} SPS30 Particulate Matter 10", + unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, + icon="mdi:blur", + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_SPS30_P2, + name=f"{DEFAULT_NAME} SPS30 Particulate Matter 2.5", + unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, + icon="mdi:blur", + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_SPS30_P4, + name=f"{DEFAULT_NAME} SPS30 Particulate Matter 4.0", + unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, + icon="mdi:blur", + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_DHT22_HUMIDITY, + name=f"{DEFAULT_NAME} DHT22 Humidity", + unit_of_measurement=PERCENTAGE, + device_class=DEVICE_CLASS_HUMIDITY, + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_DHT22_TEMPERATURE, + name=f"{DEFAULT_NAME} DHT22 Temperature", + unit_of_measurement=TEMP_CELSIUS, + device_class=DEVICE_CLASS_TEMPERATURE, + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_SIGNAL_STRENGTH, + name=f"{DEFAULT_NAME} Signal Strength", + unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, + device_class=DEVICE_CLASS_SIGNAL_STRENGTH, + entity_registry_enabled_default=False, + state_class=STATE_CLASS_MEASUREMENT, + ), + SensorEntityDescription( + key=ATTR_UPTIME, + name=f"{DEFAULT_NAME} Uptime", + device_class=DEVICE_CLASS_TIMESTAMP, + entity_registry_enabled_default=False, + ), +) diff --git a/homeassistant/components/nam/model.py b/homeassistant/components/nam/model.py deleted file mode 100644 index 0cadaad647e..00000000000 --- a/homeassistant/components/nam/model.py +++ /dev/null @@ -1,15 +0,0 @@ -"""Type definitions for Nettig Air Monitor integration.""" -from __future__ import annotations - -from typing import TypedDict - - -class SensorDescription(TypedDict): - """Sensor description class.""" - - label: str - unit: str | None - device_class: str | None - icon: str | None - enabled: bool - state_class: str | None diff --git a/homeassistant/components/nam/sensor.py b/homeassistant/components/nam/sensor.py index ae3d1e639d5..298f88d5c29 100644 --- a/homeassistant/components/nam/sensor.py +++ b/homeassistant/components/nam/sensor.py @@ -6,12 +6,11 @@ import logging from typing import cast from homeassistant.components.sensor import ( - ATTR_STATE_CLASS, DOMAIN as PLATFORM, SensorEntity, + SensorEntityDescription, ) from homeassistant.config_entries import ConfigEntry -from homeassistant.const import ATTR_DEVICE_CLASS, ATTR_ICON from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry from homeassistant.helpers.entity_platform import AddEntitiesCallback @@ -20,15 +19,7 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util.dt import utcnow from . import NAMDataUpdateCoordinator -from .const import ( - ATTR_ENABLED, - ATTR_LABEL, - ATTR_UNIT, - ATTR_UPTIME, - DOMAIN, - MIGRATION_SENSORS, - SENSORS, -) +from .const import ATTR_UPTIME, DOMAIN, MIGRATION_SENSORS, SENSORS PARALLEL_UPDATES = 1 @@ -57,12 +48,12 @@ async def async_setup_entry( ent_reg.async_update_entity(entity_id, new_unique_id=new_unique_id) sensors: list[NAMSensor | NAMSensorUptime] = [] - for sensor in SENSORS: - if getattr(coordinator.data, sensor) is not None: - if sensor == ATTR_UPTIME: - sensors.append(NAMSensorUptime(coordinator, sensor)) + for description in SENSORS: + if getattr(coordinator.data, description.key) is not None: + if description.key == ATTR_UPTIME: + sensors.append(NAMSensorUptime(coordinator, description)) else: - sensors.append(NAMSensor(coordinator, sensor)) + sensors.append(NAMSensor(coordinator, description)) async_add_entities(sensors, False) @@ -72,24 +63,23 @@ class NAMSensor(CoordinatorEntity, SensorEntity): coordinator: NAMDataUpdateCoordinator - def __init__(self, coordinator: NAMDataUpdateCoordinator, sensor_type: str) -> None: + def __init__( + self, + coordinator: NAMDataUpdateCoordinator, + description: SensorEntityDescription, + ) -> None: """Initialize.""" super().__init__(coordinator) - description = SENSORS[sensor_type] - self._attr_device_class = description[ATTR_DEVICE_CLASS] self._attr_device_info = coordinator.device_info - self._attr_entity_registry_enabled_default = description[ATTR_ENABLED] - self._attr_icon = description[ATTR_ICON] - self._attr_name = description[ATTR_LABEL] - self._attr_state_class = description[ATTR_STATE_CLASS] - self._attr_unique_id = f"{coordinator.unique_id}-{sensor_type}" - self._attr_unit_of_measurement = description[ATTR_UNIT] - self.sensor_type = sensor_type + self._attr_unique_id = f"{coordinator.unique_id}-{description.key}" + self.entity_description = description @property def state(self) -> StateType: """Return the state.""" - return cast(StateType, getattr(self.coordinator.data, self.sensor_type)) + return cast( + StateType, getattr(self.coordinator.data, self.entity_description.key) + ) @property def available(self) -> bool: @@ -100,7 +90,8 @@ class NAMSensor(CoordinatorEntity, SensorEntity): # sensors. For this reason, we mark entities for which data is missing as # unavailable. return ( - available and getattr(self.coordinator.data, self.sensor_type) is not None + available + and getattr(self.coordinator.data, self.entity_description.key) is not None ) @@ -110,7 +101,7 @@ class NAMSensorUptime(NAMSensor): @property def state(self) -> str: """Return the state.""" - uptime_sec = getattr(self.coordinator.data, self.sensor_type) + uptime_sec = getattr(self.coordinator.data, self.entity_description.key) return ( (utcnow() - timedelta(seconds=uptime_sec)) .replace(microsecond=0)