Zigbee Messages
This module provides a helpful interface to interact with Zigbee messages, both incoming and outgoing,
in a useful way using tables instead of a string of bytes. At the top level, a message will be either
a ZigbeeMessageRx
or ZigbeeMessageTx
which are constructed of a few parts. First, there is the
AddressHeader
which contains information about where the message is from and
where it is being sent to. Then will also contain a message body which will typically be constructed of
either a ZclMessageBody
or a
ZdoMessageBody
. All of the message types share a common interface that is
also shared among all of their component parts. Each of these should include implementations of the following methods:
- deserialize
for creating the table from a string of bytes
- get_length
for giving the length in bytes of this object if it were serialized
- pretty_print
for creating a human readable string representing this object
- serialize
for serializing the message frame back into a string of bytes
- from_values
for creating the table object from the component parts instead of parsing from a string. This should also be mapped to the metatable __call function for the table so the syntax Object(…) can be used for creation
Below is an example of parsing a byte stream into an Rx message:
local zb_messages = require "st.zigbee.messages"
local buf = require "st.buf"
local zb_utils = require "st.zigbee.utils"
local on_off_attr_report = "\x00\xAD\xDE\x01\xEF\xBE\x01\x04\x01\x06\x00\xFF\xFE\x06\x00\x00\xFF\x0A\x00\x00\x10\x01"
local parsed_message = zb_messages.ZigbeeMessageRx.deserialize(buf.Reader(on_off_attr_report))
print(parsed_message.zcl_header.cmd.value) -- 10
print(parsed_message.body.attr_records[1].attr_id.value) -- 0
print(parsed_message.body.attr_records[1].data.value) -- true
print(parsed_message:pretty_print(zb_utils.MULTI_LINE_FORMAT_CONFIG))
-- ZigbeeMessageRx:
-- type: 0x00
-- AddressHeader:
-- src_addr: 0xDEAD
-- src_endpoint: 0x01
-- dest_addr: 0xBEEF
-- dest_endpoint: 0x01
-- profile: 0x0104
-- cluster: OnOff
-- lqi: 0xFF
-- rssi: -2
-- body_length: 0x0006
-- ZCLMessageBody:
-- ZCLHeader:
-- frame_ctrl: 0x00
-- seqno: 0xFF
-- ZCLCommandId: 0x0A
-- ReportAttribute:
-- AttributeRecord:
-- AttributeId: 0x0000
-- DataType: Boolean
-- OnOff: true
And here is an example building a read attribute command Tx message:
local zb_messages = require "st.zigbee.messages"
local zcl_messages = require "st.zigbee.zcl"
local zb_utils = require "st.zigbee.utils"
local read_attribute = require "st.zigbee.zcl.global_commands.read_attribute"
local zb_const = require "st.zigbee.constants"
local data_types = require "st.zigbee.data_types"
local read_body = read_attribute.ReadAttribute({0x0000})
local zclh = zcl_messages.ZclHeader({
cmd = data_types.ZCLCommandId(read_attribute.ReadAttribute.ID)
})
local addrh = zb_messages.AddressHeader(
zb_const.HUB.ADDR,
zb_const.HUB.ENDPOINT,
0xDEAD,
0x01,
zb_const.HA_PROFILE_ID,
0x0006
)
local message_body = zcl_messages.ZclMessageBody({
zcl_header = zclh,
zcl_body = read_body
})
local built_message = zb_messages.ZigbeeMessageTx({
address_header = addrh,
body = message_body
})
print(built_message:pretty_print(zb_utils.MULTILINE_FORMAT_CONFIG))
-- ZigbeeMessageTx:
-- Uint16: 0x0000
-- AddressHeader:
-- src_addr: 0x0000
-- src_endpoint: 0x01
-- dest_addr: 0xDEAD
-- dest_endpoint: 0x01
-- profile: 0x0104
-- cluster: OnOff
-- ZCLMessageBody:
-- ZCLHeader:
-- frame_ctrl: 0x00
-- seqno: 0x00
-- ZCLCommandId: 0x00
-- ReadAttribute:
-- AttributeId: 0x0000
Module documentation
- class st.zigbee.AddressHeader
A class representing the addressing information of a Zigbee message
- NAME: str
“AddressHeader” used for printing
- src_addr: st.zigbee.data_types.Uint16
The source address of the device sending the message
- src_endpoint: st.zigbee.data_types.Uint8
The source endpoint of the device sending the message
- dest_addr: st.zigbee.data_types.Uint16
The destination address of the recipient of the message
- dest_endpoint: st.zigbee.data_types.Uint8
The destination endpoint of the recipient of the message
- profile: st.zigbee.data_types.Uint16
The profile Id of the message being sent
- cluster: st.zigbee.data_types.ClusterId
The cluster Id of the message
- static deserialize(buf)
A function to take a stream of bytes and parse a zigbee message address header
- Parameters
buf (
str
) – The byte string starting with the beginning of the bytes representing the AddressHeader- Returns
a new instance of the address header parsed from the bytes
- Return type
- get_fields()
A helper function used by common code to get all the component pieces of this message frame
- Returns
An array formatted table with each component field in the order their bytes should be serialized
- Return type
- get_length()
A function to return the total length in bytes this frame uses when serialized
- Returns
the length in bytes of this frame
- Return type
number
- pretty_print()
A function for printing in a human readable format
- Returns
A human readable representation of this message frame
- Return type
str
- static init(orig, src_addr, src_endpoint, dest_addr, dest_endpoint, profile, cluster)
This is a function to build an address header from its individual components
- Parameters
orig (
table
) – UNUSED This is the AddressHeader object when called with the syntax AddressHeader(…)src_addr (
st.zigbee.data_types.Uint16
) – The source address of the device sending the messagesrc_endpoint (
st.zigbee.data_types.Uint8
) – The source endpoint of the device sending the messagedest_addr (
st.zigbee.data_types.Uint16
) – The destination address of the recipient of the messagedest_endpoint (
st.zigbee.data_types.Uint8
) – The destination endpoint of the recipient of the messageprofile (
st.zigbee.data_types.Uint16
) – The profile Id of the message being sentcluster (
st.zigbee.data_types.ClusterId
) – The cluster Id of the message
- Returns
The constructed AddressHeader
- Return type
- class st.zigbee.ZigbeeMessageRx
A generic class representing an incoming zigbee message (device -> hub). For most cases this class shouldn’t be instantiated on it’s own, but instead one of
ZdoMessageRx
orZclMessageRx
should be used. This would only be used if using a profile other than those and needing a truly custom body- NAME: str
“ZigbeeMessageRx” used for printing
- type: st.zigbee.data_types.Uint8
message type (internal use only)
- address_header: st.zigbee.AddressHeader
The addressing information for this message
- lqi: st.zigbee.data_types.Uint8
The lqi of this message
- rssi: st.zigbee.data_types.Int8
The rssi of this message
- body: GenericBody
only used for a custom body
- static deserialize(buf, opts)
A function to take a stream of bytes and parse a received Zigbee Rx message (device -> hub)
This will typically result in either a
ZdoMessageRx
orZclMessageRx
but if the profile ID is unrecognized will just result in this class with a- Parameters
buf (
Reader
) – The buf positioned at the beginning of the bytes representing the ZigbeeMessageRxopts (
table
) – Additional options for controlling deserialize
- Returns
one form of a Zigbee rx message
- Return type
- get_fields()
- from_endpoint(self, endpoint)
Set the endpoint of the message source
This is primarily useful for building test commands
- Parameters
self (
st.zigbee.ZigbeeMessageRx
) – the message to update the addressing forendpoint (
number
) – the endpoint to address the message to
- Returns
self with the updated endpoint
- Return type
- from_component(self, device, component_id)
Set the addressing of the message to match a devices component
This is primarily useful for building test commands
- Parameters
self (
st.zigbee.ZigbeeMessageRx
) – the message to update the addressing fordevice (
st.zigbee.Device
) – the device this is going tocomponent_id (
str
) – the device component this should be addressed to
- Returns
self with the updated endpoint
- Return type
- get_length()
A function to return the total length in bytes this frame uses when serialized
- Returns
the length in bytes of this frame
- Return type
number
- pretty_print()
A function for printing in a human readable format
- Returns
A human readable representation of this message frame
- Return type
str
- class st.zigbee.ZigbeeMessageTx
A generic class representing an outgoing zigbee message (hub -> device). For most cases
this class shouldn’t be instantiated on it’s own, but instead one of ZdoMessageTx or ZclMessageTx should be used. This would only be used if using a profile other than those and needing a truly custom body
- NAME: str
“ZigbeeMessageTx” used for printing
- tx_options: st.zigbee.data_types.Uint16
Transmit options for this command
- address_header: st.zigbee.AddressHeader
The addressing information for this message
- body: GenericBody
only used for a custom body
- static deserialize(buf)
A function to take a stream of bytes and parse a Zigbee Tx message.
In general this will result in either a ZclMessageTx or ZdoMessageTx, and would only result in a generic ZigbeeMessageTx if the profile was unknown
- Parameters
buf (
Reader
) – The buf positioned at the beginning of the bytes representing the message- Returns
one form of a Zigbee tx message
- Return type
- get_fields()
- to_endpoint(self, endpoint)
Set the endpoint of the message to that supplied
This is primarily useful in simpler message construction through chaining
- Parameters
self (
st.zigbee.ZigbeeMessageTx
) – the message to update the addressing forendpoint (
number
) – the endpoint to address the message to
- Returns
self with the updated endpoint
- Return type
- to_component(self, device, component_id)
Set the addressing of the message to match a devices component
This is primarily useful in simpler message construction through chaining
- Parameters
self (
st.zigbee.ZigbeeMessageTx
) – the message to update the addressing fordevice (
st.zigbee.Device
) – the device this is going tocomponent_id (
str
) – the device component this should be addressed to
- Returns
self with the updated endpoint
- Return type
- get_length()
A function to return the total length in bytes this frame uses when serialized
- Returns
the length in bytes of this frame
- Return type
number
- pretty_print()
A function for printing in a human readable format
- Returns
A human readable representation of this message frame
- Return type
str
- class st.zigbee.zcl.FrameCtrl: BitmapABC
- BASE_MASK: number
0xFF Mask for the whole field
- FRAME_TYPE: number
0x03 Mask to get the frame type value
- MFG_SPECIFIC: number
0x04 Mask to get the mfg specific value
- DIRECTION: number
0x08 Mask to get the direction value
- DISABLE_DEFAULT_RESPONSE: number
0x10 Mask to get the disable default response value
- DIRECTION_CLIENT: number
0x08 The value for direction client
- DIRECTION_SERVER: number
0x00 The value for direction server
- NAME: str
“ZclFrameCtrl”
- ID: number
0x18
- is_frame_type_set()
- Returns
true if frame type is non-zero
- Return type
boolean
- set_frame_type(field_val)
- Parameters
field_val (
number
) – the new value for the frame type bit field
- get_frame_type()
- Returns
the value for the frame type bit field
- Return type
number
- unset_frame_type()
set the frame type bit field to 0
- is_cluster_specific_set()
- Returns
true if frame type is cluster specific
- Return type
boolean
- set_cluster_specific()
sets this frame control field to be cluster specific
- is_mfg_specific_set()
- Returns
true if this frame control is mfg specific
- Return type
boolean
- set_mfg_specific()
sets the mfg specific field to true
- unset_mfg_specific()
set the mfg specific bit field to false
- is_direction_set()
- Returns
true if this frame control is direction client
- Return type
boolean
- get_direction()
- Returns
the direction of this frame control
- Return type
number
- set_direction()
sets the value of the direction bit field to 1
- set_direction_server()
sets the value of the direction bit field to 0 (direction to server)
- set_direction_client()
sets the value of the direction bit field to 1 (direction to client)
- unset_direction()
sets the value of the direction bit field to 0
- is_disable_default_response_set()
- Returns
true if this frame control has default responses disabled
- Return type
boolean
- set_disable_default_response()
sets the default responses to be disabled
- unset_disable_default_response()
sets the default responses to be enabled
- class st.zigbee.zcl.Header
A class representing the Header information of a Zigbee ZCL message
- NAME: str
“ZclHeader” used for printing
- frame_ctrl: st.zigbee.zcl.FrameCtrl
The frame control for this message
- mfg_code: st.zigbee.data_types.Uint16
(optional) present if the frame_ctrl field specifies the message is manufacturer specific
- seqno: st.zigbee.data_types.Uint8
The sequence number of the message (unused in most contexts)
- cmd: st.zigbee.data_types.Uint8
The command ID for this message
- static deserialize(buf)
A function to take a stream of bytes and parse a zigbee message zcl header
- Parameters
buf (
Reader
) – The buf Reader in the position of representing the ZclHeader- Returns
a new instance of the ZclHeader parsed from the bytes
- Return type
- get_fields()
A helper function used by common code to get all the component pieces of this message frame
- Returns
An array formatted table with each component field in the order their bytes should be serialized
- Return type
- get_length()
A function to return the total length in bytes this frame uses when serialized
- Returns
the length in bytes of this frame
- Return type
number
- pretty_print()
A function for printing in a human readable format
- Returns
A human readable representation of this message frame
- Return type
str
- static from_values(orig, data_table)
This is a function to build an zcl header from its individual components
- Parameters
- Returns
The constructed ZclHeader
- Return type
- class st.zigbee.zcl.MessageBody
A class representing the body of a Zigbee ZCL message
- NAME: str
“ZclMessageBody” used for printing
- static deserialize(parent, buf)
Convert a stream of bytes into a zigbee message ZCL body
- Parameters
parent (
st.zigbee.ZigbeeMessageRx or st.zigbee.ZigbeeMessageTx
) – the full Zigbee message containing the appropriate addressing informationbuf (
Reader
) – The buf Reader in the position of representing the ZclMessageBody
- Returns
a new instance of the ZclMessageBody parsed from the bytes
- Return type
- get_fields()
A helper function used by common code to get all the component pieces of this message frame
- Returns
An array formatted table with each component field in the order their bytes should be serialized
- Return type
- get_length()
A function to return the total length in bytes this frame uses when serialized
- Returns
the length in bytes of this frame
- Return type
number
- pretty_print()
A function for printing in a human readable format
- Returns
A human readable representation of this message frame
- Return type
str
- static from_values(proto, data_table)
This is a function to build an zcl message body from its individual components
- Parameters
- Returns
The constructed containing the Zcl MessageBody
- Return type
- class st.zigbee.zdo.Header
A class representing a zigbee ZDO header
- NAME: str
“ZDOHeader” used for printing
- seqno: st.zigbee.data_types.Uint8
the sequence number for the Zigbee message
- static deserialize(buf)
A function to take a stream of bytes and parse a Zigbee Zdo header
- Parameters
buf (
Reader
) – The buf positioned at the beginning of the bytes representing the ZdoHeader- Returns
a new instance of the ZdoHeader parsed from the bytes
- Return type
- get_fields()
A helper function used by common code to get all the component pieces of this message frame
- Returns
An array formatted table with each component field in the order their bytes should be serialized
- Return type
- get_length()
A function to return the total length in bytes this frame uses when serialized
- Returns
the length in bytes of this frame
- Return type
number
- pretty_print()
A function for printing in a human readable format
- Returns
A human readable representation of this message frame
- Return type
str
- static from_values(orig, seqno)
This is a function to build a Zdo header from its individual components
- Parameters
orig (
table
) – UNUSED This is the ZclMessageRx object when called with the syntax ZclMessageRx(…)seqno (
st.zigbee.data_types.Uint8
) – the sequence number for the ZDO header
- Returns
The constructed ZdoHeader
- Return type
- class st.zigbee.zdo.MessageBody
A class representing a received zigbee ZDO message (device -> hub).
- NAME: str
“ZdoMessageRx” used for printing
- type: st.zigbee.data_types.Uint8
message type (internal use only)
- address_header: st.zigbee.AddressHeader
The addressing information for this message
- lqi: st.zigbee.data_types.Uint8
The lqi of this message
- rssi: st.zigbee.data_types.Int8
The rssi of this message
- zdo_header: st.zigbee.zdo.Header
The ZdoHeader for this message
- body: st.zigbee.zdo.MessageBody
The message body. This is a message frame that must implement serialize, get_length, pretty_print, etc.
- static deserialize(parent, buf)
A function to take a stream of bytes and parse a received Zigbee Zdo message (device -> hub)
- Parameters
parent (
table
) – A parent table for the class that includes the type, address_header, lqi, rssi, and body_lengthbuf (
Reader
) – The buf positioned at the beginning of the bytes representing the ZdoHeader
- Returns
a new instance of the ZdoMessageRx parsed from the bytes
- Return type
- get_fields()
A helper function used by common code to get all the component pieces of this message frame
- Returns
An array formatted table with each component field in the order their bytes should be serialized
- Return type
- get_length()
A function to return the total length in bytes this frame uses when serialized
- Returns
the length in bytes of this frame
- Return type
number
- pretty_print()
A function for printing in a human readable format
- Returns
A human readable representation of this message frame
- Return type
str
- static from_values(orig, data_table)
This is a function to build an zdo rx message from its individual components
- Parameters
- Returns
The constructed ZdoMessageRx
- Return type