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 10 months 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