Change time-value object present-value to not report current time. Added out-of-service property to WriteProperty.

This commit is contained in:
Steve Karg
2024-04-04 11:33:54 -05:00
parent 0cebc83d88
commit d1f92cbb8f
+56 -45
View File
@@ -3,13 +3,9 @@
* @author Steve Karg <skarg@users.sourceforge.net>
* @author Mikhail Antropov <michail.antropov@dsr-corporation.com>
* @date June 2023
* @brief Time Value objects used by a BACnet device object
*
* @section DESCRIPTION
*
* The Time Value object is an object with a present-value that
* @brief Time Value object is an object with a present-value that
* uses an bacnet time data type.
*
*
* @section LICENSE
*
* SPDX-License-Identifier: MIT
@@ -52,7 +48,8 @@ struct object_data {
/* Key List for storing the object data sorted by instance number */
static OS_Keylist Object_List;
/* callback for present value writes */
static time_value_write_present_value_callback Time_Value_Write_Present_Value_Callback;
static time_value_write_present_value_callback
Time_Value_Write_Present_Value_Callback;
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Time_Value_Properties_Required[] = { PROP_OBJECT_IDENTIFIER,
@@ -66,9 +63,8 @@ static const int Time_Value_Properties_Proprietary[] = { -1 };
/* standard properties that are arrays for this object,
but not necessary supported in this object */
static const int BACnetARRAY_Properties[] = {
PROP_EVENT_TIME_STAMPS, PROP_EVENT_MESSAGE_TEXTS,
PROP_EVENT_MESSAGE_TEXTS_CONFIG,
static const int BACnetARRAY_Properties[] = { PROP_EVENT_TIME_STAMPS,
PROP_EVENT_MESSAGE_TEXTS, PROP_EVENT_MESSAGE_TEXTS_CONFIG,
PROP_VALUE_SOURCE_ARRAY, PROP_COMMAND_TIME_ARRAY, PROP_TAGS, -1 };
/**
@@ -169,21 +165,31 @@ bool Time_Value_Present_Value(uint32_t object_instance, BACNET_TIME *value)
{
bool status = false;
struct object_data *pObject;
BACNET_DATE date;
pObject = Keylist_Data(Object_List, object_instance);
if (pObject) {
if (pObject->Out_Of_Service) {
datetime_copy_time(value, &pObject->Present_Value);
status = true;
} else {
status = datetime_local(&date, value, NULL, NULL);
}
datetime_copy_time(value, &pObject->Present_Value);
status = true;
}
return status;
}
/**
* @brief For a given object instance-number, checks the present-value for COV
* @param pObject - specific object with valid data
* @param value - floating point analog value
*/
static void Time_Value_Present_Value_COV_Detect(
struct object_data *pObject, BACNET_TIME *value)
{
if (pObject && value) {
if (datetime_compare_time(&pObject->Present_Value, value) != 0) {
pObject->Change_Of_Value = true;
}
}
}
/**
* For a given object instance-number, sets the present-value
*
@@ -199,11 +205,13 @@ bool Time_Value_Present_Value_Set(uint32_t object_instance, BACNET_TIME *value)
pObject = Keylist_Data(Object_List, object_instance);
if (pObject) {
if (datetime_compare_time(&pObject->Present_Value, value) != 0) {
pObject->Change_Of_Value = true;
datetime_copy_time(&pObject->Present_Value, value);
if (!pObject->Out_Of_Service) {
if (value) {
Time_Value_Present_Value_COV_Detect(pObject, value);
datetime_copy_time(&pObject->Present_Value, value);
status = true;
}
}
status = true;
}
return status;
@@ -228,17 +236,15 @@ static bool Time_Value_Present_Value_Write(uint32_t object_instance,
{
bool status = false;
struct object_data *pObject;
BACNET_TIME old_value = {0};
BACNET_TIME old_value = { 0 };
pObject = Keylist_Data(Object_List, object_instance);
if (pObject) {
(void)priority;
if (pObject->Write_Enabled) {
datetime_copy_time(&old_value, &pObject->Present_Value);
if (datetime_compare_time(&pObject->Present_Value, value) != 0) {
pObject->Change_Of_Value = true;
datetime_copy_time(&pObject->Present_Value, value);
}
Time_Value_Present_Value_COV_Detect(pObject, value);
datetime_copy_time(&pObject->Present_Value, value);
if (Time_Value_Write_Present_Value_Callback) {
Time_Value_Write_Present_Value_Callback(
object_instance, &old_value, value);
@@ -403,14 +409,11 @@ bool Time_Value_Description_Set(uint32_t object_instance, char *new_name)
* @param object_property - object-property to be checked
* @return true if the property is a BACnetARRAY property
*/
static bool BACnetARRAY_Property(
int object_property)
static bool BACnetARRAY_Property(int object_property)
{
return property_list_member(
BACnetARRAY_Properties, object_property);
return property_list_member(BACnetARRAY_Properties, object_property);
}
bool Time_Value_Change_Of_Value(uint32_t object_instance)
{
bool status = false;
@@ -543,8 +546,8 @@ int Time_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_OUT_OF_SERVICE:
apdu_len = encode_application_boolean(&apdu[0],
Time_Value_Out_Of_Service(rpdata->object_instance));
apdu_len = encode_application_boolean(
&apdu[0], Time_Value_Out_Of_Service(rpdata->object_instance));
break;
case PROP_DESCRIPTION:
characterstring_init_ansi(
@@ -562,8 +565,7 @@ int Time_Value_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
break;
}
/* only array properties can have array options */
if ((apdu_len >= 0) &&
(!BACnetARRAY_Property(rpdata->object_property)) &&
if ((apdu_len >= 0) && (!BACnetARRAY_Property(rpdata->object_property)) &&
(rpdata->array_index != BACNET_ARRAY_ALL)) {
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
@@ -608,23 +610,32 @@ bool Time_Value_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
switch (wp_data->object_property) {
case PROP_PRESENT_VALUE:
if (Time_Value_Out_Of_Service(wp_data->object_instance)) {
status = write_property_type_valid(wp_data, &value,
BACNET_APPLICATION_TAG_TIME);
status = write_property_type_valid(
wp_data, &value, BACNET_APPLICATION_TAG_TIME);
if (status) {
status = Time_Value_Present_Value_Write(
wp_data->object_instance,
&value.type.Time, wp_data->priority,
&wp_data->error_class, &wp_data->error_code);
status =
Time_Value_Present_Value_Write(wp_data->object_instance,
&value.type.Time, wp_data->priority,
&wp_data->error_class, &wp_data->error_code);
}
} else {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
}
break;
case PROP_OUT_OF_SERVICE:
status = write_property_type_valid(
wp_data, &value, BACNET_APPLICATION_TAG_BOOLEAN);
if (status) {
Time_Value_Out_Of_Service_Set(
wp_data->object_instance, value.type.Boolean);
}
break;
default:
if (property_lists_member(
Time_Value_Properties_Required, Time_Value_Properties_Optional,
Time_Value_Properties_Proprietary, wp_data->object_property)) {
if (property_lists_member(Time_Value_Properties_Required,
Time_Value_Properties_Optional,
Time_Value_Properties_Proprietary,
wp_data->object_property)) {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
} else {
@@ -655,7 +666,7 @@ void Time_Value_Write_Present_Value_Callback_Set(
uint8_t Time_Value_Status_Flags(uint32_t object_instance)
{
BACNET_BIT_STRING bit_string;
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);