1 'use strict';
  2 
  3 // To de done:
  4 //  - CheckLID status (should be open or closed)
  5 //  - Is it necessary to switch the bias-voltage off?
  6 //  - Get reasonable timeouts for all steps (wait, get, run)
  7 //  - Improve order to accelerate execution
  8 //
  9 // =================================================================
 10 
 11 /*
 12 var table =
 13 [
 14  [ "AGILENT_CONTROL" ],
 15  [ "BIAS_CONTROL"    ],
 16  [ "CHAT"            ],
 17  [ "DATA_LOGGER"     ],
 18  [ "DRIVE_CONTROL"   ],
 19  [ "FEEDBACK"        ],
 20  [ "FAD_CONTROL"     ],
 21  [ "FSC_CONTROL"     ],
 22  [ "FTM_CONTROL"     ],
 23  [ "LID_CONTROL"     ],
 24  [ "MAGIC_WEATHER"   ],
 25  [ "MCP"             ],
 26  [ "PWR_CONTROL"     ],
 27  [ "RATE_CONTROL"    ],
 28  [ "RATE_SCAN"       ],
 29  [ "SMART_FACT"      ],
 30  [ "TIME_CHECK"      ],
 31  [ "TNG_WEATHER"     ],
 32 ];
 33 
 34 if (dim.state("DRIVE_CONTROL").name=="Locked")
 35 {
 36     throw new Error("Drivectrl still locked... needs UNLOCK first.");
 37     //while (!dim.send("DRIVE_CONTROL"))
 38     //    v8.sleep();
 39     //dim.send("DRIVE_CONTROL/UNLOCK");
 40     //dim.wait("DRIVE_CONTROL", "Armed", 1000);
 41 }
 42 
 43 */
 44 
 45 console.out("");
 46 dim.alarm();
 47 
 48 var loop;
 49 include("scripts/Handler.js");
 50 include("scripts/CheckStates.js");
 51 
 52 // -----------------------------------------------------------------
 53 // Make sure camera electronics is switched on and has power
 54 // -----------------------------------------------------------------
 55 
 56 include("scripts/handleAgilentPowerOn24V.js");
 57 include("scripts/handleAgilentPowerOn50V.js");
 58 include("scripts/handleAgilentPowerOn80V.js");
 59 include("scripts/handlePwrCameraOn.js");
 60 
 61 checkSend(["AGILENT_CONTROL_24V","AGILENT_CONTROL_50V","AGILENT_CONTROL_80V","PWR_CONTROL"]);
 62 
 63 loop = new Handler("PowerOn");
 64 //loop.add(handleAgilentPowerOn24V);
 65 //loop.add(handleAgilentPowerOn50V);
 66 //loop.add(handleAgilentPowerOn80V);
 67 loop.add(handlePwrCameraOn);
 68 loop.run();
 69 console.out("");
 70 
 71 // If power was switched on: wait for a few seconds
 72 
 73 // -----------------------------------------------------------------
 74 // Now take care that the bias control, the ftm and the fsc are
 75 // properly connected and are in a reasonable state (e.g. the
 76 // trigger is switched off)
 77 // -----------------------------------------------------------------
 78 
 79 include("scripts/handleBiasVoltageOff.js");
 80 include("scripts/handleFtmIdle.js");
 81 include("scripts/handleFscConnected.js");
 82 include("scripts/handleFeedbackConnected.js");
 83 include("scripts/handleRatectrlConnected.js");
 84 include("scripts/handleLidClosed.js");
 85 include("scripts/handleFadConnected.js");
 86 
 87 checkSend(["BIAS_CONTROL","FAD_CONTROL","FTM_CONTROL", "FSC_CONTROL", "FEEDBACK", "RATE_CONTROL", "MCP"]);
 88 
 89 dim.send("MCP/RESET");
 90 
 91 loop = new Handler("SystemSetup");
 92 loop.add(handleBiasVoltageOff);
 93 loop.add(handleFtmIdle);
 94 loop.add(handleFscConnected);
 95 loop.add(handleFadConnected);
 96 loop.add(handleFeedbackConnected); // Feedback needs FAD to be Connected
 97 loop.add(handleRatectrlConnected);
 98 loop.add(handleLidClosed);
 99 loop.run();
100 
101 console.out("biasctrl:    "+dim.state("BIAS_CONTROL").name);
102 console.out("ftmctrl:     "+dim.state("FTM_CONTROL").name);
103 console.out("fscctrl:     "+dim.state("FSC_CONTROL").name);
104 console.out("feedback:    "+dim.state("FEEDBACK").name);
105 console.out("ratecontrol: "+dim.state("RATE_CONTROL").name);
106 console.out("fadctrl:     "+dim.state("FAD_CONTROL").name);
107 console.out("mcp:         "+dim.state("MCP").name);
108 console.out("");
109 
110 console.out("Enable all FTU");
111 dim.send("FTM_CONTROL/ENABLE_FTU", -1, true);
112 
113 // -----------------------------------------------------------------
114 // Now we check the FTU connection
115 // -----------------------------------------------------------------
116 
117 /*
118 include("scripts/handleFtuCheck.js");
119 
120 loop = new Handler("FtuCheck");
121 loop.ftuList = new Subscription("FTM_CONTROL/FTU_LIST");
122 loop.add(handleFtuCheck);
123 loop.run();
124 loop.ftuList.close();
125 
126 dim.log("All FTUs are enabled and without error.");
127 */
128 
129 console.out("Checking FTU: start");
130 include("scripts/CheckFTU.js");
131 console.out("Checking FTU: done");
132 console.out("");
133 
134 // -----------------------------------------------------------------
135 // Now we check the clock conditioner
136 // -----------------------------------------------------------------
137 
138 var sub_counter = new Subscription("FTM_CONTROL/COUNTER");
139 var counter = sub_counter.get(3000, false).counter;
140 dim.send("FTM_CONTROL/REQUEST_STATIC_DATA");
141 v8.timeout(3000, function() { if (sub_counter.get(0, false).counter>counter) return true; });
142 if (sub_counter.get(0, false).qos&0x100==0)
143     throw new Error("Clock conditioner not locked.");
144 sub_counter.close();
145 
146 // -----------------------------------------------------------------
147 // Now we can safely try to connect the FAD boards.
148 // -----------------------------------------------------------------
149 /*
150  include("scripts/handleFadConnected.js");
151 
152 // If FADs already connected
153 
154 checkSend(["FAD_CONTROL"]);
155 
156 loop = new Handler("ConnectFad");
157 loop.add(handleFadConnected);
158 loop.run();
159 
160 var failed = false;
161 dim.onchange["FAD_CONTROL"] = function(arg)
162 {
163     if (this.rc && arg.name!="Connected")
164         failed = true;
165 }
166 
167 console.out("FADs connected.");
168 console.out("");
169 
170 console.out(dim.state("FAD_CONTROL").name);
171 console.out(dim.state("MCP").name);
172 */
173 
174 // ================================================================
175 // Underflow check
176 // ================================================================
177 // Is it necessary to check for the so called 'underflow-problem'?
178 // (This is necessary after each power cycle)
179 // ----------------------------------------------------------------
180 
181 include('scripts/CheckUnderflow.js');
182 
183 // Now it is time to check the connection of the FADs
184 // it might hav thrown an exception already anyway
185 
186 
187 // ================================================================
188 // Power on drive system if power is off (do it hre to make sure not
189 // everything is switchd on at the same time)
190 // ================================================================
191 
192 //console.out("PWR: "+(dim.state("PWR_CONTROL").index&16));
193 
194 if ((dim.state("PWR_CONTROL").index&16)==0)
195 {
196     console.out("Drive cabinet not powered... Switching on.");
197     dim.send("PWR_CONTROL/TOGGLE_DRIVE");
198     v8.timeout(5000, function() { if (dim.state("PWR_CONTROL").index&16) return true; });
199 }
200 
201 include("scripts/handleDriveArmed.js");
202 
203 checkSend(["DRIVE_CONTROL"]);
204 
205 loop = new Handler("ArmDrive");
206 loop.add(handleDriveArmed);
207 loop.run();
208 
209 
210 // ================================================================
211 // Bias crate calibration
212 // ================================================================
213 // Bias crate calibration if necessary (it is aftr 4pm (local tome)
214 // and the last calibration was more than eight hours ago.
215 // -----------------------------------------------------------------
216 
217 // At this point we know that:
218 //  1) The lid is closed
219 //  2) The feedback is stopped
220 //  3) The voltage is off
221 function makeCurrentCalibration()
222 {
223     dim.send("BIAS_CONTROL/SET_ZERO_VOLTAGE");
224     dim.wait("BIAS_CONTROL", "VoltageOff", 30000); // waS: 15000
225 
226     var now = new Date();
227     dim.send("FEEDBACK/CALIBRATE");
228 
229     console.out("Wait for calibration to start");
230     dim.wait("FEEDBACK", "Calibrating", 5000);
231 
232     console.out("Wait for calibration to end");
233     dim.wait("FEEDBACK", "Calibrated", 90000);
234 
235     console.out("Calibration finished ["+(new Date()-now)+"ms]");
236 
237     console.out("Wait for voltage to be off");
238     dim.wait("BIAS_CONTROL", "VoltageOff", 30000); // was: 15000
239 }
240 
241 // Check age of calibration
242 var service_calibration = new Subscription("FEEDBACK/CALIBRATION");
243 
244 var data_calibration = service_calibration.get(3000, false);
245 
246 var age = data_calibration.time;
247 var now = new Date();
248 
249 var diff = (now-age)/3600000;
250 
251 var fb_state = dim.state("FEEDBACK").index;
252 
253 // !data_calibration.data: FEEDBACK might just be freshly
254 // started and will not yet serve this service.
255 if (fb_state<5 || (diff>8 && now.getHours()>16))
256 {
257     if (fb_state<5)
258         console.out("No BIAS crate calibration available: New calibration needed.");
259     else
260         console.out("Last BIAS crate calibration taken at "+age.toUTCString()+": New calibration needed.");
261 
262     makeCurrentCalibration();
263 }
264 
265 service_calibration.close();
266 
267 // ================================================================
268 // Setup GPS control and wait for the satellites to be locked
269 // ================================================================
270 
271 checkSend(["GPS_CONTROL"]);
272 
273 if (dim.state("GPS_CONTROL").name=="Disconnected")
274     dim.send("GPS_CONTROL/RECONNECT");
275 
276 // Wait for being connectes
277 v8.timeout(5000, function() { if (dim.state("GPS_CONTROL").name!="Disconnected") return true; });
278 
279 // Wait for status available
280 v8.timeout(5000, function() { if (dim.state("GPS_CONTROL").name!="Connected") return true; });
281 
282 if (dim.state("GPS_CONTROL").name=="Disabled")
283     dim.send("GPS_CONTROL/ENABLE");
284 
285 // Wait for gps to be enabled and locked
286 dim.wait("GPS_CONTROL", "Locked", 15000);
287 
288 // ================================================================
289 // Crosscheck all states
290 // ================================================================
291 
292 // FIXME: Check if there is a startup scheduled, if not do not force
293 // drive to be switched on
294 
295 var table =
296 [
297  [ "TNG_WEATHER"   ],
298  [ "MAGIC_WEATHER" ],
299  [ "CHAT"          ],
300  [ "SMART_FACT"    ],
301  [ "TEMPERATURE"   ],
302  [ "EVENT_SERVER",        [ "Running", "Standby" ] ],
303  [ "DATA_LOGGER",         [ "NightlyFileOpen", "WaitForRun", "Logging" ] ],
304  [ "FSC_CONTROL",         [ "Connected"                       ] ],
305  [ "MCP",                 [ "Idle"                            ] ],
306  [ "TIME_CHECK",          [ "Valid"                           ] ],
307  [ "PWR_CONTROL",         [ "SystemOn"                        ] ],
308  [ "AGILENT_CONTROL_24V", [ "VoltageOn"                       ] ],
309  [ "AGILENT_CONTROL_50V", [ "VoltageOn"                       ] ],
310  [ "AGILENT_CONTROL_80V", [ "VoltageOn"                       ] ],
311  [ "BIAS_CONTROL",        [ "VoltageOff"                      ] ],
312  [ "FEEDBACK",            [ "Calibrated"                      ] ],
313  [ "RATE_SCAN",           [ "Connected"                       ] ],
314  [ "RATE_CONTROL",        [ "Connected"                       ] ],
315  [ "DRIVE_CONTROL",       [ "Initialized", "Tracking", "OnTrack", "Locked" ] ],
316  [ "LID_CONTROL",         [ "Open", "Closed"                  ] ],
317  [ "FTM_CONTROL",         [ "Valid", "TriggerOn"              ] ],
318  [ "FAD_CONTROL",         [ "Connected", "WritingData"        ] ],
319  [ "GPS_CONTROL",         [ "Locked" ] ],
320  [ "SQM_CONTROL",         [ "Valid" ] ],
321  [ "PFMINI_CONTROL",      [ "Receiving" ] ],
322 ];
323 
324 
325 
326 if (!checkStates(table))
327 {
328     throw new Error("Something unexpected has happened. Although the startup-"+
329                     "procedure has finished, not all servers are in the state "+
330                     "in which they ought to be. Please, try to find out what "+
331                     "happened...");
332 }
333