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:

st.zigbee.AddressHeader

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:

table

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:
Returns:

The constructed AddressHeader

Return type:

st.zigbee.AddressHeader

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 or ZclMessageRx 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 or ZclMessageRx 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 ZigbeeMessageRx

  • opts (table) – Additional options for controlling deserialize

Returns:

one form of a Zigbee rx message

Return type:

st.zigbee.ZigbeeMessageRx

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 for

  • endpoint (number) – the endpoint to address the message to

Returns:

self with the updated endpoint

Return type:

st.zigbee.ZigbeeMessageRx

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 for

  • device (st.zigbee.Device) – the device this is going to

  • component_id (str) – the device component this should be addressed to

Returns:

self with the updated endpoint

Return type:

st.zigbee.ZigbeeMessageRx

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:

st.zigbee.ZigbeeMessageTx

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 for

  • endpoint (number) – the endpoint to address the message to

Returns:

self with the updated endpoint

Return type:

st.zigbee.ZigbeeMessageTx

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 for

  • device (st.zigbee.Device) – the device this is going to

  • component_id (str) – the device component this should be addressed to

Returns:

self with the updated endpoint

Return type:

st.zigbee.ZigbeeMessageTx

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:

st.zigbee.zcl.Header

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:

table

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:
  • orig (table) – UNUSED This is the AddressHeader object when called with the syntax ZclHeader(…)

  • data_table (table) – a table containing the fields of this ZclHeader. Only cmd is required as seqno and frame_ctrl will be given default values if not specified

Returns:

The constructed ZclHeader

Return type:

st.zigbee.zcl.Header

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 information

  • buf (Reader) – The buf Reader in the position of representing the ZclMessageBody

Returns:

a new instance of the ZclMessageBody parsed from the bytes

Return type:

st.zigbee.zcl.MessageBody

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:

table

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:
  • proto (table) – UNUSED This is the ZclMessageBody class when called with the syntax ZclMessageBody(…)

  • data_table (table) – a table containing the fields of this ZclMessageBody. zcl_header, and body are required.

Returns:

The constructed containing the Zcl MessageBody

Return type:

st.zigbee.zcl.MessageBody

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:

st.zigbee.zdo.Header

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:

table

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:

st.zigbee.zdo.Header

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_length

  • buf (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:

st.zigbee.zdo.MessageBody

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:

table

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:
  • orig (table) – UNUSED This is the ZdoMessageRx object when called with the syntax ZdoMessageRx(…)

  • data_table (table) – a table containing the fields of this ZdoMessageRx. address_header, zdo_header, and body are required. type, lqi, rssi are optional with defaults

Returns:

The constructed ZdoMessageRx

Return type:

st.zigbee.zdo.MessageBody