mirror of
				https://github.com/home-assistant/core.git
				synced 2025-11-04 00:19:31 +00:00 
			
		
		
		
	* add altruist integration and tests * requested fixes + remove some deprecated sensors * add tests for unknown sensor and device attribute in config_flow * use CONF_ in data_schema * suggested fixes * remove test_setup_entry_success * create ZeroconfServiceInfo in tests * use CONF_IP_ADDRESS in tests * add unique id assert * add integration to strict-typing, set unavailable if no sensor key in data, change device name * use add_suggested_values_to_schema, mmHg for pressure * update snapshots and config entry name in tests * remove changes in devcontainer config * fixture for create client error, typing in tests, remove "Altruist" from device name * change native_value_fn return type * change sensor.py docstring * remove device id from entry data, fix docstrings * remove checks for client and device attributes * use less variables in tests * change creating AltruistSensor, remove device from arguments * Update homeassistant/components/altruist/sensor.py * Update homeassistant/components/altruist/quality_scale.yaml * Update homeassistant/components/altruist/quality_scale.yaml * Update quality_scale.yaml * hassfest run * suggested fixes * set suggested_unit_of_measurement for pressure * use mock_config_entry, update snapshots * abort if cant create client on zeroconf step * move sensor names in translatin placeholders --------- Co-authored-by: Josef Zweck <josef@zweck.dev>
		
			
				
	
	
		
			250 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
"""Defines the Altruist sensor platform."""
 | 
						|
 | 
						|
from collections.abc import Callable
 | 
						|
from dataclasses import dataclass
 | 
						|
import logging
 | 
						|
 | 
						|
from homeassistant.components.sensor import (
 | 
						|
    SensorDeviceClass,
 | 
						|
    SensorEntity,
 | 
						|
    SensorEntityDescription,
 | 
						|
    SensorStateClass,
 | 
						|
)
 | 
						|
from homeassistant.const import (
 | 
						|
    CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
 | 
						|
    CONCENTRATION_PARTS_PER_MILLION,
 | 
						|
    PERCENTAGE,
 | 
						|
    SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
 | 
						|
    EntityCategory,
 | 
						|
    UnitOfPressure,
 | 
						|
    UnitOfSoundPressure,
 | 
						|
    UnitOfTemperature,
 | 
						|
)
 | 
						|
from homeassistant.core import HomeAssistant
 | 
						|
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo
 | 
						|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
 | 
						|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
 | 
						|
 | 
						|
from . import AltruistConfigEntry
 | 
						|
from .coordinator import AltruistDataUpdateCoordinator
 | 
						|
 | 
						|
_LOGGER = logging.getLogger(__name__)
 | 
						|
 | 
						|
 | 
						|
@dataclass(frozen=True)
 | 
						|
class AltruistSensorEntityDescription(SensorEntityDescription):
 | 
						|
    """Class to describe a Sensor entity."""
 | 
						|
 | 
						|
    native_value_fn: Callable[[str], float] = float
 | 
						|
    state_class = SensorStateClass.MEASUREMENT
 | 
						|
 | 
						|
 | 
						|
SENSOR_DESCRIPTIONS = [
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.HUMIDITY,
 | 
						|
        key="BME280_humidity",
 | 
						|
        translation_key="humidity",
 | 
						|
        native_unit_of_measurement=PERCENTAGE,
 | 
						|
        suggested_display_precision=2,
 | 
						|
        translation_placeholders={"sensor_name": "BME280"},
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.PRESSURE,
 | 
						|
        key="BME280_pressure",
 | 
						|
        translation_key="pressure",
 | 
						|
        native_unit_of_measurement=UnitOfPressure.PA,
 | 
						|
        suggested_unit_of_measurement=UnitOfPressure.MMHG,
 | 
						|
        suggested_display_precision=0,
 | 
						|
        translation_placeholders={"sensor_name": "BME280"},
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.TEMPERATURE,
 | 
						|
        key="BME280_temperature",
 | 
						|
        translation_key="temperature",
 | 
						|
        native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
						|
        suggested_display_precision=2,
 | 
						|
        translation_placeholders={"sensor_name": "BME280"},
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.PRESSURE,
 | 
						|
        key="BMP_pressure",
 | 
						|
        translation_key="pressure",
 | 
						|
        native_unit_of_measurement=UnitOfPressure.PA,
 | 
						|
        suggested_unit_of_measurement=UnitOfPressure.MMHG,
 | 
						|
        suggested_display_precision=0,
 | 
						|
        translation_placeholders={"sensor_name": "BMP"},
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.TEMPERATURE,
 | 
						|
        key="BMP_temperature",
 | 
						|
        translation_key="temperature",
 | 
						|
        native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
						|
        suggested_display_precision=2,
 | 
						|
        translation_placeholders={"sensor_name": "BMP"},
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.TEMPERATURE,
 | 
						|
        key="BMP280_temperature",
 | 
						|
        translation_key="temperature",
 | 
						|
        native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
						|
        suggested_display_precision=2,
 | 
						|
        translation_placeholders={"sensor_name": "BMP280"},
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.PRESSURE,
 | 
						|
        key="BMP280_pressure",
 | 
						|
        translation_key="pressure",
 | 
						|
        native_unit_of_measurement=UnitOfPressure.PA,
 | 
						|
        suggested_unit_of_measurement=UnitOfPressure.MMHG,
 | 
						|
        suggested_display_precision=0,
 | 
						|
        translation_placeholders={"sensor_name": "BMP280"},
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.HUMIDITY,
 | 
						|
        key="HTU21D_humidity",
 | 
						|
        translation_key="humidity",
 | 
						|
        native_unit_of_measurement=PERCENTAGE,
 | 
						|
        suggested_display_precision=2,
 | 
						|
        translation_placeholders={"sensor_name": "HTU21D"},
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.TEMPERATURE,
 | 
						|
        key="HTU21D_temperature",
 | 
						|
        translation_key="temperature",
 | 
						|
        native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
						|
        suggested_display_precision=2,
 | 
						|
        translation_placeholders={"sensor_name": "HTU21D"},
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.PM10,
 | 
						|
        translation_key="pm_10",
 | 
						|
        key="SDS_P1",
 | 
						|
        native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
 | 
						|
        suggested_display_precision=2,
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.PM25,
 | 
						|
        translation_key="pm_25",
 | 
						|
        key="SDS_P2",
 | 
						|
        native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
 | 
						|
        suggested_display_precision=2,
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.HUMIDITY,
 | 
						|
        key="SHT3X_humidity",
 | 
						|
        translation_key="humidity",
 | 
						|
        native_unit_of_measurement=PERCENTAGE,
 | 
						|
        suggested_display_precision=2,
 | 
						|
        translation_placeholders={"sensor_name": "SHT3X"},
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.TEMPERATURE,
 | 
						|
        key="SHT3X_temperature",
 | 
						|
        translation_key="temperature",
 | 
						|
        native_unit_of_measurement=UnitOfTemperature.CELSIUS,
 | 
						|
        suggested_display_precision=2,
 | 
						|
        translation_placeholders={"sensor_name": "SHT3X"},
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.SIGNAL_STRENGTH,
 | 
						|
        key="signal",
 | 
						|
        native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
 | 
						|
        entity_category=EntityCategory.DIAGNOSTIC,
 | 
						|
        suggested_display_precision=0,
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.SOUND_PRESSURE,
 | 
						|
        key="PCBA_noiseMax",
 | 
						|
        translation_key="noise_max",
 | 
						|
        native_unit_of_measurement=UnitOfSoundPressure.DECIBEL,
 | 
						|
        suggested_display_precision=0,
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.SOUND_PRESSURE,
 | 
						|
        key="PCBA_noiseAvg",
 | 
						|
        translation_key="noise_avg",
 | 
						|
        native_unit_of_measurement=UnitOfSoundPressure.DECIBEL,
 | 
						|
        suggested_display_precision=0,
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.CO2,
 | 
						|
        native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
 | 
						|
        translation_key="co2",
 | 
						|
        key="CCS_CO2",
 | 
						|
        suggested_display_precision=2,
 | 
						|
        translation_placeholders={"sensor_name": "CCS"},
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS,
 | 
						|
        key="CCS_TVOC",
 | 
						|
        native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
 | 
						|
        suggested_display_precision=2,
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        key="GC",
 | 
						|
        native_unit_of_measurement="μR/h",
 | 
						|
        translation_key="radiation",
 | 
						|
        suggested_display_precision=2,
 | 
						|
    ),
 | 
						|
    AltruistSensorEntityDescription(
 | 
						|
        device_class=SensorDeviceClass.CO2,
 | 
						|
        translation_key="co2",
 | 
						|
        native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
 | 
						|
        key="SCD4x_co2",
 | 
						|
        suggested_display_precision=2,
 | 
						|
        translation_placeholders={"sensor_name": "SCD4x"},
 | 
						|
    ),
 | 
						|
]
 | 
						|
 | 
						|
 | 
						|
async def async_setup_entry(
 | 
						|
    hass: HomeAssistant,
 | 
						|
    config_entry: AltruistConfigEntry,
 | 
						|
    async_add_entities: AddConfigEntryEntitiesCallback,
 | 
						|
) -> None:
 | 
						|
    """Add sensors for passed config_entry in HA."""
 | 
						|
    coordinator = config_entry.runtime_data
 | 
						|
    async_add_entities(
 | 
						|
        AltruistSensor(coordinator, sensor_description)
 | 
						|
        for sensor_description in SENSOR_DESCRIPTIONS
 | 
						|
        if sensor_description.key in coordinator.data
 | 
						|
    )
 | 
						|
 | 
						|
 | 
						|
class AltruistSensor(CoordinatorEntity[AltruistDataUpdateCoordinator], SensorEntity):
 | 
						|
    """Implementation of a Altruist sensor."""
 | 
						|
 | 
						|
    _attr_has_entity_name = True
 | 
						|
 | 
						|
    def __init__(
 | 
						|
        self,
 | 
						|
        coordinator: AltruistDataUpdateCoordinator,
 | 
						|
        description: AltruistSensorEntityDescription,
 | 
						|
    ) -> None:
 | 
						|
        """Initialize the Altruist sensor."""
 | 
						|
        super().__init__(coordinator)
 | 
						|
        self._device = coordinator.client.device
 | 
						|
        self.entity_description: AltruistSensorEntityDescription = description
 | 
						|
        self._attr_unique_id = f"{self._device.id}-{description.key}"
 | 
						|
        self._attr_device_info = DeviceInfo(
 | 
						|
            connections={(CONNECTION_NETWORK_MAC, self._device.id)},
 | 
						|
            manufacturer="Robonomics",
 | 
						|
            model="Altruist",
 | 
						|
            sw_version=self._device.fw_version,
 | 
						|
            configuration_url=f"http://{self._device.ip_address}",
 | 
						|
            serial_number=self._device.id,
 | 
						|
        )
 | 
						|
 | 
						|
    @property
 | 
						|
    def available(self) -> bool:
 | 
						|
        """Return True if entity is available."""
 | 
						|
        return (
 | 
						|
            super().available and self.entity_description.key in self.coordinator.data
 | 
						|
        )
 | 
						|
 | 
						|
    @property
 | 
						|
    def native_value(self) -> float | int:
 | 
						|
        """Return the native value of the sensor."""
 | 
						|
        string_value = self.coordinator.data[self.entity_description.key]
 | 
						|
        return self.entity_description.native_value_fn(string_value)
 |