Erick / Mbed 2 deprecated ICE_BLE_TEST

Dependencies:   NaturalTinyShell_ice libmDot-12Sept mbed-rtos mbed

Fork of ICE by Erick

Committer:
jmarkel44
Date:
Thu Oct 20 15:30:21 2016 +0000
Revision:
242:3b0086a6d625
Parent:
232:8a86b5bf38f7
Child:
253:ae850c19cf81
use of new JSON parser

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jmarkel44 164:7cecd731882e 1 /******************************************************************************
jmarkel44 164:7cecd731882e 2 *
jmarkel44 164:7cecd731882e 3 * File: CompositeControl.cpp
jmarkel44 164:7cecd731882e 4 * Desciption: ICE Composite Control Class implementation
jmarkel44 164:7cecd731882e 5 *
jmarkel44 164:7cecd731882e 6 *****************************************************************************/
jmarkel44 164:7cecd731882e 7 #include "CompositeControl.h"
jmarkel44 221:2a5e9902003c 8 #include "ConfigurationHandler.h"
jmarkel44 164:7cecd731882e 9 #include "mDot.h"
jmarkel44 242:3b0086a6d625 10 #include "cJSON.h"
jmarkel44 164:7cecd731882e 11 #include "ModbusMasterApi.h"
jmarkel44 164:7cecd731882e 12 #include "global.h"
jmarkel44 164:7cecd731882e 13 #include <string>
jmarkel44 232:8a86b5bf38f7 14 #include <iostream>
jmarkel44 232:8a86b5bf38f7 15 #include <iomanip>
jmarkel44 164:7cecd731882e 16
jmarkel44 164:7cecd731882e 17 extern mDot *GLOBAL_mdot;
jmarkel44 164:7cecd731882e 18
jmarkel44 221:2a5e9902003c 19 //
jmarkel44 221:2a5e9902003c 20 // method: load
jmarkel44 221:2a5e9902003c 21 // description: load a composite control
jmarkel44 221:2a5e9902003c 22 //
jmarkel44 221:2a5e9902003c 23 // @param none
jmarkel44 221:2a5e9902003c 24 // @return none
jmarkel44 221:2a5e9902003c 25 //
jmarkel44 220:dbe21411f962 26 bool CompositeControl::load(std::string _controlFile)
jmarkel44 164:7cecd731882e 27 {
jmarkel44 220:dbe21411f962 28 controlFile = _controlFile;
jmarkel44 220:dbe21411f962 29
jmarkel44 220:dbe21411f962 30 // open and read from the control file
jmarkel44 220:dbe21411f962 31 mDot::mdot_file file = GLOBAL_mdot->openUserFile(controlFile.c_str(), mDot::FM_RDONLY);
jmarkel44 220:dbe21411f962 32 if ( file.fd < 0 ) {
jmarkel44 220:dbe21411f962 33 logError("%s: failed to open %s\n", __func__, controlFile.c_str());
jmarkel44 220:dbe21411f962 34 return false;
jmarkel44 220:dbe21411f962 35 }
jmarkel44 220:dbe21411f962 36
jmarkel44 220:dbe21411f962 37 // read the data into a buffer
jmarkel44 220:dbe21411f962 38 char dataBuf[MAX_FILE_SIZE];
jmarkel44 220:dbe21411f962 39
jmarkel44 220:dbe21411f962 40 int bytes_read = GLOBAL_mdot->readUserFile(file, (void *)dataBuf, sizeof(dataBuf));
jmarkel44 220:dbe21411f962 41 if ( bytes_read != sizeof(dataBuf) ) {
jmarkel44 220:dbe21411f962 42 logError("%s: failed to read %d bytes from %s", __func__, sizeof(dataBuf), controlFile.c_str());
jmarkel44 220:dbe21411f962 43 // caller should destroy the object
jmarkel44 220:dbe21411f962 44 return false;
jmarkel44 220:dbe21411f962 45 }
jmarkel44 220:dbe21411f962 46
jmarkel44 220:dbe21411f962 47 // close the file
jmarkel44 220:dbe21411f962 48 GLOBAL_mdot->closeUserFile(file);
jmarkel44 220:dbe21411f962 49
jmarkel44 242:3b0086a6d625 50 cJSON * root = cJSON_Parse(dataBuf);
jmarkel44 242:3b0086a6d625 51 id = cJSON_GetObjectItem(root,"id")->valuestring;
jmarkel44 242:3b0086a6d625 52 tag = cJSON_GetObjectItem(root, "tag")->valuestring;
jmarkel44 242:3b0086a6d625 53 priority = atoi(cJSON_GetObjectItem(root, "priority")->valuestring);
jmarkel44 242:3b0086a6d625 54 ca = cJSON_GetObjectItem(root, "ca")->valuestring;
jmarkel44 242:3b0086a6d625 55 cJSON *array = cJSON_GetObjectItem(root, "outputs");
jmarkel44 242:3b0086a6d625 56 for ( int i = 0; i < cJSON_GetArraySize(array); ++i ) {
jmarkel44 242:3b0086a6d625 57 cJSON *subitem = cJSON_GetArrayItem(array, i);
jmarkel44 242:3b0086a6d625 58 std::string tag = cJSON_GetObjectItem(subitem, "tag")->valuestring;
jmarkel44 242:3b0086a6d625 59 std::string response = cJSON_GetObjectItem(subitem, "responseA")->valuestring;
jmarkel44 242:3b0086a6d625 60 OutputElement x = { tag, response };
jmarkel44 242:3b0086a6d625 61 outputs.push_back(x);
jmarkel44 220:dbe21411f962 62 }
jmarkel44 220:dbe21411f962 63
jmarkel44 164:7cecd731882e 64 return true;
jmarkel44 164:7cecd731882e 65 }
jmarkel44 164:7cecd731882e 66
jmarkel44 221:2a5e9902003c 67 //
jmarkel44 221:2a5e9902003c 68 // method: start
jmarkel44 221:2a5e9902003c 69 // description: start the composite control
jmarkel44 221:2a5e9902003c 70 //
jmarkel44 221:2a5e9902003c 71 // @param none
jmarkel44 221:2a5e9902003c 72 // @return none
jmarkel44 221:2a5e9902003c 73 //
jmarkel44 221:2a5e9902003c 74 void CompositeControl::start(void)
jmarkel44 221:2a5e9902003c 75 {
jmarkel44 221:2a5e9902003c 76 currentState = STATE_START;
jmarkel44 221:2a5e9902003c 77 }
jmarkel44 221:2a5e9902003c 78
jmarkel44 221:2a5e9902003c 79 //
jmarkel44 221:2a5e9902003c 80 // method: update
jmarkel44 221:2a5e9902003c 81 // description: updater for the composite control
jmarkel44 221:2a5e9902003c 82 //
jmarkel44 221:2a5e9902003c 83 // @param none
jmarkel44 221:2a5e9902003c 84 // @return none
jmarkel44 230:11765008ff3a 85 //
jmarkel44 221:2a5e9902003c 86 void CompositeControl::update(void)
jmarkel44 164:7cecd731882e 87 {
jmarkel44 221:2a5e9902003c 88 std::string function;
jmarkel44 221:2a5e9902003c 89
jmarkel44 221:2a5e9902003c 90 switch ( currentState ) {
jmarkel44 221:2a5e9902003c 91 case STATE_INIT:
jmarkel44 221:2a5e9902003c 92 // do nothing
jmarkel44 221:2a5e9902003c 93 break;
jmarkel44 221:2a5e9902003c 94 case STATE_START:
jmarkel44 221:2a5e9902003c 95 function = executeCommand();
jmarkel44 221:2a5e9902003c 96 if ( function == "responseA" ) {
jmarkel44 221:2a5e9902003c 97 currentState = STATE_CONTROL_ON;
jmarkel44 221:2a5e9902003c 98 triggerOutputs(function);
jmarkel44 221:2a5e9902003c 99 } else if ( function == "nothing" ) {
jmarkel44 221:2a5e9902003c 100 currentState = STATE_CONTROL_OFF;
jmarkel44 221:2a5e9902003c 101 }
jmarkel44 221:2a5e9902003c 102 break;
jmarkel44 221:2a5e9902003c 103 case STATE_CONTROL_ON:
jmarkel44 221:2a5e9902003c 104 function = executeCommand();
jmarkel44 221:2a5e9902003c 105 if ( function == "nothing" ) {
jmarkel44 221:2a5e9902003c 106 currentState = STATE_CONTROL_OFF;
jmarkel44 221:2a5e9902003c 107 unregisterControls();
jmarkel44 221:2a5e9902003c 108 } else {
jmarkel44 221:2a5e9902003c 109 // do nothing
jmarkel44 221:2a5e9902003c 110 }
jmarkel44 221:2a5e9902003c 111 break;
jmarkel44 221:2a5e9902003c 112 case STATE_CONTROL_OFF:
jmarkel44 221:2a5e9902003c 113 function = executeCommand();
jmarkel44 221:2a5e9902003c 114 if ( function == "responseA" ) {
jmarkel44 221:2a5e9902003c 115 currentState = STATE_CONTROL_ON;
jmarkel44 221:2a5e9902003c 116 triggerOutputs(function);
jmarkel44 221:2a5e9902003c 117 } else {
jmarkel44 221:2a5e9902003c 118 // do nothing
jmarkel44 221:2a5e9902003c 119 }
jmarkel44 221:2a5e9902003c 120 break;
jmarkel44 221:2a5e9902003c 121 default:
jmarkel44 221:2a5e9902003c 122 break;
jmarkel44 221:2a5e9902003c 123 }
jmarkel44 221:2a5e9902003c 124 }
jmarkel44 221:2a5e9902003c 125
jmarkel44 230:11765008ff3a 126 //
jmarkel44 221:2a5e9902003c 127 // method: executeCommand
jmarkel44 221:2a5e9902003c 128 // description: execute the command specified in the control algorithm
jmarkel44 221:2a5e9902003c 129 //
jmarkel44 221:2a5e9902003c 130 // @param none
jmarkel44 221:2a5e9902003c 131 // @return none
jmarkel44 221:2a5e9902003c 132 //
jmarkel44 221:2a5e9902003c 133 std::string CompositeControl::executeCommand(void)
jmarkel44 221:2a5e9902003c 134 {
jmarkel44 221:2a5e9902003c 135 // look up the algorithm
jmarkel44 221:2a5e9902003c 136 StringAlgorithmMap::iterator pos;
jmarkel44 221:2a5e9902003c 137 pos = algorithmTable.find(this->ca);
jmarkel44 221:2a5e9902003c 138 if ( pos != algorithmTable.end() ) {
jmarkel44 221:2a5e9902003c 139 // we found the control algorithm
jmarkel44 221:2a5e9902003c 140 return this->executeOperation(pos->second);
jmarkel44 221:2a5e9902003c 141 }
jmarkel44 221:2a5e9902003c 142 return "nothing";
jmarkel44 220:dbe21411f962 143 }
jmarkel44 220:dbe21411f962 144
jmarkel44 221:2a5e9902003c 145 //
jmarkel44 221:2a5e9902003c 146 // method: executeOperation
jmarkel44 221:2a5e9902003c 147 // description: execute an operations from the control equation
jmarkel44 221:2a5e9902003c 148 //
jmarkel44 221:2a5e9902003c 149 // @param ca -> composite control algorithm
jmarkel44 221:2a5e9902003c 150 // @return string to the result
jmarkel44 221:2a5e9902003c 151 //
jmarkel44 221:2a5e9902003c 152 std::string CompositeControl::executeOperation(const CompositeAlgorithm *ca)
jmarkel44 221:2a5e9902003c 153 {
jmarkel44 221:2a5e9902003c 154 // (this->tag) <op> <opr> = <result>
jmarkel44 221:2a5e9902003c 155 //
jmarkel44 221:2a5e9902003c 156 // example:
jmarkel44 221:2a5e9902003c 157 // this->tag = "i_flowswitch"
jmarkel44 221:2a5e9902003c 158 // opr = "1"
jmarkel44 221:2a5e9902003c 159 // op = "=="
jmarkel44 221:2a5e9902003c 160 // if true return "responseA" else return "nothing"
jmarkel44 221:2a5e9902003c 161
jmarkel44 221:2a5e9902003c 162 ModbusValue value;
jmarkel44 221:2a5e9902003c 163 bool rc = ModbusMasterReadRegister(tag,&value);
jmarkel44 221:2a5e9902003c 164 if ( rc != true ) {
jmarkel44 231:f22901955e0c 165 logError("%s cannot find tag", __func__);
jmarkel44 221:2a5e9902003c 166 return "nothing";
jmarkel44 221:2a5e9902003c 167 }
jmarkel44 221:2a5e9902003c 168
jmarkel44 230:11765008ff3a 169 // equal to operator
jmarkel44 221:2a5e9902003c 170 if ( ca->getOp() == "==" ) {
jmarkel44 230:11765008ff3a 171 // perform the equality operation
jmarkel44 221:2a5e9902003c 172 if ( value.value == atof(ca->getOpr().c_str()) ) {
jmarkel44 221:2a5e9902003c 173 return ca->getResultTrue();
jmarkel44 221:2a5e9902003c 174 } else {
jmarkel44 221:2a5e9902003c 175 return ca->getResultFalse();
jmarkel44 221:2a5e9902003c 176 }
jmarkel44 221:2a5e9902003c 177 }
jmarkel44 230:11765008ff3a 178 if ( ca->getOp() == ">=" ) {
jmarkel44 230:11765008ff3a 179 if ( value.value >= atof(ca->getOpr().c_str()) ) {
jmarkel44 232:8a86b5bf38f7 180 return ca->getResultTrue();
jmarkel44 230:11765008ff3a 181 } else {
jmarkel44 230:11765008ff3a 182 return ca->getResultFalse();
jmarkel44 230:11765008ff3a 183 }
jmarkel44 230:11765008ff3a 184 }
jmarkel44 230:11765008ff3a 185 // addition operator
jmarkel44 221:2a5e9902003c 186 if ( ca->getOp() == "+" ) {
jmarkel44 227:7153e89b6974 187 // TODO
jmarkel44 221:2a5e9902003c 188 }
jmarkel44 230:11765008ff3a 189 // multiply operator
jmarkel44 227:7153e89b6974 190 if ( ca->getOp() == "*" ) {
jmarkel44 230:11765008ff3a 191 // TODO:
jmarkel44 227:7153e89b6974 192 }
jmarkel44 230:11765008ff3a 193 // subtraction operator
jmarkel44 227:7153e89b6974 194 if ( ca->getOp() == "-" ) {
jmarkel44 227:7153e89b6974 195 // TODO:
jmarkel44 227:7153e89b6974 196 }
jmarkel44 230:11765008ff3a 197
jmarkel44 221:2a5e9902003c 198 return "nothing";
jmarkel44 221:2a5e9902003c 199 }
jmarkel44 221:2a5e9902003c 200
jmarkel44 221:2a5e9902003c 201 //
jmarkel44 221:2a5e9902003c 202 // method: triggerOutputs
jmarkel44 221:2a5e9902003c 203 // description: trigger the output(s) to do something
jmarkel44 221:2a5e9902003c 204 //
jmarkel44 221:2a5e9902003c 205 // @param result -> the result of the operation
jmarkel44 221:2a5e9902003c 206 // @return none
jmarkel44 221:2a5e9902003c 207 //
jmarkel44 221:2a5e9902003c 208 void CompositeControl::triggerOutputs(std::string result)
jmarkel44 221:2a5e9902003c 209 {
jmarkel44 221:2a5e9902003c 210
jmarkel44 221:2a5e9902003c 211 // loop through the list
jmarkel44 221:2a5e9902003c 212 StringAlgorithmMap::iterator pos;
jmarkel44 221:2a5e9902003c 213 pos = algorithmTable.find(this->ca);
jmarkel44 221:2a5e9902003c 214 if ( pos != algorithmTable.end() ) {
jmarkel44 221:2a5e9902003c 215 std::vector<OutputElement>::iterator it;
jmarkel44 221:2a5e9902003c 216 for ( it = outputs.begin(); it != outputs.end(); ++it ) {
jmarkel44 221:2a5e9902003c 217 if ( it->response == "fixed off" ) {
jmarkel44 221:2a5e9902003c 218 printf("\rSending an OFF control for %s\n", it->tag.c_str());
jmarkel44 221:2a5e9902003c 219 sendMail(it->tag, ACTION_CONTROL_OFF);
jmarkel44 221:2a5e9902003c 220 } else if ( it->response == "fixed on" ) {
jmarkel44 221:2a5e9902003c 221 printf("\rSending an ON request for %s\n", it->tag.c_str());
jmarkel44 221:2a5e9902003c 222 sendMail(it->tag, ACTION_CONTROL_ON);
jmarkel44 221:2a5e9902003c 223 }
jmarkel44 221:2a5e9902003c 224 }
jmarkel44 221:2a5e9902003c 225 } else {
jmarkel44 221:2a5e9902003c 226 logError("%s: failed to find the control algorithm %s\n", __func__, this->ca.c_str());
jmarkel44 221:2a5e9902003c 227 }
jmarkel44 221:2a5e9902003c 228 }
jmarkel44 221:2a5e9902003c 229
jmarkel44 221:2a5e9902003c 230 //
jmarkel44 221:2a5e9902003c 231 // method: sendMail
jmarkel44 221:2a5e9902003c 232 // description: send mail to the output task
jmarkel44 221:2a5e9902003c 233 //
jmarkel44 221:2a5e9902003c 234 // @param io_tag -> input/output tag
jmarkel44 221:2a5e9902003c 235 // @param action -> ON, OFF, UNREGISTER
jmarkel44 221:2a5e9902003c 236 // @return none
jmarkel44 221:2a5e9902003c 237 //
jmarkel44 221:2a5e9902003c 238 void CompositeControl::sendMail(const std::string io_tag, OutputAction action)
jmarkel44 221:2a5e9902003c 239 {
jmarkel44 222:94ea9a091d99 240 logInfo("%s: composite control attempting to send action %d\n",
jmarkel44 222:94ea9a091d99 241 __func__, action);
jmarkel44 221:2a5e9902003c 242
jmarkel44 221:2a5e9902003c 243 OutputControlMsg_t *output_mail = OutputMasterMailBox.alloc();
jmarkel44 221:2a5e9902003c 244 memset(output_mail, 0, sizeof(OutputControlMsg_t));
jmarkel44 221:2a5e9902003c 245
jmarkel44 227:7153e89b6974 246 output_mail->action = action;
jmarkel44 227:7153e89b6974 247 output_mail->controlType = CONTROL_COMPOSITE;
jmarkel44 227:7153e89b6974 248 output_mail->priority = this->priority;
jmarkel44 227:7153e89b6974 249
jmarkel44 221:2a5e9902003c 250 strncpy(output_mail->input_tag, this->tag.c_str(), sizeof(output_mail->input_tag)-1);
jmarkel44 221:2a5e9902003c 251 strncpy(output_mail->output_tag, io_tag.c_str(), sizeof(output_mail->output_tag)-1);
jmarkel44 221:2a5e9902003c 252 strncpy(output_mail->id, this->id.c_str(), sizeof(output_mail->id)-1);
jmarkel44 230:11765008ff3a 253
jmarkel44 221:2a5e9902003c 254 OutputMasterMailBox.put(output_mail);
jmarkel44 221:2a5e9902003c 255 }
jmarkel44 221:2a5e9902003c 256
jmarkel44 221:2a5e9902003c 257 //
jmarkel44 221:2a5e9902003c 258 // method: unregisterControls
jmarkel44 221:2a5e9902003c 259 // description: unregister the control with the output task
jmarkel44 230:11765008ff3a 260 //
jmarkel44 221:2a5e9902003c 261 // @param none
jmarkel44 221:2a5e9902003c 262 // @return none
jmarkel44 221:2a5e9902003c 263 //
jmarkel44 221:2a5e9902003c 264 void CompositeControl::unregisterControls(void)
jmarkel44 221:2a5e9902003c 265 {
jmarkel44 221:2a5e9902003c 266 // loop through the list
jmarkel44 221:2a5e9902003c 267 StringAlgorithmMap::iterator pos;
jmarkel44 221:2a5e9902003c 268 pos = algorithmTable.find(this->ca);
jmarkel44 221:2a5e9902003c 269 if ( pos != algorithmTable.end() ) {
jmarkel44 221:2a5e9902003c 270 std::vector<OutputElement>::iterator it;
jmarkel44 221:2a5e9902003c 271 for ( it = outputs.begin(); it != outputs.end(); ++it ) {
jmarkel44 221:2a5e9902003c 272 sendMail(it->tag, ACTION_CONTROL_UNREGISTER);
jmarkel44 221:2a5e9902003c 273 }
jmarkel44 221:2a5e9902003c 274 } else {
jmarkel44 221:2a5e9902003c 275 logError("%s: failed to find the control algorithm %s\n", __func__, this->ca.c_str());
jmarkel44 221:2a5e9902003c 276 }
jmarkel44 221:2a5e9902003c 277 }
jmarkel44 221:2a5e9902003c 278
jmarkel44 221:2a5e9902003c 279 //
jmarkel44 232:8a86b5bf38f7 280 // method: display
jmarkel44 221:2a5e9902003c 281 // description: display the pertinents
jmarkel44 221:2a5e9902003c 282 //
jmarkel44 221:2a5e9902003c 283 // @param none
jmarkel44 221:2a5e9902003c 284 // @return none
jmarkel44 221:2a5e9902003c 285 //
jmarkel44 220:dbe21411f962 286 void CompositeControl::display(void)
jmarkel44 220:dbe21411f962 287 {
jmarkel44 221:2a5e9902003c 288 const char *mapper[] = { "INIT",
jmarkel44 221:2a5e9902003c 289 "START",
jmarkel44 221:2a5e9902003c 290 "CONTROL_OFF",
jmarkel44 242:3b0086a6d625 291 "CONTROL_ON"
jmarkel44 242:3b0086a6d625 292 };
jmarkel44 232:8a86b5bf38f7 293
jmarkel44 242:3b0086a6d625 294 printf("\r\n");
jmarkel44 232:8a86b5bf38f7 295 std::cout << left << setw(10) << setfill(' ') << "composite: ";
jmarkel44 232:8a86b5bf38f7 296 std::cout << left << setw(32) << setfill(' ') << controlFile;
jmarkel44 232:8a86b5bf38f7 297 std::cout << left << setw(20) << setfill(' ') << id;
jmarkel44 232:8a86b5bf38f7 298 std::cout << left << setw(20) << setfill(' ') << tag;
jmarkel44 232:8a86b5bf38f7 299 std::cout << left << setw(6) << setfill(' ') << priority;
jmarkel44 232:8a86b5bf38f7 300 std::cout << left << setw(20) << setfill(' ') << ca;
jmarkel44 232:8a86b5bf38f7 301 std::cout << left << setw(16) << setfill(' ') << mapper[currentState];
jmarkel44 221:2a5e9902003c 302
jmarkel44 220:dbe21411f962 303 vector<OutputElement>::iterator it;
jmarkel44 220:dbe21411f962 304 for ( it = outputs.begin(); it != outputs.end(); ++it ) {
jmarkel44 232:8a86b5bf38f7 305 std::cout << left << (*it).tag << ":" << (*it).response << " ";
jmarkel44 220:dbe21411f962 306 }
jmarkel44 232:8a86b5bf38f7 307
jmarkel44 232:8a86b5bf38f7 308 std::cout.flush();
jmarkel44 232:8a86b5bf38f7 309
jmarkel44 164:7cecd731882e 310 }