Device Handler for Aqara Wired Wall Switch

Thanks for this. I notice a few other things:

  1. I’m not seeing the 0x95 and 0x98 keys
  2. I note that the door and window sensors have 0x03 keys which seem to give sensible temperatures, but are not used in the DH. Other devices, such as the wireless switch, also seem to give temperatures, which don’t look correct however.
  3. The wired switch gives a battery level, but always at the maximum.
  4. 0x0a is interesting, as it seems to give a way of building a picture of the zigbee mesh. Looks like zero refers to the hub
  5. I am seeing LQI values of 1 or 2

Hmm, I was just going off of @guyeeba’s driver. What are all the keys that you’re seeing in the check-in messages?

Yes, some devices include temperature readings in the checkin messages that appear correct, but I am not convinced that they are. My impression is that the readings are of the internal (PCB board) temperature, and are not representative of the external air temperature. The only exception to this are the Xiaomi/Aqara Temperature Humidity Sensor models, but those include temperature/humidity(/pressure) readings under different key values.

My guess is that it’s just not used.

Exactly, the ZigBee DNI (Device Network ID) for a SmartThings Hub is always 0x0000, and any other value means that the Xiaomi/Aqara device is connected via mains-powered ZigBee router (repeater) device. This would be helpful in troubleshooting, as the vast majority of ZigBee routers do not allow Xiaomi / Aqara devices to remain connected to the SmartThings’ mesh network, and knowing the DNI can help identify which router device the Xiaomi/Aqara device is connected to.

I assume you’ve already seen this, but just in case not… there are some slight differences between smartthings and hubitat in capabilities, so I don’t think it will run directly in ST, but it might have some more information.

1 Like

The keys I see are: 0x64,0x65,0x6e,0x6f,0x01,0x03,0x05,0x08,0x0a,0x99,0x9b.

6e and 6f are 0x21 and show similar information to 0x64 and 0x65 except that they are 0x02 when the unwired switch is on, 0x01 when wired.

the final 2 are always zero.

Maybe the keys you are seeing are because there is more than one revision of the no-neutral switches?

Key 0x9b doesn’t show up in other devices I have, but 0x99 is found in the check-in messages of the Aqara Vibration sensor. 0x08 shows up for a number of devices, but it’s use is still a mystery to me.

Thanks to information from veeceeoh & aonghusmor & zigbee2mqtt and based on code from Smartthings ZigBee Switch & Zooz Power Strip Outlet & Diego Schich, I made this DHT for Aqara Switch QBKG12LM.


The way is a little difference. We have 1 main DHT for general information and child for each switch.

  • Main: easy to turn on / off both switches -> easy set automation mode. If we turn on / off each switch separately: main switch will ON when any switch is ON and OFF when both switches are OFF. It also has measurement for voltage, temperature, power & energy for whole QBKG12LM.
  • Child: main will create 2 childs for 2 switches like Zooz Power Strip Outlet.

You can use and modify them for your convenient

Main DHT

/*
 *  for Aqara Switch QBKG12LM
 *
 *  use information from Smartthings ZigBee Switch & Diego Schich & Zooz Power Strip Outlet & Koenkk zigbee2mqtt
 *                     & aonghusmor & veeceeoh
 *
 *  Leza, 10-Aug-2019
 */

metadata {
	definition (name: "Aqara QBKG12LM Main", namespace: "Leza", author: "LPT", vid:"generic-switch-power-energy") {
		capability "Actuator"
		capability "Switch"
		capability "Temperature Measurement"
		capability "Voltage Measurement"
		capability "Power Meter"
		capability "Energy Meter"
		capability "Sensor"
		capability "Configuration"
		capability "Refresh"
		capability "Health Check"
		
		(1..2).each {
			//attribute "sw${it}Power", "number"
			attribute "sw${it}Switch", "string"
			attribute "sw${it}Name", "string"
			command "sw${it}On"
			command "sw${it}Off"
		}

		fingerprint	profileId: "0104", deviceId: "0051", inClusters: "0000,0001,0002,0003,0004,0005,0006,0010,000A", outClusters: "0019,000A",
					manufacturer: "LUMI", model: "lumi.ctrl_ln2.aq1", deviceJoinName: "Aqara Switch QBKG12LM"
	}	
	
	preferences {
		// Log Debug
		getBoolInput("debugOutput", "Enable Debug Logging", true)
	}

	tiles(scale: 2) {
		multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
			tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
				attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
				attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
				attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
				attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
			}
			tileAttribute("device.lastCheckin", key: "SECONDARY_CONTROL") {
				attributeState("default", label:'Last Update: ${currentValue}')
			}
		}
		
		valueTile("sw1Name", "device.sw1Name", decoration:"flat", width:5, height: 1) {
			state "default", label:'${currentValue}'
		}
		standardTile("sw1Switch", "device.sw1Switch", width:1, height: 1) {
			state "on", label:'ON', action:"sw1Off", backgroundColor: "#00A0DC"
			state "off", label:'OFF', action:"sw1On", backgroundColor:"#ffffff"
		}
		valueTile("sw2Name", "device.sw2Name", decoration:"flat", width:5, height: 1) {
			state "default", label:'${currentValue}'
		}
		standardTile("sw2Switch", "device.sw2Switch", width:1, height: 1) {
			state "on", label:'ON', action:"sw2Off", backgroundColor: "#00A0DC"
			state "off", label:'OFF', action:"sw2On", backgroundColor:"#ffffff"
		}
		
		valueTile("voltage", "device.voltage", width: 2, height: 2) {
			state "voltage", label:'${currentValue} V', icon:"st.Appliances.appliances17"
		}
		valueTile("temperature", "device.temperature", width: 2, height: 2) {
			state "temperature", label:'${currentValue} °C', icon:"st.Weather.weather2"
		}
		standardTile("refresh", "device.refresh", width: 2, height: 2) {
			state "default", label:'Refresh', action: "refresh", icon:"st.secondary.refresh-icon"
		}
		valueTile("power", "device.power", width: 3, height: 2) {
			state "power", label:'${currentValue} W', icon:"st.Appliances.appliances5"
		}
		valueTile("energy", "device.energy", width: 3, height: 2) {
			state "energy", label:'${currentValue} kWh', icon:"st.Health & Wellness.health7"
		}
		
		main (["switch"])
		details (detailsTiles)
	}
}

private getDetailsTiles() {
	def tiles = ["switch"]
	(1..2).each {
		tiles << "sw${it}Name"
		tiles << "sw${it}Switch"
	}
    tiles << "voltage" << "temperature" << "refresh" << "power" << "energy"
	return tiles
}

private getBoolInput(name, title, defaultVal) {
	input "${name}", "bool", 
	title: "${title}?", 
	defaultValue: defaultVal, 
	required: false
}

// Globals - Key IDs
private Key_TEMPERATURE()	{ 0x03 }
private Key_RSSI()			{ 0x05 }
private Key_SWITCH_1()		{ 0x64 }
private Key_SWITCH_2()		{ 0x65 }
private Key_ENERGY_METER()	{ 0x95 }
private Key_POWER_METER()	{ 0x98 }

// ZigBee - Data Types
private ZB_Data_BOOLEAN()	{ 0x10 }
private ZB_Data_UINT8()		{ 0x20 }
private ZB_Data_UINT16()	{ 0x21 }
private ZB_Data_UINT64()	{ 0x27 }
private ZB_Data_INT8()		{ 0x28 }
private ZB_Data_FLOAT4()	{ 0x39 }

def installed() { 
	// Make sure the switch get created if using the new mobile app.
	runIn(30, createChildDevices)
}

def updated() {	
	if (!isDuplicateCommand(state.lastUpdated, 3000)) {
		state.lastUpdated = new Date().time
		
		def cmds = []
		
		if (childDevices?.size() != 2)	cmds += createChildDevices()
		
		cmds += configure()
		return cmds ? response(cmds) : []
	}
}

def createChildDevices() {
	(1..2).each { endPoint ->
		if (!findChildByEndPoint(endPoint)) {			
			def dni = "${getChildDeviceNetworkId(endPoint)}"
			
			addChildSwitch(dni, endPoint)
			childUpdated(dni)
		}
	}
}

private addChildSwitch(dni, endPoint) {
	logDebug "Creating SW${endPoint} Child Device"
	addChildDevice("Leza", "Aqara QBKG12LM Child Switch", dni, null, 
		[
			completedSetup: true,
			isComponent: false,
			label: "${device.displayName}-SW${endPoint}",
			componentLabel: "SW ${endPoint}",
			componentName: "SW${endPoint}"
		]
	)
}

def configure() {	
	updateHealthCheckInterval()
}

private updateHealthCheckInterval() {
	// Device wakes up every 1 hours, this interval allows us to miss one wakeup notification before marking offline
	def minReportingInterval = (1 * 60 * 60)
	
	if (state.minReportingInterval != minReportingInterval) {
		state.minReportingInterval = minReportingInterval
		logDebug "Configured health checkInterval when updated()"
		
		// Set the Health Check interval so that it can be skipped twice plus 2 minutes.
		def checkInterval = ((minReportingInterval * 2) + (2 * 60))
		sendEvent(name: "checkInterval", value: checkInterval, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
	}
}

def childUpdated(dni) {
	logDebug "childUpdated(${dni})"
	def child = findChildByDeviceNetworkId(dni)
	def endPoint = getEndPoint(dni)
	def nameAttr = "sw${endPoint}Name"
	logDebug "${child.displayName} vs ${device.currentValue(nameAttr)}"
	if (child && "${child.displayName}" != "${device.currentValue(nameAttr)}") {
		sendEvent(name: nameAttr, value: child.displayName, displayed: false)
	}
}

def ping() {
	logDebug "ping()..."
	return zigbee.onOffRefresh()
}

def on() {
	logDebug "on()..."
	sw1On()
	sw2On()
}

def off() {
	logDebug "off()..."
	sw1Off()
	sw2Off()
}

def sw1On() { childOn(getChildDeviceNetworkId(1)) }
def sw2On() { childOn(getChildDeviceNetworkId(2)) }

def childOn(dni) {
	logDebug "childOn(${dni})..."
    
	def endPoint = getEndPoint(dni)
	
	if (endPoint == 1) {
		logDebug "On(${endPoint})..."
		//zigbee.on()
		def actions = [new physicalgraph.device.HubAction("st cmd 0x${device.deviceNetworkId} 0x01 0x0006 0x01 {}")]    
		sendHubCommand(actions)
	}
	else if (endPoint == 2) {
		logDebug "On(${endPoint})..."
		def actions = [new physicalgraph.device.HubAction("st cmd 0x${device.deviceNetworkId} 0x02 0x0006 0x01 {}")]    
		sendHubCommand(actions)
	}
}

def sw1Off() { childOff(getChildDeviceNetworkId(1)) }
def sw2Off() { childOff(getChildDeviceNetworkId(2)) }

def childOff(dni) {
	logDebug "childOff(${dni})..."
	
	def endPoint = getEndPoint(dni)
	
	if (endPoint == 1) {
		logDebug "Off(${endPoint})..."
		def actions = [new physicalgraph.device.HubAction("st cmd 0x${device.deviceNetworkId} 0x01 0x0006 0x00 {}")]
		sendHubCommand(actions)
	}
	else if (endPoint == 2) {
		logDebug "Off(${endPoint})..."
		def actions = [new physicalgraph.device.HubAction("st cmd 0x${device.deviceNetworkId} 0x02 0x0006 0x00 {}")]
		sendHubCommand(actions)
	}
}

def refresh() {
	logDebug "Refresh..."	
	def Cmds = zigbee.readAttribute(0x0001, 0x0000, [destEndpoint: 0x01]) +		// voltage
			   zigbee.readAttribute(0x0002, 0x0000, [destEndpoint: 0x01]) +		// temperature
			   zigbee.readAttribute(0x0006, 0x0000, [destEndpoint: 0x01]) +		// switch 1 state
			   zigbee.readAttribute(0x0006, 0x0000, [destEndpoint: 0x02]) +		// switch 2 state
			   zigbee.readAttribute(0x000C, 0x0055, [destEndpoint: 0x03])		// power
	return Cmds
}

def childRefresh(dni) {
	logDebug "child(${dni})Refresh..."
	
	def endPoint = getEndPoint(dni)
	
	def Cmds = zigbee.readAttribute(0x0001, 0x0000, [destEndpoint: 0x01]) +		// voltage
			   zigbee.readAttribute(0x0002, 0x0000, [destEndpoint: 0x01]) +		// temperature
			   zigbee.readAttribute(0x0006, 0x0000, [destEndpoint: endPoint])	// switch state
	
	def actions = []
	
    Cmds?.each {
		actions << new physicalgraph.device.HubAction(it)
	}
	sendHubCommand(actions, 100)
	return []
}

// Parse incoming device messages to generate events
def parse(String description) {
	logDebug "description is $description"
	def cluster = zigbee.parseDescriptionAsMap(description)
	logDebug "descMap is $cluster"
	
	if (description?.startsWith("read attr -")) {		
		// Switch state
		if ((cluster.clusterInt == 0x0006) && (cluster.attrInt == 0x0000)) {
			if(cluster.endpoint == "01") {
				state.sw1 = (cluster.value == "01" ? "on" : "off")
				executeSendEvent(findChildByEndPoint(1), createEventMap("switch", state.sw1))
				executeSendEvent(null, createEventMap("sw1Switch", state.sw1))
				executeSendEvent(null, createEventMap("switch", ((state.sw1 == "on") || (state.sw2 == "on")) ? "on" : "off"))
			}
        	else if (cluster.endpoint == "02") {
				state.sw2 = (cluster.value == "01" ? "on" : "off")
				executeSendEvent(findChildByEndPoint(2), createEventMap("switch", state.sw2))
				executeSendEvent(null, createEventMap("sw2Switch", state.sw2))
				executeSendEvent(null, createEventMap("switch", ((state.sw1 == "on") || (state.sw2 == "on")) ? "on" : "off"))
			}
		}
		// Voltage
		else if (cluster.clusterInt == 0x0001 && cluster.attrInt == 0x000) {
			if (cluster.endpoint == "01") {
				def value = (int) (Integer.parseInt(cluster.value, 16) / 10)
				executeSendEvent(null, createEventMap("voltage", value, null, "V"))
				executeSendEvent(findChildByEndPoint(1), createEventMap("voltage", value, null, "V"))
				executeSendEvent(findChildByEndPoint(2), createEventMap("voltage", value, null, "V"))
			}
		}
		// Temperature
		else if (cluster.clusterInt == 0x0002 && cluster.attrInt == 0x000) {
			if (cluster.endpoint == "01") {
				def value = Integer.parseInt(cluster.value, 16)
				if (value > 127)	value = value - 256
				executeSendEvent(null, createEventMap("temperature", value, null, "C"))
				executeSendEvent(findChildByEndPoint(1), createEventMap("temperature", value, null, "C"))
				executeSendEvent(findChildByEndPoint(2), createEventMap("temperature", value, null, "C"))
			}
		}
		// Power meter
		else if ((cluster.clusterInt == 0x000C) && (cluster.attrInt == 0x0055)) {
			if (cluster.endpoint == "03") {
				def value = Float.intBitsToFloat(Long.parseLong(cluster.value, 16).intValue())
				executeSendEvent(null, createEventMap("power", roundTwoPlaces(value), null, "W"))
			}
		}
	}
	
	if (description?.startsWith("catchall:")) {
		if ((cluster.clusterInt == 0x0000) && (cluster.attrInt == 0xFF01)) {
			Map key = [:]
			int i = 4
			int j
			
			// get keys
			while (i < cluster.data.size()) {
				// save start index
				j = i
			
				// get key type
				key.type = Integer.parseInt(cluster.data[i], 16)
				if      (key.type == Key_TEMPERATURE())		key.name = "temperature"        	
				else if (key.type == Key_RSSI())			key.name = "RSSI" 
				else if (key.type == Key_SWITCH_1())		key.name = "switch1" 
				else if (key.type == Key_SWITCH_2())		key.name = "switch2" 
				else if (key.type == Key_ENERGY_METER())	key.name = "energy" 
				else if (key.type == Key_POWER_METER())		key.name = "power" 
				else										key.name = "unknown (" + cluster.data[i] + ")"
			
				// get key value
				i++
				key.datatype = Integer.parseInt(cluster.data[i++], 16)
				if (key.datatype == ZB_Data_BOOLEAN()) {
					key.value = ((cluster.data[i] == "01") ? "on" : "off")
				}
				else if (key.datatype == ZB_Data_UINT8()) {
					key.value = Integer.parseInt(cluster.data[i], 16)
				}
				else if (key.datatype == ZB_Data_UINT16()) {
					key.value = Integer.parseInt(cluster.data[i+1] + cluster.data[i], 16)
					i += 1
				}
				else if (key.datatype == ZB_Data_UINT64()) {
					key.value = Long.parseLong(cluster.data[i+7] + cluster.data[i+6] + cluster.data[i+5] + cluster.data[i+4] +
											   cluster.data[i+3] + cluster.data[i+2] + cluster.data[i+1] + cluster.data[i], 16)
					i += 7
				}
				else if (key.datatype == ZB_Data_INT8()) {
					key.value = Integer.parseInt(cluster.data[i], 16)
					if (key.value > 127) {
						key.value = key.value - 256
					}
				}
				else if (key.datatype == ZB_Data_FLOAT4()) {
					key.value = Float.intBitsToFloat(Long.parseLong(cluster.data[i+3] + cluster.data[i+2] +
																	cluster.data[i+1] + cluster.data[i], 16).intValue())
					i += 3
				}
				logDebug "index: $j, key: $key.name, value: $key.value"
			
				// send event
				if (key.type == Key_TEMPERATURE()) {
					executeSendEvent(null, createEventMap("temperature", key.value, null, "C"))
					executeSendEvent(findChildByEndPoint(1), createEventMap("temperature", key.value, null, "C"))
					executeSendEvent(findChildByEndPoint(2), createEventMap("temperature", key.value, null, "C"))
				}
				else if (key.type == Key_SWITCH_1()) {
					state.sw1 = key.value
					executeSendEvent(findChildByEndPoint(1), createEventMap("switch", state.sw1))
					executeSendEvent(null, createEventMap("sw1Switch", state.sw1))
					executeSendEvent(null, createEventMap("switch", ((state.sw1 == "on") || (state.sw2 == "on")) ? "on" : "off"))
				}
				else if (key.type == Key_SWITCH_2()) {
					state.sw2 = key.value
					executeSendEvent(findChildByEndPoint(2), createEventMap("switch", state.sw2))
					executeSendEvent(null, createEventMap("sw2Switch", state.sw2))
					executeSendEvent(null, createEventMap("switch", ((state.sw1 == "on") || (state.sw2 == "on")) ? "on" : "off"))
				}
				else if (key.type == Key_ENERGY_METER()) {
					executeSendEvent(null, createEventMap("energy", roundTwoPlaces(key.value), null, "kWh"))
				}
				else if (key.type == Key_POWER_METER()) {
					executeSendEvent(null, createEventMap("power", roundTwoPlaces(key.value), null, "W"))
				}
			
				i++
			}
		}
	}
    
	// send event for heartbeat
	def now = new Date().format("dd-MM-yyyy HH:mm:ss", location.timeZone)
	sendEvent(name: "lastCheckin", value: now, displayed: false)
	executeSendEvent(findChildByEndPoint(1), createEventMap("lastCheckin", now))
	executeSendEvent(findChildByEndPoint(2), createEventMap("lastCheckin", now))
}

private executeSendEvent(child, evt) {
	if (evt.displayed == null)	evt.displayed = (getAttrVal(evt.name, child) != evt.value)
    
	if (evt) {
		if (child) {
			if (evt.descriptionText) {
				evt.descriptionText = evt.descriptionText.replace(device.displayName, child.displayName)
			}
            logDebug "${evt}"
			child.sendEvent(evt)						
		}
		else {
			logDebug "${evt}"
            sendEvent(evt)
		}		
	}
}

private createEventMap(name, value, displayed=null, unit=null) {	
	def eventMap = [
		name: name,
		value: value,
		displayed: displayed,
		isStateChange: true,
		descriptionText: "${device.displayName} - ${name} is ${value}"
	]
	
	if (unit) {
		eventMap.unit = unit
		eventMap.descriptionText = "${eventMap.descriptionText} ${unit}"
	}
	return eventMap
}

private getAttrVal(attrName, child=null) {
	try {
		if (child) {
			return child?.currentValue("${attrName}")
		}
		else {
			return device?.currentValue("${attrName}")
		}
	}
	catch (ex) {
		//logTrace "$ex"
		return null
	}
}

private findChildByEndPoint(endPoint) {
	def dni = "${getChildDeviceNetworkId(endPoint)}"
	return findChildByDeviceNetworkId(dni)
}

private findChildByDeviceNetworkId(dni) {
	return childDevices?.find { it.deviceNetworkId == dni }
}

private getEndPoint(childDeviceNetworkId) {
	return safeToInt("${childDeviceNetworkId}".reverse().take(1))
}

private getChildDeviceNetworkId(endPoint) {
	return "${device.deviceNetworkId}-SW${endPoint}"
}

private safeToInt(val, defaultVal=0) {
	return "${val}"?.isInteger() ? "${val}".toInteger() : defaultVal
}

private safeToDec(val, defaultVal=0) {
	return "${val}"?.isBigDecimal() ? "${val}".toBigDecimal() : defaultVal
}

private roundTwoPlaces(val) {
	return Math.round(safeToDec(val) * 100) / 100
}

private isDuplicateCommand(lastExecuted, allowedMil) {
	!lastExecuted ? false : (lastExecuted + allowedMil > new Date().time) 
}

private logDebug(msg) {
	if (settings?.debugOutput != false) {
		log.debug "$msg"
	}
}

Child DHT

/*
 *  for Aqara Switch QBKG12LM - Child Switch
 *
 *  modify code from Smartthings ZigBee Switch & Diego Schich & Zooz Power Strip Outlet
 *
 *  Leza, 10-Aug-2019
 */

metadata {
	definition (name: "Aqara QBKG12LM Child Switch", namespace: "Leza", author: "LPT", vid:"generic-switch-power-energy") {
        capability "Actuator"
		capability "Switch"
        capability "Temperature Measurement"
        capability "Voltage Measurement"
		capability "Sensor"
		capability "Refresh"
	}
    
    simulator { }

	tiles(scale: 2) {
		multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
			tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
				attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
				attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
				attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
				attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.light.off", backgroundColor:"#ffffff", nextState:"turningOn"
			}
			tileAttribute("device.lastCheckin", key: "SECONDARY_CONTROL") {
				attributeState("default", label:'Last Update: ${currentValue}')
			}
		}
		
		valueTile("voltage", "device.voltage", width: 2, height: 2) {
			state "voltage", label:'${currentValue} V', icon:"st.Appliances.appliances17"
		}
		valueTile("temperature", "device.temperature", width: 2, height: 2) {
			state "temperature", label:'${currentValue} °C', icon:"st.Weather.weather2"
		}
		standardTile("refresh", "device.refresh", width: 2, height: 2) {
			state "default", label:'Refresh', action: "refresh", icon:"st.secondary.refresh-icon"
		}

		main (["switch"])
		details(["switch", "voltage", "temperature", "refresh"])
	}
}

def installed() {}

def updated() {	
	parent.childUpdated(device.deviceNetworkId)
}

def on() {
	parent.childOn(device.deviceNetworkId)	
}

def off() {
	parent.childOff(device.deviceNetworkId)	
}

def refresh() {
	parent.childRefresh(device.deviceNetworkId)
}
2 Likes

Hi!

I have a question.Is there anything more to do besides adding the two new DHS into SM IDE?
Because on my home, all the “SW1” seems not to be working, i don’t know why…and also the Voltage input it’s always zero.

Thank you,
Vlad

Hi Vlad,

It looks like the pairing process & adding new thing are not successful. Can you give more information about them? Do you have any alarm when you add new thing? Take some snapshots of mobile app & logs of hub & new device.

Note that these DHTs are used for Aqara QBKG12LM - the wall mount 2 gang switch with Line + NEUTRAL.
Try some below tasks

  • Are your Aqara QBKG12LM connected before? If so, please remove it then reset switch (press any button more than 10 seconds) and make new pair.
  • Do you have any DHT for this switch before? Please delete them so that you have only these 2 new DHTs and they are already published.
  • Do you change device name on Smartthings app after adding new thing? Virtual device has lost DHT sometimes. Please check device tab in Smartthings IDE: if SW1 & SW2 show placeholder in Device Handler, please change them to Aqara QBKG12LM - Child.
  • The pairing with Xiaomi Aqara device is not often successful 100%. If you have any problem, try to delete thing on app, reset device and then add new thing on app and reset device again so that it is in pairing mode. You could try many times.
  • In normal operation, new device on app will show correct status of your switch when you turn on / off. Other information like temperature, power & energy will be updated by switch every 5 to 7 minutes but voltage is not, you have to press Refresh to get this value.

Hope that these tasks can help you.
LPT

Hi lpthanh,

I’ve missed the fact that my Aqara switch does not have a Neutral Line.I did not remove all the devices from Smartthings before doing all that.I will test your DHT’s with fresh start and let’s see what happens (even without neutral line ) :smiley:
Thank you for support!
I let you know,
Vlad

I am afraid that your Aqara switch cannot measure voltage because it does not have neutral line. So that it also not have power meter & energy meter.

1 Like

Yes I know ,but the rest of the DH should work, right?

Thanks for sharing the DTH! However, I am facing some issues with it on Smartthings. The Switch status and power on/off from Smartthings don’t always work, it usually ends with a loading animation. However, it works perfectly well with Smartthings automation and also on Google Home. Any idea why is that happening?

And I am currently using Aqara QBKG12LM, Samsung Connect Hub and the new Smartthings app.

Can you test and use classic app? New ST app is not supported custom device handler well at this time.

Thanks lpthanh for the quick reply! I’m unable to test with the classic app, read one other thread saying that the new hub stop allowing a connection after they tried connecting both the classic and new ST app.

The current inconvenience is that it doesn’t update if the switch is on/off so it may not operate properly. I will try to delete and add the device again to see if it makes a difference or not. Will update you if anything changes. Thanks for your effort!

hi guys do you have the handler for QBKG03LM
this is the no nutral wired aqara switch. thank you so much in advance

Hi George,

Look a few posts up.There is a brand new DH without power meter but still it’s great

Hi Ipthanh, just to update you on how it is working on v3 hub and app. I reinstalled the handler and link up the switch to the lights. The device handler works quite well for automation and Google Home, as long as you can explicitly tell it to on or off. For the v3 app and Google Home, the switch status will be updated eventually, it will take at least 2-5 mins before it shows correctly. Not ideal but I’m happy that it still works, thanks Ipthanh, veeceeoh, aonghusmor and zigbee2mqtt for all the effort!

Glad to see your feedback! It is same my things.

Hi @lpthanh do u own a Aqara Wirless Wall Switch WXKG02LM (2018 revision)? I am trying out your Main-Child method with it to see if it can work for the new ST app. This is because the new ST app only allows us to set actions for 3 interactions (Press/Double/Hold) but there are a total of 9 interactions (Single Left/Single Right/Single Both/Double Left/Double Right/Double Both/Hold Left/Hold Right/Hold Both). The concept is very similar to yours,

  • Main: Allow us to set actions for Single Both/Double Both/Hold Both
  • Child: Main will create 2 child, one for left, one for right. This allow us to set the automation for individual Single Left/Double Left/Hold Left and Single Right/Double Right/Hold Right.

I use the DTH from Original & Aqara Xiaomi Zigbee Sensors (contact, temp, motion, button, outlet, leak, etc) as the base. I am able to get it to create 2 child buttons and also create the button event for the child buttons, but I can’t seem to get the child buttons to work at all, it is neither detecting the interactions or allowing me to set actions for it. As this is the first DTH I am working on, was wondering if I could show the code for you to have a look too? And maybe point me in a direction? Thanks!

I don’t have any WXKG02LM so I am not sure about it. As you may know that we will collect information from web to make the draft DHT but we will use our own device to debug and then finish it.

© 2019 SmartThings, Inc. All Rights Reserved. Terms of Use | Privacy Policy

SmartThings; SmartApps®; Physical Graph; Hello, Home; and Hello, Smart Home are all trademarks of the SmartThings, Inc.