This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Zigbee Occupancy cluster attribute setting gives Invalid Value error

Hi,

I'm working on building a zigbee multisensor device using a nrf52840 module. I'm heavily relying on the multi sensor example and so far I've been able to add temperature, humidity and battery voltage clusters and see the data reported at my coordinator running zigbee2mqtt software. But now trying to add Occupancy (motion) sensor I've run into trouble. I have declared the Occupancy cluster with ZB_ZCL_DECLARE_OCCUPANCY_SENSING_ATTRIB_LIST and added it to my cluster list. It appears to be successful, as when powering up the device, the controller sees the initial status of the sensor I set in multi_sensor_clusters_attr_init() like this:

static void multi_sensor_clusters_attr_init(void)
{
...
    m_dev_ctx.occupancy_attr.occupancy                      = ZB_ZCL_OCCUPANCY_SENSING_OCCUPANCY_UNOCCUPIED;
    m_dev_ctx.occupancy_attr.occupancy_sensor_type          = ZB_ZCL_OCCUPANCY_SENSING_OCCUPANCY_SENSOR_TYPE_PIR;
    m_dev_ctx.occupancy_attr.occupancy_sensor_type_bitmap   = 0;
...

But when trying to change the value of the OCCUPANCY attribute, I get failures. Right now I do it in a GPIOTE pin change handler and have a switch attached to that pin.

void in_pin_sw1_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
    zb_zcl_status_t zcl_status;
    enum zb_zcl_occupancy_sensing_occupancy_e occu;
    if(nrfx_gpiote_in_is_set(PIN_SW1)) 
    {
        NRF_LOG_INFO("SW1 high");
        occu = ZB_ZCL_OCCUPANCY_SENSING_OCCUPANCY_OCCUPIED;
    }
    else
    {
        NRF_LOG_INFO("SW1 low");
        occu = ZB_ZCL_OCCUPANCY_SENSING_OCCUPANCY_UNOCCUPIED;
    }
    
    zcl_status = zb_zcl_set_attr_val(MULTI_SENSOR_ENDPOINT, 
                                     ZB_ZCL_CLUSTER_ID_OCCUPANCY_SENSING, 
                                     ZB_ZCL_CLUSTER_SERVER_ROLE, 
                                     ZB_ZCL_ATTR_OCCUPANCY_SENSING_OCCUPANCY_ID, 
                                     (zb_uint8_t *)&occu, 
                                     ZB_FALSE);
    if(zcl_status != ZB_ZCL_STATUS_SUCCESS)
    {
        NRF_LOG_INFO("Set occu fail. zcl_status: %d", zcl_status);
    }
    
}

The parameters given for zb_zcl_set_attr_val are following exactly the same conventions I use to successfully send temperature and other attributes.

When running the code and flipping the switch after the device has joined the network, the log shows:

<info> app: SW1 low
<info> app: Set occu fail. zcl_status: 135
<info> app: SW1 high
<info> app: Set occu fail. zcl_status: 135

zcl_status 135 is 0x87 which means ZB_ZCL_STATUS_INVALID_VALUE.

I simply cannot see what is wrong. I've tried also not using the enumerations and simply using zb_uint8_t data types but that gives the same result. Any pointers where to look? One thing I noticed is that when looking at ZCL specification 4.8.2.2.1, there is not mention of the OCCUPANCY_SENSOR_TYPE_BITMAP_ID attribute which is one parameter for  ZB_ZCL_DECLARE_OCCUPANCY_SENSING_ATTRIB_LIST in latest documentation. I tried modifying the header to not include that attribute in the declaration, but that did not change anything either.

Thanks for any hints!

Parents Reply Children
  • Hi! Thanks for looking into this. I uploaded the whole source as it is now to https://github.com/pekkaroi/zigbee_multisensor/. I use gcc so everything related to running with SES is probably not included, sorry about that.

    I certainly agree that the cluster setup may be the issue. As I said, I see some discrepancy between the default attribute list on your headers versus the ZCL spec so I am not sure if I've done it correctly.

    Edit: Forgot to mention. At the state of committing to github, I had implemented my own version of ZB_ZCL_DECLARE_OCCUPANCY_SENSING_ATTRIB_LIST at zigbee_custom.h. But it does not change anything if I use the original one from the zboss or my own..

  • Hello,

    I am terribly sorry for the late reply. Our Zigbee team has been really busy with release work. I received a reply the 24th of July, but I was on vacation until today. They wrote:

    --

    Hi!
    Today I looked into this cluster and if this implementation was never meant to be usable, DSR (who delivers our Zigbee Stack) had to have an idea of an "abstract"/"interface" Occupancy Sensing cluster definition.

    That said, in order to use it - you have to inherit from/extend it by adding Attribute List specific to the implemented occupancy sensor. Since you may implement all three types of occupancy sensing devices, this gives you 7 possible Occupancy Sensing cluster's attribute list definitions (and many more if you consider using customer-specific sensors).

    Whenever a customer wants to use it, than he has to define:

    • Sensor-specific attribute name, e.g.: #define ZB_ZCL_CLUSTER_ID_OCCUPANCY_SENSING_PIR ZB_ZCL_CLUSTER_ID_OCCUPANCY_SENSING
    • Sensor-specific attribute handlers, e.g.: #defineZB_ZCL_CLUSTER_ID_OCCUPANCY_SENSING_PIR_SERVER_ROLE_INIT pir_sensor_init
    • The init function has to pass the write attribute hook to the stack, e.g.:

    zb_zcl_add_cluster_handlers(ZB_ZCL_CLUSTER_ID_OCCUPANCY_SENSING_PIR,
                                  ZB_ZCL_CLUSTER_SERVER_ROLE,
                                  check_value_pir_sensor_server,
                                  write_attr_pir_sensor_server_hook,
                                  (zb_zcl_cluster_handler_t)NULL);

    Essentially, the customer has to do all steps, required to define a new, customer-specific cluster.

    --

    Best regards,

    Edvin

Related