1 'use strict'; 2 3 //this is just the class implementation of 'Observation' 4 include('scripts/Observation_class.js'); 5 6 var file = $['file'] ? $['file'] : 'scripts/schedule.js'; 7 8 console.out('Reading schedule from '+file); 9 10 // this file just contains the definition of 11 // the variable observations, which builds our nightly schedule, hence the filename 12 include(file); 13 14 // ------------------------------------------------------------------------------------- 15 16 // Get current time 17 var now = new Date(); //new Date("2013-04-07 19:00:00 UTC"); 18 19 // Because Main.js could start a new observations just in the moment between 'now' 20 // and entering the new data in the database, we have to use the unique id 21 // in Main.js to check if the current observation should be changed (and sub resetted) 22 now = new Date(now.getTime()); 23 24 //console.out("","NOW: "+now.toUTCString()); 25 26 // ------------------------------------------------------------------------------------- 27 28 console.out("Processing "+observations.length+" entries."); 29 30 var has_now = false; 31 32 // make Observation objects from user input and check if 'date' is increasing. 33 for (var i=0; i<observations.length; i++) 34 { 35 if (observations[i].date.toUpperCase()=="NOW") 36 { 37 if (has_now) 38 throw new Error("Only one entry 'now' allowed"); 39 40 has_now = true; 41 } 42 43 observations[i] = new Observation(observations[i]); 44 45 // check if the start date given by the user is increasing. 46 if (i>0 && observations[i].start <= observations[i-1].start) 47 { 48 throw new Error("Start time '"+ observations[i].start.toUTCString()+ 49 "' in row "+i+" exceeds start time in row "+(i-1)+" "+observations[i-1].start.toUTCString() ); 50 } 51 } 52 53 // Remove all past entries from the schedule 54 while (observations.length>0 && observations[0].start<now) 55 observations.shift(); 56 57 // Output for debugging 58 /* 59 console.out(""); 60 for (var i=0; i<observations.length; i++) 61 { 62 for (var j=0; j<observations[i].length; j++) 63 console.out("%3d.%3d: ".$(i,j)+JSON.stringify(observations[i][j])); 64 console.out(""); 65 }*/ 66 67 // ------------------------------------------------------------------------------------- 68 69 // Connect to database 70 var db = new Database("scheduler:5ch3du13r@www.fact-project.org/factdata"); 71 72 // get all sources from database 73 var sources = db.query("SELECT * from Source"); 74 75 // Convert SourceName to SourceKey 76 function getSourceKey(src) 77 { 78 var arr = sources.filter(function(e) { return e['fSourceName']==src; }); 79 if (arr.length==0) 80 throw new Error("Source '"+src+"' unknown."); 81 if (arr.length>1) 82 throw new Error("More than one source '"+src+"' found."); 83 return arr[0]['fSourceKEY']; 84 } 85 86 // ------------------------------------------------------------------------------------- 87 88 // List of all available measurement types 89 var measurementType = [ "STARTUP", "IDLE", "DRSCALIB", "SINGLEPE", "DATA", "RATESCAN", "SHUTDOWN", "OVTEST", "RATESCAN2", "SLEEP", "CUSTOM" ]; 90 91 // Convert measurement type to index 92 function getMeasurementTypeKey(task) 93 { 94 var idx = measurementType.indexOf(task); 95 if (idx>=0) 96 return idx; 97 98 throw new Error("Task "+task+" not supported!"); 99 } 100 101 // ------------------------------------------------------------------------------------- 102 103 var queries = [ ]; 104 105 var system_on = false; 106 107 // Now create the schedule which should be entered into the databse 108 for (var i=0; i<observations.length; i++) 109 { 110 var obs = observations[i]; 111 112 for (var j=0; j<obs.length; j++) 113 { 114 console.out(i+" "+j+" "+obs[j].start.toUTCString()); 115 var isUp = Sun.horizon(-12, obs[j].start).isUp; 116 117 if (obs[j].task=="STARTUP" && j>0) 118 throw new Error("STARTUP must be the first measurement in a list of measurements."); 119 if (obs[j].task=="DATA" && j!=obs.length-1) 120 throw new Error("DATA must be the last task in a list of measurements"); 121 if (obs[j].task=="SHUTDOWN" && j!=obs.length-1) 122 throw new Error("SHUTDOWN must be the last task in a list of measurements"); 123 if (system_on && obs[j].task=="SHUTDOWN" && isUp) 124 throw new Error("SHUTDOWN must not be scheduled after -12deg (~10min before nautical sun-rise)"); 125 // FIXME: Check also end-time! 126 if ((obs[j].task=="DATA" || obs[j].task=="RATESCAN" || obs[j].task=="RATESCAN2" ) && isUp) 127 throw new Error("Data or Ratescan must not be scheduled when the sun is up (-12deg, earlist/lastest during astronomical twilight)"); 128 129 if (obs[j].task=="STARTUP" || obs[j].task=="DATA") 130 system_on = true; 131 132 var str = "INSERT INTO Schedule SET"; 133 str += " fStart='"+obs[j].start.toISOString()+"'"; 134 str += ",fMeasurementID="+obs[j].sub; 135 str += ",fMeasurementTypeKey="+getMeasurementTypeKey(obs[j].task); 136 137 // Currently only data in the case when a source is given or ra/dec is given can be provided 138 if (obs[j].source) 139 str += ",fSourceKey="+getSourceKey(obs[j].source); 140 141 //lidclosed only needs to be inserted to DB if 'false' 142 if (obs[j].lidclosed) 143 { 144 if (obs[j].task=="RATESCAN2" && obs[j].rstype!="default") 145 str += ",fData='\"lidclosed\":"+obs[j].lidclosed+",\"rstype\":\""+obs[j].rstype+"\",\"zd\":"+obs[j].zd+",\"az\":"+obs[j].az+"'"; 146 else 147 str += ",fData='\"lidclosed\":"+obs[j].lidclosed+",\"zd\":"+obs[j].zd+",\"az\":"+obs[j].az+"'"; 148 } 149 else 150 if (obs[j].ra) 151 str += ",fData='\"ra\":"+obs[j].ra+",\"dec\":"+obs[j].dec+"'"; 152 153 if (obs[j].task=="CUSTOM") 154 str += ",fData='\"biason\":"+obs[j].biason+",\"time\":\""+obs[j].time+"\",\"threshold\":\""+obs[j].threshold+"\",\"zd\":"+obs[j].zd+",\"az\":"+obs[j].az+"'"; 155 156 queries.push(str); 157 } 158 } 159 160 if (queries.length==0) 161 { 162 console.out("","Nothing to do... no observation past "+now.toUTCString(), ""); 163 exit(); 164 } 165 166 // Output and send all queries, update the databse 167 //console.out(""); 168 169 db.query("LOCK TABLES Schedule WRITE"); 170 db.query("DELETE FROM Schedule WHERE fStart>='"+now.toISOString()+"'"); 171 for (var i=0; i<queries.length; i++) 172 db.query(queries[i]); 173 db.query("UNLOCK TABLES"); 174 175 //console.out(""); 176 177 // ====================================================================================== 178 179 // Because Main.js could start a new observations just in the moment between 'now' 180 // and entering the new data in the database, we have to use the unique id 181 // in Main.js to check if the current observation should be changed (and sub resetted) 182 var start = new Date(now.getTime());//-12*3600000); 183 184 //console.out("","START: "+now.toUTCString()); 185 186 // Get the current schedule 187 var rows = db.query("SELECT * FROM Schedule WHERE fStart>='"+start.toISOString()+"' ORDER BY fStart, fMeasurementID"); 188 189 var schedule = []; 190 var entry = -1; 191 var sub = 0; 192 193 for (var i=0; i<rows.length; i++) 194 { 195 //console.out(JSON.stringify(rows[i])); 196 197 var start = new Date(rows[i]['fStart']+" UTC"); 198 var id = rows[i]['fScheduleID']; 199 var src = rows[i]['fSourceKey']; 200 var task = rows[i]['fMeasurementTypeKey']; 201 var sub = rows[i]['fMeasurementID']; 202 var data = rows[i]['fData']; 203 204 if (sub==0) 205 entry++; 206 207 var m = { } 208 m.task = measurementType[task]; 209 210 if (src) 211 { 212 // Convert SourceKey to SourceName 213 var arr = sources.filter(function(e) { return e['fSourceKEY']==src; }); 214 if (arr.length==0) 215 throw new Error("SourceKey "+src+" unknown."); 216 217 m.source = arr[0]['fSourceName']; 218 } 219 220 if (data) 221 { 222 var obj = JSON.parse(("{"+data+"}").replace(/\ /g, "").replace(/(\w+):/gi, "\"$1\":")); 223 for (var key in obj) 224 m[key] = obj[key]; 225 } 226 227 if (!schedule[entry]) 228 schedule[entry] = { }; 229 230 schedule[entry].id = id; 231 schedule[entry].date = start; 232 233 if (!schedule[entry].measurements) 234 schedule[entry].measurements = []; 235 236 schedule[entry].measurements[sub] = m; 237 } 238 239 // ------------------------------------------------------------------------------------- 240 241 console.out("["); 242 for (var i=0; i<schedule.length; i++) 243 { 244 var obs = schedule[i]; 245 246 console.out(' { date:"'+obs.date.toISOString()+'" measurements:'); 247 var obs = obs.measurements; 248 249 console.out(" ["); 250 for (var j=0; j<obs.length; j++) 251 { 252 console.out(" "+JSON.stringify(obs[j])+","); 253 } 254 console.out(" ]"); 255 console.out(" },"); 256 } 257 console.out("]"); 258