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/CompositeControl.cpp
- Committer:
- jmarkel44
- Date:
- 2016-10-19
- Revision:
- 231:f22901955e0c
- Parent:
- 230:11765008ff3a
- Child:
- 232:8a86b5bf38f7
File content as of revision 231:f22901955e0c:
/******************************************************************************
*
* File: CompositeControl.cpp
* Desciption: ICE Composite Control Class implementation
*
*****************************************************************************/
#include "CompositeControl.h"
#include "ConfigurationHandler.h"
#include "mDot.h"
#include "MbedJSONValue.h"
#include "ModbusMasterApi.h"
#include "global.h"
#include <string>
extern mDot *GLOBAL_mdot;
//
// method: load
// description: load a composite control
//
// @param none
// @return none
//
bool CompositeControl::load(std::string _controlFile)
{
MbedJSONValue json_value; // JSON parsing element
controlFile = _controlFile;
// open and read from the control file
mDot::mdot_file file = GLOBAL_mdot->openUserFile(controlFile.c_str(), mDot::FM_RDONLY);
if ( file.fd < 0 ) {
logError("%s: failed to open %s\n", __func__, controlFile.c_str());
return false;
}
// read the data into a buffer
char dataBuf[MAX_FILE_SIZE];
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());
// caller should destroy the object
return false;
}
// close the file
GLOBAL_mdot->closeUserFile(file);
parse(json_value, dataBuf);
if ( !json_value.hasMember("id") ||
!json_value.hasMember("tag") ||
!json_value.hasMember("priority") ||
!json_value.hasMember("ca") ||
!json_value.hasMember("entries") ) {
printf("\rComposite control is missing expected tags\n");
return false;
}
id = json_value ["id"].get<string>();
tag = json_value ["tag"].get<string>();
priority = atoi(json_value["priority"].get<string>().c_str());
ca = json_value ["ca"].get<string>();
int entries = atoi(json_value["entries"].get<string>().c_str());
// populate the outputs
for ( int i = 0; i < entries; ++i ) {
std::string tag = json_value["outputs"][i]["tag"].get<string>();
Thread::wait(1000);
std::string response = json_value["outputs"][i]["responseA"].get<string>();
Thread::wait(1000);
if ( !tag.empty() && !response.empty() ) {
OutputElement x = { tag, response };
outputs.push_back(x);
} else {
return false;
}
}
return true;
}
//
// method: start
// description: start the composite control
//
// @param none
// @return none
//
void CompositeControl::start(void)
{
currentState = STATE_START;
}
//
// method: update
// description: updater for the composite control
//
// @param none
// @return none
//
void CompositeControl::update(void)
{
std::string function;
switch ( currentState ) {
case STATE_INIT:
// do nothing
break;
case STATE_START:
function = executeCommand();
if ( function == "responseA" ) {
currentState = STATE_CONTROL_ON;
triggerOutputs(function);
} else if ( function == "nothing" ) {
currentState = STATE_CONTROL_OFF;
}
break;
case STATE_CONTROL_ON:
function = executeCommand();
if ( function == "nothing" ) {
currentState = STATE_CONTROL_OFF;
unregisterControls();
} else {
// do nothing
}
break;
case STATE_CONTROL_OFF:
function = executeCommand();
if ( function == "responseA" ) {
currentState = STATE_CONTROL_ON;
triggerOutputs(function);
} else {
// do nothing
}
break;
default:
break;
}
}
//
// method: executeCommand
// description: execute the command specified in the control algorithm
//
// @param none
// @return none
//
std::string CompositeControl::executeCommand(void)
{
// look up the algorithm
StringAlgorithmMap::iterator pos;
pos = algorithmTable.find(this->ca);
if ( pos != algorithmTable.end() ) {
// we found the control algorithm
return this->executeOperation(pos->second);
}
return "nothing";
}
//
// method: executeOperation
// description: execute an operations from the control equation
//
// @param ca -> composite control algorithm
// @return string to the result
//
std::string CompositeControl::executeOperation(const CompositeAlgorithm *ca)
{
// (this->tag) <op> <opr> = <result>
//
// example:
// this->tag = "i_flowswitch"
// opr = "1"
// op = "=="
// if true return "responseA" else return "nothing"
ModbusValue value;
bool rc = ModbusMasterReadRegister(tag,&value);
if ( rc != true ) {
logError("%s cannot find tag", __func__);
return "nothing";
}
// equal to operator
if ( ca->getOp() == "==" ) {
// perform the equality operation
if ( value.value == atof(ca->getOpr().c_str()) ) {
return ca->getResultTrue();
} else {
return ca->getResultFalse();
}
}
if ( ca->getOp() == ">=" ) {
if ( value.value >= atof(ca->getOpr().c_str()) ) {
return ca->getResultTrue();
} else {
return ca->getResultFalse();
}
}
// addition operator
if ( ca->getOp() == "+" ) {
// TODO
}
// multiply operator
if ( ca->getOp() == "*" ) {
// TODO:
}
// subtraction operator
if ( ca->getOp() == "-" ) {
// TODO:
}
return "nothing";
}
//
// method: triggerOutputs
// description: trigger the output(s) to do something
//
// @param result -> the result of the operation
// @return none
//
void CompositeControl::triggerOutputs(std::string result)
{
// loop through the list
StringAlgorithmMap::iterator pos;
pos = algorithmTable.find(this->ca);
if ( pos != algorithmTable.end() ) {
std::vector<OutputElement>::iterator it;
for ( it = outputs.begin(); it != outputs.end(); ++it ) {
if ( it->response == "fixed off" ) {
printf("\rSending an OFF control for %s\n", it->tag.c_str());
sendMail(it->tag, ACTION_CONTROL_OFF);
} else if ( it->response == "fixed on" ) {
printf("\rSending an ON request for %s\n", it->tag.c_str());
sendMail(it->tag, ACTION_CONTROL_ON);
}
}
} else {
logError("%s: failed to find the control algorithm %s\n", __func__, this->ca.c_str());
}
}
//
// method: sendMail
// description: send mail to the output task
//
// @param io_tag -> input/output tag
// @param action -> ON, OFF, UNREGISTER
// @return none
//
void CompositeControl::sendMail(const std::string io_tag, OutputAction action)
{
logInfo("%s: composite control attempting to send action %d\n",
__func__, action);
OutputControlMsg_t *output_mail = OutputMasterMailBox.alloc();
memset(output_mail, 0, sizeof(OutputControlMsg_t));
output_mail->action = action;
output_mail->controlType = CONTROL_COMPOSITE;
output_mail->priority = this->priority;
strncpy(output_mail->input_tag, this->tag.c_str(), sizeof(output_mail->input_tag)-1);
strncpy(output_mail->output_tag, io_tag.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: unregisterControls
// description: unregister the control with the output task
//
// @param none
// @return none
//
void CompositeControl::unregisterControls(void)
{
// loop through the list
StringAlgorithmMap::iterator pos;
pos = algorithmTable.find(this->ca);
if ( pos != algorithmTable.end() ) {
std::vector<OutputElement>::iterator it;
for ( it = outputs.begin(); it != outputs.end(); ++it ) {
sendMail(it->tag, ACTION_CONTROL_UNREGISTER);
}
} else {
logError("%s: failed to find the control algorithm %s\n", __func__, this->ca.c_str());
}
}
//
// methid: display
// description: display the pertinents
//
// @param none
// @return none
//
void CompositeControl::display(void)
{
const char *mapper[] = { "INIT",
"START",
"CONTROL_OFF",
"CONTROL_ON"
};
\
printf("\r control file : %s\n", controlFile.c_str());
printf("\r id : %s\n", id.c_str());
printf("\r tag : %s\n", tag.c_str());
printf("\r priority : %u\n", priority);
printf("\r ca : %s\n", ca.c_str());
vector<OutputElement>::iterator it;
printf("\r outputs :\n");
for ( it = outputs.begin(); it != outputs.end(); ++it ) {
printf("\r tag-> %s\n", (*it).tag.c_str());
printf("\r response-> %s\n", (*it).response.c_str());
}
printf("\r current state : %s\n", mapper[currentState]);
printf("\r\n");
}
