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

[Device Support Request] tuya mmWave sensor _TZE200_jva8ink8

Open bzumik1 opened this issue 2 years ago • 14 comments

Problem description

Hi, could someone please help me to add following sensor _TZE200_jva8ink8 to ZHA, based on this side it should be compatible https://zigbee.blakadder.com/Moes_ZSS-QY-HP.html. Please let me know what I should provide you and I will do so.

Solution description

Add mmWave sensor to ZHA.

Screenshots/Video

Screenshots/Video

[Paste/upload your media here]

Device signature

Device signature
"signature": {
      "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.FullFunctionDevice|MainsPowered|RxOnWhenIdle|AllocateAddress: 142>, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)",
      "endpoints": {
        "1": {
          "profile_id": "0x0104",
          "device_type": "0x0107",
          "input_clusters": [
            "0x0000",
            "0x0004",
            "0x0005",
            "0x000c",
            "0x0400",
            "0x0406",
            "0xef00"
          ],
          "output_clusters": [
            "0x000a",
            "0x0019"
          ]
        }
      }

Diagnostic information

Diagnostic information
{
  "home_assistant": {
    "installation_type": "Home Assistant OS",
    "version": "2023.9.0",
    "dev": false,
    "hassio": true,
    "virtualenv": false,
    "python_version": "3.11.5",
    "docker": true,
    "arch": "x86_64",
    "timezone": "Europe/Prague",
    "os_name": "Linux",
    "os_version": "6.1.45",
    "supervisor": "2023.08.3",
    "host_os": "Home Assistant OS 10.5",
    "docker_version": "23.0.6",
    "chassis": "embedded",
    "run_as_root": true
  },
  "custom_components": {
    "hacs": {
      "version": "1.32.1",
      "requirements": [
        "aiogithubapi>=22.10.1"
      ]
    },
    "adaptive_lighting": {
      "version": "1.19.0",
      "requirements": [
        "ulid-transform"
      ]
    },
    "tedee": {
      "version": "2023.7.4",
      "requirements": [
        "pytedee-async==0.1.4"
      ]
    },
    "smartthings": {
      "version": "1.0",
      "requirements": [
        "pysmartapp==0.3.3",
        "pysmartthings==0.7.6"
      ]
    },
    "scheduler": {
      "version": "v0.0.0",
      "requirements": []
    }
  },
  "integration_manifest": {
    "domain": "zha",
    "name": "Zigbee Home Automation",
    "after_dependencies": [
      "onboarding",
      "usb"
    ],
    "codeowners": [
      "@dmulcahey",
      "@adminiuga",
      "@puddly"
    ],
    "config_flow": true,
    "dependencies": [
      "file_upload"
    ],
    "documentation": "https://www.home-assistant.io/integrations/zha",
    "iot_class": "local_polling",
    "loggers": [
      "aiosqlite",
      "bellows",
      "crccheck",
      "pure_pcapy3",
      "zhaquirks",
      "zigpy",
      "zigpy_deconz",
      "zigpy_xbee",
      "zigpy_zigate",
      "zigpy_znp",
      "universal_silabs_flasher"
    ],
    "requirements": [
      "bellows==0.36.2",
      "pyserial==3.5",
      "pyserial-asyncio==0.6",
      "zha-quirks==0.0.103",
      "zigpy-deconz==0.21.0",
      "zigpy==0.57.1",
      "zigpy-xbee==0.18.1",
      "zigpy-zigate==0.11.0",
      "zigpy-znp==0.11.4",
      "universal-silabs-flasher==0.0.13"
    ],
    "usb": [
      {
        "vid": "10C4",
        "pid": "EA60",
        "description": "*2652*",
        "known_devices": [
          "slae.sh cc2652rb stick"
        ]
      },
      {
        "vid": "1A86",
        "pid": "55D4",
        "description": "*sonoff*plus*",
        "known_devices": [
          "sonoff zigbee dongle plus v2"
        ]
      },
      {
        "vid": "10C4",
        "pid": "EA60",
        "description": "*sonoff*plus*",
        "known_devices": [
          "sonoff zigbee dongle plus"
        ]
      },
      {
        "vid": "10C4",
        "pid": "EA60",
        "description": "*tubeszb*",
        "known_devices": [
          "TubesZB Coordinator"
        ]
      },
      {
        "vid": "1A86",
        "pid": "7523",
        "description": "*tubeszb*",
        "known_devices": [
          "TubesZB Coordinator"
        ]
      },
      {
        "vid": "1A86",
        "pid": "7523",
        "description": "*zigstar*",
        "known_devices": [
          "ZigStar Coordinators"
        ]
      },
      {
        "vid": "1CF1",
        "pid": "0030",
        "description": "*conbee*",
        "known_devices": [
          "Conbee II"
        ]
      },
      {
        "vid": "10C4",
        "pid": "8A2A",
        "description": "*zigbee*",
        "known_devices": [
          "Nortek HUSBZB-1"
        ]
      },
      {
        "vid": "0403",
        "pid": "6015",
        "description": "*zigate*",
        "known_devices": [
          "ZiGate+"
        ]
      },
      {
        "vid": "10C4",
        "pid": "EA60",
        "description": "*zigate*",
        "known_devices": [
          "ZiGate"
        ]
      },
      {
        "vid": "10C4",
        "pid": "8B34",
        "description": "*bv 2010/10*",
        "known_devices": [
          "Bitron Video AV2010/10"
        ]
      }
    ],
    "zeroconf": [
      {
        "type": "_esphomelib._tcp.local.",
        "name": "tube*"
      },
      {
        "type": "_zigate-zigbee-gateway._tcp.local.",
        "name": "*zigate*"
      },
      {
        "type": "_zigstar_gw._tcp.local.",
        "name": "*zigstar*"
      },
      {
        "type": "_uzg-01._tcp.local.",
        "name": "uzg-01*"
      },
      {
        "type": "_slzb-06._tcp.local.",
        "name": "slzb-06*"
      }
    ],
    "is_built_in": true
  },
  "data": {
    "ieee": "**REDACTED**",
    "nwk": 51522,
    "manufacturer": "_TZE200_jva8ink8",
    "model": "TS0601",
    "name": "_TZE200_jva8ink8 TS0601",
    "quirk_applied": true,
    "quirk_class": "ts0601_motion.MmwRadarMotion",
    "manufacturer_code": 4098,
    "power_source": "Mains",
    "lqi": 200,
    "rssi": -50,
    "last_seen": "2023-09-08T10:41:55",
    "available": true,
    "device_type": "Router",
    "signature": {
      "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.FullFunctionDevice|MainsPowered|RxOnWhenIdle|AllocateAddress: 142>, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)",
      "endpoints": {
        "1": {
          "profile_id": "0x0104",
          "device_type": "0x0107",
          "input_clusters": [
            "0x0000",
            "0x0004",
            "0x0005",
            "0x000c",
            "0x0400",
            "0x0406",
            "0xef00"
          ],
          "output_clusters": [
            "0x000a",
            "0x0019"
          ]
        }
      },
      "manufacturer": "_TZE200_jva8ink8",
      "model": "TS0601"
    },
    "active_coordinator": false,
    "entities": [
      {
        "entity_id": "binary_sensor.senzor_pritomnosti_koupelna_pritomnost",
        "name": "_TZE200_jva8ink8 TS0601"
      },
      {
        "entity_id": "sensor.senzor_pritomnosti_koupelna_intenzita_osvetleni",
        "name": "_TZE200_jva8ink8 TS0601"
      }
    ],
    "neighbors": [
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0x29F8",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "132"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0x3E82",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "156"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0x48C2",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "180"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0x5C1E",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "244"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0x6810",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "244"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0x69B9",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "109"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0x69D1",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "157"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0x6B02",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "161"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0x6BF1",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "249"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0x71E0",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "229"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0x74E4",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "248"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0x8555",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "166"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0x9454",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "219"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0x96AA",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "125"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0xA1C1",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "165"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0xA346",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "207"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0xB665",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "159"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0xB7CD",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "237"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0xB86D",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "151"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0xD423",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "114"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0xE000",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "170"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0xE583",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "227"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0xF13B",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "130"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0xF98F",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "197"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0xFCDE",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "217"
      },
      {
        "device_type": "Router",
        "rx_on_when_idle": "On",
        "relationship": "Sibling",
        "extended_pan_id": "**REDACTED**",
        "ieee": "**REDACTED**",
        "nwk": "0xFE55",
        "permit_joining": "Unknown",
        "depth": "15",
        "lqi": "142"
      }
    ],
    "routes": [
      {
        "dest_nwk": "0x0000",
        "route_status": "Active",
        "memory_constrained": true,
        "many_to_one": true,
        "route_record_required": false,
        "next_hop": "0xE000"
      },
      {
        "dest_nwk": "0xC50E",
        "route_status": "Discovery_Underway",
        "memory_constrained": false,
        "many_to_one": false,
        "route_record_required": false,
        "next_hop": "0x0000"
      },
      {
        "dest_nwk": "0xF98F",
        "route_status": "Active",
        "memory_constrained": false,
        "many_to_one": false,
        "route_record_required": false,
        "next_hop": "0xF98F"
      },
      {
        "dest_nwk": "0x41BB",
        "route_status": "Discovery_Underway",
        "memory_constrained": false,
        "many_to_one": false,
        "route_record_required": false,
        "next_hop": "0x0000"
      }
    ],
    "endpoint_names": [
      {
        "name": "OCCUPANCY_SENSOR"
      }
    ],
    "user_given_name": "Senzor p\u0159\u00edtomnosti - koupelna",
    "device_reg_id": "99c6c0674652921dd0bb282e74be7bfb",
    "area_id": "koupelna",
    "cluster_details": {
      "1": {
        "device_type": {
          "name": "OCCUPANCY_SENSOR",
          "id": 263
        },
        "profile_id": 260,
        "in_clusters": {
          "0x0000": {
            "endpoint_attribute": "basic",
            "attributes": {
              "0x0001": {
                "attribute_name": "app_version",
                "value": 68
              },
              "0x0004": {
                "attribute_name": "manufacturer",
                "value": "_TZE200_jva8ink8"
              },
              "0x0005": {
                "attribute_name": "model",
                "value": "TS0601"
              },
              "0x0000": {
                "attribute_name": "zcl_version",
                "value": 3
              }
            },
            "unsupported_attributes": {
              "0x0012": {
                "attribute_name": "device_enabled"
              },
              "0x000c": {
                "attribute_name": "manufacturer_version_details"
              }
            }
          },
          "0x0004": {
            "endpoint_attribute": "groups",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x0005": {
            "endpoint_attribute": "scenes",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0xef00": {
            "endpoint_attribute": "tuya_manufacturer",
            "attributes": {
              "0xef65": {
                "attribute_name": "dp_101",
                "value": 1
              },
              "0xef66": {
                "attribute_name": "dp_102",
                "value": "10"
              },
              "0xef67": {
                "attribute_name": "dp_103",
                "value": " "
              },
              "0xef02": {
                "attribute_name": "dp_2",
                "value": 7
              },
              "0xef03": {
                "attribute_name": "dp_3",
                "value": 60
              },
              "0xef04": {
                "attribute_name": "dp_4",
                "value": 600
              },
              "0xef06": {
                "attribute_name": "dp_6",
                "value": 1
              },
              "0xef00": {
                "attribute_name": "mcu_version",
                "value": "2.0.9"
              }
            },
            "unsupported_attributes": {}
          },
          "0x0406": {
            "endpoint_attribute": "occupancy",
            "attributes": {
              "0x0000": {
                "attribute_name": "occupancy",
                "value": 0
              },
              "0x0020": {
                "attribute_name": "ultrasonic_o_to_u_delay",
                "value": 600
              }
            },
            "unsupported_attributes": {}
          },
          "0x000c": {
            "endpoint_attribute": "analog_input",
            "attributes": {
              "0x0055": {
                "attribute_name": "present_value",
                "value": 0.0
              }
            },
            "unsupported_attributes": {}
          },
          "0x0400": {
            "endpoint_attribute": "illuminance",
            "attributes": {
              "0x0000": {
                "attribute_name": "measured_value",
                "value": 3011.299956639812
              }
            },
            "unsupported_attributes": {}
          }
        },
        "out_clusters": {
          "0x000a": {
            "endpoint_attribute": "time",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x0019": {
            "endpoint_attribute": "ota",
            "attributes": {},
            "unsupported_attributes": {}
          }
        }
      }
    }
  }
}

Logs

Logs
[Paste the logs here]

Custom quirk

Custom quirk
"""BlitzWolf IS-3/Tuya motion rechargeable occupancy sensor."""

import math
from typing import Dict, Optional, Tuple, Union

from zigpy.profiles import zgp, zha
from zigpy.quirks import CustomDevice
import zigpy.types as t
from zigpy.zcl import foundation
from zigpy.zcl.clusters.general import (
    AnalogInput,
    Basic,
    GreenPowerProxy,
    Groups,
    Identify,
    Ota,
    Scenes,
    Time,
)
from zigpy.zcl.clusters.measurement import (
    IlluminanceMeasurement,
    OccupancySensing,
    RelativeHumidity,
    TemperatureMeasurement,
)
from zigpy.zcl.clusters.security import IasZone

from zhaquirks import Bus, LocalDataCluster, MotionOnEvent
from zhaquirks.const import (
    DEVICE_TYPE,
    ENDPOINTS,
    INPUT_CLUSTERS,
    MODELS_INFO,
    MOTION_EVENT,
    OUTPUT_CLUSTERS,
    PROFILE_ID,
)
from zhaquirks.tuya import (
    DPToAttributeMapping,
    TuyaLocalCluster,
    TuyaManufCluster,
    TuyaNewManufCluster,
)
from zhaquirks.tuya.mcu import TuyaMCUCluster

ZONE_TYPE = 0x0001


class TuyaOccupancySensing(OccupancySensing, TuyaLocalCluster):
    """Tuya local OccupancySensing cluster."""


class TuyaAnalogInput(AnalogInput, TuyaLocalCluster):
    """Tuya local AnalogInput cluster."""


class TuyaIlluminanceMeasurement(IlluminanceMeasurement, TuyaLocalCluster):
    """Tuya local IlluminanceMeasurement cluster."""


class TuyaTemperatureMeasurement(TemperatureMeasurement, TuyaLocalCluster):
    """Tuya local TemperatureMeasurement cluster."""


class TuyaRelativeHumidity(RelativeHumidity, TuyaLocalCluster):
    """Tuya local RelativeHumidity cluster."""


class NeoBatteryLevel(t.enum8):
    """NEO battery level enum."""

    BATTERY_FULL = 0x00
    BATTERY_HIGH = 0x01
    BATTERY_MEDIUM = 0x02
    BATTERY_LOW = 0x03
    USB_POWER = 0x04


class NeoMotionManufCluster(TuyaNewManufCluster):
    """Neo manufacturer cluster."""

    attributes = TuyaNewManufCluster.attributes.copy()
    attributes.update(
        {
            0xEF0D: ("dp_113", t.enum8, True),  # ramdom attribute ID
        }
    )

    dp_to_attribute: Dict[int, DPToAttributeMapping] = {
        101: DPToAttributeMapping(
            TuyaOccupancySensing.ep_attribute,
            "occupancy",
        ),
        104: DPToAttributeMapping(
            TuyaTemperatureMeasurement.ep_attribute,
            "measured_value",
            lambda x: x * 10,
        ),
        105: DPToAttributeMapping(
            TuyaRelativeHumidity.ep_attribute,
            "measured_value",
            lambda x: x * 100,
        ),
        113: DPToAttributeMapping(
            TuyaNewManufCluster.ep_attribute,
            "dp_113",
        ),
    }

    data_point_handlers = {
        101: "_dp_2_attr_update",
        104: "_dp_2_attr_update",
        105: "_dp_2_attr_update",
        113: "_dp_2_attr_update",
    }


class MmwRadarManufCluster(TuyaMCUCluster):
    """Neo manufacturer cluster."""

    # # Possible DPs and values
    # presence_state: presence
    # target distance: 1.61m
    # illuminance: 250lux
    # sensitivity: 9
    # minimum_detection_distance: 0.00m
    # maximum_detection_distance: 4.05m
    # dp_detection_delay: 0.1
    # dp_fading_time: 5.0
    # ¿illuminance?: 255lux
    # presence_brightness: no control
    # no_one_brightness: no control
    # current_brightness: off

    attributes = TuyaMCUCluster.attributes.copy()
    attributes.update(
        {
            # ramdom attribute IDs
            0xEF02: ("dp_2", t.uint32_t, True),
            0xEF03: ("dp_3", t.uint32_t, True),
            0xEF04: ("dp_4", t.uint32_t, True),
            0xEF06: ("dp_6", t.enum8, True),
            0xEF65: ("dp_101", t.uint32_t, True),
            0xEF66: ("dp_102", t.uint32_t, True),
            0xEF67: ("dp_103", t.CharacterString, True),
            0xEF69: ("dp_105", t.enum8, True),
            0xEF6A: ("dp_106", t.enum8, True),
            0xEF6B: ("dp_107", t.enum8, True),
            0xEF6C: ("dp_108", t.uint32_t, True),
        }
    )

    dp_to_attribute: Dict[int, DPToAttributeMapping] = {
        1: DPToAttributeMapping(
            TuyaOccupancySensing.ep_attribute,
            "occupancy",
        ),
        2: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_2",
        ),
        3: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_3",
        ),
        4: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_4",
        ),
        6: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_6",
        ),
        9: DPToAttributeMapping(
            TuyaAnalogInput.ep_attribute,
            "present_value",
            lambda x: x / 100,
        ),
        101: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_101",
        ),
        102: DPToAttributeMapping(
            TuyaOccupancySensing.ep_attribute,
            "ultrasonic_o_to_u_delay",
        ),
        103: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_103",
        ),
        104: DPToAttributeMapping(
            TuyaIlluminanceMeasurement.ep_attribute,
            "measured_value",
            lambda x: 10000 * math.log10(x) + 1 if x != 0 else 0,
        ),
        105: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_105",
        ),
        106: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_106",
        ),
        107: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_107",
        ),
        108: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_108",
        ),
    }

    data_point_handlers = {
        1: "_dp_2_attr_update",
        2: "_dp_2_attr_update",
        3: "_dp_2_attr_update",
        4: "_dp_2_attr_update",
        6: "_dp_2_attr_update",
        9: "_dp_2_attr_update",
        101: "_dp_2_attr_update",
        102: "_dp_2_attr_update",
        103: "_dp_2_attr_update",
        104: "_dp_2_attr_update",
        105: "_dp_2_attr_update",
        106: "_dp_2_attr_update",
        107: "_dp_2_attr_update",
        108: "_dp_2_attr_update",
    }


class MotionCluster(LocalDataCluster, MotionOnEvent):
    """Tuya Motion Sensor."""

    _CONSTANT_ATTRIBUTES = {ZONE_TYPE: IasZone.ZoneType.Motion_Sensor}
    reset_s = 15


class TuyaManufacturerClusterMotion(TuyaManufCluster):
    """Manufacturer Specific Cluster of the Motion device."""

    def handle_cluster_request(
        self,
        hdr: foundation.ZCLHeader,
        args: Tuple[TuyaManufCluster.Command],
        *,
        dst_addressing: Optional[
            Union[t.Addressing.Group, t.Addressing.IEEE, t.Addressing.NWK]
        ] = None,
    ) -> None:
        """Handle cluster request."""
        tuya_cmd = args[0]
        self.debug("handle_cluster_request--> hdr: %s, args: %s", hdr, args)
        if hdr.command_id == 0x0001 and tuya_cmd.command_id == 1027:
            self.endpoint.device.motion_bus.listener_event(MOTION_EVENT)


class TuyaMotion(CustomDevice):
    """BW-IS3 occupancy sensor."""

    def __init__(self, *args, **kwargs):
        """Init device."""
        self.motion_bus = Bus()
        super().__init__(*args, **kwargs)

    signature = {
        #  endpoint=1 profile=260 device_type=0 device_version=0 input_clusters=[0, 3]
        #  output_clusters=[3, 25]>
        MODELS_INFO: [("_TYST11_i5j6ifxj", "5j6ifxj"), ("_TYST11_7hfcudw5", "hfcudw5")],
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.ON_OFF_SWITCH,
                INPUT_CLUSTERS: [Basic.cluster_id, Identify.cluster_id],
                OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id],
            }
        },
    }

    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.OCCUPANCY_SENSOR,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Identify.cluster_id,
                    MotionCluster,
                    TuyaManufacturerClusterMotion,
                ],
                OUTPUT_CLUSTERS: [Identify.cluster_id, Ota.cluster_id],
            }
        }
    }


class NeoMotion(CustomDevice):
    """NAS-PD07 occupancy sensor."""

    signature = {
        #  endpoint=1 profile=260 device_type=81 device_version=0 input_clusters=[0, 4, 5, 61184]
        #  output_clusters=[10, 25]>
        MODELS_INFO: [
            ("_TZE200_7hfcudw5", "TS0601"),
            ("_TZE200_ppuj1vem", "TS0601"),
        ],
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    NeoMotionManufCluster.cluster_id,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            }
        },
    }

    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.OCCUPANCY_SENSOR,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    NeoMotionManufCluster,
                    TuyaOccupancySensing,
                    TuyaTemperatureMeasurement,
                    TuyaRelativeHumidity,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            }
        }
    }


class MmwRadarMotion(CustomDevice):
    """Millimeter wave occupancy sensor."""

    signature = {
        #  endpoint=1, profile=260, device_type=81, device_version=1,
        #  input_clusters=[0, 4, 5, 61184], output_clusters=[25, 10]
        MODELS_INFO: [
            ("_TZE200_ar0slwnd", "TS0601"),
            ("_TZE200_sfiy5tfs", "TS0601"),
            ("_TZE200_mrf6vtua", "TS0601"),
            ("_TZE200_ztc6ggyl", "TS0601"),
            ("_TZE204_ztc6ggyl", "TS0601"),
            ("_TZE200_wukb7rhc", "TS0601"),
            ("_TZE200_jva8ink8", "TS0601"),
        ],
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaNewManufCluster.cluster_id,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
        },
    }

    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.OCCUPANCY_SENSOR,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    MmwRadarManufCluster,
                    TuyaOccupancySensing,
                    TuyaAnalogInput,
                    TuyaIlluminanceMeasurement,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
        }
    }


class MmwRadarMotionGPP(CustomDevice):
    """Millimeter wave occupancy sensor."""

    signature = {
        #  endpoint=1, profile=260, device_type=81, device_version=1,
        #  input_clusters=[4, 5, 61184, 0], output_clusters=[25, 10])
        MODELS_INFO: [
            ("_TZE200_ar0slwnd", "TS0601"),
            ("_TZE200_sfiy5tfs", "TS0601"),
            ("_TZE200_mrf6vtua", "TS0601"),
        ],
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.SMART_PLUG,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    TuyaNewManufCluster.cluster_id,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
            242: {
                # <SimpleDescriptor endpoint=242 profile=41440 device_type=97
                # input_clusters=[]
                # output_clusters=[33]
                PROFILE_ID: zgp.PROFILE_ID,
                DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
                INPUT_CLUSTERS: [],
                OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
            },
        },
    }

    replacement = {
        ENDPOINTS: {
            1: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.OCCUPANCY_SENSOR,
                INPUT_CLUSTERS: [
                    Basic.cluster_id,
                    Groups.cluster_id,
                    Scenes.cluster_id,
                    MmwRadarManufCluster,
                    TuyaOccupancySensing,
                    TuyaAnalogInput,
                    TuyaIlluminanceMeasurement,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
            242: {
                PROFILE_ID: zgp.PROFILE_ID,
                DEVICE_TYPE: zgp.DeviceType.PROXY_BASIC,
                INPUT_CLUSTERS: [],
                OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
            },
        }
    }

Additional information

No response

bzumik1 avatar Aug 24 '23 16:08 bzumik1

Hi, could someone please help me to get this device working?

bzumik1 avatar Aug 29 '23 21:08 bzumik1

Hi, any update?

bzumik1 avatar Sep 01 '23 22:09 bzumik1

To get support post at least Device signature

evgenln avatar Sep 03 '23 19:09 evgenln

Thanks for response evgenln, could you please let me know how I can get the device signature?

bzumik1 avatar Sep 03 '23 20:09 bzumik1

To get support post at least Device signature

@evgenln could you please check if the signature I have provided is the correct one?

bzumik1 avatar Sep 08 '23 08:09 bzumik1

Also I am using custom quirk to get the basic functionality I hope this does not change the signature of the device.

"data": {
    "ieee": "**REDACTED**",
    "nwk": 51522,
    "manufacturer": "_TZE200_jva8ink8",
    "model": "TS0601",
    "name": "_TZE200_jva8ink8 TS0601",
    "quirk_applied": true,
    "quirk_class": "ts0601_motion.MmwRadarMotion",
    "manufacturer_code": 4098,
    "power_source": "Mains",
    "lqi": 200,
    "rssi": -50,
    "last_seen": "2023-09-08T10:41:55",
    "available": true,
    "device_type": "Router",
    "signature": {
      "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.FullFunctionDevice|MainsPowered|RxOnWhenIdle|AllocateAddress: 142>, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)",
      "endpoints": {
        "1": {
          "profile_id": "0x0104",
          "device_type": "0x0107",
          "input_clusters": [
            "0x0000",
            "0x0004",
            "0x0005",
            "0x000c",
            "0x0400",
            "0x0406",
            "0xef00"
          ],
          "output_clusters": [
            "0x000a",
            "0x0019"
          ]
        }
      },
      "manufacturer": "_TZE200_jva8ink8",
      "model": "TS0601"
    },
    "active_coordinator": false,
    "entities": [
      {
        "entity_id": "binary_sensor.senzor_pritomnosti_koupelna_pritomnost",
        "name": "_TZE200_jva8ink8 TS0601"
      },
      {
        "entity_id": "sensor.senzor_pritomnosti_koupelna_intenzita_osvetleni",
        "name": "_TZE200_jva8ink8 TS0601"
      }
    ],

bzumik1 avatar Sep 08 '23 08:09 bzumik1

ts0601_motion (7).zip try

evgenln avatar Sep 10 '23 17:09 evgenln

Will try thank you

bzumik1 avatar Sep 10 '23 18:09 bzumik1

Unless I am doing something wrong, it doesn't seem to work. I have uploaded the file you gave me to custom_zha_quirks and restarted HA. When it started I see the sensor there but no entities are available. My old custom quirk was able to provide me with some basics (presence, luminance). I was not able to set the cool down etc. though. I will upload here my custom quirk, maybe it will be able to help you. I could not get further with it unfortunately.

bzumik1 avatar Sep 10 '23 20:09 bzumik1

Here are also logs it took during the start if it is helpful. zha-log.txt

bzumik1 avatar Sep 10 '23 20:09 bzumik1

ah, I was looking to wrong signature This one should work ts0601_motion (8).zip

evgenln avatar Sep 10 '23 21:09 evgenln

This one looks much better, now I can see these entities:

image

the translated ones are luminance and presence. Thanks a lot for your help. What are the next steps?

bzumik1 avatar Sep 11 '23 06:09 bzumik1

@evgenln is there something we should test before this will be merged to master?

bzumik1 avatar Sep 24 '23 12:09 bzumik1

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

github-actions[bot] avatar Mar 22 '24 12:03 github-actions[bot]

I still had to resort to (an adapted version of) this quirk for Home Assistant 2024.4.1.

Tuya had a link to the following printed in the manual accompanying my sensor (TS0601 / _TZE204_e5m9c5hl ) https://github.com/wzwenzhi/Wenzhi-ZigBee2mqtt/tree/main maybe a proper quirk can be upstreamed based on this information for ZHA?

freqmod avatar Apr 29 '24 16:04 freqmod