From ab9cbf64da39fab4583fd1c0becc159342ab0b9a Mon Sep 17 00:00:00 2001 From: Joost Lekkerkerker Date: Mon, 24 Jun 2024 09:54:22 +0200 Subject: [PATCH] Add sensors to Airgradient (#120286) --- homeassistant/components/airgradient/const.py | 8 + .../components/airgradient/select.py | 15 +- .../components/airgradient/sensor.py | 173 +++++- .../components/airgradient/strings.json | 37 ++ .../airgradient/snapshots/test_sensor.ambr | 552 ++++++++++++++++++ 5 files changed, 750 insertions(+), 35 deletions(-) diff --git a/homeassistant/components/airgradient/const.py b/homeassistant/components/airgradient/const.py index bbb15a3741d..2817a27e37b 100644 --- a/homeassistant/components/airgradient/const.py +++ b/homeassistant/components/airgradient/const.py @@ -2,6 +2,14 @@ import logging +from airgradient import PmStandard + DOMAIN = "airgradient" LOGGER = logging.getLogger(__package__) + +PM_STANDARD = { + PmStandard.UGM3: "ugm3", + PmStandard.USAQI: "us_aqi", +} +PM_STANDARD_REVERSE = {v: k for k, v in PM_STANDARD.items()} diff --git a/homeassistant/components/airgradient/select.py b/homeassistant/components/airgradient/select.py index 8fac06917fd..e85e1224000 100644 --- a/homeassistant/components/airgradient/select.py +++ b/homeassistant/components/airgradient/select.py @@ -4,12 +4,7 @@ from collections.abc import Awaitable, Callable from dataclasses import dataclass from airgradient import AirGradientClient, Config -from airgradient.models import ( - ConfigurationControl, - LedBarMode, - PmStandard, - TemperatureUnit, -) +from airgradient.models import ConfigurationControl, LedBarMode, TemperatureUnit from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.const import EntityCategory @@ -18,16 +13,10 @@ from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers.entity_platform import AddEntitiesCallback from . import AirGradientConfigEntry -from .const import DOMAIN +from .const import DOMAIN, PM_STANDARD, PM_STANDARD_REVERSE from .coordinator import AirGradientConfigCoordinator from .entity import AirGradientEntity -PM_STANDARD = { - PmStandard.UGM3: "ugm3", - PmStandard.USAQI: "us_aqi", -} -PM_STANDARD_REVERSE = {v: k for k, v in PM_STANDARD.items()} - @dataclass(frozen=True, kw_only=True) class AirGradientSelectEntityDescription(SelectEntityDescription): diff --git a/homeassistant/components/airgradient/sensor.py b/homeassistant/components/airgradient/sensor.py index 6123d4289f9..f431c49ed2a 100644 --- a/homeassistant/components/airgradient/sensor.py +++ b/homeassistant/components/airgradient/sensor.py @@ -3,7 +3,13 @@ from collections.abc import Callable from dataclasses import dataclass -from airgradient.models import Measures +from airgradient import Config +from airgradient.models import ( + ConfigurationControl, + LedBarMode, + Measures, + TemperatureUnit, +) from homeassistant.components.sensor import ( SensorDeviceClass, @@ -18,60 +24,69 @@ from homeassistant.const import ( SIGNAL_STRENGTH_DECIBELS_MILLIWATT, EntityCategory, UnitOfTemperature, + UnitOfTime, ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import StateType from . import AirGradientConfigEntry -from .coordinator import AirGradientMeasurementCoordinator +from .const import PM_STANDARD, PM_STANDARD_REVERSE +from .coordinator import AirGradientConfigCoordinator, AirGradientMeasurementCoordinator from .entity import AirGradientEntity @dataclass(frozen=True, kw_only=True) -class AirGradientSensorEntityDescription(SensorEntityDescription): - """Describes AirGradient sensor entity.""" +class AirGradientMeasurementSensorEntityDescription(SensorEntityDescription): + """Describes AirGradient measurement sensor entity.""" value_fn: Callable[[Measures], StateType] -SENSOR_TYPES: tuple[AirGradientSensorEntityDescription, ...] = ( - AirGradientSensorEntityDescription( +@dataclass(frozen=True, kw_only=True) +class AirGradientConfigSensorEntityDescription(SensorEntityDescription): + """Describes AirGradient config sensor entity.""" + + value_fn: Callable[[Config], StateType] + + +MEASUREMENT_SENSOR_TYPES: tuple[AirGradientMeasurementSensorEntityDescription, ...] = ( + AirGradientMeasurementSensorEntityDescription( key="pm01", device_class=SensorDeviceClass.PM1, native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, state_class=SensorStateClass.MEASUREMENT, value_fn=lambda status: status.pm01, ), - AirGradientSensorEntityDescription( + AirGradientMeasurementSensorEntityDescription( key="pm02", device_class=SensorDeviceClass.PM25, native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, state_class=SensorStateClass.MEASUREMENT, value_fn=lambda status: status.pm02, ), - AirGradientSensorEntityDescription( + AirGradientMeasurementSensorEntityDescription( key="pm10", device_class=SensorDeviceClass.PM10, native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, state_class=SensorStateClass.MEASUREMENT, value_fn=lambda status: status.pm10, ), - AirGradientSensorEntityDescription( + AirGradientMeasurementSensorEntityDescription( key="temperature", device_class=SensorDeviceClass.TEMPERATURE, native_unit_of_measurement=UnitOfTemperature.CELSIUS, state_class=SensorStateClass.MEASUREMENT, value_fn=lambda status: status.ambient_temperature, ), - AirGradientSensorEntityDescription( + AirGradientMeasurementSensorEntityDescription( key="humidity", device_class=SensorDeviceClass.HUMIDITY, native_unit_of_measurement=PERCENTAGE, state_class=SensorStateClass.MEASUREMENT, value_fn=lambda status: status.relative_humidity, ), - AirGradientSensorEntityDescription( + AirGradientMeasurementSensorEntityDescription( key="signal_strength", device_class=SensorDeviceClass.SIGNAL_STRENGTH, native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT, @@ -80,33 +95,33 @@ SENSOR_TYPES: tuple[AirGradientSensorEntityDescription, ...] = ( entity_registry_enabled_default=False, value_fn=lambda status: status.signal_strength, ), - AirGradientSensorEntityDescription( + AirGradientMeasurementSensorEntityDescription( key="tvoc", translation_key="total_volatile_organic_component_index", state_class=SensorStateClass.MEASUREMENT, value_fn=lambda status: status.total_volatile_organic_component_index, ), - AirGradientSensorEntityDescription( + AirGradientMeasurementSensorEntityDescription( key="nitrogen_index", translation_key="nitrogen_index", state_class=SensorStateClass.MEASUREMENT, value_fn=lambda status: status.nitrogen_index, ), - AirGradientSensorEntityDescription( + AirGradientMeasurementSensorEntityDescription( key="co2", device_class=SensorDeviceClass.CO2, native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION, state_class=SensorStateClass.MEASUREMENT, value_fn=lambda status: status.rco2, ), - AirGradientSensorEntityDescription( + AirGradientMeasurementSensorEntityDescription( key="pm003", translation_key="pm003_count", native_unit_of_measurement="particles/dL", state_class=SensorStateClass.MEASUREMENT, value_fn=lambda status: status.pm003_count, ), - AirGradientSensorEntityDescription( + AirGradientMeasurementSensorEntityDescription( key="nox_raw", translation_key="raw_nitrogen", native_unit_of_measurement="ticks", @@ -114,7 +129,7 @@ SENSOR_TYPES: tuple[AirGradientSensorEntityDescription, ...] = ( entity_registry_enabled_default=False, value_fn=lambda status: status.raw_nitrogen, ), - AirGradientSensorEntityDescription( + AirGradientMeasurementSensorEntityDescription( key="tvoc_raw", translation_key="raw_total_volatile_organic_component", native_unit_of_measurement="ticks", @@ -124,6 +139,77 @@ SENSOR_TYPES: tuple[AirGradientSensorEntityDescription, ...] = ( ), ) +CONFIG_SENSOR_TYPES: tuple[AirGradientConfigSensorEntityDescription, ...] = ( + AirGradientConfigSensorEntityDescription( + key="co2_automatic_baseline_calibration_days", + translation_key="co2_automatic_baseline_calibration_days", + device_class=SensorDeviceClass.DURATION, + native_unit_of_measurement=UnitOfTime.DAYS, + entity_category=EntityCategory.DIAGNOSTIC, + value_fn=lambda config: config.co2_automatic_baseline_calibration_days, + ), + AirGradientConfigSensorEntityDescription( + key="nox_learning_offset", + translation_key="nox_learning_offset", + device_class=SensorDeviceClass.DURATION, + native_unit_of_measurement=UnitOfTime.DAYS, + entity_category=EntityCategory.DIAGNOSTIC, + value_fn=lambda config: config.nox_learning_offset, + ), + AirGradientConfigSensorEntityDescription( + key="tvoc_learning_offset", + translation_key="tvoc_learning_offset", + device_class=SensorDeviceClass.DURATION, + native_unit_of_measurement=UnitOfTime.DAYS, + entity_category=EntityCategory.DIAGNOSTIC, + value_fn=lambda config: config.tvoc_learning_offset, + ), +) + +CONFIG_LED_BAR_SENSOR_TYPES: tuple[AirGradientConfigSensorEntityDescription, ...] = ( + AirGradientConfigSensorEntityDescription( + key="led_bar_mode", + translation_key="led_bar_mode", + device_class=SensorDeviceClass.ENUM, + options=[x.value for x in LedBarMode], + entity_category=EntityCategory.DIAGNOSTIC, + value_fn=lambda config: config.led_bar_mode, + ), + AirGradientConfigSensorEntityDescription( + key="led_bar_brightness", + translation_key="led_bar_brightness", + native_unit_of_measurement=PERCENTAGE, + entity_category=EntityCategory.DIAGNOSTIC, + value_fn=lambda config: config.led_bar_brightness, + ), +) + +CONFIG_DISPLAY_SENSOR_TYPES: tuple[AirGradientConfigSensorEntityDescription, ...] = ( + AirGradientConfigSensorEntityDescription( + key="display_temperature_unit", + translation_key="display_temperature_unit", + device_class=SensorDeviceClass.ENUM, + options=[x.value for x in TemperatureUnit], + entity_category=EntityCategory.DIAGNOSTIC, + value_fn=lambda config: config.temperature_unit, + ), + AirGradientConfigSensorEntityDescription( + key="display_pm_standard", + translation_key="display_pm_standard", + device_class=SensorDeviceClass.ENUM, + options=list(PM_STANDARD_REVERSE), + entity_category=EntityCategory.DIAGNOSTIC, + value_fn=lambda config: PM_STANDARD.get(config.pm_standard), + ), + AirGradientConfigSensorEntityDescription( + key="display_brightness", + translation_key="display_brightness", + native_unit_of_measurement=PERCENTAGE, + entity_category=EntityCategory.DIAGNOSTIC, + value_fn=lambda config: config.display_brightness, + ), +) + async def async_setup_entry( hass: HomeAssistant, @@ -134,7 +220,9 @@ async def async_setup_entry( coordinator = entry.runtime_data.measurement listener: Callable[[], None] | None = None - not_setup: set[AirGradientSensorEntityDescription] = set(SENSOR_TYPES) + not_setup: set[AirGradientMeasurementSensorEntityDescription] = set( + MEASUREMENT_SENSOR_TYPES + ) @callback def add_entities() -> None: @@ -147,7 +235,7 @@ async def async_setup_entry( if description.value_fn(coordinator.data) is None: not_setup.add(description) else: - sensors.append(AirGradientSensor(coordinator, description)) + sensors.append(AirGradientMeasurementSensor(coordinator, description)) if sensors: async_add_entities(sensors) @@ -159,17 +247,33 @@ async def async_setup_entry( add_entities() + entities = [ + AirGradientConfigSensor(entry.runtime_data.config, description) + for description in CONFIG_SENSOR_TYPES + ] + if "L" in coordinator.data.model: + entities.extend( + AirGradientConfigSensor(entry.runtime_data.config, description) + for description in CONFIG_LED_BAR_SENSOR_TYPES + ) + if "I" in coordinator.data.model: + entities.extend( + AirGradientConfigSensor(entry.runtime_data.config, description) + for description in CONFIG_DISPLAY_SENSOR_TYPES + ) + async_add_entities(entities) -class AirGradientSensor(AirGradientEntity, SensorEntity): + +class AirGradientMeasurementSensor(AirGradientEntity, SensorEntity): """Defines an AirGradient sensor.""" - entity_description: AirGradientSensorEntityDescription + entity_description: AirGradientMeasurementSensorEntityDescription coordinator: AirGradientMeasurementCoordinator def __init__( self, coordinator: AirGradientMeasurementCoordinator, - description: AirGradientSensorEntityDescription, + description: AirGradientMeasurementSensorEntityDescription, ) -> None: """Initialize airgradient sensor.""" super().__init__(coordinator) @@ -180,3 +284,28 @@ class AirGradientSensor(AirGradientEntity, SensorEntity): def native_value(self) -> StateType: """Return the state of the sensor.""" return self.entity_description.value_fn(self.coordinator.data) + + +class AirGradientConfigSensor(AirGradientEntity, SensorEntity): + """Defines an AirGradient sensor.""" + + entity_description: AirGradientConfigSensorEntityDescription + coordinator: AirGradientConfigCoordinator + + def __init__( + self, + coordinator: AirGradientConfigCoordinator, + description: AirGradientConfigSensorEntityDescription, + ) -> None: + """Initialize airgradient sensor.""" + super().__init__(coordinator) + self.entity_description = description + self._attr_unique_id = f"{coordinator.serial_number}-{description.key}" + self._attr_entity_registry_enabled_default = ( + coordinator.data.configuration_control is not ConfigurationControl.LOCAL + ) + + @property + def native_value(self) -> StateType: + """Return the state of the sensor.""" + return self.entity_description.value_fn(self.coordinator.data) diff --git a/homeassistant/components/airgradient/strings.json b/homeassistant/components/airgradient/strings.json index 0ab80286570..6c079419839 100644 --- a/homeassistant/components/airgradient/strings.json +++ b/homeassistant/components/airgradient/strings.json @@ -78,6 +78,43 @@ }, "raw_nitrogen": { "name": "Raw NOx" + }, + "display_pm_standard": { + "name": "[%key:component::airgradient::entity::select::display_pm_standard::name%]", + "state": { + "ugm3": "[%key:component::airgradient::entity::select::display_pm_standard::state::ugm3%]", + "us_aqi": "[%key:component::airgradient::entity::select::display_pm_standard::state::us_aqi%]" + } + }, + "co2_automatic_baseline_calibration_days": { + "name": "Carbon dioxide automatic baseline calibration" + }, + "nox_learning_offset": { + "name": "NOx learning offset" + }, + "tvoc_learning_offset": { + "name": "VOC learning offset" + }, + "led_bar_mode": { + "name": "[%key:component::airgradient::entity::select::led_bar_mode::name%]", + "state": { + "off": "[%key:component::airgradient::entity::select::led_bar_mode::state::off%]", + "co2": "[%key:component::airgradient::entity::select::led_bar_mode::state::co2%]", + "pm": "[%key:component::airgradient::entity::select::led_bar_mode::state::pm%]" + } + }, + "led_bar_brightness": { + "name": "[%key:component::airgradient::entity::number::led_bar_brightness::name%]" + }, + "display_temperature_unit": { + "name": "[%key:component::airgradient::entity::select::display_temperature_unit::name%]", + "state": { + "c": "[%key:component::airgradient::entity::select::display_temperature_unit::state::c%]", + "f": "[%key:component::airgradient::entity::select::display_temperature_unit::state::f%]" + } + }, + "display_brightness": { + "name": "[%key:component::airgradient::entity::number::display_brightness::name%]" } } }, diff --git a/tests/components/airgradient/snapshots/test_sensor.ambr b/tests/components/airgradient/snapshots/test_sensor.ambr index e96d2be1004..c3d14c7d8fc 100644 --- a/tests/components/airgradient/snapshots/test_sensor.ambr +++ b/tests/components/airgradient/snapshots/test_sensor.ambr @@ -50,6 +50,213 @@ 'state': '778', }) # --- +# name: test_all_entities[indoor][sensor.airgradient_carbon_dioxide_automatic_baseline_calibration-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.airgradient_carbon_dioxide_automatic_baseline_calibration', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Carbon dioxide automatic baseline calibration', + 'platform': 'airgradient', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'co2_automatic_baseline_calibration_days', + 'unique_id': '84fce612f5b8-co2_automatic_baseline_calibration_days', + 'unit_of_measurement': , + }) +# --- +# name: test_all_entities[indoor][sensor.airgradient_carbon_dioxide_automatic_baseline_calibration-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'duration', + 'friendly_name': 'Airgradient Carbon dioxide automatic baseline calibration', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.airgradient_carbon_dioxide_automatic_baseline_calibration', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '8', + }) +# --- +# name: test_all_entities[indoor][sensor.airgradient_display_brightness-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.airgradient_display_brightness', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Display brightness', + 'platform': 'airgradient', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'display_brightness', + 'unique_id': '84fce612f5b8-display_brightness', + 'unit_of_measurement': '%', + }) +# --- +# name: test_all_entities[indoor][sensor.airgradient_display_brightness-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Airgradient Display brightness', + 'unit_of_measurement': '%', + }), + 'context': , + 'entity_id': 'sensor.airgradient_display_brightness', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '0', + }) +# --- +# name: test_all_entities[indoor][sensor.airgradient_display_pm_standard-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + 'ugm3', + 'us_aqi', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.airgradient_display_pm_standard', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Display PM standard', + 'platform': 'airgradient', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'display_pm_standard', + 'unique_id': '84fce612f5b8-display_pm_standard', + 'unit_of_measurement': None, + }) +# --- +# name: test_all_entities[indoor][sensor.airgradient_display_pm_standard-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'enum', + 'friendly_name': 'Airgradient Display PM standard', + 'options': list([ + 'ugm3', + 'us_aqi', + ]), + }), + 'context': , + 'entity_id': 'sensor.airgradient_display_pm_standard', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'ugm3', + }) +# --- +# name: test_all_entities[indoor][sensor.airgradient_display_temperature_unit-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + 'c', + 'f', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.airgradient_display_temperature_unit', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Display temperature unit', + 'platform': 'airgradient', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'display_temperature_unit', + 'unique_id': '84fce612f5b8-display_temperature_unit', + 'unit_of_measurement': None, + }) +# --- +# name: test_all_entities[indoor][sensor.airgradient_display_temperature_unit-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'enum', + 'friendly_name': 'Airgradient Display temperature unit', + 'options': list([ + 'c', + 'f', + ]), + }), + 'context': , + 'entity_id': 'sensor.airgradient_display_temperature_unit', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'c', + }) +# --- # name: test_all_entities[indoor][sensor.airgradient_humidity-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -101,6 +308,111 @@ 'state': '48.0', }) # --- +# name: test_all_entities[indoor][sensor.airgradient_led_bar_brightness-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.airgradient_led_bar_brightness', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'LED bar brightness', + 'platform': 'airgradient', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'led_bar_brightness', + 'unique_id': '84fce612f5b8-led_bar_brightness', + 'unit_of_measurement': '%', + }) +# --- +# name: test_all_entities[indoor][sensor.airgradient_led_bar_brightness-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Airgradient LED bar brightness', + 'unit_of_measurement': '%', + }), + 'context': , + 'entity_id': 'sensor.airgradient_led_bar_brightness', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '100', + }) +# --- +# name: test_all_entities[indoor][sensor.airgradient_led_bar_mode-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + 'off', + 'co2', + 'pm', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.airgradient_led_bar_mode', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'LED bar mode', + 'platform': 'airgradient', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'led_bar_mode', + 'unique_id': '84fce612f5b8-led_bar_mode', + 'unit_of_measurement': None, + }) +# --- +# name: test_all_entities[indoor][sensor.airgradient_led_bar_mode-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'enum', + 'friendly_name': 'Airgradient LED bar mode', + 'options': list([ + 'off', + 'co2', + 'pm', + ]), + }), + 'context': , + 'entity_id': 'sensor.airgradient_led_bar_mode', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'co2', + }) +# --- # name: test_all_entities[indoor][sensor.airgradient_nox_index-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -150,6 +462,54 @@ 'state': '1', }) # --- +# name: test_all_entities[indoor][sensor.airgradient_nox_learning_offset-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.airgradient_nox_learning_offset', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'NOx learning offset', + 'platform': 'airgradient', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'nox_learning_offset', + 'unique_id': '84fce612f5b8-nox_learning_offset', + 'unit_of_measurement': , + }) +# --- +# name: test_all_entities[indoor][sensor.airgradient_nox_learning_offset-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'duration', + 'friendly_name': 'Airgradient NOx learning offset', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.airgradient_nox_learning_offset', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '12', + }) +# --- # name: test_all_entities[indoor][sensor.airgradient_pm0_3-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -604,6 +964,102 @@ 'state': '99', }) # --- +# name: test_all_entities[indoor][sensor.airgradient_voc_learning_offset-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.airgradient_voc_learning_offset', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'VOC learning offset', + 'platform': 'airgradient', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'tvoc_learning_offset', + 'unique_id': '84fce612f5b8-tvoc_learning_offset', + 'unit_of_measurement': , + }) +# --- +# name: test_all_entities[indoor][sensor.airgradient_voc_learning_offset-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'duration', + 'friendly_name': 'Airgradient VOC learning offset', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.airgradient_voc_learning_offset', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '12', + }) +# --- +# name: test_all_entities[outdoor][sensor.airgradient_carbon_dioxide_automatic_baseline_calibration-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.airgradient_carbon_dioxide_automatic_baseline_calibration', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Carbon dioxide automatic baseline calibration', + 'platform': 'airgradient', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'co2_automatic_baseline_calibration_days', + 'unique_id': '84fce612f5b8-co2_automatic_baseline_calibration_days', + 'unit_of_measurement': , + }) +# --- +# name: test_all_entities[outdoor][sensor.airgradient_carbon_dioxide_automatic_baseline_calibration-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'duration', + 'friendly_name': 'Airgradient Carbon dioxide automatic baseline calibration', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.airgradient_carbon_dioxide_automatic_baseline_calibration', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '8', + }) +# --- # name: test_all_entities[outdoor][sensor.airgradient_nox_index-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -653,6 +1109,54 @@ 'state': '1', }) # --- +# name: test_all_entities[outdoor][sensor.airgradient_nox_learning_offset-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.airgradient_nox_learning_offset', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'NOx learning offset', + 'platform': 'airgradient', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'nox_learning_offset', + 'unique_id': '84fce612f5b8-nox_learning_offset', + 'unit_of_measurement': , + }) +# --- +# name: test_all_entities[outdoor][sensor.airgradient_nox_learning_offset-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'duration', + 'friendly_name': 'Airgradient NOx learning offset', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.airgradient_nox_learning_offset', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '12', + }) +# --- # name: test_all_entities[outdoor][sensor.airgradient_raw_nox-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -853,3 +1357,51 @@ 'state': '49', }) # --- +# name: test_all_entities[outdoor][sensor.airgradient_voc_learning_offset-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.airgradient_voc_learning_offset', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'VOC learning offset', + 'platform': 'airgradient', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'tvoc_learning_offset', + 'unique_id': '84fce612f5b8-tvoc_learning_offset', + 'unit_of_measurement': , + }) +# --- +# name: test_all_entities[outdoor][sensor.airgradient_voc_learning_offset-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'duration', + 'friendly_name': 'Airgradient VOC learning offset', + 'unit_of_measurement': , + }), + 'context': , + 'entity_id': 'sensor.airgradient_voc_learning_offset', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': '12', + }) +# ---