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

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