Repository: zigpy/zha-device-handlers
Pull request #2423 (2023-06-02 20:37:33)

Sync with upcoming zigpy release
## Proposed change
<!--
  Explain your proposed change below.
-->
Zigpy's new `attribute_updated` and ZCL schema changes break unit tests. The Sinope leak sensor also had two attributes called `zone_status`.

## Additional information
<!--
  Please include any additional information that is important to this PR.
  For example, if this PR is a potentially breaking change, mention that here.
  If this PR requires other PRs to be merged in HA Core or other projects, mention that.
  Lastly, if this PR fixes a specific issue, please include "Fixes #xxxx".
-->


## Checklist
<!--
  Put an 'x' in all boxes that apply.
  Note: You do not need to tick all boxes before creating a PR.
-->

- [x] The changes are tested and work correctly
- [x] `pre-commit` checks pass / the code has been formatted using Black
- [ ] Tests have been added to verify that the new code works


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/zigpy/zha-device-handlers/pull/2423?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zigpy) Report
Patch coverage: **`50.00`**% and project coverage change: **`-0.03`** :warning:
> Comparison is base [(`ed244c3`)](https://app.codecov.io/gh/zigpy/zha-device-handlers/commit/ed244c3af9b0ceeff4dcf63521a7c0e394dbca13?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zigpy) 85.28% compared to head [(`c08e3e4`)](https://app.codecov.io/gh/zigpy/zha-device-handlers/pull/2423?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zigpy) 85.25%.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##              dev    #2423      +/-   ##
==========================================
- Coverage   85.28%   85.25%   -0.03%     
==========================================
  Files         270      270              
  Lines        8488     8493       +5     
==========================================
+ Hits         7239     7241       +2     
- Misses       1249     1252       +3     
```


| [Impacted Files](https://app.codecov.io/gh/zigpy/zha-device-handlers/pull/2423?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zigpy) | Coverage Δ | |
|---|---|---|
| [zhaquirks/smartwings/wm25lz.py](https://app.codecov.io/gh/zigpy/zha-device-handlers/pull/2423?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zigpy#diff-emhhcXVpcmtzL3NtYXJ0d2luZ3Mvd20yNWx6LnB5) | `100.00% <ø> (ø)` | |
| [zhaquirks/xiaomi/\_\_init\_\_.py](https://app.codecov.io/gh/zigpy/zha-device-handlers/pull/2423?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zigpy#diff-emhhcXVpcmtzL3hpYW9taS9fX2luaXRfXy5weQ==) | `83.72% <ø> (ø)` | |
| [zhaquirks/xiaomi/aqara/roller\_curtain\_e1.py](https://app.codecov.io/gh/zigpy/zha-device-handlers/pull/2423?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zigpy#diff-emhhcXVpcmtzL3hpYW9taS9hcWFyYS9yb2xsZXJfY3VydGFpbl9lMS5weQ==) | `61.97% <ø> (ø)` | |
| [zhaquirks/sinope/sensor.py](https://app.codecov.io/gh/zigpy/zha-device-handlers/pull/2423?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zigpy#diff-emhhcXVpcmtzL3Npbm9wZS9zZW5zb3IucHk=) | `90.62% <50.00%> (-9.38%)` | :arrow_down: |


</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/zigpy/zha-device-handlers/pull/2423?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zigpy).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=zigpy).


Patch:
diff --git a/setup.py b/setup.py
index f21605f..0f81e4e 100644
--- a/setup.py
+++ b/setup.py
@@ -20,6 +20,6 @@ setup(
     keywords="zha quirks homeassistant hass",
     packages=find_packages(exclude=["tests"]),
     python_requires=">=3.8",
-    install_requires=["zigpy>=0.53"],
+    install_requires=["zigpy>=0.56.0"],
     tests_require=["pytest"],
 )
diff --git a/zhaquirks/sinope/sensor.py b/zhaquirks/sinope/sensor.py
index 2048d9a..7e38de7 100644
--- a/zhaquirks/sinope/sensor.py
+++ b/zhaquirks/sinope/sensor.py
@@ -45,8 +45,8 @@ class SinopeManufacturerCluster(CustomCluster):
 class SinopeTechnologiesIasZoneCluster(CustomCluster, IasZone):
     """SinopeTechnologiesIasZoneCluster custom cluster."""
 
-    class ZoneStatus(t.enum8):
-        """zone_status values."""
+    class LeakStatus(t.enum8):
+        """leak_status values."""
 
         Dry = 0x00
         Leak = 0x01
@@ -54,7 +54,7 @@ class SinopeTechnologiesIasZoneCluster(CustomCluster, IasZone):
     attributes = IasZone.attributes.copy()
     attributes.update(
         {
-            0x0030: ("zone_status", ZoneStatus, True),
+            0x0030: ("leak_status", LeakStatus, True),
         }
     )
 
diff --git a/zhaquirks/smartwings/wm25lz.py b/zhaquirks/smartwings/wm25lz.py
index a394e92..b761a19 100644
--- a/zhaquirks/smartwings/wm25lz.py
+++ b/zhaquirks/smartwings/wm25lz.py
@@ -40,7 +40,6 @@ class InvertedWindowCoveringCluster(CustomCluster, WindowCovering):
         *args,
         manufacturer: int | t.uint16_t | None = None,
         expect_reply: bool = True,
-        tries: int = 1,
         tsn: int | t.uint8_t | None = None,
         **kwargs: Any,
     ) -> Coroutine:
@@ -56,7 +55,6 @@ class InvertedWindowCoveringCluster(CustomCluster, WindowCovering):
             *args,
             manufacturer=manufacturer,
             expect_reply=expect_reply,
-            tries=tries,
             tsn=tsn,
             **kwargs,
         )
diff --git a/zhaquirks/xiaomi/__init__.py b/zhaquirks/xiaomi/__init__.py
index 79711d8..52148ae 100644
--- a/zhaquirks/xiaomi/__init__.py
+++ b/zhaquirks/xiaomi/__init__.py
@@ -676,7 +676,6 @@ class OnOffCluster(OnOff, CustomCluster):
         *args,
         manufacturer: int | t.uint16_t | None = None,
         expect_reply: bool = True,
-        tries: int = 1,
         tsn: int | t.uint8_t | None = None,
         **kwargs: Any,
     ):
diff --git a/zhaquirks/xiaomi/aqara/roller_curtain_e1.py b/zhaquirks/xiaomi/aqara/roller_curtain_e1.py
index 0adb579..1f1a01f 100644
--- a/zhaquirks/xiaomi/aqara/roller_curtain_e1.py
+++ b/zhaquirks/xiaomi/aqara/roller_curtain_e1.py
@@ -100,7 +100,6 @@ class WindowCoveringRollerE1(CustomCluster, WindowCovering):
         *args: Any,
         manufacturer: int | t.uint16_t | None = None,
         expect_reply: bool = True,
-        tries: int = 1,
         tsn: int | t.uint8_t | None = None,
         **kwargs: Any,
     ) -> Any:


Test patch:
diff --git a/tests/common.py b/tests/common.py
index 9ced1c1..dde6ac0 100644
--- a/tests/common.py
+++ b/tests/common.py
@@ -15,7 +15,7 @@ class ClusterListener:
         self.attribute_updates = []
         cluster.add_listener(self)
 
-    def attribute_updated(self, attr_id, value):
+    def attribute_updated(self, attr_id, value, timestamp):
         """Attribute updated listener."""
         self.attribute_updates.append((attr_id, value))
 
diff --git a/tests/test_xiaomi.py b/tests/test_xiaomi.py
index dcab84e..bfc3bed 100644
--- a/tests/test_xiaomi.py
+++ b/tests/test_xiaomi.py
@@ -581,88 +581,96 @@ async def test_aqara_feeder_write_attrs(
             b"\x1c_\x11f\n\xf1\xffA\t\x00\x05\x01\x04\x15\x00U\x01\x01",
             2,
             [
-                mock.call(ZCL_FEEDING, True),
-                mock.call(FEEDER_ATTR, b"\x00\x05\x01\x04\x15\x00U\x01\x01"),
+                mock.call(ZCL_FEEDING, True, mock.ANY),
+                mock.call(FEEDER_ATTR, b"\x00\x05\x01\x04\x15\x00U\x01\x01", mock.ANY),
             ],
         ),
         (
             b"\x1c_\x11l\n\xf1\xffA\x0c\x00\x05\xd0\x04\x15\x02\xbc\x040203",
             3,
             [
-                mock.call(ZCL_LAST_FEEDING_SIZE, 3),
-                mock.call(ZCL_LAST_FEEDING_SOURCE, OppleCluster.FeedingSource.Remote),
-                mock.call(FEEDER_ATTR, b"\x00\x05\xd0\x04\x15\x02\xbc\x040203"),
+                mock.call(ZCL_LAST_FEEDING_SIZE, 3, mock.ANY),
+                mock.call(
+                    ZCL_LAST_FEEDING_SOURCE, OppleCluster.FeedingSource.Remote, mock.ANY
+                ),
+                mock.call(
+                    FEEDER_ATTR, b"\x00\x05\xd0\x04\x15\x02\xbc\x040203", mock.ANY
+                ),
             ],
         ),
         (
             b"\x1c_\x11m\n\xf1\xffA\n\x00\x05\xd1\rh\x00U\x02\x00!",
             2,
             [
-                mock.call(ZCL_PORTIONS_DISPENSED, 33),
-                mock.call(FEEDER_ATTR, b"\x00\x05\xd1\rh\x00U\x02\x00!"),
+                mock.call(ZCL_PORTIONS_DISPENSED, 33, mock.ANY),
+                mock.call(FEEDER_ATTR, b"\x00\x05\xd1\rh\x00U\x02\x00!", mock.ANY),
             ],
         ),
         (
             b"\x1c_\x11n\n\xf1\xffA\x0c\x00\x05\xd2\ri\x00U\x04\x00\x00\x01\x08",
             2,
             [
-                mock.call(ZCL_WEIGHT_DISPENSED, 264),
-                mock.call(FEEDER_ATTR, b"\x00\x05\xd2\ri\x00U\x04\x00\x00\x01\x08"),
+                mock.call(ZCL_WEIGHT_DISPENSED, 264, mock.ANY),
+                mock.call(
+                    FEEDER_ATTR, b"\x00\x05\xd2\ri\x00U\x04\x00\x00\x01\x08", mock.ANY
+                ),
             ],
         ),
         (
             b"\x1c_\x11o\n\xf1\xffA\t\x00\x05\xd3\r\x0b\x00U\x01\x00",
             2,
             [
-                mock.call(ZCL_ERROR_DETECTED, False),
-                mock.call(FEEDER_ATTR, b"\x00\x05\xd3\r\x0b\x00U\x01\x00"),
+                mock.call(ZCL_ERROR_DETECTED, False, mock.ANY),
+                mock.call(FEEDER_ATTR, b"\x00\x05\xd3\r\x0b\x00U\x01\x00", mock.ANY),
             ],
         ),
         (
             b"\x1c_\x11p\n\xf1\xffA\t\x00\x05\x05\x04\x16\x00U\x01\x01",
             2,
             [
-                mock.call(ZCL_CHILD_LOCK, True),
-                mock.call(FEEDER_ATTR, b"\x00\x05\x05\x04\x16\x00U\x01\x01"),
+                mock.call(ZCL_CHILD_LOCK, True, mock.ANY),
+                mock.call(FEEDER_ATTR, b"\x00\x05\x05\x04\x16\x00U\x01\x01", mock.ANY),
             ],
         ),
         (
             b"\x1c_\x11r\n\xf1\xffA\t\x00\x05\t\x04\x17\x00U\x01\x01",
             2,
             [
-                mock.call(ZCL_DISABLE_LED_INDICATOR, True),
-                mock.call(FEEDER_ATTR, b"\x00\x05\t\x04\x17\x00U\x01\x01"),
+                mock.call(ZCL_DISABLE_LED_INDICATOR, True, mock.ANY),
+                mock.call(FEEDER_ATTR, b"\x00\x05\t\x04\x17\x00U\x01\x01", mock.ANY),
             ],
         ),
         (
             b"\x1c_\x11s\n\xf1\xffA\t\x00\x05\x0b\x04\x18\x00U\x01\x01",
             2,
             [
-                mock.call(ZCL_FEEDING_MODE, OppleCluster.FeedingMode.Schedule),
-                mock.call(FEEDER_ATTR, b"\x00\x05\x0b\x04\x18\x00U\x01\x01"),
+                mock.call(
+                    ZCL_FEEDING_MODE, OppleCluster.FeedingMode.Schedule, mock.ANY
+                ),
+                mock.call(FEEDER_ATTR, b"\x00\x05\x0b\x04\x18\x00U\x01\x01", mock.ANY),
             ],
         ),
         (
             b"\x1c_\x11u\n\xf1\xffA\t\x00\x05\x0f\x0e_\x00U\x01\x06",
             2,
             [
-                mock.call(ZCL_PORTION_WEIGHT, 6),
-                mock.call(FEEDER_ATTR, b"\x00\x05\x0f\x0e_\x00U\x01\x06"),
+                mock.call(ZCL_PORTION_WEIGHT, 6, mock.ANY),
+                mock.call(FEEDER_ATTR, b"\x00\x05\x0f\x0e_\x00U\x01\x06", mock.ANY),
             ],
         ),
         (
             b"\x1c_\x11v\n\xf1\xffA\t\x00\x05\x11\x0e\\\x00U\x01\x02",
             2,
             [
-                mock.call(ZCL_SERVING_SIZE, 2),
-                mock.call(FEEDER_ATTR, b"\x00\x05\x11\x0e\\\x00U\x01\x02"),
+                mock.call(ZCL_SERVING_SIZE, 2, mock.ANY),
+                mock.call(FEEDER_ATTR, b"\x00\x05\x11\x0e\\\x00U\x01\x02", mock.ANY),
             ],
         ),
         (
             b"\x1c_\x11{\n\xf7\x00A\x0e\x05!\x0e\x00\r#!%\x00\x00\t!\x02\x03",
             1,
             [
-                mock.call(0x00F7, b"\x05!\x0e\x00\r#!%\x00\x00\t!\x02\x03"),
+                mock.call(0x00F7, b"\x05!\x0e\x00\r#!%\x00\x00\t!\x02\x03", mock.ANY),
             ],
         ),
         (
@@ -672,6 +680,7 @@ async def test_aqara_feeder_write_attrs(
                 mock.call(
                     FEEDER_ATTR,
                     b"\x00\x05\x15\x08\x00\x08\xc8 7F09000100,7F0D000100,7F13000100",
+                    mock.ANY,
                 ),
             ],
         ),