espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.28k stars 7.35k forks source link

Zigbee - problem with raw mode #9745

Open ruediger218 opened 3 months ago

ruediger218 commented 3 months ago

Board

esp32c6

Device Description

esp32c6 dev module

Hardware Configuration

no

Version

v3.0.0

IDE Name

arduino ide

Operating System

windows 11

Flash frequency

80mhz

PSRAM enabled

yes

Upload speed

115200

Description

i want to develop a zigbee device with 4 on/off endpoints + a light endpoint for brightness configuration. my sourcecode based on the HA_on_off_light example i am not able to get callbacks when changing brightness. therefor i found a hint in using the function

this works perfect when i compile per commandline. in arduino ide i get the message: 'zb_zcl_parsed_hdr_t' was not declared in this scope are these raw functions not in the arduino environment? how can i get access to brightness (analog) values?

Sketch

bool rawCmdHandlerCb(uint8_t bufid) 
{
    uint8_t buf[zb_buf_len(bufid)];
    zb_zcl_parsed_hdr_t *cmd_info = ZB_BUF_GET_PARAM(bufid, zb_zcl_parsed_hdr_t);
    printf("cluster id: 0x%x, command id: %d\n", cmd_info->cluster_id, cmd_info->cmd_id);
    memcpy(buf, zb_buf_begin(bufid), sizeof(buf));
    if ((cmd_info->cluster_id == 8) && (cmd_info->cmd_id == 4)){
        ESP_LOGI("RAW", "brightness: %d", buf[0]);
    }
    else{
        ESP_LOGI("RAW", "bufid: %d size: %d", bufid, sizeof(buf));
        for (int i = 0; i < sizeof(buf); ++i) {
            ESP_LOGI("RAW", "buf[%d]: %d", i, buf[i]);
            //printf("0x%02X ", buf[i]);
        }
        //printf("\n");
    }

Debug Message

BewZigbee03.ino: In function 'bool rawCmdHandlerCb(uint8_t)':
BewZigbee03\BewZigbee03.ino:209:5: error: 'zb_zcl_parsed_hdr_t' was not declared in this scope
  209 |     esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, &modelid[0]);
      |     ^~~~~~~~~~~~~~~~~~~
BewZigbee03.ino:209:26: error: 'cmd_info' was not declared in this scope
  209 |     esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, &modelid[0]);
      |                          ^~~~~~~~
In file included from C:\Users\ruedi\AppData\Local\Arduino15\packages\esp32\tools\esp32-arduino-libs\idf-release_v5.1-442a798083/esp32c6/include/espressif__esp-zboss-lib/include/zboss_api.h:46,
                 from C:\Users\ruedi\Documents\Arduino\BewZigbee03\BewZigbee03.ino:22:
C:\Users\ruedi\AppData\Local\Arduino15\packages\esp32\tools\esp32-arduino-libs\idf-release_v5.1-442a798083/esp32c6/include/espressif__esp-zboss-lib/include/zboss_api_buf.h:468:45: error: expected primary-expression before ')' token
  468 | #define ZB_BUF_GET_PARAM(buf, type) ((type *)zb_buf_get_tail_func(TRACE_CALL (buf), sizeof(type)))
      |                                             ^
C:\Users\ruedi\Documents\Arduino\BewZigbee03\BewZigbee03.ino:209:37: note: in expansion of macro 'ZB_BUF_GET_PARAM'
  209 |     esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, &modelid[0]);
      |                                     ^~~~~~~~~~~~~~~~
AppData\Local\Arduino15\packages\esp32\tools\esp32-arduino-libs\idf-release_v5.1-442a798083/esp32c6/include/espressif__esp-zboss-lib/include/zboss_api_buf.h:468:46: error: expected ')' before 'zb_buf_get_tail_func'
  468 | #define ZB_BUF_GET_PARAM(buf, type) ((type *)zb_buf_get_tail_func(TRACE_CALL (buf), sizeof(type)))
      |                                     ~        ^~~~~~~~~~~~~~~~~~~~
BewZigbee03.ino:209:37: note: in expansion of macro 'ZB_BUF_GET_PARAM'
  209 |     esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, &modelid[0]);
      |                                     ^~~~~~~~~~~~~~~~

exit status 1

Compilation error: 'zb_zcl_parsed_hdr_t' was not declared in this scope

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

lbernstone commented 3 months ago

This type is defined in zcl/zb_zcl_common.h

ruediger218 commented 3 months ago

thanx a lot - but it's not the solution at all ;-(

sorry for my silly questions. now i get

undefined reference to `zb_buf_len_func(unsigned char)'

found that in zboss_api_buf.h but this didnt fix the error

P-R-O-C-H-Y commented 3 months ago

@ruediger218 Hello, can you please share where did you get those APIs from? Are they available in esp-zigbee-sdk? If yes, can you please post a link? Thanks

ruediger218 commented 3 months ago

hello, the source for the callback function is from https://github.com/espressif/esp-zigbee-sdk/issues/94 and yes, the code is working when i build in commandline idf

P-R-O-C-H-Y commented 3 months ago

The zb_buf_len_func(unsigned char) is located in zboss_api_buf.h as you wrote. I can see the file included in the libs for Esp32 Arduino. Path:

/Users/prochy/Documents/Arduino/hardware/espressif/esp32/tools/esp32-arduino-libs/esp32c6/include/espressif__esp-zboss-lib/include/zboss_api_buf.h

I don't see an issue there? Can you post your includes?

ruediger218 commented 3 months ago

my includes are as follow:

include "esp_zigbee_core.h"

include "freertos/FreeRTOS.h"

include "freertos/task.h"

include "ha/esp_zigbee_ha_standard.h"

include "zboss_api_buf.h"

include "zboss_api.h"

//include "zboss_api_zcl.h"

include "zcl/zb_zcl_common.h"

P-R-O-C-H-Y commented 3 months ago

hmm #include "zboss_api.h" is already including the "zboss_api_buf.h"

This is inside zboss_api.h:

#include "zb_version.h"
#include "zb_channel_page.h"
#include "zboss_api_core.h"
#include "zboss_api_buf.h"
#include "zboss_api_internal.h"
#include "zboss_api_nwk.h"
#include "zboss_api_af.h"
#include "zboss_api_zdo.h"
#include "zboss_api_aps.h"
#ifdef ZB_ENABLE_HA
#include "zb_ha.h"
#endif
#include "zb_address.h"
#ifdef ZB_ENABLE_SE_MIN_CONFIG
#include "zboss_api_se.h"
#endif
#ifdef ZB_ENABLE_ZCL
#include "zboss_api_zcl.h"
#endif /* ZB_ENABLE_ZCL */
#ifdef ZB_ENABLE_ZGP
#include "zboss_api_zgp.h"
#endif
ruediger218 commented 3 months ago

ok, with the includes:

include "esp_zigbee_core.h"

include "freertos/FreeRTOS.h"

include "freertos/task.h"

include "ha/esp_zigbee_ha_standard.h"

//#include "zboss_api_buf.h"

include "zboss_api.h"

//include "zboss_api_zcl.h"

include "zcl/zb_zcl_common.h"

i get the same error

c:/users/ruedi/appdata/local/arduino15/packages/esp32/tools/esp-rv32/2302/bin/../lib/gcc/riscv32-esp-elf/12.2.0/../../../../riscv32-esp-elf/bin/ld.exe: C:\Users\ruedi\AppData\Local\Temp\arduino\sketches\29E8A595CBE8784E42F9150A1F97F12D\sketch\BewZigbee03.ino.cpp.o: in function rawCmdHandlerCb(unsigned char)': C:\Users\ruedi\Documents\Arduino\BewZigbee03/BewZigbee03.ino:238: undefined reference tozb_buf_len_func(unsigned char)' c:/users/ruedi/appdata/local/arduino15/packages/esp32/tools/esp-rv32/2302/bin/../lib/gcc/riscv32-esp-elf/12.2.0/../../../../riscv32-esp-elf/bin/ld.exe: C:\Users\ruedi\Documents\Arduino\BewZigbee03/BewZigbee03.ino:239: undefined reference to zb_buf_get_tail_func(unsigned char, unsigned int)' c:/users/ruedi/appdata/local/arduino15/packages/esp32/tools/esp-rv32/2302/bin/../lib/gcc/riscv32-esp-elf/12.2.0/../../../../riscv32-esp-elf/bin/ld.exe: C:\Users\ruedi\Documents\Arduino\BewZigbee03/BewZigbee03.ino:241: undefined reference tozb_buf_begin_func(unsigned char)' collect2.exe: error: ld returned 1 exit status

exit status 1

Compilation error: exit status 1

ruediger218 commented 3 months ago

hello, in my opinion it's not a problem with the include's but a problem of the linker for me it seems that on arduino-esp the include doesn't "inform" the linker to get the spec. boss libs for linking (not all) or am i wrong? by the way: can i do anything as workarround to get the brightness callback in the normal esp_zb_core_action_handler_register ?

P-R-O-C-H-Y commented 3 months ago

@ruediger218 Will you be able to test it with Arduino as component in IDF to see if its working for you there and you have everything linked properly? Also if you can post reproducible sketch for me so I can investigate? Thanks

P-R-O-C-H-Y commented 3 months ago

Those are our linked prebuilt libs in Arduino, depending on selected zigbee mode:

esp32h2.menu.ZigbeeMode.ed=Zigbee ED (end device)
esp32h2.menu.ZigbeeMode.ed.build.zigbee_mode=-DZIGBEE_MODE_ED
esp32h2.menu.ZigbeeMode.ed.build.zigbee_libs=-lesp_zb_api_ed -lesp_zb_cli_command -lzboss_stack.ed -lzboss_port
esp32h2.menu.ZigbeeMode.zczr=Zigbee ZCZR (coordinator)
esp32h2.menu.ZigbeeMode.zczr.build.zigbee_mode=-DZIGBEE_MODE_ZCZR
esp32h2.menu.ZigbeeMode.zczr.build.zigbee_libs=-lesp_zb_api_zczr -lesp_zb_cli_command -lzboss_stack.zczr -lzboss_port
esp32h2.menu.ZigbeeMode.rcp=Zigbee RCP (radio co-processor)
esp32h2.menu.ZigbeeMode.rcp.build.zigbee_mode=-DZIGBEE_MODE_RCP
esp32h2.menu.ZigbeeMode.rcp.build.zigbee_libs=-lesp_zb_api_rcp -lesp_zb_cli_command -lzboss_stack.rcp -lzboss_port
ruediger218 commented 3 months ago

ok. i try to collect minimal files: Here is the idf file `/*

include "freertos/FreeRTOS.h"

include "freertos/task.h"

include "esp_check.h"

include "esp_log.h"

include "nvs_flash.h"

include "ha/esp_zigbee_ha_standard.h"

include "test_rawmode.h"

include "zboss_api.h"

if !defined ZB_ED_ROLE

error Define ZB_ED_ROLE in idf.py menuconfig to compile light (End Device) source code.

endif

static const char *TAG = "test_rawmode";

bool rawCmdHandlerCb(uint8_t bufid) { uint8_t buf[zb_buf_len(bufid)]; zb_zcl_parsed_hdr_t *cmd_info = ZB_BUF_GET_PARAM(bufid, zb_zcl_parsed_hdr_t); printf("cluster id: 0x%x, command id: %d\n", cmd_info->cluster_id, cmd_info->cmd_id); memcpy(buf, zb_buf_begin(bufid), sizeof(buf)); if ((cmd_info->cluster_id == 8) && (cmd_info->cmd_id == 4)){ ESP_LOGI("RAW", "brightness: %d", buf[0]); } else{ ESP_LOGI("RAW", "bufid: %d size: %d", bufid, sizeof(buf)); for (int i = 0; i < sizeof(buf); ++i) { ESP_LOGI("RAW", "buf[%d]: %d", i, buf[i]); //printf("0x%02X ", buf[i]); } //printf("\n"); } //return true; return false; }

static void esp_zb_task(void *pvParameters) { esp_zb_raw_command_handler_register(rawCmdHandlerCb); }

void app_main(void) { xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL); } the arduino sketch is following #define ARDUINO

ifndef ZIGBEE_MODE_ED

error "Zigbee end device mode is not selected in Tools->Zigbee mode"

endif

include "esp_zigbee_core.h"

include "freertos/FreeRTOS.h"

include "freertos/task.h"

define ZB_ENABLE_HA

define ZB_ENABLE_ZCL

define ZB_ENABLE_ZGP

include "zboss_api.h"

include "zcl/zb_zcl_common.h"

static const char *TAG = "test_rawmode";

/ Default End Device config /

define ESP_ZB_ZED_CONFIG() \

{ \ .esp_zb_role = ESP_ZB_DEVICE_TYPE_ED, .install_code_policy = INSTALLCODE_POLICY_ENABLE, \ .nwk_cfg = { \ .zed_cfg = \ { \ .ed_timeout = ED_AGING_TIMEOUT, \ .keep_alive = ED_KEEP_ALIVE, \ }, \ }, \ }

define ESP_ZB_DEFAULT_RADIO_CONFIG() \

{ .radio_mode = ZB_RADIO_MODE_NATIVE, }

define ESP_ZB_DEFAULT_HOST_CONFIG() \

{ .host_connection_mode = ZB_HOST_CONNECTION_MODE_NONE, }

/ Zigbee configuration /

define INSTALLCODE_POLICY_ENABLE false / enable the install code policy for security /

define ED_AGING_TIMEOUT ESP_ZB_ED_AGING_TIMEOUT_64MIN

define ED_KEEP_ALIVE 3000 / 3000 millisecond /

define HA_ESP_LIGHT_ENDPOINT 10 / esp light bulb device endpoint, used to process light controlling commands /

define HA_COLOR_DIMMABLE_LIGHT_ENDPOINT 10 / esp light switch device endpoint /

define ESP_ZB_PRIMARY_CHANNEL_MASK ESP_ZB_TRANSCEIVER_ALL_CHANNELS_MASK / Zigbee primary channel mask use in the example /

static esp_err_t zb_attribute_handler(const esp_zb_zcl_set_attr_value_message_t *message);

bool rawCmdHandlerCb(uint8_t bufid) { uint8_t buf[zb_buf_len(bufid)]; zb_zcl_parsed_hdr_t *cmd_info = ZB_BUF_GET_PARAM(bufid, zb_zcl_parsed_hdr_t); printf("cluster id: 0x%x, command id: %d\n", cmd_info->cluster_id, cmd_info->cmd_id); memcpy(buf, zb_buf_begin(bufid), sizeof(buf)); if ((cmd_info->cluster_id == 8) && (cmd_info->cmd_id == 4)){ ESP_LOGI("RAW", "brightness: %d", buf[0]); } else{ ESP_LOGI("RAW", "bufid: %d size: %d", bufid, sizeof(buf)); for (int i = 0; i < sizeof(buf); ++i) { ESP_LOGI("RAW", "buf[%d]: %d", i, buf[i]); //printf("0x%02X ", buf[i]); } //printf("\n"); } //return true; return false; }

static void esp_zb_task(void *pvParameters) { esp_zb_raw_command_handler_register(rawCmdHandlerCb); }

void app_main(void) { xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL); }

/***** Arduino functions **/ void setup() {

Serial.begin(115200); // set default RX/TX pin because nothing was defined in the call

// Init Zigbee Serial.println("Zigbee init"); esp_zb_platform_config_t config = { .radio_config = ESP_ZB_DEFAULT_RADIO_CONFIG(), .host_config = ESP_ZB_DEFAULT_HOST_CONFIG(), }; ESP_ERROR_CHECK(esp_zb_platform_config(&config));

// Start Zigbee task //Serial.println("Zigbee start main"); xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL); }

void loop() { //empty, zigbee running in task } the idf compiles fine but the arduino sketch breaks with undefined reference tozb_buf_len_func(unsigned char)'

ruediger218 commented 3 months ago

here comes test_rawmode.h `/*

include "esp_zigbee_core.h"

include "light_driver.h"

/ Zigbee configuration /

define INSTALLCODE_POLICY_ENABLE false / enable the install code policy for security /

define ED_AGING_TIMEOUT ESP_ZB_ED_AGING_TIMEOUT_64MIN

define ED_KEEP_ALIVE 3000 / 3000 millisecond /

define HA_ESP_LIGHT_ENDPOINT 10 / esp light bulb device endpoint, used to process light controlling commands /

define ESP_ZB_PRIMARY_CHANNEL_MASK ESP_ZB_TRANSCEIVER_ALL_CHANNELS_MASK / Zigbee primary channel mask use in the example /

define ESP_ZB_ZED_CONFIG() \

{                                                               \
    .esp_zb_role = ESP_ZB_DEVICE_TYPE_ED,                       \
    .install_code_policy = INSTALLCODE_POLICY_ENABLE,           \
    .nwk_cfg.zed_cfg = {                                        \
        .ed_timeout = ED_AGING_TIMEOUT,                         \
        .keep_alive = ED_KEEP_ALIVE,                            \
    },                                                          \
}

define ESP_ZB_DEFAULT_RADIO_CONFIG() \

{                                                           \
    .radio_mode = RADIO_MODE_NATIVE,                        \
}

define ESP_ZB_DEFAULT_HOST_CONFIG() \

{                                                           \
    .host_connection_mode = HOST_CONNECTION_MODE_NONE,      \
}

`

fpalarmini commented 2 months ago

@ruediger218 , please try to include zboss_api_h with linkage specification:

ifdef __cplusplus

extern "C" {

endif

include "zboss_api.h"

ifdef __cplusplus

}

endif

ruediger218 commented 2 months ago

thats the solution - thank you so much ! one little difference is that the cluster_id in arduino ide is a int > 1000 and when i use idf then its < 100, have you a hint for that?

fpalarmini commented 2 months ago

I'm not sure, does the cluster_id number make sense? Does the other device only send to cluster_id 8(LEVEL_CONTROL)? In the esp_zigbee_zcl_common.h file, there is an enum listing the cluster_id numbers.

ruediger218 commented 2 months ago

the cluster id is in the upper byte (here "8")

ruediger218 commented 2 months ago

btw can you have a look on #9856 it seems like a similar problem?

fpalarmini commented 2 months ago

I tried your code from issue #9856, here it worked. The difference is that I used a CC2531 dongle with Z2M. Try debugging with wireshark to see if there are zigbee packets leaving from your board.

fpalarmini commented 2 months ago

I tried your code from issue #9856, here it worked. The difference is that I used a CC2531 dongle with Z2M. Try debugging with wireshark to see if there are zigbee packets leaving from your board.

https://docs.espressif.com/projects/esp-zigbee-sdk/en/latest/esp32/developing.html#sniffer-and-wireshark

ruediger218 commented 2 months ago

thanks for your help. i made some more new tests and it seems that i had - for every software change in my esp code - stop zigbee2mqtt, delete my device in zigbee2mqtt database, start zigbee2mqtt and at last start my esp device (with changed code). when i changed code without deleting in the zigbee2mqtt database then there are no temperature changes visible in zigbee2mqtt status.