diff --git a/libdyson/__init__.py b/libdyson/__init__.py index d621db2..d6d6d33 100644 --- a/libdyson/__init__.py +++ b/libdyson/__init__.py @@ -6,7 +6,7 @@ DEVICE_TYPE_360_EYE, DEVICE_TYPE_360_HEURIST, DEVICE_TYPE_PURE_COOL, - DEVICE_TYPE_PURE_COOL_2021, + DEVICE_TYPE_PURE_COOL_FORMALDEHYDE, DEVICE_TYPE_PURE_COOL_DESK, DEVICE_TYPE_PURE_COOL_LINK, DEVICE_TYPE_PURE_COOL_LINK_DESK, @@ -29,6 +29,7 @@ from .dyson_360_heurist import Dyson360Heurist from .dyson_device import DysonDevice from .dyson_pure_cool import DysonPureCool +from .dyson_pure_cool import DysonPureCoolFormaldehyde from .dyson_pure_cool_link import DysonPureCoolLink from .dyson_pure_hot_cool import DysonPureHotCool from .dyson_pure_hot_cool_link import DysonPureHotCoolLink @@ -49,15 +50,16 @@ def get_device(serial: str, credential: str, device_type: str) -> Optional[Dyson return DysonPureCoolLink(serial, credential, device_type) if device_type in [ DEVICE_TYPE_PURE_COOL, - DEVICE_TYPE_PURE_COOL_2021, DEVICE_TYPE_PURE_COOL_DESK, ]: return DysonPureCool(serial, credential, device_type) + if device_type == DEVICE_TYPE_PURE_COOL_FORMALDEHYDE: + return DysonPureCoolFormaldehyde(serial, credential, device_type) if device_type == DEVICE_TYPE_PURE_HOT_COOL_LINK: return DysonPureHotCoolLink(serial, credential, device_type) - if device_type in [ - DEVICE_TYPE_PURE_HOT_COOL, - DEVICE_TYPE_PURE_HOT_COOL_NEW, + if device_type in [ + DEVICE_TYPE_PURE_HOT_COOL, + DEVICE_TYPE_PURE_HOT_COOL_NEW, ]: return DysonPureHotCool(serial, credential, device_type) if device_type == DEVICE_TYPE_PURE_HUMIDIFY_COOL: diff --git a/libdyson/const.py b/libdyson/const.py index 180e564..324ef0b 100644 --- a/libdyson/const.py +++ b/libdyson/const.py @@ -6,7 +6,7 @@ DEVICE_TYPE_PURE_COOL_LINK = "475" DEVICE_TYPE_PURE_COOL_LINK_DESK = "469" DEVICE_TYPE_PURE_COOL = "438" -DEVICE_TYPE_PURE_COOL_2021 = "438E" # Not sure about the official name +DEVICE_TYPE_PURE_COOL_FORMALDEHYDE = "438E" DEVICE_TYPE_PURE_COOL_DESK = "520" DEVICE_TYPE_PURE_HUMIDIFY_COOL = "358" DEVICE_TYPE_PURE_HOT_COOL_LINK = "455" @@ -17,7 +17,7 @@ DEVICE_TYPE_360_EYE: "360 Eye robot vacuum", DEVICE_TYPE_360_HEURIST: "360 Heurist robot vacuum", DEVICE_TYPE_PURE_COOL: "Pure Cool", - DEVICE_TYPE_PURE_COOL_2021: "Pure Cool (2021)", + DEVICE_TYPE_PURE_COOL_FORMALDEHYDE: "Pure Cool Formaldehyde", DEVICE_TYPE_PURE_COOL_DESK: "Pure Cool Desk", DEVICE_TYPE_PURE_COOL_LINK: "Pure Cool Link", DEVICE_TYPE_PURE_COOL_LINK_DESK: "Pure Cool Link Desk", diff --git a/libdyson/dyson_pure_cool.py b/libdyson/dyson_pure_cool.py index e637a1d..08e1571 100644 --- a/libdyson/dyson_pure_cool.py +++ b/libdyson/dyson_pure_cool.py @@ -175,3 +175,20 @@ def disable_oscillation(self) -> None: else: oson = "OFF" self._set_configuration(oson=oson) + + +class DysonPureCoolFormaldehyde(DysonPureCool): + """This model is compatible with PureCool but has one additional sensor.""" + + @property + def formaldehyde(self) -> Optional[int]: + """Return formaldehyde reading.""" + # Dyson documentation for Dyson Pure Cool Formaldehyde refers to + # the formaldehyde reading as HCHO (pp5). + # https://www.dyson.com/content/dam/dyson/maintenance/user-guides/en_US/airtreatment/purifiers/TP09/497043-01.pdf + # + # H-CHO is also a common way to refer to formaldehyde. + # + # This is part of environmental data as per: + # https://github.com/seanrees/prometheus-dyson/issues/13#issue-923525150 + return self._get_environmental_field_value("hcho") diff --git a/tests/test_init.py b/tests/test_init.py index 45b833a..d29fc59 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -7,7 +7,7 @@ DEVICE_TYPE_360_EYE, DEVICE_TYPE_360_HEURIST, DEVICE_TYPE_PURE_COOL, - DEVICE_TYPE_PURE_COOL_2021, + DEVICE_TYPE_PURE_COOL_FORMALDEHYDE, DEVICE_TYPE_PURE_COOL_DESK, DEVICE_TYPE_PURE_COOL_LINK, DEVICE_TYPE_PURE_COOL_LINK_DESK, @@ -19,6 +19,7 @@ Dyson360Heurist, DysonDevice, DysonPureCool, + DysonPureCoolFormaldehyde, DysonPureCoolLink, DysonPureHotCool, DysonPureHotCoolLink, @@ -37,7 +38,7 @@ (DEVICE_TYPE_PURE_COOL_LINK_DESK, DysonPureCoolLink), (DEVICE_TYPE_PURE_COOL_LINK, DysonPureCoolLink), (DEVICE_TYPE_PURE_COOL, DysonPureCool), - (DEVICE_TYPE_PURE_COOL_2021, DysonPureCool), + (DEVICE_TYPE_PURE_COOL_FORMALDEHYDE, DysonPureCoolFormaldehyde), (DEVICE_TYPE_PURE_COOL_DESK, DysonPureCool), (DEVICE_TYPE_PURE_HOT_COOL_LINK, DysonPureHotCoolLink), (DEVICE_TYPE_PURE_HOT_COOL, DysonPureHotCool), diff --git a/tests/test_pure_cool_formaldehyde.py b/tests/test_pure_cool_formaldehyde.py new file mode 100644 index 0000000..ec4a3f1 --- /dev/null +++ b/tests/test_pure_cool_formaldehyde.py @@ -0,0 +1,69 @@ +"""Tests for Pure Cool Formaldehyde""" + +import pytest + +from libdyson.const import ( + DEVICE_TYPE_PURE_COOL_FORMALDEHYDE, + ENVIRONMENTAL_FAIL, + ENVIRONMENTAL_INIT, + ENVIRONMENTAL_OFF, +) +from libdyson.dyson_pure_cool import DysonPureCoolFormaldehyde + +from . import CREDENTIAL, HOST, SERIAL +from .mocked_mqtt import MockedMQTT +from .test_pure_cool import STATUS as TEST_PURE_COOL_STATUS + +DEVICE_TYPE = DEVICE_TYPE_PURE_COOL_FORMALDEHYDE + +STATUS = TEST_PURE_COOL_STATUS +ENVIRONMENTAL_DATA = { + "data": { + "tact": "OFF", + "hact": "OFF", + "pm25": "OFF", + "pm10": "OFF", + "va10": "INIT", + "noxl": "FAIL", + "p25r": "OFF", + "p10r": "OFF", + "sltm": "OFF", + "hcho": "OFF", + "hchr": "OFF", + } +} + + +def test_properties(mqtt_client: MockedMQTT): + """Test properties of Pure Cool Link Formaldehyde.""" + device = DysonPureCoolFormaldehyde(SERIAL, CREDENTIAL, DEVICE_TYPE) + device.connect(HOST) + + # Environmental + assert device.particulate_matter_2_5 == ENVIRONMENTAL_OFF + assert device.particulate_matter_10 == ENVIRONMENTAL_OFF + assert device.volatile_organic_compounds == ENVIRONMENTAL_INIT + assert device.nitrogen_dioxide == ENVIRONMENTAL_FAIL + assert device.formaldehyde == ENVIRONMENTAL_OFF + + mqtt_client._environmental_data = { + "data": { + "tact": "2977", + "hact": "0058", + "pm25": "0009", + "pm10": "0005", + "va10": "0004", + "noxl": "0011", + "p25r": "0010", + "p10r": "0009", + "sltm": "OFF", + "hcho": "0001", + "hchr": "0002", + } + } + device.request_environmental_data() + assert device.particulate_matter_2_5 == 9 + assert device.particulate_matter_10 == 5 + assert device.volatile_organic_compounds == 4 + assert device.nitrogen_dioxide == 11 + assert device.formaldehyde == 1