Working zigbee generic, connected to network and HA
This commit is contained in:
4
common/delta_ota/CMakeLists.txt
Normal file
4
common/delta_ota/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
idf_component_register(SRC_DIRS "src"
|
||||
INCLUDE_DIRS "include"
|
||||
PRIV_REQUIRES esp_delta_ota app_update
|
||||
)
|
||||
103
common/delta_ota/include/esp_delta_ota_ops.h
Normal file
103
common/delta_ota/include/esp_delta_ota_ops.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*
|
||||
* Zigbee delta OTA Example
|
||||
*
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DELTA_OTA_UPGRADE_IMAGE_HEADER_SIZE sizeof(esp_image_header_t)
|
||||
#define DELTA_OTA_UPGRADE_PATCH_HEADER_SIZE 64
|
||||
#define DELTA_OTA_UPGRADE_DIGEST_SIZE 32
|
||||
#define DELTA_OTA_UPGRADE_MAGIC 0xfccdde10
|
||||
|
||||
typedef struct esp_delta_ota_ctx_s {
|
||||
char *header_data;
|
||||
int header_data_read;
|
||||
bool verify_patch_flag;
|
||||
bool chip_id_verified;
|
||||
} esp_delta_ota_ctx_t;
|
||||
|
||||
/**
|
||||
* @brief Commence a Delta OTA update writing to the specified partition.
|
||||
|
||||
* The specified partition is erased to the specified image size.
|
||||
*
|
||||
* If image size is not yet known, pass OTA_SIZE_UNKNOWN which will
|
||||
* cause the entire partition to be erased.
|
||||
*
|
||||
* On success, this function allocates memory that remains in use
|
||||
* until esp_delta_ota_end() is called with the returned handle.
|
||||
*
|
||||
* Note: If the rollback option is enabled and the running application has the ESP_OTA_IMG_PENDING_VERIFY state then
|
||||
* it will lead to the ESP_ERR_OTA_ROLLBACK_INVALID_STATE error. Confirm the running app before to run download a new app,
|
||||
* use esp_ota_mark_app_valid_cancel_rollback() function for it (this should be done as early as possible when you first download a new application).
|
||||
*
|
||||
* @param partition Pointer to info for partition which will receive the OTA update. Required.
|
||||
* @param image_size Size of new OTA app image. Partition will be erased in order to receive this size of image. If 0 or OTA_SIZE_UNKNOWN, the entire partition is erased.
|
||||
* @param out_handle On success, returns a handle which should be used for subsequent esp_ota_write() and esp_delta_ota_end() calls.
|
||||
|
||||
* @return
|
||||
* - ESP_OK: OTA operation commenced successfully.
|
||||
* - ESP_ERR_INVALID_ARG: partition or out_handle arguments were NULL, or partition doesn't point to an OTA app partition.
|
||||
* - ESP_ERR_NO_MEM: Cannot allocate memory for OTA operation.
|
||||
* - ESP_ERR_OTA_PARTITION_CONFLICT: Partition holds the currently running firmware, cannot update in place.
|
||||
* - ESP_ERR_NOT_FOUND: Partition argument not found in partition table.
|
||||
* - ESP_ERR_OTA_SELECT_INFO_INVALID: The OTA data partition contains invalid data.
|
||||
* - ESP_ERR_INVALID_SIZE: Partition doesn't fit in configured flash size.
|
||||
* - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash write failed.
|
||||
* - ESP_ERR_OTA_ROLLBACK_INVALID_STATE: If the running app has not confirmed state. Before performing an update, the application must be valid.
|
||||
*/
|
||||
esp_err_t esp_delta_ota_begin(const esp_partition_t *partition, size_t image_size, esp_ota_handle_t *out_handle);
|
||||
|
||||
/**
|
||||
* @brief Write Delta OTA update data to partition
|
||||
*
|
||||
* This function can be called multiple times as
|
||||
* data is received during the OTA operation. Data is written
|
||||
* sequentially to the partition.
|
||||
*
|
||||
* @param handle Handle obtained from esp_ota_begin
|
||||
* @param data Data buffer to write
|
||||
* @param size Size of data buffer in bytes.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Data was written to flash successfully, or size = 0
|
||||
* - ESP_ERR_INVALID_ARG: handle is invalid.
|
||||
* - ESP_ERR_OTA_VALIDATE_FAILED: First byte of image contains invalid app image magic byte.
|
||||
* - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash write failed.
|
||||
* - ESP_ERR_OTA_SELECT_INFO_INVALID: OTA data partition has invalid contents
|
||||
*/
|
||||
esp_err_t esp_delta_ota_write(esp_ota_handle_t handle, uint8_t *data, int size);
|
||||
|
||||
/**
|
||||
* @brief Finish Delta OTA update and validate newly written app image.
|
||||
*
|
||||
* @param handle Handle obtained from esp_delta_ota_begin().
|
||||
*
|
||||
* @note After calling esp_delta_ota_end(), the handle is no longer valid and any memory associated with it is freed (regardless of result).
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Newly written OTA app image is valid.
|
||||
* - ESP_ERR_NOT_FOUND: OTA handle was not found.
|
||||
* - ESP_ERR_INVALID_ARG: Handle was never written to.
|
||||
* - ESP_ERR_OTA_VALIDATE_FAILED: OTA image is invalid (either not a valid app image, or - if secure boot is enabled - signature failed to verify.)
|
||||
* - ESP_ERR_INVALID_STATE: If flash encryption is enabled, this result indicates an internal error writing the final encrypted bytes to flash.
|
||||
*/
|
||||
esp_err_t esp_delta_ota_end(esp_ota_handle_t handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
209
common/delta_ota/src/esp_delta_ota_ops.c
Normal file
209
common/delta_ota/src/esp_delta_ota_ops.c
Normal file
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*
|
||||
* Zigbee delta OTA Example
|
||||
*
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_check.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_app_format.h"
|
||||
#include "esp_delta_ota.h"
|
||||
|
||||
#include "esp_delta_ota_ops.h"
|
||||
|
||||
static const char *TAG = "ESP_DELTA_OTA_OPS";
|
||||
|
||||
static const esp_partition_t *s_cur_partition = NULL;
|
||||
static esp_delta_ota_handle_t s_delta_ota_handle = NULL;
|
||||
static esp_delta_ota_ctx_t *s_delta_ota_ctx = NULL;
|
||||
|
||||
static esp_err_t delta_ota_patch_header_verify(void *img_hdr_data)
|
||||
{
|
||||
uint8_t sha_256[DELTA_OTA_UPGRADE_DIGEST_SIZE] = { 0 };
|
||||
uint32_t recv_magic = 0;
|
||||
uint8_t *digest = NULL;
|
||||
|
||||
if (!img_hdr_data) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
recv_magic = *(uint32_t *)img_hdr_data;
|
||||
if (recv_magic != DELTA_OTA_UPGRADE_MAGIC) {
|
||||
ESP_LOGE(TAG, "Invalid magic word in patch");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
digest = (uint8_t *)(img_hdr_data + sizeof(uint32_t));
|
||||
esp_partition_get_sha256(s_cur_partition, sha_256);
|
||||
if (memcmp(sha_256, digest, DELTA_OTA_UPGRADE_DIGEST_SIZE) != 0) {
|
||||
ESP_LOGE(TAG, "Invalid patch, the SHA256 of the current firmware differs from that in the patch header.");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static bool delta_ota_chip_id_verify(void *bin_header_data)
|
||||
{
|
||||
esp_image_header_t *header = (esp_image_header_t *)bin_header_data;
|
||||
ESP_RETURN_ON_FALSE(header->chip_id == CONFIG_IDF_FIRMWARE_CHIP_ID, false, TAG,
|
||||
"Mismatch chip id, expected %d, found %d", CONFIG_IDF_FIRMWARE_CHIP_ID, header->chip_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static esp_err_t delta_ota_write_cb(const uint8_t *buf_p, size_t size, void *user_data)
|
||||
{
|
||||
if (size <= 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_ota_handle_t ota_handle = (esp_ota_handle_t)user_data;
|
||||
int index = 0;
|
||||
|
||||
if (!s_delta_ota_ctx->chip_id_verified) {
|
||||
if (s_delta_ota_ctx->header_data_read + size <= DELTA_OTA_UPGRADE_IMAGE_HEADER_SIZE) {
|
||||
memcpy(s_delta_ota_ctx->header_data + s_delta_ota_ctx->header_data_read, buf_p, size);
|
||||
s_delta_ota_ctx->header_data_read += size;
|
||||
return ESP_OK;
|
||||
} else {
|
||||
index = DELTA_OTA_UPGRADE_IMAGE_HEADER_SIZE - s_delta_ota_ctx->header_data_read;
|
||||
memcpy(s_delta_ota_ctx->header_data + s_delta_ota_ctx->header_data_read, buf_p, index);
|
||||
|
||||
if (!delta_ota_chip_id_verify(s_delta_ota_ctx->header_data)) {
|
||||
return ESP_ERR_INVALID_VERSION;
|
||||
}
|
||||
s_delta_ota_ctx->chip_id_verified = true;
|
||||
|
||||
// Write data in header_data buffer.
|
||||
esp_err_t err = esp_ota_write(ota_handle, s_delta_ota_ctx->header_data, DELTA_OTA_UPGRADE_IMAGE_HEADER_SIZE);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return esp_ota_write(ota_handle, buf_p + index, size - index);
|
||||
}
|
||||
|
||||
static esp_err_t delta_ota_read_cb(uint8_t *buf_p, size_t size, int src_offset)
|
||||
{
|
||||
if (size <= 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return esp_partition_read(s_cur_partition, src_offset, buf_p, size);
|
||||
}
|
||||
|
||||
esp_err_t esp_delta_ota_begin(const esp_partition_t *partition, size_t image_size, esp_ota_handle_t *out_handle)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
esp_ota_handle_t ota_handle = 0;
|
||||
esp_delta_ota_cfg_t cfg = {
|
||||
.read_cb = &delta_ota_read_cb,
|
||||
.write_cb_with_user_data = &delta_ota_write_cb,
|
||||
};
|
||||
|
||||
s_cur_partition = esp_ota_get_running_partition();
|
||||
assert(s_cur_partition);
|
||||
|
||||
ESP_RETURN_ON_FALSE(s_cur_partition->subtype < ESP_PARTITION_SUBTYPE_APP_OTA_MAX &&
|
||||
partition->subtype < ESP_PARTITION_SUBTYPE_APP_OTA_MAX, ESP_ERR_INVALID_ARG, TAG,
|
||||
"Failed to get partition info of currently or next running app");
|
||||
|
||||
ret = esp_ota_begin(partition, image_size, &ota_handle);
|
||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to begin OTA partition, status: %s", esp_err_to_name(ret));
|
||||
|
||||
cfg.user_data = (void *)ota_handle;
|
||||
s_delta_ota_handle = esp_delta_ota_init(&cfg);
|
||||
assert(s_delta_ota_handle);
|
||||
|
||||
s_delta_ota_ctx = calloc(1, sizeof(esp_delta_ota_ctx_t));
|
||||
assert(s_delta_ota_ctx);
|
||||
s_delta_ota_ctx->header_data = calloc(1, DELTA_OTA_UPGRADE_IMAGE_HEADER_SIZE);
|
||||
assert(s_delta_ota_ctx->header_data);
|
||||
|
||||
*out_handle = ota_handle;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_delta_ota_write(esp_ota_handle_t handle, uint8_t *data, int size)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
static uint8_t *patch_buf = NULL;
|
||||
static uint8_t patch_len = 0;
|
||||
const uint8_t *patch_data = (const uint8_t *)data;
|
||||
int patch_size = size;
|
||||
if (!s_delta_ota_ctx->verify_patch_flag) {
|
||||
if (!patch_buf) {
|
||||
patch_buf = calloc(1, size);
|
||||
} else {
|
||||
patch_buf = realloc(patch_buf, patch_len + size);
|
||||
}
|
||||
ESP_RETURN_ON_FALSE(patch_buf, ESP_ERR_NO_MEM, TAG, "No memory for delta OTA write");
|
||||
memcpy(patch_buf + patch_len, data, size);
|
||||
patch_len += size;
|
||||
|
||||
if (patch_len <= DELTA_OTA_UPGRADE_PATCH_HEADER_SIZE) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
ret = delta_ota_patch_header_verify(patch_buf);
|
||||
ESP_GOTO_ON_ERROR(ret, exit, TAG, "Patch Header verification failed, status: %s", esp_err_to_name(ret));
|
||||
|
||||
s_delta_ota_ctx->verify_patch_flag = true;
|
||||
patch_data = (const uint8_t *)patch_buf + DELTA_OTA_UPGRADE_PATCH_HEADER_SIZE;
|
||||
patch_size = patch_len - DELTA_OTA_UPGRADE_PATCH_HEADER_SIZE;
|
||||
}
|
||||
|
||||
if (s_delta_ota_ctx->verify_patch_flag) {
|
||||
ret = esp_delta_ota_feed_patch(s_delta_ota_handle, patch_data, patch_size);
|
||||
ESP_GOTO_ON_ERROR(ret, exit, TAG, "Failed to apply the patch on the source data, status: %s", esp_err_to_name(ret));
|
||||
}
|
||||
|
||||
exit:
|
||||
if (patch_buf) {
|
||||
free(patch_buf);
|
||||
patch_buf = NULL;
|
||||
patch_len = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t esp_delta_ota_end(esp_ota_handle_t handle)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if (s_delta_ota_ctx) {
|
||||
if (s_delta_ota_ctx->header_data) {
|
||||
free(s_delta_ota_ctx->header_data);
|
||||
s_delta_ota_ctx->header_data = NULL;
|
||||
}
|
||||
free(s_delta_ota_ctx);
|
||||
s_delta_ota_ctx = NULL;
|
||||
}
|
||||
|
||||
ret = esp_delta_ota_finalize(s_delta_ota_handle);
|
||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to finish the patch applying operation, status: %s", esp_err_to_name(ret));
|
||||
ret = esp_delta_ota_deinit(s_delta_ota_handle);
|
||||
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to clean-up delta ota process, status: %s", esp_err_to_name(ret));
|
||||
ret = esp_ota_end(handle);
|
||||
|
||||
return ret;
|
||||
}
|
||||
5
common/light_driver/CMakeLists.txt
Normal file
5
common/light_driver/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
idf_component_register(SRC_DIRS "src"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES
|
||||
led_strip
|
||||
)
|
||||
125
common/light_driver/include/light_driver.h
Normal file
125
common/light_driver/include/light_driver.h
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*
|
||||
* Zigbee light driver example
|
||||
*
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* light intensity level */
|
||||
#define LIGHT_DEFAULT_ON 1
|
||||
#define LIGHT_DEFAULT_OFF 0
|
||||
|
||||
/* LED strip configuration */
|
||||
#define CONFIG_EXAMPLE_STRIP_LED_GPIO 8
|
||||
#define CONFIG_EXAMPLE_STRIP_LED_NUMBER 1
|
||||
|
||||
|
||||
/** Convert Hue,Saturation,V to RGB
|
||||
* RGB - [0..0xffff]
|
||||
* hue - [0..0xff]
|
||||
* Sat - [0..0xff]
|
||||
* V always = (ZB_UINT16_MAX-1)
|
||||
*/
|
||||
#define HSV_to_RGB(h, s, v, r, g, b ) \
|
||||
{ \
|
||||
uint8_t i; \
|
||||
uint8_t sector = UINT8_MAX/6; \
|
||||
float f, p, q, t; \
|
||||
if( s == 0 ) { /* achromatic (grey)*/ \
|
||||
r = g = b = (v); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
i = h / sector; /* sector 0 to 5 */ \
|
||||
f = h % sector; /* factorial part of h*/ \
|
||||
p = (float)(v * ( 1.0 - (float)s/UINT8_MAX )); \
|
||||
q = (float)(v * ( 1.0 - (float)s/UINT8_MAX * f/(float)sector )); \
|
||||
t = (float)(v * ( 1.0 - (float)s/UINT8_MAX * ( 1 - f/(float)sector ) )); \
|
||||
switch( i ) { \
|
||||
case 0: r = (v); g = t; b = p; break; \
|
||||
case 1: r = q; g = (v); b = p; break; \
|
||||
case 2: r = p; g = (v); b = t; break; \
|
||||
case 3: r = p; g = q; b = (v); break; \
|
||||
case 4: r = t; g = p; b = (v); break; \
|
||||
case 5: \
|
||||
default: r = (v); g = p; b = q; break; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define XYZ_to_RGB(X, Y, Z, r, g, b) \
|
||||
{ \
|
||||
r = (float)( 3.240479*(X) -1.537150*(Y) -0.498535*(Z)); \
|
||||
g = (float)(-0.969256*(X) +1.875992*(Y) +0.041556*(Z)); \
|
||||
b = (float)( 0.055648*(X) -0.204043*(Y) +1.057311*(Z)); \
|
||||
if(r>1){r=1;} \
|
||||
if(g>1){g=1;} \
|
||||
if(b>1){b=1;} \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set light power (on/off).
|
||||
*
|
||||
* @param power The light power to be set
|
||||
*/
|
||||
void light_driver_set_power(bool power);
|
||||
|
||||
/**
|
||||
* @brief color light driver init, be invoked where you want to use color light
|
||||
*
|
||||
* @param power power on/off
|
||||
*/
|
||||
void light_driver_init(bool power);
|
||||
|
||||
/**
|
||||
* @brief Set light level
|
||||
*
|
||||
* @param level The light level to be set
|
||||
*/
|
||||
void light_driver_set_level(uint8_t level);
|
||||
|
||||
/**
|
||||
* @brief Set light color from RGB
|
||||
*
|
||||
* @param red The red color to be set
|
||||
* @param green The green color to be set
|
||||
* @param blue The blue color to be set
|
||||
*/
|
||||
void light_driver_set_color_RGB(uint8_t red, uint8_t green, uint8_t blue);
|
||||
|
||||
/**
|
||||
* @brief Set light color from color xy
|
||||
*
|
||||
* @param color_currentx The color x to be set
|
||||
* @param color_currenty The color y to be set
|
||||
*/
|
||||
void light_driver_set_color_xy(uint16_t color_current_x, uint16_t color_current_y);
|
||||
|
||||
/**
|
||||
* @brief Set light color from hue saturation
|
||||
*
|
||||
* @param hue The hue to be set
|
||||
* @param sat The sat to be set
|
||||
*/
|
||||
void light_driver_set_color_hue_sat(uint8_t hue, uint8_t sat);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
89
common/light_driver/src/light_driver.c
Normal file
89
common/light_driver/src/light_driver.c
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*
|
||||
* Zigbee light driver example
|
||||
*
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "led_strip.h"
|
||||
#include "light_driver.h"
|
||||
|
||||
static led_strip_handle_t s_led_strip;
|
||||
static uint8_t s_red = 255, s_green = 255, s_blue = 255, s_level = 255;
|
||||
|
||||
void light_driver_set_color_xy(uint16_t color_current_x, uint16_t color_current_y)
|
||||
{
|
||||
float red_f = 0, green_f = 0, blue_f = 0, color_x, color_y;
|
||||
color_x = (float)color_current_x / 65535;
|
||||
color_y = (float)color_current_y / 65535;
|
||||
/* assume color_Y is full light level value 1 (0-1.0) */
|
||||
float color_X = color_x / color_y;
|
||||
float color_Z = (1 - color_x - color_y) / color_y;
|
||||
/* change from xy to linear RGB NOT sRGB */
|
||||
XYZ_to_RGB(color_X, 1, color_Z, red_f, green_f, blue_f);
|
||||
float ratio = (float)s_level / 255;
|
||||
s_red = (uint8_t)(red_f * (float)255);
|
||||
s_green = (uint8_t)(green_f * (float)255);
|
||||
s_blue = (uint8_t)(blue_f * (float)255);
|
||||
ESP_ERROR_CHECK(led_strip_set_pixel(s_led_strip, 0, s_red * ratio, s_green * ratio, s_blue * ratio));
|
||||
ESP_ERROR_CHECK(led_strip_refresh(s_led_strip));
|
||||
}
|
||||
|
||||
void light_driver_set_color_hue_sat(uint8_t hue, uint8_t sat)
|
||||
{
|
||||
float red_f, green_f, blue_f;
|
||||
HSV_to_RGB(hue, sat, UINT8_MAX, red_f, green_f, blue_f);
|
||||
float ratio = (float)s_level / 255;
|
||||
s_red = (uint8_t)red_f;
|
||||
s_green = (uint8_t)green_f;
|
||||
s_blue = (uint8_t)blue_f;
|
||||
ESP_ERROR_CHECK(led_strip_set_pixel(s_led_strip, 0, s_red * ratio, s_green * ratio, s_blue * ratio));
|
||||
ESP_ERROR_CHECK(led_strip_refresh(s_led_strip));
|
||||
}
|
||||
|
||||
void light_driver_set_color_RGB(uint8_t red, uint8_t green, uint8_t blue)
|
||||
{
|
||||
float ratio = (float)s_level / 255;
|
||||
s_red = red;
|
||||
s_green = green;
|
||||
s_blue = blue;
|
||||
ESP_ERROR_CHECK(led_strip_set_pixel(s_led_strip, 0, red * ratio, green * ratio, blue * ratio));
|
||||
ESP_ERROR_CHECK(led_strip_refresh(s_led_strip));
|
||||
}
|
||||
|
||||
void light_driver_set_power(bool power)
|
||||
{
|
||||
ESP_ERROR_CHECK(led_strip_set_pixel(s_led_strip, 0, s_red * power, s_green * power, s_blue * power));
|
||||
ESP_ERROR_CHECK(led_strip_refresh(s_led_strip));
|
||||
}
|
||||
|
||||
void light_driver_set_level(uint8_t level)
|
||||
{
|
||||
s_level = level;
|
||||
float ratio = (float)s_level / 255;
|
||||
ESP_ERROR_CHECK(led_strip_set_pixel(s_led_strip, 0, s_red * ratio, s_green * ratio, s_blue * ratio));
|
||||
ESP_ERROR_CHECK(led_strip_refresh(s_led_strip));
|
||||
}
|
||||
|
||||
void light_driver_init(bool power)
|
||||
{
|
||||
led_strip_config_t led_strip_conf = {
|
||||
.max_leds = CONFIG_EXAMPLE_STRIP_LED_NUMBER,
|
||||
.strip_gpio_num = CONFIG_EXAMPLE_STRIP_LED_GPIO,
|
||||
};
|
||||
led_strip_rmt_config_t rmt_conf = {
|
||||
.resolution_hz = 10 * 1000 * 1000, // 10MHz
|
||||
};
|
||||
ESP_ERROR_CHECK(led_strip_new_rmt_device(&led_strip_conf, &rmt_conf, &s_led_strip));
|
||||
|
||||
light_driver_set_power(power);
|
||||
}
|
||||
5
common/switch_driver/CMakeLists.txt
Normal file
5
common/switch_driver/CMakeLists.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
idf_component_register(SRC_DIRS "src"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES
|
||||
driver
|
||||
)
|
||||
72
common/switch_driver/include/switch_driver.h
Normal file
72
common/switch_driver/include/switch_driver.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*
|
||||
* Zigbee switch driver example
|
||||
*
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "driver/gpio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* user should configure which I/O port as toggle switch input, default is GPIO9 */
|
||||
#define GPIO_INPUT_IO_TOGGLE_SWITCH GPIO_NUM_9
|
||||
|
||||
/* config button level depends on the pull up/down setting
|
||||
push button level is on level = 1 when pull-down enable
|
||||
push button level is on level = 0 when pull-up enable
|
||||
*/
|
||||
#define GPIO_INPUT_LEVEL_ON 0
|
||||
|
||||
#define ESP_INTR_FLAG_DEFAULT 0
|
||||
|
||||
#define PAIR_SIZE(TYPE_STR_PAIR) (sizeof(TYPE_STR_PAIR) / sizeof(TYPE_STR_PAIR[0]))
|
||||
|
||||
typedef enum {
|
||||
SWITCH_IDLE,
|
||||
SWITCH_PRESS_ARMED,
|
||||
SWITCH_PRESS_DETECTED,
|
||||
SWITCH_PRESSED,
|
||||
SWITCH_RELEASE_DETECTED,
|
||||
} switch_state_t;
|
||||
|
||||
typedef enum {
|
||||
SWITCH_ON_CONTROL,
|
||||
SWITCH_OFF_CONTROL,
|
||||
SWITCH_ONOFF_TOGGLE_CONTROL,
|
||||
SWITCH_LEVEL_UP_CONTROL,
|
||||
SWITCH_LEVEL_DOWN_CONTROL,
|
||||
SWITCH_LEVEL_CYCLE_CONTROL,
|
||||
SWITCH_COLOR_CONTROL,
|
||||
} switch_func_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t pin;
|
||||
switch_func_t func;
|
||||
} switch_func_pair_t;
|
||||
|
||||
typedef void (*esp_switch_callback_t)(switch_func_pair_t *param);
|
||||
|
||||
/**
|
||||
* @brief init function for switch and callback setup
|
||||
*
|
||||
* @param button_func_pair pointer of the button pair.
|
||||
* @param button_num number of button pair.
|
||||
* @param cb callback pointer.
|
||||
*/
|
||||
bool switch_driver_init(switch_func_pair_t *button_func_pair, uint8_t button_num, esp_switch_callback_t cb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
159
common/switch_driver/src/switch_driver.c
Normal file
159
common/switch_driver/src/switch_driver.c
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*
|
||||
* Zigbee switch driver example
|
||||
*
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "switch_driver.h"
|
||||
|
||||
/**
|
||||
* @brief:
|
||||
* This example code shows how to configure light switch with attribute as well as button switch handler.
|
||||
*
|
||||
* @note:
|
||||
Currently only support toggle switch functionality is available
|
||||
*
|
||||
* @note:
|
||||
* For other possible switch functions (on/off,level up/down,step up/down). User need to implement and create them by themselves
|
||||
*/
|
||||
|
||||
static QueueHandle_t gpio_evt_queue = NULL;
|
||||
/* button function pair, should be defined in switch example source file */
|
||||
static switch_func_pair_t *switch_func_pair;
|
||||
/* call back function pointer */
|
||||
static esp_switch_callback_t func_ptr;
|
||||
/* which button is pressed */
|
||||
static uint8_t switch_num;
|
||||
static const char *TAG = "ESP_ZB_SWITCH";
|
||||
|
||||
static void switch_driver_gpios_intr_enabled(bool enabled);
|
||||
|
||||
static void IRAM_ATTR gpio_isr_handler(void *arg)
|
||||
{
|
||||
switch_driver_gpios_intr_enabled(false);
|
||||
xQueueSendFromISR(gpio_evt_queue, (switch_func_pair_t *)arg, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO (switches refer to) isr
|
||||
*
|
||||
* @param enabled enable isr if true.
|
||||
*/
|
||||
static void switch_driver_gpios_intr_enabled(bool enabled)
|
||||
{
|
||||
for (int i = 0; i < switch_num; ++i) {
|
||||
if (enabled) {
|
||||
gpio_intr_enable((switch_func_pair + i)->pin);
|
||||
} else {
|
||||
gpio_intr_disable((switch_func_pair + i)->pin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tasks for checking the button event and debounce the switch state
|
||||
*
|
||||
* @param arg Unused value.
|
||||
*/
|
||||
static void switch_driver_button_detected(void *arg)
|
||||
{
|
||||
gpio_num_t io_num = GPIO_NUM_NC;
|
||||
switch_func_pair_t button_func_pair;
|
||||
static switch_state_t switch_state = SWITCH_IDLE;
|
||||
bool evt_flag = false;
|
||||
|
||||
for (;;) {
|
||||
/* check if there is any queue received, if yes read out the button_func_pair */
|
||||
if (xQueueReceive(gpio_evt_queue, &button_func_pair, portMAX_DELAY)) {
|
||||
io_num = button_func_pair.pin;
|
||||
switch_driver_gpios_intr_enabled(false);
|
||||
evt_flag = true;
|
||||
}
|
||||
while (evt_flag) {
|
||||
bool value = gpio_get_level(io_num);
|
||||
switch (switch_state) {
|
||||
case SWITCH_IDLE:
|
||||
switch_state = (value == GPIO_INPUT_LEVEL_ON) ? SWITCH_PRESS_DETECTED : SWITCH_IDLE;
|
||||
break;
|
||||
case SWITCH_PRESS_DETECTED:
|
||||
switch_state = (value == GPIO_INPUT_LEVEL_ON) ? SWITCH_PRESS_DETECTED : SWITCH_RELEASE_DETECTED;
|
||||
break;
|
||||
case SWITCH_RELEASE_DETECTED:
|
||||
switch_state = SWITCH_IDLE;
|
||||
/* callback to button_handler */
|
||||
(*func_ptr)(&button_func_pair);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (switch_state == SWITCH_IDLE) {
|
||||
switch_driver_gpios_intr_enabled(true);
|
||||
evt_flag = false;
|
||||
break;
|
||||
}
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief init GPIO configuration as well as isr
|
||||
*
|
||||
* @param button_func_pair pointer of the button pair.
|
||||
* @param button_num number of button pair.
|
||||
*/
|
||||
static bool switch_driver_gpio_init(switch_func_pair_t *button_func_pair, uint8_t button_num)
|
||||
{
|
||||
gpio_config_t io_conf = {};
|
||||
switch_func_pair = button_func_pair;
|
||||
switch_num = button_num;
|
||||
uint64_t pin_bit_mask = 0;
|
||||
|
||||
/* set up button func pair pin mask */
|
||||
for (int i = 0; i < button_num; ++i) {
|
||||
pin_bit_mask |= (1ULL << (button_func_pair + i)->pin);
|
||||
}
|
||||
/* interrupt of falling edge */
|
||||
io_conf.intr_type = GPIO_INTR_LOW_LEVEL;
|
||||
io_conf.pin_bit_mask = pin_bit_mask;
|
||||
io_conf.mode = GPIO_MODE_INPUT;
|
||||
io_conf.pull_down_en = 0;
|
||||
io_conf.pull_up_en = 1;
|
||||
/* configure GPIO with the given settings */
|
||||
gpio_config(&io_conf);
|
||||
/* create a queue to handle gpio event from isr */
|
||||
gpio_evt_queue = xQueueCreate(10, sizeof(switch_func_pair_t));
|
||||
if ( gpio_evt_queue == 0) {
|
||||
ESP_LOGE(TAG, "Queue was not created and must not be used");
|
||||
return false;
|
||||
}
|
||||
/* start gpio task */
|
||||
xTaskCreate(switch_driver_button_detected, "button_detected", 4096, NULL, 10, NULL);
|
||||
/* install gpio isr service */
|
||||
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
|
||||
for (int i = 0; i < button_num; ++i) {
|
||||
gpio_isr_handler_add((button_func_pair + i)->pin, gpio_isr_handler, (void *) (button_func_pair + i));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool switch_driver_init(switch_func_pair_t *button_func_pair, uint8_t button_num, esp_switch_callback_t cb)
|
||||
{
|
||||
if (!switch_driver_gpio_init(button_func_pair, button_num)) {
|
||||
return false;
|
||||
}
|
||||
func_ptr = cb;
|
||||
return true;
|
||||
}
|
||||
4
common/temp_sensor_driver/CMakeLists.txt
Normal file
4
common/temp_sensor_driver/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
idf_component_register(SRC_DIRS "src"
|
||||
INCLUDE_DIRS "include"
|
||||
REQUIRES driver
|
||||
)
|
||||
43
common/temp_sensor_driver/include/temp_sensor_driver.h
Normal file
43
common/temp_sensor_driver/include/temp_sensor_driver.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*
|
||||
* Zigbee temperature sensor driver example
|
||||
*
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "driver/temperature_sensor.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Temperature sensor callback
|
||||
*
|
||||
* @param[in] temperature temperature value in degrees Celsius from sensor
|
||||
*
|
||||
*/
|
||||
typedef void (*esp_temp_sensor_callback_t)(float temperature);
|
||||
|
||||
/**
|
||||
* @brief init function for temp sensor and callback setup
|
||||
*
|
||||
* @param config pointer of temperature sensor config.
|
||||
* @param update_interval sensor value update interval in seconds.
|
||||
* @param cb callback pointer.
|
||||
*
|
||||
* @return ESP_OK if the driver initialization succeed, otherwise ESP_FAIL.
|
||||
*/
|
||||
esp_err_t temp_sensor_driver_init(temperature_sensor_config_t *config, uint16_t update_interval, esp_temp_sensor_callback_t cb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
80
common/temp_sensor_driver/src/temp_sensor_driver.c
Normal file
80
common/temp_sensor_driver/src/temp_sensor_driver.c
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*
|
||||
* Zigbee temperature sensor driver example
|
||||
*
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include "temp_sensor_driver.h"
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_check.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
/**
|
||||
* @brief:
|
||||
* This example code shows how to configure temperature sensor.
|
||||
*
|
||||
* @note:
|
||||
* The callback will be called with updated temperature sensor value every $interval seconds.
|
||||
*
|
||||
*/
|
||||
|
||||
/* temperatuer sensor instance handle */
|
||||
static temperature_sensor_handle_t temp_sensor;
|
||||
/* call back function pointer */
|
||||
static esp_temp_sensor_callback_t func_ptr;
|
||||
/* update interval in seconds */
|
||||
static uint16_t interval = 1;
|
||||
|
||||
static const char *TAG = "ESP_TEMP_SENSOR_DRIVER";
|
||||
|
||||
/**
|
||||
* @brief Tasks for updating the sensor value
|
||||
*
|
||||
* @param arg Unused value.
|
||||
*/
|
||||
static void temp_sensor_driver_value_update(void *arg)
|
||||
{
|
||||
for (;;) {
|
||||
float tsens_value;
|
||||
temperature_sensor_get_celsius(temp_sensor, &tsens_value);
|
||||
if (func_ptr) {
|
||||
func_ptr(tsens_value);
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(interval * 1000));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief init temperature sensor
|
||||
*
|
||||
* @param config pointer of temperature sensor config.
|
||||
*/
|
||||
static esp_err_t temp_sensor_driver_sensor_init(temperature_sensor_config_t *config)
|
||||
{
|
||||
ESP_RETURN_ON_ERROR(temperature_sensor_install(config, &temp_sensor),
|
||||
TAG, "Fail to install on-chip temperature sensor");
|
||||
ESP_RETURN_ON_ERROR(temperature_sensor_enable(temp_sensor),
|
||||
TAG, "Fail to enable on-chip temperature sensor");
|
||||
return (xTaskCreate(temp_sensor_driver_value_update, "sensor_update", 2048, NULL, 10, NULL) == pdTRUE) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t temp_sensor_driver_init(temperature_sensor_config_t *config, uint16_t update_interval,
|
||||
esp_temp_sensor_callback_t cb)
|
||||
{
|
||||
if (ESP_OK != temp_sensor_driver_sensor_init(config)) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
func_ptr = cb;
|
||||
interval = update_interval;
|
||||
return ESP_OK;
|
||||
}
|
||||
51
common/zcl_utility/include/zcl_utility.h
Normal file
51
common/zcl_utility/include/zcl_utility.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*
|
||||
* Zigbee light driver example
|
||||
*
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_zigbee_core.h"
|
||||
|
||||
/*! Maximum length of ManufacturerName string field */
|
||||
#define ESP_ZB_ZCL_CLUSTER_ID_BASIC_MANUFACTURER_NAME_MAX_LEN 32
|
||||
|
||||
/*! Maximum length of ModelIdentifier string field */
|
||||
#define ESP_ZB_ZCL_CLUSTER_ID_BASIC_MODEL_IDENTIFIER_MAX_LEN 32
|
||||
|
||||
/** optional basic manufacturer information */
|
||||
typedef struct zcl_basic_manufacturer_info_s {
|
||||
char *manufacturer_name;
|
||||
char *model_identifier;
|
||||
} zcl_basic_manufacturer_info_t;
|
||||
|
||||
/**
|
||||
* @brief Adds manufacturer information to the ZCL basic cluster of endpoint
|
||||
*
|
||||
* @param[in] ep_list The pointer to the endpoint list with @p endpoint_id
|
||||
* @param[in] endpoint_id The endpoint identifier indicating where the ZCL basic cluster resides
|
||||
* @param[in] info The pointer to the basic manufacturer information
|
||||
* @return
|
||||
* - ESP_OK: On success
|
||||
* - ESP_ERR_INVALID_ARG: Invalid argument
|
||||
*/
|
||||
esp_err_t esp_zcl_utility_add_ep_basic_manufacturer_info(esp_zb_ep_list_t *ep_list, uint8_t endpoint_id, zcl_basic_manufacturer_info_t *info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
37
common/zcl_utility/src/zcl_utility.c
Normal file
37
common/zcl_utility/src/zcl_utility.c
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*
|
||||
* Zigbee light driver example
|
||||
*
|
||||
* This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, this
|
||||
* software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include "esp_check.h"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "zcl_utility.h"
|
||||
#include <stdint.h>
|
||||
|
||||
static const char *TAG = "ZCL_UTILITY";
|
||||
|
||||
esp_err_t esp_zcl_utility_add_ep_basic_manufacturer_info(esp_zb_ep_list_t *ep_list, uint8_t endpoint_id, zcl_basic_manufacturer_info_t *info)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
esp_zb_cluster_list_t *cluster_list = NULL;
|
||||
esp_zb_attribute_list_t *basic_cluster = NULL;
|
||||
|
||||
cluster_list = esp_zb_ep_list_get_ep(ep_list, endpoint_id);
|
||||
ESP_RETURN_ON_FALSE(cluster_list, ESP_ERR_INVALID_ARG, TAG, "Failed to find endpoint id: %d in list: %p", endpoint_id, ep_list);
|
||||
basic_cluster = esp_zb_cluster_list_get_cluster(cluster_list, ESP_ZB_ZCL_CLUSTER_ID_BASIC, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
|
||||
ESP_RETURN_ON_FALSE(basic_cluster, ESP_ERR_INVALID_ARG, TAG, "Failed to find basic cluster in endpoint: %d", endpoint_id);
|
||||
ESP_RETURN_ON_FALSE((info && info->manufacturer_name), ESP_ERR_INVALID_ARG, TAG, "Invalid manufacturer name");
|
||||
ESP_ERROR_CHECK(esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID, info->manufacturer_name));
|
||||
ESP_RETURN_ON_FALSE((info && info->model_identifier), ESP_ERR_INVALID_ARG, TAG, "Invalid model identifier");
|
||||
ESP_ERROR_CHECK(esp_zb_basic_cluster_add_attr(basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, info->model_identifier));
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user