com.tuya.zigbee
com.tuya.zigbee copied to clipboard
Device Request - 2 channel curtain module by Girier / tuya - _TZ3000_j1xl73iw / TS130F
hi, can you please add the
Girier Tuya 2 curtain module, and if possible add the possibility to calibrate the unit.
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": {} } } }
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?
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)
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 :(
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
As I don't have the tuya app, I cannot check. This would be great, though...
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 ;-)
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" :)
open the tuya app today and unfortunately I could not find the setting to change it from puls to switch....
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 :)
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 currentcurtain_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
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?
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 :-)
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.....
@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 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
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!
Hmm, it won't be easy if you are not dev, but here are the steps
- ensure you have
git
installed - pull my repo from a terminal/console:
git clone https://github.com/tfoldi/com.tuya.zigbee -b curtain_j1xl73iw
- Install nodejs including the
npm
package manager on your platform - enter to
com.tuya.zigbee
folder and install app deps withnpm
install - install homey cli: https://apps.developer.homey.app/the-basics/getting-started/homey-cli
- install docker on your platform
- issue
homey app install
fromcom.tuya.zigbee
folder
This should install the version with my changes on your homey. Good luck!
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 ??
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.