Erick / Mbed 2 deprecated ICE-F412

Dependencies:   mbed-rtos mbed

Revision:
2:02cb20446785
Parent:
1:b2e90cda7a5a
--- a/ICE-Application/src/ConfigurationHandler/Controls/SequenceControl.cpp	Tue Jan 24 19:06:45 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,546 +0,0 @@
-/******************************************************************************
-*
-* File:                SequenceControl.cpp
-* Desciption:          ICE Sequence Control class implementation
-*
-*****************************************************************************/
-
-#include "SequenceControl.h"
-#include "ICELog.h"
-#include "cJSON.h"
-#include "global.h"
-
-#include <stdlib.h>
-#include <vector>
-#include <string>
-#include <iostream>
-#include <iomanip>
-#include <stdarg.h>
-#include <assert.h>
-#include "ModbusMasterApi.h"
-#include "ConfigurationHandler.h"
-
-// for debugging - this can be set via the console command:
-//      "debug-se 1
-bool debugSequenceControl = false;
-
-static void debug(const char *fmt, ...)
-{
-    if ( debugSequenceControl ) {
-        va_list vargs;
-        va_start(vargs, fmt);
-        vfprintf(stdout, fmt, vargs);
-        va_end(vargs);
-    }
-}
-
-//
-// method:          load
-// decsription:     load data from the control file
-//
-// @param[in]       _controlFile -> the control file
-// @param[out]      none
-// @return          true on success; false on error
-//
-bool SequenceControl::load(std::string _controlFile)
-{
-    controlFile = _controlFile;
-
-    // read the data into a buffer
-    char dataBuf[MAX_FILE_SIZE*3];
-    bool rc = GLOBAL_mdot->readUserFile(controlFile.c_str(), (void *)dataBuf, sizeof(dataBuf));
-    if ( rc != true ) {
-        logError("%s: failed to read %d bytes from %s", __func__, sizeof(dataBuf), controlFile.c_str());
-        // caller should destroy the object
-        return false;
-    }
-
-    // validate the JSON tags in the control file
-    if ( validateControlData(dataBuf) != true ) {
-        logError("%s: invalid control data.", __func__);
-        return false;
-    }
-
-    // assign object data from control file
-    copyControlData(dataBuf);
-    
-    // TODO: perform additional validation 
-
-    return true;
-}
-
-
-
-// method:          validateControlData
-// description:     validates the data in the control file
-//
-// @param[in]       dataBuf -> JSON formatted string
-// @param[out]      non
-// @return          true if valid; false otherwise
-//
-bool SequenceControl::validateControlData(const char *dataBuf)
-{
-    // parse the json data
-    bool rc = true;
-    cJSON * root = cJSON_Parse(dataBuf);
-
-    // parse the control header
-    if ( !cJSON_HasObjectItem(root, "id") ||
-            !cJSON_HasObjectItem(root, "startTrigger") ||
-            !cJSON_HasObjectItem(root, "sequence") ) {
-        logError("Sequence Control is missing expected tags");
-        cJSON_Delete(root);
-        return false;
-    }
-
-    // validate the sequence table
-    cJSON *sequenceTable  = cJSON_GetObjectItem(root, "sequence");
-    for ( int i = 0; i < cJSON_GetArraySize(sequenceTable); ++i ) {
-        cJSON *entry = cJSON_GetArrayItem(sequenceTable, i);
-        if ( !cJSON_HasObjectItem(entry, "startTrigger") ) {
-            logError("Sequence Table missing startTrigger tag");
-            rc = false;
-            break;
-        }
-        if ( !cJSON_HasObjectItem(entry, "actions") ) {
-            logError("Sequence table is missing actions tag");
-            rc = false;
-            // FIXME: finish the internals 
-            break;
-        }
-        if ( !cJSON_HasObjectItem(entry, "stopTrigger") ) {
-            logError("Sequence table is missing stopTrigger tag");
-            rc = false;
-            break;
-        }
-    }
-
-    cJSON_Delete(root);
-    return rc;
-}
-
-//
-// method:          copyControlData
-// description:     copy JSON formatted control data to object
-//
-// @param[in]       dataBuf -> JSON formatted data
-// @param[out]      none
-// @return          none
-//
-void SequenceControl::copyControlData(const char* dataBuf)
-{
-    cJSON *root = cJSON_Parse(dataBuf);
-
-    id           = cJSON_GetObjectItem(root, "id")->valuestring;
-    startTrigger = cJSON_GetObjectItem(root, "startTrigger")->valuestring;
-
-    // validate the sequence table
-    cJSON *sequenceTable  = cJSON_GetObjectItem(root, "sequence");
-    for ( int i = 0; i < cJSON_GetArraySize(sequenceTable); ++i ) {
-        cJSON *entry = cJSON_GetArrayItem(sequenceTable, i);
-
-        SequenceEntry n;
-
-        n.startTrigger = cJSON_GetObjectItem(entry, "startTrigger")->valuestring;
-        n.stopTrigger  = cJSON_GetObjectItem(entry, "stopTrigger")->valuestring;
-
-        cJSON *actionList = cJSON_GetObjectItem(entry, "actions");
-        for ( int j = 0; j < cJSON_GetArraySize(actionList); ++j ) {
-            cJSON *list = cJSON_GetArrayItem(actionList, j);
-            Action_t a;
-            a.action = cJSON_GetObjectItem(list, "action")->valuestring;
-            a.id     = cJSON_GetObjectItem(list, "id")->valuestring;
-            if ( a.action == "assign" ) {
-                a.value = atof(cJSON_GetObjectItem(list, "val")->valuestring);
-            } else {
-                a.value = 0;
-            }
-            n.actions.push_back(a);
-        }
-        // push this entry onto this sequence table
-        this->sequenceTable.push_back(n);
-    }
-
-    cJSON_Delete(root);
-}
-
-//
-// method:          start
-// decsription:     start the sequence control
-//
-// @param[in]       none
-// @param[out]      none
-// @return          none
-//
-void SequenceControl::start(void)
-{
-    currentState = SEQ_STATE_START;
-}
-
-//
-// method:          run
-// decsription:     run the sequence control (performs the updates)
-//
-// @param[in]       none
-// @param[out]      none
-// @return          OK on success; error otherwise
-//
-SequenceControlError_t SequenceControl::run(void)
-{
-    SequenceControlError_t rc = SEQUENCE_CONTROL_OK;
-
-    switch ( this->currentState ) {
-        case SEQ_STATE_INIT:
-            // do nothing
-            break;
-        case SEQ_STATE_START:
-            // here we need to wait for the start trigger to happen
-            if ( this->isControlStartTriggerOn() ) {
-                debug("\r%s: [START]->start trigger->[LOADING]\n", id.c_str());
-                ModbusValue val;
-                ModbusMasterReadRegister(startTrigger, &val);
-                debug("\r%s:%s: val.value = %f\n", id.c_str(), startTrigger.c_str(), val.value);
-                currentState = SEQ_STATE_LOADING_NEXT_ENTRY;
-            } else {
-                // just continue waiting for the start trigger to fire
-            }
-            break;
-        case SEQ_STATE_LOADING_NEXT_ENTRY: {
-            // this is a transient state
-            bool rc = this->loadNextEntry();
-            if ( rc ) {
-                debug("\r%s: [LOADING]->next entry->[WAIT-START]\n", id.c_str());
-                currentState = SEQ_STATE_WAITING_START;
-            } else {
-                debug("\r%s: [LOADING]->no entries->[FINISHED]\n", id.c_str());
-                currentState = SEQ_STATE_FINISHED;
-            }
-            break;
-        }
-        case SEQ_STATE_WAITING_START:
-            // wait for the start triggers to evaluate to true
-            if ( this->isCurrentEntryStartTriggerOn() ) {
-                debug("\r%s: [WAIT-START]->perform actions->[WAIT-STOP]\n", id.c_str());
-                performActions();
-                currentState = SEQ_STATE_WAITING_STOP;
-            } else {
-                // wait until the start trigger fires
-            }
-            break;
-        case SEQ_STATE_WAITING_STOP:
-            // wait for the stop triggers to evaluate to true
-            if ( this->isCurrentEntryStopTriggerOn() ) {
-                debug("\r%s: [WAIT-STOP]->stop trigger ON->[LOAD NEXT]\n", id.c_str());
-                currentState = SEQ_STATE_LOADING_NEXT_ENTRY;
-            } else {
-                // continue waiting
-            }
-            break;
-        case SEQ_STATE_FINISHED:
-            // do any cleanup work that's needed here.
-            debug("\r%s: [FINISHED]->clearing the reg->[START]\n", id.c_str());
-            ModbusMasterWriteRegister(this->startTrigger, 0);
-            this->currentState = SEQ_STATE_START;
-            break;
-        case SEQ_STATE_MAX:
-        default:
-            logError("%s: unknown state %u\n", __func__, this->currentState);
-            rc = SEQUENCE_CONTROL_UNK_STATE;
-            break;
-    }
-    return rc;
-}
-
-//
-// method:          isControlStartTriggerOn
-// description:     true if the start trigger evals to true
-//
-// @param[in]       none
-// @param[out]      none
-// @return          true if start trigger > 0; false otherwise
-//
-bool SequenceControl::isControlStartTriggerOn(void)
-{
-    ModbusValue value;
-    bool rc = ModbusMasterReadRegister(this->startTrigger, &value);
-    if ( rc && value.value ) {
-        return true;
-    }
-
-    return false;
-}
-
-//
-// method:          isCurrentEntryStartTriggerOn
-// description;     true the current sequence entry start trigger evals to true
-//
-// @param[in]       none
-// @param[out]      none
-// @return          none
-//
-bool SequenceControl::isCurrentEntryStartTriggerOn(void)
-{
-    ModbusValue value;
-    bool rc = ModbusMasterReadRegister(this->currentEntry.startTrigger, &value);
-    if ( rc != true ) {
-        logError("%s: failed to read %s from modbus master",
-                 __func__, this->currentEntry.startTrigger.c_str());
-        return rc;
-    } else if ( value.value ) {
-        debug("\r%s:%s-> returning true\n", __func__, id.c_str());
-        return true;
-    }
-    return false;
-}
-
-//
-// method:          isCurrentEntryStopTriggerOn
-// description;     true the current sequence entry start trigger evals to true
-//
-// @param[in]       none
-// @param[out]      none
-// @return          none
-//
-bool SequenceControl::isCurrentEntryStopTriggerOn(void)
-{
-    ModbusValue value;
-    bool rc = ModbusMasterReadRegister(this->currentEntry.stopTrigger, &value);
-    if ( rc != true ) {
-        logError("%s: failed to read %s from modbus master",
-                 __func__, this->currentEntry.stopTrigger.c_str());
-        return rc;
-    } else if ( value.value ) {
-        debug("\r%s:%s-> returning true\n", __func__, id.c_str());
-        return true;
-    }
-    return false;
-}
-
-//
-// method:          loadNextEntry
-// description:     load the next entry from the sequence table
-//
-// @param[in]       none
-// @param[out[      none
-// @return          true is loaded; false otherwise
-//
-bool SequenceControl::loadNextEntry(void)
-{
-    if ( this->sequenceTable.empty() ) {
-        debug("\r%s: sequence table is empty\n", id.c_str());
-        return false;
-    }
-    if ( nextEntryIndex < this->sequenceTable.size() ) {
-        currentEntry = sequenceTable.at(nextEntryIndex++);
-        printf("\r...successfully loaded new entry\n");
-        return true;
-    }
-    return false;
-}
-
-//
-// method:          performActions
-// description:     perform the actions associated with the current entry
-//
-// @param[in]       none
-// @param[out]      none
-// @return          none
-//
-SequenceControlError_t SequenceControl::performActions(void)
-{
-    SequenceControlError_t rc = SEQUENCE_CONTROL_OK;
-
-    // possible action types:
-    //      create      -> create a control
-    //      delete      -> delete a control
-    //      modify      -> modify a control
-    //      assign      -> assign a value to a modbus register 
-    //      execute     -> execute a script
-    if ( !currentEntry.actions.empty() ) {
-        std::vector<Action_t>::const_iterator pos;
-        for ( pos = currentEntry.actions.begin(); pos != currentEntry.actions.end(); ++pos ) {
-            debug("\raction->%s on ID->%s\n", pos->action.c_str(), pos->id.c_str());
-            // based on the action, we need to determine what to do
-            // 1: determine the action
-            // 2: see if the file exists (catastrophic)
-            // 3: if it's a create or delete action, send a message to the
-            //    configuration handler
-            if ( pos->action == "createsp" ) {
-                rc = createSubControl(pos->id, CONTROL_SETPOINT);
-                assert(!rc);
-            } else if ( pos->action == "createtm" ) {
-                rc = createSubControl(pos->id, CONTROL_TIMER);
-                assert(!rc);
-            } else if ( pos->action == "deletesp" ) {
-                rc = destroySubControl(pos->id, CONTROL_SETPOINT);
-                assert(!rc);
-            } else if ( pos->action == "deletetm" ) {
-                rc = destroySubControl(pos->id, CONTROL_TIMER);
-                assert(!rc);
-            } else if ( pos->action == "execute"  ) {
-                  // not implemented 
-            } else if ( pos->action == "assign"   ) {
-              if ( assignRegister(pos->id, pos->value) != true ) {
-                  assert(0);
-              }
-            } else {
-                logError("%s: unknown action %s (%s)", __func__, pos->action.c_str(), pos->id.c_str());
-                rc = SEQUENCE_CONTROL_BAD_ACTION;
-            }
-        }
-    } else {
-        logInfo("%s: no entries in the action table", __func__);
-    }
-    return rc;
-}
-
-//
-// method:              createSubControl
-// description:         create a control that's listed in the sequence table
-//
-// @param[in]           action (create, destroy, etc.)
-// @param[in]           id -> control identifier
-// @param[out[          none
-// @return              OK on success; error otherwise
-//
-SequenceControlError_t SequenceControl::createSubControl(const std::string controlId,     
-                                                         Control_t type) 
-{
-    std::string file_prefix;
-    
-    switch (type) {
-        case CONTROL_SETPOINT:
-            file_prefix = CONTROL_SP_STR;
-            break;
-        case CONTROL_TIMER:
-            file_prefix = CONTROL_TM_STR;
-            break;
-        default:
-            logError("%s %s unsupported type %d", __func__, id.c_str(), type);
-            return SEQUENCE_CONTROL_BAD_CONTROL_TYPE;
-    }
-    
-    char filename[64];
-    snprintf(filename, sizeof(filename), "%s%s_%s%s.json", 
-               SEQUENCE_CONTROL_FILENAME_PREFIX, 
-               this->id.c_str(), 
-               file_prefix.c_str(),
-               controlId.c_str());
-               
-    debug("\r%s: searching for %s\n", id.c_str(), filename);
-    
-    // send a message to the configuration handler to create the control
-    ConfigMessage_t *msg  = ConfigHandlerMailBox.alloc();
-    memset(msg, 0, sizeof(ConfigMessage_t));
-    msg->action  = ACTION_CREATE;
-    msg->control = (Control_t)type;
-    strncpy(msg->controlFile, filename, sizeof(msg->controlFile)-1);
-
-    printf("%s: Sending a create request for control %s\r\n",
-           __func__, msg->controlFile);
-
-    ConfigHandlerMailBox.put(msg);
-
-    return SEQUENCE_CONTROL_OK;
-}
-
-//
-// method:              destroySubControl
-// description:         destroy a control that's listed in the sequence table
-//
-// @param[in]           action (create, destroy, etc.)
-// @param[in]           id -> control identifier
-// @param[out[          none
-// @return              OK on success; error otherwise
-//
-SequenceControlError_t SequenceControl::destroySubControl(const std::string controlId,
-                                                          Control_t type)
-{
-    std::string file_prefix;
-    
-    switch (type) {
-        case CONTROL_SETPOINT:
-            file_prefix = CONTROL_SP_STR;
-            break;
-        case CONTROL_TIMER:
-            file_prefix = CONTROL_TM_STR;
-            break;
-        default:
-            logError("%s %s unsupported type %d", __func__, id.c_str(), type);
-            return SEQUENCE_CONTROL_BAD_CONTROL_TYPE;
-    }
-    
-    char filename[64];
-    snprintf(filename, sizeof(filename), "%s%s_%s%s.json", 
-               SEQUENCE_CONTROL_FILENAME_PREFIX, 
-               this->id.c_str(), 
-               file_prefix.c_str(),
-               controlId.c_str());
-               
-    debug("\r%s: searching for %s\n", id.c_str(), filename);
-
-    // send a message to the configuration handler to create the control
-    ConfigMessage_t *msg  = ConfigHandlerMailBox.alloc();
-    memset(msg, 0, sizeof(ConfigMessage_t));
-    msg->action  = ACTION_DESTROY;
-    msg->control = (Control_t)type;
-    strncpy(msg->controlFile, filename, sizeof(msg->controlFile)-1);
-
-    printf("%s: Sending a create request for control %s\r\n",
-           __func__, msg->controlFile);
-
-    ConfigHandlerMailBox.put(msg);
-
-    return SEQUENCE_CONTROL_OK;
-}
-
-bool SequenceControl::assignRegister(const std::string id, float value)
-{
-    return (ModbusMasterWriteRegister(id, value));
-}
-
-//
-// method:          display
-// decsription:     display the control data
-//
-// @param[in]       none
-// @param[out]      none
-// @return          none
-//
-void SequenceControl::display(void)
-{
-    const char *mapper[] = { "INIT",
-                             "START",
-                             "LOADING",
-                             "WAIT-START",
-                             "WAIT-STOP",
-                             "FINISHED",
-                             "FAILED",
-                             "NULL"
-                           };
-
-    printf("\rid-> %s\n", id.c_str());
-    printf("\rstartTrigger-> %s\n",  startTrigger.c_str());
-    printf("\rSequenceTable: \n");
-
-    std::vector<SequenceEntry>::const_iterator seqIt;
-
-    int entry = 0;
-
-    for ( seqIt = sequenceTable.begin(); seqIt != sequenceTable.end(); ++seqIt ) {
-        printf("\rEntry %d: %s\n \r  startTrigger: %s\n",
-               ++entry,
-               (entry == nextEntryIndex-1) ? "<-currently active" : "",
-               seqIt->startTrigger.c_str());
-        std::vector<Action_t>::const_iterator actIt;
-        for ( actIt = seqIt->actions.begin(); actIt != seqIt->actions.end(); ++actIt ) {
-            printf("\r\taction-> %s, id-> %s ", actIt->action.c_str(), actIt->id.c_str());
-            if ( actIt->action == "assign" ) printf("value -> %f", actIt->value);
-            printf("\r\n");
-        }
-        printf("\r  stopTrigger: %s\n", seqIt->stopTrigger.c_str());
-    }
-
-    printf("\r\n\rcurrent state = %s\r\n\r\n", mapper[this->currentState]);
-}
-