Added COV example to Analog Value object.
This commit is contained in:
@@ -63,6 +63,7 @@ static const int Analog_Value_Properties_Required[] = {
|
|||||||
|
|
||||||
static const int Analog_Value_Properties_Optional[] = {
|
static const int Analog_Value_Properties_Optional[] = {
|
||||||
PROP_DESCRIPTION,
|
PROP_DESCRIPTION,
|
||||||
|
PROP_COV_INCREMENT,
|
||||||
#if defined(INTRINSIC_REPORTING)
|
#if defined(INTRINSIC_REPORTING)
|
||||||
PROP_TIME_DELAY,
|
PROP_TIME_DELAY,
|
||||||
PROP_NOTIFICATION_CLASS,
|
PROP_NOTIFICATION_CLASS,
|
||||||
@@ -109,6 +110,9 @@ void Analog_Value_Init(
|
|||||||
memset(&AV_Descr[i], 0x00, sizeof(ANALOG_VALUE_DESCR));
|
memset(&AV_Descr[i], 0x00, sizeof(ANALOG_VALUE_DESCR));
|
||||||
AV_Descr[i].Present_Value = 0.0;
|
AV_Descr[i].Present_Value = 0.0;
|
||||||
AV_Descr[i].Units = UNITS_NO_UNITS;
|
AV_Descr[i].Units = UNITS_NO_UNITS;
|
||||||
|
AV_Descr[i].Prior_Value = 0.0f;
|
||||||
|
AV_Descr[i].COV_Increment = 1.0f;
|
||||||
|
AV_Descr[i].Changed = false;
|
||||||
#if defined(INTRINSIC_REPORTING)
|
#if defined(INTRINSIC_REPORTING)
|
||||||
AV_Descr[i].Event_State = EVENT_STATE_NORMAL;
|
AV_Descr[i].Event_State = EVENT_STATE_NORMAL;
|
||||||
/* notification class not connected */
|
/* notification class not connected */
|
||||||
@@ -175,6 +179,28 @@ unsigned Analog_Value_Instance_To_Index(
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Analog_Value_COV_Detect(unsigned int index,
|
||||||
|
float value)
|
||||||
|
{
|
||||||
|
float prior_value = 0.0;
|
||||||
|
float cov_increment = 0.0;
|
||||||
|
float cov_delta = 0.0;
|
||||||
|
|
||||||
|
if (index < MAX_ANALOG_VALUES) {
|
||||||
|
prior_value = AV_Descr[index].Prior_Value;
|
||||||
|
cov_increment = AV_Descr[index].COV_Increment;
|
||||||
|
if (prior_value > value) {
|
||||||
|
cov_delta = prior_value - value;
|
||||||
|
} else {
|
||||||
|
cov_delta = value - prior_value;
|
||||||
|
}
|
||||||
|
if (cov_delta >= cov_increment) {
|
||||||
|
AV_Descr[index].Changed = true;
|
||||||
|
AV_Descr[index].Prior_Value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For a given object instance-number, sets the present-value at a given
|
* For a given object instance-number, sets the present-value at a given
|
||||||
* priority 1..16.
|
* priority 1..16.
|
||||||
@@ -195,6 +221,7 @@ bool Analog_Value_Present_Value_Set(
|
|||||||
|
|
||||||
index = Analog_Value_Instance_To_Index(object_instance);
|
index = Analog_Value_Instance_To_Index(object_instance);
|
||||||
if (index < MAX_ANALOG_VALUES) {
|
if (index < MAX_ANALOG_VALUES) {
|
||||||
|
Analog_Value_COV_Detect(index, value);
|
||||||
AV_Descr[index].Present_Value = value;
|
AV_Descr[index].Present_Value = value;
|
||||||
status = true;
|
status = true;
|
||||||
}
|
}
|
||||||
@@ -232,6 +259,151 @@ bool Analog_Value_Object_Name(
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For a given object instance-number, determines if the COV flag
|
||||||
|
* has been triggered.
|
||||||
|
*
|
||||||
|
* @param object_instance - object-instance number of the object
|
||||||
|
*
|
||||||
|
* @return true if the COV flag is set
|
||||||
|
*/
|
||||||
|
bool Analog_Value_Change_Of_Value(uint32_t object_instance)
|
||||||
|
{
|
||||||
|
unsigned index = 0;
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
index = Analog_Value_Instance_To_Index(object_instance);
|
||||||
|
if (index < MAX_ANALOG_VALUES) {
|
||||||
|
changed = AV_Descr[index].Changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For a given object instance-number, clears the COV flag
|
||||||
|
*
|
||||||
|
* @param object_instance - object-instance number of the object
|
||||||
|
*/
|
||||||
|
void Analog_Value_Change_Of_Value_Clear(uint32_t object_instance)
|
||||||
|
{
|
||||||
|
unsigned index = 0;
|
||||||
|
|
||||||
|
index = Analog_Value_Instance_To_Index(object_instance);
|
||||||
|
if (index < MAX_ANALOG_VALUES) {
|
||||||
|
AV_Descr[index].Changed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For a given object instance-number, loads the value_list with the COV data.
|
||||||
|
*
|
||||||
|
* @param object_instance - object-instance number of the object
|
||||||
|
* @param value_list - list of COV data
|
||||||
|
*
|
||||||
|
* @return true if the value list is encoded
|
||||||
|
*/
|
||||||
|
bool Analog_Value_Encode_Value_List(
|
||||||
|
uint32_t object_instance,
|
||||||
|
BACNET_PROPERTY_VALUE * value_list)
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
|
||||||
|
if (value_list) {
|
||||||
|
value_list->propertyIdentifier = PROP_PRESENT_VALUE;
|
||||||
|
value_list->propertyArrayIndex = BACNET_ARRAY_ALL;
|
||||||
|
value_list->value.context_specific = false;
|
||||||
|
value_list->value.tag = BACNET_APPLICATION_TAG_REAL;
|
||||||
|
value_list->value.type.Real =
|
||||||
|
Analog_Value_Present_Value(object_instance);
|
||||||
|
value_list->value.next = NULL;
|
||||||
|
value_list->priority = BACNET_NO_PRIORITY;
|
||||||
|
value_list = value_list->next;
|
||||||
|
}
|
||||||
|
if (value_list) {
|
||||||
|
value_list->propertyIdentifier = PROP_STATUS_FLAGS;
|
||||||
|
value_list->propertyArrayIndex = BACNET_ARRAY_ALL;
|
||||||
|
value_list->value.context_specific = false;
|
||||||
|
value_list->value.tag = BACNET_APPLICATION_TAG_BIT_STRING;
|
||||||
|
bitstring_init(&value_list->value.type.Bit_String);
|
||||||
|
bitstring_set_bit(&value_list->value.type.Bit_String,
|
||||||
|
STATUS_FLAG_IN_ALARM, false);
|
||||||
|
bitstring_set_bit(&value_list->value.type.Bit_String,
|
||||||
|
STATUS_FLAG_FAULT, false);
|
||||||
|
bitstring_set_bit(&value_list->value.type.Bit_String,
|
||||||
|
STATUS_FLAG_OVERRIDDEN, false);
|
||||||
|
if (Analog_Value_Out_Of_Service(object_instance)) {
|
||||||
|
bitstring_set_bit(&value_list->value.type.Bit_String,
|
||||||
|
STATUS_FLAG_OUT_OF_SERVICE, true);
|
||||||
|
} else {
|
||||||
|
bitstring_set_bit(&value_list->value.type.Bit_String,
|
||||||
|
STATUS_FLAG_OUT_OF_SERVICE, false);
|
||||||
|
}
|
||||||
|
value_list->value.next = NULL;
|
||||||
|
value_list->priority = BACNET_NO_PRIORITY;
|
||||||
|
value_list->next = NULL;
|
||||||
|
status = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Analog_Value_COV_Increment(
|
||||||
|
uint32_t object_instance)
|
||||||
|
{
|
||||||
|
unsigned index = 0;
|
||||||
|
float value = 0;
|
||||||
|
|
||||||
|
index = Analog_Value_Instance_To_Index(object_instance);
|
||||||
|
if (index < MAX_ANALOG_VALUES) {
|
||||||
|
value = AV_Descr[index].COV_Increment;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Analog_Value_COV_Increment_Set(
|
||||||
|
uint32_t object_instance,
|
||||||
|
float value)
|
||||||
|
{
|
||||||
|
unsigned index = 0;
|
||||||
|
|
||||||
|
index = Analog_Value_Instance_To_Index(object_instance);
|
||||||
|
if (index < MAX_ANALOG_VALUES) {
|
||||||
|
AV_Descr[index].COV_Increment = value;
|
||||||
|
Analog_Value_COV_Detect(index, AV_Descr[index].Present_Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Analog_Value_Out_Of_Service(
|
||||||
|
uint32_t object_instance)
|
||||||
|
{
|
||||||
|
unsigned index = 0;
|
||||||
|
bool value = false;
|
||||||
|
|
||||||
|
index = Analog_Value_Instance_To_Index(object_instance);
|
||||||
|
if (index < MAX_ANALOG_VALUES) {
|
||||||
|
value = AV_Descr[index].Out_Of_Service;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Analog_Value_Out_Of_Service_Set(
|
||||||
|
uint32_t object_instance,
|
||||||
|
bool value)
|
||||||
|
{
|
||||||
|
unsigned index = 0;
|
||||||
|
|
||||||
|
index = Analog_Value_Instance_To_Index(object_instance);
|
||||||
|
if (index < MAX_ANALOG_VALUES) {
|
||||||
|
if (AV_Descr[index].Out_Of_Service != value) {
|
||||||
|
AV_Descr[index].Changed = true;
|
||||||
|
}
|
||||||
|
AV_Descr[index].Out_Of_Service = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* return apdu len, or BACNET_STATUS_ERROR on error */
|
/* return apdu len, or BACNET_STATUS_ERROR on error */
|
||||||
int Analog_Value_Read_Property(
|
int Analog_Value_Read_Property(
|
||||||
BACNET_READ_PROPERTY_DATA * rpdata)
|
BACNET_READ_PROPERTY_DATA * rpdata)
|
||||||
@@ -323,6 +495,11 @@ int Analog_Value_Read_Property(
|
|||||||
encode_application_enumerated(&apdu[0], CurrentAV->Units);
|
encode_application_enumerated(&apdu[0], CurrentAV->Units);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_COV_INCREMENT:
|
||||||
|
apdu_len = encode_application_real(&apdu[0],
|
||||||
|
CurrentAV->COV_Increment);
|
||||||
|
break;
|
||||||
|
|
||||||
#if defined(INTRINSIC_REPORTING)
|
#if defined(INTRINSIC_REPORTING)
|
||||||
case PROP_TIME_DELAY:
|
case PROP_TIME_DELAY:
|
||||||
apdu_len =
|
apdu_len =
|
||||||
@@ -543,6 +720,23 @@ bool Analog_Value_Write_Property(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PROP_COV_INCREMENT:
|
||||||
|
status =
|
||||||
|
WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
|
||||||
|
&wp_data->error_class, &wp_data->error_code);
|
||||||
|
if (status) {
|
||||||
|
if (value.type.Real >= 0.0) {
|
||||||
|
Analog_Value_COV_Increment_Set(
|
||||||
|
wp_data->object_instance,
|
||||||
|
value.type.Real);
|
||||||
|
} else {
|
||||||
|
status = false;
|
||||||
|
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||||
|
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
#if defined(INTRINSIC_REPORTING)
|
#if defined(INTRINSIC_REPORTING)
|
||||||
case PROP_TIME_DELAY:
|
case PROP_TIME_DELAY:
|
||||||
status =
|
status =
|
||||||
|
|||||||
@@ -48,6 +48,9 @@ extern "C" {
|
|||||||
bool Out_Of_Service;
|
bool Out_Of_Service;
|
||||||
uint16_t Units;
|
uint16_t Units;
|
||||||
float Present_Value;
|
float Present_Value;
|
||||||
|
float Prior_Value;
|
||||||
|
float COV_Increment;
|
||||||
|
bool Changed;
|
||||||
#if defined(INTRINSIC_REPORTING)
|
#if defined(INTRINSIC_REPORTING)
|
||||||
uint32_t Time_Delay;
|
uint32_t Time_Delay;
|
||||||
uint32_t Notification_Class;
|
uint32_t Notification_Class;
|
||||||
|
|||||||
@@ -154,9 +154,9 @@ static object_functions_t My_Object_Table[] = {
|
|||||||
Analog_Value_Property_Lists,
|
Analog_Value_Property_Lists,
|
||||||
NULL /* ReadRangeInfo */ ,
|
NULL /* ReadRangeInfo */ ,
|
||||||
NULL /* Iterator */ ,
|
NULL /* Iterator */ ,
|
||||||
NULL /* Value_Lists */ ,
|
Analog_Value_Encode_Value_List,
|
||||||
NULL /* COV */ ,
|
Analog_Value_Change_Of_Value,
|
||||||
NULL /* COV Clear */ ,
|
Analog_Value_Change_Of_Value_Clear,
|
||||||
Analog_Value_Intrinsic_Reporting},
|
Analog_Value_Intrinsic_Reporting},
|
||||||
{OBJECT_BINARY_INPUT,
|
{OBJECT_BINARY_INPUT,
|
||||||
Binary_Input_Init,
|
Binary_Input_Init,
|
||||||
|
|||||||
Reference in New Issue
Block a user