ZigBee Reference¶
Note
As of now, any time the ZigBee library logs a message, an error will be seen. This is a known issue and will be fixed with the next deploy.
The ZigBee library contains many shorthands and conveniences for developing ZigBee Device Handlers.
ZigBee devices have fingerprints that define what the device is when it joins a ZigBee network. Currently you define the expected fingerprint for a device in the Device Handler metadata block as part of the definition. An example would look like this:
metadata {
// Automatically generated. Make future change here.
definition (name: "SmartPower Outlet", namespace: "PEA HiVE", author: "PEA HiVE") {
capability "Actuator"
capability "Switch"
capability "Power Meter"
capability "Configuration"
capability "Refresh"
capability "Sensor"
// indicates that device keeps track of heartbeat (in state.heartbeat)
attribute "heartbeat", "string"
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0B04,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3200", deviceJoinName: "Outlet"
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0B04,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3200-Sgb", deviceJoinName: "Outlet"
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0B04,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "4257050-RZHAC", deviceJoinName: "Outlet"
fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0B04,0B05", outClusters: "0019"
}
If the fingerprint declaration contains a value for both the manufacturer and model attributes, you have the option to add the deviceJoinName attribute.
| Fingerprint Attribute | Type | Value |
|---|---|---|
| deviceJoinName | String |
Overrides the device type name when pairing. This allows the developer to customize the device name while joining a ZigBee device. |
Parse methods¶
zigbee.getEvent()¶
The getEvent() method will try to parse ZigBee Clusters into a map whose key/value pairs can be directly handled by the sendEvent() method.
- Signature:
Map(String:String) zigbee.getEvent(String description)
- Parameters:
- description: The description value passed to the parse method from the device.
- Return Values:
- Map: [name: <event name>, value: <event value>]
Example
def parse(String description) {
def result = zigbee.getEvent(description)
if(result) {
sendEvent(result)
} else {
// zigbee.getEvent was unable to parse description. Description must be parsed manually.
}
}
The zigbee.getEvent() method can parse the following event types with work being done to for additional event types:
| Event Type | Cluster value |
|---|---|
| switch | 0x0006 |
| level | 0x0008 |
| power | 0x0702 and 0x0B04 |
| colorTemperature | 0x0300 |
Note
Only color temperature can be parsed. Full color control is in the works.
Note
For the power event type, the value can be reported in mW, W, or kW. This means that it is up to the developer to make adjustments to the value before calling sendEvent so it will be displayed correctly.
Low level commands¶
additionalParams¶
There are several ZigBee methods that support an optional map parameter called additionalParams. This is intended to be used to support future params without affecting backward compatibility. The following keys are supported:
| Key | Type | Description |
|---|---|---|
| mfgCode | integer | The ZigBee manufacturing code (e.g. 0x110A) |
| destEndpoint | integer | The destination endpoint for the given message (e.g. 0x02) |
zigbee.command()¶
Send a Cluster specific Command. This method is overloaded and has a couple of signatures.
- Signature:
zigbee.command(Integer Cluster, Integer Command, [String... payload])
- Parameters:
- Cluster: The Cluster ID
- Command: The Command ID
- payload (optional): Zero or more arguments required by the Command. Each argument should be passed as an ASCII hex string in little endian format of the appropriate width for the data type. For example, to pass the value 5 for a UINT24 (24-bit unsigned integer) you would pass “050000”.
- Signature:
zigbee.command(Integer Cluster, Integer Command, String payload, additionalParams=[:])
- Parameters:
- Cluster: The Cluster ID
- Command: The Command ID
- payload: An ASCII hex string in little endian format of the appropriate width for the data type. For example, to pass the value 5 for a UINT24 (24-bit unsigned integer) you would pass “050000”. You can also use the DataType.pack() method described below. If you have multiple arguments, they can just be appended in order.
- additionalParams: An optional map to specify additional parameters. See additionalParams for supported attributes.
- Examples:
- Send Move To Level Command to Level Control Cluster.
zigbee.command(0x0008, 0x04, "FE", "0500")
Where Level equals
0xFE(full on) and Transition Time equals0x0005(5 seconds)
- Send Off Command to On/Off Cluster.
zigbee.command(0x0006, 0x00)
zigbee.readAttribute()¶
Read the current attribute value of the specified Cluster.
- Signature:
zigbee.readAttribute(Integer Cluster, Integer attributeId, Map additionalParams=[:])
- Parameters:
- Cluster: The Cluster ID to read from
- attributeId: The ID of the attribute to read
- additionalParams: An optional map to specify additional parameters. See additionalParams for supported attributes.
- Example:
- Read CurrentLevel attribute of the Level Control Cluster.
zigbee.readAttribute(0x0008, 0x0000)
- Read a manufacturer specific attribute on the PEA HiVE multi-sensor
zigbee.readAttribute(0xFC02, 0x0010, [mfgCode: 0x110A])
zigbee.writeAttribute()¶
Write the attribute value of the specified Cluster.
- Signature:
zigbee.writeAttribute(Integer Cluster, Integer attributeId, Integer dataType, value, Map additionalParams=[:])
- Parameters:
- Cluster: The Cluster ID to write
- attributeId: The attribute ID to write
- dataType: The data type ID of the attribute as specified in the ZigBee Cluster library
- value: The Integer value to write for data types of boolean, unsigned int, signed int, general data, and enumerations. Other data types are not currently supported but will be added in the future. Let us know if you need a data type that is not currently supported.
- additionalParams: An optional map to specify additional parameters. See additionalParams for supported attributes.
- Example:
- Write the value 0x12AB to a unsigned 16-bit integer attribute
zigbee.writeAttribute(0x0008, 0x0010, 0x21, 0x12AB)
- Write a manufacturer specific attribute on the PEA HiVE multi-sensor
zigbee.writeAttribute(0xFC02, 0x0000, 0x20, 1, [mfgCode: 0x110A])
zigbee.configureReporting()¶
Configure a ZigBee device’s reporting properties. Refer to the Configure Reporting Command in the ZigBee Cluster Library for more information.
Signature:
zigbee.configureReporting(Integer Cluster,
Integer attributeId, Integer dataType,
Integer minReportTime, Integer MaxReportTime,
[Integer reportableChange],
Map additionalParams=[:])
- Parameters:
- Cluster: The Cluster ID of the requested report
- attributeId: The attribute ID for the requested report
- dataType: The two byte ZigBee type value for the requested report (see DataType)
- minReportTime: Minimum number of seconds between reports
- maxReportTime: Maximum number of seconds between reports
- reportableChange (optional): Amount of change needed to trigger a report. Required for analog data types. Discrete data types should always provide null for this value.
- additionalParams: An optional map to specify additional parameters. See additionalParams for supported attributes.
- Examples:
- Discrete data type
zigbee.configureReporting(0x0006, 0x0000, 0x10, 0, 600, null)
- Analog data type
zigbee.configureReporting(0x0008, 0x0000, 0x20, 1, 3600, 0x01)
- Configure a manufacturer specific report on the PEA HiVE multi-sensor
zigbee.configureReporting(0xFC02, 0x0010, 0x18, 10, 3600, 0x01, [mfgCode: 0x110A])
ZigBee Capabilities¶
The following table outlines the Commands necessary to both configure and get updated information from ZigBee devices that support the capabilities outlined below.
Note
All methods outlined in the table need the zigbee. prefix
| Capability | Configure | Refresh | Notes |
|---|---|---|---|
| Battery | configureReporting(0x0001, 0x0020, 0x20, 30, 21600, 0x01) | ||
| Color Temp | configureReporting(0x0300, 0x0007, 0x21, 1, 3600, 0x10) | readAttribute(0x0300, 0x0007) | For devices that support the Color Control Cluster (0x0300) |
| Level | configureReporting(0x0008, 0x0000, 0x20, 1, 3600, 0x01) | readAttribute(0x0008, 0x0000) | |
| Power | configureReporting(0x0702, 0x0400, 0x2A, 1, 600, 0x05) | readAttribute(0x0704, 0x0400) | For devices that support the Metering Cluster (0x0704) |
| Power | configureReporting(0x0B04, 0x050B, 0x29, 1, 600, 0x0005) | readAttribute(0x0B04, 0x050B) | For devices that support the Electrical Measurement Cluster (0x0B04) |
| Switch | configureReporting(0x0006, 0x0000, 0x10, 0, 600, null) | readAttribute(0x0006, 0x0000) | |
| Temperature | configureReporting(0x0402, 0x0000, 0x29, 30, 3600, 0x0064) |
Examples:
Get the latest level value from a dimmer switch. From the table above, we find the level capability and look at the Refresh column to find the correct Command to execute.
readAttribute(0x0008, 0x0000)
Configure the level capability for a dimmer type switch. The configure reporting Command from the table above for level configures the device for a min reporting interval of 5 seconds, a reporting interval of 1 hour (3600 s) if there has been no activity, and a min level change of 01.
configureReporting(0x0008, 0x0000, 0x20, 1, 3600, 0x01)
The following utility methods are available as capability based Commands.
zigbee.setLevel()¶
Sends the level Command, 0x04, to the level control Cluster, 0x0008 with the passed in rate.
Signature:
zigbee.setLevel(Integer level, Integer rate)
- Parameters:
- level: A value between 0-100 inclusive.
- rate: Time in tenths of a second. E.g.
rate = 100 //max valuetranslates to 10 seconds.
zigbee.setColorTemperature()¶
Sets the color to the specified temperature value in K.
Signature:
zigbee.setColorTemperature(Integer value)
- Parameters:
- value: The temperature value to set the color to in K. Usually greater than 2700
ZigBee helper commands¶
zigbee.parseDescriptionAsMap()¶
Parses a device description into a map that contains data and capabilities.
Signature:
zigbee.parseDescriptionAsMap(String description)
- Parameters:
- description: The description string from the device
zigbee.convertToHexString()¶
Convert the given value to a hex string of given width
Signature:
zigbee.convertToHexString(Integer value, Integer width)
- Parameters:
- value: Integer value to be converted
- width: the minimum width of the hex string. Default value is 2
Examples:
zigbee.convertToHexString(10, 2) //result: 0A
zigbee.convertToHexString(10, 4) //result: 000A
zigbee.convertHexToInt()¶
Convert the given hex value to an Integer
Signature:
zigbee.convertHexToInt(String value)
- Parameters:
- value: The hex value to be converted to an Integer
Example:
zigbee.convertHexToInt("0001") //result: 1
zigbee.convertHexToInt("000F") //result: 15
def myInt = zigbee.convertHexToInt("12AB") // result = 4779. The result of calling Integer.parseInt()
assert myInt == 4779 //true
assert myInt == 0x12AB //also true
zigbee.hexNotEqual()¶
Returns true if the compared hex values are not equal.
Signature:
zigbee.hexNotEqual(String hex1, String hex2)
- Parameters:
- hex1: Hex value to compare
- hex2: Hex value to compare against first value
zigbee.parseZoneStatus()¶
Returns a ZoneStatus object (see below) withe the parsed value form the message description. The description should be of the form “zone status {number}” where {number} is a hex number.
Signature:
zigbee.parseZoneStatus(String description)
- Parameters:
- description: A zone status message description.
Additional ZigBee classes¶
There are some additional classes that are provided to make interacting with and handling Zigbee messages easier.
ZoneStatus¶
The purpose of the ZoneStatus class is to handle the ZoneStatus attribute in the IAS Zone cluster. It has a single constructor that takes an int which is the ZoneStatus attribute value.
Constructor:
ZoneStatus(int zonestatus)
Example:
ZoneStatus zs = ZoneStatus(0x41) // Trouble & Alarm1
Accessing a Property/attribute¶
Once you have created the ZoneStatus object you can query the individual bits in a number of ways. First you can get the value of each individual bit (1 or 0) by accessing the property with the same name. The properties are as follows:
| Bit Number | Property Name | Values |
|---|---|---|
| 0 | alarm1 | 1 - opened or alarmed
0 - closed or not alarmed
|
| 1 | alarm2 | 1 - opened or alarmed
0 - closed or not alarmed
|
| 2 | tamper | 1 - tampered
0 - not tampered
|
| 3 | battery | 1 - low battery
0 - battery OK
|
| 4 | supervisionReports | 1 - reports
0 - does not report
|
| 5 | restoreReports | 1 - reports restore
0 - does not report restore
|
| 6 | trouble | 1 - trouble/failure
0 - OK
|
| 7 | ac | 1 - ac/mains fault
0 - ac/mains OK
|
| 8 | test | 1 - sensor is in test mode
0 - sensor is in operation mode
|
| 9 | batteryDefect | 1 - sensor detects a defective battery
0 - sensor battery is functioning normally
|
See the ZigBee Home Automation (HA) specification and the ZigBee Cluster Library (ZCL) specification for more information.
Example:
ZoneStatus zs = ZoneStatus(0x41) // Trouble & Alarm1
zs.alarm1 // 1
zs.alarm2 // 0
zs.trouble // 1
The ZoneStatus object also exposes a number of query methods for getting a true/false for each attribute value. They are as follows:
| Property Name | Query method |
|---|---|
| alarm1 | isAlarm1Set() |
| alarm2 | isAlarm2Set() |
| tamper | isTamperSet() |
| battery | isBatterySet() |
| supervisionReports | isSupervisionReportsSet() |
| restoreReports | isRestoreReportsSet() |
| trouble | isTroubleSet() |
| ac | isAcSet() |
| test | isTestSet() |
| batteryDefect | isBatteryDefectSet() |
Example of DTH parseIasMessage for a motion sensor:
private Map parseIasMessage(String description) {
ZoneStatus zs = zigbee.parseZoneStatus(description)
Map resultMap = [:]
resultMap.name = 'motion'
resultMap.value = zs.isAlarm1Set() ? 'active' : 'inactive'
return resultMap
}
DataType¶
The DataType class contains information and some utility methods for ZCL data types.
DataType constants¶
The list of types and their DataType constant name are as follows:
| ZCL Data Type | DataType constant name | ZCL numeric value |
|---|---|---|
| No Data | NO_DATA | 0x00 |
| 8-bit data | DATA8 | 0x08 |
| 16-bit data | DATA16 | 0x09 |
| 24-bit data | DATA24 | 0x0a |
| 32-bit data | DATA32 | 0x0b |
| 40-bit data | DATA40 | 0x0c |
| 48-bit data | DATA48 | 0x0d |
| 56-bit data | DATA56 | 0x0e |
| 64-bit data | DATA64 | 0x0f |
| Boolean | BOOLEAN | 0x10 |
| 8-bit bitmap | BITMAP8 | 0x18 |
| 16-bit bitmap | BITMAP16 | 0x19 |
| 24-bit bitmap | BITMAP24 | 0x1a |
| 32-bit bitmap | BITMAP32 | 0x1b |
| 40-bit bitmap | BITMAP40 | 0x1c |
| 48-bit bitmap | BITMAP48 | 0x1d |
| 56-bit bitmap | BITMAP56 | 0x1e |
| 64-bit bitmap | BITMAP64 | 0x1f |
| Unsigned 8-bit int | UINT8 | 0x20 |
| Unsigned 16-bit int | UINT16 | 0x21 |
| Unsigned 24-bit int | UINT24 | 0x22 |
| Unsigned 32-bit int | UINT32 | 0x23 |
| Unsigned 40-bit int | UINT40 | 0x24 |
| Unsigned 48-bit int | UINT48 | 0x25 |
| Unsigned 56-bit int | UINT56 | 0x26 |
| Unsigned 64-bit int | UINT64 | 0x27 |
| Signed 8-bit int | INT8 | 0x28 |
| Signed 16-bit int | INT16 | 0x29 |
| Signed 24-bit int | INT24 | 0x2a |
| Signed 32-bit int | INT32 | 0x2b |
| Signed 40-bit int | INT40 | 0x2c |
| Signed 48-bit int | INT48 | 0x2d |
| Signed 56-bit int | INT56 | 0x2e |
| Signed 64-bit int | INT64 | 0x2f |
| 8-bit enumeration | ENUM8 | 0x30 |
| 16-bit enumeration | ENUM16 | 0x31 |
| Semi-precision | FLOAT2 | 0x38 |
| Single precision | FLOAT4 | 0x39 |
| Double precision | FLOAT8 | 0x3a |
| Octet String | STRING_OCTET | 0x41 |
| Character String | STRING_CHAR | 0x42 |
| Long Octet String | STRING_LONG_OCTET | 0x43 |
| Long Character String | STRING_LONG_CHAR | 0x44 |
| Array | ARRAY | 0x48 |
| Structure | STRUCTURE | 0x4c |
| Set | SET | 0x50 |
| Bag | BAG | 0x51 |
| Time of day | TIME_OF_DAY | 0xe0 |
| Date | DATE | 0xe1 |
| UTCTime | UTCTIME | 0xe2 |
| Cluster ID | CLUSTER_ID | 0xe8 |
| Attribute ID | ATTRIBUTE_ID | 0xe9 |
| BACnet OID | BACNET_OID | 0xea |
| IEEE address | IEEE_ADDRESS | 0xf0 |
| 128-bit security key | SECKEY128 | 0xf1 |
| Unknown | UNKNOWN | 0xff |
See the ZigBee Cluster Library (ZCL) specification for more information on the different data types and how they are used.
DataType.getLength()¶
This method is used to get the length of a variable of the given type. This length is in number of bytes. For variable length or unknown types it will return null
Signature:
DataType.isVariableLength(type)
- Parameters:
- type: The type to check. This should be one of the DataType Constants defined above.
Example
DataType.getLength(DataType.UINT8) // returns 1
DataType.getLength(DataType.CLUSTER_ID) // returns 2
DataType.getLength(DataType.STRING_CHAR) // returns null
DataType.isVariableLength()¶
This method is used to test if a given type is variable length or not.
Signature:
DataType.isVariableLength(type)
- Parameters:
- type: The type to check. This should be one of the DataType Constants defined above.
Example
DataType.isVariableLength(DataType.UINT8) // returns false
DataType.isVariableLength(DataType.STRING_CHAR) // returns true
DataType.isDiscrete()¶
This method is used to test if a given type is discrete.
Signature:
DataType.isDiscrete(type)
- Parameters:
- type: The type to check. This should be one of the DataType Constants defined above.
Example
DataType.isDiscrete(DataType.UINT8) // returns true
DataType.isDiscrete(DataType.FLOAT2) // returns false
DataType.pack()¶
This method is used to pack data of a given type into hex string form. Currently not all DataTypes are supported by this method. All discrete data types are supported, but only STRING_CHAR is supported for variable length data types. If the type passed in is null, an empty string, or DataType.UNKNOWN the value of data will be returned unmodified.
Signature:
DataType.pack(data, type, littleEndian=false)
- Parameters:
- data: The data to pack, the type of this should be appropriate for the type argument
- type: The type of the data being packed. This should be one of the DataType Constants defined above.
- littleEndian: If true it will pack it with the least significant bits first.
Example
DataType.pack(0x01, DataType.UINT8) // returns "01"
DataType.pack(0x01, DataType.UINT64) // returns "0000000000000001"
DataType.pack(0x01, DataType.UINT32, true) // returns "01000000"