This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2340R5: How to declare multiple endpoints for a 3-gang smart switch

Part Number: CC2340R5

Tool/software:

I am building a 3-gang smart switch meaning that it controls three different outputs, I am assuming to control different 3 outputs using the ON_OFF_OUTPUT cluster then I shall have 3 different endpoints, one per output. However according to ZBOSS documentation, the maximum I can do is 1 endpoint, how to handle such a problem or are there any other workarounds? 

  • Hi Abdelrahman,

    It's possible to use multiple endpoints, here are some changes/additions I made to onoff_light:

    #define ZB_LOCK_ENDPOINT            11
    //...
    ZB_HA_DECLARE_DOOR_LOCK_CONTROLLER_CLUSTER_LIST(door_lock_controller_clusters,
                                                    basic_attr_list,
                                                    identify_attr_list);
    ZB_HA_DECLARE_DOOR_LOCK_CONTROLLER_EP(door_lock_controller_ep, ZB_LOCK_ENDPOINT, door_lock_controller_clusters);
    
    /* Declare application's device context for single-endpoint device */
    //ZB_HA_DECLARE_ON_OFF_OUTPUT_CTX(on_off_output_ctx, on_off_output_ep);  //MAKE SURE TO REPLACE THIS
    ZBOSS_DECLARE_DEVICE_CTX_2_EP(on_off_output_ctx, on_off_output_ep, door_lock_controller_ep);
    //...
      ZB_AF_SET_ENDPOINT_HANDLER(ZB_LOCK_ENDPOINT, zcl_specific_cluster_cmd_handler);

    Of course you should use ZBOSS_DECLARE_DEVICE_CTX_3_EP instead and modify the application callbacks to determine which endpoint the command is for.

    Regards,
    Ryan

  • Ok, I get it. but I am having a problem in defining 3 end points for the same ON_OFF_OUTPUT cluster. the problem is that 3 zb_af_simple_desc_5 is declared multiple time for defining 3 endpoints since it's defined as follows in zboss_api_af.h:

    typedef ZB_PACKED_PRE struct zb_af_simple_desc_ ## in_clusters_count ## _ ## out_clusters_count ## _s \
      {                                                                                       \
        zb_uint8_t    endpoint;                 /* Endpoint */                                \
        zb_uint16_t   app_profile_id;           /* Application profile identifier */          \
        zb_uint16_t   app_device_id;            /* Application device identifier */           \
        zb_bitfield_t app_device_version:4;     /* Application device version */              \
        zb_bitfield_t reserved:4;               /* Reserved */                                \
        zb_uint8_t    app_input_cluster_count;  /* Application input cluster count */         \
        zb_uint8_t    app_output_cluster_count; /* Application output cluster count */        \
        /* Application input and output cluster list */                                       \
        zb_uint16_t   app_cluster_list[(in_clusters_count) + (out_clusters_count)]; \
        zb_uint8_t    cluster_encryption[((in_clusters_count) + (out_clusters_count) + 7)/8]; \
      } ZB_PACKED_STRUCT     

    the in_clusters_count and the out_clusters_count for the ON_OFF_OUTPUT cluster are 5 and 0 respectively. that made me get the error the zb_af_simple_desc_5 is defined multiple times

    This is code for declaring the clusters

    /***** Trace related defines *****/
    #define ZB_TRACE_FILE_ID 40124
    
    /****** Application defines ******/
    #define ZB_SWITCH1_ENDPOINT          1
    #define ZB_SWITCH2_ENDPOINT          2
    #define ZB_SWITCH3_ENDPOINT          3
    
    #include <ti/log/Log.h>
    
    #include "ti_zigbee_config.h"
    #include "zboss_api.h"
    #include "zb_led_button.h"
    #include "zboss_api_error.h"
    
    #include <ti/devices/DeviceFamily.h>
    #include DeviceFamily_constructPath(inc/hw_fcfg.h)
    #include DeviceFamily_constructPath(inc/hw_memmap.h)
    
    /* for button handling */
    #include <ti/drivers/GPIO.h>
    #include "ti_drivers_config.h"
    
    #ifdef ZB_CONFIGURABLE_MEM
    #include "zb_mem_config_lprf3.h"
    #endif
    
    #if !defined ZB_ED_FUNC
    #error define ZB_ED_ROLE to compile the tests
    #endif
    
    
    // TODO: adjust transmit power
    
    /****** Application variables declarations ******/
    /* IEEE address of the device */
    zb_bool_t cmd_in_progress = ZB_FALSE;
    zb_bool_t perform_factory_reset = ZB_FALSE;
    zb_uint16_t g_dst_addr;
    zb_uint8_t g_addr_mode;
    zb_uint8_t g_endpoint;
    
    /****** Application function declarations ******/
    zb_uint8_t zcl_specific_cluster_cmd_handler(zb_uint8_t param);
    void on_off_read_attr_resp_handler(zb_bufid_t cmd_buf);
    void send_toggle_req(zb_uint8_t param);
    void button_press_handler(zb_uint8_t param);
    
    /****** Cluster declarations ******/
    
    // on-off attributes for the light switch
    zb_bool_t g_attr_on_off1 = ZB_ZCL_ON_OFF_ON_OFF_DEFAULT_VALUE;
    zb_bool_t g_attr_on_off2 = ZB_ZCL_ON_OFF_ON_OFF_DEFAULT_VALUE;
    zb_bool_t g_attr_on_off3 = ZB_ZCL_ON_OFF_ON_OFF_DEFAULT_VALUE;
    
    ZB_ZCL_DECLARE_ON_OFF_ATTRIB_LIST(on_off_attr_list1, &g_attr_on_off1);
    ZB_ZCL_DECLARE_ON_OFF_ATTRIB_LIST(on_off_attr_list2, &g_attr_on_off2);
    ZB_ZCL_DECLARE_ON_OFF_ATTRIB_LIST(on_off_attr_list3, &g_attr_on_off3);
    
    /* Basic cluster attributes */
    zb_uint8_t attr_power_source = ZB_ZCL_BASIC_POWER_SOURCE_MAINS_SINGLE_PHASE;
    zb_uint8_t attr_zcl_version  = 0x03;
    zb_uint8_t attr_app_version = 0x40;
    zb_uint8_t attr_stack_version = 0x02;
    zb_uint8_t attr_hardware_version = 0x01;
    zb_uint8_t attr_application_version = 0x40;
    zb_uint16_t attr_cluster_rev = 0x0001;
    zb_uint8_t attr_manufacturer_name[16];
    zb_uint8_t attr_model_id[16];
    zb_uint8_t attr_data_code = ZB_ZCL_BASIC_MODEL_IDENTIFIER_DEFAULT_VALUE;
    zb_uint8_t attr_location_id = ZB_ZCL_BASIC_LOCATION_DESCRIPTION_DEFAULT_VALUE;
    zb_uint8_t attr_ph_env = ZB_ZCL_BASIC_PHYSICAL_ENVIRONMENT_DEFAULT_VALUE;
    zb_uint8_t attr_sw_build_id[] = ZB_ZCL_BASIC_SW_BUILD_ID_DEFAULT_VALUE;
    
    ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST_EXT(basic_attr_list, 
                                        &attr_zcl_version,
                                        &attr_app_version,
                                        &attr_stack_version,
                                        &attr_hardware_version,
                                        &attr_manufacturer_name,
                                        &attr_model_id,
                                        &attr_data_code,
                                        &attr_power_source,
                                        &attr_location_id,
                                        &attr_ph_env,
                                        &attr_sw_build_id);
    
    /* Identify cluster attributes */
    zb_uint16_t attr_identify_time = 0;
    ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(identify_attr_list, &attr_identify_time);
    /* Declare cluster list for the device */
    
    zb_uint8_t g_attr_scenes_scene_count = ZB_ZCL_SCENES_SCENE_COUNT_DEFAULT_VALUE;
    zb_uint8_t g_attr_scenes_current_scene = ZB_ZCL_SCENES_CURRENT_SCENE_DEFAULT_VALUE;
    zb_uint16_t g_attr_scenes_current_group = ZB_ZCL_SCENES_CURRENT_GROUP_DEFAULT_VALUE;
    zb_uint8_t g_attr_scenes_scene_valid = ZB_ZCL_SCENES_SCENE_VALID_DEFAULT_VALUE;
    zb_uint16_t g_attr_scenes_name_support = ZB_ZCL_SCENES_NAME_SUPPORT_DEFAULT_VALUE;
    
    ZB_ZCL_DECLARE_SCENES_ATTRIB_LIST(scenes_attr_list, &g_attr_scenes_scene_count,
        &g_attr_scenes_current_scene, &g_attr_scenes_current_group,
        &g_attr_scenes_scene_valid, &g_attr_scenes_name_support);
    
    
    zb_uint8_t g_attr_name_support = 0;
    ZB_ZCL_DECLARE_GROUPS_ATTRIB_LIST(groups_attr_list, &g_attr_name_support);
    
    
    ZB_HA_DECLARE_ON_OFF_OUTPUT_CLUSTER_LIST(on_off_output_clusters1,
                                             on_off_attr_list1,
                                             basic_attr_list,
                                             identify_attr_list,
                                             groups_attr_list,
                                             scenes_attr_list);
    
    ZB_HA_DECLARE_ON_OFF_OUTPUT_CLUSTER_LIST(on_off_output_clusters2,
                                             on_off_attr_list2,
                                             basic_attr_list,
                                             identify_attr_list,
                                             groups_attr_list,
                                             scenes_attr_list);
    
    ZB_HA_DECLARE_ON_OFF_OUTPUT_CLUSTER_LIST(on_off_output_clusters3,
                                             on_off_attr_list3,
                                             basic_attr_list,
                                             identify_attr_list,
                                             groups_attr_list,
                                             scenes_attr_list);
    
    /* Declare endpoint */
    ZB_HA_DECLARE_ON_OFF_OUTPUT_EP(on_off_output_ep1, ZB_SWITCH1_ENDPOINT, on_off_output_clusters1);
    ZB_HA_DECLARE_ON_OFF_OUTPUT_EP(on_off_output_ep2, ZB_SWITCH2_ENDPOINT, on_off_output_clusters2);
    ZB_HA_DECLARE_ON_OFF_OUTPUT_EP(on_off_output_ep3, ZB_SWITCH3_ENDPOINT, on_off_output_clusters3);
    
    /* Declare application's device context for single-endpoint device */
    ZBOSS_DECLARE_DEVICE_CTX_3_EP(on_off_output_ctx, on_off_output_ep1, on_off_output_ep2, on_off_output_ep3)

    I want the 3 endpoints to be of type ON_OFF_OUTPUT clusters.  

    This is a relevant problem but it's on Nordic Side: https://devzone.nordicsemi.com/f/nordic-q-a/84787/zigbee-multiple-same-type-endpoints-conflict-and-proposed-fix and it was 3 years ago.

  • Actually I have edited the ZBOSS source code as mentioned in the aforementioned link (it was alot of edits and the code is build successfully and can be recognized as a 3-gang smart switch on TUYA side.