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;
39 readOnly_ = getSupervisorProperty(
"ReadOnly",
"1") ==
"1" ? true :
false;
40 __SUP_COUTV__(readOnly_);
44 __SUP_COUT__ <<
"Constructed." << __E__;
48 SlowControlsDashboardSupervisor::~SlowControlsDashboardSupervisor(
void)
50 __SUP_COUT__ <<
"Destructor." << __E__;
52 __SUP_COUT__ <<
"Destructed." << __E__;
56 void SlowControlsDashboardSupervisor::destroy(
void)
68 __SUP_COUT__ << __E__;
70 std::string pluginType;
75 node.
getNode(
"SlowControlsInterfacePluginType").
getValue<std::string>();
80 __SUP_COUT__ <<
"Pluging type was not definded through supervisor table, trying "
81 "supervisor property..."
84 "ControlsInterfacePluginType");
89 alarmNotifyRefreshRate_ = node.
getNode(
"AlarmCheckRefreshPeriod").
getValue<
int>();
90 __SUP_COUTV__(alarmNotifyRefreshRate_);
94 __COUT_WARN__ <<
"Couldn't find `AlarmCheckRefreshPeriod`. Default "
95 "alarmNotifyRefreshRate = "
96 << alarmNotifyRefreshRate_ <<
" seconds." << __E__;
99 __COUTV__(pluginType);
105 CorePropertySupervisorBase::getSupervisorUID(),
106 CorePropertySupervisorBase::getContextTreeNode(),
107 CorePropertySupervisorBase::getSupervisorConfigurationPath());
113 if(interface_ ==
nullptr)
115 __SS__ <<
"Slow Control interface plugin construction failed of type "
116 << pluginType << __E__;
120 interface_->setNewAlarmCallback(
121 std::bind(&SlowControlsDashboardSupervisor::handleNewAlarms,
this));
129 std::lock_guard<std::mutex> lock(cs->pluginBusyMutex_);
131 cs->interface_->initialize();
150 __SUP_COUT__ <<
"Finished init() w/ interface: " << pluginType << __E__;
153 CoreSupervisorBase::theStateMachineImplementation_.push_back(interface_);
157 void SlowControlsDashboardSupervisor::handleNewAlarms()
159 __COUT__ <<
"DEBUG handleNewAlarms" << __E__;
168 std::lock_guard<std::mutex> lock(cs->alarmCheckThreadErrorMutex_);
169 cs->alarmCheckThreadError_ =
"";
176 ->checkAlarmNotifications();
177 alarms_timestamp_ = std::chrono::system_clock::now();
179 __COUT__ <<
"checkSlowControlsAlarms() found count = " << alarms_.size()
184 for(
const auto& alarm : alarms_)
188 time_t rawtime =
static_cast<time_t
>(std::stoi(alarm[1]));
189 char* dt = ctime(&rawtime);
190 std::string subject =
"Slow Control Alarm Notification";
191 std::string message =
"PV: " + alarm[0] +
"\n" +
" at time: " + dt +
192 "\n" +
" value: " + alarm[2] +
"" +
193 " status: " + alarm[3] +
"" +
194 " severity: " + alarm[4];
196 __COUTT__ <<
"checkSlowControlsAlarms() subject '" << subject
197 <<
"' message '" << message <<
"' alarm name '" << alarm[5]
198 <<
"' notify to '" << alarm[8] <<
"' at '" << alarm[6]
199 <<
"' send mail " << alarm[7] << __E__;
204 theRemoteWebUsers_.sendSystemMessage(
205 alarm[6], subject, message, alarm[7] ==
"Yes" ?
true :
false);
209 catch(
const std::runtime_error& e)
211 __SS__ << e.what() <<
'\n';
212 std::lock_guard<std::mutex> lock(cs->alarmCheckThreadErrorMutex_);
213 cs->alarmCheckThreadError_ = ss.str();
214 __COUT_ERR__ << ss.str();
216 catch(
const std::exception& e)
218 __SS__ << e.what() <<
'\n';
219 std::lock_guard<std::mutex> lock(cs->alarmCheckThreadErrorMutex_);
220 cs->alarmCheckThreadError_ = ss.str();
221 __COUT_ERR__ << ss.str();
225 __SS__ <<
"checkSlowControlsAlarms() ERROR While sendin alarm messages"
231 catch(
const std::exception& e)
233 ss <<
"Exception message: " << e.what();
238 std::lock_guard<std::mutex> lock(cs->alarmCheckThreadErrorMutex_);
239 cs->alarmCheckThreadError_ = ss.str();
240 __COUT_ERR__ << ss.str();
243 sleep(alarmNotifyRefreshRate_);
252 __COUT__ <<
"checkSubscriptions() initializing..." << __E__;
253 std::vector<std::string> channelList;
254 std::vector<int> channelRefreshRates;
257 channelList = {
"FIRST VALUE"};
258 channelRefreshRates = {};
259 std::map<int, std::set<std::string>>::iterator mapReference =
260 cs->channelDependencyLookupMap_.begin();
261 while(mapReference !=
262 cs->channelDependencyLookupMap_
265 for(
auto channel : mapReference->second)
267 int refreshRate = 15;
268 channelRefreshRates.push_back(refreshRate);
270 __COUT__ <<
"THREAD actual time: " << std::time(NULL)
271 <<
"; uidPollTimeMap + 10 * refreshTime: "
272 << cs->uidPollTimeMap_.at(mapReference->first) + 10 * refreshRate
273 <<
" seconds" << __E__;
275 cs->uidPollTimeMap_.at(mapReference->first) + 10 * refreshRate)
279 cs->channelDependencyLookupMap_.erase(mapReference->first);
282 catch(
const std::exception& e)
288 std::vector<std::string>::iterator it =
289 find(channelList.begin(), channelList.end(), channel);
290 if(it == channelList.end())
294 channelList.push_back(channel);
295 __COUT__ <<
"Channel: " << channel <<
" refreshRate: " << refreshRate
296 <<
" seconds" << __E__;
297 __COUT__ <<
"channelDependencyLookupMap_.size(): "
298 << cs->channelDependencyLookupMap_.size()
299 <<
" UID: " << mapReference->first
300 <<
" mapReference->second.size(): "
301 << mapReference->second.size() << __E__;
309 if(channelRefreshRates.size() > 0)
311 *min_element(channelRefreshRates.begin(), channelRefreshRates.end());
313 __COUT__ <<
"Loop over channels subscribing - waiting time: " << minTime
314 <<
" seconds" << __E__;
324 CorePropertySupervisorBase::setSupervisorProperty(
325 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.CheckUserLockRequestTypes,
"*");
334 CorePropertySupervisorBase::setSupervisorProperty(
335 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
"poll");
339 CorePropertySupervisorBase::setSupervisorProperty(
340 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
341 "*=0 | getPages=1 | loadPhoebusPage=1 | getList=1 | getPVSettings=1 | getPvArchiverData=1 | generateUID=1 | getUserPermissions=1 |\
342 userActivityHeartbeat=1 | poll=1 | uid=1 | isUserAdmin=1 | getLastAlarmsData=1 | getAlarmsLogData=1 | getAlarmsCheck=1 | getPvData=1 ");
347 void SlowControlsDashboardSupervisor::request(
const std::string& requestType,
350 const WebUsers::RequestUserInfo& userInfo)
354 if(requestType !=
"getPages" && !pluginBusyMutex_.try_lock())
356 __SUP_SS__ <<
"Controls plugin is still initializing. Please try again in a "
362 __SUP_COUT__ <<
"User name is " << userInfo.username_ <<
"." << __E__;
363 __SUP_COUT__ <<
"User permission level for request '" << requestType <<
"' is "
364 << unsigned(userInfo.permissionLevel_)
365 <<
"(isAdmin=" << (userInfo.isAdmin() ?
"Yes" :
"No") <<
")."
369 handleRequest(requestType, xmlOut, cgiIn, userInfo);
371 catch(
const std::runtime_error& e)
373 __SUP_SS__ <<
"Error occurred handling request '" << requestType
374 <<
"': " << e.what() << __E__;
375 __SUP_COUT__ << ss.str();
376 xmlOut.addTextElementToData(
"Error", ss.str());
380 __SS__ <<
"Unknown error occurred handling request '" << requestType <<
"!'"
386 catch(
const std::exception& e)
388 ss <<
"Exception message: " << e.what();
393 __SUP_COUT__ << ss.str();
394 xmlOut.addTextElementToData(
"Error", ss.str());
397 pluginBusyMutex_.unlock();
398 __SUP_COUT__ << __E__;
402 void SlowControlsDashboardSupervisor::handleRequest(
403 const std::string Command,
406 const WebUsers::RequestUserInfo& userInfo)
409 __SUP_COUT__ << __E__;
411 if(Command ==
"poll")
414 Poll(cgiIn, xmlOut, uid);
416 else if(Command ==
"getPvData")
420 else if(Command ==
"userActivityHeartbeat")
426 else if(Command ==
"generateUID")
429 GenerateUID(cgiIn, xmlOut, channelList);
431 else if(Command ==
"isUserAdmin")
433 std::string json = std::string(
"{ \"message\": \"");
434 json += (userInfo.isAdmin() ?
"Yes" :
"No");
436 xmlOut.addTextElementToData(
"JSON", json.c_str());
438 else if(Command ==
"getUserPermissions")
440 GetUserPermissions(cgiIn, xmlOut, userInfo);
442 else if(Command ==
"getPVSettings")
444 __SUP_COUT__ <<
"Channel settings requested from server! " << __E__;
445 GetChannelSettings(cgiIn, xmlOut);
448 else if(Command ==
"getPvArchiverData")
450 __SUP_COUT__ <<
"Archived Channel data requested from server! " << __E__;
451 GetChannelArchiverData(cgiIn, xmlOut);
454 else if(Command ==
"getList")
456 __SUP_COUT__ <<
"Channel List requested from server! " << __E__;
457 GetList(cgiIn, xmlOut);
459 else if(Command ==
"getPages")
461 __SUP_COUT__ <<
"Requesting pages from server! " << __E__;
462 GetPages(cgiIn, xmlOut);
464 else if(Command ==
"loadPage")
467 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" " << page
470 loadPage(cgiIn, xmlOut, page, userInfo);
472 else if(Command ==
"loadPhoebusPage")
475 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" " << page
478 loadPhoebusPage(cgiIn, xmlOut, page, userInfo);
480 else if(Command ==
"createControlsPage")
482 SaveControlsPage(cgiIn, xmlOut, userInfo);
484 else if(Command ==
"createPhoebusControlsPage")
486 SavePhoebusControlsPage(cgiIn, xmlOut, userInfo);
488 else if(Command ==
"getLastAlarmsData")
490 __SUP_COUT__ <<
"Last Alarms Data requested from server! " << __E__;
491 GetLastAlarmsData(cgiIn, xmlOut);
494 else if(Command ==
"getAlarmsLogData")
496 __SUP_COUT__ <<
"Alarms Log Data requested from server! " << __E__;
497 GetAlarmsLogData(cgiIn, xmlOut);
500 else if(Command ==
"getAlarmsCheck")
502 __SUP_COUT__ <<
"Alarms Data requested from server! " << __E__;
503 GetAlarmsCheck(xmlOut);
505 else if(Command ==
"saveImageFile")
507 saveImageFile(cgiIn, xmlOut, userInfo);
511 __SUP_SS__ <<
"Request, " << Command
512 <<
", not recognized by the Slow Controls Dashboard Supervisor (was "
513 "it intended for another Supervisor?)."
518 __SUP_COUT__ <<
"" << __E__;
522 void SlowControlsDashboardSupervisor::Poll(cgicc::Cgicc& cgiIn,
HttpXmlDocument& xmlOut)
525 std::set<std::string> channels;
528 xmlOut.addTextElementToData(
"JSON", PollChannels_(channels));
532 void SlowControlsDashboardSupervisor::Poll(cgicc::Cgicc& ,
536 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
537 <<
"Polling on UID:" << UID << __E__;
539 std::map<int, std::set<std::string>>::iterator mapReference;
541 if(UID !=
"" && (mapReference = channelDependencyLookupMap_.find(std::stoi(UID))) !=
542 channelDependencyLookupMap_
545 uidPollTimeMap_.at(std::stoi(UID)) = std::time(NULL);
547 xmlOut.addTextElementToData(
548 "JSON", PollChannels_(mapReference->second));
552 xmlOut.addTextElementToData(
"JSON",
553 "{ \"message\": \"NOT_FOUND\"}");
558 std::string SlowControlsDashboardSupervisor::PollChannels_(
559 std::set<std::string>& channels,
bool resubscibe )
561 std::string JSONMessage =
"{ ";
563 for(
auto channel : channels)
567 __SUP_COUT__ << channel << __E__;
569 std::array<std::string, 4> channelInformation =
570 interface_->getCurrentValue(channel);
572 __SUP_COUT__ << channel <<
": " << channelInformation[1] <<
" : "
573 << channelInformation[3] << __E__;
575 if(channelInformation[0] !=
"NO_CHANGE")
578 JSONMessage +=
"\"" + channel +
"\": {";
579 JSONMessage +=
"\"Timestamp\":\"" + channelInformation[0] +
"\",";
580 JSONMessage +=
"\"Value\":\"" + channelInformation[1] +
"\",";
581 JSONMessage +=
"\"Status\":\"" + channelInformation[2] +
"\",";
582 JSONMessage +=
"\"Severity\":\"" + channelInformation[3] +
"\"},";
586 __SUP_COUT__ <<
"No change in value since last poll: " << channel << __E__;
590 if(channelInformation[3] ==
"INVALID" && resubscibe)
592 interface_->unsubscribe(channel);
593 interface_->subscribe(channel);
597 JSONMessage = JSONMessage.substr(0, JSONMessage.length() - 1);
599 __SUP_COUT__ << JSONMessage << __E__;
604 void SlowControlsDashboardSupervisor::GetChannelSettings(cgicc::Cgicc& cgiIn,
609 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
610 <<
"Getting settings for " << channelList << __E__;
612 std::string JSONMessage =
"{ ";
614 __SUP_COUT__ <<
"**********************" << channelList.size() << __E__;
615 if(channelList.size() > 0)
620 while((nextPos = channelList.find(
",", pos)) != std::string::npos)
622 channel = channelList.substr(pos, nextPos - pos);
624 __SUP_COUT__ << channel << __E__;
626 std::array<std::string, 9> channelSettings = interface_->getSettings(channel);
628 JSONMessage +=
"\"" + channel +
"\": {";
629 JSONMessage +=
"\"Units\": \"" + channelSettings[0] +
"\",";
630 JSONMessage +=
"\"Upper_Display_Limit\": \"" + channelSettings[1] +
"\",";
631 JSONMessage +=
"\"Lower_Display_Limit\": \"" + channelSettings[2] +
"\",";
632 JSONMessage +=
"\"Upper_Alarm_Limit\": \"" + channelSettings[3] +
"\",";
633 JSONMessage +=
"\"Upper_Warning_Limit\": \"" + channelSettings[4] +
"\",";
634 JSONMessage +=
"\"Lower_Warning_Limit\": \"" + channelSettings[5] +
"\",";
635 JSONMessage +=
"\"Lower_Alarm_Limit\": \"" + channelSettings[6] +
"\",";
636 JSONMessage +=
"\"Upper_Control_Limit\": \"" + channelSettings[7] +
"\",";
637 JSONMessage +=
"\"Lower_Control_Limit\": \"" + channelSettings[8] +
"\"},";
642 JSONMessage = JSONMessage.substr(0, JSONMessage.length() - 1);
645 __SUP_COUT__ << JSONMessage << __E__;
646 xmlOut.addTextElementToData(
"JSON", JSONMessage);
650 __SUP_COUT__ <<
"Did not find any settings because Channel list is length zero!"
653 xmlOut.addTextElementToData(
654 "JSON",
"{ \"message\": \"GetPVSettings\"}");
659 void SlowControlsDashboardSupervisor::GetChannelArchiverData(cgicc::Cgicc& cgiIn,
662 __SUP_COUT__ <<
"Requesting archived data!" << __E__;
668 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
669 <<
"Getting History for " << channelList <<
" start time: " << startTime
670 <<
" end time: " << endTime << __E__;
672 __SUP_COUT__ <<
"channelList.size(): " << channelList.size() << __E__;
673 if(channelList.size() > 0 && startTime > 0 && endTime > 0)
678 while((nextPos = channelList.find(
",", pos)) != std::string::npos)
680 channel = channelList.substr(pos, nextPos - pos);
682 __SUP_COUT__ <<
"Getting History for " << channel << __E__;
684 std::vector<std::vector<std::string>> channelInformation =
685 interface_->getChannelHistory(channel, startTime, endTime);
687 for(
auto channelData : channelInformation)
689 std::string JSONMessage =
"{ ";
690 JSONMessage +=
"\"" + channel +
"\": {";
691 JSONMessage +=
"\"Timestamp\":\"" + channelData[0] +
"\",";
692 JSONMessage +=
"\"Value\":\"" + channelData[1] +
"\",";
693 JSONMessage +=
"\"Status\":\"" + channelData[2] +
"\",";
694 JSONMessage +=
"\"Severity\":\"" + channelData[3] +
"\"},";
696 JSONMessage = JSONMessage.substr(0, JSONMessage.length() - 1);
698 xmlOut.addTextElementToData(
"JSON", JSONMessage);
706 __SUP_COUT__ <<
"Did not find any data because Channel list is length zero!"
709 xmlOut.addTextElementToData(
710 "JSON",
"{ \"message\": \"GetChannelArchiverData\"}");
715 void SlowControlsDashboardSupervisor::GetLastAlarmsData(cgicc::Cgicc& cgiIn,
718 __SUP_COUT__ <<
"Requesting last alarms data!" << __E__;
722 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
723 <<
"Getting last Alarms for " << channelList << __E__;
724 __SUP_COUT__ <<
"channelList.size(): " << channelList.size() << __E__;
726 std::vector<std::vector<std::string>> alarms;
729 std::function<void(
HttpXmlDocument&, std::vector<std::vector<std::string>>&)>
731 std::vector<std::vector<std::string>>& alarms) {
733 for(
auto& alarmRow : alarms)
735 std::string JSONMessage =
"{ ";
736 JSONMessage +=
"\"id\":\"" + alarmRow[0] +
"\",";
737 JSONMessage +=
"\"pvName\":\"" + alarmRow[1] +
"\",";
738 JSONMessage +=
"\"pvDescription\":\"" + alarmRow[2] +
"\",";
739 JSONMessage +=
"\"pvValue\":\"" + alarmRow[3] +
"\",";
740 JSONMessage +=
"\"pvStatus\":\"" + alarmRow[4] +
"\",";
741 JSONMessage +=
"\"pvSeverity\":\"" + alarmRow[5] +
"\",";
742 JSONMessage +=
"\"pvTime\":\"" + alarmRow[6] +
"\",";
744 JSONMessage = JSONMessage.substr(0, JSONMessage.length() - 1);
746 xmlOut.addTextElementToData(
"JSON", JSONMessage);
751 if(channelList.size() > 0)
756 while((nextPos = channelList.find(
",", pos)) != std::string::npos)
758 channel = channelList.substr(pos, nextPos - pos);
760 alarms = interface_->getLastAlarms(channel);
761 __SUP_COUT__ <<
"get Last Alarms for channel: " << channel << __E__;
762 jsonFiller(xmlOut, alarms);
768 alarms = interface_->getLastAlarms(
"");
769 __SUP_COUT__ <<
"get Last Alarms for all channels" << __E__;
770 jsonFiller(xmlOut, alarms);
775 void SlowControlsDashboardSupervisor::GetAlarmsCheck(
HttpXmlDocument& xmlOut)
777 __SUP_COUT__ <<
"Requesting alarms check cache data!" << __E__;
779 std::string JSONMessage =
"{ ";
780 JSONMessage +=
"\"last_check\":" +
781 std::to_string(std::chrono::duration_cast<std::chrono::seconds>(
782 alarms_timestamp_.time_since_epoch())
785 JSONMessage +=
"\"total\":" + std::to_string(alarms_.size()) +
",";
786 JSONMessage +=
"\"alarms\": [";
787 unsigned int nactive = 0;
790 for(
auto& alarmRow : alarms_)
793 JSONMessage +=
"\"name\":\"" + alarmRow[0] +
"\",";
794 if(alarmRow.size() > 9)
797 JSONMessage +=
"\"time\":\"" + alarmRow[1] +
"\",";
798 JSONMessage +=
"\"value\":\"" + alarmRow[2] +
"\",";
799 JSONMessage +=
"\"status\":\"" + alarmRow[3] +
"\",";
800 JSONMessage +=
"\"severity\":\"" + alarmRow[4] +
"\",";
803 JSONMessage.substr(0, JSONMessage.length() - 1);
807 JSONMessage.substr(0, JSONMessage.length() - 1);
809 JSONMessage +=
"], \"nactive\": " + std::to_string(nactive);
811 xmlOut.addTextElementToData(
"JSON", JSONMessage);
815 void SlowControlsDashboardSupervisor::GetAlarmsLogData(cgicc::Cgicc& cgiIn,
818 __SUP_COUT__ <<
"Requesting alarms log data!" << __E__;
822 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
823 <<
"Getting Alarms Log for " << channelList << __E__;
824 __SUP_COUT__ <<
"channelList.size(): " << channelList.size() << __E__;
826 std::vector<std::vector<std::string>> alarmsLog;
829 std::function<void(
HttpXmlDocument&, std::vector<std::vector<std::string>>&)>
831 std::vector<std::vector<std::string>>& alarmsLog) {
833 for(
auto& alarmRow : alarmsLog)
835 std::string JSONMessage =
"{ ";
836 JSONMessage +=
"\"id\":\"" + alarmRow[0] +
"\",";
837 JSONMessage +=
"\"pvName\":\"" + alarmRow[1] +
"\",";
838 JSONMessage +=
"\"pvValue\":\"" + alarmRow[2] +
"\",";
839 JSONMessage +=
"\"pvStatus\":\"" + alarmRow[3] +
"\",";
840 JSONMessage +=
"\"pvSeverity\":\"" + alarmRow[4] +
"\",";
841 JSONMessage +=
"\"pvTime\":\"" + alarmRow[5] +
"\",";
843 JSONMessage = JSONMessage.substr(0, JSONMessage.length() - 1);
845 xmlOut.addTextElementToData(
"JSON", JSONMessage);
850 if(channelList.size() > 0)
855 while((nextPos = channelList.find(
",", pos)) != std::string::npos)
857 channel = channelList.substr(pos, nextPos - pos);
859 alarmsLog = interface_->getAlarmsLog(channel);
860 __SUP_COUT__ <<
"get Alarms Log for channel: " << channel << __E__;
861 jsonFiller(xmlOut, alarmsLog);
867 alarmsLog = interface_->getAlarmsLog(
"");
868 __SUP_COUT__ <<
"get Alarms Log for all channels" << __E__;
869 jsonFiller(xmlOut, alarmsLog);
874 void SlowControlsDashboardSupervisor::GetUserPermissions(
877 const WebUsers::RequestUserInfo& )
883 void SlowControlsDashboardSupervisor::GenerateUID(cgicc::Cgicc& ,
885 std::string channelList)
887 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
888 <<
"Generating UID" << __E__;
890 std::set<std::string> channelDependencies;
894 channelDependencyLookupMap_.insert(
895 std::pair<
int, std::set<std::string>>(++UID_, channelDependencies));
897 uidPollTimeMap_.insert(std::pair<int, long int>(UID_, std::time(NULL)));
899 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" NEW UID: " << UID_
900 <<
" maps to " << channelDependencies.size() <<
" channels" << __E__;
902 xmlOut.addTextElementToData(
"JSON",
903 std::string(
"{ \"message\": \"") + std::to_string(UID_) +
908 void SlowControlsDashboardSupervisor::GetList(cgicc::Cgicc& ,
911 if(interface_ != NULL)
913 __SUP_COUT__ <<
"Interface is defined! Attempting to get list!" << __E__;
919 list = interface_->getList(
"JSON");
921 catch(std::runtime_error& e)
923 __SUP_SS__ <<
"Channel list request failed: " << e.what() << __E__;
927 __SUP_COUT__ <<
" " << list << __E__;
929 xmlOut.addTextElementToData(
"JSON", list);
933 __SUP_COUT__ <<
"Interface undefined! Failed to get list!" << __E__;
934 xmlOut.addTextElementToData(
"JSON",
"[\"None\"]");
939 void SlowControlsDashboardSupervisor::GetPages(cgicc::Cgicc& ,
942 std::vector<std::string> pages;
944 listFiles(
"",
true, &pages);
946 std::string returnJSON =
"[";
947 for(
auto it = pages.begin(); it != pages.end(); it++)
949 if(*it !=
"." && *it !=
"..")
950 returnJSON +=
"\"" + *it +
"\", ";
952 if(returnJSON.size() > 2 && returnJSON.compare(
"[") != 0)
954 __SUP_COUT__ <<
"Found pages on server!" << __E__;
955 returnJSON.resize(returnJSON.size() - 2);
961 __SUP_COUT__ <<
"No pages found on server!" << __E__;
962 returnJSON =
"[\"None\"]";
964 __SUP_COUT__ << returnJSON << __E__;
966 xmlOut.addTextElementToData(
"JSON", returnJSON);
970 void SlowControlsDashboardSupervisor::loadPage(
974 const WebUsers::RequestUserInfo& )
980 if(page.find(
"..") != std::string::npos)
982 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
983 <<
"Error! Request using '..': " << page << __E__;
985 else if(page.find(
"~") != std::string::npos)
987 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
988 <<
"Error! Request using '~': " << page << __E__;
990 else if(!(stat(page.c_str(), &buffer) == 0))
992 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
993 <<
"Error! File not found: " << page << __E__;
997 __SUP_COUT__ << page << __E__;
999 if(page.at(0) ==
'/')
1001 __SUP_COUT__ <<
"First character is '/'" << __E__;
1002 page.erase(page.begin(), page.begin() + 1);
1003 __SUP_COUT__ << page << __E__;
1006 std::string file = PAGES_DIRECTORY;
1008 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1009 <<
"Trying to load page: " << page << __E__;
1010 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1011 <<
"Trying to load page: " << file << __E__;
1015 std::ifstream infile(file);
1018 __SUP_COUT__ <<
"Failed reading file: " << file << __E__;
1020 xmlOut.addTextElementToData(
"Time",
"[\"Not Found\"]");
1021 xmlOut.addTextElementToData(
"Notes",
"[\"Not Found\"]");
1022 xmlOut.addTextElementToData(
1023 "Page", StringMacros::encodeURIComponent(page));
1026 __SUP_COUT__ <<
"Reading file" << __E__;
1028 std::string time =
"";
1029 std::string notes =
"";
1030 std::string controlsPage =
"";
1032 for(std::string line; getline(infile, line);)
1034 __SUP_COUT__ << line << __E__;
1035 if(!line.substr(0, 5).compare(
"Time:"))
1037 time = line.substr(6);
1039 else if(!line.substr(0, 6).compare(
"Notes:"))
1041 notes = line.substr(7);
1043 else if(!line.substr(0, 5).compare(
"Page:"))
1045 controlsPage = line.substr(6);
1048 __SUP_COUT__ <<
"Finished reading file" << __E__;
1049 __SUP_COUTV__(time);
1050 __SUP_COUTV__(notes);
1051 __SUP_COUTV__(controlsPage);
1053 xmlOut.addTextElementToData(
"Time", time);
1054 xmlOut.addTextElementToData(
"Notes", notes);
1055 xmlOut.addTextElementToData(
"Page", controlsPage);
1059 void SlowControlsDashboardSupervisor::loadPhoebusPage(
1063 const WebUsers::RequestUserInfo& )
1069 if(page.find(
"..") != std::string::npos)
1071 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1072 <<
"Error! Request using '..': " << page << __E__;
1074 else if(page.find(
"~") != std::string::npos)
1076 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1077 <<
"Error! Request using '~': " << page << __E__;
1079 else if(!(stat(page.c_str(), &buffer) == 0))
1081 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1082 <<
"Error! File not found: " << page << __E__;
1086 __SUP_COUT__ << page << __E__;
1088 if(page.at(0) ==
'/')
1090 __SUP_COUT__ <<
"First character is '/'" << __E__;
1091 page.erase(page.begin(), page.begin() + 1);
1092 __SUP_COUT__ << page << __E__;
1095 std::string file = PAGES_DIRECTORY;
1097 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1098 <<
"Trying to load page: " << page << __E__;
1099 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1100 <<
"Trying to load page: " << file << __E__;
1103 __SUP_COUT__ <<
"Reading file" << __E__;
1104 std::ifstream infile(file);
1107 __SUP_COUT__ <<
"Failed reading file: " << file << __E__;
1108 xmlOut.addTextElementToData(
1109 "Page", StringMacros::encodeURIComponent(page));
1114 for(std::string line; getline(infile, line);)
1118 __SUP_COUT__ << xml << __E__;
1119 xmlOut.addTextElementToData(
"PHOEBUS", xml);
1124 void SlowControlsDashboardSupervisor::SaveControlsPage(
1125 cgicc::Cgicc& cgiIn,
1127 const WebUsers::RequestUserInfo& )
1129 __SUP_COUT__ <<
"ControlsDashboard wants to create a Controls Page!" << __E__;
1138 __SUP_COUTV__(controlsPageName);
1139 __SUP_COUTV__(pageString);
1140 __SUP_COUTV__(Notes);
1141 __SUP_COUTV__(Time);
1142 __SUP_COUTV__(isControlsPagePublic);
1144 if(controlsPageName ==
"")
1147 std::string fullPath;
1148 if(isControlsPagePublic ==
"true")
1149 fullPath = (std::string)PAGES_PUBLIC_DIRECTORY;
1151 fullPath = (std::string)PAGES_PRIVATE_DIRECTORY;
1153 __SUP_COUTV__(fullPath);
1155 std::string file = fullPath + controlsPageName;
1157 __SUP_COUTV__(
"Saving Controls Page to: " + file);
1159 std::string extension = file.substr(file.length() - 4, 4);
1160 if(extension !=
".dat")
1162 __SUP_COUT__ <<
"Extension : " << extension << __E__;
1163 file += std::string(
".dat");
1165 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1166 <<
"Trying to save page: " << controlsPageName << __E__;
1167 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1168 <<
"Trying to save page as: " << file << __E__;
1172 std::ofstream outputFile;
1173 outputFile.open(file);
1174 if(!outputFile.is_open())
1176 __SUP_SS__ <<
"Failed to open file for writing: " << file << __E__;
1179 outputFile <<
"Time: " << Time <<
"\n";
1180 outputFile <<
"Notes: " << Notes <<
"\n";
1181 outputFile <<
"Page: " << pageString;
1184 __SUP_COUT__ <<
"Finished writing file" << __E__;
1190 void SlowControlsDashboardSupervisor::SavePhoebusControlsPage(
1191 cgicc::Cgicc& cgiIn,
1193 const WebUsers::RequestUserInfo& )
1195 __SUP_COUT__ <<
"ControlsDashboard wants to create a Controls Page!" << __E__;
1201 __SUP_COUTV__(controlsPageName);
1202 __SUP_COUTV__(pageString);
1203 __SUP_COUTV__(isControlsPagePublic);
1205 if(controlsPageName ==
"")
1208 std::string fullPath;
1209 if(isControlsPagePublic ==
"true")
1210 fullPath = (std::string)PAGES_PUBLIC_DIRECTORY;
1212 fullPath = (std::string)PAGES_PRIVATE_DIRECTORY;
1214 __SUP_COUTV__(fullPath);
1216 std::string file = fullPath + controlsPageName;
1218 __SUP_COUTV__(
"Saving Controls Page to: " + file);
1220 std::string extension = file.substr(file.length() - 4, 4);
1221 if(extension !=
".bob")
1223 __SUP_COUT__ <<
"Extension : " << extension << __E__;
1224 file += std::string(
".bob");
1226 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1227 <<
"Trying to save page: " << controlsPageName << __E__;
1228 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1229 <<
"Trying to save page as: " << file << __E__;
1233 std::ofstream outputFile;
1234 outputFile.open(file);
1235 if(!outputFile.is_open())
1237 __SUP_SS__ <<
"Failed to open file for writing: " << file << __E__;
1240 outputFile << pageString <<
"\n";
1243 __SUP_COUT__ <<
"Finished writing file" << __E__;
1249 void SlowControlsDashboardSupervisor::saveImageFile(
1250 cgicc::Cgicc& cgiIn,
1252 const WebUsers::RequestUserInfo& )
1254 __SUP_COUT__ <<
"ControlsDashboard wants to save the image file uploaded!" << __E__;
1256 std::string isImagePublic = cgiIn(
"isPublic");
1257 const std::vector<cgicc::FormFile>& files = cgiIn.getFiles();
1258 std::string filename;
1259 std::ofstream myfile;
1260 std::string fullPath;
1262 __SUP_COUTV__(files.size());
1263 __SUP_COUTV__(isImagePublic);
1265 if(isImagePublic ==
"true")
1266 fullPath = (std::string)PAGES_PUBLIC_DIRECTORY;
1268 fullPath = (std::string)PAGES_PRIVATE_DIRECTORY;
1270 for(
unsigned int i = 0; i < files.size(); ++i)
1272 filename = files[i].getFilename();
1273 filename = fullPath + filename;
1274 __COUT__ <<
"file " << i <<
" - " << filename << std::endl;
1276 myfile.open(filename.c_str());
1277 if(myfile.is_open())
1279 files[i].writeToStream(myfile);
1281 __SUP_COUT__ <<
"Finished writing image file" << __E__;
1289 void SlowControlsDashboardSupervisor::Subscribe(cgicc::Cgicc& ,
1295 void SlowControlsDashboardSupervisor::Unsubscribe(cgicc::Cgicc& ,
1307 struct stat fileInfo;
1308 stat(dir.c_str(), &fileInfo);
1309 if(S_ISDIR(fileInfo.st_mode))
1320 void SlowControlsDashboardSupervisor::listFiles(std::string innerDir,
1322 std::vector<std::string>* pages)
1324 std::string baseDir = PAGES_DIRECTORY;
1325 baseDir += innerDir;
1327 struct dirent* dirp;
1328 if((dp = opendir(baseDir.c_str())) == NULL)
1330 __SUP_COUT__ <<
"[ERROR: " << errno <<
" ] Couldn't open " << baseDir <<
"."
1336 while((dirp = readdir(dp)) != NULL)
1338 if(dirp->d_name != std::string(
".") && dirp->d_name != std::string(
".."))
1340 if(
isDir(baseDir + dirp->d_name) ==
true && recursive ==
true)
1343 __SUP_COUT__ <<
"[DIR]\t" << baseDir << dirp->d_name <<
"/" << __E__;
1344 listFiles(std::string(
"") + dirp->d_name +
"/",
true, pages);
1348 pages->push_back(innerDir + dirp->d_name);
1349 __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)