diff --git a/miio/integrations/zhimi/airpurifier/airpurifier_miot.py b/miio/integrations/zhimi/airpurifier/airpurifier_miot.py index 021dd10ad..9d99584dd 100644 --- a/miio/integrations/zhimi/airpurifier/airpurifier_miot.py +++ b/miio/integrations/zhimi/airpurifier/airpurifier_miot.py @@ -225,6 +225,32 @@ "device-display-unit": {"siid": 14, "piid": 1}, } +# https://home.miot-spec.com/spec/xiaomi.airp.cpa5 +_MAPPING_CPA5 = { + # Air Purifier (siid=2) + "power": {"siid": 2, "piid": 1}, + "fault": {"siid": 2, "piid": 2}, + "mode": {"siid": 2, "piid": 3}, + # Environment (siid=3) - no temperature/humidity sensor on this model + "aqi": {"siid": 3, "piid": 4}, + # Filter (siid=4) + "filter_life_remaining": {"siid": 4, "piid": 1}, + "filter_hours_used": {"siid": 4, "piid": 3}, + "filter_left_time": {"siid": 4, "piid": 4}, + # Screen (siid=6) + "led_brightness": {"siid": 6, "piid": 2}, + # Alarm (siid=7) + "buzzer": {"siid": 7, "piid": 1}, + # Physical Control Locked (siid=8) + "child_lock": {"siid": 8, "piid": 1}, + # Favorite level, lives under the "air-purifier-favorite" service (siid=9) + "favorite_level": {"siid": 9, "piid": 1}, + # custom-service (siid=10) + "motor_speed": {"siid": 10, "piid": 1}, + # AQI realtime refresh heartbeat (siid=11) + "aqi_realtime_update_duration": {"siid": 11, "piid": 1}, +} + # https://miot-spec.org/miot-spec-v2/instance?type=urn:miot-spec-v2:device:air-purifier:0000A007:zhimi-za1:2 _MAPPING_ZA1 = { # Air Purifier (siid=2) @@ -281,6 +307,7 @@ "zhimi.airpurifier.rma2": _MAPPING_RMA2, # airpurifier 4 lite "zhimi.airp.rmb1": _MAPPING_RMB1, # airpurifier 4 lite "zhimi.airpurifier.za1": _MAPPING_ZA1, # smartmi air purifier + "xiaomi.airp.cpa5": _MAPPING_CPA5, # Smart Pet Care Air Purifier } # Models requiring reversed led brightness value @@ -290,6 +317,7 @@ "zhimi.airp.mb5a", "zhimi.airp.vb4", "zhimi.airp.rmb1", + "xiaomi.airp.cpa5", ] diff --git a/miio/integrations/zhimi/airpurifier/tests/test_airpurifier_miot.py b/miio/integrations/zhimi/airpurifier/tests/test_airpurifier_miot.py index c4046e039..c5e755257 100644 --- a/miio/integrations/zhimi/airpurifier/tests/test_airpurifier_miot.py +++ b/miio/integrations/zhimi/airpurifier/tests/test_airpurifier_miot.py @@ -299,6 +299,74 @@ def test_set_led(self): self.device.set_led(True) +_INITIAL_STATE_CPA5 = { + "power": True, + "fault": 0, + "mode": 0, + "aqi": 10, + "filter_life_remaining": 80, + "filter_hours_used": 682, + "filter_left_time": 309, + "led_brightness": 1, + "buzzer": False, + "child_lock": False, + "favorite_level": 10, + "motor_speed": 354, +} + + +class DummyAirPurifierMiotCPA5(DummyAirPurifierMiot): + def __init__(self, *args, **kwargs): + self._model = "xiaomi.airp.cpa5" + self.state = _INITIAL_STATE_CPA5 + super().__init__(*args, **kwargs) + + +@pytest.fixture +def airpurifierCPA5(request): + request.cls.device = DummyAirPurifierMiotCPA5() + + +@pytest.mark.usefixtures("airpurifierCPA5") +class TestAirPurifierCPA5(TestCase): + def test_status(self): + status = self.device.status() + assert status.is_on is _INITIAL_STATE_CPA5["power"] + assert status.aqi == _INITIAL_STATE_CPA5["aqi"] + assert status.average_aqi is None + assert status.humidity is None + assert status.temperature is None + assert status.fan_level is None + assert status.led is None + assert status.mode == OperationMode(_INITIAL_STATE_CPA5["mode"]) + assert status.led_brightness == LedBrightness( + _INITIAL_STATE_CPA5["led_brightness"] + ) + assert status.led_brightness_level is None + assert status.buzzer == _INITIAL_STATE_CPA5["buzzer"] + assert status.child_lock == _INITIAL_STATE_CPA5["child_lock"] + assert status.favorite_level == _INITIAL_STATE_CPA5["favorite_level"] + assert ( + status.filter_life_remaining == _INITIAL_STATE_CPA5["filter_life_remaining"] + ) + assert status.filter_hours_used == _INITIAL_STATE_CPA5["filter_hours_used"] + assert status.filter_left_time == _INITIAL_STATE_CPA5["filter_left_time"] + assert status.motor_speed == _INITIAL_STATE_CPA5["motor_speed"] + + def test_set_led_brightness(self): + def led_brightness(): + return self.device.status().led_brightness + + self.device.set_led_brightness(LedBrightness.Bright) + assert led_brightness() == LedBrightness.Bright + + self.device.set_led_brightness(LedBrightness.Dim) + assert led_brightness() == LedBrightness.Dim + + self.device.set_led_brightness(LedBrightness.Off) + assert led_brightness() == LedBrightness.Off + + class DummyAirPurifierMiotVA2(DummyAirPurifierMiot): def __init__(self, *args, **kwargs): self._model = "zhimi.airp.va2"