From 921264b2c27cb435bfd222c0c03d06103275c1e1 Mon Sep 17 00:00:00 2001 From: dmitttri Date: Tue, 1 Apr 2025 15:56:20 +0200 Subject: [PATCH] Added write present value callbacks for Analog Value and Integer Value basic object examples. (#956) --- src/bacnet/basic/object/av.c | 36 ++++++++++++++++++++++++++++++------ src/bacnet/basic/object/av.h | 13 +++++++++++++ src/bacnet/basic/object/iv.c | 21 +++++++++++++++++++++ src/bacnet/basic/object/iv.h | 13 +++++++++++++ 4 files changed, 77 insertions(+), 6 deletions(-) diff --git a/src/bacnet/basic/object/av.c b/src/bacnet/basic/object/av.c index d54d4fb6..4371405b 100644 --- a/src/bacnet/basic/object/av.c +++ b/src/bacnet/basic/object/av.c @@ -32,6 +32,9 @@ static OS_Keylist Object_List; /* common object type */ static const BACNET_OBJECT_TYPE Object_Type = OBJECT_ANALOG_VALUE; +/* callback for present value writes */ +static analog_value_write_present_value_callback + Analog_Value_Write_Present_Value_Callback; /* clang-format off */ /* These three arrays are used by the ReadPropertyMultiple handler */ @@ -922,6 +925,7 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) { bool status = false; /* return value */ int len = 0; + float old_value = 0.0f; BACNET_APPLICATION_DATA_VALUE value = { 0 }; ANALOG_VALUE_DESCR *CurrentAV; @@ -962,13 +966,23 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) object. */ wp_data->error_class = ERROR_CLASS_PROPERTY; wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED; - } else if (Analog_Value_Present_Value_Set( - wp_data->object_instance, value.type.Real, - wp_data->priority)) { - status = true; } else { - wp_data->error_class = ERROR_CLASS_PROPERTY; - wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + old_value = + Analog_Value_Present_Value(wp_data->object_instance); + if (Analog_Value_Present_Value_Set( + wp_data->object_instance, value.type.Real, + wp_data->priority)) { + status = true; + if (Analog_Value_Write_Present_Value_Callback) { + Analog_Value_Write_Present_Value_Callback( + wp_data->object_instance, old_value, + Analog_Value_Present_Value( + wp_data->object_instance)); + } + } else { + wp_data->error_class = ERROR_CLASS_PROPERTY; + wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE; + } } } break; @@ -1101,6 +1115,16 @@ bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) return status; } +/** + * @brief Sets a callback used when present-value is written from BACnet + * @param cb - callback used to provide indications + */ +void Analog_Value_Write_Present_Value_Callback_Set( + analog_value_write_present_value_callback cb) +{ + Analog_Value_Write_Present_Value_Callback = cb; +} + /** * @brief Analog Value intrinsic reporting function. * @param object_instance [in] BACnet object-instance number of the object diff --git a/src/bacnet/basic/object/av.h b/src/bacnet/basic/object/av.h index 67ea2b96..20f3cf06 100644 --- a/src/bacnet/basic/object/av.h +++ b/src/bacnet/basic/object/av.h @@ -55,6 +55,15 @@ typedef struct analog_value_descr { #endif } ANALOG_VALUE_DESCR; +/** + * @brief Callback for gateway write present value request + * @param object_instance - object-instance number of the object + * @param old_value - floating point analog value prior to write + * @param value - floating point analog value of the write + */ +typedef void (*analog_value_write_present_value_callback)( + uint32_t object_instance, float old_value, float value); + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -84,6 +93,10 @@ int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata); BACNET_STACK_EXPORT bool Analog_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data); +BACNET_STACK_EXPORT +void Analog_Value_Write_Present_Value_Callback_Set( + analog_value_write_present_value_callback cb); + BACNET_STACK_EXPORT bool Analog_Value_Present_Value_Set( uint32_t object_instance, float value, uint8_t priority); diff --git a/src/bacnet/basic/object/iv.c b/src/bacnet/basic/object/iv.c index 47ed6a57..b1e79ded 100644 --- a/src/bacnet/basic/object/iv.c +++ b/src/bacnet/basic/object/iv.c @@ -32,6 +32,9 @@ static OS_Keylist Object_List = NULL; /* common object type */ static const BACNET_OBJECT_TYPE Object_Type = OBJECT_INTEGER_VALUE; +/* callback for present value writes */ +static integer_value_write_present_value_callback + Integer_Value_Write_Present_Value_Callback; struct integer_object { bool Out_Of_Service : 1; @@ -537,6 +540,7 @@ bool Integer_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) { bool status = false; /* return value */ int len = 0; + int32_t old_value = 0; BACNET_APPLICATION_DATA_VALUE value = { 0 }; /* decode the some of the request */ @@ -554,9 +558,16 @@ bool Integer_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) status = write_property_type_valid( wp_data, &value, BACNET_APPLICATION_TAG_SIGNED_INT); if (status) { + old_value = + Integer_Value_Present_Value(wp_data->object_instance); Integer_Value_Present_Value_Set( wp_data->object_instance, value.type.Signed_Int, wp_data->priority); + if (Integer_Value_Write_Present_Value_Callback) { + Integer_Value_Write_Present_Value_Callback( + wp_data->object_instance, old_value, + Integer_Value_Present_Value(wp_data->object_instance)); + } } break; case PROP_COV_INCREMENT: @@ -593,6 +604,16 @@ bool Integer_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data) return status; } +/** + * @brief Sets a callback used when present-value is written from BACnet + * @param cb - callback used to provide indications + */ +void Integer_Value_Write_Present_Value_Callback_Set( + integer_value_write_present_value_callback cb) +{ + Integer_Value_Write_Present_Value_Callback = cb; +} + /** * @brief For a given object instance-number, determines the COV status * @param object_instance - object-instance number of the object diff --git a/src/bacnet/basic/object/iv.h b/src/bacnet/basic/object/iv.h index e3f94710..918a533b 100644 --- a/src/bacnet/basic/object/iv.h +++ b/src/bacnet/basic/object/iv.h @@ -20,6 +20,15 @@ extern "C" { #endif /* __cplusplus */ +/** + * @brief Callback for gateway write present value request + * @param object_instance - object-instance number of the object + * @param old_value - integer preset-value prior to write + * @param value - integer preset-value of the write + */ +typedef void (*integer_value_write_present_value_callback)( + uint32_t object_instance, int32_t old_value, int32_t value); + BACNET_STACK_EXPORT void Integer_Value_Property_Lists( const int **pRequired, const int **pOptional, const int **pProprietary); @@ -46,6 +55,10 @@ int Integer_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata); BACNET_STACK_EXPORT bool Integer_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data); +BACNET_STACK_EXPORT +void Integer_Value_Write_Present_Value_Callback_Set( + integer_value_write_present_value_callback cb); + BACNET_STACK_EXPORT bool Integer_Value_Present_Value_Set( uint32_t object_instance, int32_t value, uint8_t priority);