diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index 2499d1d257..77b4f7a326 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -987,6 +987,16 @@ pytest_examples_openthread_br: - esp32c6 - openthread_br +pytest_examples_zigbee: + extends: + - .pytest_examples_dir_template + - .rules:test:example_test-esp32h2 + needs: + - build_pytest_examples_esp32h2 + tags: + - esp32h2 + - zigbee_multi_dut + pytest_components_esp32s3_usb_host: extends: - .pytest_components_dir_template diff --git a/conftest.py b/conftest.py index 881d01d182..8c575068b7 100644 --- a/conftest.py +++ b/conftest.py @@ -130,6 +130,7 @@ ENV_MARKERS = { # multi-dut markers 'ieee802154': 'ieee802154 related tests should run on ieee802154 runners.', 'openthread_br': 'tests should be used for openthread border router.', + 'zigbee_multi_dut': 'zigbee runner which have multiple duts.', 'wifi_two_dut': 'tests should be run on runners which has two wifi duts connected.', 'generic_multi_device': 'generic multiple devices whose corresponding gpio pins are connected to each other.', 'twai_network': 'multiple runners form a TWAI network.', diff --git a/examples/zigbee/.build-test-rules.yml b/examples/zigbee/.build-test-rules.yml index 36bb2e31c6..fad1c9d1f5 100644 --- a/examples/zigbee/.build-test-rules.yml +++ b/examples/zigbee/.build-test-rules.yml @@ -1,17 +1,29 @@ # Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps +.zigbee_dependencies: &zigbee_dependencies + depends_filepatterns: + - components/ieee802154/**/* + - examples/zigbee/light_sample/**/* + examples/zigbee/esp_zigbee_gateway: disable: - if: IDF_TARGET in ["esp32c2", "esp32h2"] temporary: true reason: target(s) not supported yet + <<: *zigbee_dependencies examples/zigbee/esp_zigbee_rcp: enable: - if: IDF_TARGET in ["esp32c6", "esp32h2"] reason: should able to run on esp32h2 and esp32c6 + <<: *zigbee_dependencies examples/zigbee/light_sample: enable: - if: IDF_TARGET in ["esp32c6", "esp32h2"] reason: should able to run on esp32h2 and esp32c6 + disable_test: + - if: IDF_TARGET == "esp32c6" + temporary: true + reason: only test on esp32h2 + <<: *zigbee_dependencies diff --git a/examples/zigbee/esp_zigbee_gateway/main/esp_zigbee_gateway.c b/examples/zigbee/esp_zigbee_gateway/main/esp_zigbee_gateway.c index 7e79318bd9..a6777d90b7 100644 --- a/examples/zigbee/esp_zigbee_gateway/main/esp_zigbee_gateway.c +++ b/examples/zigbee/esp_zigbee_gateway/main/esp_zigbee_gateway.c @@ -35,6 +35,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -46,12 +47,41 @@ #include "esp_coexist_internal.h" #include "esp_zigbee_gateway.h" +#include "esp_vfs_dev.h" +#include "esp_vfs_usb_serial_jtag.h" +#include "driver/usb_serial_jtag.h" + #if (!defined ZB_MACSPLIT_HOST && defined ZB_MACSPLIT_DEVICE) #error Only Zigbee gateway host device should be defined #endif static const char *TAG = "ESP_ZB_GATEWAY"; +/* Note: Please select the correct console output port based on the development board in menuconfig */ +#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG +esp_err_t esp_zb_gateway_console_init(void) +{ + esp_err_t ret = ESP_OK; + /* Disable buffering on stdin */ + setvbuf(stdin, NULL, _IONBF, 0); + + /* Minicom, screen, idf_monitor send CR when ENTER key is pressed */ + esp_vfs_dev_usb_serial_jtag_set_rx_line_endings(ESP_LINE_ENDINGS_CR); + /* Move the caret to the beginning of the next line on '\n' */ + esp_vfs_dev_usb_serial_jtag_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF); + + /* Enable non-blocking mode on stdin and stdout */ + fcntl(fileno(stdout), F_SETFL, O_NONBLOCK); + fcntl(fileno(stdin), F_SETFL, O_NONBLOCK); + + usb_serial_jtag_driver_config_t usb_serial_jtag_config = USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT(); + ret = usb_serial_jtag_driver_install(&usb_serial_jtag_config); + esp_vfs_usb_serial_jtag_use_driver(); + esp_vfs_dev_uart_register(); + return ret; +} +#endif + /********************* Define functions **************************/ static void bdb_start_top_level_commissioning_cb(uint8_t mode_mask) { @@ -136,6 +166,9 @@ void app_main(void) ESP_ERROR_CHECK(nvs_flash_init()); ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); +#if CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG + ESP_ERROR_CHECK(esp_zb_gateway_console_init()); +#endif #if CONFIG_EXAMPLE_CONNECT_WIFI ESP_ERROR_CHECK(example_connect()); #if CONFIG_ESP_COEX_SW_COEXIST_ENABLE diff --git a/examples/zigbee/esp_zigbee_gateway/main/idf_component.yml b/examples/zigbee/esp_zigbee_gateway/main/idf_component.yml index 5ce0cb5c75..1d60ab3792 100644 --- a/examples/zigbee/esp_zigbee_gateway/main/idf_component.yml +++ b/examples/zigbee/esp_zigbee_gateway/main/idf_component.yml @@ -1,7 +1,7 @@ ## IDF Component Manager Manifest File dependencies: - espressif/esp-zboss-lib: "~0.4.0" - espressif/esp-zigbee-lib: "~0.5.0" + espressif/esp-zboss-lib: "~0.5.0" + espressif/esp-zigbee-lib: "~0.7.0" ## Required IDF version idf: version: ">=5.0.0" diff --git a/examples/zigbee/esp_zigbee_rcp/main/idf_component.yml b/examples/zigbee/esp_zigbee_rcp/main/idf_component.yml index 5ce0cb5c75..1d60ab3792 100644 --- a/examples/zigbee/esp_zigbee_rcp/main/idf_component.yml +++ b/examples/zigbee/esp_zigbee_rcp/main/idf_component.yml @@ -1,7 +1,7 @@ ## IDF Component Manager Manifest File dependencies: - espressif/esp-zboss-lib: "~0.4.0" - espressif/esp-zigbee-lib: "~0.5.0" + espressif/esp-zboss-lib: "~0.5.0" + espressif/esp-zigbee-lib: "~0.7.0" ## Required IDF version idf: version: ">=5.0.0" diff --git a/examples/zigbee/light_sample/HA_on_off_light/main/esp_zb_light.h b/examples/zigbee/light_sample/HA_on_off_light/main/esp_zb_light.h index d4b89f57ef..7885b50009 100644 --- a/examples/zigbee/light_sample/HA_on_off_light/main/esp_zb_light.h +++ b/examples/zigbee/light_sample/HA_on_off_light/main/esp_zb_light.h @@ -43,8 +43,7 @@ #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 (1l << 13) /* Zigbee primary channel mask use in the example */ - +#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, \ diff --git a/examples/zigbee/light_sample/HA_on_off_light/main/idf_component.yml b/examples/zigbee/light_sample/HA_on_off_light/main/idf_component.yml index b4e6b4d084..0799daf730 100644 --- a/examples/zigbee/light_sample/HA_on_off_light/main/idf_component.yml +++ b/examples/zigbee/light_sample/HA_on_off_light/main/idf_component.yml @@ -1,7 +1,7 @@ ## IDF Component Manager Manifest File dependencies: - espressif/esp-zigbee-lib: "~0.5.0" - espressif/esp-zboss-lib: "~0.4.0" + espressif/esp-zigbee-lib: "~0.7.0" + espressif/esp-zboss-lib: "~0.5.0" espressif/led_strip: "~2.0.0" ## Required IDF version idf: diff --git a/examples/zigbee/light_sample/HA_on_off_switch/main/esp_zb_switch.h b/examples/zigbee/light_sample/HA_on_off_switch/main/esp_zb_switch.h index 7d89e241cd..3a14d46637 100644 --- a/examples/zigbee/light_sample/HA_on_off_switch/main/esp_zb_switch.h +++ b/examples/zigbee/light_sample/HA_on_off_switch/main/esp_zb_switch.h @@ -41,7 +41,7 @@ #define MAX_CHILDREN 10 /* the max amount of connected devices */ #define INSTALLCODE_POLICY_ENABLE false /* enable the install code policy for security */ #define HA_ONOFF_SWITCH_ENDPOINT 1 /* esp light switch device endpoint */ -#define ESP_ZB_PRIMARY_CHANNEL_MASK (1l << 13) /* Zigbee primary channel mask use in the example */ +#define ESP_ZB_PRIMARY_CHANNEL_MASK ESP_ZB_TRANSCEIVER_ALL_CHANNELS_MASK /* Zigbee primary channel mask use in the example */ #define ESP_ZB_ZC_CONFIG() \ { \ diff --git a/examples/zigbee/light_sample/HA_on_off_switch/main/idf_component.yml b/examples/zigbee/light_sample/HA_on_off_switch/main/idf_component.yml index c91d6de081..0a20539842 100644 --- a/examples/zigbee/light_sample/HA_on_off_switch/main/idf_component.yml +++ b/examples/zigbee/light_sample/HA_on_off_switch/main/idf_component.yml @@ -1,7 +1,7 @@ ## IDF Component Manager Manifest File dependencies: - espressif/esp-zigbee-lib: "~0.5.0" - espressif/esp-zboss-lib: "~0.4.0" + espressif/esp-zigbee-lib: "~0.7.0" + espressif/esp-zboss-lib: "~0.5.0" ## Required IDF version idf: version: ">=5.0.0" diff --git a/examples/zigbee/light_sample/pytest_esp_zigbee.py b/examples/zigbee/light_sample/pytest_esp_zigbee.py new file mode 100644 index 0000000000..0d24a7f636 --- /dev/null +++ b/examples/zigbee/light_sample/pytest_esp_zigbee.py @@ -0,0 +1,46 @@ +# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 +# !/usr/bin/env python3 + +import pathlib +import time +from typing import Tuple + +import pytest +from pytest_embedded import Dut + +CURRENT_DIR_LIGHT = str(pathlib.Path(__file__).parent / 'HA_on_off_light') +CURRENT_DIR_SWITCH = str(pathlib.Path(__file__).parent / 'HA_on_off_switch') +pytest_build_dir = CURRENT_DIR_LIGHT + '|' + CURRENT_DIR_SWITCH + + +@pytest.mark.esp32h2 +@pytest.mark.zigbee_multi_dut +@pytest.mark.parametrize( + ' count, app_path, erase_all', [ + (2, pytest_build_dir, 'y'), + ], + indirect=True, +) +# config Zigbee network +def test_config_zigbee_network(dut:Tuple[Dut, Dut]) -> None: + light = dut[0] + switch = dut[1] + time.sleep(3) + switch.expect('ESP_ZB_ON_OFF_SWITCH: Formed network successfully',timeout=30) + # get the switch extpanid + switch_node_expanid = switch.expect(r'Extended PAN ID: (([a-z0-9]{2}:?){8})',timeout=3)[1].decode() + switch_node_expanid = switch_node_expanid.replace(':','') + # get the switch panid + switch_node_panid = switch.expect(r'PAN ID: 0x([a-z0-9]+:?)',timeout=2)[1].decode() + # new device commissioned successfully + switch.expect(r'New device commissioned or rejoined \(short: 0x([a-z0-9]+)[^a-z0-9]',timeout=30)[1].decode() + # get the light node extpanid + light.expect('ESP_ZB_ON_OFF_LIGHT: Joined network successfully',timeout=20) + light_node_expanid = light.expect(r'Extended PAN ID: (([a-z0-9]{2}:?){8})',timeout=3)[1].decode() + light_node_expanid = light_node_expanid.replace(':','') + # get the light panid + light_node_panid = light.expect(r'PAN ID: 0x([a-z0-9]+:?)',timeout=2)[1].decode() + # make sure the light node join the network that switch node formed (same expanid) + if ((light_node_expanid != switch_node_expanid) or (light_node_panid != switch_node_panid)): + assert False