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

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