19 namespace ba = boost::asio;
20 namespace bs = boost::system;
21 namespace dummy = ba::placeholders;
70 const double x = R/1000;
71 return -193.804 + 96.0651*x + 134.673*x*x - 36.9091*x*x*x;
90 if (volt_ok && resi_ok)
93 fNumConsecutiveErrors++;
96 out <<
"Checksum error (V:";
97 out << hex << setfill(
'0');
103 out << setw(4) << volt_checksum;
114 out << setw(4) << resi_checksum;
120 out <<
"Nok=" << fNumConsecutiveMessages <<
", ";
121 out <<
"Nerr=" << fNumConsecutiveErrors <<
")";
125 fNumConsecutiveMessages = 0;
133 Out() <<
"Received one_message of FSC::BinaryOutput_t ... will now process it" << endl;
135 if (!CheckChecksum())
148 for (
unsigned int i=0;
i<volt.size();
i++)
151 for (
unsigned int i=0;
i<resist.size();
i++)
164 32, 36, 33, 34, 37, 38,
179 72, 76, 73, 74, 77, 78,
198 0, 1, 2, 3, 4, 5, 6, 56, 57, 58, 59, 60,
199 61, 62, 32, 33, 34, 35, 36, 63, 37, 38, 39, 24,
200 25, 26, 27, 28, 29, 30, 31,
202 12, 13, 52, 53, 44, 46, 20, 21,
204 8, 9, 48, 49, 40, 41, 16, 17,
215 vector<float> voltages;
216 vector<float> currents;
217 vector<float> humidities;
218 vector<float> temperatures;
220 for (
int *pv=mapv; *pv>=0; pv++)
221 voltages.push_back(volt[*pv]*0.001);
223 for (
int *pc=mapc; *pc>=0; pc++)
224 currents.push_back(volt[*pc]*0.005);
226 for (
int idx=0; idx<4; idx++)
228 voltages[idx +8] *= -1;
229 voltages[idx+20] *= -1;
230 currents[idx +8] *= -1;
231 currents[idx+20] *= -1;
248 for (
int *ph=maprh; *ph>=0; ph++, idx++)
249 humidities.push_back((volt[*ph]-offrh[idx])*0.0313);
255 for (
int *pt=mapt; *pt>=0; pt++)
257 temperatures.push_back(resist[*pt]>970&&resist[*pt]<1300 ? GetTempPT1000(resist[*pt]) : 0);
441 for (
size_t i=0;
i<resist.size();
i++)
443 if (resist[
i]>970 && resist[
i]<1300)
445 Out() << setw(2) <<
i <<
" - " << setw(4) << (int)resist[
i] <<
": " << setprecision(1) << fixed << GetTempPT1000(resist[
i]) << endl;
447 Out() << setw(2) << i <<
" - " << setw(4) << (int)resist[i] <<
": " <<
"----" << endl;
450 UpdateTemp(time, temperatures);
451 UpdateVolt(time, voltages);
452 UpdateCur( time, currents);
453 UpdateHum( time, humidities);
455 fNumConsecutiveErrors = 0;
456 fNumConsecutiveMessages++;
465 dummy::error, dummy::bytes_transferred));
470 void HandleRead(
const boost::system::error_code& err,
size_t bytes_received)
473 if (bytes_received==0 || err)
475 if (err==ba::error::eof)
480 if (err && err!=ba::error::eof &&
481 err!=ba::error::basic_errors::not_connected &&
482 err!=ba::error::basic_errors::operation_aborted)
485 str <<
"Reading from " << URL() <<
": " << err.message() <<
" (" << err <<
")";
488 PostClose(err!=ba::error::basic_errors::operation_aborted);
492 if (!ProcessMessage())
494 fIsAutoReconnect =
true;
495 fReconnectTimeout.expires_from_now(boost::posix_time::seconds(10));
497 this, dummy::error));
507 fNumConsecutiveErrors = 0;
508 fNumConsecutiveMessages = 0;
509 fIsAutoReconnect =
false;
516 fIsAutoReconnect =
false;
521 if (error==ba::error::basic_errors::operation_aborted)
527 str <<
"Read timeout of " << URL() <<
": " << error.message() <<
" (" << error <<
")";
546 if (fInTimeout.expires_at() > ba::deadline_timer::traits_type::now())
549 Error(
"Timeout reading data from "+URL());
556 fIsVerbose(false), fIsAutoReconnect(false), fReconnectTimeout(ioservice)
568 fPositionsSensors = vec;
573 fPositionsBias = vec;
578 return IsConnected() || fIsAutoReconnect;
600 data.insert(data.begin(),
time);
606 Update(fDimTemp, temp, time);
609 vector<Interpolator2D::vec> xy;
618 for (
int i=0;
i<31;
i++)
621 T.emplace_back(temp[
i]);
622 xy.emplace_back(fPositionsSensors[i]);
625 rms += temp[
i]*temp[
i];
630 Warn(
"No valid sensor temperatures.");
637 rms = rms<0 ? 0 : sqrt(rms);
640 const double cut_val = 0.015;
641 const bool reject = rms>4 || (fabs(fLastRms[0]-fLastRms[1])<=cut_val && fabs(rms-fLastRms[0])>cut_val);
643 fLastRms[1] = fLastRms[0];
648 Warn(
"Suspicious temperature values rejecte for BIAS_TEMP.");
658 Warn(
"Temperature values rejecte for BIAS_TEMP (calculation of weights failed).");
667 for (
int i=0;
i<320;
i++)
676 rms = rms<0 ? 0 : sqrt(rms);
680 out.assign(T.cbegin(), T.cend());
681 out.emplace_back(avg);
682 out.emplace_back(rms);
685 Update(fDimTemp2, out, time);
690 Update(fDimHum, hum, time);
695 Update(fDimVolt, volt, time);
700 Update(fDimCurrent, curr, time);
706 fDimTemp (
"FSC_CONTROL/TEMPERATURE",
"F:1;F:31;F:8;F:8;F:4;F:4;F:4",
708 "|T_sens[deg C]:Sensor compartment temperatures" 709 "|T_crate[deg C]:Temperatures crate 0 (back/front), 1 (b/f), 2 (b/f), 3 (b/f)" 710 "|T_ps[deg C]:Temp power supplies crate 0 (back/front), 1, 2, 3" 711 "|T_aux[deg C]:Auxiliary power supply temperatures FTM (top/bottom), FSC (t/b)" 712 "|T_back[deg C]:FTM backpanel temperatures FTM (top/bottom), FSC (top/bottom)" 713 "|T_eth[deg C]:Ethernet switches temperatures top (front/back), bottom (f/b)"),
714 fDimTemp2 (
"FSC_CONTROL/BIAS_TEMP",
"F:1;F:320;F:1;F:1",
716 "|T[deg C]:Interpolated temperatures at bias patch positions" 717 "|T_avg[deg C]:Average temperature calculated from all patches" 718 "|T_rms[deg C]:Temperature RMS calculated from all patches"),
719 fDimHum (
"FSC_CONTROL/HUMIDITY",
"F:1;F:4",
721 "|H[%]:Humidity sensors readout"),
722 fDimVolt (
"FSC_CONTROL/VOLTAGE",
723 "F:1;F:4;F:4;F:4;F:4;F:4;F:4;F:2;F:2;F:1;F:1",
725 "|FAD_Ud[V]:FAD digital (crate 0-3)" 726 "|FAD_Up[V]:FAD positive (crate 0-3)" 727 "|FAD_Un[V]:FAD negative (crate 0-3)" 728 "|FPA_Ud[V]:FPA digital (crate 0-3)" 729 "|FPA_Up[V]:FPA positive (crate 0-3)" 730 "|FPA_Un[V]:FPA negative (crate 0-3)" 731 "|ETH_U[V]:Ethernet switch (pos/neg)" 732 "|FTM_U[V]:FTM - trigger master (pos/neg)" 734 "|FLP_U[V]:FLP - light pulser"),
735 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",
737 "|FAD_Id[A]:FAD digital (crate 0-3)" 738 "|FAD_Ip[A]:FAD positive (crate 0-3)" 739 "|FAD_In[A]:FAD negative (crate 0-3)" 740 "|FPA_Id[A]:FPA digital (crate 0-3)" 741 "|FPA_Ip[A]:FPA positive (crate 0-3)" 742 "|FPA_In[A]:FPA negative (crate 0-3)" 743 "|ETH_I[A]:Ethernet switch (pos/neg)" 744 "|FTM_I[A]:FTM - trigger master (pos/neg)" 746 "|FLP_I[A]:FLP - light pulser")
756 template <
class T,
class S>
765 fFSC.PostClose(
false);
767 return T::GetCurrentState();
773 fFSC.PostClose(
false);
777 ba::io_service::poll();
783 fFSC.PostClose(
true);
785 return T::GetCurrentState();
799 msg << name <<
" - Received event has " << has <<
" bytes, but expected " << size <<
".";
806 if (!CheckEventSize(evt.
GetSize(),
"SetVerbosity", 1))
807 return T::kSM_FatalError;
809 fFSC.SetVerbose(evt.
GetBool());
811 return T::GetCurrentState();
820 "FSC board not connected via ethernet.");
823 "Ethernet connection to FSC established.");
826 T::AddEvent(
"SET_VERBOSE",
"B:1")
828 (
"set verbosity state" 829 "|verbosity[bool]:disable or enable verbosity for received data (yes/no), except dynamic data");
834 (
"disconnect from ethernet");
838 (
"(Re)connect ethernet connection to FSC, a new address can be given" 839 "|[host][string]:new ethernet address in the form <host:port>");
846 fFSC.SetEndpoint(url);
851 fFSC.SetVerbose(!conf.
Get<
bool>(
"quiet"));
853 const string fname1 = conf.
Get<
string>(
"sensor-pos-file");
857 T::Error(
"Reading sensor positions from "+fname1+
"failed ("+to_string(v1.size())+
")");
861 const string fname2 = conf.
Get<
string>(
"patch-pos-file");
863 if (v2.size() != 320)
865 T::Error(
"Reading bias patch positions from "+fname2+
"failed ("+to_string(v2.size())+
")");
869 fFSC.SetPositionsSensors(v1);
870 fFSC.SetPositionsBias(v2);
872 SetEndpoint(conf.
Get<
string>(
"addr"));
882 template<
class T,
class S,
class R>
885 return Main::execute<T, StateMachineFSC<S, R>>(conf);
890 po::options_description control(
"FSC control options");
891 control.add_options()
892 (
"no-dim",
po_bool(),
"Disable dim services")
893 (
"addr,a", var<string>(
"localhost:5000"),
"Network address of FSC")
894 (
"sensor-pos-file", var<string>()->required(),
"File with the positions of the 31 temperature sensors")
895 (
"patch-pos-file", var<string>()->required(),
"File with the positions of the 320 bias patches")
896 (
"quiet,q",
po_bool(
true),
"Disable printing contents of all received messages (except dynamic data) in clear text.")
914 "The fscctrl controls the FSC (FACT Slow Control) board.\n" 916 "The default is that the program is started without user intercation. " 917 "All actions are supposed to arrive as DimCommands. Using the -c " 918 "option, a local shell can be initialized. With h or help a short " 919 "help message about the usuage can be brought to the screen.\n" 921 "Usage: fscctrl [-c type] [OPTIONS]\n" 922 " or: fscctrl [OPTIONS]\n";
928 Main::PrintHelp<StateMachineFSC<StateMachine, ConnectionFSC>>();
948 int main(
int argc,
const char* argv[])
961 if (!conf.
Has(
"console"))
963 if (conf.
Get<
bool>(
"no-dim"))
964 return RunShell<LocalStream, StateMachine, ConnectionFSC>(conf);
966 return RunShell<LocalStream, StateMachineDim, ConnectionDimFSC>(conf);
969 if (conf.
Get<
bool>(
"no-dim"))
971 if (conf.
Get<
int>(
"console")==0)
972 return RunShell<LocalShell, StateMachine, ConnectionFSC>(conf);
974 return RunShell<LocalConsole, StateMachine, ConnectionFSC>(conf);
978 if (conf.
Get<
int>(
"console")==0)
979 return RunShell<LocalShell, StateMachineDim, ConnectionDimFSC>(conf);
981 return RunShell<LocalConsole, StateMachineDim, ConnectionDimFSC>(conf);
std::vector< double > Interpolate(const std::vector< double > &z) const
void HandleReconnectTimeout(const bs::error_code &)
bool SetOutputGrid(std::size_t n, double *x, double *y)
void SetupConfiguration(Configuration &conf)
ConnectionFSC(ba::io_service &ioservice, MessageImp &imp)
uint32_t ad7719_values[kNumResistanceChannels]
A general base-class describing events issues in a state machine.
size_t fNumConsecutiveMessages
void SetupConfiguration(Configuration &conf)
int Reconnect(const EventImp &evt)
virtual void UpdateTemp(float, const vector< float > &)
The base implementation of a distributed messaging system.
void UpdateCur(float time, const vector< float > &curr)
void SetPrintUsage(const std::function< void(void)> &func)
T Get(const std::string &var)
DimDescribedService fDimTemp
boost::asio::deadline_timer fReconnectTimeout
vector< Interpolator2D::vec > fPositionsBias
void UpdateHum(float time, const vector< float > &hum)
void HandleRead(const boost::system::error_code &err, size_t bytes_received)
DimDescribedService fDimCurrent
virtual void UpdateCur(float, const vector< float > &)
int main(int argc, const char *argv[])
std::string GetString() const
int SetVerbosity(const EventImp &evt)
Extra- and interpolate in 2D.
int RunShell(Configuration &conf)
virtual void UpdateHum(float, const vector< float > &)
ConnectionDimFSC(ba::io_service &ioservice, MessageImp &imp)
double GetTempPT1000(double R) const
bool CheckEventSize(size_t has, const char *name, size_t size)
void SetPositionsBias(const vector< Interpolator2D::vec > &vec)
bool Has(const std::string &var)
void SetEndpoint(const string &url)
vector< double > fLastRms
void AddOptions(const po::options_description &opt, bool visible=true)
size_t fNumConsecutiveErrors
Warning because the service this data corrsponds to might have been last updated longer ago than Local time
Commandline parsing, resource file parsing and database access.
uint16_t adc_values[kNumVoltageChannels]
void HandleReadTimeout(const bs::error_code &error)
DimDescribedService fDimHum
StateMachineFSC(ostream &out=cout)
vector< Interpolator2D::vec > fPositionsSensors
void ConnectionEstablished()
virtual void HandleReadTimeout(const boost::system::error_code &)
void SetPositionsSensors(const vector< Interpolator2D::vec > &vec)
void UpdateTemp(float time, const vector< float > &temp)
uint16_t adc_values_checksum
static std::vector< Interpolator2D::vec > ReadGrid(const std::string &filename)
po::typed_value< bool > * po_bool(bool def=false)
void UpdateVolt(float time, const vector< float > &volt)
void Update(DimDescribedService &svc, vector< float > data, float time) const
DimDescribedService fDimVolt
bool DoParse(int argc, const char **argv, const std::function< void()> &func=std::function< void()>())
virtual void UpdateVolt(float, const vector< float > &)
uint16_t ad7719_values_checksum
int EvalOptions(Configuration &conf)
DimDescribedService fDimTemp2
virtual size_t GetSize() const