Add Pure devices to Sensibo (#67695)

This commit is contained in:
G Johansson 2022-03-14 01:30:37 +01:00 committed by GitHub
parent 65821f9492
commit a6c189b450
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 16 deletions

View file

@ -103,8 +103,6 @@ async def async_setup_entry(
entities = [ entities = [
SensiboClimate(coordinator, device_id) SensiboClimate(coordinator, device_id)
for device_id, device_data in coordinator.data.parsed.items() for device_id, device_data in coordinator.data.parsed.items()
# Remove none climate devices
if device_data["hvac_modes"] and device_data["temp"]
] ]
async_add_entities(entities) async_add_entities(entities)

View file

@ -167,6 +167,12 @@ class SensiboDataUpdateCoordinator(DataUpdateCoordinator):
rssi=measurement.get("rssi"), rssi=measurement.get("rssi"),
) )
# Add information for pure devices
pure_conf = dev["pureBoostConfig"]
pure_sensitivity = pure_conf.get("sensitivity") if pure_conf else None
pure_boost_enabled = pure_conf.get("enabled") if pure_conf else None
pm25 = dev["measurements"].get("pm25")
device_data[unique_id] = { device_data[unique_id] = {
"id": unique_id, "id": unique_id,
"mac": mac, "mac": mac,
@ -200,6 +206,9 @@ class SensiboDataUpdateCoordinator(DataUpdateCoordinator):
"calibration_hum": calibration_hum, "calibration_hum": calibration_hum,
"full_capabilities": capabilities, "full_capabilities": capabilities,
"motion_sensors": motion_sensors, "motion_sensors": motion_sensors,
"pure_sensitivity": pure_sensitivity,
"pure_boost_enabled": pure_boost_enabled,
"pm25": pm25,
} }
return SensiboData(raw=data, parsed=device_data) return SensiboData(raw=data, parsed=device_data)

View file

@ -66,7 +66,6 @@ async def async_setup_entry(
SensiboNumber(coordinator, device_id, description) SensiboNumber(coordinator, device_id, description)
for device_id, device_data in coordinator.data.parsed.items() for device_id, device_data in coordinator.data.parsed.items()
for description in NUMBER_TYPES for description in NUMBER_TYPES
if device_data["hvac_modes"] and device_data["temp"]
) )

View file

@ -58,7 +58,7 @@ async def async_setup_entry(
SensiboSelect(coordinator, device_id, description) SensiboSelect(coordinator, device_id, description)
for device_id, device_data in coordinator.data.parsed.items() for device_id, device_data in coordinator.data.parsed.items()
for description in SELECT_TYPES for description in SELECT_TYPES
if device_data["hvac_modes"] and description.key in device_data["full_features"] if description.key in device_data["full_features"]
) )

View file

@ -3,6 +3,7 @@ from __future__ import annotations
from collections.abc import Callable from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
SensorDeviceClass, SensorDeviceClass,
@ -12,6 +13,7 @@ from homeassistant.components.sensor import (
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ( from homeassistant.const import (
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
ELECTRIC_POTENTIAL_VOLT, ELECTRIC_POTENTIAL_VOLT,
PERCENTAGE, PERCENTAGE,
SIGNAL_STRENGTH_DECIBELS_MILLIWATT, SIGNAL_STRENGTH_DECIBELS_MILLIWATT,
@ -24,25 +26,39 @@ from homeassistant.helpers.typing import StateType
from .const import DOMAIN from .const import DOMAIN
from .coordinator import MotionSensor, SensiboDataUpdateCoordinator from .coordinator import MotionSensor, SensiboDataUpdateCoordinator
from .entity import SensiboMotionBaseEntity from .entity import SensiboDeviceBaseEntity, SensiboMotionBaseEntity
@dataclass @dataclass
class BaseEntityDescriptionMixin: class MotionBaseEntityDescriptionMixin:
"""Mixin for required Sensibo base description keys.""" """Mixin for required Sensibo base description keys."""
value_fn: Callable[[MotionSensor], StateType] value_fn: Callable[[MotionSensor], StateType]
@dataclass @dataclass
class SensiboSensorEntityDescription( class DeviceBaseEntityDescriptionMixin:
SensorEntityDescription, BaseEntityDescriptionMixin """Mixin for required Sensibo base description keys."""
value_fn: Callable[[dict[str, Any]], StateType]
@dataclass
class SensiboMotionSensorEntityDescription(
SensorEntityDescription, MotionBaseEntityDescriptionMixin
): ):
"""Describes Sensibo Motion sensor entity.""" """Describes Sensibo Motion sensor entity."""
MOTION_SENSOR_TYPES: tuple[SensiboSensorEntityDescription, ...] = ( @dataclass
SensiboSensorEntityDescription( class SensiboDeviceSensorEntityDescription(
SensorEntityDescription, DeviceBaseEntityDescriptionMixin
):
"""Describes Sensibo Motion sensor entity."""
MOTION_SENSOR_TYPES: tuple[SensiboMotionSensorEntityDescription, ...] = (
SensiboMotionSensorEntityDescription(
key="rssi", key="rssi",
device_class=SensorDeviceClass.SIGNAL_STRENGTH, device_class=SensorDeviceClass.SIGNAL_STRENGTH,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
@ -53,7 +69,7 @@ MOTION_SENSOR_TYPES: tuple[SensiboSensorEntityDescription, ...] = (
value_fn=lambda data: data.rssi, value_fn=lambda data: data.rssi,
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
), ),
SensiboSensorEntityDescription( SensiboMotionSensorEntityDescription(
key="battery_voltage", key="battery_voltage",
device_class=SensorDeviceClass.VOLTAGE, device_class=SensorDeviceClass.VOLTAGE,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
@ -63,7 +79,7 @@ MOTION_SENSOR_TYPES: tuple[SensiboSensorEntityDescription, ...] = (
icon="mdi:battery", icon="mdi:battery",
value_fn=lambda data: data.battery_voltage, value_fn=lambda data: data.battery_voltage,
), ),
SensiboSensorEntityDescription( SensiboMotionSensorEntityDescription(
key="humidity", key="humidity",
device_class=SensorDeviceClass.HUMIDITY, device_class=SensorDeviceClass.HUMIDITY,
native_unit_of_measurement=PERCENTAGE, native_unit_of_measurement=PERCENTAGE,
@ -72,7 +88,7 @@ MOTION_SENSOR_TYPES: tuple[SensiboSensorEntityDescription, ...] = (
icon="mdi:water", icon="mdi:water",
value_fn=lambda data: data.humidity, value_fn=lambda data: data.humidity,
), ),
SensiboSensorEntityDescription( SensiboMotionSensorEntityDescription(
key="temperature", key="temperature",
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=TEMP_CELSIUS, native_unit_of_measurement=TEMP_CELSIUS,
@ -82,6 +98,23 @@ MOTION_SENSOR_TYPES: tuple[SensiboSensorEntityDescription, ...] = (
value_fn=lambda data: data.temperature, value_fn=lambda data: data.temperature,
), ),
) )
DEVICE_SENSOR_TYPES: tuple[SensiboDeviceSensorEntityDescription, ...] = (
SensiboDeviceSensorEntityDescription(
key="pm25",
device_class=SensorDeviceClass.PM25,
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
state_class=SensorStateClass.MEASUREMENT,
name="PM2.5",
icon="mdi:air-filter",
value_fn=lambda data: data["pm25"],
),
SensiboDeviceSensorEntityDescription(
key="pure_sensitivity",
name="Pure Sensitivity",
icon="mdi:air-filter",
value_fn=lambda data: data["pure_sensitivity"],
),
)
async def async_setup_entry( async def async_setup_entry(
@ -91,19 +124,28 @@ async def async_setup_entry(
coordinator: SensiboDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] coordinator: SensiboDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
async_add_entities( entities: list[SensiboMotionSensor | SensiboDeviceSensor] = []
entities.extend(
SensiboMotionSensor(coordinator, device_id, sensor_id, sensor_data, description) SensiboMotionSensor(coordinator, device_id, sensor_id, sensor_data, description)
for device_id, device_data in coordinator.data.parsed.items() for device_id, device_data in coordinator.data.parsed.items()
for sensor_id, sensor_data in device_data["motion_sensors"].items() for sensor_id, sensor_data in device_data["motion_sensors"].items()
for description in MOTION_SENSOR_TYPES for description in MOTION_SENSOR_TYPES
if device_data["motion_sensors"] if device_data["motion_sensors"]
) )
entities.extend(
SensiboDeviceSensor(coordinator, device_id, description)
for device_id, device_data in coordinator.data.parsed.items()
for description in DEVICE_SENSOR_TYPES
if device_data[description.key] is not None
)
async_add_entities(entities)
class SensiboMotionSensor(SensiboMotionBaseEntity, SensorEntity): class SensiboMotionSensor(SensiboMotionBaseEntity, SensorEntity):
"""Representation of a Sensibo Motion Sensor.""" """Representation of a Sensibo Motion Sensor."""
entity_description: SensiboSensorEntityDescription entity_description: SensiboMotionSensorEntityDescription
def __init__( def __init__(
self, self,
@ -111,7 +153,7 @@ class SensiboMotionSensor(SensiboMotionBaseEntity, SensorEntity):
device_id: str, device_id: str,
sensor_id: str, sensor_id: str,
sensor_data: MotionSensor, sensor_data: MotionSensor,
entity_description: SensiboSensorEntityDescription, entity_description: SensiboMotionSensorEntityDescription,
) -> None: ) -> None:
"""Initiate Sensibo Motion Sensor.""" """Initiate Sensibo Motion Sensor."""
super().__init__( super().__init__(
@ -131,3 +173,29 @@ class SensiboMotionSensor(SensiboMotionBaseEntity, SensorEntity):
def native_value(self) -> StateType: def native_value(self) -> StateType:
"""Return value of sensor.""" """Return value of sensor."""
return self.entity_description.value_fn(self.sensor_data) return self.entity_description.value_fn(self.sensor_data)
class SensiboDeviceSensor(SensiboDeviceBaseEntity, SensorEntity):
"""Representation of a Sensibo Device Sensor."""
entity_description: SensiboDeviceSensorEntityDescription
def __init__(
self,
coordinator: SensiboDataUpdateCoordinator,
device_id: str,
entity_description: SensiboDeviceSensorEntityDescription,
) -> None:
"""Initiate Sensibo Device Sensor."""
super().__init__(
coordinator,
device_id,
)
self.entity_description = entity_description
self._attr_unique_id = f"{device_id}-{entity_description.key}"
self._attr_name = f"{self.device_data['name']} {entity_description.name}"
@property
def native_value(self) -> StateType:
"""Return value of sensor."""
return self.entity_description.value_fn(self.device_data)