First Zigbee Driver (Window Shade)

I'm trying to learn how to write Zigbee drivers, by writing one for a roller-shade motor. I've started with a template (based on the tutorial in the documentation), with a lot of empty methods and I want to try and solve the issues one at a time.

/*
First attempt at a Zigbee Driver

*/

metadata {
definition (name: "Aqara E1 Blind motor", namespace: "montyonthebonty", author: "Chris") {
capability "Actuator"
capability "Configuration"
capability "WindowShade"
capability "Battery"

    fingerprint profileId:"0104", endpointId:"01", inClusters:"0000,0002,0003,0004,0005,0006,0009,000D,0013,0102", outClusters:"000A,0019", model:"lumi.curtain.acn002", manufacturer:"LUMI", controllerType: "ZGB"
}

}

def installed() {
log.debug "installed()"
}

def updated() {
log.debug "updated()"
}

def configure() {
log.debug "Configured"
}

def open() {
log.warn "open() not yet implemented"
}

def close() {
log.warn "close() not yet implemented"
}

def setPosition(lngPosition) {
log.warn "setPosition() not yet implemented"
}

def startPositionChange(strDirection) {
log.warn "startPositionChange() not yet implemented"
}

def stopPositionChange() {
log.warn "stopPositionChange() not yet implemented"
}

def parse(String description) {
log.debug "parse: $description"
def descMap = zigbee.parseDescriptionAsMap(description)

def rawValue
switch (descMap.clusterInt) {
case 0x0102: // On/Off
if (descMap.attrInt == 0) {
   rawValue = Integer.parseInt(descMap.value, 16)
   String switchValue
   // attribute value of 0 means off, 1 (only other valid value) means on
   switchValue = (rawValue == 0) ? "off" : "on"
   // for now, always log -- normally we would offer a preference:
   log.info "${device.displayName} switch is ${switchValue}"
   // this is what actually generates the event:
   sendEvent(name: "switch", value: switchValue, descriptionText:      "${device.displayName} switch is ${switchValue}")
}
else {
   // some atribute besides 0, which we don't care about but will log
   // for now -- could also leave out if you know it's not needed:
   log.debug "0x0006:${descMap.attrId}"
}

  // In other drivers, you may have other cases here
  // For example, case 0x0008 for level, etc.

  default:
     // Probably not needed in most drivers but might be helpful for
     // debugging -- always logging for now:
     log.debug "ignoring {descMap.clusterId}:${descMap.attrId}"
     break

}
}

None of the commands do anything yet, but I'd like to try and get my head around the information that is being sent back from the device in the 'parse' function.

I know the code there treats it like a switch, but I haven't changed it until I know what I'm looking for...

Can anybody recommend any documentation that might help me interpret it?
Thanks

Chris

Ask chatgpt or whatever but tell it not to give you any code?

I learned from examples. The first thing I looked at were virtual drivers, and then I moved into apps. I didn't jump into actual device drivers at all, and just when I felt I needed to learn more about them, AI came on the scene and makes it all easier. Though I must say I now understand writing actual device drivers better because of what I learned having AI write them and following the code.

Still, examples are probably the best way to avoid using AI.

One place is Hubitat's example drivers:

Lot's of examples at @kkossev for drivers, apps as well. Careful, he might already have a driver there that can control your shade...

@chrisbvt got what I would say are the best. Hubitat's drivers generally appear solid and relatively simple (although I think they should update them a bit, the samples are looking pretty dated). @kkossev just has a ton of Zigbee drivers and when someone comes in with a new Zigbee device I recommend they check there first! :slight_smile:

I would offer that getting the perfect fingerprint for your device is important. From the device, (model and manufacturer) you can pull the full command stuff into your base driver. Once you have all the commands the device physically supports, it really helps foundationally as you structure your driver around that.

I used Chatgpt to help me create a driver for this exact device. Feel free to look at it. I hit several snags along the way that I would never have been able to solve without AI: Driver for Aqara Smart Curtain Motor E1? - #47 by Kulfsson

Thanks

That driver is exactly what I'm looking for. Reading through it, it makes sense but I can see why you used AI to put it together. I may eventually have got there, but not any time soon!

Thanks for your help!
Chris