Sample Application Startup Guide
Overview
This guide will show you how to complete a CLI-driven demo of Gateway API's zigbee features. After reviewing these steps, you will be able to form a zigbee network and communicate with third-party zigbee devices.
Prerequisites
To Complete the Demo With a RapidConnect Gateway
You'll need:
- RapidConnect Gateway loaded with RapidConnect v3.0.8 or higher and the latest Gateway API Standalone JAR. Both of these should be pre-loaded by MMB.
To Complete the Demo With a RapidConnect USB Stick
You'll need:
- macOS, Windows, or Linux environment that can run Java.
- Java Runtime Environment, recommended version 1.8.
- Latest release of the Gateway API Standalone JAR, which is available here.
- RapidConnect USB Stick loaded with RapidConnect v3.0.8 or higher.
- Install the driver for the RapidConnect USB Stick. It is available under the heading "Step 1: Install Hardware Drivers" here.
Interacting with the GatewayClient API
After you have completed the steps shown above, the Sample App will instantiate a GatewayClient object, which will automatically connect to the RapidConnect hardware, configure it as a "Combined Interface" Zigbee device, and form a network. Once this has happened, you can type 'h' to see a list of commands:
Available Commands: ==== General Commands ==== h - help toggleLog - turn logging on/off q - quit v - get version n - network information d - list devices and their device ids ==== Gateway Client ==== f - form network p - permit join (30 sec) c - close network permit join window l - dissolve network getDevicesOfType - get a list of devices of a certain type ==== Device Commands ==== getDeviceType - get the device type of a device getProperties - get properties for a selected device id. Will perform a network request getCachedProperties - get last known properties for a selected device id. Will be empty if there are no last cached properties getProtocolProperties - gets the properties of the device in the format of the underlying protocol (i.e. zigbee). Will perform a network request getCachedProtocolProperties - gets the last known properties of the device in the format of the underlying protocol (i.e. zigbee). Will be empty if there are no last cached properties getProperty - get a specific property. Will perform a network request getCachedProperty - get the last known value of a specific property. Will be empty if there is no last known value. Will throw exception if property doesn't exist updateProperty - update a specific property for a selected device id discoverAll - perform a full discovery of all properties on a device over the network (warning: can be slow) getConnectedGatewayId - get the ID of the Gateway that this Device is connected to bind - bind a source to a destination unbind - unbind a source to a destination enableReporting - enable reporting on properties using default parameters addSwitchHandler - map a switch device to a group id addToGroup - add a device to a group removeFromGroup - remove a device from a group kickDevice - kick a remote device off the network removePropertyListeners - remove property update listeners for the selected device ping - ping a remote device to get its round trip latency registerOtaFile - register an OTA file on the server deregisterOtaFile - deregister an OTA file from the server getRegisteredOtaFiles - get the registered OTA files on the server startOtaUpgrade - notify the remote device that an OTA image is available for upgrade abortOtaUpgrade - abort an ongoing OTA upgrade registerOtaProgressHandler - register the OTA upgrade progress handler, which displays upgrade progress deregisterOtaProgressHandler - deregister the OTA upgrade progress handler, which stops displaying upgrade progress ==== Light Commands ==== on off moveToLevel - change the dimmable light level readLevel - read the dimmable light level ==== Thermostat Commands ==== readSystemMode - read the system mode, i.e. heat, cool, auto, off, etc. readFanMode - read the fan mode, i.e. off, auto, etc. readRunningMode - read the running mode of the thermostat changeSystemMode - change system mode, i.e. heat, cool, auto, off, etc. changeFanMode - change the fan mode, i.e. off, auto, etc. readOccupiedCoolingSetpoint - read the cooling setpoint readOccupiedHeatingSetpoint - read the heating setpoint setOccupiedCoolingSetpoint - set the cooling setpoint to a specific temperature setOccupiedHeatingSetpoint - set the heating setpoint to a specific temperature adjustOccupiedSetpoint - adjust the heating or cooling setpoint up or down by a specific amount ==== Zigbee Commands ==== readAttribute - read a zigbee attribute, knowing the cluster id and attribute id writeAttribute - write a zigbee attribute, knowing the cluster id, attribute id, data type, and byte values sendZclCommand - send a zcl command, knowing the command id, payload bytes, and cluster id sendZclMulticastCommand - send a zcl multicast command, knowing the group id, command id, payload bytes, and cluster id sendZclBroadcastCommand - send a zcl broadcast command, knowing the broadcast address, command id, payload bytes, and cluster id Enter a command:
Forming a Network
When the GatewayClient is instantiated, it will automatically form a network on the best available channel.
Permit Join
Type 'p' to open the Permit Join Window for 30 seconds.
Enter a command: p ... Information for connection /dev/tty.SLAB_USBtoUART is [status=NETWORK_UP, channel=20, id=0xACBF]
Joining a Device
To join a device, ensure that you have followed its commissioning process (e.g. specific sequence of button presses). Take note of the device ID when it connects. If you don't have any devices available, you can use RapidConnect Desktop to configure a unit of RapidConnect hardware as a Dimmable Light, and then Join the Network after you've opened the Permit Join window on the GatewayClient.
... Device Event: ADD Device: 0024460000153f47_1 ...
Get Devices on the Network
You can always type 'd' to get a list of all connected devices and their ID's, types, and device categories that they belong to.
You can also filter by specific device type, such as Dimmable Light, Thermostat, etc.
Enter a command: d 1) Device Id: 0024460000153f45_1, Type: Occupancy Sensor, Category: Lighting 2) Device Id: 0024460000153f46_1, Type: Thermostat, Category: HVAC 3) Device Id: 0024460000153f47_1, Type: Dimmable Light, Category: Lighting ... Enter a command: getDevicesOfType Enter a device type (i.e. light, thermostat, occupancy sensor, combined interface, etc): dimmable light 1) Device Id: 0024460000153f47_1, Type: Dimmable Light, Category: Lighting
Device Properties
When a Device joins the network, only minimal properties are known about it. Users of the API must specifically request certain properties from the remote device before they can interact with them further (such as binding, or configuring reporting, etc).
There are two ways of doing so: 1) discovering all the properties on the remote device, or 2) reading specific properties on the remote device on an as-needed basis.
Get All the Properties of the Remote Device
Type 'discoverAll', and enter the Device ID from above to trigger a read of the all the properties of the remote device. Note that this can be slow if the remote device has many properties, and/or is a sleepy end-device. This method typically wouldn't be called more than once, if at all, in a production application.
In the case of a Light device, this is what you would see.
Enter a command: discoverAll Enter a device id: 0024460000153f47_1 Performing discovery of all properties (can take a while)... Enter a command: Property update triggered for device: 0024460000153f47_1 Property: CurrentLevel, value: 0, type: percentage Discovered: name: CurrentGroup, value: 0, type: SGroupId Discovered: name: ApplicationVersion, value: 21, type: uint8 Discovered: name: ManufacturerName, value: MMB Research, type: string Discovered: name: NameSupport, value: 0x00, type: map8 Discovered: name: SceneCount, value: 0, type: uint8 Discovered: name: IdentifyTime, value: 0, type: uint16 Discovered: name: CurrentLevel, value: 0, type: percentage Discovered: name: PowerSource, value: SinglePhaseMains, type: PowerSourceEnum Discovered: name: ZCLVersion, value: 2, type: uint8 Discovered: name: ModelIdentifier, value: RapidConnect, type: string Discovered: name: HWVersion, value: 8, type: uint8 Discovered: name: CurrentScene, value: 0, type: uint8 Discovered: name: SceneValid, value: false, type: bool Discovered: name: StackVersion, value: 2, type: uint8 Discovered: name: onOff, value: false, type: boolean
Get Specific Properties of the Remote Device
In order to avoid requesting all the properties of a device (which can be slow) you can request specific properties by using 'getProperty'. If a specific property doesn't exist on the remote device, you will simply get an error. If a property does exist, it will be added to the known list of Property objects for the Device, returned to the application, and its last known value will be cached.
Enter a command: getProperty Enter a device id: 0024460000153f46_1 Enter a property name: localTemperature Retrieving property 'localTemperature' Property update triggered for device: 0024460000153f46_1 Property: localTemperature, value: 23.0, type: celsius ... Enter a property name: occupiedHeatingSetpoint Retrieving property 'occupiedHeatingSetpoint' Property update triggered for device: 0024460000153f46_1 Property: occupiedHeatingSetpoint, value: 20.0, type: celsius ... Enter a property name: occupiedCoolingSetpoint Retrieving property 'occupiedCoolingSetpoint' Property update triggered for device: 0024460000153f46_1 Property: occupiedCoolingSetpoint, value: 26.0, type: celsius ... Enter a property name: systemMode Retrieving property 'systemMode' Property update triggered for device: 0024460000153f46_1 Property: systemMode, value: auto, type: systemModeEnum ... Enter a property name: thermostatRunningMode Retrieving property 'thermostatRunningMode' Property update triggered for device: 0024460000153f46_1 Property: thermostatRunningMode, value: off, type: runningModeEnum name: thermostatRunningMode, value: Off, type: enum8 ... Enter a property name: fanMode Retrieving property 'fanMode' Property update triggered for device: 0024460000153f46_1 Property: fanMode, value: auto, type: fanModeEnum name: fanMode, value: Auto, type: enum8 ... Enter a property name: fanModeSequence Retrieving property 'fanModeSequence' name: fanModeSequence, value: OnAuto, type: enum8 ...
Getting last known (cached) values of Properties
Once Properties have been discovered or read at least once, the Device will store a list of them, as well as their last known values.
Enter a command: getCachedProperties Enter a device id: 0024460000153f46_1 name: fanMode, value: auto, type: fanModeEnum name: occupiedCoolingSetpoint, value: 26.0, type: celsius name: localTemperature, value: 23.0, type: celsius name: thermostatRunningMode, value: off, type: runningModeEnum name: systemMode, value: auto, type: systemModeEnum name: occupiedHeatingSetpoint, value: 20.0, type: celsius name: FanModeSequence, value: OnAuto, type: FanModeSequenceEnum
You can also get the last known (cached) value of a specific property
Enter a command: getCachedProperty Enter a device id: 0024460000153f46_1 Enter a property name: localTemperature name: localTemperature, value: 23.0, type: celsius
Refreshing Known Properties from the Network
Once Properties have been discovered or read at least once, the Device will store a list of them and their last known values. To refresh the known list of Properties and get their values from the remote device, you can use 'getProperty' or 'getProperties'.
Enter a command: getProperties Enter a device id: 0024460000153f46_1 Retrieving properties... name: fanMode, value: auto, type: fanModeEnum name: protocolProperty, value: {"nodeId":"0xb694","endpointId":"0x01","appProfileId":"0x0104","appDeviceId":"0x0301","appDeviceVersion":"0x01","eui":"0x0024460000153f46","protocol":"zigbee"}, type: json name: occupiedCoolingSetpoint, value: 26.0, type: celsius name: localTemperature, value: 23.0, type: celsius name: thermostatRunningMode, value: off, type: runningModeEnum name: systemMode, value: auto, type: systemModeEnum name: occupiedHeatingSetpoint, value: 20.0, type: celsius name: FanModeSequence, value: OnAuto, type: FanModeSequenceEnum ... Enter a command: getProperty Enter a device id: 0024460000153f46_1 Enter a property name: occupiedHeatingSetpoint Retrieving property 'occupiedHeatingSetpoint' name: occupiedHeatingSetpoint, value: 22.0, type: celsius
This concludes the basic GatewayClient API demo. To use the sample CLI application to interact with Devices, see the Device API section below.
Device API
Note that this API is currently under active development and subject to change.
The Device API consists of a "Generic API", as well as a "Device Specific API".
The Generic API is intended to give users access to the underlying protocol, while the Device Specific API (for example LightDevice, or ThermostatDevice) is intended to abstract away the details of the underlying protocol and offer a simpler interface for controlling devices.
Generic Zigbee Property API
If the remote device is a zigbee device, you can use the 'getProperty' and 'updateProperty' methods, using the name of the zigbee attribute itself. See Zigbee Attribute Names for a full list of attribute names that can be used with the API.
Here's an example using the "IdentifyTime" attribute:
Enter a command: updateProperty Enter a device id: 0024460000153f47_1 Enter a property name: IdentifyTime Enter a value: 30 result: 30 ...(a few seconds later)... Enter a command: getProperty Enter a device id: 0024460000153f47_1 Enter a property name: IdentifyTime Retrieving property 'IdentifyTime' name: IdentifyTime, value: 21, type: uint16
Protocol-Specific Properties API
The Protocol Properties API is intended to give users access to the underlying protocol. It uses JSON strings as the primary means of communicating with the underlying protocol.
For example, properties for zigbee devices are passed through as JSON strings. Each Cluster property contains all of its attributes and their values.
getProtocolProperties
Type 'getProtocolProperties' and then enter the Device ID from above to trigger a read of the properties of the remote device. This is only intended to be used to speak to devices that don't have a device-specific API (see below).
Enter a command: getProtocolProperties Enter a device id: 0024460000153f46_1 Retrieving protocol properties... name: 0x0000 Server, value: {"clientOrServer":"0x01","clusterId":"0x0000","attributeRecords":[{"attributeId":"0x0004","type":"0x42","bytes":"0x0C4D4D42205265736561726368"}]}, type: cluster name: 0x0003 Server, value: {"clientOrServer":"0x01","clusterId":"0x0003","attributeRecords":[]}, type: cluster name: 0x0204 Server, value: {"clientOrServer":"0x01","clusterId":"0x0204","attributeRecords":[]}, type: cluster name: 0x000A Client, value: {"clientOrServer":"0x00","clusterId":"0x000A","attributeRecords":[]}, type: cluster name: 0x0201 Server, value: {"clientOrServer":"0x01","clusterId":"0x0201","attributeRecords":[{"attributeId":"0x0000","type":"0x29","bytes":"0xFC08"},{"attributeId":"0x0011","propertyBitmask":"n/a","type":"0x29","bytes":"0x280A"},{"attributeId":"0x0012","type":"0x29","bytes":"0x9808"},{"attributeId":"0x001C","propertyBitmask":"n/a","type":"0x30","bytes":"0x01"},{"attributeId":"0x001E","type":"0x30","bytes":"0x00"}]}, type: cluster name: 0x0202 Server, value: {"clientOrServer":"0x01","clusterId":"0x0202","attributeRecords":[{"attributeId":"0x0000","type":"0x30","bytes":"0x05"},{"attributeId":"0x0001","propertyBitmask":"n/a","type":"0x30","bytes":"0x04"}]}, type: cluster
Properties for zigbee devices are passed through as JSON strings. Each Cluster property contains all known (i.e. discovered or read at least once) attributes and their values.
updateProperty
This can be used to update a specific property, by specifying the property name and value.
Enter a command: updateProperty Enter a device id: 0024460000153f46_1 Enter a property name: 0x0201 Server Enter a value: [{"attributeId":"0x0011","type":"0x29","bytes":"0x8C0A"}] Property update triggered for device: 0024460000153f46_1 Property: occupiedCoolingSetpoint, value: 27.0, type: celsius result: [{"attributeId":"0x0011","type":"0x29","bytes":"0x8C0A"}]
A property update takes an array of JSON objects. For zigbee devices, each JSON object is a "write attribute record" consisting of an attributeId (in LSB bytes), a type, and a byte string.
getProperty
A request to get a property requires only the property name.
Enter a command: getProperty Enter a device id: 0024460000153f46_1 Enter a property name: 0x0201 Server Retrieving property '0x0201 Server' name: 0x0201 Server, value: [{"attributeId":"0x0000","type":"0x29","bytes":"0xFC08"},{"attributeId":"0x0003","type":"0x29","bytes":"0x0000"},{"attributeId":"0x0023","type":"0x30","bytes":"0x00"},{"attributeId":"0x0004","type":"0x29","bytes":"0x8813"},{"attributeId":"0x0005","type":"0x29","bytes":"0x0000"},{"attributeId":"0x0006","type":"0x29","bytes":"0x8813"},{"attributeId":"0x0029","type":"0x19","bytes":"0x0000"},{"attributeId":"0x0010","type":"0x28","bytes":"0x00"},{"attributeId":"0x0011","type":"0x29","bytes":"0x8C0A"},{"attributeId":"0x0012","type":"0x29","bytes":"0x9808"},{"attributeId":"0x0015","type":"0x29","bytes":"0x0000"},{"attributeId":"0x0016","type":"0x29","bytes":"0x8813"},{"attributeId":"0x0017","type":"0x29","bytes":"0x0000"},{"attributeId":"0x0018","type":"0x29","bytes":"0x8813"},{"attributeId":"0x0019","type":"0x28","bytes":"0x0A"},{"attributeId":"0x001B","type":"0x30","bytes":"0x04"},{"attributeId":"0x001C","type":"0x30","bytes":"0x01"},{"attributeId":"0xFFFD","type":"0x21","bytes":"0x0100"},{"attributeId":"0x001E","type":"0x30","bytes":"0x00"}], type: cluster
For zigbee devices, this will return the Cluster property, which contains an array of all its attributes and values.
Light Device
Note that this API is currently under active development and subject to change.
The LightDevice API is a "Device Specific API" which is intended to abstract the underlying protocol of the device, and present a high-level interface for interacting with Lights.
There are only two properties at the time of writing: OnOff, and CurrentLevel (for a Dimmable Light).
getProperties
The device-specific API 'getProperties' will return any properties that have been defined for the device. For a Light, it would look like the following:
Enter a command: getProperties Enter a device id: 00244600000f377e_1 name: CurrentLevel, value: 0, type: percentage name: onOff, value: true, type: boolean
Note that if no properties have been discovered or read at least once, any call to 'getProperties' will return an empty list. For more details, see the API documentation for getProperties().
getProperty
'getProperty' uses the name of the Property to return its current value.
Enter a command: getProperty Enter a device id: 00244600000f2016_1 Enter a property name: onOff ... name: onOff, value: true
updateProperty
'updateProperty' sets a new property value.
Enter a command: updateProperty Enter a device id: 00244600000f2016_1 Enter a property name: onOff Enter a value: false ... result: false ... Enter a command: updateProperty Enter a device id: 00244600000f2016_1 Enter a property name: CurrentLevel Enter a value: 0 ... result: 0
Enable Reporting
LightDevice contains a convenience method to configure the OnOff and Level properties to report any changes to the GatewayClient. You can enable reporting as follows:
Enter a command: enableReporting Enter a device id: 00244600000f2016_1
Now, any registered PropertyUpdateListeners will be called when the OnOff or Level Property on the remote device changes. The Sample App, by default, will print updates to the console.
Convenience Methods
LightDevice contains some specific convenience methods, allowing users to interact with properties above from a method call instead of directly updating the properties themselves.
- on()
- off()
- moveToLevel(int)
- moveToLevel(int,int)
See the LightDevice API documentation for more details.
Thermostat Device
Note that this API is currently under active development and subject to change.
The ThermostatDevice API is a "Device Specific API" which is intended to abstract the underlying protocol of the device, and present a high-level interface for interacting with Thermostats.
getProperties
The device-specific API 'getProperties' will return any properties that have been discovered for the device. For a Thermostat, it would look like the following:
Enter a command: getProperties Enter a device id: 0024460000153f46_1 Retrieving properties... name: fanMode, value: auto, type: fanModeEnum name: occupiedCoolingSetpoint, value: 26.0, type: celsius name: localTemperature, value: 23.0, type: celsius name: thermostatRunningMode, value: off, type: runningModeEnum name: systemMode, value: auto, type: systemModeEnum name: occupiedHeatingSetpoint, value: 20.0, type: celsius name: FanModeSequence, value: OnAuto, type: FanModeSequenceEnum
Note that if no properties have been discovered or read at least once, any call to 'getProperties' will return an empty list. For more details, see the API documentation for getProperties().
getProperty
'getProperty' uses the name of the Property to get its current value.
Enter a command: getProperty Enter a device id: 00244600000f377e_1 Enter a property name: localTemperature ... name: localTemperature, value: 23.0, type: celsius
updateProperty
'updateProperty' sets a new value.
Enter a command: updateProperty Enter a device id: 00244600000f377e_1 Enter a property name: occupiedCoolingSetpoint Enter a value: 25.0 ... result: 25.0
Enable Reporting
ThermostatDevice contains a convenience method to configure the Local Temperature property to report any changes to the GatewayClient. You can enable reporting as follows:
Enter a command: enableReporting Enter a device id: 00244600000f2016_1
Now, any registered PropertyUpdateListeners will be called when the Local Temperature Property on the remote device changes. The Sample App, by default, will print updates to the console.
Change mode
Change the mode of the Thermostat
Enter a command: changeSystemMode Enter a device id: 0024460000153f46_1 enter mode (off, auto, cool, heat, emergencyHeating, preCooling, fanOnly, dry, sleep): auto ... Command: change mode finished result: auto
Change fan mode
Enter a command: changeFanMode Enter a device id: 0024460000153f46_1 enter mode (off, low, medium, high, on, auto, smart): off Command: change fan mode finished result: off Property update triggered for device: 0024460000153f46_1 Property: fanMode, value: off, type: fanModeEnum
Adjust Cooling/Heating Setpoint
Enter a command: adjustOccupiedSetpoint Enter a device id: 00244600000f1472_1 enter mode (heat, cool): cool enter amount (from -12.7 to 12.7 degrees): 5 ... Command: adjust setpoint finished result: {"zclCommandStatus":0}
Read mode
Enter a command: readSystemMode Enter a device id: 00244600000f1472_1 ... Command: read mode finished result: {"status":"SUCCESS","result":"AUTO"}
Read fan mode
Enter a command: readFanMode Enter a device id: 00244600000f1472_1 ... Command: read fan mode finished result: {"status":"SUCCESS","result":"AUTO"}
Read running mode
Enter a command: readRunningMode Enter a device id: 00244600000f1472_1 ... Command: read running mode finished result: {"status":"SUCCESS","result":"OFF"}
Read Cooling/Heating Setpoint
Enter a command: readOccupiedCoolingsetpoint Enter a device id: 00244600000f1472_1 ... Command: readOccupiedCoolingSetpoint finished result: 27.5
Conclusion/Next Steps
This tutorial has demonstrated how to use the Gateway API to instantiate a GatewayClient, form a network, and control a remote Device. Now that we've performed a simple demo, we can begin to explore the API in more detail and write an application that makes use of the GatewayClient. See the pages below for more information.
GAPI Documentation
- API
- GatewayClient
- Device
- ZigbeeDevice
- LightDevice
- ThermostatDevice
- Zigbee Attribute Names
- Basic Initialization
Sample App Source Code
The SimpleCli.java file contains the source code for the above CLI demonstration. It shows how to instantiate the GatewayClient object, and interact with Device, ThermostatDevice, and LightDevice objects.
Importing the project into Eclipse
- Download and unzip the sample project: Downloads
- Open Eclipse
- Go to File → Import
- Expand the 'General' folder and select 'Existing Projects into Workspace' from the list
- Browse to the project folder and select it, then finish importing the project.
- To run the project, right click the 'gateway-sampleapp.launch' configuration file from the 'Project Explorer' view, and select Run As → gateway-sampleapp
- The project takes an optional argument to know which serial port to connect to, or it can be provided at runtime.
Exploring the Project
The SimpleCli.java file contains the entry point to the program and starts a simple command line interface. Its purpose is to exercise the Gateway API.
Exporting a Runnable JAR
You can export the project to a runnable standalone JAR file, which can be run on a Linux, macOS, or Windows platform, by following these steps:
- Right-click the project in Eclipse, and select "Export...".
- Select "Runnable JAR".
- Choose Launch Configuration "gateway-sampleapp".
- Select an Export Destination.
- For the Library Handling option, ensure that "Extract required libraries into generated JAR" is selected.
- Click Finish.
Legal Notices
Copyright © 2020 MMB Networks, Inc. All rights reserved.
Confidential materials prepared and delivered by MMB Networks for receipt and review only by any partner subject to a valid and enforceable MMB Networks confidentiality agreement. Any receipt, review, or misuse of any of the content exchanged hereunder by any party not a party to this confidential exchange shall be subject to any and all rights available under the law. All rights, title and interest to the materials shall remain with MMB Networks.
Any suggestions provided to MMB Networks with respect to MMB Networks' products or services shall be collectively deemed “Feedback.” You, on behalf of yourself, or if you are providing Feedback on behalf of your employer or another entity, represent and warrant that you have full legal authority to bind such entity to these terms, agree to grant and hereby grant to MMB Networks a nonexclusive, perpetual, irrevocable, royalty free, worldwide license to use and otherwise exploit such Feedback within any MMB Networks products and services.