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,
39 const ConfigurationTree& theXDAQContextConfigTree,
40 const std::string& controlsConfigurationPath)
41 : SlowControlsVInterface(pluginType, interfaceUID, theXDAQContextConfigTree, controlsConfigurationPath)
44 SEVCHK(ca_context_create(ca_enable_preemptive_callback),
45 "EpicsInterface::EpicsInterface() : "
46 "ca_enable_preemptive_callback_init()");
49 EpicsInterface::~EpicsInterface() { destroy(); }
51 void EpicsInterface::destroy()
54 for(
auto it = mapOfPVInfo_.begin(); it != mapOfPVInfo_.end(); it++)
56 cancelSubscriptionToChannel(it->first);
57 destroyChannel(it->first);
58 delete(it->second->parameterPtr);
60 mapOfPVInfo_.erase(it);
64 SEVCHK(ca_poll(),
"EpicsInterface::destroy() : ca_poll");
69 void EpicsInterface::initialize()
71 __GEN_COUT__ <<
"Epics Interface now initializing!";
78 std::vector<std::string> EpicsInterface::getChannelList()
80 std::vector<std::string> pvList;
81 pvList.resize(mapOfPVInfo_.size());
82 for(
auto pv : mapOfPVInfo_)
84 __GEN_COUT__ <<
"getPVList() add: " + pv.first << __E__;
85 pvList.push_back(pv.first);
90 std::string EpicsInterface::getList(
const std::string& format)
94 std::string refreshRate =
"";
102 __GEN_COUT__ <<
"Epics Interface now retrieving pvList!";
106 __GEN_COUT__ <<
"Getting list in JSON format! There are " << mapOfPVInfo_.size() <<
" pv's.";
107 if(mapOfPVInfo_.size() == 0 && loginErrorMsg_ !=
"")
109 __GEN_SS__ <<
"No PVs found and error message: " << loginErrorMsg_ << __E__;
115 for(
auto it = mapOfPVInfo_.begin(); it != mapOfPVInfo_.end(); it++)
117 if(dcsArchiveDbConnStatus_ == 1)
119 res = PQexec(dcsArchiveDbConn, buffer);
120 snprintf(buffer,
sizeof(buffer),
"SELECT smpl_mode_id, smpl_per FROM channel WHERE name = '%s'", (it->first).c_str());
122 if(PQresultStatus(res) == PGRES_TUPLES_OK)
127 smplMode = std::stoi(PQgetvalue(res, 0, 0));
129 catch(
const std::exception& e)
133 refreshRate = PQgetvalue(res, 0, 1);
135 __GEN_COUT__ <<
"getList() \"sample rate\" SELECT result: " << it->first <<
":" << refreshRate <<
" (smpl_mode_id = " << smplMode <<
")"
140 __GEN_COUT__ <<
"SELECT failed: " << PQerrorMessage(dcsArchiveDbConn) << __E__;
145 pvList +=
"\"" + it->first +
"\", ";
148 pvList.resize(pvList.size() - 2);
150 __GEN_COUT__ << pvList << __E__;
156 void EpicsInterface::subscribe(
const std::string& pvName)
158 if(!checkIfPVExists(pvName))
160 __GEN_COUT__ << pvName <<
" doesn't exist!" << __E__;
163 createChannel(pvName);
165 subscribeToChannel(pvName, mapOfPVInfo_.find(pvName)->second->channelType);
172 void EpicsInterface::subscribeJSON(
const std::string& JSONNameString)
176 std::string JSON =
"{\"PVList\" :";
178 std::string pvList = JSONNameString;
180 if(pvList.find(JSON) != std::string::npos)
182 pvList = pvList.substr(pvList.find(JSON) + JSON.length(), std::string::npos);
185 pvList = pvList.substr(pvList.find(
"\"") + 1,
187 pvName = pvList.substr(0, pvList.find(
"\""));
189 pvList = pvList.substr(pvList.find(
"\"") + 1, std::string::npos);
192 if(checkIfPVExists(pvName))
194 createChannel(pvName);
195 subscribeToChannel(pvName, mapOfPVInfo_.find(pvName)->second->channelType);
196 SEVCHK(ca_poll(),
"EpicsInterface::subscribeJSON : ca_poll");
200 __GEN_COUT__ << pvName <<
" not found in file! Not subscribing!" << __E__;
203 }
while(pvList.find(
",") != std::string::npos);
209 void EpicsInterface::unsubscribe(
const std::string& pvName)
211 if(!checkIfPVExists(pvName))
213 __GEN_COUT__ << pvName <<
" doesn't exist!" << __E__;
217 cancelSubscriptionToChannel(pvName);
225 void EpicsInterface::eventCallback(
struct event_handler_args eha)
228 if(eha.status == ECA_NORMAL)
231 union db_access_val* pBuf = (
union db_access_val*)eha.dbr;
234 printf(
"channel %s: ", ca_name(eha.chid));
251 case DBR_CTRL_DOUBLE:
254 __COUT__ <<
"Response Type: DBR_CTRL_DOUBLE" << __E__;
257 ->writePVControlValueToRecord(ca_name(eha.chid),
258 ((
struct dbr_ctrl_double*)eha.dbr));
263 __COUT__ <<
"Response Type: DBR_DOUBLE" << __E__;
265 ((
EpicsInterface*)eha.usr)->writePVValueToRecord(ca_name(eha.chid),
266 std::to_string(*((
double*)eha.dbr)));
271 __COUT__ <<
"Response Type: DBR_STS_STRING" << __E__;
274 ->writePVAlertToQueue(ca_name(eha.chid), epicsAlarmConditionStrings[pBuf->sstrval.status], epicsAlarmSeverityStrings[pBuf->sstrval.severity]);
289 __COUT__ <<
"Response Type: DBR_STS_SHORT" << __E__;
292 ->writePVAlertToQueue(ca_name(eha.chid), epicsAlarmConditionStrings[pBuf->sshrtval.status], epicsAlarmSeverityStrings[pBuf->sshrtval.severity]);
306 __COUT__ <<
"Response Type: DBR_STS_FLOAT" << __E__;
309 ->writePVAlertToQueue(ca_name(eha.chid), epicsAlarmConditionStrings[pBuf->sfltval.status], epicsAlarmSeverityStrings[pBuf->sfltval.severity]);
323 __COUT__ <<
"Response Type: DBR_STS_ENUM" << __E__;
326 ->writePVAlertToQueue(ca_name(eha.chid), epicsAlarmConditionStrings[pBuf->senmval.status], epicsAlarmSeverityStrings[pBuf->senmval.severity]);
339 __COUT__ <<
"Response Type: DBR_STS_CHAR" << __E__;
342 ->writePVAlertToQueue(ca_name(eha.chid), epicsAlarmConditionStrings[pBuf->schrval.status], epicsAlarmSeverityStrings[pBuf->schrval.severity]);
356 __COUT__ <<
"Response Type: DBR_STS_LONG" << __E__;
359 ->writePVAlertToQueue(ca_name(eha.chid), epicsAlarmConditionStrings[pBuf->slngval.status], epicsAlarmSeverityStrings[pBuf->slngval.severity]);
373 __COUT__ <<
"Response Type: DBR_STS_DOUBLE" << __E__;
376 ->writePVAlertToQueue(ca_name(eha.chid), epicsAlarmConditionStrings[pBuf->sdblval.status], epicsAlarmSeverityStrings[pBuf->sdblval.severity]);
387 if(ca_name(eha.chid))
391 __COUT__ <<
" EpicsInterface::eventCallback: PV Name = " << ca_name(eha.chid) << __E__;
392 __COUT__ << (
char*)eha.dbr << __E__;
394 ((
EpicsInterface*)eha.usr)->writePVValueToRecord(ca_name(eha.chid),
402 printf(
"channel %s: get operation failed\n", ca_name(eha.chid));
407 void EpicsInterface::eventCallbackAlarm(
struct event_handler_args eha)
409 __COUT__ <<
" EpicsInterface::eventCallbackAlarm" << __E__;
411 if(eha.status == ECA_NORMAL) {
412 __COUT__ <<
" EpicsInterface::eventCallbackAlarm: PV Name = " << ca_name(eha.chid) << __E__;
418 void EpicsInterface::staticChannelCallbackHandler(
struct connection_handler_args cha)
420 __COUT__ <<
"webClientChannelCallbackHandler" << __E__;
426 void EpicsInterface::channelCallbackHandler(
struct connection_handler_args& cha)
429 if(cha.op == CA_OP_CONN_UP)
431 __GEN_COUT__ << pv << cha.chid <<
" connected! " << __E__;
433 mapOfPVInfo_.find(pv)->second->channelType = ca_field_type(cha.chid);
442 __GEN_COUT__ << pv <<
" disconnected!" << __E__;
447 bool EpicsInterface::checkIfPVExists(
const std::string& pvName)
451 __GEN_COUT__ <<
"EpicsInterface::checkIfPVExists(): PV Info Map Length is " << mapOfPVInfo_.size() << __E__;
454 if(mapOfPVInfo_.find(pvName) != mapOfPVInfo_.end())
460 void EpicsInterface::loadListOfPVs()
462 __GEN_COUT__ <<
"LOADING LIST OF PVS!!!!";
541 if(dcsArchiveDbConnStatus_ == 1)
546 std::string cluster =
"Mu2e";
548 __GEN_COUT__ <<
"Reading database PVS List" << __E__;
549 snprintf(buffer,
sizeof(buffer),
"SELECT name FROM channel");
550 res = PQexec(dcsArchiveDbConn, buffer);
552 if(PQresultStatus(res) == PGRES_TUPLES_OK)
554 for(
int i = 0; i < PQntuples(res); i++)
556 pv_name = PQgetvalue(res, i, 0);
558 mapOfPVInfo_[pv_name] =
new PVInfo(DBR_STRING);
560 __GEN_COUT__ <<
"Empty pv name for position = " << i << __E__;
562 __GEN_COUT__ <<
"Finished reading database PVs List!" << __E__;
567 __GEN_COUT__ <<
"SELECT failed: " << PQerrorMessage(dcsArchiveDbConn) << __E__;
572 __GEN_COUT__ <<
"Here is our pv list!" << __E__;
574 for(
auto pv : mapOfPVInfo_)
576 __GEN_COUT__ << pv.first << __E__;
589 __GEN_COUT__ <<
"Finished reading file and subscribing to pvs!" << __E__;
590 SEVCHK(ca_pend_event(0.0),
591 "EpicsInterface::subscribe() : ca_pend_event(0.0)");
596 void EpicsInterface::getControlValues(
const std::string& pvName)
600 __GEN_COUT__ <<
"EpicsInterface::getControlValues(" << pvName <<
")" << __E__;
602 if(!checkIfPVExists(pvName))
604 __GEN_COUT__ << pvName <<
" doesn't exist!" << __E__;
608 SEVCHK(ca_array_get_callback(
612 mapOfPVInfo_.find(pvName)->second->channelID,
615 "ca_array_get_callback");
620 void EpicsInterface::createChannel(
const std::string& pvName)
622 if(!checkIfPVExists(pvName))
624 __GEN_COUT__ << pvName <<
" doesn't exist!" << __E__;
627 __GEN_COUT__ <<
"Trying to create channel to " << pvName <<
":" << mapOfPVInfo_.find(pvName)->second->channelID << __E__;
629 if(mapOfPVInfo_.find(pvName)->second != NULL)
632 if(mapOfPVInfo_.find(pvName)->second->channelID != NULL)
636 if(ca_state(mapOfPVInfo_.find(pvName)->second->channelID) == cs_conn)
640 __GEN_COUT__ <<
"Channel to " << pvName <<
" already exists!" << __E__;
646 __GEN_COUT__ <<
"Channel to " << pvName <<
" exists, but is not connected! Destroying current channel." << __E__;
648 destroyChannel(pvName);
652 if(mapOfPVInfo_.find(pvName)->second->parameterPtr == NULL)
660 pvName.c_str(), staticChannelCallbackHandler, mapOfPVInfo_.find(pvName)->second->parameterPtr, 0, &(mapOfPVInfo_.find(pvName)->second->channelID)),
661 "EpicsInterface::createChannel() : ca_create_channel");
662 __GEN_COUT__ <<
"channelID: " << pvName << mapOfPVInfo_.find(pvName)->second->channelID << __E__;
664 SEVCHK(ca_replace_access_rights_event(mapOfPVInfo_.find(pvName)->second->channelID, accessRightsCallback),
665 "EpicsInterface::createChannel() : ca_replace_access_rights_event");
672 void EpicsInterface::destroyChannel(
const std::string& pvName)
674 if(mapOfPVInfo_.find(pvName)->second != NULL)
676 if(mapOfPVInfo_.find(pvName)->second->channelID != NULL)
678 status_ = ca_clear_channel(mapOfPVInfo_.find(pvName)->second->channelID);
679 SEVCHK(status_,
"EpicsInterface::destroyChannel() : ca_clear_channel");
680 if(status_ == ECA_NORMAL)
682 mapOfPVInfo_.find(pvName)->second->channelID = NULL;
685 __GEN_COUT__ <<
"Killed channel to " << pvName << __E__;
688 SEVCHK(ca_poll(),
"EpicsInterface::destroyChannel() : ca_poll");
694 __GEN_COUT__ <<
"No channel to " << pvName <<
" exists" << __E__;
701 void EpicsInterface::accessRightsCallback(
struct access_rights_handler_args args)
703 chid chid = args.chid;
705 printChidInfo(chid,
"EpicsInterface::createChannel() : accessRightsCallback");
708 void EpicsInterface::printChidInfo(chid chid,
const std::string& message)
710 __COUT__ << message.c_str() << __E__;
711 __COUT__ <<
"pv: " << ca_name(chid) <<
" type(" << ca_field_type(chid) <<
") nelements(" << ca_element_count(chid) <<
") host(" << ca_host_name(chid) <<
")"
713 __COUT__ <<
"read(" << ca_read_access(chid) <<
") write(" << ca_write_access(chid) <<
") state(" << ca_state(chid) <<
")" << __E__;
716 void EpicsInterface::subscribeToChannel(
const std::string& pvName, chtype )
718 if(!checkIfPVExists(pvName))
720 __GEN_COUT__ << pvName <<
" doesn't exist!" << __E__;
725 __GEN_COUT__ <<
"Trying to subscribe to " << pvName <<
":" << mapOfPVInfo_.find(pvName)->second->channelID << __E__;
728 if(mapOfPVInfo_.find(pvName)->second != NULL)
732 if(mapOfPVInfo_.find(pvName)->second->eventID != NULL)
736 __GEN_COUT__ <<
"Already subscribed to " << pvName <<
"!" << __E__;
750 SEVCHK(ca_create_subscription(dbf_type_to_DBR(mapOfPVInfo_.find(pvName)->second->channelType),
752 mapOfPVInfo_.find(pvName)->second->channelID,
753 DBE_VALUE | DBE_ALARM | DBE_PROPERTY,
756 &(mapOfPVInfo_.find(pvName)->second->eventID)),
757 "EpicsInterface::subscribeToChannel() : ca_create_subscription "
760 SEVCHK(ca_create_subscription(DBR_STS_DOUBLE,
762 mapOfPVInfo_.find(pvName)->second->channelID,
763 DBE_VALUE | DBE_ALARM | DBE_PROPERTY,
766 &(mapOfPVInfo_.find(pvName)->second->eventID)),
767 "EpicsInterface::subscribeToChannel() : ca_create_subscription "
770 SEVCHK(ca_create_subscription(DBR_CTRL_DOUBLE,
772 mapOfPVInfo_.find(pvName)->second->channelID,
773 DBE_VALUE | DBE_ALARM | DBE_PROPERTY,
776 &(mapOfPVInfo_.find(pvName)->second->eventID)),
777 "EpicsInterface::subscribeToChannel() : ca_create_subscription");
778 SEVCHK(ca_create_subscription(DBR_CTRL_DOUBLE,
780 mapOfPVInfo_.find(pvName)->second->channelID,
784 &(mapOfPVInfo_.find(pvName)->second->eventID)),
785 "EpicsInterface::subscribeToChannel() : ca_create_subscription");
789 __GEN_COUT__ <<
"EpicsInterface::subscribeToChannel: Created Subscription to " << mapOfPVInfo_.find(pvName)->first <<
"!\n" << __E__;
795 void EpicsInterface::cancelSubscriptionToChannel(
const std::string& pvName)
797 if(mapOfPVInfo_.find(pvName)->second != NULL)
798 if(mapOfPVInfo_.find(pvName)->second->eventID != NULL)
800 status_ = ca_clear_subscription(mapOfPVInfo_.find(pvName)->second->eventID);
802 "EpicsInterface::cancelSubscriptionToChannel() : "
803 "ca_clear_subscription");
804 if(status_ == ECA_NORMAL)
806 mapOfPVInfo_.find(pvName)->second->eventID = NULL;
809 __GEN_COUT__ <<
"Killed subscription to " << pvName << __E__;
812 SEVCHK(ca_poll(),
"EpicsInterface::cancelSubscriptionToChannel() : ca_poll");
818 __GEN_COUT__ << pvName <<
"does not have a subscription!" << __E__;
829 void EpicsInterface::readValueFromPV(
const std::string& )
838 void EpicsInterface::writePVControlValueToRecord(
const std::string& pvName,
841 struct dbr_ctrl_double* pdata)
845 __GEN_COUT__ <<
"Reading Control Values from " << pvName <<
"!" << __E__;
848 if(!checkIfPVExists(pvName))
850 __GEN_COUT__ << pvName <<
" doesn't exist!" << __E__;
853 mapOfPVInfo_.find(pvName)->second->settings = *pdata;
857 __GEN_COUT__ <<
"pvName: " << pvName << __E__;
858 __GEN_COUT__ <<
"status: " << pdata->status << __E__;
859 __GEN_COUT__ <<
"severity: " << pdata->severity << __E__;
860 __GEN_COUT__ <<
"units: " << pdata->units << __E__;
861 __GEN_COUT__ <<
"upper disp limit: " << (int)(pdata->upper_disp_limit) << __E__;
862 __GEN_COUT__ <<
"lower disp limit: " << pdata->lower_disp_limit << __E__;
863 __GEN_COUT__ <<
"upper alarm limit: " << pdata->upper_alarm_limit << __E__;
864 __GEN_COUT__ <<
"upper warning limit: " << pdata->upper_warning_limit << __E__;
865 __GEN_COUT__ <<
"lower warning limit: " << pdata->lower_warning_limit << __E__;
866 __GEN_COUT__ <<
"lower alarm limit: " << pdata->lower_alarm_limit << __E__;
867 __GEN_COUT__ <<
"upper control limit: " << pdata->upper_ctrl_limit << __E__;
868 __GEN_COUT__ <<
"lower control limit: " << pdata->lower_ctrl_limit << __E__;
870 __GEN_COUT__ <<
"Value: " << pdata->value << __E__;
876 void EpicsInterface::writePVValueToRecord(
const std::string& pvName,
const std::string& pdata)
878 std::pair<time_t, std::string> currentRecord(time(0), pdata);
880 if(!checkIfPVExists(pvName))
882 __GEN_COUT__ << pvName <<
" doesn't exist!" << __E__;
887 PVInfo* pvInfo = mapOfPVInfo_.find(pvName)->second;
889 if(pvInfo->mostRecentBufferIndex != pvInfo->
dataCache.size() - 1 && pvInfo->mostRecentBufferIndex != (
unsigned int)(-1))
891 if(pvInfo->
dataCache[pvInfo->mostRecentBufferIndex].first == currentRecord.first)
900 ++pvInfo->mostRecentBufferIndex;
901 pvInfo->
dataCache[pvInfo->mostRecentBufferIndex] = currentRecord;
906 pvInfo->mostRecentBufferIndex = 0;
913 void EpicsInterface::writePVAlertToQueue(
const std::string& pvName,
const char* status,
const char* severity)
915 if(!checkIfPVExists(pvName))
917 __GEN_COUT__ << pvName <<
" doesn't exist!" << __E__;
920 PVAlerts alert(time(0), status, severity);
921 mapOfPVInfo_.find(pvName)->second->alerts.push(alert);
930 void EpicsInterface::readPVRecord(
const std::string& pvName)
932 status_ = ca_array_get_callback(dbf_type_to_DBR_STS(mapOfPVInfo_.find(pvName)->second->channelType),
933 ca_element_count(mapOfPVInfo_.find(pvName)->second->channelID),
934 mapOfPVInfo_.find(pvName)->second->channelID,
937 SEVCHK(status_,
"EpicsInterface::readPVRecord(): ca_array_get_callback");
941 void EpicsInterface::debugConsole(
const std::string& pvName)
943 __GEN_COUT__ <<
"==============================================================="
946 for(
unsigned int it = 0; it < mapOfPVInfo_.find(pvName)->second->dataCache.size() - 1; it++)
948 if(it == mapOfPVInfo_.find(pvName)->second->mostRecentBufferIndex)
950 __GEN_COUT__ <<
"-----------------------------------------------------------"
954 __GEN_COUT__ <<
"Iteration: " << it <<
" | " << mapOfPVInfo_.find(pvName)->second->mostRecentBufferIndex <<
" | "
955 << mapOfPVInfo_.find(pvName)->second->dataCache[it].second << __E__;
956 if(it == mapOfPVInfo_.find(pvName)->second->mostRecentBufferIndex)
958 __GEN_COUT__ <<
"-----------------------------------------------------------"
963 __GEN_COUT__ <<
"==============================================================="
966 __GEN_COUT__ <<
"Status: "
967 <<
" | " << mapOfPVInfo_.find(pvName)->second->alerts.size() <<
" | " << mapOfPVInfo_.find(pvName)->second->alerts.front().status << __E__;
968 __GEN_COUT__ <<
"Severity: "
969 <<
" | " << mapOfPVInfo_.find(pvName)->second->alerts.size() <<
" | " << mapOfPVInfo_.find(pvName)->second->alerts.front().severity << __E__;
970 __GEN_COUT__ <<
"==============================================================="
977 void EpicsInterface::popQueue(
const std::string& pvName)
981 __GEN_COUT__ <<
"EpicsInterface::popQueue() " << __E__;
983 mapOfPVInfo_.find(pvName)->second->alerts.pop();
985 if(mapOfPVInfo_.find(pvName)->second->alerts.empty())
987 readPVRecord(pvName);
988 SEVCHK(ca_poll(),
"EpicsInterface::popQueue() : ca_poll");
994 std::array<std::string, 4> EpicsInterface::getCurrentValue(
const std::string& pvName)
996 __GEN_COUT__ <<
"void EpicsInterface::getCurrentValue() reached" << __E__;
998 if(mapOfPVInfo_.find(pvName) != mapOfPVInfo_.end())
1000 PVInfo* pv = mapOfPVInfo_.find(pvName)->second;
1001 std::string time, value, status, severity;
1003 int index = pv->mostRecentBufferIndex;
1005 __GEN_COUT__ << pv << index << __E__;
1007 if(0 <= index && index < pv->circularBufferSize)
1012 time = std::to_string(pv->
dataCache[index].first);
1014 status = pv->alerts.back().status;
1015 severity = pv->alerts.back().severity;
1017 else if(index == -1)
1029 severity =
"INVALID";
1033 __GEN_COUT__ <<
"Index: " << index << __E__;
1034 __GEN_COUT__ <<
"Time: " << time << __E__;
1035 __GEN_COUT__ <<
"Value: " << value << __E__;
1036 __GEN_COUT__ <<
"Status: " << status << __E__;
1037 __GEN_COUT__ <<
"Severity: " << severity << __E__;
1052 std::array<std::string, 4> currentValues = {time, value, status, severity};
1054 return currentValues;
1058 __GEN_COUT__ << pvName <<
" was not found!" << __E__;
1059 __GEN_COUT__ <<
"Trying to resubscribe to " << pvName << __E__;
1063 std::array<std::string, 4> currentValues = {
"PV Not Found",
"NF",
"N/a",
"N/a"};
1065 return currentValues;
1069 std::array<std::string, 9> EpicsInterface::getSettings(
const std::string& pvName)
1071 __GEN_COUT__ <<
"EpicsInterface::getPVSettings() reached" << __E__;
1073 if(mapOfPVInfo_.find(pvName) != mapOfPVInfo_.end())
1075 std::string units =
"DC'd", upperDisplayLimit =
"DC'd", lowerDisplayLimit =
"DC'd", upperAlarmLimit =
"DC'd", upperWarningLimit =
"DC'd",
1076 lowerWarningLimit =
"DC'd", lowerAlarmLimit =
"DC'd", upperControlLimit =
"DC'd", lowerControlLimit =
"DC'd";
1077 if(mapOfPVInfo_.find(pvName)->second != NULL)
1080 if(mapOfPVInfo_.find(pvName)->second->channelID != NULL)
1084 dbr_ctrl_double* set = &mapOfPVInfo_.find(pvName)->second->settings;
1088 upperDisplayLimit = std::to_string(set->upper_disp_limit);
1089 lowerDisplayLimit = std::to_string(set->lower_disp_limit);
1090 upperWarningLimit = std::to_string(set->upper_warning_limit);
1091 lowerWarningLimit = std::to_string(set->lower_warning_limit);
1092 upperAlarmLimit = std::to_string(set->upper_alarm_limit);
1093 lowerAlarmLimit = std::to_string(set->lower_alarm_limit);
1094 upperControlLimit = std::to_string(set->upper_ctrl_limit);
1095 lowerControlLimit = std::to_string(set->lower_ctrl_limit);
1097 __GEN_COUT__ <<
"Units : " << units << __E__;
1098 __GEN_COUT__ <<
"Upper Display Limit: " << upperDisplayLimit << __E__;
1099 __GEN_COUT__ <<
"Lower Display Limit: " << lowerDisplayLimit << __E__;
1100 __GEN_COUT__ <<
"Upper Alarm Limit : " << upperAlarmLimit << __E__;
1101 __GEN_COUT__ <<
"Upper Warning Limit: " << upperWarningLimit << __E__;
1102 __GEN_COUT__ <<
"Lower Warning Limit: " << lowerWarningLimit << __E__;
1103 __GEN_COUT__ <<
"Lower Alarm Limit : " << lowerAlarmLimit << __E__;
1104 __GEN_COUT__ <<
"Upper Control Limit: " << upperControlLimit << __E__;
1105 __GEN_COUT__ <<
"Lower Control Limit: " << lowerControlLimit << __E__;
1108 std::array<std::string, 9> s = {units,
1122 __GEN_COUT__ << pvName <<
" was not found!" << __E__;
1123 __GEN_COUT__ <<
"Trying to resubscribe to " << pvName << __E__;
1126 std::array<std::string, 9> s = {
"DC'd",
"DC'd",
"DC'd",
"DC'd",
"DC'd",
"DC'd",
"DC'd",
"DC'd",
"DC'd"};
1131 void EpicsInterface::dbSystemLogin()
1133 dcsArchiveDbConnStatus_ = 0;
1134 dcsAlarmDbConnStatus_ = 0;
1135 dcsLogDbConnStatus_ = 0;
1137 char* dbname_ =
const_cast<char*
>(getenv(
"DCS_ARCHIVE_DATABASE") ? getenv(
"DCS_ARCHIVE_DATABASE") :
"dcs_archive");
1138 char* dbhost_ =
const_cast<char*
>(getenv(
"DCS_ARCHIVE_DATABASE_HOST") ? getenv(
"DCS_ARCHIVE_DATABASE_HOST") :
"");
1139 char* dbport_ =
const_cast<char*
>(getenv(
"DCS_ARCHIVE_DATABASE_PORT") ? getenv(
"DCS_ARCHIVE_DATABASE_PORT") :
"");
1140 char* dbuser_ =
const_cast<char*
>(getenv(
"DCS_ARCHIVE_DATABASE_USER") ? getenv(
"DCS_ARCHIVE_DATABASE_USER") :
"");
1141 char* dbpwd_ =
const_cast<char*
>(getenv(
"DCS_ARCHIVE_DATABASE_PWD") ? getenv(
"DCS_ARCHIVE_DATABASE_PWD") :
"");
1144 char dcsArchiveDbConnInfo[1024];
1145 sprintf(dcsArchiveDbConnInfo,
1146 "dbname=%s host=%s port=%s \
1147 user=%s password=%s",
1155 dcsArchiveDbConn = PQconnectdb(dcsArchiveDbConnInfo);
1157 if(PQstatus(dcsArchiveDbConn) == CONNECTION_BAD)
1159 loginErrorMsg_ =
"Unable to connect to the dcs_archive database!";
1160 __GEN_COUT__ <<
"Unable to connect to the dcs_archive database!\n" << __E__;
1161 PQfinish(dcsArchiveDbConn);
1165 __GEN_COUT__ <<
"Connected to the dcs_archive database!\n" << __E__;
1166 dcsArchiveDbConnStatus_ = 1;
1170 dbname_ =
const_cast<char*
>(getenv(
"DCS_ALARM_DATABASE") ? getenv(
"DCS_ALARM_DATABASE") :
"dcs_alarm");
1171 dbhost_ =
const_cast<char*
>(getenv(
"DCS_ALARM_DATABASE_HOST") ? getenv(
"DCS_ALARM_DATABASE_HOST") :
"");
1172 dbport_ =
const_cast<char*
>(getenv(
"DCS_ALARM_DATABASE_PORT") ? getenv(
"DCS_ALARM_DATABASE_PORT") :
"");
1173 dbuser_ =
const_cast<char*
>(getenv(
"DCS_ALARM_DATABASE_USER") ? getenv(
"DCS_ALARM_DATABASE_USER") :
"");
1174 dbpwd_ =
const_cast<char*
>(getenv(
"DCS_ALARM_DATABASE_PWD") ? getenv(
"DCS_ALARM_DATABASE_PWD") :
"");
1175 char dcsAlarmDbConnInfo[1024];
1176 sprintf(dcsAlarmDbConnInfo,
1177 "dbname=%s host=%s port=%s \
1178 user=%s password=%s",
1185 dcsAlarmDbConn = PQconnectdb(dcsAlarmDbConnInfo);
1187 if(PQstatus(dcsAlarmDbConn) == CONNECTION_BAD)
1189 loginErrorMsg_ =
"Unable to connect to the dcs_alarm database!";
1190 __GEN_COUT__ <<
"Unable to connect to the dcs_alarm database!\n" << __E__;
1191 PQfinish(dcsAlarmDbConn);
1195 __GEN_COUT__ <<
"Connected to the dcs_alarm database!\n" << __E__;
1196 dcsAlarmDbConnStatus_ = 1;
1200 dbname_ =
const_cast<char*
>(getenv(
"DCS_LOG_DATABASE") ? getenv(
"DCS_LOG_DATABASE") :
"dcs_log");
1201 dbhost_ =
const_cast<char*
>(getenv(
"DCS_LOG_DATABASE_HOST") ? getenv(
"DCS_LOG_DATABASE_HOST") :
"");
1202 dbport_ =
const_cast<char*
>(getenv(
"DCS_LOG_DATABASE_PORT") ? getenv(
"DCS_LOG_DATABASE_PORT") :
"");
1203 dbuser_ =
const_cast<char*
>(getenv(
"DCS_LOG_DATABASE_USER") ? getenv(
"DCS_LOG_DATABASE_USER") :
"");
1204 dbpwd_ =
const_cast<char*
>(getenv(
"DCS_LOG_DATABASE_PWD") ? getenv(
"DCS_LOG_DATABASE_PWD") :
"");
1205 char dcsLogDbConnInfo[1024];
1206 sprintf(dcsLogDbConnInfo,
1207 "dbname=%s host=%s port=%s \
1208 user=%s password=%s",
1215 dcsLogDbConn = PQconnectdb(dcsLogDbConnInfo);
1217 if(PQstatus(dcsLogDbConn) == CONNECTION_BAD)
1219 loginErrorMsg_ =
"Unable to connect to the dcs_log database!";
1220 __GEN_COUT__ <<
"Unable to connect to the dcs_log database!\n" << __E__;
1221 PQfinish(dcsLogDbConn);
1225 __GEN_COUT__ <<
"Connected to the dcs_log database!\n" << __E__;
1226 dcsLogDbConnStatus_ = 1;
1231 void EpicsInterface::dbSystemLogout()
1233 if(PQstatus(dcsArchiveDbConn) == CONNECTION_OK)
1235 PQfinish(dcsArchiveDbConn);
1236 __GEN_COUT__ <<
"DCS_ARCHIVE DB CONNECTION CLOSED\n" << __E__;
1238 if(PQstatus(dcsAlarmDbConn) == CONNECTION_OK)
1240 PQfinish(dcsAlarmDbConn);
1241 __GEN_COUT__ <<
"DCS_ALARM DB CONNECTION CLOSED\n" << __E__;
1243 if(PQstatus(dcsLogDbConn) == CONNECTION_OK)
1245 PQfinish(dcsLogDbConn);
1246 __GEN_COUT__ <<
"DCS_LOG DB CONNECTION CLOSED\n" << __E__;
1251 std::vector<std::vector<std::string>> EpicsInterface::getChannelHistory(
const std::string& pvName,
int startTime,
int endTime)
1253 __GEN_COUT__ <<
"getChannelHistory() reached" << __E__;
1254 std::vector<std::vector<std::string>> history;
1256 if(mapOfPVInfo_.find(pvName) != mapOfPVInfo_.end())
1258 if(dcsArchiveDbConnStatus_ == 1)
1260 PGresult* res =
nullptr;
1269 "SELECT FLOOR(EXTRACT(EPOCH FROM smpl_time)), float_val, status.name, "
1270 "severity.name, smpl_per FROM channel, sample, status, severity WHERE "
1271 "channel.channel_id = sample.channel_id AND sample.severity_id = "
1272 "severity.severity_id AND sample.status_id = status.status_id AND "
1273 "channel.name = \'%s\' AND smpl_time >= TO_TIMESTAMP(\'%d\') AND smpl_time < TO_TIMESTAMP(\'%d\') ORDER BY smpl_time desc",
1274 pvName.c_str(), startTime, endTime);
1276 res = PQexec(dcsArchiveDbConn, buffer);
1278 if(PQresultStatus(res) != PGRES_TUPLES_OK)
1280 __SS__ <<
"getChannelHistory(): SELECT FROM ARCHIVER DATABASE FAILED!!! PQ ERROR: " << PQresultErrorMessage(res) << __E__;
1285 if(PQntuples(res) > 0)
1288 int nFields = PQnfields(res);
1289 history.resize(PQntuples(res));
1292 for(
int i = 0; i < PQntuples(res); i++)
1294 history[i].resize(nFields);
1295 for(
int j = 0; j < nFields; j++)
1297 history[i][j] = PQgetvalue(res, i, j);
1298 row.append(PQgetvalue(res, i, j));
1303 __GEN_COUT__ <<
"getChannelHistory(): row from select: " << row << __E__;
1309 __SS__ <<
"getChannelHistory(): FAILING GETTING DATA FROM ARCHIVER DATABASE!!! PQ ERROR: " << PQresultErrorMessage(res) << __E__;
1311 catch(
const std::exception &e)
1313 ss <<
"Exception message: " << e.what();
1321 __SS__ <<
"getChannelHistory(): ARCHIVER DATABASE CONNECTION FAILED!!! " << __E__;
1328 history[0] = {
"PV Not Found",
"NF",
"N/a",
"N/a"};
1329 __GEN_COUT__ <<
"getChannelHistory() pvName " << pvName <<
" was not found!" << __E__;
1330 __GEN_COUT__ <<
"Trying to resubscribe to " << pvName << __E__;
1338 std::vector<std::vector<std::string>> EpicsInterface::getLastAlarms(
const std::string& pvName)
1340 __GEN_COUT__ <<
"EpicsInterface::getLastAlarms() reached" << __E__;
1341 std::vector<std::vector<std::string>> alarms;
1343 if(dcsAlarmDbConnStatus_ == 1)
1345 PGresult* res =
nullptr;
1354 "SELECT pv.component_id \
1358 , status.name as status \
1359 , severity.name as severity \
1362 , pv.annunciate_ind \
1367 , pv.act_global_alarm_ind \
1368 FROM alarm_tree, pv, status, severity \
1369 WHERE pv.component_id = alarm_tree.component_id \
1370 AND pv.status_id = status.status_id \
1371 AND pv.severity_id = severity.severity_id \
1372 AND alarm_tree.name LIKE \'%%%s%%\' \
1373 ORDER BY pv.severity_id DESC;",
1376 res = PQexec(dcsAlarmDbConn, buffer);
1377 __COUT__ <<
"getLastAlarms(): SELECT pv table PQntuples(res): " << PQntuples(res) << __E__;
1379 if(PQresultStatus(res) != PGRES_TUPLES_OK)
1381 __SS__ <<
"getLastAlarms(): SELECT FROM ALARM DATABASE FAILED!!! PQ ERROR: " << PQresultErrorMessage(res) << __E__;
1386 if(PQntuples(res) > 0)
1389 int nFields = PQnfields(res);
1390 alarms.resize(PQntuples(res));
1393 for(
int i = 0; i < PQntuples(res); i++)
1395 alarms[i].resize(nFields);
1396 for(
int j = 0; j < nFields; j++)
1398 alarms[i][j] = PQgetvalue(res, i, j);
1399 row.append(PQgetvalue(res, i, j));
1411 "Alarms List Not Found",
1431 __SS__ <<
"getLastAlarms(): FAILING GETTING DATA FROM ARCHIVER DATABASE!!! PQ ERROR: " << PQresultErrorMessage(res) << __E__;
1433 catch(
const std::exception &e)
1435 ss <<
"Exception message: " << e.what();
1443 __SS__ <<
"getLastAlarms(): ALARM DATABASE CONNECTION FAILED!!! " << __E__;
1450 std::vector<std::vector<std::string>> EpicsInterface::getAlarmsLog(
const std::string& pvName)
1452 __GEN_COUT__ <<
"EpicsInterface::getAlarmsLog() reached" << __E__;
1453 std::vector<std::vector<std::string>> alarmsHistory;
1455 if(dcsLogDbConnStatus_ == 1)
1457 PGresult* res =
nullptr;
1469 , message_content.value \
1470 , msg_property_type.name as \"status\" \
1471 , message.severity \
1472 , message.datum as \"time\" \
1473 FROM message, message_content, msg_property_type \
1474 WHERE message.id = message_content.message_id \
1475 AND message_content.msg_property_type_id = msg_property_type.id \
1476 AND message.type = 'alarm' \
1477 AND message.severity != 'OK' \
1478 AND message.datum >= current_date -20 \
1479 AND message.name LIKE '%%%s%%' \
1480 ORDER BY message.datum DESC;",
1483 res = PQexec(dcsLogDbConn, buffer);
1484 __COUT__ <<
"getAlarmsLog(): SELECT message table PQntuples(res): " << PQntuples(res) << __E__;
1486 if(PQresultStatus(res) != PGRES_TUPLES_OK)
1488 __SS__ <<
"getAlarmsLog(): SELECT FROM ALARM LOG DATABASE FAILED!!! PQ ERROR: " << PQresultErrorMessage(res) << __E__;
1493 if(PQntuples(res) > 0)
1496 int nFields = PQnfields(res);
1497 alarmsHistory.resize(PQntuples(res));
1500 for(
int i = 0; i < PQntuples(res); i++)
1502 alarmsHistory[i].resize(nFields);
1503 for(
int j = 0; j < nFields; j++)
1505 alarmsHistory[i][j] = PQgetvalue(res, i, j);
1506 row.append(PQgetvalue(res, i, j));
1515 alarmsHistory.resize(1);
1516 alarmsHistory[0] = {
1518 "Alarms List Not Found",
1530 __SS__ <<
"getAlarmsLog(): FAILING GETTING DATA FROM ARCHIVER DATABASE!!! PQ ERROR: " << PQresultErrorMessage(res) << __E__;
1532 catch(
const std::exception &e)
1534 ss <<
"Exception message: " << e.what();
1542 __SS__ <<
"getAlarmsLog(): ALARM LOG DATABASE CONNECTION FAILED!!! " << __E__;
1545 return alarmsHistory;
1557 __COUT__ <<
"checkAlarm()" << __E__;
1559 auto pvIt = mapOfPVInfo_.find(pvName);
1560 if(pvIt == mapOfPVInfo_.end())
1562 __SS__ <<
"While checking for alarm status, PV name '" << pvName <<
"' was not found in PV list!" << __E__;
1566 auto valueArray = getCurrentValue(pvIt->first);
1568 std::string& time = valueArray[0];
1569 std::string& value = valueArray[1];
1570 std::string& status = valueArray[2];
1571 std::string& severity = valueArray[3];
1576 __COUTV__(severity);
1577 if(severity == EPICS_NO_ALARM || (ignoreMinor && severity == EPICS_MINOR_ALARM))
1578 return std::vector<std::string>();
1581 return std::vector<std::string>({pvIt->first, time, value, status, severity});
1588 std::vector<std::vector<std::string>> alarmReturn;
1589 std::vector<std::string> alarmRow;
1590 auto linkToAlarmsToNotify = getSelfNode().getNode(
"LinkToAlarmAlertNotificationsTable");
1592 if(!linkToAlarmsToNotify.isDisconnected())
1594 auto alarmsToNotifyGroups = linkToAlarmsToNotify.getChildren();
1596 for(
const auto& alarmsToNotifyGroup : alarmsToNotifyGroups)
1598 __COUT__ <<
"checkAlarmNotifications() alarmsToNotifyGroup: " << alarmsToNotifyGroup.first << __E__;
1600 auto alarmsToNotify = alarmsToNotifyGroup.second.getNode(
"LinkToAlarmsToMonitorTable");
1601 if(!alarmsToNotify.isDisconnected())
1603 for(
const auto& alarmToNotify : alarmsToNotify.getChildren())
1605 __COUT__ <<
"checkAlarmNotifications() alarmToNotify: " << alarmToNotify.first << __E__;
1609 alarmRow =
checkAlarm(alarmToNotify.second.getNode(
"AlarmChannelName").getValue<std::string>(),
1610 alarmToNotify.second.getNode(
"IgnoreMinorSeverity").getValue<
bool>());
1612 catch(
const std::exception& e)
1614 __COUT__ <<
"checkAlarmNotifications() alarmToNotify: " << alarmToNotify.first <<
" not in PVs List!!!" << __E__;
1617 alarmRow.push_back(alarmToNotify.first);
1618 alarmRow.push_back(alarmsToNotifyGroup.second.getNode(
"WhoToNotify").getValue<std::string>());
1619 alarmRow.push_back(alarmsToNotifyGroup.second.getNode(
"DoSendEmail").getValue<std::string>());
1620 alarmRow.push_back(alarmsToNotifyGroup.first);
1621 alarmReturn.push_back(alarmRow);
1640 void EpicsInterface::handleAlarmsForFSM(
const std::string& fsmTransitionName, ConfigurationTree linkToAlarmsToMonitor)
1642 if(!linkToAlarmsToMonitor.isDisconnected())
1644 auto alarmsToMonitor = linkToAlarmsToMonitor.getChildren();
1648 ss <<
"During '" << fsmTransitionName <<
"'... Alarms monitoring (count=" << alarmsToMonitor.size() <<
"):" << __E__;
1649 for(
const auto& alarmToMonitor : alarmsToMonitor)
1650 ss <<
"\t" << alarmToMonitor.first << __E__;
1653 unsigned foundCount = 0;
1654 for(
const auto& alarmToMonitor : alarmsToMonitor)
1656 std::vector<std::string> alarmReturn =
checkAlarm(alarmToMonitor.second.getNode(
"AlarmChannelName").getValue<std::string>(),
1657 alarmToMonitor.second.getNode(
"IgnoreMinorSeverity").getValue<
bool>());
1659 if(alarmReturn.size())
1661 ss <<
"Found alarm for channel '" << alarmReturn[0] <<
"' = {"
1662 <<
"time=" << alarmReturn[1] <<
", value=" << alarmReturn[2] <<
", status=" << alarmReturn[3] <<
", severity=" << alarmReturn[4] <<
"}!"
1669 ss << __E__ <<
"Total alarms found = " << foundCount << __E__;
1672 __COUT__ << ss.str();
1675 __COUT__ <<
"Disconnected alarms to monitor!" << __E__;
1684 handleAlarmsForFSM(
"configure", getSelfNode().getNode(
"LinkToConfigureAlarmsToMonitorTable"));
1686 __COUT__ <<
"configure(): Preparing EPICS for PVs..." << __E__;
1694 std::string slowControlsChannelsSourceTablesString =
1695 getSelfNode().getNode(
"SlowControlsChannelSourceTableList").getValueWithDefault<std::string>(
"");
1697 __COUTV__(slowControlsChannelsSourceTablesString);
1699 std::vector<std::string> slowControlsChannelsSourceTables = StringMacros::getVectorFromString(slowControlsChannelsSourceTablesString);
1700 __COUTV__(StringMacros::vectorToString(slowControlsChannelsSourceTables));
1702 for(
const auto& slowControlsChannelsSourceTable : slowControlsChannelsSourceTables)
1704 __COUTV__(slowControlsChannelsSourceTable);
1706 const SlowControlsTableBase* slowControlsTable = getConfigurationManager()->getTable<SlowControlsTableBase>(slowControlsChannelsSourceTable);
1708 if(slowControlsTable->slowControlsChannelListHasChanged())
1710 __COUT__ <<
"configure(): Handling channel list change!" << __E__;
1712 std::vector<std::pair<std::string, std::vector<std::string>>> channels;
1713 slowControlsTable->getSlowControlsChannelList(channels);
1715 for(
const auto& channel : channels)
1717 std::string pvName = channel.first;
1718 std::string descr = channel.second.at(0);
1720 int smpl_mode_id = 1;
1721 double smpl_val = 0.;
1722 double smpl_per = 60.;
1723 int retent_id = 9999;
1724 double retent_val = 9999.;
1726 double low_disp_rng = 0.;
1727 double high_disp_rng = 0.;
1728 double low_warn_lmt = atof(channel.second.at(1).c_str());
1729 double high_warn_lmt = atof(channel.second.at(2).c_str());
1730 double low_alarm_lmt = atof(channel.second.at(3).c_str());
1731 double high_alarm_lmt = atof(channel.second.at(4).c_str());
1732 int prec = atoi(channel.second.at(5).c_str());
1733 std::string unit = channel.second.at(6);
1735 if(!checkIfPVExists(pvName))
1737 mapOfPVInfo_[pvName] =
new PVInfo(DBR_STRING);
1738 __COUT__ <<
"configure(): new PV '" << pvName <<
"' found! Now subscribing" << __E__;
1742 if(dcsArchiveDbConnStatus_ == 1)
1744 PGresult* res =
nullptr;
1749 snprintf(buffer,
sizeof(buffer),
"SELECT name FROM channel WHERE name = '%s';", pvName.c_str());
1751 res = PQexec(dcsArchiveDbConn, buffer);
1752 __COUT__ <<
"configure(): SELECT channel table PQntuples(res): " << PQntuples(res) << __E__;
1754 if(PQresultStatus(res) != PGRES_TUPLES_OK)
1756 __SS__ <<
"configure(): SELECT FOR DATABASE CHANNEL TABLE FAILED!!! PV Name: " << pvName
1757 <<
" PQ ERROR: " << PQresultErrorMessage(res) << __E__;
1762 if(PQntuples(res) > 0)
1766 __COUT__ <<
"configure(): Updating PV: " << pvName <<
" in the Archiver Database channel table" << __E__;
1769 "UPDATE channel SET \
1776 WHERE name = '%s';",
1786 res = PQexec(dcsArchiveDbConn, buffer);
1788 if(PQresultStatus(res) != PGRES_COMMAND_OK)
1790 __SS__ <<
"configure(): CHANNEL UPDATE INTO DATABASE CHANNEL TABLE FAILED!!! PV Name: " << pvName
1791 <<
" PQ ERROR: " << PQresultErrorMessage(res) << __E__;
1801 __COUT__ <<
"configure(): Writing new PV in the Archiver Database channel table" << __E__;
1804 "INSERT INTO channel( \
1813 VALUES ('%s', '%s', %d, %d, %f, %f, %d, %f);",
1823 res = PQexec(dcsArchiveDbConn, buffer);
1824 if(PQresultStatus(res) != PGRES_COMMAND_OK)
1826 __SS__ <<
"configure(): CHANNEL INSERT INTO DATABASE CHANNEL TABLE FAILED!!! PV Name: " << pvName
1827 <<
" PQ ERROR: " << PQresultErrorMessage(res) << __E__;
1838 "SELECT channel.channel_id FROM channel, num_metadata WHERE channel.channel_id = num_metadata.channel_id AND channel.name = '%s';",
1841 res = PQexec(dcsArchiveDbConn, buffer);
1842 __COUT__ <<
"configure(): SELECT num_metadata table PQntuples(res): " << PQntuples(res) << __E__;
1844 if(PQresultStatus(res) != PGRES_TUPLES_OK)
1846 __SS__ <<
"configure(): SELECT FOR DATABASE NUM_METADATA TABLE FAILED!!! PV Name: " << pvName
1847 <<
" PQ ERROR: " << PQresultErrorMessage(res) << __E__;
1852 if(PQntuples(res) > 0)
1855 std::string channel_id = PQgetvalue(res, 0, 0);
1856 __COUT__ <<
"configure(): Updating PV: " << pvName <<
" channel_id: " << channel_id
1857 <<
" in the Archiver Database num_metadata table" << __E__;
1861 "UPDATE num_metadata SET \
1863 , high_disp_rng=%f \
1865 , high_warn_lmt=%f \
1866 , low_alarm_lmt=%f \
1867 , high_alarm_lmt=%f \
1870 WHERE channel_id='%s';",
1879 channel_id.c_str());
1881 res = PQexec(dcsArchiveDbConn, buffer);
1882 if(PQresultStatus(res) != PGRES_COMMAND_OK)
1884 __SS__ <<
"configure(): CHANNEL UPDATE INTO DATABASE NUM_METADATA TABLE FAILED!!! PV Name(channel_id): " << pvName <<
" "
1885 << channel_id <<
" PQ ERROR: " << PQresultErrorMessage(res) << __E__;
1894 snprintf(buffer,
sizeof(buffer),
"SELECT channel_id FROM channel WHERE name = '%s';", pvName.c_str());
1896 res = PQexec(dcsArchiveDbConn, buffer);
1897 __COUT__ <<
"configure(): SELECT channel table to check channel_id for num_metadata table. PQntuples(res): " << PQntuples(res)
1900 if(PQresultStatus(res) != PGRES_TUPLES_OK)
1902 __SS__ <<
"configure(): SELECT TO DATABASE CHANNEL TABLE FOR NUM_MATADATA TABLE FAILED!!! PV Name: " << pvName
1903 <<
" PQ ERROR: " << PQresultErrorMessage(res) << __E__;
1908 if(PQntuples(res) > 0)
1910 std::string channel_id = PQgetvalue(res, 0, 0);
1911 __COUT__ <<
"configure(): Writing new PV in the Archiver Database num_metadata table" << __E__;
1916 "INSERT INTO num_metadata( \
1926 VALUES ('%s',%f,%f,%f,%f,%f,%f,%d,'%s');",
1937 res = PQexec(dcsArchiveDbConn, buffer);
1938 if(PQresultStatus(res) != PGRES_COMMAND_OK)
1940 __SS__ <<
"configure(): CHANNEL INSERT INTO DATABASE NUM_METADATA TABLE FAILED!!! PV Name: " << pvName
1941 <<
" PQ ERROR: " << PQresultErrorMessage(res) << __E__;
1949 __SS__ <<
"configure(): CHANNEL INSERT INTO DATABASE NUM_METADATA TABLE FAILED!!! PV Name: " << pvName
1950 <<
" NOT RECOGNIZED IN CHANNEL TABLE" << __E__;
1958 __SS__ <<
"configure(): CHANNEL INSERT OR UPDATE INTO DATABASE FAILED!!! "
1959 <<
" PQ ERROR: " << PQresultErrorMessage(res) << __E__;
1961 catch(
const std::exception &e)
1963 ss <<
"Exception message: " << e.what();
1972 __COUT_INFO__ <<
"configure(): Archiver Database connection does not exist, so skipping channel update." << __E__;
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.
std::vector< std::pair< time_t, std::string > > dataCache
(10, std::pair<time_t, std::string> (0, ""));