You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hello, I am trying to develop a Zigbee thermostat which can work with smart life app. I have tested that I can connect correctly to the Gateway (a generic one from AliexPress) and the device is recognized as a Thermostat. However, as soon as I add the thermostat cluster the app stops recognizing the device. Unfortunately the internal implementation of the function esp_zb_cluster_list_add_thermostat_cluster is no public so I can not see which setting is failing. I have two threads runnning with a priority of 1 doing the pertinent delays, i have tested that it still fails without creating those threads.
Is there any other setting I have to do? Thanks in advance.
This is the code I am using:
`#include "Zigbee/Zigbee.h"
#include "esp_zigbee_core.h"
#include "esp_zigbee_trace.h"
#include "esp_zigbee_cluster.h"
#include "nvs_flash.h"
#include "string.h"
#include "esp_check.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#define TAG "ZIGBEE"
// Device and cluster definitions
#define DEFAULT_KEPP_ALIVE_INTERVAL 3000
// No need to declare first, we just overload it
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;
github-actionsbot
changed the title
Thermostat cluster issue, not able to connect with SmartLife app.
Thermostat cluster issue, not able to connect with SmartLife app. (TZ-1513)
Jan 24, 2025
Question
Conditions:
ESP-IDF Version: 5.3.1
esp-zigbee-lib: 1.6.2
esp-zboss-lib: 1.6.2
Board: custom (ESP32C6)
Hello, I am trying to develop a Zigbee thermostat which can work with smart life app. I have tested that I can connect correctly to the Gateway (a generic one from AliexPress) and the device is recognized as a Thermostat. However, as soon as I add the thermostat cluster the app stops recognizing the device. Unfortunately the internal implementation of the function
esp_zb_cluster_list_add_thermostat_cluster
is no public so I can not see which setting is failing. I have two threads runnning with a priority of 1 doing the pertinent delays, i have tested that it still fails without creating those threads.Is there any other setting I have to do? Thanks in advance.
This is the code I am using:
`#include "Zigbee/Zigbee.h"
#include "esp_zigbee_core.h"
#include "esp_zigbee_trace.h"
#include "esp_zigbee_cluster.h"
#include "nvs_flash.h"
#include "string.h"
#include "esp_check.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#define TAG "ZIGBEE"
// Device and cluster definitions
#define DEFAULT_KEPP_ALIVE_INTERVAL 3000
// Data types
#define MANUFACTURER_NAME "\x09""ESPRESSIF"
#define MODEL_IDENTIFIER "\x07"CONFIG_IDF_TARGET
#define ENDPOINT_ID (0x01)
// Private variables
static esp_zb_attribute_list_t *basicCluster;
static esp_zb_attribute_list_t *identifyServerCluster;
static esp_zb_attribute_list_t *identifyClientCluster;
static esp_zb_attribute_list_t *groupsCluster;
static esp_zb_attribute_list_t *thermostatCluster;
// Private function declaration
static void espZbTask(void *pvParameters);
static void InitializeZigbeeStack(void);
static void CreateThermostatEndpoint(void);
static void bdb_start_top_level_commissioning_cb(uint8_t mode_mask);
static esp_err_t ZigbeeActionHandler(esp_zb_core_action_callback_id_t callback_id, const void *message);
static void CreateBasicCluster(void);
static void CreateIdentityCluster(void);
static void CreateGroupsCluster(void);
static void CreateThermostatCluster(void);
static void CreateEndPoint(void);
// Public functions
void ZigbeeInit() {
ESP_LOGI(TAG, "Initializing Zigbee stack");
esp_zb_set_trace_level_mask(ESP_ZB_TRACE_LEVEL_INFO, ESP_ZB_TRACE_SUBSYSTEM_MAC | ESP_ZB_TRACE_SUBSYSTEM_APP);
esp_zb_platform_config_t config = {
.radio_config = {
.radio_mode = ZB_RADIO_MODE_NATIVE,
},
.host_config = {
.host_connection_mode = ZB_HOST_CONNECTION_MODE_NONE,
},
};
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_zb_platform_config(&config));
xTaskCreate(espZbTask, "Zigbee_main", 4096, NULL, 5, NULL);
}
bool ZigbeeIsConnected(){
return esp_zb_bdb_dev_joined();
}
// Private function definitions
void espZbTask(void *pvParameters) {
InitializeZigbeeStack();
CreateBasicCluster();
CreateIdentityCluster();
CreateGroupsCluster();
CreateThermostatCluster();
CreateEndPoint();
esp_zb_core_action_handler_register(ZigbeeActionHandler);
esp_zb_set_primary_network_channel_set(ESP_ZB_TRANSCEIVER_ALL_CHANNELS_MASK);
esp_zb_set_secondary_network_channel_set(ESP_ZB_TRANSCEIVER_ALL_CHANNELS_MASK);
ESP_ERROR_CHECK(esp_zb_start(false));
esp_zb_stack_main_loop();
}
// No need to declare first, we just overload it
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;
printf("Sig type: %s %d\r\n", esp_zb_zdo_signal_to_string(sig_type), esp_zb_bdb_dev_joined());
if (esp_zb_bdb_dev_joined()) {
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());
}
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, "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 {
ESP_LOGW(TAG, "%s failed with status: %s, retrying", esp_zb_zdo_signal_to_string(sig_type),
esp_err_to_name(err_status));
esp_zb_scheduler_alarm((esp_zb_callback_t)bdb_start_top_level_commissioning_cb,
ESP_ZB_BDB_MODE_INITIALIZATION, 1000);
}
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:
break;
}
}
void InitializeZigbeeStack(){
esp_zb_cfg_t config = {
.esp_zb_role = ESP_ZB_DEVICE_TYPE_ED, // End device
.install_code_policy = false,
.nwk_cfg.zed_cfg = {
.ed_timeout = ESP_ZB_ED_AGING_TIMEOUT_64MIN,
.keep_alive = DEFAULT_KEPP_ALIVE_INTERVAL,
}
};
esp_zb_init(&config);
}
void CreateBasicCluster() {
uint8_t zclVersion = ESP_ZB_ZCL_BASIC_ZCL_VERSION_DEFAULT_VALUE;
uint8_t appVersion = ESP_ZB_ZCL_BASIC_APPLICATION_VERSION_DEFAULT_VALUE;
uint8_t stackVersionId = ESP_ZB_ZCL_BASIC_STACK_VERSION_DEFAULT_VALUE;
uint8_t hwVersion = ESP_ZB_ZCL_BASIC_HW_VERSION_DEFAULT_VALUE;
char dataCode[] = "20250124";
char manufacturerVersionId[] = "v1.0";
char swBuildId[] = "2025-01-24_01";
uint8_t powerSource = ESP_ZB_ZCL_BASIC_POWER_SOURCE_DEFAULT_VALUE;
basicCluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_BASIC);
esp_zb_basic_cluster_add_attr(basicCluster, ESP_ZB_ZCL_ATTR_BASIC_ZCL_VERSION_ID, &zclVersion);
esp_zb_basic_cluster_add_attr(basicCluster, ESP_ZB_ZCL_ATTR_BASIC_APPLICATION_VERSION_ID, &appVersion);
esp_zb_basic_cluster_add_attr(basicCluster, ESP_ZB_ZCL_ATTR_BASIC_STACK_VERSION_ID, &stackVersionId);
esp_zb_basic_cluster_add_attr(basicCluster, ESP_ZB_ZCL_ATTR_BASIC_HW_VERSION_ID, &hwVersion);
esp_zb_basic_cluster_add_attr(basicCluster, ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID, MANUFACTURER_NAME);
esp_zb_basic_cluster_add_attr(basicCluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, MODEL_IDENTIFIER);
esp_zb_basic_cluster_add_attr(basicCluster, ESP_ZB_ZCL_ATTR_BASIC_DATE_CODE_ID, dataCode);
esp_zb_basic_cluster_add_attr(basicCluster, ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_VERSION_DETAILS_ID, manufacturerVersionId);
esp_zb_basic_cluster_add_attr(basicCluster, ESP_ZB_ZCL_ATTR_BASIC_SW_BUILD_ID, swBuildId);
esp_zb_basic_cluster_add_attr(basicCluster, ESP_ZB_ZCL_ATTR_BASIC_POWER_SOURCE_ID, &powerSource);
}
void CreateIdentityCluster() {
uint16_t identifyTime = ESP_ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE;
identifyServerCluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY);
identifyClientCluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY);
esp_zb_identify_cluster_add_attr(identifyServerCluster, ESP_ZB_ZCL_ATTR_IDENTIFY_IDENTIFY_TIME_ID, &identifyTime);
}
void CreateGroupsCluster(){
groupsCluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_GROUPS);
}
void CreateThermostatCluster(){
// thermostatCluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_THERMOSTAT);
// Define attributes for the Thermostat Cluster
int16_t local_temperature = 2000; // Example: 20.00°C
uint8_t occupancy = 0x01; // Example: Occupied
int16_t abs_min_heat_setpoint_limit = 700; // Example: 7.00°C
int16_t abs_max_heat_setpoint_limit = 3000; // Example: 30.00°C
int8_t local_temperature_calibration = 0; // Example: No calibration
int16_t occupied_heating_setpoint = 2000; // Example: 20.00°C
int16_t min_heat_setpoint_limit = 1000; // Example: 10.00°C
int16_t max_heat_setpoint_limit = 2500; // Example: 25.00°C
uint8_t system_mode = 0x03; // Example: Auto mode
uint16_t thermostat_running_state = 0x0001; // Example: Heat state
uint8_t setpoint_change_source = 0x01; // Example: Manual
uint32_t setpoint_change_source_timestamp = 0; // Example timestamp
uint8_t thermostat_programming_operation_mode = 0x00; // Default mode
uint8_t number_of_weekly_transitions = 4; // Example: 4 weekly transitions
uint8_t number_of_daily_transitions = 2; // Example: 2 daily transitions
uint8_t start_of_week = 0x00; // Example: Sunday
esp_zb_thermostat_cluster_cfg_t thermostatClusterConfig = {
.local_temperature = ESP_ZB_ZCL_THERMOSTAT_LOCAL_TEMPERATURE_DEFAULT_VALUE,
.occupied_cooling_setpoint = ESP_ZB_ZCL_THERMOSTAT_OCCUPIED_COOLING_SETPOINT_DEFAULT_VALUE,
.occupied_heating_setpoint = ESP_ZB_ZCL_THERMOSTAT_OCCUPIED_HEATING_SETPOINT_DEFAULT_VALUE,
.control_sequence_of_operation = ESP_ZB_ZCL_THERMOSTAT_CONTROL_SEQ_OF_OPERATION_DEFAULT_VALUE,
.system_mode = ESP_ZB_ZCL_THERMOSTAT_CONTROL_SYSTEM_MODE_DEFAULT_VALUE,
};
thermostatCluster = esp_zb_thermostat_cluster_create(&thermostatClusterConfig);
// Add attributes to the Thermostat Cluster
ESP_ERROR_CHECK(esp_zb_thermostat_cluster_add_attr(thermostatCluster, ESP_ZB_ZCL_ATTR_THERMOSTAT_OCCUPANCY_ID, &occupancy));
ESP_ERROR_CHECK(esp_zb_thermostat_cluster_add_attr(thermostatCluster, ESP_ZB_ZCL_ATTR_THERMOSTAT_ABS_MIN_HEAT_SETPOINT_LIMIT_ID, &abs_min_heat_setpoint_limit));
ESP_ERROR_CHECK(esp_zb_thermostat_cluster_add_attr(thermostatCluster, ESP_ZB_ZCL_ATTR_THERMOSTAT_ABS_MAX_HEAT_SETPOINT_LIMIT_ID, &abs_max_heat_setpoint_limit));
ESP_ERROR_CHECK(esp_zb_thermostat_cluster_add_attr(thermostatCluster, ESP_ZB_ZCL_ATTR_THERMOSTAT_LOCAL_TEMPERATURE_CALIBRATION_ID, &local_temperature_calibration));
ESP_ERROR_CHECK(esp_zb_thermostat_cluster_add_attr(thermostatCluster, ESP_ZB_ZCL_ATTR_THERMOSTAT_MIN_HEAT_SETPOINT_LIMIT_ID, &min_heat_setpoint_limit));
ESP_ERROR_CHECK(esp_zb_thermostat_cluster_add_attr(thermostatCluster, ESP_ZB_ZCL_ATTR_THERMOSTAT_MAX_HEAT_SETPOINT_LIMIT_ID, &max_heat_setpoint_limit));
ESP_ERROR_CHECK(esp_zb_thermostat_cluster_add_attr(thermostatCluster, ESP_ZB_ZCL_ATTR_THERMOSTAT_THERMOSTAT_RUNNING_STATE_ID, &thermostat_running_state));
ESP_ERROR_CHECK(esp_zb_thermostat_cluster_add_attr(thermostatCluster, ESP_ZB_ZCL_ATTR_THERMOSTAT_SETPOINT_CHANGE_SOURCE_ID, &setpoint_change_source));
ESP_ERROR_CHECK(esp_zb_thermostat_cluster_add_attr(thermostatCluster, ESP_ZB_ZCL_ATTR_THERMOSTAT_SETPOINT_CHANGE_SOURCE_TIMESTAMP_ID, &setpoint_change_source_timestamp));
ESP_ERROR_CHECK(esp_zb_thermostat_cluster_add_attr(thermostatCluster, ESP_ZB_ZCL_ATTR_THERMOSTAT_THERMOSTAT_PROGRAMMING_OPERATION_MODE_ID, &thermostat_programming_operation_mode));
ESP_ERROR_CHECK(esp_zb_thermostat_cluster_add_attr(thermostatCluster, ESP_ZB_ZCL_ATTR_THERMOSTAT_NUMBER_OF_WEEKLY_TRANSITIONS_ID, &number_of_weekly_transitions));
ESP_ERROR_CHECK(esp_zb_thermostat_cluster_add_attr(thermostatCluster, ESP_ZB_ZCL_ATTR_THERMOSTAT_NUMBER_OF_DAILY_TRANSITIONS_ID, &number_of_daily_transitions));
ESP_ERROR_CHECK(esp_zb_thermostat_cluster_add_attr(thermostatCluster, ESP_ZB_ZCL_ATTR_THERMOSTAT_START_OF_WEEK_ID, &start_of_week));
}
void CreateEndPoint(){
esp_zb_endpoint_config_t endPointConfig = {
.endpoint = ENDPOINT_ID,
.app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
.app_device_id = ESP_ZB_HA_THERMOSTAT_DEVICE_ID,
.app_device_version = 0
};
esp_zb_ep_list_t *endPointList = esp_zb_ep_list_create();
esp_zb_cluster_list_t *clusterList = esp_zb_zcl_cluster_list_create();
ESP_ERROR_CHECK(esp_zb_cluster_list_add_basic_cluster(clusterList, basicCluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE));
ESP_ERROR_CHECK(esp_zb_cluster_list_add_identify_cluster(clusterList, identifyServerCluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE));
ESP_ERROR_CHECK(esp_zb_cluster_list_add_identify_cluster(clusterList, identifyClientCluster, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE));
ESP_ERROR_CHECK(esp_zb_cluster_list_add_groups_cluster(clusterList, groupsCluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE));
ESP_ERROR_CHECK(esp_zb_cluster_list_add_thermostat_cluster(clusterList, thermostatCluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE));
ESP_ERROR_CHECK(esp_zb_ep_list_add_ep(endPointList, clusterList, endPointConfig));
ESP_ERROR_CHECK(esp_zb_device_register(endPointList));
}
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");
}
esp_err_t ZigbeeActionHandler(esp_zb_core_action_callback_id_t callback_id, const void *message) {
esp_err_t ret = ESP_OK;
switch (callback_id) {
case ESP_ZB_CORE_REPORT_ATTR_CB_ID:
ESP_LOGI(TAG, "ESP_ZB_CORE_REPORT_ATTR_CB_ID");
break;
case ESP_ZB_CORE_CMD_READ_ATTR_RESP_CB_ID:
ESP_LOGI(TAG, "ESP_ZB_CORE_CMD_READ_ATTR_RESP_CB_ID");
break;
case ESP_ZB_CORE_CMD_REPORT_CONFIG_RESP_CB_ID:
ESP_LOGI(TAG, "ESP_ZB_CORE_CMD_REPORT_CONFIG_RESP_CB_ID");
break;
default:
ESP_LOGW(TAG, "Receive Zigbee action(0x%x) callback", callback_id);
break;
}
return ret;
}
`
Additional context.
No response
The text was updated successfully, but these errors were encountered: