I have a scene device exactly like yours, from Zemismart. I use the driver below, it works perfectly. It was adapted to HE by a friend, I hope it may help!
/**
- Copyright 2019 G.Brown (MorkOz) - Adaptado para 4 botões (dispositivo Lonsonho) por Joao M Ferreira
- 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.
- Adapted and modified from code written by at9, motley74, sticks18 and AnotherUser
- Original sources:
- https://github.com/at-9/hubitat/blob/master/Drivers/at-9-Zemismart-3-Gang-Sticker-Switch
- SmartThingsPublic/osram-lightify-dimming-switch.groovy at master · motley74/SmartThingsPublic · GitHub
- SmartThingsPublic-1/osram-lightify-4x-switch.groovy at master · AnotherUser17/SmartThingsPublic-1 · GitHub
- Version Author Note
- 0.1 G.Brown (MorkOz) Initial release
*/
import hubitat.zigbee.zcl.DataType
metadata {
definition (name: "Zemismart Zigbee Button Remote", namespace: "gbrown", author: "G.Brown") {
capability "Actuator"
capability "PushableButton"
capability "HoldableButton"
capability "DoubleTapableButton"
capability "Configuration"
capability "Refresh"
capability "Sensor"
capability "Battery"
fingerprint inClusters: "0000,0001,0006", outClusters: "0019", manufacturer: "_TYZB02_key8kk7r", model: "TS0041"
fingerprint inClusters: "0000,0001,0006", outClusters: "0019", manufacturer: "_TYZB02_key8kk7r", model: "TS0042"
fingerprint inClusters: "0000,0001,0006", outClusters: "0019", manufacturer: "_TYZB02_key8kk7r", model: "TS0043"
fingerprint inClusters: "0000,000A,0001,0006", outClusters: "0019", manufacturer: "_TZ3000_vp6clf9d", model: "TS0044"
attribute "batteryLastReplaced", "String"
command "resetBatteryReplacedDate"
}
preferences {
input name: "debugEnable", type: "bool", title: "Enable debug logging", defaultValue: false
//Battery Voltage Range
input name: "voltsmin", title: "Min Volts (0% battery = ___ volts, range 2.0 to 2.7). Default = 2.5 Volts", description: "", type: "decimal", range: "2..2.7"
input name: "voltsmax", title: "Max Volts (100% battery = ___ volts, range 2.8 to 3.4). Default = 3.0 Volts", description: "", type: "decimal", range: "2.8..3.4"
}
}
private sendButtonNumber() {
def remoteModel = device.getDataValue("model")
switch(remoteModel){
case "TS0041":
sendEvent(name: "numberOfButtons", value: 1, isStateChange: true)
break
case "TS0042":
sendEvent(name: "numberOfButtons", value: 2, isStateChange: true)
break
case "TS0043":
sendEvent(name: "numberOfButtons", value: 3, isStateChange: true)
break
case "TS0044":
sendEvent(name: "numberOfButtons", value: 4, isStateChange: true)
break
}
}
def installed() {
sendButtonNumber
state.start = now()
}
def updated() {
sendButtonNumber
}
def refresh() {
// read battery level attributes
return zigbee.readAttribute(0x0001, 0x0020) + zigbee.configureReporting(0x0001, 0x0020, 0x20, 3600, 21600, 0x01)
// this device doesn't support 0021
zigbee.readAttribute(0x0001, 0x0021)
}
def configure() {
sendButtonNumber
def configCmds = []
for (int endpoint=1; endpoint<=3; endpoint++) {
def list = ["0006", "0001", "0000"]
// the config to the switch
for (cluster in list) {
configCmds.add("zdo bind 0x${device.deviceNetworkId} 0x0${endpoint} 0x01 0x${cluster} {${device.zigbeeId}} {}")
}
}
return configCmds
}
def parse(String description) {
Map map = [:]
if ((description?.startsWith("catchall:")) || (description?.startsWith("read attr -"))) {
def parsedMap = zigbee.parseDescriptionAsMap(description)
if (debugEnable){
log.debug("Message Map: '$parsedMap'")
}
switch(parsedMap.sourceEndpoint) {
case "04":
button = "4"
break
case "03":
button = "3"
break
case "02":
button = "2"
break
case "01":
button = "1"
break
}
switch(parsedMap.data) {
case "[00]":
name = "pushed"
break
case "[01]":
name = "doubleTapped"
break
case "[02]":
name = "held"
break
}
sendEvent(name: name, value: button, descriptionText: "Button $button was $name",isStateChange:true)
//}
if (cluster == "0001" & attrId == "0020")
// Parse battery level from hourly announcement message
map = parseBattery(valueHex)
else
//displayDebugLog("Unable to parse message")
log.debug("Unable to parse message")
if (map != [:]) {
//displayDebugLog("Creating event $map")
log.debug("Creating event $map")
return createEvent(map)
} //else
//return [:]
}
return
}
// Convert 2-byte hex string to voltage
// 0x0020 BatteryVoltage - The BatteryVoltage attribute is 8 bits in length and specifies the current actual (measured) battery voltage, in units of 100mV.
private parseBattery(valueHex) {
//displayDebugLog("Battery parse string = ${valueHex}")
log.debug("Battery parse string = ${valueHex}")
def rawVolts = hexStrToSignedInt(valueHex) / 10
def minVolts = voltsmin ? voltsmin : 2.5
def maxVolts = voltsmax ? voltsmax : 3.0
def pct = (rawVolts - minVolts) / (maxVolts - minVolts)
def roundedPct = Math.min(100, Math.round(pct * 100))
def descText = "Battery level is ${roundedPct}% (${rawVolts} Volts)"
displayInfoLog(descText)
def result = [
name : 'battery',
value : roundedPct,
unit : "%",
isStateChange : true,
descriptionText: descText
]
return result
}
//Reset the batteryLastReplaced date to current date
def resetBatteryReplacedDate(paired) {
def newlyPaired = paired ? " for newly paired sensor" : ""
sendEvent(name: "batteryLastReplaced", value: new Date().toLocaleString(), descriptionText: "Set battery last replaced date")
displayInfoLog("Setting Battery Last Replaced to current date${newlyPaired}")
}