diff --git a/.gitignore b/.gitignore index 80ae3c3..80731a7 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,9 @@ venv/ hardware/racer/fp-info-cache hardware/racer/racer-backups *.csv +!firmware/partitions_zigbee.csv +!kicad/*.csv +!scripts/sensor_log.csv # Python __pycache__/ @@ -22,4 +25,4 @@ scripts/build/ *.spec.bak # Local release staging -releases/ \ No newline at end of file +releases/ diff --git a/firmware/CMakeLists.txt b/firmware/CMakeLists.txt index 3f79349..4f71bb4 100644 --- a/firmware/CMakeLists.txt +++ b/firmware/CMakeLists.txt @@ -3,4 +3,4 @@ cmake_minimum_required(VERSION 3.16) include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(AirCube) \ No newline at end of file +project(AirCube) diff --git a/firmware/main/CMakeLists.txt b/firmware/main/CMakeLists.txt index 5b44c2b..bcfc133 100644 --- a/firmware/main/CMakeLists.txt +++ b/firmware/main/CMakeLists.txt @@ -9,6 +9,6 @@ idf_component_register(SRCS "main.c" "button.c" "history.c" "zigbee.c" - PRIV_REQUIRES spi_flash esp_partition esp_timer esp_driver_rmt esp_driver_i2c esp_driver_uart esp_driver_usb_serial_jtag vfs esp_pm esp_driver_gpio nvs_flash + PRIV_REQUIRES spi_flash esp_partition esp_timer esp_driver_rmt esp_driver_i2c esp_driver_uart esp_driver_usb_serial_jtag vfs esp_pm esp_driver_gpio nvs_flash esp_app_format espressif__esp-zigbee-lib espressif__esp-zboss-lib INCLUDE_DIRS "") diff --git a/firmware/main/zigbee.c b/firmware/main/zigbee.c index 7774e3b..898fe96 100644 --- a/firmware/main/zigbee.c +++ b/firmware/main/zigbee.c @@ -19,7 +19,9 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" +#include #include "esp_check.h" +#include "esp_app_desc.h" #include "esp_log.h" #include "nvs_flash.h" #include "nvs.h" @@ -45,12 +47,14 @@ static const char *TAG = "zigbee"; /* ZCL string attributes: first byte is the string length */ #define MANUFACTURER_NAME "\x10" "StuckAtPrototype" #define MODEL_IDENTIFIER "\x07" "AirCube" +#define SW_BUILD_ID_MAX_LEN (sizeof(((esp_app_desc_t *)0)->version) - 1) /* ── State ───────────────────────────────────────────────────────────── */ static volatile bool s_connected = false; static volatile bool s_pairing = false; static TickType_t s_pairing_start = 0; +static uint8_t s_sw_build_id[SW_BUILD_ID_MAX_LEN + 1] = { 0 }; #define PAIRING_TIMEOUT_MS 60000 /* Auto-cancel pairing after 60 s */ @@ -68,6 +72,16 @@ static uint16_t humidity_to_zb(float rh) return (uint16_t)(rh * 100.0f); } +/** Build a Zigbee Pascal string from the ESP-IDF app version. */ +static void init_sw_build_id(void) +{ + const esp_app_desc_t *app_desc = esp_app_get_description(); + size_t version_len = strnlen(app_desc->version, SW_BUILD_ID_MAX_LEN); + + s_sw_build_id[0] = (uint8_t)version_len; + memcpy(&s_sw_build_id[1], app_desc->version, version_len); +} + static void report_custom_attr(uint16_t attr_id) { esp_zb_zcl_report_attr_cmd_t report_cmd = { 0 }; @@ -225,12 +239,15 @@ static esp_zb_cluster_list_t *create_cluster_list(void) { esp_zb_cluster_list_t *cluster_list = esp_zb_zcl_cluster_list_create(); - /* ---- Basic cluster (mandatory, carries device identity) ---- */ + /* ---- Basic cluster (mandatory, carries device identity and firmware version) ---- */ + init_sw_build_id(); esp_zb_attribute_list_t *basic_cluster = esp_zb_basic_cluster_create(NULL); ESP_ERROR_CHECK(esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID, (void *)MANUFACTURER_NAME)); ESP_ERROR_CHECK(esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, (void *)MODEL_IDENTIFIER)); + ESP_ERROR_CHECK(esp_zb_basic_cluster_add_attr(basic_cluster, + ESP_ZB_ZCL_ATTR_BASIC_SW_BUILD_ID, s_sw_build_id)); ESP_ERROR_CHECK(esp_zb_cluster_list_add_basic_cluster(cluster_list, basic_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE)); diff --git a/firmware/partitions_zigbee.csv b/firmware/partitions_zigbee.csv new file mode 100644 index 0000000..8c003ac --- /dev/null +++ b/firmware/partitions_zigbee.csv @@ -0,0 +1,8 @@ +# Name, Type, SubType, Offset, Size, Flags +nvs, data, nvs, 0x9000, 0x6000, +otadata, data, ota, 0xf000, 0x2000, +phy_init, data, phy, 0x11000, 0x1000, +factory, app, factory, 0x20000, 0x3B0000, +zb_storage, data, fat, 0x3D0000, 0x4000, +zb_fct, data, fat, 0x3D4000, 0x1000, +history, data, 0x99, 0x3D5000, 0x11000, diff --git a/firmware/version.txt b/firmware/version.txt new file mode 100644 index 0000000..f0bb29e --- /dev/null +++ b/firmware/version.txt @@ -0,0 +1 @@ +1.3.0