Repository: mill1000/midea-msmart
Pull request #125 (2024-05-07 21:29:22)

Fix unsupported property warnings for Buzzer ID in logs
When testing Anion supports, some other warnings were generated in the logs about an unsupported property

```
2024-05-07 00:28:46.302 WARNING (MainThread) [msmart.device.AC.command] Unsupported property. ID: 0x001A, Size: 1.
``` 

This is due to #120, in which the Buzzer property was inserted into every Properties command. However, a parser was never defined for the response.

We don't really care about the response, so define a parser that returns None and don't store it.


Patch:
diff --git a/msmart/device/AC/command.py b/msmart/device/AC/command.py
index 7944dea..6871bba 100644
--- a/msmart/device/AC/command.py
+++ b/msmart/device/AC/command.py
@@ -485,7 +485,7 @@ class CapabilitiesResponse(Response):
                 capability_id = CapabilityId(raw_id)
             except ValueError:
                 _LOGGER.warning(
-                    "Unknown capability. ID: 0x%4X, Size: %d.", raw_id, size)
+                    "Unknown capability. ID: 0x%04X, Size: %d.", raw_id, size)
                 # Advanced to next capability
                 caps = caps[3+size:]
                 continue
@@ -792,6 +792,7 @@ class PropertiesResponse(Response):
         # keys for each. e.g. capabilities
         parsers = {
             PropertyId.ANION: lambda v: v[0],
+            PropertyId.BUZZER: lambda v: None,  # Don't bother parsing buzzer state
             PropertyId.FRESH_AIR: lambda v: (v[0], v[1], v[2]),
             PropertyId.INDOOR_HUMIDITY: lambda v: v[0],
             PropertyId.RATE_SELECT: lambda v: v[0],
@@ -823,7 +824,7 @@ class PropertiesResponse(Response):
                 property = PropertyId(raw_id)
             except ValueError:
                 _LOGGER.warning(
-                    "Unknown property. ID: 0x%4X, Size: %d.", raw_id, size)
+                    "Unknown property. ID: 0x%04X, Size: %d.", raw_id, size)
                 # Advanced to next property
                 props = props[4+size:]
                 continue
@@ -834,7 +835,8 @@ class PropertiesResponse(Response):
             # Apply parser if it exists
             if parser is not None:
                 # Parse the property
-                self._properties.update({property: parser(props[4:])})
+                if (value := parser(props[4:])) is not None:
+                    self._properties.update({property: value})
 
             else:
                 _LOGGER.warning(


Test patch:
diff --git a/msmart/device/AC/test_command.py b/msmart/device/AC/test_command.py
index 11e963a..209c89f 100644
--- a/msmart/device/AC/test_command.py
+++ b/msmart/device/AC/test_command.py
@@ -1,3 +1,4 @@
+import logging
 import unittest
 from typing import Union, cast
 
@@ -353,6 +354,9 @@ class TestCapabilitiesResponse(_TestResponseBase):
             resp = self._test_build_response(TEST_CAPABILITIES_RESPONSE)
             resp = cast(CapabilitiesResponse, resp)
 
+            # Check warning is generated for ID 0x0040
+            self.assertRegex(log.output[0], "Unknown capability. ID: 0x0040")
+
         EXPECTED_RAW_CAPABILITIES = {
             "eco_mode": True, "eco_mode_2": False, "silky_cool": False,
             "heat_mode": True, "cool_mode": True, "dry_mode": True,
@@ -477,6 +481,9 @@ class TestCapabilitiesResponse(_TestResponseBase):
             resp = self._test_build_response(TEST_CAPABILITIES_RESPONSE)
             resp = cast(CapabilitiesResponse, resp)
 
+            # Check warning is generated for ID 0x0040
+            self.assertRegex(log.output[0], "Unknown capability. ID: 0x0040")
+
         EXPECTED_RAW_CAPABILITIES = {
             "eco_mode": True, "eco_mode_2": False,
             "breeze_control": True,
@@ -663,7 +670,7 @@ class TestPropertiesResponse(_TestResponseBase):
         self.assertEqual(resp.get_property(PropertyId.SWING_UD_ANGLE), 0)
 
     def test_properties_notify(self) -> None:
-        """Test ignore property notifications."""
+        """Test we ignore property notifications."""
         # https://github.com/mill1000/midea-msmart/issues/122
         TEST_RESPONSE = bytes.fromhex(
             "aa1aac00000000000205b50310060101090001010a000101dcbcb4")
@@ -673,6 +680,25 @@ class TestPropertiesResponse(_TestResponseBase):
         # Assert response is generic
         self.assertEqual(type(resp), Response)
 
+    def test_properties_unknown_and_invalid(self) -> None:
+        """Test we warn when decoding unknown properties and that invalid properties are not stored."""
+        # https://github.com/mill1000/midea-ac-py/issues/128#issuecomment-2098342003
+        TEST_RESPONSE = bytes.fromhex(
+            "aa1bac00000000000202b0021e001004001000001a00000100000e18")
+
+        with self.assertLogs("msmart", logging.WARNING) as log:
+            resp = self._test_build_response(TEST_RESPONSE)
+            resp = cast(PropertiesResponse, resp)
+
+            # Check warning is generated for ID 0x001E
+            self.assertRegex(log.output[0], "Unknown property. ID: 0x001E")
+
+        # Assert response is a correct type
+        self.assertEqual(type(resp), PropertiesResponse)
+
+        # Assert that the buzzer property is not decoded
+        self.assertIsNone(resp.get_property(PropertyId.BUZZER))
+
 
 class TestResponseConstruct(_TestResponseBase):
     """Test construction of responses from raw data."""