source: trunk/FACT++/src/fscctrl.cc@ 14098

Last change on this file since 14098 was 14013, checked in by tbretz, 12 years ago
Set the verbosity to quiet per default.
File size: 26.6 KB
Line 
1#include <functional>
2
3#include "Dim.h"
4#include "Event.h"
5#include "Shell.h"
6#include "StateMachineDim.h"
7#include "Connection.h"
8#include "LocalControl.h"
9#include "Configuration.h"
10#include "Console.h"
11#include "Converter.h"
12
13#include "tools.h"
14
15#include "HeadersFSC.h"
16
17namespace ba = boost::asio;
18namespace bs = boost::system;
19namespace dummy = ba::placeholders;
20
21using namespace std;
22using namespace FSC;
23
24// ------------------------------------------------------------------------
25
26class ConnectionFSC : public Connection
27{
28 boost::asio::streambuf fBuffer;
29
30 bool fIsVerbose;
31 bool fDump;
32
33 ofstream fDumpStream;
34
35protected:
36
37 virtual void UpdateTemp(float, const vector<float> &)
38 {
39 }
40
41 virtual void UpdateHum(float, const vector<float>&)
42 {
43 }
44
45 virtual void UpdateVolt(float, const vector<float>&)
46 {
47 }
48
49 virtual void UpdateCur(float, const vector<float>&)
50 {
51 }
52
53 /*
54 virtual void UpdateError()
55 {
56 if (!fIsVerbose)
57 return;
58
59 Out() << endl << kRed << "Error received:" << endl;
60 Out() << fError;
61 if (fIsHexOutput)
62 Out() << Converter::GetHex<uint16_t>(fError, 16) << endl;
63 }
64*/
65
66 void Dump(const string &str)
67 {
68 if (!fDumpStream.is_open())
69 {
70 fDumpStream.open("socket_dump-fsc.txt", ios::app);
71 if (!fDumpStream)
72 {
73 //ostringstream str;
74 //str << "Open file " << name << ": " << strerror(errno) << " (errno=" << errno << ")";
75 //Error(str);
76
77 return;
78 }
79 }
80
81 fDumpStream << str << endl;
82 }
83
84private:
85 //
86 // From: http://de.wikipedia.org/wiki/Pt100
87 //
88 double GetTempPT1000(double R) const
89 {
90 const double R0 = 1000; // 1kOhm
91
92 const double a = 3.85e-3;
93
94 return (R/R0 - 1)/a;
95 }
96
97
98 void HandleReceivedData(const bs::error_code& err, size_t bytes_received, int /*type*/)
99 {
100 // Do not schedule a new read if the connection failed.
101 if (bytes_received==0 || err)
102 {
103 if (err==ba::error::eof)
104 Warn("Connection closed by remote host (FTM).");
105
106 // 107: Transport endpoint is not connected (bs::error_code(107, bs::system_category))
107 // 125: Operation canceled
108 if (err && err!=ba::error::eof && // Connection closed by remote host
109 err!=ba::error::basic_errors::not_connected && // Connection closed by remote host
110 err!=ba::error::basic_errors::operation_aborted) // Connection closed by us
111 {
112 ostringstream str;
113 str << "Reading from " << URL() << ": " << err.message() << " (" << err << ")";// << endl;
114 Error(str);
115 }
116 PostClose(err!=ba::error::basic_errors::operation_aborted);
117 return;
118 }
119
120 if (fIsVerbose)
121 Out() << kBold << "Received (" << bytes_received << " bytes):" << endl;
122
123 /*
124 "status: 00000538 \n"
125 "time_s: 764.755 \n"
126 "VOLTAGES \n"
127 " \n"
128 "enable:11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 00001111 \n"
129 " done:11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 00001111 \n"
130 "values:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 \n"
131 "RESISTANCES \n"
132 " \n"
133 "enable:11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 \n"
134 " done:11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 \n"
135 "values: \n"
136 "1000.16 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
137 "3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
138 "1197.07 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
139 " 558.59 677.92 817.26 989.39 1200.35 1503.06 1799.90 2204.18 \n"
140 "3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
141 "3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
142 "3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
143 "3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
144 "end.\n";
145 */
146/*
147 const unsigned int TIME_OFF = 3;
148 const unsigned int VOLT_OFF = 30;
149 const unsigned int CURR_OFF = 70;
150 const unsigned int HUMI_OFF = 110;
151 const unsigned int TEMP_OFF = 134;
152 */
153
154 if (fDump)
155 {
156 ostringstream msg;
157 msg << "--- " << Time().GetAsStr() << " --- received " << bytes_received << " bytes.";
158 Dump(msg.str());
159 }
160
161
162 istream is(&fBuffer);
163
164 int state = 0;
165 bool values = false;
166
167 vector<int> volt;
168 vector<float> resist;
169// int status=-1;
170 float time=0;
171
172 string buffer;
173 while (getline(is, buffer, '\n'))
174 {
175 if (fIsVerbose)
176 Out() << buffer << endl;
177 if (fDump)
178 Dump(buffer);
179
180 buffer = Tools::Trim(buffer);
181
182 if (buffer.empty())
183 continue;
184
185 if (buffer.substr(0, 4)=="end.")
186 break;
187
188 if (buffer.substr(0, 8)=="status: ")
189 {
190// status = stoi(buffer.substr(8));
191 continue;
192 }
193
194 if (buffer.substr(0, 8)=="time_s: ")
195 {
196 time = stof(buffer.substr(8));
197 continue;
198 }
199
200 if (buffer.substr(0, 8)=="VOLTAGES")
201 {
202 state = 1;
203 continue;
204 }
205
206 if (buffer.substr(0, 11)=="RESISTANCES")
207 {
208 state = 2;
209 continue;
210 }
211
212 if (state==1 && buffer.substr(0, 7)=="values:")
213 {
214 istringstream in(buffer.substr(7));
215 while (1)
216 {
217 int v;
218 in >> v;
219 if (!in)
220 break;
221
222 volt.push_back(v);
223 }
224 continue;
225 }
226
227 if (state==2 && buffer.substr(0, 7)=="values:")
228 {
229 values = true;
230 continue;
231 }
232
233 if (state==2 && !values)
234 continue;
235
236 istringstream in(buffer);
237 while (1)
238 {
239 float f;
240 in >> f;
241 if (!in)
242 break;
243
244 resist.push_back(f);
245 }
246 }
247
248 if (volt.size()!=84 || resist.size()!=64)
249 {
250 ostringstream out;
251
252 out << "Corrupted data received (" << volt.size() << " voltages and ";
253 out << resist.size() << " resistances received; 84 and 64 expected)";
254 Warn(out);
255 StartRead();
256 return;
257 }
258
259 int mapv[] =
260 {
261 0, 16, 24, 8,
262 1, 17, 25, 9,
263 2, 18, 26, 10,
264 //
265 3, 19, 27, 11,
266 4, 20, 28, 12,
267 5, 21, 29, 13,
268 //
269 32, 36, 33, 34, 37, 38,
270 //
271 -1
272 };
273
274
275 int mapc[] =
276 {
277 40, 56, 64, 48,
278 41, 57, 65, 49,
279 42, 58, 66, 50,
280 //
281 43, 59, 67, 51,
282 44, 60, 68, 52,
283 45, 61, 69, 53,
284 //
285 72, 76, 73, 74, 77, 78,
286 //
287 -1
288 };
289
290
291 int maprh[] =
292 {
293 80, 81, 82, 83, -1
294 };
295
296 int offrh[] =
297 {
298 821, 822, 816, 822,
299 };
300
301 int mapt[] =
302 {
303 // sensor compartment temperatures
304 0, 1, 2, 3, 4, 5, 6, 56, 57, 58, 59, 60,
305 61, 62, 32, 33, 34, 35, 36, 63, 37, 38, 39, 24,
306 25, 26, 27, 28, 29, 30, 31,
307 // crate temperatures (0-3, back/front)
308 12, 13, 52, 53, 44, 46, 20, 21,
309 //crate power supply temperatures (0-3)
310 8, 9, 48, 49, 40, 41, 16, 17,
311 // aux power supplies (FTM-side top/bot, FSC-side top/bot)
312 45, 50, 19, 42,
313 // backpanel (FTM-side top/bot, FSC-side top/bot)
314 11, 51, 18, 43,
315 // switch boxes (top front/back, bottom front/back)
316 15, 14, 47, 10,
317 //
318 -1
319 };
320
321 vector<float> voltages;
322 vector<float> currents;
323 vector<float> humidities;
324 vector<float> temperatures;
325
326 for (int *pv=mapv; *pv>=0; pv++)
327 voltages.push_back(volt[*pv]*0.001);
328
329 for (int *pc=mapc; *pc>=0; pc++)
330 currents.push_back(volt[*pc]*0.005);
331
332 for (int idx=0; idx<4; idx++)
333 {
334 voltages[idx +8] *= -1;
335 voltages[idx+20] *= -1;
336 currents[idx +8] *= -1;
337 currents[idx+20] *= -1;
338 }
339 voltages[12] *= 2;
340 voltages[13] *= 2;
341 voltages[14] *= 2;
342 voltages[15] *= 2;
343
344 voltages[24] *= 2;
345 voltages[25] *= 2;
346
347 voltages[27] *= -1;
348 voltages[29] *= -1;
349
350 currents[27] *= -1;
351 currents[29] *= -1;
352
353 int idx=0;
354 for (int *ph=maprh; *ph>=0; ph++, idx++)
355 humidities.push_back((volt[*ph]-offrh[idx])*0.0313);
356
357 for (int *pt=mapt; *pt>=0; pt++)
358 temperatures.push_back(resist[*pt]>800&&resist[*pt]<2000 ? GetTempPT1000(resist[*pt]) : 0);
359
360 // 0 = 3-(3+0)%4
361 // 3 = 3-(3+1)%4
362 // 2 = 3-(3+2)%4
363 // 1 = 3-(3+3)%4
364
365 /*
366 index unit offset scale crate for board:
367 0 mV 0 1 0 FAD 3.3V
368 24 mV 0 1 1 FAD 3.3V
369 16 mV 0 1 2 FAD 3.3V
370 8 mV 0 1 3 FAD 3.3V
371
372 1 mV 0 1 0 FAD 3.3V
373 25 mV 0 1 1 FAD 3.3V
374 17 mV 0 1 2 FAD 3.3V
375 9 mV 0 1 3 FAD 3.3V
376
377 2 mV 0 -1 0 FAD -2.0V
378 26 mV 0 -1 1 FAD -2.0V
379 18 mV 0 -1 2 FAD -2.0V
380 10 mV 0 -1 3 FAD -2.0V
381
382 --
383
384 3 mV 0 1 0 FPA 5.0V
385 27 mV 0 1 1 FPA 5.0V
386 19 mV 0 1 2 FPA 5.0V
387 11 mV 0 1 3 FPA 5.0V
388
389 4 mV 0 1 0 FPA 3.3V
390 28 mV 0 1 1 FPA 3.3V
391 20 mV 0 1 2 FPA 3.3V
392 12 mV 0 1 3 FPA 3.3V
393
394 5 mV 0 -1 0 FPA -3.3V
395 29 mV 0 -1 1 FPA -3.3V
396 21 mV 0 -1 2 FPA -3.3V
397 13 mV 0 -1 3 FPA -3.3V
398
399 --
400
401 32 mV 0 1 bottom ETH 5V
402 36 mV 0 1 top ETH 5V
403
404 33 mV 0 1 bottom FTM 3.3V
405 34 mV 0 -1 bottom FTM -3.3V
406
407 37 mV 0 1 top FFC 3.3V
408 38 mV 0 -1 top FLP -3.3V
409
410 -----
411
412 40 mA 0 5 0 FAD
413 64 mA 0 5 1 FAD
414 56 mA 0 5 2 FAD
415 48 mA 0 5 3 FAD
416
417 41 mA 0 5 0 FAD
418 65 mA 0 5 1 FAD
419 57 mA 0 5 2 FAD
420 49 mA 0 5 3 FAD
421
422 42 mA 0 -5 0 FAD
423 66 mA 0 -5 1 FAD
424 58 mA 0 -5 2 FAD
425 50 mA 0 -5 3 FAD
426
427 --
428
429 43 mA 0 5 0 FPA
430 67 mA 0 5 1 FPA
431 59 mA 0 5 2 FPA
432 51 mA 0 5 3 FPA
433
434 44 mA 0 5 0 FPA
435 68 mA 0 5 1 FPA
436 60 mA 0 5 2 FPA
437 52 mA 0 5 3 FPA
438
439 45 mA 0 -5 0 FPA
440 69 mA 0 -5 1 FPA
441 61 mA 0 -5 2 FPA
442 53 mA 0 -5 3 FPA
443
444 ---
445
446 72 mA 0 5 bottom ETH
447 76 mA 0 5 top ETH
448
449 73 mA 0 5 bottom FTM
450 74 mA 0 -5 bottom FTM
451
452 77 mA 0 5 top FFC
453 78 mA 0 -5 top FLP
454
455 ----
456
457 80 % RH -821 0.0313 FSP000
458 81 % RH -822 0.0313 FSP221
459 82 % RH -816 0.0313 Sector0
460 83 % RH -822 0.0313 Sector2
461 */
462
463 // TEMPERATURES
464 // 31 x Sensor plate
465 // 8 x Crate
466 // 12 x PS
467 // 4 x Backpanel
468 // 4 x Switchbox
469
470
471
472 /*
473 0 ohms FSP 000
474 1 ohms FSP 010
475 2 ohms FSP 023
476 3 ohms FSP 043
477 4 ohms FSP 072
478 5 ohms FSP 080
479 6 ohms FSP 092
480 56 ohms FSP 103
481 57 ohms FSP 111
482 58 ohms FSP 121
483 59 ohms FSP 152
484 60 ohms FSP 163
485 61 ohms FSP 171
486 62 ohms FSP 192
487 32 ohms FSP 200
488 33 ohms FSP 210
489 34 ohms FSP 223
490 35 ohms FSP 233
491 36 ohms FSP 243
492 63 ohms FSP 252
493 37 ohms FSP 280
494 38 ohms FSP 283
495 39 ohms FSP 293
496 24 ohms FSP 311
497 25 ohms FSP 321
498 26 ohms FSP 343
499 27 ohms FSP 352
500 28 ohms FSP 363
501 29 ohms FSP 371
502 30 ohms FSP 381
503 31 ohms FSP 392
504 8 ohms Crate0 ?
505 9 ohms Crate0 ?
506 48 ohms Crate1 ?
507 49 ohms Crate1 ?
508 40 ohms Crate2 ?
509 41 ohms Crate2 ?
510 16 ohms Crate3 ?
511 17 ohms Crate3 ?
512 10 ohms PS Crate 0
513 11 ohms PS Crate 0
514 50 ohms PS Crate 1
515 51 ohms PS Crate 1
516 42 ohms PS Crate 2
517 43 ohms PS Crate 2
518 18 ohms PS Crate 3
519 19 ohms PS Crate 3
520 12 ohms PS Aux0
521 52 ohms PS Aux0
522 20 ohms PS Aux1
523 44 ohms PS Aux1
524 13 ohms Backpanel ?
525 21 ohms Backpanel ?
526 45 ohms Backpanel ?
527 53 ohms Backpanel ?
528 14 ohms Switchbox0 ?
529 15 ohms Switchbox0 ?
530 46 ohms Switchbox1 ?
531 47 ohms Switchbox1 ?
532 7 ohms nc nc
533 22 ohms nc nc
534 23 ohms nc nc
535 54 ohms nc nc
536 55 ohms nc nc
537 */
538
539 if (fIsVerbose)
540 {
541 for (size_t i=0; i<resist.size(); i++)
542 if (resist[i]>800 && resist[i]<2000)
543 Out() << setw(2) << i << " - " << setw(4) << (int)resist[i] << ": " << setprecision(1) << fixed << GetTempPT1000(resist[i]) << endl;
544 else
545 Out() << setw(2) << i << " - " << setw(4) << (int)resist[i] << ": " << "----" << endl;
546 }
547
548 UpdateHum( time, humidities);
549 UpdateTemp(time, temperatures);
550 UpdateVolt(time, voltages);
551 UpdateCur( time, currents);
552
553 StartRead();
554 }
555
556 void StartRead()
557 {
558 ba::async_read_until(*this, fBuffer, "end.\n",
559 boost::bind(&ConnectionFSC::HandleReceivedData, this,
560 dummy::error, dummy::bytes_transferred, 0));
561
562 // FIXME: Add timeout here
563 }
564
565 // This is called when a connection was established
566 void ConnectionEstablished()
567 {
568 PostMessage("m", 1);
569
570 fBuffer.prepare(10000);
571 StartRead();
572 }
573
574/*
575 void HandleReadTimeout(const bs::error_code &error)
576 {
577 if (error==ba::error::basic_errors::operation_aborted)
578 return;
579
580 if (error)
581 {
582 ostringstream str;
583 str << "Read timeout of " << URL() << ": " << error.message() << " (" << error << ")";// << endl;
584 Error(str);
585
586 PostClose();
587 return;
588
589 }
590
591 if (!is_open())
592 {
593 // For example: Here we could schedule a new accept if we
594 // would not want to allow two connections at the same time.
595 return;
596 }
597
598 // Check whether the deadline has passed. We compare the deadline
599 // against the current time since a new asynchronous operation
600 // may have moved the deadline before this actor had a chance
601 // to run.
602 if (fInTimeout.expires_at() > ba::deadline_timer::traits_type::now())
603 return;
604
605 Error("Timeout reading data from "+URL());
606
607 PostClose();
608 }
609*/
610
611public:
612 ConnectionFSC(ba::io_service& ioservice, MessageImp &imp) : Connection(ioservice, imp()),
613 fIsVerbose(false), fDump(false)
614 {
615 SetLogStream(&imp);
616 }
617
618 void SetVerbose(bool b)
619 {
620 fIsVerbose = b;
621 }
622
623 void SetDumpStream(bool b)
624 {
625 fDump = b;
626 }
627};
628
629// ------------------------------------------------------------------------
630
631#include "DimDescriptionService.h"
632
633class ConnectionDimFSC : public ConnectionFSC
634{
635private:
636
637 DimDescribedService fDimTemp;
638 DimDescribedService fDimHum;
639 DimDescribedService fDimVolt;
640 DimDescribedService fDimCurrent;
641
642 void Update(DimDescribedService &svc, vector<float> data, float time) const
643 {
644 data.insert(data.begin(), time);
645 svc.Update(data);
646 }
647
648 void UpdateTemp(float time, const vector<float> &temp)
649 {
650 Update(fDimTemp, temp, time);
651 }
652
653 void UpdateHum(float time, const vector<float> &hum)
654 {
655 Update(fDimHum, hum, time);
656 }
657
658 void UpdateVolt(float time, const vector<float> &volt)
659 {
660 Update(fDimVolt, volt, time);
661 }
662
663 void UpdateCur(float time, const vector<float> &curr)
664 {
665 Update(fDimCurrent, curr, time);
666 }
667
668
669
670public:
671 ConnectionDimFSC(ba::io_service& ioservice, MessageImp &imp) :
672 ConnectionFSC(ioservice, imp),
673 fDimTemp ("FSC_CONTROL/TEMPERATURE", "F:1;F:31;F:8;F:8;F:4;F:4;F:4",
674 "|t[s]:FSC uptime"
675 "|T_sens[deg C]:Sensor compartment temperatures"
676 "|T_crate[deg C]:Temperatures crate 0 (back/front), 1 (b/f), 2 (b/f), 3 (b/f)"
677 "|T_ps[deg C]:Temp power supplies crate 0 (back/front), 1, 2, 3"
678 "|T_aux[deg C]:Auxiliary power supply temperatures FTM (top/bottom), FSC (t/b)"
679 "|T_back[deg C]:FTM backpanel temperatures FTM (top/bottom), FSC (top/bottom)"
680 "|T_eth[deg C]:Ethernet switches temperatures top (front/back), bottom (f/b)"),
681 fDimHum ("FSC_CONTROL/HUMIDITY", "F:1;F:4",
682 "|t[s]:FSC uptime"
683 "|H[%]:Humidity sensors readout"),
684 fDimVolt ("FSC_CONTROL/VOLTAGE",
685 "F:1;F:4;F:4;F:4;F:4;F:4;F:4;F:2;F:2;F:1;F:1",
686 "|t[s]:FSC uptime"
687 "|FAD_Ud[V]:FAD digital (crate 0-3)"
688 "|FAD_Up[V]:FAD positive (crate 0-3)"
689 "|FAD_Un[V]:FAD negative (crate 0-3)"
690 "|FPA_Ud[V]:FPA digital (crate 0-3)"
691 "|FPA_Up[V]:FPA positive (crate 0-3)"
692 "|FPA_Un[V]:FPA negative (crate 0-3)"
693 "|ETH_U[V]:Ethernet switch (pos/neg)"
694 "|FTM_U[V]:FTM - trigger master (pos/neg)"
695 "|FFC_U[V]:FFC"
696 "|FLP_U[V]:FLP - light pulser"),
697 fDimCurrent("FSC_CONTROL/CURRENT", "F:1;F:4;F:4;F:4;F:4;F:4;F:4;F:2;F:2;F:1;F:1",
698 "|t[s]:FSC uptime"
699 "|FAD_Id[A]:FAD digital (crate 0-3)"
700 "|FAD_Ip[A]:FAD positive (crate 0-3)"
701 "|FAD_In[A]:FAD negative (crate 0-3)"
702 "|FPA_Id[A]:FPA digital (crate 0-3)"
703 "|FPA_Ip[A]:FPA positive (crate 0-3)"
704 "|FPA_In[A]:FPA negative (crate 0-3)"
705 "|ETH_I[A]:Ethernet switch (pos/neg)"
706 "|FTM_I[A]:FTM - trigger master (pos/neg)"
707 "|FFC_I[A]:FFC"
708 "|FLP_I[A]:FLP - light pulser")
709 {
710 }
711
712 // A B [C] [D] E [F] G H [I] J K [L] M N O P Q R [S] T U V W [X] Y Z
713};
714
715// ------------------------------------------------------------------------
716
717template <class T, class S>
718class StateMachineFSC : public T, public ba::io_service, public ba::io_service::work
719{
720private:
721 S fFSC;
722
723 int Disconnect()
724 {
725 // Close all connections
726 fFSC.PostClose(false);
727
728 /*
729 // Now wait until all connection have been closed and
730 // all pending handlers have been processed
731 poll();
732 */
733
734 return T::GetCurrentState();
735 }
736
737 int Reconnect(const EventImp &evt)
738 {
739 // Close all connections to supress the warning in SetEndpoint
740 fFSC.PostClose(false);
741
742 // Now wait until all connection have been closed and
743 // all pending handlers have been processed
744 poll();
745
746 if (evt.GetBool())
747 fFSC.SetEndpoint(evt.GetString());
748
749 // Now we can reopen the connection
750 fFSC.PostClose(true);
751
752 return T::GetCurrentState();
753 }
754
755 int Execute()
756 {
757 // Dispatch (execute) at most one handler from the queue. In contrary
758 // to run_one(), it doesn't wait until a handler is available
759 // which can be dispatched, so poll_one() might return with 0
760 // handlers dispatched. The handlers are always dispatched/executed
761 // synchronously, i.e. within the call to poll_one()
762 poll_one();
763
764 return fFSC.IsConnected() ? State::kConnected : State::kDisconnected;
765 }
766
767 bool CheckEventSize(size_t has, const char *name, size_t size)
768 {
769 if (has==size)
770 return true;
771
772 ostringstream msg;
773 msg << name << " - Received event has " << has << " bytes, but expected " << size << ".";
774 T::Fatal(msg);
775 return false;
776 }
777
778 int SetVerbosity(const EventImp &evt)
779 {
780 if (!CheckEventSize(evt.GetSize(), "SetVerbosity", 1))
781 return T::kSM_FatalError;
782
783 fFSC.SetVerbose(evt.GetBool());
784
785 return T::GetCurrentState();
786 }
787
788 int SetDumpStream(const EventImp &evt)
789 {
790 if (!CheckEventSize(evt.GetSize(), "SetDumpStream", 1))
791 return T::kSM_FatalError;
792
793 fFSC.SetDumpStream(evt.GetBool());
794
795 return T::GetCurrentState();
796 }
797
798public:
799 StateMachineFSC(ostream &out=cout) :
800 T(out, "FSC_CONTROL"), ba::io_service::work(static_cast<ba::io_service&>(*this)),
801 fFSC(*this, *this)
802 {
803 // ba::io_service::work is a kind of keep_alive for the loop.
804 // It prevents the io_service to go to stopped state, which
805 // would prevent any consecutive calls to run()
806 // or poll() to do nothing. reset() could also revoke to the
807 // previous state but this might introduce some overhead of
808 // deletion and creation of threads and more.
809
810 // State names
811 T::AddStateName(State::kDisconnected, "Disconnected",
812 "FSC board not connected via ethernet.");
813
814 T::AddStateName(State::kConnected, "Connected",
815 "Ethernet connection to FSC established.");
816
817 // Verbosity commands
818 T::AddEvent("SET_VERBOSE", "B:1")
819 (bind(&StateMachineFSC::SetVerbosity, this, placeholders::_1))
820 ("set verbosity state"
821 "|verbosity[bool]:disable or enable verbosity for received data (yes/no), except dynamic data");
822
823 T::AddEvent("DUMP_STREAM", "B:1")
824 (bind(&StateMachineFSC::SetDumpStream, this, placeholders::_1))
825 (""
826 "");
827
828 // Conenction commands
829 T::AddEvent("DISCONNECT", State::kConnected)
830 (bind(&StateMachineFSC::Disconnect, this))
831 ("disconnect from ethernet");
832
833 T::AddEvent("RECONNECT", "O", State::kDisconnected, State::kConnected)
834 (bind(&StateMachineFSC::Reconnect, this, placeholders::_1))
835 ("(Re)connect ethernet connection to FTM, a new address can be given"
836 "|[host][string]:new ethernet address in the form <host:port>");
837
838 fFSC.StartConnect();
839 }
840
841 void SetEndpoint(const string &url)
842 {
843 fFSC.SetEndpoint(url);
844 }
845
846 int EvalOptions(Configuration &conf)
847 {
848 fFSC.SetVerbose(!conf.Get<bool>("quiet"));
849
850 SetEndpoint(conf.Get<string>("addr"));
851
852 return -1;
853 }
854};
855
856// ------------------------------------------------------------------------
857
858#include "Main.h"
859
860template<class T, class S, class R>
861int RunShell(Configuration &conf)
862{
863 return Main::execute<T, StateMachineFSC<S, R>>(conf);
864}
865
866void SetupConfiguration(Configuration &conf)
867{
868 po::options_description control("FTM control options");
869 control.add_options()
870 ("no-dim", po_bool(), "Disable dim services")
871 ("addr,a", var<string>("localhost:5000"), "Network address of FTM")
872 ("quiet,q", po_bool(true), "Disable printing contents of all received messages (except dynamic data) in clear text.")
873 ;
874
875 conf.AddOptions(control);
876}
877
878/*
879 Extract usage clause(s) [if any] for SYNOPSIS.
880 Translators: "Usage" and "or" here are patterns (regular expressions) which
881 are used to match the usage synopsis in program output. An example from cp
882 (GNU coreutils) which contains both strings:
883 Usage: cp [OPTION]... [-T] SOURCE DEST
884 or: cp [OPTION]... SOURCE... DIRECTORY
885 or: cp [OPTION]... -t DIRECTORY SOURCE...
886 */
887void PrintUsage()
888{
889 cout <<
890 "The ftmctrl controls the FSC (FACT Slow Control) board.\n"
891 "\n"
892 "The default is that the program is started without user intercation. "
893 "All actions are supposed to arrive as DimCommands. Using the -c "
894 "option, a local shell can be initialized. With h or help a short "
895 "help message about the usuage can be brought to the screen.\n"
896 "\n"
897 "Usage: fscctrl [-c type] [OPTIONS]\n"
898 " or: fscctrl [OPTIONS]\n";
899 cout << endl;
900}
901
902void PrintHelp()
903{
904 Main::PrintHelp<StateMachineFSC<StateMachine, ConnectionFSC>>();
905
906 /* Additional help text which is printed after the configuration
907 options goes here */
908
909 /*
910 cout << "bla bla bla" << endl << endl;
911 cout << endl;
912 cout << "Environment:" << endl;
913 cout << "environment" << endl;
914 cout << endl;
915 cout << "Examples:" << endl;
916 cout << "test exam" << endl;
917 cout << endl;
918 cout << "Files:" << endl;
919 cout << "files" << endl;
920 cout << endl;
921 */
922}
923
924int main(int argc, const char* argv[])
925{
926 Configuration conf(argv[0]);
927 conf.SetPrintUsage(PrintUsage);
928 Main::SetupConfiguration(conf);
929 SetupConfiguration(conf);
930
931 if (!conf.DoParse(argc, argv, PrintHelp))
932 return 127;
933
934 //try
935 {
936 // No console access at all
937 if (!conf.Has("console"))
938 {
939 if (conf.Get<bool>("no-dim"))
940 return RunShell<LocalStream, StateMachine, ConnectionFSC>(conf);
941 else
942 return RunShell<LocalStream, StateMachineDim, ConnectionDimFSC>(conf);
943 }
944 // Cosole access w/ and w/o Dim
945 if (conf.Get<bool>("no-dim"))
946 {
947 if (conf.Get<int>("console")==0)
948 return RunShell<LocalShell, StateMachine, ConnectionFSC>(conf);
949 else
950 return RunShell<LocalConsole, StateMachine, ConnectionFSC>(conf);
951 }
952 else
953 {
954 if (conf.Get<int>("console")==0)
955 return RunShell<LocalShell, StateMachineDim, ConnectionDimFSC>(conf);
956 else
957 return RunShell<LocalConsole, StateMachineDim, ConnectionDimFSC>(conf);
958 }
959 }
960 /*catch (std::exception& e)
961 {
962 cerr << "Exception: " << e.what() << endl;
963 return -1;
964 }*/
965
966 return 0;
967}
Note: See TracBrowser for help on using the repository browser.