ZigBee Abstraction Documentation!

Hey all!

We are excited to announce the release of our ZigBee Abstraction layer documentation. This should make writing and creating ZigBee DTHs easier and more productive. :smile:

Let us know what you think!!

Big thanks to @unixbeast and @Jim for getting these done!

ZigBee Reference

ZigBee DTH

ZigBee Example


Really good stuff, and seeing the general commands makes me feel better about moving to the Zigbee extraction from the raw formatted commands. A couple of questions/suggestions:

  1. Since Zigbee takes payloads in Little Endian as noted in the documentation, it would make sense to provide the equivalent of the swapEndianHex() method used often as a helper or even for the zigbee.convertToHexString() command to return the hex in Little Endian.

  2. Is there a maximum for the rate integer passed in the zigbee.setLevel()? It looks like there’s a comment in the example saying “max value” for 100 or 10 seconds, but zigbee can pass much higher values. This could enable the Gentle Wake Up app equivalent with one command to a smart bulb by passing 30 minutes in the rate portion (GE Links can accept this).

Really excited to see it keep moving forward!!!


Tim, this is great to see!

Have you guys given any thought to allowing us to send ZDO (ZigBee Device Objects) commands? I would like to have the ability to bind ZigBee devices together, create ZigBee Groups and send multicast. Maybe someone has figured out how to do this and I have just missed it. If so please point me in the right direction and I will run with it.

Anyway thanks very much for the docs and guidance they provide!!


Not supported now. If we did support it in the future it is probably way out.

That’s a good suggestion. We’re also looking at ways to make it so you can pass numerical arguments as integers so you don’t need to worry about how to format the arguments.

You’re correct that the Move to Level command accepts a wider range of values. We chose to limit it to 100 (10 seconds) for the setLevel function in an attempt to make it easier for non-ZigBee folks to use it. You are welcome to use zigbee.command to send the raw command and get access to the full range of values.


Hi John, we have thought about this and it would certainly enable some cool use cases. Unfortunately, providing access to the commands is much easier than figuring out how to expose them to app developers and users in intuitive and consistent way, especially across the non-ZigBee devices. I’m interested in hearing more about any specific use cases you have in mind though.


I have two perspectives when it comes to SmartThings one form an end user’s point of view and the other as a manufacture (the coopboss.com is one of our products).

From an end user’s perspective I would like to take advantage of more features that are baked into ZigBee. Here are a couple examples of what I would do with it:

  1. Binding ZigBee devices together: I wold like a simple way to bind devices together that can be bound together. This will give me lighting fast response to events and keep the traffic local. Imagine I have this 3 button ZigBee switch and I want it to turn off a ZigBee light or plug when I push the first button. If I could easily bind the two together with commands from my hub I would do it in a heart beat. This will give me instantaneous response to my button push and the ZigBee traffic would stay local. If the hub was off line everything would still work. The switch would also keep its binding to the hub so it can report to the hub a switch was pushed.

  2. Sending to a multicast addresses and grouping: I have several ZigBee lights and plugs directly connected to my SmartThings hub. For Christmas I set up 5 ZigBee color bulbs in our front yard pointed at a Merry Christmas sign, one more color bulb in our back yard pointed at a wreath, and I have a ZigBee power plug hooked up to a plastic Santa. I would like to group all the on/off clusters together so all I would have to do is send the off command to the groups multicast address. It would take 1/7th the traffic to turn all the devices off (one multicast packet versus 7 uni-cast packets). I would like to do the same thing with the color and level cluster so I could change all the bulbs’ colors and brightness levels with multicast packets. Today when I change the color of 6 ZigBee bulbs you should see the traffic that generates!

From a manufacture’s perspective: I would like to expand on what we did with our chicken coop door controller to illustrate my points. The CoopBoss was built from the ground up to work with SmartThings. We don’t have a separate hub or controller we sell, we completely rely on your hub. That being said we worked very hard to remove dependence on the cloud for its day to day functions (closing the door at night, open it in the morning) by including local sensors that monitor the environment. We primarily use the SmartThings custom device type to configure the CoopBoss, it allows the user to set the light levels that will trigger a close etc. Our mantra from the begging was to rely on as few external resources as possible. This is even apparent in the firmware and circuit design. You can pull the ZigBee radio out of thing and it will still boot up and close the door at sunset. I know this is overkill for a chicken coop door controller but we have been treating this project as a reference design for future projects. On a side note, if you saw my wife’s face after a mink got in and killed her chickens you wouldn’t think it was overkill. But I digress, back to my point. The following paragraph discuss one use case we have for binding a device.

The CoopBoss has an auxiliary input port on the mother board that can be connected to a second push button (we plan on offering an expansion kit down the road). We would like to have the ability bind that button’s end point to any ZigBee on / off device our customer desires. I know today we can use a SmartApp and have that button control any on/off device through the cloud, but keeping to our mantra of maximum reliability I would like to give our customers the option of binding it to another local ZigBee device so it wouldn’t be reliant on the cloud. In my manual I would explain and illustrate the difference between a locally bound ZigBee device opposed to connecting it through the cloud to say a Z-Wave device.

As you can see we use SmartThings as a portal for the management / administration of our ZigBee based device. If you supported more ZDO commands it would allow us to create a richer even more reliable solution for our customers. I think other makes and manufactures would find these features attractive as well. Another thing to keep in mind is no matter how reliable and rock solid you guys make the SmartThings cloud it is only going to be as reliable as the weakest link. In other words if a user has a problem with their router or local internet connection they are still going to have problems with cloud based commands. Solutions that require or promise high reliability should be as independent as possible!

To accomplish all this would only be a few ZDO commands and the ability to send cluster commands to multicast addresses. After all you can bind devices to the hub in the Configure method with your zdo bind command. I haven’t tried using that that to bind other devices together but I think others have and ran into road blocks. I wouldn’t be surprised if we can do all this today and its just a matter of you guys sharing a few commands with us!!

@tpmanley I want to say thanks for asking! It means a lot to me that you guys will take the time to ask us for input. I know your busy these days working on stability!!


I agree completely with John on these additional functions! Also a big thank you to @tpmanley for answering questions and responding thoughtfully to comments! Much appreciated!

To add my 2 cents on the matter: I’ve been wanting group support since the beginning. I’m using 15 Link bulbs in my basement to provide zone dimming control to a single circuit switch, and it’s noticeable the sequence that the commands trigger, as well as not uncommon for a bulb or two to not fire properly. It seems to be a big hassle to trigger 15 commands rapidly and then pass that traffic to a zigbee mesh and have it all delivered seamlessly. A single multicast message could do it all simultaneously, particularly since multicast messages would enable native scene support so one message could set multiple lights to different settings. I had setting up Groups and Scenes all coded and working at the deviceType level, but it was no use without the ability to send multicast messages to take action.

Anyway, a couple of ideas for how to integrate these concepts into the ST structure, and I completely understand the difficulty of bringing protocol specific features into a protocol agnostic, capability based system.

  1. Expose the commands and let this great developer community help figure out the use cases and structures for them. As I said, I had already created a group control SmartApp for creating groups, adding devices, removing devices, checking which devices were in what group, etc… It wouldn’t take long for developers to get the hang of it, especially with zigbee.zigbeeCommand() and zigbee.parseDescriptionAsMap() to take care of the major basics. You could quickly get an anecdotal test of whether these features are being used, working well and worth additional effort.

  2. New capabilities for Association (Bind in Zigbee parlance), Groups, Scenes that would lay the ground work for these features. The major HA protocols Zwave and Zigbee both support these in some manner. Device types handlers would handle adding specific devices to their protocol’s version of a group/scene using commands like addGroup(), removeGroup(), getGroup(), etc… Same for Association, which could allow the ST hub to directly associate zwave devices or bind zigbee devices. An attribute for these capabilities could be their protocol and a map of specific capabilities supported, so a GE Link would be zigbee, switch, switch level for bind, group, scene. A Hue might be zigbee, switch, switch level, color control for bind, group, scene. This map defines the interchangeability layer to be used by the control SmartApps to maintain ST’s protocol universality.

But what about cross-protocol and non-Zwave/zigbee? That’s the big issue and where ST’s wonderful event system could come in. If a device doesn’t support these directly or is not the same protocol, the Association/Group/Scene app could fall back on a simple event driven approach. Association would be a simple link like Big Switch that simply connects the same capability on two devices: Device A switch on -> turn on device B. Group would basically be Dim With Me with a virtual child built to the lowest capability of the group: all dimmers would get a virtual dimmer child, all color devices would get a virtual color dimmer child. Scene would be a virtual momentary as the trigger with some info about scene state. Again, I think the community would get this sorted very quickly.

I know it is complex, especially adding capabilities; but if the bind and multicast can be exposed, I think all of the necessary functionality to make great SmartApps already exists.

Sidenote/wish: I believe we would need the ability to send the multicast messages from a SmartApp eventHandler or virtual device; whereas today you can only send zigbee messages from within an actual zigbee device. I really wish I could send zigbee commands from a virtual device already. With the raw commands, I can address the zigbee command where I need it to go, and it would allow me to provide additional functionality to devices without requiring a user to use a custom devicetype. With v2 hub, going custom loses the user functionality; but there are features that are better handled at the hardware level (like the gentle wake up using a 30 minute rate in the setLevel command :wink:).

Thanks again! I apologize if I minimized a significant undertaking. I’m not an engineer or developer by trade, and the programmers here always give me quite the eye roll when I suggest something is simply a couple of new If/Then statements :smile:


Thanks for the awesome feedback @JohnR and @Sticks18. Your use cases make a lot of sense and your suggestions are along the same lines of what I was thinking. My wife had a baby yesterday so I don’t have time to respond in much detail right now :grinning:, but keep the feedback coming.


Congratulations on the little one!! Hope everyone is healthy and recovering well!

Been there just recently myself. Taking my 7 week old to see Santa today!

Cheers and Happy Holidays!

1 Like

ZigBee group broadcast (some devices still don’t support ZigBee Pro/multicast…) would be fantastic for sure.

Another thing I would love to see would be a method that’s called on device announce. This could be rigged to restore the previous state of a smart bulb after power failure, for example. This might not even be that hard to implement.


Can you please elaborate on this? Do you have a list of ZigBee HA devices that don’t support multicast addressing?

I don’t have a list, but I remember that some LIGHTIFY devices I tested didn’t support multicast. That’s surprising to me because they are fairly new. There was something else but I can’t remember right now.

Anyway I think broadcast is a better fit for the SmartThings hub. While multicast makes sense for something like a light switch to light bulb, for the hub to light bulb the number of hops shouldn’t be limited because the hub could be at one end of the network and the bulb on the other. Groups work just fine with broadcast.

1 Like

So when you say groups work just fine with broadcast I’m not following the logic. Group address are multicast address right. So when you send a packet to a multicast address (group ID) the 64bit IEEE address is 0xFFFF FFFF and the 16bit network address is actually the groupID. Maybe your calling this a broadcast because the IEEE address is 0xFFFF FFFF?

When I refer to a broadcast I’m talking about setting the 64bit IEEE address to 0xFFFF FFFF or the short cut of 0x0000 FFFF and the 16 bit network address to one of these settings:

  • 0xFFFC = broadcast to all routers
  • 0xFFFD = broadcast to all non-sleepy devices
  • 0xFFFE = network address unknown but I know the IEEE address
  • 0xFFFF = Broadcast to all devices. Caution: this will wake up sleeping devices to receive the packet.
1 Like

Group messages can either be broadcast or multicast. When multicast, the number of hops is limited (to whatever you want) and with broadcast it’s not. The idea behind multicast is that on a large network you can limit the radius (range) of a broadcast message.

The frame control field in the NWK header has the bit which determines if it’s unicast/broadcast or multicast. The group address is located in the APS header. Here is an example capture of a group broadcast from the switch that I made. You can see the destination address is 0xFFFF (broadcast), the group address is 0x384F, and the multicast bit is not set.

1 Like

Ahh, I see. My radio’s firmware has a multicast packet type I’m supposed to use when sending to groups. I don’t have to set that bit in the header the packet type does it for me. I guess since your seeing it with your sniffer its an acceptable practice to send broadcast messages to group addresses?

Thanks for the response! Good stuff!!

Yeah that’s the way Z-Stack does it too. You set the shortAddr to the group ID, and the addrMode to AddrGroup. But in reality the packet doesn’t use the group ID as the destination short address.

And yes I have seen other devices send group packets using the broadcast address; in order for all devices to see it it needs to be broadcast. You could unicast it I suppose but there wouldn’t be much point.

With Z-Stack it sends it as a multicast or broadcast packet depending on the MULTICAST_ENABLED compiler define.

1 Like

I’m working on a new ZigBee device type and I want to use the new methods as recommended in this documentation. My device uses the level cluster on three unique end points (0x38, 0x39, 0x40). The way I send the commands today is with the st cmd, it allows me to select the destination end point. In the example below the 0x38 is the endpoint for the level command. This works great today!

def cmds = []
cmds << "st cmd 0x${device.deviceNetworkId} 0x38 8 0 {${level} 0000}"

However, with the new zigbee.setLevel(value) command I don’t see an option to set the destination end point for the command. I checked the new documentation and I don’t see anything about sending commands to unique end points for any of the new commands. Is there an overload method for the zigbee.setLevel() command that would allow me to send these cluster commands to unique endpoints? Maybe its just not documented or I’m missing it in the current documentation?



The current API doesn’t provide a way to override the default endpoint which is generally the lowest numbered one. You’ll need to keep using st cmd for the time being. I’ll talk to the team here about updating the API to allow you to specify a different endpoint.


Thanks Tom! I think this same issue was coming up for some Osram lights too where the default endpoint didn’t contain the primary function clusters, so endpoint addressing or specifying could be important for mass produced devices too.

In the case of the Osrams, the stock style devicetypes weren’t working; but simply changing the endpoint variable to a constant 3 got them working.

1 Like