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.
ICE-Application/src/ConfigurationHandler/Controls/CompositeControl.cpp
- Committer:
- jmarkel44
- Date:
- 2017-01-24
- Revision:
- 0:61364762ee0e
File content as of revision 0:61364762ee0e:
/****************************************************************************** * * File: CompositeControl.cpp * Desciption: ICE Composite Control Class implementation * *****************************************************************************/ #include "CompositeControl.h" #include "ConfigurationHandler.h" #include "cJSON.h" #include "ModbusMasterApi.h" #include "global.h" #include "ICELog.h" #include <string> #include <iostream> #include <iomanip> #ifdef MDOT_ICE extern mDot *GLOBAL_mdot; #endif using namespace std; // // method: load // description: load a composite control // // @param[in] _controlFile -> the file containing the JSON data // @return false if an error occurs; true otherwise // bool CompositeControl::load(std::string _controlFile) { controlFile = _controlFile; char dataBuf[MAX_FILE_SIZE]; // read the control data bool rc = GLOBAL_mdot->readUserFile(controlFile.c_str(), (void *)dataBuf, sizeof(dataBuf)); if ( rc != true ) { logError("%s: failed to read %s", __func__, controlFile.c_str()); // caller should destroy the object return false; } // validate control data if ( !validateControlData(dataBuf) ) { logError("%s: failed to validate control data", __func__); return false; } // copy control data copyControlData(dataBuf); // TODO: validate the list fo outputs return true; } // // method: validateControlData // description: validate JSON formatted control data // // @param[in] buf -> JSON formatted string // @param[out] none // @return true if valid; false otherwise // bool CompositeControl::validateControlData(const char *buf) { bool rc = true; cJSON * root = cJSON_Parse(buf); if ( !cJSON_HasObjectItem(root, "id") || !cJSON_HasObjectItem(root, "tag") || !cJSON_HasObjectItem(root, "priority") || !cJSON_HasObjectItem(root, "ca") || !cJSON_HasObjectItem(root, "outputs") ) { logError("%s: control file missing expected tags", __func__); cJSON_Delete(root); return false; } cJSON_Delete(root); return rc; } // // method: copyControlData // description: copy the JSON formatted data // // @param[in] buf -> JSON formatted string // @param[out] none // @return none // void CompositeControl::copyControlData(const char *buf) { cJSON * root = cJSON_Parse(buf); id = cJSON_GetObjectItem(root,"id")->valuestring; tag = cJSON_GetObjectItem(root, "tag")->valuestring; priority = atoi(cJSON_GetObjectItem(root, "priority")->valuestring); ca = cJSON_GetObjectItem(root, "ca")->valuestring; cJSON *array = cJSON_GetObjectItem(root, "outputs"); for ( int i = 0; i < cJSON_GetArraySize(array); ++i ) { cJSON *subitem = cJSON_GetArrayItem(array, i); std::string tag = cJSON_GetObjectItem(subitem, "tag")->valuestring; std::string response = cJSON_GetObjectItem(subitem, "responseA")->valuestring; OutputElement x = { tag, response }; outputs.push_back(x); } cJSON_Delete(root); } // // 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 // CompositeControlError_t CompositeControl::update(void) { CompositeControlError_t rc = COMPOSITE_CONTROL_OK; 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: logError("%s: unknown state %d", __func__, this->currentState); rc = COMPOSITE_CONTROL_UNK_STATE; break; } return rc; } // // 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::const_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[in] 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(); } } if ( ca->getOp() == "&" ) { if ( (int)value.value & (int)atoi(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[in] result -> the result of the operation // @return none // void CompositeControl::triggerOutputs(std::string result) { // loop through the list StringAlgorithmMap::const_iterator pos; pos = algorithmTable.find(this->ca); if ( pos != algorithmTable.end() ) { std::vector<OutputElement>::const_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[in] io_tag -> input/output tag // @param[in] 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::const_iterator pos; pos = algorithmTable.find(this->ca); if ( pos != algorithmTable.end() ) { std::vector<OutputElement>::const_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()); } } // // method: display // description: display the pertinents // // @param none // @return none // void CompositeControl::display(void) { const char *mapper[] = { "INIT", "START", "CONTROL_OFF", "CONTROL_ON" }; printf("\r\n"); std::cout << left << setw(10) << setfill(' ') << "composite: "; std::cout << left << setw(40) << setfill(' ') << controlFile; std::cout << left << setw(20) << setfill(' ') << id; std::cout << left << setw(20) << setfill(' ') << tag; std::cout << left << setw(6) << setfill(' ') << priority; std::cout << left << setw(20) << setfill(' ') << ca; std::cout << left << setw(16) << setfill(' ') << mapper[currentState]; vector<OutputElement>::const_iterator it; for ( it = outputs.begin(); it != outputs.end(); ++it ) { std::cout << left << (*it).tag << ":" << (*it).response << " "; } std::cout.flush(); }