From fc3074b8fa4eeb95c3140c02700238bceff3850a Mon Sep 17 00:00:00 2001 From: skarg Date: Tue, 23 Jan 2007 21:44:29 +0000 Subject: [PATCH] Adding Load Control object state machine - not finished. --- bacnet-stack/demo/object/lc.c | 75 +++++++++++++++++++++++++++----- bacnet-stack/demo/object/lc.ide | Bin 0 -> 34682 bytes 2 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 bacnet-stack/demo/object/lc.ide diff --git a/bacnet-stack/demo/object/lc.c b/bacnet-stack/demo/object/lc.c index a7a26091..79c6e9d5 100644 --- a/bacnet-stack/demo/object/lc.c +++ b/bacnet-stack/demo/object/lc.c @@ -29,8 +29,10 @@ #include #include #include /* for memcpy */ +#include #include "bacdef.h" #include "bacdcode.h" +#include "datetime.h" #include "bacenum.h" #include "config.h" /* the custom stuff */ #include "lc.h" @@ -48,7 +50,7 @@ typedef enum BACnetShedLevelType { BACNET_SHED_TYPE_AMOUNT /* REAL */ } BACNET_SHED_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. */ #define MAX_SHED_LEVELS 3 typedef struct { @@ -71,7 +73,9 @@ static BACNET_SHED_LEVEL Actual_Shed_Level[MAX_LOAD_CONTROLS]; /* indicates the start of the duty window in which the load controlled by the Load Control object must be compliant with the requested shed. */ static BACNET_DATE_TIME Start_Time[MAX_LOAD_CONTROLS]; +static BACNET_DATE_TIME End_Time[MAX_LOAD_CONTROLS]; static BACNET_DATE_TIME Previous_Start_Time[MAX_LOAD_CONTROLS]; +static BACNET_DATE_TIME Current_Time; /* indicates the duration of the load shed action, starting at Start_Time in minutes */ @@ -118,8 +122,8 @@ void Load_Control_Init(void) Present_Value[i] = BACNET_SHED_INACTIVE; Requested_Shed_Level[i].type = BACNET_SHED_TYPE_LEVEL; Requested_Shed_Level[i].value.level = 0; - bacapp_set_datetime_values( - &Start_Time[i],0,0,0,0,0,0,0,0); + datetime_set_values(&Start_Time[i],0,0,0,0,0,0,0); + datetime_set_values(&Previous_Start_Time[i],0,0,0,0,0,0,0); Shed_Duration[i] = 0; Duty_Window[i] = 0; Load_Control_Enable[i] = true; @@ -209,6 +213,38 @@ char *Load_Control_Name(uint32_t object_instance) return NULL; } +static void Update_Current_Time(BACNET_DATE_TIME * bdatetime) +{ + time_t timer; + struct tm *tblock; + +/* +struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +}; +*/ + + timer = time(NULL); + tblock = localtime(&timer); + datetime_set_values( + bdatetime, + tblock->tm_year, + tblock->tm_mon, + tblock->tm_mday, + tblock->tm_hour, + tblock->tm_min, + tblock->tm_sec, + 0); +} + typedef enum load_control_state { SHED_INACTIVE, @@ -217,11 +253,12 @@ typedef enum load_control_state SHED_COMPLIANT } LOAD_CONTROL_STATE; -void Load_Control_State_Machine_Handler(int object_index) +void Load_Control_State_Machine(int object_index) { static LOAD_CONTROL_STATE state[MAX_LOAD_CONTROLS]; static initialized = false; unsigned i = 0; /* loop counter */ + int diff = 0; /* used for datetime comparison */ if (!initialized) { initialized = true; @@ -233,9 +270,21 @@ void Load_Control_State_Machine_Handler(int object_index) switch (state[object_index]) { case SHED_REQUEST_PENDING: - /* CancelShed */ - + Update_Current_Time(&Current_Time); + datetime_copy(&End_Time[object_index],&Start_Time[object_index]); + datetime_add_minutes(&End_Time[object_index], Shed_Duration[object_index]); + diff = datetime_compare(&End_Time[object_index],&Current_Time); + if (diff < 0) { + /* CancelShed */ + /* FIXME: stop shedding! i.e. relinquish */ + state[object_index] = SHED_INACTIVE; + break; + } + diff = datetime_compare(&Current_Time, &Start_Time[object_index]); + /* current time prior to start time */ + if (diff < 0) { + } break; case SHED_NON_COMPLIANT: break; @@ -243,8 +292,11 @@ void Load_Control_State_Machine_Handler(int object_index) break; case SHED_INACTIVE: default: - if (!bacapp_same_datetime(&Start_Time[object_index], - &Previous_Start_Time[object_index])) { + diff = datetime_compare(&Previous_Start_Time[object_index], + &Start_Time[object_index]); + if (diff != 0) { + datetime_copy(&Previous_Start_Time[object_index], + &Start_Time[object_index]); /* FIXME: calculate your Expected Shed Level */ /* FIXME: calculate your Actual Shed Level */ Expected_Shed_Level[object_index].type = @@ -277,12 +329,12 @@ void Load_Control_State_Machine_Handler(int object_index) } /* call every second or so */ -void Load_Control_State_Machine(void) +void Load_Control_State_Machine_Handler(void) { unsigned i = 0; for (i = 0; i < MAX_LOAD_CONTROLS; i++) { - Load_Control_State_Machine_Handler(i); + Load_Control_State_Machine(i); } } @@ -643,7 +695,6 @@ bool Load_Control_Write_Property(BACNET_WRITE_PROPERTY_DATA * wp_data, return status; } - #ifdef TEST #include #include @@ -695,5 +746,5 @@ int main(void) return 0; } -#endif /* TEST_ANALOG_VALUE */ +#endif /* TEST_LOAD_CONTROL */ #endif /* TEST */ diff --git a/bacnet-stack/demo/object/lc.ide b/bacnet-stack/demo/object/lc.ide new file mode 100644 index 0000000000000000000000000000000000000000..d5f5fbcf7c2dfa7558c1ab0ea94579345f550b09 GIT binary patch literal 34682 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 literal 0 HcmV?d00001