'use strict'; // ================================================================ // Code related to monitoring the fad system // ================================================================ var incomplete = 0; sub_incomplete.onchange = function(evt) { if (!evt.data) return; var inc = evt.obj['incomplete']; if (!inc || inc>0xffffffffff) return; if (incomplete>0) return; if (dim.state("MCP").name!="TakingData") return; console.out(""); dim.log("Incomplete event ["+inc+","+incomplete+"] detected, sending MCP/STOP"); incomplete = inc; dim.send("MCP/STOP"); } // ================================================================ // Code related to taking data // ================================================================ /** * reconnect to problematic FADs * * Dis- and Reconnects to FADs, found to be problematic by call-back function * onchange() to have a different CONNECTION value than 66 or 67. * * @returns * a boolean is returned. * reconnect returns true if: * * nothing needed to be reset --> no problems found by onchange() * * the reconnection went fine. * * reconnect *never returns false* so far. * * @example * if (!sub_connections.reconnect()) * exit(); */ function reconnect(list, txt) { /* var reset = [ ]; for (var i=0; i3) throw new Error("Too many boards to be reconnected. Please check what happened."); for (var i=0; i this time should be pretty identical for each run // if this takes longer than say 3s: // there might be a problem with one/more FADs // // wait until "TakingData": // --> this seems to take even some minutes sometimes... // (might be optimized rather soon, but still in the moment...) // if this takes way too long: // there might be something broken, // so maybe a very high time limit is ok here. // I think there is not much that can go wrong, // when the Thr-Calib has already started. Still it might be nice // If in the future RateControl is written so to find out that // in case the threshold finding algorithm does // *not converge as usual* // it can complain, and in this way give a hint, that the weather // might be a little bit too bad. // else: // wait until "TakingData": // --> in a non-data run this time should be pretty short again // if this takes longer than say 3s: // there might be a problem with one/more FADs // // Use this if you use the rate control to calibrate by rates //if (!dim.wait("MCP", "TakingData", -300000) ) //{ // throw new Error("MCP took longer than 5 minutes to start TakingData"+ // "maybe this idicates a problem with one of the FADs?"); //} // ================================================================ // Function for Critical voltage // ================================================================ // INSTALL a watchdog... send FAD_CONTROL/CLOSE_OPEN_FILES // could send MCP/RESET as well but would result in a timeout var callback = dim.onchange['FEEDBACK']; dim.onchange['FEEDBACK'] = function(state) { if (callback) callback.call(this, state); if ((state.name=="Critical" || state.name=="OnStandby") && (this.last!="Critical" && this.last!="OnStandby")) { console.out("Feedback state changed from "+this.last+" to "+state.name+" [takeRun.js]"); // Includes FAD_CONTROL/CLOSE_ALL_OPEN_FILES dim.send("MCP/STOP"); } this.last=state.name; } // Here we could check and handle fad losses incomplete = 0; var start = true; for (var n=0; n<3; n++) { if (start) { dim.send("MCP/START", time, count, type); if (typeof(func)=="function") func(); } try { dim.wait("MCP", "TakingData", 15000); break; } catch (e) { if (dim.state("MCP").name=="TriggerOn" && dim.state("FAD_CONTROL").name=="Connected" && dim.state("FTM_CONTROL").name=="TriggerOn") { console.out(""); console.out("Waiting for TakingData timed out. Everything looks ok, but file not yet open... waiting once more."); start = false; continue; } start = true; console.out(""); console.out(" + MCP: "+dim.state("MCP").name); console.out(" + FAD_CONTROL: "+dim.state("FAD_CONTROL").name); console.out(" + FTM_CONTROL: "+dim.state("FTM_CONTROL").name); console.out(""); if (dim.state("MCP").name!="Configuring3" || (dim.state("FAD_CONTROL").name!="Configuring1" && dim.state("FAD_CONTROL").name!="Configuring2")) throw e; console.out(""); console.out("Waiting for fadctrl to get configured timed out... checking for in-run FAD loss."); var con = sub_connections.get(); var stat = con.obj['status']; console.out("Sending MCP/RESET"); dim.send("MCP/RESET"); dim.wait("FTM_CONTROL", "Valid", 3000); dim.wait("FAD_CONTROL", "Connected", 3000); dim.wait("MCP", "Idle", 3000); var list = []; for (var i=0; i<40; i++) if (stat[i]!=0x43) list.push(i); reconnect(list, "configuration"); if (n==2) throw e; //dim.wait("MCP", "Idle", 3000); } } // This is to check if we have missed the event. This can happen as // a race condition when the MCP/STOP is sent by the event handler // but the run was not yet fully configured. var statefb = dim.state("FEEDBACK").name; if (statefb=="Critical" || statefb=="OnStandby") { console.out("Run started by FEEDBACK in state "+statefb); dim.send("MCP/STOP"); // Includes FAD_CONTROL/CLOSE_ALL_OPEN_FILES dim.onchange['FEEDBACK'] = callback; return true; } dim.wait("MCP", "Idle", time>0 ? time*1250 : undefined); // run time plus 25% // REMOVE watchdog dim.onchange['FEEDBACK'] = callback; if (incomplete) { console.out(""); console.out(" - MCP: "+dim.state("MCP").name); console.out(" - FAD_CONTROL: "+dim.state("FAD_CONTROL").name); console.out(" - FTM_CONTROL: "+dim.state("FTM_CONTROL").name); dim.wait("FTM_CONTROL", "Valid", 3000); dim.wait("FAD_CONTROL", "Connected", 3000); dim.wait("MCP", "Idle", 3000); var str = incomplete.toString(2); var len = str.length; var list = []; for (var i=0; i1000 || counter.data['N_ped']>5) && counter.data['N_ext1']==0) // 'o' for open throw new Error("No ext1 triggers received during data taking... please check the reason and report in the logbook."); dim_trg.close(); } return true; }