espressif / esp-zigbee-sdk

Espressif Zigbee SDK
Apache License 2.0
122 stars 19 forks source link

Transmit JSON data (TZ-714) #296

Closed superbagus1712 closed 1 month ago

superbagus1712 commented 2 months ago

Question

Can i transmit json data via zigbee within 100miliseconds delay ? i have tried but failed esp32c6 keep restarting

Additional context.

No response

xieqinan commented 2 months ago

@superbagus1712,

The esp-zigbee-sdk supports transmitting APS data (https://github.com/espressif/esp-zigbee-sdk/blob/main/components/esp-zigbee-lib/include/aps/esp_zigbee_aps.h#L118), which can help with your issue. However, you need to adjust the transmission time according to the data size. If the data size is less than 1024, a 500 ms delay is acceptable.

superbagus1712 commented 2 months ago

@xieqinan do you have an example to use APS data ? sorry im actually little bit confused with zigbee api

xieqinan commented 2 months ago

@superbagus1712,

The ESP-Zigbee-SDK does not provide an example for APS, but I can provide guidance on its usage.

The sender:

static void esp_zb_buttons_handler(switch_func_pair_t *button_func_pair)
{
    if (button_func_pair->func == SWITCH_ONOFF_TOGGLE_CONTROL) {
        esp_zb_apsde_data_req_t req;
        // Data
        for (int i = 0; i < sizeof(s_value); i++) {
            s_value[i] = i;
        }
        req.dst_addr_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT;
        // The basic information of destination
        req.dst_short_addr = 0xd47d;       
        req.dst_endpoint = 10;
        req.profile_id = 0x104;
        req.cluster_id = 0xFFF1;
        req.src_endpoint = 1;
        // Payload
        req.asdu_length = sizeof(s_value);
        req.asdu = s_value;
        // routing hops
        req.radius = 2;
        req.tx_options = (ESP_ZB_APSDE_TX_OPT_ACK_TX | ESP_ZB_APSDE_TX_OPT_FRAG_PERMITTED);
        req.use_alias = false;
        ESP_EARLY_LOGI(TAG, "Send aps data request");
        esp_zb_lock_acquire(portMAX_DELAY);
        esp_zb_aps_data_request(&req);
        esp_zb_lock_release();
    }
}

The receiver:

static bool zb_apsde_data_indication_handler(esp_zb_apsde_data_ind_t ind)
{
    if (!ind.status && ind.cluster_id == 0xFFF1 && ind.profile_id == 0x0104 && ind.dst_endpoint == 10) {
        ESP_LOGI(TAG, "APS data size: %d", ind.asdu_length);
        return true;
    }
    return false;
}
esp_zb_aps_data_indication_handler_register(zb_apsde_data_indication_handler);
superbagus1712 commented 2 months ago

thanks for your support @xieqinan . How about the zigbee task ? i still dont understand to add the zigbee APS task

superbagus1712 commented 2 months ago

@xieqinan i also have this problem on receiver side WhatsApp Image 2024-04-01 at 1 53 10 PM

xieqinan commented 2 months ago

@superbagus1712 ,

It's just a data formatting issue. You can refer to either ESP_LOGI(TAG, "APS data size: %lld", ind.asdu_length); or ESP_LOGI(TAG, "APS data size: %d", (uint16_t)ind.asdu_length);.

superbagus1712 commented 2 months ago

@xieqinan there s nothing happen on receiver after pressing button WhatsApp Image 2024-04-01 at 3 21 23 PM

superbagus1712 commented 2 months ago

here my senderfile @xieqinan
`typedef struct light_bulb_device_params_s { esp_zb_ieee_addr_t ieee_addr; uint8_t endpoint; uint16_t short_addr; } light_bulb_device_params_t;

static switch_func_pair_t button_func_pair[] = { {GPIO_INPUT_IO_TOGGLE_SWITCH, SWITCH_ONOFF_TOGGLE_CONTROL} };

static const char *TAG = "APSsend";

static void bdb_start_top_level_commissioning_cb(uint8_t mode_mask) { ESP_RETURN_ON_FALSE(esp_zb_bdb_start_top_level_commissioning(mode_mask) == ESP_OK, , TAG, "Failed to start Zigbee bdb commissioning"); }

static uint8_t s_value[10];

static void esp_zb_buttons_handler(switch_func_pair_t *button_func_pair) { if (button_func_pair->func == SWITCH_ONOFF_TOGGLE_CONTROL) { esp_zb_apsde_data_req_t req; // Data for (int i = 0; i < sizeof(s_value); i++) { s_value[i] = i; } req.dst_addr_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; // The basic information req.dst_short_addr = 0xd47d;
req.dst_endpoint = 10; req.profile_id = 0x104; req.cluster_id = 0xFFF1; req.src_endpoint = 10; // Payload req.asdu_length = sizeof(s_value); req.asdu = s_value; // routing req.radius = 2; req.tx_options = (ESP_ZB_APSDE_TX_OPT_ACK_TX | ESP_ZB_APSDE_TX_OPT_FRAG_PERMITTED); req.use_alias = false; ESP_EARLY_LOGI(TAG, "Send aps data request"); esp_zb_lock_acquire(portMAX_DELAY); esp_zb_aps_data_request(&req); esp_zb_lock_release(); } }

static esp_err_t deferred_driver_init(void) { ESP_RETURN_ON_FALSE(switch_driver_init(button_func_pair, PAIR_SIZE(button_func_pair), esp_zb_buttons_handler), ESP_FAIL, TAG, "Failed to initialize switch driver"); return ESP_OK; }

void esp_zb_app_signal_handler(esp_zb_app_signal_t signal_struct) { uint32_t p_sg_p = signal_struct->p_app_signal; esp_err_t err_status = signal_struct->esp_err_status; esp_zb_app_signal_type_t sig_type = p_sg_p; esp_zb_zdo_signal_device_annce_params_t dev_annce_params = NULL; switch (sig_type) { case ESP_ZB_ZDO_SIGNAL_SKIP_STARTUP: ESP_LOGI(TAG, "Initialize Zigbee stack"); esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_INITIALIZATION); break; case ESP_ZB_BDB_SIGNAL_DEVICE_FIRST_START: case ESP_ZB_BDB_SIGNAL_DEVICE_REBOOT: if (err_status == ESP_OK) { ESP_LOGI(TAG, "Deferred driver initialization %s", deferred_driver_init() ? "failed" : "successful"); ESP_LOGI(TAG, "Device started up in %s factory-reset mode", esp_zb_bdb_is_factory_new() ? "" : "non"); if (esp_zb_bdb_is_factory_new()) { ESP_LOGI(TAG, "Start network formation"); esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_FORMATION); } else { ESP_LOGI(TAG, "Device rebooted"); } } else { ESP_LOGE(TAG, "Failed to initialize Zigbee stack (status: %s)", esp_err_to_name(err_status)); } break; case ESP_ZB_BDB_SIGNAL_FORMATION: if (err_status == ESP_OK) { esp_zb_ieee_addr_t extended_pan_id; esp_zb_get_extended_pan_id(extended_pan_id); ESP_LOGI(TAG, "Formed network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx, Channel:%d, Short Address: 0x%04hx)", extended_pan_id[7], extended_pan_id[6], extended_pan_id[5], extended_pan_id[4], extended_pan_id[3], extended_pan_id[2], extended_pan_id[1], extended_pan_id[0], esp_zb_get_pan_id(), esp_zb_get_current_channel(), esp_zb_get_short_address()); esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_STEERING); } else { ESP_LOGI(TAG, "Restart network formation (status: %s)", esp_err_to_name(err_status)); esp_zb_scheduler_alarm((esp_zb_callback_t)bdb_start_top_level_commissioning_cb, ESP_ZB_BDB_MODE_NETWORK_FORMATION, 1000); } break; case ESP_ZB_BDB_SIGNAL_STEERING: if (err_status == ESP_OK) { ESP_LOGI(TAG, "Network steering started"); } break; case ESP_ZB_ZDO_SIGNAL_DEVICE_ANNCE: dev_annce_params = (esp_zb_zdo_signal_device_annce_params_t )esp_zb_app_signal_get_params(p_sg_p); ESP_LOGI(TAG, "New device commissioned or rejoined (short: 0x%04hx)", dev_annce_params->device_short_addr); esp_zb_zdo_match_desc_req_param_t cmd_req; cmd_req.dst_nwk_addr = dev_annce_params->device_short_addr; cmd_req.addr_of_interest = dev_annce_params->device_short_addr; //esp_zb_zdo_find_on_off_light(&cmd_req, user_find_cb, NULL); break; case ESP_ZB_NWK_SIGNAL_PERMIT_JOIN_STATUS: if (err_status == ESP_OK) { if ((uint8_t )esp_zb_app_signal_get_params(p_sg_p)) { ESP_LOGI(TAG, "Network(0x%04hx) is open for %d seconds", esp_zb_get_pan_id(), (uint8_t *)esp_zb_app_signal_get_params(p_sg_p)); } else { ESP_LOGW(TAG, "Network(0x%04hx) closed, devices joining not allowed.", esp_zb_get_pan_id()); } } break; default: ESP_LOGI(TAG, "ZDO signal: %s (0x%x), status: %s", esp_zb_zdo_signal_to_string(sig_type), sig_type, esp_err_to_name(err_status)); break; } }

static void esp_zb_task(void pvParameters) { / initialize Zigbee stack / esp_zb_cfg_t zb_nwk_cfg = ESP_ZB_ZC_CONFIG(); esp_zb_init(&zb_nwk_cfg); esp_zb_on_off_switch_cfg_t switch_cfg = ESP_ZB_DEFAULT_ON_OFF_SWITCH_CONFIG(); esp_zb_ep_list_t esp_zb_on_off_switch_ep = esp_zb_on_off_switch_ep_create(HA_ONOFF_SWITCH_ENDPOINT, &switch_cfg); esp_zb_device_register(esp_zb_on_off_switch_ep); esp_zb_set_primary_network_channel_set(ESP_ZB_PRIMARY_CHANNEL_MASK); ESP_ERROR_CHECK(esp_zb_start(false)); esp_zb_main_loop_iteration(); }

void app_main(void) { esp_zb_platform_config_t config = { .radio_config = ESP_ZB_DEFAULT_RADIO_CONFIG(), .host_config = ESP_ZB_DEFAULT_HOST_CONFIG(), }; ESP_ERROR_CHECK(nvs_flash_init()); ESP_ERROR_CHECK(esp_zb_platform_config(&config));

xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL);

}`

superbagus1712 commented 2 months ago

here my receiver file `static const char *TAG = "APSReceive"; /***** Define functions **/ static esp_err_t deferred_driver_init(void) { light_driver_init(LIGHT_DEFAULT_OFF); return ESP_OK; }

static void bdb_start_top_level_commissioning_cb(uint8_t mode_mask) { ESP_RETURN_ON_FALSE(esp_zb_bdb_start_top_level_commissioning(mode_mask) == ESP_OK, , TAG, "Failed to start Zigbee commissioning"); }

void esp_zb_app_signal_handler(esp_zb_app_signal_t signal_struct) { uint32_t p_sg_p = signal_struct->p_app_signal; esp_err_t err_status = signal_struct->esp_err_status; esp_zb_app_signal_type_t sig_type = p_sg_p; switch (sig_type) { case ESP_ZB_ZDO_SIGNAL_SKIP_STARTUP: ESP_LOGI(TAG, "Initialize Zigbee stack"); esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_INITIALIZATION); break; case ESP_ZB_BDB_SIGNAL_DEVICE_FIRST_START: case ESP_ZB_BDB_SIGNAL_DEVICE_REBOOT: if (err_status == ESP_OK) { ESP_LOGI(TAG, "Deferred driver initialization %s", deferred_driver_init() ? "failed" : "successful"); ESP_LOGI(TAG, "Device started up in %s factory-reset mode", esp_zb_bdb_is_factory_new() ? "" : "non"); if (esp_zb_bdb_is_factory_new()) { ESP_LOGI(TAG, "Start network steering"); esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_STEERING); } else { ESP_LOGI(TAG, "Device rebooted"); } } else { / commissioning failed */ ESP_LOGW(TAG, "Failed to initialize Zigbee stack (status: %s)", esp_err_to_name(err_status)); } break; case ESP_ZB_BDB_SIGNAL_STEERING: if (err_status == ESP_OK) { esp_zb_ieee_addr_t extended_pan_id; esp_zb_get_extended_pan_id(extended_pan_id); ESP_LOGI(TAG, "Joined network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx, Channel:%d, Short Address: 0x%04hx)", extended_pan_id[7], extended_pan_id[6], extended_pan_id[5], extended_pan_id[4], extended_pan_id[3], extended_pan_id[2], extended_pan_id[1], extended_pan_id[0], esp_zb_get_pan_id(), esp_zb_get_current_channel(), esp_zb_get_short_address()); } else { ESP_LOGI(TAG, "Network steering was not successful (status: %s)", esp_err_to_name(err_status)); esp_zb_scheduler_alarm((esp_zb_callback_t)bdb_start_top_level_commissioning_cb, ESP_ZB_BDB_MODE_NETWORK_STEERING, 1000); } break; default: ESP_LOGI(TAG, "ZDO signal: %s (0x%x), status: %s", esp_zb_zdo_signal_to_string(sig_type), sig_type, esp_err_to_name(err_status)); break; } } static bool zb_apsde_data_indication_handler(esp_zb_apsde_data_ind_t ind) { if (!ind.status && ind.cluster_id == 0xFFF1 && ind.profile_id == 0x0104 && ind.dst_endpoint == 10) { ESP_LOGI(TAG, "APS data size: %d", (uint16_t)ind.asdu_length); return true; } return false; }

static void esp_zb_task(void pvParameters) { / initialize Zigbee stack / esp_zb_cfg_t zb_nwk_cfg = ESP_ZB_ZED_CONFIG(); esp_zb_init(&zb_nwk_cfg); esp_zb_on_off_light_cfg_t light_cfg = ESP_ZB_DEFAULT_ON_OFF_LIGHT_CONFIG(); esp_zb_ep_list_t esp_zb_on_off_light_ep = esp_zb_on_off_light_ep_create(HA_ESP_LIGHT_ENDPOINT, &light_cfg); esp_zb_device_register(esp_zb_on_off_light_ep); esp_zb_aps_data_indication_handler_register(zb_apsde_data_indication_handler); esp_zb_set_primary_network_channel_set(ESP_ZB_PRIMARY_CHANNEL_MASK); ESP_ERROR_CHECK(esp_zb_start(false)); esp_zb_main_loop_iteration(); }

void app_main(void) { esp_zb_platform_config_t config = { .radio_config = ESP_ZB_DEFAULT_RADIO_CONFIG(), .host_config = ESP_ZB_DEFAULT_HOST_CONFIG(), }; ESP_ERROR_CHECK(nvs_flash_init()); ESP_ERROR_CHECK(esp_zb_platform_config(&config)); xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL); }`

superbagus1712 commented 2 months ago

@xieqinan it seems i didnt see any problem

xieqinan commented 2 months ago

Hi,

If you use the code provided by me directly, there might be some issues:

superbagus1712 commented 2 months ago

@xieqinan still same problem i have set the req.dst_short_addr to (0xaed4)

xieqinan commented 2 months ago

@xieqinan there s nothing happen on receiver after pressing button WhatsApp Image 2024-04-01 at 3 21 23 PM

The short address value 0xaed4 is taken from the picture, but it will change if the device is factory reset. Have you updated it accordingly?

superbagus1712 commented 2 months ago

@xieqinan yes already

xieqinan commented 2 months ago

@superbagus1712,

Could you utilize the sniffer to check the packet whether has been sent by the switch device?

superbagus1712 commented 2 months ago

@xieqinan what kind sniffer that i can use ?

xieqinan commented 2 months ago

@superbagus1712

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

chshu commented 1 month ago

@superbagus1712 The APS usage is commented here: https://github.com/espressif/esp-zigbee-sdk/issues/296#issuecomment-2024779903. It doesn't care what's the data format (no matter JSON or any others). Feel free to reopen if you have any further questions.