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

Last change on this file since 12000 was 11868, checked in by tbretz, 13 years ago
Two voltages need scaling by 2
File size: 24.3 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 received; 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]*0.001);
321
322 for (int *pc=mapc; *pc>=0; pc++)
323 currents.push_back(volt[*pc]*0.005);
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[26] *= 2;
333 voltages[27] *= -2;
334 voltages[29] *= -1;
335 currents[27] *= -1;
336 currents[29] *= -1;
337
338 int idx=0;
339 for (int *ph=maprh; *ph>=0; ph++, idx++)
340 humidities.push_back((volt[*ph]-offrh[idx])*0.0313);
341
342 for (int *pt=mapt; *pt>=0; pt++)
343 temperatures.push_back(resist[*pt]>800&&resist[*pt]<2000 ? GetTempPT1000(resist[*pt]) : 0);
344
345 // 0 = 3-(3+0)%4
346 // 3 = 3-(3+1)%4
347 // 2 = 3-(3+2)%4
348 // 1 = 3-(3+3)%4
349
350 /*
351 index unit offset scale crate for board:
352 0 mV 0 1 0 FAD
353 24 mV 0 1 1 FAD
354 16 mV 0 1 2 FAD
355 8 mV 0 1 3 FAD
356
357 1 mV 0 1 0 FAD
358 25 mV 0 1 1 FAD
359 17 mV 0 1 2 FAD
360 9 mV 0 1 3 FAD
361
362 2 mV 0 -1 0 FAD
363 26 mV 0 -1 1 FAD
364 18 mV 0 -1 2 FAD
365 10 mV 0 -1 3 FAD
366
367 --
368
369 3 mV 0 1 0 FPA
370 27 mV 0 1 1 FPA
371 19 mV 0 1 2 FPA
372 11 mV 0 1 3 FPA
373
374 4 mV 0 1 0 FPA
375 28 mV 0 1 1 FPA
376 20 mV 0 1 2 FPA
377 12 mV 0 1 3 FPA
378
379 5 mV 0 -1 0 FPA
380 29 mV 0 -1 1 FPA
381 21 mV 0 -1 2 FPA
382 13 mV 0 -1 3 FPA
383
384 --
385
386 32 mV 0 1 bottom ETH
387 36 mV 0 1 top ETH
388
389 33 mV 0 1 bottom FTM
390 34 mV 0 -1 bottom FTM
391
392 37 mV 0 1 top FFC
393 38 mV 0 -1 top FLP
394
395 -----
396
397 40 mA 0 5 0 FAD
398 64 mA 0 5 1 FAD
399 56 mA 0 5 2 FAD
400 48 mA 0 5 3 FAD
401
402 41 mA 0 5 0 FAD
403 65 mA 0 5 1 FAD
404 57 mA 0 5 2 FAD
405 49 mA 0 5 3 FAD
406
407 42 mA 0 -5 0 FAD
408 66 mA 0 -5 1 FAD
409 58 mA 0 -5 2 FAD
410 50 mA 0 -5 3 FAD
411
412 --
413
414 43 mA 0 5 0 FPA
415 67 mA 0 5 1 FPA
416 59 mA 0 5 2 FPA
417 51 mA 0 5 3 FPA
418
419 44 mA 0 5 0 FPA
420 68 mA 0 5 1 FPA
421 60 mA 0 5 2 FPA
422 52 mA 0 5 3 FPA
423
424 45 mA 0 -5 0 FPA
425 69 mA 0 -5 1 FPA
426 61 mA 0 -5 2 FPA
427 53 mA 0 -5 3 FPA
428
429 ---
430
431 72 mA 0 5 bottom ETH
432 76 mA 0 5 top ETH
433
434 73 mA 0 5 bottom FTM
435 74 mA 0 -5 bottom FTM
436
437 77 mA 0 5 top FFC
438 78 mA 0 -5 top FLP
439
440 ----
441
442 80 % RH -821 0.0313 FSP000
443 81 % RH -822 0.0313 FSP221
444 82 % RH -816 0.0313 Sector0
445 83 % RH -822 0.0313 Sector2
446 */
447
448 // TEMPERATURES
449 // 31 x Sensor plate
450 // 8 x Crate
451 // 12 x PS
452 // 4 x Backpanel
453 // 4 x Switchbox
454
455
456
457 /*
458 0 ohms FSP 000
459 1 ohms FSP 010
460 2 ohms FSP 023
461 3 ohms FSP 043
462 4 ohms FSP 072
463 5 ohms FSP 080
464 6 ohms FSP 092
465 56 ohms FSP 103
466 57 ohms FSP 111
467 58 ohms FSP 121
468 59 ohms FSP 152
469 60 ohms FSP 163
470 61 ohms FSP 171
471 62 ohms FSP 192
472 32 ohms FSP 200
473 33 ohms FSP 210
474 34 ohms FSP 223
475 35 ohms FSP 233
476 36 ohms FSP 243
477 63 ohms FSP 252
478 37 ohms FSP 280
479 38 ohms FSP 283
480 39 ohms FSP 293
481 24 ohms FSP 311
482 25 ohms FSP 321
483 26 ohms FSP 343
484 27 ohms FSP 352
485 28 ohms FSP 363
486 29 ohms FSP 371
487 30 ohms FSP 381
488 31 ohms FSP 392
489 8 ohms Crate0 ?
490 9 ohms Crate0 ?
491 48 ohms Crate1 ?
492 49 ohms Crate1 ?
493 40 ohms Crate2 ?
494 41 ohms Crate2 ?
495 16 ohms Crate3 ?
496 17 ohms Crate3 ?
497 10 ohms PS Crate 0
498 11 ohms PS Crate 0
499 50 ohms PS Crate 1
500 51 ohms PS Crate 1
501 42 ohms PS Crate 2
502 43 ohms PS Crate 2
503 18 ohms PS Crate 3
504 19 ohms PS Crate 3
505 12 ohms PS Aux0
506 52 ohms PS Aux0
507 20 ohms PS Aux1
508 44 ohms PS Aux1
509 13 ohms Backpanel ?
510 21 ohms Backpanel ?
511 45 ohms Backpanel ?
512 53 ohms Backpanel ?
513 14 ohms Switchbox0 ?
514 15 ohms Switchbox0 ?
515 46 ohms Switchbox1 ?
516 47 ohms Switchbox1 ?
517 7 ohms nc nc
518 22 ohms nc nc
519 23 ohms nc nc
520 54 ohms nc nc
521 55 ohms nc nc
522 */
523
524 for (size_t i=0; i<resist.size(); i++)
525 if (resist[i]>800 && resist[i]<2000)
526 cout << setw(2) << i << " - " << setw(4) << (int)resist[i] << ": " << setprecision(1) << fixed << GetTempPT1000(resist[i]) << endl;
527 else
528 cout << setw(2) << i << " - " << setw(4) << (int)resist[i] << ": " << "----" << endl;
529
530 UpdateTemp(time, temperatures);
531 UpdateVolt(time, voltages);
532 UpdateCur( time, currents);
533 UpdateHum( time, humidities);
534
535 StartRead();
536 }
537
538 void StartRead()
539 {
540 ba::async_read_until(*this, fBuffer, "end.\n",
541 boost::bind(&ConnectionFSC::HandleReceivedData, this,
542 dummy::error, dummy::bytes_transferred, 0));
543
544 // FIXME: Add timeout here
545 }
546
547 // This is called when a connection was established
548 void ConnectionEstablished()
549 {
550 PostMessage("m", 1);
551
552 fBuffer.prepare(10000);
553 StartRead();
554 }
555
556/*
557 void HandleReadTimeout(const bs::error_code &error)
558 {
559 if (error==ba::error::basic_errors::operation_aborted)
560 return;
561
562 if (error)
563 {
564 ostringstream str;
565 str << "Read timeout of " << URL() << ": " << error.message() << " (" << error << ")";// << endl;
566 Error(str);
567
568 PostClose();
569 return;
570
571 }
572
573 if (!is_open())
574 {
575 // For example: Here we could schedule a new accept if we
576 // would not want to allow two connections at the same time.
577 return;
578 }
579
580 // Check whether the deadline has passed. We compare the deadline
581 // against the current time since a new asynchronous operation
582 // may have moved the deadline before this actor had a chance
583 // to run.
584 if (fInTimeout.expires_at() > ba::deadline_timer::traits_type::now())
585 return;
586
587 Error("Timeout reading data from "+URL());
588
589 PostClose();
590 }
591*/
592
593public:
594 ConnectionFSC(ba::io_service& ioservice, MessageImp &imp) : Connection(ioservice, imp()),
595 fIsVerbose(true), fDump(false)
596 {
597 SetLogStream(&imp);
598 }
599
600 void SetVerbose(bool b)
601 {
602 fIsVerbose = b;
603 }
604
605 void SetDumpStream(bool b)
606 {
607 fDump = b;
608 }
609};
610
611// ------------------------------------------------------------------------
612
613#include "DimDescriptionService.h"
614
615class ConnectionDimFSC : public ConnectionFSC
616{
617private:
618
619 DimDescribedService fDimTemp;
620 DimDescribedService fDimHum;
621 DimDescribedService fDimVolt;
622 DimDescribedService fDimCurrent;
623
624 void Update(DimDescribedService &svc, vector<float> data, float time) const
625 {
626 data.insert(data.begin(), time);
627 svc.Update(data);
628 }
629
630 void UpdateTemp(float time, const vector<float> &temp)
631 {
632 Update(fDimTemp, temp, time);
633 }
634
635 void UpdateHum(float time, const vector<float> &hum)
636 {
637 Update(fDimHum, hum, time);
638 }
639
640 void UpdateVolt(float time, const vector<float> &volt)
641 {
642 Update(fDimVolt, volt, time);
643 }
644
645 void UpdateCur(float time, const vector<float> &curr)
646 {
647 Update(fDimCurrent, curr, time);
648 }
649
650public:
651 ConnectionDimFSC(ba::io_service& ioservice, MessageImp &imp) :
652 ConnectionFSC(ioservice, imp),
653 fDimTemp ("FSC_CONTROL/TEMPERATURE", "F:1;F:31;F:8;F:12;F:4;F:4", ""),
654 fDimHum ("FSC_CONTROL/HUMIDITY", "F:1;F:1;F:1;F:1;F:1", ""),
655 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", ""),
656 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", "")
657 {
658 }
659
660 // 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
661};
662
663// ------------------------------------------------------------------------
664
665template <class T, class S>
666class StateMachineFSC : public T, public ba::io_service, public ba::io_service::work
667{
668 int Wrap(boost::function<void()> f)
669 {
670 f();
671 return T::GetCurrentState();
672 }
673
674 function<int(const EventImp &)> Wrapper(function<void()> func)
675 {
676 return bind(&StateMachineFSC::Wrap, this, func);
677 }
678
679private:
680 S fFSC;
681
682 enum states_t
683 {
684 kStateDisconnected = 1,
685 kStateConnected = 2,
686 };
687
688 int Disconnect()
689 {
690 // Close all connections
691 fFSC.PostClose(false);
692
693 /*
694 // Now wait until all connection have been closed and
695 // all pending handlers have been processed
696 poll();
697 */
698
699 return T::GetCurrentState();
700 }
701
702 int Reconnect(const EventImp &evt)
703 {
704 // Close all connections to supress the warning in SetEndpoint
705 fFSC.PostClose(false);
706
707 // Now wait until all connection have been closed and
708 // all pending handlers have been processed
709 poll();
710
711 if (evt.GetBool())
712 fFSC.SetEndpoint(evt.GetString());
713
714 // Now we can reopen the connection
715 fFSC.PostClose(true);
716
717 return T::GetCurrentState();
718 }
719
720 int Execute()
721 {
722 // Dispatch (execute) at most one handler from the queue. In contrary
723 // to run_one(), it doesn't wait until a handler is available
724 // which can be dispatched, so poll_one() might return with 0
725 // handlers dispatched. The handlers are always dispatched/executed
726 // synchronously, i.e. within the call to poll_one()
727 poll_one();
728
729 return fFSC.IsConnected() ? kStateConnected : kStateDisconnected;
730 }
731
732 bool CheckEventSize(size_t has, const char *name, size_t size)
733 {
734 if (has==size)
735 return true;
736
737 ostringstream msg;
738 msg << name << " - Received event has " << has << " bytes, but expected " << size << ".";
739 T::Fatal(msg);
740 return false;
741 }
742
743 int SetVerbosity(const EventImp &evt)
744 {
745 if (!CheckEventSize(evt.GetSize(), "SetVerbosity", 1))
746 return T::kSM_FatalError;
747
748 fFSC.SetVerbose(evt.GetBool());
749
750 return T::GetCurrentState();
751 }
752
753 int SetDumpStream(const EventImp &evt)
754 {
755 if (!CheckEventSize(evt.GetSize(), "SetDumpStream", 1))
756 return T::kSM_FatalError;
757
758 fFSC.SetDumpStream(evt.GetBool());
759
760 return T::GetCurrentState();
761 }
762
763public:
764 StateMachineFSC(ostream &out=cout) :
765 T(out, "FSC_CONTROL"), ba::io_service::work(static_cast<ba::io_service&>(*this)),
766 fFSC(*this, *this)
767 {
768 // ba::io_service::work is a kind of keep_alive for the loop.
769 // It prevents the io_service to go to stopped state, which
770 // would prevent any consecutive calls to run()
771 // or poll() to do nothing. reset() could also revoke to the
772 // previous state but this might introduce some overhead of
773 // deletion and creation of threads and more.
774
775 // State names
776 AddStateName(kStateDisconnected, "Disconnected",
777 "FSC board not connected via ethernet.");
778
779 AddStateName(kStateConnected, "Connected",
780 "Ethernet connection to FSC established.");
781
782 // Verbosity commands
783 T::AddEvent("SET_VERBOSE", "B:1")
784 (bind(&StateMachineFSC::SetVerbosity, this, placeholders::_1))
785 ("set verbosity state"
786 "|verbosity[bool]:disable or enable verbosity for received data (yes/no), except dynamic data");
787
788 T::AddEvent("DUMP_STREAM", "B:1")
789 (bind(&StateMachineFSC::SetDumpStream, this, placeholders::_1))
790 (""
791 "");
792
793 // Conenction commands
794 AddEvent("DISCONNECT", kStateConnected)
795 (bind(&StateMachineFSC::Disconnect, this))
796 ("disconnect from ethernet");
797
798 AddEvent("RECONNECT", "O", kStateDisconnected, kStateConnected)
799 (bind(&StateMachineFSC::Reconnect, this, placeholders::_1))
800 ("(Re)connect ethernet connection to FTM, a new address can be given"
801 "|[host][string]:new ethernet address in the form <host:port>");
802
803 fFSC.StartConnect();
804 }
805
806 void SetEndpoint(const string &url)
807 {
808 fFSC.SetEndpoint(url);
809 }
810
811 int EvalOptions(Configuration &conf)
812 {
813 SetEndpoint(conf.Get<string>("addr"));
814
815 fFSC.SetVerbose(!conf.Get<bool>("quiet"));
816
817 return -1;
818 }
819};
820
821// ------------------------------------------------------------------------
822
823#include "Main.h"
824
825template<class T, class S, class R>
826int RunShell(Configuration &conf)
827{
828 return Main::execute<T, StateMachineFSC<S, R>>(conf);
829}
830
831void SetupConfiguration(Configuration &conf)
832{
833 po::options_description control("FTM control options");
834 control.add_options()
835 ("no-dim", po_bool(), "Disable dim services")
836 ("addr,a", var<string>("localhost:5000"), "Network address of FTM")
837 ("quiet,q", po_bool(), "Disable printing contents of all received messages (except dynamic data) in clear text.")
838 ;
839
840 conf.AddOptions(control);
841}
842
843/*
844 Extract usage clause(s) [if any] for SYNOPSIS.
845 Translators: "Usage" and "or" here are patterns (regular expressions) which
846 are used to match the usage synopsis in program output. An example from cp
847 (GNU coreutils) which contains both strings:
848 Usage: cp [OPTION]... [-T] SOURCE DEST
849 or: cp [OPTION]... SOURCE... DIRECTORY
850 or: cp [OPTION]... -t DIRECTORY SOURCE...
851 */
852void PrintUsage()
853{
854 cout <<
855 "The ftmctrl controls the FSC (FACT Slow Control) board.\n"
856 "\n"
857 "The default is that the program is started without user intercation. "
858 "All actions are supposed to arrive as DimCommands. Using the -c "
859 "option, a local shell can be initialized. With h or help a short "
860 "help message about the usuage can be brought to the screen.\n"
861 "\n"
862 "Usage: fscctrl [-c type] [OPTIONS]\n"
863 " or: fscctrl [OPTIONS]\n";
864 cout << endl;
865}
866
867void PrintHelp()
868{
869 /* Additional help text which is printed after the configuration
870 options goes here */
871
872 /*
873 cout << "bla bla bla" << endl << endl;
874 cout << endl;
875 cout << "Environment:" << endl;
876 cout << "environment" << endl;
877 cout << endl;
878 cout << "Examples:" << endl;
879 cout << "test exam" << endl;
880 cout << endl;
881 cout << "Files:" << endl;
882 cout << "files" << endl;
883 cout << endl;
884 */
885}
886
887int main(int argc, const char* argv[])
888{
889 Configuration conf(argv[0]);
890 conf.SetPrintUsage(PrintUsage);
891 Main::SetupConfiguration(conf);
892 SetupConfiguration(conf);
893
894 if (!conf.DoParse(argc, argv, PrintHelp))
895 return -1;
896
897 //try
898 {
899 // No console access at all
900 if (!conf.Has("console"))
901 {
902 if (conf.Get<bool>("no-dim"))
903 return RunShell<LocalStream, StateMachine, ConnectionFSC>(conf);
904 else
905 return RunShell<LocalStream, StateMachineDim, ConnectionDimFSC>(conf);
906 }
907 // Cosole access w/ and w/o Dim
908 if (conf.Get<bool>("no-dim"))
909 {
910 if (conf.Get<int>("console")==0)
911 return RunShell<LocalShell, StateMachine, ConnectionFSC>(conf);
912 else
913 return RunShell<LocalConsole, StateMachine, ConnectionFSC>(conf);
914 }
915 else
916 {
917 if (conf.Get<int>("console")==0)
918 return RunShell<LocalShell, StateMachineDim, ConnectionDimFSC>(conf);
919 else
920 return RunShell<LocalConsole, StateMachineDim, ConnectionDimFSC>(conf);
921 }
922 }
923 /*catch (std::exception& e)
924 {
925 cerr << "Exception: " << e.what() << endl;
926 return -1;
927 }*/
928
929 return 0;
930}
Note: See TracBrowser for help on using the repository browser.