1 #include "otsdaq-utilities/SlowControlsDashboard/SlowControlsDashboardSupervisor.h"
6 #include "otsdaq/SlowControlsCore/MakeSlowControls.h"
7 #include "otsdaq/SlowControlsCore/SlowControlsVInterface.h"
9 #include <boost/regex.hpp>
13 #define CONTROLS_SUPERVISOR_DATA_PATH \
14 std::string(__ENV__("SERVICE_DATA_PATH")) + "/ControlsDashboardData/"
15 #define PAGES_DIRECTORY CONTROLS_SUPERVISOR_DATA_PATH + "pages/"
16 #define PAGES_PUBLIC_DIRECTORY CONTROLS_SUPERVISOR_DATA_PATH + "pages/public/"
17 #define PAGES_PRIVATE_DIRECTORY CONTROLS_SUPERVISOR_DATA_PATH + "pages/private/"
22 SlowControlsDashboardSupervisor::SlowControlsDashboardSupervisor(
23 xdaq::ApplicationStub* stub)
26 __SUP_COUT__ <<
"Constructor." << __E__;
31 mkdir(((std::string)(CONTROLS_SUPERVISOR_DATA_PATH)).c_str(), 0755);
32 mkdir(((std::string)(PAGES_DIRECTORY)).c_str(), 0755);
33 mkdir(((std::string)(PAGES_PUBLIC_DIRECTORY)).c_str(), 0755);
34 mkdir(((std::string)(PAGES_PRIVATE_DIRECTORY)).c_str(), 0755);
37 alarmNotifyRefreshRate_ = 60;
41 __SUP_COUT__ <<
"Constructed." << __E__;
45 SlowControlsDashboardSupervisor::~SlowControlsDashboardSupervisor(
void)
47 __SUP_COUT__ <<
"Destructor." << __E__;
49 __SUP_COUT__ <<
"Destructed." << __E__;
53 void SlowControlsDashboardSupervisor::destroy(
void)
65 __SUP_COUT__ << __E__;
67 std::string pluginType;
72 node.
getNode(
"SlowControlsInterfacePluginType").
getValue<std::string>();
77 __SUP_COUT__ <<
"Pluging type was not definded through supervisor table, trying "
78 "supervisor property..."
81 "ControlsInterfacePluginType");
86 alarmNotifyRefreshRate_ = node.
getNode(
"AlarmCheckRefreshPeriod").
getValue<
int>();
87 __SUP_COUTV__(alarmNotifyRefreshRate_);
91 __COUT_WARN__ <<
"Couldn't find `AlarmCheckRefreshPeriod`. Default "
92 "alarmNotifyRefreshRate = "
93 << alarmNotifyRefreshRate_ <<
" seconds." << __E__;
96 __COUTV__(pluginType);
102 CorePropertySupervisorBase::getSupervisorUID(),
103 CorePropertySupervisorBase::getContextTreeNode(),
104 CorePropertySupervisorBase::getSupervisorConfigurationPath());
110 if(interface_ ==
nullptr)
112 __SS__ <<
"Slow Control interface plugin construction failed of type "
113 << pluginType << __E__;
117 interface_->setNewAlarmCallback(
118 std::bind(&SlowControlsDashboardSupervisor::handleNewAlarms,
this));
126 std::lock_guard<std::mutex> lock(cs->pluginBusyMutex_);
128 cs->interface_->initialize();
147 __SUP_COUT__ <<
"Finished init() w/ interface: " << pluginType << __E__;
150 CoreSupervisorBase::theStateMachineImplementation_.push_back(interface_);
154 void SlowControlsDashboardSupervisor::handleNewAlarms()
156 __COUT__ <<
"DEBUG handleNewAlarms" << __E__;
165 std::lock_guard<std::mutex> lock(cs->alarmCheckThreadErrorMutex_);
166 cs->alarmCheckThreadError_ =
"";
173 ->checkAlarmNotifications();
174 alarms_timestamp_ = std::chrono::system_clock::now();
176 __COUT__ <<
"checkSlowControlsAlarms() found count = " << alarms_.size()
181 for(
const auto& alarm : alarms_)
185 time_t rawtime =
static_cast<time_t
>(std::stoi(alarm[1]));
186 char* dt = ctime(&rawtime);
187 std::string subject =
"Slow Control Alarm Notification";
188 std::string message =
"PV: " + alarm[0] +
"\n" +
" at time: " + dt +
189 "\n" +
" value: " + alarm[2] +
"" +
190 " status: " + alarm[3] +
"" +
191 " severity: " + alarm[4];
193 __COUTT__ <<
"checkSlowControlsAlarms() subject '" << subject
194 <<
"' message '" << message <<
"' alarm name '" << alarm[5]
195 <<
"' notify to '" << alarm[8] <<
"' at '" << alarm[6]
196 <<
"' send mail " << alarm[7] << __E__;
201 theRemoteWebUsers_.sendSystemMessage(
202 alarm[6], subject, message, alarm[7] ==
"Yes" ?
true :
false);
206 catch(
const std::runtime_error& e)
208 __SS__ << e.what() <<
'\n';
209 std::lock_guard<std::mutex> lock(cs->alarmCheckThreadErrorMutex_);
210 cs->alarmCheckThreadError_ = ss.str();
211 __COUT_ERR__ << ss.str();
213 catch(
const std::exception& e)
215 __SS__ << e.what() <<
'\n';
216 std::lock_guard<std::mutex> lock(cs->alarmCheckThreadErrorMutex_);
217 cs->alarmCheckThreadError_ = ss.str();
218 __COUT_ERR__ << ss.str();
222 __SS__ <<
"checkSlowControlsAlarms() ERROR While sendin alarm messages"
228 catch(
const std::exception& e)
230 ss <<
"Exception message: " << e.what();
235 std::lock_guard<std::mutex> lock(cs->alarmCheckThreadErrorMutex_);
236 cs->alarmCheckThreadError_ = ss.str();
237 __COUT_ERR__ << ss.str();
240 sleep(alarmNotifyRefreshRate_);
249 __COUT__ <<
"checkSubscriptions() initializing..." << __E__;
250 std::vector<std::string> channelList;
251 std::vector<int> channelRefreshRates;
254 channelList = {
"FIRST VALUE"};
255 channelRefreshRates = {};
256 std::map<int, std::set<std::string>>::iterator mapReference =
257 cs->channelDependencyLookupMap_.begin();
258 while(mapReference !=
259 cs->channelDependencyLookupMap_
262 for(
auto channel : mapReference->second)
264 int refreshRate = 15;
265 channelRefreshRates.push_back(refreshRate);
267 __COUT__ <<
"THREAD actual time: " << std::time(NULL)
268 <<
"; uidPollTimeMap + 10 * refreshTime: "
269 << cs->uidPollTimeMap_.at(mapReference->first) + 10 * refreshRate
270 <<
" seconds" << __E__;
272 cs->uidPollTimeMap_.at(mapReference->first) + 10 * refreshRate)
276 cs->channelDependencyLookupMap_.erase(mapReference->first);
279 catch(
const std::exception& e)
285 std::vector<std::string>::iterator it =
286 find(channelList.begin(), channelList.end(), channel);
287 if(it == channelList.end())
291 channelList.push_back(channel);
292 __COUT__ <<
"Channel: " << channel <<
" refreshRate: " << refreshRate
293 <<
" seconds" << __E__;
294 __COUT__ <<
"channelDependencyLookupMap_.size(): "
295 << cs->channelDependencyLookupMap_.size()
296 <<
" UID: " << mapReference->first
297 <<
" mapReference->second.size(): "
298 << mapReference->second.size() << __E__;
306 if(channelRefreshRates.size() > 0)
308 *min_element(channelRefreshRates.begin(), channelRefreshRates.end());
310 __COUT__ <<
"Loop over channels subscribing - waiting time: " << minTime
311 <<
" seconds" << __E__;
321 CorePropertySupervisorBase::setSupervisorProperty(
322 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.CheckUserLockRequestTypes,
"*");
331 CorePropertySupervisorBase::setSupervisorProperty(
332 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
"poll");
334 if(CorePropertySupervisorBase::isReadOnly())
336 CorePropertySupervisorBase::setSupervisorProperty(
337 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
338 "*=0 | getPages=1 | loadPhoebusPage=1 | getList=1 | getPVSettings=1 | getPvArchiverData=1 | generateUID=1 | getUserPermissions=1 |\
339 userActivityHeartbeat=1 | poll=1 | uid=1 | isUserAdmin=1 | getLastAlarmsData=1 | getAlarmsLogData=1 | getAlarmsCheck=1 | getPvData=1 ");
340 __COUT_INFO__ <<
"readOnly true in setSupervisorProperty" << __E__;
345 void SlowControlsDashboardSupervisor::request(
const std::string& requestType,
348 const WebUsers::RequestUserInfo& userInfo)
352 if(requestType !=
"getPages" && !pluginBusyMutex_.try_lock())
354 __SUP_SS__ <<
"Controls plugin is still initializing. Please try again in a "
360 __SUP_COUT__ <<
"User name is " << userInfo.username_ <<
"." << __E__;
361 __SUP_COUT__ <<
"User permission level for request '" << requestType <<
"' is "
362 << unsigned(userInfo.permissionLevel_)
363 <<
"(isAdmin=" << (userInfo.isAdmin() ?
"Yes" :
"No") <<
")."
367 handleRequest(requestType, xmlOut, cgiIn, userInfo);
369 catch(
const std::runtime_error& e)
371 __SUP_SS__ <<
"Error occurred handling request '" << requestType
372 <<
"': " << e.what() << __E__;
373 __SUP_COUT__ << ss.str();
374 xmlOut.addTextElementToData(
"Error", ss.str());
378 __SS__ <<
"Unknown error occurred handling request '" << requestType <<
"!'"
384 catch(
const std::exception& e)
386 ss <<
"Exception message: " << e.what();
391 __SUP_COUT__ << ss.str();
392 xmlOut.addTextElementToData(
"Error", ss.str());
395 pluginBusyMutex_.unlock();
396 __SUP_COUT__ << __E__;
400 void SlowControlsDashboardSupervisor::handleRequest(
401 const std::string Command,
404 const WebUsers::RequestUserInfo& userInfo)
407 __SUP_COUT__ << __E__;
409 if(Command ==
"poll")
412 Poll(cgiIn, xmlOut, uid);
414 else if(Command ==
"getPvData")
418 else if(Command ==
"userActivityHeartbeat")
424 else if(Command ==
"generateUID")
427 GenerateUID(cgiIn, xmlOut, channelList);
429 else if(Command ==
"isUserAdmin")
431 std::string json = std::string(
"{ \"message\": \"");
432 json += (userInfo.isAdmin() ?
"Yes" :
"No");
434 xmlOut.addTextElementToData(
"JSON", json.c_str());
436 else if(Command ==
"getUserPermissions")
438 GetUserPermissions(cgiIn, xmlOut, userInfo);
440 else if(Command ==
"getPVSettings")
442 __SUP_COUT__ <<
"Channel settings requested from server! " << __E__;
443 GetChannelSettings(cgiIn, xmlOut);
446 else if(Command ==
"getPvArchiverData")
448 __SUP_COUT__ <<
"Archived Channel data requested from server! " << __E__;
449 GetChannelArchiverData(cgiIn, xmlOut);
452 else if(Command ==
"getList")
454 __SUP_COUT__ <<
"Channel List requested from server! " << __E__;
455 GetList(cgiIn, xmlOut);
457 else if(Command ==
"getPages")
459 __SUP_COUT__ <<
"Requesting pages from server! " << __E__;
460 GetPages(cgiIn, xmlOut);
462 else if(Command ==
"loadPage")
465 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" " << page
468 loadPage(cgiIn, xmlOut, page, userInfo);
470 else if(Command ==
"loadPhoebusPage")
473 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" " << page
476 loadPhoebusPage(cgiIn, xmlOut, page, userInfo);
478 else if(Command ==
"createControlsPage")
480 SaveControlsPage(cgiIn, xmlOut, userInfo);
482 else if(Command ==
"createPhoebusControlsPage")
484 SavePhoebusControlsPage(cgiIn, xmlOut, userInfo);
486 else if(Command ==
"getLastAlarmsData")
488 __SUP_COUT__ <<
"Last Alarms Data requested from server! " << __E__;
489 GetLastAlarmsData(cgiIn, xmlOut);
492 else if(Command ==
"getAlarmsLogData")
494 __SUP_COUT__ <<
"Alarms Log Data requested from server! " << __E__;
495 GetAlarmsLogData(cgiIn, xmlOut);
498 else if(Command ==
"getAlarmsCheck")
500 __SUP_COUT__ <<
"Alarms Data requested from server! " << __E__;
501 GetAlarmsCheck(xmlOut);
503 else if(Command ==
"saveImageFile")
505 saveImageFile(cgiIn, xmlOut, userInfo);
509 __SUP_SS__ <<
"Request, " << Command
510 <<
", not recognized by the Slow Controls Dashboard Supervisor (was "
511 "it intended for another Supervisor?)."
516 __SUP_COUT__ <<
"" << __E__;
520 void SlowControlsDashboardSupervisor::Poll(cgicc::Cgicc& cgiIn,
HttpXmlDocument& xmlOut)
523 std::set<std::string> channels;
526 xmlOut.addTextElementToData(
"JSON", PollChannels_(channels));
530 void SlowControlsDashboardSupervisor::Poll(cgicc::Cgicc& ,
534 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
535 <<
"Polling on UID:" << UID << __E__;
537 std::map<int, std::set<std::string>>::iterator mapReference;
539 if(UID !=
"" && (mapReference = channelDependencyLookupMap_.find(std::stoi(UID))) !=
540 channelDependencyLookupMap_
543 uidPollTimeMap_.at(std::stoi(UID)) = std::time(NULL);
545 xmlOut.addTextElementToData(
546 "JSON", PollChannels_(mapReference->second));
550 xmlOut.addTextElementToData(
"JSON",
551 "{ \"message\": \"NOT_FOUND\"}");
556 std::string SlowControlsDashboardSupervisor::PollChannels_(
557 std::set<std::string>& channels,
bool resubscibe )
559 std::string JSONMessage =
"{ ";
561 for(
auto channel : channels)
565 __SUP_COUT__ << channel << __E__;
567 std::array<std::string, 4> channelInformation =
568 interface_->getCurrentValue(channel);
570 __SUP_COUT__ << channel <<
": " << channelInformation[1] <<
" : "
571 << channelInformation[3] << __E__;
573 if(channelInformation[0] !=
"NO_CHANGE")
576 JSONMessage +=
"\"" + channel +
"\": {";
577 JSONMessage +=
"\"Timestamp\":\"" + channelInformation[0] +
"\",";
578 JSONMessage +=
"\"Value\":\"" + channelInformation[1] +
"\",";
579 JSONMessage +=
"\"Status\":\"" + channelInformation[2] +
"\",";
580 JSONMessage +=
"\"Severity\":\"" + channelInformation[3] +
"\"},";
584 __SUP_COUT__ <<
"No change in value since last poll: " << channel << __E__;
588 if(channelInformation[3] ==
"INVALID" && resubscibe)
590 interface_->unsubscribe(channel);
591 interface_->subscribe(channel);
595 JSONMessage = JSONMessage.substr(0, JSONMessage.length() - 1);
597 __SUP_COUT__ << JSONMessage << __E__;
602 void SlowControlsDashboardSupervisor::GetChannelSettings(cgicc::Cgicc& cgiIn,
607 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
608 <<
"Getting settings for " << channelList << __E__;
610 std::string JSONMessage =
"{ ";
612 __SUP_COUT__ <<
"**********************" << channelList.size() << __E__;
613 if(channelList.size() > 0)
618 while((nextPos = channelList.find(
",", pos)) != std::string::npos)
620 channel = channelList.substr(pos, nextPos - pos);
622 __SUP_COUT__ << channel << __E__;
624 std::array<std::string, 9> channelSettings = interface_->getSettings(channel);
626 JSONMessage +=
"\"" + channel +
"\": {";
627 JSONMessage +=
"\"Units\": \"" + channelSettings[0] +
"\",";
628 JSONMessage +=
"\"Upper_Display_Limit\": \"" + channelSettings[1] +
"\",";
629 JSONMessage +=
"\"Lower_Display_Limit\": \"" + channelSettings[2] +
"\",";
630 JSONMessage +=
"\"Upper_Alarm_Limit\": \"" + channelSettings[3] +
"\",";
631 JSONMessage +=
"\"Upper_Warning_Limit\": \"" + channelSettings[4] +
"\",";
632 JSONMessage +=
"\"Lower_Warning_Limit\": \"" + channelSettings[5] +
"\",";
633 JSONMessage +=
"\"Lower_Alarm_Limit\": \"" + channelSettings[6] +
"\",";
634 JSONMessage +=
"\"Upper_Control_Limit\": \"" + channelSettings[7] +
"\",";
635 JSONMessage +=
"\"Lower_Control_Limit\": \"" + channelSettings[8] +
"\"},";
640 JSONMessage = JSONMessage.substr(0, JSONMessage.length() - 1);
643 __SUP_COUT__ << JSONMessage << __E__;
644 xmlOut.addTextElementToData(
"JSON", JSONMessage);
648 __SUP_COUT__ <<
"Did not find any settings because Channel list is length zero!"
651 xmlOut.addTextElementToData(
652 "JSON",
"{ \"message\": \"GetPVSettings\"}");
657 void SlowControlsDashboardSupervisor::GetChannelArchiverData(cgicc::Cgicc& cgiIn,
660 __SUP_COUT__ <<
"Requesting archived data!" << __E__;
666 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
667 <<
"Getting History for " << channelList <<
" start time: " << startTime
668 <<
" end time: " << endTime << __E__;
670 __SUP_COUT__ <<
"channelList.size(): " << channelList.size() << __E__;
671 if(channelList.size() > 0 && startTime > 0 && endTime > 0)
676 while((nextPos = channelList.find(
",", pos)) != std::string::npos)
678 channel = channelList.substr(pos, nextPos - pos);
680 __SUP_COUT__ <<
"Getting History for " << channel << __E__;
682 std::vector<std::vector<std::string>> channelInformation =
683 interface_->getChannelHistory(channel, startTime, endTime);
685 for(
auto channelData : channelInformation)
687 std::string JSONMessage =
"{ ";
688 JSONMessage +=
"\"" + channel +
"\": {";
689 JSONMessage +=
"\"Timestamp\":\"" + channelData[0] +
"\",";
690 JSONMessage +=
"\"Value\":\"" + channelData[1] +
"\",";
691 JSONMessage +=
"\"Status\":\"" + channelData[2] +
"\",";
692 JSONMessage +=
"\"Severity\":\"" + channelData[3] +
"\"},";
694 JSONMessage = JSONMessage.substr(0, JSONMessage.length() - 1);
696 xmlOut.addTextElementToData(
"JSON", JSONMessage);
704 __SUP_COUT__ <<
"Did not find any data because Channel list is length zero!"
707 xmlOut.addTextElementToData(
708 "JSON",
"{ \"message\": \"GetChannelArchiverData\"}");
713 void SlowControlsDashboardSupervisor::GetLastAlarmsData(cgicc::Cgicc& cgiIn,
716 __SUP_COUT__ <<
"Requesting last alarms data!" << __E__;
720 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
721 <<
"Getting last Alarms for " << channelList << __E__;
722 __SUP_COUT__ <<
"channelList.size(): " << channelList.size() << __E__;
724 std::vector<std::vector<std::string>> alarms;
727 std::function<void(
HttpXmlDocument&, std::vector<std::vector<std::string>>&)>
729 std::vector<std::vector<std::string>>& alarms) {
731 for(
auto& alarmRow : alarms)
733 std::string JSONMessage =
"{ ";
734 JSONMessage +=
"\"id\":\"" + alarmRow[0] +
"\",";
735 JSONMessage +=
"\"pvName\":\"" + alarmRow[1] +
"\",";
736 JSONMessage +=
"\"pvDescription\":\"" + alarmRow[2] +
"\",";
737 JSONMessage +=
"\"pvValue\":\"" + alarmRow[3] +
"\",";
738 JSONMessage +=
"\"pvStatus\":\"" + alarmRow[4] +
"\",";
739 JSONMessage +=
"\"pvSeverity\":\"" + alarmRow[5] +
"\",";
740 JSONMessage +=
"\"pvTime\":\"" + alarmRow[6] +
"\",";
742 JSONMessage = JSONMessage.substr(0, JSONMessage.length() - 1);
744 xmlOut.addTextElementToData(
"JSON", JSONMessage);
749 if(channelList.size() > 0)
754 while((nextPos = channelList.find(
",", pos)) != std::string::npos)
756 channel = channelList.substr(pos, nextPos - pos);
758 alarms = interface_->getLastAlarms(channel);
759 __SUP_COUT__ <<
"get Last Alarms for channel: " << channel << __E__;
760 jsonFiller(xmlOut, alarms);
766 alarms = interface_->getLastAlarms(
"");
767 __SUP_COUT__ <<
"get Last Alarms for all channels" << __E__;
768 jsonFiller(xmlOut, alarms);
773 void SlowControlsDashboardSupervisor::GetAlarmsCheck(
HttpXmlDocument& xmlOut)
775 __SUP_COUT__ <<
"Requesting alarms check cache data!" << __E__;
777 std::string JSONMessage =
"{ ";
778 JSONMessage +=
"\"last_check\":" +
779 std::to_string(std::chrono::duration_cast<std::chrono::seconds>(
780 alarms_timestamp_.time_since_epoch())
783 JSONMessage +=
"\"total\":" + std::to_string(alarms_.size()) +
",";
784 JSONMessage +=
"\"alarms\": [";
785 unsigned int nactive = 0;
788 for(
auto& alarmRow : alarms_)
791 JSONMessage +=
"\"name\":\"" + alarmRow[0] +
"\",";
792 if(alarmRow.size() > 9)
795 JSONMessage +=
"\"time\":\"" + alarmRow[1] +
"\",";
796 JSONMessage +=
"\"value\":\"" + alarmRow[2] +
"\",";
797 JSONMessage +=
"\"status\":\"" + alarmRow[3] +
"\",";
798 JSONMessage +=
"\"severity\":\"" + alarmRow[4] +
"\",";
801 JSONMessage.substr(0, JSONMessage.length() - 1);
805 JSONMessage.substr(0, JSONMessage.length() - 1);
807 JSONMessage +=
"], \"nactive\": " + std::to_string(nactive);
809 xmlOut.addTextElementToData(
"JSON", JSONMessage);
813 void SlowControlsDashboardSupervisor::GetAlarmsLogData(cgicc::Cgicc& cgiIn,
816 __SUP_COUT__ <<
"Requesting alarms log data!" << __E__;
820 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
821 <<
"Getting Alarms Log for " << channelList << __E__;
822 __SUP_COUT__ <<
"channelList.size(): " << channelList.size() << __E__;
824 std::vector<std::vector<std::string>> alarmsLog;
827 std::function<void(
HttpXmlDocument&, std::vector<std::vector<std::string>>&)>
829 std::vector<std::vector<std::string>>& alarmsLog) {
831 for(
auto& alarmRow : alarmsLog)
833 std::string JSONMessage =
"{ ";
834 JSONMessage +=
"\"id\":\"" + alarmRow[0] +
"\",";
835 JSONMessage +=
"\"pvName\":\"" + alarmRow[1] +
"\",";
836 JSONMessage +=
"\"pvValue\":\"" + alarmRow[2] +
"\",";
837 JSONMessage +=
"\"pvStatus\":\"" + alarmRow[3] +
"\",";
838 JSONMessage +=
"\"pvSeverity\":\"" + alarmRow[4] +
"\",";
839 JSONMessage +=
"\"pvTime\":\"" + alarmRow[5] +
"\",";
841 JSONMessage = JSONMessage.substr(0, JSONMessage.length() - 1);
843 xmlOut.addTextElementToData(
"JSON", JSONMessage);
848 if(channelList.size() > 0)
853 while((nextPos = channelList.find(
",", pos)) != std::string::npos)
855 channel = channelList.substr(pos, nextPos - pos);
857 alarmsLog = interface_->getAlarmsLog(channel);
858 __SUP_COUT__ <<
"get Alarms Log for channel: " << channel << __E__;
859 jsonFiller(xmlOut, alarmsLog);
865 alarmsLog = interface_->getAlarmsLog(
"");
866 __SUP_COUT__ <<
"get Alarms Log for all channels" << __E__;
867 jsonFiller(xmlOut, alarmsLog);
872 void SlowControlsDashboardSupervisor::GetUserPermissions(
875 const WebUsers::RequestUserInfo& )
881 void SlowControlsDashboardSupervisor::GenerateUID(cgicc::Cgicc& ,
883 std::string channelList)
885 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
886 <<
"Generating UID" << __E__;
888 std::set<std::string> channelDependencies;
892 channelDependencyLookupMap_.insert(
893 std::pair<
int, std::set<std::string>>(++UID_, channelDependencies));
895 uidPollTimeMap_.insert(std::pair<int, long int>(UID_, std::time(NULL)));
897 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" NEW UID: " << UID_
898 <<
" maps to " << channelDependencies.size() <<
" channels" << __E__;
900 xmlOut.addTextElementToData(
"JSON",
901 std::string(
"{ \"message\": \"") + std::to_string(UID_) +
906 void SlowControlsDashboardSupervisor::GetList(cgicc::Cgicc& ,
909 if(interface_ != NULL)
911 __SUP_COUT__ <<
"Interface is defined! Attempting to get list!" << __E__;
917 list = interface_->getList(
"JSON");
919 catch(std::runtime_error& e)
921 __SUP_SS__ <<
"Channel list request failed: " << e.what() << __E__;
925 __SUP_COUT__ <<
" " << list << __E__;
927 xmlOut.addTextElementToData(
"JSON", list);
931 __SUP_COUT__ <<
"Interface undefined! Failed to get list!" << __E__;
932 xmlOut.addTextElementToData(
"JSON",
"[\"None\"]");
937 void SlowControlsDashboardSupervisor::GetPages(cgicc::Cgicc& ,
940 std::vector<std::string> pages;
942 listFiles(
"",
true, &pages);
944 std::string returnJSON =
"[";
945 for(
auto it = pages.begin(); it != pages.end(); it++)
947 if(*it !=
"." && *it !=
"..")
948 returnJSON +=
"\"" + *it +
"\", ";
950 if(returnJSON.size() > 2 && returnJSON.compare(
"[") != 0)
952 __SUP_COUT__ <<
"Found pages on server!" << __E__;
953 returnJSON.resize(returnJSON.size() - 2);
959 __SUP_COUT__ <<
"No pages found on server!" << __E__;
960 returnJSON =
"[\"None\"]";
962 __SUP_COUT__ << returnJSON << __E__;
964 xmlOut.addTextElementToData(
"JSON", returnJSON);
968 void SlowControlsDashboardSupervisor::loadPage(
972 const WebUsers::RequestUserInfo& )
978 if(page.find(
"..") != std::string::npos)
980 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
981 <<
"Error! Request using '..': " << page << __E__;
983 else if(page.find(
"~") != std::string::npos)
985 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
986 <<
"Error! Request using '~': " << page << __E__;
988 else if(!(stat(page.c_str(), &buffer) == 0))
990 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
991 <<
"Error! File not found: " << page << __E__;
995 __SUP_COUT__ << page << __E__;
997 if(page.at(0) ==
'/')
999 __SUP_COUT__ <<
"First character is '/'" << __E__;
1000 page.erase(page.begin(), page.begin() + 1);
1001 __SUP_COUT__ << page << __E__;
1004 std::string file = PAGES_DIRECTORY;
1006 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1007 <<
"Trying to load page: " << page << __E__;
1008 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1009 <<
"Trying to load page: " << file << __E__;
1013 std::ifstream infile(file);
1016 __SUP_COUT__ <<
"Failed reading file: " << file << __E__;
1018 xmlOut.addTextElementToData(
"Time",
"[\"Not Found\"]");
1019 xmlOut.addTextElementToData(
"Notes",
"[\"Not Found\"]");
1020 xmlOut.addTextElementToData(
1021 "Page", StringMacros::encodeURIComponent(page));
1024 __SUP_COUT__ <<
"Reading file" << __E__;
1026 std::string time =
"";
1027 std::string notes =
"";
1028 std::string controlsPage =
"";
1030 for(std::string line; getline(infile, line);)
1032 __SUP_COUT__ << line << __E__;
1033 if(!line.substr(0, 5).compare(
"Time:"))
1035 time = line.substr(6);
1037 else if(!line.substr(0, 6).compare(
"Notes:"))
1039 notes = line.substr(7);
1041 else if(!line.substr(0, 5).compare(
"Page:"))
1043 controlsPage = line.substr(6);
1046 __SUP_COUT__ <<
"Finished reading file" << __E__;
1047 __SUP_COUTV__(time);
1048 __SUP_COUTV__(notes);
1049 __SUP_COUTV__(controlsPage);
1051 xmlOut.addTextElementToData(
"Time", time);
1052 xmlOut.addTextElementToData(
"Notes", notes);
1053 xmlOut.addTextElementToData(
"Page", controlsPage);
1057 void SlowControlsDashboardSupervisor::loadPhoebusPage(
1061 const WebUsers::RequestUserInfo& )
1067 if(page.find(
"..") != std::string::npos)
1069 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1070 <<
"Error! Request using '..': " << page << __E__;
1072 else if(page.find(
"~") != std::string::npos)
1074 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1075 <<
"Error! Request using '~': " << page << __E__;
1077 else if(!(stat(page.c_str(), &buffer) == 0))
1079 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1080 <<
"Error! File not found: " << page << __E__;
1084 __SUP_COUT__ << page << __E__;
1086 if(page.at(0) ==
'/')
1088 __SUP_COUT__ <<
"First character is '/'" << __E__;
1089 page.erase(page.begin(), page.begin() + 1);
1090 __SUP_COUT__ << page << __E__;
1093 std::string file = PAGES_DIRECTORY;
1095 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1096 <<
"Trying to load page: " << page << __E__;
1097 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1098 <<
"Trying to load page: " << file << __E__;
1101 __SUP_COUT__ <<
"Reading file" << __E__;
1102 std::ifstream infile(file);
1105 __SUP_COUT__ <<
"Failed reading file: " << file << __E__;
1106 xmlOut.addTextElementToData(
1107 "Page", StringMacros::encodeURIComponent(page));
1112 for(std::string line; getline(infile, line);)
1116 __SUP_COUT__ << xml << __E__;
1117 xmlOut.addTextElementToData(
"PHOEBUS", xml);
1122 void SlowControlsDashboardSupervisor::SaveControlsPage(
1123 cgicc::Cgicc& cgiIn,
1125 const WebUsers::RequestUserInfo& )
1127 __SUP_COUT__ <<
"ControlsDashboard wants to create a Controls Page!" << __E__;
1136 __SUP_COUTV__(controlsPageName);
1137 __SUP_COUTV__(pageString);
1138 __SUP_COUTV__(Notes);
1139 __SUP_COUTV__(Time);
1140 __SUP_COUTV__(isControlsPagePublic);
1142 if(controlsPageName ==
"")
1145 std::string fullPath;
1146 if(isControlsPagePublic ==
"true")
1147 fullPath = (std::string)PAGES_PUBLIC_DIRECTORY;
1149 fullPath = (std::string)PAGES_PRIVATE_DIRECTORY;
1151 __SUP_COUTV__(fullPath);
1153 std::string file = fullPath + controlsPageName;
1155 __SUP_COUTV__(
"Saving Controls Page to: " + file);
1157 std::string extension = file.substr(file.length() - 4, 4);
1158 if(extension !=
".dat")
1160 __SUP_COUT__ <<
"Extension : " << extension << __E__;
1161 file += std::string(
".dat");
1163 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1164 <<
"Trying to save page: " << controlsPageName << __E__;
1165 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1166 <<
"Trying to save page as: " << file << __E__;
1170 std::ofstream outputFile;
1171 outputFile.open(file);
1172 if(!outputFile.is_open())
1174 __SUP_SS__ <<
"Failed to open file for writing: " << file << __E__;
1177 outputFile <<
"Time: " << Time <<
"\n";
1178 outputFile <<
"Notes: " << Notes <<
"\n";
1179 outputFile <<
"Page: " << pageString;
1182 __SUP_COUT__ <<
"Finished writing file" << __E__;
1188 void SlowControlsDashboardSupervisor::SavePhoebusControlsPage(
1189 cgicc::Cgicc& cgiIn,
1191 const WebUsers::RequestUserInfo& )
1193 __SUP_COUT__ <<
"ControlsDashboard wants to create a Controls Page!" << __E__;
1199 __SUP_COUTV__(controlsPageName);
1200 __SUP_COUTV__(pageString);
1201 __SUP_COUTV__(isControlsPagePublic);
1203 if(controlsPageName ==
"")
1206 std::string fullPath;
1207 if(isControlsPagePublic ==
"true")
1208 fullPath = (std::string)PAGES_PUBLIC_DIRECTORY;
1210 fullPath = (std::string)PAGES_PRIVATE_DIRECTORY;
1212 __SUP_COUTV__(fullPath);
1214 std::string file = fullPath + controlsPageName;
1216 __SUP_COUTV__(
"Saving Controls Page to: " + file);
1218 std::string extension = file.substr(file.length() - 4, 4);
1219 if(extension !=
".bob")
1221 __SUP_COUT__ <<
"Extension : " << extension << __E__;
1222 file += std::string(
".bob");
1224 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1225 <<
"Trying to save page: " << controlsPageName << __E__;
1226 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1227 <<
"Trying to save page as: " << file << __E__;
1231 std::ofstream outputFile;
1232 outputFile.open(file);
1233 if(!outputFile.is_open())
1235 __SUP_SS__ <<
"Failed to open file for writing: " << file << __E__;
1238 outputFile << pageString <<
"\n";
1241 __SUP_COUT__ <<
"Finished writing file" << __E__;
1247 void SlowControlsDashboardSupervisor::saveImageFile(
1248 cgicc::Cgicc& cgiIn,
1250 const WebUsers::RequestUserInfo& )
1252 __SUP_COUT__ <<
"ControlsDashboard wants to save the image file uploaded!" << __E__;
1254 std::string isImagePublic = cgiIn(
"isPublic");
1255 const std::vector<cgicc::FormFile>& files = cgiIn.getFiles();
1256 std::string filename;
1257 std::ofstream myfile;
1258 std::string fullPath;
1260 __SUP_COUTV__(files.size());
1261 __SUP_COUTV__(isImagePublic);
1263 if(isImagePublic ==
"true")
1264 fullPath = (std::string)PAGES_PUBLIC_DIRECTORY;
1266 fullPath = (std::string)PAGES_PRIVATE_DIRECTORY;
1268 for(
unsigned int i = 0; i < files.size(); ++i)
1270 filename = files[i].getFilename();
1271 filename = fullPath + filename;
1272 __COUT__ <<
"file " << i <<
" - " << filename << std::endl;
1274 myfile.open(filename.c_str());
1275 if(myfile.is_open())
1277 files[i].writeToStream(myfile);
1279 __SUP_COUT__ <<
"Finished writing image file" << __E__;
1287 void SlowControlsDashboardSupervisor::Subscribe(cgicc::Cgicc& ,
1293 void SlowControlsDashboardSupervisor::Unsubscribe(cgicc::Cgicc& ,
1305 struct stat fileInfo;
1306 stat(dir.c_str(), &fileInfo);
1307 if(S_ISDIR(fileInfo.st_mode))
1318 void SlowControlsDashboardSupervisor::listFiles(std::string innerDir,
1320 std::vector<std::string>* pages)
1322 std::string baseDir = PAGES_DIRECTORY;
1323 baseDir += innerDir;
1325 struct dirent* dirp;
1326 if((dp = opendir(baseDir.c_str())) == NULL)
1328 __SUP_COUT__ <<
"[ERROR: " << errno <<
" ] Couldn't open " << baseDir <<
"."
1334 while((dirp = readdir(dp)) != NULL)
1336 if(dirp->d_name != std::string(
".") && dirp->d_name != std::string(
".."))
1338 if(
isDir(baseDir + dirp->d_name) ==
true && recursive ==
true)
1341 __SUP_COUT__ <<
"[DIR]\t" << baseDir << dirp->d_name <<
"/" << __E__;
1342 listFiles(std::string(
"") + dirp->d_name +
"/",
true, pages);
1346 pages->push_back(innerDir + dirp->d_name);
1347 __SUP_COUT__ <<
"[FILE]\t" << baseDir << innerDir << dirp->d_name
static std::string postData(cgicc::Cgicc &cgi, const std::string &needle)
static std::string getOrPostData(cgicc::Cgicc &cgi, const std::string &needle)
static std::string getData(cgicc::Cgicc &cgi, const std::string &needle)
ConfigurationTree getNode(const std::string &nodeName, bool doNotThrowOnBrokenUIDLinks=false) const
void getValue(T &value) const
std::string getSupervisorProperty(const std::string &propertyName)
bool isDir(std::string dir)
Utilities, eventually to be moved.
void checkSubscriptions(SlowControlsDashboardSupervisor *cs)
Manage channel subscriptions to Interface.
virtual void forceSupervisorPropertyValues(void) override
void init(void)
called by constructor
virtual void setSupervisorPropertyDefaults(void) override
void checkSlowControlsAlarms(SlowControlsDashboardSupervisor *cs)
Manage channel subscriptions to Interface.
SlowControlsVInterface * makeSlowControls(const std::string &slowControlsPluginName, const std::string &slowControlsUID, const ConfigurationTree &configurationTree, const std::string &pathToControlsConfiguration)
void INIT_MF(const char *name)
static void getSetFromString(const std::string &inputString, std::set< std::string > &setToReturn, const std::set< char > &delimiter={',', '|', '&'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'})
static std::string decodeURIComponent(const std::string &data)