1 #include "otsdaq-utilities/ControlsDashboard/ControlsDashboardSupervisor.h"
7 #include "otsdaq-core/SlowControlsCore/SlowControlsVInterface.h"
8 #include "otsdaq-core/PluginMakers/MakeSlowControls.h"
12 #define PAGES_DIRECTORY \
13 std::string(getenv("SERVICE_DATA_PATH")) + "/ControlsDashboardData/pages/";
19 : CoreSupervisorBase(stub)
21 __SUP_COUT__ <<
"Constructor." << __E__;
23 INIT_MF(
"ControlsDashboardSupervisor");
27 __SUP_COUT__ <<
"Constructed." << __E__;
31 ControlsDashboardSupervisor::~ControlsDashboardSupervisor(
void)
33 __SUP_COUT__ <<
"Destructor." << __E__;
35 __SUP_COUT__ <<
"Destructed." << __E__;
39 void ControlsDashboardSupervisor::destroy(
void)
46 void ControlsDashboardSupervisor::init(
void)
51 __COUT__ << std::endl;
52 ConfigurationTree node = CorePropertySupervisorBase::getSupervisorTableNode();
53 std::string pluginType = node.getNode(
"ControlsInterfacePluginType").getValue();
54 __COUTV__(pluginType);
56 interface_ = makeSlowControls(
58 , node.getUIDAsString()
59 , CorePropertySupervisorBase::getContextTreeNode()
60 , CorePropertySupervisorBase::getSupervisorConfigurationPath());
61 __COUT__ << std::endl;
63 __COUT__ <<
"Finished init() w/ interface: " << pluginType << std::endl;
74 void ControlsDashboardSupervisor::setSupervisorPropertyDefaults()
76 CorePropertySupervisorBase::setSupervisorProperty(
77 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.CheckUserLockRequestTypes,
"*");
83 void ControlsDashboardSupervisor::forceSupervisorPropertyValues()
85 CorePropertySupervisorBase::setSupervisorProperty(
86 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
"poll");
90 void ControlsDashboardSupervisor::request(
const std::string& requestType, cgicc::Cgicc& cgiIn,
91 HttpXmlDocument& xmlOut,
const WebUsers::RequestUserInfo& userInfo)
146 __SUP_COUT__ <<
"User name is " << userInfo.username_ <<
"." << __E__;
147 __SUP_COUT__ <<
"User permission level for request '" << requestType <<
"' is " <<
148 unsigned(userInfo.permissionLevel_) <<
"." << __E__;
152 handleRequest(requestType,xmlOut,cgiIn,userInfo.username_);
154 catch(
const std::runtime_error& e)
156 __SS__ <<
"Error occurred handling request '" << requestType <<
157 "': " << e.what() << __E__;
158 __SUP_COUT__ << ss.str();
159 xmlOut.addTextElementToData(
"Error",ss.str());
163 __SS__ <<
"Unknown error occurred handling request '" << requestType <<
165 __SUP_COUT__ << ss.str();
166 xmlOut.addTextElementToData(
"Error",ss.str());
171 void ControlsDashboardSupervisor::handleRequest(
const std::string Command,
172 HttpXmlDocument& xmlOut, cgicc::Cgicc& cgiIn,
173 const std::string &username)
176 __COUT__ << std::endl;
178 if(Command ==
"poll")
180 std::string uid = CgiDataUtilities::getOrPostData(cgiIn,
"uid");
181 Poll(cgiIn, xmlOut, uid);
183 else if(Command ==
"generateUID")
185 std::string pvList = CgiDataUtilities::getOrPostData(cgiIn,
"PVList");
186 GenerateUID(cgiIn, xmlOut, pvList);
188 else if(Command ==
"GetPVSettings")
190 std::string pvList = CgiDataUtilities::getOrPostData(cgiIn,
"PVList");
191 GetPVSettings(cgiIn, xmlOut, pvList);
192 xmlOut.addTextElementToData(
"id", CgiDataUtilities::getData(cgiIn,
"id"));
194 else if(Command ==
"getList")
196 GetList(cgiIn, xmlOut);
198 else if(Command ==
"getPages")
200 __COUT__ <<
"Requesting pages from server! " << std::endl;
201 GetPages(cgiIn, xmlOut);
203 else if(Command ==
"loadPage")
205 std::string page = CgiDataUtilities::getData(cgiIn,
"Page");
206 __COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" " << page
209 loadPage(cgiIn, xmlOut, page);
211 __COUT__ << std::endl;
218 void ControlsDashboardSupervisor::Poll(cgicc::Cgicc& cgiIn,
219 HttpXmlDocument& xmlOut,
222 __COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
223 <<
"Polling on UID:" << UID << std::endl;
225 std::map<int, std::set<std::string>>::iterator mapReference;
228 (mapReference = pvDependencyLookupMap_.find(std::stoi(UID))) !=
229 pvDependencyLookupMap_.end())
231 std::string JSONMessage =
"{ ";
233 for(
auto pv : mapReference->second)
235 __COUT__ << pv << std::endl;
239 std::array<std::string, 4> pvInformation = interface_->getCurrentValue(pv);
241 __COUT__ << pv <<
": " << pvInformation[1] <<
" : " << pvInformation[3]
244 if(pvInformation[0] !=
"NO_CHANGE")
247 JSONMessage +=
"\"" + pv +
"\": {";
255 JSONMessage +=
"\"Timestamp\" : \"" + pvInformation[0] +
"\",";
256 JSONMessage +=
"\"Value\" : \"" + pvInformation[1] +
"\",";
257 JSONMessage +=
"\"Status\" : \"" + pvInformation[2] +
"\",";
258 JSONMessage +=
"\"Severity\" : \"" + pvInformation[3] +
"\"},";
262 __COUT__ <<
"No change in value since last poll: " << pv << std::endl;
266 if(pvInformation[3] ==
"INVALID")
268 interface_->subscribe(pv);
277 JSONMessage = JSONMessage.substr(0, JSONMessage.length() - 1);
279 __COUT__ << JSONMessage << std::endl;
280 xmlOut.addTextElementToData(
"JSON", JSONMessage);
304 xmlOut.addTextElementToData(
"JSON",
305 "{ \"message\": \"NOT_FOUND\"}");
309 void ControlsDashboardSupervisor::GetPVSettings(cgicc::Cgicc& cgiIn,
310 HttpXmlDocument& xmlOut,
313 __COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
314 <<
"Getting settings for " << pvList << std::endl;
316 std::string JSONMessage =
"{ ";
321 size_t lastIndex = pvList.find_last_of(
",");
322 std::cout <<
"**********************" << pvList.size() << std::endl;
323 if(pvList.size() > 0)
325 while((nextPos = pvList.find(
",", pos)) != std::string::npos)
327 pv = pvList.substr(pos, nextPos - pos);
329 __COUT__ << pv << std::endl;
331 std::array<std::string, 9> pvSettings = interface_->getSettings(pv);
333 JSONMessage +=
"\"" + pv +
"\": {";
334 JSONMessage +=
"\"Units \": \"" + pvSettings[0] +
"\",";
335 JSONMessage +=
"\"Upper_Display_Limit\": \"" + pvSettings[1] +
"\",";
336 JSONMessage +=
"\"Lower_Display_Limit\": \"" + pvSettings[2] +
"\",";
337 JSONMessage +=
"\"Upper_Alarm_Limit \": \"" + pvSettings[3] +
"\",";
338 JSONMessage +=
"\"Upper_Warning_Limit\": \"" + pvSettings[4] +
"\",";
339 JSONMessage +=
"\"Lower_Warning_Limit\": \"" + pvSettings[5] +
"\",";
340 JSONMessage +=
"\"Lower_Alarm_Limit \": \"" + pvSettings[6] +
"\",";
341 JSONMessage +=
"\"Upper_Control_Limit\": \"" + pvSettings[7] +
"\",";
342 JSONMessage +=
"\"Lower_Control_Limit\": \"" + pvSettings[8] +
"\"},";
347 JSONMessage = JSONMessage.substr(0, JSONMessage.length() - 1);
350 __COUT__ << JSONMessage << std::endl;
351 xmlOut.addTextElementToData(
"JSON", JSONMessage);
355 xmlOut.addTextElementToData(
356 "JSON",
"{ \"message\": \"GetPVSettings\"}");
360 void ControlsDashboardSupervisor::GenerateUID(cgicc::Cgicc& cgiIn,
361 HttpXmlDocument& xmlOut,
364 __COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" "
365 <<
"Generating UID" << std::endl;
367 std::set<std::string> pvDependencies;
372 size_t lastIndex = pvlist.find_last_of(
",");
374 if(pvlist.size() > 0)
377 __COUT__ << pvlist << std::endl;
379 while((nextPos = pvlist.find(
",", pos)) != std::string::npos)
381 pv = pvlist.substr(pos, nextPos - pos);
384 pvDependencies.insert(pv);
388 pvDependencyLookupMap_.insert(
389 std::pair<
int, std::set<std::string>>(++UID_, pvDependencies));
391 uid = (std::string(
"{ \"message\": \"") + std::to_string(UID_) +
"\"}");
395 __COUT__ << this->getApplicationDescriptor()->getLocalId()
396 <<
" PVList invalid: " << pvlist << std::endl;
397 uid =
"{ \"message\": \"-1\"}";
400 __COUT__ << this->getApplicationDescriptor()->getLocalId() <<
" NEW UID: " << UID_
403 xmlOut.addTextElementToData(
"JSON", uid);
406 void ControlsDashboardSupervisor::GetList(cgicc::Cgicc& cgiIn, HttpXmlDocument& xmlOut)
409 if(interface_ != NULL)
412 __COUT__ <<
"Interface is defined! Attempting to get list!" << std::endl;
413 __COUT__ << this->getApplicationDescriptor()->getLocalId() << std::endl;
414 std::cout <<
" " << interface_->getList(
"JSON") << std::endl;
416 xmlOut.addTextElementToData(
"JSON", interface_->getList(
"JSON"));
420 __COUT__ <<
"Interface undefined! Failed to get list!" << std::endl;
421 xmlOut.addTextElementToData(
"JSON",
"[\"None\"]");
425 void ControlsDashboardSupervisor::GetPages(cgicc::Cgicc& cgiIn, HttpXmlDocument& xmlOut)
449 std::vector<std::string> pages;
451 listFiles(
"",
true, &pages);
453 std::string returnJSON =
"[";
454 for(
auto it = pages.begin(); it != pages.end(); it++)
456 if(*it !=
"." && *it !=
"..")
457 returnJSON +=
"\"" + *it +
"\", ";
459 if(returnJSON.size() > 2 && returnJSON.compare(
"[") != 0)
461 __COUT__ <<
"Found pages on server!" << std::endl;
462 returnJSON.resize(returnJSON.size() - 2);
468 __COUT__ <<
"No pages found on server!" << std::endl;
469 returnJSON =
"[\"None\"]";
471 std::cout << returnJSON << std::endl;
473 xmlOut.addTextElementToData(
"JSON", returnJSON);
476 void ControlsDashboardSupervisor::loadPage(cgicc::Cgicc& cgiIn,
477 HttpXmlDocument& xmlOut,
482 if(page.find(
"..") != std::string::npos)
484 __COUT__ << this->getApplicationDescriptor()->getLocalId()
485 <<
"Error! Request using '..': " << page << std::endl;
487 else if(page.find(
"~") != std::string::npos)
489 __COUT__ << this->getApplicationDescriptor()->getLocalId()
490 <<
"Error! Request using '~': " << page << std::endl;
492 else if(!(stat(page.c_str(), &buffer) == 0))
494 __COUT__ << this->getApplicationDescriptor()->getLocalId()
495 <<
"Error! File not found: " << page << std::endl;
498 std::string file = PAGES_DIRECTORY file +=
"/" + page;
499 __COUT__ << this->getApplicationDescriptor()->getLocalId()
500 <<
"Trying to load page: " << page << std::endl;
501 __COUT__ << this->getApplicationDescriptor()->getLocalId()
502 <<
"Trying to load page: " << file << std::endl;
506 std::ifstream infile(file);
507 std::cout <<
"Reading file" << std::endl;
508 std::string JSONpage =
"";
509 for(std::string line; getline(infile, line);)
511 std::cout << line << std::endl;
514 std::cout <<
"Finished reading file" << std::endl;
516 xmlOut.addTextElementToData(
"JSON", JSONpage);
519 void ControlsDashboardSupervisor::Subscribe(cgicc::Cgicc& cgiIn, HttpXmlDocument& xmlOut)
523 void ControlsDashboardSupervisor::Unsubscribe(cgicc::Cgicc& cgiIn,
524 HttpXmlDocument& xmlOut)
532 bool ControlsDashboardSupervisor::isDir(std::string dir)
534 struct stat fileInfo;
535 stat(dir.c_str(), &fileInfo);
536 if(S_ISDIR(fileInfo.st_mode))
546 void ControlsDashboardSupervisor::listFiles(std::string baseDir,
548 std::vector<std::string>* pages)
550 std::string base = PAGES_DIRECTORY;
555 if((dp = opendir(base.c_str())) == NULL)
557 std::cout <<
"[ERROR: " << errno <<
" ] Couldn't open " << base <<
"."
563 while((dirp = readdir(dp)) != NULL)
565 if(dirp->d_name != std::string(
".") && dirp->d_name != std::string(
".."))
567 if(isDir(base + dirp->d_name) ==
true && recursive ==
true)
570 std::cout <<
"[DIR]\t" << baseDir << dirp->d_name <<
"/" << std::endl;
571 listFiles(baseDir + dirp->d_name +
"/",
true, pages);
575 pages->push_back(baseDir + dirp->d_name);
576 std::cout <<
"[FILE]\t" << baseDir << dirp->d_name << std::endl;