$treeview $search $mathjax $extrastylesheet
artdaq_epics_plugin
v1_02_06a
$projectbrief
|
$projectbrief
|
$searchbox |
00001 //epics_metric.cc: Epics Metric Plugin 00002 // Author: Eric Flumerfelt 00003 // Last Modified: 09/25/2015 00004 // 00005 // An implementation of the MetricPlugin interface for Epics/ChannelAccess 00006 00007 #ifndef __EPICS_METRIC__ 00008 #define __EPICS_METRIC__ 1 00009 00010 #include "artdaq-utilities/Plugins/MetricMacros.hh" 00011 #include "messagefacility/MessageLogger/MessageLogger.h" 00012 #include <unordered_map> 00013 #undef STATIC_ASSERT 00014 00015 #ifdef __clang__ 00016 #pragma clang diagnostic push 00017 #pragma clang diagnostic ignored "-Wunused-parameter" 00018 #endif 00019 #include <cadef.h> 00020 #ifdef __clang__ 00021 #pragma clang diagnostic pop 00022 #endif 00023 00027 namespace artdaq 00028 { 00032 class EpicsMetric : public MetricPlugin 00033 { 00034 private: 00035 std::string prefix_; 00036 std::unordered_map<std::string, chid> channels_; 00037 00038 bool checkChannel_(std::string name) 00039 { 00040 if (!channels_.count(name)) 00041 { 00042 chid channel; 00043 ca_search(name.c_str(), &channel); 00044 auto sts = ca_pend_io(5.0); 00045 if (sts != ECA_NORMAL) 00046 { 00047 SEVCHK(ca_clear_channel(channel), NULL); 00048 mf::LogWarning("EPICS Plugin") << "Channel " << name << " not found!"; 00049 channels_[name] = nullptr; 00050 return false; 00051 } 00052 channels_[name] = channel; 00053 return true; 00054 } 00055 return channels_[name] != nullptr; 00056 } 00057 00058 public: 00064 explicit EpicsMetric(fhicl::ParameterSet const& pset, std::string const& app_name) 00065 : MetricPlugin(pset, app_name) 00066 , prefix_(pset.get<std::string>("channel_name_prefix", "artdaq")) 00067 , channels_() {} 00068 00069 virtual ~EpicsMetric() 00070 { 00071 MetricPlugin::stopMetrics(); 00072 } 00073 00078 std::string getLibName() const override { return "epics"; } 00079 00083 void stopMetrics_() override 00084 { 00085 for (auto channel : channels_) 00086 { 00087 SEVCHK(ca_clear_channel(channel.second), NULL); 00088 } 00089 channels_.clear(); 00090 } 00091 00095 void startMetrics_() override {} 00096 00107 void sendMetric_(const std::string& name, const std::string& value, const std::string& unit) override 00108 { 00109 std::string caName = prefix_ + ":" + name; 00110 std::string tmpValue = value + " " + unit; 00111 00112 if (checkChannel_(caName)) 00113 { 00114 //DBR_STRING, 40 characters 00115 if (tmpValue.size() > 40) { tmpValue = tmpValue.erase(40); } 00116 SEVCHK(ca_put(DBR_STRING, channels_[caName], tmpValue.c_str()), NULL); 00117 SEVCHK(ca_flush_io(), NULL); 00118 } 00119 } 00120 00131 void sendMetric_(const std::string& name, const int& value, const std::string& unit) override 00132 { 00133 //DBR_LONG 00134 std::string caName = prefix_ + ":" + name; 00135 if (unit.size() > 0) 00136 { 00137 mf::LogDebug("EPICS Plugin") << "Not sure if I can send ChannelAccess Units...configure in db instead."; 00138 } 00139 00140 if (checkChannel_(caName)) 00141 { 00142 dbr_long_t val = static_cast<dbr_long_t>(value); 00143 SEVCHK(ca_put(DBR_LONG, channels_[caName], &val), NULL); 00144 SEVCHK(ca_flush_io(), NULL); 00145 } 00146 } 00147 00158 void sendMetric_(const std::string& name, const double& value, const std::string& unit) override 00159 { 00160 //DBR_DOUBLE 00161 std::string caName = prefix_ + ":" + name; 00162 if (unit.size() > 0) 00163 { 00164 mf::LogDebug("EPICS Plugin") << "Not sure if I can send ChannelAccess Units...configure in db instead."; 00165 } 00166 00167 if (checkChannel_(caName)) 00168 { 00169 dbr_double_t val = static_cast<dbr_double_t>(value); 00170 SEVCHK(ca_put(DBR_DOUBLE, channels_[caName], &val), NULL); 00171 SEVCHK(ca_flush_io(), NULL); 00172 } 00173 } 00174 00185 void sendMetric_(const std::string& name, const float& value, const std::string& unit) override 00186 { 00187 //DBR_FLOAT 00188 std::string caName = prefix_ + ":" + name; 00189 if (unit.size() > 0) 00190 { 00191 mf::LogDebug("EPICS Plugin") << "Not sure if I can send ChannelAccess Units...configure in db instead."; 00192 } 00193 00194 if (checkChannel_(caName)) 00195 { 00196 dbr_float_t val = static_cast<dbr_float_t>(value); 00197 SEVCHK(ca_put(DBR_FLOAT, channels_[caName], &val), NULL); 00198 SEVCHK(ca_flush_io(), NULL); 00199 } 00200 } 00201 00212 void sendMetric_(const std::string& name, const unsigned long int& value, const std::string& unit) override 00213 { 00214 //DBR_LONG, only unsigned type is only 16 bits, use widest integral field 00215 std::string caName = prefix_ + ":" + name; 00216 if (unit.size() > 0) 00217 { 00218 mf::LogDebug("EPICS Plugin") << "Not sure if I can send ChannelAccess Units...configure in db instead."; 00219 } 00220 00221 if (checkChannel_(caName)) 00222 { 00223 dbr_ulong_t val = static_cast<dbr_ulong_t>(value); 00224 SEVCHK(ca_put(DBR_LONG, channels_[caName], &val), NULL); 00225 SEVCHK(ca_flush_io(), NULL); 00226 } 00227 } 00228 }; 00229 } //End namespace artdaq 00230 00231 DEFINE_ARTDAQ_METRIC(artdaq::EpicsMetric) 00232 00233 #endif //End ifndef __EPICS_METRIC__