Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Device Support Request] Ikea E2123: Symfonisk sound remote Gen2 #2223

Closed
MrDodojo opened this issue Feb 24, 2023 · 99 comments · Fixed by #2273
Closed

[Device Support Request] Ikea E2123: Symfonisk sound remote Gen2 #2223

MrDodojo opened this issue Feb 24, 2023 · 99 comments · Fixed by #2273

Comments

@MrDodojo
Copy link

Is your feature request related to a problem? Please describe.
Ikea released a new Symfonisk sound remote (gen2) and it is not yet supported by ZHA. The device when added to homeassistant does not have triggers for pressing the various buttons seperately. The only triggers it has are: Device offline, has been pressed and battery level changed(while the battery level does not indicate correctly either).

Describe the solution you'd like
Support for all the buttons: Volume up & down, next & previous, play/pause and 2 custom "shortcut" buttons.

Device signature
{
  "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.EndDevice: 2>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress: 128>, manufacturer_code=4476, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)",
  "endpoints": {
    "1": {
      "profile_id": 260,
      "device_type": "0x0006",
      "in_clusters": [
        "0x0000",
        "0x0001",
        "0x0003",
        "0x0020",
        "0x1000",
        "0xfc57"
      ],
      "out_clusters": [
        "0x0003",
        "0x0004",
        "0x0006",
        "0x0008",
        "0x0019",
        "0x1000",
        "0xfc7f"
      ]
    }
  },
  "manufacturer": "IKEA of Sweden",
  "model": "SYMFONISK sound remote gen2",
  "class": "zigpy.device.Device"
}
Diagnostic information
{
  "home_assistant": {
    "installation_type": "Home Assistant OS",
    "version": "2023.2.1",
    "dev": false,
    "hassio": true,
    "virtualenv": false,
    "python_version": "3.10.7",
    "docker": true,
    "arch": "aarch64",
    "timezone": "Europe/Amsterdam",
    "os_name": "Linux",
    "os_version": "5.15.84-v8",
    "supervisor": "2023.01.1",
    "host_os": "Home Assistant OS 9.5",
    "docker_version": "20.10.22",
    "chassis": "embedded",
    "run_as_root": true
  },
  "custom_components": {
    "adaptive_lighting": {
      "version": "1.4.1",
      "requirements": []
    },
    "localtuya": {
      "version": "5.0.0",
      "requirements": []
    },
    "hacs": {
      "version": "1.30.1",
      "requirements": [
        "aiogithubapi>=22.10.1"
      ]
    }
  },
  "integration_manifest": {
    "domain": "zha",
    "name": "Zigbee Home Automation",
    "config_flow": true,
    "documentation": "https://www.home-assistant.io/integrations/zha",
    "requirements": [
      "bellows==0.34.7",
      "pyserial==3.5",
      "pyserial-asyncio==0.6",
      "zha-quirks==0.0.92",
      "zigpy-deconz==0.19.2",
      "zigpy==0.53.0",
      "zigpy-xbee==0.16.2",
      "zigpy-zigate==0.10.3",
      "zigpy-znp==0.9.2"
    ],
    "usb": [
      {
        "vid": "10C4",
        "pid": "EA60",
        "description": "*2652*",
        "known_devices": [
          "slae.sh cc2652rb stick"
        ]
      },
      {
        "vid": "1A86",
        "pid": "55D4",
        "description": "*sonoff*plus*",
        "known_devices": [
          "sonoff zigbee dongle plus v2"
        ]
      },
      {
        "vid": "10C4",
        "pid": "EA60",
        "description": "*sonoff*plus*",
        "known_devices": [
          "sonoff zigbee dongle plus"
        ]
      },
      {
        "vid": "10C4",
        "pid": "EA60",
        "description": "*tubeszb*",
        "known_devices": [
          "TubesZB Coordinator"
        ]
      },
      {
        "vid": "1A86",
        "pid": "7523",
        "description": "*tubeszb*",
        "known_devices": [
          "TubesZB Coordinator"
        ]
      },
      {
        "vid": "1A86",
        "pid": "7523",
        "description": "*zigstar*",
        "known_devices": [
          "ZigStar Coordinators"
        ]
      },
      {
        "vid": "1CF1",
        "pid": "0030",
        "description": "*conbee*",
        "known_devices": [
          "Conbee II"
        ]
      },
      {
        "vid": "10C4",
        "pid": "8A2A",
        "description": "*zigbee*",
        "known_devices": [
          "Nortek HUSBZB-1"
        ]
      },
      {
        "vid": "0403",
        "pid": "6015",
        "description": "*zigate*",
        "known_devices": [
          "ZiGate+"
        ]
      },
      {
        "vid": "10C4",
        "pid": "EA60",
        "description": "*zigate*",
        "known_devices": [
          "ZiGate"
        ]
      },
      {
        "vid": "10C4",
        "pid": "8B34",
        "description": "*bv 2010/10*",
        "known_devices": [
          "Bitron Video AV2010/10"
        ]
      }
    ],
    "codeowners": [
      "@dmulcahey",
      "@adminiuga",
      "@puddly"
    ],
    "zeroconf": [
      {
        "type": "_esphomelib._tcp.local.",
        "name": "tube*"
      },
      {
        "type": "_zigate-zigbee-gateway._tcp.local.",
        "name": "*zigate*"
      },
      {
        "type": "_zigstar_gw._tcp.local.",
        "name": "*zigstar*"
      },
      {
        "type": "_slzb-06._tcp.local.",
        "name": "slzb-06*"
      }
    ],
    "dependencies": [
      "file_upload"
    ],
    "after_dependencies": [
      "onboarding",
      "usb",
      "zeroconf"
    ],
    "iot_class": "local_polling",
    "loggers": [
      "aiosqlite",
      "bellows",
      "crccheck",
      "pure_pcapy3",
      "zhaquirks",
      "zigpy",
      "zigpy_deconz",
      "zigpy_xbee",
      "zigpy_zigate",
      "zigpy_znp"
    ],
    "is_built_in": true
  },
  "data": {
    "ieee": "**REDACTED**",
    "nwk": 10838,
    "manufacturer": "IKEA of Sweden",
    "model": "SYMFONISK sound remote gen2",
    "name": "IKEA of Sweden SYMFONISK sound remote gen2",
    "quirk_applied": false,
    "quirk_class": "zigpy.device.Device",
    "manufacturer_code": 4476,
    "power_source": "Battery or Unknown",
    "lqi": 159,
    "rssi": null,
    "last_seen": "2023-02-24T15:07:16",
    "available": true,
    "device_type": "EndDevice",
    "signature": {
      "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.EndDevice: 2>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress: 128>, manufacturer_code=4476, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)",
      "endpoints": {
        "1": {
          "profile_id": 260,
          "device_type": "0x0006",
          "in_clusters": [
            "0x0000",
            "0x0001",
            "0x0003",
            "0x0020",
            "0x1000",
            "0xfc57"
          ],
          "out_clusters": [
            "0x0003",
            "0x0004",
            "0x0006",
            "0x0008",
            "0x0019",
            "0x1000",
            "0xfc7f"
          ]
        }
      }
    },
    "active_coordinator": false,
    "entities": [
      {
        "entity_id": "sensor.ikea_of_sweden_symfonisk_sound_remote_gen2_battery",
        "name": "IKEA of Sweden SYMFONISK sound remote gen2"
      },
      {
        "entity_id": "button.ikea_of_sweden_symfonisk_sound_remote_gen2_identify",
        "name": "IKEA of Sweden SYMFONISK sound remote gen2"
      }
    ],
    "neighbors": [],
    "routes": [],
    "endpoint_names": [
      {
        "name": "REMOTE_CONTROL"
      }
    ],
    "user_given_name": null,
    "device_reg_id": "58a64db01f3b9ead5ee6417d4fe2f240",
    "area_id": "kitchen",
    "cluster_details": {
      "1": {
        "device_type": {
          "name": "REMOTE_CONTROL",
          "id": 6
        },
        "profile_id": 260,
        "in_clusters": {
          "0x0000": {
            "endpoint_attribute": "basic",
            "attributes": {
              "0x0004": {
                "attribute_name": "manufacturer",
                "value": "IKEA of Sweden"
              },
              "0x0005": {
                "attribute_name": "model",
                "value": "SYMFONISK sound remote gen2"
              }
            },
            "unsupported_attributes": {}
          },
          "0x0001": {
            "endpoint_attribute": "power",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x0003": {
            "endpoint_attribute": "identify",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x0020": {
            "endpoint_attribute": "poll_control",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x1000": {
            "endpoint_attribute": "lightlink",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0xfc57": {
            "endpoint_attribute": "manufacturer_specific",
            "attributes": {},
            "unsupported_attributes": {}
          }
        },
        "out_clusters": {
          "0x0003": {
            "endpoint_attribute": "identify",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x0004": {
            "endpoint_attribute": "groups",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x0006": {
            "endpoint_attribute": "on_off",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x0008": {
            "endpoint_attribute": "level",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x0019": {
            "endpoint_attribute": "ota",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x1000": {
            "endpoint_attribute": "lightlink",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0xfc7f": {
            "endpoint_attribute": "manufacturer_specific",
            "attributes": {},
            "unsupported_attributes": {}
          }
        }
      }
    }
  }
}
Additional logs
No Debug logs

Additional context
image
^This is the device, it has a lot of buttons and would be quite nice to use with homeassistant.

@MattWestb
Copy link
Contributor

MattWestb commented Feb 24, 2023

Where did you geeing it ??
I hope its being released iin EU very soon then its have being CSA-certified over one year now.

Edit: Its coming next week to Westbahnhoff in Vienna :-(((

@MrDodojo
Copy link
Author

MrDodojo commented Feb 24, 2023

Where did you geeing it ?? I hope its being released iin EU very soon then its have being CSA-certified over one year now.

Edit: Its coming next week to Westbahnhoff in Vienna :-(((

Got it at an Ikea in the Netherlands which is in the EU, they didn't have a lot of them so I was sure to grab one. 2 extra buttons for a total of 7 is nice to have

@MattWestb
Copy link
Contributor

Its looks very standard of the cluster and is clean but we must getting all the commands its sending.
I think its prity easy getting all Device Automatons (DA) but its needs little work getting it right and testing all is working OK.
Its only 2 IKEAs in Austria that having it on the homepage and no inside Vienna but i going and looking tomorrow if its some is having it.

One interesting thing its only Dirigera compatible and TF but shall testing that 2.

@MattWestb
Copy link
Contributor

Do you having ZHA-Toolkit https://github.com/mdeweerd/zha-toolkit installed ??

If yes bind the cluster Id: 0xfc80 on endpoint 2 and 3 to the coordinator (0x0000) and i think you shall getting the commands from the 2 shortcut buttons then its wot IKEA is doing in Dirigera then pairing it.

@MrDodojo
Copy link
Author

MrDodojo commented Feb 26, 2023

No I haven't. I just did, don't know how to use it yet. I'd appreciate if you could spoon-feed/help me what to do. Otherwise it will take me a while to understand the docs

Are you asking me to zha_toolkit.bind_ieee like this? I don't know what to set as ieee as the remote only has battery and identify as entities

service: zha_toolkit.bind_ieee
data:
  dst_endpoint: 2
  ieee: ????????
  command_data: 0
  cluster: 0xfc80

@SamDeBlock
Copy link

I have the same device, these are the debug logs for the 'dot' buttons:

1 dot button

DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=64639, SrcAddr=0xD1BF, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=63, SecurityUse=<Bool.false: 0>, TimeStamp=1453435, TSN=0, Data=b'\x15\x7C\x11\x42\x01\x01\x01', MacSrcAddr=0xD1BF, MsgResultRadius=29)
DEBUG (MainThread) [zigpy.application] Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=<AddrMode.NWK: 2>, address=0xD1BF), src_ep=1, dst=AddrModeAddress(addr_mode=<AddrMode.NWK: 2>, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=0, profile_id=260, cluster_id=64639, data=Serialized[b'\x15|\x11B\x01\x01\x01'], tx_options=<TransmitOptions.NONE: 0>, radius=29, non_member_radius=0, lqi=63, rssi=None)
DEBUG (MainThread) [zigpy.zcl] [0xD1BF:1:0xfc7f] Received ZCL frame: b'\x15|\x11B\x01\x01\x01'
DEBUG (MainThread) [zigpy.zcl] [0xD1BF:1:0xfc7f] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.CLUSTER_COMMAND: 1>, is_manufacturer_specific=True, direction=<Direction.Server_to_Client: 0>, disable_default_response=1, reserved=0, *is_cluster=True, *is_general=False, *is_reply=False), manufacturer=4476, tsn=66, command_id=1, *direction=<Direction.Server_to_Client: 0>, *is_reply=False)
WARNING (MainThread) [zigpy.zcl] [0xD1BF:1:0xfc7f] Unknown cluster command 1 b'\x01\x01'
DEBUG (MainThread) [zigpy.zcl] [0xD1BF:1:0xfc7f] Received command 0x01 (TSN 66): b'\x01\x01'
DEBUG (MainThread) [zigpy.zcl] [0xD1BF:1:0xfc7f] No explicit handler for cluster command 0x01: b'\x01\x01'

2 dot button

DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=64639, SrcAddr=0xD1BF, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=57, SecurityUse=<Bool.false: 0>, TimeStamp=2806217, TSN=0, Data=b'\x15\x7C\x11\x43\x01\x02\x01', MacSrcAddr=0xD1BF, MsgResultRadius=29)
DEBUG (MainThread) [zigpy.application] Received a packet: ZigbeePacket(src=AddrModeAddress(addr_mode=<AddrMode.NWK: 2>, address=0xD1BF), src_ep=1, dst=AddrModeAddress(addr_mode=<AddrMode.NWK: 2>, address=0x0000), dst_ep=1, source_route=None, extended_timeout=False, tsn=0, profile_id=260, cluster_id=64639, data=Serialized[b'\x15|\x11C\x01\x02\x01'], tx_options=<TransmitOptions.NONE: 0>, radius=29, non_member_radius=0, lqi=57, rssi=None)
DEBUG (MainThread) [zigpy.zcl] [0xD1BF:1:0xfc7f] Received ZCL frame: b'\x15|\x11C\x01\x02\x01'
DEBUG (MainThread) [zigpy.zcl] [0xD1BF:1:0xfc7f] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.CLUSTER_COMMAND: 1>, is_manufacturer_specific=True, direction=<Direction.Server_to_Client: 0>, disable_default_response=1, reserved=0, *is_cluster=True, *is_general=False, *is_reply=False), manufacturer=4476, tsn=67, command_id=1, *direction=<Direction.Server_to_Client: 0>, *is_reply=False)
WARNING (MainThread) [zigpy.zcl] [0xD1BF:1:0xfc7f] Unknown cluster command 1 b'\x02\x01'
DEBUG (MainThread) [zigpy.zcl] [0xD1BF:1:0xfc7f] Received command 0x01 (TSN 67): b'\x02\x01'
DEBUG (MainThread) [zigpy.zcl] [0xD1BF:1:0xfc7f] No explicit handler for cluster command 0x01: b'\x02\x01'

@MattWestb
Copy link
Contributor

MattWestb commented Feb 27, 2023

For both is the remote on original / factory firmware or is it updated by Dirigera ?
I have looking little and my have more endpoints and cluster but i was updating it and its now 0x01000032.
Signature:

  },
  "data": {
    "ieee": "**REDACTED**",
    "nwk": 43256,
    "manufacturer": "IKEA of Sweden",
    "model": "SYMFONISK sound remote gen2",
    "name": "IKEA of Sweden SYMFONISK sound remote gen2",
    "quirk_applied": false,
    "quirk_class": "zigpy.device.Device",
    "manufacturer_code": 4476,
    "power_source": "Battery or Unknown",
    "lqi": 206,
    "rssi": -54,
    "last_seen": "2023-02-27T13:52:48",
    "available": true,
    "device_type": "EndDevice",
    "signature": {
      "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.EndDevice: 2>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress: 128>, manufacturer_code=4476, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=True, *is_full_function_device=False, *is_mains_powered=False, *is_receiver_on_when_idle=False, *is_router=False, *is_security_capable=False)",
      "endpoints": {
        "1": {
          "profile_id": 260,
          "device_type": "0x0006",
          "in_clusters": [
            "0x0000",
            "0x0001",
            "0x0003",
            "0x0020",
            "0x1000",
            "0xfc7c"
          ],
          "out_clusters": [
            "0x0003",
            "0x0004",
            "0x0006",
            "0x0008",
            "0x0019",
            "0x1000"
          ]
        },
        "2": {
          "profile_id": 260,
          "device_type": "0x0006",
          "in_clusters": [
            "0x0000",
            "0x0003",
            "0xfc80"
          ],
          "out_clusters": [
            "0x0003",
            "0x0004",
            "0xfc80"
          ]
        },
        "3": {
          "profile_id": 260,
          "device_type": "0x0006",
          "in_clusters": [
            "0x0000",
            "0x0003",
            "0xfc80"
          ],
          "out_clusters": [
            "0x0003",
            "0x0004",
            "0xfc80"
          ]
        }
      }
    },
  }
}

@SamDeBlock
Copy link

Mine has definitely been updated to the latest firmware. I first connected it to the dirigera hub and then it automatically started updating.

@MrDodojo
Copy link
Author

I did not connect it to a dirigera hub since I don't have one.

@MattWestb
Copy link
Contributor

OK then its logic way @MrDodojo is having different configuration.
We must doing 2 device classes so both updated and not updated devices is working OK.
@MrDodojo pleas dont updating your device we need it for doing testing then IKEA have locking the chip so its not possible dumping the original firmware (that i normally doing) and flashing it back for doing firmware downgrading.

@MattWestb
Copy link
Contributor

@TheJulianJES I have getting the signature working OK and the quirk is loading for both device classes.
The V1 is using only EP1 for all commands and V2 is using EP1 for Light commands and EP2 for button 1 and EP3 for button 2 extra commands from cluster V1 0xFC7F / V20xFC80.

From the V1 log:

[0x0664:1:0xfc7f] Unknown cluster command 1 b'\x01\x01' = B1 Short
[0x0664:1:0xfc7f] Unknown cluster command 1 b'\x02\x01' = B2 Short
[0x0664:1:0xfc7f] Unknown cluster command 1 b'\x01\x02' = B1 Duble
[0x0664:1:0xfc7f] Unknown cluster command 1 b'\x02\x03' = B2 Held

The V2 is not reporting then its need EP 2 and 3 being bound and i dont knowing how to do that.

The next problems is the DA is crazy dim up is not triggered and left and right is triggered for both.

Can you taking one look if you can see what i have doing wrong ?

symfonisk2.zip

Thanks in advance !

@MichelBrodatzki
Copy link

I've just opened a pull request with a basic implementation for the E2123 with (probably) V1. Every button should work as a trigger for automations (and some buttons even with long press and double press).
Currently I'm struggling a bit with passing arguments as both ARGS and PARAMS (or with passing the at all as PARAMS) with the listener_event(...) approach.

@MattWestb I'm quite new to creating device handlers and I don't have an updated E2123 at hand to test my theories, but maybe the event listener approach might be a way to make implementing V2 easier? (i.e. passing the command actions from EP2 and 3 to the custom LevelControlCluster)

@MattWestb
Copy link
Contributor

Great thanks for working on the quirk for our devices @MichelBrodatzki !!

I have not testing it only looking how you have doing things and im not one code warier so i cant saying it its working or how good / bad it is only testing and see if its working OK or not.
First is better putting Ver1 for version in the device class name so not need renaming it later and remaking the tests and then its easy adding the variant 2 and so on.
Also put the firmware version in the device class dock string is good.

You is having WWAH_CLUSTER_ID in the signature and replacing it with IKEA_CLUSTER_ID that is not making any sense and can making problem if we need using the cluster in the future.

In the INIT you is making one device class ShortcutCluster for cluster 0xFC7F = OK but the Ver 2 is using cluster 0xfc80 for chortcut function on EP 2 and 3 (i must paring it with Dirigera and sniffing it for verifying it). Its very likely we need making 2 different device classes for getting it working but wait until i have sniffing the functions how Dirigera is doing it.

The device automatons shall working with only putting one of more args / parms but my test DAs is spinning completely but i getting the right events from the device and its likely we is hitting one bug in HA that braking some functions (very deep and not oft seen but its there) so take it with "little salt" for the moment until we have testing it more or finding other versions that working OK.

I starting sniffing Dirigera an then i installing your quirk and testing the V1 functions.

@MattWestb
Copy link
Contributor

Also Also i think the PowerConfiguration2AAACluster is not needed and can using the normal PowerConfiguration.cluster_id like all other V24.X firmware devices.
My Sy2 is showing 50 and 82% without doubling and is having unchanged batteries from IKEA that shall need being changed for have 100%.
What is your device reporting and is you using alkaline or rehanged batteries ?

@MattWestb
Copy link
Contributor

V2 looks using complete different commends but its having release after long press implanted and is sent from EP 2 and 3 for button 1 and 2.
Attaching the frames its sending and have the paring and the button press saved if we need it later.
Symfonisk2UpdatedDASniff.txt

It can being the command is the same as V1 then wireshark is little outdated but i dont have the knowledge analyzing that.

@MrDodojo
Copy link
Author

Anything for me to test atm? I could test the quirk MichelBrodatzki made but I don't understand how to. I added a custom quirk location to my configuration, do I need to add the whole repo or just the changed files?

@MichelBrodatzki
Copy link

MichelBrodatzki commented Feb 28, 2023

@MattWestb

First is better putting Ver1 for version in the device class name so not need renaming it later and remaking the tests and then its easy adding the variant 2 and so on.
Also put the firmware version in the device class dock string is good.

Yes, that's a great idea. To be perfectly honest with you, I've only seen this issue and your contribution after working on it for some time, so this wasn't even on my radar!

You is having WWAH_CLUSTER_ID in the signature and replacing it with IKEA_CLUSTER_ID that is not making any sense and can making problem if we need using the cluster in the future.

True, that's just an oversight and was not intended. Will be fixed!

What is your device reporting and is you using alkaline or rehanged batteries ?

I've tried both rechargeable NiMH AAA and Alkaline AAA, all new or fully charged. Both showed a battery state of 50%. Maybe that was just a ZigBee thing and the info hasn't yet truly arrived/updated. I'll first fix the other things and then I'll play around with battery reporting :-)

@MrDodojo If you're still on the old version of the sound remote, my files should work for you. To add them as a custom quirk after enabling the custom quirk location, you can follow these steps:

  1. inside the custom quirk location, create a folder named ikea
  2. to this folder add the zhaquirks/ikea/__init__.py and zhaquirks/ikea/symfonisk.py from my pull request
  3. now you need to modify symfonisk.py to not use the existing symfonisk module. Just change the line starting with from zhaquirks.ikea import ( (currently that's line 49, but may change with further commits) to from . import (. This will use the __init__.pyfrom the same folder and not the "old" from zha-device-handlers
  4. restart Home Assistant and check if the quirk was loaded (should appear under "Zigbee Info" for the device in Home Assistant)

@MattWestb
Copy link
Contributor

I have getting all the V2 commands working from the network but i cant getting them being sent to zha_events. The command part looks like this:

class ShortcutV2Cluster(CustomCluster):
    """Ikea Shortcut Button Cluster Variant 2."""

    name = "ShortcutClusterV2"
    cluster_id = 0xFC80

    server_commands = {
        0x01: foundation.ZCLCommandDef(
            "shortcut",
            {
                "shortcut_mode": t.int8s,
                "param1": t.int8s,
            },
            False,
            is_manufacturer_specific=True,
       ),
       0x02: foundation.ZCLCommandDef(
            "hold",
            {
                "held": t.uint4_t,
                "param1": t.uint4_t,
               },
            False,
            is_manufacturer_specific=True,
        ),
        0x03: foundation.ZCLCommandDef(
            "press",
            {
                "pressed": t.uint4_t,
                "param1": t.uint4_t,
            },
            False,
            is_manufacturer_specific=True,
        ),
        0x04: foundation.ZCLCommandDef(
            "releas",
            {
                "released": t.uint4_t,
                "param1": t.uint4_t,
            },
            False,
            is_manufacturer_specific=True,
        ),
        0x05: foundation.ZCLCommandDef(
        "unknown",
            {
                "unknown": t.uint4_t,
                "param1": t.uint4_t,
            },
            False,
            is_manufacturer_specific=True,
        ),
        0x06: foundation.ZCLCommandDef(
            "double",
            {
                "double_pressd": t.int8s,
                "param1": t.int8s,
            },
            False,
            is_manufacturer_specific=True,
        ),
    }

    def handle_cluster_request(
        self,
        hdr: foundation.ZCLHeader,
        args: List[Any],
        *,
        dst_addressing: Optional[
            Union[t.Addressing.Group, t.Addressing.IEEE, t.Addressing.NWK]
        ] = None,
    ):
        """Handle a cluster request."""
        self.debug(
            "%s: handle_cluster_request - Command: %s Data: %s",
            self.name,
            hdr.command_id,
            args,
        )

        if hdr.command_id == 0x01:
            self.debug("%s: sending ZHA event", self.name)

            event_args = {
                "step_mode": (
                    LevelControl.StepMode.Up
                    if args.shortcut_mode == 1
                    else LevelControl.StepMode.Down
                ),
                "step_size": args.param1,
                "transition_time": 0,
            }

            self.endpoint.out_clusters[8].listener_event(
                ZHA_SEND_EVENT, "step_with_on_off", event_args
            )

The last part i have not touched then i dont understanding it.

@javicalle do you knowing how getting the command to events ?
The log is now looks like this then pressing the button:

2023-03-05 14:01:07.573 DEBUG (MainThread) [zigpy.zcl] [0xBD72:2:0xfc80] Decoded ZCL frame: ShortcutV2Cluster:press(pressed=0, param1=0)
2023-03-05 14:01:07.576 DEBUG (MainThread) [zigpy.zcl] [0xBD72:2:0xfc80] Received command 0x03 (TSN 85): press(pressed=0, param1=0)
2023-03-05 14:01:07.580 DEBUG (MainThread) [zigpy.zcl] [0xBD72:2:0xfc80] ShortcutClusterV2: handle_cluster_request - Command: 3 Data: press(pressed=0, param1=0)

@MattWestb
Copy link
Contributor

I was looking how we have doing the TS004X implementation that is only sending events and not using strange cluster and also is doing the arg and parms OK and i like that but i cant doing the coding for Symfonisk 2.
class TuyaSmartRemoteOnOffCluster(OnOff, EventableCluster):

@javicalle
Copy link
Collaborator

@javicalle do you knowing how getting the command to events ?

Maybe implementing the EventableCluster?

class ShortcutV2Cluster(CustomCluster, EventableCluster):

You will need to add the import like:

from zhaquirks import EventableCluster, ...

@javicalle
Copy link
Collaborator

Let me take a look at the args part...

@MattWestb
Copy link
Contributor

(CustomCluster, EventableCluster) was not working so i was trying with (EventableCluster) and its loading but i dont knowing if its working.

I have copy from the tuya but i dont know how to do it working:

    def handle_cluster_request(
        self,
        hdr: foundation.ZCLHeader,
        args: List[Any],
        *,
        dst_addressing: Optional[
            Union[t.Addressing.Group, t.Addressing.IEEE, t.Addressing.NWK]
        ] = None,
    ):

        if hdr.command_id == 0x00:
            rotate_type = args[0]
            self.listener_event(
                ZHA_SEND_EVENT, self.rotate_type.get(rotate_type, "unknown"), []
            )
        elif hdr.command_id == 0x03:
            press_type = args[0]
            self.listener_event(
                ZHA_SEND_EVENT, self.press_type.get(press_type, "unknown"), []
            )

I do only having different commands 1-6 and the data looks being not interesting then can see from witch EP its coming.

@MichelBrodatzki
Copy link

Sorry for the radio silence, I've been quite busy with university. But I think I just solved the args part! Let me just test one last thing, then I'll push it and comment what I did! Give me 10min :D

@MattWestb
Copy link
Contributor

For V2 commands looks like this:

01 first frame
02 hold
03 short
04 release
05 ?
06 double

Command 0x06 is the data length 2 all other is data length 1.
Data is always length 1 but looks being irrelevant for us.

And the device is sending one command 1 and then one command 2-6.
If command 2 its sending one command 4 then being released without command 1.
So command 1 is only some button is being pressed.

@MattWestb
Copy link
Contributor

Only for information i was reading that IKEA is forcing update of version 1 to new firmware and user and we cant reversing it (chip is debug locked) so V1 is only one "factory delivered version" and not one production version.
Also it is missing release after held.

@MichelBrodatzki
Copy link

So, after testing I can say that V1 should work now. The solution actually was pretty simple, I just haven't interpreted to underlying code correctly.

So for argument passing to work properly, you just have to create a new class which inherits from CommandSchema (which in turn is a subclass of t.Struct) and then you can pass an object of that class to listener_event. The method handles CommandSchema differently to dicts and lists.

@MichelBrodatzki
Copy link

Only for information i was reading that IKEA is forcing update of version 1 to new firmware and user and we cant reversing it (chip is debug locked) so V1 is only one "factory delivered version" and not one production version. Also it is missing release after held.

That's an interesting information, thanks! I'd say that supporting V1 is still pretty important, as OTA is not on by default for ZHA, so there might still be some people on V1 when adding their E2123 to Home Assistant.

@MattWestb
Copy link
Contributor

MattWestb commented Mar 5, 2023

I think that was one TF user that was not getting the OTA then TF dont have it then Dirigera is forcing update in the background.
Also many users dont have one IKEA GW and dont getting updates if not doing it manual in ZHA so V1 its needed !

And i think Vindstyrka is not being supported by TF GW only Dirigera.

@javicalle
Copy link
Collaborator

@MattWestb I have looked at some bind() implementations in the code, but I have no idea of what must be 'binded'.
Can you share what were you doing with the 'zha-tools', maybe that gives me an idea of what kind of implementation is needed.

@TheJulianJES
Copy link
Collaborator

Yeah, and can you also send a screenshot of the "reconfiguration page" (with the quirk applied)?

A channel for the manufacturer specific cluster might need to be added to ZHA here: https://github.com/home-assistant/core/blob/dev/homeassistant/components/zha/core/channels/manufacturerspecific.py

@MattWestb
Copy link
Contributor

MattWestb commented Mar 11, 2023

@javicalle ZHA-Toolkit in yaml mode looks like this:

service: zha_toolkit.bind_ieee
data:
  ieee: 1c:34:f1:ff:fe:78:57:15
  cluster: 64640
  tries: 5
  command_data: 00:0d:6f:ff:fe:12:db:36

Symfonisk 2 V2 IEEE 1c:34:f1:ff:fe:78:57:15
The Cooorrdinator IEEE 00:0d:6f:ff:fe:12:db:36
IKEA "Matter switch cluster" 0xfc80 = 64640
and the result in the log is:

2023-03-11 21:45:54.224 DEBUG (MainThread) [custom_components.zha_toolkit] event_data {'zha_toolkit_version': 'dev', 'zigpy_version': '0.53.2', 'zigpy_rf_version': '0.34.9', 'ieee_org': 1c:34:f1:ff:fe:78:57:15, 'ieee': '1c:34:f1:ff:fe:78:57:15', 'command': 'bind_ieee', 'command_data': '00:0d:6f:ff:fe:12:db:36', 'start_time': '2023-03-11T20:45:50.616811+00:00', 'errors': [], 'params': {'cluster_id': 64640, 'dir': 0, 'tries': 5, 'expect_reply': True, 'args': [], 'read_before_write': True, 'read_after_write': True}, 'result': {2: {'src_endpoint_id': 2, 'dst_endpoint_id': 1, 'cluster_id': 64640, 'result': [<Status.SUCCESS: 0>]}, 3: {'src_endpoint_id': 3, 'dst_endpoint_id': 1, 'cluster_id': 64640, 'result': [<Status.SUCCESS: 0>]}}, 'success': True}

For @TheJulianJES:
Symf2A
Symf2B

@cooljimy84
Copy link

@cooljimy84 Can you testing the posted quirk then i have updating it and its looks working OK for my devices ? #2223 (comment)

Sorry for the late reply, do you still want me to test on my v1 remote ?

@MattWestb
Copy link
Contributor

If you like then more testing is always good and for my is the V1 working OK i only have problem getting V2 getting the extra EP getting bonded.
If you have time and cant testing and reporting back wold being great !!

Likely i can posting one updated version later with updated naming but the V1 functionality is not changed but i need testing i is not braking it :-))

@MattWestb
Copy link
Contributor

Was looking how we is doing with the famous tuya TS004F and its looks so:

class TuyaSmartRemoteOnOffCluster(OnOff, EventableCluster):

And was testing importing OnOff and putting it in like this
class ShortcutV2Cluster(OnOff, EventableCluster):
and deleting the device and restarting HA adding the device and it was binding the clusters !!!
I think OnOff is not so good so i was testing using scene cluster but the binding was not working so back to OnOff and doing more testing if getting errors then the quirk is doing it work.

Its working but it can later being one braking thing if we need changing the cluster type.

I think its little sad that ZHA is not having EventableCluster (its one custom cluster) that is being bound and i think we need it for some device and not only this one for making more nice code in the quirk for getting it working.

What was making it not making extra switches in ZHA GUI i think is the device type REMOTE_CONTROL then normally if having OnOff as one in cluster ZHA is making one for every cluster / EP.

@MattWestb
Copy link
Contributor

Updated with better naming for both V1 and V2.
Looks working OK for both types.

  endpoint_id: 1
  cluster_id: 64639
  command: ShortCutV1Events
  args:
    - 1
    - 1
  params:
    Shortcut_Button: 1
    Shortcut_Event: 1

  endpoint_id: 1
  cluster_id: 64639
  command: ShortCutV1Events
  args:
    - 1
    - 2
  params:
    Shortcut_Button: 1
    Shortcut_Event: 2

  endpoint_id: 1
  cluster_id: 64639
  command: ShortCutV1Events
  args:
    - 2
    - 3
  params:
    Shortcut_Button: 2
    Shortcut_Event: 3

Also possible making the Shortcut_Event encoded to short. double and long but its little over my knowledge so need some helping implating it or i letting it then its working OK like this.
symfonisk2RC1.zip
Last fix is moving some commands to constant but it shall not braking things if i doing it right so its coming in RC2.

@MattWestb
Copy link
Contributor

Symfonis2 RC2 with all common constants moved to quirk constants.
So V1 is having 13 working DAs and V2 17.
No warning or errors then starting HA and also then using all the button (exception hold dim up and down then the automation is stalling then its too fast).

I think i have getting all out of the device we can getting at this point.
Also i think its future secure if IKEA is adding more press function its minimal changes needed for implanting it also moving to real Matter Switch Cluster shall being easy then its being released.

symfonisk2RC2.zip

Test is more then welcome and use the privius instruction for local quirk for getting the right file structure (all 3 files in the same folder).

Also dont forgetting deleting the custom quirks then its being merged in HA and you is updating to it for not getting problem in n the future !!

@dieneuser
Copy link

@MattWestb
I have successfully tested your last quirk (RC2) with the V1 firmware. All buttons return the expected events and I can control a media player and lights with it.

THX

@MattWestb
Copy link
Contributor

Great @dieneuser !!
Was you also testing making automatons from the device card (DAs) ?

I have not testing if the device like binding to devices for controlling devices but is one secondary thing then its one sound controller and 100% group bindings is not working then its new gen firmware.

Thanks for testing the quirk !!

@javicalle
Copy link
Collaborator

No sure why the ShortcutV2Cluster is not binding/triggering the bind. It seems to be a implemented in the Cluster class:
https://github.com/zigpy/zigpy/blob/2cbb79f4335947a71c039a37ff26e87940dbd7a7/zigpy/zcl/__init__.py#L598-L599

So all the clusters have it. Maybe is not doing the why we need here, so my first recommendation would be to check the normal implementation values, since there are no logs in the methods we want to validate, I suggest adding them in the cluster like:

class ShortcutV2Cluster(EventableCluster):
    """Ikea Shortcut Button Cluster Variant 2."""

    name = "ShortcutClusterV2"
    cluster_id = IKEA_MSWITCH_CLUSTER_ID

    async def bind(self):
        """Bind cluster."""
        result = await super().bind()
        _LOGGER.debug(
            f"Binding values: device.ieee {self._endpoint.device.ieee!r}, endpoint_id: {self._endpoint.endpoint_id!r}, cluster_id: {self.cluster_id!r}, dst_address: {self._endpoint.device.application.get_dst_address(self)!r}"
        )
        return result

    .../...

If the method is not called, why can try to trigger it from another cluster (ie: OnOff or LevelControl).
If it is a question of the call values, maybe we can play around to force the right values.

I haven't found which is the reason some clusters reports the binding greencheck and others don't.

@TheJulianJES
Copy link
Collaborator

TheJulianJES commented Mar 12, 2023

I think manufacturer specific clusters have to be added here in order for ZHA to call the bind() method: https://github.com/home-assistant/core/blob/dev/homeassistant/components/zha/core/channels/manufacturerspecific.py

See PhillipsRemote for example.

@javicalle
Copy link
Collaborator

So, we need just to add the IKEA_MSWITCH_CLUSTER_ID in HA like that?:

@registries.BINDABLE_CLUSTERS.register(0xFC80)
@registries.CHANNEL_ONLY_CLUSTERS.register(0xFC80)
@registries.ZIGBEE_CHANNEL_REGISTRY.register(0xFC80)
class IkeaRemote(ZigbeeChannel):
    """Ikea Mater remote channel."""

    REPORT_CONFIG = ()

@MattWestb, can you test?

If working, then we can add the IKEA_MSWITCH_CLUSTER_ID in the registries:
https://github.com/home-assistant/core/blob/c41f91be896978f2d18d2c2b4d039dc41457e9a3/homeassistant/components/zha/core/registries.py#L31-L37

PS: here is were the magic happens:
https://github.com/home-assistant/core/blob/c41f91be896978f2d18d2c2b4d039dc41457e9a3/homeassistant/components/zha/core/registries.py#L77

@MattWestb
Copy link
Contributor

MattWestb commented Mar 12, 2023

Thanks @javicalle !!

The #2223 (comment) was not working after deleting and restart and adding ZHA was not binding the cluster and reconfigure was also not trying doing it.

With class ShortcutV2Cluster(OnOff, EventableCluster): is working great and im satisfied with it then its looks working also for more users.

The good thing is its easy if IKEA is doing changes to Matter ZCL standard cluster numbering and i dont like making PR in HA that is also not being merged (my experience of tuya TRVs) and not getting the devices working OK for our users then one is not being merged with the other.

Then i is having 3 devices under test for one week and for 2 PR and 3 PRs not being merged (they is ready for deletion from my side) and need times doing some other things 2 so i posting the PR and some that like doing it different can redoing it or not getting the devices supported if not getting accepted.

Edit: One PR is deleted so one less to care off for some..

@cooljimy84
Copy link

Symfonis2 RC2 with all common constants moved to quirk constants. So V1 is having 13 working DAs and V2 17. No warning or errors then starting HA and also then using all the button (exception hold dim up and down then the automation is stalling then its too fast).

I think i have getting all out of the device we can getting at this point. Also i think its future secure if IKEA is adding more press function its minimal changes needed for implanting it also moving to real Matter Switch Cluster shall being easy then its being released.

symfonisk2RC2.zip

Test is more then welcome and use the privius instruction for local quirk for getting the right file structure (all 3 files in the same folder).

Also dont forgetting deleting the custom quirks then its being merged in HA and you is updating to it for not getting problem in n the future !!

This works for me on the GEN2 firmware 1, though everything appears to be lower case apart from "Shortcut_Button"

@MattWestb
Copy link
Contributor

Thanks for testing and reporting back @cooljimy84 !!
I was doing all nice with upper and lower case but then putting the new constants in the system wide constants all system wide is only in lower cases and the variables is only in upper case so must changing it or i cant getting one PR merged.
Im sorry for that then for my it was looking nicer with the original casing but i cant braking the system wide system.

Is is some users with updated firmware that can testing the updated quirk ??

@MattWestb
Copy link
Contributor

Hola @javicalle !!
I was patching ZHA with your code and was changing back to
class ShortcutV2Cluster(EventableCluster):.
Deleting the device and restarting HA.
Adding the device and the manufacture cluster is being bound after being paired.
Also then doing reconfigure it is binding the cluster = OK !!

For my is one cleaner way than using OnOff cluster that is not the true cluster and making things crappy.

My thinking is making EventableClusterB (B = Bind) and putting one cluster number that is not used and getting one universal event cluster that is being bounded and is reporting OK for all devices that is needing it.

But if IKEA is releasing the ShortCut button Gen 2 in some weeks i think implanting your ZHA patch and hoping IKEA is using the same cluster number for the shortcutt commands and not doing one new version of it so i think we shall going your way.

And as normal thanks !

@MattWestb
Copy link
Contributor

One not so good thing of the ZHA binding is for users with other systems that is using zigpy is the cluster not being bonded and is not working so the devs of other systems must implanting it in there system and very likely its working out of the box with the dirty OnOff version.

@MattWestb
Copy link
Contributor

PR made for both firmware versions :-)))

@MattWestb
Copy link
Contributor

MattWestb commented Apr 6, 2023

I have updating HA to 2023.4.0 and deleting the local quirks and the V2 looks working well but i gave not testing all DA with real automation but its coming.

The V1 is reporting 160% battery renaming and ZHA is not showing the battery icon.
Was i doing wrong using the battery doubling for V1 ?
If some have more info and have doing testing i like getting feedback so we can fixing the problems.

I shall see if i can sniffing and see is its reporting Zigbee standard or old IKEA way.

Edit: I have testing all DA for both V1 and 2 and all is working OK so its no problems here.
I have not testing if the binding of EP 2 and 3 in ZHA is working then paring one V2 new but it shall working OK

@MattWestb
Copy link
Contributor

Was doing one fast sniffing and the device is reporting 80% and ZHA is doubling it as it shall and its being 160%.

ZigBee Network Layer Data, Dst: 0x0000, Src: 0xa714
ZigBee Application Support Layer Data, Dst Endpt: 1, Src Endpt: 1
    Frame Control Field: Data (0x40)
    Destination Endpoint: 1
    Cluster: Power Configuration (0x0001)
    Profile: Home Automation (0x0104)
    Source Endpoint: 1
    Counter: 23
ZigBee Cluster Library Frame, Command: Read Attributes Response, Seq: 72
    Frame Control Field: Profile-wide (0x18)
    Sequence Number: 72
    Command: Read Attributes Response (0x01)
    Status Record
        Attribute: Battery Percentage Remaining (0x0021)
        Status: Success (0x00)
        Data Type: 8-Bit Unsigned Integer (0x20)
        Remaining Battery Percentage: 80,0 [%]

So its looks like we is doing it wrong and shall not doubling the battery renaming.

Pleas reporting back how your V1 device is reporting the battery status then i dont like braking devices that is working OK if my device is not doing it right.

@javicalle
Copy link
Collaborator

Have you checked if device reports as battery powered?

@MattWestb
Copy link
Contributor

Hola :-))
No its not needed then ZHA is getting over 100% is dont displaying the battery icon (Styrbar is always sending 255 and ts the same and all"dirigera" 24.5 firmware).
If taking the doubling away its starts showing it OK in 110% sure but i like getting feedback before i doing one PR with the change and braking devices.

@1aranzant
Copy link

I paired my new gen2 remote yesterday, and it worked perfectly. But since today, I just does not work anymore. Pressing on the buttons does not send anything to ZHA, but "Press" - Identify does light up the LED.
I tried "reconfigure", but still nothing.
What should I do?

@MattWestb
Copy link
Contributor

Restarting HA
I was having the same problem after updating HA to 2023.4 and my V2 was working OK but the V1 not but was not getting any events from.
Restart and all is working OK.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants