Erick / Mbed 2 deprecated ICE-F412

Dependencies:   mbed-rtos mbed

Revision:
2:02cb20446785
Parent:
1:b2e90cda7a5a
--- a/ICE-Application/src/OutputTask/OutputTask.cpp	Tue Jan 24 19:06:45 2017 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,545 +0,0 @@
-/******************************************************************************
- *
- * File:                OutputTask.cpp
- * Desciption:          source for the ICE Output task
- *
- *****************************************************************************/
-#include <vector>
-#include <string>
-#include <algorithm>
-#include <assert.h>
-#include <time.h>
-#include "OutputTask.h"
-#include "global.h"
-#include "cJSON.h"
-#include "ModbusMasterApi.h"
-#include "LoggerApi.h"
-#include "Control.h"
-#include "rtc.h"
-#include "ICELog.h"
-
-//#include "../add-ons/MTSLog/MTSLog.h"
-
-
-// local functions
-static int  createOutput(const char *controlFile);
-static int  loadPersistentOutputs(void);
-static void writeOutputs(const std::string, const std::string);
-static int  enableOutputReqHandler(OutputControlMsg_t *msg);
-static int  disableOutputReqHandler(OutputControlMsg_t *msg);
-static int  unregisterControl(const char *id, unsigned int pri, const char *output);
-static void dumpEventRecord(EventReasonStruct_t &ev);
-
-//
-// The Output Map
-//
-// this is the main data structure used to distinguish which control has
-// priority of an output. the layout is as-follows:
-//
-// outputMap["o_rly1"]-> Control<"ManControl_rly1",       100, ON > <-- highest pri control manipulates relay
-//                       Control<"Flowswitch",            700  OFF> <-- lower pri  (queued up)
-//                       Control<"SetpointControl_rly1",  800, OFF> <-- lowest pri (queued up)
-//
-// outputMap["o_rly2"]-> Control<"Flowswitch",            700, OFF>
-//                    -> Control<"SetpointControl_rly2",  800, OFF>
-//
-// outputMap["o_rly3"]-> Control<"ManControl_rly3",       100, ON >
-//                       Control<"Flowswitch",            700, ON >
-//                       Control<"TimerControl_rly3",     750, ON >
-//
-//
-// The Control Vector (per relay) is always sorted by priority, whereas
-// the highest priority control (lower priority number) is at the front
-// (v.front()) of the list.
-//
-
-typedef std::map<std::string, std::vector<Control> > StringOutputVector_t;
-static StringOutputVector_t outputMap;
-
-// operator for sorting the outputs vectors
-bool operator<(const Control &control1, const Control &control2)
-{
-    return control1.getPriority() < control2.getPriority();
-}
-
-/*****************************************************************************
- * Function:            OutputTask
- * Description:         Main entry point for the Output Task
- *
- * @param               args -> not used
- * @return              none
- *****************************************************************************/
-void OutputTask(void const *args)
-{
-    int rc;
-    (void)args;
-
-    printf("\r%s has started...\n", __func__);
-
-#ifdef LOAD_PERSISTENT_CONFIGURATIONS
-    if ( loadPersistentOutputs() != 0 ) {
-        logError("Failed to load persistent outputs");
-    }
-#endif 
-
-    // signal the main thread to continue
-    osSignalSet(mainThreadId, sig_config_continue);
-
-    while (true) {
-        // wait for a message
-        osEvent evt = OutputMasterMailBox.get();
-        if (evt.status == osEventMail) {
-
-            OutputControlMsg_t *msg = (OutputControlMsg_t*) evt.value.p;
-
-            switch ( msg->action ) {
-                case ACTION_NEW:
-                    // read the file and and create an output entry
-                    rc = createOutput(msg->controlFile);
-                    if ( rc != 0 ) {
-                        logError("%s: failed to create output %s\n",
-                                 __func__, msg->controlFile);
-                    }
-                    break;
-                case ACTION_CONTROL_ON:
-                    logInfo("%s is requesting ON control of %s", msg->id, msg->output_tag);
-                    rc = enableOutputReqHandler(msg);
-                    if ( rc != 0 ) {
-                        logError("%s: failed to enable output for %s",
-                                 __func__, msg->id);
-                    }
-                    break;
-                case ACTION_CONTROL_OFF:
-                    logInfo("%s is requesting OFF control of %s", msg->id, msg->output_tag);
-                    rc = disableOutputReqHandler(msg);
-                    if ( rc != 0 ) {
-                        logError("%s: failed to disable output for %s",
-                                 __func__, msg->id);
-                    }
-                    break;
-                case ACTION_CONTROL_UNREGISTER:
-                    logInfo("%s is requesting its deletion from %s", msg->id, msg->output_tag);
-                    rc = unregisterControl(msg->id, msg->priority, msg->output_tag);
-                    if ( rc != 0 ) {
-                        logError("%s: failed to unregister control %s",
-                                 __func__, msg->id);
-                    }
-                    break;
-                default:
-                    logError("%s unknown action %u", __func__, msg->action);
-                    break;
-            }
-
-            // free the message
-            OutputMasterMailBox.free(msg);
-
-            // refresh the outputs
-            writeOutputs(msg->id, msg->output_tag);
-        }
-    }
-}
-
-/*****************************************************************************
- * Function:            publishEvent
- * Description:         publish an event to the logger
- *
- * @param               output  -> the output channel
- * @param               control -> the control, this can be null
- * @return              none
- *****************************************************************************/
-void publishEvent(std::string output, const Control *control)
-{
-
-    EventReasonStruct_t ev;
-    ModbusValue input_value;
-    ModbusValue output_value;
-    memset(&ev, 0, sizeof(ev));
-
-
-    // if there's no control, that means the only control that was on
-    // the relay stack has been destroyed, so we'll send a NO CONTROL
-    // event code.
-    if ( !control ) {
-        ev.eventReason = EVENT_REASON_NO_CONTROL;
-        ModbusMasterReadRegister(output, &output_value);
-        strncpy(ev.outputTag, output.c_str(), sizeof(ev.outputTag));
-        ev.outputValue = output_value.value;
-        dumpEventRecord(ev);
-        EventLoggerApi(ev);
-        return;
-    }
-
-    switch ( control->getControlType() ) {
-        case CONTROL_SETPOINT:
-        case CONTROL_COMPOSITE:
-            ev.eventReason = EVENT_REASON_AUTO;
-            strncpy(ev.inputTag, control->getInput().c_str(), sizeof(ev.inputTag));
-            strncpy(ev.outputTag, output.c_str(), sizeof(ev.outputTag));
-            ModbusMasterReadRegister(control->getInput(), &input_value);
-            ModbusMasterReadRegister(output, &output_value);
-            ev.inputValue = input_value.value;
-            ev.outputValue = output_value.value;
-            dumpEventRecord(ev);
-            EventLoggerApi(ev);
-            break;
-
-        case CONTROL_MANUAL:
-            ev.eventReason = EVENT_REASON_MANUAL;
-            strncpy(ev.outputTag, output.c_str(), sizeof(ev.outputTag));
-            ModbusMasterReadRegister(output, &output_value);
-            ev.outputValue = output_value.value;
-            dumpEventRecord(ev);
-            EventLoggerApi(ev);
-            break;
-
-        case CONTROL_TIMER:
-            ev.eventReason = EVENT_REASON_TIMER;
-            strncpy(ev.outputTag, output.c_str(), sizeof(ev.outputTag));
-            ModbusMasterReadRegister(output, &output_value);
-            ev.outputValue = output_value.value;
-            dumpEventRecord(ev);
-            EventLoggerApi(ev);
-            break;
-
-        case CONTROL_FAILSAFE:
-        case CONTROL_SENSOR_ERROR:
-            ev.eventReason = EVENT_REASON_FAILSAFE;
-            strncpy(ev.inputTag, control->getInput().c_str(), sizeof(ev.inputTag));
-            strncpy(ev.outputTag, output.c_str(), sizeof(ev.outputTag));
-            ModbusMasterReadRegister(control->getInput(), &input_value);
-            ModbusMasterReadRegister(output, &output_value);
-            ev.inputValue = input_value.value;
-            ev.outputValue = output_value.value;
-            dumpEventRecord(ev);
-            EventLoggerApi(ev);
-            break;
-
-        default:
-            logError("%s: unknown control type\n", __func__);
-            break;
-    }
-}
-
-/*****************************************************************************
- * Function:            writeOutputs
- * Description:         send a message to the modbus master of who's in control
- *
- *
- * @param[in]           id          -> control identifier
- * @param[in]           output_tag  -> the output to write
- * @return              none
- *****************************************************************************/
-static void writeOutputs(const std::string id, const std::string output_tag)
-{
-    (void) id;
-
-    if ( output_tag.empty() ) {
-        logError("%s: invalid output tag", __func__);
-        return;
-    }
-
-    StringOutputVector_t::const_iterator pos;
-
-    // find the output
-    pos = outputMap.find(output_tag);
-    if ( pos != outputMap.end() ) {
-        if ( pos->second.empty() ) {
-            // we found the output but nothing's controlling it...
-            ModbusMasterWriteRegister(pos->first, RELAY_STATUS_NOT_CONTROLLED);
-            publishEvent(pos->first, NULL);
-        } else {
-            // get the mapped state for the highest priority control
-            int mappedState = pos->second.begin()->getMappedState();
-
-            // read the register value for this output
-            ModbusValue value;
-            ModbusMasterReadRegister(pos->first, &value);
-
-            // a new higher priority control is manipulating the output,
-            // so send the new values to the modbus and publish an event
-            if ( value.value != mappedState ) {
-                ModbusMasterWriteRegister(pos->first, mappedState);
-                Control t = *(pos->second.begin());
-                publishEvent(pos->first, &t);
-            }
-        }
-        // TODO: This may be a virtual output, so we'll need to see if it
-        // exists in the vregmap
-    } else {
-        logError("%s failed to find the selected output %s",
-                 __func__, output_tag.c_str());
-    }
-}
-
-/*****************************************************************************
- * Function:            createOutput
- * Description:
- *
- * @param               outputFile -> name of output file
- * @return              none
- *****************************************************************************/
-static int createOutput(const char *outputFile)
-{
-    char dataBuf[MAX_FILE_SIZE];
-    bool status = GLOBAL_mdot->readUserFile(outputFile, (void *)dataBuf, sizeof(dataBuf));
-    if ( status != true ) {
-        logError("%s failed to read %s", __func__, outputFile);
-        return -1;
-    }
-
-    cJSON * root = cJSON_Parse(dataBuf);
-    if ( !cJSON_HasObjectItem(root, "id") ) {
-        logError("%s: error extracting expected tags", __func__);
-        cJSON_Delete(root);
-        return -1;
-    }
-
-    std::string id = cJSON_GetObjectItem(root,"id")->valuestring;
-    cJSON_Delete(root);
-
-    std::vector<Control> v;
-    outputMap[id] = v;
-
-    return 0;
-}
-
-/*****************************************************************************
- * Function:            enableOutputReqHandler
- * Description:         handle a request to enable an output
- *
- * @param[in]           msg -> the message request
- * @return              -1 on error
- *****************************************************************************/
-static int enableOutputReqHandler(OutputControlMsg_t *msg)
-{
-    // attempt to find the output in the map
-    StringOutputVector_t::iterator pos;
-
-    pos = outputMap.find(msg->output_tag);
-    if ( pos == outputMap.end() ) {
-        logError("%s: failed to find the designated output %s\n",
-                 __func__, msg->output_tag);
-        return -1;
-    }
-
-    if ( pos->second.empty() ) {
-        // this is a new request
-        std::string cid(msg->id);
-        std::string input(msg->input_tag);
-        Control c(cid, msg->controlType, input, msg->priority, CONTROL_ON);
-        pos->second.push_back(c);
-    } else {
-        // find this control in the list
-        std::vector<Control>::iterator v;
-        for ( v = pos->second.begin(); v != pos->second.end(); ++v ) {
-            if ( strcmp(v->getId().c_str(), msg->id) == 0 )  {
-                v->setState(CONTROL_ON);
-                break;
-            }
-        }
-        if ( v == pos->second.end() ) {
-            // this is a new request, so add it and sort the vector
-            std::string cid(msg->id);
-            std::string input(msg->input_tag);
-            Control c(cid, msg->controlType, input, msg->priority, CONTROL_ON);
-            pos->second.push_back(c);
-            std::sort(pos->second.begin(), pos->second.end());
-        }
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * Function:            disableOutputReqHandler
- * Description:         handle a request to disable an output
- *
- * @param[in]           msg -> the message request
- * @return              none
- *****************************************************************************/
-static int disableOutputReqHandler(OutputControlMsg_t *msg)
-{
-    // attempt to find the output in the map
-    StringOutputVector_t::iterator pos;
-
-    pos = outputMap.find(msg->output_tag);
-    if ( pos == outputMap.end() ) {
-        logError("%s: failed to find the designated output %s\n",
-                 __func__, msg->output_tag);
-        return -1;
-    }
-
-    // if the control list is empty, push this control on the list
-    if ( pos->second.empty() ) {
-        std::string cid(msg->id);
-        std::string input(msg->input_tag);
-        Control c(cid, msg->controlType, input, msg->priority, CONTROL_OFF);
-        pos->second.push_back(c);
-    } else {
-        // find this control in the list
-        std::vector<Control>::iterator v;
-        for ( v = pos->second.begin(); v != pos->second.end(); ++v ) {
-            if ( strcmp(v->getId().c_str(), msg->id) == 0 )  {
-                v->setState(CONTROL_OFF);
-                break;
-            }
-        }
-
-        if ( v == pos->second.end() ) {
-            // this is a new request, so add it and sort the vector
-            std::string cid(msg->id);
-            std::string input(msg->input_tag);
-            Control c(cid, msg->controlType, input, msg->priority, CONTROL_OFF);
-            pos->second.push_back(c);
-            std::sort(pos->second.begin(), pos->second.end());
-        }
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * Function:            unregisterControl
- * Description:
- *
- * @param               id     -> control identifier
- * @param               pri    -> priority
- * @param               output -> output (e.g. "o_rly05")
- *
- * @return              0 on success; -1 on error
- *****************************************************************************/
-static int unregisterControl(const char *id, unsigned int pri, const char *output)
-{
-    // attempt to find the output in the map
-    StringOutputVector_t::iterator pos;
-    bool found = false;
-
-    pos = outputMap.find(output);
-    if ( pos == outputMap.end() ) {
-        logError("%s: failed to find the designated output %s\n",
-                 __func__, output);
-        return -1;
-    }
-
-    // find the control in the list
-    std::vector<Control>::iterator v;
-    for ( v = pos->second.begin(); v != pos->second.end(); ++v) {
-        if ( strcmp(v->getId().c_str(), id) == 0 )  {
-            pos->second.erase(v);
-            found = true;
-            break;
-        }
-    }
-
-    if ( !found ) {
-        logError("%s: failed to find control %s in list", __func__, id);
-        return -1;
-    }
-    return 0;
-}
-
-/*****************************************************************************
- * Function:            loadPersistentOutputs
- * Description:         build the output map
- *
- * @param               none
- * @return              0 on success; -1 of failure
- *****************************************************************************/
-static int loadPersistentOutputs(void)
-{
-    bool status;
-    cJSON *root;
-    int rc = 0;
-
-    printf("\rLoading persistent outputs:\n");
-
-    std::vector<std::string> file_list = GLOBAL_mdot->listUserFiles();
-
-    for (std::vector<std::string>::const_iterator i = file_list.begin(); i != file_list.end(); ++i) {
-        // load in all of the output files
-        if( strncmp( i->c_str(), OUTPUT_STR, strlen(OUTPUT_STR)) == 0 ||
-                strncmp( i->c_str(), VOUTPUT_STR, strlen(VOUTPUT_STR)) == 0) {
-            char scratchBuf[MAX_FILE_SIZE];
-
-            status = GLOBAL_mdot->readUserFile(i->c_str(), scratchBuf, MAX_FILE_SIZE);
-            if( status != true ) {
-                logError("%s: failed to read %s", __func__, i->c_str());
-                rc = -1;
-            } else {
-                logInfo("%s: successfully read %s", __func__, i->c_str());
-            }
-
-            root = cJSON_Parse(scratchBuf);
-            std::string id = cJSON_GetObjectItem(root,"id")->valuestring;
-            printf("\r   output %s loaded\n", i->c_str());
-            cJSON_Delete(root);
-
-            // emplace the empty control vector into the output map
-            std::vector<Control> v;
-            outputMap[id] = v;
-        }
-    }
-    return rc;
-}
-
-/*****************************************************************************
- * Function:            dumpEventRecord
- * Description:         display the contents of an event record
- *
- * @param[in]           ev -> the event structure
- * @return              none
- *****************************************************************************/
-static void dumpEventRecord(EventReasonStruct_t &ev)
-{
-    const char *mapper[] = { "auto",
-                             "manual",
-                             "timer",
-                             "flow",
-                             "failsafe",
-                             "no control"
-                           };
-
-    time_t rawtime;
-    time(&rawtime);
-
-    int iyr=0, imo=0, idy=0, ihr=0, imn=0, isc=0;
-#undef TODO_ICE
-#if 0 
-    rtc_get_time(&iyr, &imo, &idy, &ihr, &imn, &isc);
-#endif 
-
-    printf("\rEVENT RECORD (%04d-%02d-%02d %02d:%02d:%02d)\r\n",
-           iyr, imo, idy, ihr, imn, isc);
-    printf("\rev.eventReason = %d (%s)\n",    ev.eventReason, mapper[ev.eventReason]);
-    printf("\rev.inputTag    = %s\n",    ev.inputTag[0]  ? ev.inputTag  : "empty");
-    printf("\rev.outputTag   = %s\n",    ev.outputTag[0] ? ev.outputTag : "empty");
-    printf("\rev.inputValue  = %.02f\n", ev.inputValue);
-    printf("\rev.outputValue = %.02f (%s)\n", ev.outputValue,
-           ((unsigned int)ev.outputValue & 1 == 1) ? "on" : "off");
-}
-
-/*****************************************************************************
- * Function:            DisplayOutputs
- * Description:         Display a list of outputs and their controls
- *
- * @param               none
- * @return              none
- *****************************************************************************/
-void DisplayOutputs(void)
-{
-    StringOutputVector_t::iterator pos;
-
-    for ( pos = outputMap.begin(); pos != outputMap.end(); ++pos ) {
-        if ( pos->second.empty() ) {
-            printf("\r  [%s]-> [no controls] \n", pos->first.c_str());
-        } else {
-            printf("\r  [%s]-> ", pos->first.c_str());
-            std::vector<Control>::iterator i;
-            for ( i = pos->second.begin(); i != pos->second.end(); ++i ) {
-                i->display();
-            }
-            printf("\n");
-        }
-    }
-    printf("\r\n");
-}