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

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