ZigBee CLI Programming
For testing purposes, you may want to understand the optional Command Line Interface (CLI) of the ZigBee stack. For its commands to make sense, you'll also need to understand several key concepts that we touch on below.
In the ZigBee introductory article, we talked about coordinators, routers, nodes, and devices and their place in the overall network. Here we will focus on the endpoints within a device. Each ZigBee packet is specified for an application and for a device.
PAN ID – The Personal Area Network (PAN) ID has to be identical in each device on the network. The coordinator comes up with this value randomly and passes it to joiners. Multiple ZigBee networks can be overlaid, each with a different PAN ID, and there will be no "eavesdropping" possible between networks.
Channel and Power – Networks can be formed on different IEEE 802.15.4 frequency channels, and at a specified transmission power. Reducing power during joining may reduce the risk of an unwanted nearby joiner.
Node – the role played by the device within the ZigBee network.
» coordinator node
» router node
» end node
» sleepy end node
A node could comprise one or several devices.
Device – a defined type within the ZigBee specification.
» HA On/Off Swtich
» Dimmable Light
Any given device type has multiple clusters that are also defined by the specification.
Endpoint – represents a device in a node logically; one node can contain multiple endpoints. For example, to identify and communicate with them, a node might implement multiple switch endpoints:
» endpoint 6 to control lights in the master bedroom
» endpoint 8 to control lights in the living room
» endpoint 12 to control lights in the kitchen.
Cluster – defines a characteristic of an endpoint, as numbered by the ZigBee specification, for that device type. Multiple clusters make up the full device definition.
server cluster: attributes that hold and return data such as that from a sensor
client cluster: commands that can request something to a
For example, typing the
info command into the
Z3Light CLI returns these clusters for endpoint 1.
in (server) cluster: 0x0000 (Basic) in (server) cluster: 0x0003 (Identify) in (server) cluster: 0x0004 (Groups) in (server) cluster: 0x0005 (Scenes) in (server) cluster: 0x0006 (On/off)
Z3Switch the list looks like this:
in (server) cluster: 0x0000 (Basic) out(client) cluster: 0x0003 (Identify) in (server) cluster: 0x0003 (Identify) out(client) cluster: 0x0006 (On/off)
Note the matching
Identify clusters, meaning these Switch clusters can command the corresponding Light clusters.
Binding – a table entry tying together like clusters on different devices. Binding is static, so that commands can be sent even after cycling power off and on. Each entry contains:
» local endpoint number
» remote permanent address (EUI64 – the remote device MAC address)
» remote endpoint number.
The binding table is maintained locally by each device.
Commissioning – a way to automatically perform multiple necessary operations between devices.
» form a network and permit joining (only for role of coordinator), or
» scan for a network and join it
» bind an initiator and a target
(for example, binding
Commissioning defines the Initiator and Target.
Initiator – an endpoint that has at least 1 cluster that initiates operational transactions, like the
On/off command of
Target – an endpoint that has at least 1 cluster that is a target of operational transactions, like the
On/off attribute of
EZ-Mode commissioning is a way of implementing commissioning defined by the original HA specification. ZigBee 3.0 defines other ways. Users can instead provide their own custom commissioning.
The history of ZigBee has resulted in a complex patchwork of commissioning methods.
In the original Home Automation profile
Coordinator sets up a new network when you issue these commands:
net find unused
net pjoin 60
Other devices join when you issue:
net find joinable
EZ-Mode commissioning is also part of that profile.
ZigBee 3.0 introduces improved mechanisms.
- Network Steering
- Find and bind for Target and Initiator
These are beyond the scope of this article; refer to Silicon Labs guides (in Simplicity Studio – Documentation) for details. But be aware that:
ZigBee 3.0 security may not work with older devices using HA profiles.
When you build a project in Simplicity, you can specify the security as mentioned here.
Using the CLI
In the introductory article, you saw how to quickly connect devices automatically. Now we'll try it one step at a time with the command line interface (CLI). You'll later send ZCL light on-off commands this way.
Start with boards prepared as follows.
|ARTIK 030 boards||Launch consoles in Simplicity. Pre-load each device function as either Z3SwitchSocHA or Z3LightSocHA.|
|ARTIK 5/7/10 boards||Use the terminal emulator to:
1. Enable a journal (or else you won't see any CLI output)
2. Start the daemon
Here we manually create a network and join it. The software stacks are still doing most of the work, but you have to use the somewhat wordy CLI interface to get things going.
To find out whether any devices are already connected, type
on each console, and look to see whether
We want to start fresh, so we want them to not match. In each console, type
Verify, using a subsequent
infocommand, that the
panIDvalue for any one device no longer matches that of another.
On the device you have chosen to be Coordinator, type
network find unused
Remember that this won't work on an A030 with the pre-built images, which were built without Coordinator capability enabled.
Again on the Coordinator, type
network pjoin 90
to permit joining for 90 seconds by other devices.
On each of the other devices, type
network find joinable
You should see the "Device Announce" message on each console.
It's worth trying this exercise several times in different configurations to make sure you understand how it works. If you're on top of it and want to skip the additional details below, jump right to entering a ZCL command.
Let's review how this all works. You can use various combinations of ARTIK 030, 5, 7, and 10 devices, along with other ZigBee-compatible devices, for a ZigBee network. Interacting with the different devices is mostly the same aside from some "shortcut" differences.
All ARTIK ZigBee devices use the same CLI commands, although you could choose to remove this extension in your own custom code to save space.
The ARTIK 030 code for Z3Switch and Z3Light enables the CLI through the Simplicity console, which is very interactive and provides a lot of feedback. The code also configures the buttons on the board for shortcut methods as explained below.
The ARTIK 5/7/10 support is provided by an API, which we interact with using two utility programs:
zigbee-testprovides shortcut methods similar to the A030 board, but uses the console numeric keys instead
zigbee-cliimplements the same CLI as the Simplicity console, but requires a journal to be enabled if you want to see its output.
If you're wondering where the ARTIK 5/7/10 list in zigbee-test comes from, it's in the ZigBee API example code.
Note that the ARTIK 5/7/10 shortcut key
 first forms the network, and then does a one-time
pjoin. If you later want to let more devices join, use
 to start another
pjoin or do it manually in
Using the CLI, have the Switch on ARTIK 5/7/10 form a network on channel 25, power 3, PAN ID of 0xabcd, and give the ARTIK 030 Light 15 seconds to join.
On ARTIK 5/7/10 Switch:
zigbee-cli ON_OFF_SWITCH network leave network form 25 3 0xabcd network pjoin 15
On ARTIK 030 Light:
network leave network find joinable
You should see an indication on the ARTIK 030 console that it has joined PAN 0xabcd.
If you were successful, feel free to jump right to entering a ZCL command.
In the example above, the ARTIK 5/7/10 Switch is the Coordinator and the ARTIK 030 Light is a simple router. Even though the router cannot form a network, it can become a parent to local end devices.
Let's say you have a smart button that you want to add to the existing network. The button uses all the same commands as you've seen above, but implements them using hardware "tricks" since it has no connection to a terminal console.
Start from A030 Z3 Light in a formed network, as explained previously.
Delete button network
Force the smart button to leave any existing network.
- Pry out battery drawer
- Hold down on button
- Reinsert battery (you'll get a steady red LED)
- Keep button held for 2 seconds ("network leave")
Join button to network
Set the ARTIK 030 Z3Light to permit joining.
network pjoin 30
Command the smart button to join.
- Pry out battery drawer again
- Hold down on button
- Reinsert battery but RELEASE button immediately after LED turns red
("network find joinable")
- Observe that the LED turns a dim blue and blinks
- Verify that it finds the network and the LED turns green to indicate NETWORK_JOINED
Bind button to light
Under ZigBee 3.0, the switch joined to the network through the Z3Light can immediately be bound to the light.
Command the smart button to send a join request and identify query.
Tap the button three times rapidly
Watch the action on the ARTIK 030 LED and the terminal emulator console.
The button is now bound to the light, and you can control the LED.
When you press the button, you'll now see a message like this on the ARTIK 030 console to indicate ON:
Rx len 3 ep 01 clus 0x0006 (on/off) FC 01 seq 72 cmd 01
and one like this to indicate OFF:
Rx len 3 ep 01 clus 0x0006 (on/off) FC 01 seq 73 cmd 00
It may take a few tries for you to understand the sequence. Note also that some of these buttons have known battery contact issues. But once you get around those you'll find this sequence is reliably reproducible.
For your convenience, we summarize the example smart button controls in this table. Some are undocumented; we report only what we have seen during testing.
|Prior State||Action||Smart Button Function|
|Joined to previous network||Insert battery with button held 2s
(make sure no devices are permitting joining at this time)
(LED steady red)
|Not joined||Insert battery with button held; release immediately on seeing red||
(LED flashes blue )
|Joining||Coordinator permits join||Joined but not bound
(LED steady green then off)
|Joined but not bound||Tap button 3x||
|Joined but not bound||Tap button 5x||issues "rejoin request", "update device", and "device announce"|
|Joined and bound||Press button||
|Joined and bound||Release button||
If you have trouble getting ZigBee networks set up, make sure you have used
network leave (or a known hardware equivalent) on all devices to tear down previous networks before starting a fresh one. Pressing a device reset button alone is generally not sufficient.
Before starting the
zigbee-cli program, you can run this command to provide debug output that "follows" events live, as they occur.
journalctl -f | grep zigbeed &
You'll get messaging to help track down issues.
Running the journal is the only way to see output from the
You may find that the On/Off test of the
zigbee-testprogram will incorrectly report "there is no endpoint to send on/off command" unless you run the journal.
An alternative use of the command:
journalctl -f -o"cat" &
strips off the date stamp for cleaner output. You can't pipe this one to
grepsince it strips off the sort term "zigbeed", so you will also see other system events.
You can instead simply dump the output of
journalctl to a file to review it at any time (not following it live).
The following information refers to features of the Simplicity Studio application code referenced in our ZigBee articles. Interpreter support for these commands is not guaranteed to be available in other ZigBee applications.
We present below the CLI commands as supported by the Z3… application code.
The general serial commands on all devices are:
• help—shows what top-level commands are available
• version—gives the stack and application version
• info—gives information about the local node
• network form [channel] [power] [panid in hex]
• network join [channel] [power] [panid in hex]
• network leave
• network pjoin [time]
• print attr—print the ZCL attribute table
• print identify—print the identify cluster state
• print groups—print the groups table
• print scenes —print the scenes table
• print c (ias-ace info)—print the ias-ace info
• print report—print the reporting table
• write [cluster] [attrID] [dataLen] [data]
• stats—if HA_ENABLE_STATS is defined, then this command shows the number of received and transmitted messages
Save keytrokes by typing only enough characters to make the keyword unique. For example, instead of
network leave try
In addition, you may find the CLI examples in this User Guide to be helpful.
in the documentation folder:
The ZigBee Cluster Library (ZCL) standard is defined by the ZigBee Alliance to be for use by alliance members only.
We present below the ZCL commands supported by the CLI.
The following are CLI serial commands used for clusters. They construct a payload, so you must issue a
send call to send the message. That is, commands will be paired like this:
zcl ... send [Node ID] [src endpoint] [dst endpoint]
The following are global serial commands used for clusters.
• zcl global read [cluster] [attrID:2]
• zcl global write [cluster] [attrID:2] [type] [data]
• zcl global uwrite [cluster] [attrID:2] [type] [data]
• zcl global nwrite [cluster] [attrID:2] [type] [data]
• zcl global discover [cluster] [attrID:2] [max # to report]
• zcl global report-read [cluster] [attrID:2] [direction:1]
• zcl global send-me-a-report [cluster] [attrID:2] [type:1] [min:2] [max:2] [chg:1-4]
• zcl global expect-report-from-me [cluster] [attrID:2] [timeout:2]
There are also cluster-specific serial commands that are available on a per-cluster basis. The application must have defined the client side of the cluster to have access to all these commands.
• zcl basic rtfd
• zcl identify id [identify time:2]
• zcl identify query
• zcl groups add [grp ID:2] [name:16]
• zcl groups view [grp ID:2]
• zcl groups get [count:1] [[groupID:2] * count]
• zcl groups remove [grp ID:2]
• zcl groups rmall
• zcl groups ad-if-id [grp ID:2] [name:16]
• zcl scenes add [groupId:2] [sceneId:1] [trans time:1] [name:n]
• zcl scenes view [groupId:2] [sceneId:1]
• zcl scenes remove [groupId:2] [sceneId:1]
• zcl scenes rmall [groupId:2]
• zcl scenes store [groupId:2] [sceneId:1]
• zcl scenes recall [groupId:2] [sceneId:1]
• zcl scenes get-membership [groupId:2]
• zcl scenes set [on/off:1 boolean] [level:1 int]
• zcl on-off off
• zcl on-off on
• zcl on-off toggle
• zcl level-control mv-to-level [level:1] [trans time:2]
• zcl level-control move [mode:1] [rate:2]
• zcl level-control step [step:1] [step size:1] [trans time:2]
• zcl level-control stop
• zcl level-control o-mv-to-level [level:1] [trans time:2]
• zcl level-control o-move [mode:1] [rate:2]
• zcl level-control o-step [step:1] [step size:1] [trans time:2]
• zcl level-control o-stop
• zcl tstat set [mode:1 int] [amount:1 int]
• zcl ias-zone enroll [zone type: 2 int] [manuf code: 2 int]
• zcl ias-zone sc [zone status: 2 int] [ext status: 1 int]
• zcl ias-ace arm [mode: 1 int]
• zcl ias-ace bypass [numZones: 1 int] [zone: * int]
• zcl ias-ace emergency
• zcl ias-ace fire
• zcl ias-ace panic
• zcl ias-ace getzm
• zcl ias-ace getzi
The following command is unique.
• zcl raw [cluster] [len] [data 0-8] [data 9-16] [data 17-24] [data 25-32]
Once devices are joined, you can start sending ZigBee ZCL commands to them.
info shows what server and client clusters are supported by a device.
print attr (or the shorthand version
prints the attribute table that shows the cluster and attribute information. This is useful when sending read attributes commands.
To create and send a read attributes command, use:
zcl global read <clus> <attr>
send <addr> <src> <dest>
where < addr > and < attr > are in hex but other parameters are often in decimal. To determine the short address < addr > of a device to send to, use the
info command and look for nodeID.
For instance, to create a read attributes for basic cluster (0), attribute ZCL version (0000), and send to Node ID 0xaabb:
zcl global read 0 0000 send 0xaabb 0 0
As another example, if the command
print a shows this:
idx clus / attr /type(len)/ rw / data 00: 000A / 0000 / 23 (04) / WRITE / 00 01 50 05 (time)
then reading that attribute on a device with shortID/Node ID 0x5AAF is done as follows:
zcl global read 10 0000 send 0x5aaf 0 0
The result will be as follows:
RX len 0B, clus 0x000A (time) FC 00 seq 00 cmd 01 payload[00 00 00 23 B8 50 01 00 ]
The payload is attribute ID (0x0000), status (0x00), type (0x23), and value (0x00 01 50 B8)
If you are daring, you may even want to try manually issuing
zdo bind commands to bind a switch and a light. The format is difficult and awkward, and the newer ZigBee 3.0 features tend to make manual operations like this unnecessary. Refer to online Silicon Labs documentation for more information on ZDO commands.