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
682 stars 633 forks source link

[BUG] cover _TZ3210_dwytrmda lift percentage is not updated #2676

Open tsensei781 opened 8 months ago

tsensei781 commented 8 months ago

Bug description

with the device identified as below: "manufacturer": "_TZ3210_dwytrmda", "model": "TS130F", "class": "zhaquirks.tuya.ts130f.TuyaTS130FTOGP"

It seems that the current_position_lift_percentage (id 0x0008) is not updated correctly leading to an unexpected behavior within HA. In my situation this variable is always set to 100 whatever the position of the cover is.

Steps to reproduce

  1. When the cover is open, request in HA to close the cover
  2. The covers closed, immediately after HA is showing the correct position and associated commands.
  3. Some times after (or if we read the current_position_lift_percentage value), HA is showing the cover as open
  4. Up command is not accessible, activating the down command forces a refresh and HA shows the cover as closed

Expected behavior

In the step 3 above, we should expect to always read the same position within HA.

Screenshots/Video

Screenshots/Video [Paste/upload your media here]

Device signature

Device signature ```json { "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": "0x0202", "input_clusters": [ "0x0000", "0x0004", "0x0005", "0x0102" ], "output_clusters": [ "0x000a", "0x0019" ] }, "242": { "profile_id": "0xa1e0", "device_type": "0x0061", "input_clusters": [], "output_clusters": [ "0x0021" ] } }, "manufacturer": "_TZ3210_dwytrmda", "model": "TS130F", "class": "zhaquirks.tuya.ts130f.TuyaTS130FTOGP" } ```

Diagnostic information

Diagnostic information ```json { "home_assistant": { "installation_type": "Home Assistant Container", "version": "2023.8.4", "dev": false, "hassio": false, "virtualenv": false, "python_version": "3.11.4", "docker": true, "arch": "x86_64", "timezone": "Europe/Paris", "os_name": "Linux", "os_version": "6.2.0-35-generic", "run_as_root": true }, "custom_components": { "pfsense": { "version": "0.1.0", "requirements": [ "mac-vendor-lookup>=0.1.11" ] }, "nest_protect": { "version": "0.4.0b1", "requirements": [] }, "cover_time_based_synced": { "version": "2.0.0", "requirements": [] }, "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" ], "requirements": [ "bellows==0.35.9", "pyserial==3.5", "pyserial-asyncio==0.6", "zha-quirks==0.0.102", "zigpy-deconz==0.21.0", "zigpy==0.56.4", "zigpy-xbee==0.18.1", "zigpy-zigate==0.11.0", "zigpy-znp==0.11.4" ], "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": "_slzb-06._tcp.local.", "name": "slzb-06*" } ], "is_built_in": true }, "data": { "ieee": "**REDACTED**", "nwk": 26601, "manufacturer": "_TZ3210_dwytrmda", "model": "TS130F", "name": "_TZ3210_dwytrmda TS130F", "quirk_applied": true, "quirk_class": "zhaquirks.tuya.ts130f.TuyaTS130FTOGP", "manufacturer_code": 4417, "power_source": "Mains", "lqi": 33, "rssi": null, "last_seen": "2023-10-22T11:29:41", "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": "0x0202", "input_clusters": [ "0x0000", "0x0004", "0x0005", "0x0102" ], "output_clusters": [ "0x000a", "0x0019" ] }, "242": { "profile_id": "0xa1e0", "device_type": "0x0061", "input_clusters": [], "output_clusters": [ "0x0021" ] } }, "manufacturer": "_TZ3210_dwytrmda", "model": "TS130F" }, "active_coordinator": false, "entities": [ { "entity_id": "cover.tz3210_dwytrmda_ts130f_cover", "name": "_TZ3210_dwytrmda TS130F" } ], "neighbors": [ { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0x3B8F", "permit_joining": "Unknown", "depth": "1", "lqi": "45" }, { "device_type": "Router", "rx_on_when_idle": "On", "relationship": "Sibling", "extended_pan_id": "**REDACTED**", "ieee": "**REDACTED**", "nwk": "0x3D88", "permit_joining": "Unknown", "depth": "1", "lqi": "78" } ], "routes": [], "endpoint_names": [ { "name": "WINDOW_COVERING_DEVICE" }, { "name": "PROXY_BASIC" } ], "user_given_name": null, "device_reg_id": "c9b9f3ce85e85bf5b029ea1901596d8b", "area_id": "cuisine", "cluster_details": { "1": { "device_type": { "name": "WINDOW_COVERING_DEVICE", "id": 514 }, "profile_id": 260, "in_clusters": { "0x0000": { "endpoint_attribute": "basic", "attributes": { "0x0003": { "attribute_name": "hw_version", "value": 1 }, "0x0004": { "attribute_name": "manufacturer", "value": "_TZ3210_dwytrmda" }, "0x0005": { "attribute_name": "model", "value": "TS130F" }, "0x0007": { "attribute_name": "power_source", "value": 1 }, "0xfffe": { "attribute_name": "reporting_status", "value": 0 } }, "unsupported_attributes": { "0x0013": { "attribute_name": "alarm_mask" }, "0x4000": { "attribute_name": "sw_build_id" } } }, "0x0004": { "endpoint_attribute": "groups", "attributes": {}, "unsupported_attributes": {} }, "0x0005": { "endpoint_attribute": "scenes", "attributes": {}, "unsupported_attributes": {} }, "0x0102": { "endpoint_attribute": "window_covering", "attributes": { "0xf001": { "attribute_name": "calibration", "value": 0 }, "0xf003": { "attribute_name": "calibration_time", "value": 172 }, "0x0008": { "attribute_name": "current_position_lift_percentage", "value": 0 }, "0x8000": { "attribute_name": "motor_mode", "value": 0 }, "0xf002": { "attribute_name": "motor_reversal", "value": 0 }, "0xf000": { "attribute_name": "tuya_moving_state", "value": 1 } }, "unsupported_attributes": { "0x0000": { "attribute_name": "window_covering_type" }, "0x0003": { "attribute_name": "current_position_lift" }, "0x0004": { "attribute_name": "current_position_tilt" }, "0x0007": { "attribute_name": "config_status" }, "0x0009": { "attribute_name": "current_position_tilt_percentage" }, "0x0010": { "attribute_name": "installed_open_limit_lift" }, "0x0011": { "attribute_name": "installed_closed_limit_lift" }, "0x0013": { "attribute_name": "installed_closed_limit_tilt" }, "0x0017": { "attribute_name": "window_covering_mode" }, "0x0015": { "attribute_name": "acceleration_time_lift" }, "0x0016": { "attribute_name": "deceleration_time_lift" }, "0x0014": { "attribute_name": "velocity_lift" }, "0x0019": { "attribute_name": "intermediate_setpoints_tilt" } } } }, "out_clusters": { "0x000a": { "endpoint_attribute": "time", "attributes": {}, "unsupported_attributes": {} }, "0x0019": { "endpoint_attribute": "ota", "attributes": { "0x0002": { "attribute_name": "current_file_version", "value": 66 }, "0x0003": { "attribute_name": "current_zigbee_stack_version", "value": 2 }, "0x0004": { "attribute_name": "downloaded_file_version", "value": 4294967295 }, "0x0006": { "attribute_name": "image_upgrade_status", "value": 0 } }, "unsupported_attributes": { "0xfffe": { "attribute_name": "reporting_status" } } } } }, "242": { "device_type": { "name": "PROXY_BASIC", "id": 97 }, "profile_id": 41440, "in_clusters": {}, "out_clusters": { "0x0021": { "endpoint_attribute": "green_power", "attributes": {}, "unsupported_attributes": {} } } } } } } ```

Logs

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

Additional information

No response

ssorgatem commented 4 months ago

Same issue here withHA 2024.2 and the following signature (different manufacturer):

{
  "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.FullFunctionDevice|MainsPowered|RxOnWhenIdle|AllocateAddress: 142>, 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=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": "0x0202",
      "input_clusters": [
        "0x0000",
        "0x0004",
        "0x0005",
        "0x0102"
      ],
      "output_clusters": [
        "0x000a",
        "0x0019"
      ]
    },
    "242": {
      "profile_id": "0xa1e0",
      "device_type": "0x0061",
      "input_clusters": [],
      "output_clusters": [
        "0x0021"
      ]
    }
  },
  "manufacturer": "_TZ3210_ol1uhvza",
  "model": "TS130F",
  "class": "zhaquirks.tuya.ts130f.TuyaTS130FTOGP"
}
the-dreamer commented 4 months ago

Same here :-)

{
  "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.FullFunctionDevice|MainsPowered|RxOnWhenIdle|AllocateAddress: 142>, 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=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": "0x0202",
      "input_clusters": [
        "0x0000",
        "0x0004",
        "0x0005",
        "0x0102"
      ],
      "output_clusters": [
        "0x000a",
        "0x0019"
      ]
    },
    "242": {
      "profile_id": "0xa1e0",
      "device_type": "0x0061",
      "input_clusters": [],
      "output_clusters": [
        "0x0021"
      ]
    }
  },
  "manufacturer": "_TZ3210_dwytrmda",
  "model": "TS130F",
  "class": "zhaquirks.tuya.ts130f.TuyaTS130FTOGP"
}

Any workaround known?

2024.2.1

the-dreamer commented 4 months ago

I need to correct me: first power on of Device No. 1 paring starts instantly and i did pair the device in HA. device No. 2 did not want to pair and i need to start paring. After Pairing the state, percentage etc. was working.

I did a force pair with device No. 1 and now also this device is showing the state and is working as expected.

ssorgatem commented 4 months ago

I need to correct me: first power on of Device No. 1 paring starts instantly and i did pair the device in HA. device No. 2 did not want to pair and i need to start paring. After Pairing the state, percentage etc. was working.

I did a force pair with device No. 1 and now also this device is showing the state and is working as expected.

what do you mean with "force pair"? Making it enter pair mode manually?

the-dreamer commented 4 months ago

yes

the-dreamer commented 4 months ago

Some update:

after some minutes, HA is loosing the values:

grafik

tsensei781 commented 4 months ago

The only workaround I found was to use several automation scripts to force the position attribute for a given range. But that's not very straightforward and needs to be re-done for every cover ...

the-dreamer commented 4 months ago

This is also something i am considering now. The value which can be read is 0. HA is getting the position from the device when changed and after some time HA seems to read out the device again and get the 0. So for my understanding the value needs to be write back to device or even don't update from device. which could be the better solution.

tsensei781 commented 4 months ago

you are right, there is the need to write the value back on the device through "Set zigbee cluster attribute"

the-dreamer commented 4 months ago

is this possible through yaml change for that device type? any hint?

MichalLytek commented 2 months ago

I have a similar issue. The status always go back to "open" after a few minutes:

image

So at 21:24 I did full close action, after a few minutes it goes back to open. So I can't open the cover in the morning because it's already open.

When I press the button to do full down close, I then still get report "open":

image

I can use the physical switches without any issues. The cover opens or close no matter the status. It only affects HA.

My workaround is to call "close" for 0.5s before "open" in my automations. However it's not so simple with the HA buttons in dashboard.

the-dreamer commented 2 months ago

As mentioned above an automation is solving the issue. The value is write back to the device. This is necessary for all devices. this is working for a while now.

alorle commented 2 weeks ago

Samehere in v2024.6.2 with the same device as @ssorgatem: _TZ3210_ol1uhvza

Same issue here withHA 2024.2 and the following signature (different manufacturer):

{
  "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.FullFunctionDevice|MainsPowered|RxOnWhenIdle|AllocateAddress: 142>, 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=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": "0x0202",
      "input_clusters": [
        "0x0000",
        "0x0004",
        "0x0005",
        "0x0102"
      ],
      "output_clusters": [
        "0x000a",
        "0x0019"
      ]
    },
    "242": {
      "profile_id": "0xa1e0",
      "device_type": "0x0061",
      "input_clusters": [],
      "output_clusters": [
        "0x0021"
      ]
    }
  },
  "manufacturer": "_TZ3210_ol1uhvza",
  "model": "TS130F",
  "class": "zhaquirks.tuya.ts130f.TuyaTS130FTOGP"
}

Something curious happens to me: I have 4 identical devices, bought on the same date and with the same firmware version. Two of them behave well and the others do not.

I don't understand it, honestly. I don't know where I have read that it could be related to the fact that some are connected directly to the Zigbee coordinator and others through a router, but I don't know how to check it.

My solution was to implement the following automation for each malfunctioning cover:

alias: Persiana cuarto (corregir posición)
description: ""
trigger:
  - platform: state
    entity_id:
      - cover.persiana_cuarto
condition: []
action:
  - variables:
      position: "{{ state_attr('cover.persiana_cuarto', 'current_position') }}"
  - delay:
      seconds: 5
  - repeat:
      while:
        - condition: template
          value_template: >-
            {{ state_attr('cover.persiana_cuarto', 'current_position') }} != position
      sequence:
        - variables:
            position: "{{ state_attr('cover.persiana_cuarto', 'current_position') }}"
        - delay:
            seconds: 5
  - service: zha.set_zigbee_cluster_attribute
    data:
      # Get IEEE from the device info page in HA
      ieee: 00:0d:6f:00:05:7d:2d:34

      # TuyaCoveringCluster (Endpoint id: 1, Id: 0x0102, Type: in)
      endpoint_id: 1
      cluster_id: 258
      cluster_type: in

      # current_position_lift_percentage (id: 0x0008)
      attribute: 8

      # set value from variable
      value: "{{ position }}"

      # do not override manufacturer code
      manufacturer: "-1"
mode: restart
tsensei781 commented 2 weeks ago

Thanks alorle for providing your script. much more efficient than mine.