Erick / Mbed 2 deprecated ICE_BLE_TEST

Dependencies:   NaturalTinyShell_ice libmDot-12Sept mbed-rtos mbed

Fork of ICE by Erick

Revision:
221:2a5e9902003c
Parent:
220:dbe21411f962
Child:
222:94ea9a091d99
--- 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