From e7147bda48396aaaa2c3269c19dfc5ae32c4360a Mon Sep 17 00:00:00 2001 From: Steve Karg Date: Sat, 15 Mar 2025 08:17:44 -0500 Subject: [PATCH] Fixed the COV for Analog Input and Analog Value objects when fault is detected in Reliability property. (#943) --- src/bacnet/basic/object/ai.c | 48 +++++++++++++++++++++++++++++++----- src/bacnet/basic/object/av.c | 48 +++++++++++++++++++++++++++++++----- 2 files changed, 84 insertions(+), 12 deletions(-) diff --git a/src/bacnet/basic/object/ai.c b/src/bacnet/basic/object/ai.c index 01238979..056de9e8 100644 --- a/src/bacnet/basic/object/ai.c +++ b/src/bacnet/basic/object/ai.c @@ -422,6 +422,24 @@ BACNET_RELIABILITY Analog_Input_Reliability(uint32_t object_instance) return value; } +/** + * @brief For a given object, gets the Fault status flag + * @param object_instance - object-instance number of the object + * @return true the status flag is in Fault + */ +static bool Analog_Input_Object_Fault(const struct analog_input_descr *pObject) +{ + bool fault = false; + + if (pObject) { + if (pObject->Reliability != RELIABILITY_NO_FAULT_DETECTED) { + fault = true; + } + } + + return fault; +} + /** * @brief For a given object instance-number, sets the reliability * @param object_instance - object-instance number of the object @@ -432,17 +450,36 @@ bool Analog_Input_Reliability_Set( uint32_t object_instance, BACNET_RELIABILITY value) { bool status = false; + bool fault = false; struct analog_input_descr *pObject; pObject = Analog_Input_Object(object_instance); if (pObject) { + fault = Analog_Input_Object_Fault(pObject); pObject->Reliability = value; + if (fault != Analog_Input_Object_Fault(pObject)) { + pObject->Changed = true; + } status = true; } return status; } +/** + * @brief For a given object instance-number, gets the Fault status flag + * @param object_instance - object-instance number of the object + * @return true the status flag is in Fault + */ +static bool Analog_Input_Fault(uint32_t object_instance) +{ + struct analog_input_descr *pObject; + + pObject = Analog_Input_Object(object_instance); + + return Analog_Input_Object_Fault(pObject); +} + /** * @brief For a given object instance-number, determines the COV status * @param object_instance - object-instance number of the object @@ -689,6 +726,7 @@ int Analog_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) BACNET_BIT_STRING bit_string; BACNET_CHARACTER_STRING char_string; float real_value = (float)1.414; + bool state = false; #if defined(INTRINSIC_REPORTING) int apdu_size = 0; #endif @@ -728,13 +766,11 @@ int Analog_Input_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) bitstring_set_bit( &bit_string, STATUS_FLAG_IN_ALARM, pObject->Event_State != EVENT_STATE_NORMAL); - bitstring_set_bit( - &bit_string, STATUS_FLAG_FAULT, - pObject->Reliability != RELIABILITY_NO_FAULT_DETECTED); + state = Analog_Input_Fault(rpdata->object_instance); + bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, state); bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); - bitstring_set_bit( - &bit_string, STATUS_FLAG_OUT_OF_SERVICE, - pObject->Out_Of_Service); + state = Analog_Input_Out_Of_Service(rpdata->object_instance); + bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, state); apdu_len = encode_application_bitstring(&apdu[0], &bit_string); break; case PROP_EVENT_STATE: diff --git a/src/bacnet/basic/object/av.c b/src/bacnet/basic/object/av.c index 74567d83..d54d4fb6 100644 --- a/src/bacnet/basic/object/av.c +++ b/src/bacnet/basic/object/av.c @@ -434,6 +434,24 @@ BACNET_RELIABILITY Analog_Value_Reliability(uint32_t object_instance) return value; } +/** + * @brief For a given object, gets the Fault status flag + * @param object_instance - object-instance number of the object + * @return true the status flag is in Fault + */ +static bool Analog_Value_Object_Fault(const struct analog_value_descr *pObject) +{ + bool fault = false; + + if (pObject) { + if (pObject->Reliability != RELIABILITY_NO_FAULT_DETECTED) { + fault = true; + } + } + + return fault; +} + /** * @brief For a given object instance-number, sets the reliability * @param object_instance - object-instance number of the object @@ -444,17 +462,36 @@ bool Analog_Value_Reliability_Set( uint32_t object_instance, BACNET_RELIABILITY value) { bool status = false; + bool fault = false; struct analog_value_descr *pObject; pObject = Analog_Value_Object(object_instance); if (pObject) { + fault = Analog_Value_Object_Fault(pObject); pObject->Reliability = value; + if (fault != Analog_Value_Object_Fault(pObject)) { + pObject->Changed = true; + } status = true; } return status; } +/** + * @brief For a given object instance-number, gets the Fault status flag + * @param object_instance - object-instance number of the object + * @return true the status flag is in Fault + */ +static bool Analog_Value_Fault(uint32_t object_instance) +{ + struct analog_value_descr *pObject; + + pObject = Analog_Value_Object(object_instance); + + return Analog_Value_Object_Fault(pObject); +} + /** * @brief For a given object instance-number, determines the COV status * @param object_instance - object-instance number of the object @@ -702,6 +739,7 @@ int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) float real_value = (float)1.414; uint8_t *apdu = NULL; ANALOG_VALUE_DESCR *CurrentAV; + bool state = false; #if defined(INTRINSIC_REPORTING) int apdu_size = 0; #endif @@ -748,13 +786,11 @@ int Analog_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata) bitstring_set_bit( &bit_string, STATUS_FLAG_IN_ALARM, (CurrentAV->Event_State != EVENT_STATE_NORMAL)); - bitstring_set_bit( - &bit_string, STATUS_FLAG_FAULT, - (CurrentAV->Reliability != RELIABILITY_NO_FAULT_DETECTED)); + state = Analog_Value_Fault(rpdata->object_instance); + bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, state); bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false); - bitstring_set_bit( - &bit_string, STATUS_FLAG_OUT_OF_SERVICE, - CurrentAV->Out_Of_Service); + state = Analog_Value_Out_Of_Service(rpdata->object_instance); + bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE, state); apdu_len = encode_application_bitstring(&apdu[0], &bit_string); break; case PROP_EVENT_STATE: