2 #include "epicsMutex.h"
3 #include "otsdaq-epics/ControlsInterfacePlugins/EpicsInterface.h"
4 #include "otsdaq/ConfigurationInterface/ConfigurationManager.h"
5 #include "otsdaq/Macros/SlowControlsPluginMacros.h"
6 #include "otsdaq/TablePlugins/SlowControlsTableBase/SlowControlsTableBase.h"
8 #pragma GCC diagnostic push
21 #pragma GCC diagnostic pop
25 #define PV_FILE_NAME std::string(getenv("SERVICE_DATA_PATH")) + "/SlowControlsDashboardData/pv_list.dat";
26 #define PV_CSV_DIR "/home/mu2edcs/mu2e-dcs/make_db/csv";
30 const std::string EpicsInterface::EPICS_NO_ALARM =
"NO_ALARM";
31 const std::string EpicsInterface::EPICS_INVALID_ALARM =
"INVALID";
32 const std::string EpicsInterface::EPICS_MINOR_ALARM =
"MINOR";
33 const std::string EpicsInterface::EPICS_MAJOR_ALARM =
"MAJOR";
37 EpicsInterface::EpicsInterface(
const std::string& pluginType,
38 const std::string& interfaceUID,
40 const std::string& controlsConfigurationPath)
42 pluginType, interfaceUID, theXDAQContextConfigTree, controlsConfigurationPath)
45 SEVCHK(ca_context_create(ca_enable_preemptive_callback),
46 "EpicsInterface::EpicsInterface() : "
47 "ca_enable_preemptive_callback_init()");
50 EpicsInterface::~EpicsInterface() { destroy(); }
52 void EpicsInterface::destroy()
55 for(
auto it = mapOfPVInfo_.begin(); it != mapOfPVInfo_.end(); it++)
57 cancelSubscriptionToChannel(it->first);
58 destroyChannel(it->first);
59 delete(it->second->parameterPtr);
61 mapOfPVInfo_.erase(it);
65 SEVCHK(ca_poll(),
"EpicsInterface::destroy() : ca_poll");
70 void EpicsInterface::initialize()
72 __GEN_COUT__ <<
"Epics Interface now initializing!";
79 std::vector<std::string> EpicsInterface::getChannelList()
81 std::vector<std::string> pvList;
82 pvList.resize(mapOfPVInfo_.size());
83 for(
auto pv : mapOfPVInfo_)
85 __GEN_COUT__ <<
"getPVList() add: " + pv.first << __E__;
86 pvList.push_back(pv.first);
91 std::string EpicsInterface::getList(
const std::string& format)
95 std::string refreshRate =
"";
103 __GEN_COUT__ <<
"Epics Interface now retrieving pvList!";
107 __GEN_COUT__ <<
"Getting list in JSON format! There are " << mapOfPVInfo_.size()
109 if(mapOfPVInfo_.size() == 0 && loginErrorMsg_ !=
"")
111 __GEN_SS__ <<
"No PVs found and error message: " << loginErrorMsg_ << __E__;
117 for(
auto it = mapOfPVInfo_.begin(); it != mapOfPVInfo_.end(); it++)
119 if(dcsArchiveDbConnStatus_ == 1)
121 res = PQexec(dcsArchiveDbConn, buffer);
125 "SELECT smpl_mode_id, smpl_per FROM channel WHERE name = '%s'",
126 (it->first).c_str());
128 if(PQresultStatus(res) == PGRES_TUPLES_OK)
133 smplMode = std::stoi(PQgetvalue(res, 0, 0));
135 catch(
const std::exception& e)
139 refreshRate = PQgetvalue(res, 0, 1);
142 <<
"getList() \"sample rate\" SELECT result: " << it->first <<
":"
143 << refreshRate <<
" (smpl_mode_id = " << smplMode <<
")" << __E__;
147 __GEN_COUT__ <<
"SELECT failed: " << PQerrorMessage(dcsArchiveDbConn)
153 pvList +=
"\"" + it->first +
"\", ";
156 pvList.resize(pvList.size() - 2);
158 __GEN_COUT__ << pvList << __E__;
164 void EpicsInterface::subscribe(
const std::string& pvName)
166 if(!checkIfPVExists(pvName))
168 __GEN_COUT__ << pvName <<
" doesn't exist!" << __E__;
171 createChannel(pvName);
173 subscribeToChannel(pvName, mapOfPVInfo_.find(pvName)->second->channelType);
180 void EpicsInterface::subscribeJSON(
const std::string& JSONNameString)
184 std::string JSON =
"{\"PVList\" :";
186 std::string pvList = JSONNameString;
188 if(pvList.find(JSON) != std::string::npos)
190 pvList = pvList.substr(pvList.find(JSON) + JSON.length(), std::string::npos);
193 pvList = pvList.substr(pvList.find(
"\"") + 1,
195 pvName = pvList.substr(0, pvList.find(
"\""));
197 pvList = pvList.substr(pvList.find(
"\"") + 1, std::string::npos);
200 if(checkIfPVExists(pvName))
202 createChannel(pvName);
203 subscribeToChannel(pvName,
204 mapOfPVInfo_.find(pvName)->second->channelType);
205 SEVCHK(ca_poll(),
"EpicsInterface::subscribeJSON : ca_poll");
209 __GEN_COUT__ << pvName <<
" not found in file! Not subscribing!" << __E__;
212 }
while(pvList.find(
",") != std::string::npos);
218 void EpicsInterface::unsubscribe(
const std::string& pvName)
220 if(!checkIfPVExists(pvName))
222 __GEN_COUT__ << pvName <<
" doesn't exist!" << __E__;
226 cancelSubscriptionToChannel(pvName);
234 void EpicsInterface::eventCallback(
struct event_handler_args eha)
237 if(eha.status == ECA_NORMAL)
240 union db_access_val* pBuf = (
union db_access_val*)eha.dbr;
243 printf(
"channel %s: ", ca_name(eha.chid));
260 case DBR_CTRL_DOUBLE:
263 __COUT__ <<
"Response Type: DBR_CTRL_DOUBLE" << __E__;
266 ->writePVControlValueToRecord(
268 ((
struct dbr_ctrl_double*)
274 __COUT__ <<
"Response Type: DBR_DOUBLE" << __E__;
277 ->writePVValueToRecord(
280 *((
double*)eha.dbr)));
285 __COUT__ <<
"Response Type: DBR_STS_STRING" << __E__;
288 ->writePVAlertToQueue(ca_name(eha.chid),
289 epicsAlarmConditionStrings[pBuf->sstrval.status],
290 epicsAlarmSeverityStrings[pBuf->sstrval.severity]);
305 __COUT__ <<
"Response Type: DBR_STS_SHORT" << __E__;
308 ->writePVAlertToQueue(ca_name(eha.chid),
309 epicsAlarmConditionStrings[pBuf->sshrtval.status],
310 epicsAlarmSeverityStrings[pBuf->sshrtval.severity]);
324 __COUT__ <<
"Response Type: DBR_STS_FLOAT" << __E__;
327 ->writePVAlertToQueue(ca_name(eha.chid),
328 epicsAlarmConditionStrings[pBuf->sfltval.status],
329 epicsAlarmSeverityStrings[pBuf->sfltval.severity]);
343 __COUT__ <<
"Response Type: DBR_STS_ENUM" << __E__;
346 ->writePVAlertToQueue(ca_name(eha.chid),
347 epicsAlarmConditionStrings[pBuf->senmval.status],
348 epicsAlarmSeverityStrings[pBuf->senmval.severity]);
361 __COUT__ <<
"Response Type: DBR_STS_CHAR" << __E__;
364 ->writePVAlertToQueue(ca_name(eha.chid),
365 epicsAlarmConditionStrings[pBuf->schrval.status],
366 epicsAlarmSeverityStrings[pBuf->schrval.severity]);
380 __COUT__ <<
"Response Type: DBR_STS_LONG" << __E__;
383 ->writePVAlertToQueue(ca_name(eha.chid),
384 epicsAlarmConditionStrings[pBuf->slngval.status],
385 epicsAlarmSeverityStrings[pBuf->slngval.severity]);
399 __COUT__ <<
"Response Type: DBR_STS_DOUBLE" << __E__;
402 ->writePVAlertToQueue(ca_name(eha.chid),
403 epicsAlarmConditionStrings[pBuf->sdblval.status],
404 epicsAlarmSeverityStrings[pBuf->sdblval.severity]);
415 if(ca_name(eha.chid))
419 __COUT__ <<
" EpicsInterface::eventCallback: PV Name = "
420 << ca_name(eha.chid) << __E__;
421 __COUT__ << (
char*)eha.dbr << __E__;
424 ->writePVValueToRecord(
433 printf(
"channel %s: get operation failed\n", ca_name(eha.chid));
438 void EpicsInterface::eventCallbackAlarm(
struct event_handler_args eha)
440 __COUT__ <<
" EpicsInterface::eventCallbackAlarm" << __E__;
442 if(eha.status == ECA_NORMAL)
444 __COUT__ <<
" EpicsInterface::eventCallbackAlarm: PV Name = " << ca_name(eha.chid)
452 void EpicsInterface::staticChannelCallbackHandler(
struct connection_handler_args cha)
454 __COUT__ <<
"webClientChannelCallbackHandler" << __E__;
460 void EpicsInterface::channelCallbackHandler(
struct connection_handler_args& cha)
463 if(cha.op == CA_OP_CONN_UP)
465 __GEN_COUT__ << pv << cha.chid <<
" connected! " << __E__;
467 mapOfPVInfo_.find(pv)->second->channelType = ca_field_type(cha.chid);
476 __GEN_COUT__ << pv <<
" disconnected!" << __E__;
481 bool EpicsInterface::checkIfPVExists(
const std::string& pvName)
485 __GEN_COUT__ <<
"EpicsInterface::checkIfPVExists(): PV Info Map Length is "
486 << mapOfPVInfo_.size() << __E__;
489 if(mapOfPVInfo_.find(pvName) != mapOfPVInfo_.end())
495 void EpicsInterface::loadListOfPVs()
497 __GEN_COUT__ <<
"LOADING LIST OF PVS!!!!";
576 if(dcsArchiveDbConnStatus_ == 1)
581 std::string cluster =
"Mu2e";
583 __GEN_COUT__ <<
"Reading database PVS List" << __E__;
584 snprintf(buffer,
sizeof(buffer),
"SELECT name FROM channel");
585 res = PQexec(dcsArchiveDbConn, buffer);
587 if(PQresultStatus(res) == PGRES_TUPLES_OK)
589 for(
int i = 0; i < PQntuples(res); i++)
591 pv_name = PQgetvalue(res, i, 0);
593 mapOfPVInfo_[pv_name] =
new PVInfo(DBR_STRING);
595 __GEN_COUT__ <<
"Empty pv name for position = " << i << __E__;
597 __GEN_COUT__ <<
"Finished reading database PVs List!" << __E__;
602 __GEN_COUT__ <<
"SELECT failed: " << PQerrorMessage(dcsArchiveDbConn)
608 __GEN_COUT__ <<
"Here is our pv list!" << __E__;
610 for(
auto pv : mapOfPVInfo_)
612 __GEN_COUT__ << pv.first << __E__;
625 __GEN_COUT__ <<
"Finished reading file and subscribing to pvs!" << __E__;
626 SEVCHK(ca_pend_event(0.0),
627 "EpicsInterface::subscribe() : ca_pend_event(0.0)");
632 void EpicsInterface::getControlValues(
const std::string& pvName)
636 __GEN_COUT__ <<
"EpicsInterface::getControlValues(" << pvName <<
")" << __E__;
638 if(!checkIfPVExists(pvName))
640 __GEN_COUT__ << pvName <<
" doesn't exist!" << __E__;
644 SEVCHK(ca_array_get_callback(
648 mapOfPVInfo_.find(pvName)->second->channelID,
651 "ca_array_get_callback");
656 void EpicsInterface::createChannel(
const std::string& pvName)
658 if(!checkIfPVExists(pvName))
660 __GEN_COUT__ << pvName <<
" doesn't exist!" << __E__;
663 __GEN_COUT__ <<
"Trying to create channel to " << pvName <<
":"
664 << mapOfPVInfo_.find(pvName)->second->channelID << __E__;
666 if(mapOfPVInfo_.find(pvName)->second != NULL)
669 if(mapOfPVInfo_.find(pvName)->second->channelID !=
674 if(ca_state(mapOfPVInfo_.find(pvName)->second->channelID) == cs_conn)
678 __GEN_COUT__ <<
"Channel to " << pvName <<
" already exists!"
686 <<
"Channel to " << pvName
687 <<
" exists, but is not connected! Destroying current channel."
690 destroyChannel(pvName);
694 if(mapOfPVInfo_.find(pvName)->second->parameterPtr == NULL)
696 mapOfPVInfo_.find(pvName)->second->parameterPtr =
701 SEVCHK(ca_create_channel(pvName.c_str(),
702 staticChannelCallbackHandler,
703 mapOfPVInfo_.find(pvName)->second->parameterPtr,
705 &(mapOfPVInfo_.find(pvName)->second->channelID)),
706 "EpicsInterface::createChannel() : ca_create_channel");
707 __GEN_COUT__ <<
"channelID: " << pvName
708 << mapOfPVInfo_.find(pvName)->second->channelID << __E__;
710 SEVCHK(ca_replace_access_rights_event(mapOfPVInfo_.find(pvName)->second->channelID,
711 accessRightsCallback),
712 "EpicsInterface::createChannel() : ca_replace_access_rights_event");
719 void EpicsInterface::destroyChannel(
const std::string& pvName)
721 if(mapOfPVInfo_.find(pvName)->second != NULL)
723 if(mapOfPVInfo_.find(pvName)->second->channelID != NULL)
725 status_ = ca_clear_channel(mapOfPVInfo_.find(pvName)->second->channelID);
726 SEVCHK(status_,
"EpicsInterface::destroyChannel() : ca_clear_channel");
727 if(status_ == ECA_NORMAL)
729 mapOfPVInfo_.find(pvName)->second->channelID = NULL;
732 __GEN_COUT__ <<
"Killed channel to " << pvName << __E__;
735 SEVCHK(ca_poll(),
"EpicsInterface::destroyChannel() : ca_poll");
741 __GEN_COUT__ <<
"No channel to " << pvName <<
" exists" << __E__;
748 void EpicsInterface::accessRightsCallback(
struct access_rights_handler_args args)
750 chid chid = args.chid;
752 printChidInfo(chid,
"EpicsInterface::createChannel() : accessRightsCallback");
755 void EpicsInterface::printChidInfo(chid chid,
const std::string& message)
757 __COUT__ << message.c_str() << __E__;
758 __COUT__ <<
"pv: " << ca_name(chid) <<
" type(" << ca_field_type(chid)
759 <<
") nelements(" << ca_element_count(chid) <<
") host("
760 << ca_host_name(chid) <<
")" << __E__;
761 __COUT__ <<
"read(" << ca_read_access(chid) <<
") write(" << ca_write_access(chid)
762 <<
") state(" << ca_state(chid) <<
")" << __E__;
765 void EpicsInterface::subscribeToChannel(
const std::string& pvName,
768 if(!checkIfPVExists(pvName))
770 __GEN_COUT__ << pvName <<
" doesn't exist!" << __E__;
775 __GEN_COUT__ <<
"Trying to subscribe to " << pvName <<
":"
776 << mapOfPVInfo_.find(pvName)->second->channelID << __E__;
779 if(mapOfPVInfo_.find(pvName)->second != NULL)
783 if(mapOfPVInfo_.find(pvName)->second->eventID !=
788 __GEN_COUT__ <<
"Already subscribed to " << pvName <<
"!" << __E__;
802 SEVCHK(ca_create_subscription(
803 dbf_type_to_DBR(mapOfPVInfo_.find(pvName)->second->channelType),
805 mapOfPVInfo_.find(pvName)->second->channelID,
806 DBE_VALUE | DBE_ALARM | DBE_PROPERTY,
809 &(mapOfPVInfo_.find(pvName)->second->eventID)),
810 "EpicsInterface::subscribeToChannel() : ca_create_subscription "
813 SEVCHK(ca_create_subscription(DBR_STS_DOUBLE,
815 mapOfPVInfo_.find(pvName)->second->channelID,
816 DBE_VALUE | DBE_ALARM | DBE_PROPERTY,
819 &(mapOfPVInfo_.find(pvName)->second->eventID)),
820 "EpicsInterface::subscribeToChannel() : ca_create_subscription "
823 SEVCHK(ca_create_subscription(DBR_CTRL_DOUBLE,
825 mapOfPVInfo_.find(pvName)->second->channelID,
826 DBE_VALUE | DBE_ALARM | DBE_PROPERTY,
829 &(mapOfPVInfo_.find(pvName)->second->eventID)),
830 "EpicsInterface::subscribeToChannel() : ca_create_subscription");
831 SEVCHK(ca_create_subscription(DBR_CTRL_DOUBLE,
833 mapOfPVInfo_.find(pvName)->second->channelID,
837 &(mapOfPVInfo_.find(pvName)->second->eventID)),
838 "EpicsInterface::subscribeToChannel() : ca_create_subscription");
842 __GEN_COUT__ <<
"EpicsInterface::subscribeToChannel: Created Subscription to "
843 << mapOfPVInfo_.find(pvName)->first <<
"!\n"
850 void EpicsInterface::cancelSubscriptionToChannel(
const std::string& pvName)
852 if(mapOfPVInfo_.find(pvName)->second != NULL)
853 if(mapOfPVInfo_.find(pvName)->second->eventID != NULL)
855 status_ = ca_clear_subscription(mapOfPVInfo_.find(pvName)->second->eventID);
857 "EpicsInterface::cancelSubscriptionToChannel() : "
858 "ca_clear_subscription");
859 if(status_ == ECA_NORMAL)
861 mapOfPVInfo_.find(pvName)->second->eventID = NULL;
864 __GEN_COUT__ <<
"Killed subscription to " << pvName << __E__;
867 SEVCHK(ca_poll(),
"EpicsInterface::cancelSubscriptionToChannel() : ca_poll");
873 __GEN_COUT__ << pvName <<
"does not have a subscription!" << __E__;
884 void EpicsInterface::readValueFromPV(
const std::string& )
893 void EpicsInterface::writePVControlValueToRecord(
894 const std::string& pvName,
897 struct dbr_ctrl_double* pdata)
901 __GEN_COUT__ <<
"Reading Control Values from " << pvName <<
"!" << __E__;
904 if(!checkIfPVExists(pvName))
906 __GEN_COUT__ << pvName <<
" doesn't exist!" << __E__;
909 mapOfPVInfo_.find(pvName)->second->settings = *pdata;
913 __GEN_COUT__ <<
"pvName: " << pvName << __E__;
914 __GEN_COUT__ <<
"status: " << pdata->status << __E__;
915 __GEN_COUT__ <<
"severity: " << pdata->severity << __E__;
916 __GEN_COUT__ <<
"units: " << pdata->units << __E__;
917 __GEN_COUT__ <<
"upper disp limit: " << (int)(pdata->upper_disp_limit) << __E__;
918 __GEN_COUT__ <<
"lower disp limit: " << pdata->lower_disp_limit << __E__;
919 __GEN_COUT__ <<
"upper alarm limit: " << pdata->upper_alarm_limit << __E__;
920 __GEN_COUT__ <<
"upper warning limit: " << pdata->upper_warning_limit << __E__;
921 __GEN_COUT__ <<
"lower warning limit: " << pdata->lower_warning_limit << __E__;
922 __GEN_COUT__ <<
"lower alarm limit: " << pdata->lower_alarm_limit << __E__;
923 __GEN_COUT__ <<
"upper control limit: " << pdata->upper_ctrl_limit << __E__;
924 __GEN_COUT__ <<
"lower control limit: " << pdata->lower_ctrl_limit << __E__;
926 __GEN_COUT__ <<
"Value: " << pdata->value << __E__;
932 void EpicsInterface::writePVValueToRecord(
const std::string& pvName,
933 const std::string& pdata)
935 std::pair<time_t, std::string> currentRecord(time(0), pdata);
937 if(!checkIfPVExists(pvName))
939 __GEN_COUT__ << pvName <<
" doesn't exist!" << __E__;
944 PVInfo* pvInfo = mapOfPVInfo_.find(pvName)->second;
946 if(pvInfo->mostRecentBufferIndex != pvInfo->
dataCache.size() - 1 &&
947 pvInfo->mostRecentBufferIndex != (
unsigned int)(-1))
949 if(pvInfo->
dataCache[pvInfo->mostRecentBufferIndex].first == currentRecord.first)
958 ++pvInfo->mostRecentBufferIndex;
959 pvInfo->
dataCache[pvInfo->mostRecentBufferIndex] = currentRecord;
964 pvInfo->mostRecentBufferIndex = 0;
971 void EpicsInterface::writePVAlertToQueue(
const std::string& pvName,
973 const char* severity)
975 if(!checkIfPVExists(pvName))
977 __GEN_COUT__ << pvName <<
" doesn't exist!" << __E__;
980 PVAlerts alert(time(0), status, severity);
981 mapOfPVInfo_.find(pvName)->second->alerts.push(alert);
990 void EpicsInterface::readPVRecord(
const std::string& pvName)
992 status_ = ca_array_get_callback(
993 dbf_type_to_DBR_STS(mapOfPVInfo_.find(pvName)->second->channelType),
994 ca_element_count(mapOfPVInfo_.find(pvName)->second->channelID),
995 mapOfPVInfo_.find(pvName)->second->channelID,
998 SEVCHK(status_,
"EpicsInterface::readPVRecord(): ca_array_get_callback");
1002 void EpicsInterface::debugConsole(
const std::string& pvName)
1004 __GEN_COUT__ <<
"==============================================================="
1007 for(
unsigned int it = 0; it < mapOfPVInfo_.find(pvName)->second->dataCache.size() - 1;
1010 if(it == mapOfPVInfo_.find(pvName)->second->mostRecentBufferIndex)
1012 __GEN_COUT__ <<
"-----------------------------------------------------------"
1016 __GEN_COUT__ <<
"Iteration: " << it <<
" | "
1017 << mapOfPVInfo_.find(pvName)->second->mostRecentBufferIndex <<
" | "
1018 << mapOfPVInfo_.find(pvName)->second->dataCache[it].second << __E__;
1019 if(it == mapOfPVInfo_.find(pvName)->second->mostRecentBufferIndex)
1021 __GEN_COUT__ <<
"-----------------------------------------------------------"
1026 __GEN_COUT__ <<
"==============================================================="
1029 __GEN_COUT__ <<
"Status: "
1030 <<
" | " << mapOfPVInfo_.find(pvName)->second->alerts.size() <<
" | "
1031 << mapOfPVInfo_.find(pvName)->second->alerts.front().status << __E__;
1032 __GEN_COUT__ <<
"Severity: "
1033 <<
" | " << mapOfPVInfo_.find(pvName)->second->alerts.size() <<
" | "
1034 << mapOfPVInfo_.find(pvName)->second->alerts.front().severity << __E__;
1035 __GEN_COUT__ <<
"==============================================================="
1042 void EpicsInterface::popQueue(
const std::string& pvName)
1046 __GEN_COUT__ <<
"EpicsInterface::popQueue() " << __E__;
1048 mapOfPVInfo_.find(pvName)->second->alerts.pop();
1050 if(mapOfPVInfo_.find(pvName)->second->alerts.empty())
1052 readPVRecord(pvName);
1053 SEVCHK(ca_poll(),
"EpicsInterface::popQueue() : ca_poll");
1059 std::array<std::string, 4> EpicsInterface::getCurrentValue(
const std::string& pvName)
1061 __GEN_COUT__ <<
"void EpicsInterface::getCurrentValue() reached" << __E__;
1063 if(mapOfPVInfo_.find(pvName) != mapOfPVInfo_.end())
1065 PVInfo* pv = mapOfPVInfo_.find(pvName)->second;
1066 std::string time, value, status, severity;
1068 int index = pv->mostRecentBufferIndex;
1070 __GEN_COUT__ << pv << index << __E__;
1072 if(0 <= index && index < pv->circularBufferSize)
1077 time = std::to_string(pv->
dataCache[index].first);
1079 status = pv->alerts.back().status;
1080 severity = pv->alerts.back().severity;
1082 else if(index == -1)
1094 severity =
"INVALID";
1098 __GEN_COUT__ <<
"Index: " << index << __E__;
1099 __GEN_COUT__ <<
"Time: " << time << __E__;
1100 __GEN_COUT__ <<
"Value: " << value << __E__;
1101 __GEN_COUT__ <<
"Status: " << status << __E__;
1102 __GEN_COUT__ <<
"Severity: " << severity << __E__;
1117 std::array<std::string, 4> currentValues = {time, value, status, severity};
1119 return currentValues;
1123 __GEN_COUT__ << pvName <<
" was not found!" << __E__;
1124 __GEN_COUT__ <<
"Trying to resubscribe to " << pvName << __E__;
1128 std::array<std::string, 4> currentValues = {
"PV Not Found",
"NF",
"N/a",
"N/a"};
1130 return currentValues;
1134 std::array<std::string, 9> EpicsInterface::getSettings(
const std::string& pvName)
1136 __GEN_COUT__ <<
"EpicsInterface::getPVSettings() reached" << __E__;
1138 if(mapOfPVInfo_.find(pvName) != mapOfPVInfo_.end())
1140 std::string units =
"DC'd", upperDisplayLimit =
"DC'd",
1141 lowerDisplayLimit =
"DC'd", upperAlarmLimit =
"DC'd",
1142 upperWarningLimit =
"DC'd", lowerWarningLimit =
"DC'd",
1143 lowerAlarmLimit =
"DC'd", upperControlLimit =
"DC'd",
1144 lowerControlLimit =
"DC'd";
1145 if(mapOfPVInfo_.find(pvName)->second != NULL)
1148 if(mapOfPVInfo_.find(pvName)->second->channelID !=
1153 dbr_ctrl_double* set = &mapOfPVInfo_.find(pvName)->second->settings;
1157 upperDisplayLimit = std::to_string(set->upper_disp_limit);
1158 lowerDisplayLimit = std::to_string(set->lower_disp_limit);
1159 upperWarningLimit = std::to_string(set->upper_warning_limit);
1160 lowerWarningLimit = std::to_string(set->lower_warning_limit);
1161 upperAlarmLimit = std::to_string(set->upper_alarm_limit);
1162 lowerAlarmLimit = std::to_string(set->lower_alarm_limit);
1163 upperControlLimit = std::to_string(set->upper_ctrl_limit);
1164 lowerControlLimit = std::to_string(set->lower_ctrl_limit);
1166 __GEN_COUT__ <<
"Units : " << units << __E__;
1167 __GEN_COUT__ <<
"Upper Display Limit: " << upperDisplayLimit << __E__;
1168 __GEN_COUT__ <<
"Lower Display Limit: " << lowerDisplayLimit << __E__;
1169 __GEN_COUT__ <<
"Upper Alarm Limit : " << upperAlarmLimit << __E__;
1170 __GEN_COUT__ <<
"Upper Warning Limit: " << upperWarningLimit << __E__;
1171 __GEN_COUT__ <<
"Lower Warning Limit: " << lowerWarningLimit << __E__;
1172 __GEN_COUT__ <<
"Lower Alarm Limit : " << lowerAlarmLimit << __E__;
1173 __GEN_COUT__ <<
"Upper Control Limit: " << upperControlLimit << __E__;
1174 __GEN_COUT__ <<
"Lower Control Limit: " << lowerControlLimit << __E__;
1177 std::array<std::string, 9> s = {units,
1191 __GEN_COUT__ << pvName <<
" was not found!" << __E__;
1192 __GEN_COUT__ <<
"Trying to resubscribe to " << pvName << __E__;
1195 std::array<std::string, 9> s = {
1196 "DC'd",
"DC'd",
"DC'd",
"DC'd",
"DC'd",
"DC'd",
"DC'd",
"DC'd",
"DC'd"};
1201 void EpicsInterface::dbSystemLogin()
1203 dcsArchiveDbConnStatus_ = 0;
1204 dcsAlarmDbConnStatus_ = 0;
1205 dcsLogDbConnStatus_ = 0;
1207 char* dbname_ =
const_cast<char*
>(
1208 getenv(
"DCS_ARCHIVE_DATABASE") ? getenv(
"DCS_ARCHIVE_DATABASE") :
"dcs_archive");
1209 char* dbhost_ =
const_cast<char*
>(
1210 getenv(
"DCS_ARCHIVE_DATABASE_HOST") ? getenv(
"DCS_ARCHIVE_DATABASE_HOST") :
"");
1211 char* dbport_ =
const_cast<char*
>(
1212 getenv(
"DCS_ARCHIVE_DATABASE_PORT") ? getenv(
"DCS_ARCHIVE_DATABASE_PORT") :
"");
1213 char* dbuser_ =
const_cast<char*
>(
1214 getenv(
"DCS_ARCHIVE_DATABASE_USER") ? getenv(
"DCS_ARCHIVE_DATABASE_USER") :
"");
1215 char* dbpwd_ =
const_cast<char*
>(
1216 getenv(
"DCS_ARCHIVE_DATABASE_PWD") ? getenv(
"DCS_ARCHIVE_DATABASE_PWD") :
"");
1219 char dcsArchiveDbConnInfo[1024];
1220 sprintf(dcsArchiveDbConnInfo,
1221 "dbname=%s host=%s port=%s \
1222 user=%s password=%s",
1230 dcsArchiveDbConn = PQconnectdb(dcsArchiveDbConnInfo);
1232 if(PQstatus(dcsArchiveDbConn) == CONNECTION_BAD)
1234 loginErrorMsg_ =
"Unable to connect to the dcs_archive database!";
1235 __GEN_COUT__ <<
"Unable to connect to the dcs_archive database!\n" << __E__;
1236 PQfinish(dcsArchiveDbConn);
1240 __GEN_COUT__ <<
"Connected to the dcs_archive database!\n" << __E__;
1241 dcsArchiveDbConnStatus_ = 1;
1245 dbname_ =
const_cast<char*
>(
1246 getenv(
"DCS_ALARM_DATABASE") ? getenv(
"DCS_ALARM_DATABASE") :
"dcs_alarm");
1247 dbhost_ =
const_cast<char*
>(
1248 getenv(
"DCS_ALARM_DATABASE_HOST") ? getenv(
"DCS_ALARM_DATABASE_HOST") :
"");
1249 dbport_ =
const_cast<char*
>(
1250 getenv(
"DCS_ALARM_DATABASE_PORT") ? getenv(
"DCS_ALARM_DATABASE_PORT") :
"");
1251 dbuser_ =
const_cast<char*
>(
1252 getenv(
"DCS_ALARM_DATABASE_USER") ? getenv(
"DCS_ALARM_DATABASE_USER") :
"");
1253 dbpwd_ =
const_cast<char*
>(
1254 getenv(
"DCS_ALARM_DATABASE_PWD") ? getenv(
"DCS_ALARM_DATABASE_PWD") :
"");
1255 char dcsAlarmDbConnInfo[1024];
1256 sprintf(dcsAlarmDbConnInfo,
1257 "dbname=%s host=%s port=%s \
1258 user=%s password=%s",
1265 dcsAlarmDbConn = PQconnectdb(dcsAlarmDbConnInfo);
1267 if(PQstatus(dcsAlarmDbConn) == CONNECTION_BAD)
1269 loginErrorMsg_ =
"Unable to connect to the dcs_alarm database!";
1270 __GEN_COUT__ <<
"Unable to connect to the dcs_alarm database!\n" << __E__;
1271 PQfinish(dcsAlarmDbConn);
1275 __GEN_COUT__ <<
"Connected to the dcs_alarm database!\n" << __E__;
1276 dcsAlarmDbConnStatus_ = 1;
1280 dbname_ =
const_cast<char*
>(getenv(
"DCS_LOG_DATABASE") ? getenv(
"DCS_LOG_DATABASE")
1282 dbhost_ =
const_cast<char*
>(
1283 getenv(
"DCS_LOG_DATABASE_HOST") ? getenv(
"DCS_LOG_DATABASE_HOST") :
"");
1284 dbport_ =
const_cast<char*
>(
1285 getenv(
"DCS_LOG_DATABASE_PORT") ? getenv(
"DCS_LOG_DATABASE_PORT") :
"");
1286 dbuser_ =
const_cast<char*
>(
1287 getenv(
"DCS_LOG_DATABASE_USER") ? getenv(
"DCS_LOG_DATABASE_USER") :
"");
1288 dbpwd_ =
const_cast<char*
>(
1289 getenv(
"DCS_LOG_DATABASE_PWD") ? getenv(
"DCS_LOG_DATABASE_PWD") :
"");
1290 char dcsLogDbConnInfo[1024];
1291 sprintf(dcsLogDbConnInfo,
1292 "dbname=%s host=%s port=%s \
1293 user=%s password=%s",
1300 dcsLogDbConn = PQconnectdb(dcsLogDbConnInfo);
1302 if(PQstatus(dcsLogDbConn) == CONNECTION_BAD)
1304 loginErrorMsg_ =
"Unable to connect to the dcs_log database!";
1305 __GEN_COUT__ <<
"Unable to connect to the dcs_log database!\n" << __E__;
1306 PQfinish(dcsLogDbConn);
1310 __GEN_COUT__ <<
"Connected to the dcs_log database!\n" << __E__;
1311 dcsLogDbConnStatus_ = 1;
1316 void EpicsInterface::dbSystemLogout()
1318 if(PQstatus(dcsArchiveDbConn) == CONNECTION_OK)
1320 PQfinish(dcsArchiveDbConn);
1321 __GEN_COUT__ <<
"DCS_ARCHIVE DB CONNECTION CLOSED\n" << __E__;
1323 if(PQstatus(dcsAlarmDbConn) == CONNECTION_OK)
1325 PQfinish(dcsAlarmDbConn);
1326 __GEN_COUT__ <<
"DCS_ALARM DB CONNECTION CLOSED\n" << __E__;
1328 if(PQstatus(dcsLogDbConn) == CONNECTION_OK)
1330 PQfinish(dcsLogDbConn);
1331 __GEN_COUT__ <<
"DCS_LOG DB CONNECTION CLOSED\n" << __E__;
1336 std::vector<std::vector<std::string>> EpicsInterface::getChannelHistory(
1337 const std::string& pvName,
int startTime,
int endTime)
1339 __GEN_COUT__ <<
"getChannelHistory() reached" << __E__;
1340 std::vector<std::vector<std::string>> history;
1342 if(mapOfPVInfo_.find(pvName) != mapOfPVInfo_.end())
1344 if(dcsArchiveDbConnStatus_ == 1)
1346 PGresult* res =
nullptr;
1352 std::string select =
1353 "SELECT FLOOR(EXTRACT(EPOCH FROM smpl_time)), float_val, "
1354 "status.name, severity.name, smpl_per "
1355 "FROM channel, sample, status, severity "
1357 "channel.channel_id = sample.channel_id "
1358 "AND sample.severity_id = severity.severity_id "
1359 "AND sample.status_id = status.status_id "
1360 "AND channel.name = \'%s\' "
1361 "AND float_val IS NOT NULL "
1362 "AND smpl_time >= TO_TIMESTAMP(\'%d\') "
1363 "AND smpl_time < TO_TIMESTAMP(\'%d\') ";
1364 if(endTime - startTime < 432000)
1365 select +=
"ORDER BY smpl_time desc";
1366 else if((endTime - startTime > 432000) && (endTime - startTime <= 864000))
1368 "AND EXTRACT(MINUTE FROM smpl_time) % 10 = 0 ORDER BY smpl_time "
1370 else if((endTime - startTime > 864000) &&
1371 (endTime - startTime <= 1296000))
1373 "AND EXTRACT(MINUTE FROM smpl_time) % 15 = 0 ORDER BY smpl_time "
1375 else if(endTime - startTime > 1296000)
1377 "AND EXTRACT(MINUTE FROM smpl_time) % 60 = 0 ORDER BY smpl_time "
1388 res = PQexec(dcsArchiveDbConn, buffer);
1390 if(PQresultStatus(res) != PGRES_TUPLES_OK)
1392 __SS__ <<
"getChannelHistory(): SELECT FROM ARCHIVER DATABASE "
1393 "FAILED!!! PQ ERROR: "
1394 << PQresultErrorMessage(res) << __E__;
1399 if(PQntuples(res) > 0)
1402 int nFields = PQnfields(res);
1403 history.resize(PQntuples(res));
1406 for(
int i = 0; i < PQntuples(res); i++)
1408 history[i].resize(nFields);
1409 for(
int j = 0; j < nFields; j++)
1411 history[i][j] = PQgetvalue(res, i, j);
1412 row.append(PQgetvalue(res, i, j));
1417 __GEN_COUT__ <<
"getChannelHistory(): row from select: " << row
1424 __SS__ <<
"getChannelHistory(): FAILING GETTING DATA FROM ARCHIVER "
1425 "DATABASE!!! PQ ERROR: "
1426 << PQresultErrorMessage(res) << __E__;
1431 catch(
const std::exception& e)
1433 ss <<
"Exception message: " << e.what();
1443 __SS__ <<
"getChannelHistory(): ARCHIVER DATABASE CONNECTION FAILED!!! "
1451 history[0] = {
"PV Not Found",
"NF",
"N/a",
"N/a"};
1452 __GEN_COUT__ <<
"getChannelHistory() pvName " << pvName <<
" was not found!"
1454 __GEN_COUT__ <<
"Trying to resubscribe to " << pvName << __E__;
1462 std::vector<std::vector<std::string>> EpicsInterface::getLastAlarms(
1463 const std::string& pvName)
1465 __GEN_COUT__ <<
"EpicsInterface::getLastAlarms() reached" << __E__;
1466 std::vector<std::vector<std::string>> alarms;
1468 if(dcsAlarmDbConnStatus_ == 1)
1470 PGresult* res =
nullptr;
1479 "SELECT pv.component_id \
1483 , status.name as status \
1484 , severity.name as severity \
1487 , pv.annunciate_ind \
1492 , pv.act_global_alarm_ind \
1493 FROM alarm_tree, pv, status, severity \
1494 WHERE pv.component_id = alarm_tree.component_id \
1495 AND pv.status_id = status.status_id \
1496 AND pv.severity_id = severity.severity_id \
1497 AND alarm_tree.name LIKE \'%%%s%%\' \
1498 ORDER BY pv.severity_id DESC;",
1501 res = PQexec(dcsAlarmDbConn, buffer);
1502 __COUT__ <<
"getLastAlarms(): SELECT pv table PQntuples(res): "
1503 << PQntuples(res) << __E__;
1505 if(PQresultStatus(res) != PGRES_TUPLES_OK)
1508 <<
"getLastAlarms(): SELECT FROM ALARM DATABASE FAILED!!! PQ ERROR: "
1509 << PQresultErrorMessage(res) << __E__;
1514 if(PQntuples(res) > 0)
1517 int nFields = PQnfields(res);
1518 alarms.resize(PQntuples(res));
1521 for(
int i = 0; i < PQntuples(res); i++)
1523 alarms[i].resize(nFields);
1524 for(
int j = 0; j < nFields; j++)
1526 alarms[i][j] = PQgetvalue(res, i, j);
1527 row.append(PQgetvalue(res, i, j));
1539 "Alarms List Not Found",
1559 __SS__ <<
"getLastAlarms(): FAILING GETTING DATA FROM ARCHIVER DATABASE!!! "
1561 << PQresultErrorMessage(res) << __E__;
1566 catch(
const std::exception& e)
1568 ss <<
"Exception message: " << e.what();
1578 __SS__ <<
"getLastAlarms(): ALARM DATABASE CONNECTION FAILED!!! " << __E__;
1585 std::vector<std::vector<std::string>> EpicsInterface::getAlarmsLog(
1586 const std::string& pvName)
1588 __GEN_COUT__ <<
"EpicsInterface::getAlarmsLog() reached" << __E__;
1589 std::vector<std::vector<std::string>> alarmsHistory;
1591 if(dcsLogDbConnStatus_ == 1)
1593 PGresult* res =
nullptr;
1606 , message_content.value \
1607 , msg_property_type.name as \"status\" \
1608 , message.severity \
1609 , message.datum as \"time\" \
1610 FROM message, message_content, msg_property_type \
1611 WHERE message.id = message_content.message_id \
1612 AND message_content.msg_property_type_id = msg_property_type.id \
1613 AND message.type = 'alarm' \
1614 AND message.severity != 'OK' \
1615 AND message.datum >= current_date -20 \
1616 AND message.name LIKE '%%%s%%' \
1617 ORDER BY message.datum DESC;",
1620 res = PQexec(dcsLogDbConn, buffer);
1621 __COUT__ <<
"getAlarmsLog(): SELECT message table PQntuples(res): "
1622 << PQntuples(res) << __E__;
1624 if(PQresultStatus(res) != PGRES_TUPLES_OK)
1626 __SS__ <<
"getAlarmsLog(): SELECT FROM ALARM LOG DATABASE FAILED!!! PQ "
1628 << PQresultErrorMessage(res) << __E__;
1633 if(PQntuples(res) > 0)
1636 int nFields = PQnfields(res);
1637 alarmsHistory.resize(PQntuples(res));
1640 for(
int i = 0; i < PQntuples(res); i++)
1642 alarmsHistory[i].resize(nFields);
1643 for(
int j = 0; j < nFields; j++)
1645 alarmsHistory[i][j] = PQgetvalue(res, i, j);
1646 row.append(PQgetvalue(res, i, j));
1655 alarmsHistory.resize(1);
1656 alarmsHistory[0] = {
1658 "Alarms List Not Found",
1670 __SS__ <<
"getAlarmsLog(): FAILING GETTING DATA FROM ARCHIVER DATABASE!!! PQ "
1672 << PQresultErrorMessage(res) << __E__;
1677 catch(
const std::exception& e)
1679 ss <<
"Exception message: " << e.what();
1689 __SS__ <<
"getAlarmsLog(): ALARM LOG DATABASE CONNECTION FAILED!!! " << __E__;
1692 return alarmsHistory;
1705 __COUT__ <<
"checkAlarm()" << __E__;
1707 auto pvIt = mapOfPVInfo_.find(pvName);
1708 if(pvIt == mapOfPVInfo_.end())
1710 __SS__ <<
"While checking for alarm status, PV name '" << pvName
1711 <<
"' was not found in PV list!" << __E__;
1715 auto valueArray = getCurrentValue(pvIt->first);
1717 std::string& time = valueArray[0];
1718 std::string& value = valueArray[1];
1719 std::string& status = valueArray[2];
1720 std::string& severity = valueArray[3];
1725 __COUTV__(severity);
1726 if(severity == EPICS_NO_ALARM || (ignoreMinor && severity == EPICS_MINOR_ALARM))
1727 return std::vector<std::string>();
1730 return std::vector<std::string>({pvIt->first, time, value, status, severity});
1737 std::vector<std::vector<std::string>> alarmReturn;
1738 std::vector<std::string> alarmRow;
1739 auto linkToAlarmsToNotify =
1740 getSelfNode().getNode(
"LinkToAlarmAlertNotificationsTable");
1742 if(!linkToAlarmsToNotify.isDisconnected())
1744 auto alarmsToNotifyGroups = linkToAlarmsToNotify.getChildren();
1746 for(
const auto& alarmsToNotifyGroup : alarmsToNotifyGroups)
1748 __COUT__ <<
"checkAlarmNotifications() alarmsToNotifyGroup: "
1749 << alarmsToNotifyGroup.first << __E__;
1751 auto alarmsToNotify =
1752 alarmsToNotifyGroup.second.getNode(
"LinkToAlarmsToMonitorTable");
1753 if(!alarmsToNotify.isDisconnected())
1755 for(
const auto& alarmToNotify : alarmsToNotify.getChildren())
1757 __COUT__ <<
"checkAlarmNotifications() alarmToNotify: "
1758 << alarmToNotify.first << __E__;
1763 checkAlarm(alarmToNotify.second.getNode(
"AlarmChannelName")
1764 .getValue<std::string>(),
1765 alarmToNotify.second.getNode(
"IgnoreMinorSeverity")
1768 catch(
const std::exception& e)
1770 __COUT__ <<
"checkAlarmNotifications() alarmToNotify: "
1771 << alarmToNotify.first <<
" not in PVs List!!!" << __E__;
1774 alarmRow.push_back(alarmToNotify.first);
1775 alarmRow.push_back(alarmsToNotifyGroup.second.getNode(
"WhoToNotify")
1776 .getValue<std::string>());
1777 alarmRow.push_back(alarmsToNotifyGroup.second.getNode(
"DoSendEmail")
1778 .getValue<std::string>());
1779 alarmRow.push_back(alarmsToNotifyGroup.first);
1780 alarmReturn.push_back(alarmRow);
1799 void EpicsInterface::handleAlarmsForFSM(
const std::string& fsmTransitionName,
1804 auto alarmsToMonitor = linkToAlarmsToMonitor.
getChildren();
1808 ss <<
"During '" << fsmTransitionName
1809 <<
"'... Alarms monitoring (count=" << alarmsToMonitor.size() <<
"):" << __E__;
1810 for(
const auto& alarmToMonitor : alarmsToMonitor)
1811 ss <<
"\t" << alarmToMonitor.first << __E__;
1814 unsigned foundCount = 0;
1815 for(
const auto& alarmToMonitor : alarmsToMonitor)
1817 std::vector<std::string> alarmReturn =
checkAlarm(
1818 alarmToMonitor.second.getNode(
"AlarmChannelName").getValue<std::string>(),
1819 alarmToMonitor.second.getNode(
"IgnoreMinorSeverity").getValue<
bool>());
1821 if(alarmReturn.size())
1823 ss <<
"Found alarm for channel '" << alarmReturn[0] <<
"' = {"
1824 <<
"time=" << alarmReturn[1] <<
", value=" << alarmReturn[2]
1825 <<
", status=" << alarmReturn[3] <<
", severity=" << alarmReturn[4]
1832 ss << __E__ <<
"Total alarms found = " << foundCount << __E__;
1835 __COUT__ << ss.str();
1838 __COUT__ <<
"Disconnected alarms to monitor!" << __E__;
1846 handleAlarmsForFSM(
"configure",
1847 getSelfNode().getNode(
"LinkToConfigureAlarmsToMonitorTable"));
1849 __COUT__ <<
"configure(): Preparing EPICS for PVs..." << __E__;
1858 slowControlsChannelsSourceTablesString =
1860 .getNode(
"SlowControlsChannelSourceTableList")
1861 .getValueWithDefault<std::string>(
"");
1863 __COUTV__(slowControlsChannelsSourceTablesString);
1865 std::vector<std::string> slowControlsChannelsSourceTables =
1869 for(
const auto& slowControlsChannelsSourceTable : slowControlsChannelsSourceTables)
1871 __COUTV__(slowControlsChannelsSourceTable);
1875 slowControlsChannelsSourceTable);
1879 __COUT__ <<
"configure(): Handling channel list change!" << __E__;
1881 std::vector<std::pair<std::string, std::vector<std::string>>> channels;
1882 slowControlsTable->getSlowControlsChannelList(channels);
1884 for(
const auto& channel : channels)
1886 std::string pvName = channel.first;
1887 std::string descr = channel.second.at(0);
1889 int smpl_mode_id = 1;
1890 double smpl_val = 0.;
1891 double smpl_per = 60.;
1892 int retent_id = 9999;
1893 double retent_val = 9999.;
1895 double low_disp_rng = 0.;
1896 double high_disp_rng = 0.;
1897 double low_warn_lmt = atof(channel.second.at(1).c_str());
1898 double high_warn_lmt = atof(channel.second.at(2).c_str());
1899 double low_alarm_lmt = atof(channel.second.at(3).c_str());
1900 double high_alarm_lmt = atof(channel.second.at(4).c_str());
1901 int prec = atoi(channel.second.at(5).c_str());
1902 std::string unit = channel.second.at(6);
1904 if(!checkIfPVExists(pvName))
1906 mapOfPVInfo_[pvName] =
new PVInfo(DBR_STRING);
1907 __COUT__ <<
"configure(): new PV '" << pvName
1908 <<
"' found! Now subscribing" << __E__;
1912 if(dcsArchiveDbConnStatus_ == 1)
1914 PGresult* res =
nullptr;
1921 "SELECT name FROM channel WHERE name = '%s';",
1924 res = PQexec(dcsArchiveDbConn, buffer);
1925 __COUT__ <<
"configure(): SELECT channel table PQntuples(res): "
1926 << PQntuples(res) << __E__;
1928 if(PQresultStatus(res) != PGRES_TUPLES_OK)
1930 __SS__ <<
"configure(): SELECT FOR DATABASE CHANNEL TABLE "
1931 "FAILED!!! PV Name: "
1932 << pvName <<
" PQ ERROR: " << PQresultErrorMessage(res)
1938 if(PQntuples(res) > 0)
1942 __COUT__ <<
"configure(): Updating PV: " << pvName
1943 <<
" in the Archiver Database channel table"
1947 "UPDATE channel SET \
1954 WHERE name = '%s';",
1964 res = PQexec(dcsArchiveDbConn, buffer);
1966 if(PQresultStatus(res) != PGRES_COMMAND_OK)
1968 __SS__ <<
"configure(): CHANNEL UPDATE INTO DATABASE "
1969 "CHANNEL TABLE FAILED!!! PV Name: "
1971 <<
" PQ ERROR: " << PQresultErrorMessage(res)
1982 __COUT__ <<
"configure(): Writing new PV in the Archiver "
1983 "Database channel table"
1987 "INSERT INTO channel( \
1996 VALUES ('%s', '%s', %d, %d, %f, %f, %d, %f);",
2006 res = PQexec(dcsArchiveDbConn, buffer);
2007 if(PQresultStatus(res) != PGRES_COMMAND_OK)
2009 __SS__ <<
"configure(): CHANNEL INSERT INTO DATABASE "
2010 "CHANNEL TABLE FAILED!!! PV Name: "
2012 <<
" PQ ERROR: " << PQresultErrorMessage(res)
2023 "SELECT channel.channel_id FROM channel, num_metadata "
2024 "WHERE channel.channel_id = num_metadata.channel_id AND "
2025 "channel.name = '%s';",
2028 res = PQexec(dcsArchiveDbConn, buffer);
2030 <<
"configure(): SELECT num_metadata table PQntuples(res): "
2031 << PQntuples(res) << __E__;
2033 if(PQresultStatus(res) != PGRES_TUPLES_OK)
2035 __SS__ <<
"configure(): SELECT FOR DATABASE NUM_METADATA "
2036 "TABLE FAILED!!! PV Name: "
2037 << pvName <<
" PQ ERROR: " << PQresultErrorMessage(res)
2043 if(PQntuples(res) > 0)
2046 std::string channel_id = PQgetvalue(res, 0, 0);
2047 __COUT__ <<
"configure(): Updating PV: " << pvName
2048 <<
" channel_id: " << channel_id
2049 <<
" in the Archiver Database num_metadata table"
2054 "UPDATE num_metadata SET \
2056 , high_disp_rng=%f \
2058 , high_warn_lmt=%f \
2059 , low_alarm_lmt=%f \
2060 , high_alarm_lmt=%f \
2063 WHERE channel_id='%s';",
2072 channel_id.c_str());
2074 res = PQexec(dcsArchiveDbConn, buffer);
2075 if(PQresultStatus(res) != PGRES_COMMAND_OK)
2077 __SS__ <<
"configure(): CHANNEL UPDATE INTO DATABASE "
2078 "NUM_METADATA TABLE FAILED!!! PV "
2079 "Name(channel_id): "
2080 << pvName <<
" " << channel_id
2081 <<
" PQ ERROR: " << PQresultErrorMessage(res)
2093 "SELECT channel_id FROM channel WHERE name = '%s';",
2096 res = PQexec(dcsArchiveDbConn, buffer);
2098 <<
"configure(): SELECT channel table to check "
2099 "channel_id for num_metadata table. PQntuples(res): "
2100 << PQntuples(res) << __E__;
2102 if(PQresultStatus(res) != PGRES_TUPLES_OK)
2104 __SS__ <<
"configure(): SELECT TO DATABASE CHANNEL TABLE "
2105 "FOR NUM_MATADATA TABLE FAILED!!! PV Name: "
2107 <<
" PQ ERROR: " << PQresultErrorMessage(res)
2113 if(PQntuples(res) > 0)
2115 std::string channel_id = PQgetvalue(res, 0, 0);
2116 __COUT__ <<
"configure(): Writing new PV in the Archiver "
2117 "Database num_metadata table"
2123 "INSERT INTO num_metadata( \
2133 VALUES ('%s',%f,%f,%f,%f,%f,%f,%d,'%s');",
2144 res = PQexec(dcsArchiveDbConn, buffer);
2145 if(PQresultStatus(res) != PGRES_COMMAND_OK)
2147 __SS__ <<
"configure(): CHANNEL INSERT INTO DATABASE "
2148 "NUM_METADATA TABLE FAILED!!! PV Name: "
2150 <<
" PQ ERROR: " << PQresultErrorMessage(res)
2159 __SS__ <<
"configure(): CHANNEL INSERT INTO DATABASE "
2160 "NUM_METADATA TABLE FAILED!!! PV Name: "
2161 << pvName <<
" NOT RECOGNIZED IN CHANNEL TABLE"
2170 __SS__ <<
"configure(): CHANNEL INSERT OR UPDATE INTO DATABASE "
2172 <<
" PQ ERROR: " << PQresultErrorMessage(res) << __E__;
2177 catch(
const std::exception& e)
2179 ss <<
"Exception message: " << e.what();
2190 __COUT_INFO__ <<
"configure(): Archiver Database connection does not "
2191 "exist, so skipping channel update."
bool isDisconnected(void) const
std::vector< std::pair< std::string, ConfigurationTree > > getChildren(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool byPriority=false, bool onlyStatusTrue=false) const
std::vector< std::string > checkAlarm(const std::string &pvName, bool ignoreMinor=false)
virtual void configure(void) override
Configure override for Epics.
std::vector< std::vector< std::string > > checkAlarmNotifications(void) override
Check Alarms from Epics.
virtual bool slowControlsChannelListHasChanged(void) const
std::vector< std::pair< time_t, std::string > > dataCache
(10, std::pair<time_t, std::string> (0, ""));
static void getVectorFromString(const std::string &inputString, std::vector< std::string > &listToReturn, const std::set< char > &delimiter={',', '|', '&'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'}, std::vector< char > *listOfDelimiters=0, bool decodeURIComponents=false)
static std::string vectorToString(const std::vector< T > &setToReturn, const std::string &delimeter=", ")