Add support for Zemismart ZM79E-DT (Tuya)
See original GitHub issueI recently found out that there is a Zigbee variant of the Zemismart curtain motors that have the Zigbee receiver included in the motor itself instead of the switch:
I paired it with zigbee2mqtt to check what it’s sending and the receiving part is simple enough.
Started moving:
type 'commandSetDataResponse', cluster 'manuSpecificTuyaDimmer', data '{"status":0,"transid":1,"dp":1031,"fn":0,"data":{"type":"Buffer","data":[0]}}' from endpoint 1 with groupID 0
{
"status":0,
"transid":1,
"dp":1031,
"fn":0,
"data":{
"type":"Buffer",
"data":[
0
]
}
}
Arrived at location (60% in this example):
type 'commandSetDataResponse', cluster 'manuSpecificTuyaDimmer', data '{"status":0,"transid":1,"dp":515,"fn":0,"data":{"type":"Buffer","data":[0,0,0,60]}}' from endpoint 1 with groupID 0
{
"status":0,
"transid":1,
"dp":515,
"fn":0,
"data":{
"type":"Buffer",
"data":[
0,
0,
0,
60
]
}
}
Range goes from 0-100, 124 means it is not calibrated yet. 100 is all the way open, 0 is all the way closed.
Now for the actual question: How to figure out what to send to control it? Do I need more info from Zemismart or can I get that information from the database entry?
{
"id":59,
"type":"Router",
"ieeeAddr":"0x086bd7fffedae046",
"nwkAddr":8448,
"manufId":0,
"manufName":"_TYST11_cowvfni3",
"powerSource":"Mains (single phase)",
"modelId":"owvfni3\u0000",
"epList":[
1
],
"endpoints":{
"1":{
"profId":260,
"epId":1,
"devId":256,
"inClusterList":[
0,
3,
4,
5,
6
],
"outClusterList":[
25
],
"clusters":{
"genBasic":{
"attributes":{
"modelId":"owvfni3\u0000",
"manufacturerName":"_TYST11_cowvfni3",
"powerSource":1,
"zclVersion":3,
"stackVersion":0,
"hwVersion":1,
"dateCode":"20180727"
}
}
},
"binds":[
]
}
},
"appVersion":255,
"stackVersion":0,
"hwVersion":1,
"dateCode":"20180727",
"zclVersion":3,
"interviewCompleted":true,
"meta":{
},
"lastSeen":1586857228701
}
I saw that there is already a sendTuyaCommand function here for a thermostat. I assume I can use that for my purpose since the protocol looks identical.
A few more, smaller question:
The motor keeps sending{"appVersion":73}
10x at a time, every few minutes. Does it expect a response?There is a null terminator (\u0000) in the modelId, judging by the existing entries I just take that over to the devices.json as is?- Is it possible to send “raw” commands to a device via zigbee2mqtt for testing? Seems like a pain to have to restart after every change on the converter
- Is there a standard for which state is considered open? 0 or 100? 0 or 1? Float or integer? Home Assistant seems to handle it the same way as the motor (100 is fully open).
I took pictures of the motor, just for reference:
Data sheet of that chip is available here.
The motors all seem to be identical except the chip on the bottom is replaced by a Zigbee/wi-fi/Z-wave module.
Issue Analytics
- State:
- Created 3 years ago
- Comments:30 (19 by maintainers)
Zemismart was nice enough to send me the full technical documentation (even including source code), so kudos to them for being so open about their products.
For future reference, @kirovilya I worked from your comment here.
However, the description for dp is wrong (assuming the protocol is identical between devices).
The dp is actually split into two parts, the first byte is the value type and the second part is the actual dp identifier.
These are the types taken from their source code and should apply to all devices that use this protocol:
My device doesn’t use strings, raw and bool so I can’t test them.
The second part is the actual ID for my device, I got this list from them:
The first part of the data is always the length (can be 0 for enums), followed by the actual data.
So a working command for my device would be
dp:
data:
I got the following working so far:
Still gotta integrate everything into Home Assistant and maybe add the available configuration options but everything is looking good so far.
Yes, the Zigbee/Z-wave module is just strapped to the curtain motor and communicates with it via a serial port.
The 433 MHz receiver is another way to control it that the included remote uses.