/**
* Zemismart ZigBee Wall Switch Multi-Gang
* Device Driver for Hubitat Elevation hub
*
* Based on Muxa's driver Version 0.2.0, last updated Feb 5, 2020
*
* https://community.hubitat.com/t/zemismart-zigbee-1-2-3-4-gang-light-switches/21124/36?u=kkossev
*
* Ver. 0.0.1 2019-08-21 Muxa - first version
* Ver. 0.1.0 2020-02-05 Muxa - Driver name "Zemismart ZigBee Wall Switch Multi-Gang"
* Ver. 0.2.1 2022-02-26 kkossev - TuyaBlackMagic for TS0003 _TZ3000_vjhcenzo
* Ver. 0.2.2 2022-02-27 kkossev - TS0004 4-button, logEnable, txtEnable, ping(), intercept cluster: E000 attrId: D001 and D002 exceptions;
* Ver. 0.2.3 2022-03-04 kkossev - powerOnState options
* Ver. 0.2.4 2022-04-16 kkossev - _TZ3000_w58g68s3 Yagusmart 3 gang zigbee switch fingerprint
* Ver. 0.2.5 2022-05-28 kkossev - _TYZB01_Lrjzz1UV Zemismart 3 gang zigbee switch fingerprint; added TS0011 TS0012 TS0013 models and fingerprints; more TS002, TS003, TS004 manufacturers
* Ver. 0.2.6 2022-06-03 kkossev - powerOnState and Debug logs improvements; importUrl; singleThreaded
* Ver. 0.2.7 2022-06-06 kkossev - command '0B' (command response) bug fix; added Tuya Zugbee mini switch TMZ02L (_TZ3000_txpirhfq); bug fix for TS0011 single-gang switches.
* Ver. 0.2.8 2022-07-13 kkossev - added _TZ3000_18ejxno0 and _TZ3000_qewo8dlz fingerprints; added TS0001 wall switches fingerprints; added TS011F 2-gang wall outlets; added switchType configuration
* Ver. 0.2.9 2022-09-29 kkossev - added _TZ3000_hhiodade (ZTS-EU_1gang); added TS0001 _TZ3000_oex7egmt; _TZ3000_b9vanmes; _TZ3000_zmy4lslw
* Ver. 0.2.10 2022-10-15 kkossev - _TZ3000_hhiodade fingerprint correction; added _TZ3000_ji4araar
* Ver. 0.2.11 2022-11-07 kkossev - added _TZ3000_tqlv4ug4
* Ver. 0.2.12 2022-11-11 kkossev - added _TZ3000_cfnprab5 (TS011F) Xenon 4-gang + 2 USB extension; _TYZB01_vkwryfdr (TS0115) UseeLink; _TZ3000_udtmrasg (TS0003)
* Ver. 0.2.13 2022-11-12 kkossev - tuyaBlackMagic() for Xenon similar to Tuya Metering Plug; _TZ3000_cfnprab5 fingerprint correction; added SiHAS and NodOn switches
* Ver. 0.2.14 2022-11-23 kkossev - added 'ledMOode' command; fingerprints critical bug fix.
* Ver. 0.2.15 2022-11-23 kkossev - added added _TZ3000_zmy1waw6
* Ver. 0.3.0 2023-01-07 kkossev - noBindingButPolling() for _TZ3000_fvh3pjaz _TZ3000_9hpxg80k _TZ3000_wyhuocal
* Ver. 0.3.1 2023-01-22 kkossev - restored TS0003 _TZ3000_vjhcenzo fingerprint; added _TZ3000_iwhuhzdo
* Ver. 0.4.0 2023-01-22 kkossev - parsing multiple attributes;
* Ver. 0.4.1 2023-02-10 kkossev - IntelliJ lint; added _TZ3000_18ejxno0 third fingerprint;
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
* for the specific language governing permissions and limitations under the License.
*/
import hubitat.device.HubAction
import hubitat.device.Protocol
import groovy.transform.Field
def version() { "0.4.1" }
def timeStamp() { "2023/02/10 10:43 PM" }
@Field static final Boolean debug = false
metadata {
definition(name: "Zemismart ZigBee Wall Switch Multi-Gang", namespace: "muxa", author: "Muxa", importUrl: "https://raw.githubusercontent.com/kkossev/hubitat-muxa-fork/development/drivers/zemismart-zigbee-multigang-switch.groovy", singleThreaded: true) {
capability "Initialize"
capability "Actuator"
capability "Configuration"
capability "Refresh"
capability "Switch"
capability "Health Check"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0001", manufacturer: "_TZ3000_npzfdcof", deviceJoinName: "Tuya Zigbee Switch" // https://www.aliexpress.com/item/1005002852788275.html
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0001", manufacturer: "_TZ3000_hktqahrq", deviceJoinName: "Tuya Zigbee Switch"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0001", manufacturer: "_TZ3000_mx3vgyea", deviceJoinName: "Tuya Zigbee Switch"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0001", manufacturer: "_TZ3000_5ng23zjs", deviceJoinName: "Tuya Zigbee Switch"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0001", manufacturer: "_TZ3000_rmjr4ufz", deviceJoinName: "Tuya Zigbee Switch"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0001", manufacturer: "_TZ3000_v7gnj3ad", deviceJoinName: "Tuya Zigbee Switch"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0001", manufacturer: "_TZ3000_mx3vgyea", deviceJoinName: "Tuya Zigbee Switch"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0001", manufacturer: "_TZ3000_qsp2pwtf", deviceJoinName: "Tuya Zigbee Switch"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS000F", manufacturer: "_TZ3000_m9af2l6g", deviceJoinName: "Tuya Zigbee Switch"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0001", manufacturer: "_TZ3000_oex7egmt", deviceJoinName: "Tuya 1 gang Zigbee switch MYQ-KLS01L" //https://expo.tuya.com/product/601097
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0001", manufacturer: "_TZ3000_tqlv4ug4", deviceJoinName: "GIRIER Tuya ZigBee 3.0 Light Switch Module" //https://community.hubitat.com/t/girier-tuya-zigbee-3-0-light-switch-module-smart-diy-breaker-1-2-3-4-gang-supports-2-way-control/104546
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006", outClusters: "0019", model: "TS0002", manufacturer: "Zemismart", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,000A,0004,0005,0006", outClusters: "0019", model: "TS0002", manufacturer: "_TZ3000_tas0zemd", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,000A,0004,0005,0006", outClusters: "0019", model: "TS0002", manufacturer: "_TYZB01_tas0zemd", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,000A,0004,0005,0006", outClusters: "0019", model: "TS0002", manufacturer: "_TZ3000_7hp93xpr", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0004,0005,0006", outClusters: "0019", model: "TS0002", manufacturer: "_TZ3000_7hp93xpr", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0004,0005,0006", outClusters: "0019,000A", model: "TS0002", manufacturer: "_TZ3000_vjhyd6ar", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006", outClusters: "0019", model: "TS0002", manufacturer: "_TZ3000_tonrapsk", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006", outClusters: "0019", model: "TS0002", manufacturer: "_TZ3000_bvrlqyj7", deviceJoinName: "Avatto Zigbee Switch Multi-Gang" // check!
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006", outClusters: "0019", model: "TS0002", manufacturer: "_TZ3000_atp7xmd9", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang" // check!
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006", outClusters: "0019", model: "TS0002", manufacturer: "_TZ3000_h34ihclt", deviceJoinName: "Tuya Zigbee Switch Multi-Gang" // check!
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006", outClusters: "0019", model: "TS0002", manufacturer: "_TYZB01_wmak4qjy", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang" // check!
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006,E000,E001", outClusters: "0019,000A", model: "TS0002", manufacturer: "_TZ3000_qn8qvk9y", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0002", manufacturer: "_TZ3000_b9vanmes", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0002", manufacturer: "_TZ3000_tqlv4ug4", deviceJoinName: "GIRIER Tuya ZigBee 3.0 Light Switch Module"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,0702,0B04,E000,E001,0000", outClusters: "0019,000A", model: "TS0002", manufacturer: "_TZ3000_zmy4lslw", deviceJoinName: "Tuya Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,000A,0004,0005,0006", outClusters: "0019", model: "TS0003", manufacturer: "_TYZB01_pdevogdj", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,000A,0004,0005,0006", outClusters: "0019", model: "TS0003", manufacturer: "_TZ3000_pdevogdj", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006", outClusters: "0019", model: "TS0003", manufacturer: "_TZ3000_odzoiovu", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006", outClusters: "0019", model: "TS0003", manufacturer: "_TZ3000_vsasbzkf", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006", outClusters: "0019", model: "TS0003", manufacturer: "_TZ3000_34zbimxh", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006", outClusters: "0019", model: "TS0003", manufacturer: "_TZ3000_odzoiovu", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0004,0005,0006", outClusters: "0019", model: "TS0003", manufacturer: "_TZ3000_wqfdvxen", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0004,0005,0006", outClusters: "0019", model: "TS0003", manufacturer: "_TZ3000_c0wbnbbf", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0004,0005,0006", outClusters: "0019", model: "TS0003", manufacturer: "_TZ3000_c0wbnbbf", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001", outClusters: "0019,000A", model: "TS0003", manufacturer: "_TZ3000_tbfw3xj0", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0003", manufacturer: "_TZ3000_tqlv4ug4", deviceJoinName: "GIRIER Tuya ZigBee 3.0 Light Switch Module"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0003", manufacturer: "_TZ3000_vjhcenzo", deviceJoinName: "Tuya 3-gang Switch"
fingerprint profileId: "0104", endpointId: "01", inClusters: "2101,0000", outClusters: "0021", model: "TS0003", manufacturer: "_TZ3000_udtmrasg", deviceJoinName: "Tuya 3-gang Switch"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0003", manufacturer: "_TZ3000_iwhuhzdo", deviceJoinName: "Zemismart ZL-LU03"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006", outClusters: "0019", model: "TS0004", manufacturer: "_TZ3000_ltt60asa", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang" // check!
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006", outClusters: "0019", model: "TS0004", manufacturer: "_TZ3000_excgg5kb", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang" // check!
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006", outClusters: "0019", model: "TS0004", manufacturer: "_TZ3000_a37eix1s", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang" // check!
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,000A,0004,0005,0006", outClusters: "0019", model: "TS0004", manufacturer: "_TZ3000_go9rahj5", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001", outClusters: "0019", model: "TS0004", manufacturer: "_TZ3000_aqgofyol", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0004", manufacturer: "_TZ3000_excgg5kb" // 4-relays module
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0004", manufacturer: "_TZ3000_w58g68s3" // Yagusmart 3 gang zigbee switch
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0004", manufacturer: "_TZ3000_tqlv4ug4", deviceJoinName: "GIRIER Tuya ZigBee 3.0 Light Switch Module"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006", outClusters: "0019", model: "TS0011", manufacturer: "_TZ3000_ybaprszv", deviceJoinName: "Zemismart Zigbee Switch No Neutral"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0011", manufacturer: "_TZ3000_txpirhfq", deviceJoinName: "Tuya Zigbee Mini Switch TMZ02L"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0011", manufacturer: "_TZ3000_hhiodade", deviceJoinName: "Moes ZTS-EU_1gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,0000", outClusters: "0019,000A", model: "TS0011", manufacturer: "_TZ3000_hhiodade", deviceJoinName: "Moes ZTS-EU_1gang" // https://community.hubitat.com/t/uk-moes-zigbee-1-2-3-or-4-gang-light-switch/89747/5?u=kkossev
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0011", manufacturer: "_TZ3000_ji4araar", deviceJoinName: "Tuya 1 gang switch"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,0000", outClusters: "0019,000A", model: "TS0011", manufacturer: "_TZ3000_9hpxg80k", deviceJoinName: "Tuya 1 gang" // https://github.com/zigpy/zha-device-handlers/issues/535
fingerprint profileId: "0104", endpointId: "01", inClusters: "0001,0007,0000,0003,0004,0005,0006,E000,E001,0002", outClusters: "0019,000A", model: "TS0012", manufacturer: "_TZ3000_k008kbls", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang" // check!
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006", outClusters: "0019", model: "TS0012", manufacturer: "_TZ3000_uz5xzdgy", deviceJoinName: "Zemismart Zigbee Switch No Neutral"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0004,0005,0006", outClusters: "0019,000A", model: "TS0012", manufacturer: "_TZ3000_fvh3pjaz", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0004,0005,0006,EF00", outClusters: "0019,000A", model: "TS0012", manufacturer: "_TZ3000_lupfd8zu", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001", outClusters: "0019,000A", model: "TS0012", manufacturer: "_TZ3000_jl7qyupf", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,0000", outClusters: "0019,000A", model: "TS0012", manufacturer: "_TZ3000_18ejxno0", deviceJoinName: "Tuya Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006,E000,E001", outClusters: "0019,000A", model: "TS0012", manufacturer: "_TZ3000_18ejxno0", deviceJoinName: "Tuya Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,E000,E001,0000", outClusters: "0019,000A", model: "TS0012", manufacturer: "_TZ3000_18ejxno0", deviceJoinName: "Tuya Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0006", outClusters: "0019", model: "TS0013", manufacturer: "_TYZB01_Lrjzz1UV", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang" // check!
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0006", outClusters: "0019", model: "TS0013", manufacturer: "_TZ3000_bvrlqyj7", deviceJoinName: "Avatto Zigbee Switch Multi-Gang" // check!
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0006", outClusters: "0019", model: "TS0013", manufacturer: "_TZ3000_wu0shw0i", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang" // check!
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0006", outClusters: "0019", model: "TS0013", manufacturer: "_TYZB01_stv9a4gy", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang" // check!
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0004,0005,0006", outClusters: "0019,000A", model: "TS0013", manufacturer: "_TZ3000_wyhuocal", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0004,0005,0006", outClusters: "0019", model: "TS0013", manufacturer: "_TYZB01_mqel1whf", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0006", outClusters: "0019", model: "TS0013", manufacturer: "_TZ3000_fvh3pjaz", deviceJoinName: "Zemismart Zigbee Switch Multi-Gang" // check!
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0006", outClusters: "0019", model: "TS0013", manufacturer: "_TYZB01_mtlhqn48", deviceJoinName: "Lonsonho Zigbee Switch Multi-Gang" // check!
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0006", outClusters: "0019", model: "TS0013", manufacturer: "TUYATEC-O6SNCwd6", deviceJoinName: "TUYATEC Zigbee Switch Multi-Gang" // check!
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0006", outClusters: "0019", model: "TS0013", manufacturer: "_TZ3000_h34ihclt", deviceJoinName: "Tuya Zigbee Switch Multi-Gang" // check!
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006", outClusters: "0019", model: "TS0013", manufacturer: "_TZ3000_k44bsygw", deviceJoinName: "Zemismart Zigbee Switch No Neutral"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0003,0004,0005,0006,0000", outClusters: "0019,000A", model: "TS0013", manufacturer: "_TZ3000_qewo8dlz", deviceJoinName: "Tuya Zigbee Switch 3 Gang No Neutral" // @dingyang.yee https://www.aliexpress.com/item/4000298926256.html https://github.com/Koenkk/zigbee2mqtt/issues/6138#issuecomment-774720939
/* these do NOT work with Hubitat !
fingerprint profileId:"0104", endpointId:"01", inClusters:"0003,0004,0005,0006,E000,E001,0000", outClusters:"0019,000A", model:"TS011F", manufacturer:"_TZ3000_cfnprab5", deviceJoinName: "Xenon 4-gang + 2 USB extension" //https://community.hubitat.com/t/xenon-4-gang-2-usb-extension-unable-to-switch-off-individual-sockets/101384/14?u=kkossev
fingerprint profileId:"0104", endpointId:"01", inClusters:"0000,0006,0003,0004,0005,E001", outClusters:"0019,000A", model:"TS011F", manufacturer:"_TZ3000_cfnprab5", deviceJoinName: "Xenon 4-gang + 2 USB extension" //https://community.hubitat.com/t/xenon-4-gang-2-usb-extension-unable-to-switch-off-individual-sockets/101384/14?u=kkossev
*/
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0004,0005,0006", outClusters: "0019,000A", model: "TS011F", manufacturer: "_TZ3000_zmy1waw6", deviceJoinName: "Moes 1 gang" // https://github.com/zigpy/zha-device-handlers/issues/1262
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,000A,0004,0005,0006", outClusters: "0019", model: "TS0115", manufacturer: "_TYZB01_vkwryfdr", deviceJoinName: "UseeLink Power Strip" //https://community.hubitat.com/t/another-brick-in-the-wall-tuya-joins-the-zigbee-alliance/44152/28?u=kkossev
// SiHAS Switch (2~6 Gang)
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0006,0019", outClusters: "0003,0004,0019", manufacturer: "ShinaSystem", model: "SBM300Z2", deviceJoinName: "SiHAS Switch 2-gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0006,0019", outClusters: "0003,0004,0019", manufacturer: "ShinaSystem", model: "SBM300Z3", deviceJoinName: "SiHAS Switch 3-gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0006,0019", outClusters: "0003,0004,0019", manufacturer: "ShinaSystem", model: "SBM300Z4", deviceJoinName: "SiHAS Switch 4-gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0006,0019", outClusters: "0003,0004,0019", manufacturer: "ShinaSystem", model: "SBM300Z5", deviceJoinName: "SiHAS Switch 5-gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0006,0019", outClusters: "0003,0004,0019", manufacturer: "ShinaSystem", model: "SBM300Z6", deviceJoinName: "SiHAS Switch 6-gang"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0006,0019", outClusters: "0003,0004,0019", manufacturer: "ShinaSystem", model: "ISM300Z3", deviceJoinName: "SiHAS Switch 3-gang"
// NodOn
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006,0007,0008,1000,FC57", outClusters: "0003,0006,0019", manufacturer: "NodOn", model: "SIN-4-2-20", deviceJoinName: "NodOn Light 2 channels"
// https://nodon.pro/en/produits/zigbee-pro-on-off-lighting-relay-switch/
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0003,0004,0005,0006,0007,0008,1000,FC57", outClusters: "0003,0006,0019", manufacturer: "NodOn", model: "SIN-4-2-20_PRO", deviceJoinName: "NodOn Light 2 channels"
command "powerOnState", [
[name: "powerOnState", type: "ENUM", constraints: ["--- Select ---", "OFF", "ON", "Last state"], description: "Select Power On State"]
]
command "switchType", [
[name: "switchType", type: "ENUM", constraints: ["--- Select ---", "toggle", "state", "momentary"], description: "Select Switch Type"] // 0: 'toggle', 1: 'state', 2: 'momentary'
]
command "ledMode", [
[name: "ledMode", type: "ENUM", constraints: ["--- Select ---", "Disabled", "Lit when On", "Lit when Off"], description: "Select LED Mode"]
]
if (debug == true) {
command "test", ["string"]
}
attribute "lastCheckin", "string"
}
preferences {
input(name: "logEnable", type: "bool", title: "Enable debug logging", defaultValue: true)
input(name: "txtEnable", type: "bool", title: "Enable description text logging", defaultValue: true)
input(title: "IMPORTANT", description: "In order to operate normally, please pair the device to HE after changing to this driver!", type: "paragraph", element: "paragraph")
}
}
private boolean isHEProblematic() {
device.getDataValue("manufacturer") in ["_TZ3000_okaz9tjs", "_TZ3000_r6buo8ba", "_TZ3000_cfnprab5", "SONOFF", "Woolley", "unknown"]
}
private boolean noBindingButPolling() {
device.getDataValue("manufacturer") in ['_TZ3000_fvh3pjaz', '_TZ3000_9hpxg80k', '_TZ3000_wyhuocal']
} //0x4001 OnTime: value 0 //0x4002 OffWaitTime: value 0
// Parse incoming device messages to generate events
def parse(String description) {
checkDriverVersion()
//log.debug "${device.displayName} Parsing '${description}'"
def descMap = [:]
try {
descMap = zigbee.parseDescriptionAsMap(description)
}
catch (e) {
if (settings?.logEnable) log.warn "${device.displayName} exception caught while parsing description ${description} \r descMap: ${descMap}"
return null
}
logDebug "Parsed descMap: ${descMap} (description:${description})"
Map map = null // [:]
if (descMap.attrId != null) {
//log.trace "parsing descMap.attrId ${descMap.attrId}"
parseAttributes(descMap)
return
}
/*
else if (descMap.cluster == "0006" && descMap.attrId == "0000") {
processOnOff( descMap )
} // OnOff cluster, attrId "0000"
else if (descMap.cluster == "0006" && descMap.attrId != "0000") { // other attr
processOnOfClusterOtherAttr( descMap )
}
else if (descMap.cluster == "E001") { // Tuya Switch Mode cluster
processOnOfClusterOtherAttr( descMap )
}
*/
else if (descMap?.clusterId == "0013" && descMap?.profileId != null && descMap?.profileId == "0000") {
logInfo "device model ${device.data.model}, manufacturer ${device.data.manufacturer} re-joined the network (deviceNetworkId ${device.properties.deviceNetworkId}, zigbeeId ${device.properties.zigbeeId})"
} else {
logDebug "${device.displayName} unprocessed EP: ${descMap.sourceEndpoint} cluster: ${descMap.clusterId} attrId: ${descMap.attrId}"
}
}
def parseAttributes(Map descMap) {
// attribute report received
List attrData = [[cluster: descMap.cluster, attrId: descMap.attrId, value: descMap.value, status: descMap.status]]
descMap.additionalAttrs.each {
attrData << [cluster: descMap.cluster, attrId: it.attrId, value: it.value, status: it.status]
}
//log.trace "attrData 2 = ${attrData} "
attrData.each {
parseSingleAttribute(it, descMap)
} // for each attribute
}
private void parseSingleAttribute(Map it, Map descMap) {
//log.trace "parseSingleAttribute :${it}"
if (it.status == "86") {
log.warn "${device.displayName} Read attribute response: unsupported Attributte ${it.attrId} cluster ${descMap.cluster}"
return
}
switch (it.cluster) {
case "0000":
parseBasicClusterAttribute(it)
break
case "0006":
//log.warn "case cluster 0006"
switch (it.attrId) {
case "0000":
//log.warn "case cluster 0006 attrId 0000"
processOnOff(it, descMap)
break
default:
//log.warn "case cluster 0006 attrId ${it.attrId}"
processOnOfClusterOtherAttr(it)
break
}
break
case "0008":
if (logEnable) log.warn "${device.displayName} may be a dimmer? This is not the right driver...cluster:${cluster} attrId ${it.attrId} value:${it.value}"
break
case "0300":
if (logEnable) log.warn "${device.displayName} may be a bulb? This is not the right driver...cluster:${cluster} attrId ${it.attrId} value:${it.value}"
break
case "0702":
case "0B04":
if (logEnable) log.warn "${device.displayName} may be a power monitoring socket? This is not the right driver...cluster:${cluster} attrId ${it.attrId} value:${it.value}"
break
case "E000":
case "E001":
processOnOfClusterOtherAttr(it)
break
case "EF00": // Tuya cluster
log.warn "${device.displayName} NOT PROCESSED Tuya Cluster EF00 attribute ${it.attrId}\n descMap = ${descMap}"
break
case "FFFD": // TuyaClusterRevision
if (logEnable) log.warn "${device.displayName} Tuya Cluster Revision cluster:${cluster} attrId ${it.attrId} value:${it.value}"
break
case "FFFE": // AttributeReportingStatus
if (logEnable) log.warn "${device.displayName} Tuya Attribute Reporting Status cluster:${cluster} attrId ${it.attrId} value:${it.value}"
break
default:
if (logEnable) {
String respType = (command == "0A") ? "reportResponse" : "readAttributeResponse"
log.warn "${device.displayName} parseAttributes: NOT PROCESSED: cluster ${descMap.cluster} attribite:${it.attrId}, value:${it.value}, encoding:${it.encoding}, respType:${respType}"
}
break
} // it.cluster
}
def parseBasicClusterAttribute(Map it) {
// https://github.com/zigbeefordomoticz/Domoticz-Zigbee/blob/6df64ab4656b65ec1a450bd063f71a350c18c92e/Modules/readClusters.py
switch (it.attrId) {
case "0000":
logDebug "ZLC version: ${it.value}" // default 0x03
break
case "0001":
logDebug "Applicaiton version: ${it.value}" // For example, 0b 01 00 0001 = 1.0.1, where 0x41 is 1.0.1
break // https://developer.tuya.com/en/docs/iot-device-dev/tuya-zigbee-lighting-dimmer-swith-access-standard?id=K9ik6zvlvbqyw
case "0002":
logDebug "Stack version: ${it.value}" // default 0x02
break
case "0003":
logDebug "HW version: ${it.value}" // default 0x01
break
case "0004":
logDebug "Manufacturer name: ${it.value}"
break
case "0005":
logDebug "Model Identifier: ${it.value}"
break
case "0007":
logDebug "Power Source: ${it.value}" // enum8-0x30 default 0x03
break
case "4000": //software build
logDebug "softwareBuild: ${it.value}"
//updateDataValue("$LAB softwareBuild",it.value ?: "unknown")
break
case "FFE2":
case "FFE4":
logDebug "Attribite ${it.attrId} : ${it.value}"
break
case "FFFD": // Cluster Revision (Tuya specific)
logDebug "Cluster Revision 0xFFFD: ${it.value}" //uint16 -0x21 default 0x0001
break
case "FFFE": // Tuya specific
logDebug "Tuya specific 0xFFFE: ${it.value}"
break
default:
if (logEnable) log.warn "${device.displayName} parseBasicClusterAttribute cluster:${cluster} UNKNOWN attrId ${it.attrId} value:${it.value}"
}
}
def processOnOff(it, descMap) {
// descMap.command =="0A" - switch toggled physically
// descMap.command =="01" - get switch status
// descMap.command =="0B" - command response
def cd = getChildDevice("${device.id}-${descMap.endpoint}")
if (cd == null) {
if (!(device.data.model in ['TS0011', 'TS0001'])) {
log.warn "${device.displayName} Child device ${device.id}-${descMap.endpoint} not found. Initialise parent device first"
return
}
}
def switchAttribute = descMap.value == "01" ? "on" : "off"
if (cd != null) {
if (descMap.command in ["0A", "0B"]) {
// switch toggled
cd.parse([[name: "switch", value: switchAttribute, descriptionText: "Child switch ${descMap.endpoint} turned $switchAttribute"]])
} else if (descMap.command == "01") {
// report switch status
cd.parse([[name: "switch", value: switchAttribute, descriptionText: "Child switch ${descMap.endpoint} is $switchAttribute"]])
}
}
if (switchAttribute == "on") {
logDebug "Parent switch on"
sendEvent(name: "switch", value: "on")
return
} else if (switchAttribute == "off") {
def cdsOn = 0
// cound number of switches on
getChildDevices().each { child ->
if (getChildId(child) != descMap.endpoint && child.currentValue('switch') == "on") {
cdsOn++
}
}
if (cdsOn == 0) {
logDebug "Parent switch off"
sendEvent(name: "switch", value: "off")
return
}
}
}
def off() {
if (settings?.txtEnable) log.info "${device.displayName} Turning all child switches off"
"he cmd 0x${device.deviceNetworkId} 0xFF 0x0006 0x0 {}"
}
def on() {
if (settings?.txtEnable) log.info "${device.displayName} Turning all child switches on"
"he cmd 0x${device.deviceNetworkId} 0xFF 0x0006 0x1 {}"
}
def refresh() {
logDebug "refreshing"
"he rattr 0x${device.deviceNetworkId} 0xFF 0x0006 0x0"
}
def ping() {
refresh()
}
private Integer convertHexToInt(hex) {
Integer.parseInt(hex, 16)
}
private String getChildId(childDevice) {
return childDevice.deviceNetworkId.substring(childDevice.deviceNetworkId.length() - 2)
}
def componentOn(childDevice) {
logDebug "sending componentOn ${childDevice.deviceNetworkId}"
sendHubCommand(new HubAction("he cmd 0x${device.deviceNetworkId} 0x${getChildId(childDevice)} 0x0006 0x1 {}", Protocol.ZIGBEE))
}
def componentOff(childDevice) {
logDebug "sending componentOff ${childDevice.deviceNetworkId}"
sendHubCommand(new HubAction("he cmd 0x${device.deviceNetworkId} 0x${getChildId(childDevice)} 0x0006 0x0 {}", Protocol.ZIGBEE))
}
def componentRefresh(childDevice) {
logDebug "sending componentRefresh ${childDevice.deviceNetworkId} ${childDevice}"
sendHubCommand(new HubAction("he rattr 0x${device.deviceNetworkId} 0x${getChildId(childDevice)} 0x0006 0x0", Protocol.ZIGBEE))
}
def setupChildDevices() {
logDebug "Parent setupChildDevices"
deleteObsoleteChildren()
def buttons = 0
switch (device.data.model) {
case 'SBM300Z6':
buttons = 6
break
case 'TS011F':
if (device.data.manufacturer == '_TZ3000_zmy1waw6') {
buttons = 1
break
} else {
// continue below
}
case 'TS0115':
case 'SBM300Z5':
buttons = 5
break
case 'TS0004':
case 'TS0014':
case 'SBM300Z4':
buttons = 4
break
case 'TS0003':
case 'TS0013':
case 'SBM300Z3':
case 'ISM300Z3':
buttons = 3
break
case 'TS0002':
case 'TS0012':
case 'SBM300Z2':
case 'SIN-4-2-20':
case 'SIN-4-2-20_PRO':
buttons = 2
break
case 'TS0011':
case 'TS0001':
buttons = 0
break
default:
break
}
logDebug "model: ${device.data.model} buttons: $buttons"
createChildDevices((int) buttons)
}
def createChildDevices(int buttons) {
logDebug "Parent createChildDevices"
if (buttons == 0)
return
for (i in 1..buttons) {
def childId = "${device.id}-0${i}"
def existingChild = getChildDevices()?.find { it.deviceNetworkId == childId }
if (existingChild) {
log.info "${device.displayName} Child device ${childId} already exists (${existingChild})"
} else {
log.info "${device.displayName} Creatung device ${childId}"
addChildDevice("hubitat", "Generic Component Switch", childId, [isComponent: true, name: "Switch EP0${i}", label: "${device.displayName} EP0${i}"])
}
}
}
def deleteObsoleteChildren() {
logDebug "Parent deleteChildren"
getChildDevices().each { child ->
if (!child.deviceNetworkId.startsWith(device.id) || child.deviceNetworkId == "${device.id}-00") {
log.info "${device.displayName} Deleting ${child.deviceNetworkId}"
deleteChildDevice(child.deviceNetworkId)
}
}
}
def driverVersionAndTimeStamp() { version() + ' ' + timeStamp() }
def checkDriverVersion() {
if (state.driverVersion == null || (driverVersionAndTimeStamp() != state.driverVersion)) {
if (txtEnable == true) log.debug "${device.displayName} updating the settings from the current driver ${device.properties.typeName} version ${state.driverVersion} to the new version ${driverVersionAndTimeStamp()} [model ${device.data.model}, manufacturer ${device.data.manufacturer}, application ${device.data.application}, endpointId ${device.endpointId}]"
initializeVars(fullInit = false)
state.driverVersion = driverVersionAndTimeStamp()
}
}
void initializeVars(boolean fullInit = true) {
if (settings?.txtEnable) log.info "${device.displayName} InitializeVars()... fullInit = ${fullInit}"
if (fullInit == true) {
state.clear()
state.driverVersion = driverVersionAndTimeStamp()
}
if (settings?.logEnable == null) device.updateSetting("logEnable", true)
if (settings?.txtEnable == null) device.updateSetting("txtEnable", true)
}
def initialize() {
logDebug "Initializing..."
initializeVars(fullInit = true)
configure() // added 11/12/2022
setupChildDevices()
}
def installed() {
logInfo "Parent installed, typeName ${device.properties.typeName}, version ${driverVersionAndTimeStamp()}, deviceNetworkId ${device.properties.deviceNetworkId}, zigbeeId ${device.properties.zigbeeId}"
logInfo "model ${device.data.model}, manufacturer ${device.data.manufacturer}, application ${device.data.application}, endpointId ${device.endpointId}"
}
def updated() {
logDebug "Parent updated"
}
def tuyaBlackMagic() {
List cmds = []
cmds += zigbee.readAttribute(0x0000, [0x0004, 0x0000, 0x0001, 0x0005, 0x0007, 0xfffe], [:], delay = 200)
cmds += zigbee.writeAttribute(0x0000, 0xffde, 0x20, 0x0d, [destEndpoint: 0x01], delay = 50)
return cmds
}
def configure() {
logDebug " configure().."
List cmds = []
if (device.data.manufacturer in ["_TZ3000_cfnprab5", "_TZ3000_okaz9tjs"]) {
log.warn "this device ${device.data.manufacturer} is known to NOT work with HE!"
}
cmds += tuyaBlackMagic()
if (noBindingButPolling()) {
//these will send out device anounce message at ervery 2 mins as heart beat, setting 0x0099 to 1 will disable it.
cmds += zigbee.writeAttribute(zigbee.BASIC_CLUSTER, 0x0099, 0x20, 0x01, [mfgCode: 0x0000])
// Hack : Need to disable reporting for thoses devices, else It will enable a auto power off after 2mn. // see https://github.com/dresden-elektronik/deconz-rest-plugin/issues/3693
// https://github.com/Mariano-Github/Edge-Drivers-Beta/blob/652bcfbcf7b8ab8a14557e097b740216760f2b02/zigbee-multi-switch-v4-childs/src/init.lua
log.warn "disabling ${device.data.manufacturer} device announce message every 2 mins and skipping reporting configuiration!"
cmds += zigbee.onOffRefresh()
} else {
//cmds += refresh()
cmds += zigbee.onOffConfig()
cmds += zigbee.onOffRefresh()
}
sendZigbeeCommands(cmds)
}
void sendZigbeeCommands(List cmds) {
logDebug "sendZigbeeCommands : ${cmds}"
sendHubCommand(new hubitat.device.HubMultiAction(cmds, hubitat.device.Protocol.ZIGBEE))
}
def logDebug(msg) {
String sDnMsg = device?.displayName + " " + msg
if (settings?.logEnable) log.debug sDnMsg
}
def logInfo(msg) {
String sDnMsg = device?.displayName + " " + msg
if (settings?.txtEnable) log.info sDnMsg
}
def powerOnState(relayMode) {
List cmds = []
int modeEnum = 99
switch (relayMode) {
case "OFF":
modeEnum = 0
break
case "ON":
modeEnum = 1
break
case "Last state":
modeEnum = 2
break
default:
log.error "${device.displayName} please select a Power On State option"
return
}
logDebug("setting Power On State option to: ${relayMode} (${modeEnum}")
cmds += zigbee.writeAttribute(0x0006, 0x8002, DataType.ENUM8, modeEnum)
sendZigbeeCommands(cmds)
}
def switchType(type) {
List cmds = []
int modeEnum = 99
switch (type) {
case "toggle":
modeEnum = 0
break
case "state":
modeEnum = 1
break
case "momentary":
modeEnum = 2
break
default:
log.error "${device.displayName} please select a Switch Type"
return
}
logDebug("setting Switch Type to: ${type} (${modeEnum})")
cmds += zigbee.writeAttribute(0xE001, 0xD030, DataType.ENUM8, modeEnum)
sendZigbeeCommands(cmds)
}
// mode = value == 0 ? "Disabled" : value == 1 ? "Lit when On" : value == 2 ? "Lit when Off" : null
// [name:"ledMode", type: "ENUM", constraints: ["--- Select ---", "Disabled", "Lit when On", "Lit when Off], description: "Select LED Mode"]
def ledMode(mode) {
List cmds = []
int modeEnum = 99
switch (mode) {
case "Disabled":
modeEnum = 0
break
case "Lit when On":
modeEnum = 1
break
case "Lit when Off":
modeEnum = 2
break
default:
log.error "${device.displayName} please select a LED mode option"
return
}
logDebug("setting LED mode option to: ${mode} (${modeEnum})")
cmds += zigbee.writeAttribute(0x0006, 0x8001, DataType.ENUM8, modeEnum)
sendZigbeeCommands(cmds)
}
def processOnOfClusterOtherAttr(Map it) {
//logDebug "processOnOfClusterOtherAttr attribute ${it.attrId} value=${it.value}"
def mode
def attrName
def value
try {
value = it.value as int
}
catch (e) {
value = it.value
}
def clusterPlusAttr = it.cluster + "_" + it.attrId
//log.trace "clusterPlusAttr = ${clusterPlusAttr}"
switch (clusterPlusAttr) {
case "0006_4001":
case "0006_4002":
attrName = "attribute " + clusterPlusAttr
mode = value.toString()
break
case "0006_8000":
attrName = "Child Lock"
mode = value == 0 ? "off" : "on"
break
case "0006_8001":
attrName = "LED mode"
mode = value == 0 ? "Disabled" : value == 1 ? "Lit when On" : value == 2 ? "Lit when Off" : null
break
case "0006_8002":
attrName = "Power On State"
mode = value == 0 ? "off" : value == 1 ? "on" : value == 2 ? "Last state" : null
break
case "E000_D001":
case "E000_D002":
case "E000_D003":
attrName = "attribute " + clusterPlusAttr
mode = value.toString()
break
case "E001_D030":
attrName = "Switch Type"
mode = value == 0 ? "toggle" : value == 1 ? "state" : value == 2 ? "momentary state" : null
break
default:
logDebug "processOnOfClusterOtherAttr: UNPROCESSED On/Off Cluster attrId: ${it.attrId} value: ${it.value}"
return
}
if (txtEnable) log.info "${device.displayName} ${attrName} is: ${mode} (${value})"
}
def test(description) {
log.warn "testing ${description}"
parse(description)
}