2026-01-01 1:51 AM - edited 2026-01-01 1:55 AM
Hi there and happy new year!
I am currently trying to develop a dimmable color light with an stm32wb55 (Nucleo Board).
Everything seems to work when connecting the device to a zigbee2mqtt server over zigbee.
But actually all color server related callbacks are never invoked and i have no clue why.
The other clusters are working just fine and the callbacks are called (on/off, brightness).
My endpoint setup code:
/**
* @brief Configure Zigbee application endpoints
* None
* @retval None
*/
static void APP_ZIGBEE_ConfigEndpoints(void)
{
struct ZbApsmeAddEndpointReqT req;
struct ZbApsmeAddEndpointConfT conf;
memset(&req, 0, sizeof(req));
/* Endpoint: SW1_ENDPOINT */
req.profileId = ZCL_PROFILE_HOME_AUTOMATION;
req.deviceId = ZCL_DEVICE_COLOR_DIMMABLE_LIGHT;
req.endpoint = SW1_ENDPOINT;
ZbZclAddEndpoint(zigbee_app_info.zb, &req, &conf);
assert(conf.status == ZB_STATUS_SUCCESS);
/* Basic client/server */
zigbee_app_info.basic_client_1 = ZbZclBasicClientAlloc(zigbee_app_info.zb, SW1_ENDPOINT);
assert(zigbee_app_info.basic_client_1 != NULL);
ZbZclClusterEndpointRegister(zigbee_app_info.basic_client_1);
/* Identify client/server */
zigbee_app_info.identify_client_1 = ZbZclIdentifyClientAlloc(zigbee_app_info.zb, SW1_ENDPOINT);
assert(zigbee_app_info.identify_client_1 != NULL);
ZbZclClusterEndpointRegister(zigbee_app_info.identify_client_1);
zigbee_app_info.identify_server_1 = ZbZclIdentifyServerAlloc(zigbee_app_info.zb, SW1_ENDPOINT, NULL);
assert(zigbee_app_info.identify_server_1 != NULL);
ZbZclClusterEndpointRegister(zigbee_app_info.identify_server_1);
/* OnOff client/server */
zigbee_app_info.onOff_client_1 = ZbZclOnOffClientAlloc(zigbee_app_info.zb, SW1_ENDPOINT);
assert(zigbee_app_info.onOff_client_1 != NULL);
ZbZclClusterEndpointRegister(zigbee_app_info.onOff_client_1);
zigbee_app_info.onOff_server_1 = ZbZclOnOffServerAlloc(zigbee_app_info.zb, SW1_ENDPOINT, &OnOffServerCallbacks_1, NULL);
assert(zigbee_app_info.onOff_server_1 != NULL);
ZbZclClusterEndpointRegister(zigbee_app_info.onOff_server_1);
/* ColorControl client/server */
zigbee_app_info.colorControl_client_1 = ZbZclColorClientAlloc(zigbee_app_info.zb, SW1_ENDPOINT);
assert(zigbee_app_info.colorControl_client_1 != NULL);
ZbZclClusterEndpointRegister(zigbee_app_info.colorControl_client_1);
struct ZbColorClusterConfig colorServerConfig_1 = {
.callbacks = ColorServerCallbacks_1,
.capabilities = ZCL_COLOR_CAP_HS | ZCL_COLOR_CAP_XY
/* Please complete the other attributes according to your application:
* .capabilities //uint8_t (e.g. ZCL_COLOR_CAP_HS)
* .enhanced_supported //bool
*/
/* USER CODE BEGIN ColorServerConfig1 */
/* USER CODE END ColorServerConfig1 */
};
zigbee_app_info.colorControl_server_1 = ZbZclColorServerAlloc(zigbee_app_info.zb, SW1_ENDPOINT, zigbee_app_info.onOff_server_1, NULL, 0, &colorServerConfig_1, NULL);
assert(zigbee_app_info.colorControl_server_1 != NULL);
ZbZclClusterEndpointRegister(zigbee_app_info.colorControl_server_1);
/* LevelControl client/server */
zigbee_app_info.levelControl_client_1 = ZbZclLevelClientAlloc(zigbee_app_info.zb, SW1_ENDPOINT);
assert(zigbee_app_info.levelControl_client_1 != NULL);
ZbZclClusterEndpointRegister(zigbee_app_info.levelControl_client_1);
zigbee_app_info.levelControl_server_1 = ZbZclLevelServerAlloc(zigbee_app_info.zb, SW1_ENDPOINT, zigbee_app_info.onOff_server_1, &LevelServerCallbacks_1, NULL);
assert(zigbee_app_info.levelControl_server_1 != NULL);
ZbZclClusterEndpointRegister(zigbee_app_info.levelControl_server_1);
/* USER CODE BEGIN CONFIG_ENDPOINT */
uint8_t level = 128;
ZbZclAttrIntegerWrite(zigbee_app_info.levelControl_server_1,
ZCL_LEVEL_ATTR_CURRLEVEL,
level);
/* Init Color Temperature */
uint16_t temp = 370;
ZbZclAttrIntegerWrite(zigbee_app_info.colorControl_server_1,
ZCL_COLOR_ATTR_CURRENT_HUE,
temp);
/* USER CODE END CONFIG_ENDPOINT */
}Current callbacks:
struct zigbee_app_info
{
bool has_init;
struct ZigBeeT *zb;
enum ZbStartType startupControl;
enum ZbStatusCodeT join_status;
uint32_t join_delay;
bool init_after_join;
struct ZbZclClusterT *basic_client_1;
struct ZbZclClusterT *identify_client_1;
struct ZbZclClusterT *identify_server_1;
struct ZbZclClusterT *onOff_client_1;
struct ZbZclClusterT *onOff_server_1;
struct ZbZclClusterT *colorControl_client_1;
struct ZbZclClusterT *colorControl_server_1;
struct ZbZclClusterT *levelControl_client_1;
struct ZbZclClusterT *levelControl_server_1;
};
static struct zigbee_app_info zigbee_app_info;
/* OnOff server 1 custom callbacks */
static enum ZclStatusCodeT onOff_server_1_off(struct ZbZclClusterT *cluster, struct ZbZclAddrInfoT *srcInfo, void *arg);
static enum ZclStatusCodeT onOff_server_1_on(struct ZbZclClusterT *cluster, struct ZbZclAddrInfoT *srcInfo, void *arg);
static enum ZclStatusCodeT onOff_server_1_toggle(struct ZbZclClusterT *cluster, struct ZbZclAddrInfoT *srcInfo, void *arg);
static struct ZbZclOnOffServerCallbacksT OnOffServerCallbacks_1 =
{
.off = onOff_server_1_off,
.on = onOff_server_1_on,
.toggle = onOff_server_1_toggle,
};
/* ColorControl server 1 custom callbacks */
static enum ZclStatusCodeT colorControl_server_1_move_to_hue_sat(struct ZbZclClusterT *cluster, struct ZbZclColorClientMoveToHueSatReqT *req, struct ZbZclAddrInfoT *srcInfo, void *arg);
static enum ZclStatusCodeT colorControl_server_1_move_to_color_xy(struct ZbZclClusterT *cluster, struct ZbZclColorClientMoveToColorXYReqT *req, struct ZbZclAddrInfoT *srcInfo, void *arg);
static struct ZbZclColorServerCallbacksT ColorServerCallbacks_1 =
{
.move_to_hue_sat = colorControl_server_1_move_to_hue_sat,
.move_to_color_xy = colorControl_server_1_move_to_color_xy,
};
/* LevelControl server 1 custom callbacks */
static enum ZclStatusCodeT levelControl_server_1_move_to_level(struct ZbZclClusterT *cluster, struct ZbZclLevelClientMoveToLevelReqT *req, struct ZbZclAddrInfoT *srcInfo, void *arg);
static enum ZclStatusCodeT levelControl_server_1_move(struct ZbZclClusterT *cluster, struct ZbZclLevelClientMoveReqT *req, struct ZbZclAddrInfoT *srcInfo, void *arg);
static enum ZclStatusCodeT levelControl_server_1_step(struct ZbZclClusterT *cluster, struct ZbZclLevelClientStepReqT *req, struct ZbZclAddrInfoT *srcInfo, void *arg);
static enum ZclStatusCodeT levelControl_server_1_stop(struct ZbZclClusterT *cluster, struct ZbZclLevelClientStopReqT *req, struct ZbZclAddrInfoT *srcInfo, void *arg);
static struct ZbZclLevelServerCallbacksT LevelServerCallbacks_1 =
{
.move_to_level = levelControl_server_1_move_to_level,
.move = levelControl_server_1_move,
.step = levelControl_server_1_step,
.stop = levelControl_server_1_stop,
};
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Functions Definition ------------------------------------------------------*/
/* OnOff server off 1 command callback */
static enum ZclStatusCodeT onOff_server_1_off(struct ZbZclClusterT *cluster, struct ZbZclAddrInfoT *srcInfo, void *arg)
{
/* USER CODE BEGIN 0 OnOff server 1 off 1 */
APP_DBG("Move temp");
return ZCL_STATUS_SUCCESS;
/* USER CODE END 0 OnOff server 1 off 1 */
}
/* OnOff server on 1 command callback */
static enum ZclStatusCodeT onOff_server_1_on(struct ZbZclClusterT *cluster, struct ZbZclAddrInfoT *srcInfo, void *arg)
{
/* USER CODE BEGIN 1 OnOff server 1 on 1 */
APP_DBG("Move temp");
return ZCL_STATUS_SUCCESS;
/* USER CODE END 1 OnOff server 1 on 1 */
}
/* OnOff server toggle 1 command callback */
static enum ZclStatusCodeT onOff_server_1_toggle(struct ZbZclClusterT *cluster, struct ZbZclAddrInfoT *srcInfo, void *arg)
{
/* USER CODE BEGIN 2 OnOff server 1 toggle 1 */
APP_DBG("Move temp");
return ZCL_STATUS_SUCCESS;
/* USER CODE END 2 OnOff server 1 toggle 1 */
}
/* ColorControl server move_to_hue_sat 1 command callback */
static enum ZclStatusCodeT colorControl_server_1_move_to_hue_sat(struct ZbZclClusterT *cluster, struct ZbZclColorClientMoveToHueSatReqT *req, struct ZbZclAddrInfoT *srcInfo, void *arg)
{
/* USER CODE BEGIN 3 ColorControl server 1 move_to_hue_sat 1 */
return ZCL_STATUS_SUCCESS;
/* USER CODE END 3 ColorControl server 1 move_to_hue_sat 1 */
}
/* ColorControl server move_to_color_xy 1 command callback */
static enum ZclStatusCodeT colorControl_server_1_move_to_color_xy(struct ZbZclClusterT *cluster, struct ZbZclColorClientMoveToColorXYReqT *req, struct ZbZclAddrInfoT *srcInfo, void *arg)
{
/* USER CODE BEGIN 4 ColorControl server 1 move_to_color_xy 1 */
return ZCL_STATUS_SUCCESS;
/* USER CODE END 4 ColorControl server 1 move_to_color_xy 1 */
}
/* LevelControl server move_to_level 1 command callback */
static enum ZclStatusCodeT levelControl_server_1_move_to_level(struct ZbZclClusterT *cluster, struct ZbZclLevelClientMoveToLevelReqT *req, struct ZbZclAddrInfoT *srcInfo, void *arg)
{
/* USER CODE BEGIN 5 LevelControl server 1 move_to_level 1 */
return ZCL_STATUS_SUCCESS;
/* USER CODE END 5 LevelControl server 1 move_to_level 1 */
}
/* LevelControl server move 1 command callback */
static enum ZclStatusCodeT levelControl_server_1_move(struct ZbZclClusterT *cluster, struct ZbZclLevelClientMoveReqT *req, struct ZbZclAddrInfoT *srcInfo, void *arg)
{
/* USER CODE BEGIN 6 LevelControl server 1 move 1 */
return ZCL_STATUS_SUCCESS;
/* USER CODE END 6 LevelControl server 1 move 1 */
}
/* LevelControl server step 1 command callback */
static enum ZclStatusCodeT levelControl_server_1_step(struct ZbZclClusterT *cluster, struct ZbZclLevelClientStepReqT *req, struct ZbZclAddrInfoT *srcInfo, void *arg)
{
/* USER CODE BEGIN 7 LevelControl server 1 step 1 */
return ZCL_STATUS_SUCCESS;
/* USER CODE END 7 LevelControl server 1 step 1 */
}
/* LevelControl server stop 1 command callback */
static enum ZclStatusCodeT levelControl_server_1_stop(struct ZbZclClusterT *cluster, struct ZbZclLevelClientStopReqT *req, struct ZbZclAddrInfoT *srcInfo, void *arg)
{
/* USER CODE BEGIN 8 LevelControl server 1 stop 1 */
return ZCL_STATUS_SUCCESS;
/* USER CODE END 8 LevelControl server 1 stop 1 */
}The device shown in zigbee2mqtt:
I attached the full app_zigbee.c file aswell.
Maybe one has an idea whats going on here, as all other function callbacks are working as expected. Its just the color stuff :)