zigpy / zha-device-handlers

ZHA device handlers bridge the functionality gap created when manufacturers deviate from the ZCL specification, handling deviations and exceptions by parsing custom messages to and from Zigbee devices.
Apache License 2.0
750 stars 686 forks source link

[BUG] Quirk Issue / Question #2648

Closed ThiSaadeh closed 5 months ago

ThiSaadeh commented 1 year ago

Bug description

I've recently bought a smart plug from Tuya which is labeled as: "_TZ3000_lotmgthb TS011F", it loads the standard "zhaquirks.tuya.ts011f_plug.Plug", I've noticed that the ENDPOINT and INPUT_CLUSTERS are pretty similar, except that the one in the quirk includes an INPUT as [9] but reading the remainder of the quirks within the same file I couldn't figure out what it stands for, I can write and load custom quirks, but writing my own custom quirk by using others as an example I land at the standard quirk mentioned above.

The issue is, the pug itself only switches on/off but everything else from turning off the led, child lock, etc doesn't work at all.

P.s.: I re-wrote the quirk using the skeleton of a different one that works at home, but honestly it looks exactly the same as the quirk it's already loading on it.

Steps to reproduce

Adding the plug and going through the device settings page trying to change params on it doesnt work, but it doesnt throw errors on the log, it just doesnt affect the unit.

Expected behavior

Led turn-off/turn-on, last state setup or child lock doesn't work on it.

Screenshots/Video

Screenshots/Video [Paste/upload your media here]

Device signature

Device signature ```json "signature": { "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)", "endpoints": { "1": { "profile_id": "0x0104", "device_type": "0x010a", "input_clusters": [ "0x0000", "0x0003", "0x0004", "0x0005", "0x0006", "0x0702", "0x0b04", "0xe000", "0xe001" ], "output_clusters": [ "0x000a", "0x0019" ] } }, "manufacturer": "_TZ3000_lotmgthb", "model": "TS011F" }, ```

Diagnostic information

Diagnostic information ```json { "home_assistant": { "installation_type": "Home Assistant OS", "version": "2023.10.3", "dev": false, "hassio": true, "virtualenv": false, "python_version": "3.11.5", "docker": true, "arch": "aarch64", "timezone": "America/Sao_Paulo", "os_name": "Linux", "os_version": "6.1.21-v8", "supervisor": "2023.10.0", "host_os": "Home Assistant OS 11.0", "docker_version": "24.0.6", "chassis": "embedded", "run_as_root": true }, "custom_components": { "sonoff": { "version": "3.5.2", "requirements": [ "pycryptodome>=3.6.6" ] }, "watchman": { "version": "0.5.1", "requirements": [ "prettytable==3.0.0" ] }, "hacs": { "version": "1.33.0", "requirements": [ "aiogithubapi>=22.10.1" ] } }, "integration_manifest": { "domain": "zha", "name": "Zigbee Home Automation", "after_dependencies": [ "onboarding", "usb" ], "codeowners": [ "@dmulcahey", "@adminiuga", "@puddly" ], "config_flow": true, "dependencies": [ "file_upload" ], "documentation": "https://www.home-assistant.io/integrations/zha", "iot_class": "local_polling", "loggers": [ "aiosqlite", "bellows", "crccheck", "pure_pcapy3", "zhaquirks", "zigpy", "zigpy_deconz", "zigpy_xbee", "zigpy_zigate", "zigpy_znp", "universal_silabs_flasher" ], "requirements": [ "bellows==0.36.5", "pyserial==3.5", "pyserial-asyncio==0.6", "zha-quirks==0.0.104", "zigpy-deconz==0.21.1", "zigpy==0.57.2", "zigpy-xbee==0.18.3", "zigpy-zigate==0.11.0", "zigpy-znp==0.11.5", "universal-silabs-flasher==0.0.14", "pyserial-asyncio-fast==0.11" ], "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" ] } ], "zeroconf": [ { "type": "_esphomelib._tcp.local.", "name": "tube*" }, { "type": "_zigate-zigbee-gateway._tcp.local.", "name": "*zigate*" }, { "type": "_zigstar_gw._tcp.local.", "name": "*zigstar*" }, { "type": "_uzg-01._tcp.local.", "name": "uzg-01*" }, { "type": "_slzb-06._tcp.local.", "name": "slzb-06*" } ], "is_built_in": true }, "data": { "ieee": "**REDACTED**", "nwk": 58737, "manufacturer": "_TZ3000_lotmgthb", "model": "TS011F", "name": "_TZ3000_lotmgthb TS011F", "quirk_applied": true, "quirk_class": "zhaquirks.tuya.ts011f_plug.Plug", "manufacturer_code": 4417, "power_source": "Mains", "lqi": 144, "rssi": -64, "last_seen": "2023-10-14T19:23:55", "available": true, "device_type": "Router", "signature": { "node_descriptor": "NodeDescriptor(logical_type=, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=, mac_capability_flags=, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)", "endpoints": { "1": { "profile_id": "0x0104", "device_type": "0x010a", "input_clusters": [ "0x0000", "0x0003", "0x0004", "0x0005", "0x0006", "0x0702", "0x0b04", "0xe000", "0xe001" ], "output_clusters": [ "0x000a", "0x0019" ] } }, "manufacturer": "_TZ3000_lotmgthb", "model": "TS011F" }, "active_coordinator": false, "entities": [ { "entity_id": "button.tomada_hall_entrada_identify", "name": "_TZ3000_lotmgthb TS011F" }, { "entity_id": "select.tomada_hall_entrada_power_on_state", "name": "_TZ3000_lotmgthb TS011F" }, { "entity_id": "select.tomada_hall_entrada_backlight_mode", "name": "_TZ3000_lotmgthb TS011F" }, { "entity_id": "sensor.tomada_hall_entrada_rms_current", "name": "_TZ3000_lotmgthb TS011F" }, { "entity_id": "sensor.tomada_hall_entrada_rms_voltage", "name": "_TZ3000_lotmgthb TS011F" }, { "entity_id": "sensor.tomada_hall_entrada_power_factor", "name": "_TZ3000_lotmgthb TS011F" }, { "entity_id": "sensor.tomada_hall_entrada_active_power", "name": "_TZ3000_lotmgthb TS011F" }, { "entity_id": "sensor.tomada_hall_entrada_summation_delivered", "name": "_TZ3000_lotmgthb TS011F" }, { "entity_id": "switch.tomada_hall_entrada_switch", "name": "_TZ3000_lotmgthb TS011F" }, { "entity_id": "switch.tomada_hall_entrada_child_lock", "name": "_TZ3000_lotmgthb TS011F" } ], "neighbors": [], "routes": [], "endpoint_names": [ { "name": "ON_OFF_PLUG_IN_UNIT" } ], "user_given_name": "Tomada Hall Entrada", "device_reg_id": "44660936b737cd5b8edf9b32d4346904", "area_id": "cozinha", "cluster_details": { "1": { "device_type": { "name": "ON_OFF_PLUG_IN_UNIT", "id": 266 }, "profile_id": 260, "in_clusters": { "0x0000": { "endpoint_attribute": "basic", "attributes": { "0x0001": { "attribute_name": "app_version", "value": 192 }, "0x0004": { "attribute_name": "manufacturer", "value": "_TZ3000_lotmgthb" }, "0x0005": { "attribute_name": "model", "value": "TS011F" }, "0x0007": { "attribute_name": "power_source", "value": 1 }, "0xfffe": { "attribute_name": "reporting_status", "value": 0 }, "0x0000": { "attribute_name": "zcl_version", "value": 3 } }, "unsupported_attributes": {} }, "0x0003": { "endpoint_attribute": "identify", "attributes": {}, "unsupported_attributes": {} }, "0x0004": { "endpoint_attribute": "groups", "attributes": {}, "unsupported_attributes": {} }, "0x0005": { "endpoint_attribute": "scenes", "attributes": {}, "unsupported_attributes": {} }, "0x0006": { "endpoint_attribute": "on_off", "attributes": { "0x8001": { "attribute_name": "backlight_mode", "value": 0 }, "0x8000": { "attribute_name": "child_lock", "value": 1 }, "0x4002": { "attribute_name": "off_wait_time", "value": 0 }, "0x0000": { "attribute_name": "on_off", "value": 1 }, "0x4001": { "attribute_name": "on_time", "value": 0 }, "0x8002": { "attribute_name": "power_on_state", "value": 2 } }, "unsupported_attributes": { "0x4003": { "attribute_name": "start_up_on_off" } } }, "0x0702": { "endpoint_attribute": "smartenergy_metering", "attributes": { "0x0000": { "attribute_name": "current_summ_delivered", "value": 71 }, "0x0302": { "attribute_name": "divisor", "value": 100 }, "0x0306": { "attribute_name": "metering_device_type", "value": 0 }, "0x0301": { "attribute_name": "multiplier", "value": 1 }, "0x0200": { "attribute_name": "status", "value": 0 }, "0x0303": { "attribute_name": "summation_formatting", "value": 0 }, "0x0300": { "attribute_name": "unit_of_measure", "value": 0 } }, "unsupported_attributes": { "0x0400": { "attribute_name": "instantaneous_demand" }, "0x0100": { "attribute_name": "current_tier1_summ_delivered" }, "0x0102": { "attribute_name": "current_tier2_summ_delivered" }, "0x0304": { "attribute_name": "demand_formatting" }, "0x0104": { "attribute_name": "current_tier3_summ_delivered" }, "0x0106": { "attribute_name": "current_tier4_summ_delivered" }, "0x0108": { "attribute_name": "current_tier5_summ_delivered" }, "0x010a": { "attribute_name": "current_tier6_summ_delivered" } } }, "0x0b04": { "endpoint_attribute": "electrical_measurement", "attributes": { "0x0603": { "attribute_name": "ac_current_divisor", "value": 1000 }, "0x0602": { "attribute_name": "ac_current_multiplier", "value": 1 }, "0x050b": { "attribute_name": "active_power", "value": 0 }, "0x0508": { "attribute_name": "rms_current", "value": 0 }, "0x0505": { "attribute_name": "rms_voltage", "value": 125 } }, "unsupported_attributes": { "0x0300": { "attribute_name": "ac_frequency" }, "0x0601": { "attribute_name": "ac_voltage_divisor" }, "0x0302": { "attribute_name": "ac_frequency_max" }, "0x0600": { "attribute_name": "ac_voltage_multiplier" }, "0x0604": { "attribute_name": "ac_power_multiplier" }, "0x050d": { "attribute_name": "active_power_max" }, "0x0605": { "attribute_name": "ac_power_divisor" }, "0x0507": { "attribute_name": "rms_voltage_max" }, "0x0401": { "attribute_name": "ac_frequency_divisor" }, "0x050a": { "attribute_name": "rms_current_max" }, "0x0000": { "attribute_name": "measurement_type" }, "0x0403": { "attribute_name": "power_divisor" }, "0x050f": { "attribute_name": "apparent_power" }, "0x0402": { "attribute_name": "power_multiplier" }, "0x0400": { "attribute_name": "ac_frequency_multiplier" } } }, "0xe000": { "endpoint_attribute": "tuya_manufacturer_specific_57344", "attributes": {}, "unsupported_attributes": {} }, "0xe001": { "endpoint_attribute": "tuya_external_switch_type", "attributes": { "0xd030": { "attribute_name": "external_switch_type", "value": 0 } }, "unsupported_attributes": {} } }, "out_clusters": { "0x000a": { "endpoint_attribute": "time", "attributes": {}, "unsupported_attributes": {} }, "0x0019": { "endpoint_attribute": "ota", "attributes": {}, "unsupported_attributes": {} } } } } } } ```

Logs

Logs ```python [Paste the logs here] ```

Additional information

This is exactly what I had written:

class Plug_v2_Mod(CustomDevice):
    """Another TS011F Tuya plug. First one using this definition is _TZ3000_lotmgthb."""

    signature = {
        MODELS_INFO: [("_TZ3000_lotmgthb", "TS011F")],
        ENDPOINTS: {
            # "profile_id": 260,
            # "device_type": "0x010a",
            # "in_clusters": ["0x0000", "0x0003", "0x0004", "0x0005", "0x0006", "0x0702", "0x0b04", "0xe000", "0xe001"],
            # "out_clusters": ["0x000a", "0x0019"]
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_PLUG_IN_UNIT,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Identify.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    OnOff.cluster_id,
                    Metering.cluster_id,
                    ElectricalMeasurement.cluster_id,
                    TuyaZBE000Cluster.cluster_id,
                    TuyaZBExternalSwitchTypeCluster.cluster_id,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
        },
    }
    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_PLUG_IN_UNIT,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Identify.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaZBOnOffAttributeCluster,
                    TuyaZBMeteringCluster,
                    TuyaZBElectricalMeasurement,
                    TuyaZBE000Cluster,
                    TuyaZBExternalSwitchTypeCluster,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
        },
    }
TheJulianJES commented 1 year ago

Change CustomDevice to EnchantedDevice (might need to import that). Then, restart HA with the new custom quirk and reconfigure the plug using the UI (or re-pair it). Then, check if it works. Otherwise, I think your plug doesn't support those attributes for some reason.

ThiSaadeh commented 1 year ago

Out of curiosity, what's the difference between Custom and Enchanted?

I just did what you recommended, I can see the quirk loaded into the system on the log:

Logger: zhaquirks Source: components/zha/init.py:122 First occurred: 20:35:32 (1 occurrences) Last logged: 20:35:32

Loaded custom quirks. Please contribute them to https://github.com/zigpy/zha-device-handlers

But removing/adding the plug still defaults to the standard Plug implementation, so looking at the re-added plug lists:

Quirk: zhaquirks.tuya.ts011f_plug.Plug

Instead of the one I wrote-up. Did I miss anything? Thanks!

ThiSaadeh commented 1 year ago

It was missing Endpoint 242, I got it re-added using the custom quirk, but still couldnt get it to work with the Led Status / Last State / Child lock.

TheJulianJES commented 11 months ago

Custom and Enchanted?

Enchanted "casts a Tuya spell" when reconfiguring clusters (so during pairing) that Tuya devices need in order to work properly. (They try to detect if they're connected to a Tuya hub)

But removing/adding the plug still defaults to the standard Plug implementation

Well, then you don't need a custom quirk, because an existing one already matches. If child lock and so on don't work, then it's possible that the plug just doesn't support them in the first place.

How are you trying to configure those options? Using the clusters menu (Manage Zigbee device)? If so, make sure to only change the upper text field. Always leave the lower text field completely empty. Can you read the attributes on the Tuya OnOff clusters using the clusters UI?

github-actions[bot] commented 5 months ago

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.