30 var SmartLaunch = SmartLaunch || {};
32 if (typeof Debug ==
'undefined')
33 throw(
'ERROR: Debug is undefined! Must include Debug.js before SmartLaunch.js');
34 else if (typeof Globals ==
'undefined')
35 throw(
'ERROR: Globals is undefined! Must include Globals.js before SmartLaunch.js');
37 SmartLaunch.MENU_PRIMARY_COLOR =
"rgb(220, 187, 165)";
38 SmartLaunch.MENU_SECONDARY_COLOR =
"rgb(130, 51, 51)";
42 SmartLaunch.doShowContexts =
false;
43 SmartLaunch.subsystems = [];
48 SmartLaunch.systemToContextMap = {};
68 SmartLaunch.create =
function() {
99 var _CHECKBOX_MIN_W = 240;
100 var _CHECKBOX_MAX_W = 540;
101 var _LAUNCH_MIN_W = 525;
105 var _needEventListeners =
true;
107 var _subsetBasePath =
"XDAQContextTable";
109 var _systemStatusArray = [];
110 var _contextRecords = [];
116 var _inTransition =
false;
117 var _wasInTransition =
false;
118 var _timeInState = 0;
119 var _transitionPercentComplete = 0;
121 var _transitionName =
"";
123 var _fsmName, _fsmWindowName;
124 var _getStateTimer = 0;
125 var _runFSMTimer = 0;
127 var _running =
false;
133 SmartLaunch.launcher =
this;
134 Debug.log(
"SmartLaunch.launcher constructed");
137 Debug.log(
"SmartLaunch.launcher initialized");
144 Debug.log(
"Smart Launch init ");
145 DesktopContent.tooltip(
"Smart Launch",
146 "Welcome to the Smart Launch user interface. "+
147 "Select which pieces of the configuration you want to enable, and then press the launch button!" +
149 "Once the pieces you want are enabled, press the run button!"
153 ConfigurationAPI.getSubsetRecords(
156 localGetContextRecordsHandler
160 window.clearTimeout(_getStateTimer);
161 _getStateTimer = window.setTimeout(getCurrentState,1000);
166 function localGetContextRecordsHandler(records)
169 console.log(records);
170 _contextRecords = records;
175 if(_needEventListeners)
177 window.addEventListener(
"resize",redrawWindow);
178 _needEventListeners =
false;
182 readEnabledSubsystems();
191 function createElements()
193 Debug.log(
"createElements");
216 cel = document.getElementById(
"content");
219 cel = document.createElement(
"div");
220 cel.setAttribute(
"id",
"content");
231 sl = document.createElement(
"div");
232 sl.setAttribute(
"id",
"subsystemDiv");
233 el = document.createElement(
"div");
234 el.setAttribute(
"id",
"subsystemDivContainer");
241 al = document.createElement(
"a");
242 al.setAttribute(
"id",
"launchLink");
243 al.onclick =
function()
245 Debug.log(
"clicked launch");
246 SmartLaunch.launcher.launch();
249 el = document.createElement(
"div");
250 el.setAttribute(
"id",
"launchDiv");
251 el.innerHTML =
"Launch";
256 al = document.createElement(
"a");
257 al.setAttribute(
"id",
"runLink");
258 al.onclick =
function()
260 Debug.log(
"clicked run");
261 SmartLaunch.launcher.run();
264 el = document.createElement(
"div");
265 el.setAttribute(
"id",
"runDiv");
266 el.innerHTML =
"Run";
271 sl = document.createElement(
"div");
272 sl.setAttribute(
"id",
"runStatusDiv");
273 sl.style.top =
"10px";
283 document.body.appendChild(cel);
291 function readEnabledSubsystems()
295 Debug.log(
"readEnabledSubsystems");
297 var recordsArray = [];
299 for(var i=0; i<SmartLaunch.subsystems.length; ++i)
301 for(var j=0; j<SmartLaunch.systemToContextMap[SmartLaunch.subsystems[i]].length; ++j)
302 recordsArray.push(SmartLaunch.systemToContextMap[SmartLaunch.subsystems[i]][j]);
304 if(SmartLaunch.doShowContexts)
305 for(var i=0; i<_contextRecords.length; ++i)
306 recordsArray.push(_contextRecords[i]);
308 console.log(
"recordsArray",recordsArray);
310 ConfigurationAPI.getFieldValuesForRecords(
314 localStatusForRecordsHandler
320 Debug.log(
"There was error reading the status of the configuration subsystems (" +
321 "were the subsystem variables setup properly?): " +
322 e, Debug.HIGH_PRIORITY);
327 function localStatusForRecordsHandler(recFieldValues)
329 Debug.log(
"localStatusForRecordsHandler value-length=" + recFieldValues.length)
330 var statusArray = [];
331 for(var i in recFieldValues)
333 recFieldValues[i].fieldValue ==
"On"?
true:
false);
335 console.log(
"statusArray",statusArray);
337 _systemStatusArray = [];
339 for(var i=0; i<SmartLaunch.subsystems.length; ++i)
341 _systemStatusArray.push(
true);
342 for(var j=0; j<SmartLaunch.systemToContextMap[SmartLaunch.subsystems[i]].length; ++j,++k)
344 _systemStatusArray[i] =
false;
346 if(SmartLaunch.doShowContexts)
347 for(var i=0; i<_contextRecords.length; ++i, ++k)
348 _systemStatusArray.push(statusArray[k]);
350 console.log(
"_systemStatusArray",_systemStatusArray);
363 function redrawWindow()
368 var w = window.innerWidth | 0;
369 var h = window.innerHeight | 0;
371 if(w < _LAUNCH_MIN_W)
373 if(h < _LAUNCH_MIN_W)
376 Debug.log(
"redrawWindow to " + w +
" - " + h);
378 var sdiv = document.getElementById(
"subsystemDiv");
379 var ldiv = document.getElementById(
"launchDiv");
380 var rdiv = document.getElementById(
"runDiv");
381 _runStatusDiv = runStatusDiv = document.getElementById(
"runStatusDiv");
383 var chkH = _CHECKBOX_H;
385 if(chkW < _CHECKBOX_MIN_W) chkW = _CHECKBOX_MIN_W;
386 if(chkW > _CHECKBOX_MAX_W) chkW = _CHECKBOX_MAX_W;
388 var sdivH = 66 + chkH*SmartLaunch.subsystems.length;
390 if(SmartLaunch.doShowContexts)
392 sdivH += 66 + chkH*_contextRecords.length;
402 var sdivY = (h-sdivH)/2;
419 var ldivX = _MARGIN + chkW;
421 if(ldivSz > w - ldivX - _MARGIN*3)
422 ldivSz = w - ldivX - _MARGIN*3;
424 var ldivY = (h-ldivSz)/2 - ldivSz/2;
425 var lratio = 180/300;
427 var rdivX = _MARGIN + chkW;
429 var rdivY = ldivY + ldivSz;
430 var rratio = 180/300;
438 var hideableSubsystems = SmartLaunch.subsystems.length && SmartLaunch.doShowContexts;
439 var hideableContexts = SmartLaunch.subsystems.length;
441 if(SmartLaunch.subsystems.length)
443 if(hideableSubsystems)
444 str +=
"<a onclick='SmartLaunch.launcher.toggleCheckboxDiv(0);' title='Hide/Show Subsystems'>";
445 str +=
"<h3>Subsystems</h3>";
446 if(hideableSubsystems)
449 str +=
"<div id='ssCheckboxDiv'>";
450 for(var i=0;i<SmartLaunch.subsystems.length;++i,++statusIndex)
452 str +=
"<div class='ssCheckbox' style='height:" + chkH +
"px;" +
454 str +=
"<div class='pretty p-icon p-round p-smooth' onclick='SmartLaunch.launcher.handleCheckbox(" +
455 statusIndex +
");' >";
456 str +=
" <input type='checkbox' class='subsystemCheckboxes' " +
457 (_systemStatusArray[statusIndex]?
"checked":
"") +
459 str +=
"<div class='state p-success'>";
460 str +=
"<i class='icon mdi mdi-check'></i>";
461 str +=
"<label>" + SmartLaunch.subsystems[i] +
"</label>";
465 str +=
"<div id='clearDiv'></div>";
469 else if(!SmartLaunch.doShowContexts)
471 str +=
"No subsystem configuration definition found.";
475 if(SmartLaunch.doShowContexts)
478 str +=
"<a onclick='SmartLaunch.launcher.toggleCheckboxDiv(1);' title='Hide/Show Contexts'>";
479 str +=
"<h3>Individual Contexts</h3>";
483 if(!_contextRecords.length)
484 str +=
"No contexts found.";
487 str +=
"<div id='ctxCheckboxDiv'>";
488 for(var i=0; i<_contextRecords.length; ++i,++statusIndex)
490 str +=
"<div class='ssCheckbox' style='height:" + chkH +
"px;" +
492 str +=
"<div class='pretty p-icon p-round p-smooth' onclick='SmartLaunch.launcher.handleCheckbox(" +
493 statusIndex +
");' >";
494 str +=
" <input type='checkbox' class='subsystemCheckboxes' " +
495 (_systemStatusArray[statusIndex]?
"checked":
"") +
497 str +=
"<div class='state p-success'>";
498 str +=
"<i class='icon mdi mdi-check'></i>";
499 str +=
"<label>" + _contextRecords[i] +
"</label>";
503 str +=
"<div id='clearDiv'></div>";
509 sdiv.style.left = (sdivX-20) +
"px";
510 sdiv.style.top = sdivY +
"px";
511 sdiv.style.height = sdivH +
"px";
512 sdiv.style.width = sdivW +
"px";
513 sdiv.style.display =
"block";
516 sdiv = document.getElementById(
"subsystemDivContainer");
517 sdiv.style.left = (sdivX-20) +
"px";
518 sdiv.style.top = sdivY +
"px";
519 sdiv.style.height = sdivH +
"px";
520 sdiv.style.width = sdivW +
"px";
522 sdiv.innerHTML = str;
523 sdiv.style.display =
"block";
541 ldiv.style.left = (ldivX + (w - ldivX - _MARGIN*2 - ldivSz)/2) +
"px";
542 ldiv.style.top = (ldivY+((ldivSz-ldivSz*lratio)/2)) +
"px";
544 ldiv.style.width = ldivSz +
"px";
545 ldiv.style.paddingTop = (ldivSz*lratio/2 - 36/2) +
"px";
546 ldiv.style.paddingBottom = (ldivSz*lratio/2- 36/2) +
"px";
550 ldiv.style.borderRadius = ldivSz +
"px/" + (ldivSz*200/300) +
"px";
551 ldiv.style.fontSize = ldivSz/10 +
"px";
553 ldiv.style.display =
"block";
560 rdiv.style.left = (rdivX + (w - rdivX - _MARGIN*2 - rdivSz)/2) +
"px";
561 rdiv.style.top = (rdivY+((rdivSz-rdivSz*rratio)/2)) +
"px";
563 rdiv.style.width = rdivSz +
"px";
564 rdiv.style.paddingTop = (rdivSz*rratio/2 - 36/2) +
"px";
565 rdiv.style.paddingBottom = (rdivSz*rratio/2- 36/2) +
"px";
569 rdiv.style.borderRadius = rdivSz +
"px/" + (rdivSz*200/300) +
"px";
570 rdiv.style.fontSize = rdivSz/10 +
"px";
572 rdiv.style.display =
"block";
575 runStatusDiv.style.left = (rdivX + _MARGIN + (w - rdivX - _MARGIN*2 - rdivSz)/2) +
"px";
576 runStatusDiv.style.top = (h/2 - 50) +
"px";
577 runStatusDiv.style.width = (rdivSz + _MARGIN) +
"px";
578 runStatusDiv.style.fontSize = rdivSz/15 +
"px";
586 function getCurrentState()
588 window.clearTimeout(_getStateTimer);
590 DesktopContent.XMLHttpRequest(
"Request?RequestType=getCurrentState" +
591 "&fsmName=" + _fsmName,
593 localGetStateHandler,
602 function localGetStateHandler(req,
id,err)
606 Debug.log(
"Error: " + err, Debug.HIGH_PRIORITY);
611 _state = DesktopContent.getXMLValue(req,
"current_state");
612 _inTransition = DesktopContent.getXMLValue(req,
"in_transition") ==
"1";
613 _timeInState = DesktopContent.getXMLValue(req,
"time_in_state") | 0;
614 _runNumber = DesktopContent.getXMLValue(req,
"run_number");
615 _transitionPercentComplete = DesktopContent.getXMLValue(req,
"transition_progress") | 0;
617 if(_transitionPercentComplete > 100)
620 _transitionPercentComplete = 100;
633 window.clearTimeout(_getStateTimer);
634 _getStateTimer = window.setTimeout(getCurrentState,1000);
641 function displayState()
648 if(_state ==
"Running")
653 document.getElementById(
"runDiv").innerHTML =
"Stop";
661 document.getElementById(
"runDiv").innerHTML =
"Run";
667 str +=
"<table cellspacing='0' cellpadding='0'>";
671 str +=
"<tr><td style='font-weight: bold; padding-right:20px;'>Transition:</td><td>" +
672 _transitionName +
"</td></tr>";
674 str +=
"<tr><td style='font-weight: bold; padding-right:20px;'>Current State:</td><td>" +
675 _state +
"</td></tr>";
684 let i = _runNumber.lastIndexOf(
' ');
687 let hdr = _runNumber.substr(0,i);
688 let num = _runNumber.substr(i+1);
689 stateStr =
"Running <br> " + _runNumber;
690 str +=
"<tr><td style='font-weight: bold; padding-right:20px;'>" +
699 let progressStr =
"";
702 progressStr = _transitionPercentComplete +
" %";
704 str +=
"<tr><td style='font-weight: bold; padding-right:20px;'>Progress:</td><td>" +
705 progressStr +
"</td></tr>";
707 if(!_wasInTransition)
708 _wasInTransition =
true;
710 else if(_wasInTransition)
713 _wasInTransition =
false;
714 progressStr = 100 +
" %";
716 str +=
"<tr><td style='font-weight: bold; padding-right:20px;'>Transitioning:</td><td>" +
717 progressStr +
"</td></tr>";
723 var hours = (_timeInState/60.0/60.0)|0;
724 var mins = ((_timeInState%(60*60))/60.0)|0;
725 var secs = _timeInState%60;
728 if(mins < 10) tstr +=
"0";
730 if(secs < 10) tstr +=
"0";
733 str +=
"<tr><td style='font-weight: bold; padding-right:20px;'>Time-in-State:</td><td>" + tstr +
"</td></tr>";
738 _runStatusDiv.innerHTML = str;
740 _runStatusDiv.style.display =
"block";
742 catch(e) {console.log(e);}
747 this.launch =
function()
750 DesktopContent.popUpVerification(
751 "Are you sure you want to relaunch otsdaq?",
753 0,
"#efeaea",0,
"#770000");
756 function localLaunch()
758 Debug.log(
"localLaunch");
760 var checkboxes = document.getElementsByClassName(
'subsystemCheckboxes');
761 console.log(
"checkboxes",checkboxes);
762 var checkedArray = [];
763 for(var i=0;i<checkboxes.length;++i)
764 checkedArray.push(checkboxes[i].checked);
765 console.log(
"checkedArray",checkedArray);
767 var recordsArray = [];
768 var valuesArray = [];
772 if(SmartLaunch.doShowContexts)
775 for(var i=0; i<_contextRecords.length; ++i)
777 recordsArray.push(_contextRecords[i]);
778 valuesArray.push(checkedArray[SmartLaunch.subsystems.length+i]?
785 for(var i=0; i<SmartLaunch.subsystems.length; ++i)
787 for(var j=0; j<SmartLaunch.systemToContextMap[SmartLaunch.subsystems[i]].length; ++j)
789 recordsArray.push(SmartLaunch.systemToContextMap[SmartLaunch.subsystems[i]][j]);
790 valuesArray.push(checkedArray[i]?
"1":
"0");
795 console.log(
"recordsArray",recordsArray);
796 console.log(
"valuesArray",valuesArray);
799 var localModifiedTables = undefined;
801 localSetSequenceOfRecords();
804 function localSetSequenceOfRecords()
806 ConfigurationAPI.setFieldValuesForRecords(
808 recordsArray[recordIndex],
810 valuesArray[recordIndex],
811 function(modifiedTables)
813 Debug.log(
"recordIndex = " + recordIndex);
815 if(modifiedTables.length == 0)
817 Debug.log(
"Something went very wrong. Notify administrators.",
818 Debug.HIGH_PRIORITY);
823 if(recordIndex == recordsArray.length)
825 Debug.log(
"Done with sequence.");
828 ConfigurationAPI.saveModifiedTables(modifiedTables,
830 function(savedTables, savedGroups, savedAliases)
832 if(!savedTables.length)
834 Debug.log(
"Something went very wrong. Notify administrators.",
835 Debug.HIGH_PRIORITY);
839 Debug.log(
"Successfully applied subsystem selections!", Debug.INFO_PRIORITY);
843 Debug.log(
"Relaunching ots...");
844 SmartLaunch.launcher.gatewayLaunchOts();
851 console.log(
"setFieldValuesForRecords modifiedTables",modifiedTables);
852 localModifiedTables = modifiedTables;
853 localSetSequenceOfRecords();
856 ,localModifiedTables);
863 this.gatewayLaunchOts =
function()
865 Debug.log(
"Relaunching otsdaq!",Debug.INFO_PRIORITY);
868 window.clearTimeout(_getStateTimer);
871 DesktopContent._blockSystemCheckMailbox.innerHTML =
"1";
872 window.setTimeout(localDelayedLaunch,1000);
876 function localDelayedLaunch()
878 DesktopContent.XMLHttpRequest(
"Request?" +
879 "RequestType=gatewayLaunchOTS",
883 Debug.log(
"gatewayLaunchOts handler ");
889 function localCountDown()
891 Debug.log(
"Waiting " + countDown +
" seconds for startup sequence...",
892 Debug.INFO_PRIORITY);
894 window.setTimeout(
function() {
895 Debug.log(
"localCountDown handler ");
900 DesktopContent._blockSystemCheckMailbox.innerHTML =
"";
902 Debug.log(
"And we are back!",Debug.INFO_PRIORITY);
921 this.run =
function()
925 var timeoutCount = 0;
926 var operativeWord =
"starting";
931 DesktopContent.popUpVerification(
932 "Are you sure you want to stop the run?",
934 0,
"#efeaea",0,
"#770000");
939 Debug.log(
"localStop");
941 operativeWord =
"stopping";
947 DesktopContent.popUpVerification(
948 "Are you sure you want to start a run?",
950 0,
"#efeaea",0,
"#770000");
955 Debug.log(
"localRun");
957 window.clearTimeout(_runFSMTimer);
960 if(timeoutCount > 60)
962 Debug.log(
"Timeout reached! Giving up on " + operativeWord +
" the run.", Debug.HIGH_PRIORITY);
968 window.clearTimeout(_getStateTimer);
969 _getStateTimer = window.setTimeout(getCurrentState,1000);
971 window.clearTimeout(_runFSMTimer);
972 _runFSMTimer = window.setTimeout(localRun,1000);
976 if(lastState == _state)
978 Debug.log(
"State machine is not progressing! Stuck in '" +
979 _state +
".' Giving up on " + operativeWord +
" the run.", Debug.HIGH_PRIORITY);
985 let transitionPostData =
"";
987 if(_state ==
"Initial")
989 _transitionName =
"Initialize";
991 else if(_state ==
"Failed")
996 Debug.log(
"Fault encountered! Giving up on " + operativeWord +
" the run.", Debug.HIGH_PRIORITY);
999 _transitionName =
"Halt";
1001 else if(_state ==
"Halted")
1003 _transitionName =
"Configure";
1005 transitionPostData =
"ConfigurationAlias=" +
"defaultSystemAlias";
1007 else if(_state ==
"Configured")
1009 if(operativeWord ==
"stopping")
1012 Debug.log(
"<i>otsdaq</i> has now Stopped! " +
1013 _runNumber +
".", Debug.INFO_PRIORITY);
1017 _transitionName =
"Start";
1019 else if(_state ==
"Paused")
1021 _transitionName =
"Start";
1023 else if(_state ==
"Running")
1025 if(operativeWord ==
"stopping")
1027 _transitionName =
"Stop";
1032 Debug.log(
"<i>otsdaq</i> is now Running! " +
1033 _runNumber +
".", Debug.INFO_PRIORITY);
1039 Debug.log(
"Unknown action for current state '" + _state +
"'..." +
1040 "Giving up on " + operativeWord +
" the run.", Debug.HIGH_PRIORITY);
1044 _inTransition =
true;
1045 _transitionPercentComplete = 0;
1049 Debug.log(
"_transitionName = " + _transitionName +
1050 " transitionPostData = " + transitionPostData);
1052 DesktopContent.XMLHttpRequest(
"StateMachineXgiHandler?StateMachine=" +
1054 "&fsmName=" + _fsmName +
1055 "&fsmWindowName=" + _fsmWindowName,
1061 var success = DesktopContent.getXMLValue(req,
"state_tranisition_attempted") ==
"1";
1064 var err = DesktopContent.getXMLValue(req,
"state_tranisition_attempted_err");
1066 Debug.log(err,Debug.HIGH_PRIORITY);
1067 Debug.log(
"Server indicated failure to attempt state transition. " +
1068 "Giving up on " + operativeWord +
" the run.",Debug.HIGH_PRIORITY);
1073 window.clearTimeout(_runFSMTimer);
1074 _runFSMTimer = window.setTimeout(localRun,3000);
1086 this.toggleCheckboxDiv =
function(i)
1088 Debug.log(
"toggleCheckboxDiv(i) " + i);
1093 el = document.getElementById(
"ssCheckboxDiv");
1094 el.style.display = (el.style.display ==
"none")?
"block":
"none";
1098 el = document.getElementById(
"ctxCheckboxDiv");
1099 el.style.display = (el.style.display ==
"none")?
"block":
"none";
1101 else throw(
"Invalid index checkbox div " + i);
1106 this.handleCheckbox =
function(c)
1108 Debug.log(
"handleCheckbox(c) " + c);
1110 var checkboxes = document.getElementsByClassName(
'subsystemCheckboxes');
1111 console.log(
"checkboxes",checkboxes);
1112 var checkedArray = [];
1113 for(var i=0;i<checkboxes.length;++i)
1114 checkedArray.push(checkboxes[i].checked);
1115 console.log(
"checkedArray",checkedArray);
1117 Debug.log(
"set to " + checkedArray[c]);
1120 var contextEnabledMap = {};
1121 for(var i=0; i<_contextRecords.length; ++i)
1122 contextEnabledMap[_contextRecords[i]] = [checkedArray[SmartLaunch.subsystems.length+i],
1123 SmartLaunch.subsystems.length+i];
1126 if(c < SmartLaunch.subsystems.length)
1129 for(var j=0; j<SmartLaunch.systemToContextMap[SmartLaunch.subsystems[c]].length; ++j)
1133 SmartLaunch.systemToContextMap[SmartLaunch.subsystems[c]][j]
1134 ][0] = checkedArray[c];
1136 checkboxes[contextEnabledMap[
1137 SmartLaunch.systemToContextMap[SmartLaunch.subsystems[c]][j]
1138 ][1]].checked = checkedArray[c];
1146 contextEnabledMap[_contextRecords[c - SmartLaunch.subsystems.length]][0] = checkedArray[c];
1149 console.log(
"contextEnabledMap",contextEnabledMap);
1153 for(var i=0;i<SmartLaunch.subsystems.length;++i)
1159 for(var j=0; j<SmartLaunch.systemToContextMap[SmartLaunch.subsystems[i]].length; ++j)
1161 if(!contextEnabledMap[
1162 SmartLaunch.systemToContextMap[SmartLaunch.subsystems[i]][j]][0])
1170 checkboxes[i].checked = enabled;