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

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