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 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
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
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
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
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
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 }
00230
00231 DEFINE_ARTDAQ_METRIC(artdaq::EpicsMetric)
00232
00233 #endif //End ifndef __EPICS_METRIC__