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
Diff: src/ConfigurationHandler/Controls/CompositeControl.cpp
- Revision:
- 221:2a5e9902003c
- Parent:
- 220:dbe21411f962
- Child:
- 222:94ea9a091d99
diff -r dbe21411f962 -r 2a5e9902003c src/ConfigurationHandler/Controls/CompositeControl.cpp
--- a/src/ConfigurationHandler/Controls/CompositeControl.cpp Fri Oct 14 13:32:47 2016 +0000
+++ b/src/ConfigurationHandler/Controls/CompositeControl.cpp Fri Oct 14 21:30:21 2016 +0000
@@ -5,6 +5,7 @@
*
*****************************************************************************/
#include "CompositeControl.h"
+#include "ConfigurationHandler.h"
#include "mDot.h"
#include "MbedJSONValue.h"
#include "ModbusMasterApi.h"
@@ -13,11 +14,21 @@
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;
+ printf("\rDEBUG: attempting to load the composite control\n");
+ Thread::wait(500);
+
// open and read from the control file
mDot::mdot_file file = GLOBAL_mdot->openUserFile(controlFile.c_str(), mDot::FM_RDONLY);
if ( file.fd < 0 ) {
@@ -40,26 +51,25 @@
parse(json_value, dataBuf);
- if ( !json_value.hasMember("id") ||
- !json_value.hasMember("input") ||
- !json_value.hasMember("ca") ||
- !json_value.hasMember("priority") ||
+ 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>();
- std::string input = json_value["input"].get<string>();
+ id = json_value ["id"].get<string>();
+ tag = json_value ["tag"].get<string>();
priority = atoi(json_value["priority"].get<string>().c_str());
- inputs.push_back(input);
- ca = json_value["ca"].get<string>();
+ ca = json_value ["ca"].get<string>();
int entries = atoi(json_value["entries"].get<string>().c_str());
for ( int i = 0; i < entries; ++i ) {
std::string tag = json_value["outputs"][i]["tag"].get<string>();
- std::string response = json_value["outputs"][i]["response"].get<string>();
+ std::string response = json_value["outputs"][i]["responseA"].get<string>();
if ( !tag.empty() && !response.empty() ) {
OutputElement x = { tag, response };
outputs.push_back(x);
@@ -68,29 +78,232 @@
}
}
+ printf("RETURN TRUE\n");
+
return true;
}
-// unregister the control with the output task
-void CompositeControl::unregisterControl(void)
+//
+// 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 ) {
+ printf("\rDEBUG: %s cannot find tag\n", __func__);
+ return "nothing";
+ }
+
+ if ( ca->getOp() == "==" ) {
+ //printf("\rvalue = %f opr = %f\n", value.value, atof(ca->getOpr().c_str()));
+ if ( value.value == atof(ca->getOpr().c_str()) ) {
+ return ca->getResultTrue();
+ } else {
+ return ca->getResultFalse();
+ }
+ }
+ if ( ca->getOp() == "+" ) {
+ // do nothing
+ }
+ 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)
+{
+ printf("\rTRIGGER THE OUTPUTS\n");
+
+ // 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: %s attempting to start feed on relay %s\n",
+ __func__, controlFile.c_str(), tag.c_str());
+
+ OutputControlMsg_t *output_mail = OutputMasterMailBox.alloc();
+ memset(output_mail, 0, sizeof(OutputControlMsg_t));
+
+ output_mail->action = action;
+ output_mail->controlType = CONTROL_COMPOSITE;
+ 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);
+ output_mail->priority = this->priority;
+ 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<std::string>::iterator pos;
- for ( pos = inputs.begin(); pos != inputs.end(); ++pos ) {
- printf("\r input : %s\n", (*pos).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");
}
\ No newline at end of file
