zha-device-handlers icon indicating copy to clipboard operation
zha-device-handlers copied to clipboard

[Device Support Request] TS0041 needs quirk from TS0044

Open OlivierHens opened this issue 2 years ago • 6 comments

Tried adding a switch very similar to the Tuya 1 button switch (TS0041) but failed. Quirk does not get loaded due to endpoints mismatch. link to switch on Ali : https://nl.aliexpress.com/item/1005002858374901.html

However the endpoints are matching those present in TS0044.py Seems that these buttons are created in mass with 4 buttons and depending on housing and soldering only 1, 2, 3 or 4 are active.

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=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, 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": "0x0000",
      "in_clusters": [
        "0x0000",
        "0x0001",
        "0x0006",
        "0xe000"
      ],
      "out_clusters": [
        "0x000a",
        "0x0019"
      ]
    },
    "2": {
      "profile_id": 260,
      "device_type": "0x0000",
      "in_clusters": [
        "0x0001",
        "0x0006"
      ],
      "out_clusters": []
    },
    "3": {
      "profile_id": 260,
      "device_type": "0x0000",
      "in_clusters": [
        "0x0001",
        "0x0006"
      ],
      "out_clusters": []
    },
    "4": {
      "profile_id": 260,
      "device_type": "0x0000",
      "in_clusters": [
        "0x0001",
        "0x0006"
      ],
      "out_clusters": []
    }
  },
  "manufacturer": "_TZ3000_x7mej5oc",
  "model": "TS0041",
  "class": "zigpy.device.Device"
Diagnostic information
{
  "home_assistant": {
    "installation_type": "Home Assistant OS",
    "version": "2022.5.3",
    "dev": false,
    "hassio": true,
    "virtualenv": false,
    "python_version": "3.9.9",
    "docker": true,
    "arch": "x86_64",
    "timezone": "Europe/Brussels",
    "os_name": "Linux",
    "os_version": "5.10.108",
    "supervisor": "2022.05.1",
    "host_os": "Home Assistant OS 7.6",
    "docker_version": "20.10.9",
    "chassis": "vm",
    "run_as_root": true
  },
  "custom_components": {
    "hacs": {
      "version": "1.24.5",
      "requirements": [
        "aiogithubapi>=21.11.0"
      ]
    },
    "eufy_security": {
      "version": "1.0.0",
      "requirements": [
        "python-eufy-security==0.3.1"
      ]
    }
  },
  "integration_manifest": {
    "domain": "zha",
    "name": "Zigbee Home Automation",
    "config_flow": true,
    "documentation": "https://www.home-assistant.io/integrations/zha",
    "requirements": [
      "bellows==0.29.0",
      "pyserial==3.5",
      "pyserial-asyncio==0.6",
      "zha-quirks==0.0.73",
      "zigpy-deconz==0.16.0",
      "zigpy==0.45.1",
      "zigpy-xbee==0.14.0",
      "zigpy-zigate==0.7.4",
      "zigpy-znp==0.7.0"
    ],
    "usb": [
      {
        "vid": "10C4",
        "pid": "EA60",
        "description": "*2652*",
        "known_devices": [
          "slae.sh cc2652rb stick"
        ]
      },
      {
        "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": "10C4",
        "pid": "8B34",
        "description": "*bv 2010/10*",
        "known_devices": [
          "Bitron Video AV2010/10"
        ]
      }
    ],
    "codeowners": [
      "@dmulcahey",
      "@adminiuga"
    ],
    "zeroconf": [
      {
        "type": "_esphomelib._tcp.local.",
        "name": "tube*"
      }
    ],
    "after_dependencies": [
      "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": 43773,
    "manufacturer": "_TZ3000_x7mej5oc",
    "model": "TS0041",
    "name": "_TZ3000_x7mej5oc TS0041",
    "quirk_applied": false,
    "quirk_class": "zigpy.device.Device",
    "manufacturer_code": 4417,
    "power_source": "Battery or Unknown",
    "lqi": null,
    "rssi": null,
    "last_seen": "2022-05-11T20:02:01",
    "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=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, 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": "0x0000",
          "in_clusters": [
            "0x0000",
            "0x0001",
            "0x0006",
            "0xe000"
          ],
          "out_clusters": [
            "0x000a",
            "0x0019"
          ]
        },
        "2": {
          "profile_id": 260,
          "device_type": "0x0000",
          "in_clusters": [
            "0x0001",
            "0x0006"
          ],
          "out_clusters": []
        },
        "3": {
          "profile_id": 260,
          "device_type": "0x0000",
          "in_clusters": [
            "0x0001",
            "0x0006"
          ],
          "out_clusters": []
        },
        "4": {
          "profile_id": 260,
          "device_type": "0x0000",
          "in_clusters": [
            "0x0001",
            "0x0006"
          ],
          "out_clusters": []
        }
      }
    },
    "entities": [
      {
        "entity_id": "sensor.hall_switch_power",
        "name": "_TZ3000_x7mej5oc TS0041"
      },
      {
        "entity_id": "switch.hall_switch_on_off",
        "name": "_TZ3000_x7mej5oc TS0041"
      },
      {
        "entity_id": "switch.hall_switch_on_off_2",
        "name": "_TZ3000_x7mej5oc TS0041"
      },
      {
        "entity_id": "switch.hall_switch_on_off_3",
        "name": "_TZ3000_x7mej5oc TS0041"
      },
      {
        "entity_id": "switch.hall_switch_on_off_4",
        "name": "_TZ3000_x7mej5oc TS0041"
      }
    ],
    "neighbors": [],
    "endpoint_names": [
      {
        "name": "ON_OFF_SWITCH"
      },
      {
        "name": "ON_OFF_SWITCH"
      },
      {
        "name": "ON_OFF_SWITCH"
      },
      {
        "name": "ON_OFF_SWITCH"
      }
    ],
    "user_given_name": "Hall switch",
    "device_reg_id": "74288230d087e0ca4b6cebcf1273e0c8",
    "area_id": "hall"
  }
}

Big thanks to @dmulcahey for guiding me trough and helping out!

Please shout if more info is needed!

OlivierHens avatar May 11 '22 19:05 OlivierHens

So, I scratched something out that may help us in the future: https://github.com/zigpy/zha-device-handlers/blob/9e0fb0e7d0664cc6e097989e1c541196034bd8e3/quirk_generator/locate_matches.py

this will take a diagnostics file from ZHA and attempt to find existing quirks that may match the device. It's still very rough but I did test it with this case.

to solve this... should we import the matching class into ts0041.py and just override MODEL?

dmulcahey avatar May 11 '22 20:05 dmulcahey

If using the quirk for TS0044 for all TS004X devices the events is working OK but you is getting 9 Device Automatons i ZHA GUI that is not working and is false.

Better adding the "new" signature in all quirks and its working OK and looks nice.

Its also possible adding our TS004F in one universal quirk but then you is getting around 20 DA that is not working for most device and looks very bad.

MattWestb avatar May 12 '22 04:05 MattWestb

Maybe we can just add (in the same ts0041.py file):

class TuyaSmartRemote0041TI(TuyaSmartRemote0044TI):
    """Another Tuya 4-button remote device with time on in cluster."""

    signature = TuyaSmartRemote0044TI.signature.copy()
    signature.update(
        {
            MODEL: "TS0041",
        }
    )

All the TS004X quirks in just one file will be a very large file that will get messy soon.

I'm not sure I understand you @MattWestb, but I wouldn't mix the TS004F with other devices (they seem quite different to me)

javicalle avatar May 12 '22 18:05 javicalle

Very likely its coming TS042 and TS0043 device with the same cluster / endpoint config but is having different model info. One new thing its having one "0xe000" cluster but i think the manufacture is using the same PCB for remotes and switches (at least the "old" version was having it) and is planing using the new firmware the same way.

For the TS004F is having the same PCB as the "normal" ts004X device and is having the same commands and 3 EP as the ts0044 only that it is having dimmer functionality in the firmware (with working touch link functionality).

My point was / is keep the quirks and not putting devices in wrong classes then its making all worse. So ts0041 with 4 EP is still one TS0041 and not one TS0044 device.

Add the new signature in one new device class and i think all is working OK

MattWestb avatar May 12 '22 18:05 MattWestb

My point was why copy the entire sig into another class… import it, extend it and override just the difference.

dmulcahey avatar May 12 '22 20:05 dmulcahey

Anybody found a solution for this ? i bought same switch on aliexpress and cant add it as switch . its always end with Fail because endpoint list mismatch: {1} {1, 2, 3, 4}.

Draconuss avatar Jul 27 '22 22:07 Draconuss

yeah any solution, bought this one too but the buttons don't activate anything in the log image

matda59 avatar Sep 01 '22 06:09 matda59

@matda59 Tried this? https://medium.com/@edwarddubilyer/chinese-ts0041-1-bang-zigbee-scene-switch-on-zha-troubleshooting-dd75a90a485f

I don't know whether zigpy can be modified to analyze a device name and number of switches first and then applies the corresponding quirk.

jzielke84 avatar Dec 13 '22 12:12 jzielke84

That could be a possible quirk:

ts0041.py
"""Tuya 1 Button Remote."""

from zigpy.profiles import zha
from zigpy.quirks import CustomDevice
from zigpy.zcl.clusters.general import Basic, OnOff, Ota, PowerConfiguration, Time

from zhaquirks.const import (
    BUTTON_1,
    COMMAND,
    DEVICE_TYPE,
    DOUBLE_PRESS,
    ENDPOINT_ID,
    ENDPOINTS,
    INPUT_CLUSTERS,
    LONG_PRESS,
    MODEL,
    OUTPUT_CLUSTERS,
    PROFILE_ID,
    SHORT_PRESS,
)
from zhaquirks.tuya import TuyaSmartRemoteOnOffCluster, TuyaZBE000Cluster
from zhaquirks.tuya.ts0044 import TuyaSmartRemote0044TOPlusA


class Tuya1ButtonTriggers:
    """Tuya 1-button remote device triggers."""

    device_automation_triggers = {
        (SHORT_PRESS, BUTTON_1): {ENDPOINT_ID: 1, COMMAND: SHORT_PRESS},
        (LONG_PRESS, BUTTON_1): {ENDPOINT_ID: 1, COMMAND: LONG_PRESS},
        (DOUBLE_PRESS, BUTTON_1): {ENDPOINT_ID: 1, COMMAND: DOUBLE_PRESS},
    }


class TuyaSmartRemote0041TO(CustomDevice, Tuya1ButtonTriggers):
    """Tuya 1-button remote device with time on out."""

    signature = {
        # SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=0, device_version=1, input_clusters=[0, 1, 6], output_clusters=[25, 10])
        MODEL: "TS0041",
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    PowerConfiguration.cluster_id,
                    OnOff.cluster_id,
                ],
                OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id],
            },
        },
    }
    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    PowerConfiguration.cluster_id,
                    TuyaSmartRemoteOnOffCluster,
                ],
                OUTPUT_CLUSTERS: [Ota.cluster_id, Time.cluster_id],
            },
        },
    }


class TuyaSmartRemote0041TI(CustomDevice, Tuya1ButtonTriggers):
    """Tuya 1-button remote device with time on in."""

    signature = {
        # SizePrefixedSimpleDescriptor(endpoint=1, profile=260, device_type=0, device_version=1, input_clusters=[0, 10, 1, 6], output_clusters=[25]))
        MODEL: "TS0041",
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    PowerConfiguration.cluster_id,
                    OnOff.cluster_id,
                    Time.cluster_id,
                ],
                OUTPUT_CLUSTERS: [Ota.cluster_id],
            },
        },
    }
    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    PowerConfiguration.cluster_id,
                    TuyaSmartRemoteOnOffCluster,
                    Time.cluster_id,
                ],
                OUTPUT_CLUSTERS: [Ota.cluster_id],
            },
        },
    }


class TuyaSmartRemote0041_Var03(CustomDevice, Tuya1ButtonTriggers):
    """Tuya 1-button remote device (variant 03)."""

    signature = {
        MODEL: "TS0041",
        ENDPOINTS: TuyaSmartRemote0044TOPlusA.signature[ENDPOINTS]
    }
    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.REMOTE_CONTROL,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    PowerConfiguration.cluster_id,
                    TuyaSmartRemoteOnOffCluster,
                    TuyaZBE000Cluster,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
        },
    }

There is a good guide to enable your local quirks folder:

  • https://github.com/zigpy/zha-device-handlers/discussions/693#discussioncomment-857274

Copy in that folder the proposed quirk. Save changes, restart HA and repair the device.

javicalle avatar Dec 13 '22 20:12 javicalle

Any updates on this?

Hedda avatar Apr 18 '23 06:04 Hedda

There hasn't been any activity on this issue recently. Due to the high number of incoming GitHub notifications, we have to clean some of the old issues, as many of them have already been resolved with the latest updates. Please make sure to update to the latest version and check if that solves the issue. Let us know if that works for you by adding a comment 👍 This issue has now been marked as stale and will be closed if no further activity occurs. Thank you for your contributions.

github-actions[bot] avatar Oct 15 '23 07:10 github-actions[bot]