Koenkk / zigbee2mqtt

Zigbee 🐝 to MQTT bridge πŸŒ‰, get rid of your proprietary Zigbee bridges πŸ”¨
https://www.zigbee2mqtt.io
GNU General Public License v3.0
12.22k stars 1.69k forks source link

[New device support]: #22844

Open 72longboard opened 6 months ago

72longboard commented 6 months ago

Link

https://es.aliexpress.com/item/1005006923987304.html?srcSns=sns_Copy&spreadType=socialShare&bizType=ProductDetail&social_params=6000095348167&aff_fcid=edc5a5efbe864160b08f0be54d56e580-1717115370159-07010-_onkx4EO&tt=MG&aff_fsk=_onkx4EO&aff_platform=default&sk=_onkx4EO&aff_trace_key=edc5a5efbe864160b08f0be54d56e580-1717115370159-07010-_onkx4EO&shareId=6000095348167&businessType=ProductDetail&platform=AE&terminal_id=4f343b0e05b24ec5a29e575a82deeb16&afSmartRedirect=y

Database entry

{"id":18,"type":"EndDevice","ieeeAddr":"0x94b216fffef1b487","nwkAddr":47149,"manufId":4098,"manufName":"_TZ3210_5rta89nj","powerSource":"Battery","modelId":"TS0601","epList":[1],"endpoints":{"1":{"profId":260,"epId":1,"devId":1026,"inClusterList":[0,3,1,1280,61184],"outClusterList":[10,25],"clusters":{},"binds":[],"configuredReportings":[],"meta":{}}},"appVersion":74,"stackVersion":1,"hwVersion":1,"dateCode":"","zclVersion":3,"interviewCompleted":true,"meta":{},"lastSeen":1717113801806}

Comments

Please make a new registration so that I can use this product

External definition

const {identify, battery, iasZoneAlarm} = require('zigbee-herdsman-converters/lib/modernExtend');

const definition = {
    zigbeeModel: ['TS0601'],
    model: 'TS0601',
    vendor: '_TZ3210_5rta89nj',
    description: 'Automatically generated definition',
    extend: [identify(), battery(), iasZoneAlarm({"zoneType":"generic","zoneAttributes":["alarm_1","alarm_2","tamper","battery_low"]})],
    meta: {},
};

module.exports = definition;
kkqq9320 commented 6 months ago

I found datapoints, but I'm not sure how to create an external converter. datapoints is here,

`[4, 'battery_level'],

[102, 'device_control'], [103, 'security_mode'], [104, 'ratio_of_opening'], [105, 'charge_state'], [106, 'manual_mode'], [107, 'fault'], [108, 'motor_calibration'], [109, 'installation_type'], [110, 'slow_stop'], [111, 'solar_energy_current'], [112, 'fixed_window_sash'], [113, 'motor_timeout'], [114, 'window_state'] `

plplaaa2 commented 5 months ago

Although some progress has been made, the external converter can read data points but cannot be controlled.


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 legacy = require('zigbee-herdsman-converters/lib/legacy');
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 definition = {
    zigbeeModel: [
        '5rta89nj' // Tubular motors
    ],
    fingerprint: [
// Curtain motors:
        {modelID: 'TS0601', manufacturerName: '_TZ3210_5rta89nj'},
    ],
    model: 'TS0601',
    vendor: '_TZ3210_5rta89nj',
    description: 'window pusher',
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    configure: tuya.configureMagicPacket,
    exposes: [
        e.battery(),
        e.cover_position('position', 'state', ea.STATE_SET,['OPEN', 'CLOSE', 'STOP']).withDescription('Window Control'),
        e.enum('alarm_mode', ea.STATE_SET, ['True', 'False']),
        e.binary('charge_state', ea.STATE, 'charging', 'discharging'),
        e.enum('manual_mode', ea.STATE_SET, ['True', 'False']),
        e.binary('error', ea.STATE, true, false).withDescription('Fault'),
        e.numeric('calibration', ea.STATE_SET).withValueMin(10).withValueMax(90).withDescription('Motor calibration').withUnit('s'),
        e.enum('motor_direction', ea.STATE_SET, ['left', 'right']).withDescription('Install Side'),
        e.enum('mode', ea.STATE_SET, ['True', 'False']).withDescription('Slow_stop'),
        e.numeric('countdown', ea.STATE_SET).withValueMin(10).withValueMax(90).withDescription('Motor Timeout').withUnit('s'),
        e.binary('window_detection', ea.STATE, true, false).withDescription('Window State'),

    ],
    meta: {
        // All datapoints go in here
        tuyaDatapoints: [
            [4, 'battery', tuya.valueConverter.raw],
            [102, 'state', tuya.valueConverterBasic.lookup({'OPEN': tuya.enum(0), 'CLOSE': tuya.enum(1), 'STOP': tuya.enum(2)})],
            [103, 'alarm_mode', tuya.valueConverterBasic.lookup({'True': tuya.enum(0), 'False': tuya.enum(1),})],
            [104, 'position', tuya.valueConverter.coverPosition],
            [104, 'position', tuya.valueConverter.raw],
            [105, 'charge_state', tuya.valueConverter.trueFalse1],
            [106, 'manual_mode', tuya.valueConverterBasic.lookup({'True': tuya.enum(0), 'False': tuya.enum(1),})],
            [107, 'error', tuya.valueConverter.trueFalse1],
            [108, 'calibration', tuya.valueConverter.calibration],
            [108, 'calibration', tuya.valueConverter.raw],
            [109, 'motor_direction', tuya.valueConverterBasic.lookup({'left': tuya.enum(0), 'right': tuya.enum(1)})],
            [110, 'mode', tuya.valueConverterBasic.lookup({'True': tuya.enum(0), 'False': tuya.enum(1)})],
            [113, 'countdown', tuya.valueConverter.countdown],
            [113, 'countdown', tuya.valueConverter.raw],
            [114, 'window_detection', tuya.valueConverter.trueFalse0],
            ],
    },
    extend: [
        // A preferred new way of extending functionality.
    ],
};

module.exports = definition; ```
tribakzero commented 5 months ago

I have the same device and the external converter works great to display some values like the battery, state, position, window_detection although it seems like the state is inverted (I open the window and it says it's closed).

Hope I could help actively but at least you have a beta tester here. πŸ™

ezeghers commented 5 months ago

I have the same device and the external converter works great to display some values like the battery, state, position, window_detection although it seems like the state is inverted (I open the window and it says it's closed).

Hope I could help actively but at least you have a beta tester here. πŸ™

Regarding the Open/closed state being reversed, it does the same in the the Moes or Smartlife app. Mine is mounted on the left side of the inside window and regardless of the settings in the app, it does not reverse. I sent it to the Moes support for them to investigate.

qkddn49 commented 5 months ago

λ‚˜λŠ” λ™μΌν•œ μž₯치λ₯Ό 가지고 있으며 μ™ΈλΆ€ λ³€ν™˜κΈ°λŠ” μƒνƒœκ°€ λ°˜μ „λœ κ²ƒμ²˜λŸΌ λ³΄μ΄μ§€λ§Œ 배터리, μƒνƒœ, μœ„μΉ˜, window_Detectionκ³Ό 같은 일뢀 값을 ν‘œμ‹œν•˜λŠ” 데 ν›Œλ₯­ν•˜κ²Œ μž‘λ™ν•©λ‹ˆλ‹€(창을 μ—΄λ©΄ λ‹«ν˜€ μžˆλ‹€κ³  ν‘œμ‹œλ©λ‹ˆλ‹€).

μ œκ°€ 적극적으둜 도움을 λ“œλ¦΄ 수 있기λ₯Ό λ°”λΌμ§€λ§Œ 적어도 μ—¬κΈ°μ—λŠ” 베타 ν…ŒμŠ€ν„°κ°€ μžˆμŠ΅λ‹ˆλ‹€. πŸ™

.Can I get the source code?

tribakzero commented 5 months ago

λ‚˜λŠ” λ™μΌν•œ μž₯치λ₯Ό 가지고 있으며 μ™ΈλΆ€ λ³€ν™˜κΈ°λŠ” μƒνƒœκ°€ λ°˜μ „λœ κ²ƒμ²˜λŸΌ λ³΄μ΄μ§€λ§Œ 배터리, μƒνƒœ, μœ„μΉ˜, window_Detectionκ³Ό 같은 일뢀 값을 ν‘œμ‹œν•˜λŠ” 데 ν›Œλ₯­ν•˜κ²Œ μž‘λ™ν•©λ‹ˆλ‹€(창을 μ—΄λ©΄ λ‹«ν˜€ μžˆλ‹€κ³  ν‘œμ‹œλ©λ‹ˆλ‹€). μ œκ°€ 적극적으둜 도움을 λ“œλ¦΄ 수 있기λ₯Ό λ°”λΌμ§€λ§Œ 적어도 μ—¬κΈ°μ—λŠ” 베타 ν…ŒμŠ€ν„°κ°€ μžˆμŠ΅λ‹ˆλ‹€. πŸ™

.Can I get the source code?

https://github.com/Koenkk/zigbee2mqtt/issues/22844#issuecomment-2171450055

qkddn49 commented 5 months ago

It's explained that it can't be controlled Is it controlled?

tribakzero commented 5 months ago

It's explained that it can't be controlled Is it controlled?

Current external converter allows to read values, no control enabled at the moment.

Although some progress has been made, the external converter can read data points but cannot be controlled.

qkddn49 commented 5 months ago

I got it. Thank you.

kkossev commented 5 months ago

Although some progress has been made, the external converter can read data points but cannot be controlled.

@plplaaa2 this device requires command 0x04 to be used when writing 0xEF00 cluster Data Points (instead of 0x00). Probably @koenk can help.

acortelyou commented 4 months ago

@kkossev Based on your work I've got something partially working.

The missing link was tuyaSendCommand: 0x04 as you discovered.

Below is the work in progress, once I've had some time to play around with it and figure out what is and isn't actually working I'll trying submitting the device.

For now at least I can open and close via automation so #closeenough.

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 modernExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');

const definition = {
    fingerprint: [
        {
            modelID: 'TS0601',
            manufacturerName: '_TZ3210_5rta89nj',
        },
    ],
    vendor: 'MOES',
    model: 'ZC-LP01',
    description: 'Smart Sliding Window Pusher',
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    onEvent: tuya.onEventSetTime,
    configure: tuya.configureMagicPacket,
    exposes: [
        e.battery(),
        tuya.exposes.batteryState(),
        e.cover_position('position', 'state', ea.STATE_SET, ['Open', 'Close', 'Stop']).withDescription('Window Control'),
        e.enum('alarm_mode', ea.STATE_SET, ['True', 'False']),
        e.binary('charge_state', ea.STATE, 'Charging', 'Discharging'),
        e.enum('manual_mode', ea.STATE_SET, ['True', 'False']),
        e.binary('fault', ea.STATE, ['Motor Fault', 'Clear']).withDescription('Fault'),
        e.numeric('calibration', ea.STATE_SET).withValueMin(10).withValueMax(90).withDescription('Motor Calibration').withUnit('s'),
        e.enum('motor_direction', ea.STATE_SET, ['Left', 'Right']).withDescription('Motor Direction'),
        e.enum('slow_stop', ea.STATE_SET, ['Enabled', 'Disabled']).withDescription('Slow Stop'),
        e.numeric('solar_energy_current', ea.STATE).withValueMin(0).withValueMax(99999).withDescription('Solar Energy Current'),
        e.enum('fixed_window_sash', ea.STATE_SET, ['True', 'False']),
        e.numeric('motor_timeout', ea.STATE_SET).withValueMin(10).withValueMax(90).withDescription('Motor Timeout').withUnit('s'),
        e.binary('window_detection', ea.STATE, ['True','False']).withDescription('Window Detection'),

    ],
    meta: {
        tuyaSendCommand: 0x04,
        tuyaDatapoints: [
            [4, 'battery', tuya.valueConverter.raw],
            [102, 'state', tuya.valueConverterBasic.lookup({open: 0, close: 1, stop: 2})],
            [103, 'alarm_mode', tuya.valueConverter.trueFalse0],
            [104, 'position', tuya.valueConverter.coverPosition],
            [104, 'position', tuya.valueConverter.raw],
            [105, 'charge_state', tuya.valueConverter.trueFalse1],
            [106, 'manual_mode', tuya.valueConverter.trueFalse0],
            [107, 'fault', tuya.valueConverter.trueFalse1],
            [108, 'calibration', tuya.valueConverter.raw],
            [109, 'motor_direction', tuya.valueConverterBasic.lookup({left: 0, right: 1})],
            [110, 'slow_stop', tuya.valueConverter.trueFalse0],
            [111, 'solar_energy_current', tuya.valueConverter.raw]
            [112, 'fixed_window_sash', tuya.valueConverter.trueFalse0],
            [113, 'motor_timeout', tuya.valueConverter.countdown],
            [113, 'motor_timeout', tuya.valueConverter.raw],
            [114, 'window_detection', tuya.valueConverter.trueFalse0],
        ],
    },
    extend: [
    ],
};

module.exports = definition;
72longboard commented 4 months ago

@kkossev Based on your work I've got something partially working.

The missing link was tuyaSendCommand: 0x04 as you discovered.

Below is the work in progress, once I've had some time to play around with it and figure out what is and isn't actually working I'll trying submitting the device.

For now at least I can open and close via automation so #closeenough.

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 modernExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');

const definition = {
    fingerprint: [
        {
            modelID: 'TS0601',
            manufacturerName: '_TZ3210_5rta89nj',
        },
    ],
    vendor: 'MOES',
    model: 'ZC-LP01',
    description: 'Smart Sliding Window Pusher',
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    onEvent: tuya.onEventSetTime,
    configure: tuya.configureMagicPacket,
    exposes: [
        e.battery(),
        tuya.exposes.batteryState(),
        e.cover_position('position', 'state', ea.STATE_SET, ['Open', 'Close', 'Stop']).withDescription('Window Control'),
        e.enum('alarm_mode', ea.STATE_SET, ['True', 'False']),
        e.binary('charge_state', ea.STATE, 'Charging', 'Discharging'),
        e.enum('manual_mode', ea.STATE_SET, ['True', 'False']),
        e.binary('fault', ea.STATE, ['Motor Fault', 'Clear']).withDescription('Fault'),
        e.numeric('calibration', ea.STATE_SET).withValueMin(10).withValueMax(90).withDescription('Motor Calibration').withUnit('s'),
        e.enum('motor_direction', ea.STATE_SET, ['Left', 'Right']).withDescription('Motor Direction'),
        e.enum('slow_stop', ea.STATE_SET, ['Enabled', 'Disabled']).withDescription('Slow Stop'),
        e.numeric('solar_energy_current', ea.STATE).withValueMin(0).withValueMax(99999).withDescription('Solar Energy Current'),
        e.enum('fixed_window_sash', ea.STATE_SET, ['True', 'False']),
        e.numeric('motor_timeout', ea.STATE_SET).withValueMin(10).withValueMax(90).withDescription('Motor Timeout').withUnit('s'),
        e.binary('window_detection', ea.STATE, ['True','False']).withDescription('Window Detection'),

    ],
    meta: {
        tuyaSendCommand: 0x04,
        tuyaDatapoints: [
            [4, 'battery', tuya.valueConverter.raw],
            [102, 'state', tuya.valueConverterBasic.lookup({open: 0, close: 1, stop: 2})],
            [103, 'alarm_mode', tuya.valueConverter.trueFalse0],
            [104, 'position', tuya.valueConverter.coverPosition],
            [104, 'position', tuya.valueConverter.raw],
            [105, 'charge_state', tuya.valueConverter.trueFalse1],
            [106, 'manual_mode', tuya.valueConverter.trueFalse0],
            [107, 'fault', tuya.valueConverter.trueFalse1],
            [108, 'calibration', tuya.valueConverter.raw],
            [109, 'motor_direction', tuya.valueConverterBasic.lookup({left: 0, right: 1})],
            [110, 'slow_stop', tuya.valueConverter.trueFalse0],
            [111, 'solar_energy_current', tuya.valueConverter.raw]
            [112, 'fixed_window_sash', tuya.valueConverter.trueFalse0],
            [113, 'motor_timeout', tuya.valueConverter.countdown],
            [113, 'motor_timeout', tuya.valueConverter.raw],
            [114, 'window_detection', tuya.valueConverter.trueFalse0],
        ],
    },
    extend: [
    ],
};

module.exports = definition;

It's Working!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Great Thx!!!!

lutterodt commented 4 months ago

@kkossev Based on your work I've got something partially working.

The missing link was tuyaSendCommand: 0x04 as you discovered.

Below is the work in progress, once I've had some time to play around with it and figure out what is and isn't actually working I'll trying submitting the device.

For now at least I can open and close via automation so #closeenough.

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 modernExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const e = exposes.presets;
const ea = exposes.access;
const tuya = require('zigbee-herdsman-converters/lib/tuya');

const definition = {
    fingerprint: [
        {
            modelID: 'TS0601',
            manufacturerName: '_TZ3210_5rta89nj',
        },
    ],
    vendor: 'MOES',
    model: 'ZC-LP01',
    description: 'Smart Sliding Window Pusher',
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    onEvent: tuya.onEventSetTime,
    configure: tuya.configureMagicPacket,
    exposes: [
        e.battery(),
        tuya.exposes.batteryState(),
        e.cover_position('position', 'state', ea.STATE_SET, ['Open', 'Close', 'Stop']).withDescription('Window Control'),
        e.enum('alarm_mode', ea.STATE_SET, ['True', 'False']),
        e.binary('charge_state', ea.STATE, 'Charging', 'Discharging'),
        e.enum('manual_mode', ea.STATE_SET, ['True', 'False']),
        e.binary('fault', ea.STATE, ['Motor Fault', 'Clear']).withDescription('Fault'),
        e.numeric('calibration', ea.STATE_SET).withValueMin(10).withValueMax(90).withDescription('Motor Calibration').withUnit('s'),
        e.enum('motor_direction', ea.STATE_SET, ['Left', 'Right']).withDescription('Motor Direction'),
        e.enum('slow_stop', ea.STATE_SET, ['Enabled', 'Disabled']).withDescription('Slow Stop'),
        e.numeric('solar_energy_current', ea.STATE).withValueMin(0).withValueMax(99999).withDescription('Solar Energy Current'),
        e.enum('fixed_window_sash', ea.STATE_SET, ['True', 'False']),
        e.numeric('motor_timeout', ea.STATE_SET).withValueMin(10).withValueMax(90).withDescription('Motor Timeout').withUnit('s'),
        e.binary('window_detection', ea.STATE, ['True','False']).withDescription('Window Detection'),

    ],
    meta: {
        tuyaSendCommand: 0x04,
        tuyaDatapoints: [
            [4, 'battery', tuya.valueConverter.raw],
            [102, 'state', tuya.valueConverterBasic.lookup({open: 0, close: 1, stop: 2})],
            [103, 'alarm_mode', tuya.valueConverter.trueFalse0],
            [104, 'position', tuya.valueConverter.coverPosition],
            [104, 'position', tuya.valueConverter.raw],
            [105, 'charge_state', tuya.valueConverter.trueFalse1],
            [106, 'manual_mode', tuya.valueConverter.trueFalse0],
            [107, 'fault', tuya.valueConverter.trueFalse1],
            [108, 'calibration', tuya.valueConverter.raw],
            [109, 'motor_direction', tuya.valueConverterBasic.lookup({left: 0, right: 1})],
            [110, 'slow_stop', tuya.valueConverter.trueFalse0],
            [111, 'solar_energy_current', tuya.valueConverter.raw]
            [112, 'fixed_window_sash', tuya.valueConverter.trueFalse0],
            [113, 'motor_timeout', tuya.valueConverter.countdown],
            [113, 'motor_timeout', tuya.valueConverter.raw],
            [114, 'window_detection', tuya.valueConverter.trueFalse0],
        ],
    },
    extend: [
    ],
};

module.exports = definition;

This actually works! Frontend control achieved! HA Community man! However, as indicated by a contributor up top, mounting the pusher on the left side of the "pushed window" is inverted on the controls. Looking to see if a DP for inversion control is available like it is on other zigbee devices.

ezeghers commented 4 months ago

Gave this a try. Zigbee2mqtt responds to changes but I can't control it. If I manually open or close the window, it changes in Z3M but if I try to open or close the window in HA/Z2M the window does not respond. I checked that it is loading the updated config given above. Everything does work when I connect it through the Moes app.

A few weeks ago, I reported the left side/right side reversed issue and they gave me a firmware update for the window pusher. That update fixed the reverse issue in the Moes app. I wonder if that firmware update is the cause of this issue.

tribakzero commented 4 months ago

@ezeghers mind sharing the firmware to test it?

ezeghers commented 4 months ago

@ezeghers mind sharing the firmware to test it?

I'm not sure how I can. They pushed it to me through the Moes app.

ezeghers commented 4 months ago

Looks like I got it to work. I had to remove the pusher device in Z2M, saved my Z2M configuration, uninstalled Z2M from HA, reinstalled Z2M, restored the configuration and re-linked the device.

tribakzero commented 4 months ago

@ezeghers great news, so you have the switch correctly now and also able to trigger it from Z2M?

I'll ping moes for the firmware, thanks!

acortelyou commented 4 months ago

The version I posted has bugs with the converters still, but the open/close commands do work.

I haven't had time to take a look but I suspect it will be a quick fix, just need to find docs on the "right" way to model the datapoints.

If someone wants to post the doc or fix it quicker feel free.

I suggest we align with the hubitat version.

ezeghers commented 4 months ago

@ezeghers great news, so you have the switch correctly now and also able to trigger it from Z2M?

I'll ping moes for the firmware, thanks!

It works and the open/closed state kind of works. Using the cover entity I can slide up to open the window and down to close, which is what I would expect. The status of the cover however always says Closed. Screenshot_20240727-141634 Screenshot_20240727-141954

plplaaa2 commented 4 months ago

I made a nearly finished yaml. I hope everyone uses this code well.

Caution: This setting works fine with the firmware modified by Tuya. (Firmware update has changed the direction of the motor.) If you haven't updated to Tuya Gateway, you need to reverse the motor direction.

image

Additions

What you can do:

  1. Window control
  2. State of charge
  3. Manual mode
  4. Motor Time Out
  5. InstallSide
  6. Slow stop
  7. window detection (unfortunately not a binary sensor)

Unchecked parts

motor fault (not occurring, And not even in tuya smart) Solar charging current amount (not even in tuya smart, I think it's a dummy data point)

What you can't do

fixed_window_sash (We already have an install side) motor calibration ( = motor time out)

Useless

alarm mode (I don't know what the hell it's for. Opening the window in alarm mode doesn't change anything. And not even in tuya smart. )

And finally, some values (position, etc.) need to be installed to come out.

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 tuya = require('zigbee-herdsman-converters/lib/tuya');
const modernExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const e = exposes.presets;
const ea = exposes.access;

const definition = {
    zigbeeModel: [
        '5rta89nj' // Tubular motors
    ],
    fingerprint: [
// Curtain motors:
        {modelID: 'TS0601', manufacturerName: '_TZ3210_5rta89nj'},
    ],
    model: 'ZC-LP01',
    vendor: 'Moes',
    description: 'window pusher',
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    onEvent: tuya.onEventSetTime,
    configure: tuya.configureMagicPacket,
    exposes: [
        e.battery(),
        e.cover_position('position', 'state', ea.STATE_SET,['OPEN', 'CLOSE', 'STOP']).withDescription('Window Control'),
        e.binary('charge_state', ea.STATE, 'True', 'False'),
        e.enum('manual_mode', ea.STATE_SET, ['Enable', 'Disable']),
        e.binary('fault', ea.STATE, 'True', 'False').withDescription('Motor Fault'),
        e.numeric('countdown', ea.STATE_SET).withValueMin(10).withValueMax(90).withDescription('Mortor timeout').withUnit('s'),
        e.enum('motor_direction', ea.STATE_SET, ['Left Side', 'Right Side']).withDescription('Install Side Type'),
        e.enum('mode', ea.STATE_SET, ['Enable', 'Disable']).withDescription('Slow_stop'),
        e.enum('window_detection', ea.STATE, ['Opened', 'Closed', 'Pending']).withDescription('Window Detection'),

    ],
    meta: {
        // All datapoints go in here
        tuyaSendCommand: 0x04,
        tuyaDatapoints: [
            [4, 'battery', tuya.valueConverter.raw],
            [102, 'state', tuya.valueConverterBasic.lookup({'OPEN': tuya.enum(0), 'CLOSE': tuya.enum(1), 'STOP': tuya.enum(2)})],            
            [104, 'position', tuya.valueConverter.coverPosition],
            [104, 'position', tuya.valueConverter.raw],
            [105, 'charge_state', tuya.valueConverter.trueFalse1],
            [106, 'manual_mode', tuya.valueConverterBasic.lookup({'Enable': tuya.enum(0), 'Disable': tuya.enum(1),})],            
            [108, 'countdown', tuya.valueConverter.raw],
            [109, 'motor_direction', tuya.valueConverterBasic.lookup({'Left Side': tuya.enum(1), 'Right Side': tuya.enum(0)})],
            [110, 'mode', tuya.valueConverterBasic.lookup({'Enable': tuya.enum(1), 'Disable': tuya.enum(0)})],
            [114, 'window_detection', tuya.valueConverterBasic.lookup({Opened: 0, Closed: 1, Pending: 2})],
            ],
    },
    extend: [
        // A preferred new way of extending functionality.
    ],
};

module.exports = definition;
acortelyou commented 4 months ago

dp 102 seems to be "set state" while dp 114 seems to be "get state", haven't figured out how to expose that properly yet.

Maybe composite()? Maybe commandsWindowCovering()? Maybe action?

Also there is e.cover_mode() which expected reversed aka motor_direction, maintenance aka manual_mode, and calibration aka countdown but i'm not sure how to map correctly either because this device seems to use enums and cover mode uses binary.

Zigbee is crazy @Koenkk I can't sort out how I'm "supposed" to do anything.

Koenkk commented 4 months ago

If the converter from @plplaaa2 works well, could somebody make pull request to tuya.ts for out-of-the-box support?

acortelyou commented 4 months ago

If the converter from @plplaaa2 works well, could somebody make pull request to tuya.ts for out-of-the-box support?

@Koenkk it's not in a good state yet. Most of the exposes show up as null at best.

114\window_detection is actually the report-only state and 102\state is the issue-only state.

I haven't seen charge_state or current actually return any data at all.

acortelyou commented 3 months ago

I know it's missing some datapoints but, more importantly, the following is working 100% as expected without any errors for me.

I experimented with the other datapoints but they either didn't have an effect or didn't work in ways I understood.

If someone has an actual tuya gateway and wants to debug the extra settings go for it but this is good enough for me at the moment: full control and state of the basic functions.

const tuya = require('zigbee-herdsman-converters/lib/tuya');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const e = exposes.presets;
const ea = exposes.access;

const definition = {
    fingerprint: tuya.fingerprint('TS0601', ['_TZ3210_5rta89nj']),
    model: 'ZC-LP01',
    vendor: 'Moes',
    description: 'Sliding Window Pusher',
    options: [exposes.options.invert_cover()],
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    exposes: [
        e.cover_position().setAccess('position', ea.STATE_SET),
    ],
    meta: {
        tuyaSendCommand: 0x04,
        tuyaDatapoints: [
            [102, 'state', tuya.valueConverterBasic.lookup({CLOSE: tuya.enum(0), OPEN: tuya.enum(1), STOP: tuya.enum(2)})],
            [104, 'position', tuya.valueConverter.coverPosition],
            [114, 'state', tuya.valueConverterBasic.lookup({CLOSE: tuya.enum(0), OPEN: tuya.enum(1), STOP: tuya.enum(2)})],
        ],
    },
    extend: [
        tuya.modernExtend.dpBattery({dp: 4}),
    ],
};

module.exports = definition;
ezeghers commented 3 months ago

I know it's missing some datapoints but, more importantly, the following is working 100% as expected without any errors for me.

I experimented with the other datapoints but they either didn't have an effect or didn't work in ways I understood.

If someone has an actual tuya gateway and wants to debug the extra settings go for it but this is good enough for me at the moment: full control and state of the basic functions.

const tuya = require('zigbee-herdsman-converters/lib/tuya');
const exposes = require('zigbee-herdsman-converters/lib/exposes');
const e = exposes.presets;
const ea = exposes.access;

const definition = {
    fingerprint: tuya.fingerprint('TS0601', ['_TZ3210_5rta89nj']),
    model: 'ZC-LP01',
    vendor: 'Moes',
    description: 'Sliding Window Pusher',
    options: [exposes.options.invert_cover()],
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    exposes: [
        e.cover_position().setAccess('position', ea.STATE_SET),
    ],
    meta: {
        tuyaSendCommand: 0x04,
        tuyaDatapoints: [
            [102, 'state', tuya.valueConverterBasic.lookup({CLOSE: tuya.enum(0), OPEN: tuya.enum(1), STOP: tuya.enum(2)})],
            [104, 'position', tuya.valueConverter.coverPosition],
            [114, 'state', tuya.valueConverterBasic.lookup({CLOSE: tuya.enum(0), OPEN: tuya.enum(1), STOP: tuya.enum(2)})],
        ],
    },
    extend: [
        tuya.modernExtend.dpBattery({dp: 4}),
    ],
};

module.exports = definition;

Thanks for your work. Yes, this works with the basic functions, but for me, the Open and Close where switched around. As mentioned previously, I got a firmware update from Moes to correct the backward Open/Close status'.

acortelyou commented 3 months ago

Perhaps some of my seemingly non-deterministic results were due to not having upgraded the firmware. I may give that a shot in the future.

I would suggest sticking to modernExtend for anyone looking to add the other datapoints as it is more explicit about the from and to datatypes which was giving me difficulty.

@ezeghers I am curious, is your invert_cover setting set to true or false? perhaps the state value converter needs to account for that in the same way position does.

DavidWAbrahams commented 3 months ago

Working correctly here. While it initially had the direction reversed, it is now working as expected using the latest external_converter from @acortelyou and invert_cover: true for the device in my config/zigbee2mqtt/config.yaml

ezeghers commented 3 months ago

Perhaps some of my seemingly non-deterministic results were due to not having upgraded the firmware. I may give that a shot in the future.

I would suggest sticking to modernExtend for anyone looking to add the other datapoints as it is more explicit about the from and to datatypes which was giving me difficulty.

@ezeghers I am curious, is your invert_cover setting set to true or false? perhaps the state value converter needs to account for that in the same way position does.

I don't have an invert cover setting so I assume that means false.

acortelyou commented 3 months ago

I don't have an invert cover setting so I assume that means false.

If you're using my version it's an "option" in the code which show up under "Settings (Specific)" in the web-ui.

But yeah if you let it alone that means false.

With different firmware versions and orientations out there having a separate invert option for both position and state is probably for the best.

I'll see if I can get that working and send the PR.

tribakzero commented 3 months ago

To me it's working great after updating the invert_cover setting too.

razserv2010 commented 3 months ago

I would appreciate your help please. I bought the MOES Tuya ZigBee Smart Sliding Window Pusher And I try to add it with z2m but it is not supported. How did you manage to add it? Χ¦Χ™ΧœΧ•Χ מבך 2024-08-14 175427

tribakzero commented 3 months ago

@razserv2010 follow the thread, you need to add a file and a config to your HA in order for it to work.

razserv2010 commented 3 months ago

@razserv2010 follow the thread, you need to add a file and a config to your HA in order for it to work.

Hi, I followed and understood that some file needed to be added, but I did not understand which one and where to add it, if you could give me a guide for this I would be very happy.

tribakzero commented 3 months ago

@razserv2010 Copy this to a file: https://github.com/Koenkk/zigbee2mqtt/issues/22844#issuecomment-2270195989 named /homeassistant/zigbee2mqtt/ZC-LP01.js

Then inside /homeassistant/zigbee2mqtt/configuration.yaml add the following to the root and restart.

external_converters:

You may need to set your invert_cover following these steps: https://github.com/Koenkk/zigbee2mqtt/issues/22844#issuecomment-2278771683

That should be it.

razserv2010 commented 3 months ago

@razserv2010 Copy this to a file: #22844 (comment) named /homeassistant/zigbee2mqtt/ZC-LP01.js

Then inside /homeassistant/zigbee2mqtt/configuration.yaml add the following to the root and restart.

external_converters:

  • ZC-LP01.js

You may need to set your invert_cover following these steps: #22844 (comment)

That should be it.

It works, thank you very much

moshiko2312 commented 3 months ago

Wow thanks

moshiko2312 commented 3 months ago

I fix the manual mode button, need look like this

[106, 'manual_mode', tuya.valueConverterBasic.lookup({'Disable': tuya.enum(0), 'Enable': tuya.enum(1),})],

tribakzero commented 3 months ago

@moshiko2312 you mean now you have an extra setting inside the "Settings (specific)" tab to enable/disable the physical buttons? To me the buttons didn't worked, and by adding that line it didn't showed the setting anywhere but the buttons are enabled once more, so if it was it, then thanks.

moshiko2312 commented 3 months ago

@tribakzero

image
moshiko2312 commented 3 months ago

@tribakzero

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 tuya = require('zigbee-herdsman-converters/lib/tuya');
const modernExtend = require('zigbee-herdsman-converters/lib/modernExtend');
const e = exposes.presets;
const ea = exposes.access;

const definition = {
    zigbeeModel: [
        '5rta89nj' // Tubular motors
    ],
    fingerprint: [
// Curtain motors:
        {modelID: 'TS0601', manufacturerName: '_TZ3210_5rta89nj'},
    ],
    model: 'ZC-LP01',
    vendor: 'Moes',
    description: 'window pusher',
    fromZigbee: [tuya.fz.datapoints],
    toZigbee: [tuya.tz.datapoints],
    onEvent: tuya.onEventSetTime,
    configure: tuya.configureMagicPacket,
    exposes: [
        e.battery(),
        e.cover_position('position', 'state', ea.STATE_SET,['OPEN', 'CLOSE', 'STOP']).withDescription('Window Control'),
        e.binary('charge_state', ea.STATE, 'True', 'False'),
        e.enum('manual_mode', ea.STATE_SET, ['Enable', 'Disable']),
        e.binary('fault', ea.STATE, 'True', 'False').withDescription('Motor Fault'),
        e.numeric('countdown', ea.STATE_SET).withValueMin(10).withValueMax(90).withDescription('Mortor timeout').withUnit('s'),
        e.enum('motor_direction', ea.STATE_SET, ['Left Side', 'Right Side']).withDescription('Install Side Type'),
        e.enum('mode', ea.STATE_SET, ['Enable', 'Disable']).withDescription('Slow_stop'),
        e.enum('window_detection', ea.STATE, ['Opened', 'Closed', 'Pending']).withDescription('Window Detection'),

    ],
    meta: {
        // All datapoints go in here
        tuyaSendCommand: 0x04,
        tuyaDatapoints: [
            [4, 'battery', tuya.valueConverter.raw],
            [102, 'state', tuya.valueConverterBasic.lookup({'OPEN': tuya.enum(0), 'CLOSE': tuya.enum(1), 'STOP': tuya.enum(2)})],            
            [104, 'position', tuya.valueConverter.coverPosition],
            [104, 'position', tuya.valueConverter.raw],
            [105, 'charge_state', tuya.valueConverter.trueFalse1],
            [106, 'manual_mode', tuya.valueConverterBasic.lookup({'Disable': tuya.enum(0), 'Enable': tuya.enum(1),})],            
            [108, 'countdown', tuya.valueConverter.raw],
            [109, 'motor_direction', tuya.valueConverterBasic.lookup({'Left Side': tuya.enum(1), 'Right Side': tuya.enum(0)})],
            [110, 'mode', tuya.valueConverterBasic.lookup({'Enable': tuya.enum(1), 'Disable': tuya.enum(0)})],
            [114, 'window_detection', tuya.valueConverterBasic.lookup({Opened: 0, Closed: 1, Pending: 2})],
            ],
    },
    extend: [
        // A preferred new way of extending functionality.
    ],
};

module.exports = definition;
tribakzero commented 3 months ago

@moshiko2312 to me that's only state, position, battery and linkquality πŸ˜”

moshiko2312 commented 3 months ago

@moshiko2312 to me that's only state, position, battery and linkquality πŸ˜”

look up I put the code

tribakzero commented 3 months ago

@moshiko2312 no idea why, but even copy/pasting and deleting and adding the device again still show me the same inputs. At least the buttons work hehe.

effoc commented 3 months ago

@moshiko2312 no idea why, but even copy/pasting and deleting and adding the device again still show me the same inputs. At least the buttons work hehe.

I have to reboot my server and not only HA to make new changes to work

tribakzero commented 3 months ago

Thanks @effoc that did it. Now with @moshiko2312 version I'm noticing that the feature to reverse the direction isn't working, if you add: options: [exposes.options.invert_cover()] to the root of the definition object it does what I suppose Motor direction intended, keep in mind that this setting is in the specific tab.

Remember to reboot the whole thing for changes to take effect, for whatever reason that is.

Snowbars2000 commented 2 months ago

@razserv2010 Copy this to a file: #22844 (comment) named /homeassistant/zigbee2mqtt/ZC-LP01.js

Then inside /homeassistant/zigbee2mqtt/configuration.yaml add the following to the root and restart.

external_converters:

  • ZC-LP01.js

You may need to set your invert_cover following these steps: #22844 (comment)

That should be it.

Thanks for the simple but very good advice. I just wanted to say that I needed to put a minus "-" before the file name and then everything worked.

external_converters

ronaldopdc commented 1 month ago

}, extend: [ // A preferred new way of extending functionality. ], options: [exposes.options.invert_cover()], };

module.exports = definition;

@tribakzero, great work, but for, me the feature to reverse the direction isn't working. I put the options: [exposes.options.invert_cover()] as above and it isn't working. Can you help me please?