Add Pure devices to Sensibo (#67695)
This commit is contained in:
parent
65821f9492
commit
a6c189b450
5 changed files with 90 additions and 16 deletions
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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"]
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue