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

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