Changeset 14518 for trunk/FACT++/src


Ignore:
Timestamp:
10/24/12 12:35:52 (12 years ago)
Author:
tbretz
Message:
Almost working version.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/pwrctrl.cc

    r14516 r14518  
    11#include <boost/bind.hpp>
    22
    3 #include <string>    // std::string
    4 #include <algorithm> // std::transform
    5 #include <cctype>    // std::tolower
     3#include <string>
    64
    75#include <QtXml/QDomDocument>
     
    1816#include "tools.h"
    1917
    20 #include "HeadersLid.h"
     18#include "HeadersPower.h"
    2119
    2220namespace ba = boost::asio;
     
    2927{
    3028protected:
    31 
    32     struct Status
    33     {
    34         bool fWaterFlowOk;
    35         bool fWaterLevelOk;
    36 
    37         bool fPwrBiasOn;
    38         bool fPwr24VOn;
    39         bool fPwrPumpOn;
    40         bool fPwrDriveOn;
    41 
    42         bool fDriveMainSwitchOn;
    43         bool fDriveFeedbackOn;
    44 
    45         Status() { }
    46 
    47         bool Set(bool &rc, const QString &value)
    48         {
    49             rc = value.toInt();
    50             return true;
    51         }
    52 
    53         bool Set(const QDomNamedNodeMap &map)
    54         {
    55             if (!map.contains("id") || !map.contains("title"))
    56                 return false;
    57 
    58             QString item  = map.namedItem("id").nodeValue();
    59             QString value = map.namedItem("title").nodeValue();
    60 
    61             if (item==(QString("flow_meter")))
    62                 return Set(fWaterFlowOk, value);
    63 
    64             if (item==(QString("level")))
    65                 return Set(fWaterLevelOk, value);
    66 
    67             if (item==(QString("bias_power")))
    68                 return Set(fPwrBiasOn, value);
    69 
    70             if (item==(QString("power_24v")))
    71                 return Set(fPwr24VOn, value);
    72 
    73             if (item==(QString("pump")))
    74                 return Set(fPwrPumpOn, value);
    75 
    76             if (item==(QString("drive_power")))
    77                 return Set(fPwrDriveOn, value);
    78 
    79             if (item==(QString("drive_on")))
    80                 return Set(fDriveMainSwitchOn, value);
    81 
    82             if (item==(QString("drive_enable")))
    83                 return Set(fDriveFeedbackOn, value);
    84 
    85             return false;
    86         }
    87 
    88         void Print(ostream &out, const string &title, const bool &val, const string &t="enabled", const string &f="disabled")
    89         {
    90             out << setw(15) << (title+":");
    91             if (val)
    92                 out << kGreen << t << endl;
    93             else
    94                 out << kRed   << f << endl;
    95         }
    96 
    97         void Print(ostream &out)
    98         {
    99             Print(out, "Water flow",     fWaterFlowOk,  "ok", "low");
    100             Print(out, "Water level",    fWaterLevelOk, "ok", "low");
    101             Print(out, "Power bias",     fPwrBiasOn);
    102             Print(out, "Power 24V",      fPwr24VOn);
    103             Print(out, "Power pump",     fPwrPumpOn);
    104             Print(out, "Power drive",    fPwrDriveOn);
    105             Print(out, "Drive main",     fDriveMainSwitchOn, "on", "off");
    106             Print(out, "Drive feedback", fDriveFeedbackOn,   "on", "off");
    107         }
    108 
    109     };
     29    bool fIsValid;
    11030
    11131private:
     
    11333
    11434    bool fIsVerbose;
     35    bool fDebugRx;
    11536
    11637    string fSite;
     
    12344    Time fLastReport;
    12445
    125     Status fStatus;
    126 
    127     virtual void Update(const Status &)
     46    Power::Status fStatus;
     47
     48    virtual void Update(const Power::Status &)
    12849    {
    12950    }
     
    13253    void ProcessAnswer()
    13354    {
    134         if (fIsVerbose)
     55        if (fDebugRx)
    13556        {
    13657            Out() << "------------------------------------------------------" << endl;
     
    13960        }
    14061
    141         /*
    142         fRdfData =
    143             "HTTP/1.1 200 OK\n"
    144             "Content-Type: text/html\n"
    145             "Connnection: close\r\n"
    146             "\r\n"
    147             "<!DOCTYPE HTML>\n"
    148             "<html><head>\n"
    149             "<meta http-equiv=\"refresh\" content=\"1 URL=index.html\"/>\n"
    150             "<title>FACT camera power interlock control</title>\n"
    151             "</head><body>\n"
    152             "<FORM NAME=\"Form\">"
    153             "<P/><INPUT TYPE=\"SUBMIT\" NAME=\"D2off\"    VALUE=\"Disable Pump\"/>--> FC_OFF HIGH for 0.5 seconds <br/>\n"
    154             "<P/><INPUT TYPE=\"SUBMIT\" NAME=\"D2on\"     VALUE=\"Enable Pump\" />--> FC_ON  HIGH for 3.0 seconds <br/>\n"
    155             "<P/><INPUT TYPE=\"SUBMIT\" NAME=\"toggle_x\" VALUE=\"Toggle X\"    />--> ... well it toggles X       <br/>\n"
    156             "<P/><INPUT TYPE=\"SUBMIT\" NAME=\"toggle_y\" VALUE=\"Toggle Y\"    />--> ... well it toggles Y       <br/>\n"
    157             "FC_OK :2  is <font color=\"red\"   size=\"20\"><span id=\"FC_OK\" value=\"0\">LOW  </span></font><br />\n"
    158             "BP_ON :3  is <font color=\"red\"   size=\"20\"><span id=\"BP_ON\" value=\"0\">LOW  </span></font><br />\n"
    159             "IL_ON :14 is <font color=\"green\" size=\"20\"><span id=\"IL_ON\" value=\"1\">HIGH </span></font><br />\n"
    160             "FL_OK :15 is <font color=\"green\" size=\"20\"><span id=\"FL_OK\" value=\"1\">HIGH </span></font><br />\n"
    161             "FP_EN :16 is <font color=\"red\"   size=\"20\"><span id=\"FP_EN\" value=\"0\">LOW  </span></font><br />\n"
    162             "X_ON  :17 is <font color=\"red\"   size=\"20\"><span id=\"X_ON\"  value=\"0\">LOW  </span></font><br />\n"
    163             "Y_ON  :18 is <font color=\"red\"   size=\"20\"><span id=\"Y_ON\"  value=\"0\">LOW  </span></font><br />\n"
    164             "Z_OK  :19 is <font color=\"red\"   size=\"20\"><span id=\"Z_OK\"  value=\"0\">LOW  </span></font><br />\n"
    165             "</FORM>\n"
    166             "</body></html>\n";
    167         */
    168 
    16962        const size_t p1 = fRdfData.find("\r\n\r\n");
    170         //const size_t p1 = fRdfData.find("\n\n");
    17163        if (p1==string::npos)
    17264        {
     
    18779        }
    18880
     81        if (fDebugRx)
     82            Out() << "Parsed:\n-------\n" << doc.toString().toStdString() << endl;
     83
     84        const QDomNodeList imageElems = doc.elementsByTagName("span");
     85
     86        for (unsigned int i=0; i<imageElems.length(); i++)
     87        {
     88            const QDomElement e = imageElems.item(i).toElement();
     89
     90            const QDomNamedNodeMap att = e.attributes();
     91
     92            if (fStatus.Set(att))
     93                fIsValid = true;
     94        }
     95
    18996        if (fIsVerbose)
    190         {
    191             Out() << "Parsed:\n-------\n" << doc.toString().toStdString() << endl;
    192             Out() << "------------------------------------------------------" << endl;
    193         }
    194 
    195         const QDomNodeList imageElems = doc.elementsByTagName("span"); // "input"
    196 
    197         /*
    198         // elementById
    199         for (unsigned int i=0; i<imageElems.length(); i++)
    200         {
    201             QDomElement e = imageElems.item(i).toElement();
    202             Out() << "<" << e.tagName().toStdString() << " ";
    203 
    204             QDomNamedNodeMap att = e.attributes();
    205 
    206             for (int j=0; j<att.size(); j++)
    207             {
    208                 Out() << att.item(j).nodeName().toStdString() << "=";
    209                 Out() << att.item(j).nodeValue().toStdString() << " ";
    210             }
    211             Out() << "> " << e.text().toStdString() << endl;
    212         }*/
    213 
    214         for (unsigned int i=0; i<imageElems.length(); i++)
    215         {
    216             const QDomElement e = imageElems.item(i).toElement();
    217 
    218             const QDomNamedNodeMap att = e.attributes();
    219 
    220             fStatus.Set(att);
    221         }
    222 
    223         if (fIsVerbose)
    224         {
    22597            fStatus.Print(Out());
    226             Out() << "------------------------------------------------------" << endl;
    227         }
    22898
    22999        Update(fStatus);
    230100
    231101        fRdfData = "";
    232 
    233         /*
    234         if ((fLid1.status!="Open" && fLid1.status!="Closed" && fLid1.status!="Unknown") ||
    235             (fLid2.status!="Open" && fLid2.status!="Closed" && fLid2.status!="Unknown"))
    236         {
    237             Warn("Lid status unknown ("+fLid1.status+"/"+fLid2.status+")");
    238             PostClose(false);
    239             return;
    240         }*/
    241102
    242103        fLastReport = Time();
     
    251112            if (err==ba::error::eof)
    252113            {
    253                 ProcessAnswer();
     114                if (!fRdfData.empty())
     115                    ProcessAnswer();
    254116                return;
    255117            }
     
    273135        fRdfData += string(fArray.data(), bytes_received);
    274136
    275         //cout << "." << flush;
    276 
    277137        // Does the message contain a header?
    278138        const size_t p1 = fRdfData.find("\r\n\r\n");
     
    282142            const size_t p2 = fRdfData.find("\r\n\r\n", p1+4);
    283143            if (p2!=string::npos)
    284             {
    285144                ProcessAnswer();
    286             }
    287145        }
    288146
     
    369227public:
    370228    ConnectionInterlock(ba::io_service& ioservice, MessageImp &imp) : Connection(ioservice, imp()),
    371         fIsVerbose(true), fLastReport(Time::none), fKeepAlive(ioservice)
     229        fIsValid(false), fIsVerbose(true), fDebugRx(false), fLastReport(Time::none), fKeepAlive(ioservice)
    372230    {
    373231        SetLogStream(&imp);
     
    377235    {
    378236        fIsVerbose = b;
     237    }
     238
     239    void SetDebugRx(bool b)
     240    {
     241        fDebugRx = b;
    379242        Connection::SetVerbose(b);
    380243    }
     
    393256    {
    394257        fNextCommand = post;
    395         //PostRequest("POST", post);
    396258    }
    397259
     
    400262        PostRequest("POST", fNextCommand);
    401263        fNextCommand = "";
    402 
    403         //fLid1.status = "";
    404         //fLid2.status = "";
    405264
    406265        fKeepAlive.expires_from_now(boost::posix_time::seconds(fInterval));
     
    416275    int GetState() const
    417276    {
    418         using namespace Lid;
     277        using namespace Power::State;
    419278
    420279        // Timeout
    421280        if (fLastReport.IsValid() && fLastReport+boost::posix_time::seconds(fInterval*2)<Time())
    422             return State::kDisconnected;
     281            return Power::State::kDisconnected;
     282
     283        // No dat areceived yet
     284        if (!fIsValid)
     285            return Power::State::kConnected;
    423286
    424287        /*
    425         // Inconsistency
    426         if (fLid1.status!=fLid2.status)
    427             return State::kInconsistent;
    428 
    429         // Unknown
    430         if (fLid1.status=="Unknown")
    431             return State::kUnknown;
    432 
    433         // Closed
    434         if (fLid1.status=="Closed")
    435             return State::kClosed;
    436 
    437         // Open
    438         if (fLid1.status=="Open")
    439             return State::kOpen;
    440          */
    441         return State::kConnected;
     288         bool fWaterFlowOk;
     289         bool fWaterLevelOk;
     290         bool fPwrBiasOn;
     291         bool fPwr24VOn;
     292         bool fPwrPumpOn;
     293         bool fPwrDriveOn;
     294         bool fDriveMainSwitchOn;
     295         bool fDriveFeedbackOn;
     296        */
     297
     298        if (!fStatus.fWaterLevelOk || (fStatus.fPwrPumpOn && !fStatus.fWaterFlowOk))
     299            return kCoolingFailure;
     300
     301        const int rc =
     302            (fStatus.fPwrBiasOn       ? kBiasOn   : 0) |
     303            (fStatus.fPwrPumpOn       ? kCameraOn : 0) |
     304            (fStatus.fDriveFeedbackOn ? kDriveOn  : 0);
     305
     306        return rc==0 ? kSystemOff : rc;
    442307    }
    443308};
     
    452317{
    453318private:
    454     //DimDescribedService fDim;
     319    DimDescribedService fDim;
    455320
    456321public:
    457322    ConnectionDimWeather(ba::io_service& ioservice, MessageImp &imp) :
    458         ConnectionInterlock(ioservice, imp)/*,
    459         fDim("PWR_CONTROL/DATA", "S:2;F:2;F:2",
    460              "|status[bool]:Lid1/2 open or closed"
    461              "|I[A]:Lid1/2 current"
    462              "|P[dac]:Lid1/2 hall sensor position in averaged dac counts")*/
    463     {
    464     }
    465 
    466     void Update(const Status &status)
    467     {
    468             /*
    469         struct DimData
    470         {
    471             int16_t status[2];
    472             float   current[2];
    473             float   position[2];
    474 
    475             DimData() { status[0] = status[1] = -1; }
    476 
    477         } __attribute__((__packed__));
    478 
    479         DimData data;
    480 
    481         if (l1.status=="Open")
    482             data.status[0] = 1;
    483         if (l1.status=="Closed")
    484             data.status[0] = 0;
    485 
    486         if (l2.status=="Open")
    487             data.status[1] = 1;
    488         if (l2.status=="Closed")
    489             data.status[1] = 0;
    490 
    491         data.current[0]  = l1.current;
    492         data.current[1]  = l2.current;
    493 
    494         data.position[0] = l1.position;
    495         data.position[1] = l2.position;
    496 
    497         fDim.Update(data);*/
     323        ConnectionInterlock(ioservice, imp),
     324        fDim("PWR_CONTROL/DATA", "B:1;B:1;B:1;B:1;B:1;B:1;B:1;B:1",
     325             "|water_lvl[bool]:Water level ok"
     326             "|water_flow[bool]:Water flowing"
     327             "|pwr_24V[bool]:24V power enabled"
     328             "|pwr_pump[bool]:Pump power enabled"
     329             "|pwr_bias[bool]:Bias power enabled"
     330             "|pwr_drive[bool]:Drive power enabled (command value)"
     331             "|main_drive[bool]:Drive manual main switch on"
     332             "|feedback_drive[bool]:Drive power on (feedback value)")
     333    {
     334    }
     335
     336    void Update(const Power::Status &status)
     337    {
     338        fDim.setQuality(status.GetVal());
     339        fDim.Update(status);
    498340    }
    499341};
     
    505347{
    506348private:
    507     S fLid;
     349    S fPower;
    508350    Time fLastCommand;
    509351
     
    524366            return T::kSM_FatalError;
    525367
    526         fLid.SetVerbose(evt.GetBool());
     368        fPower.SetVerbose(evt.GetBool());
    527369
    528370        return T::GetCurrentState();
    529371    }
    530372
     373    int SetDebugRx(const EventImp &evt)
     374    {
     375        if (!CheckEventSize(evt.GetSize(), "SetDebugRx", 1))
     376            return T::kSM_FatalError;
     377
     378        fPower.SetDebugRx(evt.GetBool());
     379
     380        return T::GetCurrentState();
     381    }
     382
    531383    int Post(const EventImp &evt)
    532384    {
    533         fLid.Post(evt.GetText());
     385        fPower.Post(evt.GetText());
    534386        return T::GetCurrentState();
    535387    }
    536388
    537     int Open()
    538     {
     389    int SetCameraPower(const EventImp &evt)
     390    {
     391        if (!CheckEventSize(evt.GetSize(), "SetCameraPower", 1))
     392            return T::kSM_FatalError;
     393
    539394        fLastCommand = Time();
    540         fLid.Post("Button5=");
    541         return Lid::State::kMoving;
    542     }
    543     int Close()
     395        fPower.Post(evt.GetBool() ? "cam_on=" : "cam_off=");
     396        return T::GetCurrentState();
     397    }
     398
     399    int ToggleDrive()
    544400    {
    545401        fLastCommand = Time();
    546         fLid.Post("Button6=");
    547         return Lid::State::kMoving;
    548 
    549     }
    550     /*
    551     int MoveMotor(const EventImp &evt, int mid)
    552     {
    553         if (!CheckEventSize(evt.GetSize(), "MoveMotor", 2))
    554             return T::kSM_FatalError;
    555 
    556         if (evt.GetUShort()>0xfff)
    557         {
    558             ostringstream msg;
    559             msg << "Position " << evt.GetUShort() << " for motor " << mid+1 << " out of range [0,1023].";
    560             T::Error(msg);
    561             return T::GetCurrentState();
    562         }
    563 
    564         fLid.MoveMotor(mid, evt.GetUShort());
    565 
     402        fPower.Post("dt=");
    566403        return T::GetCurrentState();
    567     }*/
     404
     405    }
    568406
    569407    int Execute()
     
    576414        poll_one();
    577415
    578         const int rc = fLid.GetState();
    579 
    580         if (T::GetCurrentState()==Lid::State::kMoving &&
    581             (rc==Lid::State::kConnected || rc==Lid::State::kDisconnected) &&
    582             fLastCommand+boost::posix_time::seconds(6*fLid.GetInterval()) < Time())
    583             return Lid::State::kMoving;
    584 
    585         return rc==Lid::State::kConnected ? T::GetCurrentState() : rc;
     416        return fPower.GetState();
    586417    }
    587418
     
    589420public:
    590421    StateMachinePowerControl(ostream &out=cout) :
    591         T(out, "LID_CONTROL"), ba::io_service::work(static_cast<ba::io_service&>(*this)),
    592         fLid(*this, *this)
     422        T(out, "PWR_CONTROL"), ba::io_service::work(static_cast<ba::io_service&>(*this)),
     423        fPower(*this, *this)
    593424    {
    594425        // ba::io_service::work is a kind of keep_alive for the loop.
     
    600431
    601432        // State names
    602         T::AddStateName(Lid::State::kDisconnected, "NoConnection",
     433        T::AddStateName(Power::State::kDisconnected, "NoConnection",
    603434                     "No connection to web-server could be established recently");
    604435
    605         T::AddStateName(Lid::State::kConnected, "Connected",
     436        T::AddStateName(Power::State::kConnected, "Connected",
    606437                     "Connection established, but status still not known");
    607438
    608         T::AddStateName(Lid::State::kInconsistent, "Inconsistent",
    609                      "Both lids show different states");
    610 
    611         T::AddStateName(Lid::State::kUnknown, "Unknown",
    612                      "Arduino resports both lids in an unknown status");
    613 
    614         T::AddStateName(Lid::State::kClosed, "Closed",
    615                      "Both lids are closed");
    616 
    617         T::AddStateName(Lid::State::kOpen, "Open",
    618                      "Both lids are open");
     439        T::AddStateName(Power::State::kSystemOff, "PowerOff",
     440                     "Camera, Bias and Drive power off");
     441
     442        T::AddStateName(Power::State::kBiasOn, "BiasOn",
     443                     "Camera and Drive power off, Bias on");
     444
     445        T::AddStateName(Power::State::kDriveOn, "DriveOn",
     446                     "Camera and Bias power off, Drive on");
     447
     448        T::AddStateName(Power::State::kCameraOn, "CameraOn",
     449                     "Drive and Bias power off, Camera on");
     450
     451        T::AddStateName(Power::State::kDriveOn|Power::State::kCameraOn, "BiasOff",
     452                     "Camera and Drive power on, Bias off");
     453
     454        T::AddStateName(Power::State::kBiasOn|Power::State::kCameraOn, "DriveOff",
     455                     "Camera and Bias power on, Drive off");
     456
     457        T::AddStateName(Power::State::kDriveOn|Power::State::kBiasOn, "CameraOff",
     458                     "Drive and Bias power on, Camera off");
     459
     460        T::AddStateName(Power::State::kDriveOn|Power::State::kBiasOn|Power::State::kCameraOn, "SystemOn",
     461                     "Camera, Bias and drive power on");
    619462
    620463
     
    623466            (bind(&StateMachinePowerControl::SetVerbosity, this, placeholders::_1))
    624467            ("set verbosity state"
    625              "|verbosity[bool]:disable or enable verbosity for received data (yes/no), except dynamic data");
    626 
    627         T::AddEvent("OPEN", Lid::State::kInconsistent, Lid::State::kClosed)
    628             (bind(&StateMachinePowerControl::Open, this));
    629 
    630         T::AddEvent("CLOSE", Lid::State::kInconsistent, Lid::State::kOpen)
    631             (bind(&StateMachinePowerControl::Close, this));
     468             "|verbosity[bool]:disable or enable verbosity for interpreted data (yes/no)");
     469
     470        T::AddEvent("SET_DEBUG_RX", "B")
     471            (bind(&StateMachinePowerControl::SetDebugRx, this, placeholders::_1))
     472            ("set debux-rx state"
     473             "|debug[bool]:dump received text and parsed text to console (yes/no)");
     474
     475        T::AddEvent("CAMERA_POWER", "B")
     476            (bind(&StateMachinePowerControl::SetCameraPower, this, placeholders::_1));
     477
     478        T::AddEvent("TOGGLE_DRIVE")
     479            (bind(&StateMachinePowerControl::ToggleDrive, this));
    632480
    633481        T::AddEvent("POST", "C")
     
    639487    int EvalOptions(Configuration &conf)
    640488    {
    641         fLid.SetVerbose(!conf.Get<bool>("quiet"));
    642         fLid.SetInterval(conf.Get<uint16_t>("interval"));
    643         fLid.SetDebugTx(conf.Get<bool>("debug-tx"));
    644         fLid.SetSite(conf.Get<string>("url"));
    645         fLid.SetEndpoint(conf.Get<string>("addr"));
    646         fLid.StartConnect();
     489        fPower.SetVerbose(!conf.Get<bool>("quiet"));
     490        fPower.SetInterval(conf.Get<uint16_t>("interval"));
     491        fPower.SetDebugTx(conf.Get<bool>("debug-tx"));
     492        fPower.SetDebugRx(conf.Get<bool>("debug-rx"));
     493        fPower.SetSite(conf.Get<string>("url"));
     494        fPower.SetEndpoint(conf.Get<string>("addr"));
     495        fPower.StartConnect();
    647496
    648497        return -1;
     
    671520        ("interval,i", var<uint16_t>(5), "Interval between two updates on the server in seconds")
    672521        ("debug-tx",   po_bool(), "Enable debugging of ethernet transmission.")
     522        ("debug-rx",   po_bool(), "Enable debugging for received data.")
    673523        ;
    674524
Note: See TracChangeset for help on using the changeset viewer.