Erick / Mbed 2 deprecated ICE-F412

Dependencies:   mbed-rtos mbed

Committer:
jmarkel44
Date:
Tue Jan 24 19:05:33 2017 +0000
Revision:
0:61364762ee0e
Port from IAR to Nucleo-F412 board

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jmarkel44 0:61364762ee0e 1 /******************************************************************************
jmarkel44 0:61364762ee0e 2 *
jmarkel44 0:61364762ee0e 3 * File: TimerControl.cpp
jmarkel44 0:61364762ee0e 4 * Desciption: ICE Timer Control Class implementation
jmarkel44 0:61364762ee0e 5 *
jmarkel44 0:61364762ee0e 6 *****************************************************************************/
jmarkel44 0:61364762ee0e 7 #include "TimerControl.h"
jmarkel44 0:61364762ee0e 8 #include "ModbusMasterApi.h"
jmarkel44 0:61364762ee0e 9 #include "ICELog.h"
jmarkel44 0:61364762ee0e 10 #include "cJSON.h"
jmarkel44 0:61364762ee0e 11 #include "global.h"
jmarkel44 0:61364762ee0e 12 #include "timerUtils.h"
jmarkel44 0:61364762ee0e 13 #include "utilities.h"
jmarkel44 0:61364762ee0e 14 #include <string>
jmarkel44 0:61364762ee0e 15 #include <iostream>
jmarkel44 0:61364762ee0e 16 #include <iomanip>
jmarkel44 0:61364762ee0e 17
jmarkel44 0:61364762ee0e 18 // for debugging - this can be set via the console command:
jmarkel44 0:61364762ee0e 19 // "debug-sp 1 or debug-sp 0
jmarkel44 0:61364762ee0e 20 bool debugTimerControl = false;
jmarkel44 0:61364762ee0e 21
jmarkel44 0:61364762ee0e 22 static void debug(const char *fmt, ...)
jmarkel44 0:61364762ee0e 23 {
jmarkel44 0:61364762ee0e 24 if ( debugTimerControl ) {
jmarkel44 0:61364762ee0e 25 va_list vargs;
jmarkel44 0:61364762ee0e 26 va_start(vargs, fmt);
jmarkel44 0:61364762ee0e 27 vfprintf(stdout, fmt, vargs);
jmarkel44 0:61364762ee0e 28 va_end(vargs);
jmarkel44 0:61364762ee0e 29 }
jmarkel44 0:61364762ee0e 30 }
jmarkel44 0:61364762ee0e 31
jmarkel44 0:61364762ee0e 32 #ifdef MDOT_ICE
jmarkel44 0:61364762ee0e 33 extern mDot *GLOBAL_mdot;
jmarkel44 0:61364762ee0e 34 #endif
jmarkel44 0:61364762ee0e 35
jmarkel44 0:61364762ee0e 36 //
jmarkel44 0:61364762ee0e 37 // method: load
jmarkel44 0:61364762ee0e 38 // description: load the pertinents from the control file
jmarkel44 0:61364762ee0e 39 //
jmarkel44 0:61364762ee0e 40 // @param _controlFile
jmarkel44 0:61364762ee0e 41 // @return true if loaded; false otherwise
jmarkel44 0:61364762ee0e 42 //
jmarkel44 0:61364762ee0e 43 bool TimerControl::load(std::string _controlFile)
jmarkel44 0:61364762ee0e 44 {
jmarkel44 0:61364762ee0e 45 controlFile = _controlFile;
jmarkel44 0:61364762ee0e 46
jmarkel44 0:61364762ee0e 47 char dataBuf[MAX_FILE_SIZE];
jmarkel44 0:61364762ee0e 48 // read the control data
jmarkel44 0:61364762ee0e 49 bool rc = GLOBAL_mdot->readUserFile(controlFile.c_str(), (void *)dataBuf, sizeof(dataBuf));
jmarkel44 0:61364762ee0e 50 if ( rc != true ) {
jmarkel44 0:61364762ee0e 51 logError("%s: failed to read %s", __func__, controlFile.c_str());
jmarkel44 0:61364762ee0e 52 return false;
jmarkel44 0:61364762ee0e 53 }
jmarkel44 0:61364762ee0e 54
jmarkel44 0:61364762ee0e 55 // validate the control data
jmarkel44 0:61364762ee0e 56 if ( !validateControlData(dataBuf) ) {
jmarkel44 0:61364762ee0e 57 logError("%s: failed to validate control data", __func__);
jmarkel44 0:61364762ee0e 58 return false;
jmarkel44 0:61364762ee0e 59 }
jmarkel44 0:61364762ee0e 60
jmarkel44 0:61364762ee0e 61 // copy the control data
jmarkel44 0:61364762ee0e 62 copyControlData(dataBuf);
jmarkel44 0:61364762ee0e 63
jmarkel44 0:61364762ee0e 64 ModbusValue val;
jmarkel44 0:61364762ee0e 65 // validate the output
jmarkel44 0:61364762ee0e 66 if ( ModbusMasterReadRegister(output, &val) == false ) {
jmarkel44 0:61364762ee0e 67 logError("%s failed to find %s", id.c_str(), output.c_str());
jmarkel44 0:61364762ee0e 68 return false;
jmarkel44 0:61364762ee0e 69 }
jmarkel44 0:61364762ee0e 70
jmarkel44 0:61364762ee0e 71 isVirtualOutput = Util_isVirtualOutput(output) ? true : false;
jmarkel44 0:61364762ee0e 72
jmarkel44 0:61364762ee0e 73 return true;
jmarkel44 0:61364762ee0e 74
jmarkel44 0:61364762ee0e 75 }
jmarkel44 0:61364762ee0e 76
jmarkel44 0:61364762ee0e 77 //
jmarkel44 0:61364762ee0e 78 // method: validateControlData
jmarkel44 0:61364762ee0e 79 // description: validates the data in the control file
jmarkel44 0:61364762ee0e 80 //
jmarkel44 0:61364762ee0e 81 // @param[in] dataBuf -> JSON formatted string
jmarkel44 0:61364762ee0e 82 // @param[out] non
jmarkel44 0:61364762ee0e 83 // @return true if valid; false otherwise
jmarkel44 0:61364762ee0e 84 //
jmarkel44 0:61364762ee0e 85 bool TimerControl::validateControlData(const char *buf)
jmarkel44 0:61364762ee0e 86 {
jmarkel44 0:61364762ee0e 87 bool rc = true;
jmarkel44 0:61364762ee0e 88 cJSON * root = cJSON_Parse(buf);
jmarkel44 0:61364762ee0e 89
jmarkel44 0:61364762ee0e 90 if ( !cJSON_HasObjectItem(root, "id") ||
jmarkel44 0:61364762ee0e 91 !cJSON_HasObjectItem(root, "output") ||
jmarkel44 0:61364762ee0e 92 !cJSON_HasObjectItem(root, "priority") ||
jmarkel44 0:61364762ee0e 93 !cJSON_HasObjectItem(root, "day") ||
jmarkel44 0:61364762ee0e 94 !cJSON_HasObjectItem(root, "startHour") ||
jmarkel44 0:61364762ee0e 95 !cJSON_HasObjectItem(root, "startMin") ||
jmarkel44 0:61364762ee0e 96 !cJSON_HasObjectItem(root, "startSec") ||
jmarkel44 0:61364762ee0e 97 !cJSON_HasObjectItem(root, "duration") ||
jmarkel44 0:61364762ee0e 98 !cJSON_HasObjectItem(root, "week")) {
jmarkel44 0:61364762ee0e 99 logError("%s: control file is missing expected tags", __func__);
jmarkel44 0:61364762ee0e 100 rc = false;
jmarkel44 0:61364762ee0e 101 }
jmarkel44 0:61364762ee0e 102 cJSON_Delete(root);
jmarkel44 0:61364762ee0e 103 return rc;
jmarkel44 0:61364762ee0e 104 }
jmarkel44 0:61364762ee0e 105
jmarkel44 0:61364762ee0e 106 //
jmarkel44 0:61364762ee0e 107 // method: copyControlData
jmarkel44 0:61364762ee0e 108 // description: copy JSON formatted control data to object
jmarkel44 0:61364762ee0e 109 //
jmarkel44 0:61364762ee0e 110 // @param[in] dataBuf -> JSON formatted data
jmarkel44 0:61364762ee0e 111 // @param[out] none
jmarkel44 0:61364762ee0e 112 // @return none
jmarkel44 0:61364762ee0e 113 //
jmarkel44 0:61364762ee0e 114 void TimerControl::copyControlData(const char *buf)
jmarkel44 0:61364762ee0e 115 {
jmarkel44 0:61364762ee0e 116 cJSON *root = cJSON_Parse(buf);
jmarkel44 0:61364762ee0e 117
jmarkel44 0:61364762ee0e 118 id = cJSON_GetObjectItem(root,"id")->valuestring;
jmarkel44 0:61364762ee0e 119 output = cJSON_GetObjectItem(root, "output")->valuestring;
jmarkel44 0:61364762ee0e 120 priority = (unsigned int)atoi(cJSON_GetObjectItem(root, "priority")->valuestring);
jmarkel44 0:61364762ee0e 121 std::string day_str = cJSON_GetObjectItem(root, "day")->valuestring;
jmarkel44 0:61364762ee0e 122
jmarkel44 0:61364762ee0e 123 if ( day_str == "sun" ) {
jmarkel44 0:61364762ee0e 124 day = DAY_SCHEDULE_SUNDAY_MASK;
jmarkel44 0:61364762ee0e 125 } else if ( day_str == "mon" ) {
jmarkel44 0:61364762ee0e 126 day = DAY_SCHEDULE_MONDAY_MASK;
jmarkel44 0:61364762ee0e 127 } else if ( day_str == "tue" ) {
jmarkel44 0:61364762ee0e 128 day = DAY_SCHEDULE_TUESDAY_MASK;
jmarkel44 0:61364762ee0e 129 } else if ( day_str == "wed" ) {
jmarkel44 0:61364762ee0e 130 day = DAY_SCHEDULE_WEDNESDAY_MASK;
jmarkel44 0:61364762ee0e 131 } else if ( day_str == "thu" ) {
jmarkel44 0:61364762ee0e 132 day = DAY_SCHEDULE_THURSDAY_MASK;
jmarkel44 0:61364762ee0e 133 } else if ( day_str == "fri" ) {
jmarkel44 0:61364762ee0e 134 day = DAY_SCHEDULE_FRIDAY_MASK;
jmarkel44 0:61364762ee0e 135 } else if ( day_str == "sat" ) {
jmarkel44 0:61364762ee0e 136 day = DAY_SCHEDULE_SATURDAY_MASK;
jmarkel44 0:61364762ee0e 137 } else {
jmarkel44 0:61364762ee0e 138 debug("\r%s:%s-> one-shot timer found\n", __func__, id.c_str());
jmarkel44 0:61364762ee0e 139 day = DAY_SCHEDULE_NOT_SPECIFIED; // one-shot timer
jmarkel44 0:61364762ee0e 140 }
jmarkel44 0:61364762ee0e 141
jmarkel44 0:61364762ee0e 142 startHour = atoi(cJSON_GetObjectItem(root, "startHour")->valuestring);
jmarkel44 0:61364762ee0e 143 startMin = atoi(cJSON_GetObjectItem(root, "startMin")->valuestring);
jmarkel44 0:61364762ee0e 144 startSec = atoi(cJSON_GetObjectItem(root, "startSec")->valuestring);
jmarkel44 0:61364762ee0e 145 duration = atoi(cJSON_GetObjectItem(root, "duration")->valuestring);
jmarkel44 0:61364762ee0e 146
jmarkel44 0:61364762ee0e 147 std::string week_str = cJSON_GetObjectItem(root, "week")->valuestring;
jmarkel44 0:61364762ee0e 148 if ( week_str == "every" ) {
jmarkel44 0:61364762ee0e 149 week = WEEKLY_CHOICE_EVERY_WEEK;
jmarkel44 0:61364762ee0e 150 } else if ( week_str == "first" ) {
jmarkel44 0:61364762ee0e 151 week = WEEKLY_CHOICE_FIRST_WEEK;
jmarkel44 0:61364762ee0e 152 } else if ( week_str == "second" ) {
jmarkel44 0:61364762ee0e 153 week = WEEKLY_CHOICE_SECOND_WEEK;
jmarkel44 0:61364762ee0e 154 } else if ( week_str == "third" ) {
jmarkel44 0:61364762ee0e 155 week = WEEKLY_CHOICE_THIRD_WEEK;
jmarkel44 0:61364762ee0e 156 } else if ( week_str == "fourth" ) {
jmarkel44 0:61364762ee0e 157 week = WEEKLY_CHOICE_FOURTH_WEEK;
jmarkel44 0:61364762ee0e 158 } else if ( week_str == "last" ) {
jmarkel44 0:61364762ee0e 159 week = WEEKLY_CHOICE_LAST_WEEK;
jmarkel44 0:61364762ee0e 160 } else if ( week_str == "everyother") {
jmarkel44 0:61364762ee0e 161 week = WEEKLY_CHOICE_EVERYOTHER_WEEK;
jmarkel44 0:61364762ee0e 162 } else {
jmarkel44 0:61364762ee0e 163 week = WEEKLY_CHOICE_NOT_SPECIFIED; // one-shot timer
jmarkel44 0:61364762ee0e 164 }
jmarkel44 0:61364762ee0e 165
jmarkel44 0:61364762ee0e 166 cJSON_Delete(root);
jmarkel44 0:61364762ee0e 167 }
jmarkel44 0:61364762ee0e 168
jmarkel44 0:61364762ee0e 169 //
jmarkel44 0:61364762ee0e 170 // method: start
jmarkel44 0:61364762ee0e 171 // description: initialize the control
jmarkel44 0:61364762ee0e 172 //
jmarkel44 0:61364762ee0e 173 // @param none
jmarkel44 0:61364762ee0e 174 // @return none
jmarkel44 0:61364762ee0e 175 //
jmarkel44 0:61364762ee0e 176 void TimerControl::start(void)
jmarkel44 0:61364762ee0e 177 {
jmarkel44 0:61364762ee0e 178 // calculate the next scheduled start time
jmarkel44 0:61364762ee0e 179 if ( day == DAY_SCHEDULE_NOT_SPECIFIED ) {
jmarkel44 0:61364762ee0e 180 // start running right away
jmarkel44 0:61364762ee0e 181 nextScheduledStartTime = time(0);
jmarkel44 0:61364762ee0e 182 debug("\r%s: %s is a one-shot timer.\n", __func__, id.c_str());
jmarkel44 0:61364762ee0e 183 } else {
jmarkel44 0:61364762ee0e 184 nextScheduledStartTime = time(0) + calcStartTime();
jmarkel44 0:61364762ee0e 185 }
jmarkel44 0:61364762ee0e 186 struct tm * timeinfo;
jmarkel44 0:61364762ee0e 187 timeinfo = localtime((time_t*)&nextScheduledStartTime);
jmarkel44 0:61364762ee0e 188 debug("Timer %s started, begins at %s", this->id.c_str(), asctime(timeinfo));
jmarkel44 0:61364762ee0e 189
jmarkel44 0:61364762ee0e 190 currentState = STATE_OFF;
jmarkel44 0:61364762ee0e 191 }
jmarkel44 0:61364762ee0e 192
jmarkel44 0:61364762ee0e 193 //
jmarkel44 0:61364762ee0e 194 // method: update
jmarkel44 0:61364762ee0e 195 // description: run the state machine
jmarkel44 0:61364762ee0e 196 //
jmarkel44 0:61364762ee0e 197 // @param none
jmarkel44 0:61364762ee0e 198 // @return OK on success; error otherwise
jmarkel44 0:61364762ee0e 199 //
jmarkel44 0:61364762ee0e 200 TimerControlError_t TimerControl::update(void)
jmarkel44 0:61364762ee0e 201 {
jmarkel44 0:61364762ee0e 202 TimerControlError_t rc = TIMER_CONTROL_OK;
jmarkel44 0:61364762ee0e 203
jmarkel44 0:61364762ee0e 204 unsigned long currentTime = time(0);
jmarkel44 0:61364762ee0e 205
jmarkel44 0:61364762ee0e 206 switch ( this->currentState ) {
jmarkel44 0:61364762ee0e 207 case STATE_INIT:
jmarkel44 0:61364762ee0e 208 // do nothing; timer is waiting for start signal
jmarkel44 0:61364762ee0e 209 break;
jmarkel44 0:61364762ee0e 210 case STATE_OFF: {
jmarkel44 0:61364762ee0e 211 if ( currentTime >= nextScheduledStartTime &&
jmarkel44 0:61364762ee0e 212 currentTime <= nextScheduledStartTime + duration ) {
jmarkel44 0:61364762ee0e 213 currentState = STATE_RUNNING;
jmarkel44 0:61364762ee0e 214 this->startFeed();
jmarkel44 0:61364762ee0e 215 startTime = currentTime; // record the actual start time
jmarkel44 0:61364762ee0e 216 debug("\r%s: [OFF]->in timing window->[RUNNING] %s\n", id.c_str(), displayTime());
jmarkel44 0:61364762ee0e 217 }
jmarkel44 0:61364762ee0e 218 break;
jmarkel44 0:61364762ee0e 219 }
jmarkel44 0:61364762ee0e 220 case STATE_RUNNING:
jmarkel44 0:61364762ee0e 221 if ( currentTime >= startTime + duration ) {
jmarkel44 0:61364762ee0e 222 this->stopFeed();
jmarkel44 0:61364762ee0e 223 currentState = STATE_FINISHED;
jmarkel44 0:61364762ee0e 224 debug("\r%s: [RUNNING]->time elapsed->[OFF] %s\n", id.c_str(), displayTime());
jmarkel44 0:61364762ee0e 225 }
jmarkel44 0:61364762ee0e 226 break;
jmarkel44 0:61364762ee0e 227 case STATE_FINISHED:
jmarkel44 0:61364762ee0e 228 if ( day == DAY_SCHEDULE_NOT_SPECIFIED || week == WEEKLY_CHOICE_NOT_SPECIFIED ) {
jmarkel44 0:61364762ee0e 229 // one shot-timer, just disable it.
jmarkel44 0:61364762ee0e 230 nextScheduledStartTime = 0;
jmarkel44 0:61364762ee0e 231 startTime = 0;
jmarkel44 0:61364762ee0e 232 currentState = STATE_DISABLED;
jmarkel44 0:61364762ee0e 233 debug("\r%s: [FINISHED]->one shot timer->[DISABLED] %s\n", id.c_str(), displayTime());
jmarkel44 0:61364762ee0e 234 } else {
jmarkel44 0:61364762ee0e 235 // calculate the next scheduled start time
jmarkel44 0:61364762ee0e 236 nextScheduledStartTime = time(0) + calcStartTime();
jmarkel44 0:61364762ee0e 237 startTime = 0;
jmarkel44 0:61364762ee0e 238 // unregister with the output task
jmarkel44 0:61364762ee0e 239 currentState = STATE_OFF;
jmarkel44 0:61364762ee0e 240 debug("\r%s: [FINISHED]->time elapsed->[OFF] %s\n", id.c_str(), displayTime());
jmarkel44 0:61364762ee0e 241 }
jmarkel44 0:61364762ee0e 242 this->unregisterControl();
jmarkel44 0:61364762ee0e 243 break;
jmarkel44 0:61364762ee0e 244 case STATE_DISABLED:
jmarkel44 0:61364762ee0e 245 // do nothing
jmarkel44 0:61364762ee0e 246 break;
jmarkel44 0:61364762ee0e 247 default:
jmarkel44 0:61364762ee0e 248 logError("%s: unknown state %d", __func__, this->currentState);
jmarkel44 0:61364762ee0e 249 rc = TIMER_CONTROL_UNK_STATE;
jmarkel44 0:61364762ee0e 250 break;
jmarkel44 0:61364762ee0e 251 }
jmarkel44 0:61364762ee0e 252 return rc;
jmarkel44 0:61364762ee0e 253 }
jmarkel44 0:61364762ee0e 254
jmarkel44 0:61364762ee0e 255 //
jmarkel44 0:61364762ee0e 256 // method: startFeed
jmarkel44 0:61364762ee0e 257 // description: signal the output thread to start a feed
jmarkel44 0:61364762ee0e 258 //
jmarkel44 0:61364762ee0e 259 // @param none
jmarkel44 0:61364762ee0e 260 // @return none
jmarkel44 0:61364762ee0e 261 void TimerControl::startFeed(void)
jmarkel44 0:61364762ee0e 262 {
jmarkel44 0:61364762ee0e 263 logInfo("%s: %s attempting to start feed on relay %s\n",
jmarkel44 0:61364762ee0e 264 __func__, controlFile.c_str(), output.c_str());
jmarkel44 0:61364762ee0e 265
jmarkel44 0:61364762ee0e 266 if ( isVirtualOutput ) {
jmarkel44 0:61364762ee0e 267 // write to the virtual register map
jmarkel44 0:61364762ee0e 268 ModbusMasterWriteRegister(output, 1.0);
jmarkel44 0:61364762ee0e 269 } else {
jmarkel44 0:61364762ee0e 270 // send a message to the output thread
jmarkel44 0:61364762ee0e 271 OutputControlMsg_t *output_mail = OutputMasterMailBox.alloc();
jmarkel44 0:61364762ee0e 272 memset(output_mail, 0, sizeof(OutputControlMsg_t));
jmarkel44 0:61364762ee0e 273
jmarkel44 0:61364762ee0e 274 output_mail->action = ACTION_CONTROL_ON;
jmarkel44 0:61364762ee0e 275 output_mail->controlType = CONTROL_TIMER;
jmarkel44 0:61364762ee0e 276 output_mail->priority = priority;
jmarkel44 0:61364762ee0e 277
jmarkel44 0:61364762ee0e 278 strncpy(output_mail->output_tag, this->output.c_str(), sizeof(output_mail->output_tag)-1);
jmarkel44 0:61364762ee0e 279 strncpy(output_mail->id, this->id.c_str(), sizeof(output_mail->id)-1);
jmarkel44 0:61364762ee0e 280 OutputMasterMailBox.put(output_mail);
jmarkel44 0:61364762ee0e 281 }
jmarkel44 0:61364762ee0e 282 }
jmarkel44 0:61364762ee0e 283
jmarkel44 0:61364762ee0e 284 //
jmarkel44 0:61364762ee0e 285 // method: stopFeed
jmarkel44 0:61364762ee0e 286 // description: signal the output thread to stop a feed
jmarkel44 0:61364762ee0e 287 //
jmarkel44 0:61364762ee0e 288 // @param none
jmarkel44 0:61364762ee0e 289 // @return none
jmarkel44 0:61364762ee0e 290 //
jmarkel44 0:61364762ee0e 291 void TimerControl::stopFeed(void)
jmarkel44 0:61364762ee0e 292 {
jmarkel44 0:61364762ee0e 293 logInfo("%s: %s attempting to start feed on relay %s\n",
jmarkel44 0:61364762ee0e 294 __func__, controlFile.c_str(), output.c_str());
jmarkel44 0:61364762ee0e 295
jmarkel44 0:61364762ee0e 296 if ( isVirtualOutput ) {
jmarkel44 0:61364762ee0e 297 // write to the virtual register map
jmarkel44 0:61364762ee0e 298 ModbusMasterWriteRegister(output, 0.0);
jmarkel44 0:61364762ee0e 299 } else {
jmarkel44 0:61364762ee0e 300 // send a message to the output thread
jmarkel44 0:61364762ee0e 301 OutputControlMsg_t *output_mail = OutputMasterMailBox.alloc();
jmarkel44 0:61364762ee0e 302 memset(output_mail, 0, sizeof(OutputControlMsg_t));
jmarkel44 0:61364762ee0e 303
jmarkel44 0:61364762ee0e 304 output_mail->action = ACTION_CONTROL_OFF;
jmarkel44 0:61364762ee0e 305 output_mail->controlType = CONTROL_TIMER;
jmarkel44 0:61364762ee0e 306 output_mail->priority = priority;
jmarkel44 0:61364762ee0e 307
jmarkel44 0:61364762ee0e 308 strncpy(output_mail->output_tag, this->output.c_str(), sizeof(output_mail->output_tag)-1);
jmarkel44 0:61364762ee0e 309 strncpy(output_mail->id, this->id.c_str(), sizeof(output_mail->id)-1);
jmarkel44 0:61364762ee0e 310 OutputMasterMailBox.put(output_mail);
jmarkel44 0:61364762ee0e 311 }
jmarkel44 0:61364762ee0e 312 }
jmarkel44 0:61364762ee0e 313
jmarkel44 0:61364762ee0e 314 //
jmarkel44 0:61364762ee0e 315 // method: unregisterControl
jmarkel44 0:61364762ee0e 316 // description: send OFF indication to Output Master for this control's
jmarkel44 0:61364762ee0e 317 // relay
jmarkel44 0:61364762ee0e 318 //
jmarkel44 0:61364762ee0e 319 // @param none
jmarkel44 0:61364762ee0e 320 // @return none
jmarkel44 0:61364762ee0e 321 //
jmarkel44 0:61364762ee0e 322 void TimerControl::unregisterControl(void)
jmarkel44 0:61364762ee0e 323 {
jmarkel44 0:61364762ee0e 324 logInfo("%s: %s attempting to unregister %s\n",
jmarkel44 0:61364762ee0e 325 __func__, id.c_str(), controlFile.c_str());
jmarkel44 0:61364762ee0e 326
jmarkel44 0:61364762ee0e 327 if ( isVirtualOutput ) {
jmarkel44 0:61364762ee0e 328 ModbusMasterWriteRegister(output, 0.0);
jmarkel44 0:61364762ee0e 329 } else {
jmarkel44 0:61364762ee0e 330
jmarkel44 0:61364762ee0e 331 OutputControlMsg_t *output_mail = OutputMasterMailBox.alloc();
jmarkel44 0:61364762ee0e 332 memset(output_mail, 0, sizeof(OutputControlMsg_t));
jmarkel44 0:61364762ee0e 333
jmarkel44 0:61364762ee0e 334 output_mail->action = ACTION_CONTROL_UNREGISTER;
jmarkel44 0:61364762ee0e 335 output_mail->controlType = CONTROL_TIMER;
jmarkel44 0:61364762ee0e 336 output_mail->priority = priority;
jmarkel44 0:61364762ee0e 337 strncpy(output_mail->output_tag, this->output.c_str(), sizeof(output_mail->output_tag)-1);
jmarkel44 0:61364762ee0e 338 strncpy(output_mail->id, this->id.c_str(), sizeof(output_mail->id)-1);
jmarkel44 0:61364762ee0e 339
jmarkel44 0:61364762ee0e 340 OutputMasterMailBox.put(output_mail);
jmarkel44 0:61364762ee0e 341 }
jmarkel44 0:61364762ee0e 342 }
jmarkel44 0:61364762ee0e 343
jmarkel44 0:61364762ee0e 344 //
jmarkel44 0:61364762ee0e 345 // method: calcStarTime
jmarkel44 0:61364762ee0e 346 // description: calculate the number of seconds until the next
jmarkel44 0:61364762ee0e 347 // timer starts.
jmarkel44 0:61364762ee0e 348 //
jmarkel44 0:61364762ee0e 349 // @param[in] none
jmarkel44 0:61364762ee0e 350 // @param[out] none
jmarkel44 0:61364762ee0e 351 // @return none
jmarkel44 0:61364762ee0e 352 //
jmarkel44 0:61364762ee0e 353 unsigned long TimerControl::calcStartTime(void) const
jmarkel44 0:61364762ee0e 354 {
jmarkel44 0:61364762ee0e 355 TSC_SCHED_ELEM schedTimeDate;
jmarkel44 0:61364762ee0e 356 TSC_SCHED_ELEM pNowTimeDate;
jmarkel44 0:61364762ee0e 357 unsigned long pDiffInSeconds;
jmarkel44 0:61364762ee0e 358 CNTL_HR_MIN_STRUCT startTime;
jmarkel44 0:61364762ee0e 359
jmarkel44 0:61364762ee0e 360 startTime.hour = startHour;
jmarkel44 0:61364762ee0e 361 startTime.minute = startMin;
jmarkel44 0:61364762ee0e 362 startTime.second = startSec;
jmarkel44 0:61364762ee0e 363
jmarkel44 0:61364762ee0e 364 pNowTimeDate.calTime = time( NULL );
jmarkel44 0:61364762ee0e 365 localtime_r( &pNowTimeDate.calTime, &pNowTimeDate.requestTime );
jmarkel44 0:61364762ee0e 366
jmarkel44 0:61364762ee0e 367 pNowTimeDate.schedule.startDate.year = pNowTimeDate.requestTime.tm_year - 100; /* years since 1900 */
jmarkel44 0:61364762ee0e 368 pNowTimeDate.schedule.startDate.year += 2000;
jmarkel44 0:61364762ee0e 369 pNowTimeDate.schedule.startDate.month = pNowTimeDate.requestTime.tm_mon + 1; /* months 1 - 12 */
jmarkel44 0:61364762ee0e 370 pNowTimeDate.schedule.startDate.day = pNowTimeDate.requestTime.tm_mday;
jmarkel44 0:61364762ee0e 371 pNowTimeDate.schedule.startTime.hour = pNowTimeDate.requestTime.tm_hour;
jmarkel44 0:61364762ee0e 372 pNowTimeDate.schedule.startTime.minute = pNowTimeDate.requestTime.tm_min;
jmarkel44 0:61364762ee0e 373 pNowTimeDate.schedule.startTime.second = pNowTimeDate.requestTime.tm_sec;
jmarkel44 0:61364762ee0e 374
jmarkel44 0:61364762ee0e 375 /* setup schedTimeDate with the current date, time and the required schedule */
jmarkel44 0:61364762ee0e 376 schedTimeDate.schedule.startDate = pNowTimeDate.schedule.startDate;
jmarkel44 0:61364762ee0e 377 schedTimeDate.schedule.startTime = startTime;
jmarkel44 0:61364762ee0e 378 schedTimeDate.schedule.dailySchedule = day;
jmarkel44 0:61364762ee0e 379 schedTimeDate.schedule.weeklySchedule = (WEEKLY_CHOICES)week;
jmarkel44 0:61364762ee0e 380 schedTimeDate.calTime = pNowTimeDate.calTime;
jmarkel44 0:61364762ee0e 381 schedTimeDate.requestTime = pNowTimeDate.requestTime;
jmarkel44 0:61364762ee0e 382
jmarkel44 0:61364762ee0e 383 TSCutilComputeStartDate( &schedTimeDate );
jmarkel44 0:61364762ee0e 384 Util_dateTimeDiff( &pNowTimeDate.schedule, &schedTimeDate.schedule, &pDiffInSeconds );
jmarkel44 0:61364762ee0e 385
jmarkel44 0:61364762ee0e 386 return pDiffInSeconds;
jmarkel44 0:61364762ee0e 387 }
jmarkel44 0:61364762ee0e 388
jmarkel44 0:61364762ee0e 389 const char* TimerControl::displayTime(void)
jmarkel44 0:61364762ee0e 390 {
jmarkel44 0:61364762ee0e 391 struct tm * timeinfo;
jmarkel44 0:61364762ee0e 392 time_t currentTime = time(0);
jmarkel44 0:61364762ee0e 393 timeinfo = localtime(&currentTime);
jmarkel44 0:61364762ee0e 394 return asctime(timeinfo);
jmarkel44 0:61364762ee0e 395 }
jmarkel44 0:61364762ee0e 396
jmarkel44 0:61364762ee0e 397 //
jmarkel44 0:61364762ee0e 398 // method: display
jmarkel44 0:61364762ee0e 399 // description: display the elements of this timer control object
jmarkel44 0:61364762ee0e 400 //
jmarkel44 0:61364762ee0e 401 // @param none
jmarkel44 0:61364762ee0e 402 // @return none
jmarkel44 0:61364762ee0e 403 //
jmarkel44 0:61364762ee0e 404 void TimerControl::display(void)
jmarkel44 0:61364762ee0e 405 {
jmarkel44 0:61364762ee0e 406 string mapper[] = { "INIT",
jmarkel44 0:61364762ee0e 407 "OFF",
jmarkel44 0:61364762ee0e 408 "RUNNING",
jmarkel44 0:61364762ee0e 409 "FINISHED",
jmarkel44 0:61364762ee0e 410 "DISABLED"
jmarkel44 0:61364762ee0e 411 };
jmarkel44 0:61364762ee0e 412
jmarkel44 0:61364762ee0e 413 printf("\r\n");
jmarkel44 0:61364762ee0e 414 std::string day_str;
jmarkel44 0:61364762ee0e 415 if ( day == DAY_SCHEDULE_SUNDAY_MASK ) {
jmarkel44 0:61364762ee0e 416 day_str = "Sun";
jmarkel44 0:61364762ee0e 417 } else if ( day == DAY_SCHEDULE_MONDAY_MASK ) {
jmarkel44 0:61364762ee0e 418 day_str = "Mon";
jmarkel44 0:61364762ee0e 419 } else if ( day == DAY_SCHEDULE_TUESDAY_MASK ) {
jmarkel44 0:61364762ee0e 420 day_str = "Tue";
jmarkel44 0:61364762ee0e 421 } else if ( day == DAY_SCHEDULE_WEDNESDAY_MASK ) {
jmarkel44 0:61364762ee0e 422 day_str = "Wed";
jmarkel44 0:61364762ee0e 423 } else if ( day == DAY_SCHEDULE_THURSDAY_MASK ) {
jmarkel44 0:61364762ee0e 424 day_str = "Thu";
jmarkel44 0:61364762ee0e 425 } else if ( day == DAY_SCHEDULE_FRIDAY_MASK ) {
jmarkel44 0:61364762ee0e 426 day_str = "Fri";
jmarkel44 0:61364762ee0e 427 } else if ( day == DAY_SCHEDULE_SATURDAY_MASK ) {
jmarkel44 0:61364762ee0e 428 day_str = "Sat";
jmarkel44 0:61364762ee0e 429 }
jmarkel44 0:61364762ee0e 430 std::string week_str;
jmarkel44 0:61364762ee0e 431 if ( week == WEEKLY_CHOICE_EVERY_WEEK ) {
jmarkel44 0:61364762ee0e 432 week_str = "every";
jmarkel44 0:61364762ee0e 433 } else if ( week == WEEKLY_CHOICE_FIRST_WEEK ) {
jmarkel44 0:61364762ee0e 434 week_str = "first";
jmarkel44 0:61364762ee0e 435 } else if ( week == WEEKLY_CHOICE_SECOND_WEEK ) {
jmarkel44 0:61364762ee0e 436 week_str = "second";
jmarkel44 0:61364762ee0e 437 } else if ( week == WEEKLY_CHOICE_THIRD_WEEK ) {
jmarkel44 0:61364762ee0e 438 week_str = "third";
jmarkel44 0:61364762ee0e 439 } else if ( week == WEEKLY_CHOICE_FOURTH_WEEK ) {
jmarkel44 0:61364762ee0e 440 week_str = "fourth";
jmarkel44 0:61364762ee0e 441 } else if ( week == WEEKLY_CHOICE_LAST_WEEK ) {
jmarkel44 0:61364762ee0e 442 week_str = "last";
jmarkel44 0:61364762ee0e 443 } else if ( week == WEEKLY_CHOICE_EVERYOTHER_WEEK ) {
jmarkel44 0:61364762ee0e 444 week_str = "everyother";
jmarkel44 0:61364762ee0e 445 }
jmarkel44 0:61364762ee0e 446
jmarkel44 0:61364762ee0e 447 char time_str[12];
jmarkel44 0:61364762ee0e 448 snprintf(time_str, sizeof(time_str), "%02d:%02d:%02d", startHour, startMin, startSec);
jmarkel44 0:61364762ee0e 449
jmarkel44 0:61364762ee0e 450 cout << left << setw(8) << setfill(' ') << "timer:";
jmarkel44 0:61364762ee0e 451 cout << left << setw(32) << setfill(' ') << controlFile;
jmarkel44 0:61364762ee0e 452 cout << left << setw(12) << setfill(' ') << id;
jmarkel44 0:61364762ee0e 453 cout << "output: " << left << setw(16) << setfill(' ') << output;
jmarkel44 0:61364762ee0e 454 cout << left << setw(6) << setfill(' ') << priority;
jmarkel44 0:61364762ee0e 455 cout << "(" << setw(12) << week_str << ")" << day_str << "-> ";
jmarkel44 0:61364762ee0e 456 cout << left << setw(12) << setfill(' ') << time_str;
jmarkel44 0:61364762ee0e 457 cout << left << setw(10) << "duration: " << left << setw(6) << setfill(' ') << duration;
jmarkel44 0:61364762ee0e 458 cout << left << setw(10) << setfill(' ') << mapper[currentState];
jmarkel44 0:61364762ee0e 459 if ( currentState == STATE_RUNNING ) {
jmarkel44 0:61364762ee0e 460 cout << left << setw(11) << setfill(' ') << "ends in: " << (startTime + duration) - time(NULL) << " seconds ";
jmarkel44 0:61364762ee0e 461 } else if ( currentState == STATE_FINISHED || currentState == STATE_DISABLED ) {
jmarkel44 0:61364762ee0e 462 // show nothing
jmarkel44 0:61364762ee0e 463 } else {
jmarkel44 0:61364762ee0e 464 cout << left << setw(11) << setfill(' ') << "starts in: " << calcStartTime() << " seconds ";
jmarkel44 0:61364762ee0e 465 }
jmarkel44 0:61364762ee0e 466 cout.flush();
jmarkel44 0:61364762ee0e 467 }