source: trunk/FACT++/src/smartfact.cc@ 13717

Last change on this file since 13717 was 13704, checked in by tbretz, 13 years ago
A fix for the color of the bias information; added colors to the current page; implemented fad connection stuff
File size: 44.5 KB
Line 
1#include "Dim.h"
2#include "Event.h"
3#include "Shell.h"
4#include "StateMachineDim.h"
5#include "Connection.h"
6#include "Configuration.h"
7#include "Console.h"
8#include "Converter.h"
9#include "DimServiceInfoList.h"
10#include "PixelMap.h"
11
12#include "tools.h"
13#include "DimData.h"
14
15#include "LocalControl.h"
16
17#include "HeadersFAD.h"
18#include "HeadersBIAS.h"
19#include "HeadersFTM.h"
20
21using namespace std;
22
23// ------------------------------------------------------------------------
24
25#include "DimDescriptionService.h"
26
27// ------------------------------------------------------------------------
28
29const static string kHtmlWhite = "#ffffff";
30const static string kHtmlYellow = "#fffff0";
31const static string kHtmlRed = "#fff8f0";
32const static string kHtmlGreen = "#f0fff0";
33const static string kHtmlBlue = "#f0f0ff";
34
35class StateMachineSmartFACT : public StateMachineDim, public DimInfoHandler
36{
37private:
38 enum states_t
39 {
40 kStateDimNetworkNA = 1,
41 kStateRunning,
42 };
43
44 // ------------------------- Internal variables -----------------------
45
46 PixelMap fPixelMap;
47
48 Time fLastUpdate;
49
50 string fPath;
51
52 // ----------------------------- Data storage -------------------------
53
54 uint32_t fMcpConfigurationState;
55 int64_t fMcpConfigurationMaxTime;
56 int64_t fMcpConfigurationMaxEvents;
57 string fMcpConfigurationName;
58 Time fMcpConfigurationRunStart;
59
60 enum weather_t { kWeatherBegin=0, kTemp = kWeatherBegin, kDew, kHum, kPress, kWind, kGusts, kDir, kWeatherEnd = kDir+1 };
61 deque<float> fMagicWeatherHist[kWeatherEnd];
62
63 vector<float> fFeedbackCalibration;
64
65 float fFeedbackTempOffset;
66 float fFeedbackUserOffset;
67
68 vector<float> fBiasControlVoltageVec;
69
70 float fBiasControlVoltageMed;
71 float fBiasControlCurrentMed;
72 float fBiasControlCurrentMax;
73
74 deque<float> fBiasControlCurrentHist;
75 deque<float> fFscControlTemperatureHist;
76
77 float fFscControlTemperatureAvg;
78 float fFscControlHumidityAvg;
79
80 float fDriveControlPointingZd;
81 string fDriveControlPointingAz;
82 float fDriveControlTrackingDev;
83 string fDriveControlSourceName;
84
85 int64_t fFadControlNumEvents;
86
87 float fFtmControlTriggerRateCam;
88 deque<float> fFtmControlTriggerRateHist;
89
90 vector<float> fFtmPatchThresholds;
91
92 uint64_t fRateScanDataId;
93 deque<float> fRateScanDataHist;
94
95 // ------------- Initialize variables before the Dim stuff ------------
96
97 DimServiceInfoList fNetwork;
98
99 class DimState : public DimInfoHandler
100 {
101 public:
102 DimState(const string &n, const string s="STATE") :
103 server(n), info(make_pair(Time(), -2)),
104 dim((n+"/"+s).c_str(), (void*)NULL, 0, this) { }
105
106 string server;
107 pair<Time, int> info;
108 string msg;
109
110 DimStampedInfo dim;
111
112 void infoHandler()
113 {
114 DimInfo *curr = getInfo(); // get current DimInfo address
115 if (!curr || curr != &dim)
116 return;
117
118 const bool disconnected = dim.getSize()==0;
119
120 // Make sure getTimestamp is called _before_ getTimestampMillisecs
121 const int tsec = dim.getTimestamp();
122 const int tms = dim.getTimestampMillisecs();
123
124 info = make_pair(Time(tsec, tms*1000),
125 disconnected ? -2 : dim.getQuality());
126
127 msg = disconnected ? "" : dim.getString();
128 }
129
130 const Time &time() const { return info.first; }
131 const int &state() const { return info.second; }
132
133 const string &name() const { return server; }
134 };
135
136 class DimVersion : public DimState
137 {
138 public:
139 DimVersion() : DimState("DIS_DNS", "VERSION_NUMBER") { }
140
141 void infoHandler()
142 {
143 DimInfo *curr = getInfo(); // get current DimInfo address
144 if (!curr || curr != &dim)
145 return;
146
147 DimState::infoHandler();
148
149 info.second = dim.getSize()==4 ? dim.getInt() : 0;
150 }
151
152 string version() const
153 {
154 if (info.second==0)
155 return "Offline";
156
157 ostringstream out;
158 out << "V" << info.second/100 << 'r' << info.second%100;
159 return out.str();
160 }
161 };
162
163
164 DimVersion fDim;
165 DimState fDimMcp;
166 DimState fDimControl;
167 DimState fDimDataLogger;
168 DimState fDimDriveControl;
169 DimState fDimMagicWeather;
170 DimState fDimFeedback;
171 DimState fDimBiasControl;
172 DimState fDimFtmControl;
173 DimState fDimFadControl;
174 DimState fDimFscControl;
175 DimState fDimRateControl;
176 DimState fDimRateScan;
177 DimState fDimChatServer;
178
179 DimStampedInfo fDimMcpConfiguration;
180
181 DimStampedInfo fDimDriveControlPointing;
182 DimStampedInfo fDimDriveControlTracking;
183 DimStampedInfo fDimDriveControlSource;
184
185 DimStampedInfo fDimFscControlTemperature;
186 DimStampedInfo fDimFscControlHumidity;
187
188 DimStampedInfo fDimMagicWeatherData;
189
190 DimStampedInfo fDimFeedbackDeviation;
191 DimStampedInfo fDimFeedbackCalibration;
192
193 DimStampedInfo fDimBiasControlVoltage;
194 DimStampedInfo fDimBiasControlCurrent;
195
196 DimStampedInfo fDimFadConnections;
197 DimStampedInfo fDimFadEvents;
198
199 DimStampedInfo fDimFtmControlTriggerRates;
200 DimStampedInfo fDimFtmControlStaticData;
201
202 DimStampedInfo fDimRateScanData;
203
204 DimStampedInfo *fDimFadControlEventData;
205
206 // -------------------------------------------------------------------
207
208 const State GetState(const DimState &s) const
209 {
210 return fNetwork.GetState(s.name(), s.state());
211 }
212
213 bool HandleService(DimInfo *curr, const DimInfo &service, void (StateMachineSmartFACT::*handle)(const DimData &))
214 {
215 if (curr!=&service)
216 return false;
217
218 (this->*handle)(DimData(curr));
219 return true;
220 }
221
222
223 bool CheckDataSize(const DimData &d, const char *name, size_t size, bool min=false)
224 {
225 if ((!min && d.data.size()==size) || (min && d.data.size()>size))
226 return true;
227
228 ostringstream msg;
229 msg << name << " - Received service has " << d.data.size() << " bytes, but expected ";
230 if (min)
231 msg << "more than ";
232 msg << size << ".";
233 Warn(msg);
234 return false;
235 }
236
237
238 // -------------------------------------------------------------------
239
240 template<class T>
241 void WriteBinary(const string &fname, const T &t, double scale, double offset=0)
242 {
243 vector<uint8_t> val(t.size(), 0);
244 for (uint64_t i=0; i<t.size(); i++)
245 {
246 float range = nearbyint(128*(t[i]-offset)/scale); // [-2V; 2V]
247 if (range>127)
248 range=127;
249 if (range<0)
250 range=0;
251 val[i] = (uint8_t)range;
252 }
253
254 const char *ptr = reinterpret_cast<char*>(val.data());
255
256 ofstream fout(fPath+"/"+fname+".bin");
257 fout << offset << '\n';
258 fout << offset+scale << '\n';
259 fout.write(ptr, val.size()*sizeof(uint8_t));
260 }
261
262 // -------------------------------------------------------------------
263
264 struct Statistics
265 {
266 float min;
267 float max;
268 float med;
269 float avg;
270 //float rms;
271
272 template<class T>
273 Statistics(const T &t, size_t offset_min=0, size_t offset_max=0)
274 : min(0), max(0), med(0), avg(0)
275 {
276 if (t.size()==0)
277 return;
278
279 T copy(t);
280 sort(copy.begin(), copy.end());
281
282 if (offset_min>t.size())
283 offset_min = 0;
284 if (offset_max>t.size())
285 offset_max = 0;
286
287 min = copy[offset_min];
288 max = copy[copy.size()-1-offset_max];
289 avg = accumulate (t.begin(), t.end(), 0.)/t.size();
290
291 const size_t p = t.size()/2;
292
293 med = copy[p];
294 }
295 };
296
297 void HandleMcpConfiguration(const DimData &d)
298 {
299 if (!CheckDataSize(d, "Mcp:Configuration", 16, true))
300 return;
301
302 fMcpConfigurationState = d.qos;
303 fMcpConfigurationMaxTime = d.get<uint64_t>();
304 fMcpConfigurationMaxEvents = d.get<uint64_t>(8);
305 fMcpConfigurationName = d.ptr<char>(16);
306
307 if (d.qos==12)
308 fMcpConfigurationRunStart = Time();
309 }
310
311 void WriteWeather(const DimData &d, const string &name, int i, float min, float max)
312 {
313 const Statistics stat(fMagicWeatherHist[i]);
314
315 ostringstream out;
316 out << setprecision(3);
317 out << d.time.JavaDate() << '\n';
318
319 out << "#ffffff\t" << fMagicWeatherHist[i].back() << '\n';
320 out << "#ffffff\t" << stat.min << '\n';
321 out << "#ffffff\t" << stat.avg << '\n';
322 out << "#ffffff\t" << stat.max << '\n';
323
324 ofstream(fPath+"/"+name+".txt") << out.str();
325
326 WriteBinary("magicweather-"+name+"-hist", fMagicWeatherHist[i], max-min, min);
327 }
328
329 void HandleMagicWeatherData(const DimData &d)
330 {
331 if (!CheckDataSize(d, "MagicWeather:Data", 7*4+2))
332 return;
333
334 // Store a history of the last 300 entries
335 for (int i=kWeatherBegin; i<kWeatherEnd; i++)
336 {
337 fMagicWeatherHist[i].push_back(d.ptr<float>(2)[i]);
338 if (fMagicWeatherHist[i].size()>300)
339 fMagicWeatherHist[i].pop_front();
340 }
341
342 static const char *dir[] =
343 {
344 "N", "NNE", "NE", "ENE",
345 "E", "ESE", "SE", "SSE",
346 "S", "SSW", "SW", "WSW",
347 "W", "WNW", "NW", "NNW"
348 };
349
350 const uint16_t idx = uint16_t(floor(fmod(fMagicWeatherHist[kDir].back()+360+11.25, 360)/22.5));
351
352 ostringstream out;
353 out << d.time.JavaDate() << '\n';
354 for (int i=0; i<6; i++)
355 out << "#ffffff\t" << fMagicWeatherHist[i].back() << '\n';
356 out << "#ffffff\t" << dir[idx] << '\n';
357
358
359 ofstream(fPath+"/magicweather.txt") << out.str();
360
361 WriteWeather(d, "temp", kTemp, -5, 35);
362 WriteWeather(d, "dew", kDew, -5, 35);
363 WriteWeather(d, "hum", kHum, 0, 100);
364 WriteWeather(d, "wind", kWind, 0, 100);
365 WriteWeather(d, "gusts", kGusts, 0, 100);
366 WriteWeather(d, "press", kPress, 700, 1000);
367 }
368
369 void HandleDriveControlPointing(const DimData &d)
370 {
371 if (!CheckDataSize(d, "DriveControl:Pointing", 16))
372 return;
373
374 fDriveControlPointingZd = d.get<double>();
375
376 const double az = d.get<double>(8);
377
378 static const char *dir[] =
379 {
380 "N", "NNE", "NE", "ENE",
381 "E", "ESE", "SE", "SSE",
382 "S", "SSW", "SW", "WSW",
383 "W", "WNW", "NW", "NNW"
384 };
385
386 const uint16_t i = uint16_t(floor(fmod(az+360+11.25, 360)/22.5));
387 fDriveControlPointingAz = dir[i];
388
389 ostringstream out;
390 out << d.time.JavaDate() << '\n';
391
392 out << setprecision(5);
393 out << fDriveControlPointingZd << '\n';
394 out << az << '\n';
395
396 ofstream(fPath+"/drive-pointing.txt") << out.str();
397 }
398
399 void HandleDriveControlTracking(const DimData &d)
400 {
401 if (!CheckDataSize(d, "DriveControl:Tracking", 56))
402 return;
403
404 const double zd = d.get<double>(3*8) * M_PI / 180;
405 const double dzd = d.get<double>(5*8) * M_PI / 180;
406 const double daz = d.get<double>(6*8) * M_PI / 180;
407
408 // Correct:
409 // const double d = cos(del) - sin(zd+dzd)*sin(zd)*(1.-cos(daz));
410
411 // Simplified:
412 const double dev = cos(dzd) - sin(zd+dzd)*sin(zd)*(1.-cos(daz));
413 fDriveControlTrackingDev = acos(dev) * 180 / M_PI * 3600;
414
415 if (fDriveControlTrackingDev<0.01)
416 fDriveControlTrackingDev=0;
417 }
418
419 void HandleDriveControlSource(const DimData &d)
420 {
421 if (!CheckDataSize(d, "DriveControl:Source", 7*4+2, true))
422 return;
423
424 const double *ptr = d.ptr<double>();
425
426 const double ra = ptr[0]; // Ra[h]
427 const double dec = ptr[1]; // Dec[deg]
428 const double woff = ptr[4]; // Wobble offset [deg]
429 const double wang = ptr[5]; // Wobble angle [deg]
430
431 fDriveControlSourceName = d.ptr<char>(6*8);
432
433 ostringstream out;
434 out << d.time.JavaDate() << '\n';
435
436 out << "#ffffff\t" << fDriveControlSourceName << '\n';
437 out << setprecision(5);
438 out << "#ffffff\t" << ra << '\n';
439 out << "#ffffff\t" << dec << '\n';
440 out << setprecision(3);
441 out << "#ffffff\t" << woff << '\n';
442 out << "#ffffff\t" << wang << '\n';
443
444 ofstream(fPath+"/drive.txt") << out.str();
445 }
446
447 void HandleFeedbackCalibration(const DimData &d)
448 {
449 if (!CheckDataSize(d, "Feedback:Calibration", 3*4*416))
450 {
451 fFeedbackCalibration.clear();
452 return;
453 }
454
455 const float *ptr = d.ptr<float>();
456 fFeedbackCalibration.assign(ptr+2*416, ptr+3*416);
457 }
458
459 void HandleFeedbackDeviation(const DimData &d)
460 {
461 if (!CheckDataSize(d, "Feedback:Deviation", 2*4*416+8))
462 return;
463
464 const float *ptr = d.ptr<float>();
465 vector<float> dev(ptr+416, ptr+416+320);
466
467 fFeedbackTempOffset = ptr[2*416];
468 fFeedbackUserOffset = ptr[2*416+1];
469
470 for (int i=0; i<320; i++)
471 dev[i] -= fFeedbackTempOffset+fFeedbackUserOffset;
472
473 // Write the 160 patch values to a file
474 WriteBinary("feedback-deviation", dev, 1);
475
476 const Statistics stat(dev, 3);
477
478 ostringstream out;
479 out << setprecision(3);
480 out << d.time.JavaDate() << '\n';
481 out << kHtmlWhite << '\t' << fFeedbackUserOffset << '\n';
482 out << kHtmlWhite << '\t' << fFeedbackTempOffset << '\n';
483 out << kHtmlWhite << '\t' << stat.min << '\n';
484 out << kHtmlWhite << '\t' << stat.med << '\n';
485 out << kHtmlWhite << '\t' << stat.avg << '\n';
486 out << kHtmlWhite << '\t' << stat.max << '\n';
487 ofstream(fPath+"/feedback.txt") << out.str();
488 }
489
490 void HandleBiasControlVoltage(const DimData &d)
491 {
492 if (!CheckDataSize(d, "BiasControl:Voltage", 1664))
493 {
494 fBiasControlVoltageVec.clear();
495 return;
496 }
497
498 fBiasControlVoltageVec.assign(d.ptr<float>(), d.ptr<float>()+320);
499
500 const Statistics stat(fBiasControlVoltageVec);
501
502 fBiasControlVoltageMed = stat.med;
503
504 vector<float> val(320, 0);
505 for (int i=0; i<320; i++)
506 {
507 const int idx = (fPixelMap.hv(i).hw()/9)*2+fPixelMap.hv(i).group();
508 val[idx] = fBiasControlVoltageVec[i];
509 }
510
511 if (fDimBiasControl.state()==BIAS::kVoltageOn)
512 WriteBinary("biascontrol-voltage", val, 10, 65);
513 else
514 WriteBinary("biascontrol-voltage", val, 75);
515
516 ostringstream out;
517 out << setprecision(3);
518 out << d.time.JavaDate() << '\n';
519 out << kHtmlWhite << '\t' << stat.min << '\n';
520 out << kHtmlWhite << '\t' << stat.med << '\n';
521 out << kHtmlWhite << '\t' << stat.avg << '\n';
522 out << kHtmlWhite << '\t' << stat.max << '\n';
523 ofstream(fPath+"/voltage.txt") << out.str();
524
525 }
526
527 void HandleBiasControlCurrent(const DimData &d)
528 {
529 if (!CheckDataSize(d, "BiasControl:Current", 832))
530 return;
531
532 // Convert dac counts to uA
533 vector<float> v(320);
534 for (int i=0; i<320; i++)
535 v[i] = d.ptr<uint16_t>()[i] * 5000./4096;
536
537 const bool cal = fFeedbackCalibration.size()>0 && fBiasControlVoltageVec.size()>0;
538
539 // Calibrate the data (subtract offset)
540 if (cal)
541 for (int i=0; i<320; i++)
542 {
543 v[i] -= fBiasControlVoltageVec[i]/fFeedbackCalibration[i]*1e6;
544 v[i] /= fPixelMap.hv(i).group() ? 5 : 4;
545 }
546
547 // Get the maximum of each patch
548 vector<float> val(320, 0);
549 for (int i=0; i<320; i++)
550 {
551 const int idx = (fPixelMap.hv(i).hw()/9)*2+fPixelMap.hv(i).group();
552 val[idx] = v[i];
553 }
554
555 // Write the 160 patch values to a file
556 WriteBinary("biascontrol-current", val, 100);
557
558 const Statistics stat(v, 0, 3);
559
560 // Exclude the three crazy channels
561 fBiasControlCurrentMed = stat.med;
562 fBiasControlCurrentMax = stat.max;
563
564 // Store a history of the last 60 entries
565 fBiasControlCurrentHist.push_back(fBiasControlCurrentMed);
566 if (fBiasControlCurrentHist.size()>360)
567 fBiasControlCurrentHist.pop_front();
568
569 // write the history to a file
570 WriteBinary("biascontrol-current-hist", fBiasControlCurrentHist, 100);
571
572 const string col0 = cal ? kHtmlGreen : kHtmlWhite;
573
574 string col1 = col0;
575 string col2 = col0;
576 string col3 = col0;
577 string col4 = col0;
578
579 if (cal && stat.min>65)
580 col1 = kYellow;
581 if (cal && stat.min>80)
582 col1 = kRed;
583
584 if (cal && stat.med>65)
585 col2 = kYellow;
586 if (cal && stat.med>80)
587 col2 = kRed;
588
589 if (cal && stat.avg>65)
590 col3 = kYellow;
591 if (cal && stat.avg>80)
592 col3 = kRed;
593
594 if (cal && stat.max>65)
595 col4 = kYellow;
596 if (cal && stat.max>80)
597 col4 = kRed;
598
599 ostringstream out;
600 out << setprecision(3);
601 out << d.time.JavaDate() << '\n';
602 out << col0 << '\t' << (cal?"yes":"no") << '\n';
603 out << col1 << '\t' << stat.min << '\n';
604 out << col2 << '\t' << stat.med << '\n';
605 out << col3 << '\t' << stat.avg << '\n';
606 out << col4 << '\t' << stat.max << '\n';
607 ofstream(fPath+"/current.txt") << out.str();
608 }
609
610 void HandleFadEvents(const DimData &d)
611 {
612 if (!CheckDataSize(d, "FadControl:Events", 4*4))
613 {
614 fFadControlNumEvents = -1;
615 return;
616 }
617
618 fFadControlNumEvents = d.get<uint32_t>();
619 }
620
621 void HandleFadConnections(const DimData &d)
622 {
623 if (!CheckDataSize(d, "FadControl:Connections", 41))
624 {
625 //fStatusEventBuilderLabel->setText("Offline");
626 return;
627 }
628
629 string rc(40, '-'); // orange/red [45]
630
631 const uint8_t *ptr = d.ptr<uint8_t>();
632
633 int c[4] = { '.', '.', '.', '.' };
634
635 for (int i=0; i<40; i++)
636 {
637 const uint8_t stat1 = ptr[i]&3;
638 const uint8_t stat2 = ptr[i]>>3;
639
640 if (stat1==0 && stat2==0)
641 rc[i] = '.'; // gray [46]
642 else
643 if (stat1>=2 && stat2==8)
644 rc[i] = stat1==2?'+':'*'; // green [43] : check [42]
645
646 if (rc[i]<c[i/10])
647 c[i/10] = rc[i];
648 }
649
650 string col[4];
651 for (int i=0; i<4; i++)
652 switch (c[i])
653 {
654 case '.': col[i]=kHtmlWhite; break;
655 case '-': col[i]=kHtmlRed; break;
656 case '+': col[i]=kHtmlYellow; break;
657 case '*': col[i]=kHtmlGreen; break;
658 }
659
660 ostringstream out;
661 out << setprecision(3);
662 out << d.time.JavaDate() << '\n';
663 out << col[0] << '\t' << rc.substr( 0, 10) << '\n';
664 out << col[1] << '\t' << rc.substr(10, 10) << '\n';
665 out << col[2] << '\t' << rc.substr(20, 10) << '\n';
666 out << col[3] << '\t' << rc.substr(30, 10) << '\n';
667 ofstream(fPath+"/fad.txt") << out.str();
668 }
669
670 void HandleFtmControlTriggerRates(const DimData &d)
671 {
672 if (!CheckDataSize(d, "FtmControl:TriggerRates", 24+160+640+8))
673 return;
674
675 // New run started
676 if (d.get<float>(20)<0)
677 return;
678
679 fFtmControlTriggerRateCam = d.get<float>(20);
680
681 const float *brates = d.ptr<float>(24); // Board rate
682 const float *prates = d.ptr<float>(24+160); // Patch rate
683
684 // Store a history of the last 60 entries
685 fFtmControlTriggerRateHist.push_back(fFtmControlTriggerRateCam);
686 if (fFtmControlTriggerRateHist.size()>60)
687 fFtmControlTriggerRateHist.pop_front();
688
689 // FIXME: Add statistics for all kind of rates
690
691 WriteBinary("ftmcontrol-triggerrate-hist",
692 fFtmControlTriggerRateHist, 100);
693 WriteBinary("ftmcontrol-boardrates",
694 vector<float>(brates, brates+40), 10);
695 WriteBinary("ftmcontrol-patchrates",
696 vector<float>(prates, prates+160), 10);
697
698 ostringstream out;
699 out << setprecision(3);
700 out << d.time.JavaDate() << '\n';
701 out << "#ffffff\t" << fFtmControlTriggerRateCam << '\n';
702
703 ofstream(fPath+"/trigger.txt") << out.str();
704
705 const Statistics bstat(vector<float>(brates, brates+40));
706 const Statistics pstat(vector<float>(prates, prates+160));
707
708 out.str("");
709 out << d.time.JavaDate() << '\n';
710 out << kHtmlWhite << '\t' << bstat.min << '\n';
711 out << kHtmlWhite << '\t' << bstat.med << '\n';
712 out << kHtmlWhite << '\t' << bstat.avg << '\n';
713 out << kHtmlWhite << '\t' << bstat.max << '\n';
714 ofstream(fPath+"/boardrates.txt") << out.str();
715
716 out.str("");
717 out << d.time.JavaDate() << '\n';
718 out << kHtmlWhite << '\t' << pstat.min << '\n';
719 out << kHtmlWhite << '\t' << pstat.med << '\n';
720 out << kHtmlWhite << '\t' << pstat.avg << '\n';
721 out << kHtmlWhite << '\t' << pstat.max << '\n';
722 ofstream(fPath+"/patchrates.txt") << out.str();
723 }
724
725 void HandleFtmControlStaticData(const DimData &d)
726 {
727 if (!CheckDataSize(d, "FtmControl:StaticData", 740))
728 return;
729
730 const uint16_t *ptr = d.ptr<uint16_t>(260);
731 vector<uint16_t> vec(ptr, ptr+160);
732
733 WriteBinary("ftmcontrol-thresholds", vec, 1000);
734
735 const Statistics stat(vec);
736
737 ostringstream out;
738 out << d.time.JavaDate() << '\n';
739 out << kHtmlWhite << '\t' << stat.min << '\n';
740 out << kHtmlWhite << '\t' << stat.med << '\n';
741 out << kHtmlWhite << '\t' << stat.avg << '\n';
742 out << kHtmlWhite << '\t' << stat.max << '\n';
743 ofstream(fPath+"/thresholds.txt") << out.str();
744 }
745
746 void HandleFadControlEventData(const DimData &d)
747 {
748 if (!CheckDataSize(d, "FadControl:EventData", 23040))
749 return;
750
751 //const float *avg = d.ptr<float>();
752 //const float *rms = d.ptr<float>(1440*sizeof(float));
753 const float *dat = d.ptr<float>(1440*sizeof(float)*2);
754 //const float *pos = d.ptr<float>(1440*sizeof(float)*3);
755
756 vector<float> max(320, -2);
757 for (int i=0; i<1440; i++)
758 {
759 if (i%9==8)
760 continue;
761
762 const int idx = (fPixelMap.hw(i).hw()/9)*2+fPixelMap.hw(i).group();
763 const double v = dat[i]/1000;
764 if (v>max[idx])
765 max[idx]=v;
766 }
767
768 switch (d.qos)
769 {
770 case 0: WriteBinary("fadcontrol-eventdata", max, 2, -1); break;
771 case 1: WriteBinary("fadcontrol-eventdata", max, 2, 0); break;
772 default: WriteBinary("fadcontrol-eventdata", max, 0.25, 0); break;
773 }
774 }
775
776 void HandleFscControlTemperature(const DimData &d)
777 {
778 if (!CheckDataSize(d, "FscControl:Temperature", 240))
779 return;
780
781 const float *ptr = d.ptr<float>(4);
782
783 double avg = 0;
784 double rms = 0;
785 double min = 99;
786 double max = -99;
787
788 int num = 0;
789 for (const float *t=ptr; t<ptr+31; t++)
790 {
791 if (*t==0)
792 continue;
793
794 if (*t>max)
795 max = *t;
796
797 if (*t<min)
798 min = *t;
799
800 avg += *t;
801 rms += *t * *t;
802
803 num++;
804 }
805
806 avg /= num;
807 rms = sqrt(rms/num-avg*avg);
808
809 fFscControlTemperatureAvg = avg;
810
811 fFscControlTemperatureHist.push_back(avg);
812 if (fFscControlTemperatureHist.size()>300)
813 fFscControlTemperatureHist.pop_front();
814
815 const Statistics stat(fFscControlTemperatureHist);
816
817 ostringstream out;
818 out << setprecision(3);
819 out << d.time.JavaDate() << '\n';
820 out << "#ffffff\t" << min << '\n';
821 out << "#ffffff\t" << avg << '\n';
822 out << "#ffffff\t" << max << '\n';
823 out << "#ffffff\t" << stat.min << '\n';
824 out << "#ffffff\t" << stat.avg << '\n';
825 out << "#ffffff\t" << stat.max << '\n';
826
827 ofstream(fPath+"/fsc.txt") << out.str();
828
829 WriteBinary("fsccontrol-temperature-hist",
830 fFscControlTemperatureHist, 30);
831 }
832
833 void HandleFscControlHumidity(const DimData &d)
834 {
835 if (!CheckDataSize(d, "FscControl:Humidity", 5*4))
836 return;
837
838 const float *ptr = d.ptr<float>(4);
839
840 double avg = 0;
841 int num = 0;
842
843 for (const float *t=ptr; t<ptr+4; t++)
844 if (*t>0)
845 {
846 avg += *t;
847 num++;
848 }
849
850 fFscControlHumidityAvg = avg/num;
851 }
852
853 void HandleRateScanData(const DimData &d)
854 {
855 if (!CheckDataSize(d, "RateScan:Data", 24+200*40))
856 return;
857
858 const uint64_t id = d.get<uint64_t>();
859 const float rate = log10(d.get<float>(20));
860
861 if (fRateScanDataId!=id)
862 {
863 fRateScanDataHist.clear();
864 fRateScanDataId = id;
865 }
866 fRateScanDataHist.push_back(rate);
867
868 WriteBinary("ratescan-hist", fRateScanDataHist, 10, -1);
869 }
870
871 // -------------------------------------------------------------------
872
873 void infoHandler()
874 {
875 DimInfo *curr = getInfo(); // get current DimInfo address
876 if (!curr)
877 return;
878
879 if (HandleService(curr, fDimMcpConfiguration, &StateMachineSmartFACT::HandleMcpConfiguration))
880 return;
881 if (HandleService(curr, fDimMagicWeatherData, &StateMachineSmartFACT::HandleMagicWeatherData))
882 return;
883 if (HandleService(curr, fDimDriveControlPointing, &StateMachineSmartFACT::HandleDriveControlPointing))
884 return;
885 if (HandleService(curr, fDimDriveControlTracking, &StateMachineSmartFACT::HandleDriveControlTracking))
886 return;
887 if (HandleService(curr, fDimDriveControlSource, &StateMachineSmartFACT::HandleDriveControlSource))
888 return;
889 if (HandleService(curr, fDimFeedbackDeviation, &StateMachineSmartFACT::HandleFeedbackDeviation))
890 return;
891 if (HandleService(curr, fDimFeedbackCalibration, &StateMachineSmartFACT::HandleFeedbackCalibration))
892 return;
893 if (HandleService(curr, fDimBiasControlVoltage, &StateMachineSmartFACT::HandleBiasControlVoltage))
894 return;
895 if (HandleService(curr, fDimBiasControlCurrent, &StateMachineSmartFACT::HandleBiasControlCurrent))
896 return;
897 if (HandleService(curr, fDimFadConnections, &StateMachineSmartFACT::HandleFadConnections))
898 return;
899 if (HandleService(curr, fDimFadEvents, &StateMachineSmartFACT::HandleFadEvents))
900 return;
901 if (HandleService(curr, fDimFtmControlTriggerRates, &StateMachineSmartFACT::HandleFtmControlTriggerRates))
902 return;
903 if (HandleService(curr, fDimFtmControlStaticData, &StateMachineSmartFACT::HandleFtmControlStaticData))
904 return;
905 if (HandleService(curr, *fDimFadControlEventData, &StateMachineSmartFACT::HandleFadControlEventData))
906 return;
907 if (HandleService(curr, fDimFscControlTemperature, &StateMachineSmartFACT::HandleFscControlTemperature))
908 return;
909 if (HandleService(curr, fDimFscControlHumidity, &StateMachineSmartFACT::HandleFscControlHumidity))
910 return;
911 if (HandleService(curr, fDimRateScanData, &StateMachineSmartFACT::HandleRateScanData))
912 return;
913 }
914
915 bool CheckEventSize(size_t has, const char *name, size_t size)
916 {
917 if (has==size)
918 return true;
919
920 ostringstream msg;
921 msg << name << " - Received event has " << has << " bytes, but expected " << size << ".";
922 Fatal(msg);
923 return false;
924 }
925
926 void PrintState(const DimState &state) const
927 {
928 const State rc = GetState(state);
929
930 Out() << state.time().GetAsStr("%H:%M:%S.%f").substr(0, 12) << " - ";
931 Out() << kBold << state.name() << ": ";
932 if (rc.index==-2)
933 {
934 Out() << kReset << "Offline" << endl;
935 return;
936 }
937 Out() << rc.name << "[" << rc.index << "]";
938 Out() << kReset << " - " << kBlue << rc.comment << endl;
939 }
940
941 int Print() const
942 {
943 Out() << fDim.time().GetAsStr("%H:%M:%S.%f").substr(0, 12) << " - ";
944 Out() << kBold << "DIM_DNS: " << fDim.version() << endl;
945
946 PrintState(fDimMcp);
947 PrintState(fDimControl);
948 PrintState(fDimDataLogger);
949 PrintState(fDimDriveControl);
950 PrintState(fDimFadControl);
951 PrintState(fDimFtmControl);
952 PrintState(fDimBiasControl);
953 PrintState(fDimFeedback);
954 PrintState(fDimRateControl);
955 PrintState(fDimFscControl);
956 PrintState(fDimMagicWeather);
957 PrintState(fDimRateScan);
958 PrintState(fDimChatServer);
959
960 return GetCurrentState();
961 }
962
963 string GetStateHtml(const DimState &state, int green) const
964 {
965 const State rc = GetState(state);
966
967 if (rc.index==-2 && state.state()>-2)
968 {
969 ostringstream out;
970 out << kWhite << '\t' << state.state() << '\n';
971 return out.str();
972 }
973
974 //ostringstream msg;
975 //msg << kHtmlWhite << '\t' << rc.name << " [" << rc.index << "]\n";
976 //return msg.str();
977
978 if (rc.index<1)
979 return kHtmlWhite + "\t---\n";
980
981
982 return (rc.index<green?kHtmlYellow:kHtmlGreen) + '\t' + rc.name + '\n';
983 }
984
985 int Execute()
986 {
987 // Dispatch (execute) at most one handler from the queue. In contrary
988 // to run_one(), it doesn't wait until a handler is available
989 // which can be dispatched, so poll_one() might return with 0
990 // handlers dispatched. The handlers are always dispatched/executed
991 // synchronously, i.e. within the call to poll_one()
992 //poll_one();
993
994 if (fDim.state()==0)
995 return kStateDimNetworkNA;
996
997 Time now;
998 if (now-fLastUpdate<boost::posix_time::seconds(1))
999 return kStateRunning;
1000
1001 fLastUpdate=now;
1002
1003 ostringstream out;
1004 out << now.JavaDate() << '\n';
1005 out << setprecision(3);
1006
1007 // -------------- System status --------------
1008 if (fDimMcp.state()>=5) // Idle
1009 {
1010 string col = kHtmlBlue;
1011 if (fMcpConfigurationState!= 5 &&
1012 fMcpConfigurationState!=11 &&
1013 fMcpConfigurationState!=12) // 9 e.g. Configuring3
1014 col = kHtmlYellow;
1015 else
1016 if (fDimFadControl.state()==FAD::kWritingData)
1017 col = kHtmlGreen;
1018
1019 out << col << '\t' << fMcpConfigurationName;
1020
1021 if (fMcpConfigurationMaxEvents>0 || fMcpConfigurationMaxTime>0 || fMcpConfigurationState==12)
1022 out << " [";
1023 if (fMcpConfigurationMaxEvents>0)
1024 {
1025 if (fFadControlNumEvents>0 && fMcpConfigurationState==12)
1026 out << fMcpConfigurationMaxEvents-fFadControlNumEvents;
1027 else
1028 out << fMcpConfigurationMaxEvents;
1029 }
1030 if (fMcpConfigurationMaxEvents>0 && (fMcpConfigurationMaxTime>0 || fMcpConfigurationState==12))
1031 out << '/';
1032 if (fMcpConfigurationMaxTime>0)
1033 {
1034 if (fMcpConfigurationState==12)
1035 {
1036
1037 const uint32_t dt = (Time()-fMcpConfigurationRunStart).total_seconds();
1038 if (dt>fMcpConfigurationMaxTime)
1039 out << "---";
1040 else
1041 out << fMcpConfigurationMaxTime-dt << 's';
1042 }
1043 else
1044 out << fMcpConfigurationMaxTime << 's';
1045 }
1046 else
1047 {
1048 if (fMcpConfigurationState==12)
1049 {
1050 ostringstream d;
1051 d << Time()-fMcpConfigurationRunStart;
1052 out << d.str().substr(3, 5);
1053 }
1054 }
1055
1056 if (fMcpConfigurationMaxEvents>0 || fMcpConfigurationMaxTime>0 || fMcpConfigurationState==12)
1057 out << ']';
1058 }
1059 else
1060 out << kHtmlWhite;
1061 out << '\n';
1062
1063 // ------------------ Drive -----------------
1064 if (fDimDriveControl.state()>=5) // Armed, Moving, Tracking
1065 {
1066 const State rc = GetState(fDimDriveControl);
1067 string col = kHtmlGreen;
1068 if (rc.index==6) // Moving
1069 col = kHtmlBlue;
1070 if (rc.index==5) // Armed
1071 col = kHtmlWhite;
1072 out << col << '\t';
1073 out << rc.name << '\t';
1074 out << fDriveControlPointingZd << '\t';
1075 out << fDriveControlPointingAz << '\t';
1076 if (fDimDriveControl.state()==7)
1077 {
1078 out << setprecision(2);
1079 out << fDriveControlTrackingDev << '\t';
1080 out << setprecision(3);
1081 out << fDriveControlSourceName << '\n';
1082 }
1083 else
1084 out << "\t\n";
1085 }
1086 else
1087 out << kHtmlWhite << '\n';
1088
1089 // ------------------- FSC ------------------
1090 if (fDimFscControl.state()>1)
1091 {
1092 out << kHtmlGreen << '\t' << fFscControlTemperatureAvg << '\n';
1093 }
1094 else
1095 out << kHtmlWhite << '\n';
1096
1097 // --------------- MagicWeather -------------
1098 if (fDimMagicWeather.state()==3 && fMagicWeatherHist[kWeatherBegin].size()>0)
1099 {
1100 /*
1101 const float diff = fMagicWeatherHist[kTemp].back()-fMagicWeatherHist[kDew].back();
1102 string col1 = kHtmlRed;
1103 if (diff>0.3)
1104 col1 = kHtmlYellow;
1105 if (diff>0.7)
1106 col1 = kHtmlGreen;
1107 */
1108
1109 const float wind = fMagicWeatherHist[kGusts].back();
1110 const float hum = fMagicWeatherHist[kHum].back();
1111 string col = kHtmlGreen;
1112 if (wind>35 || hum>95)
1113 col = kHtmlYellow;
1114 if (wind>50 || hum>98)
1115 col = kHtmlRed;
1116
1117 out << col << '\t';
1118 out << fMagicWeatherHist[kHum].back() << '\t';
1119 out << fMagicWeatherHist[kGusts].back() << '\n';
1120 }
1121 else
1122 out << kHtmlWhite << "\n";
1123
1124 // --------------- FtmControl -------------
1125 if (fDimFtmControl.state()>=FTM::kIdle)
1126 {
1127 string col = kHtmlGreen;
1128 if (fFtmControlTriggerRateCam<15)
1129 col = kHtmlYellow;
1130 if (fFtmControlTriggerRateCam>100)
1131 col = kHtmlRed;
1132
1133 out << col << '\t' << fFtmControlTriggerRateCam << '\n';
1134 }
1135 else
1136 out << kHtmlWhite << '\n';
1137
1138 // --------------- BiasControl -------------
1139 if (fDimBiasControl.state()==BIAS::kRamping ||
1140 fDimBiasControl.state()==BIAS::kOverCurrent ||
1141 fDimBiasControl.state()==BIAS::kVoltageOn ||
1142 fDimBiasControl.state()==BIAS::kVoltageOff)
1143 {
1144 string col = fBiasControlVoltageMed>3?kHtmlGreen:kHtmlWhite;
1145 if (fBiasControlCurrentMax>65)
1146 col = kHtmlYellow;
1147 if (fBiasControlCurrentMax>80)
1148 col = kHtmlRed;
1149
1150 // Bias in overcurrent => Red
1151 if (fDimBiasControl.state()==BIAS::kOverCurrent)
1152 col = kHtmlRed;
1153
1154 // MCP in ReadyForDatataking/Configuring/Configured/TriggerOn/TakingData
1155 // and Bias not in "data-taking state' => Red
1156 if (fDimMcp.state()>5 &&
1157 fDimBiasControl.state()!=BIAS::kVoltageOn &&
1158 fDimBiasControl.state()!=BIAS::kVoltageOff)
1159 col = kHtmlRed;
1160
1161 const bool cal = fFeedbackCalibration.size();
1162
1163 // Feedback is currently calibrating => Blue
1164 if (fDimFeedback.state()==13)
1165 {
1166 out << kHtmlBlue << '\t';
1167 out << "***\t";
1168 out << "***\t";
1169 }
1170 else
1171 {
1172 out << col << '\t';
1173 out << fBiasControlCurrentMed << '\t';
1174 if (cal)
1175 out << fBiasControlCurrentMax;
1176 else
1177 out << "&mdash; ";
1178 out << '\t';
1179 }
1180 out << fBiasControlVoltageMed << '\n';
1181 }
1182 else
1183 out << kHtmlWhite << '\n';
1184
1185
1186 // ------------------------------------------
1187
1188 ofstream(fPath+"/fact.txt") << out.str();
1189
1190 // ==========================================
1191
1192 out.str("");
1193 out << now.JavaDate() << '\n';
1194
1195 if (fDim.state()==0)
1196 out << kHtmlWhite << "\tOffline\n\n\n\n\n\n\n\n\n\n\n\n";
1197 else
1198 {
1199 out << kHtmlGreen << '\t' << fDim.version() << '\n';
1200
1201 out << GetStateHtml(fDimMcp, 4);
1202 out << kHtmlWhite << '\t' << (fDimControl.state()>-2?fDimControl.msg:"---") << "\n";
1203 out << GetStateHtml(fDimDataLogger, 1);
1204 out << GetStateHtml(fDimDriveControl, 2);
1205 out << GetStateHtml(fDimFadControl, FAD::kConnected);
1206 out << GetStateHtml(fDimFtmControl, FTM::kConnected);
1207 out << GetStateHtml(fDimBiasControl, BIAS::kConnected);
1208 out << GetStateHtml(fDimFeedback, 4);
1209 out << GetStateHtml(fDimRateControl, 4);
1210 out << GetStateHtml(fDimFscControl, 2);
1211 out << GetStateHtml(fDimMagicWeather, 2);
1212 out << GetStateHtml(fDimRateScan, 4);
1213 out << GetStateHtml(fDimChatServer, 1);
1214 }
1215
1216 ofstream(fPath+"/status.txt") << out.str();
1217
1218 return kStateRunning;
1219 }
1220
1221public:
1222 StateMachineSmartFACT(ostream &out=cout) : StateMachineDim(out, "SMART_FACT"),
1223 fPath("www/smartfact/data"),
1224 fMcpConfigurationMaxTime(0),
1225 fMcpConfigurationMaxEvents(0),
1226 fRateScanDataId(0),
1227 //---
1228 fDimMcp ("MCP"),
1229 fDimControl ("DIM_CONTROL"),
1230 fDimDataLogger ("DATA_LOGGER"),
1231 fDimDriveControl ("DRIVE_CONTROL"),
1232 fDimMagicWeather ("MAGIC_WEATHER"),
1233 fDimFeedback ("FEEDBACK"),
1234 fDimBiasControl ("BIAS_CONTROL"),
1235 fDimFtmControl ("FTM_CONTROL"),
1236 fDimFadControl ("FAD_CONTROL"),
1237 fDimFscControl ("FSC_CONTROL"),
1238 fDimRateControl ("RATE_CONTROL"),
1239 fDimRateScan ("RATE_SCAN"),
1240 fDimChatServer ("CHAT_SERVER"),
1241 //---
1242 fDimMcpConfiguration ("MCP/CONFIGURATION", (void*)NULL, 0, this),
1243 //---
1244 fDimDriveControlPointing ("DRIVE_CONTROL/POINTING_POSITION", (void*)NULL, 0, this),
1245 fDimDriveControlTracking ("DRIVE_CONTROL/TRACKING_POSITION", (void*)NULL, 0, this),
1246 fDimDriveControlSource ("DRIVE_CONTROL/SOURCE_POSITION", (void*)NULL, 0, this),
1247 //---
1248 fDimFscControlTemperature ("FSC_CONTROL/TEMPERATURE", (void*)NULL, 0, this),
1249 fDimFscControlHumidity ("FSC_CONTROL/HUMIDITY", (void*)NULL, 0, this),
1250 //---
1251 fDimMagicWeatherData ("MAGIC_WEATHER/DATA", (void*)NULL, 0, this),
1252 //---
1253 fDimFeedbackDeviation ("FEEDBACK/DEVIATION", (void*)NULL, 0, this),
1254 fDimFeedbackCalibration ("FEEDBACK/CALIBRATION", (void*)NULL, 0, this),
1255 //---
1256 fDimBiasControlVoltage ("BIAS_CONTROL/VOLTAGE", (void*)NULL, 0, this),
1257 fDimBiasControlCurrent ("BIAS_CONTROL/CURRENT", (void*)NULL, 0, this),
1258 //---
1259 fDimFadConnections ("FAD_CONTROL/CONNECTIONS", (void*)NULL, 0, this),
1260 fDimFadEvents ("FAD_CONTROL/EVENTS", (void*)NULL, 0, this),
1261 //---
1262 fDimFtmControlTriggerRates("FTM_CONTROL/TRIGGER_RATES", (void*)NULL, 0, this),
1263 fDimFtmControlStaticData ("FTM_CONTROL/STATIC_DATA", (void*)NULL, 0, this),
1264 //-
1265 fDimRateScanData ("RATE_SCAN/DATA", (void*)NULL, 0, this),
1266 //-
1267 fDimFadControlEventData(0)
1268 {
1269 // State names
1270 AddStateName(kStateDimNetworkNA, "DimNetworkNotAvailable",
1271 "The Dim DNS is not reachable.");
1272
1273 AddStateName(kStateRunning, "Running", "");
1274
1275 // Verbosity commands
1276// AddEvent("SET_VERBOSE", "B:1")
1277// (bind(&StateMachineMCP::SetVerbosity, this, placeholders::_1))
1278// ("set verbosity state"
1279// "|verbosity[bool]:disable or enable verbosity for received data (yes/no), except dynamic data");
1280
1281 AddEvent("PRINT")
1282 (bind(&StateMachineSmartFACT::Print, this))
1283 ("");
1284 }
1285 ~StateMachineSmartFACT()
1286 {
1287 delete fDimFadControlEventData;
1288 }
1289 int EvalOptions(Configuration &conf)
1290 {
1291 if (!fPixelMap.Read(conf.Get<string>("pixel-map-file")))
1292 {
1293 Error("Reading mapping table from "+conf.Get<string>("pixel-map-file")+" failed.");
1294 return 1;
1295 }
1296
1297 // First move all the dim services to another class so that
1298 // they can be instatiated all at once _after_ path was set
1299 //fPath = conf.Get<string>("path");
1300
1301 // Pixel map is needed to deal with this service
1302 fDimFadControlEventData=new DimStampedInfo("FAD_CONTROL/EVENT_DATA", (void*)NULL, 0, this);
1303
1304 return -1;
1305 }
1306};
1307
1308// ------------------------------------------------------------------------
1309
1310#include "Main.h"
1311
1312template<class T>
1313int RunShell(Configuration &conf)
1314{
1315 return Main::execute<T, StateMachineSmartFACT>(conf);
1316}
1317
1318void SetupConfiguration(Configuration &conf)
1319{
1320 po::options_description control("Smart FACT");
1321 control.add_options()
1322 ("pixel-map-file", var<string>("FACTmapV5a.txt"), "Pixel mapping file. Used here to get the default reference voltage")
1323 ("path", var<string>("www/smartfact/data"), "Output path for the data-files")
1324 ;
1325
1326 conf.AddOptions(control);
1327}
1328
1329/*
1330 Extract usage clause(s) [if any] for SYNOPSIS.
1331 Translators: "Usage" and "or" here are patterns (regular expressions) which
1332 are used to match the usage synopsis in program output. An example from cp
1333 (GNU coreutils) which contains both strings:
1334 Usage: cp [OPTION]... [-T] SOURCE DEST
1335 or: cp [OPTION]... SOURCE... DIRECTORY
1336 or: cp [OPTION]... -t DIRECTORY SOURCE...
1337 */
1338void PrintUsage()
1339{
1340 cout <<
1341 "SmartFACT is a tool writing the files needed for the SmartFACT web interface.\n"
1342 "\n"
1343 "The default is that the program is started without user intercation. "
1344 "All actions are supposed to arrive as DimCommands. Using the -c "
1345 "option, a local shell can be initialized. With h or help a short "
1346 "help message about the usuage can be brought to the screen.\n"
1347 "\n"
1348 "Usage: smartfact [-c type] [OPTIONS]\n"
1349 " or: smartfact [OPTIONS]\n";
1350 cout << endl;
1351}
1352
1353void PrintHelp()
1354{
1355 Main::PrintHelp<StateMachineSmartFACT>();
1356
1357 /* Additional help text which is printed after the configuration
1358 options goes here */
1359
1360 /*
1361 cout << "bla bla bla" << endl << endl;
1362 cout << endl;
1363 cout << "Environment:" << endl;
1364 cout << "environment" << endl;
1365 cout << endl;
1366 cout << "Examples:" << endl;
1367 cout << "test exam" << endl;
1368 cout << endl;
1369 cout << "Files:" << endl;
1370 cout << "files" << endl;
1371 cout << endl;
1372 */
1373}
1374
1375int main(int argc, const char* argv[])
1376{
1377 Configuration conf(argv[0]);
1378 conf.SetPrintUsage(PrintUsage);
1379 Main::SetupConfiguration(conf);
1380 SetupConfiguration(conf);
1381
1382 if (!conf.DoParse(argc, argv, PrintHelp))
1383 return -1;
1384
1385 //try
1386 {
1387 // No console access at all
1388 if (!conf.Has("console"))
1389 {
1390// if (conf.Get<bool>("no-dim"))
1391// return RunShell<LocalStream, StateMachine, ConnectionFSC>(conf);
1392// else
1393 return RunShell<LocalStream>(conf);
1394 }
1395 // Cosole access w/ and w/o Dim
1396/* if (conf.Get<bool>("no-dim"))
1397 {
1398 if (conf.Get<int>("console")==0)
1399 return RunShell<LocalShell, StateMachine, ConnectionFSC>(conf);
1400 else
1401 return RunShell<LocalConsole, StateMachine, ConnectionFSC>(conf);
1402 }
1403 else
1404*/ {
1405 if (conf.Get<int>("console")==0)
1406 return RunShell<LocalShell>(conf);
1407 else
1408 return RunShell<LocalConsole>(conf);
1409 }
1410 }
1411 /*catch (std::exception& e)
1412 {
1413 cerr << "Exception: " << e.what() << endl;
1414 return -1;
1415 }*/
1416
1417 return 0;
1418}
Note: See TracBrowser for help on using the repository browser.