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!