Repository: zigpy/zha-device-handlers

Issue:
Ikea Remote E1810 not matching quirks?
I'm trying to setup a new Ikea 5 button remote E1810 in ha but am not seeing any `zha_event`s. The logs say `Fail because profile_id mismatch on at least one endpoint` My endpoint information is `<SimpleDescriptor endpoint=1 profile=260 device_type=2080 device_version=1 input_clusters=[0, 1, 3, 32, 4096, 64636] output_clusters=[3, 4, 6, 8, 25, 4096]>`

I'm using the HUSBZB-1 and I was able to pair it with the ikea gateway and verify that it's on the latest firmware revision 2.3.014

Finally here's the full pairing log:

```
[0x0000:zdo] ZDO request 0x0036: [60, <Bool.false: 0>]
[0x5544:zdo] ZDO request 0x0006: [0xfffd, 49246, [25], []]
[0x0000:zdo] ZDO request 0x0036: [60, <Bool.false: 0>]
Device 0xd800 (ec:1b:bd:ff:fe:2a:c8:eb) joined the network
[0xd800] Requesting 'Node Descriptor'
[0xd800] Extending timeout for 0x0a request
Device 0xe02c (ec:1b:bd:ff:fe:2a:c8:eb) joined the network
Device ec:1b:bd:ff:fe:2a:c8:eb changed id (0xd800 => 0xe02c)
Canceling old initialize call
[0xe02c] Requesting Node Descriptor failed: 
[0xe02c] Discovering endpoints
[0xe02c] Extending timeout for 0x0c request
[0xe02c] Requesting 'Node Descriptor'
[0xe02c] Extending timeout for 0x0e request
Device 0xe02c (ec:1b:bd:ff:fe:2a:c8:eb) joined the network
Skip initialization for existing device ec:1b:bd:ff:fe:2a:c8:eb
[0xe02c:zdo] ZDO request 0x0013: [0xe02c, ec:1b:bd:ff:fe:2a:c8:eb, 128]
[0xe02c] Discovered endpoints: [1]
[0xe02c:1] Discovering endpoint information
[0xe02c] Extending timeout for 0x10 request
[0xe02c] Node Descriptor: <Optional byte1=2 byte2=64 mac_capability_flags=128 manufacturer_code=4476 maximum_buffer_size=82 maximum_incoming_transfer_size=82 server_mask=11264 maximum_outgoing_transfer_size=82 descriptor_capability_field=0>
[0xe02c] Discovering endpoints
[0xe02c] Extending timeout for 0x12 request
[0xe02c:1] Discovered endpoint information: <SimpleDescriptor endpoint=1 profile=260 device_type=2080 device_version=1 input_clusters=[0, 1, 3, 32, 4096, 64636] output_clusters=[3, 4, 6, 8, 25, 4096]>
[0xe02c] Extending timeout for 0x14 request
[0xe02c] Discovered endpoints: [1]
[0xe02c:1] Discovering endpoint information
[0xe02c] Extending timeout for 0x16 request
Ignoring message (b'181401040000420e494b4541206f662053776564656e0500004216545241444652492072656d6f746520636f6e74726f6c') on cluster 0: unknown endpoint or cluster id: 'No cluster ID 0x0000 on (ec:1b:bd:ff:fe:2a:c8:eb, 1)'
[0xe02c:1] Discovered endpoint information: <SimpleDescriptor endpoint=1 profile=260 device_type=2080 device_version=1 input_clusters=[0, 1, 3, 32, 4096, 64636] output_clusters=[3, 4, 6, 8, 25, 4096]>
[0xe02c] Extending timeout for 0x18 request
[0xe02c:1:0x0000] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=24 command_id=Command.Read_Attributes_rsp>
[0xe02c:1] Manufacturer: IKEA of Sweden
[0xe02c:1] Model: TRADFRI remote control
Checking quirks for IKEA of Sweden TRADFRI remote control (ec:1b:bd:ff:fe:2a:c8:eb)
Considering <class 'zhaquirks.ikea.fivebtnremote.IkeaTradfriRemote'>
Fail because profile_id mismatch on at least one endpoint
Considering <class 'zigpy.quirks.ikea.TradfriPlug'>
Fail because endpoint list mismatch: {1, 2, 242} {1}
Considering <class 'zigpy.quirks.smartthings.SmartthingsMultiPurposeSensor'>
Fail because device_type mismatch on at least one endpoint
Considering <class 'bellows.zigbee.application.EZSPCoordinator'>
Fail because device_type mismatch on at least one endpoint
Considering <class 'zhaquirks.gledopto.soposhgu10.SoposhGU10'>
Fail because endpoint list mismatch: {11, 13} {1}
Considering <class 'zhaquirks.lutron.lzl4bwhl01remote.LutronLZL4BWHL01Remote2'>
Fail because profile_id mismatch on at least one endpoint
Considering <class 'zhaquirks.netvox.z308e3ed.Z308E3ED'>
Fail because device_type mismatch on at least one endpoint
Considering <class 'zhaquirks.osram.a19twhite.A19TunableWhite'>
Fail because endpoint list mismatch: {3} {1}
Considering <class 'zhaquirks.philips.rwl021.PhilipsRWL021'>
Fail because endpoint list mismatch: {1, 2} {1}
Considering <class 'zhaquirks.smartthings.tag_v4.SmartThingsTagV4'>
Fail because device_type mismatch on at least one endpoint
Considering <class 'zhaquirks.xbee.xbee3_io.XBee3Sensor'>
Fail because endpoint list mismatch: {232, 230} {1}
Considering <class 'zhaquirks.xbee.xbee_io.XbeeSensor'>
Fail because endpoint list mismatch: {232, 230} {1}
Considering <class 'zhaquirks.xiaomi.mija.smoke.MijiaHoneywellSmokeDetectorSensor'>
Fail because device_type mismatch on at least one endpoint
device - 0xe02c:ec:1b:bd:ff:fe:2a:c8:eb entering async_device_initialized - is_new_join: True
device - 0xe02c:ec:1b:bd:ff:fe:2a:c8:eb has joined the ZHA zigbee network
[0xe02c](TRADFRI remote control): started configuration
[0xe02c:ZDO](TRADFRI remote control): channel: 'async_configure' stage succeeded
[0xe02c] Extending timeout for 0x1a request
[0xe02c] Extending timeout for 0x1c request
[0xe02c] Extending timeout for 0x1e request
[0xe02c:1:0x0000]: bound 'basic' cluster: Status.SUCCESS
[0xe02c:1:0x0000]: finished channel configuration
[0xe02c] Extending timeout for 0x20 request
[0xe02c:1:0x0001]: bound 'power' cluster: Status.SUCCESS
[0xe02c] Extending timeout for 0x22 request
[0xe02c:1:0x1000]: bound 'lightlink' cluster: Status.SUCCESS
[0xe02c:1:0x1000]: finished channel configuration
[0xe02c:1:0x1000]: channel: 'async_configure' stage succeeded
[0xe02c] Extending timeout for 0x24 request
[0xe02c:1:0x0000] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=32 command_id=Command.Read_Attributes_rsp>
[0xe02c:1:0x0001] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=34 command_id=Command.Configure_Reporting_rsp>
[0xe02c:1:0x0000]: initializing channel: from_cache: False
[0xe02c:1:0x0000]: channel: 'async_configure' stage succeeded
[0xe02c] Extending timeout for 0x26 request
[0xe02c:1:0x0001]: reporting 'battery_voltage' attr on 'power' cluster: 3600/10800/1: Result: '[[<ConfigureReportingResponseRecord status=Status.SUCCESS>]]'
[0xe02c:1:0x0006]: bound 'on_off' cluster: Status.SUCCESS
[0xe02c:1:0x0006]: finished channel configuration
[0xe02c:1:0x0006]: channel: 'async_configure' stage succeeded
[0xe02c] Extending timeout for 0x28 request
[0xe02c:1:0x0001] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=False> manufacturer=None tsn=40 command_id=Command.Configure_Reporting_rsp>
[0xe02c:1:0x0008]: bound 'level' cluster: Status.SUCCESS
[0xe02c:1:0x0008]: finished channel configuration
[0xe02c:1:0x0008]: channel: 'async_configure' stage succeeded
[0xe02c:1:0x0001]: reporting 'battery_percentage_remaining' attr on 'power' cluster: 3600/10800/1: Result: '[[<ConfigureReportingResponseRecord status=Status.SUCCESS>]]'
[0xe02c:1:0x0001]: finished channel configuration
[0xe02c:1:0x0001]: channel: 'async_configure' stage succeeded
[0xe02c](TRADFRI remote control): completed configuration
[0xe02c](TRADFRI remote control): stored in registry: ZhaDeviceEntry(name='IKEA of Sweden TRADFRI remote control', ieee='ec:1b:bd:ff:fe:2a:c8:eb', last_seen=1575931626.889638)
[0xe02c](TRADFRI remote control): started initialization
[0xe02c:ZDO](TRADFRI remote control): entry loaded from storage: ZhaDeviceEntry(name='IKEA of Sweden TRADFRI remote control', ieee='ec:1b:bd:ff:fe:2a:c8:eb', last_seen=1575931626.889638)
[0xe02c:ZDO](TRADFRI remote control): channel: 'async_initialize' stage succeeded
[0xe02c] Extending timeout for 0x2a request
[0xe02c] Extending timeout for 0x2c request
[0xe02c:1:0x1000]: initializing channel: from_cache: False
[0xe02c:1:0x1000]: channel: 'async_initialize' stage succeeded
[0xe02c:1:0x0006]: initializing channel: from_cache: False
[0xe02c:1:0x0006]: channel: 'async_initialize' stage succeeded
[0xe02c:1:0x0008]: initializing channel: from_cache: False
[0xe02c:1:0x0008]: channel: 'async_initialize' stage succeeded
[0xe02c:1:0x0000] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=42 command_id=Command.Read_Attributes_rsp>
[0xe02c:1:0x0000]: initializing channel: from_cache: False
[0xe02c:1:0x0000]: channel: 'async_initialize' stage succeeded
[0xe02c:1:0x0001] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=44 command_id=Command.Read_Attributes_rsp>
[0xe02c] Extending timeout for 0x2e request
[0xe02c:1:0x0001] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=46 command_id=Command.Read_Attributes_rsp>
[0xe02c] Extending timeout for 0x30 request
[0xe02c:1:0x0001] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=48 command_id=Command.Read_Attributes_rsp>
[0xe02c] Extending timeout for 0x32 request
[0xe02c:zdo] ZDO request 0x0036: [180, <Bool.true: 1>]
[0xe02c:1:0x0003] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=CLUSTER_COMMAND manufacturer_specific=False is_reply=False disable_default_response=False> manufacturer=None tsn=2 command_id=1>
[0xe02c:1:0x0003] ZCL request 0x0001: []
[0xe02c:1:0x0003] No handler for cluster command 1
[0xe02c:1:0x0001] ZCL deserialize: <ZCLHeader frame_control=<FrameControl frame_type=GLOBAL_COMMAND manufacturer_specific=False is_reply=True disable_default_response=True> manufacturer=None tsn=50 command_id=Command.Read_Attributes_rsp>
[0xe02c:1:0x0001]: initializing channel: from_cache: False
[0xe02c:1:0x0001]: channel: 'async_initialize' stage succeeded
[0xe02c](TRADFRI remote control): power source: Battery or Unknown
[0xe02c](TRADFRI remote control): completed initialization
[0xe02c] Extending timeout for 0x34 request
```


Discussion:
I’ll add another quirk to support this alternative version. They seem to be releasing 2 versions of each device. 1 using the zha profile and one using the zll profile.

Resolving patch:
diff --git a/zhaquirks/ikea/fivebtnremotezha.py b/zhaquirks/ikea/fivebtnremotezha.py
new file mode 100644
--- /dev/null
+++ b/zhaquirks/ikea/fivebtnremotezha.py
@@ -0,0 +1,185 @@
+"""Device handler for IKEA of Sweden TRADFRI remote control."""
+from zigpy.profiles import zha
+from zigpy.quirks import CustomDevice
+import zigpy.types as t
+from zigpy.zcl.clusters.general import (
+    Basic,
+    Groups,
+    Identify,
+    LevelControl,
+    OnOff,
+    Ota,
+    PollControl,
+    PowerConfiguration,
+    Scenes,
+)
+from zigpy.zcl.clusters.lightlink import LightLink
+
+from . import IKEA, LightLinkCluster
+from .. import DoublingPowerConfigurationCluster, EventableCluster
+from ..const import (
+    ARGS,
+    CLUSTER_ID,
+    COMMAND,
+    COMMAND_HOLD,
+    COMMAND_MOVE,
+    COMMAND_MOVE_ON_OFF,
+    COMMAND_PRESS,
+    COMMAND_RELEASE,
+    COMMAND_STEP,
+    COMMAND_STEP_ON_OFF,
+    COMMAND_TOGGLE,
+    DEVICE_TYPE,
+    DIM_DOWN,
+    DIM_UP,
+    ENDPOINT_ID,
+    ENDPOINTS,
+    INPUT_CLUSTERS,
+    LEFT,
+    LONG_PRESS,
+    MODELS_INFO,
+    OUTPUT_CLUSTERS,
+    PROFILE_ID,
+    RIGHT,
+    SHORT_PRESS,
+    TURN_ON,
+)
+
+IKEA_CLUSTER_ID = 0xFC7C  # decimal = 64636
+
+
+class ScenesCluster(EventableCluster, Scenes):
+    """Ikea Scenes cluster."""
+
+    def __init__(self, *args, **kwargs):
+        """Init."""
+        super().__init__(*args, **kwargs)
+        self.server_commands.update(
+            {
+                0x0007: ("press", (t.int16s, t.int8s, t.int8s), False),
+                0x0008: ("hold", (t.int16s, t.int8s), False),
+                0x0009: ("release", (t.int16s,), False),
+            }
+        )
+
+
+class IkeaTradfriRemote(CustomDevice):
+    """Custom device representing IKEA of Sweden TRADFRI remote control."""
+
+    signature = {
+        # <SimpleDescriptor endpoint=1 profile=260 device_type=2080
+        # device_version=1
+        # input_clusters=[0, 1, 3, 32, 4096, 64636]
+        # output_clusters=[3, 4, 6, 8, 25, 4096]>
+        MODELS_INFO: [(IKEA, "TRADFRI remote control")],
+        ENDPOINTS: {
+            1: {
+                PROFILE_ID: zha.PROFILE_ID,
+                DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER,
+                INPUT_CLUSTERS: [
+                    Basic.cluster_id,
+                    PowerConfiguration.cluster_id,
+                    Identify.cluster_id,
+                    PollControl.cluster_id,
+                    LightLink.cluster_id,
+                    IKEA_CLUSTER_ID,
+                ],
+                OUTPUT_CLUSTERS: [
+                    Identify.cluster_id,
+                    Groups.cluster_id,
+                    OnOff.cluster_id,
+                    LevelControl.cluster_id,
+                    Ota.cluster_id,
+                    LightLink.cluster_id,
+                ],
+            }
+        },
+    }
+
+    replacement = {
+        ENDPOINTS: {
+            1: {
+                PROFILE_ID: zha.PROFILE_ID,
+                DEVICE_TYPE: zha.DeviceType.NON_COLOR_CONTROLLER,
+                INPUT_CLUSTERS: [
+                    Basic.cluster_id,
+                    DoublingPowerConfigurationCluster,
+                    Identify.cluster_id,
+                    PollControl.cluster_id,
+                    LightLinkCluster,
+                    IKEA_CLUSTER_ID,
+                ],
+                OUTPUT_CLUSTERS: [
+                    Identify.cluster_id,
+                    Groups.cluster_id,
+                    ScenesCluster,
+                    OnOff.cluster_id,
+                    LevelControl.cluster_id,
+                    Ota.cluster_id,
+                    LightLink.cluster_id,
+                ],
+            }
+        }
+    }
+
+    device_automation_triggers = {
+        (SHORT_PRESS, TURN_ON): {
+            COMMAND: COMMAND_TOGGLE,
+            CLUSTER_ID: 6,
+            ENDPOINT_ID: 1,
+        },
+        (LONG_PRESS, TURN_ON): {
+            COMMAND: COMMAND_RELEASE,
+            CLUSTER_ID: 5,
+            ENDPOINT_ID: 1,
+            ARGS: [],
+        },
+        (SHORT_PRESS, DIM_UP): {
+            COMMAND: COMMAND_STEP_ON_OFF,
+            CLUSTER_ID: 8,
+            ENDPOINT_ID: 1,
+            ARGS: [0, 43, 5],
+        },
+        (LONG_PRESS, DIM_UP): {
+            COMMAND: COMMAND_MOVE_ON_OFF,
+            CLUSTER_ID: 8,
+            ENDPOINT_ID: 1,
+            ARGS: [0, 83],
+        },
+        (SHORT_PRESS, DIM_DOWN): {
+            COMMAND: COMMAND_STEP,
+            CLUSTER_ID: 8,
+            ENDPOINT_ID: 1,
+            ARGS: [1, 43, 5],
+        },
+        (LONG_PRESS, DIM_DOWN): {
+            COMMAND: COMMAND_MOVE,
+            CLUSTER_ID: 8,
+            ENDPOINT_ID: 1,
+            ARGS: [1, 83],
+        },
+        (SHORT_PRESS, LEFT): {
+            COMMAND: COMMAND_PRESS,
+            CLUSTER_ID: 5,
+            ENDPOINT_ID: 1,
+            ARGS: [257, 13, 0],
+        },
+        (LONG_PRESS, LEFT): {
+            COMMAND: COMMAND_HOLD,
+            CLUSTER_ID: 5,
+            ENDPOINT_ID: 1,
+            ARGS: [3329, 0],
+        },
+        (SHORT_PRESS, RIGHT): {
+            COMMAND: COMMAND_PRESS,
+            CLUSTER_ID: 5,
+            ENDPOINT_ID: 1,
+            ARGS: [256, 13, 0],
+        },
+        (LONG_PRESS, RIGHT): {
+            COMMAND: COMMAND_HOLD,
+            CLUSTER_ID: 5,
+            ENDPOINT_ID: 1,
+            ARGS: [3328, 0],
+        },
+    }


Test patch: