Zigbee Data Types
Contents
Module Description
This module contains implementations and utility functions around the usage of Zigbee data types in the lua
environment. While the individual data types are all defined in their own files these files will be lazily
loaded when using a normal dot syntax with the module. E.g. data_typs.Uint8
will return the Uint8
class after loading it from it’s individual file.
All data type implementations will share a number of characteristics. First, every data type will define the following functions:
Instance functions
- serialize
This will serialize the data type into the bytes used to send in a Zigbee message (e.g. Uint16 with a value of 2 would result in “\x02\x00” note that it will be little endian)
- get_length
This will return the length of this type in bytes when serialized (e.g. Uint16 would return 2)
- pretty_print
This will return a string with a human readable representation of the instance (e.g. “Uint16: 0x0002”)
Static functions
- deserialize
This will convert from a stream of bytes into the parsed table structure
- __call
This is actually defined on the metatable but allows for creation of the type through call syntax (e.g.
Uint16(0x0002)
)
In addition the data types will have the following fields defined
- ID
The Zigbee ZCL specified type ID for this type (e.g. 0x21 for Uint16)
- NAME
A string representing the name of the data type (e.g. “Uint16” for Uint16)
- is_discrete
A boolean defining if the type is a discrete type
- is_fixed_length
A boolean defining if the type is of fixed length
There are two exceptions to this rule. The first is ZigbeeDataType
as this is a representation
of fields in Zigbee messages that represent the data type Ids. Thus it does not have an ID
field as it is not a
separate data type itself, but in all other functionality it works as a Uint8
. The second
exception is ZCLCommandId
for very similar reasons. It is not an actual Zigbee data type
but is instead used when a message field represents a ZCL command ID. It also does not have an ID field but otherwise
works identically to a Uint8
.
Examples
Creating a Data Type Value
Simple creation of some types from raw values
-- Import the module
local data_types = require "st.zigbee.data_types"
local utils = require "st.zigbee.utils"
local uint = data_types.Uint16(0x0002)
uint.NAME -- "Uint16"
uint.ID -- 0x21
uint.value -- 2
local int = data_types.Int32(-5)
int.NAME -- "Int32"
int.ID -- 0x2B
int.value -- -5
print(utils.get_print_safe_string(int:serialize()))
-- "\xFB\xFF\xFF\xFF"
In the context of writing an attribute
-- Import the required libraries
local data_types = require "st.zigbee.data_types"
local zcl_commands = require "st.zigbee.zcl.global_commands"
local constants = require "st.zigbee.constants"
local IASZone = (require "st.zigbee.zcl.clusters").IASZone
local cie_addr = data_types.IeeeAddress("\x01\x02\x03\x04\x05\x06\x07\x08")
local attr_id = data_types.AttributeId(IASZone.attributes.IASCIEAddress.ID)
local data_type_val = data_types.ZigbeeDataType(data_types.IeeeAddress.ID)
local cie_attr_write = zcl_commands.WriteAttribute.AttributeRecord(attr_id, data_type_val, cie_addr)
local write_body = zcl_commands.WriteAttribute({ cie_attr_write })
Parsing a Data Type Value From a Byte String
-- Import the required libraries
local data_types = require "st.zigbee.data_types"
local bytes = "\xFB\xFF\xFF\xFF"
local parsed_val = data_types.parse_data_type(data_types.Int32.ID, bytes)
parsed_val.NAME -- "Int32"
parsed_val.ID -- 0x2B
parsed_val.value -- -5
local parsed_val_2 = data_types.Int32.deserialize(bytes)
parsed_val_2.NAME -- "Int32"
parsed_val_2.ID -- 0x2B
parsed_val_2.value -- -5
Verifying Data Types as Arguments to Other Functions
-- Import the required libraries
local data_types = require "st.zigbee.data_types"
function build_attr_report_record(attr_id, data_type, value)
local out = {}
out.attr_id = data_types.validate_or_build_type(attr_id, data_types.AttributeId, "attr_id")
out.data_type = data_types.validate_or_build_type(data_type, data_types.ZigbeeDataType, "data_type")
out.data = data_types.validate_or_build_type(value, data_types.get_data_type_by_id(out.data_type.value), "data")
return out
end
local out_table = build_attr_report_record(0x0000, 0x21, 0x0005)
out_table.attr_id.value -- 0x0000
out_table.attr_id.ID -- 0xE9
out_table.attr_id.NAME -- AttributeId
out_table.data_type.value -- 0x21
out_table.data.value -- 0x0005
out_table.data.ID -- 0x21
out_table.data.NAME -- Unt16
local attr_id = data_types.AttributeId(0x0000)
local data_type_val = data_types.ZigbeeDataType(0x21)
local data = data_types.Uint16(0x0005)
local out_table_2 = build_attr_report_record(attr_id, data_type_val, data)
out_table_2.attr_id.value -- 0x0000
out_table_2.attr_id.ID -- 0xE9
out_table_2.attr_id.NAME -- AttributeId
out_table_2.data_type.value -- 0x21
out_table_2.data.value -- 0x0005
out_table_2.data.ID -- 0x21
out_table_2.data.NAME -- Unt16
Utility Functions
- st.zigbee.data_types.get_data_type_by_id(id)
This will take the data type ID and return the corresponding class that can be used for parsing/construction
- Parameters
id (
number
) – the data type id- Returns
the data type class for the corresponding ID
- Return type
- st.zigbee.data_types.parse_data_type(data_type_id, buf, field_name)
This will take the data type ID and then byte string and parse the data type into a class instance
- Parameters
data_type_id (
number
) – the data type idbuf (
Reader
) – the bytes representing the data, only the necesary bytes will be consumed additional bytes ignoredfield_name (
str
) – the field name of the data type
- Returns
the parsed data type represented in the string arg
- Return type
- st.zigbee.data_types.validate_or_build_type(value, data_type, name)
Build and/or verify that a value is of appropriate type
This is primarily useful in the from_values methods used in constructing messages. The reason this is useful is it allows us to take a “value” that could be either, the raw value of the desired data type (e.g. a lua number type) or the already built zigbee data type class instance (e.g. a Uint8 <0x05>). This method will then verify that it either is already a constructed type of the correct value OR use the raw value to construct it. This allows us to easily accept arguments of either type in the constructor functions
- Parameters
value – the value for the data type, either the raw type to construct with, or the data type table
data_type (
st.zigbee.data_types.DataType
) – The data type class that the value should be, or be constructed intoname (
str
) – the constructed data type will have its “field_name” field set to this for proper pretty printing
- Returns
the constructed data type of the correct value
- Return type
- class st.zigbee.data_types.st.zigbee.data_types.DataType
- Abstract
A generic class defining the interface shared across all Zigbee data types
- NAME: str
pretty print class name
- ID: number
the Zigbee data type ID for this data type
- static deserialize(bytes, field_name)
Parse this DataType from a string of bytes
- Parameters
bytes (
str
) – the bytes containing the st.zigbee.data_types.DataType only byte_length bytes will be consumed extra will be ignoredfield_name (
str
) – optional name of this field (used when pretty_printing)
- Returns
the parsed version of DataType
- Return type
- get_length()
Get the length in bytes of this DataType
- Returns
the byte length of this DataType
- Return type
number
- pretty_print()
Format this DataType in a human readable way
- Returns
A human readable string of this DataType
- Return type
str
Custom Data Types
- class st.zigbee.data_types.ZigbeeDataType: st.zigbee.data_types.UintABC
A representation of a field in a Zigbee message providing the ID of a Zigbee Data Type creation of this
will verify that the value is a known data type, and pretty printing will include that data type name
- NAME: str
“DataType”
- byte_length: number
1
- value: number
This is the ID of a Zigbee data type
- class st.zigbee.data_types.ZCLCommandId: st.zigbee.data_types.UintABC
A representation of a field in a Zigbee message providing the ID of a Zigbee ZCL Command. As this command
ID could represent a manufacturer/cluster specific command the value is not validated against a specific list.
- NAME: str
“ZCLCommandId”
- byte_length: number
1
- value: number
This is the ID of a ZCL command
Zigbee Data Types
This is the base type of the DataType classes. It is abstract and not instatiable itself, and contains no funcitonality but defines the interface.
- class st.zigbee.data_types.DataType
- Abstract
A generic class defining the interface shared across all Zigbee data types
- NAME: str
pretty print class name
- ID: number
the Zigbee data type ID for this data type
- static deserialize(bytes, field_name)
Parse this DataType from a string of bytes
- Parameters
bytes (
str
) – the bytes containing the st.zigbee.data_types.DataType only byte_length bytes will be consumed extra will be ignoredfield_name (
str
) – optional name of this field (used when pretty_printing)
- Returns
the parsed version of DataType
- Return type
- get_length()
Get the length in bytes of this DataType
- Returns
the byte length of this DataType
- Return type
number
- pretty_print()
Format this DataType in a human readable way
- Returns
A human readable string of this DataType
- Return type
str
NoData
- class st.zigbee.data_types.NoDataABC: st.zigbee.data_types.DataType
Classes being created using the NoDataABC class represent Zigbee data types that have no body
- static new_mt(base)
This function will create a new metatable with the appropriate functionality for a Zigbee NoData
- class st.zigbee.data_types.NoData: st.zigbee.data_types.NoDataABC
- ID: number
0x00
- NAME: str
“NoData”
- value: nil
this data type has no body
Data
- class st.zigbee.data_types.DataABC: st.zigbee.data_types.DataType
Classes being created using the DataABC class represent Zigbee data types whose lua “value” is stored as a generic byte string as the direct structure is not known or not storable in another way. In general these are the Zigbee data types Data8-Data64 represented by IDs 0x08-0x0F. However, due to limitations of lua numbers numeric types of 64 bit length use this base as well.
- static new_mt(base, byte_length)
This function will create a new metatable with the appropriate functionality for a Zigbee Data field
- Parameters
base (
table
) – the base meta table, this will include the ID and NAME of the type being representedbyte_length (
number
) – the length in bytes of this Data field
- class st.zigbee.data_types.Data8: st.zigbee.data_types.DataABC
- ID: number
0x08
- NAME: str
“Data8”
- byte_length: number
1
- value: str
The raw bytes of this data field
- class st.zigbee.data_types.Data16: st.zigbee.data_types.DataABC
- ID: number
0x09
- NAME: str
“Data16”
- byte_length: number
2
- value: str
The raw bytes of this data field
- class st.zigbee.data_types.Data24: st.zigbee.data_types.DataABC
- ID: number
0x0A
- NAME: str
“Data24”
- byte_length: number
3
- value: str
The raw bytes of this data field
- class st.zigbee.data_types.Data32: st.zigbee.data_types.DataABC
- ID: number
0x0B
- NAME: str
“Data32”
- byte_length: number
4
- value: str
The raw bytes of this data field
- class st.zigbee.data_types.Data40: st.zigbee.data_types.DataABC
- ID: number
0x0C
- NAME: str
“Data40”
- byte_length: number
5
- value: str
The raw bytes of this data field
- class st.zigbee.data_types.Data48: st.zigbee.data_types.DataABC
- ID: number
0x0D
- NAME: str
“Data48”
- byte_length: number
6
- value: str
The raw bytes of this data field
Boolean
- class st.zigbee.data_types.BooleanABC: st.zigbee.data_types.DataType
Classes being created using the BooleanABC class represent Zigbee data types whose lua “value” is stored as a boolean.
- static new_mt(base)
This function will create a new metatable with the appropriate functionality for a Zigbee Boolean
- class st.zigbee.data_types.Boolean: st.zigbee.data_types.BooleanABC
- ID: number
0x10
- NAME: str
“Boolean”
- value: boolean
The value of this boolean data type
Bitmap
- class st.zigbee.data_types.BitmapABC: st.zigbee.data_types.DataType
Classes being created using the BitmapABC class represent Zigbee data types whose lua “value” is stored as an unsigned number, but has individual bit fields. In general these are the Zigbee data types Bitmap8-Bitmap56 represented by IDs 0x18-0x1F. Bitmap64 has to be treated differently due to lua limitations.
- is_bit_set(bit_number)
Check if a specific bit is set in this bitmap field
- Parameters
bit_number (
number
) – the bit position (1 being lsb) to check- Returns
true if the specified bit is 1
- Return type
boolean
- class st.zigbee.data_types.Bitmap8: st.zigbee.data_types.BitmapABC
- ID: number
0x18
- NAME: str
“Bitmap8”
- byte_length: number
1
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Bitmap16: st.zigbee.data_types.BitmapABC
- ID: number
0x19
- NAME: str
“Bitmap16”
- byte_length: number
2
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Bitmap24: st.zigbee.data_types.BitmapABC
- ID: number
0x1A
- NAME: str
“Bitmap24”
- byte_length: number
3
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Bitmap32: st.zigbee.data_types.BitmapABC
- ID: number
0x1B
- NAME: str
“Bitmap32”
- byte_length: number
4
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Bitmap40: st.zigbee.data_types.BitmapABC
- ID: number
0x1C
- NAME: str
“Bitmap40”
- byte_length: number
5
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Bitmap48: st.zigbee.data_types.BitmapABC
- ID: number
0x1D
- NAME: str
“Bitmap48”
- byte_length: number
6
- value: number
This is the actual value of the instance of the data type
Uint
- class st.zigbee.data_types.UintABC: st.zigbee.data_types.DataType
Classes being created using the UintABC class represent Zigbee data types whose lua “value” is stored as an unsigned number. In general these are the Zigbee data types Uint8-Uint56 represented by IDs 0x20-0x26. Uint64 has to be treated differently due to lua limitations. In addition there are several other ID types that derive their behavior from Uint as well.
- class st.zigbee.data_types.Uint8: st.zigbee.data_types.UintABC
- ID: number
0x20
- NAME: str
“Uint8”
- byte_length: number
1
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Uint16: st.zigbee.data_types.UintABC
- ID: number
0x21
- NAME: str
“Uint16”
- byte_length: number
2
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Uint24: st.zigbee.data_types.UintABC
- ID: number
0x22
- NAME: str
“Uint24”
- byte_length: number
3
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Uint32: st.zigbee.data_types.UintABC
- ID: number
0x23
- NAME: str
“Uint32”
- byte_length: number
4
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Uint40: st.zigbee.data_types.UintABC
- ID: number
0x24
- NAME: str
“Uint40”
- byte_length: number
5
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Uint48: st.zigbee.data_types.UintABC
- ID: number
0x25
- NAME: str
“Uint48”
- byte_length: number
6
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Uint56: st.zigbee.data_types.UintABC
- ID: number
0x26
- NAME: str
“Uint56”
- byte_length: number
7
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Uint64: st.zigbee.data_types.DataABC
Because lua only supports 64 bit numbers it is not possible to natively store a number that is
64 bits long and unsigned. So we actually inherit from the Data zigbee type and store the bytes of the number directly. Thus usage of this will be different
- ID: number
0x27
- NAME: str
“Uint64”
- byte_length: number
8
- value: str
This is the actual value of the instance of the data type
Int
- class st.zigbee.data_types.IntABC: st.zigbee.data_types.DataType
Classes being created using the IntABC class represent Zigbee data types whose lua “value” is stored as a signed number. In general these are the Zigbee data types Int8-Int56 represented by IDs 0x28-0x2E. Int64 has to be treated differently due to lua limitations.
- class st.zigbee.data_types.Int8: st.zigbee.data_types.IntABC
- ID: number
0x28
- NAME: str
“Int8”
- byte_length: number
1
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Int16: st.zigbee.data_types.IntABC
- ID: number
0x29
- NAME: str
“Int16”
- byte_length: number
1
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Int24: st.zigbee.data_types.IntABC
- ID: number
0x2A
- NAME: str
“Int24”
- byte_length: number
3
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Int32: st.zigbee.data_types.IntABC
- ID: number
0x2B
- NAME: str
“Int32”
- byte_length: number
4
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Int40: st.zigbee.data_types.IntABC
- ID: number
0x2C
- NAME: str
“Int40”
- byte_length: number
5
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Int48: st.zigbee.data_types.IntABC
- ID: number
0x2D
- NAME: str
“Int48”
- byte_length: number
6
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Int56: st.zigbee.data_types.IntABC
- ID: number
0x2E
- NAME: str
“Int56”
- byte_length: number
7
- value: number
This is the actual value of the instance of the data type
- class st.zigbee.data_types.Int64: st.zigbee.data_types.DataABC
Because lua only supports 64 bit numbers it is not possible to natively store a number that is
64 bits long and unsigned. In this case our number is signed so we could possibly use a native number However, to maintain consistency with all other 64 bit Zigbee types we actually inherit from the DataABC Zigbee type and store the bytes of the number directly. Thus usage of this will be different.
- ID: number
0x2F
- NAME: str
“Int64”
- byte_length: number
8
- value: str
This is the actual value of the instance of the data type
Enum
- class st.zigbee.data_types.EnumABC: st.zigbee.data_types.DataType
Classes being created using the EnumABC class represent Zigbee data types whose lua value is stored as an unsigned number. In general these are the Zigbee data types Enum8 and Enum16 represented by IDs 0x30 and 0x31.
Floating Points
- class st.zigbee.data_types.FloatABC: st.zigbee.data_types.DataType
This represents a number of the form (1 + mantissa) * 2 ^ exponent with some exceptions see the ZCL spec for further details
- mantissa: number
The fractional component of the number
- exponent: number
The exponent for 2
- sign: number
either 1 if the value is negative or 0 if positive
- static new_mt(base, byte_length, mantissa_bit_length, exponent_bit_length)
This function will create a new metatable with the appropriate functionality for a Zigbee Float field
- Parameters
base (
table
) – the base meta table, this will include the ID and NAME of the type being representedbyte_length (
number
) – the length in bytes of this Float fieldmantissa_bit_length (
number
) – the number of bits to use for the mantissa fieldexponent_bit_length (
number
) – the number of bits to use for the exponent field
- class st.zigbee.data_types.SemiPrecisionFloat: st.zigbee.data_types.FloatABC
- ID: number
0x38
- NAME: str
“SemiPrecision”
- byte_length: number
2
- mantissa_bit_length: number
10
- exponent_bit_length: number
5
Strings
- class st.zigbee.data_types.StringABC: st.zigbee.data_types.DataType
Classes being created using the StringABC class represent Zigbee data types whose lua “value” is stored as a string. In general these are the Zigbee data types CharString, OctetString, LongCharString, and LongOctetString represented by IDs 0x41-0x44. All of these are length prefixed and there is no difference in the lua storage between Octet and Char strings.
- static new_mt(base, length_byte_length)
This function will create a new metatable with the appropriate functionality for a Zigbee String
- Parameters
base (
table
) – the base meta table, this will include the ID and NAME of the type being representedlength_byte_length (
number
) – the length in bytes of this String
- class st.zigbee.data_types.OctetString: st.zigbee.data_types.StringABC
- ID: number
0x41
- NAME: str
“OctetString”
- length_byte_length: number
1 (This is the number of bytes the length description takes)
- byte_length: number
the length of this string (not including the length bytes)
- value: str
The string representation of this field (note this does not include the length bytes)
- class st.zigbee.data_types.CharString: st.zigbee.data_types.StringABC
- ID: number
0x42
- NAME: str
“CharString”
- length_byte_length: number
1 (This is the number of bytes the length description takes)
- byte_length: number
the length of this string (not including the length bytes)
- value: str
The string representation of this field (note this does not include the length bytes)
- class st.zigbee.data_types.LongOctetString: st.zigbee.data_types.StringABC
- ID: number
0x43
- NAME: str
“LongOctetString”
- length_byte_length: number
2 (This is the number of bytes the length description takes)
- byte_length: number
the length of this string (not including the length bytes)
- value: str
The string representation of this field (note this does not include the length bytes)
- class st.zigbee.data_types.LongCharString: st.zigbee.data_types.StringABC
- ID: number
0x44
- NAME: str
“LongCharString”
- length_byte_length: number
2 (This is the number of bytes the length description takes)
- byte_length: number
the length of this string (not including the length bytes)
- value: str
The string representation of this field (note this does not include the length bytes)
Ordered Sequences
- class st.zigbee.data_types.ArrayABC: st.zigbee.data_types.DataType
Classes being created using the ArrayABC class represent Zigbee data types whose lua “value” is stored as an array of Zigbee data types all of the same type.
- static new_mt(base)
This function will create a new metatable with the appropriate functionality for a Zigbee Array
- class st.zigbee.data_types.Array: st.zigbee.data_types.ArrayABC
- ID: number
0x48
- NAME: str
“Array”
- value: table
the list of elements in this array
- class st.zigbee.data_types.StructureABC: st.zigbee.data_types.DataType
Classes being created using the StructureABC class represent Zigbee data types whose lua “value” is stored as an array of Zigbee data types each of which can be a separate type.
- static new_mt(base)
This function will create a new metatable with the appropriate functionality for a Zigbee Structure
- class st.zigbee.data_types.Structure: st.zigbee.data_types.StructureABC
- ID: number
0x4C
- NAME: str
“Structure”
- value: table
the list of elements in this structure
Collections
Set: Not yet implemented Bag: Not yet implemented
Time
- class st.zigbee.data_types.TimeOfDayABC: st.zigbee.data_types.DataType
Classes being created using the TimeOfDayABC class represent Zigbee data types whose lua “value” is stored as a set of hours, minutes, seconds, and hundredths of seconds (all Uints)
- static new_mt(base)
This function will create a new metatable with the appropriate functionality for a Zigbee TimeOfDay
- class st.zigbee.data_types.TimeOfDay: st.zigbee.data_types.TimeOfDayABC
- ID: number
0xE0
- NAME: str
“TimeOfDay”
- hours: st.zigbee.data_types.Uint8
The hours value of this time
- minutes: st.zigbee.data_types.Uint8
The minutes value of this time
- seconds: st.zigbee.data_types.Uint8
The seconds value of this time
- hundredths: st.zigbee.data_types.Uint8
The hundredths value of this time
- class st.zigbee.data_types.DateABC: st.zigbee.data_types.DataType
Classes being created using the DateABC class represent Zigbee data types whose lua “value” is stored as a set of hours, minutes, seconds, and hundredths of seconds (all Uints)
- static new_mt(base)
This function will create a new metatable with the appropriate functionality for a Zigbee Date
- class st.zigbee.data_types.Date: st.zigbee.data_types.DateABC
- ID: number
0xE1
- NAME: str
“Date”
- year: st.zigbee.data_types.Uint8
The year of this date (year - 1900, e.g. 119 for 2019)
- month: st.zigbee.data_types.Uint8
The month value of this date (1 - 12)
- day_of_month: st.zigbee.data_types.Uint8
The day of the month value of this date
- day_of_week: st.zigbee.data_types.Uint8
The day of week value of this date (1 - 7)
Identifiers
- class st.zigbee.data_types.ClusterId: st.zigbee.data_types.UintABC
- ID: number
0xE8
- NAME: str
“ClusterId”
- byte_length: number
2
- value: number
The cluster ID this represents