Aeotec DSC18103-ZWEU Z-Wave Micro Smart Switch

Here’s my device type based off the original, but made to work for this specific product (switch not dimmer) and report information correctly.

'
/**

  • Copyright 2015 SmartThings and gpsmith
  • Based on original implementation by SmartThings but fixed some of the issues.
  • Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except
  • in compliance with the License. You may obtain a copy of the License at:
  •  http://www.apache.org/licenses/LICENSE-2.0
    
  • Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
  • on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
  • for the specific language governing permissions and limitations under the License.

*/
metadata {
definition (name: “Aeon Outlet DEBUG”, namespace: “gpsmith”, author: “SmartThings and gpsmith”) {
capability "Energy Meter"
capability "Actuator"
capability "Switch"
capability "Configuration"
capability "Polling"
capability "Refresh"
capability “Sensor”

	command "reset"

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

// simulator metadata
simulator {
	status "on":  "command: 2003, payload: FF"
	status "off": "command: 2003, payload: 00"

	for (int i = 0; i <= 100; i += 10) {
		status "energy  ${i} kWh": new physicalgraph.zwave.Zwave().meterV2.meterReport(
			scaledMeterValue: i, precision: 3, meterType: 0, scale: 0, size: 4).incomingMessage()
	}

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

}

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.switch.on", backgroundColor: "#fdbc32"
          attributeState "off", label: '${name}', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff"
		}
    }

	valueTile("power", "device.power", decoration: "flat", width: 3, height: 2) {
    	state "power", label:'${currentValue} W'
	}

	valueTile("energy", "device.energy", decoration: "flat", width: 3, height: 2) {
		state "default", label:'${currentValue} kWh\n(total)'
	}
    
	standardTile("reset", "device.energy", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
		state "default", label:'reset kWh', action:"reset"
	}
	standardTile("configure", "device.power", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
		state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
	}
	standardTile("refresh", "device.power", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
		state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
	}

	main "switch"
	details(["switch","energy","power","refresh","reset","configure"])  
    //details(["switch","energy","reset","refresh","configure"])
}

}

def parse(String description) {
def result = null
def cmd = zwave.parse(description, [0x20: 1, 0x32: 3])
if (cmd) {
log.debug cmd
result = createEvent(zwaveEvent(cmd))
}
return result
}

def zwaveEvent(physicalgraph.zwave.commands.meterv3.MeterReport cmd) {
if (cmd.scale == 0) {
[name: “energy”, value: (String.format("%6.3f", cmd.scaledMeterValue)), unit: “kWh”]
} else if (cmd.scale == 1) {
[name: “energy”, value: cmd.scaledMeterValue, unit: “kVAh”]
}
else {
//log.debug “Fallen to W”
[name: “power”, value: Math.round(cmd.scaledMeterValue), unit: “W”]
}
}

`
/*
v2 didn’t seem to be working.
def zwaveEvent(physicalgraph.zwave.commands.meterv2.MeterReport cmd) {
if (cmd.scale == 0) {
[name: “energy”, value: cmd.scaledMeterValue, unit: “kWh”]
} else if (cmd.scale == 1) {
[name: “energy”, value: cmd.scaledMeterValue, unit: “kVAh”]
}
else {
debug.log “Fallen to W”
//[name: “power”, value: Math.round(cmd.meterValue), unit: “W”]
//[name: “power”, value: Math.round(cmd.scaledMeterValue), unit: “W”]
}
}
*/

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.Command cmd) {
// Handles all Z-Wave commands we aren’t interested in
//log.debug “Unhandled: ${cmd}”
[:]
}

def on() {
delayBetween([
zwave.basicV1.basicSet(value: 0xFF).format(),
zwave.switchBinaryV1.switchBinaryGet().format()
])
}

def off() {
delayBetween([
zwave.basicV1.basicSet(value: 0x00).format(),
zwave.switchBinaryV1.switchBinaryGet().format()
])
}

def poll() {
delayBetween([
zwave.switchBinaryV1.switchBinaryGet().format(),
zwave.meterV2.meterGet().format()
])
}

def refresh() {
zwave.switchBinaryV1.switchBinaryGet().format()
}

def reset() {
return [
zwave.meterV2.meterReset().format(),
zwave.meterV2.meterGet().format()
]
}

def configure() {

log.debug "Send Configuration to device"
delayBetween([

	//zwave.configurationV1.configurationSet(parameterNumber: 101, size: 4, scaledConfigurationValue: 8).format(),   // energy in kWh
    //zwave.configurationV1.configurationSet(parameterNumber: 111, size: 4, scaledConfigurationValue: 300).format(), // every 5 min      
  
    zwave.configurationV1.configurationSet(parameterNumber: 101, size: 4, scaledConfigurationValue: 4).format(),   // energy in Watts
	zwave.configurationV1.configurationSet(parameterNumber: 111, size: 4, scaledConfigurationValue: 5).format(), 	// every 5 sec
    
    zwave.configurationV1.configurationSet(parameterNumber: 91, size: 2, scaledConfigurationValue: 1).format(), 	// Send report for a 1W change
    
	zwave.configurationV1.configurationSet(parameterNumber: 102, size: 4, scaledConfigurationValue: 8).format(),	//  energy in kWh
	zwave.configurationV1.configurationSet(parameterNumber: 103, size: 4, scaledConfigurationValue: 300).format()	//  every 5 min
])

}
`

there ya go… I was going to say there’s a lot of extraneous stuff in my smart dimmer code you wouldn’t need on the micro switch… I don’t have any of them or I would’ve knocked out a handler. Does you metering stuff work? Those bits of the code look a bit wonky @Gupster

metering works fine. from memory the switch needed the newer version of the protocol and a slightly different config to actually report something. as soon as i did that it came through. I recall doing some testing, as it controls two bulbs and it gives the right total and then responds if I unscrew one.

Used this code:

works great

Interesting. So on the meter command class, there should only be one version the sensor in the switch uses technically. Though it may be say version 3, version 2 will work if no v3 specific stuff is used. Same goes for ones like sensor multi level. V5 of that class adds tons of sensor types. Aeon labs has engineering sheets for all their devices and if you don’t find one there if you go to the ZWave alliance site you can find them because they are certified. That will tell you exactly which version and what classes and whether they are secure or insecure etc. it makes writing code a lot easier because you know what to expect. That said there is always tweaking after the fact.

Cheers

Waken up an old thread. So does this mean that a DTH for Aeon Smart Switch 6 will work for the DSC18103? Including reporting power and energy?

Probably. Zwave is a standard. Where things get wonky is with manufacturer and product specific configuration setting and quirks. Give it a try. Worst case it doesn’t work. I’d try the generic zwave metering switch first though.

The good thing with aeon they publish the data sheets so it’s easy to tweak existing drivers to work for it.