A new custom driver that provides support for Namron (Sunricher) wall battery switch (scene)
- manufacturer: NAMRON AS
- model: 4512793
- 1, 2 or 3 rocker switches (dip switch configured)
@kkossev , this is mostly "your work" and me adjusting ... Feel free to fit into your builds no questions asked ![]()
/**
* =======================================================================================
* Namron Simplify - 4512793 Driver (1, 2, or 3-Way Rocker)
* Multi-tap support.
* =======================================================================================
*/
metadata {
definition (name: "Namron Simplify - 4512793", namespace: "custom", author: "oalund") {
capability "Configuration"
capability "PushableButton"
capability "DoubleTapableButton"
capability "HoldableButton"
capability "ReleasableButton"
capability "Battery"
capability "Refresh"
capability "Initialize"
fingerprint profileId: "0104", endpointId: "01", inClusters: "0000,0001,0003,E004", outClusters: "0003,0019", model: "Fallback", manufacturer: "Namron"
}
preferences {
input(name: 'deviceModel', type: 'enum', title: '<b>Button Layout (DIP Switch)</b>',
options: ["2":"1-Way (1 Rocker)", "4":"2-Way (2 Rockers)", "6":"3-Way (3 Rockers)"], defaultValue: "4")
input(name: 'logEnable', type: 'bool', title: '<b>Enable debug logging</b>', defaultValue: true)
input(name: 'txtEnable', type: 'bool', title: '<b>Enable info text logging</b>', defaultValue: true)
}
}
def parse(String description) {
if (logEnable) log.debug "Namron received: ${description}"
def descMap = zigbee.parseDescriptionAsMap(description)
// 1. BUTTON LOGIC (Cluster E004)
if (descMap.clusterId == "E004" || descMap.clusterInt == 57348) {
if (descMap.data != null && descMap.data.size() >= 2) {
String btnHex = descMap.data[0] // Knappen (01, 02, 03, 04...)
String cmdHex = descMap.data[1] // Handlingen (01=Push, 08=Double, 02=Hold, 04=Rel)
int btnNum = 0
switch(btnHex) {
case "01": btnNum = 1; break;
case "02": btnNum = 2; break;
case "03": btnNum = 3; break;
case "04": btnNum = 4; break;
case "05": btnNum = 5; break;
case "06": btnNum = 6; break;
}
int maxButtons = (deviceModel ?: "6") as Integer
if (btnNum > 0 && btnNum <= maxButtons) {
switch(cmdHex) {
case "01": // PUSH
if (txtEnable) log.info "${device.displayName}: Button ${btnNum} pushed"
sendEvent(name: "pushed", value: btnNum, isStateChange: true)
break
case "08": // DOUBLE TAP
if (txtEnable) log.info "${device.displayName}: Button ${btnNum} doubleTapped"
sendEvent(name: "doubleTapped", value: btnNum, isStateChange: true)
break
case "02": // HOLD
if (txtEnable) log.info "${device.displayName}: Button ${btnNum} held"
sendEvent(name: "held", value: btnNum, isStateChange: true)
break
case "04": // RELEASE
if (txtEnable) log.info "${device.displayName}: Button ${btnNum} released"
sendEvent(name: "released", value: btnNum, isStateChange: true)
break
}
}
}
return null
}
// 2. BATTERY LOGIC (Cluster 0001)
if (descMap.clusterId == "0001" || descMap.clusterInt == 1) {
if (descMap.attrId == "0020" || descMap.attrInt == 32) {
if (descMap.value != null) {
def v = Integer.parseInt(descMap.value, 16)
if (logEnable) log.debug "Battery Voltage: ${v/10}V"
}
} else if (descMap.attrId == "0021" || descMap.attrInt == 33) {
if (descMap.value != null) {
def rawValue = Integer.parseInt(descMap.value, 16)
handleBattery(rawValue)
}
}
return null
}
}
def handleBattery(rawValue) {
def pct = 0
if (rawValue > 200) pct = 100
else if (rawValue >= 134) pct = 100
else pct = (rawValue / 1.34).toInteger()
if (txtEnable) log.info "${device.displayName} Battery: ${pct}%"
sendEvent(name: "battery", value: pct, unit: "%")
}
def refresh() {
log.info "Refreshing battery status..."
return zigbee.readAttribute(0x0001, [0x0020, 0x0021], [:], delay = 50)
}
def initialize() {
int btnCount = (deviceModel ?: "4") as Integer
sendEvent(name: "numberOfButtons", value: btnCount)
}
def configure() {
log.info "Configuring reporting and reading attributes..."
initialize()
List<String> configCmds = zigbee.configureReporting(0x0001, 0x0020, 0x20, 3600, 43200, 0x01) +
zigbee.configureReporting(0x0001, 0x0021, 0x20, 3600, 43200, 0x01)
return configCmds + refresh()
}