Zwave Power Strip from AEON

Anyone else make any more progress on this? I would love to see the reporting piece working for this device, and still be able to turn on and off the individual switches.

@jwu thanx
Noted on command 1 being get and scale as parameter. Two parameters have been used above, 0 and 16…

Kindly point me to a link where I can reference other commands and parameters.

Thanx again.

@thrash99er

Have you tried the device type code I posted in this thread ? That should report energy and power values for all and individual outlets.

@jjhamb

The user manual you posted for your device has very detailed explanation and examples of all available commands for your device. I think you should be able to cross-reference the Zwave command examples in your manual with the device type code you have so far to figure out how to put all supported command in device type code.

@jwu I’ve used the device type from @chrisb And using his binder, I can control all of the individual outlets through the virtual on/off switches, but I need to be able to control the outlets individually AND get the reporting.

Do you have that working? I will try it out, but I’m not sure which device type I should be using, and do i still need to use the binder on it to control the individual outlets?

I am trying @jwu I am trying :frowning:

@thrash99er

Here’s the device type code I modified from @chrisb 's version that includes power and energy reporting:

If you hit the configure button the device should report the usage every 2 minutes. You can modify the value (in seconds) for parameter 111 in the configure block to change the reporting frequency. You can also use the refresh button to force an update right away. You do still need the binding app to be able to control individual switches via another app.

@jjhamb

From the output of the refresh command it seems that all the endpoints are reporting properly ? Are you still encountering issue with the reporting or are you trying to get additional functionality working ?

1 Like

@jwu What custom attributes and commands, and capabilities does this device type need?

@thrash99er

Capabilities:
Refresh
Power Meter
Energy Meter
Switch
Configuration
Polling

Custom Attributes:
switch1
switch2
switch3
switch4
power1
energy1
power2
energy2
power3
energy3
power4
energy4
power5
energy5
power6
energy6

Custom Commands:
on1
off1
on2
off2
on3
off3
on4
off4
test
reset

@thrash99er

Or you can add the following code to the metadata section

	definition (name: "Aeon Smartstrip", author: "jwu") {
		capability "Power Meter"
		capability "Configuration"
		capability "Energy Meter"
		capability "Polling"
		capability "Refresh"
		capability "Switch"

		attribute "switch1", "string"
		attribute "switch2", "string"
		attribute "switch3", "string"
		attribute "switch4", "string"
		attribute "power1", "string"
		attribute "energy1", "string"
		attribute "power2", "string"
		attribute "energy2", "string"
		attribute "power3", "string"
		attribute "energy3", "string"
		attribute "power4", "string"
		attribute "energy4", "string"
		attribute "power5", "string"
		attribute "energy5", "string"
		attribute "power6", "string"
		attribute "energy6", "string"

		command "on1"
		command "off1"
		command "on2"
		command "off2"
		command "on3"
		command "off3"
		command "on4"
		command "off4"
		command "test"
		command "reset"
	}

@jwu hi again

Device handler below is working for me as for as ON/OF of individual relays is concerned. Tiles for the individual relay (switch2 for relay1) changes colour too. Value tiles for power and energy update when I hit refresh.

Here is what I need to fix/incorporate.
A) I want to be able to update state (ON/OF) of all tiles when any one tile changes state.
B) I also want to update all power and energy tiles when A happens

can you help? I tried calling refresh() in on1() but then only refresh gets called, first part of the code does not trigger the switch.

def on1() {
	delayBetween([
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:1, parameter:[255]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format()
	])
refresh()
}

Complete device handler is as under:

/**
 *  Based on Aeon Smartstrip
 *  Devive handler for TKB TZ04 dual Realy insert
 *  
 *  By using BINARY_SWITCH_SET Command of Multi Channel Command Class Encapsulateion Command, 
 *  you can switch both Relay1 and Relay2 ON/OFF by setting endpoint to 1 or switch Relay1 ON/OFF 
 *  by setting endpoint to 2 or switch Relay1 ON/OFF by setting endpoint to 3
 *  Status of Endpoint 1 returns ON when either relay 1 or 2 is ON or both or ON
 *
 *  Device is capable of metering (combined when endpoint is set to 1) and individually when set to 2 or 3
 *
 *  TODO
 *  Standard TILES work an relays cn be switched on or off by setting endpoints 1-3
 *  However value tiles only get updated after hitting refresh
 */
 // for the UI
metadata {
	// Automatically generated. Make future change here.
	definition (name: "Aeon Smart Strip", author: "jjhamb@yahoo.com") {
		capability "Energy Meter"
		capability "Refresh"
		capability "Power Meter"
		capability "Switch"
		capability "Configuration"
		capability "Polling"

		attribute "power1", "string"
		attribute "power2", "string"
		attribute "power3", "string"
		attribute "energy1", "string"
		attribute "energy2", "string"
		attribute "energy3", "string"
		attribute "switch1", "string"
		attribute "switch2", "string"
		attribute "switch3", "string"

		command "on1"
		command "off1"
		command "on2"
		command "off2"
		command "on3"
		command "off3"
		command "testA"
		command "testB"        
	}

	simulator {
		// TODO: define status and reply messages here
	}

	tiles {
        valueTile("power", "device.power", decoration: "flat") {
			state "default", label:'${currentValue} W'
		}
		valueTile("energy", "device.energy", decoration: "flat") {
			state "default", label:'${currentValue} kWh'
		}
		standardTile("switch1", "device.switch1",canChangeIcon: true) {
                        state "on", label: "switch1", action: "off1", icon: "st.switches.switch.on", backgroundColor: "#79b821"
                        state "off", label: "switch1", action: "on1", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
                }
        standardTile("switch2", "device.switch2",canChangeIcon: true) {
                        state "on", label: "switch2", action: "off2", icon: "st.switches.switch.on", backgroundColor: "#79b821"
                        state "off", label: "switch2", action: "on2", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
                }
        standardTile("switch3", "device.switch3",canChangeIcon: true) {
                        state "on", label: "switch3", action: "off3", icon: "st.switches.switch.on", backgroundColor: "#79b821"
                        state "off", label: "switch3", action:"on3", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
                }
        standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
                        state "default", label:"", action:"refresh", icon:"st.secondary.refresh"
                }
        standardTile("reset", "device.switch", inactiveLabel: false, decoration: "flat") {
        				state "default", label:"reset kWh", action:"reset"
                }
        standardTile("configure", "device.switch", inactiveLabel: false, decoration: "flat") {
        				state "default", label:"", action:"configure", icon:"st.secondary.configure"
                }
           
        valueTile("power2", "device.power2", decoration: "flat") {
			state "default", label:'${currentValue} W'
		}
		valueTile("energy2", "device.energy2", decoration: "flat") {
			state "default", label:'${currentValue} kWh'
		}
        valueTile("power3", "device.power3", decoration: "flat") {
			state "default", label:'${currentValue} W'
		}
		valueTile("energy3", "device.energy3", decoration: "flat") {
			state "default", label:'${currentValue} kWh'
		}
        

        main(["switch1", "power", "energy"])
        details(["switch1", "power", "energy", "switch2", "power2", "energy2", 
        "switch3", "power3", "energy3", "refresh", "configure", "reset"])
	}
}

// 0x25 0x32 0x27 0x70 0x85 0x72 0x86 0x60 0xEF 0x82

// 0x25: switch binary
// 0x32: meter
// 0x27: switch all
// 0x70: configuration
// 0x85: association
// 0x86: version
// 0x60: multi-channel
// 0xEF: mark
// 0x82: hail

// parse events into attributes
def parse(String description) {
	 log.debug "Parsing desc => '${description}'"

    def result = null
    def cmd = zwave.parse(description, [0x60:3, 0x25:1, 0x32:1, 0x70:1])
    if (cmd) {
        result = createEvent(zwaveEvent(cmd))
    }
    log.debug "Parsing result => '${result}'"
    return result
}

//Reports

def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
        [name: "switch", value: cmd.value ? "on" : "off", type: "physical"]
}

def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd) {
        [name: "switch", value: cmd.value ? "on" : "off", type: "digital"]
}

def zwaveEvent(physicalgraph.zwave.commands.meterv1.MeterReport cmd) {
	def map = []
    
	if (cmd.scale == 0) {
    	map = [ name: "energy", value: cmd.scaledMeterValue, unit: "kWh" ]
    }
    else if (cmd.scale == 2) {
    	map = [ name: "power", value: Math.round(cmd.scaledMeterValue), unit: "W" ]
    }
    
    map
}

def zwaveEvent(int endPoint, physicalgraph.zwave.commands.meterv1.MeterReport cmd) {
	// MeterReport(deltaTime: 1368, meterType: 1, meterValue: [0, 3, 29, 17], precision: 3, previousMeterValue: [0, 3, 29, 17], rateType: 1, reserved02: false, scale: 0, scaledMeterValue: 204.049, scaledPreviousMeterValue: 204.049, size: 4)
	 log.debug "EndPoint $endPoint, MeterReport $cmd"
    def map = []
    
    if (cmd.scale == 0) {
    	map = [ name: "energy" + endPoint, value: cmd.scaledMeterValue, unit: "kWh" ]
    }
    else if (cmd.scale == 2) {
    	map = [ name: "power" + endPoint, value: Math.round(cmd.scaledMeterValue), unit: "W" ]
    }
    
    map
}

/*
def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
	 log.debug "MultiChannelCmdEncap $cmd"
    
    def map = [ name: "switch$cmd.sourceEndPoint" ]
    if (cmd.commandClass == 37){
    	if (cmd.parameter == [0]) {
        	map.value = "off"
        }
        if (cmd.parameter == [255]) {
            map.value = "on"
        }
        map
    }
    else if (cmd.commandClass == 50) {
    	// bitAddress: false, command: 2, commandClass: 50, destinationEndPoint: 1, parameter: [33, 100, 0, 0, 0, 0, 0, 94, 0, 0, 0, 0], res01: false, sourceEndPoint: 1
        def hex1 = { n -> String.format("%02X", n) }
        def desc = "command: ${hex1(cmd.commandClass)}${hex1(cmd.command)}, payload: " + cmd.parameter.collect{hex1(it)}.join(" ")
        // Re-assign source end point 3-6 to 1-4 and 1-2 to 5-6 to sync up with the switch end points. 
        // Source end point in the message refers to always-on sockets.
        zwaveEvent((cmd.sourceEndPoint > 3) ? (cmd.sourceEndPoint-3) : (cmd.sourceEndPoint+3), zwave.parse(desc, [ 0x60:3, 0x25:1, 0x32:1, 0x70:1 ]))
    }
}
*/
def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
    log.debug "MultiChannelCmdEncap $cmd"
    
    def map = [ name: "switch$cmd.sourceEndPoint" ]
    if (cmd.commandClass == 37){
    	if (cmd.parameter == [0]) {
        	map.value = "off"
        }
        if (cmd.parameter == [255]) {
            map.value = "on"
        }
        map
    }
    else if (cmd.commandClass == 50) {
        def hex1 = { n -> String.format("%02X", n) }
        def desc = "command: ${hex1(cmd.commandClass)}${hex1(cmd.command)}, payload: " + cmd.parameter.collect{hex1(it)}.join(" ")
        zwaveEvent(cmd.sourceEndPoint, zwave.parse(desc, [ 0x60:3, 0x25:1, 0x32:1, 0x70:1 ]))
    }
}

def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCapabilityReport cmd) {
//	  [50, 37, 32], dynamic: false, endPoint: 1, genericDeviceClass: 16, specificDeviceClass: 1)
    log.debug "multichannelv3.MultiChannelCapabilityReport $cmd"
}

def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {
	log.debug "Configuration Report for parameter ${cmd.parameterNumber}: Value is ${cmd.configurationValue}, Size is ${cmd.size}"
}

def zwaveEvent(physicalgraph.zwave.Command cmd) {
        // Handles all Z-Wave commands we aren't interested in
        [:]
    log.debug "Capture All $cmd"
}

// handle commands
def refresh() {
	def cmds = []
 
 	for ( i in 1..3 )
    	cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:i, commandClass:37, command:2).format()
    	
    for ( i in 1..3 ) {
        cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:i, commandClass:50, command:1, parameter:[0]).format()
        cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:i, commandClass:50, command:1, parameter:[16]).format()
	}
    
    cmds << zwave.meterV2.meterGet(scale:0).format()
    cmds << zwave.meterV2.meterGet(scale:2).format()
    
    delayBetween(cmds)
}

def on(value) {
	log.debug "value $value"
	delayBetween([
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint: value, commandClass:37, command:1, parameter:[255]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint: value, commandClass:37, command:2).format()
	])
}

def off(value) {
	log.debug "value $value"
	delayBetween([
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint: value, commandClass:37, command:1, parameter:[0]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint: value, commandClass:37, command:2).format()
	])
}

def poll() {
	log.debug "Poll - Refreshing"
	refresh()
}

def configure() {
	log.debug "Executing 'configure'"
    delayBetween([
    	zwave.configurationV1.configurationSet(parameterNumber:101, size:4, configurationValue: [ 0, 0, 127, 127 ]).format(),	// Report meter on all channels (6 sockets + master)
        zwave.configurationV1.configurationSet(parameterNumber:111, size:4, scaledConfigurationValue: 120).format(),		// 120s interval for meter reports
        zwave.configurationV1.configurationSet(parameterNumber:4, configurationValue: [0]).format()				// Report reguarly
    ])
}

def on1() {
	delayBetween([
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:1, parameter:[255]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format()
	])
}

def off1() {
	delayBetween([
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:1, parameter:[0]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format()
	])
}

def on2() {
	delayBetween([
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:37, command:1, parameter:[255]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:37, command:2).format()
	])
}

def off2() {
	delayBetween([
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:37, command:1, parameter:[0]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:37, command:2).format()
	])
}

def on3() {
	delayBetween([
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:37, command:1, parameter:[255]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:37, command:2).format()
	])
}

def off3() {
	delayBetween([
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:37, command:1, parameter:[0]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:37, command:2).format()
	])
}

/**
//test
def testB() {
	def cmds = []
         cmds << zwave.multiChannelV3.multiChannelCapabilityGet(endPoint:1).format()
         cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:50, command:1, parameter:[0]).format()
         cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:50, command:1, parameter:[16]).format()
	     cmds << zwave.multiChannelV3.multiChannelEndPointFind(genericDeviceClass:32).format()
	     cmds << zwave.multiChannelV3.multiChannelEndPointGet().format()
         cmds << zwave.meterV2.meterGet(scale:0).format()
         cmds << zwave.meterV2.meterGet(scale:2).format()
        cmds << zwave.configurationV1.configurationGet(parameterNumber:101).format() 
        cmds << zwave.configurationV1.configurationGet(parameterNumber:4).format()
        cmds << zwave.configurationV1.configurationGet(parameterNumber:90).format()
	log.debug "Sending ${cmds.inspect()}"
	delayBetween(cmds, 2300)
}

def testA() {
 log.debug "testA"
 def cmds = []
// cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:50, command:1, parameter:[0]).format()
// cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:50, command:1, parameter:[16]).format()
// cmds <<		zwave.switchBinaryV1.switchBinaryGet().format()
// cmds <<		zwave.meterV2.meterGet(scale: 0).format()
cmds <<	zwave.meterV3.meterGet(scale: 0).format()
log.debug "$cmds"
delayBetween(cmds, 1000)
 }
**/
//reset
def reset() {
	def cmds = []
    cmds << zwave.meterV2.meterReset().format()
    cmds << zwave.meterV2.meterGet(scale:0).format()
    for ( i in 1..6 ) 
    	cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:i, commandClass:50, command:1, parameter:[0]).format()
        
	delayBetween(cmds)
}

@jwu … Finally! this seems to be working and updating :slight_smile:

/**
 *  Based on Aeon Smartstrip with inputs from @jwu
 *  Devive handler for TKB TZ04 dual Relay insert
 *  
 *  By using BINARY_SWITCH_SET Command of Multi Channel Command Class Encapsulateion Command, 
 *  you can switch both Relay1 and Relay2 ON/OFF by setting endpoint to 1 or switch Relay1 ON/OFF 
 *  by setting endpoint to 2 or switch Relay1 ON/OFF by setting endpoint to 3
 *  Status of Endpoint 1 returns ON when either relay 1 or 2 is ON or both or ON
 *
 *  Device is capable of metering (combined when endpoint is set to 1) and individually when set to 2 or 3
 *

 */
 // for the UI
metadata {
	// Automatically generated. Make future change here.
	definition (name: "Aeon Smart Strip", author: "jjhamb@yahoo.com") {
		capability "Energy Meter"
		capability "Refresh"
		capability "Power Meter"
		capability "Switch"
		capability "Configuration"
		capability "Polling"

		attribute "power1", "string"
		attribute "power2", "string"
		attribute "power3", "string"
		attribute "energy1", "string"
		attribute "energy2", "string"
		attribute "energy3", "string"
		attribute "switch1", "string"
		attribute "switch2", "string"
		attribute "switch3", "string"

		command "on1"
		command "off1"
		command "on2"
		command "off2"
		command "on3"
		command "off3"
		command "testA"
		command "testB"        
	}

	simulator {
		// TODO: define status and reply messages here
	}

	tiles {
        valueTile("power", "device.power", decoration: "flat") {
			state "default", label:'${currentValue} W'
		}
		valueTile("energy", "device.energy", decoration: "flat") {
			state "default", label:'${currentValue} kWh'
		}
		standardTile("switch1", "device.switch1",canChangeIcon: true) {
                        state "on", label: "switch1", action: "off1", icon: "st.switches.switch.on", backgroundColor: "#79b821"
                        state "off", label: "switch1", action: "on1", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
                }
        standardTile("switch2", "device.switch2",canChangeIcon: true) {
                        state "on", label: "switch2", action: "off2", icon: "st.switches.switch.on", backgroundColor: "#79b821"
                        state "off", label: "switch2", action: "on2", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
                }
        standardTile("switch3", "device.switch3",canChangeIcon: true) {
                        state "on", label: "switch3", action: "off3", icon: "st.switches.switch.on", backgroundColor: "#79b821"
                        state "off", label: "switch3", action:"on3", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
                }
        standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
                        state "default", label:"", action:"refresh", icon:"st.secondary.refresh"
                }
        standardTile("reset", "device.switch", inactiveLabel: false, decoration: "flat") {
        				state "default", label:"reset kWh", action:"reset"
                }
        standardTile("configure", "device.switch", inactiveLabel: false, decoration: "flat") {
        				state "default", label:"", action:"configure", icon:"st.secondary.configure"
                }
           
        valueTile("power2", "device.power2", decoration: "flat") {
			state "default", label:'${currentValue} W'
		}
		valueTile("energy2", "device.energy2", decoration: "flat") {
			state "default", label:'${currentValue} kWh'
		}
        valueTile("power3", "device.power3", decoration: "flat") {
			state "default", label:'${currentValue} W'
		}
		valueTile("energy3", "device.energy3", decoration: "flat") {
			state "default", label:'${currentValue} kWh'
		}
        

        main(["switch1", "power", "energy"])
        details(["switch1", "power", "energy", "switch2", "power2", "energy2", 
        "switch3", "power3", "energy3", "refresh", "configure", "reset"])
	}
}

// 0x25 0x32 0x27 0x70 0x85 0x72 0x86 0x60 0xEF 0x82

// 0x25: switch binary
// 0x32: meter
// 0x27: switch all
// 0x70: configuration
// 0x85: association
// 0x86: version
// 0x60: multi-channel
// 0xEF: mark
// 0x82: hail

// parse events into attributes
def parse(String description) {
	 log.debug "Parsing desc => '${description}'"

    def result = null
    def cmd = zwave.parse(description, [0x60:3, 0x25:1, 0x32:1, 0x70:1])
    if (cmd) {
        result = createEvent(zwaveEvent(cmd))
    }
    log.debug "Parsing result => '${result}'"
    return result
}

//Reports

def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
        [name: "switch", value: cmd.value ? "on" : "off", type: "physical"]
}

def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd) {
        [name: "switch", value: cmd.value ? "on" : "off", type: "digital"]
}

def zwaveEvent(physicalgraph.zwave.commands.meterv1.MeterReport cmd) {
	def map = []
    
	if (cmd.scale == 0) {
    	map = [ name: "energy", value: cmd.scaledMeterValue, unit: "kWh" ]
    }
    else if (cmd.scale == 2) {
    	map = [ name: "power", value: Math.round(cmd.scaledMeterValue), unit: "W" ]
    }
    
    map
}

def zwaveEvent(int endPoint, physicalgraph.zwave.commands.meterv1.MeterReport cmd) {
	// MeterReport(deltaTime: 1368, meterType: 1, meterValue: [0, 3, 29, 17], precision: 3, previousMeterValue: [0, 3, 29, 17], rateType: 1, reserved02: false, scale: 0, scaledMeterValue: 204.049, scaledPreviousMeterValue: 204.049, size: 4)
	 log.debug "EndPoint $endPoint, MeterReport $cmd"
    def map = []
    
    if (cmd.scale == 0) {
    	map = [ name: "energy" + endPoint, value: cmd.scaledMeterValue, unit: "kWh" ]
    }
    else if (cmd.scale == 2) {
    	map = [ name: "power" + endPoint, value: Math.round(cmd.scaledMeterValue), unit: "W" ]
    }
    
    map
}

/*
def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
	 log.debug "MultiChannelCmdEncap $cmd"
    
    def map = [ name: "switch$cmd.sourceEndPoint" ]
    if (cmd.commandClass == 37){
    	if (cmd.parameter == [0]) {
        	map.value = "off"
        }
        if (cmd.parameter == [255]) {
            map.value = "on"
        }
        map
    }
    else if (cmd.commandClass == 50) {
    	// bitAddress: false, command: 2, commandClass: 50, destinationEndPoint: 1, parameter: [33, 100, 0, 0, 0, 0, 0, 94, 0, 0, 0, 0], res01: false, sourceEndPoint: 1
        def hex1 = { n -> String.format("%02X", n) }
        def desc = "command: ${hex1(cmd.commandClass)}${hex1(cmd.command)}, payload: " + cmd.parameter.collect{hex1(it)}.join(" ")
        // Re-assign source end point 3-6 to 1-4 and 1-2 to 5-6 to sync up with the switch end points. 
        // Source end point in the message refers to always-on sockets.
        zwaveEvent((cmd.sourceEndPoint > 3) ? (cmd.sourceEndPoint-3) : (cmd.sourceEndPoint+3), zwave.parse(desc, [ 0x60:3, 0x25:1, 0x32:1, 0x70:1 ]))
    }
}
*/
def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
    log.debug "MultiChannelCmdEncap $cmd"
    
    def map = [ name: "switch$cmd.sourceEndPoint" ]
    if (cmd.commandClass == 37){
    	if (cmd.parameter == [0]) {
        	map.value = "off"
        }
        if (cmd.parameter == [255]) {
            map.value = "on"
        }
        map
    }
    else if (cmd.commandClass == 50) {
        def hex1 = { n -> String.format("%02X", n) }
        def desc = "command: ${hex1(cmd.commandClass)}${hex1(cmd.command)}, payload: " + cmd.parameter.collect{hex1(it)}.join(" ")
        zwaveEvent(cmd.sourceEndPoint, zwave.parse(desc, [ 0x60:3, 0x25:1, 0x32:1, 0x70:1 ]))
    }
}

def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCapabilityReport cmd) {
//	  [50, 37, 32], dynamic: false, endPoint: 1, genericDeviceClass: 16, specificDeviceClass: 1)
    log.debug "multichannelv3.MultiChannelCapabilityReport $cmd"
}

def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {
	log.debug "Configuration Report for parameter ${cmd.parameterNumber}: Value is ${cmd.configurationValue}, Size is ${cmd.size}"
}

def zwaveEvent(physicalgraph.zwave.Command cmd) {
        // Handles all Z-Wave commands we aren't interested in
        [:]
    log.debug "Capture All $cmd"
}

// handle commands
def refresh() {
	def cmds = []
 
 	for ( i in 1..3 )
    	cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:i, commandClass:37, command:2).format()
    	
    for ( i in 1..3 ) {
        cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:i, commandClass:50, command:1, parameter:[0]).format()
        cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:i, commandClass:50, command:1, parameter:[16]).format()
	}
    
    cmds << zwave.meterV2.meterGet(scale:0).format()
    cmds << zwave.meterV2.meterGet(scale:2).format()
    
    delayBetween(cmds)
}

def on(value) {
	log.debug "value $value"
	delayBetween([
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint: value, commandClass:37, command:1, parameter:[255]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint: value, commandClass:37, command:2).format()
	])
}

def off(value) {
	log.debug "value $value"
	delayBetween([
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint: value, commandClass:37, command:1, parameter:[0]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint: value, commandClass:37, command:2).format()
	])
}

def poll() {
	log.debug "Poll - Refreshing"
	refresh()
}

def configure() {
	log.debug "Executing 'configure'"
    delayBetween([
    	zwave.configurationV1.configurationSet(parameterNumber:101, size:4, configurationValue: [ 0, 0, 127, 127 ]).format(),	// Report meter on all channels (6 sockets + master)
        zwave.configurationV1.configurationSet(parameterNumber:111, size:4, scaledConfigurationValue: 120).format(),		// 120s interval for meter reports
        zwave.configurationV1.configurationSet(parameterNumber:4, configurationValue: [0]).format()				// Report reguarly
    ])
}

def on1() {
	delayBetween([
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:1, parameter:[255]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:37, command:2).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:37, command:2).format(),
        zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:50, command:1, parameter:[0]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:50, command:1, parameter:[16]).format(),
        zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:50, command:1, parameter:[0]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:50, command:1, parameter:[16]).format(),
		zwave.meterV2.meterGet(scale:0).format(),
    	zwave.meterV2.meterGet(scale:2).format()
	])
}

def off1() {
	delayBetween([
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:1, parameter:[0]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:37, command:2).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:37, command:2).format(),
        zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:50, command:1, parameter:[0]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:50, command:1, parameter:[16]).format(),
        zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:50, command:1, parameter:[0]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:50, command:1, parameter:[16]).format(),
		zwave.meterV2.meterGet(scale:0).format(),
    	zwave.meterV2.meterGet(scale:2).format()
    ])
}

def on2() {
	delayBetween([
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:37, command:1, parameter:[255]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:37, command:2).format(),
        zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:50, command:1, parameter:[0]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:50, command:1, parameter:[16]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format(),
		zwave.meterV2.meterGet(scale:0).format(),
    	zwave.meterV2.meterGet(scale:2).format()
    ])
}

def off2() {
	delayBetween([
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:37, command:1, parameter:[0]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:37, command:2).format(),
        zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:50, command:1, parameter:[0]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:2, commandClass:50, command:1, parameter:[16]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format(),
		zwave.meterV2.meterGet(scale:0).format(),
    	zwave.meterV2.meterGet(scale:2).format()
	])
}

def on3() {
	delayBetween([
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:37, command:1, parameter:[255]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:37, command:2).format(),
        zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:50, command:1, parameter:[0]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:50, command:1, parameter:[16]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format(),
		zwave.meterV2.meterGet(scale:0).format(),
    	zwave.meterV2.meterGet(scale:2).format()
	])
}

def off3() {
	delayBetween([
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:37, command:1, parameter:[0]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:37, command:2).format(),
        zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:50, command:1, parameter:[0]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:50, command:1, parameter:[16]).format(),
		zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:37, command:2).format(),
		zwave.meterV2.meterGet(scale:0).format(),
    	zwave.meterV2.meterGet(scale:2).format()
	])
}

/**
//test
def testB() {
	def cmds = []
         cmds << zwave.multiChannelV3.multiChannelCapabilityGet(endPoint:1).format()
         cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:50, command:1, parameter:[0]).format()
         cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:3, commandClass:50, command:1, parameter:[16]).format()
	     cmds << zwave.multiChannelV3.multiChannelEndPointFind(genericDeviceClass:32).format()
	     cmds << zwave.multiChannelV3.multiChannelEndPointGet().format()
         cmds << zwave.meterV2.meterGet(scale:0).format()
         cmds << zwave.meterV2.meterGet(scale:2).format()
        cmds << zwave.configurationV1.configurationGet(parameterNumber:101).format() 
        cmds << zwave.configurationV1.configurationGet(parameterNumber:4).format()
        cmds << zwave.configurationV1.configurationGet(parameterNumber:90).format()
	log.debug "Sending ${cmds.inspect()}"
	delayBetween(cmds, 2300)
}

def testA() {
 log.debug "testA"
 def cmds = []
// cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:50, command:1, parameter:[0]).format()
// cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:50, command:1, parameter:[16]).format()
// cmds <<		zwave.switchBinaryV1.switchBinaryGet().format()
// cmds <<		zwave.meterV2.meterGet(scale: 0).format()
cmds <<	zwave.meterV3.meterGet(scale: 0).format()
log.debug "$cmds"
delayBetween(cmds, 1000)
 }
**/
//reset
def reset() {
	def cmds = []
    cmds << zwave.meterV2.meterReset().format()
    cmds << zwave.meterV2.meterGet(scale:0).format()
    for ( i in 1..6 ) 
    	cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:i, commandClass:50, command:1, parameter:[0]).format()
        
	delayBetween(cmds)
}
1 Like

Hi again @jwu
My value tiles (power/energy) give data till two decimal places in IDE but only integer values in iOS App, any hints opn how to get decimal value in iOS?

Is there a reason the outlet 4 was left out?
Thanks

1 Like

I just added the 4th outlet in the device type if you wanted me to share it.

@Danny -
My Device handler is for TKB TZ04 dual Relay insert. Device has two relays/switches (EndPoint 2 & 3). Endpoint 1 controls both relays as a single switch. Endpoint 1 also generates meter reports for combined endpoint 2 & 3.

TZ04 Z-wave In Wall Dual Relay Switch (power meter)
http://www.tkbhome.com/?cn-p-d-253.html

@jjhamb that makes sense, I usually skim more than I read. Now that you said that I saw it in the description.

Yes, please share. Thanks!

@mcourt88 What do you need? Do you need the device type or app or what exactly?

Let me know, and I’ll post it up here.

Morgan

@thrash99er Thanks Morgan, I think I have the device type from jialong (https://github.com/jialong/smartthings/blob/master/device-types/aeon_smartstrip) so I think the other aspect I need is the app. I’ve been through this post 3 times now but I’m looking through NOOB eyes and haven’t put the correct combo together for success so I may be missing something else. I’m not sure what to do with the binder either.

Thanks for paying it forward Morgan!

-Mike