Adding Lighting Control object demo. - in progress.
This commit is contained in:
@@ -168,7 +168,9 @@ typedef enum {
|
|||||||
PROP_EVENT_TIME_STAMPS = 130,
|
PROP_EVENT_TIME_STAMPS = 130,
|
||||||
PROP_LOG_BUFFER = 131,
|
PROP_LOG_BUFFER = 131,
|
||||||
PROP_LOG_DEVICE_OBJECT = 132,
|
PROP_LOG_DEVICE_OBJECT = 132,
|
||||||
PROP_LOG_ENABLE = 133,
|
/* The enable property is renamed from log-enable in
|
||||||
|
Addendum b to ANSI/ASHRAE 135-2004(135b-2) */
|
||||||
|
PROP_ENABLE = 133,
|
||||||
PROP_LOG_INTERVAL = 134,
|
PROP_LOG_INTERVAL = 134,
|
||||||
PROP_MAXIMUM_VALUE = 135,
|
PROP_MAXIMUM_VALUE = 135,
|
||||||
PROP_MINIMUM_VALUE = 136,
|
PROP_MINIMUM_VALUE = 136,
|
||||||
|
|||||||
@@ -42,10 +42,10 @@
|
|||||||
static BACNET_SHED_STATE Present_Value[MAX_LOAD_CONTROLS];
|
static BACNET_SHED_STATE Present_Value[MAX_LOAD_CONTROLS];
|
||||||
|
|
||||||
typedef enum BACnetShedLevelType {
|
typedef enum BACnetShedLevelType {
|
||||||
BACNET_SHED_PERCENT, /* Unsigned */
|
BACNET_SHED_TYPE_PERCENT, /* Unsigned */
|
||||||
BACNET_SHED_LEVEL, /* Unsigned */
|
BACNET_SHED_TYPE_LEVEL, /* Unsigned */
|
||||||
BACNET_SHED_AMOUNT /* REAL */
|
BACNET_SHED_TYPE_AMOUNT /* REAL */
|
||||||
} BACNET_SHED_LEVEL_TYPE;
|
} BACNET_SHED_TYPE_LEVEL_TYPE;
|
||||||
|
|
||||||
/* The shed levels for the LEVEL choice of BACnetShedLevel
|
/* The shed levels for the LEVEL choice of BACnetShedLevel
|
||||||
that have meaning for this particular Load Control object. */
|
that have meaning for this particular Load Control object. */
|
||||||
@@ -76,18 +76,31 @@ static unsigned Load_Control_Duty_Window[MAX_LOAD_CONTROLS];
|
|||||||
currently enabled to respond to load shed requests. */
|
currently enabled to respond to load shed requests. */
|
||||||
static boolean Load_Control_Enable[MAX_LOAD_CONTROLS];
|
static boolean Load_Control_Enable[MAX_LOAD_CONTROLS];
|
||||||
|
|
||||||
|
/* optional: indicates the baseline power consumption value
|
||||||
|
for the sheddable load controlled by this object,
|
||||||
|
if a fixed baseline is used.
|
||||||
|
The units of Full_Duty_Baseline are kilowatts.*/
|
||||||
static float Full_Duty_Baseline[MAX_LOAD_CONTROLS];
|
static float Full_Duty_Baseline[MAX_LOAD_CONTROLS];
|
||||||
|
|
||||||
|
/* Indicates the amount of power that the object expects
|
||||||
|
to be able to shed in response to a load shed request. */
|
||||||
static BACNET_SHED_LEVEL Expected_Shed_Level[MAX_LOAD_CONTROLS];
|
static BACNET_SHED_LEVEL Expected_Shed_Level[MAX_LOAD_CONTROLS];
|
||||||
|
|
||||||
|
/* Indicates the actual amount of power being shed in response
|
||||||
|
to a load shed request. */
|
||||||
static BACNET_SHED_LEVEL Actual_Shed_Level[MAX_LOAD_CONTROLS];
|
static BACNET_SHED_LEVEL Actual_Shed_Level[MAX_LOAD_CONTROLS];
|
||||||
|
|
||||||
|
/* Represents the shed levels for the LEVEL choice of
|
||||||
|
BACnetShedLevel that have meaning for this particular
|
||||||
|
Load Control object. */
|
||||||
static unsigned Shed_Levels[MAX_LOAD_CONTROLS][MAX_SHED_LEVELS];
|
static unsigned Shed_Levels[MAX_LOAD_CONTROLS][MAX_SHED_LEVELS];
|
||||||
|
|
||||||
|
/* represents a description of the shed levels that the
|
||||||
|
Load Control object can take on. */
|
||||||
static char *Shed_Level_Descriptions[MAX_SHED_LEVELS] = {
|
static char *Shed_Level_Descriptions[MAX_SHED_LEVELS] = {
|
||||||
"dim lights 30%",
|
"dim lights 10%",
|
||||||
"dim lights 20%",
|
"dim lights 20%",
|
||||||
"dim lights 10%"
|
"dim lights 30%"
|
||||||
};
|
};
|
||||||
|
|
||||||
/* we need to have our arrays initialized before answering any calls */
|
/* we need to have our arrays initialized before answering any calls */
|
||||||
@@ -102,7 +115,7 @@ void Load_Control_Init(void)
|
|||||||
for (i = 0; i < MAX_LOAD_CONTROLS; i++) {
|
for (i = 0; i < MAX_LOAD_CONTROLS; i++) {
|
||||||
/* FIXME: load saved data? */
|
/* FIXME: load saved data? */
|
||||||
Present_Value[i] = BACNET_SHED_INACTIVE;
|
Present_Value[i] = BACNET_SHED_INACTIVE;
|
||||||
Requested_Shed_Level[i].type = BACNET_SHED_LEVEL;
|
Requested_Shed_Level[i].type = BACNET_SHED_TYPE_LEVEL;
|
||||||
Requested_Shed_Level[i].value.level = 0;
|
Requested_Shed_Level[i].value.level = 0;
|
||||||
Load_Control_Start_Time[i].date.year = 2000;
|
Load_Control_Start_Time[i].date.year = 2000;
|
||||||
Load_Control_Start_Time[i].date.month = 1;
|
Load_Control_Start_Time[i].date.month = 1;
|
||||||
@@ -119,8 +132,12 @@ void Load_Control_Init(void)
|
|||||||
for (j = 0; j < MAX_SHED_LEVELS; j++) {
|
for (j = 0; j < MAX_SHED_LEVELS; j++) {
|
||||||
/* FIXME: fake data for lighting application */
|
/* FIXME: fake data for lighting application */
|
||||||
/* The array shall be ordered by increasing shed amount. */
|
/* The array shall be ordered by increasing shed amount. */
|
||||||
Shed_Levels[i][j] = 70 + (j * (30/MAX_SHED_LEVELS));
|
Shed_Levels[i][j] = 90 - (j * (30/MAX_SHED_LEVELS));
|
||||||
}
|
}
|
||||||
|
Expected_Shed_Level[i].type = BACNET_SHED_TYPE_LEVEL;
|
||||||
|
Expected_Shed_Level[i].value.level = 0;
|
||||||
|
Actual_Shed_Level[i].type = BACNET_SHED_TYPE_LEVEL;
|
||||||
|
Actual_Shed_Level[i].value.level = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,6 +231,7 @@ int Load_Control_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
bool state = false;
|
bool state = false;
|
||||||
|
|
||||||
Load_Control_Init();
|
Load_Control_Init();
|
||||||
|
object_index = Load_Control_Instance_To_Index(object_instance);
|
||||||
switch (property) {
|
switch (property) {
|
||||||
case PROP_OBJECT_IDENTIFIER:
|
case PROP_OBJECT_IDENTIFIER:
|
||||||
apdu_len = encode_tagged_object_id(&apdu[0], OBJECT_LOAD_CONTROL,
|
apdu_len = encode_tagged_object_id(&apdu[0], OBJECT_LOAD_CONTROL,
|
||||||
@@ -258,33 +276,87 @@ int Load_Control_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
apdu_len = encode_tagged_enumerated(&apdu[0], EVENT_STATE_NORMAL);
|
apdu_len = encode_tagged_enumerated(&apdu[0], EVENT_STATE_NORMAL);
|
||||||
break;
|
break;
|
||||||
case PROP_ENABLE:
|
case PROP_ENABLE:
|
||||||
object_index = Load_Control_Instance_To_Index(object_instance);
|
|
||||||
state = Load_Control_Enable[object_index];
|
state = Load_Control_Enable[object_index];
|
||||||
apdu_len = encode_tagged_boolean(&apdu[0], state);
|
apdu_len = encode_tagged_boolean(&apdu[0], state);
|
||||||
break;
|
break;
|
||||||
case PROP_REQUESTED_SHED_LEVEL:
|
case PROP_REQUESTED_SHED_LEVEL:
|
||||||
object_index = Load_Control_Instance_To_Index(object_instance);
|
|
||||||
switch (Requested_Shed_Level[object_index].type)
|
switch (Requested_Shed_Level[object_index].type)
|
||||||
{
|
{
|
||||||
case BACNET_SHED_PERCENT:
|
case BACNET_SHED_TYPE_PERCENT:
|
||||||
apdu_len = encode_tagged_unsigned(&apdu[0],
|
apdu_len = encode_context_unsigned(&apdu[0], 0,
|
||||||
Requested_Shed_Level[object_index].value.percent);
|
Requested_Shed_Level[object_index].value.percent);
|
||||||
break;
|
break;
|
||||||
case BACNET_SHED_AMOUNT:
|
case BACNET_SHED_TYPE_AMOUNT:
|
||||||
apdu_len = encode_tagged_real(&apdu[0],
|
apdu_len = encode_context_real(&apdu[0], 2,
|
||||||
Requested_Shed_Level[object_index].value.amount);
|
Requested_Shed_Level[object_index].value.amount);
|
||||||
break;
|
break;
|
||||||
case BACNET_SHED_LEVEL:
|
case BACNET_SHED_TYPE_LEVEL:
|
||||||
default:
|
default:
|
||||||
apdu_len = encode_tagged_unsigned(&apdu[0],
|
apdu_len = encode_context_unsigned(&apdu[0], 1,
|
||||||
Requested_Shed_Level[object_index].value.level);
|
Requested_Shed_Level[object_index].value.level);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROP_START_TIME:
|
case PROP_START_TIME:
|
||||||
|
len = encode_tagged_date(&apdu[0],
|
||||||
|
&Load_Control_Start_Time[object_index].date);
|
||||||
|
apdu_len = len;
|
||||||
|
len = encode_tagged_time(&apdu[apdu_len],
|
||||||
|
&Load_Control_Start_Time[object_index].time);
|
||||||
|
apdu_len += len;
|
||||||
|
break;
|
||||||
|
case PROP_SHED_DURATION:
|
||||||
|
apdu_len = encode_tagged_unsigned(&apdu[0],
|
||||||
|
Load_Control_Shed_Duration[object_index]);
|
||||||
|
break;
|
||||||
|
case PROP_DUTY_WINDOW:
|
||||||
|
apdu_len = encode_tagged_unsigned(&apdu[0],
|
||||||
|
Load_Control_Duty_Window[object_index]);
|
||||||
|
break;
|
||||||
|
case PROP_ENABLE:
|
||||||
|
apdu_len = encode_tagged_boolean(&apdu[0],
|
||||||
|
Load_Control_Enable[object_index]);
|
||||||
|
break;
|
||||||
|
case PROP_FULL_DUTY_BASELINE: /* optional */
|
||||||
|
apdu_len = encode_tagged_real(&apdu[0],
|
||||||
|
Full_Duty_Baseline[object_index]);
|
||||||
|
break;
|
||||||
|
case PROP_EXPECTED_SHED_LEVEL:
|
||||||
|
switch (Expected_Shed_Level[object_index].type)
|
||||||
|
{
|
||||||
|
case BACNET_SHED_TYPE_PERCENT:
|
||||||
|
apdu_len = encode_context_unsigned(&apdu[0], 0,
|
||||||
|
Expected_Shed_Level[object_index].value.percent);
|
||||||
|
break;
|
||||||
|
case BACNET_SHED_TYPE_AMOUNT:
|
||||||
|
apdu_len = encode_context_real(&apdu[0], 2,
|
||||||
|
Expected_Shed_Level[object_index].value.amount);
|
||||||
|
break;
|
||||||
|
case BACNET_SHED_TYPE_LEVEL:
|
||||||
|
default:
|
||||||
|
apdu_len = encode_context_unsigned(&apdu[0], 1,
|
||||||
|
Expected_Shed_Level[object_index].value.level);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PROP_ACTUAL_SHED_LEVEL:
|
||||||
|
switch (Actual_Shed_Level[object_index].type)
|
||||||
|
{
|
||||||
|
case BACNET_SHED_TYPE_PERCENT:
|
||||||
|
apdu_len = encode_context_unsigned(&apdu[0], 0,
|
||||||
|
Actual_Shed_Level[object_index].value.percent);
|
||||||
|
break;
|
||||||
|
case BACNET_SHED_TYPE_AMOUNT:
|
||||||
|
apdu_len = encode_context_real(&apdu[0], 2,
|
||||||
|
Actual_Shed_Level[object_index].value.amount);
|
||||||
|
break;
|
||||||
|
case BACNET_SHED_TYPE_LEVEL:
|
||||||
|
default:
|
||||||
|
apdu_len = encode_context_unsigned(&apdu[0], 1,
|
||||||
|
Actual_Shed_Level[object_index].value.level);
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -300,7 +372,6 @@ int Load_Control_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
/* if no index was specified, then try to encode the entire list */
|
/* if no index was specified, then try to encode the entire list */
|
||||||
/* into one packet. */
|
/* into one packet. */
|
||||||
else if (array_index == BACNET_ARRAY_ALL) {
|
else if (array_index == BACNET_ARRAY_ALL) {
|
||||||
object_index = Load_Control_Instance_To_Index(object_instance);
|
|
||||||
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
|
for (i = 0; i < BACNET_MAX_PRIORITY; i++) {
|
||||||
/* FIXME: check if we have room before adding it to APDU */
|
/* FIXME: check if we have room before adding it to APDU */
|
||||||
if (Load_Control_Level[object_index][i] ==
|
if (Load_Control_Level[object_index][i] ==
|
||||||
@@ -321,7 +392,6 @@ int Load_Control_Encode_Property_APDU(uint8_t * apdu,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
object_index = Load_Control_Instance_To_Index(object_instance);
|
|
||||||
if (array_index <= BACNET_MAX_PRIORITY) {
|
if (array_index <= BACNET_MAX_PRIORITY) {
|
||||||
if (Load_Control_Level[object_index][array_index] ==
|
if (Load_Control_Level[object_index][array_index] ==
|
||||||
ANALOG_LEVEL_NULL)
|
ANALOG_LEVEL_NULL)
|
||||||
@@ -369,6 +439,7 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* decode the some of the request */
|
/* decode the some of the request */
|
||||||
|
object_index = Load_Control_Instance_To_Index(wp_data->object_instance);
|
||||||
switch (wp_data->object_property) {
|
switch (wp_data->object_property) {
|
||||||
case PROP_PRESENT_VALUE:
|
case PROP_PRESENT_VALUE:
|
||||||
if (wp_data->value.tag == BACNET_APPLICATION_TAG_REAL) {
|
if (wp_data->value.tag == BACNET_APPLICATION_TAG_REAL) {
|
||||||
@@ -381,9 +452,6 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
(wp_data->value.type.Real >= 0.0) &&
|
(wp_data->value.type.Real >= 0.0) &&
|
||||||
(wp_data->value.type.Real <= 100.0)) {
|
(wp_data->value.type.Real <= 100.0)) {
|
||||||
level = (uint8_t) wp_data->value.type.Real;
|
level = (uint8_t) wp_data->value.type.Real;
|
||||||
object_index =
|
|
||||||
Load_Control_Instance_To_Index(wp_data->
|
|
||||||
object_instance);
|
|
||||||
priority--;
|
priority--;
|
||||||
Load_Control_Level[object_index][priority] = level;
|
Load_Control_Level[object_index][priority] = level;
|
||||||
/* Note: you could set the physical output here if we
|
/* Note: you could set the physical output here if we
|
||||||
@@ -404,8 +472,6 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
}
|
}
|
||||||
} else if (wp_data->value.tag == BACNET_APPLICATION_TAG_NULL) {
|
} else if (wp_data->value.tag == BACNET_APPLICATION_TAG_NULL) {
|
||||||
level = ANALOG_LEVEL_NULL;
|
level = ANALOG_LEVEL_NULL;
|
||||||
object_index =
|
|
||||||
Load_Control_Instance_To_Index(wp_data->object_instance);
|
|
||||||
priority = wp_data->priority;
|
priority = wp_data->priority;
|
||||||
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
|
if (priority && (priority <= BACNET_MAX_PRIORITY)) {
|
||||||
priority--;
|
priority--;
|
||||||
@@ -428,8 +494,6 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data,
|
|||||||
break;
|
break;
|
||||||
case PROP_OUT_OF_SERVICE:
|
case PROP_OUT_OF_SERVICE:
|
||||||
if (wp_data->value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
|
if (wp_data->value.tag == BACNET_APPLICATION_TAG_BOOLEAN) {
|
||||||
object_index =
|
|
||||||
Load_Control_Instance_To_Index(wp_data->object_instance);
|
|
||||||
Load_Control_Out_Of_Service[object_index] =
|
Load_Control_Out_Of_Service[object_index] =
|
||||||
wp_data->value.type.Boolean;
|
wp_data->value.type.Boolean;
|
||||||
status = true;
|
status = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user