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::
337 setSupervisorProperty(
338 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES
339 .UserPermissionsThreshold,
340 "*=0 | getPages=1 | loadPhoebusPage=1 | getList=1 | getPVSettings=1 | getPvArchiverData=1 | generateUID=1 | getUserPermissions=1 |\
341 userActivityHeartbeat=1 | poll=1 | uid=1 | isUserAdmin=1 | getLastAlarmsData=1 | getAlarmsLogData=1 | getAlarmsCheck=1 | getPvData=1 ");
343 CorePropertySupervisorBase::
344 setSupervisorProperty(
345 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES
346 .AllowNoLoginRequestTypes,
347 "getPages | getList | loadPhoebusPage | generateUID | poll | "
349 __COUT_INFO__ <<
"readOnly true in setSupervisorProperty" << __E__;
354 void SlowControlsDashboardSupervisor::request(
const std::string& requestType,
357 const WebUsers::RequestUserInfo& userInfo)
359 __SUP_COUT__ <<
"requestType: " << requestType <<
", "
360 <<
"userInfo.username_: " << userInfo.username_ << __E__;
363 if(requestType !=
"getPages" && !pluginBusyMutex_.try_lock())
365 __SUP_SS__ <<
"Controls plugin is still initializing. Please try again in a "
371 __SUP_COUT__ <<
"User name is " << userInfo.username_ <<
"." << __E__;
372 __SUP_COUT__ <<
"User permission level for request '" << requestType <<
"' is "
373 << unsigned(userInfo.permissionLevel_)
374 <<
"(isAdmin=" << (userInfo.isAdmin() ?
"Yes" :
"No") <<
")."
378 handleRequest(requestType, xmlOut, cgiIn, userInfo);
380 catch(
const std::runtime_error& e)
382 __SUP_SS__ <<
"Error occurred handling request '" << requestType
383 <<
"': " << e.what() << __E__;
384 __SUP_COUT__ << ss.str();
385 xmlOut.addTextElementToData(
"Error", ss.str());
389 __SS__ <<
"Unknown error occurred handling request '" << requestType <<
"!'"
395 catch(
const std::exception& e)
397 ss <<
"Exception message: " << e.what();
402 __SUP_COUT__ << ss.str();
403 xmlOut.addTextElementToData(
"Error", ss.str());
406 pluginBusyMutex_.unlock();
407 __SUP_COUT__ << __E__;
411 void SlowControlsDashboardSupervisor::handleRequest(
412 const std::string Command,
415 const WebUsers::RequestUserInfo& userInfo)
418 __SUP_COUT__ << __E__;
420 if(Command ==
"poll")
423 Poll(cgiIn, xmlOut, uid);
425 else if(Command ==
"getPvData")
429 else if(Command ==
"userActivityHeartbeat")
435 else if(Command ==
"generateUID")
438 GenerateUID(cgiIn, xmlOut, channelList);
440 else if(Command ==
"isUserAdmin")
442 std::string json = std::string(
"{ \"message\": \"");
443 json += (userInfo.isAdmin() ?
"Yes" :
"No");
445 xmlOut.addTextElementToData(
"JSON", json.c_str());
447 else if(Command ==
"getUserPermissions")
449 GetUserPermissions(cgiIn, xmlOut, userInfo);
451 else if(Command ==
"getPVSettings")
453 __SUP_COUT__ <<
"Channel settings requested from server! " << __E__;
454 GetChannelSettings(cgiIn, xmlOut);
457 else if(Command ==
"getPvArchiverData")
459 __SUP_COUT__ <<
"Archived Channel data requested from server! " << __E__;
460 GetChannelArchiverData(cgiIn, xmlOut);
463 else if(Command ==
"getList")
465 __SUP_COUT__ <<
"Channel List requested from server! " << __E__;
466 GetList(cgiIn, xmlOut);
468 else if(Command ==
"getPages")
470 __SUP_COUT__ <<
"Requesting pages from server! " << __E__;
471 GetPages(cgiIn, xmlOut);
473 else if(Command ==
"loadPage")
476 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" " << page
479 loadPage(cgiIn, xmlOut, page, userInfo);
481 else if(Command ==
"loadPhoebusPage")
484 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" " << page
487 loadPhoebusPage(cgiIn, xmlOut, page, userInfo);
489 else if(Command ==
"createControlsPage")
491 SaveControlsPage(cgiIn, xmlOut, userInfo);
493 else if(Command ==
"createPhoebusControlsPage")
495 SavePhoebusControlsPage(cgiIn, xmlOut, userInfo);
497 else if(Command ==
"getLastAlarmsData")
499 __SUP_COUT__ <<
"Last Alarms Data requested from server! " << __E__;
500 GetLastAlarmsData(cgiIn, xmlOut);
503 else if(Command ==
"getAlarmsLogData")
505 __SUP_COUT__ <<
"Alarms Log Data requested from server! " << __E__;
506 GetAlarmsLogData(cgiIn, xmlOut);
509 else if(Command ==
"getAlarmsCheck")
511 __SUP_COUT__ <<
"Alarms Data requested from server! " << __E__;
512 GetAlarmsCheck(xmlOut);
514 else if(Command ==
"saveImageFile")
516 saveImageFile(cgiIn, xmlOut, userInfo);
520 __SUP_SS__ <<
"Request, " << Command
521 <<
", not recognized by the Slow Controls Dashboard Supervisor (was "
522 "it intended for another Supervisor?)."
527 __SUP_COUT__ <<
"" << __E__;
531 void SlowControlsDashboardSupervisor::Poll(cgicc::Cgicc& cgiIn,
HttpXmlDocument& xmlOut)
534 std::set<std::string> channels;
537 xmlOut.addTextElementToData(
"JSON", PollChannels_(channels));
541 void SlowControlsDashboardSupervisor::Poll(cgicc::Cgicc& ,
545 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
546 <<
"Polling on UID:" << UID << __E__;
548 std::map<int, std::set<std::string>>::iterator mapReference;
550 if(UID !=
"" && (mapReference = channelDependencyLookupMap_.find(std::stoi(UID))) !=
551 channelDependencyLookupMap_
554 uidPollTimeMap_.at(std::stoi(UID)) = std::time(NULL);
556 xmlOut.addTextElementToData(
557 "JSON", PollChannels_(mapReference->second));
561 xmlOut.addTextElementToData(
"JSON",
562 "{ \"message\": \"NOT_FOUND\"}");
567 std::string SlowControlsDashboardSupervisor::PollChannels_(
568 std::set<std::string>& channels,
bool resubscibe )
570 std::string JSONMessage =
"{ ";
572 for(
auto channel : channels)
576 __SUP_COUT__ << channel << __E__;
578 std::array<std::string, 4> channelInformation =
579 interface_->getCurrentValue(channel);
581 __SUP_COUT__ << channel <<
": " << channelInformation[1] <<
" : "
582 << channelInformation[3] << __E__;
584 if(channelInformation[0] !=
"NO_CHANGE")
587 JSONMessage +=
"\"" + channel +
"\": {";
588 JSONMessage +=
"\"Timestamp\":\"" + channelInformation[0] +
"\",";
589 JSONMessage +=
"\"Value\":\"" + channelInformation[1] +
"\",";
590 JSONMessage +=
"\"Status\":\"" + channelInformation[2] +
"\",";
591 JSONMessage +=
"\"Severity\":\"" + channelInformation[3] +
"\"},";
595 __SUP_COUT__ <<
"No change in value since last poll: " << channel << __E__;
599 if(channelInformation[3] ==
"INVALID" && resubscibe)
601 interface_->unsubscribe(channel);
602 interface_->subscribe(channel);
606 JSONMessage = JSONMessage.substr(0, JSONMessage.length() - 1);
608 __SUP_COUT__ << JSONMessage << __E__;
613 void SlowControlsDashboardSupervisor::GetChannelSettings(cgicc::Cgicc& cgiIn,
618 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
619 <<
"Getting settings for " << channelList << __E__;
621 std::string JSONMessage =
"{ ";
623 __SUP_COUT__ <<
"**********************" << channelList.size() << __E__;
624 if(channelList.size() > 0)
629 while((nextPos = channelList.find(
",", pos)) != std::string::npos)
631 channel = channelList.substr(pos, nextPos - pos);
633 __SUP_COUT__ << channel << __E__;
635 std::array<std::string, 9> channelSettings = interface_->getSettings(channel);
637 JSONMessage +=
"\"" + channel +
"\": {";
638 JSONMessage +=
"\"Units\": \"" + channelSettings[0] +
"\",";
639 JSONMessage +=
"\"Upper_Display_Limit\": \"" + channelSettings[1] +
"\",";
640 JSONMessage +=
"\"Lower_Display_Limit\": \"" + channelSettings[2] +
"\",";
641 JSONMessage +=
"\"Upper_Alarm_Limit\": \"" + channelSettings[3] +
"\",";
642 JSONMessage +=
"\"Upper_Warning_Limit\": \"" + channelSettings[4] +
"\",";
643 JSONMessage +=
"\"Lower_Warning_Limit\": \"" + channelSettings[5] +
"\",";
644 JSONMessage +=
"\"Lower_Alarm_Limit\": \"" + channelSettings[6] +
"\",";
645 JSONMessage +=
"\"Upper_Control_Limit\": \"" + channelSettings[7] +
"\",";
646 JSONMessage +=
"\"Lower_Control_Limit\": \"" + channelSettings[8] +
"\"},";
651 JSONMessage = JSONMessage.substr(0, JSONMessage.length() - 1);
654 __SUP_COUT__ << JSONMessage << __E__;
655 xmlOut.addTextElementToData(
"JSON", JSONMessage);
659 __SUP_COUT__ <<
"Did not find any settings because Channel list is length zero!"
662 xmlOut.addTextElementToData(
663 "JSON",
"{ \"message\": \"GetPVSettings\"}");
668 void SlowControlsDashboardSupervisor::GetChannelArchiverData(cgicc::Cgicc& cgiIn,
671 __SUP_COUT__ <<
"Requesting archived data!" << __E__;
677 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
678 <<
"Getting History for " << channelList <<
" start time: " << startTime
679 <<
" end time: " << endTime << __E__;
681 __SUP_COUT__ <<
"channelList.size(): " << channelList.size() << __E__;
682 if(channelList.size() > 0 && startTime > 0 && endTime > 0)
687 while((nextPos = channelList.find(
",", pos)) != std::string::npos)
689 channel = channelList.substr(pos, nextPos - pos);
691 __SUP_COUT__ <<
"Getting History for " << channel << __E__;
693 std::vector<std::vector<std::string>> channelInformation =
694 interface_->getChannelHistory(channel, startTime, endTime);
696 for(
auto channelData : channelInformation)
698 std::string JSONMessage =
"{ ";
699 JSONMessage +=
"\"" + channel +
"\": {";
700 JSONMessage +=
"\"Timestamp\":\"" + channelData[0] +
"\",";
701 JSONMessage +=
"\"Value\":\"" + channelData[1] +
"\",";
702 JSONMessage +=
"\"Status\":\"" + channelData[2] +
"\",";
703 JSONMessage +=
"\"Severity\":\"" + channelData[3] +
"\"},";
705 JSONMessage = JSONMessage.substr(0, JSONMessage.length() - 1);
707 xmlOut.addTextElementToData(
"JSON", JSONMessage);
715 __SUP_COUT__ <<
"Did not find any data because Channel list is length zero!"
718 xmlOut.addTextElementToData(
719 "JSON",
"{ \"message\": \"GetChannelArchiverData\"}");
724 void SlowControlsDashboardSupervisor::GetLastAlarmsData(cgicc::Cgicc& cgiIn,
727 __SUP_COUT__ <<
"Requesting last alarms data!" << __E__;
731 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
732 <<
"Getting last Alarms for " << channelList << __E__;
733 __SUP_COUT__ <<
"channelList.size(): " << channelList.size() << __E__;
735 std::vector<std::vector<std::string>> alarms;
738 std::function<void(
HttpXmlDocument&, std::vector<std::vector<std::string>>&)>
740 std::vector<std::vector<std::string>>& alarms) {
742 for(
auto& alarmRow : alarms)
744 std::string JSONMessage =
"{ ";
745 JSONMessage +=
"\"id\":\"" + alarmRow[0] +
"\",";
746 JSONMessage +=
"\"pvName\":\"" + alarmRow[1] +
"\",";
747 JSONMessage +=
"\"pvDescription\":\"" + alarmRow[2] +
"\",";
748 JSONMessage +=
"\"pvValue\":\"" + alarmRow[3] +
"\",";
749 JSONMessage +=
"\"pvStatus\":\"" + alarmRow[4] +
"\",";
750 JSONMessage +=
"\"pvSeverity\":\"" + alarmRow[5] +
"\",";
751 JSONMessage +=
"\"pvTime\":\"" + alarmRow[6] +
"\",";
753 JSONMessage = JSONMessage.substr(0, JSONMessage.length() - 1);
755 xmlOut.addTextElementToData(
"JSON", JSONMessage);
760 if(channelList.size() > 0)
765 while((nextPos = channelList.find(
",", pos)) != std::string::npos)
767 channel = channelList.substr(pos, nextPos - pos);
769 alarms = interface_->getLastAlarms(channel);
770 __SUP_COUT__ <<
"get Last Alarms for channel: " << channel << __E__;
771 jsonFiller(xmlOut, alarms);
777 alarms = interface_->getLastAlarms(
"");
778 __SUP_COUT__ <<
"get Last Alarms for all channels" << __E__;
779 jsonFiller(xmlOut, alarms);
784 void SlowControlsDashboardSupervisor::GetAlarmsCheck(
HttpXmlDocument& xmlOut)
786 __SUP_COUT__ <<
"Requesting alarms check cache data!" << __E__;
788 std::string JSONMessage =
"{ ";
789 JSONMessage +=
"\"last_check\":" +
790 std::to_string(std::chrono::duration_cast<std::chrono::seconds>(
791 alarms_timestamp_.time_since_epoch())
794 JSONMessage +=
"\"total\":" + std::to_string(alarms_.size()) +
",";
795 JSONMessage +=
"\"alarms\": [";
796 unsigned int nactive = 0;
799 for(
auto& alarmRow : alarms_)
802 JSONMessage +=
"\"name\":\"" + alarmRow[0] +
"\",";
803 if(alarmRow.size() > 9)
806 JSONMessage +=
"\"time\":\"" + alarmRow[1] +
"\",";
807 JSONMessage +=
"\"value\":\"" + alarmRow[2] +
"\",";
808 JSONMessage +=
"\"status\":\"" + alarmRow[3] +
"\",";
809 JSONMessage +=
"\"severity\":\"" + alarmRow[4] +
"\",";
812 JSONMessage.substr(0, JSONMessage.length() - 1);
816 JSONMessage.substr(0, JSONMessage.length() - 1);
818 JSONMessage +=
"], \"nactive\": " + std::to_string(nactive);
820 xmlOut.addTextElementToData(
"JSON", JSONMessage);
824 void SlowControlsDashboardSupervisor::GetAlarmsLogData(cgicc::Cgicc& cgiIn,
827 __SUP_COUT__ <<
"Requesting alarms log data!" << __E__;
831 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
832 <<
"Getting Alarms Log for " << channelList << __E__;
833 __SUP_COUT__ <<
"channelList.size(): " << channelList.size() << __E__;
835 std::vector<std::vector<std::string>> alarmsLog;
838 std::function<void(
HttpXmlDocument&, std::vector<std::vector<std::string>>&)>
840 std::vector<std::vector<std::string>>& alarmsLog) {
842 for(
auto& alarmRow : alarmsLog)
844 std::string JSONMessage =
"{ ";
845 JSONMessage +=
"\"id\":\"" + alarmRow[0] +
"\",";
846 JSONMessage +=
"\"pvName\":\"" + alarmRow[1] +
"\",";
847 JSONMessage +=
"\"pvValue\":\"" + alarmRow[2] +
"\",";
848 JSONMessage +=
"\"pvStatus\":\"" + alarmRow[3] +
"\",";
849 JSONMessage +=
"\"pvSeverity\":\"" + alarmRow[4] +
"\",";
850 JSONMessage +=
"\"pvTime\":\"" + alarmRow[5] +
"\",";
852 JSONMessage = JSONMessage.substr(0, JSONMessage.length() - 1);
854 xmlOut.addTextElementToData(
"JSON", JSONMessage);
859 if(channelList.size() > 0)
864 while((nextPos = channelList.find(
",", pos)) != std::string::npos)
866 channel = channelList.substr(pos, nextPos - pos);
868 alarmsLog = interface_->getAlarmsLog(channel);
869 __SUP_COUT__ <<
"get Alarms Log for channel: " << channel << __E__;
870 jsonFiller(xmlOut, alarmsLog);
876 alarmsLog = interface_->getAlarmsLog(
"");
877 __SUP_COUT__ <<
"get Alarms Log for all channels" << __E__;
878 jsonFiller(xmlOut, alarmsLog);
883 void SlowControlsDashboardSupervisor::GetUserPermissions(
886 const WebUsers::RequestUserInfo& )
892 void SlowControlsDashboardSupervisor::GenerateUID(cgicc::Cgicc& ,
894 std::string channelList)
896 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
897 <<
"Generating UID" << __E__;
899 std::set<std::string> channelDependencies;
903 channelDependencyLookupMap_.insert(
904 std::pair<
int, std::set<std::string>>(++UID_, channelDependencies));
906 uidPollTimeMap_.insert(std::pair<int, long int>(UID_, std::time(NULL)));
908 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" NEW UID: " << UID_
909 <<
" maps to " << channelDependencies.size() <<
" channels" << __E__;
911 xmlOut.addTextElementToData(
"JSON",
912 std::string(
"{ \"message\": \"") + std::to_string(UID_) +
917 void SlowControlsDashboardSupervisor::GetList(cgicc::Cgicc& ,
920 if(interface_ != NULL)
922 __SUP_COUT__ <<
"Interface is defined! Attempting to get list!" << __E__;
928 list = interface_->getList(
"JSON");
930 catch(std::runtime_error& e)
932 __SUP_SS__ <<
"Channel list request failed: " << e.what() << __E__;
936 __SUP_COUT__ <<
" " << list << __E__;
938 xmlOut.addTextElementToData(
"JSON", list);
942 __SUP_COUT__ <<
"Interface undefined! Failed to get list!" << __E__;
943 xmlOut.addTextElementToData(
"JSON",
"[\"None\"]");
948 void SlowControlsDashboardSupervisor::GetPages(cgicc::Cgicc& ,
951 std::vector<std::string> pages;
953 listFiles(
"",
true, &pages);
955 std::string returnJSON =
"[";
956 for(
auto it = pages.begin(); it != pages.end(); it++)
958 if(*it !=
"." && *it !=
"..")
959 returnJSON +=
"\"" + *it +
"\", ";
961 if(returnJSON.size() > 2 && returnJSON.compare(
"[") != 0)
963 __SUP_COUT__ <<
"Found pages on server!" << __E__;
964 returnJSON.resize(returnJSON.size() - 2);
970 __SUP_COUT__ <<
"No pages found on server!" << __E__;
971 returnJSON =
"[\"None\"]";
973 __SUP_COUT__ << returnJSON << __E__;
975 xmlOut.addTextElementToData(
"JSON", returnJSON);
979 void SlowControlsDashboardSupervisor::loadPage(
983 const WebUsers::RequestUserInfo& )
989 if(page.find(
"..") != std::string::npos)
991 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
992 <<
"Error! Request using '..': " << page << __E__;
994 else if(page.find(
"~") != std::string::npos)
996 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
997 <<
"Error! Request using '~': " << page << __E__;
999 else if(!(stat(page.c_str(), &buffer) == 0))
1001 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1002 <<
"Error! File not found: " << page << __E__;
1006 __SUP_COUT__ << page << __E__;
1008 if(page.at(0) ==
'/')
1010 __SUP_COUT__ <<
"First character is '/'" << __E__;
1011 page.erase(page.begin(), page.begin() + 1);
1012 __SUP_COUT__ << page << __E__;
1015 std::string file = PAGES_DIRECTORY;
1017 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1018 <<
"Trying to load page: " << page << __E__;
1019 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1020 <<
"Trying to load page: " << file << __E__;
1024 std::ifstream infile(file);
1027 __SUP_COUT__ <<
"Failed reading file: " << file << __E__;
1029 xmlOut.addTextElementToData(
"Time",
"[\"Not Found\"]");
1030 xmlOut.addTextElementToData(
"Notes",
"[\"Not Found\"]");
1031 xmlOut.addTextElementToData(
1032 "Page", StringMacros::encodeURIComponent(page));
1035 __SUP_COUT__ <<
"Reading file" << __E__;
1037 std::string time =
"";
1038 std::string notes =
"";
1039 std::string controlsPage =
"";
1041 for(std::string line; getline(infile, line);)
1043 __SUP_COUT__ << line << __E__;
1044 if(!line.substr(0, 5).compare(
"Time:"))
1046 time = line.substr(6);
1048 else if(!line.substr(0, 6).compare(
"Notes:"))
1050 notes = line.substr(7);
1052 else if(!line.substr(0, 5).compare(
"Page:"))
1054 controlsPage = line.substr(6);
1057 __SUP_COUT__ <<
"Finished reading file" << __E__;
1058 __SUP_COUTV__(time);
1059 __SUP_COUTV__(notes);
1060 __SUP_COUTV__(controlsPage);
1062 xmlOut.addTextElementToData(
"Time", time);
1063 xmlOut.addTextElementToData(
"Notes", notes);
1064 xmlOut.addTextElementToData(
"Page", controlsPage);
1068 void SlowControlsDashboardSupervisor::loadPhoebusPage(
1072 const WebUsers::RequestUserInfo& )
1078 if(page.find(
"..") != std::string::npos)
1080 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1081 <<
"Error! Request using '..': " << page << __E__;
1083 else if(page.find(
"~") != std::string::npos)
1085 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1086 <<
"Error! Request using '~': " << page << __E__;
1088 else if(!(stat(page.c_str(), &buffer) == 0))
1090 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1091 <<
"Error! File not found: " << page << __E__;
1095 __SUP_COUT__ << page << __E__;
1097 if(page.at(0) ==
'/')
1099 __SUP_COUT__ <<
"First character is '/'" << __E__;
1100 page.erase(page.begin(), page.begin() + 1);
1101 __SUP_COUT__ << page << __E__;
1104 std::string file = PAGES_DIRECTORY;
1106 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1107 <<
"Trying to load page: " << page << __E__;
1108 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1109 <<
"Trying to load page: " << file << __E__;
1112 __SUP_COUT__ <<
"Reading file" << __E__;
1113 std::ifstream infile(file);
1116 __SUP_COUT__ <<
"Failed reading file: " << file << __E__;
1117 xmlOut.addTextElementToData(
1118 "Page", StringMacros::encodeURIComponent(page));
1123 for(std::string line; getline(infile, line);)
1127 __SUP_COUT__ << xml << __E__;
1128 xmlOut.addTextElementToData(
"PHOEBUS", xml);
1133 void SlowControlsDashboardSupervisor::SaveControlsPage(
1134 cgicc::Cgicc& cgiIn,
1136 const WebUsers::RequestUserInfo& )
1138 __SUP_COUT__ <<
"ControlsDashboard wants to create a Controls Page!" << __E__;
1147 __SUP_COUTV__(controlsPageName);
1148 __SUP_COUTV__(pageString);
1149 __SUP_COUTV__(Notes);
1150 __SUP_COUTV__(Time);
1151 __SUP_COUTV__(isControlsPagePublic);
1153 if(controlsPageName ==
"")
1156 std::string fullPath;
1157 if(isControlsPagePublic ==
"true")
1158 fullPath = (std::string)PAGES_PUBLIC_DIRECTORY;
1160 fullPath = (std::string)PAGES_PRIVATE_DIRECTORY;
1162 __SUP_COUTV__(fullPath);
1164 std::string file = fullPath + controlsPageName;
1166 __SUP_COUTV__(
"Saving Controls Page to: " + file);
1168 std::string extension = file.substr(file.length() - 4, 4);
1169 if(extension !=
".dat")
1171 __SUP_COUT__ <<
"Extension : " << extension << __E__;
1172 file += std::string(
".dat");
1174 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1175 <<
"Trying to save page: " << controlsPageName << __E__;
1176 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1177 <<
"Trying to save page as: " << file << __E__;
1181 std::ofstream outputFile;
1182 outputFile.open(file);
1183 if(!outputFile.is_open())
1185 __SUP_SS__ <<
"Failed to open file for writing: " << file << __E__;
1188 outputFile <<
"Time: " << Time <<
"\n";
1189 outputFile <<
"Notes: " << Notes <<
"\n";
1190 outputFile <<
"Page: " << pageString;
1193 __SUP_COUT__ <<
"Finished writing file" << __E__;
1199 void SlowControlsDashboardSupervisor::SavePhoebusControlsPage(
1200 cgicc::Cgicc& cgiIn,
1202 const WebUsers::RequestUserInfo& )
1204 __SUP_COUT__ <<
"ControlsDashboard wants to create a Controls Page!" << __E__;
1210 __SUP_COUTV__(controlsPageName);
1211 __SUP_COUTV__(pageString);
1212 __SUP_COUTV__(isControlsPagePublic);
1214 if(controlsPageName ==
"")
1217 std::string fullPath;
1218 if(isControlsPagePublic ==
"true")
1219 fullPath = (std::string)PAGES_PUBLIC_DIRECTORY;
1221 fullPath = (std::string)PAGES_PRIVATE_DIRECTORY;
1223 __SUP_COUTV__(fullPath);
1225 std::string file = fullPath + controlsPageName;
1227 __SUP_COUTV__(
"Saving Controls Page to: " + file);
1229 std::string extension = file.substr(file.length() - 4, 4);
1230 if(extension !=
".bob")
1232 __SUP_COUT__ <<
"Extension : " << extension << __E__;
1233 file += std::string(
".bob");
1235 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1236 <<
"Trying to save page: " << controlsPageName << __E__;
1237 __SUP_COUT__ << this->getApplicationDescriptor()->getLocalId()
1238 <<
"Trying to save page as: " << file << __E__;
1242 std::ofstream outputFile;
1243 outputFile.open(file);
1244 if(!outputFile.is_open())
1246 __SUP_SS__ <<
"Failed to open file for writing: " << file << __E__;
1249 outputFile << pageString <<
"\n";
1252 __SUP_COUT__ <<
"Finished writing file" << __E__;
1258 void SlowControlsDashboardSupervisor::saveImageFile(
1259 cgicc::Cgicc& cgiIn,
1261 const WebUsers::RequestUserInfo& )
1263 __SUP_COUT__ <<
"ControlsDashboard wants to save the image file uploaded!" << __E__;
1265 std::string isImagePublic = cgiIn(
"isPublic");
1266 const std::vector<cgicc::FormFile>& files = cgiIn.getFiles();
1267 std::string filename;
1268 std::ofstream myfile;
1269 std::string fullPath;
1271 __SUP_COUTV__(files.size());
1272 __SUP_COUTV__(isImagePublic);
1274 if(isImagePublic ==
"true")
1275 fullPath = (std::string)PAGES_PUBLIC_DIRECTORY;
1277 fullPath = (std::string)PAGES_PRIVATE_DIRECTORY;
1279 for(
unsigned int i = 0; i < files.size(); ++i)
1281 filename = files[i].getFilename();
1282 filename = fullPath + filename;
1283 __COUT__ <<
"file " << i <<
" - " << filename << std::endl;
1285 myfile.open(filename.c_str());
1286 if(myfile.is_open())
1288 files[i].writeToStream(myfile);
1290 __SUP_COUT__ <<
"Finished writing image file" << __E__;
1298 void SlowControlsDashboardSupervisor::Subscribe(cgicc::Cgicc& ,
1304 void SlowControlsDashboardSupervisor::Unsubscribe(cgicc::Cgicc& ,
1316 struct stat fileInfo;
1317 stat(dir.c_str(), &fileInfo);
1318 if(S_ISDIR(fileInfo.st_mode))
1329 void SlowControlsDashboardSupervisor::listFiles(std::string innerDir,
1331 std::vector<std::string>* pages)
1333 std::string baseDir = PAGES_DIRECTORY;
1334 baseDir += innerDir;
1336 struct dirent* dirp;
1337 if((dp = opendir(baseDir.c_str())) == NULL)
1339 __SUP_COUT__ <<
"[ERROR: " << errno <<
" ] Couldn't open " << baseDir <<
"."
1345 while((dirp = readdir(dp)) != NULL)
1347 if(dirp->d_name != std::string(
".") && dirp->d_name != std::string(
".."))
1349 if(
isDir(baseDir + dirp->d_name) ==
true && recursive ==
true)
1352 __SUP_COUT__ <<
"[DIR]\t" << baseDir << dirp->d_name <<
"/" << __E__;
1353 listFiles(std::string(
"") + dirp->d_name +
"/",
true, pages);
1357 pages->push_back(innerDir + dirp->d_name);
1358 __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)