Custom zigbee2mqtt in C ++ with boost and exceptions


Home automation is an ambiguous thing, everyone understands by it something of their own: for someone it is to connect a heater via a wi-fi socket, and for someone give a home server, kilometers of cable, KNX and integrators’ working hours. If in city apartments the “smart home” system is not always a blessing, then for a country house or summer cottage the need for its availability increases greatly: control the heating, turn off the lights or warm up the electric stove in your favorite sauna before arrival. Moreover, such a system should be simple, cheap and able to work autonomously: no one wants to come to a house frozen due to the fallen Internet. And what needs to be done if the ready-made solutions do not completely suit, the right thing is to write it yourself …

For the combination of devices, the zigbee protocol was chosen for two reasons: firstly, it is wireless, and in the country no one wants to spend on unnecessary communications, and secondly, it is quite energy efficient and some kind of sensor or cutout can be powered by a CR2032 battery for several years without the need to supply external power.

The original idea was to attach to the project zigbee2mqtt your mini-server and hang on it all the logic for controlling a smart home (although rather a dacha). The disadvantages of this approach: firstly, secondary, and secondly, it is a separate server, separate zigbee2mqtt and a separate mqtt broker for unification, which obviously does not add reliability. Therefore, the first thing I had to start writing was my own library for working with a zigbee network on one of the most popular and affordable zigbee controllers. cc2531 from Texas Instruments.

With the documentation on zigbee chips, the situation is ambiguous – it exists, it is quite detailed, many of the nuances are well described, it is completely unclear from it how everything works and what to do about it. So with cc2531 it was clear how to organize the exchange of commands with the controller, but its initialization and configuration as a coordinator is not described normally anywhere. After unsuccessful searches in foreign forums, I realized that it is easier to study work on a live chip, since the SDK contains a Z-tool utility for it, which allows you to manually send commands and view responses.

True, it turned out very quickly that the newly launched controller was not going to somehow work with previously paired devices (Xiaomi WXKG01LM button and WSDCGQ01LM temperature sensor, etc.).

That being said, zigbee2mqtt worked correctly with both of them. The fastest way to start working through the Z-tool was to first start zigbee2mqtt, let it do everything that it needs to do, and then close it and, without restarting the controller, connect through the utility. And, oddly enough, this method worked.

As a result, it was quite quickly possible to understand the logic of work when receiving messages, pairing devices, etc., but it was impossible to move on without initialization.

For several days I dug into the source code of zigbee2mqtt, but I could not fully understand the logic, especially since it is blurred between the Koenkk project itself and its separate modules for working zigbee (zigbee-herdsman and zigbee-herdsman-converters). Having decided that it is better to enter from the reverse engineering side, zigbee2mqtt was launched through the Advanced Serial Port Monitor port sniffer, and a dump of its work was written to a file.

Soon a parser was written that produced something more readable from the dump and work began to recreate the logic of the work:

SYS_PING : ;
SYS_PING_SRSP : 0x79 0x7 ;
SYS_VERSION : ;
SYS_VERSION_SRSP : 0x2 0x2 0x2 0x7 0x2 0xd9 0x14 0x34 0x1 0x2 0x0 0x0 0x0 0x0 ;
SYS_OSAL_NV_READ : 0x60 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x1 0x55 ;
SYS_OSAL_NV_READ : 0x60 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x1 0x55 ;
SYS_OSAL_NV_READ : 0x84 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x4 0x0 0x8 0x0 0x0 ;
SYS_OSAL_NV_READ : 0x63 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x1 0x0 ;
SYS_OSAL_NV_READ : 0x83 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x2 0xff 0xff ;
SYS_OSAL_NV_READ : 0x83 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x2 0xff 0xff ;
UTIL_GET_DEVICE_INFO : ;
UTIL_GET_DEVICE_INFO_SRSP : 0x0 0xf0 0xa6 0x38 0x19 0x0 0x4b 0x12 0x0 0x0 0x0 0x7 0x9 0x4 0x7d 0x14 0x7a 0x43 0x82 0x85 0xa0 0x45 ;
ZDO_ACTIVE_EP_REQ : 0x0 0x0 0x0 0x0 ;
ZDO_ACTIVE_EP_SRSP : 0x0 ;
ZDO_ACTIVE_EP_RSP : 0x0 0x0 0x0 0x0 0x0 0xe 0xf2 0x2f 0xd 0xc 0x6e 0xb 0xa 0x8 0x6 0x5 0x4 0x3 0x2 0x1 ;
ZDO_ACTIVE_EP_REQ : 0x0 0x0 0x0 0x0 ;
ZDO_ACTIVE_EP_SRSP : 0x0 ;
ZDO_ACTIVE_EP_RSP : 0x0 0x0 0x0 0x0 0x0 0xe 0xf2 0x2f 0xd 0xc 0x6e 0xb 0xa 0x8 0x6 0x5 0x4 0x3 0x2 0x1 ;
UTIL_GET_DEVICE_INFO : ;
UTIL_GET_DEVICE_INFO_SRSP : 0x0 0xf0 0xa6 0x38 0x19 0x0 0x4b 0x12 0x0 0x0 0x0 0x7 0x9 0x4 0x7d 0x14 0x7a 0x43 0x82 0x85 0xa0 0x45 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0xf2 ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0xf2 0xe0 0xa1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0x2f ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0x2f 0x4 0x1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0xd ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0xa 0xd 0x4 0x1 0x5 0x0 0x0 0x1 0x19 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0xc ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0xc 0x5e 0xc0 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0x6e ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0x6e 0x4 0x1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0xb ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0xe 0xb 0x4 0x1 0x0 0x4 0x0 0x1 0x1 0x5 0x2 0x0 0x5 0x2 0x5 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0xa ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0xa 0x4 0x1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0x8 ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0x8 0x4 0x1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0x6 ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0x6 0x9 0x1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0x5 ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0x5 0x8 0x1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0x4 ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0x4 0x7 0x1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0x3 ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0x3 0x5 0x1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0x2 ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0x2 0x1 0x1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0x1 ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0x1 0x4 0x1 0x5 0x0 0x0 0x0 0x0 ;
SYS_VERSION : ;
SYS_VERSION_SRSP : 0x2 0x2 0x2 0x7 0x2 0xd9 0x14 0x34 0x1 0x2 0x0 0x0 0x0 0x0 ;
SYS_OSAL_NV_READ : 0x1 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x8 0xf0 0xa6 0x38 0x19 0x0 0x4b 0x12 0x0 ;
SYS_OSAL_NV_READ : 0x21 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x6e 0x4f 0x5 0x2 0x10 0x14 0x10 0x0 0x14 0x0 0x0 0x0 0x1 0x5 0x1 0x8f 0x7 0x0 0x2 0x5 0x1e 0x0 0x0 0xb 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x62 0x1a 0x8 0x0 0x8 0x0 0x0 0xf 0xf 0x4 0x0 0x1 0x0 0x0 0x0 0x1 0x0 0x0 0x0 0x0 0xf0 0xa6 0x38 0x19 0x0 0x4b 0x12 0x0 0x1 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x3c 0x3 0x0 0x1 0x78 0xa 0x1 0x0 0x0 0x1d 0xf 0x0 ;
SYS_OSAL_NV_READ : 0x83 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x2 0xff 0xff ;
SYS_OSAL_NV_READ : 0x2d 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x8 0xdd 0xdd 0xdd 0xdd 0xdd 0xdd 0xdd 0xdd ;
SYS_OSAL_NV_READ : 0x3a 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x11 0x0 0x1 0x3 0x5 0x7 0x9 0xb 0xd 0xf 0x0 0x2 0x4 0x6 0x8 0xa 0xc 0xd ;
SYS_OSAL_NV_READ : 0x3b 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x11 0x0 0x1 0x3 0x5 0x7 0x9 0xb 0xd 0xf 0x0 0x2 0x4 0x6 0x8 0xa 0xc 0xd ;
SYS_OSAL_NV_READ : 0x47 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x8 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ;
SYS_OSAL_NV_READ : 0x62 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x10 0x1 0x3 0x5 0x7 0x9 0xb 0xd 0xf 0x0 0x2 0x4 0x6 0x8 0xa 0xc 0xd ;
SYS_OSAL_NV_READ : 0x63 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x1 0x0 ;
SYS_OSAL_NV_READ : 0x84 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x4 0x0 0x8 0x0 0x0 ;
SYS_OSAL_NV_READ : 0x11 0x1 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x13 0x1e 0x1 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xff 0x0 0x0 ;
SYS_OSAL_NV_READ : 0x75 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0xc 0x35 0x34 0x2f 0x0 0xf0 0xa6 0x38 0x19 0x0 0x4b 0x12 0x0 ;
ZDO_MGMT_PERMIT_JOIN_REQ : 0xf 0xfc 0xff 0xfe 0x0 ;
ZDO_MGMT_PERMIT_JOIN_SRSP : 0x0 ;
ZDO_MGMT_PERMIT_JOIN_RSP : 0x0 0x0 0x0 ;
AF_DATA_CONFIRM : 0x0 0xf2 0x1 ;
SYS_PING : ;
SYS_PING_SRSP : 0x79 0x7 ;
SYS_VERSION : ;
SYS_VERSION_SRSP : 0x2 0x2 0x2 0x7 0x2 0xd9 0x14 0x34 0x1 0x2 0x0 0x0 0x0 0x0 ;
SYS_OSAL_NV_READ : 0x60 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x1 0x55 ;
SYS_OSAL_NV_READ : 0x60 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x1 0x55 ;
SYS_OSAL_NV_READ : 0x84 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x4 0x0 0x8 0x0 0x0 ;
SYS_OSAL_NV_READ : 0x63 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x1 0x0 ;
SYS_OSAL_NV_READ : 0x83 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x2 0xff 0xff ;
SYS_OSAL_NV_READ : 0x83 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x2 0xff 0xff ;
UTIL_GET_DEVICE_INFO : ;
UTIL_GET_DEVICE_INFO_SRSP : 0x0 0xf0 0xa6 0x38 0x19 0x0 0x4b 0x12 0x0 0xfe 0xff 0x7 0x0 0x0 ;
ZDO_STARTUP_FROM_APP : 0x64 0x0 ;
ZDO_STARTUP_FROM_APP_SRSP : 0x0 ;
ZDO_STATE_CHANGE_IND : 0x9 ;
ZDO_ACTIVE_EP_REQ : 0x0 0x0 0x0 0x0 ;
ZDO_ACTIVE_EP_SRSP : 0x0 ;
ZDO_ACTIVE_EP_RSP : 0x0 0x0 0x0 0x0 0x0 0x0 ;
AF_REGISTER : 0x1 0x4 0x1 0x5 0x0 0x0 0x0 0x0 0x0 ;
AF_REGISTER_SRSP : 0x0 ;
AF_REGISTER : 0x2 0x1 0x1 0x5 0x0 0x0 0x0 0x0 0x0 ;
AF_REGISTER_SRSP : 0x0 ;
AF_REGISTER : 0x3 0x5 0x1 0x5 0x0 0x0 0x0 0x0 0x0 ;
AF_REGISTER_SRSP : 0x0 ;
AF_REGISTER : 0x4 0x7 0x1 0x5 0x0 0x0 0x0 0x0 0x0 ;
AF_REGISTER_SRSP : 0x0 ;
AF_REGISTER : 0x5 0x8 0x1 0x5 0x0 0x0 0x0 0x0 0x0 ;
AF_REGISTER_SRSP : 0x0 ;
AF_REGISTER : 0x6 0x9 0x1 0x5 0x0 0x0 0x0 0x0 0x0 ;
AF_REGISTER_SRSP : 0x0 ;
AF_REGISTER : 0x8 0x4 0x1 0x5 0x0 0x0 0x0 0x0 0x0 ;
AF_REGISTER_SRSP : 0x0 ;
AF_REGISTER : 0xa 0x4 0x1 0x5 0x0 0x0 0x0 0x0 0x0 ;
AF_REGISTER_SRSP : 0x0 ;
AF_REGISTER : 0xb 0x4 0x1 0x0 0x4 0x0 0x0 0x1 0x1 0x5 0x2 0x0 0x5 0x2 0x5 ;
AF_REGISTER_SRSP : 0x0 ;
AF_REGISTER : 0x6e 0x4 0x1 0x5 0x0 0x0 0x0 0x0 0x0 ;
AF_REGISTER_SRSP : 0x0 ;
AF_REGISTER : 0xc 0x5e 0xc0 0x5 0x0 0x0 0x0 0x0 0x0 ;
AF_REGISTER_SRSP : 0x0 ;
AF_REGISTER : 0xd 0x4 0x1 0x5 0x0 0x0 0x0 0x1 0x19 0x0 0x0 ;
AF_REGISTER_SRSP : 0x0 ;
AF_REGISTER : 0x2f 0x4 0x1 0x5 0x0 0x0 0x0 0x0 0x0 ;
AF_REGISTER_SRSP : 0x0 ;
AF_REGISTER : 0xf2 0xe0 0xa1 0x5 0x0 0x0 0x0 0x0 0x0 ;
AF_REGISTER_SRSP : 0x0 ;
ZDO_ACTIVE_EP_REQ : 0x0 0x0 0x0 0x0 ;
ZDO_ACTIVE_EP_SRSP : 0x0 ;
ZDO_ACTIVE_EP_RSP : 0x0 0x0 0x0 0x0 0x0 0xe 0xf2 0x2f 0xd 0xc 0x6e 0xb 0xa 0x8 0x6 0x5 0x4 0x3 0x2 0x1 ;
UTIL_GET_DEVICE_INFO : ;
UTIL_GET_DEVICE_INFO_SRSP : 0x0 0xf0 0xa6 0x38 0x19 0x0 0x4b 0x12 0x0 0x0 0x0 0x7 0x9 0x4 0x7d 0x14 0x7a 0x43 0x82 0x85 0xa0 0x45 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0xf2 ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0xf2 0xe0 0xa1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0x2f ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0x2f 0x4 0x1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0xd ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0xa 0xd 0x4 0x1 0x5 0x0 0x0 0x1 0x19 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0xc ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0xc 0x5e 0xc0 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0x6e ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0x6e 0x4 0x1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0xb ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0xe 0xb 0x4 0x1 0x0 0x4 0x0 0x1 0x1 0x5 0x2 0x0 0x5 0x2 0x5 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0xa ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0xa 0x4 0x1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0x8 ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0x8 0x4 0x1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0x6 ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0x6 0x9 0x1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0x5 ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0x5 0x8 0x1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0x4 ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0x4 0x7 0x1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0x3 ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0x3 0x5 0x1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0x2 ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0x2 0x1 0x1 0x5 0x0 0x0 0x0 0x0 ;
ZDO_SIMPLE_DESC_REQ : 0x0 0x0 0x0 0x0 0x1 ;
ZDO_SIMPLE_DESC_SRSP : 0x0 ;
ZDO_SIMPLE_DESC_RSP : 0x0 0x0 0x0 0x0 0x0 0x8 0x1 0x4 0x1 0x5 0x0 0x0 0x0 0x0 ;
SYS_VERSION : ;
SYS_VERSION_SRSP : 0x2 0x2 0x2 0x7 0x2 0xd9 0x14 0x34 0x1 0x2 0x0 0x0 0x0 0x0 ;
SYS_OSAL_NV_READ : 0x1 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x8 0xf0 0xa6 0x38 0x19 0x0 0x4b 0x12 0x0 ;
SYS_OSAL_NV_READ : 0x21 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x6e 0x4f 0x5 0x2 0x10 0x14 0x10 0x0 0x14 0x0 0x0 0x0 0x1 0x5 0x1 0x8f 0x7 0x0 0x2 0x5 0x1e 0x0 0x0 0xb 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x62 0x1a 0x8 0x0 0x8 0x0 0x0 0xf 0xf 0x4 0x0 0x1 0x0 0x0 0x0 0x1 0x0 0x0 0x0 0x0 0xf0 0xa6 0x38 0x19 0x0 0x4b 0x12 0x0 0x1 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x3c 0x3 0x0 0x1 0x78 0xa 0x1 0x0 0x0 0x1d 0xf 0x0 ;
SYS_OSAL_NV_READ : 0x83 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x2 0xff 0xff ;
SYS_OSAL_NV_READ : 0x2d 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x8 0xdd 0xdd 0xdd 0xdd 0xdd 0xdd 0xdd 0xdd ;
SYS_OSAL_NV_READ : 0x3a 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x11 0x0 0x1 0x3 0x5 0x7 0x9 0xb 0xd 0xf 0x0 0x2 0x4 0x6 0x8 0xa 0xc 0xd ;
SYS_OSAL_NV_READ : 0x3b 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x11 0x0 0x1 0x3 0x5 0x7 0x9 0xb 0xd 0xf 0x0 0x2 0x4 0x6 0x8 0xa 0xc 0xd ;
SYS_OSAL_NV_READ : 0x47 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x8 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ;
SYS_OSAL_NV_READ : 0x62 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x10 0x1 0x3 0x5 0x7 0x9 0xb 0xd 0xf 0x0 0x2 0x4 0x6 0x8 0xa 0xc 0xd ;
SYS_OSAL_NV_READ : 0x63 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x1 0x0 ;
SYS_OSAL_NV_READ : 0x84 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x4 0x0 0x8 0x0 0x0 ;
SYS_OSAL_NV_READ : 0x11 0x1 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0x13 0x29 0x1 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0xff 0x0 0x0 ;
SYS_OSAL_NV_READ : 0x75 0x0 0x0 ;
SYS_OSAL_NV_READ_SRSP : 0x0 0xc 0x17 0x39 0x2f 0x0 0xf0 0xa6 0x38 0x19 0x0 0x4b 0x12 0x0 ;
ZDO_MGMT_PERMIT_JOIN_REQ : 0xf 0xfc 0xff 0xfe 0x0 ;
ZDO_MGMT_PERMIT_JOIN_SRSP : 0x0 ;
ZDO_MGMT_PERMIT_JOIN_RSP : 0x0 0x0 0x0 ;
AF_DATA_CONFIRM : 0x0 0xf2 0x1 ;

In total, in order to run ZNP as a coordinator, the minimum required:

  • write the settings to the non-volatile memory of the controller, in theory it is done once upon first power-up

  • reload

  • start work as a team ZDO_STARTUP_FROM_APP

  • register standard endpoints (one number one is enough for a home automation profile 0x0104)

Studying the zigbee2mqtt exchange dump more than once helped me out in case of problems in the initialization of devices connected to the network.

After some time, the zigbee part of the home automation mini-server was written in C ++ using Boost.Asio, and logic was screwed to it that combines devices into functional units (for example, a heating unit can combine a relay and a temperature sensor). But all this needs to be managed at least for connecting devices, and at most for full control via the Internet. As a result, the protocol for the second end of the system was chosen … mqtt (via the library mqtt_cpp), and the mini-server in some way became even more similar to the zigbee2mqtt project from which it all began.

The source code and a more detailed description of the project can be found at github

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *