We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[Device Support Request] Decoupled mode for ctrl_neutral (QBKG04LM/QBKG03LM/QBKG21LM/QBKG22LM)
**Is your feature request related to a problem? Please describe.**
Similar to #365, but for `ctrl_neutral` implementation. I think that once implemented it can be easily adapted.

In my case I want to implement QBKG04LM decoupled mode.
It can be done easily, following @albalaing indications (https://github.com/zigpy/zha-device-handlers/issues/365#issuecomment-636510316).

The problem is that without the click button events it is not useful, so it is necessary to also implement the generation of ZHA events.

**Describe the solution you'd like**

Before implement anything you can see that device generate 4 messages:
```
2021-01-09 21:46:29 DEBUG (MainThread) [zigpy.device] Ignoring message (b'18500a0000100000001001') on cluster 6: unknown endpoint or cluster id: 4
2021-01-09 21:46:31 DEBUG (MainThread) [zigpy.device] Ignoring message (b'18510a00001000') on cluster 6: unknown endpoint or cluster id: 4
2021-01-09 21:46:32 DEBUG (MainThread) [zigpy.device] Ignoring message (b'18520a00001001') on cluster 6: unknown endpoint or cluster id: 4
2021-01-09 21:46:32 DEBUG (MainThread) [zigpy.device] Ignoring message (b'18530a00001002') on cluster 6: unknown endpoint or cluster id: 4
```

This messages are (in order):
* click
* hold
* release
* double_click

You can see that the click message corresponds in some way to the hold+release messages (00001000+00001001)


I think I'm halfway done (the decoupled part is working as expected), but I'm not satisfied with the event generation part. 


When a `replacement` for endpoint 4 (and 5) is implemented you can get the `on_off` attribute reported. But IMO this approach has the following problems:
* add a new entity in HA for click button events
* it is not possible to differentiate the `click` event from `hold` and `release`
* the `double_click` event cannot be handled (parse error)


Want I think that would be implemented is:
* no HA button entity
* full events control, not only hold and release


Any help in this regard is welcome.


**Device signature - this can be acquired by removing the device from ZHA and pairing it again from the add devices screen. Be sure to add the entire content of the log panel after pairing the device to a code block below this line.**
The device signature is known and correct.

**Additional context**
Although I am not sure if it can be done this way, I have tried without success to implement a replacement that transforms events from the `OnOff` cluster to the `MultistateInput` cluster.

My current implementation is as follows (only the relevant part):
```
    class BasicClusterDecoupled(BasicCluster):
        """Adds attributes for decoupled mode"""
        def __init__(self, *args, **kwargs):
            """Init."""
            self.attributes = BasicCluster.attributes.copy()
            self.attributes.update({ 0xFF22: ("left_decoupled_mode", t.uint8_t)})
            self.attributes.update({ 0xFF23: ("right_decoupled_mode", t.uint8_t)})
            super().__init__(*args, **kwargs)


    class CustomOnOffCluster(OnOffCluster):
        """Fire ZHA events for on off cluster."""

        cluster_id = OnOff.cluster_id

        def __init__(self, *args, **kwargs):
            """Init."""
            self._current_state = {}
            super().__init__(*args, **kwargs)

        def _update_attribute(self, attrid, value):
            _LOGGER.info("%s: %s", attrid, value)
            if attrid == 0:
                self._current_state = PRESS_TYPES.get(value)
                event_args = {
                    PRESS_TYPE: self._current_state,
                    VALUE: value,
                }
                self.listener_event(ZHA_SEND_EVENT, COMMAND_CLICK, event_args)
            super()._update_attribute(attrid, self._current_state)


    replacement = {
        SKIP_CONFIGURATION: True,
        ENDPOINTS: {
            .../...
            4: {                                                                   
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,                         
                INPUT_CLUSTERS: [                                                  
                    MultistateInput.cluster_id,                                        
                    CustomOnOffCluster,                                        
                ],                                                                 
                OUTPUT_CLUSTERS: [],                                               
            },  
            5: {                                                                   
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,                         
                INPUT_CLUSTERS: [                                                  
                    MultistateInput.cluster_id,                                        
                    CustomOnOffCluster,                                        
                ],                                                                 
                OUTPUT_CLUSTERS: [],                                               
            },  
        },
    }
```



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `zhaquirks/xiaomi/aqara/ctrl_neutral.py`
Content:
```
1 """Xiaomi aqara single key wall switch devices."""
2 import logging
3 
4 from zigpy.profiles import zha
5 from zigpy.zcl.clusters.general import (
6     AnalogInput,
7     Basic,
8     BinaryOutput,
9     DeviceTemperature,
10     Groups,
11     Identify,
12     MultistateInput,
13     OnOff,
14     Ota,
15     Scenes,
16     Time,
17 )
18 
19 from .. import (
20     LUMI,
21     BasicCluster,
22     OnOffCluster,
23     XiaomiCustomDevice,
24     XiaomiPowerConfiguration,
25 )
26 from ...const import (
27     DEVICE_TYPE,
28     ENDPOINTS,
29     INPUT_CLUSTERS,
30     MODELS_INFO,
31     OUTPUT_CLUSTERS,
32     PROFILE_ID,
33     SKIP_CONFIGURATION,
34 )
35 
36 DOUBLE = "double"
37 HOLD = "long press"
38 PRESS_TYPES = {0: "long press", 1: "single", 2: "double"}
39 SINGLE = "single"
40 STATUS_TYPE_ATTR = 0x0055  # decimal = 85
41 XIAOMI_CLUSTER_ID = 0xFFFF
42 XIAOMI_DEVICE_TYPE = 0x5F01
43 XIAOMI_DEVICE_TYPE2 = 0x5F02
44 XIAOMI_DEVICE_TYPE3 = 0x5F03
45 
46 _LOGGER = logging.getLogger(__name__)
47 
48 # click attr 0xF000
49 # single click 0x3FF1F00
50 # double click 0xCFF1F00
51 
52 
53 class CtrlNeutral(XiaomiCustomDevice):
54     """Aqara single and double key switch device."""
55 
56     signature = {
57         MODELS_INFO: [
58             (LUMI, "lumi.ctrl_neutral1"),
59             (LUMI, "lumi.ctrl_neutral2"),
60             (LUMI, "lumi.switch.b1lacn02"),
61             (LUMI, "lumi.switch.b2lacn02"),
62         ],
63         ENDPOINTS: {
64             # <SimpleDescriptor endpoint=1 profile=260 device_type=6
65             # device_version=2
66             # input_clusters=[0, 3, 1, 2, 25, 10]
67             # output_clusters=[0, 10, 25]>
68             1: {
69                 PROFILE_ID: zha.PROFILE_ID,
70                 DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL,
71                 INPUT_CLUSTERS: [
72                     Basic.cluster_id,
73                     Identify.cluster_id,
74                     XiaomiPowerConfiguration.cluster_id,
75                     DeviceTemperature.cluster_id,
76                     Ota.cluster_id,
77                     Time.cluster_id,
78                 ],
79                 OUTPUT_CLUSTERS: [Basic.cluster_id, Time.cluster_id, Ota.cluster_id],
80             },
81             # <SimpleDescriptor endpoint=2 profile=260 device_type=256
82             # device_version=2
83             # input_clusters=[16, 6, 4, 5]
84             # output_clusters=[]>
85             2: {
86                 PROFILE_ID: zha.PROFILE_ID,
87                 DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
88                 INPUT_CLUSTERS: [
89                     BinaryOutput.cluster_id,
90                     OnOff.cluster_id,
91                     Groups.cluster_id,
92                     Scenes.cluster_id,
93                 ],
94                 OUTPUT_CLUSTERS: [],
95             },
96             # <SimpleDescriptor endpoint=3 profile=260 device_type=256
97             # device_version=2
98             # input_clusters=[16, 6, 4, 5]
99             # output_clusters=[]
100             3: {
101                 PROFILE_ID: zha.PROFILE_ID,
102                 DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,
103                 INPUT_CLUSTERS: [
104                     BinaryOutput.cluster_id,
105                     OnOff.cluster_id,
106                     Groups.cluster_id,
107                     Scenes.cluster_id,
108                 ],
109                 OUTPUT_CLUSTERS: [],
110             },
111             # <SimpleDescriptor endpoint=4 profile=260 device_type=0
112             # device_version=2
113             # input_clusters=[18, 6]
114             # output_clusters=[]>
115             4: {
116                 PROFILE_ID: zha.PROFILE_ID,
117                 DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
118                 INPUT_CLUSTERS: [MultistateInput.cluster_id, OnOff.cluster_id],
119                 OUTPUT_CLUSTERS: [],
120             },
121             # <SimpleDescriptor endpoint=5 profile=260 device_type=0
122             # device_version=2
123             # input_clusters=[18, 6]
124             # output_clusters=[]>
125             5: {
126                 PROFILE_ID: zha.PROFILE_ID,
127                 DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
128                 INPUT_CLUSTERS: [MultistateInput.cluster_id, OnOff.cluster_id],
129                 OUTPUT_CLUSTERS: [],
130             },
131             # <SimpleDescriptor endpoint=6 profile=260 device_type=0
132             # device_version=2
133             # input_clusters=[18, 6]
134             # output_clusters=[]>
135             6: {
136                 PROFILE_ID: zha.PROFILE_ID,
137                 DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
138                 INPUT_CLUSTERS: [MultistateInput.cluster_id, OnOff.cluster_id],
139                 OUTPUT_CLUSTERS: [],
140             },
141             # <SimpleDescriptor endpoint=8 profile=260 device_type=83
142             # device_version=2
143             # input_clusters=[12]
144             # output_clusters=[]>
145             8: {
146                 PROFILE_ID: zha.PROFILE_ID,
147                 DEVICE_TYPE: zha.DeviceType.METER_INTERFACE,
148                 INPUT_CLUSTERS: [AnalogInput.cluster_id],
149                 OUTPUT_CLUSTERS: [],
150             },
151         },
152     }
153 
154     replacement = {
155         SKIP_CONFIGURATION: True,
156         ENDPOINTS: {
157             1: {
158                 DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL,
159                 INPUT_CLUSTERS: [
160                     BasicCluster,
161                     Identify.cluster_id,
162                     XiaomiPowerConfiguration.cluster_id,
163                     DeviceTemperature.cluster_id,
164                     Ota.cluster_id,
165                     Time.cluster_id,
166                 ],
167                 OUTPUT_CLUSTERS: [Basic.cluster_id, Time.cluster_id, Ota.cluster_id],
168             },
169             2: {
170                 DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
171                 INPUT_CLUSTERS: [
172                     BinaryOutput.cluster_id,
173                     OnOffCluster,
174                     Groups.cluster_id,
175                     Scenes.cluster_id,
176                 ],
177                 OUTPUT_CLUSTERS: [],
178             },
179             3: {
180                 DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
181                 INPUT_CLUSTERS: [
182                     BinaryOutput.cluster_id,
183                     OnOffCluster,
184                     Groups.cluster_id,
185                     Scenes.cluster_id,
186                 ],
187                 OUTPUT_CLUSTERS: [],
188             },
189         },
190     }
191
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/zhaquirks/xiaomi/aqara/ctrl_neutral.py b/zhaquirks/xiaomi/aqara/ctrl_neutral.py
--- a/zhaquirks/xiaomi/aqara/ctrl_neutral.py
+++ b/zhaquirks/xiaomi/aqara/ctrl_neutral.py
@@ -1,6 +1,7 @@
 """Xiaomi aqara single key wall switch devices."""
 import logging
 
+from zigpy import types as t
 from zigpy.profiles import zha
 from zigpy.zcl.clusters.general import (
     AnalogInput,
@@ -23,16 +24,30 @@
     XiaomiCustomDevice,
     XiaomiPowerConfiguration,
 )
+from ... import EventableCluster
 from ...const import (
+    ARGS,
+    ATTRIBUTE_ID,
+    ATTRIBUTE_NAME,
+    BUTTON,
+    CLUSTER_ID,
+    COMMAND,
+    COMMAND_ATTRIBUTE_UPDATED,
+    COMMAND_DOUBLE,
+    COMMAND_HOLD,
+    COMMAND_RELEASE,
     DEVICE_TYPE,
+    ENDPOINT_ID,
     ENDPOINTS,
     INPUT_CLUSTERS,
     MODELS_INFO,
     OUTPUT_CLUSTERS,
     PROFILE_ID,
     SKIP_CONFIGURATION,
+    VALUE,
 )
 
+ATTRIBUTE_ON_OFF = "on_off"
 DOUBLE = "double"
 HOLD = "long press"
 PRESS_TYPES = {0: "long press", 1: "single", 2: "double"}
@@ -53,6 +68,20 @@
 class CtrlNeutral(XiaomiCustomDevice):
     """Aqara single and double key switch device."""
 
+    class BasicClusterDecoupled(BasicCluster):
+        """Adds attributes for decoupled mode."""
+
+        # Known Options for 'decoupled_mode_<button>':
+        # * 254 (decoupled)
+        # * 18 (relay controlled)
+        manufacturer_attributes = {
+            0xFF22: ("decoupled_mode_left", t.uint8_t),
+            0xFF23: ("decoupled_mode_right", t.uint8_t),
+        }
+
+    class WallSwitchOnOffCluster(EventableCluster, OnOff):
+        """WallSwitchOnOffCluster: fire events corresponding to press type."""
+
     signature = {
         MODELS_INFO: [
             (LUMI, "lumi.ctrl_neutral1"),
@@ -157,7 +186,7 @@
             1: {
                 DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL,
                 INPUT_CLUSTERS: [
-                    BasicCluster,
+                    BasicClusterDecoupled,
                     Identify.cluster_id,
                     XiaomiPowerConfiguration.cluster_id,
                     DeviceTemperature.cluster_id,
@@ -186,5 +215,34 @@
                 ],
                 OUTPUT_CLUSTERS: [],
             },
+            4: {
+                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
+                INPUT_CLUSTERS: [
+                    MultistateInput.cluster_id,
+                    WallSwitchOnOffCluster,
+                ],
+                OUTPUT_CLUSTERS: [],
+            },
+        },
+    }
+
+    device_automation_triggers = {
+        (COMMAND_HOLD, BUTTON): {
+            ENDPOINT_ID: 4,
+            CLUSTER_ID: 6,
+            COMMAND: COMMAND_ATTRIBUTE_UPDATED,
+            ARGS: {ATTRIBUTE_ID: 0, ATTRIBUTE_NAME: ATTRIBUTE_ON_OFF, VALUE: 0},
+        },
+        (COMMAND_RELEASE, BUTTON): {
+            ENDPOINT_ID: 4,
+            CLUSTER_ID: 6,
+            COMMAND: COMMAND_ATTRIBUTE_UPDATED,
+            ARGS: {ATTRIBUTE_ID: 0, ATTRIBUTE_NAME: ATTRIBUTE_ON_OFF, VALUE: 1},
+        },
+        (COMMAND_DOUBLE, BUTTON): {
+            ENDPOINT_ID: 4,
+            CLUSTER_ID: 6,
+            COMMAND: COMMAND_ATTRIBUTE_UPDATED,
+            ARGS: {ATTRIBUTE_ID: 0, ATTRIBUTE_NAME: ATTRIBUTE_ON_OFF, VALUE: 2},
         },
     }

{"golden_diff": "diff --git a/zhaquirks/xiaomi/aqara/ctrl_neutral.py b/zhaquirks/xiaomi/aqara/ctrl_neutral.py\n--- a/zhaquirks/xiaomi/aqara/ctrl_neutral.py\n+++ b/zhaquirks/xiaomi/aqara/ctrl_neutral.py\n@@ -1,6 +1,7 @@\n \"\"\"Xiaomi aqara single key wall switch devices.\"\"\"\n import logging\n \n+from zigpy import types as t\n from zigpy.profiles import zha\n from zigpy.zcl.clusters.general import (\n     AnalogInput,\n@@ -23,16 +24,30 @@\n     XiaomiCustomDevice,\n     XiaomiPowerConfiguration,\n )\n+from ... import EventableCluster\n from ...const import (\n+    ARGS,\n+    ATTRIBUTE_ID,\n+    ATTRIBUTE_NAME,\n+    BUTTON,\n+    CLUSTER_ID,\n+    COMMAND,\n+    COMMAND_ATTRIBUTE_UPDATED,\n+    COMMAND_DOUBLE,\n+    COMMAND_HOLD,\n+    COMMAND_RELEASE,\n     DEVICE_TYPE,\n+    ENDPOINT_ID,\n     ENDPOINTS,\n     INPUT_CLUSTERS,\n     MODELS_INFO,\n     OUTPUT_CLUSTERS,\n     PROFILE_ID,\n     SKIP_CONFIGURATION,\n+    VALUE,\n )\n \n+ATTRIBUTE_ON_OFF = \"on_off\"\n DOUBLE = \"double\"\n HOLD = \"long press\"\n PRESS_TYPES = {0: \"long press\", 1: \"single\", 2: \"double\"}\n@@ -53,6 +68,20 @@\n class CtrlNeutral(XiaomiCustomDevice):\n     \"\"\"Aqara single and double key switch device.\"\"\"\n \n+    class BasicClusterDecoupled(BasicCluster):\n+        \"\"\"Adds attributes for decoupled mode.\"\"\"\n+\n+        # Known Options for 'decoupled_mode_<button>':\n+        # * 254 (decoupled)\n+        # * 18 (relay controlled)\n+        manufacturer_attributes = {\n+            0xFF22: (\"decoupled_mode_left\", t.uint8_t),\n+            0xFF23: (\"decoupled_mode_right\", t.uint8_t),\n+        }\n+\n+    class WallSwitchOnOffCluster(EventableCluster, OnOff):\n+        \"\"\"WallSwitchOnOffCluster: fire events corresponding to press type.\"\"\"\n+\n     signature = {\n         MODELS_INFO: [\n             (LUMI, \"lumi.ctrl_neutral1\"),\n@@ -157,7 +186,7 @@\n             1: {\n                 DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL,\n                 INPUT_CLUSTERS: [\n-                    BasicCluster,\n+                    BasicClusterDecoupled,\n                     Identify.cluster_id,\n                     XiaomiPowerConfiguration.cluster_id,\n                     DeviceTemperature.cluster_id,\n@@ -186,5 +215,34 @@\n                 ],\n                 OUTPUT_CLUSTERS: [],\n             },\n+            4: {\n+                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,\n+                INPUT_CLUSTERS: [\n+                    MultistateInput.cluster_id,\n+                    WallSwitchOnOffCluster,\n+                ],\n+                OUTPUT_CLUSTERS: [],\n+            },\n+        },\n+    }\n+\n+    device_automation_triggers = {\n+        (COMMAND_HOLD, BUTTON): {\n+            ENDPOINT_ID: 4,\n+            CLUSTER_ID: 6,\n+            COMMAND: COMMAND_ATTRIBUTE_UPDATED,\n+            ARGS: {ATTRIBUTE_ID: 0, ATTRIBUTE_NAME: ATTRIBUTE_ON_OFF, VALUE: 0},\n+        },\n+        (COMMAND_RELEASE, BUTTON): {\n+            ENDPOINT_ID: 4,\n+            CLUSTER_ID: 6,\n+            COMMAND: COMMAND_ATTRIBUTE_UPDATED,\n+            ARGS: {ATTRIBUTE_ID: 0, ATTRIBUTE_NAME: ATTRIBUTE_ON_OFF, VALUE: 1},\n+        },\n+        (COMMAND_DOUBLE, BUTTON): {\n+            ENDPOINT_ID: 4,\n+            CLUSTER_ID: 6,\n+            COMMAND: COMMAND_ATTRIBUTE_UPDATED,\n+            ARGS: {ATTRIBUTE_ID: 0, ATTRIBUTE_NAME: ATTRIBUTE_ON_OFF, VALUE: 2},\n         },\n     }\n", "issue": "[Device Support Request] Decoupled mode for ctrl_neutral (QBKG04LM/QBKG03LM/QBKG21LM/QBKG22LM)\n**Is your feature request related to a problem? Please describe.**\r\nSimilar to #365, but for `ctrl_neutral` implementation. I think that once implemented it can be easily adapted.\r\n\r\nIn my case I want to implement QBKG04LM decoupled mode.\r\nIt can be done easily, following @albalaing indications (https://github.com/zigpy/zha-device-handlers/issues/365#issuecomment-636510316).\r\n\r\nThe problem is that without the click button events it is not useful, so it is necessary to also implement the generation of ZHA events.\r\n\r\n**Describe the solution you'd like**\r\n\r\nBefore implement anything you can see that device generate 4 messages:\r\n```\r\n2021-01-09 21:46:29 DEBUG (MainThread) [zigpy.device] Ignoring message (b'18500a0000100000001001') on cluster 6: unknown endpoint or cluster id: 4\r\n2021-01-09 21:46:31 DEBUG (MainThread) [zigpy.device] Ignoring message (b'18510a00001000') on cluster 6: unknown endpoint or cluster id: 4\r\n2021-01-09 21:46:32 DEBUG (MainThread) [zigpy.device] Ignoring message (b'18520a00001001') on cluster 6: unknown endpoint or cluster id: 4\r\n2021-01-09 21:46:32 DEBUG (MainThread) [zigpy.device] Ignoring message (b'18530a00001002') on cluster 6: unknown endpoint or cluster id: 4\r\n```\r\n\r\nThis messages are (in order):\r\n* click\r\n* hold\r\n* release\r\n* double_click\r\n\r\nYou can see that the click message corresponds in some way to the hold+release messages (00001000+00001001)\r\n\r\n\r\nI think I'm halfway done (the decoupled part is working as expected), but I'm not satisfied with the event generation part. \r\n\r\n\r\nWhen a `replacement` for endpoint 4 (and 5) is implemented you can get the `on_off` attribute reported. But IMO this approach has the following problems:\r\n* add a new entity in HA for click button events\r\n* it is not possible to differentiate the `click` event from `hold` and `release`\r\n* the `double_click` event cannot be handled (parse error)\r\n\r\n\r\nWant I think that would be implemented is:\r\n* no HA button entity\r\n* full events control, not only hold and release\r\n\r\n\r\nAny help in this regard is welcome.\r\n\r\n\r\n**Device signature - this can be acquired by removing the device from ZHA and pairing it again from the add devices screen. Be sure to add the entire content of the log panel after pairing the device to a code block below this line.**\r\nThe device signature is known and correct.\r\n\r\n**Additional context**\r\nAlthough I am not sure if it can be done this way, I have tried without success to implement a replacement that transforms events from the `OnOff` cluster to the `MultistateInput` cluster.\r\n\r\nMy current implementation is as follows (only the relevant part):\r\n```\r\n    class BasicClusterDecoupled(BasicCluster):\r\n        \"\"\"Adds attributes for decoupled mode\"\"\"\r\n        def __init__(self, *args, **kwargs):\r\n            \"\"\"Init.\"\"\"\r\n            self.attributes = BasicCluster.attributes.copy()\r\n            self.attributes.update({ 0xFF22: (\"left_decoupled_mode\", t.uint8_t)})\r\n            self.attributes.update({ 0xFF23: (\"right_decoupled_mode\", t.uint8_t)})\r\n            super().__init__(*args, **kwargs)\r\n\r\n\r\n    class CustomOnOffCluster(OnOffCluster):\r\n        \"\"\"Fire ZHA events for on off cluster.\"\"\"\r\n\r\n        cluster_id = OnOff.cluster_id\r\n\r\n        def __init__(self, *args, **kwargs):\r\n            \"\"\"Init.\"\"\"\r\n            self._current_state = {}\r\n            super().__init__(*args, **kwargs)\r\n\r\n        def _update_attribute(self, attrid, value):\r\n            _LOGGER.info(\"%s: %s\", attrid, value)\r\n            if attrid == 0:\r\n                self._current_state = PRESS_TYPES.get(value)\r\n                event_args = {\r\n                    PRESS_TYPE: self._current_state,\r\n                    VALUE: value,\r\n                }\r\n                self.listener_event(ZHA_SEND_EVENT, COMMAND_CLICK, event_args)\r\n            super()._update_attribute(attrid, self._current_state)\r\n\r\n\r\n    replacement = {\r\n        SKIP_CONFIGURATION: True,\r\n        ENDPOINTS: {\r\n            .../...\r\n            4: {                                                                   \r\n                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,                         \r\n                INPUT_CLUSTERS: [                                                  \r\n                    MultistateInput.cluster_id,                                        \r\n                    CustomOnOffCluster,                                        \r\n                ],                                                                 \r\n                OUTPUT_CLUSTERS: [],                                               \r\n            },  \r\n            5: {                                                                   \r\n                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,                         \r\n                INPUT_CLUSTERS: [                                                  \r\n                    MultistateInput.cluster_id,                                        \r\n                    CustomOnOffCluster,                                        \r\n                ],                                                                 \r\n                OUTPUT_CLUSTERS: [],                                               \r\n            },  \r\n        },\r\n    }\r\n```\r\n\r\n\n", "before_files": [{"content": "\"\"\"Xiaomi aqara single key wall switch devices.\"\"\"\nimport logging\n\nfrom zigpy.profiles import zha\nfrom zigpy.zcl.clusters.general import (\n    AnalogInput,\n    Basic,\n    BinaryOutput,\n    DeviceTemperature,\n    Groups,\n    Identify,\n    MultistateInput,\n    OnOff,\n    Ota,\n    Scenes,\n    Time,\n)\n\nfrom .. import (\n    LUMI,\n    BasicCluster,\n    OnOffCluster,\n    XiaomiCustomDevice,\n    XiaomiPowerConfiguration,\n)\nfrom ...const import (\n    DEVICE_TYPE,\n    ENDPOINTS,\n    INPUT_CLUSTERS,\n    MODELS_INFO,\n    OUTPUT_CLUSTERS,\n    PROFILE_ID,\n    SKIP_CONFIGURATION,\n)\n\nDOUBLE = \"double\"\nHOLD = \"long press\"\nPRESS_TYPES = {0: \"long press\", 1: \"single\", 2: \"double\"}\nSINGLE = \"single\"\nSTATUS_TYPE_ATTR = 0x0055  # decimal = 85\nXIAOMI_CLUSTER_ID = 0xFFFF\nXIAOMI_DEVICE_TYPE = 0x5F01\nXIAOMI_DEVICE_TYPE2 = 0x5F02\nXIAOMI_DEVICE_TYPE3 = 0x5F03\n\n_LOGGER = logging.getLogger(__name__)\n\n# click attr 0xF000\n# single click 0x3FF1F00\n# double click 0xCFF1F00\n\n\nclass CtrlNeutral(XiaomiCustomDevice):\n    \"\"\"Aqara single and double key switch device.\"\"\"\n\n    signature = {\n        MODELS_INFO: [\n            (LUMI, \"lumi.ctrl_neutral1\"),\n            (LUMI, \"lumi.ctrl_neutral2\"),\n            (LUMI, \"lumi.switch.b1lacn02\"),\n            (LUMI, \"lumi.switch.b2lacn02\"),\n        ],\n        ENDPOINTS: {\n            # <SimpleDescriptor endpoint=1 profile=260 device_type=6\n            # device_version=2\n            # input_clusters=[0, 3, 1, 2, 25, 10]\n            # output_clusters=[0, 10, 25]>\n            1: {\n                PROFILE_ID: zha.PROFILE_ID,\n                DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL,\n                INPUT_CLUSTERS: [\n                    Basic.cluster_id,\n                    Identify.cluster_id,\n                    XiaomiPowerConfiguration.cluster_id,\n                    DeviceTemperature.cluster_id,\n                    Ota.cluster_id,\n                    Time.cluster_id,\n                ],\n                OUTPUT_CLUSTERS: [Basic.cluster_id, Time.cluster_id, Ota.cluster_id],\n            },\n            # <SimpleDescriptor endpoint=2 profile=260 device_type=256\n            # device_version=2\n            # input_clusters=[16, 6, 4, 5]\n            # output_clusters=[]>\n            2: {\n                PROFILE_ID: zha.PROFILE_ID,\n                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,\n                INPUT_CLUSTERS: [\n                    BinaryOutput.cluster_id,\n                    OnOff.cluster_id,\n                    Groups.cluster_id,\n                    Scenes.cluster_id,\n                ],\n                OUTPUT_CLUSTERS: [],\n            },\n            # <SimpleDescriptor endpoint=3 profile=260 device_type=256\n            # device_version=2\n            # input_clusters=[16, 6, 4, 5]\n            # output_clusters=[]\n            3: {\n                PROFILE_ID: zha.PROFILE_ID,\n                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,\n                INPUT_CLUSTERS: [\n                    BinaryOutput.cluster_id,\n                    OnOff.cluster_id,\n                    Groups.cluster_id,\n                    Scenes.cluster_id,\n                ],\n                OUTPUT_CLUSTERS: [],\n            },\n            # <SimpleDescriptor endpoint=4 profile=260 device_type=0\n            # device_version=2\n            # input_clusters=[18, 6]\n            # output_clusters=[]>\n            4: {\n                PROFILE_ID: zha.PROFILE_ID,\n                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,\n                INPUT_CLUSTERS: [MultistateInput.cluster_id, OnOff.cluster_id],\n                OUTPUT_CLUSTERS: [],\n            },\n            # <SimpleDescriptor endpoint=5 profile=260 device_type=0\n            # device_version=2\n            # input_clusters=[18, 6]\n            # output_clusters=[]>\n            5: {\n                PROFILE_ID: zha.PROFILE_ID,\n                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,\n                INPUT_CLUSTERS: [MultistateInput.cluster_id, OnOff.cluster_id],\n                OUTPUT_CLUSTERS: [],\n            },\n            # <SimpleDescriptor endpoint=6 profile=260 device_type=0\n            # device_version=2\n            # input_clusters=[18, 6]\n            # output_clusters=[]>\n            6: {\n                PROFILE_ID: zha.PROFILE_ID,\n                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,\n                INPUT_CLUSTERS: [MultistateInput.cluster_id, OnOff.cluster_id],\n                OUTPUT_CLUSTERS: [],\n            },\n            # <SimpleDescriptor endpoint=8 profile=260 device_type=83\n            # device_version=2\n            # input_clusters=[12]\n            # output_clusters=[]>\n            8: {\n                PROFILE_ID: zha.PROFILE_ID,\n                DEVICE_TYPE: zha.DeviceType.METER_INTERFACE,\n                INPUT_CLUSTERS: [AnalogInput.cluster_id],\n                OUTPUT_CLUSTERS: [],\n            },\n        },\n    }\n\n    replacement = {\n        SKIP_CONFIGURATION: True,\n        ENDPOINTS: {\n            1: {\n                DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL,\n                INPUT_CLUSTERS: [\n                    BasicCluster,\n                    Identify.cluster_id,\n                    XiaomiPowerConfiguration.cluster_id,\n                    DeviceTemperature.cluster_id,\n                    Ota.cluster_id,\n                    Time.cluster_id,\n                ],\n                OUTPUT_CLUSTERS: [Basic.cluster_id, Time.cluster_id, Ota.cluster_id],\n            },\n            2: {\n                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,\n                INPUT_CLUSTERS: [\n                    BinaryOutput.cluster_id,\n                    OnOffCluster,\n                    Groups.cluster_id,\n                    Scenes.cluster_id,\n                ],\n                OUTPUT_CLUSTERS: [],\n            },\n            3: {\n                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,\n                INPUT_CLUSTERS: [\n                    BinaryOutput.cluster_id,\n                    OnOffCluster,\n                    Groups.cluster_id,\n                    Scenes.cluster_id,\n                ],\n                OUTPUT_CLUSTERS: [],\n            },\n        },\n    }\n", "path": "zhaquirks/xiaomi/aqara/ctrl_neutral.py"}], "after_files": [{"content": "\"\"\"Xiaomi aqara single key wall switch devices.\"\"\"\nimport logging\n\nfrom zigpy import types as t\nfrom zigpy.profiles import zha\nfrom zigpy.zcl.clusters.general import (\n    AnalogInput,\n    Basic,\n    BinaryOutput,\n    DeviceTemperature,\n    Groups,\n    Identify,\n    MultistateInput,\n    OnOff,\n    Ota,\n    Scenes,\n    Time,\n)\n\nfrom .. import (\n    LUMI,\n    BasicCluster,\n    OnOffCluster,\n    XiaomiCustomDevice,\n    XiaomiPowerConfiguration,\n)\nfrom ... import EventableCluster\nfrom ...const import (\n    ARGS,\n    ATTRIBUTE_ID,\n    ATTRIBUTE_NAME,\n    BUTTON,\n    CLUSTER_ID,\n    COMMAND,\n    COMMAND_ATTRIBUTE_UPDATED,\n    COMMAND_DOUBLE,\n    COMMAND_HOLD,\n    COMMAND_RELEASE,\n    DEVICE_TYPE,\n    ENDPOINT_ID,\n    ENDPOINTS,\n    INPUT_CLUSTERS,\n    MODELS_INFO,\n    OUTPUT_CLUSTERS,\n    PROFILE_ID,\n    SKIP_CONFIGURATION,\n    VALUE,\n)\n\nATTRIBUTE_ON_OFF = \"on_off\"\nDOUBLE = \"double\"\nHOLD = \"long press\"\nPRESS_TYPES = {0: \"long press\", 1: \"single\", 2: \"double\"}\nSINGLE = \"single\"\nSTATUS_TYPE_ATTR = 0x0055  # decimal = 85\nXIAOMI_CLUSTER_ID = 0xFFFF\nXIAOMI_DEVICE_TYPE = 0x5F01\nXIAOMI_DEVICE_TYPE2 = 0x5F02\nXIAOMI_DEVICE_TYPE3 = 0x5F03\n\n_LOGGER = logging.getLogger(__name__)\n\n# click attr 0xF000\n# single click 0x3FF1F00\n# double click 0xCFF1F00\n\n\nclass CtrlNeutral(XiaomiCustomDevice):\n    \"\"\"Aqara single and double key switch device.\"\"\"\n\n    class BasicClusterDecoupled(BasicCluster):\n        \"\"\"Adds attributes for decoupled mode.\"\"\"\n\n        # Known Options for 'decoupled_mode_<button>':\n        # * 254 (decoupled)\n        # * 18 (relay controlled)\n        manufacturer_attributes = {\n            0xFF22: (\"decoupled_mode_left\", t.uint8_t),\n            0xFF23: (\"decoupled_mode_right\", t.uint8_t),\n        }\n\n    class WallSwitchOnOffCluster(EventableCluster, OnOff):\n        \"\"\"WallSwitchOnOffCluster: fire events corresponding to press type.\"\"\"\n\n    signature = {\n        MODELS_INFO: [\n            (LUMI, \"lumi.ctrl_neutral1\"),\n            (LUMI, \"lumi.ctrl_neutral2\"),\n            (LUMI, \"lumi.switch.b1lacn02\"),\n            (LUMI, \"lumi.switch.b2lacn02\"),\n        ],\n        ENDPOINTS: {\n            # <SimpleDescriptor endpoint=1 profile=260 device_type=6\n            # device_version=2\n            # input_clusters=[0, 3, 1, 2, 25, 10]\n            # output_clusters=[0, 10, 25]>\n            1: {\n                PROFILE_ID: zha.PROFILE_ID,\n                DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL,\n                INPUT_CLUSTERS: [\n                    Basic.cluster_id,\n                    Identify.cluster_id,\n                    XiaomiPowerConfiguration.cluster_id,\n                    DeviceTemperature.cluster_id,\n                    Ota.cluster_id,\n                    Time.cluster_id,\n                ],\n                OUTPUT_CLUSTERS: [Basic.cluster_id, Time.cluster_id, Ota.cluster_id],\n            },\n            # <SimpleDescriptor endpoint=2 profile=260 device_type=256\n            # device_version=2\n            # input_clusters=[16, 6, 4, 5]\n            # output_clusters=[]>\n            2: {\n                PROFILE_ID: zha.PROFILE_ID,\n                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,\n                INPUT_CLUSTERS: [\n                    BinaryOutput.cluster_id,\n                    OnOff.cluster_id,\n                    Groups.cluster_id,\n                    Scenes.cluster_id,\n                ],\n                OUTPUT_CLUSTERS: [],\n            },\n            # <SimpleDescriptor endpoint=3 profile=260 device_type=256\n            # device_version=2\n            # input_clusters=[16, 6, 4, 5]\n            # output_clusters=[]\n            3: {\n                PROFILE_ID: zha.PROFILE_ID,\n                DEVICE_TYPE: zha.DeviceType.ON_OFF_LIGHT,\n                INPUT_CLUSTERS: [\n                    BinaryOutput.cluster_id,\n                    OnOff.cluster_id,\n                    Groups.cluster_id,\n                    Scenes.cluster_id,\n                ],\n                OUTPUT_CLUSTERS: [],\n            },\n            # <SimpleDescriptor endpoint=4 profile=260 device_type=0\n            # device_version=2\n            # input_clusters=[18, 6]\n            # output_clusters=[]>\n            4: {\n                PROFILE_ID: zha.PROFILE_ID,\n                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,\n                INPUT_CLUSTERS: [MultistateInput.cluster_id, OnOff.cluster_id],\n                OUTPUT_CLUSTERS: [],\n            },\n            # <SimpleDescriptor endpoint=5 profile=260 device_type=0\n            # device_version=2\n            # input_clusters=[18, 6]\n            # output_clusters=[]>\n            5: {\n                PROFILE_ID: zha.PROFILE_ID,\n                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,\n                INPUT_CLUSTERS: [MultistateInput.cluster_id, OnOff.cluster_id],\n                OUTPUT_CLUSTERS: [],\n            },\n            # <SimpleDescriptor endpoint=6 profile=260 device_type=0\n            # device_version=2\n            # input_clusters=[18, 6]\n            # output_clusters=[]>\n            6: {\n                PROFILE_ID: zha.PROFILE_ID,\n                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,\n                INPUT_CLUSTERS: [MultistateInput.cluster_id, OnOff.cluster_id],\n                OUTPUT_CLUSTERS: [],\n            },\n            # <SimpleDescriptor endpoint=8 profile=260 device_type=83\n            # device_version=2\n            # input_clusters=[12]\n            # output_clusters=[]>\n            8: {\n                PROFILE_ID: zha.PROFILE_ID,\n                DEVICE_TYPE: zha.DeviceType.METER_INTERFACE,\n                INPUT_CLUSTERS: [AnalogInput.cluster_id],\n                OUTPUT_CLUSTERS: [],\n            },\n        },\n    }\n\n    replacement = {\n        SKIP_CONFIGURATION: True,\n        ENDPOINTS: {\n            1: {\n                DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL,\n                INPUT_CLUSTERS: [\n                    BasicClusterDecoupled,\n                    Identify.cluster_id,\n                    XiaomiPowerConfiguration.cluster_id,\n                    DeviceTemperature.cluster_id,\n                    Ota.cluster_id,\n                    Time.cluster_id,\n                ],\n                OUTPUT_CLUSTERS: [Basic.cluster_id, Time.cluster_id, Ota.cluster_id],\n            },\n            2: {\n                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,\n                INPUT_CLUSTERS: [\n                    BinaryOutput.cluster_id,\n                    OnOffCluster,\n                    Groups.cluster_id,\n                    Scenes.cluster_id,\n                ],\n                OUTPUT_CLUSTERS: [],\n            },\n            3: {\n                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,\n                INPUT_CLUSTERS: [\n                    BinaryOutput.cluster_id,\n                    OnOffCluster,\n                    Groups.cluster_id,\n                    Scenes.cluster_id,\n                ],\n                OUTPUT_CLUSTERS: [],\n            },\n            4: {\n                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,\n                INPUT_CLUSTERS: [\n                    MultistateInput.cluster_id,\n                    WallSwitchOnOffCluster,\n                ],\n                OUTPUT_CLUSTERS: [],\n            },\n        },\n    }\n\n    device_automation_triggers = {\n        (COMMAND_HOLD, BUTTON): {\n            ENDPOINT_ID: 4,\n            CLUSTER_ID: 6,\n            COMMAND: COMMAND_ATTRIBUTE_UPDATED,\n            ARGS: {ATTRIBUTE_ID: 0, ATTRIBUTE_NAME: ATTRIBUTE_ON_OFF, VALUE: 0},\n        },\n        (COMMAND_RELEASE, BUTTON): {\n            ENDPOINT_ID: 4,\n            CLUSTER_ID: 6,\n            COMMAND: COMMAND_ATTRIBUTE_UPDATED,\n            ARGS: {ATTRIBUTE_ID: 0, ATTRIBUTE_NAME: ATTRIBUTE_ON_OFF, VALUE: 1},\n        },\n        (COMMAND_DOUBLE, BUTTON): {\n            ENDPOINT_ID: 4,\n            CLUSTER_ID: 6,\n            COMMAND: COMMAND_ATTRIBUTE_UPDATED,\n            ARGS: {ATTRIBUTE_ID: 0, ATTRIBUTE_NAME: ATTRIBUTE_ON_OFF, VALUE: 2},\n        },\n    }\n", "path": "zhaquirks/xiaomi/aqara/ctrl_neutral.py"}]}