##// END OF EJS Templates
Fix utc time handling
Juan C. Espinoza -
r44:74ffee4b5884
parent child
Show More
@@ -1,713 +1,710
1 1
2 2 var icon = {
3 3 'width': 20,
4 4 'path': 'M18.303,4.742l-1.454-1.455c-0.171-0.171-0.475-0.171-0.646,0l-3.061,3.064H2.019c-0.251,0-0.457,0.205-0.457,0.456v9.578c0,0.251,0.206,0.456,0.457,0.456h13.683c0.252,0,0.457-0.205,0.457-0.456V7.533l2.144-2.146C18.481,5.208,18.483,4.917,18.303,4.742 M15.258,15.929H2.476V7.263h9.754L9.695,9.792c-0.057,0.057-0.101,0.13-0.119,0.212L9.18,11.36h-3.98c-0.251,0-0.457,0.205-0.457,0.456c0,0.253,0.205,0.456,0.457,0.456h4.336c0.023,0,0.899,0.02,1.498-0.127c0.312-0.077,0.55-0.137,0.55-0.137c0.08-0.018,0.155-0.059,0.212-0.118l3.463-3.443V15.929z M11.241,11.156l-1.078,0.267l0.267-1.076l6.097-6.091l0.808,0.808L11.241,11.156z',
5 5 'ascent': 20,
6 6 'descent': 2,
7 7 };
8 8
9 9 function list2dict(values) {
10 10
11 11 var o = {};
12 12 $.each(values, function () {
13 13 o[this.name] = this.value;
14 14 });
15 15 return o;
16 16 };
17 17 /* In this class is defined all the function to RTI plot */
18 18 class PcolorBuffer {
19 19 constructor({ div, data }) {
20 20 this.div = document.getElementById(div);
21 21 this.n = 0;
22 22 this.divs = [];
23 23 this.wait = false;
24 24 this.lastRan = Date.now();
25 25 this.lastFunc = null;
26 26 this.zbuffer = [];
27 27 this.xbuffer = [];
28 28 this.empty = Array(data.metadata.yrange.length).fill(null);
29 29 this.timespan = 12;
30 30 this.metadata = data.metadata;
31 31 this.setup(data);
32 32 }
33 33 /* This function is used to plot all the data that have the DB and just is used when is loaded or reloaded*/
34 34 setup(data) {
35 35 this.last = data.time.slice(-1);
36 36 var diffArr = [];
37 37 for(var i=0; i<data.time.length-1; i++){
38 38 diffArr.push(data.time[i+1]-data.time[i]);
39 39 }
40 40 this.interval = Math.round(Math.min.apply(null, diffArr)*100 / 100);
41 41 if (data.time.length == 1) {
42 42 var values = { 'time': data.time, 'data': data['data'].map(function (x) { return [x] }) };
43 43 } else {
44 44 var values = this.fill_gaps(data.time, data['data'], this.interval, data['data'].length);
45 45 }
46 46 var t = values.time.map(function (x) {
47 47 var a = new Date(x * 1000);
48 // This condition is used to change from UTC to LT
49 //if (data.metadata.localtime == true){
50 a.setTime( a.getTime() + a.getTimezoneOffset()*60*1000 );
51 //}
48 if (data.metadata.localtime == 0){
49 a.setTime( a.getTime() + a.getTimezoneOffset()*60*1000 );
50 }
52 51 return a;
53 52 });
54 53
55 54 var label;
56 //if (data.metadata.localtime == true){
57 label = "[LT]";
58
59 //}
60 //else{
61 // label = "[UTC]";
62 //}
55 if (data.metadata.localtime == 1){
56 label = "[LT]";
57 }else{
58 label = "[UTC]";
59 }
63 60
64 61 for (var i = 0; i < data['data'].length; i++) {
65 62 var layout = {
66 63 height: 350,
67 64 xaxis: {
68 65 title: 'Time ' + label,
69 66 showgrid: false,
70 67 linewidth: 2,
71 68 size: 12,
72 69 mirror: true,
73 70 },
74 71 yaxis: {
75 72 title: data.metadata.ylabel || 'km',
76 73 showgrid: false,
77 74 linewidth: 2,
78 75 size: 12,
79 76 mirror: true,
80 77 },
81 78 titlefont: {
82 79 size: 16,
83 80 },
84 81 margin: {
85 82 t: 30,
86 83 }
87 84 };
88 85 var iDiv = document.createElement('div');
89 86 iDiv.id = 'plot-' + i;
90 87 this.zbuffer.push([]);
91 88 this.n = this.n + 1;
92 89 this.div.appendChild(iDiv);
93 90 this.divs.push(iDiv.id);
94 91 var trace = {
95 92 z: values.data[i],
96 93 x: t,
97 94 y: data.metadata.yrange,
98 95 colorscale: this.metadata.colormap || 'Jet',
99 96 transpose: true,
100 97 type: 'heatmap'
101 98 };
102 99
103 100 if (this.metadata.zmin) { trace.zmin = this.metadata.zmin }
104 101 if (this.metadata.zmax) { trace.zmax = this.metadata.zmax }
105 102
106 103 var tm = new Date(this.last * 1000);
107 tm.setTime( tm.getTime() + tm.getTimezoneOffset()*60*1000 );
108
104 if (data.metadata.localtime == 0){
105 tm.setTime( tm.getTime() + tm.getTimezoneOffset()*60*1000 );
106 }
109 107 if ('titles' in this.metadata){
110 108 layout.title = this.metadata.titles[i] + ' - ' + tm.toLocaleString();
111 109 }else{
112 110 layout.title = 'Ch ' + i + ' - ' + tm.toLocaleString();
113 111 }
114 112
115 113 var conf = {
116 114 modeBarButtonsToRemove: ['sendDataToCloud', 'autoScale2d', 'hoverClosestCartesian', 'hoverCompareCartesian', 'lasso2d', 'select2d', 'zoomIn2d', 'zoomOut2d', 'toggleSpikelines'],
117 115 modeBarButtonsToAdd: [{
118 116 name: 'Edit plot',
119 117 icon: icon,
120 118 click: function (gd) {
121 119 var div = gd.id;
122 120 $('input[id=id_plotdiv]').val(div);
123 121 $('#setup').modal('show');
124 122 }
125 123 }],
126 124 displaylogo: false,
127 125 showTips: true
128 126 };
129 127 Plotly.newPlot('plot-' + i, [trace], layout, conf);
130 128 }
131 129 $('#id_ymin').val(Math.min(...this.metadata.yrange));
132 130 $('#id_ymax').val(Math.max(...this.metadata.yrange));
133 131 if (this.metadata.zmin) {
134 132 $('#id_zmin').val(this.metadata.zmin);
135 133 } else {
136 134 $('#id_zmin').val(Math.min(...values.data[0][0]));
137 135 }
138 136 if (this.metadata.zmax) {
139 137 $('#id_zmax').val(this.metadata.zmax);
140 138 } else {
141 139 $('#id_zmax').val(Math.max(...values.data[0][0]));
142 140 }
143 141 }
144 142
145 143 getSize() {
146 144 var div = document.getElementById(this.divs[0]);
147 145 var t = this.xbuffer.slice(-1)[0];
148 146 var n = 0;
149 147 var timespan = this.timespan * 1000 * 60 * 60;
150 148
151 149 while ((t - div.data[0].x[n]) > timespan) {
152 150 n += 1;
153 151 }
154 152 if(n>720){
155 153 return 720;
156 154 }else{
157 155 return n;
158 156 }
159 157 }
160 158
161 159 fill_gaps(xBuffer, zBuffer, interval, N) {
162 160
163 161 var x = [xBuffer[0]];
164 162 var z = [];
165 163 var last;
166 164
167 165 for (var j = 0; j < N; j++) {
168 166 z.push([zBuffer[j][0]]);
169 167 }
170 168
171 169 for (var i = 1; i < xBuffer.length; i++) {
172 170 var cnt = 0;
173 171 last = x[x.length-1];
174 172 while (Math.abs(parseFloat(xBuffer[i]) - last ) > 1.5 * parseFloat(interval)) {
175 173 cnt += 1;
176 174 last = last + interval;
177 175 x.push(last);
178 176 for (var j = 0; j < N; j++) {
179 177 z[j].push(this.empty);
180 178 }
181 179 // Avoid infinite loop
182 180 if (cnt == 100) { break; }
183 181 }
184 182 x.push(xBuffer[i]);
185 183 for (var j = 0; j < N; j++) {
186 184 z[j].push(zBuffer[j][i]);
187 185 }
188 186 }
189 187 return { 'time': x, 'data': z };
190 188 }
191 189
192 190 plot() {
193 191 // add new data to plots and empty buffers
194 192 var N = this.getSize();
195 193 // // // // console.log('Plotting...');
196 194 for (var i = 0; i < this.n; i++) {
197 195 var div = document.getElementById(this.divs[i]);
198 196 if (N > 0) {
199 197 div.data[0].z = div.data[0].z.slice(N, )
200 198 div.data[0].x = div.data[0].x.slice(N, )
201 199 }
202 200 Plotly.extendTraces(div, {
203 201 z: [this.zbuffer[i]],
204 202 x: [this.xbuffer]
205 203 }, [0]);
206 204 this.zbuffer[i] = [];
207 205 }
208 206 this.xbuffer = [];
209 207 }
210 208 //This function just add the last data and is used if previously was used setup()
211 209 update(obj) {
212 210
213 211 // fill data gaps
214 212 var cnt = 0;
215 213
216 214 while (Math.abs(parseFloat(obj.time[0]) - this.last) > 1.5 * parseFloat(this.interval)) {
217 215 cnt += 1;
218 216 this.last += this.interval;
219 217 var newt = new Date((this.last) * 1000);
220 // This condition is used to change from UTC to LT
221 // if (obj.metadata.localtime == true){
222 newt.setTime( newt.getTime() + newt.getTimezoneOffset()*60*1000 );
223 //}
218 if (obj.metadata.localtime == 0){
219 newt.setTime( newt.getTime() + newt.getTimezoneOffset()*60*1000 );
220 }
224 221 this.xbuffer.push(newt);
225 222 for (var i = 0; i < obj['data'].length; i++) {
226 223 this.zbuffer[i].push(this.empty);
227 224 }
228 225 // Avoid infinite loop
229 226 if (cnt == 100) { break; }
230 227 }
231 228
232 229 // update buffers
233 230 this.last = parseFloat(obj.time[0]);
234 231 var t = new Date(obj.time[0] * 1000);
235 // This condition is used to change from UTC to LT
236 //if (obj.metadata.localtime == true){
237 t.setTime( t.getTime() + t.getTimezoneOffset()*60*1000 );
238 //}
232 if (obj.metadata.localtime == 0){
233 t.setTime( t.getTime() + t.getTimezoneOffset()*60*1000 );
234 }
239 235 this.xbuffer.push(t);
240 236 for (var i = 0; i < obj['data'].length; i++) {
241 237 this.zbuffer[i].push(obj['data'][i]);
242 238 var div = document.getElementById(this.divs[i]);
243 239
244 240 if ('titles' in obj.metadata){
245 241 var title = obj.metadata.titles[i] + ' - ' + t.toLocaleString();
246 242 }else{
247 243 var title = 'Ch ' + i + ' - ' + t.toLocaleString();
248 244 }
249 245
250 246 Plotly.relayout(div, {
251 247 title: title
252 248 });
253 249 }
254 250
255 251 if (!this.wait) {
256 252 this.plot();
257 253 this.wait = true;
258 254 } else {
259 255 clearTimeout(this.lastFunc)
260 256 this.lastFunc = setTimeout(function (scope) {
261 257 if ((Date.now() - scope.lastRan) >= 30000) {
262 258 scope.plot()
263 259 scope.lastRan = Date.now()
264 260 }
265 261 }, 30000 - (Date.now() - this.lastRan), this)
266 262 }
267 263 }
268 264 // With this function You can change parameters in your plot
269 265 restyle(values) {
270 266
271 267 var values = list2dict(values);
272 268 var div = document.getElementById(values.plotdiv);
273 269
274 270 Plotly.relayout(div, {
275 271 yaxis: {
276 272 range: [values.ymin, values.ymax],
277 273 title: this.metadata.ylabel || 'km',
278 274 linewidth: 2,
279 275 size: 12,
280 276 mirror: true,
281 277 }
282 278
283 279 });
284 280
285 281 Plotly.restyle(div, {
286 282 zmin: values.zmin,
287 283 zmax: values.zmax,
288 284 colorscale: values.colormap
289 285 });
290 286 }
291 287 }
292 288 /* In this class is defined all the function to SPC plot */
293 289 class Pcolor {
294 290 constructor({ div, data }) {
295 291 this.div = document.getElementById(div);
296 292 this.n = 0;
297 293 this.divs = [];
298 294 this.metadata = data.metadata;
299 295 this.setup(data);
300 296 }
301 297 /* This function is used to plot all the data that have the DB and just is used when is loaded or reloaded*/
302 298 setup(data) {
303 299 for (var i = 0; i < data['data'].length; i++) {
304 300 var layout = {
305 301 margin: {
306 302 t:30,
307 303 },
308 304 height: 320,
309 305 xaxis: {
310 306 title: data.metadata.xlabel || 'Velocity',
311 307 showgrid: false,
312 308 zeroline: false,
313 309 linewidth: 2,
314 310 mirror: true,
315 311 size: 12,
316 312 },
317 313 yaxis: {
318 314 title: data.metadata.ylabel || 'km',
319 315 showgrid: false,
320 316 linewidth: 2,
321 317 mirror: 'all',
322 318 size: 12,
323 319 },
324 320 titlefont: {
325 321 size: 14
326 322 },
327 323 };
328 324 var iDiv = document.createElement('div');
329 325 iDiv.id = 'plot-' + i;
330 326 iDiv.className += iDiv.className ? ' col-md-6' : 'col-md-6';
331 327 this.n = this.n + 1;
332 328 this.div.appendChild(iDiv);
333 329 this.divs.push(iDiv.id);
334 330 var trace1 = {
335 331 z: data['data'][i],
336 332 y: data.metadata.yrange,
337 333 x: data.metadata.xrange,
338 334 colorscale: this.metadata.colormap || 'Jet',
339 335 transpose: true,
340 336 type: 'heatmap'
341 337 };
342 338
343 339 if (this.metadata.zmin) {
344 340 trace1.zmin = this.metadata.zmin
345 341 }
346 342 if (this.metadata.zmax) {
347 343 trace1.zmax = this.metadata.zmax;
348 344 }
349 345
350 346 var t = new Date(data.time * 1000);
351 //if (data.metadata.localtime == true){
352 t.setTime( t.getTime() + t.getTimezoneOffset()*60*1000 );
353 //}
347 if (data.metadata.localtime == 0){
348 t.setTime( t.getTime() + t.getTimezoneOffset()*60*1000 );
349 }
354 350 if ('titles' in data.metadata){
355 351 layout.title = data.metadata.titles[i] + ' ' + t.toLocaleString();
356 352 }else{
357 353 layout.title = 'Ch ' + i + ': ' + t.toLocaleString();
358 354 }
359 355 var conf = {
360 356 modeBarButtonsToRemove: ['sendDataToCloud', 'autoScale2d', 'hoverClosestCartesian', 'hoverCompareCartesian', 'lasso2d', 'select2d', 'zoomIn2d', 'zoomOut2d', 'toggleSpikelines'],
361 357 modeBarButtonsToAdd: [{
362 358 name: 'Edit plot',
363 359 icon: icon,
364 360 click: function (gd) {
365 361 var div = gd.id;
366 362 $('input[id=id_plotdiv]').val(div);
367 363 $('#setup').modal('show');
368 364 }
369 365 }],
370 366 displaylogo: false,
371 367 showTips: true
372 368 };
373 369
374 370 var traces = [trace1]
375 371
376 372 Plotly.newPlot('plot-' + i, traces, layout, conf);
377 373 }
378 374 $('#id_ymin').val(Math.min(...this.metadata.yrange));
379 375 $('#id_ymax').val(Math.max(...this.metadata.yrange));
380 376 $('#id_xmin').val(Math.min(...this.metadata.xrange));
381 377 $('#id_xmax').val(Math.max(...this.metadata.xrange));
382 378
383 379 if (this.metadata.zmin) {
384 380 $('#id_zmin').val(this.metadata.zmin);
385 381 } else {
386 382 $('#id_zmin').val(Math.min(...data.data[0][0]));
387 383 }
388 384 if (this.metadata.zmax) {
389 385 $('#id_zmax').val(this.metadata.zmax);
390 386 } else {
391 387 $('#id_zmax').val(Math.max(...data.data[0][0]));
392 388 }
393 389 }
394 390
395 391 plot(obj) {
396 392 this.data = obj;
397 393 // add new data to plots and empty buffers
398 394 // // // console.log('Plotting...');
399 395 var t = new Date(obj.time[0] * 1000);
400 // This condition is used to change from UTC to LT
401 //if (obj.metadata.localtime == true){
402 t.setTime( t.getTime() + t.getTimezoneOffset()*60*1000 );
403 //}
396 if (obj.metadata.localtime == 0){
397 t.setTime( t.getTime() + t.getTimezoneOffset()*60*1000 );
398 }
404 399 for (var i = 0; i < this.n; i++) {
405 400 var div = document.getElementById(this.divs[i]);
406 401
407 402 if ('titles' in obj.metadata){
408 403 var title = obj.metadata.titles[i] + ' ' + t.toLocaleString();
409 404 }else{
410 405 var title = 'Ch ' + i + ': ' + t.toLocaleString();
411 406 }
412 407
413 408 Plotly.relayout(div, {
414 409 title: title,
415 410 });
416 411
417 412 Plotly.restyle(div, {
418 413 z: [obj['data'][i]],
419 414 x: [obj.xrange]
420 415 }, [0]);
421 416 }
422 417 }
423 418
424 419 update(data) {
425 420 this.plot(data);
426 421 }
427 422
428 423 restyle(values) {
429 424
430 425 var values = list2dict(values);
431 426 var div = document.getElementById(values.plotdiv);
432 427
433 428 Plotly.relayout(div, {
434 429 yaxis: {
435 430 title: this.metadata.ylabel || 'km',
436 431 linewidth: 2,
437 432 range: [values.ymin, values.ymax]
438 433 },
439 434 xaxis: {
440 435 title: this.metadata.xlabel || 'Velocity',
441 436 linewidth: 2,
442 437 mirror: true,
443 438 range: [values.xmin, values.xmax]
444 439 }
445 440 });
446 441
447 442 Plotly.restyle(div, {
448 443 zmin: values.zmin,
449 444 zmax: values.zmax,
450 445 colorscale: values.colormap
451 446 });
452 447 }
453 448 }
454 449
455 450 class ScatterBuffer {
456 451 constructor({ div, data }) {
457 452 this.div = document.getElementById(div);
458 453 this.n = 0;
459 454 this.wait = false;
460 455 this.lastRan = Date.now();
461 456 this.lastFunc = null;
462 457 this.ybuffer = [];
463 458 this.xbuffer = [];
464 459 this.timespan = 12;
465 460 this.metadata = data.metadata;
466 461 this.setup(data);
467 462 }
468 463 /* This function is used to plot all the data that have the DB and just is used when is loaded or reloaded*/
469 464 setup(data) {
470 465
471 466 var traces = [];
472 467 this.last = data.time.slice(-1);
473 468 var diffArr = [];
474 469 for(var i=0; i<data.time.length-1; i++){
475 470 diffArr.push(data.time[i+1]-data.time[i]);
476 471 }
477 472 this.interval = Math.round(Math.min.apply(null, diffArr)*100 / 100);
478 473
479 474 if (data.time.length == 1) {
480 475 var values = { 'time': data.time, 'data': data['data'] };
481 476 } else {
482 477 var values = this.fill_gaps(data.time, data['data'], this.interval, data['data'].length);
483 478 }
484 479
485 480 var t = values.time.map(function (x) {
486 481 var a = new Date(x * 1000);
487 482 // This condition is used to change from UTC to LT
488 //if (data.metadata.localtime == true){
489 a.setTime( a.getTime() + a.getTimezoneOffset()*60*1000 );
490 //}
483 if (data.metadata.localtime == 0){
484 a.setTime( a.getTime() + a.getTimezoneOffset()*60*1000 );
485 }
491 486 return a;
492 487 });
493 488
494 489 for (var i = 0; i < data['data'].length; i++) {
495 490
496 491 this.n = this.n + 1;
497 492 this.ybuffer.push([]);
498 493 var trace = {
499 494 x: t,
500 495 y: values.data[i],
501 496 mode: 'lines',
502 497 type: 'scatter',
503 498 name: 'Channel ' + i,
504 499 connectgaps: false,
505 500 };
506 501
507 502 traces.push(trace);
508 503 }
509 504
510 505 var label;
511 label = "[LT]";
506 if (data.metadata.localtime == 1){
507 label = "[LT]";
508 }else{
509 label = "[UTC]";
510 }
512 511
513 512 var layout = {
514 513 height: 300,
515 514 title: t.slice(-1).toLocaleString(),
516 515 font: {
517 516 size: 12,
518 517 },
519 518 xaxis: {
520 519 title: 'Time ' + label,
521 520 size: 12,
522 521 linewidth: 2,
523 522 mirror: true,
524 523 },
525 524 yaxis: {
526 525 title: data.metadata.ylabel || 'dB',
527 526 linewidth: 2,
528 527 mirror: true,
529 528 },
530 529 titlefont: {
531 530 size: 16,
532 531 },
533 532 margin: {
534 533 t: 30,
535 534 }
536 535 };
537 536
538 537 if (data.metadata.ymin) { layout.yaxis.range = [data.metadata.ymin, data.metadata.ymax] }
539 538
540 539 var conf = {
541 540 modeBarButtonsToRemove: ['sendDataToCloud', 'autoScale2d', 'hoverClosestCartesian', 'hoverCompareCartesian', 'lasso2d', 'select2d', 'zoomIn2d', 'zoomOut2d', 'toggleSpikelines'],
542 541 modeBarButtonsToAdd: [{
543 542 name: 'Edit plot',
544 543 icon: icon,
545 544 click: function (gd) {
546 545 $('#setup').modal('show');
547 546 }
548 547 }],
549 548 displaylogo: false,
550 549 showTips: true
551 550 };
552 551 Plotly.newPlot('plot', traces, layout, conf);
553 552
554 553 if (this.metadata.ymin) {
555 554 $('#id_ymin').val(this.metadata.ymin);
556 555 } else {
557 556 $('#id_ymin').val(layout.yaxis.range[0]);
558 557 }
559 558 if (this.metadata.ymax) {
560 559 $('#id_ymax').val(this.metadata.ymax);
561 560 } else {
562 561 $('#id_ymax').val(layout.yaxis.range[1]);
563 562 }
564 563 }
565 564
566 565 getSize() {
567 566 var t = this.xbuffer.slice(-1)[0];
568 567 var n = 0;
569 568 var timespan = this.timespan * 1000 * 60 * 60;
570 569
571 570 while ((t - this.div.data[0].x[n]) > timespan) {
572 571 n += 1;
573 572 }
574 573 if(n>720){
575 574 return 720;
576 575 }else{
577 576 return n;
578 577 }
579 578 }
580 579
581 580 fill_gaps(xBuffer, yBuffer, interval, N) {
582 581
583 582 var x = [xBuffer[0]];
584 583 var y = [];
585 584
586 585 for (var j = 0; j < N; j++) {
587 586 y.push([yBuffer[j][0]]);
588 587 }
589 588
590 589 var last;
591 590
592 591 for (var i = 1; i < xBuffer.length; i++) {
593 592 var cnt = 0;
594 593 last = x.slice(-1)[0];
595 594 while (Math.abs(parseFloat(xBuffer[i]) - last) > 1.5 * parseFloat(interval)) {
596 595 cnt += 1;
597 596 last = last + interval;
598 597 x.push(last);
599 598 for (var j = 0; j < N; j++) {
600 599 y[j].push(null);
601 600 }
602 601 // Avoid infinite loop
603 602 if (cnt == 50) { break; }
604 603 }
605 604 x.push(xBuffer[i]);
606 605
607 606 for (var j = 0; j < N; j++) {
608 607 y[j].push(yBuffer[j][i]);
609 608 }
610 609 }
611 610 return { 'time': x, 'data': y };
612 611 }
613 612
614 613 plot() {
615 614 // add new data to plots and empty buffers
616 615 var xvalues = [];
617 616 var yvalues = [];
618 617 var traces = [];
619 618 var N = this.getSize();
620 619 // // console.log('Plotting...');
621 620 for (var i = 0; i < this.n; i++) {
622 621 if (N > 0) {
623 622 this.div.data[i].y = this.div.data[i].y.slice(N, )
624 623 this.div.data[i].x = this.div.data[i].x.slice(N, )
625 624 }
626 625 yvalues.push(this.ybuffer[i]);
627 626 xvalues.push(this.xbuffer);
628 627 traces.push(i);
629 628 this.ybuffer[i] = [];
630 629 }
631 630 Plotly.extendTraces(this.div, {
632 631 y: yvalues,
633 632 x: xvalues
634 633 }, traces);
635 634 this.xbuffer = [];
636 635 }
637 636 //This function just add the last data and is used if previously was used setup()
638 637 update(obj) {
639 638 // fill data gaps
640 639 var cnt = 0;
641 640 while (Math.abs(parseFloat(obj.time[0]) - this.last ) > 1.5 * parseFloat(this.interval)) {
642 641 cnt += 1;
643 642 this.last += this.interval;
644 643 var newt = new Date((this.last) * 1000);
645 // This condition is used to change from UTC to LT
646 //if (obj.metadata.localtime == true){
647 newt.setTime( newt.getTime() + newt.getTimezoneOffset()*60*1000 );
648 //}
644 if (obj.metadata.localtime == 0){
645 newt.setTime( newt.getTime() + newt.getTimezoneOffset()*60*1000 );
646 }
649 647 this.xbuffer.push(newt);
650 648 for (var i = 0; i < this.n; i++) {
651 649 this.ybuffer[i].push(null);
652 650 }
653 651 // Avoid infinite loop
654 652 if (cnt == 100) { break; }
655 653 }
656 654
657 655 // update buffers
658 656 this.last = parseFloat(obj.time[0]);
659 657 var t = new Date(obj.time[0] * 1000);
660 // This condition is used to change from UTC to LT
661 //if (obj.metadata.localtime == true){
662 t.setTime( t.getTime() + t.getTimezoneOffset()*60*1000 );
663 //}
658 if (obj.metadata.localtime == 0){
659 t.setTime( t.getTime() + t.getTimezoneOffset()*60*1000 );
660 }
664 661 this.xbuffer.push(t);
665 662 for (var i = 0; i < this.n; i++) {
666 663 this.ybuffer[i].push(obj['data'][i][0]);
667 664 }
668 665
669 666 Plotly.relayout(this.div, {
670 667 title: t.toLocaleString(),
671 668 });
672 669
673 670 if (!this.wait) {
674 671 this.plot();
675 672 this.wait = true;
676 673 } else {
677 674 clearTimeout(this.lastFunc)
678 675 this.lastFunc = setTimeout(function (scope) {
679 676 if ((Date.now() - scope.lastRan) >= 30000) {
680 677 scope.plot()
681 678 scope.lastRan = Date.now()
682 679 }
683 680 }, 30000 - (Date.now() - this.lastRan), this)
684 681 }
685 682 }
686 683
687 684 restyle(values) {
688 685
689 686 var values = list2dict(values);
690 687 Plotly.relayout(this.div, {
691 688 yaxis: {
692 689 range: [values.ymin, values.ymax],
693 690 title: this.metadata.ylabel || 'dB'
694 691 }
695 692 });
696 693 }
697 694 }
698 695
699 696 class StaticPlot {
700 697 constructor({ div, data }) {
701 698 this.div = document.getElementById(div);
702 699 this.setup(data);
703 700 }
704 701
705 702 setup(data) {
706 703 document.querySelectorAll('[id="image"]')[0].src = 'data:image/png;base64, '+data["data"];
707 704 }
708 705
709 706 update(obj) {
710 707 document.querySelectorAll('[id="image"]')[0].src = 'data:image/png;base64, '+obj["data"];
711 708 // console.log('Plotting...');
712 709 }
713 710 } No newline at end of file
@@ -1,143 +1,170
1 1 {% extends 'base.html' %}
2 2 {% load static%}
3 3 {% block content %}
4 4 <p>Useful tools and data from other partners/observatories.</p>
5 5 <div class="card-columns p-2">
6
7 <div class="card text-justify">
8 <div class="card-body">
9 <h5 class="card-title">DOY Calendar</h5>
10 <p class="card-text">The day of year (DOY) is the sequential day number starting with day 1 on January 1st</p>
11 <input type="date" class="form-control tools-date" id="doy-date" placeholder="yyyy-mm-dd"
12 aria-describedby="validationTooltipSkynoiseDate" value="{% now 'Y-m-d' %}" required>
13 <div class="invalid-tooltip">
14 Please enter a valid date.
15 </div>
16 <p id="pdoy" class="card-text text-center" style="padding-top: 0.5em; font-weight:500; font-size:1.5em; color:var(--secondary);">DOY: {{doy}}</p>
17 </div>
18 </div>
19
20
6 21 <div class="card text-justify">
7 22 <img src="{% static 'images/skynoise.png' %}" class="card-img-top" alt="...">
8 23 <div class="card-body">
9 24 <h5 class="card-title">Sky noise</h5>
10 25 <p class="card-text">Sky brightness at 50 MHz, useful for antenna calibrations and measure radar's sensitivity.
11 26 </p>
12 27 <input type="date" class="form-control tools-date" id="skynoise-date" placeholder="dd/mm/yy"
13 28 aria-describedby="validationTooltipSkynoiseDate" value="{% now 'Y-m-d' %}" required>
14 29 <div class="invalid-tooltip">
15 30 Please enter a valid date.
16 31 </div>
17 32 <a class="btn btn-primary m-1" data-toggle="modal" href="#toolModal" data-title="Sky Noise"
18 33 data-image="{% url 'url_skynoise' %}">Go</a>
19 34 </div>
20 35 </div>
21 36
22 37 <div class="card text-justify">
23 38 <div class="card-body">
24 39 <h5 class="card-title">Over JRO</h5>
25 40 <p class="card-text">Main antenna radiation pattern for several experiments.
26 41
27 42 <input type="date" class="form-control form-control-sm tools-date" id="overjro-date" placeholder="dd/mm/yy"
28 43 aria-describedby="validationTooltipOverJRODate" value="{% now 'Y-m-d' %}" required>
29 44 <div class="invalid-tooltip">
30 45 Please enter a valid date.
31 46 </div>
32 47 <select name="experiment" class="form-control form-control-sm">
33 48 <option value="-1">Experiment:</option>
34 49 <option value="-1">------------------</option>
35 50 <option value="20">Vertical Drifts</option>
36 51 <option value="[21,22]">East West 1996</option>
37 52 <option value="[25,26]">East West 2003</option>
38 53 <option value="23">Differential Phase 2000</option>
39 54 <option value="24">Differential Phase 2004 High Alt</option>
40 55 <option value="27">Differential Phase 2005 - 2006</option>
41 56 <option value="[28,29]">DEWD 2005</option>
42 57 <option value="2710">DVD 2006 - 2008</option>
43 58 <option value="-1">------------------</option>
44 59 <option value="10">Oblique ISR On-Axis</option>
45 60 <option value="11">Oblique ISR 4.5</option>
46 61 <option value="12">Oblique ISR 6.0S</option>
47 62 <option value="13">Oblique ISR 3.0N</option>
48 63 <option value="-1">------------------</option>
49 64 <option value="[30,31]">JULIA CP2</option>
50 65 <option value="32">JULIA CP3</option>
51 66 <option value="35">JULIA V (2005-2006)</option>
52 67 <option value="[33,34]">JULIA EW 2003</option>
53 68 <option value="[35,36]">JULIA EW (2006-2007)</option>
54 69 <option value="-1">------------------</option>
55 70 <option value="0">Modulo Rx</option>
56 71 <option value="1">1/16 Rx</option>
57 72 <option value="2">1/4 Rx</option>
58 73 <option value="3">All Rx</option>
59 74 <option value="-1">------------------</option>
60 75 <option value="40">EW Imaging 1996</option>
61 76 <option value="41">EW Imaging 2003</option>
62 77 <option value="43">EW Imaging 2006-2008</option>
63 78 <option value="-1">------------------</option>
64 79 <option value="50">MST North (Fritts)</option>
65 80 <option value="51">MST West (Fritts)</option>
66 81 <option value="52">MST South (Fritts)</option>
67 82 <option value="53">MST East (Fritts)</option>
68 83 <option value="-1">------------------</option>
69 84 <option value="54">Vertical (Yellow Cables)</option>
70 85 </select>
71 86 <br>
72 87 <p class="card-text">Choose object:
73 88 <div class="form-check card-text">
74 89 <input class="form-check-input" type="checkbox" id="inlineCheckbox1" value="option1">
75 90 <label class="form-check-label" for="inlineCheckbox1">B Field</label><br>
76 91 <input class="form-check-input" type="checkbox" id="inlineCheckbox1" value="option1">
77 92 <label class="form-check-label" for="inlineCheckbox1">Sun</label><br>
78 93 <input class="form-check-input" type="checkbox" id="inlineCheckbox1" value="option1">
79 94 <label class="form-check-label" for="inlineCheckbox1">Moon</label><br>
80 95 <input class="form-check-input" type="checkbox" id="inlineCheckbox1" value="option1">
81 96 <label class="form-check-label" for="inlineCheckbox1">Hydra</label><br>
82 97 <input class="form-check-input" type="checkbox" id="inlineCheckbox1" value="option1">
83 98 <label class="form-check-label" for="inlineCheckbox1">Galaxy Center</label>
84 99 </div>
85 100 </p>
86 101 </div>
87 102 <a class="btn btn-primary m-1" data-toggle="modal" href="#toolModal" data-title="Over JRO"
88 103 data-image="{% url 'url_overjro' %}">Go</a>
89 104 </div>
90 105
91 106 <div class="card text-justify">
92 107 <img src="{% static 'images/kp.png' %}" class="card-img-top" alt="...">
93 108 <div class="card-body">
94 109 <h5 class="card-title">Kp Index</h5>
95 110 <p class="card-text">The K-index, are used to characterize the magnitude of geomagnetic storms. Kp is an excellent
96 111 indicator of disturbances in the Earth's magnetic field (<a
97 112 href="https://www.swpc.noaa.gov/products/planetary-k-index" target="_blank">NOAA/SWPC</a>).</p>
98 113 <a class="btn btn-primary" data-toggle="modal" href="#toolModal" data-title="Kp Index"
99 114 data-image="https://services.swpc.noaa.gov/images/planetary-k-index.gif">Go</a>
100 115 </div>
101 116 </div>
102 117 </div>
103 118
104 </div>
105
106 119 <!-- Modal -->
107 120 <div class="modal fade" id="toolModal" tabindex="-1" role="dialog" aria-labelledby="toolModalTitle" aria-hidden="true">
108 121 <div class="modal-dialog modal-lg" role="document">
109 122 <div class="modal-content">
110 123 <div class="modal-header">
111 124 <h5 class="modal-title" id="toolModalTitle">Modal title</h5>
112 125 <button type="button" class="close" data-dismiss="modal" aria-label="Close">
113 126 <span aria-hidden="true">&times;</span>
114 127 </button>
115 128 </div>
116 129 <div class="modal-body text-center">
117 130 <img class="img-fluid" src="">
118 131 </div>
119 132 </div>
120 133 </div>
121 134 </div>
122 135
123 136 {% endblock content %}
124 137
125 138 {% block script %}
126 139 <script>
140
127 141 $('#toolModal').on('show.bs.modal', function (e) {
128 142
129 143 //get data attribute of the clicked element
130 144 var title = $(e.relatedTarget).data('title');
131 145 var image = $(e.relatedTarget).data('image');
132 146
133 147 if (image.indexOf('skynoise') > 0) {
134 148 var dt = $('#skynoise-date').val();
135 149 image += '?date=' + dt;
136 150 }
137 151
138 152 //populate values
139 153 $(e.currentTarget).find('h5').text(title);
140 154 $(e.currentTarget).find('img').attr('src', image);
141 155 });
156
157 $('#doy-date').change(function() {
158 var old = new Date($(this).val());
159 var now = new Date(old.getTime()+old.getTimezoneOffset()*60*1000);
160 var start = new Date(now.getFullYear(), 0, 0);
161 var diff = (now - start) // + ((start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000);
162 var oneDay = 1000 * 60 * 60 * 24;
163 var doy = Math.floor(diff / oneDay);
164 $('#pdoy').text("DOY: " + doy);
165 console.log(now);
166 console.log(start);
167 });
168
142 169 </script>
143 170 {% endblock script %} No newline at end of file
@@ -1,242 +1,238
1 1 #!/usr/bin/python
2 2 # -*- coding: UTF-8 -*-
3 3
4 4
5 5 import os
6 6 import time
7 7 from datetime import datetime
8 8
9 9 from django import forms
10 10 from django.contrib import messages
11 11 from django.utils.safestring import mark_safe
12 12 from django.shortcuts import render
13 13 from django.http import HttpResponse
14 14
15 15 import mongoengine
16 16
17 17 from plotter.models import Experiment, ExpDetail, PlotMeta, PlotData
18 18
19 19 from utils.plots import skynoise_plot
20 20
21 21 host = os.environ.get('HOST_MONGO', 'localhost')
22 22 mongoengine.connect('dbplots', host=host, port=27017)
23 23
24 24
25 25 # Forms
26 26 class SearchForm(forms.Form):
27 27
28 28 experiment = forms.ChoiceField()
29 29 plot = forms.ChoiceField()
30 30
31 31 def __init__(self, *args, **kwargs):
32 32
33 33 exp_choices = kwargs.pop('exp_choices', [])
34 34 plt_choices = kwargs.pop('plt_choices', [])
35 35 super(SearchForm, self).__init__(*args, **kwargs)
36 36 self.fields['experiment'].choices = [(0, 'Select Experiment')] + exp_choices
37 37 self.fields['plot'].choices = [(0, 'Select Plot')] + plt_choices
38 38 # we use this class to change the parameter in Scatter plot using the function plotly.restyle in jroplot.js
39 39 class ScatterSetupForm(forms.Form):
40 40
41 41 plotdiv = forms.CharField(widget=forms.HiddenInput())
42 42 ymax = forms.CharField(initial=30)
43 43 ymin = forms.CharField(initial=10)
44 44
45 45 # we use this class to change the parameter in RTI plot using the function plotly.restyle in jroplot.js
46 46 class RTISetupForm(forms.Form):
47 47
48 48 plotdiv = forms.CharField(widget=forms.HiddenInput())
49 49 colormap = forms.ChoiceField(choices=[('Jet', 'Jet'), ('Viridis', 'Viridis'), ('RdBu', 'RdBu')])
50 50 zmax = forms.CharField(initial=30)
51 51 zmin = forms.CharField(initial=10)
52 52 ymax = forms.CharField(initial=180)
53 53 ymin = forms.CharField(initial=80)
54 54
55 55 # we use this class to change the parameter in SPC plot using the function plotly.restyle in jroplot.js
56 56 class SPCSetupForm(forms.Form):
57 57
58 58 plotdiv = forms.CharField(widget=forms.HiddenInput())
59 59 colormap = forms.ChoiceField(choices=[('Jet', 'Jet'), ('Viridis', 'Viridis'), ('RdBu', 'RdBu')])
60 60 #como es un perfil xmin y xmax deben ser iguales a zmin y zmax
61 61 xmax = forms.CharField(initial=30)
62 62 xmin = forms.CharField(initial=10)
63 63 #x2max = forms.CharField(initial=30)
64 64 #x2min = forms.CharField(initial=10)
65 65 ymax = forms.CharField(initial=180)
66 66 ymin = forms.CharField(initial=80)
67 67 zmax = forms.CharField(initial=30)
68 68 zmin = forms.CharField(initial=10)
69 69
70 70 # Create your views here.
71 71 def main(request, tag=None):
72 72
73 73 kwargs = {}
74 date = request.GET.get('date', datetime.now().strftime('%d-%m-%Y'))
74 date = request.GET.get('date', datetime.utcnow().strftime('%d-%m-%Y'))
75 75 exps = ExpDetail.objects(date=datetime.strptime(date, '%d-%m-%Y'))
76 76
77 77 tmp = {}
78 78 for exp in exps:
79 79 label = exp.tag.lower().strip() if exp.tag else 'other'
80 80 if label in tmp:
81 81 tmp[label] += 1
82 82 else:
83 83 tmp[label] = 1
84 84 tags = []
85 85
86 86 for key, value in tmp.items():
87 87 if tag == key:
88 88 tags.append({'name': key, 'n': tmp[key], 'active': 'active'})
89 89 else:
90 90 tags.append({'name': key, 'n': tmp[key]})
91 91
92 92 kwargs['tags'] = tags
93 93
94 94 if tag:
95 95 experiments = []
96 96 for exp in exps:
97 97 label = exp.tag.lower().strip() if exp.tag else 'other'
98 98 if label != tag:
99 99 continue
100 100 dum = {}
101 101 dum['code'] = exp.experiment.code
102 102 dum['plots'] = []
103 103 dum['name'] = exp.experiment.name
104 dt = datetime.now()
105
106 t = time.mktime(dt.timetuple())
107 t -= 5*60*60
104
105 t = time.time()
108 106
109 107 if (t-exp['last_time']) > 6*exp['interval']:
110 108 status = 'Offline'
111 109 clase = 'alertas-offline'
112 110 style = 'danger'
113 lastDataDate = exp['last_time']
114 111 elif (t-exp['last_time']) > 3*exp['interval']:
115 112 status = 'Delayed'
116 113 clase = 'alertas-delayed'
117 114 style = 'warning'
118 lastDataDate = exp['last_time']
119 115 else:
120 116 status = 'Online'
121 117 clase = 'alertas-online'
122 118 style = 'success'
123 lastDataDate = exp['last_time']
124 119
125 120 dum['status'] = status
126 121 dum['class'] = clase
127 122 dum['style']= style
128 dum['date']= datetime.utcfromtimestamp(lastDataDate)
123 dum['date']= datetime.fromtimestamp(exp['last_time'])
129 124 for plot in exp.plots():
130 125 dum['plots'].append({'plot': plot.plot, 'name': plot.plot.replace('_', ' ').title(), 'id':plot.id})
131 126 experiments.append(dum)
132 127
133 128 kwargs['experiments'] = experiments
134 129 kwargs['tag'] = tag
135 130
136 131 kwargs['date'] = date
137 132 kwargs['title'] = 'Home'
138 133 kwargs['sidebar'] = True
139 134
140 135 return render(request, 'home.html', kwargs)
141 136
142 137 def about(request):
143 138 '''
144 139 '''
145 140 kwargs = {
146 141 'title': 'About'
147 142 }
148 143 return render(request, 'about.html', kwargs)
149 144
150 145
151 146 def tools(request):
152 147 '''
153 148 '''
154 149 kwargs = {
155 'title': 'Tools'
150 'title': 'Tools',
151 'doy': (datetime.today().date()-datetime.today().date().replace(month=1, day=1)).days + 1
156 152 }
157 153 return render(request, 'tools.html', kwargs)
158 154
159 155 def reports(request):
160 156 '''
161 157 '''
162 158 kwargs = {
163 159 'title': 'Reports',
164 160 }
165 161 return render(request, 'reports.html', kwargs)
166 162
167 163 def plot(request, code=None, plot=None):
168 164 '''
169 165 '''
170 166
171 167 realtime = False
172 168 date = request.GET.get('date', None)
173 169 if date is None:
174 date = datetime.now().strftime('%d-%m-%Y')
170 date = datetime.utcnow().strftime('%d-%m-%Y')
175 171 realtime = True
176 172 exp = Experiment.objects.get(code=int(code))
177 173 detail = ExpDetail.objects.get(experiment=exp, date=datetime.strptime(date, '%d-%m-%Y'))
178 174 meta = PlotMeta.objects.get(exp_detail=detail, plot=plot)
179 175 tag = detail.tag.lower().strip() if detail.tag else 'other'
180 176
181 177 kwargs = {
182 178 'code': code,
183 179 'plot': plot,
184 180 'meta':meta,
185 181 'date': date,
186 182 'id': meta.pk,
187 183 'realtime': realtime,
188 184 'title': 'Home',
189 185 'name' : exp.name,
190 186 'sidebar': True,
191 187 'tag' : tag,
192 188 'plots': []
193 189 }
194 190
195 191 for plt in detail.plots():
196 192 kwargs['plots'].append({'plot': plt.plot, 'name': plt.plot.replace('_', ' ').title()})
197 193
198 194 # Logic to show my views
199 195 if meta.metadata['type'] == 'pcolorbuffer':
200 196 kwargs['setup_form'] = RTISetupForm()
201 197 kwargs['fn_plot'] = 'PcolorBuffer'
202 198 return render(request, 'plot.html', kwargs)
203 199 elif meta.metadata['type'] == 'pcolor':
204 200 kwargs['setup_form'] = SPCSetupForm()
205 201 kwargs['fn_plot'] = 'Pcolor'
206 202 return render(request, 'plot.html', kwargs)
207 203 elif meta.metadata['type'] == 'scatterbuffer':
208 204 kwargs['setup_form'] = ScatterSetupForm()
209 205 kwargs['fn_plot'] = 'ScatterBuffer'
210 206 return render(request, 'plot.html', kwargs)
211 207 elif meta.metadata['type'] == 'image':
212 208 kwargs['image'] = True
213 209 kwargs['fn_plot'] = 'StaticPlot'
214 210 return render(request, 'plot.html', kwargs)
215 211 else:
216 212 return render(request, 'home.html', {})
217 213
218 214 def plot_skynoise(request):
219 215
220 216 date = request.GET.get('date', None)
221 217 if date is None:
222 218 date = datetime.now()
223 219 else:
224 220 date = datetime.strptime(date, '%Y-%m-%d')
225 221
226 222 data = skynoise_plot(date.year, date.month, date.day)
227 223 response = HttpResponse(data.getvalue(), content_type='image/png')
228 224
229 225 return response
230 226
231 227 def plot_overjro(request):
232 228
233 229 date = request.GET.get('date', None)
234 230 if date is None:
235 231 date = datetime.now()
236 232 else:
237 233 date = datetime.strptime(date, '%Y-%m-%d')
238 234
239 235 data = skynoise_plot(date.year, date.month, date.day)
240 236 response = HttpResponse(data.getvalue(), content_type='image/png')
241 237
242 238 return response No newline at end of file
@@ -1,175 +1,169
1 1 #!/usr/bin/python
2 2 # -*- coding: UTF-8 -*-
3 3
4 4 import os
5 5 import sys
6 6 import json
7 7 import simplejson
8 8 from datetime import datetime
9 9 import time
10 10 import zmq
11 11 import mongoengine
12 12 import django
13 13 from threading import Thread
14 14
15 15 sys.path.append(os.environ.get('APP_DIR', '../'))
16 16 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "realtime.settings")
17 17 django.setup()
18 18
19 19 from plotter.models import Experiment, ExpDetail, PlotMeta, PlotData
20 20
21 21 host_mongo = os.environ.get('HOST_MONGO', 'localhost')
22 22 mongoengine.connect('dbplots', host=host_mongo, port=27017)
23 23
24 24 import channels.layers
25 25 from asgiref.sync import async_to_sync
26 26
27 27 channel = channels.layers.get_channel_layer()
28 28
29 29 def loaddata():
30 30 print('Loading Experiments...')
31 31 if os.environ.get('APP_DIR', None) is not None:
32 32 file_exp = os.path.join(os.environ.get('APP_DIR'), 'scripts', 'experiments.json')
33 33 else:
34 34 file_exp = './experiments.json'
35 35 for tup in json.load(open(file_exp)):
36 36 print(tup)
37 37 exp = Experiment.objects(code=tup['code']).modify(
38 38 upsert=True, # To add a new row
39 39 new=True,
40 40 set__code=tup['code'],
41 41 set__name=tup['name'],
42 42 )
43 43 exp.save()
44 44
45 45 #============== funcion para modificar datos en la tabla ==============
46 46 def update(buffer):
47 47 dt = datetime.utcfromtimestamp(buffer['time'])
48 48 interval = buffer['metadata'].pop('interval')
49 49 tag = buffer['metadata'].pop('tag') if 'tag' in buffer['metadata'] else ''
50 50 exp = Experiment.objects.get(code=buffer['code'])
51 51
52 52 detail = ExpDetail.objects(experiment=exp, date=dt.date()).modify(
53 53 upsert=True,
54 54 new=True,
55 55 set__experiment=exp,
56 56 set__date=dt.date(),
57 57 set__last_time = buffer['time'],
58 58 set__interval = interval,
59 59 set__tag = tag,
60 60 )
61 61
62 62 label = buffer['plot'].replace(' ', '_').lower()
63 63 plot = PlotMeta.objects(exp_detail=detail, plot=label).modify(
64 64 upsert=True,
65 65 new=True,
66 66 set__metadata = buffer['metadata']
67 67 )
68 68 #plot.save()
69 69
70 70 data = PlotData.objects(plot=plot, time=buffer['time']).modify(
71 71 upsert=True, # To add a new row
72 72 new=True,
73 73 set__time = buffer['time'],
74 74 set__data = buffer['data']
75 75 )
76 76
77 77 #data.save()
78 78
79 79 if datetime.now().date() == dt.date():
80 80 return True
81 81
82 82 return False
83 83
84 84 # Function that is checking the state of my clients every 30s
85 85 def check_times():
86 86
87 87 while True:
88 88 dt = datetime.now()
89 89 exps = ExpDetail.objects(date=dt.date())
90 90
91 91 for detail in exps:
92 92 code = detail.experiment.code
93 93 plot = detail.plots()[0]
94 data_time = detail['last_time']
95 t = time.mktime(dt.timetuple())
96 t -= 5*60*60
97 data_time = detail['last_time'] + 5*60*60
94 t = time.time()
98 95
99 96 message = {
100 97 'code': code,
101 'time': data_time
98 'time': detail['last_time']
102 99 }
103 100
104 101 if (t-detail['last_time']) > 6*detail['interval']:
105 102 value = 'danger'
106 103 elif (t-detail['last_time']) > 3*detail['interval']:
107 104 value = 'warning'
108 105 else:
109 106 value = 'success'
110 107
111 108 print(('{} {} {} {} {}'.format(code, t, detail['last_time'], (t-detail['last_time']), value)))
112 109
113 110 message['value'] = value
114 111
115 112 async_to_sync(channel.group_send)(
116 113 'main',
117 114 {
118 115 'type': 'zmq_message',
119 116 'message': json.dumps(message)
120 117 }
121 118 )
122 119
123 120 time.sleep(60)
124 121
125 122 def main():
126 123 print('Starting ZMQ server...')
127 124 context = zmq.Context()
128 125 receiver = context.socket(zmq.REP)
129 126 receiver.bind("tcp://0.0.0.0:4444")
130 127 t = Thread(target=check_times)
131 128 t.start()
132 129
133 130 while True:
134 131
135 132 buffer = receiver.recv_json()
136 133 if not isinstance(buffer, dict):
137 134 print('Invalid data received: {}').format(str(buffer))
138 135 continue
139
140 if buffer['metadata']['localtime'] == True: # Ask which type of time is coming: LT o UTC
141 buffer['time'] -= 5*60*60
142 136
143 137 if not update(buffer):
144 138 print('Updating {} for code {}'.format(
145 139 buffer['plot'],
146 140 buffer['code']
147 141 ))
148 142 else:
149 143 buffer['time'] = [buffer['time']]
150 144 group = '{}_{}'.format(
151 145 buffer['code'],
152 146 buffer['plot'].replace(' ', '_').lower()
153 147 )
154 148 async_to_sync(channel.group_send)(
155 149 group,
156 150 {
157 151 'type': 'zmq_message',
158 152 'message': simplejson.dumps(buffer, ignore_nan=True)
159 153 }
160 154 )
161 155
162 156 print('Sending to group {}_{} - {} bytes'.format(
163 157 buffer['code'],
164 158 buffer['plot'].replace(' ', '_').lower(),
165 159 len(str(buffer)))
166 160 )
167 161
168 162 receiver.send_string('ok')
169 163
170 164 receiver.close()
171 165 context.term()
172 166
173 167 if __name__=='__main__':
174 168 loaddata()
175 169 main()
General Comments 0
You need to be logged in to leave comments. Login now