Salus SP600 driver with power dependant motion attribute

I developed this just as a test really but has proved quite useful to me so thought I would post it here in case it's any use to anyone else.

I can't take credit for 99% of the driver as it's a mongrel mix of existing community drivers. What I have done is add motion sensor capability and upper and lower power limit inputs. So rather than have rules that work out if an appliance is active or not I now do it directly in the driver and just monitor the motion attribute.

IE When the Active power threshold is set to 10W and the Inactive to 2W, the motion goes active when power first goes over 10W and only goes inactive again if it is less than or equal to 2W. These are the settings I use for our dishwasher.

To me it keeps things simpler than having the logic elsewhere.

I don't have a Github account so I've just pasted the code below

**
 * 
 *  Driver for Salus SP600 Smart Plug with Power based Motion Sensor switching*
 *  
 *	
 */


metadata {

	definition (name: "Salus SP600 Smart Outlet GT04", namespace: "Salus", author: "Salus") {

		capability "Configuration"
		capability "Switch"
		capability "Power Meter"
		capability "Refresh"
		capability "Sensor"
		capability "Motion Sensor"

		fingerprint profileId: "0104", inClusters: "0000, 0001, 0003, 0004, 0005, 0006, 0402, 0702, FC01", outClusters: "0019", manufacturer: "Computime", model: "SP600", deviceJoinName: "Salus SP600 Smart Plug"
	}

}


preferences {
	
	input name: "logEnable", type: "bool", title: "Enable debug logging", defaultValue: true
	input name: "txtEnable", type: "bool", title: "Enable descriptionText logging", defaultValue: true
	input name: "ReportMin", type: "number", title: "Minimum Report Time (seconds)", defaultValue: 1
	input name: "ReportDelta", type: "long", title: "Minimum Report Watt change 1 to 10", defaultValue: 5
	input name: "SwitchLevel", type: "number", title: "Power > Threshold for Motion Active", defaultValue: 10
    input name: "SwitchLevel2", type: "number", title: "Power <= Threshold for Motion InActive", defaultValue: 10
}



def initialize() {
	
	log.warn "Initialize Called!"

	configure()
	
}

def logsOff(){

	log.warn "debug logging disabled!"

	device.updateSetting("logEnable",[value:"false",type:"bool"])

}

def updated(){

	log.info "Updated Called!"

	log.warn "debug logging is: ${logEnable == true}"
	log.warn "description logging is: ${txtEnable == true}"
	
	if (logEnable) runIn(1800,logsOff)

}

def parse(String description) {

	if (logEnable) {
		
		log.debug "Parse Called!"
		log.debug "description is $description"

	}
	
	def eventMap = zigbee.getEvent(description)

	if (!eventMap) {
		
		eventMap = getDescription(zigbee.parseDescriptionAsMap(description))	

	}

	if (eventMap) {
	
		if (txtEnable) log.info "$device eventMap name: ${eventMap.name} value: ${eventMap.value}"

		sendEvent(eventMap)
        if (eventMap.name == "power") {
        def int powerValue = eventMap.value.toInteger()
        if (powerValue > SwitchLevel.toInteger()) sendEvent(name: "motion", value: "active", descriptionText: "Motion Active")
        if (powerValue <= SwitchLevel2.toInteger()) sendEvent(name: "motion", value: "inactive", descriptionText: "Motion Inactive")
        }
	}
	else {
		
//		log.warn "DID NOT PARSE MESSAGE for description: $description"			
		
		def descriptionMap = zigbee.parseDescriptionAsMap(description)
		if (logEnable) log.debug "descriptionMAp: $descriptionMap"			

	}	

}

def off() {

	zigbee.off()

}

def on() {

	zigbee.on()

}

def refresh() {
	
	if (logEnable) log.debug "Refresh Called!"
	
	zigbee.onOffRefresh() + simpleMeteringPowerRefresh()

}

def configure() {

	if (logEnable) log.debug "Configure Called!"

	zigbee.onOffConfig() + simpleMeteringPowerConfig() + zigbee.onOffRefresh() + simpleMeteringPowerRefresh()

}

def simpleMeteringPowerRefresh() {

	zigbee.readAttribute(0x0702, 0x0400)

}

def simpleMeteringPowerConfig(minReportTime=ReportMin.toInteger(), maxReportTime=600, reportableChange=ReportDelta.toInteger()) {

	zigbee.configureReporting(0x0702, 0x0400, DataType.INT24, minReportTime, maxReportTime, reportableChange)

}

def getDescription(descMap) {

	def powerValue = "undefined"

	if (descMap.cluster == "0702") {

		if (descMap.attrId == "0400") {

			if(descMap.value != "ffff") powerValue = zigbee.convertHexToInt(descMap.value)

		}

	}
	else if (descMap.clusterId == "0702") {

		if(descMap.command == "07"){

			return	[name: "update", value: "power (0702) capability configured successfully"]

		}

	}
	else if (descMap.clusterId == "0006") {

		if(descMap.command == "07"){

			return	[name: "update", value: "switch (0006) capability configured successfully"]

		}

	}

	if (powerValue != "undefined"){

		return	[name: "power", value: powerValue]

	}
	else {

		return null

	}

}