How to send readresponse on OnOff Output Cluster to Coordinator?

I am trying to send a OnOff output cluster information to Co-ordinator when a button is pressed in the nrf52840 DK.  The problem is the during the initial registration, the OnOff command is correctly sent, but after the button is pressed, I am unable to find the correct method to send the readresponse

Here is the complete program

#include <zephyr/types.h>
#include <zephyr.h>
#include <device.h>
#include <soc.h>
#include <drivers/pwm.h>
#include <logging/log.h>
#include <dk_buttons_and_leds.h>
#include <settings/settings.h>

#include <zboss_api.h>
#include <zboss_api_addons.h>
#include <zb_mem_config_med.h>
#include <zigbee/zigbee_app_utils.h>
#include <zigbee/zigbee_error_handler.h>
#include <zigbee/zigbee_zcl_scenes.h>
#include <zb_nrf_platform.h>

/* Switch endpoint */
#define HA_SWITCH_ENDPOINT      12

/* Version of the application software (1 byte). */
#define SWITCH_INIT_BASIC_APP_VERSION     01

/* Version of the implementation of the Zigbee stack (1 byte). */
#define SWITCH_INIT_BASIC_STACK_VERSION   10

/* Version of the hardware of the device (1 byte). */
#define SWITCH_INIT_BASIC_HW_VERSION      11

/* Manufacturer name (32 bytes). */
#define SWITCH_INIT_BASIC_MANUF_NAME      "DongleNordic"

/* Model number assigned by manufacturer (32-bytes long string). */
#define SWITCH_INIT_BASIC_MODEL_ID        "DongleSwitch"

/* First 8 bytes specify the date of manufacturer of the device
 * in ISO 8601 format (YYYYMMDD). The rest (8 bytes) are manufacturer specific.
 */
#define SWITCH_INIT_BASIC_DATE_CODE       "202201207777"

/* Type of power sources available for the device.
 * For possible values see section 3.2.2.2.8 of ZCL specification.
 */
#define SWITCH_INIT_BASIC_POWER_SOURCE    ZB_ZCL_BASIC_POWER_SOURCE_BATTERY

/* Describes the physical location of the device (16 bytes).
 * May be modified during commisioning process.
 */
#define SWITCH_INIT_BASIC_LOCATION_DESC   "Home"

/* Describes the type of physical environment.
 * For possible values see section 3.2.2.2.10 of ZCL specification.
 */
#define SWITCH_INIT_BASIC_PH_ENV          ZB_ZCL_BASIC_ENV_UNSPECIFIED

#define TOGGLE_SWITCH					DK_BTN3_MSK

/* Nordic PWM nodes don't have flags cells in their specifiers, so
 * this is just future-proofing.
 */
#define FLAGS_OR_ZERO(node) \
	COND_CODE_1(DT_PHA_HAS_CELL(node, pwms, flags), \
		    (DT_PWMS_FLAGS(node)), (0))


#ifndef ZB_ED_ROLE
#error Define ZB_END_DEVICE_ROLE to compile enddevice source code.
#endif

static void switch_send_on_off(zb_bufid_t bufid, zb_uint16_t on_off);

LOG_MODULE_REGISTER(app);

/** 
 * Placeholder for the bulb context 
 * Stores all settings and static values.
 **/
typedef struct 
{
	zb_zcl_basic_attrs_ext_t         basic_attr;
	zb_zcl_identify_attrs_t          identify_attr;
	zb_zcl_scenes_attrs_t            scenes_attr;
	zb_zcl_groups_attrs_t            groups_attr;
 	zb_zcl_on_off_attrs_t            on_off_attr;
} on_off_device_ctx_t;
/* Zigbee device application context storage. */
static on_off_device_ctx_t dev_ctx;

ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(
	identify_attr_list,
	&dev_ctx.identify_attr.identify_time);

ZB_ZCL_DECLARE_GROUPS_ATTRIB_LIST(
	groups_attr_list,
	&dev_ctx.groups_attr.name_support);

ZB_ZCL_DECLARE_SCENES_ATTRIB_LIST(
	scenes_attr_list,
	&dev_ctx.scenes_attr.scene_count,
	&dev_ctx.scenes_attr.current_scene,
	&dev_ctx.scenes_attr.current_group,
	&dev_ctx.scenes_attr.scene_valid,
	&dev_ctx.scenes_attr.name_support);

ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST_EXT(
	basic_attr_list,
	&dev_ctx.basic_attr.zcl_version,
	&dev_ctx.basic_attr.app_version,
	&dev_ctx.basic_attr.stack_version,
	&dev_ctx.basic_attr.hw_version,
	dev_ctx.basic_attr.mf_name,
	dev_ctx.basic_attr.model_id,
	dev_ctx.basic_attr.date_code,
	&dev_ctx.basic_attr.power_source,
	dev_ctx.basic_attr.location_id,
	&dev_ctx.basic_attr.ph_env,
	dev_ctx.basic_attr.sw_ver);

/* On/Off cluster attributes additions data */
ZB_ZCL_DECLARE_ON_OFF_ATTRIB_LIST(
	on_off_attr_list,
	&dev_ctx.on_off_attr.on_off);

ZB_HA_DECLARE_ON_OFF_OUTPUT_CLUSTER_LIST(on_off_output_clusters,
    on_off_attr_list, basic_attr_list, identify_attr_list, groups_attr_list,
    scenes_attr_list);

ZB_HA_DECLARE_ON_OFF_OUTPUT_EP(on_off_output_ep, HA_SWITCH_ENDPOINT, on_off_output_clusters);

ZB_HA_DECLARE_ON_OFF_OUTPUT_CTX(on_off_output_ctx, on_off_output_ep);

/**@brief Callback for button events.
 *
 * @param[in]   button_state  Bitmask containing buttons state.
 * @param[in]   has_changed   Bitmask containing buttons
 *                            that have changed their state.
 */
static void button_changed(uint32_t button_state, uint32_t has_changed)
{
	zb_ret_t zb_err_code;
	zb_uint16_t cmd_id = ZB_ZCL_CMD_ON_OFF_ON_ID;
	zb_err_code = zb_buf_get_out_delayed_ext(switch_send_on_off, cmd_id, 0);
	ZB_ERROR_CHECK(zb_err_code);
}

/**@brief Function for initializing LEDs and Buttons. */
static void configure_gpio(void)
{
	int err;

	err = dk_buttons_init(button_changed);
	if (err) {
		LOG_ERR("Cannot init buttons (err: %d)", err);
	}
}

/**@brief Function for sending ON/OFF requests to the network / co-ordinator.
 *
 * @param[in]   bufid    Non-zero reference to Zigbee stack buffer that will be
 *                       used to construct on/off request.
 * @param[in]   cmd_id   ZCL command id.
 */
static void switch_send_on_off(zb_bufid_t bufid, zb_uint16_t cmd_id)
{
	LOG_INF("Send ON/OFF command: %d", cmd_id);
	zb_uint16_t coordinator_address = 0x0000;
	dev_ctx.on_off_attr.on_off = (zb_bool_t)ZB_ZCL_ON_OFF_IS_ON;				

	ZB_ZCL_ON_OFF_SEND_REQ(bufid,
				coordinator_address,
				ZB_APS_ADDR_MODE_16_ENDP_PRESENT,
				HA_SWITCH_ENDPOINT,
				HA_SWITCH_ENDPOINT,
				ZB_AF_HA_PROFILE_ID,
				ZB_ZCL_ENABLE_DEFAULT_RESPONSE,
				cmd_id,
				NULL);
}

/**@brief Callback function for handling ZCL commands.
 *
 * @param[in]   bufid   Reference to Zigbee stack buffer
 *                      used to pass received data.
 */
static void zcl_device_cb(zb_bufid_t bufid)
{
	zb_uint8_t cluster_id;
	zb_uint8_t attr_id;
	zb_uint8_t endpoint_invoked;	
	zb_zcl_device_callback_param_t  *device_cb_param =
		ZB_BUF_GET_PARAM(bufid, zb_zcl_device_callback_param_t);
	
	endpoint_invoked = device_cb_param->endpoint;

	LOG_INF("%s id %hd", __func__, device_cb_param->device_cb_id);

	LOG_INF("EndPoint Called is %d ", endpoint_invoked);

	/* Set default response value. */
	device_cb_param->status = RET_OK;
	LOG_INF("ZB Callback started %c", bufid);	

	LOG_INF("%s status: %hd", __func__, device_cb_param->status);
}

/**@brief Zigbee stack event handler.
 *
 * @param[in]   bufid   Reference to the Zigbee stack buffer
 *                      used to pass signal.
 */
void zboss_signal_handler(zb_bufid_t bufid)
{
	/* No application-specific behavior is required.
	 * Call default signal handler.
	 */
	ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid));

	/* All callbacks should either reuse or free passed buffers.
	 * If bufid == 0, the buffer is invalid (not passed).
	 */
	if (bufid) {
		zb_buf_free(bufid);
	}
}

void error(void)
{
	while (true) {
		/* Spin forever */
		k_sleep(K_MSEC(1000));
	}
}

void main(void)
{
	int err;

	LOG_INF("Starting Switch example");

	/* Initialize */
	configure_gpio();
	err = settings_subsys_init();
	if (err) {
		LOG_ERR("settings initialization failed");
	}

	LOG_INF("Registering Device");
	/* Register callback for handling ZCL commands. */
	ZB_ZCL_REGISTER_DEVICE_CB(zcl_device_cb);

	LOG_INF("Setting Switch Context");
	/* Register dimmer switch device context (all the endpoints). */
	ZB_AF_REGISTER_DEVICE_CTX(&on_off_output_ctx);

	/* Initialize ZCL scene table */
	// zcl_scenes_init();

	/* Settings should be loaded after zcl_scenes_init */
	err = settings_load();
	if (err) {
		LOG_ERR("settings loading failed");
	}

	/* Start Zigbee default thread */
	zigbee_enable();

	LOG_INF("Switch example started");

	while (1) {
		// k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
	}
}

1. When the image is flashed in DK, it properly registers to the Zigbee2MQTT and send the correct response  - please see the the Part 1 in the snapshot below.  The Cluster is 'genOnOff, type 'readResponse' and json data {'OnOff':0}

2. After button is clicked - DK BTN3 in this case, the type changes to 'commandOn' with json data being empty - please see the Part 2 in the snapshot below.  It is obviously due to the macro ZB_ZCL_ON_OFF_SEND_REQ. But I would need the cluster and the payload sent just like # 1.  Which macro should I use to retain the type 'readResponse' for cluster 'genOnOff' and fill in the json data? This is for the OnOff Output ZCL

Parents
  • Hi,

    Can you clarify what you mean by the read response? Is this something the DK should send, or the coordinator? Is this as a response to the ON/OFF command, or are you thinking about the Read Attributes command?

    I see you are sending the ON/OFF command to the endpoint of the light switch. Is the endpoint on the coordinator also 12, so that the command is sent to the correct endpoint?

    Best regards,

    Marte

  • Hi Marte,

    Can you clarify what you mean by the read response? Is this something the DK should send, or the coordinator? Is this as a response to the ON/OFF command, or are you thinking about the Read Attributes command?

    1.    If you check the screenshot above (pasted the text below), it has this debug messages in Zigbee2Mqtt (Z2M). This is issued just when the DK connects to Z2M.  So the initial setup of the OnOff Cluster generates the type 'readResponse' from cluster genOnOff  and send to co-ordinator

    Debug Received Zigbee message from 'dev_board', type 'readResponse', cluster 'genOnOff', data '{"onOff":0}' from endpoint 12 with groupID 0

    However, when I press the button, as I explained in the above post, I call the macro 'ZB_ZCL_ON_OFF_SEND_REQ which generates the following. Looks like this call modifies the type to 'commandOn' and data payload is empty. So my question is there a macro which generates the same zigbee message which is called during initialization? This could be reused during button press and send to co-ordinator

    Debug Received Zigbee message from 'dev_board', type 'commandOn', cluster 'genOnOff', data '{}' from endpoint 12 with groupID 0

    2.  For the second point you asked

    I see you are sending the ON/OFF command to the endpoint of the light switch. Is the endpoint on the coordinator also 12, so that the command is sent to the correct endpoint?

    I am just sending the ON/OFF command to the co-ordinator. There is technically no LightSwitch.  The Z2M (running as a co-ordinator) just receives the Zigbee messages and converts to MQTT messages.  So it does not matter which endpoint the zigbee command from the DK is sent to.  As long as the messages is received by the co-ordinator (running Z2M) it it good. And this is what I am trying to indicate, during the initial connect when DK connects, the Zigbee Mesages generate has a correct 'type' - readResponse and 'data' {"onOff":0} , but after button press, I believe the Macro changes the type to 'CommandOn' and the data JSON is empty.  Hence, wanted to know how can the same method / macro be used which might be called during initial connect.

    Hope I am clear.  You may check the main.c for more details

  • Hi,

    Manju_rn said:
    So my question is there a macro which generates the same zigbee message which is called during initialization?

    To answer this I need to know what readResponse actually is. In the Zigbee specification you have different types of read responses, but there is nothing simply called read response, which is why I asked for a clarification as to what sort of read response this is. It would be better to know what you want to achieve with the read response. Do you want to read what the value of the OnOff attribute is, and if so on which device? Or is the goal to do something else? I have not been able to find a lot of documentation as to what specifically the readResponse in Zigbee2MQTT is, so knowing more about what it is you want to do would make it easier for me to figure out what command you can use.

    Manju_rn said:
    However, when I press the button, as I explained in the above post, I call the macro 'ZB_ZCL_ON_OFF_SEND_REQ which generates the following. Looks like this call modifies the type to 'commandOn' and data payload is empty

    This is because the macro ZB_ZCL_ON_OFF_SEND_REQ sends an On or Off command from the On/Off cluster. The parameter cmd_id decides which of the commands is sent, and in your code you are using the ID of the On command, so you are sending the On command, resulting in the type in Zigbee2MQTT being 'commandOn'.

    Manju_rn said:
    2.  For the second point you asked

    As for your second point the DK is implemented and acting as a light switch in your program, which is why i called it a light switch. It does, however, matter which endpoint the command is sent to if you are sending On/Off command to turn something on or off. But since you are saying that you want to get the read response I am not sure if sending the On command is actually what you want to do or not, so please specify what it is you want to achieve with this program.

    Best regards,

    Marte

  • I have not been able to find a lot of documentation as to what specifically the readResponse in Zigbee2MQTT is, so knowing more about what it is you want to do would make it easier for me to figure out what command you can use

    Please check the following code in the Zigbee2MQTT Converters. These converters basically a layer in Z2M which parses the Zigbee messages  https://github.com/Koenkk/zigbee-herdsman-converters/blob/master/converters/fromZigbee.js#L740

        on_off: {
            cluster: 'genOnOff',
            type: ['attributeReport', 'readResponse'],
            convert: (model, msg, publish, options, meta) => {
                if (msg.data.hasOwnProperty('onOff')) {
                    const property = postfixWithEndpointName('state', msg, model);
                    return {[property]: msg.data['onOff'] === 1 ? 'ON' : 'OFF'};
                }
            },
        },

    It looks for the Cluster 'genOnOff' with type 'readResponse' and the attribute of 'onOff".  This is written based on the ZCL specs for OnOff Cluster. 

    I realized that the reporting is not configured, I was of the assumption that the macro ZB_HA_DECLARE_ON_OFF_OUTPUT_EP would enable the reporting.  Anyway, I have configured the reporting like this.

    static void configure_reporting_locally(void)
    {
      zb_zcl_reporting_info_t rep_info;
      memset(&rep_info, 0, sizeof(rep_info));
    
      rep_info.direction      = ZB_ZCL_CONFIGURE_REPORTING_SEND_REPORT;
      rep_info.ep             = HA_SWITCH_ENDPOINT;
      rep_info.cluster_id     = ZB_ZCL_CLUSTER_ID_ON_OFF;
      rep_info.cluster_role   = ZB_ZCL_CLUSTER_SERVER_ROLE;
      rep_info.attr_id        = ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID;
    
      rep_info.u.send_info.min_interval = 0;
      rep_info.u.send_info.max_interval = 0;
      rep_info.u.send_info.delta.u8     = 1;
       
      rep_info.dst.short_addr = 0x0000 ; //Hex 
      rep_info.dst.endpoint   = 12 ;     //Decimal 
      rep_info.dst.profile_id = ZB_AF_HA_PROFILE_ID ;
    
      zb_zcl_put_reporting_info(&rep_info,ZB_TRUE);
    }
    
    void zboss_signal_handler(zb_bufid_t bufid) 
    {
    	zb_zdo_app_signal_hdr_t *p_sg_p = NULL;
    	zb_zdo_app_signal_type_t sig = zb_get_app_signal(bufid, &p_sg_p);
    	zb_ret_t status = ZB_GET_APP_SIGNAL_STATUS(bufid);
    
    	/* Update network status LED */
    	// zigbee_led_status_update(bufid, ZIGBEE_NETWORK_STATE_LED);
    
    	switch (sig) 
    	{
    		case ZB_BDB_SIGNAL_DEVICE_REBOOT:
    			/* fall-through */
    		case ZB_BDB_SIGNAL_STEERING:
    			/* Call default signal handler. */
    			ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid));
    			if (status == RET_OK) 
    			{
    				LOG_INF("Steering Completed. Going ahead with reporting configuration");
    				configure_reporting_locally();
    			}
    			break;
    
    		default:
    			/* Call default signal handler. */
    			ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid));
    			break;
    	}
    
    	if (bufid) 
    	{
    		zb_buf_free(bufid);
    	}
    }

    The above setting does not send any configuration details to Z2M.  Is there some code I need to call specifically to set the reporting?

    However, I have noticed that when I send the reporting configuration request from Z2M to DK, then the reporting get enabled.  However, this does not help as I want to configure the reporting from the device - DK in this case.

  • ZB_HA_DECLARE_ON_OFF_OUTPUT_EP

    Realized that there was a small change needed at Z2M to receive the reporting configuration, so the quoted method does indeed initalize the reporting. Hence, the method 'configure_reporting_locally" that was written is not really required to configure reporting.

    However, the default reporting takes the min interval value as 0, and the max interval value as 3600 (see the snapshot for Z2M). However, the intention was to enable enable reporting based on the value change, so the max interval value should be 0 I believe. 

    So I guess I will still have to use the configure_reporting_locally, but somehow the call zb_zcl_put_reporting_info(&rep_info,ZB_TRUE);  does not invoke any zigbee message.  Is there another method I could use to update the default reporting values of max and Min intervals?

Reply
  • ZB_HA_DECLARE_ON_OFF_OUTPUT_EP

    Realized that there was a small change needed at Z2M to receive the reporting configuration, so the quoted method does indeed initalize the reporting. Hence, the method 'configure_reporting_locally" that was written is not really required to configure reporting.

    However, the default reporting takes the min interval value as 0, and the max interval value as 3600 (see the snapshot for Z2M). However, the intention was to enable enable reporting based on the value change, so the max interval value should be 0 I believe. 

    So I guess I will still have to use the configure_reporting_locally, but somehow the call zb_zcl_put_reporting_info(&rep_info,ZB_TRUE);  does not invoke any zigbee message.  Is there another method I could use to update the default reporting values of max and Min intervals?

Children
  • Hi,

    So the coordinator does configure reporting, but only with a reportable interval and not on change? From looking at the last code you shared this seems to be correct. If it is the coordinator sending the configure reporting command, do you know where the command is filled and sent? In order to configure reporting on when the attribute value is changed you need to set the reportable change field to the minimum change to the attribute that will result in a report being issued.

    Manju_rn said:
    However, the default reporting takes the min interval value as 0, and the max interval value as 3600 (see the snapshot for Z2M). However, the intention was to enable enable reporting based on the value change, so the max interval value should be 0 I believe. 

    It should not be necessary to set the max interval to 0 in order to get reportable value change as far as I am aware.

    It would also be useful to get a sniffer log of what packets the coordinator is sending and to be able to see the fields of the packets. Do you have an additional nRF52840 DK or Dongle? If so you can use it as a sniffer using nRF Sniffer for 802.15.4. If you get a sniffer log of this you can upload the log as a pcap file here and I will take a look at it. If so, you need to either start the sniffer before the coordinator starts the network so the packets are decrypted, or share the network key so I can decrypt the packets.

    Best regards,

    Marte

  • So the coordinator does configure reporting, but only with a reportable interval and not on change?

    Yes, here is the code. There is a override also - see the #2 below, I need to figure out how to use it.

    1. As given before the code for the device to be registered

    https://github.com/Koenkk/zigbee2mqtt.io/blob/master/docs/externalConvertersExample/switch.js#L19

    2. The code for the reporting library used in the above code

    https://github.com/Koenkk/zigbee-herdsman-converters/blob/master/lib/reporting.js#L66

    You can see that this variable repInterval.HOUR is populated by default for Max interval.  However, there is a provision to use override and need to figure out how to use when in #1

        onOff: async (endpoint, overrides) => {
            const p = payload('onOff', 0, repInterval.HOUR, 0, overrides);
            await endpoint.configureReporting('genOnOff', p);

    So can I say that that Z2M is always invoking Client to Server Reporting request.  Hence, my DK code did not require the reporting configuration? 

    It should not be necessary to set the max interval to 0 in order to get reportable value change as far as I am aware.

    Well, Z2M allows the max interval to be changed from its UI as well. When I change Max and Min interval to 0, then it sends a configuration request to DK and then DK sends the reporting only on Change.

    Hopefully, if the override works fine than I need not configure any reporting on DK.  But yeah I am aware that reporting then would not work in other zigbee co-ordinator where such provision may not be there.

    Yes, I do have the dongle, will configure this as sniffer later today to capture the packets

  • Hi,

    Manju_rn said:
    So can I say that that Z2M is always invoking Client to Server Reporting request.  Hence, my DK code did not require the reporting configuration? 

    To configure attribute reporting only one of the devices, either the device reporting the attributes or the one receiving the attributes, need to send a Configure Reporting command. So if the coordinator configures it, then you do not need to do anything extra on the DK. The DK should start reporting the attribute automatically if the Configure Reporting command is successful and the attribute is reportable.

    Manju_rn said:
    Well, Z2M allows the max interval to be changed from its UI as well. When I change Max and Min interval to 0, then it sends a configuration request to DK and then DK sends the reporting only on Change.

    So it behaves as expected now? You are correct that setting max reporting interval to 0 will turn off periodic reporting, causing it to only report on attribute change if this is configured. If this is non-zero it will keep reporting periodically regardless of whether it also reports on attribute change.

    Manju_rn said:
    But yeah I am aware that reporting then would not work in other zigbee co-ordinator where such provision may not be there.

    You will always need one of the devices to configure the reporting anyways. If a device is expected to receive attribute reports from a certain device, then it makes sense that the receiving device is able to configure attribute reporting. All it needs to do is to create a binding for the cluster that should be reported by sending a bind request, and then send a configure reporting command.

    Best regards,

    Marte

  • The DK should start reporting the attribute automatically if the Configure Reporting command is successful and the attribute is reportable.

    Thanks. While the manual push (via Z2M UI) of the configure reporting from Z2M works (I still have not be able to do it automatically when DK joins the Z2M), I would still want to make it work from the DK.  I used the methods you mentioned in earlier post, but the reporting still is not working. Can you please let me know from where I should call this?

    Can you please indicate where should I call this? in the void zboss_signal_handler(zb_bufid_t bufid) for the case ZB_BDB_SIGNAL_STEERING: ?  Since I could not find anything like case like ZB_BDB_JOIN.

    my nrf dongle is broken, I think during one of the experimentation in another thread, so will have to check that on weekend to recover. So sniffer data will have to wait a bit longer

  • Here is the status. 

    1. I was not able to get the reporting configure from server to client (Dongle/DK to Z2M).

    2. I was able to get the reporting automatically configured  from Z2M to Dongle (without clicking anything on the Z2M). Hence there was no need to add any reporting configuration code in the dongle / DK

    So if somebody is working with Z2M and needs to have the reporting configured from client to server, they could utilize the below. The key point here is to use both reporting.bind  & endpoint.configureReporting calls in the .js file.  Not sure why the bind call is required, but without the bind the configure reporting call is not sent to Dongle/ DK from Z2M.   The bind is technically doing nothing as the endpoint specified can be open

    const fz = require('zigbee-herdsman-converters/converters/fromZigbee');
    const tz = require('zigbee-herdsman-converters/converters/toZigbee');
    const exposes = require('zigbee-herdsman-converters/lib/exposes');
    const reporting = require('zigbee-herdsman-converters/lib/reporting');
    const extend = require('zigbee-herdsman-converters/lib/extend');
    const e = exposes.presets;
    const ea = exposes.access;
    
    const definition = {
        zigbeeModel: ['DongleSwitch'], // The model ID from: Device with modelID 'lumi.sens' is not supported.
        model: '1.0', // Vendor model number, look on the device for a model number
        vendor: 'DongleNordic', // Vendor of the device (only used for documentation and startup logging)
        description: 'dongle_52840', // Description of the device, copy from vendor site. (only used for documentation and startup logging)
        fromZigbee: [fz.on_off],
        toZigbee: [tz.on_off],
        exposes: [e.switch()],
        configure: async (device, coordinatorEndpoint, logger) => {
           const endpoint = device.getEndpoint(12);
           await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
           const payload = [{
               attribute: 'onOff',
               minimumReportInterval: 0,
               maximumReportInterval: 0,
                reportableChange: 0,
               }];
           await endpoint.configureReporting('genOnOff', payload);
       },
    };

    I will spend sometime later to sniff the packets from Dongle / DK to Z2M when the server side reporting is configured and find out why this is not working. This will be required, since server (Dongle / DK) as end device are expected to contain all the functionality than depending upon coordinator / network to provide that functionality

Related