Now that we have formed a network, it’s time to verify that we can successfully send messages between our light and switch. To do this will be using simple ZCL commands to start and
First click on the serial console of the switch. At the prompt enter:
zcl on-off toggle
This builds a Zigbee Clusters Library command frame. You can tell it was constructed correctly because of the output:
Msg: clus 0x0006, cmd 0x02, len 3 buffer: 01 00 02
Cluster 0x0006 corresponds to the on-off cluster.
Command 0x02 is the toggle command and length 3 corresponds to the length of the command buffer.
The buffer is 01 for the frame control, 00 for the sequence number and 02 for the command id for toggle.
Now we want to send this command to our light. Because our light is the coordinator, we know it’s Zigbee node ID is 0x0000. Because we want to send these commands from end point 1 on the switch and to endpoint 1 on the light our command to send this would be:
send 0 1 1
Hitting enter you will see on the light that it received a message for it’s 0x0006 cluster with command 02.
T00000000:RX len 3, ep 01, clus 0x0006 (On/off) FC 01 seq 00 cmd 02 payload
On the switch, you will see it received a message as well.
T00000000:RX len 5, ep 01, clus 0x0006 (On/off) FC 08 seq 05 cmd 0B payload[02 00 ]
This is a default response as it is sent back from the light to the switch.
If we look at App Builder, you can see these messages sent in the transaction view, a ZCL: Toggle followed by a ZCL: DefaultResponse. You can look at details of each message as they are sent on the side panel. For example, if you look within the event details of the the DefaultResponse, you can see that the response is Status: SUCCESS, meaning that the message was sent and properly handled.
Because our light is our network coordinator, we know that it’s address is 0x0000. However, most of the time we can’t trust that this will be the case. We need some sort of functionality to get our switch to look for and find our light and then join with the light so that it can easily send messages to the light instead of needing to know the address of the light. Additionally, the switch and light need some means of discovering if they share common clusters, like the off-off cluster. To assist with this, Zigbee provides finding & binding as a standard means of performing just this action.
If you remember back when we created our light and switch, we added a Find and Bind plugin to each device. The Light utilized the Find and Bind Target plugin while the Switch utilized the Find and Bind Initiator plugin. With these plugins, it makes finding and binding easy. Instead of having our light looking for ZCL messages doing endpoint discovery and having to manually construct a full set of ZCL messages to be sent across our network, asking for nodes to identify themselves as well as their endpoints and clusters and then binding like clusters, the plugins will take care of it all for us.
What we will first do is make the light a find and bind target for its endpoints. This will make it monitor network traffic and look for devices which are doing Find and Bind Initiation. To do this we will enter the following command:
plugin find-and-bind target 1
This tells endpoint 1 to act as an endpoint target. You will know the command works because you will see:
Find and Bind Target: Start target: 0x00
Now on the switch we must start it as an initiator. This is a similar function, but instead of target, we use:
plugin find-and-bind initiator 1
When you enter on this, you will see traffic in both the serial window as well as the network capture window as well. The process will be complete when you see
Find and Bind Initiator: Complete: 0x00
In the serial console.
Looking at the network traffic, you can see:
1. Our switch sends out a broadcast ZCL: IdentifyQuery. This is responded to by our light.
2. Then the switch asks the light for its full EUI64 address, the light responds to this with its EUI64.
3. Then finally the switch sends a simple descriptor request to get cluster information from the light. The light responds with 5 clusters which it is server: 0, 3, 4, 5 and 6 and no clusters which it is a client.
From this information our switch with then creates binding with clusters that it matches. For the 5 server clusters on the light, it looks to see if it is a client cluster on any of those, for the switch those are clusters 3 (identify) and 6 (on-off). So if you go to the CLI of the switch and print the binding table, you will see these new bindings, which are bound to the EUI64, not just the short ID. To print the binding table, use the following command:
option binding-table print
The output will look like this:
# type nwk loc rem clus node eui 0: UNICA 0 0x01 0x01 0x0003 0x0000 (>)000B57FFFEDEA263 1: UNICA 0 0x01 0x01 0x0006 0x0000 (>)000B57FFFEDEA263
With these bindings we can then use a bsend command to tell our device to send commands to a binding for a particular endpoint.
zcl on-off toggle bsend 1
This sends a command to our bindings on endpoint 1.
With this information, we can get to the step of making our light and switch act like a light and switch. The light will turn on or off LEDs based on attribute state, while our switch will respond to a button press instead of sending commands due to CLI entries.