I am new to homey app development, and I am basically trying to do one specific thing, which is to change an attribute in a Zigbee device that I have. The device is a Tuya valve controller, and it is supported in this app:
The problem is that the app does not support changing any attributes, and the valve controller does have an attribute/setting that controls the power on behaviour. By default it will close the valve when power is restored after a power loss, which I really don’t want. The device can be set to either open, close or last state, but it is tucked away in a custom cluster (if I am using the wrong terminology here, please excuse me).
I found some code for a different system which shows me the cluster and attribute ID. This thread has the info: [RELEASE] Tuya Zigbee Valve driver (w/ healthStatus) - Custom Drivers - Hubitat
The cluster ID is 57345, and the attribute in question is 53264. What I have done is to clone the app mentioned above, and I have tried to add that cluster as a custom cluster, and when I try to read that attribute, I get this response in the log:
2023-06-03T13:43:53.053Z zigbee-clusters:cluster ep: 1, cl: powerOnstate (57345) read attributes [ 53264 ]
2023-06-03T13:43:53.077Z zigbee-clusters:cluster ep: 1, cl: powerOnstate (57345) send frame ZCLStandardHeader {
frameControl: [],
data: powerOnstate.readAttributes { attributes: [ 53264 ] },
cmdId: 0,
trxSequenceNumber: 1
}
2023-06-03T13:43:53.272Z zigbee-clusters:cluster ep: 1, cl: powerOnstate (57345) received frame readAttributesStructured.response powerOnstate.readAttributesStructured.response {
attributes: <Buffer 10 d0 00 30 00>
}
2023-06-03T13:43:53.290Z zigbee-clusters:cluster ep: 1, cl: powerOnstate (57345) read attributes result { attributes: <Buffer 10 d0 00 30 00> }
powerOnstate is the name I have given to this cluster. From what I can tell, I am actually getting something back from the device, but I am not sure why I am getting what looks to be three bytes (00 30 00), when the value apparently should be a byte (or an enum8).
The default value in the device is 0, so I am guessing that the 30 is actually ascii zero, so I probably want to change that to 32, but writing always fails in a way similar to this:
2023-06-03T13:43:53.303Z zigbee-clusters:cluster ep: 1, cl: powerOnstate (57345) send frame ZCLStandardHeader {
frameControl: [],
data: powerOnstate.writeAttributes { attributes: <Buffer 10 d0 29 32 00> },
cmdId: 2,
trxSequenceNumber: 2
}
2023-06-03T13:43:53.477Z zigbee-clusters:cluster ep: 1, cl: powerOnstate (57345) received frame writeAttributesAtomic.response powerOnstate.writeAttributesAtomic.response {
attributes: [ AttributeResponse { status: 'INVALID_DATA_TYPE', id: 53264 } ]
}
I am not sure if the INVALID_DATA_TYPE is something returned from the device, but it does look like Homey actually tried to send something (at least it prints what looks like the buffer to send).
In this specific instance, I tried to write the attribute with this call:
await this.zclNode.endpoints[1].clusters.powerOnstate.writeAttributes({ powerOnstate: 0x000032 });
Not sure why the buffer that Homey tries to write contains the value 29, but I have been unable to find some proper docs to understand this.
I’ve tried changing the data type for this attribute to different types, but I can never seem to get Homey to write something that appears to generate a buffer that looks like the one read. This is my cluster spec file where the data type is defined:
'use strict';
const Cluster = require('../Cluster');
const { ZCLDataTypes } = require('../zclTypes');
const ATTRIBUTES = {
powerOnstate: { id: 53264, type: ZCLDataTypes.int16 },
};
const COMMANDS = {};
class PoweronstateCluster extends Cluster {
static get ID() {
return 57345;
}
static get NAME() {
return 'powerOnstate';
}
static get ATTRIBUTES() {
return ATTRIBUTES;
}
static get COMMANDS() {
return COMMANDS;
}
}
Cluster.addCluster(PoweronstateCluster);
module.exports = PoweronstateCluster;
I have tried various data types, but I am really not understanding properly what I am doing. Not sure if it is possible to make sense of any of what I wrote, but if anyone can offer some pointers for me, I’d be grateful.
I don’t need to be able to change this from within the app, I just want to get it written to the device, and then I’ll just use the original app to control the valve. I am assuming that this setting is stored in nonvolatile memory in the device, so once changed, it will stay changed.