diff --git a/lib/zboss/include/zcl/zb_zcl_reporting.h b/lib/zboss/include/zcl/zb_zcl_reporting.h index 62015dfd..50e349bd 100644 --- a/lib/zboss/include/zcl/zb_zcl_reporting.h +++ b/lib/zboss/include/zcl/zb_zcl_reporting.h @@ -89,6 +89,8 @@ union zb_zcl_attr_var_u zb_uint32_t u32; zb_int32_t s32; zb_uint48_t u48; + zb_single_t single; + zb_64bit_data_t data64; /* DOUBLE, raw bytes: keeps the union 4-byte aligned */ zb_uint8_t data_buf[4]; zb_uint32_t data_buf_crc32; }; diff --git a/lib/zboss/src/zcl/zcl_common.c b/lib/zboss/src/zcl/zcl_common.c index c42e7ec4..1af6f6c2 100644 --- a/lib/zboss/src/zcl/zcl_common.c +++ b/lib/zboss/src/zcl/zcl_common.c @@ -421,6 +421,7 @@ zb_uint8_t* zb_zcl_put_value_to_packet(zb_uint8_t *cmd_ptr, zb_uint8_t attr_type case ZB_ZCL_ATTR_TYPE_S16: case ZB_ZCL_ATTR_TYPE_16BITMAP: case ZB_ZCL_ATTR_TYPE_16BIT_ENUM: + case ZB_ZCL_ATTR_TYPE_SEMI: ZB_ZCL_PACKET_PUT_DATA16(cmd_ptr, attr_value); break; @@ -509,6 +510,7 @@ zb_uint8_t* zb_zcl_put_value_to_packet(zb_uint8_t *cmd_ptr, zb_uint8_t attr_type case ZB_ZCL_ATTR_TYPE_64BITMAP: case ZB_ZCL_ATTR_TYPE_U64: case ZB_ZCL_ATTR_TYPE_S64: + case ZB_ZCL_ATTR_TYPE_DOUBLE: case ZB_ZCL_ATTR_TYPE_IEEE_ADDR: ZB_ZCL_PACKET_PUT_DATA64(cmd_ptr, attr_value); break; @@ -543,6 +545,7 @@ zb_uint8_t zb_zcl_get_analog_attribute_size(zb_uint8_t attr_type) case ZB_ZCL_ATTR_TYPE_U16: case ZB_ZCL_ATTR_TYPE_S16: + case ZB_ZCL_ATTR_TYPE_SEMI: ret = sizeof(zb_uint16_t); break; @@ -553,6 +556,7 @@ zb_uint8_t zb_zcl_get_analog_attribute_size(zb_uint8_t attr_type) case ZB_ZCL_ATTR_TYPE_U32: case ZB_ZCL_ATTR_TYPE_S32: + case ZB_ZCL_ATTR_TYPE_SINGLE: ret = sizeof(zb_uint32_t); break; @@ -563,6 +567,7 @@ zb_uint8_t zb_zcl_get_analog_attribute_size(zb_uint8_t attr_type) case ZB_ZCL_ATTR_TYPE_U64: case ZB_ZCL_ATTR_TYPE_S64: + case ZB_ZCL_ATTR_TYPE_DOUBLE: ret = sizeof(zb_uint64_t); break; @@ -595,6 +600,9 @@ zb_bool_t zb_zcl_is_analog_data_type(zb_uint8_t attr_type) case ZB_ZCL_ATTR_TYPE_S32: case ZB_ZCL_ATTR_TYPE_S48: case ZB_ZCL_ATTR_TYPE_S64: + case ZB_ZCL_ATTR_TYPE_SEMI: + case ZB_ZCL_ATTR_TYPE_SINGLE: + case ZB_ZCL_ATTR_TYPE_DOUBLE: case ZB_ZCL_ATTR_TYPE_UTC_TIME: ret = ZB_TRUE; break; @@ -824,6 +832,7 @@ void zb_zcl_fix_endian(zb_uint8_t *data_ptr, zb_uint8_t data_type) case ZB_ZCL_ATTR_TYPE_U16: case ZB_ZCL_ATTR_TYPE_S16: case ZB_ZCL_ATTR_TYPE_16BITMAP: + case ZB_ZCL_ATTR_TYPE_SEMI: ZB_HTOLE16(&int_vars.u16, data_ptr); ZB_MEMCPY(data_ptr, &int_vars.u16, sizeof(zb_uint16_t)); break; @@ -832,11 +841,13 @@ void zb_zcl_fix_endian(zb_uint8_t *data_ptr, zb_uint8_t data_type) case ZB_ZCL_ATTR_TYPE_U32: case ZB_ZCL_ATTR_TYPE_S32: case ZB_ZCL_ATTR_TYPE_32BITMAP: + case ZB_ZCL_ATTR_TYPE_SINGLE: ZB_HTOLE32(&int_vars.u32, data_ptr); ZB_MEMCPY(data_ptr, &int_vars.u32, sizeof(zb_uint32_t)); break; case ZB_ZCL_ATTR_TYPE_64BIT: + case ZB_ZCL_ATTR_TYPE_DOUBLE: case ZB_ZCL_ATTR_TYPE_IEEE_ADDR: ZB_HTOLE64(&int_vars.u64, data_ptr); ZB_MEMCPY(data_ptr, &int_vars.u64, sizeof(zb_ieee_addr_t)); diff --git a/lib/zboss/src/zcl/zcl_general_commands.c b/lib/zboss/src/zcl/zcl_general_commands.c index 682e9729..37ea332b 100644 --- a/lib/zboss/src/zcl/zcl_general_commands.c +++ b/lib/zboss/src/zcl/zcl_general_commands.c @@ -1242,6 +1242,15 @@ void zb_zcl_read_report_config_cmd_handler(zb_uint8_t param) case ZB_ZCL_ATTR_TYPE_S32: ZB_ZCL_PACKET_PUT_DATA32(resp_data, &attr_rep_info->u.send_info.delta.s32); /*Add signed 32-bit delta field*/ break; + case ZB_ZCL_ATTR_TYPE_SEMI: + ZB_ZCL_PACKET_PUT_DATA16(resp_data, &attr_rep_info->u.send_info.delta.u16); /*Add half float delta field, raw bits*/ + break; + case ZB_ZCL_ATTR_TYPE_SINGLE: + ZB_ZCL_PACKET_PUT_DATA32(resp_data, &attr_rep_info->u.send_info.delta.single); /*Add single float delta field*/ + break; + case ZB_ZCL_ATTR_TYPE_DOUBLE: + ZB_ZCL_PACKET_PUT_DATA64(resp_data, attr_rep_info->u.send_info.delta.data64); /*Add double float delta field*/ + break; case ZB_ZCL_ATTR_TYPE_U48: ZB_ZCL_PACKET_PUT_DATA48(resp_data, &attr_rep_info->u.send_info.delta.u48); /*Add 48-bit delta field*/ break; diff --git a/lib/zboss/src/zcl/zcl_reporting.c b/lib/zboss/src/zcl/zcl_reporting.c index fa55e364..d9c7cb58 100644 --- a/lib/zboss/src/zcl/zcl_reporting.c +++ b/lib/zboss/src/zcl/zcl_reporting.c @@ -1273,6 +1273,29 @@ void zb_zcl_save_reported_value(zb_zcl_reporting_info_t *rep_info, zb_zcl_attr_t break; } + case ZB_ZCL_ATTR_TYPE_SINGLE: + { + /* memcpy: attribute storage is not guaranteed to be float-aligned */ + ZB_MEMCPY(&rep_info->u.send_info.reported_value.single, attr_desc->data_p, sizeof(zb_single_t)); + TRACE_MSG(TRACE_ZCL3, "reported SINGLE [%hd %hd %hd %hd]", + (FMT__H_H_H_H, + rep_info->u.send_info.reported_value.data_buf[0], rep_info->u.send_info.reported_value.data_buf[1], + rep_info->u.send_info.reported_value.data_buf[2], rep_info->u.send_info.reported_value.data_buf[3])); + break; + } + + case ZB_ZCL_ATTR_TYPE_DOUBLE: + { + ZB_MEMCPY(rep_info->u.send_info.reported_value.data64, attr_desc->data_p, ZB_64BIT_SIZE); + TRACE_MSG(TRACE_ZCL3, "reported DOUBLE [%hd %hd %hd %hd %hd %hd %hd %hd]", + (FMT__H_H_H_H_H_H_H_H, + rep_info->u.send_info.reported_value.data64[0], rep_info->u.send_info.reported_value.data64[1], + rep_info->u.send_info.reported_value.data64[2], rep_info->u.send_info.reported_value.data64[3], + rep_info->u.send_info.reported_value.data64[4], rep_info->u.send_info.reported_value.data64[5], + rep_info->u.send_info.reported_value.data64[6], rep_info->u.send_info.reported_value.data64[7])); + break; + } + case ZB_ZCL_ATTR_TYPE_U48: { rep_info->u.send_info.reported_value.u48 = *(zb_uint48_t*)attr_desc->data_p; @@ -1416,6 +1439,43 @@ static zb_bool_t check_delta_value(zb_zcl_reporting_info_t *rep_info) break; } + case ZB_ZCL_ATTR_TYPE_SINGLE: + { + zb_single_t cur_value; + zb_single_t delta; + + ZB_MEMCPY(&cur_value, attr_desc->data_p, sizeof(zb_single_t)); + delta = ZB_ABS(cur_value - rep_info->u.send_info.reported_value.single); + + TRACE_MSG(TRACE_ZCL3, "reported SINGLE [%hd %hd %hd %hd]", + (FMT__H_H_H_H, + rep_info->u.send_info.reported_value.data_buf[0], rep_info->u.send_info.reported_value.data_buf[1], + rep_info->u.send_info.reported_value.data_buf[2], rep_info->u.send_info.reported_value.data_buf[3])); + ret = (delta >= rep_info->u.send_info.delta.single)?(RET_OK ):(RET_IGNORE ); + break; + } + + case ZB_ZCL_ATTR_TYPE_DOUBLE: + { + double cur_value; + double reported_value; + double min_delta; + double delta; + + ZB_MEMCPY(&cur_value, attr_desc->data_p, sizeof(double)); + ZB_MEMCPY(&reported_value, rep_info->u.send_info.reported_value.data64, sizeof(double)); + ZB_MEMCPY(&min_delta, rep_info->u.send_info.delta.data64, sizeof(double)); + delta = ZB_ABS(cur_value - reported_value); + + TRACE_MSG(TRACE_ZCL3, "reported DOUBLE [%hd %hd %hd %hd %hd %hd %hd %hd]", + (FMT__H_H_H_H_H_H_H_H, + rep_info->u.send_info.reported_value.data64[0], rep_info->u.send_info.reported_value.data64[1], + rep_info->u.send_info.reported_value.data64[2], rep_info->u.send_info.reported_value.data64[3], + rep_info->u.send_info.reported_value.data64[4], rep_info->u.send_info.reported_value.data64[5], + rep_info->u.send_info.reported_value.data64[6], rep_info->u.send_info.reported_value.data64[7])); + ret = (delta >= min_delta)?(RET_OK ):(RET_IGNORE ); + break; + } case ZB_ZCL_ATTR_TYPE_U48: {