Koenkk / zigbee2mqtt

Zigbee 🐝 to MQTT bridge 🌉, get rid of your proprietary Zigbee bridges 🔨
https://www.zigbee2mqtt.io
GNU General Public License v3.0
11.72k stars 1.64k forks source link

[New device support]: for Tuya M100S with 24G radar #18237

Open DosPH opened 1 year ago

DosPH commented 1 year ago

Link

https://shopee.ph/ZigBee-Wifi-24G-MmWave-Radar-Human-Presence-Motion-Sensor-With-Luminosity-Distance-Detection-5-110-220V-Tuya-Smart-Life-Home-DIY-i.458442746.21881172707?sp_atk=c89bca14-cb63-4ccb-acdf-36f123ccff3e&xptdk=c89bca14-cb63-4ccb-acdf-36f123ccff3e

Database entry

{"id":65,"type":"Router","ieeeAddr":"0xa4c13855222f4904","nwkAddr":2607,"manufId":4417,"manufName":"_TZE204_ijxvkhd0","powerSource":"Mains (single phase)","modelId":"TS0601","epList":[1,242],"endpoints":{"1":{"profId":260,"epId":1,"devId":81,"inClusterList":[4,5,61184,0],"outClusterList":[25,10],"clusters":{"genBasic":{"attributes":{"modelId":"TS0601","manufacturerName":"_TZE204_ijxvkhd0","powerSource":1,"zclVersion":3,"appVersion":74,"stackVersion":0,"hwVersion":1,"dateCode":""}}},"binds":[],"configuredReportings":[],"meta":{}},"242":{"profId":41440,"epId":242,"devId":97,"inClusterList":[],"outClusterList":[33],"clusters":{},"binds":[],"configuredReportings":[],"meta":{}}},"appVersion":74,"stackVersion":0,"hwVersion":1,"dateCode":"","zclVersion":3,"interviewCompleted":true,"meta":{},"lastSeen":1688723423810,"defaultSendRequestWhen":"immediate"}

Comments

anyone have tried to have this new tuya m100s with 24G radar working? this is the same square wallmount type with a Type C connector as power source.

External converter

No response

Supported color modes

No response

Color temperature range

No response

dinde commented 10 months ago

Hi, Same issues here. Tested with the Ceiling version 24G and Wall version 24G Both are using the external converter provided here.

Tested the latest converter with following settings:

Door is closed when I pass by the closed door, it detects motion and presence. I can't set less sentivity or detection distance less than these values.

Quick question: is the 5.8G version working correctly in z2m ?

Hope it helps.

nickgoh commented 10 months ago

Hi, Same issues here. Tested with the Ceiling version 24G and Wall version 24G Both are using the external converter provided here.

Tested the latest converter with following settings:

  • Motion Sensitivity: 2 (minimum I could set)
  • Presence Sensitivity: 3 (same minimum)
  • Detection Distance Max: 1,5m (same minimum)
  • Fading time: 10s

Door is closed when I pass by the closed door, it detects motion and presence. I can't set less sentivity or detection distance less than these values.

Quick question: is the 5.8G version working correctly in z2m ?

Hope it helps.

try set the sensitivity the other way around

nickgoh commented 10 months ago

i have modified the converter base on the param of tuya app, so far is working good . motion_sensitivity : Level 2-7 (base on tuya dev device log only, not sure how accurate) presence_sensitivity : Level 3-9 (base on tuya dev device log only, not sure how accurate) sensitivity value: lowest is the most sensitive distance : 1.5-5.5m ( base on tuya app) fading Time : 1-1500 sec (base on tuya app) issue : i am not sure why the value of motion & present sensitivity will mutiply by 10 after setting

const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const e = exposes.presets;
const ea = exposes.access;

const tzDatapoints = {
    ...tuya.tz.datapoints,
    key: [
        'switch_1', 'switch_2', 'countdown_1', 'countdown_2', 'work_mode', 'bright_value', 'temp_value', 'illuminance_value', 
          'presence_state', 'move_sensitivity', 'motion_sensitivity', 'detection_distance_max', 'detection_distance_min', 'far_detection', 'target_dis_closest', 'fading_time', 'presence_sensitivity', 'man_state' 
    ],
}

const definition = {
    fingerprint: [ { modelID: 'TS0601', manufacturerName: '_TZE204_ijxvkhd0'}],
    model: 'ZY-M100-24G',
    vendor: 'TuYa',
    description: 'Micro Motion Sensor v1.2 ',
    configure: tuya.configureMagicPacket,
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tzDatapoints],
  exposes: [
      e.illuminance_lux(), e.presence(),
      e.enum('presence_state', ea.STATE, ['none', 'present', 'moving']).withDescription('Presence state'),
      e.numeric('motion_sensitivity', ea.STATE_SET).withValueMin(2).withValueMax(7).withValueStep(1).withDescription('Motion sensitivity'),
      e.numeric('presence_sensitivity', ea.STATE_SET).withValueMin(3).withValueMax(9).withValueStep(1).withDescription('Presence sensitivity'),
      e.numeric('detection_distance_max', ea.STATE_SET).withValueMin(1.5).withValueMax(5.5).withValueStep(1).withDescription('Max detection distance').withUnit('m'),
      e.numeric('fading_time', ea.STATE_SET).withValueMin(0).withValueMax(1500).withValueStep(1).withDescription('Delay time').withUnit('s'),
      e.numeric('target_distance', ea.STATE).withDescription('Distance to target').withUnit('m'),

  ],

  meta: {
      tuyaDatapoints: [
          [104, 'illuminance_lux', tuya.valueConverter.raw],
          [105, 'presence_state', tuya.valueConverterBasic.lookup({'None': tuya.enum(0), 'Present': tuya.enum(1), 'Moving': tuya.enum(2)})],
          [106, 'motion_sensitivity', tuya.valueConverter.raw], //2-7
          [107, 'detection_distance_max', tuya.valueConverter.divideBy100],
          [109, 'target_distance', tuya.valueConverter.divideBy100],
          [110, 'fading_time', tuya.valueConverter.raw],
          [111, 'presence_sensitivity', tuya.valueConverter.raw],// 2-9
          [112, 'presence', tuya.valueConverter.trueFalse1],
      ],
  },
};

module.exports = definition;

modify two row ..

        [106, 'motion_sensitivity', tuya.valueConverter.divideBy10],

        [111, 'presence_sensitivity', tuya.valueConverter.divideBy10],

now the two value of motion & present sensitivity are corrects

Confirm works better with this code.

But question is does anyone have the ceiling version of this sensor? Because the settings not working for 100%. I can set any value for motion and presence sensitivity but is always change to 10: image

I think this might be similar situation with previous 5G generation where the drivers were a bit different for both if I am not mistaken.

Hi, i am using the ceiling version and the setting sticks , try to reset the divece n repair ?

achessoux commented 10 months ago

Tested the latest converter with following settings:

  • Motion Sensitivity: 2 (minimum I could set)
  • Presence Sensitivity: 3 (same minimum)
  • Detection Distance Max: 1,5m (same minimum)
  • Fading time: 10s

Door is closed when I pass by the closed door, it detects motion and presence. I can't set less sentivity or detection distance less than these values.

Hello,

I've the Ceiling version 24G, with the same settings and the custom converter given above, I've the same issue : my toilet light gets on when I pass by the closed door. No possibility to lower the distance and the sensitivity... I used to have a movement detector from aqara and it was the opposite: the light turned off after a while when I was sitted (because it is a movement sensor). That's why I bought this presence sensor.

To see this sensor working perfectly, I rely on developer work. So, while waiting for an update, I take the time to gracefully thank @MTokarev for his first steps, @mindtripper for his fine tuning and also @Koenkk for his general and huge implication.

Dataninja126 commented 10 months ago

i have modified the converter base on the param of tuya app, so far is working good . motion_sensitivity : Level 2-7 (base on tuya dev device log only, not sure how accurate) presence_sensitivity : Level 3-9 (base on tuya dev device log only, not sure how accurate) sensitivity value: lowest is the most sensitive distance : 1.5-5.5m ( base on tuya app) fading Time : 1-1500 sec (base on tuya app) issue : i am not sure why the value of motion & present sensitivity will mutiply by 10 after setting

const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const e = exposes.presets;
const ea = exposes.access;

const tzDatapoints = {
    ...tuya.tz.datapoints,
    key: [
        'switch_1', 'switch_2', 'countdown_1', 'countdown_2', 'work_mode', 'bright_value', 'temp_value', 'illuminance_value', 
          'presence_state', 'move_sensitivity', 'motion_sensitivity', 'detection_distance_max', 'detection_distance_min', 'far_detection', 'target_dis_closest', 'fading_time', 'presence_sensitivity', 'man_state' 
    ],
}

const definition = {
    fingerprint: [ { modelID: 'TS0601', manufacturerName: '_TZE204_ijxvkhd0'}],
    model: 'ZY-M100-24G',
    vendor: 'TuYa',
    description: 'Micro Motion Sensor v1.2 ',
    configure: tuya.configureMagicPacket,
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tzDatapoints],
    exposes: [
        e.illuminance_lux(), e.presence(),
        e.enum('presence_state', ea.STATE, ['none', 'present', 'moving']).withDescription('Presence state'),
        e.numeric('motion_sensitivity', ea.STATE_SET).withValueMin(2).withValueMax(7).withValueStep(1).withDescription('Motion sensitivity'),
        e.numeric('presence_sensitivity', ea.STATE_SET).withValueMin(3).withValueMax(9).withValueStep(1).withDescription('Presence sensitivity'),
        e.numeric('detection_distance_max', ea.STATE_SET).withValueMin(1.5).withValueMax(5.5).withValueStep(1).withDescription('Max detection distance').withUnit('m'),
        e.numeric('fading_time', ea.STATE_SET).withValueMin(0).withValueMax(1500).withValueStep(1).withDescription('Delay time').withUnit('s'),
        e.numeric('target_distance', ea.STATE).withDescription('Distance to target').withUnit('m'),

    ],

    meta: {
        tuyaDatapoints: [
            [104, 'illuminance_lux', tuya.valueConverter.raw],
            [105, 'presence_state', tuya.valueConverterBasic.lookup({'None': tuya.enum(0), 'Present': tuya.enum(1), 'Moving': tuya.enum(2)})],
            [106, 'motion_sensitivity', tuya.valueConverter.raw], //2-7
            [107, 'detection_distance_max', tuya.valueConverter.divideBy100],
            [109, 'target_distance', tuya.valueConverter.divideBy100],
            [110, 'fading_time', tuya.valueConverter.raw],
            [111, 'presence_sensitivity', tuya.valueConverter.raw],// 2-9
            [112, 'presence', tuya.valueConverter.trueFalse1],
        ],
    },
};

module.exports = definition;

modify two row ..

      [106, 'motion_sensitivity', tuya.valueConverter.divideBy10],

      [111, 'presence_sensitivity', tuya.valueConverter.divideBy10],

now the two value of motion & present sensitivity are corrects

Thank you for this code! The modifications are working much better; however I'm experiencing the presence state switch from "None" to Present" and vice versa every few minutes regardless of the sensitivity settings.

Edit: Sensitivity settings no longer stick and revert back

Dillton commented 10 months ago

i have modified the converter base on the param of tuya app, so far is working good . motion_sensitivity : Level 2-7 (base on tuya dev device log only, not sure how accurate) presence_sensitivity : Level 3-9 (base on tuya dev device log only, not sure how accurate) sensitivity value: lowest is the most sensitive distance : 1.5-5.5m ( base on tuya app) fading Time : 1-1500 sec (base on tuya app) issue : i am not sure why the value of motion & present sensitivity will mutiply by 10 after setting

const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const e = exposes.presets;
const ea = exposes.access;

const tzDatapoints = {
    ...tuya.tz.datapoints,
    key: [
        'switch_1', 'switch_2', 'countdown_1', 'countdown_2', 'work_mode', 'bright_value', 'temp_value', 'illuminance_value', 
          'presence_state', 'move_sensitivity', 'motion_sensitivity', 'detection_distance_max', 'detection_distance_min', 'far_detection', 'target_dis_closest', 'fading_time', 'presence_sensitivity', 'man_state' 
    ],
}

const definition = {
    fingerprint: [ { modelID: 'TS0601', manufacturerName: '_TZE204_ijxvkhd0'}],
    model: 'ZY-M100-24G',
    vendor: 'TuYa',
    description: 'Micro Motion Sensor v1.2 ',
    configure: tuya.configureMagicPacket,
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tzDatapoints],
    exposes: [
        e.illuminance_lux(), e.presence(),
        e.enum('presence_state', ea.STATE, ['none', 'present', 'moving']).withDescription('Presence state'),
        e.numeric('motion_sensitivity', ea.STATE_SET).withValueMin(2).withValueMax(7).withValueStep(1).withDescription('Motion sensitivity'),
        e.numeric('presence_sensitivity', ea.STATE_SET).withValueMin(3).withValueMax(9).withValueStep(1).withDescription('Presence sensitivity'),
        e.numeric('detection_distance_max', ea.STATE_SET).withValueMin(1.5).withValueMax(5.5).withValueStep(1).withDescription('Max detection distance').withUnit('m'),
        e.numeric('fading_time', ea.STATE_SET).withValueMin(0).withValueMax(1500).withValueStep(1).withDescription('Delay time').withUnit('s'),
        e.numeric('target_distance', ea.STATE).withDescription('Distance to target').withUnit('m'),

    ],

    meta: {
        tuyaDatapoints: [
            [104, 'illuminance_lux', tuya.valueConverter.raw],
            [105, 'presence_state', tuya.valueConverterBasic.lookup({'None': tuya.enum(0), 'Present': tuya.enum(1), 'Moving': tuya.enum(2)})],
            [106, 'motion_sensitivity', tuya.valueConverter.raw], //2-7
            [107, 'detection_distance_max', tuya.valueConverter.divideBy100],
            [109, 'target_distance', tuya.valueConverter.divideBy100],
            [110, 'fading_time', tuya.valueConverter.raw],
            [111, 'presence_sensitivity', tuya.valueConverter.raw],// 2-9
            [112, 'presence', tuya.valueConverter.trueFalse1],
        ],
    },
};

module.exports = definition;

modify two row ..

      [106, 'motion_sensitivity', tuya.valueConverter.divideBy10],

      [111, 'presence_sensitivity', tuya.valueConverter.divideBy10],

now the two value of motion & present sensitivity are corrects

Confirm works better with this code. But question is does anyone have the ceiling version of this sensor? Because the settings not working for 100%. I can set any value for motion and presence sensitivity but is always change to 10: image I think this might be similar situation with previous 5G generation where the drivers were a bit different for both if I am not mistaken.

Hi, i am using the ceiling version and the setting sticks , try to reset the divece n repair ?

Thanks for the tip but reseting and repairing was the first I tried. So unfortunatelly this does not help.

dinde commented 10 months ago

Hi guys,

I can't test it because I sent it back but there is the converter provided by seller below:

const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const e = exposes.presets;
const ea = exposes.access;
const legacy = require('zigbee-herdsman-converters/lib/legacy');

const tuya = require('zigbee-herdsman-converters/lib/tuya');

const dataTypes = {
    raw: 0, // [ bytes ]
    bool: 1, // [0/1]
    number: 2, // [ 4 byte value ]
    string: 3, // [ N byte string ]
    enum: 4, // [ 0-255 ]
    bitmap: 5, // [ 1,2,4 bytes ] as bits
};

const dpMap = {
    dpPresenceState: 112, //是否存在,仅上报
    dpState: 105, //感应状态
    dpMoveSensitivity: 106, //灵敏度
    dpPresenceSensitivity: 111, //灵敏度

    dpTimeout: 110, //感应延迟

    dpDistance: 109, //目标距离

    dpRange: 107, //最远距离范围
    dpIlluminanceLux: 104, //光照度

};
const fzLocal = {
    cluster: 'manuSpecificTuya',
    type: ['commandDataResponse', 'commandDataReport'],
    convert: (model, msg, publish, options, meta) => {
        const dp = msg.data.dpValues[0].dp;
        const data = msg.data;
        const value = legacy.getDataValue(data.dpValues[0]);
        const result = {};

        switch (dp) {
            case dpMap.dpPresenceState:
                result.presence = value ? true : false;
                break;
            case dpMap.dpMoveSensitivity: //灵敏度
                result.move_sensitivity = (value / 10);
                break;
            case dpMap.dpPresenceSensitivity: //静止灵敏度
                result.presence_sensitivity = (value / 10);
                break;
            case dpMap.dpRange: //雷达距离15-55
                result.radar_range = (value / 100);
                break;
            case dpMap.dpDistance: //目标距离
                result.distance = (value / 100);
                break;
            case dpMap.dpTimeout: //延迟时间0-600
                result.presence_timeout = (value);
                break;
            case dpMap.dpIlluminanceLux: //光照度
                result.illuminance_lux = (value);
                break;

            case dpMap.dpState:
                result.state = {
                    0: 'none',
                    1: 'presence',
                    2: 'move'
                } [value];
                break;

                // meta.logger.debug(
                //  `未解析的数据DP: ${dp} DATA: ${JSON.stringify(msg.data)}`
                // );

        }
        return result;
    },
}
const tzLocal = {
    key: [
        'move_sensitivity',
        'presence_sensitivity',
        'radar_range',
        'presence_timeout',

    ],
    convertSet: async (entity, key, value, meta) => {

        switch (key) {
            case 'move_sensitivity':
                await legacy.sendDataPointValue(entity, dpMap.dpMoveSensitivity, value);
                break;
            case 'presence_sensitivity':
                await legacy.sendDataPointValue(entity, dpMap.dpPresenceSensitivity, value);
                break;
            case 'radar_range':
                await legacy.sendDataPointValue(entity, dpMap.dpRange, value * 100);
                break;
            case 'presence_timeout':
                await legacy.sendDataPointValue(entity, dpMap.dpTimeout, value);
                break;

        }
        return {
            key: value
        };
    },

}

module.exports = [{
    fingerprint: [{
        modelID: 'TS0601',
        manufacturerName: '_TZE204_ijxvkhd0',
    }],
    model: '24G 人体存在传感器',
    vendor: 'TuYa',
    description: '24G 人体存在传感器',
    fromZigbee: [fzLocal],
    toZigbee: [tzLocal],
    onEvent: legacy.onEventSetLocalTime,
    exposes: [

        exposes.enum('state', ea.STATE, ['none', 'presence', 'move'])
        .withDescription('感应状态'),

        e.presence().withDescription('是否在家'),

        exposes.numeric('distance', ea.STATE)
        .withDescription('目标距离'),

        e.illuminance_lux(),
        exposes.numeric('move_sensitivity', ea.STATE_SET).withValueMin(1)
        .withValueMax(10)
        .withValueStep(1)
        .withDescription('运动雷达灵敏度'),

        exposes.numeric('presence_sensitivity', ea.STATE_SET).withValueMin(1)
        .withValueMax(10)
        .withValueStep(1)
        .withDescription('静止雷达灵敏度'),

        exposes.numeric('radar_range', ea.STATE_SET).withValueMin(1.5)
        .withValueMax(5.5)
        .withValueStep(1)
        .withUnit('米').withDescription('雷达感应距离'),

        exposes.numeric('presence_timeout', ea.STATE_SET).withValueMin(1)
        .withValueMax(1500)
        .withValueStep(1)
        .withUnit('秒').withDescription('延迟时间'),

    ],
    meta: {
        multiEndpoint: true,
        tuyaDatapoints: [

            [112, 'presence', tuya.valueConverter.trueFalse1],
            [106, 'move_sensitivity', tuya.valueConverter.divideBy10],
            [111, 'presence_sensitivity', tuya.valueConverter.divideBy10],

            [107, 'radar_range', tuya.valueConverter.divideBy100],
            [109, 'distance', tuya.valueConverter.divideBy100],
            [110, 'presence_timeout', tuya.valueConverter.raw],
            [104, 'illuminance_lux', tuya.valueConverter.raw],
            [105, 'state', tuya.valueConverterBasic.lookup({
                'none': 0,
                'presence': 1,
                'move': 2
            })],

        ],
    },

}, ];

HTH

akumamg commented 10 months ago

Hi guys,

I can't test it because I sent it back but there is the converter provided by seller below:

const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const e = exposes.presets;
const ea = exposes.access;
const legacy = require('zigbee-herdsman-converters/lib/legacy');

const tuya = require('zigbee-herdsman-converters/lib/tuya');

const dataTypes = {
  raw: 0, // [ bytes ]
  bool: 1, // [0/1]
  number: 2, // [ 4 byte value ]
  string: 3, // [ N byte string ]
  enum: 4, // [ 0-255 ]
  bitmap: 5, // [ 1,2,4 bytes ] as bits
};

const dpMap = {
  dpPresenceState: 112, //是�存在,仅上报
  dpState: 105, //感应状�
  dpMoveSensitivity: 106, //��度
  dpPresenceSensitivity: 111, //��度

  dpTimeout: 110, //感应延迟

  dpDistance: 109, //目标�离

  dpRange: 107, //最远�离范围
  dpIlluminanceLux: 104, //光照度

};
const fzLocal = {
  cluster: 'manuSpecificTuya',
  type: ['commandDataResponse', 'commandDataReport'],
  convert: (model, msg, publish, options, meta) => {
      const dp = msg.data.dpValues[0].dp;
      const data = msg.data;
      const value = legacy.getDataValue(data.dpValues[0]);
      const result = {};

      switch (dp) {
          case dpMap.dpPresenceState:
              result.presence = value ? true : false;
              break;
          case dpMap.dpMoveSensitivity: //��度
              result.move_sensitivity = (value / 10);
              break;
          case dpMap.dpPresenceSensitivity: //�止��度
              result.presence_sensitivity = (value / 10);
              break;
          case dpMap.dpRange: //雷达�离15-55
              result.radar_range = (value / 100);
              break;
          case dpMap.dpDistance: //目标�离
              result.distance = (value / 100);
              break;
          case dpMap.dpTimeout: //延迟时间0-600
              result.presence_timeout = (value);
              break;
          case dpMap.dpIlluminanceLux: //光照度
              result.illuminance_lux = (value);
              break;

          case dpMap.dpState:
              result.state = {
                  0: 'none',
                  1: 'presence',
                  2: 'move'
              } [value];
              break;

              // meta.logger.debug(
              //  `未解�的数�DP: ${dp} DATA: ${JSON.stringify(msg.data)}`
              // );

      }
      return result;
  },
}
const tzLocal = {
  key: [
      'move_sensitivity',
      'presence_sensitivity',
      'radar_range',
      'presence_timeout',

  ],
  convertSet: async (entity, key, value, meta) => {

      switch (key) {
          case 'move_sensitivity':
              await legacy.sendDataPointValue(entity, dpMap.dpMoveSensitivity, value);
              break;
          case 'presence_sensitivity':
              await legacy.sendDataPointValue(entity, dpMap.dpPresenceSensitivity, value);
              break;
          case 'radar_range':
              await legacy.sendDataPointValue(entity, dpMap.dpRange, value * 100);
              break;
          case 'presence_timeout':
              await legacy.sendDataPointValue(entity, dpMap.dpTimeout, value);
              break;

      }
      return {
          key: value
      };
  },

}

module.exports = [{
  fingerprint: [{
      modelID: 'TS0601',
      manufacturerName: '_TZE204_ijxvkhd0',
  }],
  model: '24G 人体存在传感器',
  vendor: 'TuYa',
  description: '24G 人体存在传感器',
  fromZigbee: [fzLocal],
  toZigbee: [tzLocal],
  onEvent: legacy.onEventSetLocalTime,
  exposes: [

      exposes.enum('state', ea.STATE, ['none', 'presence', 'move'])
      .withDescription('感应状�'),

      e.presence().withDescription('是�在家'),

      exposes.numeric('distance', ea.STATE)
      .withDescription('目标�离'),

      e.illuminance_lux(),
      exposes.numeric('move_sensitivity', ea.STATE_SET).withValueMin(1)
      .withValueMax(10)
      .withValueStep(1)
      .withDescription('�动雷达��度'),

      exposes.numeric('presence_sensitivity', ea.STATE_SET).withValueMin(1)
      .withValueMax(10)
      .withValueStep(1)
      .withDescription('�止雷达��度'),

      exposes.numeric('radar_range', ea.STATE_SET).withValueMin(1.5)
      .withValueMax(5.5)
      .withValueStep(1)
      .withUnit('米').withDescription('雷达感应�离'),

      exposes.numeric('presence_timeout', ea.STATE_SET).withValueMin(1)
      .withValueMax(1500)
      .withValueStep(1)
      .withUnit('秒').withDescription('延迟时间'),

  ],
  meta: {
      multiEndpoint: true,
      tuyaDatapoints: [

          [112, 'presence', tuya.valueConverter.trueFalse1],
          [106, 'move_sensitivity', tuya.valueConverter.divideBy10],
          [111, 'presence_sensitivity', tuya.valueConverter.divideBy10],

          [107, 'radar_range', tuya.valueConverter.divideBy100],
          [109, 'distance', tuya.valueConverter.divideBy100],
          [110, 'presence_timeout', tuya.valueConverter.raw],
          [104, 'illuminance_lux', tuya.valueConverter.raw],
          [105, 'state', tuya.valueConverterBasic.lookup({
              'none': 0,
              'presence': 1,
              'move': 2
          })],

      ],
  },

}, ];

HTH

I just tested and looks like its working :) But you need translate description.

Dataninja126 commented 10 months ago

@akumamg could you provide the translated description version :)

dinde commented 10 months ago

@akumamg could you provide the translated description version :)

There you go:

const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const e = exposes.presets;
const ea = exposes.access;
const legacy = require('zigbee-herdsman-converters/lib/legacy');

const tuya = require('zigbee-herdsman-converters/lib/tuya');

const dataTypes = {
    raw: 0, // [ bytes ]
    bool: 1, // [0/1]
    number: 2, // [ 4 byte value ]
    string: 3, // [ N byte string ]
    enum: 4, // [ 0-255 ]
    bitmap: 5, // [ 1,2,4 bytes ] as bits
};

const dpMap = {
    dpPresenceState: 112, //是�存在,仅上报
    dpState: 105, //感应状�
    dpMoveSensitivity: 106, //��度
    dpPresenceSensitivity: 111, //��度

    dpTimeout: 110, //感应延迟

    dpDistance: 109, //目标�离

    dpRange: 107, //最远�离范围
    dpIlluminanceLux: 104, //光照度

};
const fzLocal = {
    cluster: 'manuSpecificTuya',
    type: ['commandDataResponse', 'commandDataReport'],
    convert: (model, msg, publish, options, meta) => {
        const dp = msg.data.dpValues[0].dp;
        const data = msg.data;
        const value = legacy.getDataValue(data.dpValues[0]);
        const result = {};

        switch (dp) {
            case dpMap.dpPresenceState:
                result.presence = value ? true : false;
                break;
            case dpMap.dpMoveSensitivity: 
                result.move_sensitivity = (value / 10);
                break;
            case dpMap.dpPresenceSensitivity: 
                result.presence_sensitivity = (value / 10);
                break;
            case dpMap.dpRange: 
                result.radar_range = (value / 100);
                break;
            case dpMap.dpDistance: 
                result.distance = (value / 100);
                break;
            case dpMap.dpTimeout: 
                result.presence_timeout = (value);
                break;
            case dpMap.dpIlluminanceLux: 
                result.illuminance_lux = (value);
                break;

            case dpMap.dpState:
                result.state = {
                    0: 'none',
                    1: 'presence',
                    2: 'move'
                } [value];
                break;
        }
        return result;
    },
}
const tzLocal = {
    key: [
        'move_sensitivity',
        'presence_sensitivity',
        'radar_range',
        'presence_timeout',

    ],
    convertSet: async (entity, key, value, meta) => {

        switch (key) {
            case 'move_sensitivity':
                await legacy.sendDataPointValue(entity, dpMap.dpMoveSensitivity, value);
                break;
            case 'presence_sensitivity':
                await legacy.sendDataPointValue(entity, dpMap.dpPresenceSensitivity, value);
                break;
            case 'radar_range':
                await legacy.sendDataPointValue(entity, dpMap.dpRange, value * 100);
                break;
            case 'presence_timeout':
                await legacy.sendDataPointValue(entity, dpMap.dpTimeout, value);
                break;

        }
        return {
            key: value
        };
    },

}

module.exports = [{
    fingerprint: [{
        modelID: 'TS0601',
        manufacturerName: '_TZE204_ijxvkhd0',
    }],
    model: 'ZY-M100-24G',
    vendor: 'TuYa',
    description: '24G Micro Motion Sensor',
    fromZigbee: [fzLocal],
    toZigbee: [tzLocal],
    onEvent: legacy.onEventSetLocalTime,
    exposes: [

        exposes.enum('state', ea.STATE, ['none', 'presence', 'move'])
        .withDescription('Presence State'),

        e.presence(),

        exposes.numeric('distance', ea.STATE)
        .withDescription('Distance'),

        e.illuminance_lux(),
        exposes.numeric('move_sensitivity', ea.STATE_SET).withValueMin(1)
        .withValueMax(10)
        .withValueStep(1)
        .withDescription('Motion Sensitivity'),

        exposes.numeric('presence_sensitivity', ea.STATE_SET).withValueMin(1)
        .withValueMax(10)
        .withValueStep(1)
        .withDescription('Presence Sensitivity'),

        exposes.numeric('radar_range', ea.STATE_SET).withValueMin(1.5)
        .withValueMax(5.5)
        .withValueStep(1)
        .withUnit('m').withDescription('Detection Range'),

        exposes.numeric('presence_timeout', ea.STATE_SET).withValueMin(1)
        .withValueMax(1500)
        .withValueStep(1)
        .withUnit('s').withDescription('Presence Time Out'),

    ],
    meta: {
        multiEndpoint: true,
        tuyaDatapoints: [

            [112, 'presence', tuya.valueConverter.trueFalse1],
            [106, 'move_sensitivity', tuya.valueConverter.divideBy10],
            [111, 'presence_sensitivity', tuya.valueConverter.divideBy10],

            [107, 'radar_range', tuya.valueConverter.divideBy100],
            [109, 'distance', tuya.valueConverter.divideBy100],
            [110, 'presence_timeout', tuya.valueConverter.raw],
            [104, 'illuminance_lux', tuya.valueConverter.raw],
            [105, 'state', tuya.valueConverterBasic.lookup({
                'none': 0,
                'presence': 1,
                'move': 2
            })],

        ],
    },

}, ];
nickgoh commented 10 months ago

@akumamg could you provide the translated description version :)

There you go:

const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const e = exposes.presets;
const ea = exposes.access;
const legacy = require('zigbee-herdsman-converters/lib/legacy');

const tuya = require('zigbee-herdsman-converters/lib/tuya');

const dataTypes = {
  raw: 0, // [ bytes ]
  bool: 1, // [0/1]
  number: 2, // [ 4 byte value ]
  string: 3, // [ N byte string ]
  enum: 4, // [ 0-255 ]
  bitmap: 5, // [ 1,2,4 bytes ] as bits
};

const dpMap = {
  dpPresenceState: 112, //是�存在,仅上报
  dpState: 105, //感应状�
  dpMoveSensitivity: 106, //��度
  dpPresenceSensitivity: 111, //��度

  dpTimeout: 110, //感应延迟

  dpDistance: 109, //目标�离

  dpRange: 107, //最远�离范围
  dpIlluminanceLux: 104, //光照度

};
const fzLocal = {
  cluster: 'manuSpecificTuya',
  type: ['commandDataResponse', 'commandDataReport'],
  convert: (model, msg, publish, options, meta) => {
      const dp = msg.data.dpValues[0].dp;
      const data = msg.data;
      const value = legacy.getDataValue(data.dpValues[0]);
      const result = {};

      switch (dp) {
          case dpMap.dpPresenceState:
              result.presence = value ? true : false;
              break;
          case dpMap.dpMoveSensitivity: 
              result.move_sensitivity = (value / 10);
              break;
          case dpMap.dpPresenceSensitivity: 
              result.presence_sensitivity = (value / 10);
              break;
          case dpMap.dpRange: 
              result.radar_range = (value / 100);
              break;
          case dpMap.dpDistance: 
              result.distance = (value / 100);
              break;
          case dpMap.dpTimeout: 
              result.presence_timeout = (value);
              break;
          case dpMap.dpIlluminanceLux: 
              result.illuminance_lux = (value);
              break;

          case dpMap.dpState:
              result.state = {
                  0: 'none',
                  1: 'presence',
                  2: 'move'
              } [value];
              break;
      }
      return result;
  },
}
const tzLocal = {
  key: [
      'move_sensitivity',
      'presence_sensitivity',
      'radar_range',
      'presence_timeout',

  ],
  convertSet: async (entity, key, value, meta) => {

      switch (key) {
          case 'move_sensitivity':
              await legacy.sendDataPointValue(entity, dpMap.dpMoveSensitivity, value);
              break;
          case 'presence_sensitivity':
              await legacy.sendDataPointValue(entity, dpMap.dpPresenceSensitivity, value);
              break;
          case 'radar_range':
              await legacy.sendDataPointValue(entity, dpMap.dpRange, value * 100);
              break;
          case 'presence_timeout':
              await legacy.sendDataPointValue(entity, dpMap.dpTimeout, value);
              break;

      }
      return {
          key: value
      };
  },

}

module.exports = [{
  fingerprint: [{
      modelID: 'TS0601',
      manufacturerName: '_TZE204_ijxvkhd0',
  }],
  model: 'ZY-M100-24G',
  vendor: 'TuYa',
  description: '24G Micro Motion Sensor',
  fromZigbee: [fzLocal],
  toZigbee: [tzLocal],
  onEvent: legacy.onEventSetLocalTime,
  exposes: [

      exposes.enum('state', ea.STATE, ['none', 'presence', 'move'])
      .withDescription('Presence State'),

      e.presence(),

      exposes.numeric('distance', ea.STATE)
      .withDescription('Distance'),

      e.illuminance_lux(),
      exposes.numeric('move_sensitivity', ea.STATE_SET).withValueMin(1)
      .withValueMax(10)
      .withValueStep(1)
      .withDescription('Motion Sensitivity'),

      exposes.numeric('presence_sensitivity', ea.STATE_SET).withValueMin(1)
      .withValueMax(10)
      .withValueStep(1)
      .withDescription('Presence Sensitivity'),

      exposes.numeric('radar_range', ea.STATE_SET).withValueMin(1.5)
      .withValueMax(5.5)
      .withValueStep(1)
      .withUnit('m').withDescription('Detection Range'),

      exposes.numeric('presence_timeout', ea.STATE_SET).withValueMin(1)
      .withValueMax(1500)
      .withValueStep(1)
      .withUnit('s').withDescription('Presence Time Out'),

  ],
  meta: {
      multiEndpoint: true,
      tuyaDatapoints: [

          [112, 'presence', tuya.valueConverter.trueFalse1],
          [106, 'move_sensitivity', tuya.valueConverter.divideBy10],
          [111, 'presence_sensitivity', tuya.valueConverter.divideBy10],

          [107, 'radar_range', tuya.valueConverter.divideBy100],
          [109, 'distance', tuya.valueConverter.divideBy100],
          [110, 'presence_timeout', tuya.valueConverter.raw],
          [104, 'illuminance_lux', tuya.valueConverter.raw],
          [105, 'state', tuya.valueConverterBasic.lookup({
              'none': 0,
              'presence': 1,
              'move': 2
          })],

      ],
  },

}, ];

Confirm working , 1 had the higest sensitivity and 10 being the lowest.

Sensitivity value will divided by 10 after set but will return to normal value after a while.

Dataninja126 commented 10 months ago

@akumamg could you provide the translated description version :)

There you go:

const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const e = exposes.presets;
const ea = exposes.access;
const legacy = require('zigbee-herdsman-converters/lib/legacy');

const tuya = require('zigbee-herdsman-converters/lib/tuya');

const dataTypes = {
  raw: 0, // [ bytes ]
  bool: 1, // [0/1]
  number: 2, // [ 4 byte value ]
  string: 3, // [ N byte string ]
  enum: 4, // [ 0-255 ]
  bitmap: 5, // [ 1,2,4 bytes ] as bits
};

const dpMap = {
  dpPresenceState: 112, //是�存在,仅上报
  dpState: 105, //感应状�
  dpMoveSensitivity: 106, //��度
  dpPresenceSensitivity: 111, //��度

  dpTimeout: 110, //感应延迟

  dpDistance: 109, //目标�离

  dpRange: 107, //最远�离范围
  dpIlluminanceLux: 104, //光照度

};
const fzLocal = {
  cluster: 'manuSpecificTuya',
  type: ['commandDataResponse', 'commandDataReport'],
  convert: (model, msg, publish, options, meta) => {
      const dp = msg.data.dpValues[0].dp;
      const data = msg.data;
      const value = legacy.getDataValue(data.dpValues[0]);
      const result = {};

      switch (dp) {
          case dpMap.dpPresenceState:
              result.presence = value ? true : false;
              break;
          case dpMap.dpMoveSensitivity: 
              result.move_sensitivity = (value / 10);
              break;
          case dpMap.dpPresenceSensitivity: 
              result.presence_sensitivity = (value / 10);
              break;
          case dpMap.dpRange: 
              result.radar_range = (value / 100);
              break;
          case dpMap.dpDistance: 
              result.distance = (value / 100);
              break;
          case dpMap.dpTimeout: 
              result.presence_timeout = (value);
              break;
          case dpMap.dpIlluminanceLux: 
              result.illuminance_lux = (value);
              break;

          case dpMap.dpState:
              result.state = {
                  0: 'none',
                  1: 'presence',
                  2: 'move'
              } [value];
              break;
      }
      return result;
  },
}
const tzLocal = {
  key: [
      'move_sensitivity',
      'presence_sensitivity',
      'radar_range',
      'presence_timeout',

  ],
  convertSet: async (entity, key, value, meta) => {

      switch (key) {
          case 'move_sensitivity':
              await legacy.sendDataPointValue(entity, dpMap.dpMoveSensitivity, value);
              break;
          case 'presence_sensitivity':
              await legacy.sendDataPointValue(entity, dpMap.dpPresenceSensitivity, value);
              break;
          case 'radar_range':
              await legacy.sendDataPointValue(entity, dpMap.dpRange, value * 100);
              break;
          case 'presence_timeout':
              await legacy.sendDataPointValue(entity, dpMap.dpTimeout, value);
              break;

      }
      return {
          key: value
      };
  },

}

module.exports = [{
  fingerprint: [{
      modelID: 'TS0601',
      manufacturerName: '_TZE204_ijxvkhd0',
  }],
  model: 'ZY-M100-24G',
  vendor: 'TuYa',
  description: '24G Micro Motion Sensor',
  fromZigbee: [fzLocal],
  toZigbee: [tzLocal],
  onEvent: legacy.onEventSetLocalTime,
  exposes: [

      exposes.enum('state', ea.STATE, ['none', 'presence', 'move'])
      .withDescription('Presence State'),

      e.presence(),

      exposes.numeric('distance', ea.STATE)
      .withDescription('Distance'),

      e.illuminance_lux(),
      exposes.numeric('move_sensitivity', ea.STATE_SET).withValueMin(1)
      .withValueMax(10)
      .withValueStep(1)
      .withDescription('Motion Sensitivity'),

      exposes.numeric('presence_sensitivity', ea.STATE_SET).withValueMin(1)
      .withValueMax(10)
      .withValueStep(1)
      .withDescription('Presence Sensitivity'),

      exposes.numeric('radar_range', ea.STATE_SET).withValueMin(1.5)
      .withValueMax(5.5)
      .withValueStep(1)
      .withUnit('m').withDescription('Detection Range'),

      exposes.numeric('presence_timeout', ea.STATE_SET).withValueMin(1)
      .withValueMax(1500)
      .withValueStep(1)
      .withUnit('s').withDescription('Presence Time Out'),

  ],
  meta: {
      multiEndpoint: true,
      tuyaDatapoints: [

          [112, 'presence', tuya.valueConverter.trueFalse1],
          [106, 'move_sensitivity', tuya.valueConverter.divideBy10],
          [111, 'presence_sensitivity', tuya.valueConverter.divideBy10],

          [107, 'radar_range', tuya.valueConverter.divideBy100],
          [109, 'distance', tuya.valueConverter.divideBy100],
          [110, 'presence_timeout', tuya.valueConverter.raw],
          [104, 'illuminance_lux', tuya.valueConverter.raw],
          [105, 'state', tuya.valueConverterBasic.lookup({
              'none': 0,
              'presence': 1,
              'move': 2
          })],

      ],
  },

}, ];

Confirm this works much better. Thank you @akumamg and @dinde. Something interesting still happening with motion sensitivity in Zigbee2mqtt, but this converter has solved many of my issues.

kkossev commented 10 months ago

If I read the latest converter code correctly, it works this way:

I.e. the device requires the sensitivity parameters to be sent in the range of 1 to 10, but reports them back multiplied by 10?

mindtripper commented 10 months ago

If I read the latest converter code correctly, it works this way:

  • move_sensitivity and presence_sensitivity are sent from Z2M to the device as integer values in the range of 1 to 10
  • move_sensitivity and presence_sensitivity are received by Z2M from the device are in the range of 10 to 100 and are divided by 10.

I.e. the device requires the sensitivity parameters to be sent in the range of 1 to 10, but reports them back multiplied by 10?

Yes, this is what I found using my rudimentary version of the converter. https://github.com/Koenkk/zigbee2mqtt/issues/18237#issuecomment-1686357343

Dataninja126 commented 10 months ago

If I read the latest converter code correctly, it works this way:

  • move_sensitivity and presence_sensitivity are sent from Z2M to the device as integer values in the range of 1 to 10
  • move_sensitivity and presence_sensitivity are received by Z2M from the device are in the range of 10 to 100 and are divided by 10.

I.e. the device requires the sensitivity parameters to be sent in the range of 1 to 10, but reports them back multiplied by 10?

Seems to be the case, but Home Assistant doesn't like it and reports this error in the logs

Logger: homeassistant.components.mqtt.number
Source: components/mqtt/number.py:201
Integration: MQTT ([documentation](https://www.home-assistant.io/integrations/mqtt), [issues](https://github.com/home-assistant/core/issues?q=is%3Aissue+is%3Aopen+label%3A%22integration%3A+mqtt%22))
First occurred: 9:21:26 AM (5992 occurrences)
Last logged: 10:09:27 AM

Invalid value for number.move_sensitivity: 30 (range 1.0 - 10.0)
Invalid value for number.presence_sensitivity: 30 (range 1.0 - 10.0)
Adaaks commented 10 months ago

the latest converter doesnt seem to work for me, it always detects presence or move, even though nobody is in room...anyone have same issue?

the detection distance, fading time, motion sesnsitivity is greyed out

image

Adaaks commented 10 months ago

setting move and presence to 2 seems to do the trick, it seems as though this sensor is really sensitive on the lowest mode

Adaaks commented 10 months ago

for some reason the mm wave sensor flickers to presence and then goes back to none shortly after, distance is 1.5m or 0m, is this because of bugs, or is it because i cant set detetion distance min??? there is 100% no movement in room

kingunlim commented 10 months ago

none of the fixes works right sadly :( i hope there will there be a working version in the future. otherwise i must return. someone know if the zha version is working?

kkossev commented 10 months ago

I can't report success too...

We will need a WireShark capture file that includes the pairing/initialisation from Tuya Zigbee GW and the commands sent when the presets are sent to the device from Smart Life app.

kingunlim commented 10 months ago

my main problem is, that i tried every setting but when i lay on my couch and be still the presence change to not present, so basically i have a motion sensor at the moment :(

kingunlim commented 10 months ago

is this just a problem because the 24g device is so new and so the support is not there yet, or is it a other problem that the device is just bad?

patrex0304 commented 10 months ago

I can do the wireshark capture, but i am not quite sure how that could help. Is there a source how the capture can be analyzed? Already done a capture but i could not figure things out.

kkossev commented 10 months ago

From the WireShark capture file, we should be able to see if the Tuya Zigbee GW sends any unusual initialization commands during the pairing process, whether SmartLife sends the two sensitivity parameters (DP 106 and 111) multiplied by 10 or not, whether it uses the standard SETDATA command 0x00 or not (some Tuya devices may require non-standard command 0x04 for setting the DP values), etc..

The sniff should include pairing of the _TZE204_ijxvkhd0 to a Tuya gateway and changing the settings ( L1..L5) from the Smart Life app.

nickgoh commented 10 months ago

From the WireShark capture file, we should be able to see if the Tuya Zigbee GW sends any unusual initialization commands during the pairing process, whether SmartLife sends the two sensitivity parameters (DP 106 and 111) multiplied by 10 or not, whether it uses the standard SETDATA command 0x00 or not (some Tuya devices may require non-standard command 0x04 for setting the DP values), etc..

The sniff should include pairing of the _TZE204_ijxvkhd0 to a Tuya gateway and changing the settings ( L1..L5) from the Smart Life app.

Hi , i just did a sniffing but i m not sure how to decrypt the data but it appear to be using 0x00 command.

smartlife_pairing.pcap.gz smartlife__mmwave24G_L1_to_L5.pcap.gz

kkossev commented 10 months ago

Hi , i just did a sniffing but i m not sure how to decrypt the data but it appear to be using 0x00 command.

smartlife_pairing.pcap.gz smartlife__mmwave24G_L1_to_L5.pcap.gz

Thank you!

From my quick analysis of the L1_to_L5 pcap file :

Now I think that only these certain combinations of the presence_sensitivity and move_sensitivity are retained : Level presence_sensitivity move_sensitivity
L1 9 7
L2 7 6
L3 6 4
L4 4 2
L5 3 2

I will have to experiment whether sending the two sensitivity parameters at once is a requrement, or simly sticking to the allowed combinations is enough.

It is still a mystery however, why the sensitivity parameters in Tuya app are sent and received as numbers in the range 2..9, but when used with another Zigbee coordinator the sensitivity parameters are returned multiplied by 10. The answer can be in the first PCAP file ...

kkossev commented 10 months ago
  • after the combined command, the move_sensitivity is sent once again, which is a bit strange

Seems like this is the key!

The two sensitivity parameters must be sent two times to the device - then the settings are retained. If a sensitivity parameter is changed, but sent only once - after some time the device reverts back to the previous value.

Sending all the radar parameters two times within a few seconds was confirmed to be working (in another home automation system). The valid range is 1..9. All presence_sensitivity / move_sensitivity combinations are accepted and stored, not only these in the presets table.

kingunlim commented 10 months ago

@kkossev thank for all your work, also thanks to @nickgoh for providing the cap.

does that mean there will be a new dev update or do you need to investigate more?

best regards

kingunlim commented 10 months ago

i tried to set the values 2 times but always the same it just jumps right back to default values :(

kkossev commented 10 months ago

Are you using any converters for this device? If yes, try disabling them.

Actually, I am not quite sure how it is possible to send all the device parameters again,without changing any of them in HA... As I mentioned, the successful tests were made in another home automation system. And unfortunately I don't have exactly this mmWave sensor to try it myself.

UPDATE: I just got an update today that the device is returning the two sensitivity parameters back multiplied by 10 .. : ( I.e. the move_sensitivity and presence_sensitivity sent twice in the 1..9 range are retained but reported back from the device in the 10..90 range. Obviously, there are still more issues remaining to be solved.

kingunlim commented 10 months ago

Are you using any converters for this device? If yes, try disabling them.

Actually, I am not quite sure how it is possible to send all the device parameters again,without changing any of them in HA... As I mentioned, the successful tests were made in another home automation system. And unfortunately I don't have exactly this mmWave sensor to try it myself.

UPDATE: I just got an update today that the device is returning the two sensitivity parameters back multiplied by 10 .. : ( I.e. the move_sensitivity and presence_sensitivity sent twice in the 1..9 range are retained but reported back from the device in the 10..90 range. Obviously, there are still more issues remaining to be solved.

thanks for your answer.

no i removed the converters and reinstalled the dev version of zigbee2mqtt so i got the newest version. but still i can't configure the settings so that they are valid :(

sry, i don't know the process of how devices will be compatible with zigbee2mqtt: do you think it just needs time till the device will be fully compatible?

best regards

Carabin79 commented 10 months ago

Thanks to all of you for your help. Can the issue be reopened, as it's not working out of the box

kingunlim commented 10 months ago

yeah please reopen its not solved yet :(

ippo112 commented 10 months ago

the last version is better, but not all issues are solved, please re-open! it !

kkossev commented 10 months ago

This is the Groovy patch that worked in Hubitat :

def divideBy10( val ) { if (val > 10) { return (val as int) / 10 } else { return (val as int) } }

The few communication logs that I have received show that the presence_sensitivity and move_sensitivity are reported from the device multiplied by 10. However, I had complaints that sometimes the two sensitivity parameter values were shown as 0 (zero) - probably in some cases, they are reported as seen in the WireShark sniff, i.e. not multiplied, but in the range 1..9. Adding the condition "divide by 10 only when the reported value is greater than 10" seems to be working, Today there was a second used who confirmed that the changed sensitivity parameters (1..9) are retained by the device and not reverted later. One saving only is enough.

Hope this helps.

kenni commented 10 months ago

From my quick analysis of the L1_to_L5 pcap file :

  • both the move_sensitivity and presence_sensitivity settings are in the range of 2 to 9, i.e. they are not multiplied by 10.

  • Tuya Zigbee GW sends the two sensitivity settings in one single, combined command. Example:

  • after the combined command, the move_sensitivity is sent once again, which is a bit strange

Now I think that only these certain combinations of the presence_sensitivity and move_sensitivity are retained :

Level presence_sensitivity move_sensitivity L1 9 7 L2 7 6 L3 6 4 L4 4 2 L5 3 2 I will have to experiment whether sending the two sensitivity parameters at once is a requrement, or simly sticking to the allowed combinations is enough.

@kkossev, this sounds very interesting. I have two of these devices, from factory they are (according to Zigbee2mqtt) configured with: "Motion sensibility" = 2 "Presence sensibility" = 2,5

I tried to change the Motion sensibility to 1 in Zigbee2mqtt, but instead it resulted in the device being stuck at: "Motion sensibility" = 10 "Presence sensibility" = 0

...and the device has stopped working. It updates illuminance and linkquality, but doesn't update Presence, Presence state or Target distance. Every time I try to change one of the two values, it just jumps back to 10 or 0 respectively. Removing and re-adding the device or resetting the device by holding the physical button doesn't change anything. So it seems like the device is bricked for now, at least without access to a Tuya-bridge, which might be able to restore the settings in the device. Let me know if I can provide any kind of details or debugging info to help add full support for the device.

I've now ordered a Tuya Zigbee gateway to see if it can bring the device back to life and perhaps be used for additional debugging.

Carabin79 commented 10 months ago

Is there some updates regarding @kkossev comment ?

drc13a commented 10 months ago

From my quick analysis of the L1_to_L5 pcap file :

  • both the move_sensitivity and presence_sensitivity settings are in the range of 2 to 9, i.e. they are not multiplied by 10.
  • Tuya Zigbee GW sends the two sensitivity settings in one single, combined command. Example:
  • after the combined command, the move_sensitivity is sent once again, which is a bit strange

Now I think that only these certain combinations of the presence_sensitivity and move_sensitivity are retained : Level presence_sensitivity move_sensitivity L1 9 7 L2 7 6 L3 6 4 L4 4 2 L5 3 2 I will have to experiment whether sending the two sensitivity parameters at once is a requrement, or simly sticking to the allowed combinations is enough.

@kkossev, this sounds very interesting. I have two of these devices, from factory they are (according to Zigbee2mqtt) configured with: "Motion sensibility" = 2 "Presence sensibility" = 2,5

I tried to change the Motion sensibility to 1 in Zigbee2mqtt, but instead it resulted in the device being stuck at: "Motion sensibility" = 10 "Presence sensibility" = 0

...and the device has stopped working. It updates illuminance and linkquality, but doesn't update Presence, Presence state or Target distance. Every time I try to change one of the two values, it just jumps back to 10 or 0 respectively. Removing and re-adding the device or resetting the device by holding the physical button doesn't change anything. So it seems like the device is bricked for now, at least without access to a Tuya-bridge, which might be able to restore the settings in the device. Let me know if I can provide any kind of details or debugging info to help add full support for the device.

I've now ordered a Tuya Zigbee gateway to see if it can bring the device back to life and perhaps be used for additional debugging.

I just wanted to quickly pop my head in to say I had the same issue with mine after mucking around with the sensitivity settings in z2m (a non responsive device)

But the good news is pairing it to a tuya hub and setting it's sensitivities based on it's levels there got it going again and it's now back in z2m (but I'm not touching sensitivity setting in there)

LuisAlbertoFP commented 9 months ago

This code works for me, it needs to be improved. Especially eliminate the use of legacy.


const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const legacy = require('zigbee-herdsman-converters/lib/legacy');
const e = exposes.presets;
const ea = exposes.access;

const myValueConverter = {sensitivity :{
        from: (v) => {
            const value = parseInt(v);
            if (value>10)  {
                v = Math.round(value/10);
            }
            return v;
        },
        to: (v) => {
           const value = parseInt(v);
            if (value>10)  {
                v = Math.round(value/10);
            }
            return v;
        },
    }, 
 }

const tzDatapoints = {
    ...tuya.tz.datapoints,
    key: [
        'switch_1', 'switch_2', 'countdown_1', 'countdown_2', 'work_mode', 'bright_value', 'temp_value', 'illuminance_value', 'presets',
          'presence_state', 'move_sensitivity', 'motion_sensitivity', 'detection_distance_max', 'detection_distance_min', 'far_detection', 'target_dis_closest', 'presence_timeout', 'presence_sensitivity', 'man_state' 
    ],
    convertSet: async (entity, key, value, meta) => {
        const sendCommand = utils.getMetaValue(entity, meta.mapped, 'tuyaSendCommand', undefined, 'dataRequest');
        switch (key) {
            case 'presets':
                switch (value) {
                    case 'L1':
                        await legacy.sendDataPointValue(entity, 106, 7);
                        await legacy.sendDataPointValue(entity, 111, 9);
                    break;
                    case 'L2':
                        await legacy.sendDataPointValue(entity, 106, 6);
                        await legacy.sendDataPointValue(entity, 111, 7);
                    break;
                    case 'L3':
                        await legacy.sendDataPointValue(entity, 106, 4);
                        await legacy.sendDataPointValue(entity, 111, 6);
                    break;
                    case 'L4':
                        await legacy.sendDataPointValue(entity, 106, 2);
                        await legacy.sendDataPointValue(entity, 111, 4);
                    break;
                    case 'L5':
                        await legacy.sendDataPointValue(entity, 106, 2);
                        await legacy.sendDataPointValue(entity, 111, 3);
                    break;                    
                    default:
                        break
                }
                break;
            default:
                break;
        }
    }
}

const definition = {
    fingerprint: [ { modelID: 'TS0601', manufacturerName: '_TZE204_ijxvkhd0'}],
    model: 'ZY-M100-24G',
    vendor: 'TuYa',
    description: 'Micro Motion Sensor v1.2 ',
    configure: tuya.configureMagicPacket,
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tzDatapoints],
    exposes: [
        e.illuminance_lux(), e.presence(),
        e.enum('presence_state', ea.STATE, ['none', 'present', 'moving']).withDescription('Presence state'),
        e.enum('presets', ea.STATE_SET, ['L1', 'L2', 'L3','L4','L5']).withDescription('Presets'),
        e.numeric('motion_sensitivity', ea.STATE_SET).withValueMin(2).withValueMax(7).withValueStep(1).withDescription('Motion sensitivity'),
        e.numeric('presence_sensitivity', ea.STATE_SET).withValueMin(3).withValueMax(9).withValueStep(1).withDescription('Presence sensitivity'),
        e.numeric('detection_distance_max', ea.STATE_SET).withValueMin(1.5).withValueMax(5.5).withValueStep(1).withDescription('Max detection distance').withUnit('m'),
        e.numeric('presence_timeout', ea.STATE_SET).withValueMin(0).withValueMax(1500).withValueStep(1).withDescription('Presence Time Out').withUnit('s'),
        e.numeric('target_distance', ea.STATE).withDescription('Distance to target').withUnit('m'),

    ],

    meta: {
        tuyaDatapoints: [
            [104, 'illuminance_lux', tuya.valueConverter.raw],
            [105, 'presence_state', tuya.valueConverterBasic.lookup({'None': tuya.enum(0), 'Present': tuya.enum(1), 'Moving': tuya.enum(2)})],
            [106, 'motion_sensitivity', myValueConverter.sensitivity], //2-7
            [107, 'detection_distance_max', tuya.valueConverter.divideBy100],
            [109, 'target_distance', tuya.valueConverter.divideBy100],
            [110, 'presence_timeout', tuya.valueConverter.raw],
            [111, 'presence_sensitivity',  myValueConverter.sensitivity],// 2-9
            [112, 'presence', tuya.valueConverter.trueFalse1],
        ],
    },
};

module.exports = definition; 
Dillton commented 9 months ago

This code works for me, it needs to be improved. Especially eliminate the use of legacy.

const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const legacy = require('zigbee-herdsman-converters/lib/legacy');
const e = exposes.presets;
const ea = exposes.access;

const myValueConverter = {sensitivity :{
        from: (v) => {
            const value = parseInt(v);
            if (value>10)  {
                v = Math.round(value/10);
            }
            return v;
        },
        to: (v) => {
           const value = parseInt(v);
            if (value>10)  {
                v = Math.round(value/10);
            }
            return v;
        },
    }, 
 }

const tzDatapoints = {
    ...tuya.tz.datapoints,
    key: [
        'switch_1', 'switch_2', 'countdown_1', 'countdown_2', 'work_mode', 'bright_value', 'temp_value', 'illuminance_value', 'presets',
          'presence_state', 'move_sensitivity', 'motion_sensitivity', 'detection_distance_max', 'detection_distance_min', 'far_detection', 'target_dis_closest', 'presence_timeout', 'presence_sensitivity', 'man_state' 
    ],
    convertSet: async (entity, key, value, meta) => {
        const sendCommand = utils.getMetaValue(entity, meta.mapped, 'tuyaSendCommand', undefined, 'dataRequest');
        switch (key) {
            case 'presets':
                switch (value) {
                    case 'L1':
                        await legacy.sendDataPointValue(entity, 106, 7);
                        await legacy.sendDataPointValue(entity, 111, 9);
                    break;
                    case 'L2':
                        await legacy.sendDataPointValue(entity, 106, 6);
                        await legacy.sendDataPointValue(entity, 111, 7);
                    break;
                    case 'L3':
                        await legacy.sendDataPointValue(entity, 106, 4);
                        await legacy.sendDataPointValue(entity, 111, 6);
                    break;
                    case 'L4':
                        await legacy.sendDataPointValue(entity, 106, 2);
                        await legacy.sendDataPointValue(entity, 111, 4);
                    break;
                    case 'L5':
                        await legacy.sendDataPointValue(entity, 106, 2);
                        await legacy.sendDataPointValue(entity, 111, 3);
                    break;                    
                    default:
                        break
                }
                break;
            default:
                break;
        }
    }
}

const definition = {
    fingerprint: [ { modelID: 'TS0601', manufacturerName: '_TZE204_ijxvkhd0'}],
    model: 'ZY-M100-24G',
    vendor: 'TuYa',
    description: 'Micro Motion Sensor v1.2 ',
    configure: tuya.configureMagicPacket,
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tzDatapoints],
  exposes: [
      e.illuminance_lux(), e.presence(),
      e.enum('presence_state', ea.STATE, ['none', 'present', 'moving']).withDescription('Presence state'),
      e.enum('presets', ea.STATE_SET, ['L1', 'L2', 'L3','L4','L5']).withDescription('Presets'),
        e.numeric('motion_sensitivity', ea.STATE_SET).withValueMin(2).withValueMax(7).withValueStep(1).withDescription('Motion sensitivity'),
      e.numeric('presence_sensitivity', ea.STATE_SET).withValueMin(3).withValueMax(9).withValueStep(1).withDescription('Presence sensitivity'),
      e.numeric('detection_distance_max', ea.STATE_SET).withValueMin(1.5).withValueMax(5.5).withValueStep(1).withDescription('Max detection distance').withUnit('m'),
      e.numeric('presence_timeout', ea.STATE_SET).withValueMin(0).withValueMax(1500).withValueStep(1).withDescription('Presence Time Out').withUnit('s'),
      e.numeric('target_distance', ea.STATE).withDescription('Distance to target').withUnit('m'),

  ],

  meta: {
      tuyaDatapoints: [
          [104, 'illuminance_lux', tuya.valueConverter.raw],
          [105, 'presence_state', tuya.valueConverterBasic.lookup({'None': tuya.enum(0), 'Present': tuya.enum(1), 'Moving': tuya.enum(2)})],
          [106, 'motion_sensitivity', myValueConverter.sensitivity], //2-7
          [107, 'detection_distance_max', tuya.valueConverter.divideBy100],
          [109, 'target_distance', tuya.valueConverter.divideBy100],
          [110, 'presence_timeout', tuya.valueConverter.raw],
          [111, 'presence_sensitivity',  myValueConverter.sensitivity],// 2-9
          [112, 'presence', tuya.valueConverter.trueFalse1],
      ],
  },
};

module.exports = definition; 

Hi and thank you for this. From first impression I can confirm with this code the radars working for me I would say the best compared to previous codes.

Even the Ceiling version with stucked motion and presence sensitivity on 10 was able to recover to normal values and start working again without reseting it through Tuya GW.

However it's been only 1 day with this code so far so take my comment with reserve I will keep monitor the behaviour for few more days until I decide to use it inside some automations etc...

Dillton commented 9 months ago

Found one thing already I am now unable to change Detection distance max it stays on previous value.

LuisAlbertoFP commented 9 months ago

Fixed, try it @Dillton


const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const legacy = require('zigbee-herdsman-converters/lib/legacy');
const e = exposes.presets;
const ea = exposes.access;

const myValueConverter = {sensitivity :{
        from: (v) => {
            const value = parseInt(v);
            if (value>10)  {
                v = Math.round(value/10);
            }
            return v;
        },
        to: (v) => {
           const value = parseInt(v);
            if (value>10)  {
                v = Math.round(value/10);
            }
            return v;
        },
    }, 
    distance :{
        from: (v) => {
            const value = parseFloat(v);
            if (value>=100){
               v = value / 100;
            }
            return v;
        },
        to: (v) => {
            return v;
        },
    }, 
 }

const tzDatapoints = {
    ...tuya.tz.datapoints,
    key: [
          'presets',
          'presence_state', 'move_sensitivity', 'motion_sensitivity', 'detection_distance_max', 
          'detection_distance_min', 'far_detection', 'target_dis_closest', 'presence_timeout', 'presence_sensitivity', 'man_state' 
    ],
    convertSet: async (entity, key, value, meta) => {
        const sendCommand = utils.getMetaValue(entity, meta.mapped, 'tuyaSendCommand', undefined, 'dataRequest');
        switch (key) {
            case 'presets':
                switch (value) {
                    case 'L1':
                        await legacy.sendDataPointValue(entity, 106, 7);
                        await legacy.sendDataPointValue(entity, 111, 9);
                    break;
                    case 'L2':
                        await legacy.sendDataPointValue(entity, 106, 6);
                        await legacy.sendDataPointValue(entity, 111, 7);
                    break;
                    case 'L3':
                        await legacy.sendDataPointValue(entity, 106, 4);
                        await legacy.sendDataPointValue(entity, 111, 6);
                    break;
                    case 'L4':
                        await legacy.sendDataPointValue(entity, 106, 2);
                        await legacy.sendDataPointValue(entity, 111, 4);
                    break;
                    case 'L5':
                        await legacy.sendDataPointValue(entity, 106, 2);
                        await legacy.sendDataPointValue(entity, 111, 3);
                    break;                    
                    default:
                        break
                }
                break;
            case 'motion_sensitivity':
                await legacy.sendDataPointValue(entity, 106, value);
            break;
            case 'presence_sensitivity':
                await legacy.sendDataPointValue(entity, 111, value);
            break;
            case 'detection_distance_max':
                const v = parseFloat(value)*100;
                 await legacy.sendDataPointValue(entity, 107, v);
            break;
            case 'presence_timeout':
                 await legacy.sendDataPointValue(entity, 110, value);
            break;

            default:
                break;
        }
    }
}

const definition = {
    fingerprint: [ { modelID: 'TS0601', manufacturerName: '_TZE204_ijxvkhd0'}],
    model: 'ZY-M100-24G',
    vendor: 'TuYa',
    description: 'Micro Motion Sensor v1.2 ',
    configure: tuya.configureMagicPacket,
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tzDatapoints],
    exposes: [
        e.illuminance_lux(), e.presence(),
        e.enum('presence_state', ea.STATE, ['none', 'present', 'moving']).withDescription('Presence state'),
        e.enum('presets', ea.STATE_SET, ['L1', 'L2', 'L3','L4','L5']).withDescription('Presets'),
        e.numeric('motion_sensitivity', ea.STATE_SET).withValueMin(2).withValueMax(7).withValueStep(1).withDescription('Motion sensitivity'),
        e.numeric('presence_sensitivity', ea.STATE_SET).withValueMin(3).withValueMax(9).withValueStep(1).withDescription('Presence sensitivity'),
        e.numeric('detection_distance_max', ea.STATE_SET).withValueMin(1.5).withValueMax(5.5).withValueStep(0.5).withDescription('Max detection distance').withUnit('m'),
        e.numeric('presence_timeout', ea.STATE_SET).withValueMin(0).withValueMax(1500).withValueStep(1).withDescription('Presence Time Out').withUnit('s'),
        e.numeric('target_distance', ea.STATE).withDescription('Distance to target').withUnit('m'),

    ],

    meta: {
        tuyaDatapoints: [
            [104, 'illuminance_lux', tuya.valueConverter.raw],
            [105, 'presence_state', tuya.valueConverterBasic.lookup({'None': tuya.enum(0), 'Present': tuya.enum(1), 'Moving': tuya.enum(2)})],
            [106, 'motion_sensitivity', myValueConverter.sensitivity], //2-7
            [107, 'detection_distance_max', tuya.valueConverter.divideBy100],
            [109, 'target_distance', tuya.valueConverter.divideBy100],
            [110, 'presence_timeout', tuya.valueConverter.raw],
            [111, 'presence_sensitivity',  myValueConverter.sensitivity],// 2-9
            [112, 'presence', tuya.valueConverter.trueFalse1],
        ],
    },
};

module.exports = definition;
Dillton commented 9 months ago

Thank you @LuisAlbertoFP I will test today afternoon.

mindtripper commented 9 months ago

Device works quite well @LuisAlbertoFP. Also configurable from Home Assistant.

Nonsense112 commented 9 months ago

I've tried it @LuisAlbertoFP but I can't change the radar max distance. The radar range option in the page is showing the new value, but the device is reporting the old value. Also the presets option always show as 'null'. The presets option is necessary? Using the vendor code posted by @dinde I could change the sensitivity values but after trying a few time because they kept jumping to 0.1

Thank you!

LuisAlbertoFP commented 9 months ago

Presets I did not think of it for storing values, it simply serves to set the sensitivity values that SmartLife allows. It can be deleted.

Detection distance max: only allows values ending in 0.5. I have changed the step.

Thanks @Nonsense112

Fixed code


const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
const tz = require('zigbee-herdsman-converters/converters/toZigbee');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const reporting = require('zigbee-herdsman-converters/lib/reporting');
const extend = require('zigbee-herdsman-converters/lib/extend');
const ota = require('zigbee-herdsman-converters/lib/ota');
const tuya = require('zigbee-herdsman-converters/lib/tuya');
const utils = require('zigbee-herdsman-converters/lib/utils');
const globalStore = require('zigbee-herdsman-converters/lib/store');
const legacy = require('zigbee-herdsman-converters/lib/legacy');
const e = exposes.presets;
const ea = exposes.access;

const myValueConverter = {sensitivity :{
        from: (v) => {
            const value = parseInt(v);
            if (value>10)  {
                v = Math.round(value/10);
            } 
            return v;
        },
        to: (v) => {
           const value = parseInt(v);
            if (value>10)  {
                v = Math.round(value/10);
            }
            return v;
        },
    }, 
    distance :{
        from: (v) => {
            let value = Number(v);
            if (value >=150) {
                    value = value / 100;
                } 
            return value;
        },
        to: (v) => {
            return Number(v)*100;
        },
    }, 
 }

const tzDatapoints = {
    ...tuya.tz.datapoints,
    key: [
          'presets',
          'presence_state', 'move_sensitivity', 'motion_sensitivity', 'detection_distance_max', 
          'detection_distance_min', 'far_detection', 'target_dis_closest', 'presence_timeout', 'presence_sensitivity', 'man_state' 
    ],
    convertSet: async (entity, key, value, meta) => {
        const sendCommand = utils.getMetaValue(entity, meta.mapped, 'tuyaSendCommand', undefined, 'dataRequest');
        switch (key) {
            case 'presets':
                switch (value) {
                    case 'L1':
                        await legacy.sendDataPointValue(entity, 106, 7);
                        await legacy.sendDataPointValue(entity, 111, 9);
                    break;
                    case 'L2':
                        await legacy.sendDataPointValue(entity, 106, 6);
                        await legacy.sendDataPointValue(entity, 111, 7);
                    break;
                    case 'L3':
                        await legacy.sendDataPointValue(entity, 106, 4);
                        await legacy.sendDataPointValue(entity, 111, 6);
                    break;
                    case 'L4':
                        await legacy.sendDataPointValue(entity, 106, 2);
                        await legacy.sendDataPointValue(entity, 111, 4);
                    break;
                    case 'L5':
                        await legacy.sendDataPointValue(entity, 106, 2);
                        await legacy.sendDataPointValue(entity, 111, 3);
                    break;                    
                    default:
                        break
                }
                break;
            case 'motion_sensitivity':
                await legacy.sendDataPointValue(entity, 106, value);
            break;
            case 'presence_sensitivity':
                await legacy.sendDataPointValue(entity, 111, value);
            break;
            case 'detection_distance_max':
                v = Math.round(Number(value)*100);
                await legacy.sendDataPointValue(entity, 107, v);
            break;
            case 'presence_timeout':
                 await legacy.sendDataPointValue(entity, 110, value);
            break;

            default:
                break;
        }
    }
}

const definition = {
    fingerprint: [ { modelID: 'TS0601', manufacturerName: '_TZE204_ijxvkhd0'}],
    model: 'ZY-M100-24G',
    vendor: 'TuYa',
    description: 'Micro Motion Sensor v1.2 ',
    configure: tuya.configureMagicPacket,
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tzDatapoints],
    exposes: [
        e.illuminance_lux(), e.presence(),
        e.enum('presence_state', ea.STATE, ['none', 'present', 'moving']).withDescription('Presence state'),
        /* Remove the preset line if you do not like the way it works. */
                e.enum('presets', ea.STATE_SET, ['L1', 'L2', 'L3','L4','L5']).withDescription('Presets'),
        e.numeric('motion_sensitivity', ea.STATE_SET).withValueMin(2).withValueMax(7).withValueStep(1).withDescription('Motion sensitivity'),
        e.numeric('presence_sensitivity', ea.STATE_SET).withValueMin(3).withValueMax(9).withValueStep(1).withDescription('Presence sensitivity'),
        e.numeric('detection_distance_max', ea.STATE_SET).withValueMin(1.5).withValueMax(5.5).withValueStep(1).withDescription('Max detection distance').withUnit('m'),
    //  e.numeric('detection_distance_max', ea.STATE_SET).withValueMin(150).withValueMax(550).withValueStep(50).withDescription('Max detection distance').withUnit('cm'),
        e.numeric('presence_timeout', ea.STATE_SET).withValueMin(0).withValueMax(1500).withValueStep(1).withDescription('Presence Time Out').withUnit('s'),
        e.numeric('target_distance', ea.STATE).withDescription('Distance to target').withUnit('cm'),

    ],

    meta: {
        tuyaDatapoints: [
            [104, 'illuminance_lux', tuya.valueConverter.raw],
            [105, 'presence_state', tuya.valueConverterBasic.lookup({'None': tuya.enum(0), 'Present': tuya.enum(1), 'Moving': tuya.enum(2)})],
            [106, 'motion_sensitivity', myValueConverter.sensitivity], //2-7
            [107, 'detection_distance_max', myValueConverter.distance],
            [109, 'target_distance', tuya.valueConverter.divideBy100],
            [110, 'presence_timeout', tuya.valueConverter.raw],
            [111, 'presence_sensitivity',  myValueConverter.sensitivity],// 2-9
            [112, 'presence', tuya.valueConverter.trueFalse1],
        ],
    },
};

module.exports = definition;
Landcross commented 9 months ago

I have a Tuya ZY-M100-24G that I tried to change the settings of and is now stuck as well as described above (all settings to 10 and only does lux reading now). Google brought me here. Is there any way to unstuck it? Any ETA for a fix in stable?

Dillton commented 9 months ago

I have a Tuya ZY-M100-24G that I tried to change the settings of and is now stuck as well as described above (all settings to 10 and only does lux reading now). Google brought me here. Is there any way to unstuck it? Any ETA for a fix in stable?

Hi @Landcross, the last code from @LuisAlbertoFP made the trick for me. I was also stucked at the same values. Currently I am running 4th day with 3 of those radars used in automations. Everything is working fine so far.

Landcross commented 9 months ago

I have a Tuya ZY-M100-24G that I tried to change the settings of and is now stuck as well as described above (all settings to 10 and only does lux reading now). Google brought me here. Is there any way to unstuck it? Any ETA for a fix in stable?

Hi @Landcross, the last code from @LuisAlbertoFP made the trick for me. I was also stucked at the same values. Currently I am running 4th day with 3 of those radars used in automations. Everything is working fine so far.

Thanks, but I'm not sure how to use that code. I'm simply using Zigbee2mqtt within Home Assistant

Dillton commented 9 months ago

I have a Tuya ZY-M100-24G that I tried to change the settings of and is now stuck as well as described above (all settings to 10 and only does lux reading now). Google brought me here. Is there any way to unstuck it? Any ETA for a fix in stable?

Hi @Landcross, the last code from @LuisAlbertoFP made the trick for me. I was also stucked at the same values. Currently I am running 4th day with 3 of those radars used in automations. Everything is working fine so far.

Thanks, but I'm not sure how to use that code. I'm simply using Zigbee2mqtt within Home Assistant

You have to add it as external converter to configuration.yaml for Z2M. https://www.zigbee2mqtt.io/guide/configuration/more-config-options.html#external-converters