Zwave Power Strip from AEON

No error’s get logged. I’ll open a support ticket, maybe it’s related to my github integration being broken, thanks for the suggestion!

I also have a issue with A Power Strip maybe someone here can help me with it. The issue is that in de simulator it works all fine, I can power the node’s on and off seperatly. But on my app i can only switch the node’s off.

metadata {
	definition (name: "GreenWave", namespace: "greenwave", author: "Smartthings") {
		capability "Switch"
		capability "Energy Meter"
		capability "Power Meter"
		capability "Refresh"
		capability "Configuration"
		capability "Actuator"
		capability "Sensor"

		command "reset"

		(1..6).each { n ->
			attribute "switch$n", "enum", ["on", "off"]
			attribute "power$n", "number"
			attribute "energy$n", "number"
			command "on$n"
			command "off$n"
			command "reset$n"
		}

		fingerprint deviceId: "0x1001", inClusters: "0x25,0x32,0x27,0x70,0x85,0x72,0x86,0x60", outClusters: "0x82"
	}

	// simulator metadata
	simulator {
		status "on":  "command: 2003, payload: FF"
		status "off":  "command: 2003, payload: 00"
		status "switch1 on": "command: 600D, payload: 01 00 25 03 FF"
		status "switch1 off": "command: 600D, payload: 01 00 25 03 00"
		status "switch6 on": "command: 600D, payload: 06 00 25 03 FF"
		status "switch6 off": "command: 600D, payload: 06 00 25 03 00"
		status "power": new physicalgraph.zwave.Zwave().meterV1.meterReport(
		        scaledMeterValue: 30, precision: 3, meterType: 4, scale: 2, size: 4).incomingMessage()
		status "energy": new physicalgraph.zwave.Zwave().meterV1.meterReport(
		        scaledMeterValue: 200, precision: 3, meterType: 0, scale: 0, size: 4).incomingMessage()
		status "power1": "command: 600D, payload: 0100" + new physicalgraph.zwave.Zwave().meterV1.meterReport(
		        scaledMeterValue: 30, precision: 3, meterType: 4, scale: 2, size: 4).format()
		status "energy2": "command: 600D, payload: 0200" + new physicalgraph.zwave.Zwave().meterV1.meterReport(
		        scaledMeterValue: 200, precision: 3, meterType: 0, scale: 0, size: 4).format()

		// reply messages
		reply "2001FF,delay 100,2502": "command: 2503, payload: FF"
		reply "200100,delay 100,2502": "command: 2503, payload: 00"
	}

	// tile definitions
	tiles {
		standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
			state "on", label: '${name}', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821"
			state "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
		}
		valueTile("power", "device.power", decoration: "flat") {
			state "default", label:'${currentValue} W'
		}
		valueTile("energy", "device.energy", decoration: "flat") {
			state "default", label:'${currentValue} kWh'
		}
		standardTile("reset", "device.energy", inactiveLabel: false, decoration: "flat") {
			state "default", label:'reset kWh', action:"reset"
		}
		standardTile("refresh", "device.power", inactiveLabel: false, decoration: "flat") {
			state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
		}


		(1..6).each { n ->
			standardTile("switch$n", "switch$n", canChangeIcon: true) {
            	state "off", label: '${name}', action: "on$n", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
				state "on", label: '${name}', action: "off$n", icon: "st.switches.switch.on", backgroundColor: "#79b821"
			}
			valueTile("power$n", "power$n", decoration: "flat") {
				state "default", label:'${currentValue} W'
			}
			valueTile("energy$n", "energy$n", decoration: "flat") {
				state "default", label:'${currentValue} kWh'
			}
		}

		main(["switch", "power", "energy", "switch1", "switch2", "switch3", "switch4", "switch5", "switch6"])
		details(["switch","power","energy",
				 "switch1","power1","energy1",
				 "switch2","power2","energy2",
				 "switch3","power3","energy3",
				 "switch4","power4","energy4",
                 "switch5","power5","energy5",
                 "switch6","power6","energy6",
				 "refresh","reset"])
	}
}


def parse(String description) {
	def result = null
	if (description.startsWith("Err")) {
		result = createEvent(descriptionText:description, isStateChange:true)
	} else if (description != "updated") {
		def cmd = zwave.parse(description, [0x60: 3, 0x32: 3, 0x25: 1, 0x20: 1])
		if (cmd) {
			result = zwaveEvent(cmd, null)
		}
	}
	log.debug "parsed '${description}' to ${result.inspect()}"
	result
}

def endpointEvent(endpoint, map) {
	if (endpoint) {
		map.name = map.name + endpoint.toString()
	}
	createEvent(map)
}

def zwaveEvent(physicalgraph.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd, ep) {
	def encapsulatedCommand = cmd.encapsulatedCommand([0x32: 3, 0x25: 1, 0x20: 1])
	if (encapsulatedCommand) {
		if (encapsulatedCommand.commandClassId == 0x32) {
			// Metered outlets are numbered differently than switches
			Integer endpoint = cmd.sourceEndPoint
			if (endpoint > 2) {
				zwaveEvent(encapsulatedCommand, endpoint - 2)
			} else if (endpoint == 0) {
				zwaveEvent(encapsulatedCommand, 0)
			} else {
				log.debug("Ignoring metered outlet $endpoint msg: $encapsulatedCommand")
				[]
			}
		} else {
			zwaveEvent(encapsulatedCommand, cmd.sourceEndPoint as Integer)
		}
	}
}

def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd, endpoint) {
	def map = [name: "switch", type: "physical", value: (cmd.value ? "on" : "off")]
	def events = [endpointEvent(endpoint, map)]
	def cmds = []
	if (endpoint) {
		cmds += delayBetween([2,0].collect { s -> encap(zwave.meterV3.meterGet(scale: s), endpoint) }, 1000)
		if(endpoint < 4) cmds += ["delay 1500", encap(zwave.basicV1.basicGet(), endpoint + 1)]
	} else if (events[0].isStateChange) {
		events += (1..4).collect { ep -> endpointEvent(ep, map.clone()) }
		cmds << "delay 3000"
		cmds += delayBetween((0..4).collect { ep -> encap(zwave.meterV3.meterGet(scale: 2), ep) }, 800)
	}
	if(cmds) events << response(cmds)
	events
}

def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd, endpoint) {
	def map = [name: "switch", value: (cmd.value ? "on" : "off")]
	def events = [endpointEvent(endpoint, map)]
	def cmds = []
	if (!endpoint && events[0].isStateChange) {
		events += (1..4).collect { ep -> endpointEvent(ep, map.clone()) }
		cmds << "delay 3000"
		cmds += delayBetween((1..4).collect { ep -> encap(zwave.meterV3.meterGet(scale: 2), ep) })
	}
	if(cmds) events << response(cmds)
	events
}

def zwaveEvent(physicalgraph.zwave.commands.meterv3.MeterReport cmd, ep) {
	def event = [:]
	def cmds = []
	if (cmd.scale < 2) {
		def val = Math.round(cmd.scaledMeterValue*100)/100.0
		event = endpointEvent(ep, [name: "energy", value: val, unit: ["kWh", "kVAh"][cmd.scale]])
	} else {
		event = endpointEvent(ep, [name: "power", value: Math.round(cmd.scaledMeterValue), unit: "W"])
	}
	if (!ep && event.isStateChange && event.name == "energy") {
		// Total strip energy consumption changed, check individual outlets
		(1..4).each { endpoint ->
			cmds << encap(zwave.meterV2.meterGet(scale: 0), endpoint)
			cmds << "delay 400"
		}
	}
	cmds ? [event, response(cmds)] : event
}

def zwaveEvent(physicalgraph.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd, ep) {
	updateDataValue("MSR", String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId))
	null
}

def zwaveEvent(physicalgraph.zwave.Command cmd, ep) {
	log.debug "${device.displayName}: Unhandled ${cmd}" + (ep ? " from endpoint $ep" : "")
}

def onOffCmd(value, endpoint = null) {
	[
		encap(zwave.basicV1.basicSet(value: value), endpoint),
		"delay 500",
		encap(zwave.switchBinaryV1.switchBinaryGet(), endpoint),
		"delay 3000",
		encap(zwave.meterV3.meterGet(scale: 2), endpoint)
	]
}

def on() { onOffCmd(0xFF) }
def off() { onOffCmd(0x0) }

def on1() { onOffCmd(0xFF, 1) }
def on2() { onOffCmd(0xFF, 2) }
def on3() { onOffCmd(0xFF, 3) }
def on4() { onOffCmd(0xFF, 4) }
def on5() { onOffCmd(0xFF, 5) }
def on6() { onOffCmd(0xFF, 6) }

def off1() { onOffCmd(0x0, 1) }
def off2() { onOffCmd(0x0, 2) }
def off3() { onOffCmd(0x0, 3) }
def off4() { onOffCmd(0x0, 4) }
def off5() { onOffCmd(0x0, 5) }
def off6() { onOffCmd(0x0, 6) }

def refresh() {
	delayBetween([
		zwave.basicV1.basicGet().format(),
		zwave.meterV3.meterGet(scale: 0).format(),
		zwave.meterV3.meterGet(scale: 2).format(),
		encap(zwave.basicV1.basicGet(), 1)  // further gets are sent from the basic report handler
	])
}

def resetCmd(endpoint = null) {
	delayBetween([
		encap(zwave.meterV2.meterReset(), endpoint),
		encap(zwave.meterV2.meterGet(scale: 0), endpoint)
	])
}

def reset() {
	delayBetween([resetCmd(null), reset1(), reset2(), reset3(), reset4(), reset5(), reset6()])
}

def reset1() { resetCmd(1) }
def reset2() { resetCmd(2) }
def reset3() { resetCmd(3) }
def reset4() { resetCmd(4) }
def reset5() { resetCmd(5) }
def reset6() { resetCmd(6) }
def configure() {
	def cmds = [
		zwave.configurationV1.configurationSet(parameterNumber: 101, size: 4, configurationValue: [0, 0, 0, 1]).format(),
		zwave.configurationV1.configurationSet(parameterNumber: 102, size: 4, configurationValue: [0, 0, 0x79, 0]).format(),
		zwave.configurationV1.configurationSet(parameterNumber: 112, size: 4, scaledConfigurationValue: 90).format(),
	]
	[5, 8, 9, 10, 11].each { p ->
		cmds << zwave.configurationV1.configurationSet(parameterNumber: p, size: 2, scaledConfigurationValue: 5).format()
	}
	[12, 15, 16, 17, 18].each { p ->
		cmds << zwave.configurationV1.configurationSet(parameterNumber: p, size: 1, scaledConfigurationValue: 50).format()
	}
	cmds += [
		zwave.configurationV1.configurationSet(parameterNumber: 111, size: 4, scaledConfigurationValue: 15*60).format(),
		zwave.configurationV1.configurationSet(parameterNumber: 4, size: 1, configurationValue: [1]).format(),
	]
	delayBetween(cmds) + "delay 5000" + refresh()
}

private encap(cmd, endpoint) {
	if (endpoint) {
		if (cmd.commandClassId == 0x32) {
			// Metered outlets are numbered differently than switches
			if (endpoint < 0x80) {
				endpoint += 2
			} else {
				endpoint = ((endpoint & 0x7F) << 2) | 0x80
			}
		}
		zwave.multiChannelV3.multiChannelCmdEncap(destinationEndPoint:endpoint).encapsulate(cmd).format()
	} else {
		cmd.format()
	}
}

@WEBNAR Try my device handler. It is posted a few posts up. You can also use the SmartApp if you want to have individual virtual switches that correspond to the physical switches.

I tried it but that didn’t do a thing for me also i am new to Smartthings since a couple of hours. So i don’t see the screen Virtual or Physical Switch.

How can i create a virtual switch? i don’t see the option in the app.

@WEBNAR FAQ: Creating a virtual Device

1 Like

With your app i get the following error:
java.lang.NullPointerException

I think i found it…got 1 switch working now. Needed to run your app from my phone…thanks

@michaelahess I found a way to delete an installed SmartApp from the ide.

My Locations > smartapps > “edit” button towards the top > Then click on “uninstall” on the SmartApp that is giving you problems.

Tried that, said there was an error and it couldn’t do it :frowning: sent an email to support yesterday, we’ll see if they can clean it up.

I’m pretty sure it’s my fault, instead of just uninstalling the app “the right way” I wasn’t thinking and removed all the vs’ from the app, so only the physical device was associated with the smartapp, then I deleted the vs’, then I REALLY stupidly deleted the device type, then tried to delete the parent smartapp. I’m 99% certain that put it into a WTF state and is giving me the errors.

After putting everything back “right” it wouldn’t let me create a new vs even, totally FUBAR’d it.

Support gave me an idea, and it seems to have worked. Even though the old Cooper Lee smartapp wasn’t associated with the actual smart strip devices anymore, it might be “under the hood” so I removed all smartapps linked to the strips, pollster didn’t remove even though it showed it wasn’t associated, but soon as I did that, and set the broken smartapp instances back to the strips, it let me delete the smartapp instances, then the smartapps! This also removed all the virtual switches that had been created by that app.

So now I’m going through and re-adding all the virtual switches, but after linking them with your smartapp, they aren’t updating except for showing the 4 switched outlet power levels. The previous virtual switches, which were created with the Cooper Lee app, had shown all stuff correctly, the two unswitched outlets and the power strip itself as well as the 5 actual switches.

I’m too confused at this point after all I’ve done to figure out how this happened, but after I recreate everything I’ll think it through again.

@michaelahess Hmmmm, I’m not sure what could be going on. Possibly platform issues? Are you using my device handler? Are all of its functions working?

There really isn’t much to the sync app and it is working for me on my Aeon and Philio. The virtual switches that you created are using the Simulated Energy Switch device type?

Yeah, using your device handler, everything works as it should. I’m sure it’s platform issues or something with my account, I’ve had some weird things lately. Support said there is an issue with github integration, and I have other devices that say they are associated to certain smartapps that never were.

I’m going to wipe and redo a lot of things, try to clean it all up. I’m sure it’s not your code.

Thanks erocm1231. This works very well. I did note one issue, which doesn’t matter to me, but might to others. The kWh reading is always zero for all the virtual devices as well as the SmartStrip master. The W reading is good for all.

@Sorapp The kWh reading might not actually show anything other than 0 until there is a change in its value. It kind of depends on when you started using my device type and if you were using someone else’s.

You might want to check in a few days. Also, it should set the configuration parameters for reporting automatically, but if you want to make sure, press the configure button in the app for the device.

Apparently it must accumulate over time because now, about 3 hours later, there are kWh readings. Sorry for the false alarm. Your routines are really great they do just what I wanted. Thanks again.

So, I’ve removed and recreated the virtual smartapp instances and the virtual switches. The listed states are what’s not working I guess, some say “no states found” some say just power, some say power, energy, and switch. Like it’s not syncing them completely.

Before when I was having all the other troubles, I set 8 virtual switches in the smartapp instance and assigned them to the four switches and the outlets and the master power and switch, and they all worked, I think it was actually remnants of the Cooper Lee stuff, so it was covering up other issues.

Any idea why the fresh new ones wouldn’t want to update? Or where I could look to see what they are doing or think they should be doing?

@michaelahess So my Physical / Virtual sync only supports switches named switch1, switch2, switch3, etc. My device type only has switch1, switch2, switch3, and switch4 (these are the 4 switched outlets on the strip). So with my device type and my SmartApp you can only have virtual switches with the 4 switched outlets. That is probably why it isn’t working for you.

All of the physical / virtual sync type apps I have seen work in this way. The one you were using before mine is an exception.

I don’t plan on ever syncing the “master” switch with a virtual switch because it works with SmartThings as is. I didn’t plan on syncing the two extra outlets with “virtual outlets”, but I will consider it.

Cool, good to know that’s how all these work. It’s not a big deal with the master like you said, just struck me being so different. The two outlets really don’t matter either tbh, I don’t monitor them individually. Thanks for doing this one!

@erocm1231 Eric,

wanted to thank you for your device type code and smartapp. I love the Aeon SmartStrip and it did a fantastic job with my xmas lights this past year but I had to use the default device type which was laggy and didn’t give me good readouts. I was using the old code that @cooperglee had out there. The device type worked well and I got consistent read outs but I could not use the smartapp to save my life. I had errors all over the place. So I went back to using the default device type again.

Anyways when activity picked back up in this thread I saw your code and gave it a shot tonight and everything worked flawlessly. Including the virtual switches which I notoriously have issues with. So Thank you! I’ll be looking into getting more of these for around the house!