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

Device Management

This module provides a helper functions for interacting with Zigbee messages related to device management, such as configuring reporting, and cluster bindings. There are also functions relating to device health and refresh which rely on the presence of monitored and configured attributes on the device.

st.zigbee.device_management.attr_refresh(device, cluster, attribute, mfg_code)

Build a read attribute command

Parameters:
  • device (st.zigbee.Device) – the device to address the read attribute to

  • cluster (number) – the cluster id of the attribute to read

  • attribute (number) – the attribute id to read

  • mfg_code (number) – Optional: the mfg code if the attribute is mfg specific

Returns:

the constructed read attribute ZigbeeTx command

Return type:

st.zigbee.zcl.ReadAttribute

st.zigbee.device_management.build_bind_request(device, cluster, hub_zigbee_eui, ep_id)

Build a ZDO bind request

Parameters:
  • device (st.Device) – the device to address the bind request to

  • cluster (number) – the cluster id of the attribute to read

  • hub_zigbee_eui (str) – the byte string for the hub’s zigbee eui for binding

  • ep_id (number or nil) – the endpoint to bind

Returns:

the constructed bind request ZigbeeTx command

Return type:

st.zigbee.zdo.BindRequest

st.zigbee.device_management.attr_config(device, attr_config)

Configure an attribute for reporting

This will not include the ZDO bind request for the cluster, which will need to be sent separately.

Parameters:
Returns:

the constructed configure reporting ZigbeeTx command

Return type:

st.zigbee.zcl.ConfigureReporting

st.zigbee.device_management.check_all_devices_for_health(driver)

Check all devices managed by this driver and send reads for stale attributes

This will call the check_for_health function for each device managed by this driver. Note that we the automatic driver health check functionality for monitored attributes is deprecated.

Parameters:

driver (Driver) – the driver context

st.zigbee.device_management.write_ias_cie_address(device, cie_address)

Write the hubs Zigbee EUI as the CIE address for the IAS Zone device

Parameters:
  • device (st.Device) – the device to write the CIE address to

  • cie_address (str) – the 8 byte address to write to the cie address for the IAS zone cluster

st.zigbee.device_management.configure_ias_zone(device, ias_zone_configuration_method, cie_address)

Configure IAS Zone for the given device using the given ias_zone_configuration_method

Parameters:
  • device (st.Device) – the device to configure IAS Zone for

  • ias_zone_configuration_method (number) – One of the defined IAS Zone configuration methods

  • cie_address (str) – the 8 byte address to write to the cie address for the IAS zone cluster

st.zigbee.device_management.configure(driver, device)

Configure all of the necessary attributes for a given device

This will look at all the attribute_configurations defined for a driver and attempt to configure each of those attributes for the given device

Parameters:
  • driver (Driver) – the driver context

  • device (st.Device) – the device to configure

st.zigbee.device_management.refresh(driver, device)

Refresh all of the configured attributes for a given device

This will look at all the attribute_configurations defined for a driver and attempt to read the value of each of them for the given device

Parameters:
  • driver (Driver) – the driver context

  • device (st.Device) – the device to configure

st.zigbee.device_management.init_device_health(driver)

Set up a driver to have attribute health checking enabled

Parameters:

driver (Driver) – the driver to configure health checks for