Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: NaturalTinyShell_ice libmDot-12Sept mbed-rtos mbed
Fork of ICE by
src/ConfigurationHandler/Controls/TimerControl.cpp
- Committer:
- jmarkel44
- Date:
- 2016-09-27
- Revision:
- 136:6ad7ba157b70
- Parent:
- 133:c871de2d2b90
- Child:
- 141:d924caf402c2
File content as of revision 136:6ad7ba157b70:
/******************************************************************************
*
* File: TimerControl.cpp
* Desciption: ICE Timer Control Class implementation
*
*****************************************************************************/
#include "TimerControl.h"
#include "mDot.h"
#include "MbedJSONValue.h"
#include "global.h"
#include <string>
extern mDot *GLOBAL_mdot;
//
// method: load
// description: load the pertinents from the control file
//
// @param _controlFile
// @return true if loaded; false otherwise
//
bool TimerControl::load(string _controlFile)
{
MbedJSONValue json_value; // json parsing element
// try to open the control file
mDot::mdot_file file = GLOBAL_mdot->openUserFile(_controlFile.c_str(), mDot::FM_RDONLY);
if ( file.fd < 0 ) {
return false;
}
// read the data into a buffer
char dataBuf[1024];
int bytes_read = GLOBAL_mdot->readUserFile(file, (void *)dataBuf, sizeof(dataBuf));
if ( bytes_read != sizeof(dataBuf) ) {
logError("%s: failed to read %d bytes from %s", __func__, sizeof(dataBuf), controlFile.c_str());
return false;
}
// close the file
GLOBAL_mdot->closeUserFile(file);
parse(json_value, dataBuf);
// the pertinents
controlFile = _controlFile;
id = json_value["id"].get<string>();
output = json_value["output"].get<string>();
// create the schedule
Schedule_t s;
s.priority = atol(json_value["priority"].get<string>().c_str());
s.startTime = atol(json_value["starttime"].get<string>().c_str());
s.duration = atol(json_value["duration"].get<string>().c_str());
// push it on the list
schedule.push_back(s);
return true;
}
//
// method: start
// description: initialize the control
//
// @param none
// @return none
//
void TimerControl::start(void)
{
currentState = STATE_OFF;
vector<Schedule_t>::iterator pos;
if ( schedule.empty() ) return;
#if 0
for ( pos = schedule.begin(); pos != schedule.end(); ++pos ) {
if ( (pos->startTime + pos->duration) < time(NULL) ) {
schedule.erase(pos);
}
}
#endif
}
//
// method: timerStart
// description: examine the timestamp to determine if the timer control
// should be running
//
// @param none
// @return true if timer should be running; false otherwise
//
bool TimerControl::timerStart(void)
{
// schedules should be sorted in order, so always check the first
if ( !schedule.empty() ) {
unsigned long currentTime = time(NULL);
// does it fit?
if ( currentTime < schedule.front().startTime ) {
return false;
}
if ( currentTime >= schedule.front().startTime &&
currentTime < (schedule.front().startTime + schedule.front().duration) ) {
logInfo("%s signals feed start", __func__);
return true;
} else {
logInfo("%s: schedule for %s has expired", __func__, id.c_str());
schedule.erase(schedule.begin());
this->unregisterControl();
}
}
return false;
}
//
// method: timerStop
// description: determines if a running timer should has reached its duration
//
// @param none
// @return true if the timer has expired; false otherwise
//
bool TimerControl::timerStop(void)
{
// if current time is greater than start time + feed duration...
if ( time(NULL) >= (schedule.front().startTime + schedule.front().duration) ) {
logInfo("%s signals a feed stop", __func__);
return true;
}
return false;
}
//
// method: update
// description: run the simplified state machine
//
// @param none
// @return none
//
void TimerControl::update(void)
{
switch ( this->currentState ) {
case STATE_OFF:
if ( this->timerStart() ) {
currentState = STATE_RUNNING;
this->startFeed();
}
break;
case STATE_RUNNING:
if ( this->timerStop() ) {
currentState = STATE_OFF;
this->stopFeed();
}
break;
case STATE_DISABLED:
// not implelmented
default:
break;
}
}
//
// method: startFeed
// description: signal the output thread to start a feed
//
// @param none
// @return none
void TimerControl::startFeed(void)
{
logInfo("%s: %s attempting to start feed on relay %s\n",
__func__, controlFile.c_str(), output.c_str());
OutputControlMsg_t *output_mail = OutputMasterMailBox.alloc();
memset(output_mail, 0, sizeof(OutputControlMsg_t));
output_mail->action = ACTION_CONTROL_ON;
output_mail->controlType = CONTROL_TIMER;
output_mail->priority = this->schedule.front().priority;
strncpy(output_mail->output_tag, this->output.c_str(), sizeof(output_mail->output_tag)-1);
strncpy(output_mail->id, this->id.c_str(), sizeof(output_mail->id)-1);
OutputMasterMailBox.put(output_mail);
}
//
// method: stopFeed
// description: signal the output thread to stop a feed
//
// @param none
// @return none
void TimerControl::stopFeed(void)
{
logInfo("%s: %s attempting to start feed on relay %s\n",
__func__, controlFile.c_str(), output.c_str());
OutputControlMsg_t *output_mail = OutputMasterMailBox.alloc();
memset(output_mail, 0, sizeof(OutputControlMsg_t));
output_mail->action = ACTION_CONTROL_OFF;
output_mail->controlType = CONTROL_TIMER;
output_mail->priority = this->schedule.front().priority;
strncpy(output_mail->output_tag, this->output.c_str(), sizeof(output_mail->output_tag)-1);
strncpy(output_mail->id, this->id.c_str(), sizeof(output_mail->id)-1);
OutputMasterMailBox.put(output_mail);
}
// Method: unregisterControl
// Description: send OFF indication to Output Master for this control's
// relay
//
// @param none
// @return none
void TimerControl::unregisterControl(void)
{
logInfo("%s: %s attempting to unregister %s\n",
__func__, controlFile.c_str());
OutputControlMsg_t *output_mail = OutputMasterMailBox.alloc();
memset(output_mail, 0, sizeof(OutputControlMsg_t));
output_mail->action = ACTION_CONTROL_UNREGISTER;
output_mail->controlType = CONTROL_TIMER;
output_mail->priority = this->schedule.front().priority;
strncpy(output_mail->output_tag, this->output.c_str(), sizeof(output_mail->output_tag)-1);
strncpy(output_mail->id, this->id.c_str(), sizeof(output_mail->id)-1);
OutputMasterMailBox.put(output_mail);
}
//
// methid: display
// description: display the elements of this timer control object
//
// @param none
// @return none
//
void TimerControl::display(void)
{
string mapper[] = { "OFF",
"RUNNING",
"DISABLED"
};
printf("\r controlFile : %s \n", controlFile.c_str());
printf("\r id : %s \n", id.c_str());
printf("\r output : %s \n", output.c_str());
std::vector<Schedule_t>::iterator pos;
int counter = 0;
if ( schedule.empty() ) {
printf("\rNo scheduled timers\r\n");
return;
} else {
for ( pos = schedule.begin(); pos != schedule.end(); ++pos ) {
printf("\r Schedule %d\n", ++counter);
printf("\r priority : %u \n", pos->priority);
printf("\r start time : %lu\n", pos->startTime);
printf("\r duration : %u sec\n", pos->duration);
printf("\r end time : %lu\n", pos->startTime + pos->duration);
printf("\r current time : %lu\n", time(NULL));
printf("\r expires in : %lu sec\n", (pos->startTime + pos->duration) - time(NULL));
}
}
printf("\r current State : %s\n", mapper[currentState].c_str());
}
