Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Device Support Request] ZY-M100 #2378

Closed
diogo-madeira opened this issue May 4, 2023 · 193 comments
Closed

[Device Support Request] ZY-M100 #2378

diogo-madeira opened this issue May 4, 2023 · 193 comments
Labels
custom quirk available A custom quirk is available to solve the issue, but it's not merged in the repo yet stale Issue is inactivate and might get closed soon Tuya Request/PR regarding a Tuya device

Comments

@diogo-madeira
Copy link

diogo-madeira commented May 4, 2023

Problem description

It apears in HA, but without any sensor.

Solution description

Any

Screenshots/Video

Screenshots/Video

[Paste/upload your media here]

Device signature

Device 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.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)",
  "endpoints": {
    "1": {
      "profile_id": "0x0104",
      "device_type": "0x0051",
      "input_clusters": [
        "0x0000",
        "0x0004",
        "0x0005",
        "0xef00"
      ],
      "output_clusters": [
        "0x000a",
        "0x0019"
      ]
    },
    "242": {
      "profile_id": "0xa1e0",
      "device_type": "0x0061",
      "input_clusters": [],
      "output_clusters": [
        "0x0021"
      ]
    }
  },
  "manufacturer": "_TZE204_sxm7l9xa",
  "model": "TS0601",
  "class": "zigpy.device.Device"
}

Diagnostic information

Diagnostic information
{
  "home_assistant": {
    "installation_type": "Home Assistant OS",
    "version": "2023.5.0",
    "dev": false,
    "hassio": true,
    "virtualenv": false,
    "python_version": "3.10.11",
    "docker": true,
    "arch": "x86_64",
    "timezone": "America/Recife",
    "os_name": "Linux",
    "os_version": "6.1.25",
    "supervisor": "2023.04.1",
    "host_os": "Home Assistant OS 10.1",
    "docker_version": "23.0.3",
    "chassis": "vm",
    "run_as_root": true
  },
  "custom_components": {
    "sonoff": {
      "version": "3.5.1",
      "requirements": [
        "pycryptodome>=3.6.6"
      ]
    },
    "nodered": {
      "version": "1.2.0",
      "requirements": []
    },
    "smartir": {
      "version": "1.17.6",
      "requirements": [
        "aiofiles==0.6.0"
      ]
    },
    "powercalc": {
      "version": "v1.5.1",
      "requirements": [
        "numpy>=1.21.1"
      ]
    },
    "hacs": {
      "version": "1.32.1",
      "requirements": [
        "aiogithubapi>=22.10.1"
      ]
    },
    "thermal_comfort": {
      "version": "2.1.1",
      "requirements": []
    },
    "nuki_ng": {
      "version": "0.2.1",
      "requirements": []
    },
    "ytube_music_player": {
      "version": "20230321.01",
      "requirements": [
        "ytmusicapi==0.25.0",
        "pytube==10.5.1",
        "integrationhelper==0.2.2"
      ]
    },
    "google_photos": {
      "version": "v0.5.0",
      "requirements": [
        "google-api-python-client>=2.71.0",
        "pillow>=9.1.1,<10.0.0"
      ]
    },
    "ble_monitor": {
      "version": "11.11.1",
      "requirements": [
        "pycryptodomex>=3.14.1",
        "janus>=1.0.0",
        "aioblescan>=0.2.14",
        "btsocket>=0.2.0",
        "pyric>=0.1.6.3"
      ]
    },
    "browser_mod": {
      "version": "2.2.1",
      "requirements": []
    },
    "xiaomi_cloud_map_extractor": {
      "version": "v2.2.0",
      "requirements": [
        "pillow",
        "pybase64",
        "python-miio",
        "requests",
        "pycryptodome"
      ]
    }
  },
  "integration_manifest": {
    "domain": "zha",
    "name": "Zigbee Home Automation",
    "after_dependencies": [
      "onboarding",
      "usb"
    ],
    "codeowners": [
      "@dmulcahey",
      "@adminiuga",
      "@puddly"
    ],
    "config_flow": true,
    "dependencies": [
      "file_upload"
    ],
    "documentation": "https://www.home-assistant.io/integrations/zha",
    "iot_class": "local_polling",
    "loggers": [
      "aiosqlite",
      "bellows",
      "crccheck",
      "pure_pcapy3",
      "zhaquirks",
      "zigpy",
      "zigpy_deconz",
      "zigpy_xbee",
      "zigpy_zigate",
      "zigpy_znp"
    ],
    "requirements": [
      "bellows==0.35.2",
      "pyserial==3.5",
      "pyserial-asyncio==0.6",
      "zha-quirks==0.0.99",
      "zigpy-deconz==0.21.0",
      "zigpy==0.55.0",
      "zigpy-xbee==0.18.0",
      "zigpy-zigate==0.11.0",
      "zigpy-znp==0.11.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"
        ]
      }
    ],
    "zeroconf": [
      {
        "type": "_esphomelib._tcp.local.",
        "name": "tube*"
      },
      {
        "type": "_zigate-zigbee-gateway._tcp.local.",
        "name": "*zigate*"
      },
      {
        "type": "_zigstar_gw._tcp.local.",
        "name": "*zigstar*"
      },
      {
        "type": "_slzb-06._tcp.local.",
        "name": "slzb-06*"
      }
    ],
    "is_built_in": true
  },
  "data": {
    "ieee": "**REDACTED**",
    "nwk": 49103,
    "manufacturer": "_TZE204_sxm7l9xa",
    "model": "TS0601",
    "name": "_TZE204_sxm7l9xa TS0601",
    "quirk_applied": false,
    "quirk_class": "zigpy.device.Device",
    "manufacturer_code": 4417,
    "power_source": "Mains",
    "lqi": 98,
    "rssi": null,
    "last_seen": "2023-05-04T09:59:08",
    "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.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)",
      "endpoints": {
        "1": {
          "profile_id": "0x0104",
          "device_type": "0x0051",
          "input_clusters": [
            "0x0000",
            "0x0004",
            "0x0005",
            "0xef00"
          ],
          "output_clusters": [
            "0x000a",
            "0x0019"
          ]
        },
        "242": {
          "profile_id": "0xa1e0",
          "device_type": "0x0061",
          "input_clusters": [],
          "output_clusters": [
            "0x0021"
          ]
        }
      },
      "manufacturer": "_TZE204_sxm7l9xa",
      "model": "TS0601"
    },
    "active_coordinator": false,
    "entities": [],
    "neighbors": [],
    "routes": [],
    "endpoint_names": [
      {
        "name": "SMART_PLUG"
      },
      {
        "name": "unknown 97 device_type of 0xa1e0 profile id"
      }
    ],
    "user_given_name": "Radar",
    "device_reg_id": "147de22f46ce6385a2bf8b83e1363256",
    "area_id": null,
    "cluster_details": {
      "1": {
        "device_type": {
          "name": "SMART_PLUG",
          "id": 81
        },
        "profile_id": 260,
        "in_clusters": {
          "0x0004": {
            "endpoint_attribute": "groups",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x0005": {
            "endpoint_attribute": "scenes",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0xef00": {
            "endpoint_attribute": null,
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x0000": {
            "endpoint_attribute": "basic",
            "attributes": {
              "0x0001": {
                "attribute_name": "app_version",
                "value": 74
              },
              "0x0004": {
                "attribute_name": "manufacturer",
                "value": "_TZE204_sxm7l9xa"
              },
              "0x0005": {
                "attribute_name": "model",
                "value": "TS0601"
              }
            },
            "unsupported_attributes": {}
          }
        },
        "out_clusters": {
          "0x0019": {
            "endpoint_attribute": "ota",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x000a": {
            "endpoint_attribute": "time",
            "attributes": {},
            "unsupported_attributes": {}
          }
        }
      },
      "242": {
        "device_type": {
          "name": "unknown",
          "id": 97
        },
        "profile_id": 41440,
        "in_clusters": {},
        "out_clusters": {
          "0x0021": {
            "endpoint_attribute": "green_power",
            "attributes": {},
            "unsupported_attributes": {}
          }
        }
      }
    }
  }
}

Logs

Logs
[Paste the logs here]

Custom quirk

Custom quirk
[Paste your custom quirk here]

Additional information

No response

@b2un0
Copy link
Contributor

b2un0 commented May 10, 2023

relates to Koenkk/zigbee2mqtt#17483

@b2un0
Copy link
Contributor

b2un0 commented May 10, 2023

Details

{
  "home_assistant": {
    "installation_type": "Home Assistant Container",
    "version": "2023.5.2",
    "dev": false,
    "hassio": false,
    "virtualenv": false,
    "python_version": "3.10.11",
    "docker": true,
    "arch": "aarch64",
    "timezone": "Europe/Berlin",
    "os_name": "Linux",
    "os_version": "6.1.21-v8+",
    "run_as_root": true
  },
  "custom_components": {
    "zha_toolkit": {
      "version": "v0.8.39",
      "requirements": [
        "packaging>=20.8",
        "pytz"
      ]
    },
    "xiaomi_miio_fan": {
      "version": "2022.8.0.0",
      "requirements": [
        "construct==2.10.56",
        "python-miio>=0.5.12"
      ]
    },
    "localtuya": {
      "version": "5.0.0",
      "requirements": []
    },
    "avanza_stock": {
      "version": "1.2.0",
      "requirements": [
        "pyavanza==0.6.0"
      ]
    },
    "xiaomi_miot": {
      "version": "0.7.8",
      "requirements": [
        "construct==2.10.56",
        "python-miio>=0.5.6",
        "micloud>=0.3"
      ]
    },
    "hacs": {
      "version": "1.32.1",
      "requirements": [
        "aiogithubapi>=22.10.1"
      ]
    },
    "auto_backup": {
      "version": "1.3.2",
      "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"
    ],
    "requirements": [
      "bellows==0.35.2",
      "pyserial==3.5",
      "pyserial-asyncio==0.6",
      "zha-quirks==0.0.99",
      "zigpy-deconz==0.21.0",
      "zigpy==0.55.0",
      "zigpy-xbee==0.18.0",
      "zigpy-zigate==0.11.0",
      "zigpy-znp==0.11.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"
        ]
      }
    ],
    "zeroconf": [
      {
        "type": "_esphomelib._tcp.local.",
        "name": "tube*"
      },
      {
        "type": "_zigate-zigbee-gateway._tcp.local.",
        "name": "*zigate*"
      },
      {
        "type": "_zigstar_gw._tcp.local.",
        "name": "*zigstar*"
      },
      {
        "type": "_slzb-06._tcp.local.",
        "name": "slzb-06*"
      }
    ],
    "is_built_in": true
  },
  "data": {
    "ieee": "**REDACTED**",
    "nwk": 37381,
    "manufacturer": "_TZE204_sxm7l9xa",
    "model": "TS0601",
    "name": "_TZE204_sxm7l9xa TS0601",
    "quirk_applied": false,
    "quirk_class": "zigpy.device.Device",
    "manufacturer_code": 4417,
    "power_source": "Mains",
    "lqi": 255,
    "rssi": -31,
    "last_seen": "2023-05-10T16:50:41",
    "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.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)",
      "endpoints": {
        "1": {
          "profile_id": "0x0104",
          "device_type": "0x0051",
          "input_clusters": [
            "0x0000",
            "0x0004",
            "0x0005",
            "0xef00"
          ],
          "output_clusters": [
            "0x000a",
            "0x0019"
          ]
        },
        "242": {
          "profile_id": "0xa1e0",
          "device_type": "0x0061",
          "input_clusters": [],
          "output_clusters": [
            "0x0021"
          ]
        }
      },
      "manufacturer": "_TZE204_sxm7l9xa",
      "model": "TS0601"
    },
    "active_coordinator": false,
    "entities": [],
    "neighbors": [],
    "routes": [],
    "endpoint_names": [
      {
        "name": "SMART_PLUG"
      },
      {
        "name": "unknown 97 device_type of 0xa1e0 profile id"
      }
    ],
    "user_given_name": null,
    "device_reg_id": "adde545ae3ac7c4a6087c835d1180281",
    "area_id": null,
    "cluster_details": {
      "1": {
        "device_type": {
          "name": "SMART_PLUG",
          "id": 81
        },
        "profile_id": 260,
        "in_clusters": {
          "0x0004": {
            "endpoint_attribute": "groups",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x0005": {
            "endpoint_attribute": "scenes",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0xef00": {
            "endpoint_attribute": null,
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x0000": {
            "endpoint_attribute": "basic",
            "attributes": {
              "0x0004": {
                "attribute_name": "manufacturer",
                "value": "_TZE204_sxm7l9xa"
              },
              "0x0005": {
                "attribute_name": "model",
                "value": "TS0601"
              }
            },
            "unsupported_attributes": {}
          }
        },
        "out_clusters": {
          "0x0019": {
            "endpoint_attribute": "ota",
            "attributes": {},
            "unsupported_attributes": {}
          },
          "0x000a": {
            "endpoint_attribute": "time",
            "attributes": {},
            "unsupported_attributes": {}
          }
        }
      },
      "242": {
        "device_type": {
          "name": "unknown",
          "id": 97
        },
        "profile_id": 41440,
        "in_clusters": {},
        "out_clusters": {
          "0x0021": {
            "endpoint_attribute": "green_power",
            "attributes": {},
            "unsupported_attributes": {}
          }
        }
      }
    }
  }
}

Nwk: 0x9205
Pairing Log:
home-assistant_zha_2023-05-10T14-48-30.769Z.log

--

the device looks like the same as _TZE204_ztc6ggyl which is available in

("_TZE204_ztc6ggyl", "TS0601"),

duplicated the ts0601_motion.py to my quirks folder and added the _TZE204_sxm7l9xa under the _TZE204_ztc6ggyl line.
But the quirk does not applied. don't know why..

@Woll3
Copy link

Woll3 commented May 10, 2023

Details

Nwk: 0x9205 Pairing Log: home-assistant_zha_2023-05-10T14-48-30.769Z.log

--

the device looks like the same as _TZE204_ztc6ggyl which is available in

("_TZE204_ztc6ggyl", "TS0601"),

duplicated the ts0601_motion.py to my quirks folder and added the _TZE204_sxm7l9xa under the _TZE204_ztc6ggyl line. But the quirk does not applied. don't know why..

Thanks for the hint! 👍
For me, this doesn't work.
I tried the following two quirks:

}, "data": { "ieee": "**REDACTED**", "nwk": 22172, "manufacturer": "_TZE204_sxm7l9xa", "model": "TS0601", "name": "_TZE204_sxm7l9xa TS0601", "quirk_applied": true, "quirk_class": "ts0601_human_presence_sensor.MmwRadarMotion_var03", "manufacturer_code": 4417, "power_source": "Mains", "lqi": 255, "rssi": -70, "last_seen": "2023-05-11T00:01:10", "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.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)", "endpoints": { "1": { "profile_id": "0x0104", "device_type": "0x0107", "input_clusters": [ "0x0000", "0x0004", "0x0005", "0x0006", "0x0406", "0xef00" ], "output_clusters": [ "0x000a", "0x0019" ] }, "242": { "profile_id": "0xa1e0", "device_type": "0x0061", "input_clusters": [], "output_clusters": [ "0x0021" ] } }, "manufacturer": "_TZE204_sxm7l9xa", "model": "TS0601" },

@programmieramt
Copy link

Hello, I just had the same issues with zigbee2mqtt:

The _TZE204_ztc6ggyl has different "datapoints" then the _TZE204_sxm7l9xa so it is not done with just adding the manufacture id.
For z2mqtt you see the differents here: Koenkk/zigbee2mqtt#17483 (comment)

Never worked with quirks but will try to check if possible

@programmieramt
Copy link

Here is the description for the datapoints:

104 - Lux
105 - Presence
106 - Motion sensitivity
107 - Max detection distance
108 - Min detection distance
109 - Target distance
110 - Detection delay
111 - Fading time

@Woll3
Copy link

Woll3 commented May 15, 2023

"""ZY-M100 Human Presence Sensor"""
#https://github.com/zigpy/zha-device-handlers/issues/2378


#based on
#"""BlitzWolf IS-3/Tuya motion rechargeable occupancy sensor."""
#https://github.com/zigpy/zha-device-handlers/blob/a221e682e9baffe95588eb6708d096cfc481cd5d/zhaquirks/tuya/ts0601_motion.py#L352

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

from zigpy.profiles import 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):
    """ZY-M100 manufacturer cluster."""

    attributes = TuyaMCUCluster.attributes.copy()
    attributes.update(
        {
            0xEF00: ("dp_0", t.CharacterString, True),
            0xEF68: ("dp_104", t.enum8, True),
            0xEF69: ("dp_105", t.enum8, True),
            0xEF6A: ("dp_106", t.enum8, True),
            0xEF6B: ("dp_107", t.uint16_t, True),
            0xEF6C: ("dp_108", t.uint16_t, True),
            0xEF6D: ("dp_109", t.uint16_t, True),
            0xEF6E: ("dp_110", t.uint8_t, True),
            0xEF6F: ("dp_111", t.uint8_t, True),
        }
    )

    dp_to_attribute: Dict[int, DPToAttributeMapping] = {
        104: DPToAttributeMapping(
            TuyaIlluminanceMeasurement.ep_attribute,
            "measured_value",
            lambda x: 10000 * math.log10(x) + 1 if x != 0 else 0,
        ),
        105: DPToAttributeMapping(
            TuyaOccupancySensing.ep_attribute,
            "occupancy",
        ),
        106: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_106",
        ),
        107: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_107",
        ),
        108: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_108",
        ),
        109: DPToAttributeMapping(
            TuyaAnalogInput.ep_attribute,
            "present_value",
            lambda x: x / 100,
        ),
        110: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_110",
        ),
        111: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "dp_111",
        ),
    }

    data_point_handlers = {
        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",
        109: "_dp_2_attr_update",
        110: "_dp_2_attr_update",
        111: "_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 MmwRadarMotionZYM100(CustomDevice):
    """ZY-M100 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: [
            ("_TZE204_sxm7l9xa", "TS0601")
        ],
        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: 41440,
                DEVICE_TYPE: 97,
                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: 41440,
                DEVICE_TYPE: 97,
                INPUT_CLUSTERS: [],
                OUTPUT_CLUSTERS: [GreenPowerProxy.cluster_id],
            },
        }
    }

I tried to modify this file but the code is not working. The sensor doesn't use the quirk! Mhh! Where is there error?

@programmieramt
Copy link

Did you just added the manufacturer Id? _TZE204_sxm7l9xa I think we have to do a new matching for the datapoints in the new quirk

@Woll3
Copy link

Woll3 commented May 16, 2023

Did you just added the manufacturer Id? _TZE204_sxm7l9xa I think we have to do a new matching for the datapoints in the new quirk

No, I tried to match the data points according to your table above -> #2378 (comment)

@hiscorebob
Copy link

I tried to modify this file but the code is not working. The sensor doesn't use the quirk! Mhh! Where is there error?

Never used a quirk before, this is also new to me.
I tried using your quirk, and noticed the Logs get flooded with "unknown cluster command" messages.

@TheJulianJES TheJulianJES added the Tuya Request/PR regarding a Tuya device label May 17, 2023
@dieneuser
Copy link

dieneuser commented May 20, 2023

Did you just added the manufacturer Id? _TZE204_sxm7l9xa I think we have to do a new matching for the datapoints in the new quirk

I can confirm the behavior. The Quirk does not seem to be used:
image
zha-796e67a077f16237422834223f8280f9-_TZE204_sxm7l9xa TS0601-b56351faae6a353ffd0cbb4ae7e1bb53.json.txt

The following message appears in the logger:

Logger: zigpy.zcl
Source: runner.py:179
First occurred: 13:36:19 (3938 occurrences)
Last logged: 13:54:27

- [0xFFDC:1:0xef00] Unknown cluster command 2 b'\x00\xf4n\x02\x00\x04\x00\x00\x00\x96'
- [0xFFDC:1:0xef00] Unknown cluster command 2 b'\x00\xf5m\x02\x00\x04\x00\x00\x00\x00'
- [0xFFDC:1:0xef00] Unknown cluster command 2 b'\x00\xf6i\x04\x00\x01\x00'
- [0xFFDC:1:0xef00] Unknown cluster command 2 b'\x00\xf7h\x02\x00\x04\x00\x00\x00['
- [0xFFDC:1:0xef00] Unknown cluster command 2 b'\x00\xf8m\x02\x00\x04\x00\x00\x00\x00'

@programmieramt
Copy link

I also tried several quirks and stuff but the device doesn’t use them

@rofo69
Copy link

rofo69 commented May 22, 2023

Really not sure which of the many threads about this device to post on, but I've managed to get the ZHA quirk working for me with the basic occupancy sensor and illuminance using this quirk that I put together from various others floating around:-

Its based on the _TZE204_sxm7l9xa variant.

Its basically Wolf's altered quirk above but I've changed the device signature to work with the _TZE204_sxm7l9xa variant.

If anyone can extend it to expose the configuration options that would be amazing.

ts0601_motion.zip

@NCC1941
Copy link

NCC1941 commented May 23, 2023

Really not sure which of the many threads about this device to post on, but I've managed to get the ZHA quirk working for me with the basic occupancy sensor and illuminance using this quirk that I put together from various others floating around:-

Its based on the _TZE204_sxm7l9xa variant.

Its basically Wolf's altered quirk above but I've changed the device signature to work with the _TZE204_sxm7l9xa variant.

If anyone can extend it to expose the configuration options that would be amazing.

ts0601_motion.zip

For whatever it's worth, the quirk you've provided didn't work with my _TZE204_sxm7l9xa. Similar result as above with the other quirk(s), my device just doesn't use the quirk.

In case it's relevant, I do also have a _TZE204_ztc6ggyl which I'm using with the other quirk that provides all of the configuration options. That one uses its quirk, and seems to work fine.

@programmieramt
Copy link

Really not sure which of the many threads about this device to post on, but I've managed to get the ZHA quirk working for me with the basic occupancy sensor and illuminance using this quirk that I put together from various others floating around:-
Its based on the _TZE204_sxm7l9xa variant.
Its basically Wolf's altered quirk above but I've changed the device signature to work with the _TZE204_sxm7l9xa variant.
If anyone can extend it to expose the configuration options that would be amazing.
ts0601_motion.zip

For whatever it's worth, the quirk you've provided didn't work with my _TZE204_sxm7l9xa. Similar result as above with the other quirk(s), my device just doesn't use the quirk.

In case it's relevant, I do also have a _TZE204_ztc6ggyl which I'm using with the other quirk that provides all of the configuration options. That one uses its quirk, and seems to work fine.

Same for me the quirk is not used

@rofo69
Copy link

rofo69 commented May 23, 2023

Can you post the device signature for the _TZE204_ztc6ggyl and your _TZE204_sxm7l9xa and I'll try to see why it's not picking up.

@programmieramt
Copy link

programmieramt commented May 23, 2023

Is this everyhting you need?

{
  "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.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=4417, maximum_buffer_size=66, maximum_incoming_transfer_size=66, server_mask=10752, maximum_outgoing_transfer_size=66, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)",
  "endpoints": {
    "1": {
      "profile_id": "0x0104",
      "device_type": "0x0051",
      "input_clusters": [
        "0x0000",
        "0x0004",
        "0x0005",
        "0xef00"
      ],
      "output_clusters": [
        "0x000a",
        "0x0019"
      ]
    },
    "242": {
      "profile_id": "0xa1e0",
      "device_type": "0x0061",
      "input_clusters": [],
      "output_clusters": [
        "0x0021"
      ]
    }
  },
  "manufacturer": "_TZE204_sxm7l9xa",
  "model": "TS0601",
  "class": "zigpy.device.Device"
}

Edit: I dont know why it is not formatted
Edit2: Now with the right signature @rofo69

@rofo69
Copy link

rofo69 commented May 23, 2023

Go to the device in zha click the the dots next to the reconfigure button. Then choose manage zigbee device then click signature and paste those for both your devices.

I have the _TZE204_sxm7l9xa working again. I must have broken something in the file I posted. I will upload in about an hour or so. I am away from my pc atm.

@rofo69
Copy link

rofo69 commented May 23, 2023

Can you also post the sig for _TZE204_ztc6ggyl

@programmieramt
Copy link

Can you also post the sig for _TZE204_ztc6ggyl

Here. This device works and also exposes the config values to the fronted

{
  "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.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 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",
        "0x000d",
        "0x0400",
        "0x0406",
        "0xef00"
      ],
      "output_clusters": [
        "0x000a",
        "0x0019"
      ]
    },
    "2": {
      "profile_id": "0x0104",
      "device_type": "0x0007",
      "input_clusters": [
        "0x000d"
      ],
      "output_clusters": []
    },
    "3": {
      "profile_id": "0x0104",
      "device_type": "0x0007",
      "input_clusters": [
        "0x000d"
      ],
      "output_clusters": []
    },
    "4": {
      "profile_id": "0x0104",
      "device_type": "0x0007",
      "input_clusters": [
        "0x000d"
      ],
      "output_clusters": []
    },
    "5": {
      "profile_id": "0x0104",
      "device_type": "0x0007",
      "input_clusters": [
        "0x000d"
      ],
      "output_clusters": []
    }
  },
  "manufacturer": "_TZE204_ztc6ggyl",
  "model": "TS0601",
  "class": "presence_new.TuyaMmwRadarOccupancy"
}

@rofo69
Copy link

rofo69 commented May 23, 2023

Could you unload your working quirk on _TZE204_ztc6ggyl then reload HA and show me what the sig looks like without the quirk loaded. Then you can put it back again.

@rofo69
Copy link

rofo69 commented May 23, 2023

I'll post my working basic quirk for _TZE204_sxm7l9xa in about 45 minutes when I am back.

@programmieramt
Copy link

Could you unload your working quirk on _TZE204_ztc6ggyl then reload HA and show me what the sig looks like without the quirk loaded. Then you can put it back again.

{
{
  "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.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 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": "_TZE204_ztc6ggyl",
  "model": "TS0601",
  "class": "zhaquirks.tuya.ts0601_motion.MmwRadarMotion"
}

This is the signature without the quirk. But without the quirk it does not exposed the config to HA

@rofo69
Copy link

rofo69 commented May 23, 2023

Thats fine, i just wanted to compare both against _TZE204_sxm7l9xa, as I'm no quirk expert.

Here is the correct quirk that gives at least some functionality. I've also corrected the original link above.

ts0601_motion.zip

I'll see if i can figure out how to expose the config entries.

@programmieramt
Copy link

programmieramt commented May 23, 2023

Thats fine, i just wanted to compare both against _TZE204_sxm7l9xa, as I'm no quirk expert.

Here is the correct quirk that gives at least some functionality. I've also corrected the original link above.

ts0601_motion.zip

I'll see if i can figure out how to expose the config entries.

Great. Looks good. The occupancy sensor is now exposed. Thank you


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

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

from zhaquirks import Bus, LocalDataCluster, MotionOnEvent
from zhaquirks.const import (
    DEVICE_TYPE,
    ENDPOINTS,
    INPUT_CLUSTERS,
    MODEL,
    MOTION_EVENT,
    OUTPUT_CLUSTERS,
    PROFILE_ID,
)

from zhaquirks.tuya import (
    NoManufacturerCluster,
    TuyaLocalCluster,
    TuyaNewManufCluster,
)
from zhaquirks.tuya.mcu import (
    # TuyaDPType,
    DPToAttributeMapping,
    TuyaAttributesCluster,
    TuyaMCUCluster,
)


class TuyaMmwRadarSelfTest(t.enum8):
    """Mmw radar self test values."""
    TESTING = 0
    TEST_SUCCESS = 1
    TEST_FAILURE = 2
    OTHER = 3
    COMM_FAULT = 4
    RADAR_FAULT = 5

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

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

class TuyaMmwRadarSensitivity(TuyaAttributesCluster, AnalogOutput):
    """AnalogOutput cluster for sensitivity."""

    def __init__(self, *args, **kwargs):
        """Init."""
        super().__init__(*args, **kwargs)
        self._update_attribute(
            self.attributes_by_name["description"].id, "Sensitivity"
        )
        self._update_attribute(self.attributes_by_name["min_present_value"].id, 1)
        self._update_attribute(self.attributes_by_name["max_present_value"].id, 9)
        self._update_attribute(self.attributes_by_name["resolution"].id, 1)

class TuyaMmwRadarMinRange(TuyaAttributesCluster, AnalogOutput):
    """AnalogOutput cluster for min range."""

    def __init__(self, *args, **kwargs):
        """Init."""
        super().__init__(*args, **kwargs)
        self._update_attribute(
            self.attributes_by_name["description"].id, "Min range"
        )
        self._update_attribute(self.attributes_by_name["min_present_value"].id, 0)
        self._update_attribute(self.attributes_by_name["max_present_value"].id, 950)
        self._update_attribute(self.attributes_by_name["resolution"].id, 10)
        self._update_attribute(
            self.attributes_by_name["engineering_units"].id, 118
        )  # 31: meters

class TuyaMmwRadarMaxRange(TuyaAttributesCluster, AnalogOutput):
    """AnalogOutput cluster for max range."""

    def __init__(self, *args, **kwargs):
        """Init."""
        super().__init__(*args, **kwargs)
        self._update_attribute(
            self.attributes_by_name["description"].id, "Max range"
        )
        self._update_attribute(self.attributes_by_name["min_present_value"].id, 0)
        self._update_attribute(self.attributes_by_name["max_present_value"].id, 950)
        self._update_attribute(self.attributes_by_name["resolution"].id, 10)
        self._update_attribute(
            self.attributes_by_name["engineering_units"].id, 118
        )  # 31: meters

class TuyaMmwRadarDetectionDelay(TuyaAttributesCluster, AnalogOutput):
    """AnalogOutput cluster for detection delay."""

    def __init__(self, *args, **kwargs):
        """Init."""
        super().__init__(*args, **kwargs)
        self._update_attribute(
            self.attributes_by_name["description"].id, "Detection delay"
        )
        self._update_attribute(self.attributes_by_name["min_present_value"].id, 000)
        self._update_attribute(self.attributes_by_name["max_present_value"].id, 20000)
        self._update_attribute(self.attributes_by_name["resolution"].id, 100)
        self._update_attribute(
            self.attributes_by_name["engineering_units"].id, 159
        )  # 73: seconds

class TuyaMmwRadarFadingTime(TuyaAttributesCluster, AnalogOutput):
    """AnalogOutput cluster for fading time."""

    def __init__(self, *args, **kwargs):
        """Init."""
        super().__init__(*args, **kwargs)
        self._update_attribute(
            self.attributes_by_name["description"].id, "Fading time"
        )
        self._update_attribute(self.attributes_by_name["min_present_value"].id, 0000)
        self._update_attribute(self.attributes_by_name["max_present_value"].id, 200000)
        self._update_attribute(self.attributes_by_name["resolution"].id, 1000)
        self._update_attribute(
            self.attributes_by_name["engineering_units"].id, 159
        )  # 73: seconds

class TuyaMmwRadarTargetDistance(TuyaAttributesCluster, AnalogInput):
    """AnalogInput cluster for target distance."""

    def __init__(self, *args, **kwargs):
        """Init."""
        super().__init__(*args, **kwargs)
        self._update_attribute(
            self.attributes_by_name["description"].id, "Target distance"
        )
        self._update_attribute(
            self.attributes_by_name["engineering_units"].id, 31
        )  # 31: meters



class TuyaMmwRadarCluster(NoManufacturerCluster, TuyaMCUCluster):
    """Mmw radar cluster."""
    attributes = TuyaMCUCluster.attributes.copy()
    attributes.update(
        {
            # ramdom attribute IDs
            0xEF01: ("occupancy", t.uint32_t, True),
            0xEF02: ("sensitivity", t.uint32_t, True),
            0xEF03: ("min_range", t.uint32_t, True),
            0xEF04: ("max_range", t.uint32_t, True),
            0xEF06: ("self_test", TuyaMmwRadarSelfTest, True),
            0xEF09: ("target_distance", t.uint32_t, True),
            0xEF65: ("detection_delay", t.uint32_t, True),
            0xEF66: ("fading_time", t.uint32_t, True),
            0xEF67: ("cli", t.CharacterString, True),
            0xEF68: ("illuminance", t.uint32_t, True),
        }
    )

    dp_to_attribute: Dict[int, DPToAttributeMapping] = {
        1: DPToAttributeMapping(
            TuyaOccupancySensing.ep_attribute,
            "occupancy",
            # dp_type=TuyaDPType.BOOL,
        ),
        2: DPToAttributeMapping(
            TuyaMmwRadarSensitivity.ep_attribute,
            "present_value",
            # dp_type=TuyaDPType.VALUE,
        ),
        3: DPToAttributeMapping(
            TuyaMmwRadarMinRange.ep_attribute,
            "present_value",
            # dp_type=TuyaDPType.VALUE,
            endpoint_id=2,
            #converter=lambda x: x / 100,
            #dp_converter=lambda x: x * 100,
        ),
        4: DPToAttributeMapping(
            TuyaMmwRadarMaxRange.ep_attribute,
            "present_value",
            # dp_type=TuyaDPType.VALUE,
            endpoint_id=3,
            #converter=lambda x: x / 100,
            #dp_converter=lambda x: x * 100,
        ),
        6: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "self_test",
            # dp_type=TuyaDPType.ENUM,
        ),
        9: DPToAttributeMapping(
            TuyaMmwRadarTargetDistance.ep_attribute,
            "present_value",
            #converter=lambda x: x / 100,
            # dp_type=TuyaDPType.VALUE,
        ),
        101: DPToAttributeMapping(
            TuyaMmwRadarDetectionDelay.ep_attribute,
            "present_value",
            # dp_type=TuyaDPType.VALUE,
            converter=lambda x: x * 100,
            dp_converter=lambda x: x // 100,
            endpoint_id=4,
        ),
        102: DPToAttributeMapping(
            TuyaMmwRadarFadingTime.ep_attribute,
            "present_value",
            # dp_type=TuyaDPType.VALUE,
            converter=lambda x: x * 100,
            dp_converter=lambda x: x // 100,
            endpoint_id=5,
        ),
        103: DPToAttributeMapping(
            TuyaMCUCluster.ep_attribute,
            "cli",
            # dp_type=TuyaDPType.STRING,
        ),
        104: DPToAttributeMapping(
            TuyaIlluminanceMeasurement.ep_attribute,
            "measured_value",
            # dp_type=TuyaDPType.VALUE,
            converter=lambda x: int(math.log10(x) * 10000 + 1) if x > 0 else int(0),
        ),
    }

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

class TuyaMmwRadarOccupancy(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"),
        ],
        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,
                    TuyaMmwRadarCluster,
                    TuyaIlluminanceMeasurement,
                    TuyaOccupancySensing,
                    TuyaMmwRadarTargetDistance,
                    TuyaMmwRadarSensitivity,
                ],
                OUTPUT_CLUSTERS: [Time.cluster_id, Ota.cluster_id],
            },
            2: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.COMBINED_INTERFACE,
                INPUT_CLUSTERS: [
                    TuyaMmwRadarMinRange,
                ],
                OUTPUT_CLUSTERS: [],
            },
            3: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.COMBINED_INTERFACE,
                INPUT_CLUSTERS: [
                    TuyaMmwRadarMaxRange,
                ],
                OUTPUT_CLUSTERS: [],
            },
            4: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.COMBINED_INTERFACE,
                INPUT_CLUSTERS: [
                    TuyaMmwRadarDetectionDelay,
                ],
                OUTPUT_CLUSTERS: [],
            },
            5: {
                PROFILE_ID: zha.PROFILE_ID,
                DEVICE_TYPE: zha.DeviceType.COMBINED_INTERFACE,
                INPUT_CLUSTERS: [
                    TuyaMmwRadarFadingTime,
                ],
                OUTPUT_CLUSTERS: [],
            },
        }
    }

This is the quirk which exposes the config

@rofo69
Copy link

rofo69 commented May 23, 2023

Ok, I've started working through modifying the quirks I have and am getting close:

image

But the logs are throwing some errors that I need to chase down.

@rofo69
Copy link

rofo69 commented May 23, 2023

Ok, through a fair bit of trial and error, I think I have a working quirk with config options.
I can't get detection distance as a sensor working yet, but I might have a go.

I think you might need that sensor working for the min and max range config options to work (I'm guessing).

modded_ts0601_motion.zip

@programmieramt
Copy link

Ok, through a fair bit of trial and error, I think I have a working quirk with config options. I can't get detection distance as a sensor working yet, but I might have a go.

I think you might need that sensor working for the min and max range config options to work (I'm guessing).

modded_ts0601_motion.zip

For me looks good. I am not sure if the value are used but I can configure it

@rofo69
Copy link

rofo69 commented May 23, 2023

If you could test the settings, let me know if they seem to be effective.

@diogo-madeira
Copy link
Author

diogo-madeira commented May 23, 2023

Ok, through a fair bit of trial and error, I think I have a working quirk with config options. I can't get detection distance as a sensor working yet, but I might have a go.

I think you might need that sensor working for the min and max range config options to work (I'm guessing).

modded_ts0601_motion.zip

I tried this quirk.... I can see all options, the illuminance sensor works, but the Occupancy sensor is not working....

Edit: After 5 minutes it starts to work.... I'll test if it's working right.

@rofo69
Copy link

rofo69 commented Nov 8, 2023

@evgenln

it happens when you submit an invalid value, different sensors have different ranges. Most easiest way to check for acceptable try to send values in the manage device and read back specialty if you use the device with fast feedback. Another reason of the issue is implementation, I resolved it for myself. Try to remove all configuration entries from endpoint 1, and keep each config in a separate endpoint

Have you adjusted the quirk above then ? Can you share what you have done ?

@evgenln
Copy link
Contributor

evgenln commented Nov 8, 2023

You can take a look e.g to #2543 (comment)
I did quick port of pupular PR to support device user asked. Compare replacment of TuyaMmwRadarOccupancyVariant1 (modificated by me) with TuyaMmwRadarOccupancyVariant2 or 3 (original from pupular PR).

@evgenln
Copy link
Contributor

evgenln commented Nov 8, 2023

By they way I droped _TZE204_sxm7l9xa usage and moved to by _TZE204_clrdrnya, it is way better 24 G model.
Also did ZHA as custom component with abilety to create entries as I need, the only issue update it but I do it only time to time as my setup stabile now.
Unfortunately, ZHA with the inability to expose entries the easy way (e.g from quirks) already faced with support collapse and things will go worse day by day

@MasterDevwi
Copy link

Strange, mine does work and occupancy (with fading time set to 0) clears after about 20 seconds from leaving the room. Perhaps restart HA, or delete the re-pair the device ? Although the full settings don't all work, I have a 'working' device that can detect presence and illuminance okay. Would be better if we could adjust all the settings, but someone will figure that out.

Huh strange. I can't get it to work at all, even after many HA restarts, removing and re-pairing the device, and even deleting pycache.

@rofo69
Copy link

rofo69 commented Nov 9, 2023

Is there any chance there is something in the room keeping the detection on ?

@MasterDevwi
Copy link

Is there any chance there is something in the room keeping the detection on ?

I don't think so, since I can't even get it to trigger on. It always thinks the room is empty.

@rofo69
Copy link

rofo69 commented Nov 10, 2023

Thats really strange. All i can say is that that happened to me originally, until I changed the fading time to zero. Since then its worked:-

image

image

Interestingly, fading time seems to no longer be a supported config option in this quirk, HA has now greyed it out. (Its still in the cluster values).

Are you changing the fading time in endpoint 5, or endpoint 1 ? I've done it in both just to be sure:-

image

and

image

@fracarvic
Copy link

I modified existing quirk with zigbee2mqtt converters datapoints and result seems to work well.

ts0601_TZE204_ijxvkhd0_presence.zip

Please try it and tell your results. I need to reset device (hold button some seconds) unpair and pair again and, at least for me, all is working ok.

I have it working perfectly in a small bathroom, with only 5 seconds of fading time. Max range value are in cm, and seems only acceptable resolution are 1mt

Motion and presence sensitivity acceptable values are 1..9, but device returns multiplied by 10. I need to put a lambda function converter only for returned values. I didn't have time to test different values, but, at least, values are stored correctly.

.
image

@rofo69
Copy link

rofo69 commented Nov 10, 2023

Looks good. Illuminance sensor didn't initially show up, and an HA restart and it appeared. This happens on the other tuya mmwave sensors too for some reason... Good job!

Fading time now definitely works. Will test out the sensitivity and see.

@MasterDevwi
Copy link

MasterDevwi commented Nov 19, 2023

Thank you both for your help.

@rofo69, I didn't realize there was a second fading_time in Endpoint 1. I tried changing that one too, but no luck.

Next, I deleted my current quirk and uploaded the one @fracarvic shared. To be safe, I also made sure to remove the sensor from HA, deleted pycache, and restarted HA. After re-pairing, the device is picked up and I see @fracarvic's changes... but occupancy still always says "Clear." I've tried various settings to no avail, including matching the screenshot above as well as setting the sensitivity and max_range to the maximum. Nothing seems to work. I'm stumped.

image

image

For what it's worth, I recently purchased a Tuya hub just to make sure the device isn't defective. The device seems to work perfectly in the Tuya app. So I just need to figure out why I can't get it to work with Home Assistant.

@rofo69
Copy link

rofo69 commented Nov 19, 2023

Just a warning to others.
The blakadder site mentions that the device above, specifically the ts0601_TZE204_ijxvkhd0 variant of the ZY-M100 can cause issues with your zigbee network.
Since having this online for a couple of weeks, it does work as expected, using the quirk @fracarvic posted above, but I've been noticing regular drop outs of devices that just didn't happen before. I'm going to disconnect it and see if it resolves the issue. I will post back here in a week or so with an update.

@fracarvic
Copy link

My _TZE204_ijxvkhd0 keeps working prefectly more than a week.

@MasterDevwi , testing other quirks my device stops working and always report clear occupancy. Maybe other quirks send incorrect values, and seems that unpair and repair doesn't reset device config values. My solution was unpair, hold reset button of device a couple of seconds, and pair again. Maybe this can help you.

@rofo69 , I enable zha debug and our device sends always, every second, target distance. If theres nobody on the room, always report 0 as target distance, always, every second. I only have 4 zigbee devices and this didn't cause problems for me, but people that have a lot of devices maybe are affected by this traffic.

Anyway, I order a ceiling version of _TZE204_clrdrnya device for testing, as @evgenln says it's a better device.

@rofo69
Copy link

rofo69 commented Nov 20, 2023

Even just a couple of days since deactivating the device i can see a noticeable improvement in stability on my zigbee network, which has around 60 devices on it. I think I might put his in the 'spares' drawer for now, and use something else like an EP1 or EPLite.

I might also remove my other older ZY-M100 as it also spams the zigbee network.. approximately every 1.5 seconds.

@andregoncalvespires
Copy link

It is regrettable that the behavior of these devices is not corrected, as they are great value for money and work very well for what they propose.

I have a little more than 70 ZigBee devices, including 4 ZY-M100 presence sensors. I didn't understand why my network became completely unstable and even compromised the zigbee2mqtt service by activating the watchdog whenever I tried to add more than 70 devices. I updated firmware, changed dongle, same problem.

Having more than one dongle, I decided to migrate to zha, but as these devices and two others are not or were not compatible, I kept Z2MQTT just for them. My surprise, more than 70 working perfectly on both networks.

This only confirms the warning of network overload by mmwave tuya.

I don't intend to stop using them, even if I have to maintain both networks. The best option would be a firmware update via Tuya for these presence sensors.

@rofo69
Copy link

rofo69 commented Nov 21, 2023

@andregoncalvespires - Exactly my thoughts. They seem to work well enough in isolation, but these network issues are a deal breaker for me, unless I move them to their own network as you have done.

In the end, I've gone down the everything presence route. These are EspHome/WIFI based, but more importantly, only broadcast when a state changes.

I found that even with just 2 tuya mmwave sensors, it was getting harder and harder to pair devices to the network, and random devices would randomly drop off the network or fail to respond correctly.

@EliasADN
Copy link

@fracarvic, I have the model TZE204_e5m9c5hl and with your file it works correctly, I just had to rename the file and modify the line 211 where the model is declared.
image

@thomasmielke70
Copy link

@fracarvic, I have the model TZE204_e5m9c5hl and with your file it works correctly, I just had to rename the file and modify the line 211 where the model is declared.

Same here. I installed two TZE204_e5m9c5hl yesterday and did the same. Works fine.

@BrewNinja
Copy link

Thank you @fracarvic. Your quirk worked perfect with my _TZE204_ijxvkhd0.

@Trikos
Copy link

Trikos commented Dec 2, 2023

I just found this issue, thanks god... It seems to work, but the occupancy always on Detected state. Are you also getting stuck to Detected? Also, I dont know how to set the value correctly, there is a good combination that you use?
I have the ijxvkhd0 model

@OwlBawl
Copy link

OwlBawl commented Dec 17, 2023

I just found this issue, thanks god... It seems to work, but the occupancy always on Detected state. Are you also getting stuck to Detected? Also, I dont know how to set the value correctly, there is a good combination that you use? I have the ijxvkhd0 model

try to set defaults sensitivity
7 and 9 to max
and distans to 5.5
had few times luck on "unstuck" with settings change. Not instantly anyway

@mbhforum
Copy link

mbhforum commented Dec 20, 2023

I am having the same issue with the Device Handler being stuck on "Detected" for Occupancy. My device is TS0601
by _TZE204_ijxvkhd0. I am using HA in a Docker container with a SkyConnect USB Zigbee dongle.

@ArnoldMo
Copy link

ArnoldMo commented Dec 20, 2023

I just found this issue, thanks god... It seems to work, but the occupancy always on Detected state. Are you also getting stuck to Detected? Also, I dont know how to set the value correctly, there is a good combination that you use? I have the ijxvkhd0 model

try to set defaults sensitivity 7 and 9 to max and distans to 5.5 had few times luck on "unstuck" with settings change. Not instantly anyway

I have set fade time 2sec
max range to 550 (max)
sensitivity both 9 (max)

and Occupancy works with a few second delay
I used @fracarvic quirk and restarted everything set the values, removed devices, restarted HA and the device, addend device, set the values again and restarted HA and device again

@Trikos
Copy link

Trikos commented Dec 21, 2023

Finally using the latest quirk of fixtse It works.
But after 5-6H of running the whole system froze. All HA became unavailable. It is a very bad sensor, sending out every second zigbee messages....
Anyway, if you try that quirks MUST work. Install it following the guide, then try restarting HA and place the sensors in a free space without anything blocking it

Copy link

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 github-actions bot added the stale Issue is inactivate and might get closed soon label Jun 18, 2024
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Jun 25, 2024
@igorsantos07
Copy link

Oh well, there we go. Another perfectly fine issue getting shut down because of an aggressive bot while maintainers didn't have the time to go through it.

@Nick75wien
Copy link

I have a TZE204_qasjif9e and tried several quirks now but I don't get any controls for that sensor
When I changed the quirks file I deleted the sensor, added the new file, restarted HA and readded the sonsor
What could be the problem ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
custom quirk available A custom quirk is available to solve the issue, but it's not merged in the repo yet stale Issue is inactivate and might get closed soon Tuya Request/PR regarding a Tuya device
Projects
None yet
Development

No branches or pull requests