10 #include <sys/statvfs.h> 46 #include <boost/filesystem.hpp> 74 const static string kWhite =
"#ffffff";
76 const static string kRed =
"#fff8f0";
77 const static string kGreen =
"#f0fff0";
78 const static string kBlue =
"#f0f0ff";
111 if (jd>rs.rise || jd>rs.set)
133 const double JD = time.
JD();
146 fSunRise00 = sun00.rise;
147 fSunRise06 = sun06.rise;
148 fSunRise12 = sun12.rise;
149 fSunRise18 = sun18.rise;
151 fSunSet00 = sun00.set;
152 fSunSet06 = sun06.set;
153 fSunSet12 = sun12.set;
154 fSunSet18 = sun18.set;
156 array<double,8> arr =
169 state = std::min_element(arr.begin(), arr.end())-arr.begin();
183 description = name[state];
185 const string txt = fSunRise18<fSunSet18 ?
189 description +=
" ["+txt+
"]";
340 const double JD = time.
JD();
344 fRise =
Time(moon.rise);
345 fTransit =
Time(moon.transit);
346 fSet =
Time(moon.set);
352 const bool is_up = JD>moon.rise;
353 const bool is_sinking = JD>moon.transit;
354 const bool is_dn = JD>moon.set;
358 fRise =
Time(moon.rise);
360 fTransit =
Time(moon.transit);
362 fSet =
Time(moon.set);
375 if (fRise <fTransit && fRise <fSet) state = 0;
376 if (fTransit<fSet && fTransit<fRise) state = 1;
377 if (fSet <fRise && fSet <fTransit) state = 2;
385 if (!visible || disk<25)
390 const string arr = fSet<fRise ?
395 out << setprecision(2);
396 out << (visible?
"visible ":
"") << (disk<0.1?0:disk) <<
"% [" << arr <<
"]";
398 description = out.str();
402 double Angle(
double r,
double d)
const 404 const double theta0 = M_PI/2-d*M_PI/180;
405 const double phi0 = r*M_PI/12;
407 const double theta1 = M_PI/2-dec*M_PI/180;
408 const double phi1 = ra*M_PI/12;
410 const double x0 = sin(theta0) * cos(phi0);
411 const double y0 = sin(theta0) * sin(phi0);
412 const double z0 = cos(theta0);
414 const double x1 = sin(theta1) * cos(phi1);
415 const double y1 = sin(theta1) * sin(phi1);
416 const double z1 = cos(theta1);
418 double arg = x0*x1 + y0*y1 + z0*z1;
419 if(arg > 1.0) arg = 1.0;
420 if(arg < -1.0) arg = -1.0;
422 return acos(arg) * 180/M_PI;
427 if (angle<10 || angle>150)
429 if (angle<20 || angle>140)
447 kStateDimNetworkNA = 1,
463 const boost::posix_time::time_duration
deltat;
467 EventHist(
const boost::posix_time::time_duration &dt=boost::posix_time::hours(12), uint64_t mx=UINT64_MAX) : deltat(dt), max(mx) { }
471 while (!empty() && (front().
time+deltat<
t ||
size()>max))
482 const auto is = it++;
492 for (
auto it=
begin(); it!=
end(); it++)
494 const string tm = it->time.GetAsStr(
"%H:%M:%S ");
495 out << (tm!=last?tm:
"--:--:-- ") << it->msg <<
"<br/>";
505 for (
auto it=rbegin(); it!=rend(); it++)
506 out << it->time.GetAsStr(
"%H:%M:%S ") << it->msg <<
"<br/>";
539 enum weather_t { kWeatherBegin=0, kTemp = kWeatherBegin, kDew, kHum, kPress, kWind, kGusts, kDir, kWeatherEnd = kDir+1 };
540 deque<float> fMagicWeatherHist[kWeatherEnd];
587 deque<float> fRateScanDataHist[41];
655 static const char *dir[] =
657 "N",
"NNE",
"NE",
"ENE",
658 "E",
"ESE",
"SE",
"SSE",
659 "S",
"SSW",
"SW",
"WSW",
660 "W",
"WNW",
"NW",
"NNW" 663 const uint16_t idx = uint16_t(floor(angle/22.5+16.5))%16;
678 msg << name <<
" - Received service has " << d.
GetSize() <<
" bytes, but expected ";
689 void WriteBinaryVec(
const Time &tm,
const string &fname,
const vector<T> &vec,
double scale,
double offset=0,
const string &title=
"",
const string &col=
"")
696 out << offset <<
'\n';
697 out << offset+scale <<
'\n';
698 out << setprecision(3);
700 out << title <<
'\x7f';
704 out << stat.
min <<
'\n';
705 out << stat.
med <<
'\n';
706 out << stat.
max <<
'\x7f';
710 for (
auto it=vec.cbegin(); it!=vec.cend(); it++)
714 vector<uint8_t> val(it->size());
715 for (uint64_t
i=0;
i<it->size();
i++)
717 float range = nearbyint(126*(
double(it->at(
i))-offset)/scale);
722 val[
i] = (uint8_t)range;
725 const char *ptr =
reinterpret_cast<char*
>(val.data());
726 out.write(ptr, val.size()*
sizeof(uint8_t));
730 ofstream(fPath+
"/"+fname+
".bin") << out.str();
754 WriteBinaryVec(d.
GetTime(), fname, vector<T>(&
t, &t+1), scale, offset,
"",
"000");
758 void WriteCam(
const EventImp &d,
const string &fname,
const T &
t,
double scale,
double offset=0)
760 WriteBinaryVec(d.
GetTime(), fname, vector<T>(&
t, &t+1), scale, offset,
"",
"");
776 : min(0), max(0), med(0), avg(0)
782 sort(copy.begin(), copy.end());
784 if (offset_min>t.size())
786 if (offset_max>t.size())
789 min = copy[offset_min];
790 max = copy[copy.size()-1-offset_max];
791 avg = accumulate (t.begin(), t.end(), 0.)/t.size();
793 const size_t p = copy.size()/2;
794 med = copy.size()%2 ? copy[p] : (copy[p-1]+copy[p])/2.;
806 out << setprecision(3);
809 out <<
"<->" << fControlMessageHist.
get() <<
"</->";
812 ofstream(fPath+
"/scriptlog.data") << out.str();
818 return GetCurrentState();
823 for (
auto it=fControlAlarmHist.begin(); it!=fControlAlarmHist.end(); it++)
830 HandleControlMessageImp(d);
832 return GetCurrentState();
846 #if BOOST_VERSION < 104600 847 const string file = boost::filesystem::path(fDimControl.
file).filename();
849 const string file = boost::filesystem::path(fDimControl.
file).filename().string();
858 fControlMessageHist.clear();
859 HandleControlMessageImp(
Event(d,
"========================================", 41));
862 HandleControlMessageImp(
Event(d, (
"----- "+fDimControl.
shortmsg+
" -----").data(), fDimControl.
shortmsg.length()+13));
863 if (!file.empty() && d.
GetQoS()<2)
864 HandleControlMessageImp(
Event(d, file.data(), file.length()+1));
870 HandleControlMessageImp(
Event(d,
"========================================", 41));
885 out <<
"<->" << fMcpConfigurationHist.
rget() <<
"</->";
888 ofstream(fPath+
"/observations.data") << out.str();
893 const int32_t &last = fDimFscControl.
last.second;
894 const int32_t &state = fDimFscControl.
state();
901 AddMcpConfigurationHist(d,
"<B>FSC swiched on</B>");
907 AddMcpConfigurationHist(d,
"<B>FSC swiched off</B>");
916 if (!CheckDataSize(d,
"Mcp:Configuration", 16,
true))
919 fMcpConfigurationMaxTime = 0;
920 fMcpConfigurationMaxEvents = 0;
921 fMcpConfigurationName =
"";
923 return GetCurrentState();
934 SetAudio(
"losticks");
936 fLastRunFinishedWithZeroEvents = fFadControlNumEvents==0;
939 out <<
"<#darkred>" << d.
Ptr<
char>(16);
940 if (!fDriveControlSourceName.empty())
941 out <<
" [" << fDriveControlSourceName <<
']';
942 out <<
" (N=" << fFadControlNumEvents <<
')';
945 AddMcpConfigurationHist(d, out.str());
950 fMcpConfigurationRunStart =
Time();
951 SetAudio(
"losticks");
954 out <<
"<#darkgreen>" << fMcpConfigurationName;
955 if (!fDriveControlSourceName.empty())
956 out <<
" [" << fDriveControlSourceName <<
']';
957 if (fFadControlStartRun>0)
958 out <<
" (Run " << fFadControlStartRun <<
')';
961 AddMcpConfigurationHist(d, out.str());
964 fMcpConfigurationState = d.
GetQoS();
965 fMcpConfigurationMaxTime = d.
Get<uint64_t>();
966 fMcpConfigurationMaxEvents = d.
Get<uint64_t>(8);
967 fMcpConfigurationName = d.
Ptr<
char>(16);
969 return GetCurrentState();
977 out << setprecision(3);
980 out <<
HTML::kWhite <<
'\t' << fMagicWeatherHist[
i].back() <<
'\n';
985 ofstream(fPath+
"/"+name+
".data") << out.str();
987 WriteHist(d,
"hist-magicweather-"+name, fMagicWeatherHist[i], max-min, min);
992 if (!CheckDataSize(d,
"MagicWeather:Data", 7*4+2))
993 return GetCurrentState();
996 for (
int i=kWeatherBegin;
i<kWeatherEnd;
i++)
998 fMagicWeatherHist[
i].push_back(d.
Ptr<
float>(2)[
i]);
999 if (fMagicWeatherHist[
i].
size()>300)
1000 fMagicWeatherHist[
i].pop_front();
1008 out << setprecision(2);
1013 out << setprecision(3);
1014 for (
int i=0;
i<6;
i++)
1015 out <<
HTML::kWhite <<
'\t' << fMagicWeatherHist[
i].back() <<
'\n';
1016 out <<
HTML::kWhite <<
'\t' << GetDir(fMagicWeatherHist[kDir].back()) <<
'\n';
1018 if (!fTngWeatherDustHist.empty())
1019 out << fTngWeatherDustHist.back() <<
'\t' << fTngWeatherDustTime.
GetAsStr(
"%H:%M") <<
'\n';
1023 ofstream(fPath+
"/weather.data") << out.str();
1025 WriteWeather(d,
"temp", kTemp, -5, 35);
1026 WriteWeather(d,
"dew", kDew, -5, 35);
1027 WriteWeather(d,
"hum", kHum, 0, 100);
1028 WriteWeather(d,
"wind", kWind, 0, 100);
1029 WriteWeather(d,
"gusts", kGusts, 0, 100);
1030 WriteWeather(d,
"press", kPress, 700, 1000);
1032 return GetCurrentState();
1037 if (!CheckDataSize(d,
"TngWeather:Dust", 4))
1038 return GetCurrentState();
1040 fTngWeatherDustTime = d.
GetTime();
1042 fTngWeatherDustHist.push_back(d.
GetFloat());
1043 if (fTngWeatherDustHist.size()>300)
1044 fTngWeatherDustHist.pop_front();
1048 const double scale = stat.
max>0 ? pow(10, ceil(log10(stat.
max))) : 0;
1050 WriteHist(d,
"hist-tng-dust", fTngWeatherDustHist, scale);
1055 ofstream(fPath+
"/tngdust.data") << out.str();
1057 return GetCurrentState();
1062 const int32_t &last = fDimFscControl.
last.second;
1063 const int32_t &state = fDimFscControl.
state();
1069 AddMcpConfigurationHist(d,
"Drive ready");
1072 AddMcpConfigurationHist(d,
"Drive not ready");
1079 if (!CheckDataSize(d,
"DriveControl:Pointing", 16))
1080 return GetCurrentState();
1082 fDriveControlPointingZd = d.
Get<
double>();
1084 const double az = d.
Get<
double>(8);
1086 fDriveControlPointingAz = GetDir(az);
1091 out << setprecision(0) << fixed;
1092 out <<
HTML::kWhite <<
'\t' << az <<
'\t' << fDriveControlPointingAz <<
'\n';
1093 out <<
HTML::kWhite <<
'\t' << fDriveControlPointingZd <<
'\n';
1095 ofstream(fPath+
"/pointing.data") << out.str();
1097 return GetCurrentState();
1102 if (!CheckDataSize(d,
"DriveControl:Tracking", 96))
1103 return GetCurrentState();
1107 const double Ra = d.
Get<
double>(0*8);
1108 const double Dec = d.
Get<
double>(1*8);
1109 const double Zd = d.
Get<
double>(6*8);
1110 const double Az = d.
Get<
double>(7*8);
1112 const double dev = d.
Get<
double>(11*8);
1114 fDriveControlTrackingDevHist.push_back(dev);
1115 if (fDriveControlTrackingDevHist.size()>300)
1116 fDriveControlTrackingDevHist.pop_front();
1118 WriteHist(d,
"hist-control-deviation", fDriveControlTrackingDevHist, 120);
1123 out <<
HTML::kWhite <<
'\t' << fDriveControlSourceName <<
'\n';
1124 out << setprecision(5);
1127 out << setprecision(3);
1132 fDriveControlMoonDist = -1;
1136 const double angle = fMoon.
Angle(Ra, Dec);
1137 out <<
Moon::Color(angle) <<
'\t' << setprecision(3) << angle <<
'\n';
1139 fDriveControlMoonDist = angle;
1144 ofstream(fPath+
"/tracking.data") << out.str();
1146 return GetCurrentState();
1151 if (!CheckDataSize(d,
"DriveControl:Source", 5*8+31))
1152 return GetCurrentState();
1154 const double *ptr = d.
Ptr<
double>();
1156 const double ra = ptr[0];
1157 const double dec = ptr[1];
1158 const double woff = ptr[2];
1159 const double wang = ptr[3];
1160 const double period = ptr[4];
1162 fDriveControlSourceName = d.
Ptr<
char>(5*8);
1167 out <<
HTML::kWhite <<
'\t' << fDriveControlSourceName <<
'\n';
1168 out << setprecision(5);
1171 out << setprecision(3);
1176 ofstream(fPath+
"/source.data") << out.str();
1178 return GetCurrentState();
1183 if (!CheckDataSize(d,
"Feedback:CalibratedCurrents", (416+1+1+1+1+1+416+1+1)*
sizeof(
float)+
sizeof(uint32_t)))
1184 return GetCurrentState();
1186 const float *ptr = d.
Ptr<
float>();
1188 double power_tot = 0;
1189 double power_apd = 0;
1191 if (fBiasControlVoltageVec.size()>0)
1194 for (
int i=0;
i<320;
i++)
1197 if (
i==66 ||
i==191 ||
i==193)
1201 const int N = fPixelMap.
hv(
i).
count();
1208 double Iapd = ptr[
i] * 1e-6;
1209 double Iout = Iapd*N;
1211 double UdrpCam = 1000 *Iout;
1212 double UdrpApd = (R5+2000)*Iout;
1214 const double pwrCam = Iout * (fBiasControlVoltageVec[
i]-UdrpCam);
1215 const double pwrApd = Iout * (fBiasControlVoltageVec[
i]-UdrpApd);
1220 power_tot += pwrCam;
1223 power_apd += pwrApd;
1228 power_apd /= (320-3)*1e-3;
1235 fBiasControlPowerTot = power_tot;
1240 vector<float> val(320, 0);
1241 for (
int i=0;
i<320;
i++)
1243 const int idx = (fPixelMap.
hv(
i).
hw()/9)*2+fPixelMap.
hv(
i).
group();
1248 WriteCam(d,
"cam-biascontrol-current", val, 100);
1255 vector<float> cpy(ptr, ptr+320);
1262 fBiasControlCurrentMed = stat.
med;
1263 fBiasControlCurrentMax = stat.
max;
1266 fBiasControlCurrentHist.push_back(fBiasControlCurrentMed);
1267 if (fBiasControlCurrentHist.size()>360)
1268 fBiasControlCurrentHist.pop_front();
1271 WriteHist(d,
"hist-biascontrol-current", fBiasControlCurrentHist, 125);
1301 out << setprecision(3);
1304 out << col1 <<
'\t' << stat.
min <<
'\n';
1305 out << col2 <<
'\t' << stat.
med <<
'\n';
1306 out << col3 <<
'\t' << stat.
avg <<
'\n';
1307 out << col4 <<
'\t' << stat.
max <<
'\n';
1308 out <<
HTML::kWhite <<
'\t' << power_tot <<
"W [" << power_apd <<
"mW]\n";
1309 ofstream(fPath+
"/current.data") << out.str();
1313 const float Unom = ptr[2*416+6];
1314 const float Utmp = ptr[2*416+7];
1316 vector<float> Uov(ptr+416+6, ptr+416+6+320);
1318 WriteCam(d,
"cam-feedback-overvoltage", Uov, 0.2, -0.1);
1324 out << setprecision(3);
1331 ofstream(fPath+
"/feedback.data") << out.str();
1333 return GetCurrentState();
1339 return GetCurrentState();
1341 if (!CheckDataSize(d,
"BiasControl:Current", 832))
1342 return GetCurrentState();
1345 vector<float> v(320);
1346 for (
int i=0;
i<320;
i++)
1347 v[
i] = d.
Ptr<uint16_t>()[
i] * 5000./4096;
1349 fBiasControlPowerTot = 0;
1352 vector<float> val(320, 0);
1353 for (
int i=0;
i<320;
i++)
1359 const int idx = (hv.
hw()/9)*2+hv.
group();
1364 WriteCam(d,
"cam-biascontrol-current", val, 1000);
1369 fBiasControlCurrentMed = stat.
med;
1370 fBiasControlCurrentMax = stat.
max;
1373 fBiasControlCurrentHist.push_back(fBiasControlCurrentMed);
1374 if (fBiasControlCurrentHist.size()>360)
1375 fBiasControlCurrentHist.pop_front();
1378 WriteHist(d,
"hist-biascontrol-current", fBiasControlCurrentHist, 1000);
1381 out << setprecision(3);
1384 out << HTML::kWhite <<
'\t' << stat.
min <<
'\n';
1385 out << HTML::kWhite <<
'\t' << stat.
med <<
'\n';
1386 out << HTML::kWhite <<
'\t' << stat.
avg <<
'\n';
1387 out << HTML::kWhite <<
'\t' << stat.
max <<
'\n';
1388 out << HTML::kWhite <<
'\t' <<
"---\n";
1389 ofstream(fPath+
"/current.data") << out.str();
1391 return GetCurrentState();
1396 if (!CheckDataSize(d,
"BiasControl:Voltage", 1664))
1398 fBiasControlVoltageVec.clear();
1399 return GetCurrentState();
1402 fBiasControlVoltageVec.assign(d.
Ptr<
float>(), d.
Ptr<
float>()+320);
1404 const Statistics stat(fBiasControlVoltageVec);
1406 fBiasControlVoltageMed = stat.
med;
1408 vector<float> val(320, 0);
1409 for (
int i=0;
i<320;
i++)
1411 const int idx = (fPixelMap.
hv(
i).
hw()/9)*2+fPixelMap.
hv(
i).
group();
1412 val[idx] = fBiasControlVoltageVec[
i];
1416 WriteCam(d,
"cam-biascontrol-voltage", val, 10, 65);
1418 WriteCam(d,
"cam-biascontrol-voltage", val, 75);
1421 out << setprecision(3);
1427 ofstream(fPath+
"/voltage.data") << out.str();
1429 return GetCurrentState();
1434 if (!CheckDataSize(d,
"FadControl:Events", 4*4))
1436 fFadControlNumEvents = -1;
1437 return GetCurrentState();
1440 fFadControlNumEvents = d.
Get<uint32_t>();
1442 return GetCurrentState();
1447 if (!CheckDataSize(d,
"FadControl:StartRun", 16))
1449 fFadControlStartRun = -1;
1450 return GetCurrentState();
1453 fFadControlStartRun = d.
Get<int64_t>();
1455 return GetCurrentState();
1460 if (!CheckDataSize(d,
"FadControl:DrsRuns", 5*4))
1462 fFadControlDrsStep = -1;
1463 return GetCurrentState();
1466 const uint32_t *ptr = d.
Ptr<uint32_t>();
1467 fFadControlDrsStep = ptr[0];
1468 fFadControlDrsRuns[0] = ptr[1];
1469 fFadControlDrsRuns[1] = ptr[2];
1470 fFadControlDrsRuns[2] = ptr[3];
1472 return GetCurrentState();
1477 if (!CheckDataSize(d,
"FadControl:Connections", 41))
1480 return GetCurrentState();
1485 const uint8_t *ptr = d.
Ptr<uint8_t>();
1487 int c[4] = {
'.',
'.',
'.',
'.' };
1489 for (
int i=0;
i<40;
i++)
1491 const uint8_t stat1 = ptr[
i]&3;
1492 const uint8_t stat2 = ptr[
i]>>3;
1494 if (stat1==0 && stat2==0)
1497 if (stat1>=2 && stat2==8)
1498 rc[
i] = stat1==2?
'+':
'*';
1505 for (
int i=0;
i<4;
i++)
1515 out << setprecision(3);
1517 out << col[0] <<
'\t' << rc.substr( 0, 10) <<
'\n';
1518 out << col[1] <<
'\t' << rc.substr(10, 10) <<
'\n';
1519 out << col[2] <<
'\t' << rc.substr(20, 10) <<
'\n';
1520 out << col[3] <<
'\t' << rc.substr(30, 10) <<
'\n';
1521 ofstream(fPath+
"/fad.data") << out.str();
1523 return GetCurrentState();
1544 if (!CheckDataSize(d,
"FtmControl:TriggerRates", 24+160+640+8))
1546 fFtmControlTriggerRateTooLow = 0;
1547 return GetCurrentState();
1556 fFtmControlTriggerRateTooLow =
1561 fFtmControlState = d.
GetQoS();
1567 fFtmControlTriggerRateHist.push_back(dim.
fTriggerRate);
1568 if (fFtmControlTriggerRateHist.size()>300)
1569 fFtmControlTriggerRateHist.pop_front();
1573 WriteHist(d,
"hist-ftmcontrol-triggerrate",
1574 fFtmControlTriggerRateHist, 100);
1575 WriteCam(d,
"cam-ftmcontrol-boardrates",
1576 vector<float>(brates, brates+40), 10);
1577 WriteCam(d,
"cam-ftmcontrol-patchrates",
1578 vector<float>(prates, prates+160), 10);
1581 out << setprecision(3);
1585 ofstream(fPath+
"/trigger.data") << out.str();
1587 const Statistics bstat(vector<float>(brates, brates+ 40));
1588 const Statistics pstat(vector<float>(prates, prates+160));
1596 ofstream(fPath+
"/boardrates.data") << out.str();
1604 ofstream(fPath+
"/patchrates.data") << out.str();
1606 return GetCurrentState();
1612 return GetCurrentState();
1616 fFtmControlState = d.
GetQoS();
1623 WriteCam(d,
"cam-ftmcontrol-thresholds-patch", vecp, 1000);
1624 WriteCam(d,
"cam-ftmcontrol-thresholds-board", vecb, 100);
1629 fFtmPatchThresholdMed = statp.
med;
1630 fFtmBoardThresholdMed = statb.
med;
1637 ofstream(fPath+
"/thresholds-board.data") << out.str();
1644 ofstream(fPath+
"/thresholds-patch.data") << out.str();
1650 ofstream(fPath+
"/thresholds.data") << out.str();
1672 out << HTML::kWhite <<
'\t' << (dat.
HasTrigger()?
"on":
"off") <<
" / " << (dat.
HasExt1()?
"on":
"off") <<
" / " << (dat.
HasExt2()?
"on":
"off") <<
'\n';
1673 out << HTML::kWhite <<
'\t' << (dat.
HasVeto()?
"on":
"off") <<
" / " << (dat.
HasClockConditioner()?
"time cal":
"marker") <<
'\n';
1677 out << HTML::kWhite <<
'\t' << dat.
fDeadTime <<
'\n';
1680 for (
int i=1;
i<40;
i++)
1687 out << HTML::kWhite <<
'\t' << 0.5*vp <<
"\n";
1689 ofstream(fPath+
"/ftm.data") << out.str();
1694 return GetCurrentState();
1700 return GetCurrentState();
1708 for (
int i=0;
i<4;
i++)
1711 for (
int j=0; j<10; j++)
1714 if (sdata.
fPing[
i*10+j]==1)
1720 out << sdata.
fPing[
i*10+j];
1727 fFtmControlFtuOk = cnt==40;
1729 ofstream(fPath+
"/ftu.data") << out.str();
1731 return GetCurrentState();
1736 if (!CheckDataSize(d,
"FadControl:EventData", 23040+8))
1737 return GetCurrentState();
1739 const float *dat = d.
Ptr<
float>(1440*
sizeof(float)*2)+2;
1756 vector<float> val(1440);
1757 for (
int i=0;
i<1440;
i++)
1758 val[
i] = dat[
i%9==8 ?
i-2 :
i]/1000;
1760 vector<float> sorted(val);
1761 nth_element(sorted.begin(), sorted.begin()+3, sorted.end(),
1762 std::greater<float>());
1766 const float min = fFadControlDrsRuns[0]==0 ? -1 : 0;
1774 scale = max(0.25f, sorted[3]);
1780 WriteCam(d,
"cam-fadcontrol-eventdata", val, scale, min);
1782 return GetCurrentState();
1787 if (!CheckDataSize(d,
"Stats", 4*8))
1789 fFreeSpace = UINT64_MAX;
1790 return GetCurrentState();
1796 return GetCurrentState();
1801 if (!CheckDataSize(d,
"FscControl:Temperature", 240))
1802 return GetCurrentState();
1804 const float *ptr = d.
Ptr<
float>(4);
1812 for (
const float *
t=ptr;
t<ptr+31;
t++)
1832 rms = rms<0 ? 0 : sqrt(rms);
1835 static double pre_rms1 = 1.5;
1836 static double pre_rms2 = 0;
1838 const double cut = pre_rms1 + 0.1;
1840 const bool reject = rms>cut && pre_rms2<cut;
1842 pre_rms2 = pre_rms1;
1846 return GetCurrentState();
1849 if (!fMagicWeatherHist[kTemp].empty())
1851 fFscControlTemperatureHist.push_back(avg-fMagicWeatherHist[kTemp].back());
1852 if (fFscControlTemperatureHist.size()>300)
1853 fFscControlTemperatureHist.pop_front();
1856 const Statistics stat(fFscControlTemperatureHist);
1859 out << setprecision(3);
1861 out <<
HTML::kWhite <<
'\t' << fFscControlHumidityAvg <<
'\n';
1866 ofstream(fPath+
"/fsc.data") << out.str();
1868 WriteHist(d,
"hist-fsccontrol-temperature",
1869 fFscControlTemperatureHist, 10);
1872 out << setprecision(3);
1878 ofstream(fPath+
"/camtemp.data") << out.str();
1880 return GetCurrentState();
1885 if (!CheckDataSize(d,
"FscControl:BiasTemp", 323*4))
1886 return GetCurrentState();
1888 const float *ptr = d.
Ptr<
float>(4);
1889 const float avg = d.
Get<
float>(321*4);
1892 vector<double> tout(320);
1893 for (
int i=0;
i<320;
i++)
1895 const int idx = (fPixelMap.
hv(
i).
hw()/9)*2+fPixelMap.
hv(
i).
group();
1899 WriteCam(d,
"cam-fsccontrol-temperature", tout, 3, avg-1.75);
1901 return GetCurrentState();
1906 if (!CheckDataSize(d,
"FscControl:Humidity", 5*4))
1907 return GetCurrentState();
1909 const float *ptr = d.
Ptr<
float>(4);
1914 for (
const float *
t=ptr;
t<ptr+4;
t++)
1915 if (*
t>0 && *
t<=100 &&
t!=ptr+2 )
1921 fFscControlHumidityAvg = num>0 ? avg/num : 0;
1923 return GetCurrentState();
1928 if (!CheckDataSize(d,
"PfMini:Data",
sizeof(
PFmini::Data)))
1929 return GetCurrentState();
1935 out << fixed << setprecision(1);
1941 ofstream(fPath+
"/pfmini.data") << out.str();
1943 fPfMiniTemperatureHist.push_back(data.
temp);
1944 if (fPfMiniTemperatureHist.size()>60*4)
1945 fPfMiniTemperatureHist.pop_front();
1947 fPfMiniHumidityHist.push_back(data.
hum);
1948 if (fPfMiniHumidityHist.size()>60*4)
1949 fPfMiniHumidityHist.pop_front();
1951 WriteHist(d,
"hist-pfmini-temp",
1952 fPfMiniTemperatureHist, 45, 0);
1954 WriteHist(d,
"hist-pfmini-hum",
1955 fPfMiniHumidityHist, 100, 0);
1957 return GetCurrentState();
1962 if (!CheckDataSize(d,
"GpsControl:Nema",
sizeof(
GPS::NEMA)))
1963 return GetCurrentState();
1974 case 1: out <<
HTML::kGreen <<
"\tGPS fix [1]\n";
break;
1975 case 2: out << HTML::kGreen <<
"\tDifferential fix [2]\n";
break;
1976 default: out <<
HTML::kRed <<
"\tinvalid [" << nema.
qos <<
"]\n";
break;
1987 ofstream(fPath+
"/gps.data") << out.str();
1989 return GetCurrentState();
1994 if (!CheckDataSize(d,
"SqmControl:Data",
sizeof(
SQM::Data)))
1995 return GetCurrentState();
2009 ofstream(fPath+
"/sqm.data") << out.str();
2011 return GetCurrentState();
2027 if (!CheckDataSize(d,
"Temperature:Data", 3*
sizeof(
float)))
2028 return GetCurrentState();
2030 const float *
temp = d.
Ptr<
float>();
2034 out << fixed << setprecision(1);
2037 out << GetTempColor(temp[1]) <<
'\t' << temp[1] <<
'\n';
2038 out << GetTempColor(temp[0]) <<
'\t' << temp[0] <<
'\n';
2039 out << GetTempColor(temp[2]) <<
'\t' << temp[2] <<
'\n';
2041 ofstream(fPath+
"/temperature.data") << out.str();
2043 fTemperatureControlHist.push_back(temp[0]);
2044 if (fTemperatureControlHist.size()>60)
2045 fTemperatureControlHist.pop_front();
2047 WriteHist(d,
"hist-temperaturecontrol",
2048 fTemperatureControlHist, 45, 0);
2050 return GetCurrentState();
2055 if (!CheckDataSize(d, (
"Agilent"+ext+
":Data").c_str(), 4*
sizeof(
float)))
2056 return GetCurrentState();
2058 const float *
data = d.
Ptr<
float>();
2062 out << fixed << setprecision(1);
2070 ofstream(fPath+
"/agilent"+ext+
".data") << out.str();
2072 return GetCurrentState();
2077 if (!CheckDataSize(d,
"RateScan:Data", 824))
2078 return GetCurrentState();
2080 const uint64_t
id = d.
Get<uint64_t>();
2081 const float *rate = d.
Ptr<
float>(20);
2083 if (fRateScanDataId!=
id)
2085 for (
int i=0;
i<41;
i++)
2086 fRateScanDataHist[
i].
clear();
2087 fRateScanDataId =
id;
2089 fRateScanDataHist[0].push_back(log10(rate[0]));
2092 for (
int i=1;
i<41;
i++)
2094 fRateScanDataHist[
i].push_back(log10(rate[
i]));
2101 fRateScanBoard %= 40;
2103 WriteHist(d,
"hist-ratescan", fRateScanDataHist[0], 10, -2);
2104 WriteCam(d,
"cam-ratescan-board", fRateScanDataHist[fRateScanBoard+1], 10, -4);
2107 out << setprecision(3);
2109 out <<
HTML::kWhite <<
'\t' << fFtmBoardThresholdMed <<
'\n';
2110 out <<
HTML::kWhite <<
'\t' << fFtmPatchThresholdMed <<
'\n';
2111 out <<
HTML::kWhite <<
'\t' << floor(pow(10, fRateScanDataHist[0].back())+.5) <<
'\n';
2114 ofstream(fPath+
"/ratescan.data") << out.str();
2118 out <<
HTML::kWhite <<
'\t' << int(fRateScanBoard) <<
'\n';
2119 out <<
HTML::kWhite <<
'\t' << pow(10, fRateScanDataHist[fRateScanBoard+1].back()) <<
'\n';
2121 ofstream(fPath+
"/ratescan_board.data") << out.str();
2123 return GetCurrentState();
2128 if (!CheckDataSize(d,
"RateControl:Threshold", 18))
2129 return GetCurrentState();
2131 const uint16_t th = d.
Get<uint16_t>();
2133 fRateControlThreshold.push_back(th);
2134 if (fRateControlThreshold.size()>300)
2135 fRateControlThreshold.pop_front();
2137 WriteHist(d,
"hist-ratecontrol-threshold", fRateControlThreshold, 1000);
2139 return GetCurrentState();
2145 return GetCurrentState();
2147 if (
Time()<d.
GetTime()+boost::posix_time::minutes(1))
2148 SetAudio(
"message");
2153 out << setprecision(3);
2154 out <<
Header(d) <<
'\n';
2156 out <<
"<->" << fChatHist.
rget() <<
"</->";
2159 ofstream(fPath+
"/chat.data") << out.str();
2161 return GetCurrentState();
2173 case -3: out <<
HTML::kWhite <<
"\tNot running\n";
break;
2174 case -2: out <<
HTML::kBlue <<
"\tLoading\n";
break;
2175 case -1: out << HTML::kBlue <<
"\tStarted\n";
break;
2179 ofstream(fPath+
"/dotest.data") << out.str();
2200 Out() << fDimDNS << endl;
2201 Out() << fDimMcp << endl;
2202 Out() << fDimControl << endl;
2203 Out() << fDimDataLogger << endl;
2204 Out() << fDimDriveControl << endl;
2205 Out() << fDimTimeCheck << endl;
2206 Out() << fDimFadControl << endl;
2207 Out() << fDimFtmControl << endl;
2208 Out() << fDimBiasControl << endl;
2209 Out() << fDimFeedback << endl;
2210 Out() << fDimRateControl << endl;
2211 Out() << fDimFscControl << endl;
2212 Out() << fDimAgilentControl24 << endl;
2213 Out() << fDimAgilentControl50 << endl;
2214 Out() << fDimAgilentControl80 << endl;
2215 Out() << fDimPwrControl << endl;
2216 Out() << fDimLidControl << endl;
2217 Out() << fDimMagicWeather << endl;
2218 Out() << fDimTngWeather << endl;
2219 Out() << fDimMagicLidar << endl;
2220 Out() << fDimTemperature << endl;
2221 Out() << fDimRateScan << endl;
2222 Out() << fDimChat << endl;
2223 Out() << fDimSkypeClient << endl;
2225 return GetCurrentState();
2233 if (&state==&fDimControl)
2259 return col +
'\t' + rc.name +
'\n';
2266 fErrorList.erase(err);
2270 const bool isnew = fErrorList.insert(err).second;
2272 fErrorHist.
add(err);
2281 vector<Nova::SolarObjects> fCoordinates;
2283 void CalcCoordinates(
double jd)
2287 fCoordinates.clear();
2288 for (
double h=0; h<1; h+=1./(24*12))
2289 fCoordinates.emplace_back(jd+h);
2292 pair<vector<float>, pair<Time, float>> GetVisibility(
Nova::EquPosn *src=0)
2306 for (
auto it=fCoordinates.begin(); it!=fCoordinates.end(); it++)
2309 moon = it->fMoonEqu;
2313 if (it->fJD>sunset && it->fJD<sunrise)
2314 alt.push_back(hrz.alt);
2322 if (it->fJD>sunset && it->fJD<sunrise && hrz.alt>15)
2326 if (max<=15 || cnt==0)
2327 return make_pair(vector<float>(), make_pair(
Time(), 0));
2329 return make_pair(alt, make_pair(maxjd, maxjd>sunset&&maxjd<sunrise?max:0));
2332 pair<vector<float>, pair<Time, float>> GetLightCondition(
const Nova::EquPosn &src_pos)
2343 for (
auto it=fCoordinates.begin(); it!=fCoordinates.end(); it++)
2347 if (it->fJD>sunset && it->fJD<sunrise)
2359 if (it->fJD>sunset && it->fJD<sunrise && cur>0)
2363 if (max<=0 || cnt==0)
2364 return make_pair(vector<float>(), make_pair(
Time(), 0));
2366 return make_pair(vec, make_pair(maxjd, maxjd>sunset&&maxjd<sunrise?max:-1));
2374 CalcCoordinates(now.
JD());
2383 out << setprecision(3);
2385 out << color[4] <<
'\t' << fSun.fSunRise18.GetAsStr(
"%H:%M") <<
'\n';
2386 out << color[5] <<
'\t' << fSun.fSunRise12.GetAsStr(
"%H:%M") <<
'\n';
2387 out << color[6] <<
'\t' << fSun.fSunRise06.GetAsStr(
"%H:%M") <<
'\n';
2388 out << color[7] <<
'\t' << fSun.fSunRise00.GetAsStr(
"%H:%M") <<
'\n';
2390 out << color[0] <<
'\t' << fSun.fSunSet00.GetAsStr(
"%H:%M") <<
'\n';
2391 out << color[1] <<
'\t' << fSun.fSunSet06.GetAsStr(
"%H:%M") <<
'\n';
2392 out << color[2] <<
'\t' << fSun.fSunSet12.GetAsStr(
"%H:%M") <<
'\n';
2393 out << color[3] <<
'\t' << fSun.fSunSet18.GetAsStr(
"%H:%M") <<
'\n';
2395 ofstream(fPath+
"/sun.data") << out.str();
2403 out << color[0] <<
'\t' << fMoon.
fRise.
GetAsStr(
"%H:%M") <<
'\n';
2405 out << color[2] <<
'\t' << fMoon.
fSet.
GetAsStr(
"%H:%M") <<
'\n';
2419 if (fMoon.
zd>45 && fMoon.
zd<80)
2424 out << col <<
'\t' << fMoon.
zd <<
'\t' << GetDir(fMoon.
az) <<
'\n';
2427 ostringstream out2, out3, out4;
2428 out2 << setprecision(3);
2438 Entry(
const string &n,
float v,
int c) : name(n), value(v),
color(c%8) { }
2440 const string &Col()
const 2444 static const string hcol[] = {
"888",
"8cf",
"c8f",
"bbb",
"8fc",
"cf8",
"f8c",
"fc8" };
2448 vector<float> GetColor(
double scale,
double offset=0)
const 2450 vector<float> rc(3);
2451 rc[0] = double(Col()[0])*scale/126+offset;
2452 rc[1] = double(Col()[1])*scale/126+offset;
2453 rc[2] = double(Col()[2])*scale/126+offset;
2458 multimap<Time, Entry> culmination;
2459 multimap<Time, Entry> lightcond;
2460 vector<vector<float>> alt;
2461 vector<vector<float>> cur;
2467 pair<vector<float>, pair<Time, float>> vism = GetVisibility();
2468 if (!vism.first.empty())
2470 const Entry entry(
"Moon", vism.second.second, ccol);
2471 culmination.insert(make_pair(vism.second.first, entry));
2472 const vector<float> col = entry.GetColor(75, 15);
2473 vism.first.insert(vism.first.begin(), col.begin(), col.end());
2474 alt.push_back(vism.first);
2483 const mysqlpp::StoreQueryResult res =
2484 Database(fDatabase).query(
"SELECT fSourceName, fRightAscension, fDeclination FROM Source WHERE fSourceTypeKEY=1").store();
2486 out << HTML::kWhite <<
'\t';
2487 out2 << HTML::kWhite <<
'\t';
2488 out3 << HTML::kWhite <<
'\t';
2489 out4 << HTML::kWhite <<
'\t';
2491 for (vector<mysqlpp::Row>::const_iterator v=res.begin(); v<res.end(); v++)
2493 const string name = (*v)[0].c_str();
2494 const double ra = (*v)[1];
2495 const double dec = (*v)[2];
2503 pair<vector<float>, pair<Time, float>> vis = GetVisibility(&pos);
2504 if (!vis.first.empty())
2506 const Entry entry(name, vis.second.second, ccol);
2507 culmination.insert(make_pair(vis.second.first, entry));
2508 const vector<float> col = entry.GetColor(75, 15);
2509 vis.first.insert(vis.first.begin(), col.begin(), col.end());
2510 alt.push_back(vis.first);
2514 pair<vector<float>, pair<Time, float>> lc = GetLightCondition(pos);
2515 if (!lc.first.empty())
2517 const Entry entry2(name, lc.second.second, lcol);
2518 lightcond.insert(make_pair(lc.second.first, entry2));
2519 const vector<float> col2 = entry2.GetColor(100);
2520 lc.first.insert(lc.first.begin(), col2.begin(), col2.end());
2521 cur.push_back(lc.first);
2535 out2 <<
"<tr bgcolor='" << col <<
"'>";
2536 out2 <<
"<td>" << name <<
"</td>";
2539 out2 <<
"<td>" << hrz.
zd <<
"°</td>";
2540 out2 <<
"<td>" << GetDir(hrz.
az) <<
"</td>";
2543 out2 <<
"<td/><td/>";
2546 const int32_t angle = fMoon.
Angle(ra, dec);
2548 out <<
"<tr bgcolor='" <<
Moon::Color(angle) <<
"'>";
2549 out <<
"<td>" << name <<
"</td>";
2550 out <<
"<td>" << round(angle) <<
"°</td>";
2554 for (
auto it=culmination.begin(); it!=culmination.end(); it++)
2556 const Entry &e = it->second;
2557 if (it!=culmination.begin())
2559 out3 <<
"<B#" << e.Col() <<
">" << e.name <<
"</B>";
2561 out3 <<
" [" << nearbyint(90-e.value) <<
"°]";
2564 out4 << setprecision(3);
2566 for (
auto it=lightcond.begin(); it!=lightcond.end(); it++)
2568 const Entry &e = it->second;
2569 if (it!=lightcond.begin())
2571 out4 <<
"<B#" << e.Col() <<
">" << e.name <<
"</B>";
2573 out4 <<
" [" << nearbyint(e.value) <<
"]";
2576 const Time st = fSun.fSunSet12;;
2577 const Time rs = fSun.fSunRise12;
2579 ostringstream title;
2582 title << ((rs>st?rs-st:st-rs)/20).minutes();
2590 out << HTML::kWhite <<
'\t' <<
Time()-now <<
'\n';
2591 out2 << HTML::kWhite <<
'\t' <<
Time()-now <<
'\n';
2593 WriteBinaryVec(now,
"hist-visibility", alt, 75, 15,
"Alt "+title.str());
2594 WriteBinaryVec(now,
"hist-current-prediction", cur, 100, 0,
"I " +title.str());
2596 catch (
const exception &e)
2600 out << HTML::kWhite <<
'\t' <<
"ERROR - "+string(e.what()) <<
'\n';
2601 out2 << HTML::kWhite <<
'\t' <<
"ERROR - "+string(e.what()) <<
'\n';
2602 out3 << HTML::kWhite <<
'\t' <<
"ERROR - "+string(e.what()) <<
'\n';
2603 out4 << HTML::kWhite <<
'\t' <<
"ERROR - "+string(e.what()) <<
'\n';
2607 ofstream(fPath+
"/moon.data") << out.str();
2608 ofstream(fPath+
"/source-list.data") << out2.str();
2609 ofstream(fPath+
"/visibility.data") << out3.str();
2610 ofstream(fPath+
"/current-prediction.data") << out4.str();
2616 if (now-fLastUpdate<boost::posix_time::seconds(1))
2617 return fDimDNS.
online() ? kStateRunning : kStateDimNetworkNA;
2622 bool reqscript =
false;
2627 const string query =
Tools::Form(
"SELECT COUNT(*) FROM calendar.Data WHERE NOT u LIKE 'moon' AND y=%d AND m=%d AND d=%d",
2630 const mysqlpp::StoreQueryResult res =
Database(fDatabase).query(query).store();
2632 const uint32_t cnt = res[0][0];
2634 reqscript = cnt>0 && (fSun.
state==3 || fSun.
state==4);
2636 catch (
const exception &e)
2638 Out() << e.what() << endl;
2644 statvfs(
"/daq", &vfs);
2646 const uint64_t freedaq = vfs.f_bsize*vfs.f_bavail;
2650 const bool data_taking =
2654 const bool data_run =
2655 fMcpConfigurationName==
"data" ||
2656 fMcpConfigurationName==
"data-rt";
2658 const bool bias_on =
2663 const bool calibrated =
2666 const bool haderr = !fErrorList.empty();
2668 bool newerr =
false;
2670 newerr |= SetError(!fDimDNS.
online(),
2671 "<b><#darkred>DIM network not available</#></b>");
2672 newerr |= SetError(!fDimControl.
online(),
2673 "<b>no dimctrl server available</b>");
2674 newerr |= SetError(fDimDataLogger.
state()<20 || fDimDataLogger.
state()>40,
2675 "<b>datalogger not ready</b>");
2677 newerr |= SetError(fDimControl.
state()!=3 && reqscript,
2678 "<b>No script running during datataking time.</b>");
2683 newerr |= SetError(fDimDriveControl.
state()>0xff && data_taking && data_run,
2684 "Drive in ERROR state during data-run");
2685 newerr |= SetError(fDriveControlMoonDist>155,
2686 "Moon within the field-of-view of the cones");
2687 newerr |= SetError(fDriveControlMoonDist>=0 && fDriveControlMoonDist<3,
2688 "Moon within the field-of-view of the camera");
2691 "BIAS not operating during data-run");
2693 "BIAS channels in OverCurrent");
2695 "BIAS voltage not at reference");
2698 "Feedback in standby due to high currents");
2701 newerr |= SetError(bias_on && calibrated && fBiasControlCurrentMed>115,
2702 "Median current (excl. crazy) exceeds 115µA/pix");
2703 newerr |= SetError(bias_on && calibrated && fBiasControlCurrentMax>160,
2704 "Maximum current (excl. crazy) exceeds 160µA/pix");
2706 newerr |= SetError(fFscControlHumidityAvg>60,
2707 "Average camera humidity exceed 60%");
2709 newerr |= SetError(!fPfMiniHumidityHist.empty() && fPfMiniHumidityHist.back()>50,
2710 "Camera humidity inside camera exceeds 50% (PFmini)");
2711 newerr |= SetError(!fTemperatureControlHist.empty() && (fTemperatureControlHist.back()<26.5 || fTemperatureControlHist.back()>29),
2712 "Container temperature outside [26.5;29]°C");
2714 newerr |= SetError(!fMagicWeatherHist[kHum].empty() && fMagicWeatherHist[kHum].back()>98 && fDimLidControl.
state()==
Lid::State::kOpen,
2715 "Outside humidity exceeds 98% while lid is open");
2717 "Wind gusts exceed 50km/h during tracking");
2719 newerr |= SetError(fDimFscControl.
state()>=
FSC::State::kConnected && !fFscControlTemperatureHist.empty() && fFscControlTemperatureHist.back()>15,
2720 "Sensor temperature exceeds outside temperature by more than 15°C");
2722 newerr |= SetError(fFtmControlTriggerRateTooLow>0,
2723 "Trigger rate below 1Hz while trigger switched on");
2726 "FTM - clock conditioner not locked!");
2728 newerr |= SetError(fDimTimeCheck.
state()==1,
2729 "Warning NTP time difference of drive PC exceeds 1s");
2730 newerr |= SetError(fDimTimeCheck.
state()<1,
2731 "Warning timecheck not running");
2735 fBiasControlVoltageMed>3,
2736 "Bias voltage switched on, but bias crate not calibrated");
2738 newerr |= SetError(fLastRunFinishedWithZeroEvents,
2739 "Last run finshed, but contained zero events.");
2741 newerr |= SetError(fFreeSpace<uint64_t(50000000000),
2742 "Less than 50GB disk space left on newdaq.");
2744 newerr |= SetError(freedaq<uint64_t(800000000000),
2745 "Less than 800GB disk space left on daq.");
2748 "Cooling unit reports failure!");
2750 for (
auto it=fControlAlarmHist.begin(); it!=fControlAlarmHist.end(); it++)
2751 newerr |= SetError(it->time.IsValid(), it->msg);
2752 fControlAlarmHist.
clean();;
2754 fLastRunFinishedWithZeroEvents =
false;
2786 out <<
"<->" << fErrorHist.
rget() <<
"<->";
2789 ofstream(fPath+
"/errorhist.data") << out.str();
2793 out <<
Header(now) <<
'\t' << (!fErrorList.empty()) <<
'\t' << (fDimControl.
state()>0) <<
'\n';
2794 out << setprecision(3);
2796 for (
auto it=fErrorList.begin(); it!=fErrorList.end(); it++)
2797 out << *it <<
"<br/>";
2800 if (haderr || !fErrorList.empty())
2801 ofstream(fPath+
"/error.data") << out.str();
2806 out <<
Header(now) <<
'\t' << (!fErrorList.empty()) <<
'\t' << (fDimControl.
state()>0) <<
'\n';
2807 out << setprecision(3);
2813 switch (fMcpConfigurationState)
2828 if (fDimFadControl.
state()==FAD::State::kRunInProgress)
2845 const string conf = fMcpConfigurationName.length()>0?
" ["+fMcpConfigurationName+
"]":
"";
2846 switch (fMcpConfigurationState)
2849 out <<
"Idle" << conf;
2854 out <<
"Configuring" << conf;
2857 out <<
"Configured" << conf;
2861 out << fMcpConfigurationName;
2862 if (fFadControlDrsRuns[2]>0)
2863 out <<
"(" << fFadControlDrsRuns[2] <<
")";
2869 out <<
"Calibrating threshold";
2872 out <<
"Rate scan in progress";
2875 out <<
"Lid moving";
2882 if (fMcpConfigurationMaxEvents>0)
2884 const int64_t de = int64_t(fMcpConfigurationMaxEvents) - int64_t(fFadControlNumEvents);
2888 evt << fMcpConfigurationMaxEvents;
2894 if (fFadControlNumEvents>2999)
2895 evt << floor(fFadControlNumEvents/1000) <<
'k';
2897 evt << fFadControlNumEvents;
2902 if (fMcpConfigurationMaxTime>0)
2904 const uint32_t dt = (
Time()-fMcpConfigurationRunStart).total_seconds();
2906 tim << fMcpConfigurationMaxTime-dt <<
's';
2908 tim << fMcpConfigurationMaxTime <<
's';
2913 tim << fMcpConfigurationRunStart.
SecondsTo();
2916 const bool has_evt = !evt.str().empty();
2917 const bool has_tim = !tim.str().empty();
2919 if (has_evt || has_tim)
2922 if (has_evt && has_tim)
2925 if (has_evt || has_tim)
2936 const uint32_t
dev = !fDriveControlTrackingDevHist.empty() ? round(fDriveControlTrackingDevHist.back()) : 0;
2952 if (fDimDriveControl.
state()>0xff)
2957 out << fDriveControlPointingAz <<
' ';
2958 out << fDriveControlPointingZd <<
"°";
2959 out << setprecision(2);
2963 out <<
" ± " << dev <<
'"';
2964 if (!fDriveControlSourceName.empty())
2965 out <<
" [" << fDriveControlSourceName <<
']';
2970 out << setprecision(3);
2973 out << HTML::kWhite <<
'\t';
2988 out <<
" [" << fMoon.
disk <<
"%]";
2991 if (fDimDNS.
online() && fDimDriveControl.
state()>0xff)
3001 if (fFscControlTemperatureHist.back()>9)
3003 if (fFscControlTemperatureHist.back()>15)
3006 out << col <<
'\t' << fFscControlTemperatureHist.back() <<
'\n';
3009 out << HTML::kWhite <<
'\n';
3023 const float wind = fMagicWeatherHist[kGusts].back();
3024 const float hum = fMagicWeatherHist[kHum].back();
3026 if (wind>35 || hum>95)
3028 if (wind>45 || hum>98)
3032 out << fMagicWeatherHist[kHum].back() <<
'\t';
3033 out << setprecision(2);
3034 out << fMagicWeatherHist[kGusts].back() <<
'\n';
3035 out << setprecision(3);
3038 out << HTML::kWhite <<
"\n";
3044 if (!fFtmControlTriggerRateHist.empty())
3046 if (fFtmControlTriggerRateHist.back()<15)
3048 if (fFtmControlTriggerRateHist.back()>100)
3051 out << col <<
'\t' << fFtmControlTriggerRateHist.back() <<
" Hz";
3055 out <<
" (" << setprecision(4) << fFtmPatchThresholdMed <<
')';
3059 out << HTML::kWhite <<
'\n';
3065 if (fDimDNS.
online() && (bias_on || bias_off))
3071 if (fBiasControlCurrentMed>95 || fBiasControlCurrentMax>135)
3073 if (fBiasControlCurrentMed>100 || fBiasControlCurrentMax>140)
3098 out << setprecision(fBiasControlCurrentMed<100?2:3);
3099 out << (bias_off ? 0 : (fBiasControlCurrentMed<10?fBiasControlCurrentMed:floor(fBiasControlCurrentMed))) <<
'\t';
3106 out << setprecision(fBiasControlCurrentMax<100?2:3);
3107 out << (bias_off ? 0 : (fBiasControlCurrentMax<10?fBiasControlCurrentMax:floor(fBiasControlCurrentMax)));
3115 out << setprecision(2) << fBiasControlPowerTot <<
" W";
3117 out << setprecision(3) << (bias_off ? 0 : fBiasControlVoltageMed) <<
" V";
3121 out << HTML::kWhite <<
'\n';
3123 ofstream(fPath+
"/fact.data") << out.str();
3128 out <<
Header(now) <<
'\t' << (!fErrorList.empty()) <<
'\t' << (fDimControl.
state()>0) <<
'\n';
3131 out << HTML::kWhite <<
"\tOffline\n\n\n\n\n\n\n\n\n\n\n\n\n";
3135 dt << (
Time()-fRunTime);
3139 out << GetStateHtml(fDimControl, 0);
3141 out << GetStateHtml(fDimDataLogger, 1);
3143 out << GetStateHtml(fDimTimeCheck, 1);
3163 out << GetStateHtml(fDimChat, 0);
3164 out << GetStateHtml(fDimSkypeClient, 1);
3167 if (fFreeSpace>uint64_t(199999999999))
3169 if (fFreeSpace>uint64_t(999999999999))
3171 if (fFreeSpace==UINT64_MAX)
3177 if (freedaq>uint64_t(999999999999))
3179 if (freedaq>uint64_t(149999999999))
3181 if (freedaq==UINT64_MAX)
3186 out <<
HTML::kGreen <<
'\t' << dt.str().substr(0, dt.str().length()-7) <<
'\n';
3189 ofstream(fPath+
"/status.data") << out.str();
3191 if (now-fLastAstroCalc>boost::posix_time::seconds(15))
3194 fLastAstroCalc = now;
3197 return fDimDNS.
online() ? kStateRunning : kStateDimNetworkNA;
3203 fLastAstroCalc(
boost::date_time::neg_infin),
3204 fPath(
"www/smartfact/data"),
3205 fControlScriptDepth(0),
3206 fMcpConfigurationState(
DimState::kOffline),
3207 fMcpConfigurationMaxTime(0),
3208 fMcpConfigurationMaxEvents(0),
3209 fLastRunFinishedWithZeroEvents(false),
3210 fTngWeatherDustTime(
Time::none),
3211 fBiasControlVoltageMed(0),
3212 fBiasControlCurrentMed(0),
3213 fBiasControlCurrentMax(0),
3214 fFscControlHumidityAvg(0),
3215 fDriveControlMoonDist(-1),
3216 fFadControlNumEvents(0),
3217 fFadControlDrsRuns(3),
3221 fFreeSpace(UINT64_MAX),
3224 fDimDataLogger (
"DATA_LOGGER"),
3225 fDimDriveControl (
"DRIVE_CONTROL"),
3226 fDimTimeCheck (
"TIME_CHECK"),
3227 fDimMagicWeather (
"MAGIC_WEATHER"),
3228 fDimMagicLidar (
"MAGIC_LIDAR"),
3229 fDimTngWeather (
"TNG_WEATHER"),
3230 fDimTemperature (
"TEMPERATURE"),
3231 fDimFeedback (
"FEEDBACK"),
3232 fDimBiasControl (
"BIAS_CONTROL"),
3233 fDimFtmControl (
"FTM_CONTROL"),
3234 fDimFadControl (
"FAD_CONTROL"),
3235 fDimFscControl (
"FSC_CONTROL"),
3236 fDimPfMiniControl (
"PFMINI_CONTROL"),
3237 fDimGpsControl (
"GPS_CONTROL"),
3238 fDimSqmControl (
"SQM_CONTROL"),
3239 fDimAgilentControl24(
"AGILENT_CONTROL_24V"),
3240 fDimAgilentControl50(
"AGILENT_CONTROL_50V"),
3241 fDimAgilentControl80(
"AGILENT_CONTROL_80V"),
3242 fDimPwrControl (
"PWR_CONTROL"),
3243 fDimLidControl (
"LID_CONTROL"),
3244 fDimRateControl (
"RATE_CONTROL"),
3245 fDimRateScan (
"RATE_SCAN"),
3247 fDimSkypeClient (
"SKYPE_CLIENT")
3283 Subscribe(
"DIM_CONTROL/MESSAGE")
3286 Subscribe(
"MCP/CONFIGURATION")
3289 Subscribe(
"DRIVE_CONTROL/POINTING_POSITION")
3291 Subscribe(
"DRIVE_CONTROL/TRACKING_POSITION")
3293 Subscribe(
"DRIVE_CONTROL/SOURCE_POSITION")
3296 Subscribe(
"FSC_CONTROL/TEMPERATURE")
3298 Subscribe(
"FSC_CONTROL/HUMIDITY")
3300 Subscribe(
"FSC_CONTROL/BIAS_TEMP")
3303 Subscribe(
"PFMINI_CONTROL/DATA")
3306 Subscribe(
"GPS_CONTROL/NEMA")
3309 Subscribe(
"SQM_CONTROL/DATA")
3312 Subscribe(
"TEMPERATURE/DATA")
3315 Subscribe(
"AGILENT_CONTROL_24V/DATA")
3317 Subscribe(
"AGILENT_CONTROL_50V/DATA")
3319 Subscribe(
"AGILENT_CONTROL_80V/DATA")
3322 Subscribe(
"MAGIC_WEATHER/DATA")
3324 Subscribe(
"TNG_WEATHER/DUST")
3327 Subscribe(
"FEEDBACK/CALIBRATED_CURRENTS")
3330 Subscribe(
"BIAS_CONTROL/VOLTAGE")
3332 Subscribe(
"BIAS_CONTROL/CURRENT")
3335 Subscribe(
"FAD_CONTROL/CONNECTIONS")
3337 Subscribe(
"FAD_CONTROL/EVENTS")
3339 Subscribe(
"FAD_CONTROL/START_RUN")
3341 Subscribe(
"FAD_CONTROL/DRS_RUNS")
3343 Subscribe(
"FAD_CONTROL/EVENT_DATA")
3345 Subscribe(
"FAD_CONTROL/STATS")
3348 Subscribe(
"DATA_LOGGER/STATS")
3351 Subscribe(
"FTM_CONTROL/TRIGGER_RATES")
3353 Subscribe(
"FTM_CONTROL/STATIC_DATA")
3355 Subscribe(
"FTM_CONTROL/FTU_LIST")
3358 Subscribe(
"RATE_CONTROL/THRESHOLD")
3361 Subscribe(
"RATE_SCAN/DATA")
3364 Subscribe(
"CHAT/MESSAGE")
3371 AddStateName(kStateDimNetworkNA,
"DimNetworkNotAvailable",
3372 "The Dim DNS is not reachable.");
3374 AddStateName(kStateRunning,
"Running",
"");
3380 (
"Print a list of the states of all connected servers.");
3385 if (!fPixelMap.
Read(conf.
Get<
string>(
"pixel-map-file")))
3387 Error(
"Reading mapping table from "+conf.
Get<
string>(
"pixel-map-file")+
" failed.");
3391 fPath = conf.
Get<
string>(
"path");
3392 fDatabase = conf.
Get<
string>(
"source-database");
3395 if (stat(fPath.c_str(), &st))
3397 Error(fPath+
" does not exist!");
3401 if ((st.st_mode&S_IFDIR)==0)
3403 Error(fPath+
" not a directory!");
3407 if ((st.st_mode&S_IWUSR)==0)
3409 Error(fPath+
" has no write permission!");
3413 if ((st.st_mode&S_IXUSR)==0)
3415 Error(fPath+
" has no execute permission!");
3422 ofstream(fPath+
"/error.data") << out.str();
3437 StateMachineSmartFACT::fIsServer = !conf.
Get<
bool>(
"client");
3438 return Main::execute<T, StateMachineSmartFACT>(conf);
3443 po::options_description control(
"Smart FACT");
3444 control.add_options()
3445 (
"pixel-map-file", var<string>()->required(),
"Pixel mapping file. Used here to get the default reference voltage")
3446 (
"path", var<string>(
"www/smartfact/data"),
"Output path for the data-files")
3447 (
"source-database", var<string>(
""),
"Database link as in\n\tuser:password@server[:port]/database.")
3448 (
"client",
po_bool(
false),
"For a standalone client choose this option.")
3466 "SmartFACT is a tool writing the files needed for the SmartFACT web interface.\n" 3468 "The default is that the program is started without user intercation. " 3469 "All actions are supposed to arrive as DimCommands. Using the -c " 3470 "option, a local shell can be initialized. With h or help a short " 3471 "help message about the usuage can be brought to the screen.\n" 3473 "Usage: smartfact [-c type] [OPTIONS]\n" 3474 " or: smartfact [OPTIONS]\n";
3480 Main::PrintHelp<StateMachineSmartFACT>();
3500 int main(
int argc,
const char* argv[])
3510 if (!conf.
Has(
"console"))
3511 return RunShell<LocalStream>(conf);
3513 if (conf.
Get<
int>(
"console")==0)
3514 return RunShell<LocalShell>(conf);
3516 return RunShell<LocalConsole>(conf);
int HandleSqmData(const EventImp &d)
DimDescribedState fDimGpsControl
string GetTempColor(float t)
Time fMcpConfigurationRunStart
void WriteWeather(const EventImp &d, const string &name, int i, float min, float max)
DimDescribedState fDimPwrControl
DimDescribedState fDimPfMiniControl
int32_t fFtmControlTriggerRateTooLow
int HandlePfMiniData(const EventImp &d)
virtual State description() const
deque< float > fDriveControlTrackingDevHist
DimDescribedState fDimMagicWeather
virtual void Subscribe(StateMachineImp &imp)
int HandleStats(const EventImp &d)
static const string kYellow
uint64_t JavaDate() const
A general base-class describing events issues in a state machine.
int HandleFadConnections(const EventImp &d)
const char * GetText() const
deque< float > fFscControlTemperatureHist
deque< float > fTngWeatherDustHist
DimDescribedState fDimDriveControl
EquPosn GetLunarEquCoords(double jd, double precision=0)
void SetupConfiguration(Configuration &conf)
bool CheckDataSize(const EventImp &d, const char *name, size_t size, bool min=false)
int HandleDrivePointing(const EventImp &d)
Adds some functionality to boost::posix_time::ptime for our needs.
deque< float > fPfMiniHumidityHist
void SetPrintUsage(const std::function< void(void)> &func)
T Get(const std::string &var)
uint32_t NightAsInt() const
int HandleFscHumidity(const EventImp &d)
DimDescribedState fDimLidControl
deque< float > fBiasControlCurrentHist
void WriteHist(const EventImp &d, const string &fname, const T &t, double scale, double offset=0)
uint8_t fPing[40]
Address of FTU board.
float fFscControlHumidityAvg
int HandleGpsNema(const EventImp &d)
int main(int argc, const char *argv[])
uint16_t fMultiplicityPhysics
Intensity of LEDs (0-127)
const int32_t & state() const
int HandleFtmStaticData(const EventImp &d)
int HandleRateControlThreshold(const EventImp &d)
DimDescribedState fDimDataLogger
int HandleDriveControlStateChange(const EventImp &d)
EventHist fMcpConfigurationHist
DimDescribedState fDimMagicLidar
std::pair< Time, int32_t > last
int RunShell(Configuration &conf)
DimDescribedState fDimChat
double GetLunarDisk(double jd)
State description() const
FTM and FTUs are being reconfigured.
void add(const string &s, const Time &t=Time())
DimDescribedState fDimAgilentControl80
uint16_t fDelayTimeMarker
EventHist fControlAlarmHist
DimDescribedState fDimFeedback
std::string SecondsTo(const Time &=Time()) const
void WriteBinaryVec(const Time &tm, const string &fname, const vector< T > &vec, double scale, double offset=0, const string &title="", const string &col="")
std::string version() const
int32_t fFadControlDrsStep
bool fLastRunFinishedWithZeroEvents
DimDescribedState fDimMcp
DimDescribedState fDimSkypeClient
deque< float > fFtmControlTriggerRateHist
float fFtmBoardThresholdMed
int HandleDoTest(const EventImp &d)
string Header(const EventImp &d)
DimDescribedState fDimAgilentControl24
int HandleRateScanData(const EventImp &d)
vector< float > fBiasControlVoltageVec
DimDescribedState fDimTngWeather
int HandleDriveTracking(const EventImp &d)
int HandleMagicWeatherData(const EventImp &d)
int HandleDimControlMessage(const EventImp &d)
bool Has(const std::string &var)
DimDescribedState fDimAgilentControl50
float fBiasControlPowerTot
void AddOptions(const po::options_description &opt, bool visible=true)
void SetupConfiguration(Configuration &conf)
int HandleFadEvents(const EventImp &d)
string Header(const Time &d)
int HandleBiasCurrent(const EventImp &d)
string fDriveControlSourceName
void AddCallback(const std::string &script, const callback &cb)
int HandleTngWeatherDust(const EventImp &d)
string fDriveControlPointingAz
uint16_t fMultiplicity[40]
static const string kBlue
DimDescribedState fDimTimeCheck
string GetStateHtml(const DimState &state, int green) const
virtual Time GetTime() const
int HandleFadEventData(const EventImp &d)
static const string kWhite
void AddMcpConfigurationHist(const EventImp &d, const string &msg)
virtual int GetQoS() const
Nova::RstTime Rst(double jd, double hrz=LN_SOLAR_STANDART_HORIZON)
int HandleFeedbackCalibratedCurrents(const EventImp &d)
Warning because the service this data corrsponds to might have been last updated longer ago than Local time
int HandleChatMsg(const EventImp &d)
RstTime GetLunarRst(double jd, const LnLatPosn &obs=ORM())
string fMcpConfigurationName
int HandleFtmTriggerRates(const EventImp &d)
Commandline parsing, resource file parsing and database access.
EventElement(const Time &t, const string &s)
uint64_t GetJavaDate() const
bool SetError(bool b, const string &err)
uint16_t fTriggerInterval
int HandleFtmFtuList(const EventImp &d)
int32_t fControlScriptDepth
static const string kGreen
RstTime GetSolarRst(double jd, const LnLatPosn &obs, double hrz=LN_SOLAR_STANDART_HORIZON)
Statistics(const T &t, size_t offset_min=0, size_t offset_max=0)
int64_t fMcpConfigurationMaxEvents
DimDescribedState fDimRateScan
int HandleDriveSource(const EventImp &d)
float fDriveControlMoonDist
int HandleFscTemperature(const EventImp &d)
int Execute()
Is called continously to execute actions in the current state.
vector< uint32_t > fFadControlDrsRuns
void SetAudio(const string &name)
uint16_t fMultiplicityCalib
DimDescribedState fDimBiasControl
virtual void Subscribe(StateMachineImp &imp)
HrzPosn GetHrzFromEqu(const EquPosn &equ, const LnLatPosn &obs, double jd)
bool HasClockConditioner() const
deque< float > fRateControlThreshold
static string Color(double angle)
Class for a state machine implementation within a DIM network.
int HandleFadStartRun(const EventImp &d)
uint16_t fTriggerSeqLPint
A comment which is always printed.
Concerete implementation of an EventImp stroring name, format, data and time.
uint16_t fTriggerSeqLPext
const boost::posix_time::time_duration deltat
deque< float > fPfMiniTemperatureHist
Error, something unexpected happened, but needs user intervention (i.e. it needs a signal to the user...
float fDriveControlPointingZd
DimDescribedState fDimTemperature
int64_t fFadControlStartRun
DimDescribedState fDimSqmControl
Return to feeserver c CVS log Up to[MAIN] dcscvs FeeServer feeserver src Wed FeeServer_v0 v0 dev
float fFtmPatchThresholdMed
int64_t fMcpConfigurationMaxTime
int HandleMcpConfiguration(const EventImp &d)
string GetDir(const double angle)
int HandleControlStateChange(const EventImp &d)
double Angle(double r, double d) const
DimDescribedState fDimFtmControl
std::string MinutesTo(const Time &=Time()) const
int HandleFscControlStateChange(const EventImp &d)
po::typed_value< bool > * po_bool(bool def=false)
DimDescribedState fDimFadControl
deque< float > fTemperatureControlHist
EventHist(const boost::posix_time::time_duration &dt=boost::posix_time::hours(12), uint64_t mx=UINT64_MAX)
DimDescribedState fDimFscControl
int64_t fFadControlNumEvents
T Get(size_t offset=0) const
bool IsActive(int i) const
std::string GetAsStr(const char *fmt="%Y-%m-%d %H:%M:%S") const
float fBiasControlCurrentMed
float fBiasControlVoltageMed
bool Read(const std::string &fname)
DimDescribedState fDimRateControl
bool DoParse(int argc, const char **argv, const std::function< void()> &func=std::function< void()>())
const T & Ref(size_t offset=0) const
int HandleBiasVoltage(const EventImp &d)
float fBiasControlCurrentMax
StateMachineSmartFACT(ostream &out=cout)
void WriteCam(const EventImp &d, const string &fname, const T &t, double scale, double offset=0)
Do not initialize the time.
double PredictI(const Nova::SolarObjects &so, const Nova::EquPosn &srcEqu)
Trigger output enabled, configuration ignored.
void SetCallback(const callback &cb)
int HandleAgilentData(const EventImp &d, const string &ext)
EventHist fControlMessageHist
const T * Ptr(size_t offset=0) const
int HandleTemperatureData(const EventImp &d)
int EvalOptions(Configuration &conf)
int HandleFscBiasTemp(const EventImp &d)
int HandleFadDrsRuns(const EventImp &d)
int32_t fMcpConfigurationState
const PixelMapEntry & hv(int board, int channel) const
virtual size_t GetSize() const
void HandleControlMessageImp(const EventImp &d)