From 15b1d9d2a8848f073a7b63f20ea05d4815f27124 Mon Sep 17 00:00:00 2001 From: rbaron Date: Mon, 5 Dec 2022 18:50:26 +0100 Subject: [PATCH] Batt, temp and humi show up (with reporting!) on HA with zigbee2mqtt :)) --- code/nrf-connect/samples/zigbee/b-parasite.js | 30 +++++++ code/nrf-connect/samples/zigbee/src/main.c | 85 ++++++++++++++++++- .../samples/zigbee/src/zb_range_extender.h | 44 ++++++++-- 3 files changed, 150 insertions(+), 9 deletions(-) create mode 100644 code/nrf-connect/samples/zigbee/b-parasite.js diff --git a/code/nrf-connect/samples/zigbee/b-parasite.js b/code/nrf-connect/samples/zigbee/b-parasite.js new file mode 100644 index 0000000..262e9a2 --- /dev/null +++ b/code/nrf-connect/samples/zigbee/b-parasite.js @@ -0,0 +1,30 @@ +// This is a zigbee2mqtt zigbee2mqtt.io converter for this sample. +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: ['b-parasite'], + model: 'b-parasite', + vendor: 'b-parasite', + description: 'IoT development board - Zigbee sample', + fromZigbee: [fz.temperature, fz.humidity, fz.battery], + toZigbee: [], + exposes: [e.temperature(), e.humidity(), e.battery()], + configure: async (device, coordinatorEndpoint, logger) => { + const endpoint = device.getEndpoint(10); + await reporting.bind( + endpoint, + coordinatorEndpoint, + ['genPowerCfg', 'msTemperatureMeasurement', 'msRelativeHumidity']); + await reporting.batteryPercentageRemaining(endpoint); + await reporting.temperature(endpoint); + await reporting.humidity(endpoint); + } +}; + +module.exports = definition; \ No newline at end of file diff --git a/code/nrf-connect/samples/zigbee/src/main.c b/code/nrf-connect/samples/zigbee/src/main.c index 65d6fe3..d6a210f 100644 --- a/code/nrf-connect/samples/zigbee/src/main.c +++ b/code/nrf-connect/samples/zigbee/src/main.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -56,8 +57,11 @@ LOG_MODULE_REGISTER(app, LOG_LEVEL_INF); struct zb_device_ctx { zb_zcl_basic_attrs_ext_t basic_attr; zb_zcl_identify_attrs_t identify_attr; + // In units of 0.01 C. zb_zcl_temp_measurement_attrs_t temp_measure_attrs; prst_rel_humidity_attrs_t rel_humidity_attrs; + // In units of 100 mV. + prst_batt_attrs_t batt_attrs; }; /* Zigbee device application context storage. */ @@ -93,12 +97,42 @@ ZB_ZCL_DECLARE_REL_HUMIDITY_MEASUREMENT_ATTRIB_LIST( &dev_ctx.rel_humidity_attrs.min_val, &dev_ctx.rel_humidity_attrs.max_val); +// ZB_ZCL_DECLARE_POWER_CONFIG_ATTRIB_LIST( +// batt_attr_list, +// &dev_ctx.batt_voltage, +// NULL, +// NULL, +// NULL, +// NULL, +// NULL); + +// https://devzone.nordicsemi.com/f/nordic-q-a/85315/zboss-declare-power-config-attribute-list-for-battery-bat_num +#define bat_num +ZB_ZCL_DECLARE_POWER_CONFIG_BATTERY_ATTRIB_LIST_EXT( + batt_attr_list, + &dev_ctx.batt_attrs.voltage, + /*battery_size=*/NULL, + /*battery_quantity=*/&dev_ctx.batt_attrs.quantity, + /*battery_rated_voltage=*/&dev_ctx.batt_attrs.size, + /*battery_alarm_mask=*/NULL, + /*battery_voltage_min_threshold=*/&dev_ctx.batt_attrs.voltage_min_thres, + /*battery_percentage_remaining=*/&dev_ctx.batt_attrs.percentage, + /*battery_voltage_threshold1=*/NULL, + /*battery_voltage_threshold2=*/NULL, + /*battery_voltage_threshold3=*/NULL, + /*battery_percentage_min_threshold=*/&dev_ctx.batt_attrs.percentage_min_thres, + /*battery_percentage_threshold1=*/NULL, + /*battery_percentage_threshold2=*/NULL, + /*battery_percentage_threshold3=*/NULL, + /*battery_alarm_state=*/NULL); + ZB_DECLARE_RANGE_EXTENDER_CLUSTER_LIST( app_template_clusters, basic_attr_list, identify_attr_list, temp_measurement_attr_list, - rel_humi_attr_list); + rel_humi_attr_list, + basic_attr_list); ZB_DECLARE_RANGE_EXTENDER_EP( app_template_ep, @@ -135,6 +169,21 @@ static void app_clusters_attr_init(void) { ZB_ZCL_CLUSTER_SERVER_ROLE, ZB_ZCL_ATTR_REL_HUMIDITY_MEASUREMENT_VALUE_ID, (zb_uint8_t*)&rel_humidity, ZB_FALSE); + static zb_uint8_t batt_voltage = 33; + zb_zcl_set_attr_val(APP_TEMPLATE_ENDPOINT, ZB_ZCL_CLUSTER_ID_POWER_CONFIG, + ZB_ZCL_CLUSTER_SERVER_ROLE, ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_VOLTAGE_ID, + (zb_uint8_t*)&batt_voltage, ZB_FALSE); + + static zb_uint8_t batt_percentage = 33; + zb_zcl_set_attr_val(APP_TEMPLATE_ENDPOINT, ZB_ZCL_CLUSTER_ID_POWER_CONFIG, + ZB_ZCL_CLUSTER_SERVER_ROLE, ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_PERCENTAGE_REMAINING_ID, + (zb_uint8_t*)&batt_percentage, ZB_FALSE); + + static zb_uint8_t batt_quantity = 31; + zb_zcl_set_attr_val(APP_TEMPLATE_ENDPOINT, ZB_ZCL_CLUSTER_ID_POWER_CONFIG, + ZB_ZCL_CLUSTER_SERVER_ROLE, ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_QUANTITY_ID, + (zb_uint8_t*)&batt_quantity, ZB_FALSE); + /* Identify cluster attributes data. */ dev_ctx.identify_attr.identify_time = ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE; @@ -266,6 +315,36 @@ void zboss_signal_handler(zb_bufid_t bufid) { } } +void update_sensors_cb(zb_uint8_t arg) { + static zb_uint8_t batt = 10; + batt += 1; + + LOG_INF("Updating sensonrs"); + zb_zcl_set_attr_val(APP_TEMPLATE_ENDPOINT, ZB_ZCL_CLUSTER_ID_POWER_CONFIG, + ZB_ZCL_CLUSTER_SERVER_ROLE, ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_VOLTAGE_ID, + (zb_uint8_t*)&batt, ZB_FALSE); + + static zb_uint8_t batt_percentage = 10; + batt_percentage += 1; + zb_zcl_set_attr_val(APP_TEMPLATE_ENDPOINT, ZB_ZCL_CLUSTER_ID_POWER_CONFIG, + ZB_ZCL_CLUSTER_SERVER_ROLE, ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_PERCENTAGE_REMAINING_ID, + (zb_uint8_t*)&batt_percentage, ZB_FALSE); + + static zb_int16_t temperature_value = 27; + temperature_value += 1; + zb_zcl_set_attr_val(APP_TEMPLATE_ENDPOINT, ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, + ZB_ZCL_CLUSTER_SERVER_ROLE, ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID, + (zb_uint8_t*)&temperature_value, ZB_FALSE); + + static zb_int16_t rel_humi = 12; + rel_humi += 1; + zb_zcl_set_attr_val(APP_TEMPLATE_ENDPOINT, ZB_ZCL_CLUSTER_ID_REL_HUMIDITY_MEASUREMENT, + ZB_ZCL_CLUSTER_SERVER_ROLE, ZB_ZCL_ATTR_REL_HUMIDITY_MEASUREMENT_VALUE_ID, + (zb_uint8_t*)&rel_humi, ZB_FALSE); + + ZB_SCHEDULE_APP_ALARM(update_sensors_cb, NULL, ZB_TIME_ONE_SECOND * 1); +} + void main(void) { LOG_INF("Starting Zigbee application template example"); @@ -281,10 +360,14 @@ void main(void) { /* Register handlers to identify notifications */ ZB_AF_SET_IDENTIFY_NOTIFICATION_HANDLER(APP_TEMPLATE_ENDPOINT, identify_cb); + update_sensors_cb(/*arg=*/0); + zb_bdb_set_legacy_device_support(1); /* Start Zigbee default thread */ zigbee_enable(); zb_bdb_set_legacy_device_support(1); + // zigbee_configure_sleepy_behavior(/*enable=*/true); + LOG_INF("Zigbee application template started"); } diff --git a/code/nrf-connect/samples/zigbee/src/zb_range_extender.h b/code/nrf-connect/samples/zigbee/src/zb_range_extender.h index 6ebf33e..728a7fa 100644 --- a/code/nrf-connect/samples/zigbee/src/zb_range_extender.h +++ b/code/nrf-connect/samples/zigbee/src/zb_range_extender.h @@ -24,7 +24,7 @@ /** @cond internals_doc */ /** Range extender IN (server) clusters number */ -#define ZB_RANGE_EXTENDER_IN_CLUSTER_NUM 4 +#define ZB_RANGE_EXTENDER_IN_CLUSTER_NUM 5 /** Range extender OUT (client) clusters number */ #define ZB_RANGE_EXTENDER_OUT_CLUSTER_NUM 0 @@ -33,7 +33,7 @@ (ZB_RANGE_EXTENDER_IN_CLUSTER_NUM + ZB_RANGE_EXTENDER_OUT_CLUSTER_NUM) /** Number of attribute for reporting on Range extender device */ -#define ZB_RANGE_EXTENDER_REPORT_ATTR_COUNT 0 +#define ZB_RANGE_EXTENDER_REPORT_ATTR_COUNT 3 typedef struct { zb_uint16_t rel_humidity; @@ -41,12 +41,30 @@ typedef struct { zb_uint16_t max_val; } prst_rel_humidity_attrs_t; +// Power configuration cluster - section 3.3. +typedef struct { + zb_uint8_t voltage; + zb_uint8_t percentage; + zb_uint8_t quantity; + zb_uint8_t size; + zb_uint8_t rated_voltage; + zb_uint8_t voltage_min_thres; + zb_uint8_t percentage_min_thres; +} prst_batt_attrs_t; +// ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_VOLTAGE_ID(voltage, ), \ + // ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_SIZE_ID(size, ), \ + // ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_QUANTITY_ID(quantity, ), \ + // ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_RATED_VOLTAGE_ID(rated_voltage, ), \ + // ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_ALARM_MASK_ID(alarm_mask, ), \ + // ZB_SET_ATTR_DESCR_WITH_ZB_ZCL_ATTR_POWER_CONFIG_BATTERY_VOLTAGE_MIN_THRESHOLD_ID(voltage_min_threshold, ), \ + #define ZB_DECLARE_RANGE_EXTENDER_CLUSTER_LIST( \ cluster_list_name, \ basic_attr_list, \ identify_attr_list, \ temp_measurement_attr_list, \ - rel_humidity_attr_list) \ + rel_humidity_attr_list, \ + batt_att_list) \ zb_zcl_cluster_desc_t cluster_list_name[] = \ { \ ZB_ZCL_CLUSTER_DESC( \ @@ -72,6 +90,12 @@ typedef struct { ZB_ZCL_ARRAY_SIZE(rel_humidity_attr_list, zb_zcl_attr_t), \ (rel_humi_attr_list), \ ZB_ZCL_CLUSTER_SERVER_ROLE, \ + ZB_ZCL_MANUF_CODE_INVALID), \ + ZB_ZCL_CLUSTER_DESC( \ + ZB_ZCL_CLUSTER_ID_POWER_CONFIG, \ + ZB_ZCL_ARRAY_SIZE(batt_attr_list, zb_zcl_attr_t), \ + (batt_attr_list), \ + ZB_ZCL_CLUSTER_SERVER_ROLE, \ ZB_ZCL_MANUF_CODE_INVALID)} /** @cond internals_doc */ @@ -95,10 +119,13 @@ typedef struct { 0, \ in_clust_num, \ out_clust_num, \ - {ZB_ZCL_CLUSTER_ID_BASIC, \ - ZB_ZCL_CLUSTER_ID_IDENTIFY, \ - ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, \ - ZB_ZCL_CLUSTER_ID_REL_HUMIDITY_MEASUREMENT}} + { \ + ZB_ZCL_CLUSTER_ID_BASIC, \ + ZB_ZCL_CLUSTER_ID_IDENTIFY, \ + ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, \ + ZB_ZCL_CLUSTER_ID_REL_HUMIDITY_MEASUREMENT, \ + ZB_ZCL_CLUSTER_ID_POWER_CONFIG, \ + }} /** @endcond */ /* internals_doc */ @@ -109,12 +136,13 @@ typedef struct { * @param cluster_list - endpoint cluster list */ #define ZB_DECLARE_RANGE_EXTENDER_EP(ep_name, ep_id, cluster_list) \ + ZBOSS_DEVICE_DECLARE_REPORTING_CTX(reporting_ctx_##ep_name, ZB_RANGE_EXTENDER_REPORT_ATTR_COUNT); \ ZB_ZCL_DECLARE_RANGE_EXTENDER_SIMPLE_DESC(ep_name, ep_id, \ ZB_RANGE_EXTENDER_IN_CLUSTER_NUM, ZB_RANGE_EXTENDER_OUT_CLUSTER_NUM); \ ZB_AF_DECLARE_ENDPOINT_DESC(ep_name, ep_id, ZB_AF_HA_PROFILE_ID, 0, NULL, \ ZB_ZCL_ARRAY_SIZE(cluster_list, zb_zcl_cluster_desc_t), cluster_list, \ (zb_af_simple_desc_1_1_t *)&simple_desc_##ep_name, \ - 0, NULL, /* No reporting ctx */ \ + ZB_RANGE_EXTENDER_REPORT_ATTR_COUNT, reporting_ctx_##ep_name, \ 0, NULL) /* No CVC ctx */ /*! @} */