zigbee2mqtt icon indicating copy to clipboard operation
zigbee2mqtt copied to clipboard

ZY-M100-24GV3 does not hold settings

Open musapinar opened this issue 11 months ago • 11 comments

What happened?

ZY-M100-24GV3 does not hold "specific settings" after a power outage.

Model : TS0601 Manufacturer : _TZE204_ya4ft0w4

What did you expect to happen?

Persist specific settings :

  • Move sensitivity
  • Presence sensitivity
  • Detection distance min
  • Detection distance max
  • Presence timeout

Save them in /zigbee2mqtt/configuration.yaml I guess, and retrieve them after grid power is restored.

Btw, shouldn't these sliders appear in the "Settings (specific)" tab instead of the "Exposes" tab ? Wouldn't this explain why settings are not saved ? Might be a mistake when this device was added to z2m ? 399388956-dcbdac53-037c-4508-9ee4-77bd6af342b9

I tried this without any success : 399389004-662133a4-17c0-462a-af1b-a0156e27b0d8 (Also tried without "device_options")

How to reproduce it (minimal and precise)

  • Set specific settings
  • Turn circuit breaker off
  • Turn circuit breaker on
  • All specific settings have been lost, they are now the factory default ones

Zigbee2MQTT version

2.0.0

Adapter firmware version

20240710

Adapter

zStack3x0

Setup

haos addon, running on oracle vm

Debug log

none

musapinar avatar Jan 08 '25 21:01 musapinar

Hi. I'm having the exact issue with mine.

I feel like changing the settings is not actually making any difference. For example, I changed the distance to 6.25m and it is only detecting at 3m or whatever the default is.

tam481 avatar Jan 14 '25 21:01 tam481

I can confirm that this is still an issue in the 2.1 release despite being listed as fixed.

Rebooted my RPi and the settings reset back to default :-(

tam481 avatar Feb 06 '25 12:02 tam481

Issue still exists.. :(

orzechszek avatar Feb 16 '25 17:02 orzechszek

same device, same issue but values always reset back to zero

ssepulveda avatar Feb 17 '25 14:02 ssepulveda

same device, same issue for me, settings reset after some times.

cdenfert avatar Feb 18 '25 17:02 cdenfert

I noticed even though move/presence sensitivity reset back to zero for unknown reasons, that it the case only in the z2m UI (on the sliders). The entities states in the dev tools seem ok. But they do indeed reset after a power outage / breaker reset iirc

musapinar avatar Feb 25 '25 17:02 musapinar

same problem... does not seem to have a solution.

xino222 avatar Mar 04 '25 00:03 xino222

I've ordered a Tuya hub so that I can further investigate. I intend to unpair from z2m, pair to the Tuya hub and set the ZY-M100-24GV3 via the SmartLife iOS app and see how the settings behave in the following days (do they reset too ?). Hopefully it will narrow down the issue and tell if it's z2m related, or firmware/hardware.

musapinar avatar Mar 16 '25 14:03 musapinar

Just received the Tuya hub and paired the device with SmartLife.

  • The app says it's a "V2", while z2m registered it as a "V3"

Image

Image

  • Sadly the device does not hold the settings. Toggling the circuit breaker on/off does reset the device settings (sensitivities, ranges, etc) back to factory defaults in the mobile app as well.
  • I will let the app/hub run a few days to see if settings do reset (reboot ?) the way they did in z2m.

Image

Image

Overall, eventhough the integration in z2m seems wrong (steps and min values are not similar to the app), this device (or at least its firmware) is mediocre :

  • It does not persist/retrieve settings (no eeprom ?)
  • It spams the zigbee network like crazy, unnecessarily. Imo, the code should behave like this : do not broadcast any data unless a state has changed.

I like the form-factor (ceiling mount). The idea was great, but the execution is potatoe.

musapinar avatar Mar 20 '25 00:03 musapinar

same device, same issue but values always reset back to zero

OsipovOV avatar Mar 20 '25 02:03 OsipovOV

I have 2 devices that do reset their values every 10 minutes very precisely. It also resets values after it has detected a presence, then again a few times every 10 seconds. Here is an overview of the "presence timeout" setting. It resets to 45s while I want to enforce it to 5s. See the pattern :

Image

My 4 other devices (also TS0601 / _TZE200_ya4ft0w4) do not have this madness. I figured that weird behavior after I created an automation to restore settings to my desired values :

alias: Restore mmWave settings for couloir_bureau
triggers:
  - entity_id: switch.capteur_presence_humaine_couloir_bureau_find_switch
    to: "on"
    trigger: state
  - value_template: >
      {{
      (states('number.capteur_presence_humaine_couloir_bureau_move_sensitivity')
      | default(1337) | int) !=
      (states('input_number.default_capteur_presence_humaine_couloir_bureau_move_sensitivity')
      | int) }}
    trigger: template
  - value_template: >
      {{
      (states('number.capteur_presence_humaine_couloir_bureau_presence_sensitivity')
      | default(1337) | int) !=
      (states('input_number.default_capteur_presence_humaine_couloir_bureau_presence_sensitivity')
      | int) }}
    trigger: template
  - value_template: >
      {{
      (states('number.capteur_presence_humaine_couloir_bureau_detection_distance_min')
      | default(1337.0) | float) !=
      (states('input_number.default_capteur_presence_humaine_couloir_bureau_detection_distance_min')
      | float) }}
    trigger: template
  - value_template: >
      {{
      (states('number.capteur_presence_humaine_couloir_bureau_detection_distance_max')
      | default(1337.0) | float) !=
      (states('input_number.default_capteur_presence_humaine_couloir_bureau_detection_distance_max')
      | float) }}
    trigger: template
  - value_template: >
      {{
      (states('number.capteur_presence_humaine_couloir_bureau_presence_timeout')
      | default(1337) | int) !=
      (states('input_number.default_capteur_presence_humaine_couloir_bureau_presence_timeout')
      | int) }}
    trigger: template
conditions:
  - condition: or
    conditions:
      - condition: state
        entity_id: switch.capteur_presence_humaine_couloir_bureau_find_switch
        state: "on"
      - condition: template
        value_template: >
          {{
          (states('number.capteur_presence_humaine_couloir_bureau_move_sensitivity')
          | default(1337) | int) !=
          (states('input_number.default_capteur_presence_humaine_couloir_bureau_move_sensitivity')
          | int) }}
      - condition: template
        value_template: >
          {{
          (states('number.capteur_presence_humaine_couloir_bureau_presence_sensitivity')
          | default(1337) | int) !=
          (states('input_number.default_capteur_presence_humaine_couloir_bureau_presence_sensitivity')
          | int) }}
      - condition: template
        value_template: >
          {{
          (states('number.capteur_presence_humaine_couloir_bureau_detection_distance_min')
          | default(1337.0) | float) !=
          (states('input_number.default_capteur_presence_humaine_couloir_bureau_detection_distance_min')
          | float) }}
      - condition: template
        value_template: >
          {{
          (states('number.capteur_presence_humaine_couloir_bureau_detection_distance_max')
          | default(1337.0) | float) !=
          (states('input_number.default_capteur_presence_humaine_couloir_bureau_detection_distance_max')
          | float) }}
      - condition: template
        value_template: >
          {{
          (states('number.capteur_presence_humaine_couloir_bureau_presence_timeout')
          | default(1337) | int) !=
          (states('input_number.default_capteur_presence_humaine_couloir_bureau_presence_timeout')
          | int) }}
actions:
  - data:
      topic: zigbee2mqtt/capteur_presence_humaine_couloir_bureau/set
      payload: |-
        {
          "find_switch": "OFF",
          "move_sensitivity": "{{ states('input_number.default_capteur_presence_humaine_couloir_bureau_move_sensitivity') }}",
          "presence_sensitivity": "{{ states('input_number.default_capteur_presence_humaine_couloir_bureau_presence_sensitivity') }}",
          "detection_distance_min": "{{ states('input_number.default_capteur_presence_humaine_couloir_bureau_detection_distance_min') }}",
          "detection_distance_max": "{{ states('input_number.default_capteur_presence_humaine_couloir_bureau_detection_distance_max') }}",
          "presence_timeout": "{{ states('input_number.default_capteur_presence_humaine_couloir_bureau_presence_timeout') }}"
        }
    action: mqtt.publish
mode: queued

  • default(1337) is because I want to catch situations where it returns "unknown" or "unavailable" instead of an int/float.
  • triggers and conditions do repeat because I want the conditions to be reevaluated when the queue is processed.
  • helpers (input_number) are used because you cannot put variable in triggers. Easier to maintain/customize later on.

There are probably many many different firmware versions for the same "V3" devices. I have some devices that do send data every 1 second even when nothing happens. I have some others that are silent when nothing occurs, but do send massive bursts of the same data every 10 seconds if there is a presence.

TL;DR : firmware sucks

musapinar avatar Mar 21 '25 04:03 musapinar

I have 2 devices that do reset their values every 10 minutes very precisely. It also resets values after it has detected a presence, then again a few times every 10 seconds. Here is an overview of the "presence timeout" setting. It resets to 45s while I want to enforce it to 5s. See the pattern :

Image

My 4 other devices (also TS0601 / _TZE200_ya4ft0w4) do not have this madness. I figured that weird behavior after I created an automation to restore settings to my desired values :

alias: Restore mmWave settings for couloir_bureau
triggers:
  - entity_id: switch.capteur_presence_humaine_couloir_bureau_find_switch
    to: "on"
    trigger: state
  - value_template: >
      {{
      (states('number.capteur_presence_humaine_couloir_bureau_move_sensitivity')
      | default(1337) | int) !=
      (states('input_number.default_capteur_presence_humaine_couloir_bureau_move_sensitivity')
      | int) }}
    trigger: template
  - value_template: >
      {{
      (states('number.capteur_presence_humaine_couloir_bureau_presence_sensitivity')
      | default(1337) | int) !=
      (states('input_number.default_capteur_presence_humaine_couloir_bureau_presence_sensitivity')
      | int) }}
    trigger: template
  - value_template: >
      {{
      (states('number.capteur_presence_humaine_couloir_bureau_detection_distance_min')
      | default(1337.0) | float) !=
      (states('input_number.default_capteur_presence_humaine_couloir_bureau_detection_distance_min')
      | float) }}
    trigger: template
  - value_template: >
      {{
      (states('number.capteur_presence_humaine_couloir_bureau_detection_distance_max')
      | default(1337.0) | float) !=
      (states('input_number.default_capteur_presence_humaine_couloir_bureau_detection_distance_max')
      | float) }}
    trigger: template
  - value_template: >
      {{
      (states('number.capteur_presence_humaine_couloir_bureau_presence_timeout')
      | default(1337) | int) !=
      (states('input_number.default_capteur_presence_humaine_couloir_bureau_presence_timeout')
      | int) }}
    trigger: template
conditions:
  - condition: or
    conditions:
      - condition: state
        entity_id: switch.capteur_presence_humaine_couloir_bureau_find_switch
        state: "on"
      - condition: template
        value_template: >
          {{
          (states('number.capteur_presence_humaine_couloir_bureau_move_sensitivity')
          | default(1337) | int) !=
          (states('input_number.default_capteur_presence_humaine_couloir_bureau_move_sensitivity')
          | int) }}
      - condition: template
        value_template: >
          {{
          (states('number.capteur_presence_humaine_couloir_bureau_presence_sensitivity')
          | default(1337) | int) !=
          (states('input_number.default_capteur_presence_humaine_couloir_bureau_presence_sensitivity')
          | int) }}
      - condition: template
        value_template: >
          {{
          (states('number.capteur_presence_humaine_couloir_bureau_detection_distance_min')
          | default(1337.0) | float) !=
          (states('input_number.default_capteur_presence_humaine_couloir_bureau_detection_distance_min')
          | float) }}
      - condition: template
        value_template: >
          {{
          (states('number.capteur_presence_humaine_couloir_bureau_detection_distance_max')
          | default(1337.0) | float) !=
          (states('input_number.default_capteur_presence_humaine_couloir_bureau_detection_distance_max')
          | float) }}
      - condition: template
        value_template: >
          {{
          (states('number.capteur_presence_humaine_couloir_bureau_presence_timeout')
          | default(1337) | int) !=
          (states('input_number.default_capteur_presence_humaine_couloir_bureau_presence_timeout')
          | int) }}
actions:
  - data:
      topic: zigbee2mqtt/capteur_presence_humaine_couloir_bureau/set
      payload: |-
        {
          "find_switch": "OFF",
          "move_sensitivity": "{{ states('input_number.default_capteur_presence_humaine_couloir_bureau_move_sensitivity') }}",
          "presence_sensitivity": "{{ states('input_number.default_capteur_presence_humaine_couloir_bureau_presence_sensitivity') }}",
          "detection_distance_min": "{{ states('input_number.default_capteur_presence_humaine_couloir_bureau_detection_distance_min') }}",
          "detection_distance_max": "{{ states('input_number.default_capteur_presence_humaine_couloir_bureau_detection_distance_max') }}",
          "presence_timeout": "{{ states('input_number.default_capteur_presence_humaine_couloir_bureau_presence_timeout') }}"
        }
    action: mqtt.publish
mode: queued
  • default(1337) is because I want to catch situations where it returns "unknown" or "unavailable" instead of an int/float.
  • triggers and conditions do repeat because I want the conditions to be reevaluated when the queue is processed.
  • helpers (input_number) are used because you cannot put variable in triggers. Easier to maintain/customize later on.

There are probably many many different firmware versions for the same "V3" devices. I have some devices that do send data every 1 second even when nothing happens. I have some others that are silent when nothing occurs, but do send massive bursts of the same data every 10 seconds if there is a presence.

TL;DR : firmware sucks

@musapinar I'm curious how you got your automation to trigger when the entities number.* do not reset themselves but instead the sliders in z2m (mqtt) seem to be generating the errors.

jjfs127 avatar Apr 02 '25 14:04 jjfs127

@jjfs127 This automation runs only when HA restarts (typically after an update or if the circuit breaker has been turned on/off since this device does not hold settings but resets to factory defaults after it has lost power). I had to improve it a bit btw. Here is the working version :

alias: Restore mmWave settings for couloir_bureau
triggers:
  - entity_id: switch.capteur_presence_humaine_couloir_bureau_find_switch
    to: "on"
    trigger: state
  - value_template: |
      {{ 
        (states('number.capteur_presence_humaine_couloir_bureau_move_sensitivity') | int(default=1337)) != 
        (states('input_number.default_capteur_presence_humaine_couloir_bureau_move_sensitivity') | int) 
      }}
    trigger: template
  - value_template: |
      {{ 
        (states('number.capteur_presence_humaine_couloir_bureau_presence_sensitivity') | int(default=1337)) != 
        (states('input_number.default_capteur_presence_humaine_couloir_bureau_presence_sensitivity') | int) 
      }}
    trigger: template
  - value_template: |
      {{ 
        (states('number.capteur_presence_humaine_couloir_bureau_detection_distance_min') | float(default=1337.0)) != 
        (states('input_number.default_capteur_presence_humaine_couloir_bureau_detection_distance_min') | float) 
      }}
    trigger: template
  - value_template: |
      {{ 
        (states('number.capteur_presence_humaine_couloir_bureau_detection_distance_max') | float(default=1337.0)) != 
        (states('input_number.default_capteur_presence_humaine_couloir_bureau_detection_distance_max') | float) 
      }}
    trigger: template
  - value_template: |
      {{ 
        (states('number.capteur_presence_humaine_couloir_bureau_presence_timeout') | int(default=1337)) != 
        (states('input_number.default_capteur_presence_humaine_couloir_bureau_presence_timeout') | int) 
      }}
    trigger: template
conditions:
  - condition: or
    conditions:
      - condition: state
        entity_id: switch.capteur_presence_humaine_couloir_bureau_find_switch
        state: "on"
      - condition: template
        value_template: |
          {{ 
            (states('number.capteur_presence_humaine_couloir_bureau_move_sensitivity') | int(default=1337)) != 
            (states('input_number.default_capteur_presence_humaine_couloir_bureau_move_sensitivity') | int) 
          }}
      - condition: template
        value_template: |
          {{ 
            (states('number.capteur_presence_humaine_couloir_bureau_presence_sensitivity') | int(default=1337)) != 
            (states('input_number.default_capteur_presence_humaine_couloir_bureau_presence_sensitivity') | int) 
          }}
      - condition: template
        value_template: |
          {{ 
            (states('number.capteur_presence_humaine_couloir_bureau_detection_distance_min') | float(default=1337.0)) != 
            (states('input_number.default_capteur_presence_humaine_couloir_bureau_detection_distance_min') | float) 
          }}
      - condition: template
        value_template: |
          {{ 
            (states('number.capteur_presence_humaine_couloir_bureau_detection_distance_max') | float(default=1337.0)) != 
            (states('input_number.default_capteur_presence_humaine_couloir_bureau_detection_distance_max') | float) 
          }}
      - condition: template
        value_template: |
          {{ 
            (states('number.capteur_presence_humaine_couloir_bureau_presence_timeout') | int(default=1337)) != 
            (states('input_number.default_capteur_presence_humaine_couloir_bureau_presence_timeout') | int) 
          }}
actions:
  - data:
      topic: zigbee2mqtt/capteur_presence_humaine_couloir_bureau/set
      payload: |-
        {
          "find_switch": "OFF",
          "move_sensitivity": {{ states('input_number.default_capteur_presence_humaine_couloir_bureau_move_sensitivity') | int }},
          "presence_sensitivity": {{ states('input_number.default_capteur_presence_humaine_couloir_bureau_presence_sensitivity') | int }},
          "detection_distance_min": {{ states('input_number.default_capteur_presence_humaine_couloir_bureau_detection_distance_min') | float }},
          "detection_distance_max": {{ states('input_number.default_capteur_presence_humaine_couloir_bureau_detection_distance_max') | float }},
          "presence_timeout": {{ states('input_number.default_capteur_presence_humaine_couloir_bureau_presence_timeout') | int }}
        }
    action: mqtt.publish
mode: queued

You are right saying the entities states values are correct in the dev tools but mismatch in the z2m UI sliders. I highlighted this oddity earlier here or in other related threads.

So i resorted to what someone else did : a Node-RED flow. This way I can sniff what goes in and override out if it is 0 (zero) Image

It's hacky and inelegant but it does work.

I also dumped the firmware out of the less chatty/verbose one of my 6 devices to flash the others (which were blasting payloads every second) using an ST-LINK via UART

The original firmware (and Tuya generally) is bad. I read somewhere a seller (Wenzhi on AE ?) said it was initially designed for the industry to estimate distances. So not quite appropriate for our domestic use cases I guess. I personally will probably ditch the whole inner parts some day and fit an esp32 + HLK-LD1115H-24G + custom integration (or esphome)

It is not related to z2m imo. I am closing this issue. Good luck.

musapinar avatar Apr 03 '25 21:04 musapinar

'input_number.default_capteur_presence_humaine_couloir_bureau_move_sensitivity'

Hi, when you put this in the automation, what is the default value?. Can you replace this variable with a net value?. I don't understand where you set the value by default.

montoyra avatar Apr 07 '25 08:04 montoyra

'input_number.default_capteur_presence_humaine_couloir_bureau_move_sensitivity'

Hi, when you put this in the automation, what is the default value?. Can you replace this variable with a net value?. I don't understand where you set the value by default.

You're better off making a node red flow as above than an automation as the entities in HA don't seem to reflect the zero values only the sliders do in z2m.

jjfs127 avatar Apr 07 '25 15:04 jjfs127