Hello
I recently bought a Zigbee switch with 4 channels. Unfortunately, I'm not able to correctly configure it on Hubitat.
Here is a link to this device : Module de commutateur d'éclairage intelligent Zigbee 4CH, DC 5/12/32V, RF433, relais de réception 10A, fonctionne avec Alexa Google Assistant,Tuya Smart Life | AliExpress
I already read this post Tuya Zigbee Wall Switch (aka. Lonsonho or Bandi) - #29 by jacubmikita and try the @martinkura solution : Tuya Zigbee Wall Switch (aka. Lonsonho or Bandi) - #50 by martinkura adapting his code to my case...but after some attempts and debug, i'm not able to do it with success...
When I set the parent device to "GE Zigbee Swith" type i'm able to torn on and off the first channel of the device...However, if I set the Child Device with same type, it doesn't work
Do you have some suggestions ?
Here is the signature of my device :
- endpointId: 01
- application: 43
- softwareBuild:
- inClusters: 0003,0004,0005,0006,E000,E001,0000
- outClusters: 0019,000A
- model: TS0004
- isMultiEP: true
- manufacturer: _TZ3000_excgg5kb
And the code that I use on my driver :
import hubitat.device.HubAction
import hubitat.device.Protocol
metadata {
definition (name: "Tuya ZigBee Switch module 1/2/3/4-Gang", namespace: "Moes 1.31", author: "Martin Kura") {
capability "Initialize"
capability "Actuator"
// capability "Configuration"
capability "Refresh"
capability "Switch"
fingerprint profileId:"0104", model:"TS0601", manufacturer:"_TZE200_amp6tsvy", endpointId:"01", inClusters:"0000,0004,0005,EF00", outClusters:"0019,000A", application:"42", deviceJoinName: "Moes 1-Gang Switch / ZTS-EU1"
fingerprint profileId:"0104", model:"TS0601", manufacturer:"_TZE200_g1ib5ldv", endpointId:"01", inClusters:"0000,0004,0005,EF00", outClusters:"0019,000A", application:"42", deviceJoinName: "Moes 2-Gang Switch / ZTS-EU2"
fingerprint profileId:"0104", model:"TS0601", manufacturer:"_TZE200_tz32mtza", endpointId:"01", inClusters:"0000,0004,0005,EF00", outClusters:"0019,000A", application:"42", deviceJoinName: "Moes 3-Gang Switch / ZTS-EU3"
fingerprint profileId:"0104", model:"TS0004", manufacturer:"_TZ3000_excgg5kb", endpointId:"01", inClusters:"0003,0004,0005,0006,E000,E001,0000", outClusters:"0019,000A", application:"43", deviceJoinName: "Tuya 4CH Zigbee"
}
attribute "switchLightMode","enum",["OFF", "ON", "Position"]
attribute "relayMode","enum",["OFF", "ON", "Last state"]
attribute "lastCheckin", "string"
preferences {
input(name: "switchLightMode", type: "enum", title: ("Switch Backlight Mode"), description: ("- select type of backlight indicator (default: Position)"), options: ["OFF", "ON", "Position"], defaultValue: "Position", submitOnChange: true)
input(name: "relayMode", type: "enum", title: ("Switch Relay Mode"), description: ("- select relay renew state after AC failed (default: OFF)"), options: ["OFF", "ON", "Last state"], defaultValue: "OFF", submitOnChange: true)
input(name: "debugLogging", type: "bool", title: ("Enable debug logging"), description: "", defaultValue: true, submitOnChange: true, displayDuringSetup: true)
input(name: "infoLogging", type: "bool", title: ("Enable info logging"), description: "", defaultValue: true, submitOnChange: true, displayDuringSetup: true)
}
}
def initialize() {
if (infoLogging) log.info "Initializing..."
log.warn "Debug logging will be automatically disabled after 30 minutes!"
setupChildDevices()
device.updateSetting("switchLightMode",[type:"enum",value:"Position"])
device.updateSetting("relayMode",[type:"enum",value:"OFF"])
device.updateSetting("debugLogging",[type:"bool",value:"true"])
device.updateSetting("infoLogging",[type:"bool",value:"true"])
if (debugLogging) runIn(1800,logsOff)
refresh()
}
void logsOff(){
log.warn "Debug logging disabled..."
device.updateSetting("debugLogging",[value:"false",type:"bool"])
}
/*def configure(){
if (debugLogging) log.debug "Configuring Reporting and Bindings..."
def cmds = [
//bindings
"zdo bind 0x${device.deviceNetworkId} 0x01 0x00 0xEF00 {${device.zigbeeId}} {}", "delay 200",
"zdo bind 0x${device.deviceNetworkId} 0x01 0x01 0xEF00 {${device.zigbeeId}} {}", "delay 200",
//"zdo bind 0x${device.deviceNetworkId} 0x${device.endpointId} 0x01 0x0004 {${device.zigbeeId}} {}", "delay 200",
//"zdo bind 0x${device.deviceNetworkId} 0x${device.endpointId} 0x01 0x0005 {${device.zigbeeId}} {}", "delay 200",
//reporting
"he cr 0x${device.deviceNetworkId} 0x${device.endpointId} 0xEF00 0 0x00 0 0xFFFF {}","delay 200",
"he cr 0x${device.deviceNetworkId} 0x${device.endpointId} 0xEF00 0 0x01 0 0xFFFF {}", "delay 200",
//"he cr 0x${device.deviceNetworkId} 0x${device.endpointId} 0x0300 0 0x0000 0 0xFFFF {}", "delay 200",
//"he cr 0x${device.deviceNetworkId} 0x${device.endpointId} 0x0300 0 0x0001 0 0xFFFF {}", "delay 200",
// "he cr 0x${device.deviceNetworkId} 0x${device.endpointId} 0x0300 0 0x0007 0 0xFFFF {}", "delay 200",
// "he cr 0x${device.deviceNetworkId} 0x${device.endpointId} 0x0300 0 0x0008 1 0xFFFE {}", "delay 200",
] + refresh()
return cmds
} */
def installed() {
log.info "Installing..."
log.warn "Debug logging will be automatically disabled after 30 minutes!"
setupChildDevices()
device.updateSetting("switchLightMode",[type:"enum",value:"Position"])
device.updateSetting("relayMode",[type:"enum",value:"OFF"])
device.updateSetting("debugLogging",[type:"bool",value:"true"])
device.updateSetting("infoLogging",[type:"bool",value:"true"])
if (debugLogging) runIn(1800,logsOff)
refresh()
}
def updated() {
log.warn "debug logging is: ${debugLogging == true}"
log.warn "description logging is: ${infoLogging == true}"
if (infoLogging) log.info "Updated..."
if (debugLogging) log.debug "Parent updated"
switchLightModeConfig() + relayModeConfig() + refresh()
}
private getCLUSTER_TUYA() { 0xEF00 }
// private getSETDATA() { 0x00 }
// Parse incoming device messages to generate events
def parse(String description) {
if (description?.startsWith('catchall:') || description?.startsWith('read attr -')) {
Map descMap = zigbee.parseDescriptionAsMap(description)
if (descMap?.clusterInt==CLUSTER_TUYA) {
if (debugLogging) log.debug descMap
if ( descMap?.command == "01" || descMap?.command == "02" ) {
def switchFunc = (descMap?.data[2])
def switchAttr = (descMap?.data[3])
def switchState = (descMap?.data[6]) == "01" ? "on" : "off"
if (switchFunc <= "03" && switchAttr =="01") {
def cd = getChildDevice("${device.id}-${switchFunc}")
if (cd == null) {
return createEvent(name: "switch", value: switchState)
}
if (descMap?.command == "00") {
// switch toggled
cd.parse([[name: "switch", value:switchState, descriptionText: "Child switch ${switchFunc} turned $switchState"]])
}
else if (descMap?.command == "01") {
// report switch status
cd.parse([[name: "switch", value:switchState, descriptionText: "Child switch ${switchFunc} is $switchState"]])
}
if (switchState == "on") {
if (debugLogging) log.debug "Parent Switch ON"
return createEvent(name: "switch", value: "on")
}
else if (switchState == "off") {
def cdsOn = 0
// cound number of switches on
getChildDevices().each {child ->
if (getChildId(child) != switchFunc && child.currentValue('switch') == "on") {
cdsOn++
}
}
if (cdsOn == 0) {
if (debugLogging) log.debug "Parent Switch OFF"
return createEvent(name: "switch", value: "off")
}
}
}
}
}
}
}
def lastCheckin() { // send event for heartbeat
def now = new Date()
sendEvent(name: "lastCheckin", value: now)
}
def off() {
if (infoLogging) log.info "Turn all switches OFF"
return [
"he cmd 0x${device.deviceNetworkId} 0x${device.endpointId} 0xEF00 0x00 {0001010100010002010001000301000100}","delay 200",
//"he rattr 0x${device.deviceNetworkId} 0x${device.endpointId} 0xEF00 0x01 {}","delay 200"
]
}
def on() {
if (infoLogging) log.info "Turn all switches ON"
return [
"he cmd 0x${device.deviceNetworkId} 0x${device.endpointId} 0xEF00 0x00 {0001010100010102010001010301000101}","delay 200",
// "he rattr 0x${device.deviceNetworkId} 0x${device.endpointId} 0xEF00 0x01 {}","delay 200"
]
}
def refresh() {
if (infoLogging) log.info "Refreshing..."
return [
//"he rattr 0x${device.deviceNetworkId} 0x${device.endpointId} 0xEF00 0x04 {}","delay 200", //light state
//"he rattr 0x${device.deviceNetworkId} 0x${device.endpointId} 0xEF00 0x01 {}","delay 200", //light state
//"he rattr 0x${device.deviceNetworkId} 0x${device.endpointId} 0x0005 0x00 {}","delay 200", //
lastCheckin()
]
}
private String getChildId(childDevice) {
return childDevice.deviceNetworkId.substring(childDevice.deviceNetworkId.length() - 2)
}
def componentOn(childDevice) {
if (debugLogging) log.debug "component state is ON - ${childDevice} {${childDevice.deviceNetworkId}}"
if (infoLogging) log.info "${childDevice} is ON"
String fullDataOn = "0001" + getChildId(childDevice) + "01000101"
sendHubCommand(new HubAction("he cmd 0x${device.deviceNetworkId} 0x${device.endpointId} 0xEF00 0x00 {${fullDataOn}}", Protocol.ZIGBEE))
if (debugLogging) log.debug "{executed} 0x${device.deviceNetworkId} 0x${device.endpointId} 0xEF00 0x00 {${fullDataOn}}"
}
def componentOff(childDevice) {
if (debugLogging) log.debug "component state is OFF - ${childDevice} {${childDevice.deviceNetworkId}}"
if (infoLogging) log.info "${childDevice} is OFF"
String fullDataOff = "0001" + getChildId(childDevice) + "01000100"
sendHubCommand(new HubAction("he cmd 0x${device.deviceNetworkId} 0x${device.endpointId} 0xEF00 0x00 {${fullDataOff}}", Protocol.ZIGBEE))
if (debugLogging) log.debug "{executed} 0x${device.deviceNetworkId} 0x${device.endpointId} 0xEF00 0x00 {${fullDataOff}}"
}
def componentRefresh(childDevice) {
if (debugLogging) log.debug "component refresh ${childDevice.deviceNetworkId} ${childDevice}"
sendHubCommand(new HubAction("he rattr 0x${device.deviceNetworkId} 0x${device.endpointId} 0xEF00 0x00", Protocol.ZIGBEE))
if (debugLogging) log.debug "{executed} 0x${device.deviceNetworkId} 0x${device.endpointId} 0xEF00 0x00"
}
def setupChildDevices() {
if (debugLogging) log.debug "Parent setupChildDevices"
deleteObsoleteChildren()
def buttons = 0
switch (device.data.manufacturer) {
case '_TZE200_amp6tsvy':
buttons = 1
break
case '_TZE200_g1ib5ldv':
buttons = 2
break
case '_TZE200_tz32mtza':
buttons = 3
break
case '_TZ3000_excgg5kb' :
buttons = 4
break
}
if (infoLogging) log.info "model: ${device.data.manufacturer} buttons: $buttons"
createChildDevices((int)buttons)
}
def createChildDevices(int buttons) {
if (debugLogging) log.debug "Parent createChildDevices"
if (buttons <= 1){
if (debugLogging) log.debug "This device have only: $buttons button, Child devices not needed."
return }
else
for (i in 1..buttons) {
def childId = "${device.id}-0${i}"
def existingChild = getChildDevices()?.find { it.deviceNetworkId == childId}
if (existingChild) {
if (infoLogging) log.info "Child device ${childId} already exists (${existingChild})"
}
else {
if (infoLogging) log.info "Creating device ${childId}"
addChildDevice("hubitat", "GE Zigbee Switch", childId, [isComponent: true, name: "Switch EP0${i}", label: "${device.displayName} EP0${i}"])
}
}
}
def deleteObsoleteChildren() {
if (debugLogging) log.debug "Parent deleteChildren"
getChildDevices().each {child->
if (!child.deviceNetworkId.startsWith(device.id) || child.deviceNetworkId == "${device.id}-00") {
if (infoLogging) log.info "Deleting ${child.deviceNetworkId}"
deleteChildDevice(child.deviceNetworkId)
}
}
}
def switchLightModeConfig(){
def cmds = []
switch(switchLightMode) {
case "OFF":
if (infoLogging) log.info "Backlight - OFF"
zigbee.command(0xEF00, 0x0, "00010f04000100")
break
case "ON":
if (infoLogging) log.info "Backlight - ON"
zigbee.command(0xEF00, 0x0, "00010f04000101")
break
case "Position":
if (infoLogging) log.info "Backlight - position"
zigbee.command(0xEF00, 0x0, "00010f04000102")
break
}
}
def relayModeConfig(){
def cmds = []
switch(relayMode) {
case "OFF":
if (infoLogging) log.info "Relay state - OFF"
zigbee.command(0xEF00, 0x0, "00010e04000100")
break
case "ON":
if (infoLogging) log.info "Relay state - ON"
zigbee.command(0xEF00, 0x0, "00010e04000101")
break
case "Last state":
if (infoLogging) log.info "Relay state - last state"
zigbee.command(0xEF00, 0x0, "00010e04000102")
break
}
}
Thanks for your help