00001
00002
00003
00004
00005
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 auto sts = ca_search(name.c_str(), &channel);
00044 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:
00063 explicit EpicsMetric(fhicl::ParameterSet pset)
00064 : MetricPlugin(pset)
00065 , prefix_(pset.get<std::string>("channel_name_prefix", "artdaq"))
00066 , channels_() {}
00067
00068 virtual ~EpicsMetric()
00069 {
00070 MetricPlugin::stopMetrics();
00071 }
00072
00077 std::string getLibName() const override { return "epics"; }
00078
00082 void stopMetrics_() override
00083 {
00084 for (auto channel : channels_)
00085 {
00086 SEVCHK(ca_clear_channel(channel.second), NULL);
00087 }
00088 channels_.clear();
00089 }
00090
00094 void startMetrics_() override {}
00095
00106 void sendMetric_(const std::string& name, const std::string& value, const std::string& unit) override
00107 {
00108 std::string caName = prefix_ + ":" + name;
00109 std::string tmpValue = value + " " + unit;
00110
00111 if (checkChannel_(caName))
00112 {
00113
00114 if (tmpValue.size() > 40) { tmpValue = tmpValue.erase(40); }
00115 SEVCHK(ca_put(DBR_STRING, channels_[caName], tmpValue.c_str()), NULL);
00116 SEVCHK(ca_flush_io(), NULL);
00117 }
00118 }
00119
00130 void sendMetric_(const std::string& name, const int& value, const std::string& unit) override
00131 {
00132
00133 std::string caName = prefix_ + ":" + name;
00134 if (unit.size() > 0)
00135 {
00136 mf::LogDebug("EPICS Plugin") << "Not sure if I can send ChannelAccess Units...configure in db instead.";
00137 }
00138
00139 if (checkChannel_(caName))
00140 {
00141 dbr_long_t val = static_cast<dbr_long_t>(value);
00142 SEVCHK(ca_put(DBR_LONG, channels_[caName], &val), NULL);
00143 SEVCHK(ca_flush_io(), NULL);
00144 }
00145 }
00146
00157 void sendMetric_(const std::string& name, const double& value, const std::string& unit) override
00158 {
00159
00160 std::string caName = prefix_ + ":" + name;
00161 if (unit.size() > 0)
00162 {
00163 mf::LogDebug("EPICS Plugin") << "Not sure if I can send ChannelAccess Units...configure in db instead.";
00164 }
00165
00166 if (checkChannel_(caName))
00167 {
00168 dbr_double_t val = static_cast<dbr_double_t>(value);
00169 SEVCHK(ca_put(DBR_DOUBLE, channels_[caName], &val), NULL);
00170 SEVCHK(ca_flush_io(), NULL);
00171 }
00172 }
00173
00184 void sendMetric_(const std::string& name, const float& value, const std::string& unit) override
00185 {
00186
00187 std::string caName = prefix_ + ":" + name;
00188 if (unit.size() > 0)
00189 {
00190 mf::LogDebug("EPICS Plugin") << "Not sure if I can send ChannelAccess Units...configure in db instead.";
00191 }
00192
00193 if (checkChannel_(caName))
00194 {
00195 dbr_float_t val = static_cast<dbr_float_t>(value);
00196 SEVCHK(ca_put(DBR_FLOAT, channels_[caName], &val), NULL);
00197 SEVCHK(ca_flush_io(), NULL);
00198 }
00199 }
00200
00211 void sendMetric_(const std::string& name, const unsigned long int& value, const std::string& unit) override
00212 {
00213
00214 std::string caName = prefix_ + ":" + name;
00215 if (unit.size() > 0)
00216 {
00217 mf::LogDebug("EPICS Plugin") << "Not sure if I can send ChannelAccess Units...configure in db instead.";
00218 }
00219
00220 if (checkChannel_(caName))
00221 {
00222 dbr_ulong_t val = static_cast<dbr_ulong_t>(value);
00223 SEVCHK(ca_put(DBR_LONG, channels_[caName], &val), NULL);
00224 SEVCHK(ca_flush_io(), NULL);
00225 }
00226 }
00227 };
00228 }
00229
00230 DEFINE_ARTDAQ_METRIC(artdaq::EpicsMetric)
00231
00232 #endif //End ifndef __EPICS_METRIC__