Ignore:
Timestamp:
06/02/12 12:52:44 (12 years ago)
Author:
tbretz
Message:
Added history for errors; updated error handling to be able to do some audio; added some audio for camera on/off; removed the '0Hz' after a new run has been started; fixed a chat server issue
File:
1 edited

Legend:

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

    r14014 r14034  
    374374    vector<uint32_t> fFadControlDrsRuns;
    375375
    376     float  fFtmControlTriggerRateCam;
    377376    deque<float> fFtmControlTriggerRateHist;
     377    bool         fFtmControlNewRunStarted;
    378378
    379379    float fFtmPatchThresholdMed;
     
    387387    uint8_t   fRateScanBoard;
    388388    deque<float> fRateScanDataHist[41];
     389
     390    set<string>   fErrorList;
     391    deque<string> fErrorHist;
    389392
    390393    Sun   fSun;
     
    397400
    398401    // --------------------------- File header ----------------------------
    399 
    400     int fHasError;
    401402
    402403    Time   fAudioTime;
     
    438439    DimDescribedState fDimRateControl;
    439440    DimDescribedState fDimRateScan;
    440     DimDescribedState fDimChatServer;
     441    DimDescribedState fDimChat;
    441442    DimDescribedState fDimSkypeClient;
    442443
     
    605606    }
    606607
     608    void HandleFscControlStateChange()
     609    {
     610        const int32_t &last  = fDimFscControl.last.second;
     611        const int32_t &state = fDimFscControl.state();
     612
     613        if (last==DimState::kOffline || state==DimState::kOffline)
     614            return;
     615
     616        if (last<FSC::State::kConnected && state==FSC::State::kConnected)
     617            SetAudio("sound_13");
     618
     619        if (last==FSC::State::kConnected && state<FSC::State::kConnected)
     620            SetAudio("sound_14");
     621    }
     622
    607623    int HandleMcpConfiguration(const EventImp &d)
    608624    {
     
    617633        }
    618634
    619         if (fMcpConfigurationState==MCP::State::kTakingData && d.GetQoS()==MCP::State::kIdle)
     635        // If a run ends and no script is running play a tirili
     636        if (fMcpConfigurationState==MCP::State::kTakingData && d.GetQoS()==MCP::State::kIdle && fDimControl.state()<-2)
    620637            SetAudio("sound_10");
    621638
    622         if (fMcpConfigurationState==MCP::State::kTriggerOn && d.GetQoS()==MCP::State::kTakingData)
     639        // If a run ends and a script is running just play a simple 'tick'
     640        if (fMcpConfigurationState==MCP::State::kTakingData && d.GetQoS()==MCP::State::kIdle && fDimControl.state()>=-2)
    623641            SetAudio("losticks");
     642
     643        if (d.GetQoS()==MCP::State::kTakingData)
     644        {
     645            fMcpConfigurationRunStart = Time();
     646            SetAudio("losticks");
     647        }
    624648
    625649        fMcpConfigurationState     = d.GetQoS();
     
    627651        fMcpConfigurationMaxEvents = d.Get<uint64_t>(8);
    628652        fMcpConfigurationName      = d.Ptr<char>(16);
    629 
    630         if (d.GetQoS()==MCP::State::kTakingData)
    631             fMcpConfigurationRunStart = Time();
    632653
    633654        return GetCurrentState();
     
    779800        out << setprecision(5);
    780801        out << fDriveControlPointingZd << '\n';
    781         out << az << '\n';
    782 
    783         ofstream(fPath+"/drive-pointing.data") << out.str();
     802        out << az << '\t' << fDriveControlPointingAz << '\n';
     803
     804        ofstream(fPath+"/pointing.data") << out.str();
    784805
    785806        return GetCurrentState();
     
    11671188            return GetCurrentState();
    11681189
     1190        const double crate = d.Get<float>(20);     // Camera rate
     1191
    11691192        // New run started
    1170         if (d.Get<float>(20)<0)
     1193        if (crate<0)
     1194        {
     1195            fFtmControlNewRunStarted = true;
    11711196            return GetCurrentState();
    1172 
    1173         fFtmControlTriggerRateCam = d.Get<float>(20);
     1197        }
     1198        fFtmControlNewRunStarted = false;
    11741199
    11751200        const float *brates = d.Ptr<float>(24);     // Board rate
     
    11771202
    11781203        // Store a history of the last 60 entries
    1179         fFtmControlTriggerRateHist.push_back(fFtmControlTriggerRateCam);
     1204        fFtmControlTriggerRateHist.push_back(crate);
    11801205        if (fFtmControlTriggerRateHist.size()>60)
    11811206            fFtmControlTriggerRateHist.pop_front();
     
    11931218        out << setprecision(3);
    11941219        out << d.GetJavaDate() << '\n';
    1195         out << HTML::kWhite << '\t' << fFtmControlTriggerRateCam << '\n';
     1220        out << HTML::kWhite << '\t' << crate << '\n';
    11961221
    11971222        ofstream(fPath+"/trigger.data") << out.str();
     
    15711596        Out() << fDimTngWeather   << endl;
    15721597        Out() << fDimRateScan     << endl;
    1573         Out() << fDimChatServer   << endl;
     1598        Out() << fDimChat         << endl;
    15741599        Out() << fDimSkypeClient  << endl;
    15751600
     
    15991624        //return msg.str();
    16001625
    1601         if (rc.index<1)
     1626        if (rc.index<0)
    16021627            return HTML::kWhite + "\t&mdash;\n";
    16031628
     
    16091634
    16101635        return col + '\t' + rc.name + '\n';
     1636    }
     1637
     1638    bool SetError(bool b, const string &err)
     1639    {
     1640        if (!b)
     1641        {
     1642            fErrorList.erase(err);
     1643            return 0;
     1644        }
     1645
     1646        const bool isnew = fErrorList.insert(err).second;
     1647
     1648        if (isnew)
     1649        {
     1650            ostringstream msg;
     1651            msg << "<pre>" << Time().GetAsStr("%m-%d %H:%M") << "</pre> <->" << err << "</->";
     1652            if (find(fErrorHist.begin(), fErrorHist.end(), msg.str())==fErrorHist.end())
     1653            {
     1654                fErrorHist.push_front(msg.str());
     1655                if (fErrorHist.size()>80)
     1656                    fErrorHist.pop_back();
     1657            }
     1658        }
     1659
     1660        return isnew;
    16111661    }
    16121662
     
    16321682            fDimMcp.state()==MCP::State::kTakingData;
    16331683
    1634         ostringstream msg;
    1635 
    1636         if (fHasError==2)
    1637             msg << "SmartFACT backend initializing." << endl;
    1638         if (!fDimDNS.online())
    1639             msg << "DIM network not available.<br/>";
    1640         if (fDimDriveControl.state()>0xff && data_taking)
    1641             msg << "Drive in ERROR state during data-taking<br/>";
    1642         if (fDimBiasControl.state()<BIAS::State::kRamping && data_taking)
    1643             msg << "BIAS not operating during data-taking<br/>";
    1644         if (fDimBiasControl.state()==BIAS::State::kOverCurrent)
    1645             msg << "BIAS channels in OverCurrent<br/>";
    1646         if (fDimBiasControl.state()==BIAS::State::kNotReferenced)
    1647             msg << "BIAS voltage not at reference<br/>";
    1648         if (fFeedbackCalibration.size()>0)
    1649         {
    1650             if (fBiasControlCurrentMed>75)
    1651                 msg << "Median current exceeds 75&micro;A/pix<br/>";
    1652             if (fBiasControlCurrentMax>90)
    1653                 msg << "Maximum current exceeds 90&micro;A/pix<br/>";
    1654         }
    1655         if (fMagicWeatherHist[kHum].size()>0 && fMagicWeatherHist[kHum].back()>98 && data_taking)
    1656             msg << "Outside humidity exceeds 98% during data-taking<br/>";
    1657         if (fMagicWeatherHist[kGusts].size()>0 && fMagicWeatherHist[kGusts].back()>98 && fDimDriveControl.state()==Drive::State::kTracking)
    1658             msg << "Wind gusts exceed 50km/h during tracking<br/>";
    1659         if (fFscControlTemperatureHist.size()>0 && fFscControlTemperatureHist.back()>7)
    1660             msg << "Sensor temperature exceeds outside temperature by more than 7&deg;C<br/>";
    1661         if (fFtmControlTriggerRateCam<0.01 && data_taking)
    1662             msg << "Trigger rate below 10mHz during data taking<br/>";
    1663         if (fFscControlHumidityAvg>60)
    1664             msg << "Average camera humidity exceed 60%<br/>";
    1665         if (!fDimControl.online())
    1666             msg << "dimctrl offline<br/>";
    1667 
    1668         if (fDriveControlMoonDist>155)
    1669             msg << "Moon within the field-of-view of the cones<br/>";
    1670         if (fDriveControlMoonDist>=0 && fDriveControlMoonDist<3)
    1671             msg << "Moon within the field-of-view of the camera<br/>";
    1672 
    1673         if (fDimTimeCheck.state()==2)
    1674             msg << "Warning NTP time difference of drive PC exceeds 1s.<br/>";
    1675 
    1676 
    1677         if (fDimFeedback.state()!=Feedback::State::kCalibrating &&
    1678             fDimBiasControl.state()==BIAS::State::kVoltageOn &&
    1679             fBiasControlVoltageMed>3 &&
    1680             fFeedbackCalibration.size()==0)
    1681             msg << "bias voltage switched on, but bias crate not calibrated.";
     1684        const bool data_run =
     1685            fMcpConfigurationName=="data" ||
     1686            fMcpConfigurationName=="data-rt";
     1687
     1688        const bool haderr = fErrorList.size()>0;
     1689
     1690        bool newerr = false;
     1691
     1692        newerr |= SetError(!fDimDNS.online(),
     1693                           "<b><#darkred>DIM network not available</#></b>");
     1694        newerr |= SetError(!fDimControl.online(),
     1695                           "<b>dimctrl offline</b>");
     1696
     1697        //newerr |= SetError(fDimDriveControl.state()==Drive::State::kLocked,
     1698        //                   "<b><#darkred>Drive in LOCKED state, drive was automatically parked</#></b>");
     1699
     1700        newerr |= SetError(fDimDriveControl.state()>0xff && data_taking && data_run,
     1701                           "Drive in ERROR state during data-taking");
     1702        newerr |= SetError(fDriveControlMoonDist>155,
     1703                           "Moon within the field-of-view of the cones");
     1704        newerr |= SetError(fDriveControlMoonDist>=0 && fDriveControlMoonDist<3,
     1705                           "Moon within the field-of-view of the camera");
     1706
     1707        newerr |= SetError(fDimBiasControl.state()<BIAS::State::kRamping && data_taking,
     1708                           "BIAS not operating during data-taking");
     1709        newerr |= SetError(fDimBiasControl.state()==BIAS::State::kOverCurrent,
     1710                           "BIAS channels in OverCurrent");
     1711        newerr |= SetError(fDimBiasControl.state()==BIAS::State::kNotReferenced,
     1712                           "BIAS voltage not at reference");
     1713
     1714        newerr |= SetError(fFeedbackCalibration.size()>0 && fBiasControlCurrentMed>80,
     1715                           "Median current exceeds 80&micro;A/pix");
     1716        newerr |= SetError(fFeedbackCalibration.size()>0 && fBiasControlCurrentMax>100,
     1717                           "Maximum current exceeds 100&micro;A/pix");
     1718
     1719        newerr |= SetError(fFscControlHumidityAvg>60,
     1720                           "Average camera humidity exceed 60%");
     1721
     1722        newerr |= SetError(fMagicWeatherHist[kHum].size()>0 && fMagicWeatherHist[kHum].back()>98 && data_taking,
     1723                           "Outside humidity exceeds 98% during data-taking");
     1724        newerr |= SetError(fMagicWeatherHist[kGusts].size()>0 && fMagicWeatherHist[kGusts].back()>98 && fDimDriveControl.state()==Drive::State::kTracking,
     1725                           "Wind gusts exceed 50km/h during tracking");
     1726
     1727        newerr |= SetError(fFscControlTemperatureHist.size()>0 && fFscControlTemperatureHist.back()>8,
     1728                           "Sensor temperature exceeds outside temperature by more than 8&deg;C");
     1729
     1730        if (fFtmControlTriggerRateHist.size()>0 && !fFtmControlNewRunStarted)
     1731        {
     1732            newerr |= SetError(fFtmControlTriggerRateHist.size()>0 && fFtmControlTriggerRateHist.back()<0.01 && fDimMcp.state()==MCP::State::kTakingData,
     1733                               "Trigger rate below 10mHz during data taking");
     1734        }
     1735
     1736        newerr |= SetError(fDimTimeCheck.state()==1,
     1737                           "Warning NTP time difference of drive PC exceeds 1s");
     1738        newerr |= SetError(fDimTimeCheck.state()<1,
     1739                           "Warning timecheck not running");
     1740
     1741        newerr |= SetError(fDimFeedback.state()!=Feedback::State::kCalibrating &&
     1742                           fDimBiasControl.state()==BIAS::State::kVoltageOn &&
     1743                           fBiasControlVoltageMed>3 &&
     1744                           fFeedbackCalibration.size()==0,
     1745                           "Bias voltage switched on, but bias crate not calibrated");
    16821746
    16831747        // FTM in Connected instead of Idle --> power cyclen
     
    16961760          Out() << fDimMagicWeather << endl;
    16971761          Out() << fDimRateScan     << endl;
    1698           Out() << fDimChatServer   << endl;
     1762          Out() << fDimChat         << endl;
    16991763          */
    17001764
     
    17031767
    17041768        // --------------------------------------------------------------
    1705 
    1706         const bool haserror = msg.str().size()>0;
    1707 
    17081769        ostringstream out;
    1709         out << Header(now) << '\t' << haserror << '\t' << (fDimControl.state()>-3) << '\n';
     1770
     1771        if (newerr)
     1772        {
     1773            SetAudio("sound_7");
     1774
     1775            out << now.JavaDate() << '\n';
     1776            out << HTML::kWhite << '\t';
     1777            for (auto it=fErrorHist.begin(); it!=fErrorHist.end(); it++)
     1778                out << *it << "<br/>";
     1779            out << '\n';
     1780
     1781            ofstream(fPath+"/errorhist.data") << out.str();
     1782        }
     1783
     1784        out.str("");
     1785        out << Header(now) << '\t' << (fErrorList.size()>0) << '\t' << (fDimControl.state()>-3) << '\n';
    17101786        out << setprecision(3);
    1711         out << HTML::kWhite << '\t' << msg.str() << '\n';
    1712 
    1713         if (haserror || fHasError)
     1787        out << HTML::kWhite << '\t';
     1788        for (auto it=fErrorList.begin(); it!=fErrorList.end(); it++)
     1789            out << *it << "<br/>";
     1790        out << '\n';
     1791
     1792        if (haderr || fErrorList.size()>0)
    17141793            ofstream(fPath+"/error.data") << out.str();
    17151794
    1716         fHasError = haserror;
    1717 
    1718         if (!fDimDNS.online())
    1719             return kStateDimNetworkNA;
    1720 
    17211795        // ==============================================================
    17221796
    17231797        out.str("");
    1724         out << Header(now) << '\t' << fHasError << '\t' << (fDimControl.state()>-3) << '\n';
     1798        out << Header(now) << '\t' << (fErrorList.size()>0) << '\t' << (fDimControl.state()>-3) << '\n';
    17251799        out << setprecision(3);
    17261800
    17271801        // -------------- System status --------------
    1728         if (fDimMcp.state()>=MCP::State::kIdle) // Idle
     1802        if (fDimDNS.online() && fDimMcp.state()>=MCP::State::kIdle) // Idle
    17291803        {
    17301804            string col = HTML::kBlue;
     
    18431917
    18441918        // ------------------ Drive -----------------
    1845         if (fDimDriveControl.state()>=Drive::State::kArmed)   // Armed, Moving, Tracking
     1919        if (fDimDNS.online() && fDimDriveControl.state()>=Drive::State::kArmed)   // Armed, Moving, Tracking
    18461920        {
    18471921            const double dev = fDriveControlTrackingDevHist.size()>0 ? fDriveControlTrackingDevHist.back() : 0;
     
    18591933                    col = HTML::kRed;
    18601934            }
     1935            if (rc.index==0x100)
     1936                col = HTML::kRed;
    18611937            out << col << '\t';
    18621938
     
    18961972
    18971973        // ------------------- FSC ------------------
    1898         if (fDimFscControl.state()>FSC::State::kDisconnected && fFscControlTemperatureHist.size()>0)
     1974        if (fDimDNS.online() && fDimFscControl.state()>FSC::State::kDisconnected && fFscControlTemperatureHist.size()>0)
    18991975        {
    19001976            out << HTML::kGreen << '\t' << fFscControlTemperatureHist.back() << '\n';
     
    19041980
    19051981        // --------------- MagicWeather -------------
    1906         if (fDimMagicWeather.state()==MagicWeather::State::kReceiving && fMagicWeatherHist[kWeatherBegin].size()>0)
     1982        if (fDimDNS.online() && fDimMagicWeather.state()==MagicWeather::State::kReceiving && fMagicWeatherHist[kWeatherBegin].size()>0)
    19071983        {
    19081984            /*
     
    19332009
    19342010        // --------------- FtmControl -------------
    1935         if (fDimFtmControl.state()==FTM::State::kTriggerOn)
     2011        if (fDimDNS.online() && fDimFtmControl.state()==FTM::State::kTriggerOn)
    19362012        {
    19372013            string col = HTML::kGreen;
    1938             if (fFtmControlTriggerRateCam<15)
    1939                 col = HTML::kYellow;
    1940             if (fFtmControlTriggerRateCam>100)
    1941                 col = HTML::kRed;
    1942 
    1943             out << col << '\t' << fFtmControlTriggerRateCam << " Hz";
     2014            if (fFtmControlTriggerRateHist.size()>0 && !fFtmControlNewRunStarted)
     2015            {
     2016                if (fFtmControlTriggerRateHist.back()<15)
     2017                    col = HTML::kYellow;
     2018                if (fFtmControlTriggerRateHist.back()>100)
     2019                    col = HTML::kRed;
     2020
     2021                out << col << '\t' << fFtmControlTriggerRateHist.back() << " Hz";
     2022            }
     2023
    19442024            if (fDimBiasControl.state()==BIAS::State::kVoltageOn)
    19452025                out << " (" << fFtmPatchThresholdMed << ')';
     
    19502030
    19512031        // --------------- BiasControl -------------
    1952         if (fDimBiasControl.state()==BIAS::State::kRamping     ||
    1953             fDimBiasControl.state()==BIAS::State::kOverCurrent ||
    1954             fDimBiasControl.state()==BIAS::State::kVoltageOn   ||
    1955             fDimBiasControl.state()==BIAS::State::kVoltageOff)
     2032        if (fDimDNS.online() &&
     2033            (fDimBiasControl.state()==BIAS::State::kRamping     ||
     2034             fDimBiasControl.state()==BIAS::State::kOverCurrent ||
     2035             fDimBiasControl.state()==BIAS::State::kVoltageOn   ||
     2036             fDimBiasControl.state()==BIAS::State::kVoltageOff))
    19562037        {
    19572038            const bool off = fDimBiasControl.state()==BIAS::State::kVoltageOff;
     
    19592040
    19602041            string col = fBiasControlVoltageMed>3?HTML::kGreen:HTML::kWhite;
    1961             if (fBiasControlCurrentMax>65)
     2042            if (fBiasControlCurrentMed>60 || fBiasControlCurrentMax>80)
    19622043                col = HTML::kYellow;
    1963             if (fBiasControlCurrentMax>80)
     2044            if (fBiasControlCurrentMed>70 || fBiasControlCurrentMax>90)
    19642045                col = HTML::kRed;
    19652046
     
    20152096
    20162097        out.str("");
    2017         out << Header(now) << '\t' << fHasError << '\t' << (fDimControl.state()>-3) << '\n';
     2098        out << Header(now) << '\t' << (fErrorList.size()>0) << '\t' << (fDimControl.state()>-3) << '\n';
    20182099
    20192100        if (!fDimDNS.online())
     
    20402121            out << GetStateHtml(fDimTngWeather,   2);
    20412122            out << GetStateHtml(fDimRateScan,     4);
    2042             out << GetStateHtml(fDimChatServer,   1);
     2123            out << GetStateHtml(fDimChat,         0);
    20432124            out << GetStateHtml(fDimSkypeClient,  1);
    20442125
     
    20482129        ofstream(fPath+"/status.data") << out.str();
    20492130
    2050         return kStateRunning;
     2131        return fDimDNS.online() ? kStateRunning : kStateDimNetworkNA;
    20512132    }
    20522133
     
    20562137        fPath("www/smartfact/data"),
    20572138        fControlScriptDepth(0),
    2058         fMcpConfigurationState(-256),
     2139        fMcpConfigurationState(DimState::kOffline),
    20592140        fMcpConfigurationMaxTime(0),
    20602141        fMcpConfigurationMaxEvents(0),
     
    20672148        fFadControlNumEvents(0),
    20682149        fFadControlDrsRuns(3),
    2069         fFtmControlTriggerRateCam(0),
    20702150        fRateScanDataId(0),
    20712151        fRateScanBoard(0),
    2072         fHasError(2),
    20732152        // ---
    20742153        fDimMcp         ("MCP"),
     
    20852164        fDimRateControl ("RATE_CONTROL"),
    20862165        fDimRateScan    ("RATE_SCAN"),
    2087         fDimChatServer  ("CHAT_SERVER"),
     2166        fDimChat        ("CHAT"),
    20882167        fDimSkypeClient ("SKYPE_CLIENT")
    20892168    {
     
    21032182        fDimRateControl.Subscribe(*this);
    21042183        fDimRateScan.Subscribe(*this);
    2105         fDimChatServer.Subscribe(*this);
     2184        fDimChat.Subscribe(*this);
    21062185        fDimSkypeClient.Subscribe(*this);
    21072186
     2187        fDimFscControl.SetCallback(bind(&StateMachineSmartFACT::HandleFscControlStateChange, this));
    21082188        fDimControl.SetCallback(bind(&StateMachineSmartFACT::HandleControlStateChange, this, placeholders::_1));
    21092189        fDimControl.AddCallback("dotest.dim", bind(&StateMachineSmartFACT::HandleDoTest, this, placeholders::_1));
     
    21892269
    21902270        fPath = conf.Get<string>("path");
     2271
     2272        ostringstream out;
     2273        out << Time().JavaDate() << '\n';
     2274
     2275        ofstream(fPath+"/errorhist.data") << out.str();
     2276        ofstream(fPath+"/error.data")     << out.str();
    21912277
    21922278        return -1;
Note: See TracChangeset for help on using the changeset viewer.