Changed the load control object AbleToMeetShed to only check immediate, and added CanNowComplyWithShed function to attempt to meet the shed request while in the non-compliant state. (#1191)
This commit is contained in:
@@ -52,6 +52,9 @@ The git repositories are hosted at the following sites:
|
||||
|
||||
### Changed
|
||||
|
||||
* Changed the load control object AbleToMeetShed to only check for immediate
|
||||
shed ability and added CanNowComplyWithShed function to attempt to meet the
|
||||
shed request while in the non-compliant state. (#1191)
|
||||
* Changed the size of MAX_HEADER in BACDL_MULTIPLE because 8 is not
|
||||
big enough for some datalinks (e.g. mstp). (#1170)
|
||||
* Changed printf() in many apps to use debug_printf() and friends. (#1168)
|
||||
|
||||
+141
-138
@@ -412,7 +412,7 @@ Shed_Level_Default_Set(BACNET_SHED_LEVEL *dest, BACNET_SHED_LEVEL_TYPE type)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determine if the object can meet the shed request
|
||||
* @brief Determine if the object can immediately meet the shed request
|
||||
* @param pObject - object instance to get
|
||||
* @return true if the object can meet the shed request
|
||||
*/
|
||||
@@ -429,19 +429,46 @@ static bool Able_To_Meet_Shed_Request(struct object_data *pObject)
|
||||
pObject->Manipulated_Object_Instance,
|
||||
pObject->Manipulated_Object_Property, &priority, &level);
|
||||
requested_level = Requested_Shed_Level_Value(pObject);
|
||||
if (level >= requested_level) {
|
||||
if (level < requested_level) {
|
||||
status = true;
|
||||
}
|
||||
}
|
||||
if (status) {
|
||||
status = false;
|
||||
/* can we control the output? */
|
||||
if (priority >= pObject->Priority_For_Writing) {
|
||||
/* is the level able to be lowered? */
|
||||
requested_level = Requested_Shed_Level_Value(pObject);
|
||||
if (level >= requested_level) {
|
||||
status = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determine if the object can now comply with the shed request
|
||||
* @param pObject - object instance to get
|
||||
* @return true if the object can comply with the shed request
|
||||
*/
|
||||
static bool Can_Now_Comply_With_Shed(struct object_data *pObject)
|
||||
{
|
||||
float level = 0.0f;
|
||||
float requested_level = 0.0f;
|
||||
uint8_t priority = 0;
|
||||
bool status = false;
|
||||
|
||||
if (pObject->Manipulated_Object_Read) {
|
||||
pObject->Manipulated_Object_Read(
|
||||
pObject->Manipulated_Object_Type,
|
||||
pObject->Manipulated_Object_Instance,
|
||||
pObject->Manipulated_Object_Property, &priority, &level);
|
||||
requested_level = Requested_Shed_Level_Value(pObject);
|
||||
if (level <= requested_level) {
|
||||
status = true;
|
||||
}
|
||||
}
|
||||
if (!status) {
|
||||
/* the object attempts to meet the shed request
|
||||
until the shed is achieved. */
|
||||
if (pObject->Manipulated_Object_Write) {
|
||||
pObject->Manipulated_Object_Write(
|
||||
pObject->Manipulated_Object_Type,
|
||||
pObject->Manipulated_Object_Instance,
|
||||
pObject->Manipulated_Object_Property,
|
||||
pObject->Priority_For_Writing,
|
||||
Requested_Shed_Level_Value(pObject));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,24 +574,26 @@ void Load_Control_State_Machine(
|
||||
" is after Start Time\n",
|
||||
object_index);
|
||||
/* AbleToMeetShed */
|
||||
/* If the current time is after Start_Time and the object
|
||||
is able to achieve the shed request immediately,
|
||||
it shall shed its loads, calculate Expected_Shed_Level
|
||||
and Actual_Shed_Level, and enter the SHED_COMPLIANT state. */
|
||||
if (Able_To_Meet_Shed_Request(pObject)) {
|
||||
Shed_Level_Copy(
|
||||
&pObject->Expected_Shed_Level,
|
||||
&pObject->Requested_Shed_Level);
|
||||
if (pObject->Manipulated_Object_Write) {
|
||||
pObject->Manipulated_Object_Write(
|
||||
pObject->Manipulated_Object_Type,
|
||||
pObject->Manipulated_Object_Instance,
|
||||
pObject->Manipulated_Object_Property,
|
||||
pObject->Priority_For_Writing,
|
||||
Requested_Shed_Level_Value(pObject));
|
||||
}
|
||||
Shed_Level_Copy(
|
||||
&pObject->Actual_Shed_Level,
|
||||
&pObject->Requested_Shed_Level);
|
||||
pObject->Present_Value = BACNET_SHED_COMPLIANT;
|
||||
} else {
|
||||
/* CannotMeetShed */
|
||||
/* If the current time is after Start_Time,
|
||||
and the object is unable to meet the shed
|
||||
request immediately, it shall begin shedding
|
||||
its loads, calculate Expected_Shed_Level and
|
||||
Actual_Shed_Level, and enter the SHED_NON_COMPLIANT
|
||||
state. */
|
||||
Shed_Level_Default_Set(
|
||||
&pObject->Expected_Shed_Level,
|
||||
pObject->Requested_Shed_Level.type);
|
||||
@@ -576,6 +605,10 @@ void Load_Control_State_Machine(
|
||||
}
|
||||
break;
|
||||
case BACNET_SHED_NON_COMPLIANT:
|
||||
/* In the SHED_NON_COMPLIANT state, the object attempts
|
||||
to meet the shed request until the shed is achieved,
|
||||
the object is reconfigured, or the request has completed
|
||||
unsuccessfully. */
|
||||
datetime_copy(&pObject->End_Time, &pObject->Start_Time);
|
||||
datetime_add_minutes(&pObject->End_Time, pObject->Shed_Duration);
|
||||
diff = datetime_compare(&pObject->End_Time, bdatetime);
|
||||
@@ -598,7 +631,7 @@ void Load_Control_State_Machine(
|
||||
pObject->Present_Value = BACNET_SHED_REQUEST_PENDING;
|
||||
break;
|
||||
}
|
||||
if (Able_To_Meet_Shed_Request(pObject)) {
|
||||
if (Can_Now_Comply_With_Shed(pObject)) {
|
||||
/* CanNowComplyWithShed */
|
||||
debug_printf(
|
||||
"Load Control[%d]:Able to meet Shed Request\n",
|
||||
@@ -606,14 +639,6 @@ void Load_Control_State_Machine(
|
||||
Shed_Level_Copy(
|
||||
&pObject->Expected_Shed_Level,
|
||||
&pObject->Requested_Shed_Level);
|
||||
if (pObject->Manipulated_Object_Write) {
|
||||
pObject->Manipulated_Object_Write(
|
||||
pObject->Manipulated_Object_Type,
|
||||
pObject->Manipulated_Object_Instance,
|
||||
pObject->Manipulated_Object_Property,
|
||||
pObject->Priority_For_Writing,
|
||||
Requested_Shed_Level_Value(pObject));
|
||||
}
|
||||
Shed_Level_Copy(
|
||||
&pObject->Actual_Shed_Level,
|
||||
&pObject->Requested_Shed_Level);
|
||||
@@ -869,6 +894,24 @@ bool Load_Control_Manipulated_Variable_Reference_Set(
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the number of shed levels in this array
|
||||
* @param object_instance [in] BACnet object instance number
|
||||
* @return Count of shed levels in the list.
|
||||
*/
|
||||
static int Load_Control_Shed_Levels_Count(uint32_t object_instance)
|
||||
{
|
||||
int count = 0;
|
||||
struct object_data *pObject = NULL;
|
||||
|
||||
pObject = Object_Instance_Data(object_instance);
|
||||
if (pObject) {
|
||||
count = Keylist_Count(pObject->Shed_Level_List);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Encode a BACnetARRAY property element
|
||||
* @param object_instance [in] BACnet object instance number
|
||||
@@ -1089,7 +1132,7 @@ int Load_Control_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
BACnet_Shed_Level_Encode(apdu, &pObject->Actual_Shed_Level);
|
||||
break;
|
||||
case PROP_SHED_LEVELS:
|
||||
count = Keylist_Count(pObject->Shed_Level_List);
|
||||
count = Load_Control_Shed_Levels_Count(rpdata->object_instance);
|
||||
apdu_len = bacnet_array_encode(
|
||||
rpdata->object_instance, rpdata->array_index,
|
||||
Load_Control_Shed_Levels_Encode, count, apdu, apdu_size);
|
||||
@@ -1102,7 +1145,7 @@ int Load_Control_Read_Property(BACNET_READ_PROPERTY_DATA *rpdata)
|
||||
}
|
||||
break;
|
||||
case PROP_SHED_LEVEL_DESCRIPTIONS:
|
||||
count = Keylist_Count(pObject->Shed_Level_List);
|
||||
count = Load_Control_Shed_Levels_Count(rpdata->object_instance);
|
||||
apdu_len = bacnet_array_encode(
|
||||
rpdata->object_instance, rpdata->array_index,
|
||||
Load_Control_Shed_Level_Descriptions_Encode, count, apdu,
|
||||
@@ -1328,126 +1371,78 @@ static bool Load_Control_Duty_Window_Write(
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief For a given object instance-number, writes to the property value
|
||||
* @param wp_data - BACNET_WRITE_PROPERTY_DATA data, including
|
||||
* requested data and space for the reply, or error response.
|
||||
*
|
||||
* @return false if an error is loaded, true if no errors
|
||||
* @brief Decode a BACnetLIST property element to determine the element length
|
||||
* @param object_instance [in] BACnet object instance number
|
||||
* @param apdu [in] Buffer in which the APDU contents are extracted
|
||||
* @param apdu_size [in] The size of the APDU buffer
|
||||
* @return The length of the decoded apdu, or BACNET_STATUS_ERROR on error
|
||||
*/
|
||||
static bool Load_Control_Shed_Levels_Write(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
static int BACnet_Shed_Level_Element_Length(
|
||||
uint32_t object_instance, uint8_t *apdu, size_t apdu_size)
|
||||
{
|
||||
struct object_data *pObject;
|
||||
BACNET_UNSIGNED_INTEGER unsigned_value;
|
||||
struct shed_level_data *entry;
|
||||
int len = 0, index = 0, count = 0, apdu_len = 0, apdu_size = 0;
|
||||
KEY key;
|
||||
uint8_t *apdu;
|
||||
(void)object_instance;
|
||||
return bacnet_shed_level_decode(apdu, apdu_size, NULL);
|
||||
}
|
||||
|
||||
pObject = Object_Instance_Data(wp_data->object_instance);
|
||||
if (!pObject) {
|
||||
wp_data->error_class = ERROR_CLASS_OBJECT;
|
||||
wp_data->error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||
return false;
|
||||
}
|
||||
count = Keylist_Count(pObject->Shed_Level_List);
|
||||
if (wp_data->array_index == 0) {
|
||||
/* This array is not required to be resizable
|
||||
through BACnet write services */
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
return false;
|
||||
} else if (wp_data->array_index == BACNET_ARRAY_ALL) {
|
||||
/* The size of this array shall be equal to the
|
||||
size of the Shed_Level_Descriptions array.*/
|
||||
/* will the array elements sent fit in the whole array? */
|
||||
apdu = wp_data->application_data;
|
||||
apdu_size = wp_data->application_data_len;
|
||||
while (count > 0) {
|
||||
len = bacnet_unsigned_application_decode(
|
||||
&apdu[apdu_len], apdu_size - apdu_len, &unsigned_value);
|
||||
if (len > 0) {
|
||||
if (unsigned_value > UINT32_MAX) {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
return false;
|
||||
}
|
||||
apdu_len += len;
|
||||
} else {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
return false;
|
||||
}
|
||||
count--;
|
||||
}
|
||||
if (apdu_len != wp_data->application_data_len) {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
return false;
|
||||
}
|
||||
/* write entire array - we know the size and values are valid */
|
||||
/**
|
||||
* @brief Write a value to a BACnetLIST property element value
|
||||
* using a BACnetARRAY write utility function
|
||||
* @param object_instance [in] BACnet object instance number
|
||||
* @param array_index [in] array index to write:
|
||||
* 0=array size, 1 to N for individual array members
|
||||
* @param application_data [in] encoded element value
|
||||
* @param application_data_len [in] The size of the encoded element value
|
||||
* @return BACNET_ERROR_CODE value
|
||||
*/
|
||||
static BACNET_ERROR_CODE BACnet_Shed_Level_Element_Write(
|
||||
uint32_t object_instance,
|
||||
BACNET_ARRAY_INDEX array_index,
|
||||
uint8_t *application_data,
|
||||
size_t application_data_len)
|
||||
{
|
||||
BACNET_ERROR_CODE error_code = ERROR_CODE_UNKNOWN_OBJECT;
|
||||
BACNET_SHED_LEVEL shed_level = { 0 };
|
||||
struct shed_level_data *entry = NULL;
|
||||
int len = 0;
|
||||
struct object_data *pObject = NULL;
|
||||
KEY key = 0;
|
||||
int count = 0;
|
||||
|
||||
pObject = Object_Instance_Data(object_instance);
|
||||
if (pObject) {
|
||||
count = Keylist_Count(pObject->Shed_Level_List);
|
||||
apdu = wp_data->application_data;
|
||||
apdu_size = wp_data->application_data_len;
|
||||
while (count > 0) {
|
||||
len = bacnet_unsigned_application_decode(
|
||||
&apdu[apdu_len], apdu_size - apdu_len, &unsigned_value);
|
||||
if (array_index == 0) {
|
||||
/* This array is not required to be resizable
|
||||
through BACnet write services */
|
||||
error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
|
||||
} else if (array_index <= count) {
|
||||
len = bacnet_shed_level_decode(
|
||||
application_data, application_data_len, &shed_level);
|
||||
if (len > 0) {
|
||||
apdu_len += len;
|
||||
if (unsigned_value <= UINT32_MAX) {
|
||||
index = count - 1;
|
||||
entry = Keylist_Data_Delete_By_Index(
|
||||
pObject->Shed_Level_List, index);
|
||||
key = (uint32_t)unsigned_value;
|
||||
index =
|
||||
Keylist_Data_Add(pObject->Shed_Level_List, key, entry);
|
||||
if (index < 0) {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code =
|
||||
ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
|
||||
return false;
|
||||
/* represents the shed levels for the LEVEL choice */
|
||||
if (shed_level.type != BACNET_SHED_TYPE_LEVEL) {
|
||||
error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
} else if (shed_level.value.level <= 100) {
|
||||
/* our implementation uses percent of baseline */
|
||||
key = array_index - 1;
|
||||
entry = Keylist_Data(pObject->Shed_Level_List, key);
|
||||
if (entry) {
|
||||
entry->Value = (float)shed_level.value.level;
|
||||
} else {
|
||||
error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
|
||||
}
|
||||
} else {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
return false;
|
||||
error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
}
|
||||
}
|
||||
count--;
|
||||
}
|
||||
} else if (wp_data->array_index <= count) {
|
||||
len = bacnet_unsigned_application_decode(
|
||||
wp_data->application_data, wp_data->application_data_len,
|
||||
&unsigned_value);
|
||||
if (len > 0) {
|
||||
if (unsigned_value <= UINT32_MAX) {
|
||||
index = wp_data->array_index - 1;
|
||||
entry = Keylist_Data_Delete_By_Index(
|
||||
pObject->Shed_Level_List, index);
|
||||
key = (uint32_t)unsigned_value;
|
||||
index = Keylist_Data_Add(pObject->Shed_Level_List, key, entry);
|
||||
if (index < 0) {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
|
||||
return false;
|
||||
error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
}
|
||||
} else {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_INVALID_DATA_TYPE;
|
||||
return false;
|
||||
error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||
}
|
||||
} else {
|
||||
wp_data->error_class = ERROR_CLASS_PROPERTY;
|
||||
wp_data->error_code = ERROR_CODE_INVALID_ARRAY_INDEX;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return error_code;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1492,7 +1487,7 @@ static bool Load_Control_Enable_Write(
|
||||
bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
{
|
||||
bool status = false; /* return value */
|
||||
int len = 0;
|
||||
int len = 0, count = 0;
|
||||
BACNET_APPLICATION_DATA_VALUE value = { 0 };
|
||||
|
||||
if (wp_data == NULL) {
|
||||
@@ -1562,7 +1557,15 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA *wp_data)
|
||||
break;
|
||||
|
||||
case PROP_SHED_LEVELS:
|
||||
status = Load_Control_Shed_Levels_Write(wp_data);
|
||||
count = Load_Control_Shed_Levels_Count(wp_data->object_instance);
|
||||
wp_data->error_code = bacnet_array_write(
|
||||
wp_data->object_instance, wp_data->array_index,
|
||||
BACnet_Shed_Level_Element_Length,
|
||||
BACnet_Shed_Level_Element_Write, count,
|
||||
wp_data->application_data, wp_data->application_data_len);
|
||||
if (wp_data->error_code == ERROR_CODE_SUCCESS) {
|
||||
status = true;
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_ENABLE:
|
||||
|
||||
@@ -257,3 +257,42 @@ bool bacnet_shed_level_from_ascii(BACNET_SHED_LEVEL *value, const char *argv)
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize a BACnetShedLevel structure
|
||||
* @param value - pointer to the BACNET_SHED_LEVEL structure
|
||||
* @param type - type of shed level
|
||||
* @param level - level value as float
|
||||
* @return true on success, else false
|
||||
*/
|
||||
bool bacnet_shed_level_init(
|
||||
BACNET_SHED_LEVEL *value, BACNET_SHED_LEVEL_TYPE type, float level)
|
||||
{
|
||||
if (!value) {
|
||||
return false;
|
||||
}
|
||||
value->type = type;
|
||||
switch (type) {
|
||||
case BACNET_SHED_TYPE_PERCENT:
|
||||
if (level < 0.0f || level > 100.0f) {
|
||||
return false;
|
||||
}
|
||||
value->value.percent = (BACNET_UNSIGNED_INTEGER)level;
|
||||
break;
|
||||
case BACNET_SHED_TYPE_LEVEL:
|
||||
if (level < 0.0f) {
|
||||
return false;
|
||||
}
|
||||
value->value.level = (BACNET_UNSIGNED_INTEGER)level;
|
||||
break;
|
||||
case BACNET_SHED_TYPE_AMOUNT:
|
||||
if (level < 0.0f) {
|
||||
return false;
|
||||
}
|
||||
value->value.amount = level;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,10 @@ int bacapp_snprintf_shed_level(
|
||||
BACNET_STACK_EXPORT
|
||||
bool bacnet_shed_level_from_ascii(BACNET_SHED_LEVEL *value, const char *argv);
|
||||
|
||||
BACNET_STACK_EXPORT
|
||||
bool bacnet_shed_level_init(
|
||||
BACNET_SHED_LEVEL *value, BACNET_SHED_LEVEL_TYPE type, float level);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <zephyr/ztest.h>
|
||||
#include <bacnet/bacdcode.h>
|
||||
#include <bacnet/bacstr.h>
|
||||
#include <bacnet/bactext.h>
|
||||
#include <bacnet/basic/object/ao.h>
|
||||
#include <bacnet/basic/object/lc.h>
|
||||
#include <property_test.h>
|
||||
@@ -40,8 +41,8 @@ static bool is_float_equal(float x1, float x2)
|
||||
* @brief Test
|
||||
*/
|
||||
|
||||
static void
|
||||
Load_Control_WriteProperty_Request_Shed_Level(int instance, unsigned level)
|
||||
static void Load_Control_WriteProperty_Request_Shed_Level(
|
||||
int instance, BACNET_SHED_LEVEL_TYPE type, float level)
|
||||
{
|
||||
bool status = false;
|
||||
BACNET_APPLICATION_DATA_VALUE value = { 0 };
|
||||
@@ -52,8 +53,7 @@ Load_Control_WriteProperty_Request_Shed_Level(int instance, unsigned level)
|
||||
wp_data.array_index = BACNET_ARRAY_ALL;
|
||||
wp_data.priority = BACNET_NO_PRIORITY;
|
||||
wp_data.object_property = PROP_REQUESTED_SHED_LEVEL;
|
||||
value.type.Shed_Level.type = BACNET_SHED_TYPE_LEVEL;
|
||||
value.type.Shed_Level.value.level = level;
|
||||
bacnet_shed_level_init(&value.type.Shed_Level, type, level);
|
||||
wp_data.application_data_len = bacapp_encode_known_property(
|
||||
&wp_data.application_data[0], &value, wp_data.object_type,
|
||||
wp_data.object_property);
|
||||
@@ -457,7 +457,8 @@ static void testLoadControlStateMachine(void)
|
||||
zassert_true(status, NULL);
|
||||
status = Load_Control_Update_Interval_Set(object_instance, 0);
|
||||
zassert_true(status, NULL);
|
||||
Load_Control_WriteProperty_Request_Shed_Level(object_instance, 0);
|
||||
Load_Control_WriteProperty_Request_Shed_Level(
|
||||
object_instance, BACNET_SHED_TYPE_LEVEL, 0.0f);
|
||||
Load_Control_WriteProperty_Start_Time(
|
||||
object_instance, 2007, 2, 27, 15, 0, 0, 0);
|
||||
Load_Control_WriteProperty_Shed_Duration(object_instance, 5);
|
||||
@@ -480,7 +481,8 @@ static void testLoadControlStateMachine(void)
|
||||
status = Load_Control_Update_Interval_Set(object_instance, 0);
|
||||
zassert_true(status, NULL);
|
||||
Load_Control_WriteProperty_Enable(object_instance, true);
|
||||
Load_Control_WriteProperty_Request_Shed_Level(object_instance, 1);
|
||||
Load_Control_WriteProperty_Request_Shed_Level(
|
||||
object_instance, BACNET_SHED_TYPE_LEVEL, 1.0f);
|
||||
Load_Control_WriteProperty_Shed_Duration(object_instance, 5);
|
||||
Load_Control_WriteProperty_Start_Time(
|
||||
object_instance, 2007, 2, 27, 15, 0, 0, 0);
|
||||
@@ -503,7 +505,8 @@ static void testLoadControlStateMachine(void)
|
||||
status = Load_Control_Update_Interval_Set(object_instance, 0);
|
||||
zassert_true(status, NULL);
|
||||
Load_Control_WriteProperty_Enable(object_instance, true);
|
||||
Load_Control_WriteProperty_Request_Shed_Level(object_instance, 1);
|
||||
Load_Control_WriteProperty_Request_Shed_Level(
|
||||
object_instance, BACNET_SHED_TYPE_LEVEL, 1.0f);
|
||||
Load_Control_WriteProperty_Shed_Duration(object_instance, 5);
|
||||
Load_Control_WriteProperty_Start_Time(
|
||||
object_instance, 2007, 2, 27, 15, 0, 0, 0);
|
||||
@@ -517,7 +520,8 @@ static void testLoadControlStateMachine(void)
|
||||
zassert_equal(
|
||||
Load_Control_Present_Value(object_instance),
|
||||
BACNET_SHED_REQUEST_PENDING, NULL);
|
||||
Load_Control_WriteProperty_Request_Shed_Level(object_instance, 2);
|
||||
Load_Control_WriteProperty_Request_Shed_Level(
|
||||
object_instance, BACNET_SHED_TYPE_LEVEL, 2.0f);
|
||||
Load_Control_Timer(object_instance, 1);
|
||||
zassert_equal(
|
||||
Load_Control_Present_Value(object_instance),
|
||||
@@ -556,7 +560,8 @@ static void testLoadControlStateMachine(void)
|
||||
status = Load_Control_Update_Interval_Set(object_instance, 0);
|
||||
zassert_true(status, NULL);
|
||||
Load_Control_WriteProperty_Enable(object_instance, true);
|
||||
Load_Control_WriteProperty_Request_Shed_Level(object_instance, 1);
|
||||
Load_Control_WriteProperty_Request_Shed_Level(
|
||||
object_instance, BACNET_SHED_TYPE_LEVEL, 1.0f);
|
||||
Load_Control_WriteProperty_Shed_Duration(object_instance, 120);
|
||||
Load_Control_WriteProperty_Start_Time(
|
||||
object_instance, 2007, 2, 27, 15, 0, 0, 0);
|
||||
@@ -570,8 +575,8 @@ static void testLoadControlStateMachine(void)
|
||||
zassert_equal(
|
||||
Load_Control_Present_Value(object_instance),
|
||||
BACNET_SHED_REQUEST_PENDING, NULL);
|
||||
/* set to lowest value so we cannot meet the shed level */
|
||||
Test_Present_Value_Priority_Set(0.0f, 16);
|
||||
/* set to value that cannot meet the shed level immediately */
|
||||
Test_Present_Value_Priority_Set(100.0f, 16);
|
||||
datetime_set_values(&bdatetime, 2007, 2, 27, 16, 0, 0, 0);
|
||||
datetime_timesync(&bdatetime.date, &bdatetime.time, false);
|
||||
Load_Control_Timer(object_instance, 1);
|
||||
@@ -598,7 +603,8 @@ static void testLoadControlStateMachine(void)
|
||||
status = Load_Control_Update_Interval_Set(object_instance, 0);
|
||||
zassert_true(status, NULL);
|
||||
Load_Control_WriteProperty_Enable(object_instance, true);
|
||||
Load_Control_WriteProperty_Request_Shed_Level(object_instance, 1);
|
||||
Load_Control_WriteProperty_Request_Shed_Level(
|
||||
object_instance, BACNET_SHED_TYPE_LEVEL, 1.0f);
|
||||
Load_Control_WriteProperty_Shed_Duration(object_instance, 120);
|
||||
Load_Control_WriteProperty_Start_Time(
|
||||
object_instance, 2007, 2, 27, 15, 0, 0, 0);
|
||||
@@ -612,8 +618,8 @@ static void testLoadControlStateMachine(void)
|
||||
zassert_equal(
|
||||
Load_Control_Present_Value(object_instance),
|
||||
BACNET_SHED_REQUEST_PENDING, NULL);
|
||||
/* set to lowest value so we cannot meet the shed level */
|
||||
Test_Present_Value_Priority_Set(0.0f, 16);
|
||||
/* not able to meet the shed level immediately */
|
||||
Test_Present_Value_Priority_Set(100.0f, 16);
|
||||
datetime_set_values(&bdatetime, 2007, 2, 27, 16, 0, 0, 0);
|
||||
datetime_timesync(&bdatetime.date, &bdatetime.time, false);
|
||||
Load_Control_Timer(object_instance, 1);
|
||||
@@ -700,11 +706,8 @@ static void testLoadControlStateMachine(void)
|
||||
status = Load_Control_Update_Interval_Set(object_instance, 0);
|
||||
zassert_true(status, NULL);
|
||||
Load_Control_WriteProperty_Enable(object_instance, true);
|
||||
shed_level.type = BACNET_SHED_TYPE_PERCENT;
|
||||
shed_level.value.percent = 20;
|
||||
status =
|
||||
Load_Control_Requested_Shed_Level_Set(object_instance, &shed_level);
|
||||
zassert_true(status, NULL);
|
||||
Load_Control_WriteProperty_Request_Shed_Level(
|
||||
object_instance, BACNET_SHED_TYPE_PERCENT, 20.0f);
|
||||
Load_Control_WriteProperty_Start_Time(
|
||||
object_instance, 2007, 2, 27, 15, 0, 0, 0);
|
||||
Load_Control_WriteProperty_Shed_Duration(object_instance, 5);
|
||||
@@ -714,6 +717,7 @@ static void testLoadControlStateMachine(void)
|
||||
shed_state = Load_Control_Present_Value(object_instance);
|
||||
zassert_equal(shed_state, BACNET_SHED_REQUEST_PENDING, NULL);
|
||||
/* configure for non-compliance */
|
||||
Test_Present_Value_Priority_Set(100.0f, 16);
|
||||
datetime_set_values(&bdatetime, 2007, 2, 27, 15, 0, 2, 0);
|
||||
datetime_timesync(&bdatetime.date, &bdatetime.time, false);
|
||||
Load_Control_Timer(object_instance, 1);
|
||||
@@ -721,7 +725,7 @@ static void testLoadControlStateMachine(void)
|
||||
zassert_equal(shed_state, BACNET_SHED_NON_COMPLIANT, NULL);
|
||||
/* configure for compliance */
|
||||
priority = Load_Control_Priority_For_Writing(object_instance);
|
||||
Test_Present_Value_Priority_Set(20.0f, priority);
|
||||
Test_Present_Value_Priority_Set(20.0f, 16);
|
||||
datetime_set_values(&bdatetime, 2007, 2, 27, 15, 0, 3, 0);
|
||||
datetime_timesync(&bdatetime.date, &bdatetime.time, false);
|
||||
Load_Control_Timer(object_instance, 1);
|
||||
@@ -736,8 +740,8 @@ static void testLoadControlStateMachine(void)
|
||||
status = Load_Control_Update_Interval_Set(object_instance, 0);
|
||||
zassert_true(status, NULL);
|
||||
Load_Control_WriteProperty_Enable(object_instance, true);
|
||||
shed_level.type = BACNET_SHED_TYPE_AMOUNT;
|
||||
shed_level.value.amount = 0.0f;
|
||||
Load_Control_WriteProperty_Request_Shed_Level(
|
||||
object_instance, BACNET_SHED_TYPE_AMOUNT, 0.0f);
|
||||
status =
|
||||
Load_Control_Requested_Shed_Level_Set(object_instance, &shed_level);
|
||||
zassert_true(status, NULL);
|
||||
@@ -759,6 +763,8 @@ static void testLoadControlStateMachine(void)
|
||||
zassert_true(status, NULL);
|
||||
status = Load_Control_Update_Interval_Set(object_instance, 0);
|
||||
zassert_true(status, NULL);
|
||||
status = Load_Control_Full_Duty_Baseline_Set(object_instance, 100.0f);
|
||||
zassert_true(status, NULL);
|
||||
Load_Control_WriteProperty_Enable(object_instance, true);
|
||||
shed_level.type = BACNET_SHED_TYPE_AMOUNT;
|
||||
shed_level.value.amount = 10.0f;
|
||||
@@ -774,6 +780,9 @@ static void testLoadControlStateMachine(void)
|
||||
shed_state = Load_Control_Present_Value(object_instance);
|
||||
zassert_equal(shed_state, BACNET_SHED_REQUEST_PENDING, NULL);
|
||||
/* configure for non-compliance */
|
||||
priority = Load_Control_Priority_For_Writing(object_instance);
|
||||
Test_Present_Value_Priority_Set(100.0f, priority);
|
||||
zassert_true(status, NULL);
|
||||
datetime_set_values(&bdatetime, 2007, 2, 27, 15, 0, 2, 0);
|
||||
datetime_timesync(&bdatetime.date, &bdatetime.time, false);
|
||||
Load_Control_Timer(object_instance, 1);
|
||||
@@ -781,7 +790,6 @@ static void testLoadControlStateMachine(void)
|
||||
zassert_equal(shed_state, BACNET_SHED_NON_COMPLIANT, NULL);
|
||||
/* configure for compliance - amount reference full-duty-baseline */
|
||||
priority = Load_Control_Priority_For_Writing(object_instance);
|
||||
status = Load_Control_Full_Duty_Baseline_Set(object_instance, 11.0f);
|
||||
zassert_true(status, NULL);
|
||||
Test_Present_Value_Priority_Set(10.0f, priority);
|
||||
datetime_set_values(&bdatetime, 2007, 2, 27, 15, 0, 3, 0);
|
||||
|
||||
Reference in New Issue
Block a user