_TZE200_3towulqd TS0601 Tuya Motion Sensor with illuminance sensor

Hello, the device is possible to connect to ZHA integration
but then it is not really recognized
the device is bought from here:
https://de.aliexpress.com/item/1005004294995498.html?spm=a2g0o.productlist.0.0.7cff2ed9XwpAXp&algo_pvid=c25e2c8c-63d9-4cea-bb0c-5f190d010c75&aem_p4p_detail=202206032153431297942660195650067651185&algo_exp_id=c25e2c8c-63d9-4cea-bb0c-5f190d010c75-55&pdp_ext_f={"sku_id"%3A"12000028662981700"}&pdp_npi=2%40dis!EUR!!11.38!!!!!%400b0a01f816543184230937794e1339!12000028662981700!sea

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": "0x0402",
      "in_clusters": [
        "0x0000",
        "0x0001",
        "0x0500"
      ],
      "out_clusters": [
        "0x000a",
        "0x0019"
      ]
    }
  },
  "manufacturer": "_TZE200_3towulqd",
  "model": "TS0601",
  "class": "zigpy.device.Device"
}

Don't remove the extra line breaks outside the ``` marks.

Diagnostic information
{
  "home_assistant": {
    "installation_type": "Home Assistant OS",
    "version": "2022.6.1",
    "dev": false,
    "hassio": true,
    "virtualenv": false,
    "python_version": "3.9.12",
    "docker": true,
    "arch": "x86_64",
    "timezone": "Europe/Berlin",
    "os_name": "Linux",
    "os_version": "5.15.41",
    "supervisor": "2022.05.3",
    "host_os": "Home Assistant OS 8.1",
    "docker_version": "20.10.14",
    "chassis": "vm",
    "run_as_root": true
  },
  "custom_components": {
    "ecowitt": {
      "version": "0.7",
      "requirements": [
        "pyecowitt==0.14"
      ]
    },
    "frigate": {
      "version": "2.3",
      "requirements": []
    },
    "hacs": {
      "version": "1.25.5",
      "requirements": [
        "aiogithubapi>=22.2.4"
      ]
    },
    "sonoff": {
      "version": "3.0.5",
      "requirements": [
        "pycryptodome>=3.6.6"
      ]
    },
    "alarmo": {
      "version": "v1.9.3",
      "requirements": []
    },
    "remote_homeassistant": {
      "version": "3.6",
      "requirements": []
    },
    "ble_monitor": {
      "version": "8.8.0",
      "requirements": [
        "pycryptodomex>=3.14.1",
        "janus>=1.0.0",
        "aioblescan>=0.2.12",
        "btsocket>=0.2.0",
        "pyric>=<IP_ADDRESS>"
      ]
    }
  },
  "integration_manifest": {
    "domain": "zha",
    "name": "Zigbee Home Automation",
    "config_flow": true,
    "documentation": "https://www.home-assistant.io/integrations/zha",
    "requirements": [
      "bellows==0.30.0",
      "pyserial==3.5",
      "pyserial-asyncio==0.6",
      "zha-quirks==0.0.75",
      "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": "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"
    ],
    "zeroconf": [
      {
        "type": "_esphomelib._tcp.local.",
        "name": "tube*"
      },
      {
        "type": "_zigate-zigbee-gateway._tcp.local.",
        "name": "*zigate*"
      }
    ],
    "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": 46235,
    "manufacturer": "_TZE200_3towulqd",
    "model": "TS0601",
    "name": "_TZE200_3towulqd TS0601",
    "quirk_applied": false,
    "quirk_class": "zigpy.device.Device",
    "manufacturer_code": 4417,
    "power_source": "Battery or Unknown",
    "lqi": 18,
    "rssi": null,
    "last_seen": "2022-06-03T19:40:04",
    "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",
            "0x0500"
          ],
          "out_clusters": [
            "0x000a",
            "0x0019"
          ]
        }
      }
    },
    "entities": [
      {
        "entity_id": "binary_sensor.tze200_3towulqd_ts0601_5bc87feb_ias_zone",
        "name": "_TZE200_3towulqd TS0601"
      },
      {
        "entity_id": "sensor.tze200_3towulqd_ts0601_5bc87feb_power",
        "name": "_TZE200_3towulqd TS0601"
      }
    ],
    "neighbors": [],
    "endpoint_names": [
      {
        "name": "IAS_ZONE"
      }
    ],
    "user_given_name": null,
    "device_reg_id": "c2fdfe7937f3ebd26c55aef21bd6cda7",
    "area_id": "diele"
  }
}
``

</details>

<details>
<summary>Additional logs</summary>

</details>
![Tuya-2-in-1-Zigbee-Mini-PIR-Motion-Bewegung-Menschlichen-K-rper-Detektor-Helligkeit-Leuchtdichte-Sensor jpg_Q90 jpg_](https://user-images.githubusercontent.com/10437947/171983923-ae98c69e-3f83-4cad-a7f7-5c028696490b.png)

Most implementation extracted from the info in:

https://github.com/Koenkk/zigbee2mqtt/issues/12364
https://github.com/Koenkk/zigbee-herdsman-converters/pull/4219/files

Proposed quirk:

ts0601_swicth.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,
)

ZONE_TYPE = 0x0001

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,
        ),
        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,
        ),
    }

    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,
                ],
                OUTPUT_CLUSTERS: [
                    Time.cluster_id,
                    Ota.cluster_id,
                ],
            }
        }
    }

The device is a low power device and reading/setting values can be difficult:

https://github.com/jaspernlp/zigbee2mqtt.io/blob/master/docs/devices/ZG-204ZL.md#reading-and-setting-values

Thank you for your answer, but i do not really know what to do with this code..
i assume i should copy it into a file and upload it to HA?
but i already have TS601 switch you wrote a quirk for me already ..
the question is.. how do i know if i can remove that "hand made quirks" because its now in HA zha integration itself?
Best regards Markus

One approach is just configure a zha local quirk folder. This is a guide of the steps to follow:

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

Copy the propposed file in the local folder and restart. If everything is fine, the device signature will change and maybe some new entities will show up in HA.

ok. it seems that every device i buy at the moment is ts0601 and additionally has issues.

i made file but corrected from ts0601_swicth.py to ts0601_switch.py
and copied your suggest into that file.  after restart
{
"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",
"0xef00"
],
"out_clusters": [
"0x000a",
"0x0019"
]
}
},
"manufacturer": "_TZE200_3towulqd",
"model": "TS0601",
"class": "ts0601_switch.PirMotion"
}
good news.. the battery with 100% is reporting.
but no entities movement or brightness :-(

Is the 'normal' behaviour for most of the Tuya devices (not only yours). If you don't like troubles I would suggest you that avoid them.
The device is loading the quirk, but maybe the DP mapping is not good. Please, enable the debug logs and attach the relevant info (formatted inside ``` please). For enabling the logs:
https://www.home-assistant.io/integrations/zha/#debug-logging

corrected from ts0601_swicth.py to ts0601_switch.py

Ouch 😅

Hi i could successfully activate logs. but dont know how to filter the relevant info for you..
the log is so big
only zigpy interesting?

Usually looking at the logs while interacting with the device and copying the generated logs.
There's not an easy way to do.
I'm not sure in this case, but with some devices you can look for the device identifier, the most right number (456789) from [1234:1:456789] in the logs.

<TuyaDPType.VALUE: 2>, function=0, raw=b'\xaa\x02\x00\x00', *payload=682))
2022-06-13 18:48:53 WARNING (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=87, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\xaa\x02\x00\x00', *payload=682)))
2022-06-13 18:48:53 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.GLOBAL_COMMAND: 0>, is_manufacturer_specific=False, is_reply=1, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True), tsn=37, command_id=<GeneralCommand.Default_Response: 11>, *is_reply=True)
2022-06-13 18:48:53 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply: Default_Response(command_id=2, status=<Status.UNSUP_CLUSTER_COMMAND: 129>)
2022-06-13 18:48:53 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x4269), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=61184, TSN=37, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x25\x0B\x02\x81')
2022-06-13 18:48:53 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-06-13 18:48:53 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=37)
2022-06-13 18:48:54 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=61184, SrcAddr=0x4269, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=153, SecurityUse=<Bool.false: 0>, TimeStamp=2117896, TSN=0, Data=b'\x09\x26\x02\x00\x58\x01\x04\x00\x01\x01', MacSrcAddr=0x4269, MsgResultRadius=29)
2022-06-13 18:48:54 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received ZCL frame: b'\x09\x26\x02\x00\x58\x01\x04\x00\x01\x01'
2022-06-13 18:48:54 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.CLUSTER_COMMAND: 1>, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=38, command_id=2, *is_reply=True)
2022-06-13 18:48:54 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame: PirMotionManufCluster:set_data_response(data=TuyaCommand(status=0, tsn=88, dp=1, data=TuyaData(dp_type=<TuyaDPType.ENUM: 4>, function=0, raw=b'\x01', *payload=<enum8.undefined_0x01: 1>)))
2022-06-13 18:48:54 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received command 0x02 (TSN 38): set_data_response(data=TuyaCommand(status=0, tsn=88, dp=1, data=TuyaData(dp_type=<TuyaDPType.ENUM: 4>, function=0, raw=b'\x01', *payload=<enum8.undefined_0x01: 1>)))
2022-06-13 18:48:54 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No datapoint handler for TuyaCommand(status=0, tsn=88, dp=1, data=TuyaData(dp_type=<TuyaDPType.ENUM: 4>, function=0, raw=b'\x01', *payload=<enum8.undefined_0x01: 1>))
2022-06-13 18:48:54 WARNING (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=88, dp=1, data=TuyaData(dp_type=<TuyaDPType.ENUM: 4>, function=0, raw=b'\x01', *payload=<enum8.undefined_0x01: 1>)))
2022-06-13 18:48:54 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.GLOBAL_COMMAND: 0>, is_manufacturer_specific=False, is_reply=1, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True), tsn=38, command_id=<GeneralCommand.Default_Response: 11>, *is_reply=True)
2022-06-13 18:48:54 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply: Default_Response(command_id=2, status=<Status.UNSUP_CLUSTER_COMMAND: 129>)
2022-06-13 18:48:54 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x4269), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=61184, TSN=38, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x26\x0B\x02\x81')
2022-06-13 18:48:54 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-06-13 18:48:54 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=38)
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy_znp.api] Sending request: SYS.Ping.Req()
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy_znp.api] Received command: SYS.Ping.Rsp(Capabilities=<MTCapabilities.APP_CNF|GP|UTIL|ZDO|AF|SYS: 1625>)
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=61184, SrcAddr=0x4269, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=153, SecurityUse=<Bool.false: 0>, TimeStamp=2211875, TSN=0, Data=b'\x09\x27\x02\x00\x59\x0C\x02\x00\x04\x00\x00\x02\xAA', MacSrcAddr=0x4269, MsgResultRadius=29)
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received ZCL frame: b'\x09\x27\x02\x00\x59\x0C\x02\x00\x04\x00\x00\x02\xAA'
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.CLUSTER_COMMAND: 1>, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=39, command_id=2, *is_reply=True)
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame: PirMotionManufCluster:set_data_response(data=TuyaCommand(status=0, tsn=89, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\xaa\x02\x00\x00', *payload=682)))
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received command 0x02 (TSN 39): set_data_response(data=TuyaCommand(status=0, tsn=89, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\xaa\x02\x00\x00', *payload=682)))
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No datapoint handler for TuyaCommand(status=0, tsn=89, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\xaa\x02\x00\x00', *payload=682))
2022-06-13 18:48:55 WARNING (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=89, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\xaa\x02\x00\x00', *payload=682)))
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.GLOBAL_COMMAND: 0>, is_manufacturer_specific=False, is_reply=1, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True), tsn=39, command_id=<GeneralCommand.Default_Response: 11>, *is_reply=True)
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply: Default_Response(command_id=2, status=<Status.UNSUP_CLUSTER_COMMAND: 129>)
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x4269), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=61184, TSN=39, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x27\x0B\x02\x81')
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=39)
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=61184, SrcAddr=0x4269, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=149, SecurityUse=<Bool.false: 0>, TimeStamp=2225736, TSN=0, Data=b'\x09\x28\x02\x00\x5A\x01\x04\x00\x01\x00', MacSrcAddr=0x4269, MsgResultRadius=29)
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received ZCL frame: b'\x09\x28\x02\x00\x5A\x01\x04\x00\x01\x00'
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.CLUSTER_COMMAND: 1>, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=40, command_id=2, *is_reply=True)
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame: PirMotionManufCluster:set_data_response(data=TuyaCommand(status=0, tsn=90, dp=1, data=TuyaData(dp_type=<TuyaDPType.ENUM: 4>, function=0, raw=b'\x00', *payload=<enum8.undefined_0x00: 0>)))
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received command 0x02 (TSN 40): set_data_response(data=TuyaCommand(status=0, tsn=90, dp=1, data=TuyaData(dp_type=<TuyaDPType.ENUM: 4>, function=0, raw=b'\x00', *payload=<enum8.undefined_0x00: 0>)))
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No datapoint handler for TuyaCommand(status=0, tsn=90, dp=1, data=TuyaData(dp_type=<TuyaDPType.ENUM: 4>, function=0, raw=b'\x00', *payload=<enum8.undefined_0x00: 0>))
2022-06-13 18:48:55 WARNING (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=90, dp=1, data=TuyaData(dp_type=<TuyaDPType.ENUM: 4>, function=0, raw=b'\x00', *payload=<enum8.undefined_0x00: 0>)))
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.GLOBAL_COMMAND: 0>, is_manufacturer_specific=False, is_reply=1, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True), tsn=40, command_id=<GeneralCommand.Default_Response: 11>, *is_reply=True)
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply: Default_Response(command_id=2, status=<Status.UNSUP_CLUSTER_COMMAND: 129>)
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x4269), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=61184, TSN=40, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x28\x0B\x02\x81')
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-06-13 18:48:55 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=40)
2022-06-13 18:49:08 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=61184, SrcAddr=0x4269, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=153, SecurityUse=<Bool.false: 0>, TimeStamp=3054932, TSN=0, Data=b'\x09\x29\x02\x00\x5B\x0C\x02\x00\x04\x00\x00\x02\x92', MacSrcAddr=0x4269, MsgResultRadius=29)
2022-06-13 18:49:08 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received ZCL frame: b'\x09\x29\x02\x00\x5B\x0C\x02\x00\x04\x00\x00\x02\x92'
2022-06-13 18:49:08 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.CLUSTER_COMMAND: 1>, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=41, command_id=2, *is_reply=True)
2022-06-13 18:49:09 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame: PirMotionManufCluster:set_data_response(data=TuyaCommand(status=0, tsn=91, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\x92\x02\x00\x00', *payload=658)))
2022-06-13 18:49:09 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received command 0x02 (TSN 41): set_data_response(data=TuyaCommand(status=0, tsn=91, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\x92\x02\x00\x00', *payload=658)))
2022-06-13 18:49:09 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No datapoint handler for TuyaCommand(status=0, tsn=91, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\x92\x02\x00\x00', *payload=658))
2022-06-13 18:49:09 WARNING (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=91, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\x92\x02\x00\x00', *payload=658)))
2022-06-13 18:49:09 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.GLOBAL_COMMAND: 0>, is_manufacturer_specific=False, is_reply=1, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True), tsn=41, command_id=<GeneralCommand.Default_Response: 11>, *is_reply=True)
2022-06-13 18:49:09 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply: Default_Response(command_id=2, status=<Status.UNSUP_CLUSTER_COMMAND: 129>)
2022-06-13 18:49:09 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x4269), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=61184, TSN=41, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x29\x0B\x02\x81')
2022-06-13 18:49:09 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-06-13 18:49:09 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=41)
2022-06-13 18:49:21 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=61184, SrcAddr=0x4269, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=123, SecurityUse=<Bool.false: 0>, TimeStamp=3812443, TSN=0, Data=b'\x09\x2A\x02\x00\x5C\x0C\x02\x00\x04\x00\x00\x02\x62', MacSrcAddr=0x4269, MsgResultRadius=29)
2022-06-13 18:49:21 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received ZCL frame: b'\x09\x2A\x02\x00\x5C\x0C\x02\x00\x04\x00\x00\x02\x62'
2022-06-13 18:49:21 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.CLUSTER_COMMAND: 1>, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=42, command_id=2, *is_reply=True)
2022-06-13 18:49:21 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame: PirMotionManufCluster:set_data_response(data=TuyaCommand(status=0, tsn=92, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'b\x02\x00\x00', *payload=610)))
2022-06-13 18:49:21 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received command 0x02 (TSN 42): set_data_response(data=TuyaCommand(status=0, tsn=92, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'b\x02\x00\x00', *payload=610)))
2022-06-13 18:49:21 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No datapoint handler for TuyaCommand(status=0, tsn=92, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'b\x02\x00\x00', *payload=610))
2022-06-13 18:49:21 WARNING (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=92, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'b\x02\x00\x00', *payload=610)))
2022-06-13 18:49:21 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.GLOBAL_COMMAND: 0>, is_manufacturer_specific=False, is_reply=1, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True), tsn=42, command_id=<GeneralCommand.Default_Response: 11>, *is_reply=True)
2022-06-13 18:49:21 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply: Default_Response(command_id=2, status=<Status.UNSUP_CLUSTER_COMMAND: 129>)
2022-06-13 18:49:21 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x4269), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=61184, TSN=42, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x2A\x0B\x02\x81')
2022-06-13 18:49:21 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-06-13 18:49:21 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=42)
2022-06-13 18:49:25 DEBUG (MainThread) [zigpy_znp.api] Sending request: SYS.Ping.Req()
2022-06-13 18:49:25 DEBUG (MainThread) [zigpy_znp.api] Received command: SYS.Ping.Rsp(Capabilities=<MTCapabilities.APP_CNF|GP|UTIL|ZDO|AF|SYS: 1625>)
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=61184, SrcAddr=0x4269, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=94, SecurityUse=<Bool.false: 0>, TimeStamp=4941751, TSN=0, Data=b'\x09\x2B\x02\x00\x5D\x0C\x02\x00\x04\x00\x00\x00\x0B', MacSrcAddr=0x4269, MsgResultRadius=29)
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received ZCL frame: b'\x09\x2B\x02\x00\x5D\x0C\x02\x00\x04\x00\x00\x00\x0B'
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.CLUSTER_COMMAND: 1>, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=43, command_id=2, *is_reply=True)
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame: PirMotionManufCluster:set_data_response(data=TuyaCommand(status=0, tsn=93, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\x0b\x00\x00\x00', *payload=11)))
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received command 0x02 (TSN 43): set_data_response(data=TuyaCommand(status=0, tsn=93, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\x0b\x00\x00\x00', *payload=11)))
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No datapoint handler for TuyaCommand(status=0, tsn=93, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\x0b\x00\x00\x00', *payload=11))
2022-06-13 18:49:39 WARNING (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=93, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\x0b\x00\x00\x00', *payload=11)))
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.GLOBAL_COMMAND: 0>, is_manufacturer_specific=False, is_reply=1, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True), tsn=43, command_id=<GeneralCommand.Default_Response: 11>, *is_reply=True)
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply: Default_Response(command_id=2, status=<Status.UNSUP_CLUSTER_COMMAND: 129>)
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x4269), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=61184, TSN=43, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x2B\x0B\x02\x81')
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=43)
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=61184, SrcAddr=0x4269, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=94, SecurityUse=<Bool.false: 0>, TimeStamp=4955974, TSN=0, Data=b'\x09\x2C\x02\x00\x5E\x01\x04\x00\x01\x01', MacSrcAddr=0x4269, MsgResultRadius=29)
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received ZCL frame: b'\x09\x2C\x02\x00\x5E\x01\x04\x00\x01\x01'
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.CLUSTER_COMMAND: 1>, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=44, command_id=2, *is_reply=True)
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame: PirMotionManufCluster:set_data_response(data=TuyaCommand(status=0, tsn=94, dp=1, data=TuyaData(dp_type=<TuyaDPType.ENUM: 4>, function=0, raw=b'\x01', *payload=<enum8.undefined_0x01: 1>)))
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received command 0x02 (TSN 44): set_data_response(data=TuyaCommand(status=0, tsn=94, dp=1, data=TuyaData(dp_type=<TuyaDPType.ENUM: 4>, function=0, raw=b'\x01', *payload=<enum8.undefined_0x01: 1>)))
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No datapoint handler for TuyaCommand(status=0, tsn=94, dp=1, data=TuyaData(dp_type=<TuyaDPType.ENUM: 4>, function=0, raw=b'\x01', *payload=<enum8.undefined_0x01: 1>))
2022-06-13 18:49:39 WARNING (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=94, dp=1, data=TuyaData(dp_type=<TuyaDPType.ENUM: 4>, function=0, raw=b'\x01', *payload=<enum8.undefined_0x01: 1>)))
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.GLOBAL_COMMAND: 0>, is_manufacturer_specific=False, is_reply=1, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True), tsn=44, command_id=<GeneralCommand.Default_Response: 11>, *is_reply=True)
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply: Default_Response(command_id=2, status=<Status.UNSUP_CLUSTER_COMMAND: 129>)
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x4269), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=61184, TSN=44, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x2C\x0B\x02\x81')
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-06-13 18:49:39 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=44)
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=61184, SrcAddr=0x4269, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=87, SecurityUse=<Bool.false: 0>, TimeStamp=5140770, TSN=0, Data=b'\x09\x2D\x02\x00\x5F\x0C\x02\x00\x04\x00\x00\x00\x41', MacSrcAddr=0x4269, MsgResultRadius=29)
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received ZCL frame: b'\x09\x2D\x02\x00\x5F\x0C\x02\x00\x04\x00\x00\x00\x41'
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.CLUSTER_COMMAND: 1>, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=45, command_id=2, *is_reply=True)
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame: PirMotionManufCluster:set_data_response(data=TuyaCommand(status=0, tsn=95, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'A\x00\x00\x00', *payload=65)))
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received command 0x02 (TSN 45): set_data_response(data=TuyaCommand(status=0, tsn=95, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'A\x00\x00\x00', *payload=65)))
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No datapoint handler for TuyaCommand(status=0, tsn=95, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'A\x00\x00\x00', *payload=65))
2022-06-13 18:49:42 WARNING (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=95, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'A\x00\x00\x00', *payload=65)))
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.GLOBAL_COMMAND: 0>, is_manufacturer_specific=False, is_reply=1, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True), tsn=45, command_id=<GeneralCommand.Default_Response: 11>, *is_reply=True)
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply: Default_Response(command_id=2, status=<Status.UNSUP_CLUSTER_COMMAND: 129>)
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x4269), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=61184, TSN=45, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x2D\x0B\x02\x81')
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=45)
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=61184, SrcAddr=0x4269, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=98, SecurityUse=<Bool.false: 0>, TimeStamp=5154531, TSN=0, Data=b'\x09\x2E\x02\x00\x60\x01\x04\x00\x01\x00', MacSrcAddr=0x4269, MsgResultRadius=29)
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received ZCL frame: b'\x09\x2E\x02\x00\x60\x01\x04\x00\x01\x00'
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.CLUSTER_COMMAND: 1>, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=46, command_id=2, *is_reply=True)
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame: PirMotionManufCluster:set_data_response(data=TuyaCommand(status=0, tsn=96, dp=1, data=TuyaData(dp_type=<TuyaDPType.ENUM: 4>, function=0, raw=b'\x00', *payload=<enum8.undefined_0x00: 0>)))
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received command 0x02 (TSN 46): set_data_response(data=TuyaCommand(status=0, tsn=96, dp=1, data=TuyaData(dp_type=<TuyaDPType.ENUM: 4>, function=0, raw=b'\x00', *payload=<enum8.undefined_0x00: 0>)))
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No datapoint handler for TuyaCommand(status=0, tsn=96, dp=1, data=TuyaData(dp_type=<TuyaDPType.ENUM: 4>, function=0, raw=b'\x00', *payload=<enum8.undefined_0x00: 0>))
2022-06-13 18:49:42 WARNING (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=96, dp=1, data=TuyaData(dp_type=<TuyaDPType.ENUM: 4>, function=0, raw=b'\x00', *payload=<enum8.undefined_0x00: 0>)))
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.GLOBAL_COMMAND: 0>, is_manufacturer_specific=False, is_reply=1, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True), tsn=46, command_id=<GeneralCommand.Default_Response: 11>, *is_reply=True)
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply: Default_Response(command_id=2, status=<Status.UNSUP_CLUSTER_COMMAND: 129>)
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x4269), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=61184, TSN=46, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x2E\x0B\x02\x81')
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-06-13 18:49:42 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=46)
2022-06-13 18:49:53 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.IncomingMsg.Callback(GroupId=0x0000, ClusterId=61184, SrcAddr=0x4269, SrcEndpoint=1, DstEndpoint=1, WasBroadcast=<Bool.false: 0>, LQI=80, SecurityUse=<Bool.false: 0>, TimeStamp=5825100, TSN=0, Data=b'\x09\x2F\x02\x00\x61\x0C\x02\x00\x04\x00\x00\x02\xDA', MacSrcAddr=0x4269, MsgResultRadius=29)
2022-06-13 18:49:53 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received ZCL frame: b'\x09\x2F\x02\x00\x61\x0C\x02\x00\x04\x00\x00\x02\xDA'
2022-06-13 18:49:53 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.CLUSTER_COMMAND: 1>, is_manufacturer_specific=0, is_reply=1, disable_default_response=0, reserved=0, *is_cluster=True, *is_general=False), tsn=47, command_id=2, *is_reply=True)
2022-06-13 18:49:53 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Decoded ZCL frame: PirMotionManufCluster:set_data_response(data=TuyaCommand(status=0, tsn=97, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\xda\x02\x00\x00', *payload=730)))
2022-06-13 18:49:53 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Received command 0x02 (TSN 47): set_data_response(data=TuyaCommand(status=0, tsn=97, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\xda\x02\x00\x00', *payload=730)))
2022-06-13 18:49:53 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No datapoint handler for TuyaCommand(status=0, tsn=97, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\xda\x02\x00\x00', *payload=730))
2022-06-13 18:49:53 WARNING (MainThread) [zigpy.zcl] [0x4269:1:0xef00] No 'handle_set_data_response' tuya handler found for set_data_response(data=TuyaCommand(status=0, tsn=97, dp=12, data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>, function=0, raw=b'\xda\x02\x00\x00', *payload=730)))
2022-06-13 18:49:53 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply header: ZCLHeader(frame_control=FrameControl(frame_type=<FrameType.GLOBAL_COMMAND: 0>, is_manufacturer_specific=False, is_reply=1, disable_default_response=1, reserved=0, *is_cluster=False, *is_general=True), tsn=47, command_id=<GeneralCommand.Default_Response: 11>, *is_reply=True)
2022-06-13 18:49:53 DEBUG (MainThread) [zigpy.zcl] [0x4269:1:0xef00] Sending reply: Default_Response(command_id=2, status=<Status.UNSUP_CLUSTER_COMMAND: 129>)
2022-06-13 18:49:53 DEBUG (MainThread) [zigpy_znp.api] Sending request: AF.DataRequestExt.Req(DstAddrModeAddress=AddrModeAddress(mode=<AddrMode.NWK: 2>, address=0x4269), DstEndpoint=1, DstPanId=0x0000, SrcEndpoint=1, ClusterId=61184, TSN=47, Options=<TransmitOptions.SUPPRESS_ROUTE_DISC_NETWORK: 32>, Radius=30, Data=b'\x18\x2F\x0B\x02\x81')
2022-06-13 18:49:53 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataRequestExt.Rsp(Status=<Status.SUCCESS: 0>)
2022-06-13 18:49:53 DEBUG (MainThread) [zigpy_znp.api] Received command: AF.DataConfirm.Callback(Status=<Status.SUCCESS: 0>, Endpoint=1, TSN=47)
2022-06-13 18:49:55 DEBUG (MainThread) [zigpy_znp.api] Sending request: SYS.Ping.Req()
2022-06-13 18:49:55 DEBUG (MainThread) [zigpy_znp.api] Received command: SYS.Ping.Rsp(Capabilities=<MTCapabilities.APP_CNF|GP|UTIL|ZDO|AF|SYS: 1625>)

The device signature is telling us that the quirk has been applied:
  "class": "ts0601_switch.PirMotion"

But logs complains that can't find the DP definition:
2022-06-13 18:48:53 WARNING (MainThread) [zigpy.zcl] [0x4269:1:0xef00]
  No 'handle_set_data_response' tuya handler found for set_data_response(
    data=TuyaCommand(
      status=0,
      tsn=87,
      dp=12,     <--- *
      data=TuyaData(dp_type=<TuyaDPType.VALUE: 2>,
      function=0,
      raw=b'\xaa\x02\x00\x00',
      *payload=682)
    )
  )

2022-06-13 18:48:54 WARNING (MainThread) [zigpy.zcl] [0x4269:1:0xef00]
  No 'handle_set_data_response' tuya handler found for set_data_response(
    data=TuyaCommand(
      status=0,
      tsn=88,
      dp=1,    <--- *
      data=TuyaData(dp_type=<TuyaDPType.ENUM: 4>,
      function=0,
      raw=b'\x01',
      *payload=<enum8.undefined_0x01: 1>)
    )
  )

@itsolon, I have updated the replacement part of the quirk, can you test the new version?:
    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,
                ],
            }
        }
    }

maybe the missing entity is old and can be removed? it seems the occupancy reports very fast

maybe the missing entity is old and can be removed?

Yes, probably it is.
Please, look at the logs for any device related errors.

does this device have iaszone which means occupation.. and second entity motion which means motion
like aquara motion sensor has?

You should be able to set the sensitivity_level and keep_time attributes from the PirMotionManufCluster cluster.
Accepted values would be:
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

For setting the value, just write the numeric value (0, 1, 2, ...) and push the "SET ZIGBEE ATTRIBUTE".
To check if value is setted, just push the "GET ZIGBEE ATTRIBUTE".

at the moment it works like this

The device is reporting just a boolean value at DP_1.
We can implement it like an IasZone Motion_Sensor or like an OccupancySensing, but not both.
According to the manufacturer, it would be a "Human Motion Sensor":

https://aliexpress.com/item/1005004294995498.html

Probably if the device signature already has a IasZone would be better implement as a IasZone Motion_Sensor 🤷🏻♂

i try to use your code and test what i can find out.

The IasZone alternative woud be like:

add a new MotionSensorCluster class:

class MotionSensorCluster(IasZone, TuyaLocalCluster):
    """Tuya Motion_Sensor Sensor."""

    _CONSTANT_ATTRIBUTES = {ZONE_TYPE: IasZone.ZoneType.Motion_Sensor}

replace the dp_to_attribute mapping in PirMotionManufCluster class:

        1: DPToAttributeMapping(
            MotionSensorCluster.ep_attribute,
            "zone_status",
            dp_type=TuyaDPType.BOOL,
            converter=lambda x: IasZone.ZoneStatus.Alarm_1 if x else 0,
        ),

replace the replacement part in PirMotion class:

    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.IAS_ZONE,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    TuyaPowerConfigurationCluster,
                    PirMotionManufCluster,
                    MotionSensorCluster,
                    TuyaIlluminanceMeasurement,
                ],
                OUTPUT_CLUSTERS: [
                    Time.cluster_id,
                    Ota.cluster_id,
                ],
            }
        }
    }

This would replace the OccupancySensing with an IasZone cluster.

Does this sensor now work without custom files in HA? Because I have the same and it doesnt seem to work

Does this sensor now work without custom files in HA? Because I have the same and it doesnt seem to work

HI KrOnAsk i have to tell you that this device didnt work with zha for me.. that was (mainly) the reason to switch over to zigbee2mqtt where it is supported even with a small picture of it..
there it works like a charm.
even other devices i had to fight for were supported out of the box there.
as far as i can say i do not regret to quit zha for the moment.
possible that i come back some time but this was it for now
Thank you to the great support javicalle and matt west ,, they always gave their best.! trying get things to work
but for this device i decided to switch over to zigbee2mqtt,
reason:?
i counted how many devices are supported there and how many at zha,
i dont remember the correct number but it was 3 times more
like 500 to 1500 devices ..
no question about it.
Best regards Markus

ZHA is supporting all devices that is Zigbee (ZCL) compatible out of the box and not making strange things like most tuya and Xiaomi devises id doing and is not working as standard Zigbee devices.
If you is baying one new model Philips HUE bulb that is not added to Z2M its not working but in ZHA is working with all ground functions and can needing some patching for getting some extras Philips have putting in so in the end all system have good and bad sides.

Hello,
I bought the same motion sensor from aliexpress and had the same problems as the originator of this ticket.
@javicalle - thanks a lot for you advises and your code. I was able to get the motion sensor working after following all you recommended changes from the original python file. Just 1 thing I still noticed:
The motion sensor state was inverted.
I changed the following in dp_to_attribute
            converter=lambda x: IasZone.ZoneStatus.Alarm_1 if not x else 0,
Maybe there is a better way to fix this, but I'm quite new on ZHA.
For all the others who want to use:
"""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,
    ZONE_TYPE,
)
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 MotionSensorCluster(IasZone, TuyaLocalCluster):
    """Tuya Motion_Sensor Sensor."""

    _CONSTANT_ATTRIBUTES = {ZONE_TYPE: IasZone.ZoneType.Motion_Sensor}

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(
            MotionSensorCluster.ep_attribute,
            "zone_status",
            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 )/ 10,
        ),
    }

    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,
                    MotionSensorCluster,
                    TuyaIlluminanceMeasurement,
                ],
                OUTPUT_CLUSTERS: [
                    Time.cluster_id,
                    Ota.cluster_id,
                ],
            }
        }
    }

Can we reopen this issue?
I've just got one of these sensors and it would be great to get it supported in ZHA than need to use a quirk.

I would love that too

Just because there is a lot going on in this thread, the current solution to this is as follows:

Create a folder for your custom quirks (I created /config/zha_quirks/)
Create a quirk/file in this directory (I followed the guide above and called it "ts0601_pirmotion.py"). This file should contain (this was copied from a post above - I didn't create this):
`"""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,
    ),
    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,
    ),
}

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,
            ],
        }
    }
}`

Add the following to your config.yaml

zha:
  custom_quirks_path: /config/zha_quirks/

Restart HA
Sensors for Illuminance and Occupancy should be added to your entity (you might need to re-add your device)

Another user has submitted a pull request here - https://github.com/home-assistant/home-assistant.io/pull/23884

I used the quirk at

Hello, I bought the same motion sensor from aliexpress and had the same problems as the originator of this ticket.
@javicalle - thanks a lot for you advises and your code. I was able to get the motion sensor working after following all you recommended changes from the original python file. Just 1 thing I still noticed:
The motion sensor state was inverted. I changed the following in dp_to_attribute  converter=lambda x: IasZone.ZoneStatus.Alarm_1 if not x else 0, Maybe there is a better way to fix this, but I'm quite new on ZHA.
For all the others who want to use:
"""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,
    ZONE_TYPE,
)
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 MotionSensorCluster(IasZone, TuyaLocalCluster):
    """Tuya Motion_Sensor Sensor."""

    _CONSTANT_ATTRIBUTES = {ZONE_TYPE: IasZone.ZoneType.Motion_Sensor}

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(
            MotionSensorCluster.ep_attribute,
            "zone_status",
            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 )/ 10,
        ),
    }

    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,
                    MotionSensorCluster,
                    TuyaIlluminanceMeasurement,
                ],
                OUTPUT_CLUSTERS: [
                    Time.cluster_id,
                    Ota.cluster_id,
                ],
            }
        }
    }

I used this Quirk and its kinda working but the Luminance value doesnt show at all but the rest is working, could u maybe help why its not there

Can someone help me ?
It looks like that for me and it just shows detected the whole time.

It has been working before?
It is the device loading the quirk?
Any relevant info in your logs?
I would try to pair the device again.

I deleted the quirk and added it again, but it still didnt work but then I changed some cluster setting (I dont know which one anymore cause I changed or tried to change allot) and now it reports Motion and that all works great but the Lux value is stuck at 1,9 lux which is for sure not true but it also doesnt change when I turn the light on.

Hi, did you managed to find out what you changed to get the luminance sensor to work?  I've added the quirk and motion is excellent but there is no luminance sensor present.
Also just to thank @javicalle also for getting me this far with this device quirk.  Thought i'd bought a lemon when i first tried it in ZHA and it didn't detect anything, really appreciated.

I deleted the quirk and added it again, but it still didnt work but then I changed some cluster setting (I dont know which one anymore cause I changed or tried to change allot) and now it reports Motion and that all works great but the Lux value is stuck at 1,9 lux which is for sure not true but it also doesnt change when I turn the light on.

Hi, did you managed to find out what you changed to get the luminance sensor to work? I've added the quirk and motion is excellent but there is no luminance sensor present.
Also just to thank @javicalle also for getting me this far with this device quirk. Thought i'd bought a lemon when i first tried it in ZHA and it didn't detect anything, really appreciated.

No I definetly changed it for the worse, it doesnt work at all or just really flaky now.

I deleted the quirk and added it again, but it still didnt work but then I changed some cluster setting (I dont know which one anymore cause I changed or tried to change allot) and now it reports Motion and that all works great but the Lux value is stuck at 1,9 lux which is for sure not true but it also doesnt change when I turn the light on.

Hi, did you managed to find out what you changed to get the luminance sensor to work? I've added the quirk and motion is excellent but there is no luminance sensor present.
Also just to thank @javicalle also for getting me this far with this device quirk. Thought i'd bought a lemon when i first tried it in ZHA and it didn't detect anything, really appreciated.

No I definetly changed it for the worse, it doesnt work at all or just really flaky now.

Argh, sorry to hear that.
Typical after i posted my question the sensor is now working as expected for me.  I deleted everything i'd tried, recopied the code from @javicalle post, restarted HA and re-added the sensor.  I've no idea what changed because i didn't do anything different than previous attempts and yet this time it worked.

I deleted the quirk and added it again, but it still didnt work but then I changed some cluster setting (I dont know which one anymore cause I changed or tried to change allot) and now it reports Motion and that all works great but the Lux value is stuck at 1,9 lux which is for sure not true but it also doesnt change when I turn the light on.

I share your problem. I've read through the discussion here and carefully followed the guidance. The Illuminance sensor is there but its range seems to be from 1.0 (darkness) to 2.0 (directly under a bulb.)
Looking at the 'measured_value' attribute seems to give actual useful numbers that are specific. It seems like that's what needs to be exposed as a sensor.

Holy cow it's fixed. Either through the many removals and restarts or because I changed line 92.
converter=lambda x: (10000.0 * math.log10(x) + 1.0 if x != 0 else 0),
I found that version in another device handler here. I now correctly see values peaking at 1000 in the sensor.

I'm pretty sure that the right expression must be:
converter=lambda x: 10000.0 * math.log10(x + 1.0)

This way for 0<x<1 values remains positive. With the current version for values 0<x<1 you can get negative values that don't make sense to me.

(Example with a 10 scale to see the behavior)

I can't see that quirk or similar in the code. Could anyone create the PR for that quirk?

something interesting i just found with my PIR.
the quirk works for motion detection and battery.....but illuminance is still buggy and doesn't seem correct just seems to stick between a value of 0 and 2
one other thing i noticed is that if it's too dark in an area, the motion sensor will detect motion (as evident by the red light flashing indicating motion detected) but it will not tell HA and instead will leave it in a stuck state
for example:
motion triggered + room dark = motion stays locked to triggered in ZHA
applying light to motion = motion resets and functions again
motion triggered + normal room light = motion triggers then un-triggers as per usual operation.
Curious as if anyone else has noticed this?
here's a diagnostic log
{   "home_assistant": {     "installation_type": "Home Assistant OS",     "version": "2022.11.4",     "dev": false,     "hassio": true,     "virtualenv": false,     "python_version": "3.10.7",     "docker": true,     "arch": "x86_64",     "timezone": "America/New_York",     "os_name": "Linux",     "os_version": "5.15.74",     "supervisor": "2022.11.2",     "host_os": "Home Assistant OS 9.3",     "docker_version": "20.10.18",     "chassis": "vm",     "run_as_root": true   },   "custom_components": {     "nodered": {       "version": "0.5.2",       "requirements": []     },     "blueiris": {       "version": "1.0.12",       "requirements": []     },     "hacs": {       "version": "1.28.4",       "requirements": [         "aiogithubapi>=22.2.4"       ]     },     "nws_alerts": {       "version": "2.5",       "requirements": []     },     "truenas": {       "version": "0.0.0",       "requirements": []     },     "weatheralerts": {       "version": "0.1.5",       "requirements": []     },     "tesla_custom": {       "version": "3.3.1",       "requirements": [         "teslajsonpy==3.2.2"       ]     },     "zha_toolkit": {       "version": "v0.8.26",       "requirements": [         "packaging>=20.8"       ]     }   },   "integration_manifest": {     "domain": "zha",     "name": "Zigbee Home Automation",     "config_flow": true,     "documentation": "https://www.home-assistant.io/integrations/zha",     "requirements": [       "bellows==0.34.2",       "pyserial==3.5",       "pyserial-asyncio==0.6",       "zha-quirks==0.0.86",       "zigpy-deconz==0.19.0",       "zigpy==0.51.5",       "zigpy-xbee==0.16.2",       "zigpy-zigate==0.10.3",       "zigpy-znp==0.9.1"     ],     "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*"       }     ],     "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": 36286,     "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": -65,     "last_seen": "2022-11-27T16:00:12",     "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.motion_by_bed_iaszone",         "name": "_TZE200_3towulqd TS0601"       },       {         "entity_id": "sensor.motion_by_bed_battery",         "name": "_TZE200_3towulqd TS0601"       },       {         "entity_id": "sensor.motion_by_bed_illuminance",         "name": "_TZE200_3towulqd TS0601"       }     ],     "neighbors": [],     "endpoint_names": [       {         "name": "IAS_ZONE"       }     ],     "user_given_name": "Motion by bed",     "device_reg_id": "c36b24b9479ad8f9d3442f87dd18499c",     "area_id": null,     "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": {               "0x0021": {                 "attribute_name": "battery_percentage_remaining",                 "value": 200               }             },             "unsupported_attributes": {               "0x0020": {                 "attribute_name": "battery_voltage"               },               "0x0021": {                 "attribute_name": "battery_percentage_remaining"               },               "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": {               "0x0001": {                 "attribute_name": "zone_type",                 "value": 13               },               "0x0002": {                 "attribute_name": "zone_status",                 "value": 0               },               "0x0010": {                 "attribute_name": "cie_addr",                 "value": "00:0d:6f:00:17:20:6a:90"               }             },             "unsupported_attributes": {               "0x0000": {                 "attribute_name": "zone_state"               },               "0x0002": {                 "attribute_name": "zone_status"               }             }           },           "0x0400": {             "endpoint_attribute": "illuminance",             "attributes": {               "0x0000": {                 "attribute_name": "measured_value",                 "value": 1813.0133566428553               }             },             "unsupported_attributes": {}           }         },         "out_clusters": {           "0x000a": {             "endpoint_attribute": "time",             "attributes": {},             "unsupported_attributes": {}           },           "0x0019": {             "endpoint_attribute": "ota",             "attributes": {},             "unsupported_attributes": {}           }         }       }     }   } }

something interesting i just found with my PIR.
the quirk works for motion detection and battery.....but illuminance is still buggy and doesn't seem correct just seems to stick between a value of 0 and 2
one other thing i noticed is that if it's too dark in an area, the motion sensor will detect motion (as evident by the red light flashing indicating motion detected) but it will not tell HA and instead will leave it in a stuck state
for example:
motion triggered + room dark = motion stays locked to triggered in ZHA
applying light to motion = motion resets and functions again
motion triggered + normal room light = motion triggers then un-triggers as per usual operation.
Curious as if anyone else has noticed this?
here's a diagnostic log`

I experienced similar with my units and this quirk in ZHA.  I found motion would often stick on for hours for seeming no reason and wouldn't clear until mounting / dismount the pir.  This was across four different sensors.  I'd pretty much given up on them as a poor devices but swapped to using zigbee2mqtt and (touch wood) they've been working perfectly since then.
I'm now tempted to order more because they are good value, compact, accurate and the luminance sensor is an added bonus.

something interesting i just found with my PIR.
the quirk works for motion detection and battery.....but illuminance is still buggy and doesn't seem correct just seems to stick between a value of 0 and 2
one other thing i noticed is that if it's too dark in an area, the motion sensor will detect motion (as evident by the red light flashing indicating motion detected) but it will not tell HA and instead will leave it in a stuck state
for example:
motion triggered + room dark = motion stays locked to triggered in ZHA
applying light to motion = motion resets and functions again
motion triggered + normal room light = motion triggers then un-triggers as per usual operation.
Curious as if anyone else has noticed this?
here's a diagnostic log`

I experienced similar with my units and this quirk in ZHA. I found motion would often stick on for hours for seeming no reason and wouldn't clear until mounting / dismount the pir. This was across four different sensors. I'd pretty much given up on them as a poor devices but swapped to using zigbee2mqtt and (touch wood) they've been working perfectly since then.
I'm now tempted to order more because they are good value, compact, accurate and the luminance sensor is an added bonus.

Exactly same happening here. I thought myzigbee network is overcrowded and it is missing messages but seems yet again the ZHA is the culprit.

I also got the motion sensor to work using the quirk posted. However, now the Illuminance sensor doesn't work anymore (used to work out of the box without the quirk). It is now stuck at 1000 lx. Anyone else with the same problem?
I use ZHA with a Conbee II stick.

I can really recommend using zigbee2mqtt
There the sensor works like a charm
I understand that you want to use the built in Standard ZigBee functionality of home assistant which is quite cool..
But for me – as i Have many different sensors and themostates – there was no way without going away from the Standard zha
Give it a try and then you will be without those quirks..
Best Regards
Markus
Gesendet von Mailhttps://go.microsoft.com/fwlink/?LinkId=550986 für Windows
Von: @.>
Gesendet: Samstag, 17. Dezember 2022 12:29
An: @.>
Cc: Markus @.>; @.>
Betreff: Re: [zigpy/zha-device-handlers] _TZE200_3towulqd TS0601 Tuya Motion Sensor with illuminance sensor (Issue #1599)
I also got the motion sensor to work using the quirk posted. However, now the Illuminance sensor doesn't work anymore (used to work out of the box without the quirk). It is now stuck at 1000 lx. Anyone else with the same problem?
I use ZHA with a Conbee II stick.
—
Reply to this email directly, view it on GitHubhttps://github.com/zigpy/zha-device-handlers/issues/1599#issuecomment-1356214497, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ACPUKO66DSZYZHPGYNQQTHTWNWPZHANCNFSM5XZ35VCQ.
You are receiving this because you were mentioned.Message ID: @.***>

Having the same issue with this sensor.
Can someone recommend one that will work just fine with ZHA?

Having the same issue with this sensor. Can someone recommend one that will work just fine with ZHA?

I followed the suggestions in this thread (sounds much more complicated than it is... I got it to work without having deep knowledge of YAML or HA in general). I had to restart the system and bind the sensor again... since then it works for me without a problem for the last 3 weeks...

Having the same issue with this sensor. Can someone recommend one that will work just fine with ZHA?

I followed the suggestions in this thread (sounds much more complicated than it is... I got it to work without having deep knowledge of YAML or HA in general). I had to restart the system and bind the sensor again... since then it works for me without a problem for the last 3 weeks...

I installed also the quirk manually (not really complicated, I'm a dev myself) and it is indeed working but it still has this issue that it won't recognize motion when it's dark. Are you sure you're not having this problem as well?

I installed also the quirk manually (not really complicated, I'm a dev myself) and it is indeed working but it still has this issue that it won't recognize motion when it's dark. Are you sure you're not having this problem as well?

I just did a quick test (with my second sensor that I haven't mounted yet). I took it into my bathroom that has no window and gets pretty much 100 % dark. Mine works just fine. It had no issue detecting motion. I can shoot a video of it later if you want....

I installed also the quirk manually (not really complicated, I'm a dev myself) and it is indeed working but it still has this issue that it won't recognize motion when it's dark. Are you sure you're not having this problem as well?

I just did a quick test (with my second sensor that I haven't mounted yet). I took it into my bathroom that has no window and gets pretty much 100 % dark. Mine works just fine. It had no issue detecting motion. I can shoot a video of it later if you want....

Ah ok that's good. I'll try to configure it again from scratch to see if it works. Just a clarification: you're using ZHA and not zigbee2mqtt right?

I installed also the quirk manually (not really complicated, I'm a dev myself) and it is indeed working but it still has this issue that it won't recognize motion when it's dark. Are you sure you're not having this problem as well?

I just did a quick test (with my second sensor that I haven't mounted yet). I took it into my bathroom that has no window and gets pretty much 100 % dark. Mine works just fine. It had no issue detecting motion. I can shoot a video of it later if you want....

Ah ok that's good. I'll try to configure it again from scratch to see if it works. Just a clarification: you're using ZHA and not zigbee2mqtt right? And if i may ask on which hardware?

Yes... ZHA... Give me 5mins and I'll post a video... just to make sure I got the same sensor or there isn't some sort of miss-understanding...

Ah ok that's good. I'll try to configure it again from scratch to see if it works. Just a clarification: you're using ZHA and not zigbee2mqtt right? And if i may ask on which hardware?

Here it is.... didn't do a very good job filming because I had to dim the screen down to the point where I could hardly see what I was filming... However, you can clearly see the sensor triggering... https://youtu.be/5ldyrA5Ct-I

Thank you so much for the video and yep, it seems that your setup (sensor, installation) is exactly the same. I tried to delete the sensor and re-install it. For now it is working as expected but I'll let you know tonight with no lights and hope that it works.
P.S. Just to be clear until now the motion was also detected by the sensor in dark environments (the red light was flashing) but it wasn't picked up by ZHA.

You're right, it works now :D
Super happy and thanks for giving me hope and the reason to test it again

I got a Conbee II as well. Just to make sure the motion didn't get picked up after turning on the light, I just did another test. I put the sensor under a thick blanked in a dark room and had my hand under the blanket as well. This allowed me to move the hand under the blanket (in complete darkness) and watch home assistant at the same time. Works fine every-time...

do you also get all these false positives? the sensor seems to work really well when I test it but during the night I get all these detected motion events and there is definitely no motion where the sensor is placed.

I don't, see attached picture. Could you possibly have a faulty sensor?

I don't, see attached picture. Could you possibly have a faulty sensor?

I mean, due to all the problems that I had until now with the quirk I tend to believe the problem would be in the integration, and not the sensor, but honestly I have no other clue.
I've done some test with the sensor and it seems to work really well: it is not triggered by sudden light changes or far away movements. But leaving it on I can see all these triggers in the logbook. I'm not sure if the sensor did really pick up any movement, as I wasn't there to see if the red light flashes, so I don't really know how to debug..I also tried to change the sensitivity to low as.zigbeee attribute but that didn't seem to change anything.
The only thing left to do is to leave the sensor in a closed space and see if it detects any movement there, otherwise I don't have any other idea.

I don't, see attached picture. Could you possibly have a faulty sensor?

I mean, due to all the problems that I had until now with the quirk I tend to believe the problem would be in the integration, and not the sensor, but honestly I have no other clue. I've done some test with the sensor and it seems to work really well: it is not triggered by sudden light changes or far away movements. But leaving it on I can see all these triggers in the logbook. I'm not sure if the sensor did really pick up any movement, as I wasn't there to see if the red light flashes, so I don't really know how to debug..I also tried to change the sensitivity to low as.zigbeee attribute but that didn't seem to change anything. The only thing left to do is to leave the sensor in a closed space and see if it detects any movement there, otherwise I don't have any other idea.

This is the same in my situation there is no movement and it does detect it, i thought maybe its a bad reception so i moved another antenna and power plug in the area acting as a repeater but also this didn't do much.
I am going to remove them for now since i can't turn on or off my lights in the workshop.

If getting false detection then not have restarting HA and the log looks OK and no errors or warning its very likely sent  from the device = bad device.

will check the logs, but otherwise i'd have a bad batch , hope not since i have 5 in use...

honestly i think these devices are just hit or miss.
I ended up returning my tuya and buying an Ikea motion sensor. Even though the latter is way less configurable, has more latency and goes offline after a while, it still does not detect motion when there is none (what a sensor like this should do 😄) and just works

@guidocioni Try reconfiguration from the device card and waking the device then sending to it (its not easy then its sleeping very log if its the new model) then all IKEA controllers is missing some config after being pared. If its OK its making one check in every 55 minutes (not the old one its still ZLL) = OK configured. IKEA motion sensor is not one real motion sensor is one OnOff controller (sending commands to light groups) but its working OK.
Only if battery is being old / week they can start sending false detection.

Thanks for all this, I got it to work with this quirk.
I probably made a mistake by buying this for illuminance reporting, but here goed nothing…
is it possible to get the sensor to report based on a determined change in Lux? Or at least in certain intervals?

I'd be happy for some sort of times lux update. I found it only really
reports lux along with a motion event. I've been trying to work around it
by basing automations on lux OR a certain time of day as a backup.
On Fri, Feb 3, 2023, 11:06 a.m. Bafnek @.***> wrote:

Thanks for all this, I got it to work with this quirk.
I probably made a mistake by buying this for illuminance reporting, but
here goed nothing…
is it possible to get the sensor to report based on a determined change in
Lux? Or at least in certain intervals?
—
Reply to this email directly, view it on GitHub
https://github.com/zigpy/zha-device-handlers/issues/1599#issuecomment-1416077530,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AF36VXSVBFWDFFFL2XG46PLWVUUHBANCNFSM5XZ35VCQ
.
You are receiving this because you commented.Message ID:
@.***>

Most implementation extracted from the info in:
* [[New device support]: ZG-204ZL / TS0601 _TZE200_3towulqd / PIR sensor with illuminance Koenkk/zigbee2mqtt#12364](https://github.com/Koenkk/zigbee2mqtt/issues/12364)

* https://github.com/Koenkk/zigbee-herdsman-converters/pull/4219/files

Proposed quirk:
ts0601_pirmotion.py
The device is a low power device and reading/setting values can be difficult:
* https://github.com/jaspernlp/zigbee2mqtt.io/blob/master/docs/devices/ZG-204ZL.md#reading-and-setting-values

Thanks a mil!! Finally my PIR with luminance meter works!

Hey,
I'm having the (seemingly) same pir sensor and have the problem, that my illuminance sensor doesn't show anything useful.
It only shows 1 or 2.
If I read the cluster measured value I get different values that also update from differing brightness.
Is there something wrong in the conversion of my sensor values?

Hello,
Why is this quirk not pushed to official release ?
Regards,

I updated to the latest Home Assistant version today (2023.3.0). Since then, the custom quirk doesn't work for me anymore and I get the following error:
Logger: homeassistant.config_entries
Source: zha_quirks/ts0601_pirmotion.py:22
First occurred: 00:15:37 (1 occurrences)
Last logged: 00:15:37
Error setting up entry ConBee II - /dev/serial/by-id/usb-dresden_elektronik_ingenieurtechnik_GmbH_ConBee_II_DE2492391-if00, s/n: DE2492391 - dresden elektronik ingenieurtechnik GmbH - 1CF1:0030 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 100, 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 "", line 548, in _check_name_wrapper
File "", line 1063, in load_module
File "", line 888, in load_module
File "", line 290, in _load_module_shim
File "", line 719, in _load
File "", line 688, in _load_unlocked
File "", line 883, in exec_module
File "", line 241, in _call_with_frames_removed
File "/config/zha_quirks/ts0601_pirmotion.py", line 22, in
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)
The custom quirk causes most zigbee devices to stop working. If I delete it... all devices work fine again except for the motion sensor. Any chance anybody knows what the issue is?

That wouldn't happen if a PR is created for that quirk...
Just remove all the dp_type=TuyaDPType.XXXXXX from the dp_to_attribute part:
    dp_to_attribute: Dict[int, DPToAttributeMapping] = {
        1: DPToAttributeMapping(
            MotionSensorCluster.ep_attribute,
            "zone_status",
            dp_type=TuyaDPType.BOOL,   # <-- REMOVE FROM ALL DPs
            converter=lambda x: IasZone.ZoneStatus.Alarm_1 if not x else 0,
        ),
        .../...

@javicalle I tried but I'm still getting an error.
Here is what I did (just in case I'm miss-understanding what I'm supposed to do):
Original quirk:
`"""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.0 * math.log10(x + 1.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,
            ],
        }
    }
}

`
Modified Quirk:
`"""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",
        converter=lambda x: IasZone.ZoneStatus.Alarm_1 if not x else 0,
    ),
    4: DPToAttributeMapping(
        TuyaPowerConfigurationCluster.ep_attribute,
        "battery_percentage_remaining",
    ),
    9: DPToAttributeMapping(
        TuyaMCUCluster.ep_attribute,
        "sensitivity_level",
        converter=lambda x: SensitivityLevel(x),
    ),
    10: DPToAttributeMapping(
        TuyaMCUCluster.ep_attribute,
        "keep_time",
        converter=lambda x: OnTimeValues(x),
    ),
    12: DPToAttributeMapping(
        TuyaIlluminanceMeasurement.ep_attribute,
        "measured_value",
        converter=lambda x: 10000.0 * math.log10(x + 1.0)
    ),
}`

I'm not getting the following Error after re-starting Home Assistant:
Home Assistant Core
2023-03-02 09:28:29.240 ERROR (MainThread) [homeassistant.config_entries] Error setting up entry ConBee II - /dev/serial/by-id/usb-dresden_elektronik_ingenieurtechnik_GmbH_ConBee_II_DE2492391-if00, s/n: DE2492391 - dresden elektronik ingenieurtechnik GmbH - 1CF1:0030 for zha
File "/usr/src/homeassistant/homeassistant/components/zha/init.py", line 100, in async_setup_entry
File "/usr/local/lib/python3.10/site-packages/zhaquirks/init.py", line 409, in setup
File "/config/zha_quirks/ts0601_pirmotion.py", line 22, in
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)

Remove also the TuyaDPType from the import part:
from zhaquirks.tuya.mcu import (
    DPToAttributeMapping,
    TuyaDPType,  # <-- REMOVE
    TuyaMCUCluster,
    TuyaPowerConfigurationCluster,
)

PS: to format code put it inside ``` marks.

Thank you very much! It is working now (obviously haven't had a chance to properly test it yet, but so far everything looks good). In case anybody else is looking for the "fixed" quirk, here is the one that is currently working for me (Home Assistant 2023.3.0):
https://hochseesegelteam.ch/privatemedia/homeassistantfiles/ts0601_pirmotion.py.txt
(remove ".txt" file ending before using)

Reopening until whatever custom quirk is available here is merged into zha-quirks.

Most implementation extracted from the info in:

[New device support]: ZG-204ZL / TS0601 _TZE200_3towulqd / PIR sensor with illuminance Koenkk/zigbee2mqtt#12364
https://github.com/Koenkk/zigbee-herdsman-converters/pull/4219/files

Proposed quirk:
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,
        ),
        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,
        ),
    }

    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,
                ],
            }
        }
    }

The device is a low power device and reading/setting values can be difficult:

https://github.com/jaspernlp/zigbee2mqtt.io/blob/master/docs/devices/ZG-204ZL.md#reading-and-setting-values

Excuse me, maybe someone could help me see what I'm doing wrong...
I have the same small motion sensors from Aliexpress:

I connected it with the zha integration, but it appeared as a smoke detector. So I searched and found this quirk. I copied the code into a python file and named it "motion _sensor.py" and put it into a custom quirks folder in my home assistant server, and in the configuration.yaml file I wrote this:
zha:   custom_quirks_path: /config/custom_zha_quirks/
But when I restart HA it completely disables my zha, and gives this error:
`Logger: homeassistant.config_entries
Source: custom_zha_quirks/motion_sensor.py:22
First occurred: 13:28:52 (1 occurrences)
Last logged: 13:28:52
Error setting up entry Sonoff Zigbee 3.0 USB Dongle Plus - Sonoff Zigbee 3.0 USB Dongle Plus 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 "", line 548, in _check_name_wrapper
File "", line 1063, in load_module
File "", line 888, in load_module
File "", line 290, in _load_module_shim
File "", line 719, in _load
File "", line 688, in _load_unlocked
File "", line 883, in exec_module
File "", line 241, in _call_with_frames_removed
File "/config/custom_zha_quirks/motion_sensor.py", line 22, in
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)
`
What am I doing wrong? I would appreciate any help, thanks in advance!

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

Can some of the people updating this please submit it as a pull request?

Can you explain how to set the sensor timing further?

Most implementation extracted from the info in:

[New device support]: ZG-204ZL / TS0601 _TZE200_3towulqd / PIR sensor with illuminance Koenkk/zigbee2mqtt#12364
https://github.com/Koenkk/zigbee-herdsman-converters/pull/4219/files

Proposed quirk:
ts0601_pirmotion.py
The device is a low power device and reading/setting values can be difficult:

https://github.com/jaspernlp/zigbee2mqtt.io/blob/master/docs/devices/ZG-204ZL.md#reading-and-setting-values

Update ts0601_pirmotion.py by removing all TuyaDPType related code and restart HA twice times <--I don't know why need restart twice times to get all entity work. but it works.

updated 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 zigpy.zcl import foundation

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,
    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)})

    async def write_attributes(self, attributes, manufacturer=None):
        """Overwrite to force manufacturer code."""

        return await super().write_attributes(
            attributes, manufacturer=foundation.ZCLHeader.NO_MANUFACTURER_ID
        )

    dp_to_attribute: Dict[int, DPToAttributeMapping] = {
        1: DPToAttributeMapping(
            TuyaOccupancySensing.ep_attribute,
            "occupancy",
            converter=lambda x: IasZone.ZoneStatus.Alarm_1 if not x else 0,
        ),
        4: DPToAttributeMapping(
            TuyaPowerConfigurationCluster.ep_attribute,
            "battery_percentage_remaining",
        ),
        9: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "sensitivity_level",
            converter=lambda x: SensitivityLevel(x),
        ),
        10: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "keep_time",
            converter=lambda x: OnTimeValues(x),
        ),
        12: DPToAttributeMapping(
            TuyaIlluminanceMeasurement.ep_attribute,
            "measured_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,
                ],
            }
        }
    }

Most implementation extracted from the info in:

[New device support]: ZG-204ZL / TS0601 _TZE200_3towulqd / PIR sensor with illuminance Koenkk/zigbee2mqtt#12364
https://github.com/Koenkk/zigbee-herdsman-converters/pull/4219/files

Proposed quirk:
ts0601_pirmotion.py
The device is a low power device and reading/setting values can be difficult:

https://github.com/jaspernlp/zigbee2mqtt.io/blob/master/docs/devices/ZG-204ZL.md#reading-and-setting-values

TuyaDPType seems not in mcu anymore --> #2190 (comment) Update ts0601_pirmotion.py by removing all TuyaDPType related code and restart HA twice times <--I don't know why need restart twice times to get all entity work. but it works.
updated ts0601_pirmotion.py

Hello with this quirks my sensor goes on and off the oresence detection every minute itself

Hello, I have the same sensor but the sensor does not provide values in HA. The sensor works in zigbee2mqtt without any problem but in HA not. I performed all needed settings that means I created ts0601_pirmotion.py file, add path to custom_zha_quirks folder etc. Do You know what problem could be there ?
Zigbee2MQTT:info  2023-04-18 10:48:30: MQTT publish: topic 'zigbee2mqtt/0xa4c1385103a7db06', payload '{"battery":100,"illuminance":850,"keep_time":"10","linkquality":142,"occupancy":false,"sensitivity":"high"}'

There's been a change in the bindings since the quirk in the above thread was written and it no longer works.  Here's an updated version that has worked for me to get Power, Occupancy and Luminance working.  The only issue that I'm having is that the occupancy sensor appears to be inverted, meaning that when motion is detected it's clearing the occupancy and when there's no motion it sets occupancy.  Additionally the device is updating the status every 10 seconds so if I'm near it, it's continually flipping status from occupied to unoccupied.  I've attempted to change the PirMotionManfuCluster : keeptime attribute as well as the TuyaOccupancySensing : pir_o_to_u_delay attributes but none appear to have any affect on the delay between occupied to unoccupied.  I may just try to integrate this in to the automation that if the status hasn't changed in 5 mins then trigger an unoccupied action but I'd rather see this get improved in the integration.
`"""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.mcu import (
DPToAttributeMapping,
TuyaMCUCluster,
TuyaPowerConfigurationCluster,
)
from zhaquirks.tuya import (
TuyaLocalCluster
)
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",
    ),
    4: DPToAttributeMapping(
        TuyaPowerConfigurationCluster.ep_attribute,
        "battery_percentage_remaining",
    ),
    9: DPToAttributeMapping(
        TuyaMCUCluster.ep_attribute,
        "sensitivity_level",
        converter=lambda x: SensitivityLevel(x),
    ),
    10: DPToAttributeMapping(
        TuyaMCUCluster.ep_attribute,
        "keep_time",
        converter=lambda x: OnTimeValues(x),
    ),
    12: DPToAttributeMapping(
        TuyaIlluminanceMeasurement.ep_attribute,
        "measured_value",
        converter=lambda x: 10000 * math.log10(x) + 1,
    ),
}

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,
            ],
        }
    }
}`

I have created a pull request with the quirk in this issue, to try and get it merged upstream instead of being left in an issue.
However it may need input from people more knowledgeable than me, so any assistance in getting this committed will be helpful.

Hello, @Naheem ! I just tried the quirk, and though HA now perfectly shows the "Occupancy" sensor, the Illuminance sensor is not being shown, but I can perfectly get its reading in the device manager as shown in this screen shot (sorry for the Spanish):

The question would clearly be... how can I turn that into a Sensor?  Or is this working differently for you?

Hi,
I'm going to ZHA but I don't find how to change the value of the sensitivity of the sensor.
I use the updated script of the sensor but it doesn't work.
Thank you for your help.

https://github.com/zigpy/zha-device-handlers/issues/1599#issuecomment-1482281897 working perfectly for me, thank you and thanks to thatguy-za for the steps to get it working!

I installed the quirk and according to the logs it's getting loaded.
Anyway, I cannot see any configuration about keep_time. I restarted the HA instance and I didn't have any quirk before, so no cache was there already.
Am I doing something wrong?

Quirks as follow works good for presence and illuminance but no battery.
Any news?
`"""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 zigpy.zcl import foundation
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,
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)})

async def write_attributes(self, attributes, manufacturer=None):
    """Overwrite to force manufacturer code."""

    return await super().write_attributes(
        attributes, manufacturer=foundation.ZCLHeader.NO_MANUFACTURER_ID
    )

dp_to_attribute: Dict[int, DPToAttributeMapping] = {
    1: DPToAttributeMapping(
        TuyaOccupancySensing.ep_attribute,
        "occupancy",
        converter=lambda x: IasZone.ZoneStatus.Alarm_1 if not x else 0,
    ),
    4: DPToAttributeMapping(
        TuyaPowerConfigurationCluster.ep_attribute,
        "battery_percentage_remaining",
    ),
    9: DPToAttributeMapping(
        TuyaMCUCluster.ep_attribute,
        "sensitivity_level",
        converter=lambda x: SensitivityLevel(x),
    ),
    10: DPToAttributeMapping(
        TuyaMCUCluster.ep_attribute,
        "keep_time",
        converter=lambda x: OnTimeValues(x),
    ),
    12: DPToAttributeMapping(
        TuyaIlluminanceMeasurement.ep_attribute,
        "measured_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: [