From 5abf77662a4d317cc26fd4c2a9db46ffee19b414 Mon Sep 17 00:00:00 2001 From: Robert Svensson Date: Wed, 22 May 2024 07:33:55 +0200 Subject: [PATCH] Support carbon dioxide and formaldehyde sensors in deCONZ (#117877) * Add formaldehyde sensor * Add carbon dioxide sensor * Bump pydeconz to v116 --- homeassistant/components/deconz/manifest.json | 2 +- homeassistant/components/deconz/sensor.py | 24 ++++++ requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/deconz/test_sensor.py | 86 +++++++++++++++++++ 5 files changed, 113 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/deconz/manifest.json b/homeassistant/components/deconz/manifest.json index ef2f4a73c1b..2f58cacfa2c 100644 --- a/homeassistant/components/deconz/manifest.json +++ b/homeassistant/components/deconz/manifest.json @@ -8,7 +8,7 @@ "iot_class": "local_push", "loggers": ["pydeconz"], "quality_scale": "platinum", - "requirements": ["pydeconz==115"], + "requirements": ["pydeconz==116"], "ssdp": [ { "manufacturer": "Royal Philips Electronics", diff --git a/homeassistant/components/deconz/sensor.py b/homeassistant/components/deconz/sensor.py index 750019dc680..e67c0129147 100644 --- a/homeassistant/components/deconz/sensor.py +++ b/homeassistant/components/deconz/sensor.py @@ -11,8 +11,10 @@ from pydeconz.interfaces.sensors import SensorResources from pydeconz.models.event import EventType from pydeconz.models.sensor import SensorBase as PydeconzSensorBase from pydeconz.models.sensor.air_quality import AirQuality +from pydeconz.models.sensor.carbon_dioxide import CarbonDioxide from pydeconz.models.sensor.consumption import Consumption from pydeconz.models.sensor.daylight import DAYLIGHT_STATUS, Daylight +from pydeconz.models.sensor.formaldehyde import Formaldehyde from pydeconz.models.sensor.generic_status import GenericStatus from pydeconz.models.sensor.humidity import Humidity from pydeconz.models.sensor.light_level import LightLevel @@ -76,8 +78,10 @@ ATTR_EVENT_ID = "event_id" T = TypeVar( "T", AirQuality, + CarbonDioxide, Consumption, Daylight, + Formaldehyde, GenericStatus, Humidity, LightLevel, @@ -155,6 +159,16 @@ ENTITY_DESCRIPTIONS: tuple[DeconzSensorDescription, ...] = ( state_class=SensorStateClass.MEASUREMENT, native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, ), + DeconzSensorDescription[CarbonDioxide]( + key="carbon_dioxide", + supported_fn=lambda device: True, + update_key="measured_value", + value_fn=lambda device: device.carbon_dioxide, + instance_check=CarbonDioxide, + device_class=SensorDeviceClass.CO2, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=CONCENTRATION_PARTS_PER_BILLION, + ), DeconzSensorDescription[Consumption]( key="consumption", supported_fn=lambda device: device.consumption is not None, @@ -174,6 +188,16 @@ ENTITY_DESCRIPTIONS: tuple[DeconzSensorDescription, ...] = ( icon="mdi:white-balance-sunny", entity_registry_enabled_default=False, ), + DeconzSensorDescription[Formaldehyde]( + key="formaldehyde", + supported_fn=lambda device: True, + update_key="measured_value", + value_fn=lambda device: device.formaldehyde, + instance_check=Formaldehyde, + device_class=SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS, + state_class=SensorStateClass.MEASUREMENT, + native_unit_of_measurement=CONCENTRATION_PARTS_PER_BILLION, + ), DeconzSensorDescription[GenericStatus]( key="status", supported_fn=lambda device: device.status is not None, diff --git a/requirements_all.txt b/requirements_all.txt index 8074401a955..2e2de8ac7e7 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1773,7 +1773,7 @@ pydaikin==2.11.1 pydanfossair==0.1.0 # homeassistant.components.deconz -pydeconz==115 +pydeconz==116 # homeassistant.components.delijn pydelijn==1.1.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 24892d2093d..f1adec850a1 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1390,7 +1390,7 @@ pycsspeechtts==1.0.8 pydaikin==2.11.1 # homeassistant.components.deconz -pydeconz==115 +pydeconz==116 # homeassistant.components.dexcom pydexcom==0.2.3 diff --git a/tests/components/deconz/test_sensor.py b/tests/components/deconz/test_sensor.py index 4950928f2e6..1e1ca6efe7c 100644 --- a/tests/components/deconz/test_sensor.py +++ b/tests/components/deconz/test_sensor.py @@ -275,6 +275,49 @@ TEST_DATA = [ "next_state": "50", }, ), + ( # Carbon dioxide sensor + { + "capabilities": { + "measured_value": { + "unit": "PPB", + } + }, + "config": { + "on": True, + "reachable": True, + }, + "etag": "dc3a3788ddd2a2d175ead376ea4d814c", + "lastannounced": None, + "lastseen": "2024-02-02T21:13Z", + "manufacturername": "_TZE200_dwcarsat", + "modelid": "TS0601", + "name": "CarbonDioxide 35", + "state": { + "lastupdated": "2024-02-02T21:14:37.745", + "measured_value": 370, + }, + "type": "ZHACarbonDioxide", + "uniqueid": "xx:xx:xx:xx:xx:xx:xx:xx-01-040d", + }, + { + "entity_count": 1, + "device_count": 3, + "entity_id": "sensor.carbondioxide_35", + "unique_id": "xx:xx:xx:xx:xx:xx:xx:xx-01-040d-carbon_dioxide", + "state": "370", + "entity_category": None, + "device_class": SensorDeviceClass.CO2, + "state_class": CONCENTRATION_PARTS_PER_BILLION, + "attributes": { + "device_class": "carbon_dioxide", + "friendly_name": "CarbonDioxide 35", + "state_class": SensorStateClass.MEASUREMENT, + "unit_of_measurement": CONCENTRATION_PARTS_PER_BILLION, + }, + "websocket_event": {"state": {"measured_value": 500}}, + "next_state": "500", + }, + ), ( # Consumption sensor { "config": {"on": True, "reachable": True}, @@ -354,6 +397,49 @@ TEST_DATA = [ "next_state": "dusk", }, ), + ( # Formaldehyde + { + "capabilities": { + "measured_value": { + "unit": "PPM", + } + }, + "config": { + "on": True, + "reachable": True, + }, + "etag": "bb01ac0313b6724e8c540a6eef7cc3cb", + "lastannounced": None, + "lastseen": "2024-02-02T21:13Z", + "manufacturername": "_TZE200_dwcarsat", + "modelid": "TS0601", + "name": "Formaldehyde 34", + "state": { + "lastupdated": "2024-02-02T21:14:46.810", + "measured_value": 1, + }, + "type": "ZHAFormaldehyde", + "uniqueid": "xx:xx:xx:xx:xx:xx:xx:xx-01-042b", + }, + { + "entity_count": 1, + "device_count": 3, + "entity_id": "sensor.formaldehyde_34", + "unique_id": "xx:xx:xx:xx:xx:xx:xx:xx-01-042b-formaldehyde", + "state": "1", + "entity_category": None, + "device_class": SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS, + "state_class": SensorStateClass.MEASUREMENT, + "attributes": { + "device_class": "volatile_organic_compounds", + "friendly_name": "Formaldehyde 34", + "state_class": SensorStateClass.MEASUREMENT, + "unit_of_measurement": CONCENTRATION_PARTS_PER_BILLION, + }, + "websocket_event": {"state": {"measured_value": 2}}, + "next_state": "2", + }, + ), ( # Generic status sensor { "config": {