Got manufacturer data to show as "b-parasite" in zigbee2mqtt

This commit is contained in:
rbaron 2022-12-04 14:30:54 +01:00
parent f05d1f8e3b
commit f090b25a2c
2 changed files with 152 additions and 138 deletions

View file

@ -19,7 +19,7 @@ CONFIG_MAIN_THREAD_PRIORITY=7
CONFIG_ZIGBEE=y CONFIG_ZIGBEE=y
CONFIG_ZIGBEE_APP_UTILS=y CONFIG_ZIGBEE_APP_UTILS=y
CONFIG_ZIGBEE_ROLE_ROUTER=y CONFIG_ZIGBEE_ROLE_END_DEVICE=y
# Enable DK LED and Buttons library # Enable DK LED and Buttons library
CONFIG_DK_LIBRARY=y CONFIG_DK_LIBRARY=y

View file

@ -9,36 +9,41 @@
* @brief Zigbee application template. * @brief Zigbee application template.
*/ */
#include <dk_buttons_and_leds.h>
#include <zb_nrf_platform.h>
#include <zboss_api.h>
#include <zboss_api_addons.h>
#include <zephyr/kernel.h> #include <zephyr/kernel.h>
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
#include <dk_buttons_and_leds.h>
#include <zboss_api.h>
#include <zigbee/zigbee_error_handler.h>
#include <zigbee/zigbee_app_utils.h> #include <zigbee/zigbee_app_utils.h>
#include <zb_nrf_platform.h> #include <zigbee/zigbee_error_handler.h>
#include "zb_range_extender.h" #include "zb_range_extender.h"
/* Device endpoint, used to receive ZCL commands. */ /* Device endpoint, used to receive ZCL commands. */
#define APP_TEMPLATE_ENDPOINT 10 #define APP_TEMPLATE_ENDPOINT 10
/* Type of power sources available for the device. /* Type of power sources available for the device.
* For possible values see section 3.2.2.2.8 of ZCL specification. * For possible values see section 3.2.2.2.8 of ZCL specification.
*/ */
#define TEMPLATE_INIT_BASIC_POWER_SOURCE ZB_ZCL_BASIC_POWER_SOURCE_DC_SOURCE // #define TEMPLATE_INIT_BASIC_POWER_SOURCE ZB_ZCL_BASIC_POWER_SOURCE_DC_SOURCE
#define TEMPLATE_INIT_BASIC_POWER_SOURCE ZB_ZCL_BASIC_POWER_SOURCE_BATTERY
/* LED indicating that device successfully joined Zigbee network. */ /* LED indicating that device successfully joined Zigbee network. */
#define ZIGBEE_NETWORK_STATE_LED DK_LED3 #define ZIGBEE_NETWORK_STATE_LED DK_LED3
/* LED used for device identification. */ /* LED used for device identification. */
#define IDENTIFY_LED DK_LED4 #define IDENTIFY_LED DK_LED4
/* Button used to enter the Identify mode. */ /* Button used to enter the Identify mode. */
#define IDENTIFY_MODE_BUTTON DK_BTN4_MSK #define IDENTIFY_MODE_BUTTON DK_BTN4_MSK
/* Button to start Factory Reset */ /* Button to start Factory Reset */
#define FACTORY_RESET_BUTTON IDENTIFY_MODE_BUTTON #define FACTORY_RESET_BUTTON IDENTIFY_MODE_BUTTON
#define PRST_BASIC_MANUF_NAME "b-parasite"
#define PRST_BASIC_MODEL_ID "b-parasite 1.2.0"
LOG_MODULE_REGISTER(app, LOG_LEVEL_INF); LOG_MODULE_REGISTER(app, LOG_LEVEL_INF);
@ -46,113 +51,126 @@ LOG_MODULE_REGISTER(app, LOG_LEVEL_INF);
* Stores all settings and static values. * Stores all settings and static values.
*/ */
struct zb_device_ctx { struct zb_device_ctx {
zb_zcl_basic_attrs_t basic_attr; zb_zcl_basic_attrs_ext_t basic_attr;
zb_zcl_identify_attrs_t identify_attr; zb_zcl_identify_attrs_t identify_attr;
}; };
/* Zigbee device application context storage. */ /* Zigbee device application context storage. */
static struct zb_device_ctx dev_ctx; static struct zb_device_ctx dev_ctx;
ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST( ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(
identify_attr_list, identify_attr_list,
&dev_ctx.identify_attr.identify_time); &dev_ctx.identify_attr.identify_time);
ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST( ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST_EXT(
basic_attr_list, basic_attr_list,
&dev_ctx.basic_attr.zcl_version, &dev_ctx.basic_attr.zcl_version,
&dev_ctx.basic_attr.power_source); &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);
ZB_DECLARE_RANGE_EXTENDER_CLUSTER_LIST( ZB_DECLARE_RANGE_EXTENDER_CLUSTER_LIST(
app_template_clusters, app_template_clusters,
basic_attr_list, basic_attr_list,
identify_attr_list); identify_attr_list);
ZB_DECLARE_RANGE_EXTENDER_EP( ZB_DECLARE_RANGE_EXTENDER_EP(
app_template_ep, app_template_ep,
APP_TEMPLATE_ENDPOINT, APP_TEMPLATE_ENDPOINT,
app_template_clusters); app_template_clusters);
ZBOSS_DECLARE_DEVICE_CTX_1_EP( ZBOSS_DECLARE_DEVICE_CTX_1_EP(
app_template_ctx, app_template_ctx,
app_template_ep); app_template_ep);
/**@brief Function for initializing all clusters attributes. */ /**@brief Function for initializing all clusters attributes. */
static void app_clusters_attr_init(void) static void app_clusters_attr_init(void) {
{ /* Basic cluster attributes data */
/* Basic cluster attributes data */ dev_ctx.basic_attr.zcl_version = ZB_ZCL_VERSION;
dev_ctx.basic_attr.zcl_version = ZB_ZCL_VERSION; dev_ctx.basic_attr.power_source = TEMPLATE_INIT_BASIC_POWER_SOURCE;
dev_ctx.basic_attr.power_source = TEMPLATE_INIT_BASIC_POWER_SOURCE; // dev_ctx.basic_attr.mf_name
ZB_ZCL_SET_STRING_VAL(
dev_ctx.basic_attr.mf_name,
PRST_BASIC_MANUF_NAME,
ZB_ZCL_STRING_CONST_SIZE(PRST_BASIC_MANUF_NAME));
/* Identify cluster attributes data. */ ZB_ZCL_SET_STRING_VAL(
dev_ctx.identify_attr.identify_time = dev_ctx.basic_attr.model_id,
ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE; PRST_BASIC_MODEL_ID,
ZB_ZCL_STRING_CONST_SIZE(PRST_BASIC_MODEL_ID));
/* Identify cluster attributes data. */
dev_ctx.identify_attr.identify_time =
ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE;
} }
/**@brief Function to toggle the identify LED /**@brief Function to toggle the identify LED
* *
* @param bufid Unused parameter, required by ZBOSS scheduler API. * @param bufid Unused parameter, required by ZBOSS scheduler API.
*/ */
static void toggle_identify_led(zb_bufid_t bufid) static void toggle_identify_led(zb_bufid_t bufid) {
{ static int blink_status;
static int blink_status;
dk_set_led(IDENTIFY_LED, (++blink_status) % 2); dk_set_led(IDENTIFY_LED, (++blink_status) % 2);
ZB_SCHEDULE_APP_ALARM(toggle_identify_led, bufid, ZB_MILLISECONDS_TO_BEACON_INTERVAL(100)); ZB_SCHEDULE_APP_ALARM(toggle_identify_led, bufid, ZB_MILLISECONDS_TO_BEACON_INTERVAL(100));
} }
/**@brief Function to handle identify notification events on the first endpoint. /**@brief Function to handle identify notification events on the first endpoint.
* *
* @param bufid Unused parameter, required by ZBOSS scheduler API. * @param bufid Unused parameter, required by ZBOSS scheduler API.
*/ */
static void identify_cb(zb_bufid_t bufid) static void identify_cb(zb_bufid_t bufid) {
{ zb_ret_t zb_err_code;
zb_ret_t zb_err_code;
if (bufid) { if (bufid) {
/* Schedule a self-scheduling function that will toggle the LED */ /* Schedule a self-scheduling function that will toggle the LED */
ZB_SCHEDULE_APP_CALLBACK(toggle_identify_led, bufid); ZB_SCHEDULE_APP_CALLBACK(toggle_identify_led, bufid);
} else { } else {
/* Cancel the toggling function alarm and turn off LED */ /* Cancel the toggling function alarm and turn off LED */
zb_err_code = ZB_SCHEDULE_APP_ALARM_CANCEL(toggle_identify_led, ZB_ALARM_ANY_PARAM); zb_err_code = ZB_SCHEDULE_APP_ALARM_CANCEL(toggle_identify_led, ZB_ALARM_ANY_PARAM);
ZVUNUSED(zb_err_code); ZVUNUSED(zb_err_code);
dk_set_led(IDENTIFY_LED, 0); dk_set_led(IDENTIFY_LED, 0);
} }
} }
/**@brief Starts identifying the device. /**@brief Starts identifying the device.
* *
* @param bufid Unused parameter, required by ZBOSS scheduler API. * @param bufid Unused parameter, required by ZBOSS scheduler API.
*/ */
static void start_identifying(zb_bufid_t bufid) static void start_identifying(zb_bufid_t bufid) {
{ ZVUNUSED(bufid);
ZVUNUSED(bufid);
if (ZB_JOINED()) { if (ZB_JOINED()) {
/* Check if endpoint is in identifying mode, /* Check if endpoint is in identifying mode,
* if not put desired endpoint in identifying mode. * if not put desired endpoint in identifying mode.
*/ */
if (dev_ctx.identify_attr.identify_time == if (dev_ctx.identify_attr.identify_time ==
ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE) { ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE) {
zb_ret_t zb_err_code = zb_bdb_finding_binding_target(
APP_TEMPLATE_ENDPOINT);
zb_ret_t zb_err_code = zb_bdb_finding_binding_target( if (zb_err_code == RET_OK) {
APP_TEMPLATE_ENDPOINT); LOG_INF("Enter identify mode");
} else if (zb_err_code == RET_INVALID_STATE) {
if (zb_err_code == RET_OK) { LOG_WRN("RET_INVALID_STATE - Cannot enter identify mode");
LOG_INF("Enter identify mode"); } else {
} else if (zb_err_code == RET_INVALID_STATE) { ZB_ERROR_CHECK(zb_err_code);
LOG_WRN("RET_INVALID_STATE - Cannot enter identify mode"); }
} else { } else {
ZB_ERROR_CHECK(zb_err_code); LOG_INF("Cancel identify mode");
} zb_bdb_finding_binding_target_cancel();
} else { }
LOG_INF("Cancel identify mode"); } else {
zb_bdb_finding_binding_target_cancel(); LOG_WRN("Device not in a network - cannot enter identify mode");
} }
} else {
LOG_WRN("Device not in a network - cannot enter identify mode");
}
} }
/**@brief Callback for button events. /**@brief Callback for button events.
@ -161,42 +179,40 @@ static void start_identifying(zb_bufid_t bufid)
* @param[in] has_changed Bitmask containing buttons * @param[in] has_changed Bitmask containing buttons
* that have changed their state. * that have changed their state.
*/ */
static void button_changed(uint32_t button_state, uint32_t has_changed) static void button_changed(uint32_t button_state, uint32_t has_changed) {
{ if (IDENTIFY_MODE_BUTTON & has_changed) {
if (IDENTIFY_MODE_BUTTON & has_changed) { if (IDENTIFY_MODE_BUTTON & button_state) {
if (IDENTIFY_MODE_BUTTON & button_state) { /* Button changed its state to pressed */
/* Button changed its state to pressed */ } else {
} else { /* Button changed its state to released */
/* Button changed its state to released */ if (was_factory_reset_done()) {
if (was_factory_reset_done()) { /* The long press was for Factory Reset */
/* The long press was for Factory Reset */ LOG_DBG("After Factory Reset - ignore button release");
LOG_DBG("After Factory Reset - ignore button release"); } else {
} else { /* Button released before Factory Reset */
/* Button released before Factory Reset */
/* Start identification mode */ /* Start identification mode */
ZB_SCHEDULE_APP_CALLBACK(start_identifying, 0); ZB_SCHEDULE_APP_CALLBACK(start_identifying, 0);
} }
} }
} }
check_factory_reset_button(button_state, has_changed); check_factory_reset_button(button_state, has_changed);
} }
/**@brief Function for initializing LEDs and Buttons. */ /**@brief Function for initializing LEDs and Buttons. */
static void configure_gpio(void) static void configure_gpio(void) {
{ int err;
int err;
err = dk_buttons_init(button_changed); err = dk_buttons_init(button_changed);
if (err) { if (err) {
LOG_ERR("Cannot init buttons (err: %d)", err); LOG_ERR("Cannot init buttons (err: %d)", err);
} }
err = dk_leds_init(); err = dk_leds_init();
if (err) { if (err) {
LOG_ERR("Cannot init LEDs (err: %d)", err); LOG_ERR("Cannot init LEDs (err: %d)", err);
} }
} }
/**@brief Zigbee stack event handler. /**@brief Zigbee stack event handler.
@ -204,42 +220,40 @@ static void configure_gpio(void)
* @param[in] bufid Reference to the Zigbee stack buffer * @param[in] bufid Reference to the Zigbee stack buffer
* used to pass signal. * used to pass signal.
*/ */
void zboss_signal_handler(zb_bufid_t bufid) void zboss_signal_handler(zb_bufid_t bufid) {
{ /* Update network status LED. */
/* Update network status LED. */ zigbee_led_status_update(bufid, ZIGBEE_NETWORK_STATE_LED);
zigbee_led_status_update(bufid, ZIGBEE_NETWORK_STATE_LED);
/* No application-specific behavior is required. /* No application-specific behavior is required.
* Call default signal handler. * Call default signal handler.
*/ */
ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid)); ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid));
/* All callbacks should either reuse or free passed buffers. /* All callbacks should either reuse or free passed buffers.
* If bufid == 0, the buffer is invalid (not passed). * If bufid == 0, the buffer is invalid (not passed).
*/ */
if (bufid) { if (bufid) {
zb_buf_free(bufid); zb_buf_free(bufid);
} }
} }
void main(void) void main(void) {
{ LOG_INF("Starting Zigbee application template example");
LOG_INF("Starting Zigbee application template example");
/* Initialize */ /* Initialize */
configure_gpio(); configure_gpio();
register_factory_reset_button(FACTORY_RESET_BUTTON); register_factory_reset_button(FACTORY_RESET_BUTTON);
/* Register device context (endpoints). */ /* Register device context (endpoints). */
ZB_AF_REGISTER_DEVICE_CTX(&app_template_ctx); ZB_AF_REGISTER_DEVICE_CTX(&app_template_ctx);
app_clusters_attr_init(); app_clusters_attr_init();
/* Register handlers to identify notifications */ /* Register handlers to identify notifications */
ZB_AF_SET_IDENTIFY_NOTIFICATION_HANDLER(APP_TEMPLATE_ENDPOINT, identify_cb); ZB_AF_SET_IDENTIFY_NOTIFICATION_HANDLER(APP_TEMPLATE_ENDPOINT, identify_cb);
/* Start Zigbee default thread */ /* Start Zigbee default thread */
zigbee_enable(); zigbee_enable();
LOG_INF("Zigbee application template started"); LOG_INF("Zigbee application template started");
} }