com.tuya.zigbee icon indicating copy to clipboard operation
com.tuya.zigbee copied to clipboard

Device Request - 2 channel curtain module by Girier / tuya - _TZ3000_j1xl73iw / TS130F

Open pwvandeursen opened this issue 1 year ago • 18 comments

hi, can you please add the

Girier Tuya 2 curtain module, and if possible add the possibility to calibrate the unit.

image https://nl.aliexpress.com/item/1005005225077998.html?spm=a2g0o.order_list.order_list_main.52.407779d23c3SJn&gatewayAdapt=glo2nld

"ids":` { "modelId": "TS130F", "manufacturerName": "_TZ3000_j1xl73iw" }, "endpoints": { "endpointDescriptors": [ { "endpointId": 1, "applicationProfileId": 260, "applicationDeviceId": 514, "applicationDeviceVersion": 0, "_reserved1": 1, "inputClusters": [ 4, 5, 6, 258, 57345, 0 ], "outputClusters": [ 25, 10 ] }, { "endpointId": 2, "applicationProfileId": 260, "applicationDeviceId": 514, "applicationDeviceVersion": 0, "_reserved1": 1, "inputClusters": [ 4, 5, 6, 258, 57345 ], "outputClusters": [] }, { "endpointId": 242, "applicationProfileId": 41440, "applicationDeviceId": 97, "applicationDeviceVersion": 0, "_reserved1": 0, "inputClusters": [], "outputClusters": [ 33 ] } ], "endpoints": { "1": { "clusters": { "groups": { "attributes": [ { "acl": [ "readable", "reportable" ], "id": 0, "name": "nameSupport", "value": { "type": "Buffer", "data": [ 0 ] }, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "reportable" ], "id": 65533, "name": "clusterRevision", "value": 2, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } } ] }, "scenes": { "attributes": [ { "acl": [ "readable", "reportable" ], "id": 0, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "reportable" ], "id": 1, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "reportable" ], "id": 2, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "reportable" ], "id": 3, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "reportable" ], "id": 4, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "reportable" ], "id": 65533, "name": "clusterRevision", "value": 2, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } } ] }, "onOff": { "attributes": [ { "acl": [ "readable", "writable", "reportable" ], "id": 20480, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "writable", "reportable" ], "id": 32769, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "writable", "reportable" ], "id": 16385, "name": "onTime", "value": 0, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "writable", "reportable" ], "id": 16386, "name": "offWaitTime", "value": 0, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } } ] }, "windowCovering": { "attributes": [ { "acl": [ "readable", "writable", "reportable" ], "id": 8, "name": "currentPositionLiftPercentage", "value": 100, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "writable", "reportable" ], "id": 61440, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "writable", "reportable" ], "id": 61441, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "writable", "reportable" ], "id": 61442, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "writable", "reportable" ], "id": 61443, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "writable", "reportable" ], "id": 32768, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } } ] }, "basic": { "attributes": [ { "acl": [ "readable", "reportable" ], "id": 0, "name": "zclVersion", "value": 3 }, { "acl": [ "readable", "reportable" ], "id": 1, "name": "appVersion", "value": 70 }, { "acl": [ "readable", "reportable" ], "id": 2, "name": "stackVersion", "value": 0 }, { "acl": [ "readable", "reportable" ], "id": 3, "name": "hwVersion", "value": 1 }, { "acl": [ "readable", "reportable" ], "id": 4, "name": "manufacturerName", "value": "_TZ3000_j1xl73iw" }, { "acl": [ "readable", "reportable" ], "id": 5, "name": "modelId", "value": "TS130F" }, { "acl": [ "readable", "reportable" ], "id": 6, "name": "dateCode", "value": "" }, { "acl": [ "readable", "reportable" ], "id": 7, "name": "powerSource", "value": "mains" }, { "acl": [ "readable", "writable", "reportable" ], "id": 65502 }, { "acl": [ "readable", "reportable" ], "id": 65533, "name": "clusterRevision", "value": 2 }, { "acl": [ "readable", "reportable" ], "id": 65534, "name": "attributeReportingStatus", "value": "PENDING" }, { "acl": [ "readable", "reportable" ], "id": 65506 }, { "acl": [ "readable", "reportable" ], "id": 65507 } ] } }, "bindings": { "ota": { "attributes": [ { "acl": [ "readable" ], "id": 0 }, { "acl": [ "readable" ], "id": 1 }, { "acl": [ "readable" ], "id": 2 }, { "acl": [ "readable" ], "id": 3 }, { "acl": [ "readable" ], "id": 4 }, { "acl": [ "readable" ], "id": 5 }, { "acl": [ "readable" ], "id": 6 }, { "acl": [ "readable" ], "id": 7 }, { "acl": [ "readable" ], "id": 8 }, { "acl": [ "readable" ], "id": 9 }, { "acl": [ "readable" ], "id": 65533, "name": "clusterRevision", "value": 3 } ] }, "time": { "attributes": [ { "acl": [ "readable" ], "id": 65533, "name": "clusterRevision", "value": 1 } ] } } }, "2": { "clusters": { "groups": { "attributes": [ { "acl": [ "readable", "reportable" ], "id": 0, "name": "nameSupport", "value": { "type": "Buffer", "data": [ 0 ] }, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "reportable" ], "id": 65533, "name": "clusterRevision", "value": 2, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } } ] }, "scenes": { "attributes": [ { "acl": [ "readable", "reportable" ], "id": 0, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "reportable" ], "id": 1, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "reportable" ], "id": 2, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "reportable" ], "id": 3, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "reportable" ], "id": 4, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "reportable" ], "id": 65533, "name": "clusterRevision", "value": 2, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } } ] }, "onOff": { "attributes": [ { "acl": [ "readable", "writable", "reportable" ], "id": 16385, "name": "onTime", "value": 0, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "writable", "reportable" ], "id": 16386, "name": "offWaitTime", "value": 0, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } } ] }, "windowCovering": { "attributes": [ { "acl": [ "readable", "writable", "reportable" ], "id": 8, "name": "currentPositionLiftPercentage", "value": 0, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "writable", "reportable" ], "id": 61440, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "writable", "reportable" ], "id": 61441, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "writable", "reportable" ], "id": 61442, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "writable", "reportable" ], "id": 61443, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } }, { "acl": [ "readable", "writable", "reportable" ], "id": 32768, "reportingConfiguration": { "status": "NOT_FOUND", "direction": "reported" } } ] } }, "bindings": {} }, "242": { "clusters": {}, "bindings": {} } } }

pwvandeursen avatar Sep 12 '23 20:09 pwvandeursen

I have this device. It's recognized by HA, but I am unable to do the calibration of the curtains. Any advice how to do it?

sanchosk avatar Nov 29 '23 20:11 sanchosk

only way I know how to do it now is through the TUYA gateway I have lying around. I do calibration there, and unfortunately also keep it connected to that gateway (can't bring it into Homey at the moment, because if I do, the calibration data is lost to Homey)

pwvandeursen avatar Dec 04 '23 09:12 pwvandeursen

There is one more way - you can do it using home assistant by sending specific command. However, there is one more problem with the module - I have switches for my curtains, not buttons. If I toggle the switch to go up, it will (after 4 seconds) reset the device to pairing mode :(

sanchosk avatar Dec 14 '23 12:12 sanchosk

can you not in the tuya app change the mode? for the normal buttons I can change them from switch to push button mode.

I have not checked that for the curtain switch though

pwvandeursen avatar Dec 14 '23 12:12 pwvandeursen

As I don't have the tuya app, I cannot check. This would be great, though...

sanchosk avatar Dec 14 '23 12:12 sanchosk

you need the Tuya gateway for that. I dd buy one from ali-express, just to be able to configure the Tuya devices I have. Good thing is, when you change a setting in the Tuya app through the gateway, it remains persistent in Homey ;-)

pwvandeursen avatar Dec 14 '23 12:12 pwvandeursen

I've seen some online videos from testing this using TuYa GW and I don't remember having such option there, but I might be wrong. I'll order the TuYa GW then and will test. Maybe I have an old one somewhere in a pile of "non-open-source-junk" :)

sanchosk avatar Dec 14 '23 12:12 sanchosk

open the tuya app today and unfortunately I could not find the setting to change it from puls to switch....

pwvandeursen avatar Dec 14 '23 20:12 pwvandeursen

Thanks for saving me the time to go through the garbage pile. Not very good news, considering that my switches are 6x more expensive than the zigbee device :)

sanchosk avatar Dec 14 '23 20:12 sanchosk

I bought this _TZ3000_j1xl73iw device yesterday and after some googling I made it work similar to HA's approach. In short, I've added a new calibrationTime to TuyaWindowCoveringCluster.js:


class TuyaWindowCoveringCluster extends WindowCoveringCluster {

    static get ATTRIBUTES() {
        return {
            windowCoverStatus: {
                id: 61440,
                type: ZCLDataTypes.enum8 ({
                    Open: 0,
                    Close: 1,
                    Stop: 2
                }),
            },
            calibration: {
                id: 61441,
                type: ZCLDataTypes.enum8 ({
                    End: 0,
                    Start: 1,
                }),
            },
            motorReversal: {
                id: 61442,
                type: ZCLDataTypes.enum8 ({
                    Off: 0,
                    On: 1,
                }),
            },
            calibrationTime: {
                id: 61443,
                type: ZCLDataTypes.uint16,
            },            
        };
    }

Then added a new driver.js to the curtain_module to make it child of ZigBeeDriver:


'use strict';

const { ZigBeeDriver } = require('homey-zigbeedriver');

class curtainmodule extends ZigBeeDriver {

}

module.exports = curtainmodule;

In driver.compose.js defined a subdevice for the L3/L4 outputs as well as the second endpoint for it:

    "endpoints": {
      "1": {
        "clusters": [0, 4, 5, 6, 258, 57345],
        "bindings": [258]
      },
      "2": {
        "clusters": [4, 5, 6, 258, 57345],
        "bindings": [258]
      }
    },
    "devices": {
      "secondModule": {
        "class": "curtain",
        "name": {
          "en": "Curtain Module (2)"
        },
        "capabilities": ["windowcoverings_set"],
        "energy": {
          "approximation": {
            "usageOn": 0,
            "usageOff": 0
          }
        }
      }
    },

and finally set the calibration time to 30 seconds (from the the default 10):

const TuyaWindowCoveringCluster = require("../../lib/TuyaWindowCoveringCluster");

Cluster.addCluster(TuyaWindowCoveringCluster);
// [...]
class curtainmodule extends ZigBeeDevice {
  async onNodeInit({ zclNode }) {
    this.printNode();

    const { subDeviceId } = this.getData();
    const endpoint = subDeviceId === "secondModule" ? 2 : 1;

    this.log("Device data: ", subDeviceId);
    this.log("Endpoint: ", endpoint);

    this._reportDebounceEnabled = false;

    this.registerCapability("windowcoverings_set", CLUSTER.WINDOW_COVERING, {
      endpoint: endpoint,
      reportOpts: {
        configureAttributeReporting: {
          minInterval: 0, // No minimum reporting interval
          maxInterval: 30000, // Maximally every ~8 hours
          minChange: 5, // Report when value changed by 5
        },
      },
    });

    await this.zclNode.endpoints[endpoint].clusters.windowCovering.writeAttributes({ calibrationTime: 300 });

    await this.zclNode.endpoints[endpoint].clusters.windowCovering
      .readAttributes("calibrationTime")
      .then((res) => {
        this.log("Calibration time is: ", res);
      });

It is working well now if I set the percentage on both devices (L1/L2 and L3/L4), but for some reason when I fully lift the second device (windowcoverings_set → 1) it controls the first device. However, if I say windowcoverings_set → 0.99, then it controls the good one, so I am about to fix this in the meantime.

I am happy to help make this part of the original code base, I can create a PR if you want or anyone can use the code from above. If you want me to create a PR, a few questions:

  • As I am using subdevice do you want me to move the code under a new driver like curtain_module_2_gang or keep it in the current curtain_module
  • I am using TuyaWindowCoveringCluster but it is commented out in the original code - I assume there is a reason for that

and finally, thank you for making this project, I am using it everyday

tfoldi avatar Dec 21 '23 08:12 tfoldi

Just found out that some of my code is pretty similar to #474. Could that be merged so I can only add the subdevice handling?

tfoldi avatar Dec 21 '23 09:12 tfoldi

Hi tfoldi, Great progress. does that mean the curtain (when the code is merged) can both be added to homey and calibrated? would be really great. Will probably need to wait then for a new version of the app. fingers crossed we get a nice christmas gift :-)

pwvandeursen avatar Dec 23 '23 09:12 pwvandeursen

Just found out that some of my code is pretty similar to #474. Could that be merged so I can only add the subdevice handling?

@tfoldi were you able to get this added? I did not see it in the drivers for 2.20 yet.....

pwvandeursen avatar Jan 23 '24 14:01 pwvandeursen

@tfoldi ,

just saw this one passing by #729 , which also has the curtain calibration. Unfortunately, this is not something I can do, so asking what the status is and if this one is ready for the next release by @JohanBendz

pwvandeursen avatar Mar 08 '24 12:03 pwvandeursen

@pwvandeursen had some time today and polished my version a little bit. Feel free to try it out and let me know if there is anything off

tfoldi avatar Apr 27 '24 14:04 tfoldi

hi @tfoldi , great to hear! i'm sorry to have to ask, but how do I test this? Not a coder so no clue about pull request and loading this in a test on my side... if you can point me in the right direction I'll do the reading tries.... thanks!

pwvandeursen avatar Apr 27 '24 14:04 pwvandeursen

Hmm, it won't be easy if you are not dev, but here are the steps

  1. ensure you have git installed
  2. pull my repo from a terminal/console: git clone https://github.com/tfoldi/com.tuya.zigbee -b curtain_j1xl73iw
  3. Install nodejs including the npm package manager on your platform
  4. enter to com.tuya.zigbee folder and install app deps with npm install
  5. install homey cli: https://apps.developer.homey.app/the-basics/getting-started/homey-cli
  6. install docker on your platform
  7. issue homey app install from com.tuya.zigbee folder

This should install the version with my changes on your homey. Good luck!

tfoldi avatar Apr 27 '24 17:04 tfoldi

Haven't been able to get this working, so hopefully this one will be added (together with #361 #729, #766, #808) to the next release by @JohanBendz ??

pwvandeursen avatar May 24 '24 13:05 pwvandeursen

Added to current Curtain Module driver as neew functionality has been added to it as per request. Do get back if this is not working.

JohanBendz avatar Sep 07 '24 23:09 JohanBendz