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
752 stars 688 forks source link

_TZE200_3towulqd TS0601 Tuya Motion Sensor with illuminance sensor [BUG] #2097

Closed yanivf38 closed 12 months ago

yanivf38 commented 1 year ago

Describe the bug I've been using the quark that @javicalle suggested for the motion sensor and noticed that it works fine with a problem where if the room is dark the motion sensor occupancy trigger doesn't work. if I add some light to the room the sensor works fine. I than re-sync'd the device with tuya's smart life app and it doesn't seems to have that issue. I confirmed the behavior with several sensors.

Is there something that can be done or is it limitation of the dp instructions?

To Reproduce

  1. Installed ZHA and add the ZHA quirk as suggest here - https://github.com/zigpy/zha-device-handlers/issues/1599#
  2. sync the motion sensor with ZHA
  3. make sure the room is dark
  4. walk around - you'll notice that the sensor get triggered as the red light turns on
  5. observe - no trigger in HA logs for the motion occupancy sensor

Expected behavior To get triggered in all situations. Note: this doesn't happen if the device is using TUYA native integration and the sensor synced with smart-life

TheJulianJES commented 1 year ago

Please also provide the device signature and diagnostic information for the device, so the issue post is complete.

javicalle commented 1 year ago

Can be related to the sensitivity_level? I mean, device can detect the movement but a low sensitivity makes that no event will be trigered.

If not related (in addition to providing the data from the device) activate the debug logs and attach them to the issue.

yanivf38 commented 1 year ago

thank you @javicalle. I'll turn debugging on. Calling device info shows that the sensitivity in both cases is set to high. For now I switched back to using tuya hub.

Kaot93 commented 1 year ago

Probably have the same bug. Haven't tested it very much but I get no clearance in complete darkness either, which is pretty odd I think.

Also my illuminance sensor doesn't deliver anything useful, while I get differing values if I read the cluster itself. Is there something with the conversion?

javicalle commented 1 year ago

Without any debug logs from device with the normal and the rogue behavior anything can't be do?

Kaot93 commented 1 year ago

I think that's the stuff you want to know:


{
  "home_assistant": {
    "installation_type": "Home Assistant OS",
    "version": "2023.2.3",
    "dev": false,
    "hassio": true,
    "virtualenv": false,
    "python_version": "3.10.7",
    "docker": true,
    "arch": "x86_64",
    "timezone": "Europe/Berlin",
    "os_name": "Linux",
    "os_version": "5.15.90",
    "supervisor": "2023.01.1",
    "host_os": "Home Assistant OS 9.5",
    "docker_version": "20.10.22",
    "chassis": "vm",
    "run_as_root": true
  },
  "custom_components": {
    "omada": {
      "version": "0.4.0-beta.1",
      "requirements": []
    },
    "adaptive_lighting": {
      "version": "1.4.1",
      "requirements": []
    },
    "dreame_vacuum": {
      "version": "v0.16.3",
      "requirements": [
        "pillow",
        "numpy",
        "pybase64",
        "requests",
        "pycryptodome",
        "python-miio>=0.5.6",
        "py-mini-racer"
      ]
    },
    "multimatic": {
      "version": "1.14.0b1",
      "requirements": [
        "pymultimatic==0.7.0b2"
      ]
    },
    "tapo": {
      "version": "1.5.1",
      "requirements": [
        "plugp100==2.5.1"
      ]
    },
    "localtuya": {
      "version": "5.0.0",
      "requirements": []
    },
    "dwd_weather": {
      "version": "1.2.24",
      "requirements": [
        "simple_dwd_weatherforecast==1.1.5",
        "markdownify==0.6.5"
      ]
    },
    "zha_toolkit": {
      "version": "v0.8.33",
      "requirements": [
        "packaging>=20.8",
        "pytz"
      ]
    },
    "hacs": {
      "version": "1.30.1",
      "requirements": [
        "aiogithubapi>=22.10.1"
      ]
    },
    "better_thermostat": {
      "version": "1.0.1",
      "requirements": []
    }
  },
  "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": 56167,
    "manufacturer": "_TZE200_3towulqd",
    "model": "TS0601",
    "name": "_TZE200_3towulqd TS0601",
    "quirk_applied": true,
    "quirk_class": "ts0601_pirmotion.PirMotion",
    "manufacturer_code": 4417,
    "power_source": "Battery or Unknown",
    "lqi": 255,
    "rssi": -75,
    "last_seen": "2023-02-10T08:25:39",
    "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": "0x0402",
          "in_clusters": [
            "0x0000",
            "0x0001",
            "0x0400",
            "0x0500",
            "0xef00"
          ],
          "out_clusters": [
            "0x000a",
            "0x0019"
          ]
        }
      }
    },
    "active_coordinator": false,
    "entities": [
      {
        "entity_id": "binary_sensor.badezimmer_bewegung_iaszone_2",
        "name": "_TZE200_3towulqd TS0601"
      },
      {
        "entity_id": "sensor.badezimmer_bewegung_battery_2",
        "name": "_TZE200_3towulqd TS0601"
      },
      {
        "entity_id": "sensor.badezimmer_bewegung_illuminance",
        "name": "_TZE200_3towulqd TS0601"
      }
    ],
    "neighbors": [],
    "routes": [],
    "endpoint_names": [
      {
        "name": "IAS_ZONE"
      }
    ],
    "user_given_name": "Badezimmer Bewegung ",
    "device_reg_id": "bce8f9650f395427382edba8166d8b0c",
    "area_id": "badezimmer",
    "cluster_details": {
      "1": {
        "device_type": {
          "name": "IAS_ZONE",
          "id": 1026
        },
        "profile_id": 260,
        "in_clusters": {
          "0x0000": {
            "endpoint_attribute": "basic",
            "attributes": {
              "0x0004": {
                "attribute_name": "manufacturer",
                "value": "_TZE200_3towulqd"
              },
              "0x0005": {
                "attribute_name": "model",
                "value": "TS0601"
              }
            },
            "unsupported_attributes": {}
          },
          "0x0001": {
            "endpoint_attribute": "power",
            "attributes": {
              "0x0020": {
                "attribute_name": "battery_voltage",
                "value": 0
              },
              "0x0021": {
                "attribute_name": "battery_percentage_remaining",
                "value": 200
              }
            },
            "unsupported_attributes": {
              "0x0031": {
                "attribute_name": "battery_size"
              },
              "0x0033": {
                "attribute_name": "battery_quantity"
              }
            }
          },
          "0xef00": {
            "endpoint_attribute": "tuya_manufacturer",
            "attributes": {
              "0xef09": {
                "attribute_name": "sensitivity_level",
                "value": 2
              },
              "0xef0a": {
                "attribute_name": "keep_time",
                "value": 0
              }
            },
            "unsupported_attributes": {}
          },
          "0x0500": {
            "endpoint_attribute": "ias_zone",
            "attributes": {
              "0x0000": {
                "attribute_name": "zone_state",
                "value": 0
              },
              "0x0001": {
                "attribute_name": "zone_type",
                "value": 13
              },
              "0x0002": {
                "attribute_name": "zone_status",
                "value": 1
              },
              "0x0010": {
                "attribute_name": "cie_addr",
                "value": [
                  119,
                  110,
                  9,
                  255,
                  255,
                  46,
                  33,
                  0
                ]
              }
            },
            "unsupported_attributes": {}
          },
          "0x0400": {
            "endpoint_attribute": "illuminance",
            "attributes": {
              "0x0000": {
                "attribute_name": "measured_value",
                "value": 2953.3763366673043
              }
            },
            "unsupported_attributes": {
              "0x0002": {
                "attribute_name": "max_measured_value"
              }
            }
          }
        },
        "out_clusters": {
          "0x000a": {
            "endpoint_attribute": "time",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x0019": {
            "endpoint_attribute": "ota",
            "attributes": {},
            "unsupported_attributes": {}
          }
        }
      }
    }
  }
}
``|
MattWestb commented 1 year ago

The devs need debug logs from ZHA then paring and also then sending commands to and from the device. One guide for setting the debug longing is here https://github.com/zigpy/zha-device-handlers/discussions/693#discussioncomment-4559550

Kaot93 commented 1 year ago

I attached the Logfile here:

Did my best filtering out the relevant time window. HA.log

jure123 commented 1 year ago

I think I found a fix for this:

In ts0601_pirmotion.py quirk, find this line: converter=lambda x: 10000 * math.log10(x) + 1

and modify it to: converter=lambda x: 10000 * math.log10(x) + 1 if x != 0 else 0

The quirk failed in full darkness when illumination was 0, because math.log10(0) threw "ValueError: math domain error", so the quirk failed to update the senzor status in ZHA.

The whole fixed quirk file:

ts0601_pirmotion.py ``` """BlitzWolf IS-3/Tuya motion rechargeable occupancy sensor.""" import math from typing import Dict from zigpy.profiles import zha from zigpy.quirks import CustomDevice import zigpy.types as t from zigpy.zcl.clusters.general import Basic, Ota, Time from zigpy.zcl.clusters.measurement import IlluminanceMeasurement, OccupancySensing from zigpy.zcl.clusters.security import IasZone from zhaquirks.const import ( DEVICE_TYPE, ENDPOINTS, INPUT_CLUSTERS, MODELS_INFO, OUTPUT_CLUSTERS, PROFILE_ID, ) from zhaquirks.tuya import TuyaLocalCluster from zhaquirks.tuya.mcu import ( DPToAttributeMapping, TuyaDPType, TuyaMCUCluster, TuyaPowerConfigurationCluster, ) class TuyaOccupancySensing(OccupancySensing, TuyaLocalCluster): """Tuya local OccupancySensing cluster.""" class TuyaIlluminanceMeasurement(IlluminanceMeasurement, TuyaLocalCluster): """Tuya local IlluminanceMeasurement cluster.""" class SensitivityLevel(t.enum8): """Sensitivity level enum.""" LOW = 0x00 MEDIUM = 0x01 HIGH = 0x02 class OnTimeValues(t.enum8): """Sensitivity level enum.""" _10_SEC = 0x00 _30_SEC = 0x01 _60_SEC = 0x02 _120_SEC = 0x03 class PirMotionManufCluster(TuyaMCUCluster): """Neo manufacturer cluster.""" attributes = TuyaMCUCluster.attributes.copy() attributes.update({0xEF09: ("sensitivity_level", SensitivityLevel)}) attributes.update({0xEF0A: ("keep_time", OnTimeValues)}) dp_to_attribute: Dict[int, DPToAttributeMapping] = { 1: DPToAttributeMapping( TuyaOccupancySensing.ep_attribute, "occupancy", dp_type=TuyaDPType.BOOL, converter=lambda x: IasZone.ZoneStatus.Alarm_1 if not x else 0, ), 4: DPToAttributeMapping( TuyaPowerConfigurationCluster.ep_attribute, "battery_percentage_remaining", dp_type=TuyaDPType.VALUE, ), 9: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "sensitivity_level", dp_type=TuyaDPType.ENUM, converter=lambda x: SensitivityLevel(x), ), 10: DPToAttributeMapping( TuyaMCUCluster.ep_attribute, "keep_time", dp_type=TuyaDPType.ENUM, converter=lambda x: OnTimeValues(x), ), 12: DPToAttributeMapping( TuyaIlluminanceMeasurement.ep_attribute, "measured_value", dp_type=TuyaDPType.VALUE, converter=lambda x: 10000 * math.log10(x) + 1 if x != 0 else 0, ), } data_point_handlers = { 1: "_dp_2_attr_update", 4: "_dp_2_attr_update", 9: "_dp_2_attr_update", 10: "_dp_2_attr_update", 12: "_dp_2_attr_update", } class PirMotion(CustomDevice): """Tuya PIR motion sensor.""" signature = { MODELS_INFO: [("_TZE200_3towulqd", "TS0601")], ENDPOINTS: { # endpoints=1 profile=260 device_type=0x0402 # in_clusters=[0x0000, 0x0001, 0x0500], # out_clusters=[0x000a, 0x0019] 1: { PROFILE_ID: zha.PROFILE_ID, DEVICE_TYPE: zha.DeviceType.IAS_ZONE, INPUT_CLUSTERS: [ Basic.cluster_id, TuyaPowerConfigurationCluster.cluster_id, IasZone.cluster_id, ], OUTPUT_CLUSTERS: [ Time.cluster_id, Ota.cluster_id, ], } }, } replacement = { ENDPOINTS: { 1: { PROFILE_ID: zha.PROFILE_ID, DEVICE_TYPE: zha.DeviceType.IAS_ZONE, INPUT_CLUSTERS: [ Basic.cluster_id, TuyaPowerConfigurationCluster, PirMotionManufCluster, TuyaOccupancySensing, TuyaIlluminanceMeasurement, ], OUTPUT_CLUSTERS: [ Time.cluster_id, Ota.cluster_id, ], } } } ```

@javicalle, would you be so kind and apply this fix to your original ts0601_pirmotion.py quirk you posted here: https://github.com/zigpy/zha-device-handlers/issues/1599#issuecomment-1146852599 ? Actually this log(x) fix has been mentioned in some later comments in that post but many users haven't noticed it. Also your original quirk reports inverted occupancy status (occupied / cleared are inverted). My file above also fixes this (using: converter=lambda x: IasZone.ZoneStatus.Alarm_1 if not x else 0,). It would be very helpful to update your original quirk because most users install that version and probably many have hard time experiencing those issues. Thanks!

Kaot93 commented 1 year ago

That makes sense. I will try your fix

My illuminance sensor also only gives values of 1 or 2 while the "measured value" cluster readout give values up to 3000. Is there maybe something wrong with the conversion for my sensor?

Edit: A first short test before bed shows, that you might have solved the issue started in the opening post as well as the wrong values of the illuminance sensor. So both working for me now (laszone sensor update while dark as well as good value for illuminance).

Thank you!

kruebsam commented 1 year ago

As of what I did find out, the structure/content of those "zhaquirks.tuya.mcu" and "zhaquirks.tuya" did change with the latest update as of March 23 resulting in the below errors. I tried to fix it, but couldn´t find out how. Any ideas?

Logger: homeassistant.config_entries
Source: custom_zha_quirks/ts0601_pirmotion.py:22
First occurred: 21:47:39 (1 occurrences)
Last logged: 21:47:39

Error setting up entry socket://192.168.2.9:8888 for zha
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/config_entries.py", line 383, in async_setup
    result = await component.async_setup_entry(hass, self)
  File "/usr/src/homeassistant/homeassistant/components/zha/__init__.py", line 110, in async_setup_entry
    setup_quirks(config)
  File "/usr/local/lib/python3.10/site-packages/zhaquirks/__init__.py", line 409, in setup
    importer.find_module(modname).load_module(modname)
  File "<frozen importlib._bootstrap_external>", line 548, in _check_name_wrapper
  File "<frozen importlib._bootstrap_external>", line 1063, in load_module
  File "<frozen importlib._bootstrap_external>", line 888, in load_module
  File "<frozen importlib._bootstrap>", line 290, in _load_module_shim
  File "<frozen importlib._bootstrap>", line 719, in _load
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/config/custom_zha_quirks/ts0601_pirmotion.py", line 22, in <module>
    from zhaquirks.tuya.mcu import (
ImportError: cannot import name 'TuyaDPType' from 'zhaquirks.tuya.mcu' (/usr/local/lib/python3.10/site-packages/zhaquirks/tuya/mcu/__init__.py)
javicalle commented 1 year ago

Check here: https://github.com/zigpy/zha-device-handlers/issues/2250#issuecomment-1453978417

matteozamu commented 1 year ago

Does anyone have the opposite status on the motion sensor? I mean, I always have motion detect when there is no movement whereas I get no "cleared (no detected)" when there is movement around.

ethzero commented 1 year ago

Does anyone have the opposite status on the motion sensor? I mean, I always have motion detect when there is no movement whereas I get no "cleared (no detected)" when there is movement around.

Absolutely! I had a "TS0202 by_TZ3000_6ygjfyll", a simple PIR-only sensor working completely fine for weeks. I then:

I've now subsequently disabled the ts0601_pirmotion.py quirk (by simply renaming it ts0601_pirmotion.py.DISABLED and removing it's __pycache__ file twin) and restarting HA. This has effectively rolled-back the TS0202 to it's previous working state and obviously my trio of TS0601s no longer work, again.

Happy to provide any further debugging info if directed to where this can be found in HA.

matteozamu commented 1 year ago

Hi everyone, any updates about this issue? Is there any information I can provide to help?

github-actions[bot] commented 1 year 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.