Zy-m100 presence detector with Tuya MCU

I got me a Tuya presence detector, it has a Tuya MCU, and a WBR3 module. This module has beed replaced with a ESP-12S and running esphome.

Tasmota has support for this thanks to @blakadder Tuya mmWave Presence Sensor (ZY-M100) Configuration for Tasmota
But I don’t use MQTT or Tasmota.

The Tuya MCU component on ESPhome appears not to support this MCU.

uart:
  rx_pin: GPIO3
  tx_pin: GPIO1
  baud_rate: 9600

tuya:

Logs:

[16:26:43][C][tuya:033]: Tuya:
[16:26:43][C][tuya:036]:   Initialization failed. Current init_state: 0
[16:26:43][C][tuya:041]:   If no further output is received, confirm that this is a supported Tuya device.
[16:26:47][V][tuya:383]: Sending Tuya: CMD=0x00 VERSION=0 DATA=[] INIT_STATE=0
[16:26:47][V][tuya:383]: Sending Tuya: CMD=0x00 VERSION=0 DATA=[] INIT_STATE=0
[16:26:47][V][tuya:383]: Sending Tuya: CMD=0x00 VERSION=0 DATA=[] INIT_STATE=0
[16:26:48][V][tuya:383]: Sending Tuya: CMD=0x00 VERSION=0 DATA=[] INIT_STATE=0
[16:26:48][V][tuya:383]: Sending Tuya: CMD=0x00 VERSION=0 DATA=[] INIT_STATE=0
[16:26:48][E][tuya:409]: Initialization failed at init_state 0

Has anyone manage to get this working on ESPhome?

Hi LCL,

I’ve uploaded the guide for ESP-IDF and Arduino using an ESP32-C3 chip but you can make sure incompatible values have been corrected before flashing your chip i.e. platform and chip/board variant to esp8266 either modwifi or wroom_02 for 2mb flash

See below:-

Tuya ZY-M100 | esphome-devices

Regards,
ashp

1 Like

Great success!
Thank you!

So I checked your code and noticed that you used baud rate of 115200 while I used 9600, which looks like that was the main reason it did not appear to work.

Just changing my code to the correct baud rate (115200) made it communicate.

I now used your code and did a change on the lambda code in the text_sensor Self Check Result and changed the single equal with a double, so that it would validate the state and not trying to set it.
It did report a warning on that while compiling.

Also the Tuya MCU integration does report a error when using other baudrate then 9600

[02:04:10][E][uart:015]:   Invalid baud_rate: Integration requested baud_rate 9600 but you have 115200!

How did you know to use 115200 baud rate?
I was looking on the Tuya documentation, probably not deep enough, but did not find anything.

I have other tuya based devices and some require 115200 baud rate to communicate with the STM based tuya mcu

Hi,
i just bought this sensor, tried to compile your esp-idf example, but esphome compiler gives these errors:

/config/esphome/presence-klet2.yaml:118:28: error: suggest parentheses around assignment used as truth value [-Werror=parentheses]
       if (id(selfcheck).state = 0) {
           ~~~~~~~~~~~~~~~~~^~~
/config/esphome/presence-klet2.yaml:121:33: error: suggest parentheses around assignment used as truth value [-Werror=parentheses]
       else if (id(selfcheck).state = 1) {
                ~~~~~~~~~~~~~~~~~^~~
/config/esphome/presence-klet2.yaml:124:33: error: suggest parentheses around assignment used as truth value [-Werror=parentheses]
       else if (id(selfcheck).state = 2) {
                ~~~~~~~~~~~~~~~~~^~~
/config/esphome/presence-klet2.yaml:127:33: error: suggest parentheses around assignment used as truth value [-Werror=parentheses]
       else if (id(selfcheck).state = 3) {
                ~~~~~~~~~~~~~~~~~^~~
/config/esphome/presence-klet2.yaml:130:33: error: suggest parentheses around assignment used as truth value [-Werror=parentheses]
       else if (id(selfcheck).state = 4) {
                ~~~~~~~~~~~~~~~~~^~~
/config/esphome/presence-klet2.yaml:133:33: error: suggest parentheses around assignment used as truth value [-Werror=parentheses]
       else if (id(selfcheck).state = 5) {

Do you have any clue why? ESPHome addon is latest available, HA also.

Yes, the example code is incorrect with the validation.

id(selfcheck).state = 2
has to change to id(selfcheck).state == 2

one equal sign = will assign a value to a variable and two == will check the value of the variable to equals the value.
so id(selfcheck).state = 2 will assign the value of 2 to id(selfcheck).state
id(selfcheck).state == 2 will se if the value of id(selfcheck).state equals 2 and that will return true or false and the if statement expects true boolean to execute the code within the { }

So change all the
id(selfcheck).state = 1 to id(selfcheck).state == 1
id(selfcheck).state = 2 to id(selfcheck).state == 2
etc… in the lambda of the text_sensor and you should be fine.

1 Like

Great, thanks a lot! Now compile is succesfull.
What can i say…i’m not an experienced programmer, so i didn’t notice this error. Now when you told me i know that there should be “==”… so thanks again!

I spent whole afternoon learning and configuring this sensor via Tuya integration, and… i can’t emphasize enough how much i hate tuya and it’s complicated learning process… I didn’t manage to get “local tuya” running, only official version, so it’s one reason more for esphome, since it runs locally. Hopefully it will work perfect. Main thing is that i have a working esphome file now. I have a couple of esp32-C3 modules lying in the drawer, i’ll try it out tomorrow, it’s getting late here.

Thanks guys, I’ve updated the offending code in esphome-devices so others should not hit this issue, should be updated soon.

2 Likes

Just to let you guys know… above code works PERFECTLY! Many thanks again!
A small warning: first time code must be uploaded via esphome’s browser install page on esp32-c3. Installing bin file with esp32 flasher doesn’t work! All other updates are then made via wifi.

I love it compared to original tuya… i managed to make local tuya to work, but esphome is better, faster, and, above all: it’s totally local, which i prefer.

Hi @ashp, I’ve transplanted ESP32 C3 12F to this sensor. However, MCU module doesn’t seem to work for me. I pretty much took your configuration on ESPHome. I’m getting this error:

21:41:54][C][tuya:041]: Tuya:
[21:41:54][C][tuya:044]:   Initialization failed. Current init_state: 0
[21:41:54][C][tuya:049]:   If no further output is received, confirm that this is a supported Tuya device.
[21:41:57][E][tuya:433]: Initialization failed at init_state 0

Any ideas? Thanks.

Please provide your yaml so we can help debugging.

But looks like you have the same issue I had and that was the baud_rate was incorrect.
So either it’s set to the wrong rate ( maybe tuya has made an update? ) or you have hardware issue on the TX / RX lines, maybe check soldering?

Here is my config:

substitutions:
  device_ssid: "Tuya Sensor"
  device_name: tuyasensor1
  device_description: "Tuya ZY-M100 Human Prescence Sensor ESP32-C3 ESP-IDF"
  friendly_name: "Tuya ZY-M100 Human Prescence Sensor"
  main_device_id: "tuyasensor1" # Put the name that you want to see in Home Assistant.
  project_name: "tuya.zy-m100-wifi-esp-idf"
  project_version: "1.0"

esphome:
  name: ${device_name}
  comment: ${device_description}
  platformio_options:
    board_build.flash_mode: dio
  project:
    name: "${project_name}"
    version: "${project_version}"

esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: esp-idf

#esp32:
#  board: esp32-c3-devkitm-1
#  framework:
#    type: arduino
#    version: 2.0.5
#    platform_version: 5.2.0



# Enable Home Assistant API
api:
  password: !secret api_password
#  encryption:
#    key: !secret api_encryption_key

# Enable logging
logger:

ota:
  safe_mode: true
  password: !secret ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  power_save_mode: none
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: ${device_ssid} Fallback Hotspot
    password: !secret ap_password

sensor:
  # WiFi Signal sensor.
  - platform: wifi_signal
    name: ${friendly_name} Signal strength
    update_interval: 60s
    internal: true
  # Uptime Sensor
  - platform: uptime
    name: "${friendly_name} Uptime"
    id: uptime_sensor
    update_interval: 360s
    on_raw_value:
      then:
        - text_sensor.template.publish:
            id: uptime_human
            state: !lambda |-
              int seconds = round(id(uptime_sensor).raw_state);
              int days = seconds / (24 * 3600);
              seconds = seconds % (24 * 3600);
              int hours = seconds / 3600;
              seconds = seconds % 3600;
              int minutes = seconds /  60;
              seconds = seconds % 60;
              return (
                (days ? to_string(days) + "d " : "") +
                (hours ? to_string(hours) + "h " : "") +
                (minutes ? to_string(minutes) + "m " : "") +
                (to_string(seconds) + "s")
              ).c_str();
# Light Sensor
  - platform: tuya
    name: "${friendly_name} Light Intensity"
    id: light_intensity
    sensor_datapoint: 104
    unit_of_measurement: "lux"
    icon: "mdi:brightness-5"
    device_class: "illuminance"
    state_class: "measurement"
# Distance from Detected Object
  - platform: "tuya"
    name: "${friendly_name} Target Distance"
    id: target_distance
    sensor_datapoint: 9
    unit_of_measurement: "cm"
    icon: "mdi:eye"
    device_class: "distance"
    state_class: "measurement"
# Self Check Number
  - platform: "tuya"
    name: "Self Check Number"
    id: selfcheck
    sensor_datapoint: 6
    internal: True

text_sensor:
  # Expose WiFi information as sensors.
  - platform: wifi_info
    ip_address:
      name: ${friendly_name} IP
    ssid:
      name: ${friendly_name} SSID
    bssid:
      name: ${friendly_name} BSSID
  # Expose Uptime
  - platform: template
    name: ${friendly_name} Uptime Human Readable
    id: uptime_human
    icon: mdi:clock-start
  - platform: template
    name: "${friendly_name} Self Check Result"
    icon: mdi:eye
    lambda: |-
      if (id(selfcheck).state == 0) {
        return {"Checking"};
      }
      else if (id(selfcheck).state == 1) {
        return {"Check Success"};
      }
      else if (id(selfcheck).state == 2) {
        return {"Check Failure"};
      }
      else if (id(selfcheck).state == 3) {
        return {"Others"};
      }
      else if (id(selfcheck).state == 4) {
        return {"Comm Fault"};
      }
      else if (id(selfcheck).state == 5) {
        return {"Radar Fault"};
      }
      else return {"Unknown"};

switch:
  # this provides for a possibility to restart from the web console or Home automation should we ever need it
  - platform: restart
    name: "${friendly_name} Restart"
  - platform: safe_mode
    name: "${friendly_name} Restart (Safe Mode)"

uart:
  rx_pin: GPIO20
  tx_pin: GPIO21
  baud_rate: 115200

# Register the Tuya MCU connection
tuya:

number:
  - platform: "tuya"
    name: "${friendly_name} Sensitivity"
    number_datapoint: 2
    min_value: 0
    max_value: 9
    step: 1
    icon: "mdi:ray-vertex"
  - platform: "tuya"
    name: "${friendly_name} Near Detection"
    number_datapoint: 3
    min_value: 0
    max_value: 1000
    step: 1
    mode: slider
    unit_of_measurement: "cm"
    icon: "mdi:signal-distance-variant"
  - platform: "tuya"
    name: "${friendly_name} Far Detection"
    number_datapoint: 4
    min_value: 0
    max_value: 1000
    step: 1
    mode: slider
    unit_of_measurement: "cm"
    icon: "mdi:signal-distance-variant"
  - platform: "tuya"
    name: "${friendly_name} Detection Delay"
    number_datapoint: 101
    min_value: 0
    max_value: 100
    step: 1
    unit_of_measurement: "s"
    mode: slider
    icon: "mdi:clock"
  - platform: "tuya"
    name: "${friendly_name} Fading Time"
    number_datapoint: 102
    min_value: 0
    max_value: 1500
    step: 1
    unit_of_measurement: "s"
    mode: slider
    icon: "mdi:clock"

binary_sensor:
  - platform: status
    name: "${friendly_name} Status"
  - platform: "tuya"
    name: "${friendly_name} Presence State"
    sensor_datapoint: 1
    device_class: motion

I don’t think there is issue with TX/RX line. The soldering looks good to me. I transplanted another sensor and it also has the same issue :(. Tuya might have changed their code?

Btw, my sensor is the ceiling mount.

Ok… is that the roof mounted sensor? … never mind you answered that in your post :slight_smile:
maybe the connections are not the same as you had same issue on two.
So if you are sure that the TX and RX are correct, try setting baud_rate: 9600 under uart.
Maybe this sensor uses that baud and not the 115200 the wall mounted one used.

Yeah I’ve tried 9600 baud rate as well but it still doesn’t work. TX and RX are correct as they are the same as the Tuya chip.

can you take multiple detail photos of the internals? Maybe we can identify something to get this to work.

Here are some photos:

Between the pcbs is there any ICs there?

he needs to set logger to 0 see ESPHome | Tuya MCU

# Make sure logging is not using the serial port
logger:
  baud_rate: 0

correct me if I’m wrong

I am waiting for my modules to arrive to do the transplant. I am wondering if you mange to get it working.

Just looking at your jump wire it seemed to be attaching to Gpio5 rather than EN. I guess that didn’t cause problem since you were still able to get the chip booted.

Did you manage to get it working? I have tried with two of my sensors and they don’t work with log output just like yours. I have the wall mounted ones.

I have a couple ceiling version but they take mains power. I wanted to solder wires on to the pads to test it out before I solder the chip on since it’s a pain to take them off. I wanted to try because it is very unlikely that my heat gun would have damaged the ceiling version since I just used solder wick to take the pcb off then use heat gun to take the zigbee chip off.