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 #include "cadef.h"
00015
00019 namespace artdaq
00020 {
00024 class EpicsMetric : public MetricPlugin
00025 {
00026 private:
00027 std::string prefix_;
00028 std::unordered_map<std::string, chid> channels_;
00029
00030 bool checkChannel_(std::string name)
00031 {
00032 if (!channels_.count(name))
00033 {
00034 chid channel;
00035 auto sts = ca_search(name.c_str(), &channel);
00036 sts = ca_pend_io(5.0);
00037 if (sts != ECA_NORMAL)
00038 {
00039 SEVCHK(ca_clear_channel(channel), NULL);
00040 mf::LogWarning("EPICS Plugin") << "Channel " << name << " not found!";
00041 channels_[name] = nullptr;
00042 return false;
00043 }
00044 channels_[name] = channel;
00045 return true;
00046 }
00047 return channels_[name] != nullptr;
00048 }
00049
00050 public:
00055 explicit EpicsMetric(fhicl::ParameterSet pset)
00056 : MetricPlugin(pset)
00057 , prefix_(pset.get<std::string>("channel_name_prefix", "artdaq"))
00058 , channels_() {}
00059
00060 virtual ~EpicsMetric()
00061 {
00062 MetricPlugin::stopMetrics();
00063 }
00064
00069 std::string getLibName() const override { return "epics"; }
00070
00074 void stopMetrics_() override
00075 {
00076 for (auto channel : channels_)
00077 {
00078 SEVCHK(ca_clear_channel(channel.second), NULL);
00079 }
00080 channels_.clear();
00081 }
00082
00086 void startMetrics_() override {}
00087
00098 void sendMetric_(const std::string& name, const std::string& value, const std::string& unit) override
00099 {
00100 std::string caName = prefix_ + ":" + name;
00101 std::string tmpValue = value + " " + unit;
00102
00103 if (checkChannel_(caName))
00104 {
00105
00106 if (tmpValue.size() > 40) { tmpValue = tmpValue.erase(40); }
00107 SEVCHK(ca_put(DBR_STRING, channels_[caName], tmpValue.c_str()), NULL);
00108 SEVCHK(ca_flush_io(), NULL);
00109 }
00110 }
00111
00122 void sendMetric_(const std::string& name, const int& value, const std::string& unit) override
00123 {
00124
00125 std::string caName = prefix_ + ":" + name;
00126 if (unit.size() > 0)
00127 {
00128 mf::LogDebug("EPICS Plugin") << "Not sure if I can send ChannelAccess Units...configure in db instead.";
00129 }
00130
00131 if (checkChannel_(caName))
00132 {
00133 dbr_long_t val = static_cast<dbr_long_t>(value);
00134 SEVCHK(ca_put(DBR_LONG, channels_[caName], &val), NULL);
00135 SEVCHK(ca_flush_io(), NULL);
00136 }
00137 }
00138
00149 void sendMetric_(const std::string& name, const double& value, const std::string& unit) override
00150 {
00151
00152 std::string caName = prefix_ + ":" + name;
00153 if (unit.size() > 0)
00154 {
00155 mf::LogDebug("EPICS Plugin") << "Not sure if I can send ChannelAccess Units...configure in db instead.";
00156 }
00157
00158 if (checkChannel_(caName))
00159 {
00160 dbr_double_t val = static_cast<dbr_double_t>(value);
00161 SEVCHK(ca_put(DBR_DOUBLE, channels_[caName], &val), NULL);
00162 SEVCHK(ca_flush_io(), NULL);
00163 }
00164 }
00165
00176 void sendMetric_(const std::string& name, const float& value, const std::string& unit) override
00177 {
00178
00179 std::string caName = prefix_ + ":" + name;
00180 if (unit.size() > 0)
00181 {
00182 mf::LogDebug("EPICS Plugin") << "Not sure if I can send ChannelAccess Units...configure in db instead.";
00183 }
00184
00185 if (checkChannel_(caName))
00186 {
00187 dbr_float_t val = static_cast<dbr_float_t>(value);
00188 SEVCHK(ca_put(DBR_FLOAT, channels_[caName], &val), NULL);
00189 SEVCHK(ca_flush_io(), NULL);
00190 }
00191 }
00192
00203 void sendMetric_(const std::string& name, const unsigned long int& value, const std::string& unit) override
00204 {
00205
00206 std::string caName = prefix_ + ":" + name;
00207 if (unit.size() > 0)
00208 {
00209 mf::LogDebug("EPICS Plugin") << "Not sure if I can send ChannelAccess Units...configure in db instead.";
00210 }
00211
00212 if (checkChannel_(caName))
00213 {
00214 dbr_ulong_t val = static_cast<dbr_ulong_t>(value);
00215 SEVCHK(ca_put(DBR_LONG, channels_[caName], &val), NULL);
00216 SEVCHK(ca_flush_io(), NULL);
00217 }
00218 }
00219 };
00220 }
00221
00222 DEFINE_ARTDAQ_METRIC(artdaq::EpicsMetric)
00223
00224 #endif //End ifndef __EPICS_METRIC__