##// END OF EJS Templates
Avance scheduler
Renato Huallpa -
r388:7b60d9ecd28a
parent child
Show More
@@ -1,1082 +1,1082
1 1 from django.db import models
2 2 from apps.main.models import Configuration , User
3 3 from django.urls import reverse
4 4 from celery.execute import send_task
5 5 from datetime import datetime
6 6 import ast
7 7 import socket
8 8 import json
9 9 import requests
10 10 import struct
11 11 import os, sys, time
12 12
13 13 from .mqtt import client as mqtt_client
14 14 from radarsys.socketconfig import sio as sio
15 15 import json
16 16
17 17 antenna_default = json.dumps({
18 18 "antenna_up": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
19 19 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
20 20 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
21 21 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
22 22 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
23 23 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
24 24 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
25 25 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0]
26 26 ]
27 27 ,
28 28 "antenna_down": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
29 29 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
30 30 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
31 31 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
32 32 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
33 33 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
34 34 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
35 35 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0]],
36 36 })
37 37
38 38
39 39 tx_default = json.dumps({
40 40 "up": [[1,1,1,1,0,0,0,0],
41 41 [1,1,1,1,0,0,0,0],
42 42 [1,1,1,1,0,0,0,0],
43 43 [1,1,1,1,0,0,0,0],
44 44 [0,0,0,0,1,1,1,1],
45 45 [0,0,0,0,1,1,1,1],
46 46 [0,0,0,0,1,1,1,1],
47 47 [0,0,0,0,1,1,1,1]],
48 48
49 49 "down": [[1,1,1,1,0,0,0,0],
50 50 [1,1,1,1,0,0,0,0],
51 51 [1,1,1,1,0,0,0,0],
52 52 [1,1,1,1,0,0,0,0],
53 53 [0,0,0,0,1,1,1,1],
54 54 [0,0,0,0,1,1,1,1],
55 55 [0,0,0,0,1,1,1,1],
56 56 [0,0,0,0,1,1,1,1]],
57 57 })
58 58
59 59 rx_default = json.dumps({
60 60 "up": [[1,1,1,1,0,0,0,0],
61 61 [1,1,1,1,0,0,0,0],
62 62 [1,1,1,1,0,0,0,0],
63 63 [1,1,1,1,0,0,0,0],
64 64 [0,0,0,0,1,1,1,1],
65 65 [0,0,0,0,1,1,1,1],
66 66 [0,0,0,0,1,1,1,1],
67 67 [0,0,0,0,1,1,1,1]],
68 68
69 69 "down": [[1,1,1,1,0,0,0,0],
70 70 [1,1,1,1,0,0,0,0],
71 71 [1,1,1,1,0,0,0,0],
72 72 [1,1,1,1,0,0,0,0],
73 73 [0,0,0,0,1,1,1,1],
74 74 [0,0,0,0,1,1,1,1],
75 75 [0,0,0,0,1,1,1,1],
76 76 [0,0,0,0,1,1,1,1]],
77 77 })
78 78
79 79 status_default = '0000000000000000000000000000000000000000000000000000000000000000'
80 80 default_messages = {}
81 81
82 82 for i in range(1,65):
83 83 default_messages[str(i)] = "Module "+str(i)
84 84
85 85
86 86 ues_default = json.dumps({
87 87 "up": [0.533333,0.00000,1.06667,0.00000],
88 88 "down": [0.533333,0.00000,1.06667,0.00000]
89 89 })
90 90
91 91 onlyrx_default = json.dumps({
92 92 "up": False,
93 93 "down": False
94 94 })
95 95
96 96 def up_convertion(cadena):
97 97 valores = []
98 98 for c in cadena:
99 99 if c == 1.0: valores=valores+['000']
100 100 if c == 2.0: valores=valores+['001']
101 101 if c == 3.0: valores=valores+['010']
102 102 if c == 0.0: valores=valores+['011']
103 103 if c == 0.5: valores=valores+['100']
104 104 if c == 1.5: valores=valores+['101']
105 105 if c == 2.5: valores=valores+['110']
106 106 if c == 3.5: valores=valores+['111']
107 107
108 108 return valores
109 109
110 110 def up_conv_bits(value):
111 111
112 112 if value == 1.0: bits="000"
113 113 if value == 2.0: bits="001"
114 114 if value == 3.0: bits="010"
115 115 if value == 0.0: bits="011"
116 116 if value == 0.5: bits="100"
117 117 if value == 1.5: bits="101"
118 118 if value == 2.5: bits="110"
119 119 if value == 3.5: bits="111"
120 120
121 121 return bits
122 122
123 123 def down_convertion(cadena):
124 124 valores = []
125 125 for c in cadena:
126 126 if c == 1.0: valores=valores+['000']
127 127 if c == 2.0: valores=valores+['001']
128 128 if c == 3.0: valores=valores+['010']
129 129 if c == 0.0: valores=valores+['011']
130 130 if c == 0.5: valores=valores+['100']
131 131 if c == 1.5: valores=valores+['101']
132 132 if c == 2.5: valores=valores+['110']
133 133 if c == 3.5: valores=valores+['111']
134 134
135 135 return valores
136 136
137 137 def down_conv_bits(value):
138 138
139 139 if value == 1.0: bits="000"
140 140 if value == 2.0: bits="001"
141 141 if value == 3.0: bits="010"
142 142 if value == 0.0: bits="011"
143 143 if value == 0.5: bits="100"
144 144 if value == 1.5: bits="101"
145 145 if value == 2.5: bits="110"
146 146 if value == 3.5: bits="111"
147 147
148 148 return bits
149 149
150 150 def up_conv_value(bits):
151 151
152 152 if bits == "000": value=1.0
153 153 if bits == "001": value=2.0
154 154 if bits == "010": value=3.0
155 155 if bits == "011": value=0.0
156 156 if bits == "100": value=0.5
157 157 if bits == "101": value=1.5
158 158 if bits == "110": value=2.5
159 159 if bits == "111": value=3.5
160 160
161 161 return value
162 162
163 163 def down_conv_value(bits):
164 164
165 165 if bits == "000": value=1.0
166 166 if bits == "001": value=2.0
167 167 if bits == "010": value=3.0
168 168 if bits == "011": value=0.0
169 169 if bits == "100": value=0.5
170 170 if bits == "101": value=1.5
171 171 if bits == "110": value=2.5
172 172 if bits == "111": value=3.5
173 173
174 174 return value
175 175
176 176 def ip2position(module_number):
177 177 j=0
178 178 i=0
179 179 for x in range(0,module_number-1):
180 180 j=j+1
181 181 if j==8:
182 182 i=i+1
183 183 j=0
184 184
185 185 pos = [i,j]
186 186 return pos
187 187
188 188
189 189 def fromBinary2Char(binary_string):
190 190 number = int(binary_string, 2)
191 191 #Plus 33 to avoid more than 1 characters values such as: '\x01'-'\x1f'
192 192 number = number + 33
193 193 char = chr(number)
194 194 return char
195 195
196 196 def fromChar2Binary(char):
197 197 number = ord(char) - 33
198 198 #Minus 33 to get the real value
199 199 bits = bin(number)[2:]
200 200 #To ensure we have a string with 6bits
201 201 if len(bits) < 6:
202 202 bits = bits.zfill(6)
203 203 return bits
204 204
205 205 OPERATION_MODES = (
206 206 (0, 'Manual'),
207 207 (1, 'Automatic'),
208 208 )
209 209
210 210 class ABSConfiguration(Configuration):
211 211 active_beam = models.PositiveSmallIntegerField(verbose_name='Active Beam', default=0)
212 212 module_status = models.CharField(verbose_name='Module Status', max_length=10000, default=status_default)
213 213 operation_mode = models.PositiveSmallIntegerField(verbose_name='Operation Mode', choices=OPERATION_MODES, default = 0)
214 214 operation_value = models.FloatField(verbose_name='Periodic (seconds)', default="10", null=True, blank=True)
215 215 module_messages = models.CharField(verbose_name='Modules Messages', max_length=10000, default=json.dumps(default_messages))
216 216
217 217 class Meta:
218 218 db_table = 'abs_configurations'
219 219
220 220 def get_absolute_url_plot(self):
221 221 return reverse('url_plot_abs_patterns', args=[str(self.id)])
222 222
223 223
224 224 def parms_to_dict(self):
225 225
226 226 parameters = {}
227 227
228 228 parameters['device_id'] = self.device.id
229 229 parameters['label'] = self.label
230 230 parameters['device_type'] = self.device.device_type.name
231 231 parameters['beams'] = {}
232 232
233 233 beams = ABSBeam.objects.filter(abs_conf=self)
234 234 b=1
235 235 for beam in beams:
236 236 #absbeam = ABSBeam.objects.get(pk=beams[beam])
237 237 parameters['beams']['beam'+str(b)] = beam.parms_to_dict()#absbeam.parms_to_dict()
238 238 b+=1
239 239
240 240 return parameters
241 241
242 242
243 243 def dict_to_parms(self, parameters):
244 244
245 245 self.label = parameters['label']
246 246
247 247 absbeams = ABSBeam.objects.filter(abs_conf=self)
248 248 beams = parameters['beams']
249 249
250 250 if absbeams:
251 251 beams_number = len(beams)
252 252 absbeams_number = len(absbeams)
253 253 if beams_number==absbeams_number:
254 254 i = 1
255 255 for absbeam in absbeams:
256 256 absbeam.dict_to_parms(beams['beam'+str(i)])
257 257 i = i+1
258 258 elif beams_number > absbeams_number:
259 259 i = 1
260 260 for absbeam in absbeams:
261 261 absbeam.dict_to_parms(beams['beam'+str(i)])
262 262 i=i+1
263 263 for x in range(i,beams_number+1):
264 264 new_beam = ABSBeam(
265 265 name =beams['beam'+str(i)]['name'],
266 266 antenna =json.dumps(beams['beam'+str(i)]['antenna']),
267 267 abs_conf = self,
268 268 tx =json.dumps(beams['beam'+str(i)]['tx']),
269 269 rx =json.dumps(beams['beam'+str(i)]['rx']),
270 270 ues =json.dumps(beams['beam'+str(i)]['ues']),
271 271 only_rx =json.dumps(beams['beam'+str(i)]['only_rx'])
272 272 )
273 273 new_beam.save()
274 274 i=i+1
275 275 else: #beams_number < absbeams_number:
276 276 i = 1
277 277 for absbeam in absbeams:
278 278 if i <= beams_number:
279 279 absbeam.dict_to_parms(beams['beam'+str(i)])
280 280 i=i+1
281 281 else:
282 282 absbeam.delete()
283 283 else:
284 284 for beam in beams:
285 285 new_beam = ABSBeam(
286 286 name =beams[beam]['name'],
287 287 antenna =json.dumps(beams[beam]['antenna']),
288 288 abs_conf = self,
289 289 tx =json.dumps(beams[beam]['tx']),
290 290 rx =json.dumps(beams[beam]['rx']),
291 291 ues =json.dumps(beams[beam]['ues']),
292 292 only_rx =json.dumps(beams[beam]['only_rx'])
293 293 )
294 294 new_beam.save()
295 295
296 296
297 297
298 298 def update_from_file(self, parameters):
299 299
300 300 self.dict_to_parms(parameters)
301 301 self.save()
302 302
303 303
304 304 def get_beams(self, **kwargs):
305 305 '''
306 306 This function returns ABS Configuration beams
307 307 '''
308 308 return ABSBeam.objects.filter(abs_conf=self.pk, **kwargs)
309 309
310 310 def clone(self, **kwargs):
311 311
312 312 beams = self.get_beams()
313 313 self.pk = None
314 314 self.id = None
315 315 for attr, value in kwargs.items():
316 316 setattr(self, attr, value)
317 317 self.save()
318 318
319 319 for beam in beams:
320 320 beam.clone(abs_conf=self)
321 321
322 322 #-----For Active Beam-----
323 323 new_beams = ABSBeam.objects.filter(abs_conf=self)
324 324 self.active_beam = new_beams[0].id
325 325 self.save()
326 326 #-----For Active Beam-----
327 327 #-----For Device Status---
328 328 self.device.status = 3
329 329 self.device.save()
330 330 #-----For Device Status---
331 331
332 332 return self
333 333
334 334
335 335 def start_device(self):
336 336
337 337 if self.device.status == 3:
338 338
339 339 try:
340 340 #self.write_device()
341 341 send_task('task_change_beam', [self.id],)
342 342 self.message = 'ABS running'
343 343
344 344 except Exception as e:
345 345 self.message = str(e)
346 346 return False
347 347
348 348 return True
349 349
350 350 else:
351 351 self.message = 'Please, select Write ABS Device first.'
352 352 return False
353 353
354 354
355 355 def stop_device(self):
356
356 print("estoy en ABS models")
357 357 self.device.status = 2
358 358 self.device.save()
359 359 self.message = 'ABS has been stopped.'
360 360 self.save()
361 361
362 362 return True
363 363
364 364 def stop_device_mqtt(self):
365 365
366 366 self.device.status = 2
367 367 self.device.save()
368 368 self.message = 'ABS has been stopped.'
369 369 self.save()
370 370
371 371 mqtt_client.publish(os.environ.get('TOPIC_ABS', 'abs/beams'),"STOP")
372 372
373 373 return True
374 374
375 375 def write_device(self):
376 376
377 377 """
378 378 This function sends the beams list to every abs module.
379 379 It needs 'module_conf' function
380 380 """
381 381 print("Write 3")
382 382
383 383 beams = ABSBeam.objects.filter(abs_conf=self)
384 384 nbeams = len(beams)
385 385
386 386 # Se manda a cero RC para poder realizar cambio de beam
387 387 if self.experiment is None:
388 388 confs = []
389 389 else:
390 390 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
391 391 confdds = ''
392 392 confjars = ''
393 393 confrc = ''
394 394 #TO STOP DEVICES: DDS-JARS-RC
395 395 for i in range(0,len(confs)):
396 396 if i==0:
397 397 for conf in confs:
398 398 if conf.device.device_type.name == 'dds':
399 399 confdds = conf
400 400 confdds.stop_device()
401 401 break
402 402 if i==1:
403 403 for conf in confs:
404 404 if conf.device.device_type.name == 'jars':
405 405 confjars = conf
406 406 confjars.stop_device()
407 407 break
408 408 if i==2:
409 409 for conf in confs:
410 410 if conf.device.device_type.name == 'rc':
411 411 confrc = conf
412 412 confrc.stop_device()
413 413 break
414 414
415 415 '''
416 416 if self.connected_modules() == 0 :
417 417 print("No encuentra modulos")
418 418 self.message = "No ABS Module detected."
419 419 return False
420 420 '''
421 421 #-------------Write each abs module-----------
422 422
423 423 if beams:
424 424 block_id = 0
425 425 message = 'SNDF{:03d}{:02d}{:02d}'.format(nbeams, nbeams, block_id)
426 426 for i, status in enumerate(self.module_status):
427 427 message += ''.join([fromBinary2Char(beam.module_6bits(i)) for beam in beams])
428 428 status = ['0'] * 64
429 429 n = 0
430 430
431 431 print("Llega una antes entrar a multicast4")
432 432
433 433 sock = self.send_multicast(message)
434 434
435 435 while True:
436 436 #for i in range(32):
437 437 try:
438 438 data, address = sock.recvfrom(1024)
439 439 print (address, data)
440 440 data = data.decode("utf-8")
441 441 if data == '1':
442 442 status[int(address[0][10:])-1] = '3'
443 443 #print (int(address[0][10:])-1)
444 444 elif data == '0':
445 445 status[int(address[0][10:])-1] = '1'
446 446 except socket.timeout:
447 447 print('Timeout')
448 448 break
449 449 except Exception as e:
450 450 print ('Error {}'.format(e))
451 451 n += 1
452 452 sock.close()
453 453 else:
454 454 self.message = "ABS Configuration does not have beams"
455 455 print('No beams')
456 456 #Start DDS-RC-JARS
457 457 if confdds:
458 458 confdds.start_device()
459 459 if confrc:
460 460 #print confrc
461 461 confrc.start_device()
462 462 if confjars:
463 463 confjars.start_device()
464 464 return False
465 465
466 466 if n == 64:
467 467 self.message = "Could not write ABS Modules"
468 468 self.device.status = 0
469 469 self.module_status = ''.join(status)
470 470 self.save()
471 471 print('Could not write ABS')
472 472 #Start DDS-RC-JARS
473 473 if confdds:
474 474 confdds.start_device()
475 475 if confrc:
476 476 #print confrc
477 477 confrc.start_device()
478 478 if confjars:
479 479 confjars.start_device()
480 480 return False
481 481 else:
482 482 self.message = "ABS Beams List have been sent to ABS Modules"
483 483 print('ABS beams list sent')
484 484 self.active_beam = beams[0].pk
485 485
486 486 #Start DDS-RC-JARS
487 487 if confdds:
488 488 confdds.start_device()
489 489 if confrc:
490 490 #print confrc
491 491 confrc.start_device()
492 492 if confjars:
493 493 confjars.start_device()
494 494
495 495 print('Inicia intento de salvar device.status')
496 496 self.device.status = 3
497 497 self.module_status = ''.join(status)
498 498 #print(status)
499 499 self.save()
500 500 print('Estatus salvado')
501 501 conf_active, __ = ABSActive.objects.get_or_create(pk=1)
502 502 conf_active.conf = self
503 503 conf_active.save()
504 504 return True
505 505
506 506 def write_device_mqtt(self):
507 507
508 508 if self.experiment is None:
509 509 confs = []
510 510 else:
511 511 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
512 512 confdds = ''
513 513 confjars = ''
514 514 confrc = ''
515 515 #TO STOP DEVICES: DDS-JARS-RC
516 516 for i in range(0,len(confs)):
517 517 if i==0:
518 518 for conf in confs:
519 519 if conf.device.device_type.name == 'dds':
520 520 confdds = conf
521 521 confdds.stop_device()
522 522 break
523 523 if i==1:
524 524 for conf in confs:
525 525 if conf.device.device_type.name == 'jars':
526 526 confjars = conf
527 527 confjars.stop_device()
528 528 break
529 529 if i==2:
530 530 for conf in confs:
531 531 if conf.device.device_type.name == 'rc':
532 532 confrc = conf
533 533 confrc.stop_device()
534 534 break
535 535
536 536 apuntes_up_down=''
537 537 beams = ABSBeam.objects.filter(abs_conf=self)
538 538
539 539 inicializacion="{\"beams\":["
540 540 finalizacion="]}"
541 541
542 542 for beam in beams:
543 543 beam.antenna=beam.antenna[1:]
544 544 info="{\"id\":"+str(beam.id)+","+beam.antenna + ","
545 545 apuntes_up_down=apuntes_up_down+info
546 546
547 547 apuntes_up_down=apuntes_up_down[:len(apuntes_up_down)-1]
548 548 apuntes_up_down=inicializacion+ apuntes_up_down+finalizacion
549 549 mqtt_client.publish(os.environ.get('TOPIC_ABS', 'abs/beams'),apuntes_up_down)
550 550
551 551 #Start DDS-RC-JARS
552 552 if confdds:
553 553 confdds.start_device()
554 554 if confrc:
555 555 #print confrc
556 556 confrc.start_device()
557 557 if confjars:
558 558 confjars.start_device()
559 559
560 560 return True
561 561
562 562 def read_module(self, module):
563 563
564 564 """
565 565 Read out-bits (up-down) of 1 abs module NOT for Configuration
566 566 """
567 567
568 568 ip_address = self.device.ip_address
569 569 ip_address = ip_address.split('.')
570 570 module_seq = (ip_address[0],ip_address[1],ip_address[2])
571 571 dot = '.'
572 572 module_ip = dot.join(module_seq)+'.'+str(module)
573 573 module_port = self.device.port_address
574 574 read_route = 'http://'+module_ip+':'+str(module_port)+'/read'
575 575
576 576 module_status = json.loads(self.module_status)
577 577 print(read_route)
578 578
579 579 module_bits = ''
580 580
581 581 try:
582 582 r_read = requests.get(read_route, timeout=0.5)
583 583 answer = r_read.json()
584 584 module_bits = answer['allbits']
585 585 except:
586 586 return {}
587 587
588 588 return module_bits
589 589
590 590 def read_device(self):
591 591
592 592 parms = {}
593 593 # Reads active modules.
594 594 module_status = json.loads(self.module_status)
595 595 total = 0
596 596 for status in module_status:
597 597 if module_status[status] != 0:
598 598 module_bits = self.read_module(int(status))
599 599 bits={}
600 600 if module_bits:
601 601 bits = (str(module_bits['um2']) + str(module_bits['um1']) + str(module_bits['um0']) +
602 602 str(module_bits['dm2']) + str(module_bits['dm1']) + str(module_bits['dm0']) )
603 603 parms[str(status)] = bits
604 604
605 605 total +=1
606 606
607 607 if total==0:
608 608 self.message = "No ABS Module detected. Please select 'Status'."
609 609 return False
610 610
611 611
612 612
613 613 self.message = "ABS Modules have been read"
614 614 #monitoreo_tx = JROABSClnt_01CeCnMod000000MNTR10
615 615 return parms
616 616
617 617
618 618 def connected_modules(self):
619 619 """
620 620 This function returns the number of connected abs-modules without updating.
621 621 """
622 622 num = 0
623 623 print(self.module_status)
624 624 for i, status in enumerate(self.module_status):
625 625 if status != '0':
626 626 num += 1
627 627 #print('status {}:{}'.format(i+1, status))
628 628 return num
629 629
630 630 def send_multicast(self, message):
631 631 #print("Send multicast")
632 632 multicast_group = ('224.3.29.71', 10000)
633 633 # Create the datagram socket
634 634 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
635 635 sock.settimeout(1)
636 636 local_ip = os.environ.get('LOCAL_IP', '0.0.0.0')
637 637 local_ip = '0.0.0.0'
638 638 print("He llegado a IP local")
639 639
640 640 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip))
641 641 sock.sendto(message.encode(), multicast_group)
642 642 print('Sending ' + message)
643 643 return sock
644 644
645 645 def status_device(self):
646 646 """
647 647 This function returns the status of all abs-modules as one.
648 648 If at least one module is connected, its answer is "1"
649 649 """
650 650 print ('Status device')
651 651 print (self.active_beam)
652 652 beams = ABSBeam.objects.filter(abs_conf=self)
653 653 #print beams[self.active_beam-1].module_6bits(0)
654 654 active = ABSActive.objects.get(pk=1)
655 655 if active.conf != self:
656 656 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_url()
657 657 self.message += "\n"
658 658 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
659 659
660 660 return False
661 661
662 662 sock = self.send_multicast('MNTR')
663 663
664 664 n = 0
665 665 status = ['0'] * 64
666 666
667 667 while True:
668 668 #for i in range(32):
669 669 #if True:
670 670 try:
671 671 print("Recibiendo")
672 672 address = None
673 673 data, address = sock.recvfrom(2)
674 674 print (address, data)
675 675 print("!!!!")
676 676 data = data.decode()
677 677 aux_mon = "1"
678 678 aux_expected = aux_mon
679 679 if(len(data)==2):
680 680 print ("data[1]: ")
681 681 print (data[1])
682 682 aux_mon = fromChar2Binary(data[1])
683 683 print (aux_mon)
684 684 aux_i = (str(address[0]).split('.'))[3]
685 685 print (aux_i)
686 686 print ('Active beam')
687 687 beam_active = ABSBeam.objects.get(pk=self.active_beam)
688 688 print (beam_active)
689 689 aux_expected = beam_active.module_6bits(int(aux_i)-1)
690 690 print (aux_expected)
691 691
692 692 print ("data[0]: ")
693 693 print (data[0])
694 694
695 695 if data[0] == '1':
696 696 status[int(address[0][10:])-1] = '3'
697 697 if aux_mon == aux_expected:
698 698 print ('Es igual')
699 699 else:
700 700 print ('Es diferente')
701 701 status[int(address[0][10:])-1] = '2'
702 702
703 703 elif data[0] == '0':
704 704 status[int(address[0][10:])-1] = '1'
705 705 n += 1
706 706 print('Module: {} connected'.format(address))
707 707 except socket.timeout:
708 708 print('Timeout')
709 709 break
710 710 except:
711 711 print('Module: {} error'.format(address))
712 712 pass
713 713
714 714 sock.close()
715 715
716 716 if n > 0:
717 717 self.message = 'ABS modules Status have been updated.'
718 718 self.device.status = 1
719 719 else:
720 720 self.device.status = 0
721 721 self.message = 'No ABS module is connected.'
722 722 self.module_status = ''.join(status)
723 723 self.save()
724 724
725 725 return self.device.status
726 726
727 727
728 728 def send_beam(self, beam_pos):
729 729 """
730 730 This function connects to a multicast group and sends the beam number
731 731 to all abs modules.
732 732 """
733 733 print ('Send beam')
734 734 print (self.active_beam)
735 735 beams = ABSBeam.objects.filter(abs_conf=self)
736 736 #print beams[self.active_beam-1].module_6bits(0)
737 737 active = ABSActive.objects.get(pk=1)
738 738 if active.conf != self:
739 739 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_url()
740 740 self.message += "\n"
741 741 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
742 742
743 743 return False
744 744
745 745 # Se manda a cero RC para poder realizar cambio de beam
746 746 if self.experiment is None:
747 747 confs = []
748 748 else:
749 749 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
750 750 confdds = ''
751 751 confjars = ''
752 752 confrc = ''
753 753 #TO STOP DEVICES: DDS-JARS-RC
754 754 for i in range(0,len(confs)):
755 755 if i==0:
756 756 for conf in confs:
757 757 if conf.device.device_type.name == 'dds':
758 758 confdds = conf
759 759 confdds.stop_device()
760 760 break
761 761 if i==1:
762 762 for conf in confs:
763 763 if conf.device.device_type.name == 'jars':
764 764 confjars = conf
765 765 confjars.stop_device()
766 766 break
767 767 if i==2:
768 768 for conf in confs:
769 769 if conf.device.device_type.name == 'rc':
770 770 confrc = conf
771 771 confrc.stop_device()
772 772 break
773 773 if beam_pos > 0:
774 774 beam_pos = beam_pos - 1
775 775 else:
776 776 beam_pos = 0
777 777
778 778 #El indice del apunte debe ser menor que el numero total de apuntes
779 779 #El servidor tcp en el embebido comienza a contar desde 0
780 780 status = ['0'] * 64
781 781 message = 'CHGB{}'.format(beam_pos)
782 782 sock = self.send_multicast(message)
783 783 while True:
784 784 #for i in range(32):
785 785 try:
786 786 data, address = sock.recvfrom(1024)
787 787 print (address, data)
788 788 data = data.decode()
789 789 if data == '1':
790 790 status[int(address[0][10:])-1] = '3'
791 791 elif data == '0':
792 792 status[int(address[0][10:])-1] = '1'
793 793 except socket.timeout:
794 794 print('Timeout')
795 795 break
796 796 except Exception as e:
797 797 print ('Error {}'.format(e))
798 798 pass
799 799
800 800 sock.close()
801 801
802 802 #Start DDS-RC-JARS
803 803 if confdds:
804 804 confdds.start_device()
805 805 if confrc:
806 806 #print confrc
807 807 confrc.start_device()
808 808 if confjars:
809 809 confjars.start_device()
810 810
811 811 self.message = "ABS Beam has been changed"
812 812 self.module_status = ''.join(status)
813 813 self.save()
814 814 return True
815 815
816 816
817 817 def get_absolute_url_import(self):
818 818 return reverse('url_import_abs_conf', args=[str(self.id)])
819 819
820 820 class ABSActive(models.Model):
821 821 conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration', on_delete=models.CASCADE)
822 822
823 823 class Meta:
824 824 db_table = 'abs_absactive'
825 825
826 826 class ABSBeam(models.Model):
827 827
828 828 name = models.CharField(max_length=60, default='Beam')
829 829 antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default)
830 830 abs_conf = models.ForeignKey('ABSConfiguration', null=True,
831 831 verbose_name='ABS Configuration', on_delete=models.CASCADE)
832 832 tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default)
833 833 rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default)
834 834 s_time = models.TimeField(verbose_name='Star Time', default='00:00:00')
835 835 e_time = models.TimeField(verbose_name='End Time', default='23:59:59')
836 836 ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default)
837 837 only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default)
838 838
839 839 class Meta:
840 840 db_table = 'abs_beams'
841 841
842 842 def __unicode__(self):
843 843 return u'%s' % (self.name)
844 844
845 845 def parms_to_dict(self):
846 846
847 847 parameters = {}
848 848 parameters['name'] = self.name
849 849 parameters['antenna'] = ast.literal_eval(self.antenna)
850 850 parameters['abs_conf'] = self.abs_conf.name
851 851 parameters['tx'] = ast.literal_eval(self.tx)
852 852 parameters['rx'] = ast.literal_eval(self.rx)
853 853 parameters['s_time'] = self.s_time.strftime("%H:%M:%S")
854 854 parameters['e_time'] = self.e_time.strftime("%H:%M:%S")
855 855 parameters['ues'] = ast.literal_eval(self.ues)
856 856 parameters['only_rx'] = json.loads(self.only_rx)
857 857
858 858 return parameters
859 859
860 860 def dict_to_parms(self, parameters):
861 861
862 862 self.name = parameters['name']
863 863 self.antenna = json.dumps(parameters['antenna'])
864 864 #self.abs_conf = parameters['abs_conf']
865 865 self.tx = json.dumps(parameters['tx'])
866 866 self.rx = json.dumps(parameters['rx'])
867 867 #self.s_time = parameters['s_time']
868 868 #self.e_time = parameters['e_time']
869 869 self.ues = json.dumps(parameters['ues'])
870 870 self.only_rx = json.dumps(parameters['only_rx'])
871 871 self.save()
872 872
873 873
874 874 def clone(self, **kwargs):
875 875
876 876 self.pk = None
877 877 self.id = None
878 878 for attr, value in kwargs.items():
879 879 setattr(self, attr, value)
880 880
881 881 self.save()
882 882
883 883 return self
884 884
885 885
886 886 def module_6bits(self, module):
887 887 """
888 888 This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module
889 889 """
890 890 module += 1
891 891 if module > 64:
892 892 beam_bits = ""
893 893 return beam_bits
894 894
895 895 data = ast.literal_eval(self.antenna)
896 896 up_data = data['antenna_up']
897 897 down_data = data['antenna_down']
898 898
899 899 pos = ip2position(module)
900 900 up_value = up_data[pos[0]][pos[1]]
901 901 down_value = down_data[pos[0]][pos[1]]
902 902
903 903 up_bits = up_conv_bits(up_value)
904 904 down_bits = down_conv_bits(down_value)
905 905 beam_bits = up_bits+down_bits
906 906
907 907 return beam_bits
908 908
909 909
910 910 @property
911 911 def get_upvalues(self):
912 912 """
913 913 This function reads antenna pattern and show the up-value of one abs module
914 914 """
915 915
916 916 data = ast.literal_eval(self.antenna)
917 917 up_data = data['antenna_up']
918 918
919 919 up_values = []
920 920 for data in up_data:
921 921 for i in range(0,8):
922 922 up_values.append(data[i])
923 923
924 924 return up_values
925 925
926 926 @property
927 927 def antenna_upvalues(self):
928 928 """
929 929 This function reads antenna pattern and show the up - values of one abs beam
930 930 in a particular order
931 931 """
932 932 data = ast.literal_eval(self.antenna)
933 933 up_data = data['antenna_up']
934 934
935 935 return up_data
936 936
937 937 @property
938 938 def antenna_downvalues(self):
939 939 """
940 940 This function reads antenna pattern and show the down - values of one abs beam
941 941 in a particular order
942 942 """
943 943 data = ast.literal_eval(self.antenna)
944 944 down_data = data['antenna_down']
945 945
946 946 return down_data
947 947
948 948 @property
949 949 def get_downvalues(self):
950 950 """
951 951 This function reads antenna pattern and show the down-value of one abs module
952 952 """
953 953
954 954 data = ast.literal_eval(self.antenna)
955 955 down_data = data['antenna_down']
956 956
957 957 down_values = []
958 958 for data in down_data:
959 959 for i in range(0,8):
960 960 down_values.append(data[i])
961 961
962 962 return down_values
963 963
964 964 @property
965 965 def get_up_ues(self):
966 966 """
967 967 This function shows the up-ues-value of one beam
968 968 """
969 969 data = ast.literal_eval(self.ues)
970 970 up_ues = data['up']
971 971
972 972 return up_ues
973 973
974 974 @property
975 975 def get_down_ues(self):
976 976 """
977 977 This function shows the down-ues-value of one beam
978 978 """
979 979 data = ast.literal_eval(self.ues)
980 980 down_ues = data['down']
981 981
982 982 return down_ues
983 983
984 984 @property
985 985 def get_up_onlyrx(self):
986 986 """
987 987 This function shows the up-onlyrx-value of one beam
988 988 """
989 989 data = json.loads(self.only_rx)
990 990 up_onlyrx = data['up']
991 991
992 992 return up_onlyrx
993 993
994 994 @property
995 995 def get_down_onlyrx(self):
996 996 """
997 997 This function shows the down-onlyrx-value of one beam
998 998 """
999 999 data = json.loads(self.only_rx)
1000 1000 down_onlyrx = data['down']
1001 1001
1002 1002 return down_onlyrx
1003 1003
1004 1004 @property
1005 1005 def get_tx(self):
1006 1006 """
1007 1007 This function shows the tx-values of one beam
1008 1008 """
1009 1009 data = json.loads(self.tx)
1010 1010
1011 1011 return data
1012 1012
1013 1013 @property
1014 1014 def get_uptx(self):
1015 1015 """
1016 1016 This function shows the up-tx-values of one beam
1017 1017 """
1018 1018 data = json.loads(self.tx)
1019 1019 up_data = data['up']
1020 1020
1021 1021 up_values = []
1022 1022 for data in up_data:
1023 1023 for i in range(0,8):
1024 1024 up_values.append(data[i])
1025 1025
1026 1026 return up_values
1027 1027
1028 1028 @property
1029 1029 def get_downtx(self):
1030 1030 """
1031 1031 This function shows the down-tx-values of one beam
1032 1032 """
1033 1033 data = json.loads(self.tx)
1034 1034 down_data = data['down']
1035 1035
1036 1036 down_values = []
1037 1037 for data in down_data:
1038 1038 for i in range(0,8):
1039 1039 down_values.append(data[i])
1040 1040
1041 1041 return down_values
1042 1042
1043 1043
1044 1044
1045 1045 @property
1046 1046 def get_rx(self):
1047 1047 """
1048 1048 This function shows the rx-values of one beam
1049 1049 """
1050 1050 data = json.loads(self.rx)
1051 1051
1052 1052 return data
1053 1053
1054 1054 @property
1055 1055 def get_uprx(self):
1056 1056 """
1057 1057 This function shows the up-rx-values of one beam
1058 1058 """
1059 1059 data = json.loads(self.rx)
1060 1060 up_data = data['up']
1061 1061
1062 1062 up_values = []
1063 1063 for data in up_data:
1064 1064 for i in range(0,8):
1065 1065 up_values.append(data[i])
1066 1066
1067 1067 return up_values
1068 1068
1069 1069 @property
1070 1070 def get_downrx(self):
1071 1071 """
1072 1072 This function shows the down-rx-values of one beam
1073 1073 """
1074 1074 data = json.loads(self.rx)
1075 1075 down_data = data['down']
1076 1076
1077 1077 down_values = []
1078 1078 for data in down_data:
1079 1079 for i in range(0,8):
1080 1080 down_values.append(data[i])
1081 1081
1082 1082 return down_values
@@ -1,39 +1,39
1 1 import os
2 2 import paho.mqtt.client as mqtt
3 3 from radarsys import settings
4 4 from radarsys.socketconfig import sio as sio
5 5
6 6 lista_ack=[
7 7 chr( 33 ), chr( 34 ), chr( 35 ), chr( 36 ), chr( 37 ), chr( 38 ), chr( 39 ), chr( 40 ), chr( 41 ), chr( 42 ), chr( 43 ), chr( 44 ), chr( 45 ), chr( 46 ), chr( 47 ), chr( 48 ), chr( 49 ), chr( 50 ), chr( 51 ), chr( 52 ), chr( 53 ), chr( 54 ), chr( 55 ), chr( 56 ), chr( 57 ), chr( 58 ), chr( 59 ), chr( 60 ), chr( 61 ), chr( 62 ), chr( 63 ), chr( 64 ), chr( 65 ), chr( 66 ), chr( 67 ), chr( 68 ), chr( 69 ), chr( 70 ), chr( 71 ), chr( 72 ), chr( 73 ), chr( 74 ), chr( 75 ), chr( 76 ), chr( 77 ), chr( 78 ), chr( 79 ), chr( 80 ), chr( 81 ), chr( 82 ), chr( 83 ), chr( 84 ), chr( 85 ), chr( 86 ), chr( 87 ), chr( 88 ), chr( 89 ), chr( 90 ), chr( 91 ), chr( 92 ), chr( 93 ), chr( 94 ), chr( 95 ), chr( 96 )
8 8 ]
9 9
10 10 lista_ack_dismatching=[
11 11 chr( 97 ), chr( 98 ), chr( 99 ), chr( 100 ), chr( 101 ), chr( 102 ), chr( 103 ), chr( 104 ), chr( 105 ), chr( 106 ), chr( 107 ), chr( 108 ), chr( 109 ), chr( 110 ), chr( 111 ), chr( 112 ), chr( 113 ), chr( 114 ), chr( 115 ), chr( 116 ), chr( 117 ), chr( 118 ), chr( 119 ), chr( 120 ), chr( 121 ), chr( 122 ), chr( 123 ), chr( 124 ), chr( 125 ), chr( 126 ), chr( 127 ), chr( 128 ), chr( 129 ), chr( 130 ), chr( 131 ), chr( 132 ), chr( 133 ), chr( 134 ), chr( 135 ), chr( 136 ), chr( 137 ), chr( 138 ), chr( 139 ), chr( 140 ), chr( 141 ), chr( 142 ), chr( 143 ), chr( 144 ), chr( 145 ), chr( 146 ), chr( 147 ), chr( 148 ), chr( 149 ), chr( 150 ), chr( 151 ), chr( 152 ), chr( 153 ), chr( 154 ), chr( 155 ), chr( 156 ), chr( 157 ), chr( 158 ), chr( 159 ), chr(160)
12 12 ]
13 13
14 14 def on_connect(mqtt_client, userdata, flags, rc):
15 15 if rc == 0:
16 print('Connected successfully')
16 # print('Connected successfully')
17 17 mqtt_client.subscribe(os.environ.get('TOPIC_ABS_ACK','abs/beams_ack'))
18 18 else:
19 19 print('Bad connection. Code:', rc)
20 20
21 21 def on_message(mqtt_client, userdata, msg):
22 22 # print(f'Received message on topic: {msg.topic} with payload: {msg.payload}', flush=True)
23 23 # message= str(msg.payload)
24 24 # sio.emit('abs_ws',data={'msg':message})
25 25 #message=str(msg.payload)
26 26 #lista_ack.pop(message)
27 27 print("Mientras" ,flush=True)
28 28
29 29
30 30
31 31 client = mqtt.Client()
32 32 client.on_connect = on_connect
33 33 client.on_message = on_message
34 34 client.username_pw_set(os.environ.get('MQTT_USER', 'abs'), os.environ.get('MQTT_PASSWORD', 'abs'))
35 35 client.connect(
36 36 host=os.environ.get('MQTT_SERVER', '10.10.10.200'),
37 37 port=int(settings.os.environ.get('MQTT_PORT', 1883)),
38 38 keepalive=int(os.environ.get('MQTT_KEEPALIVE', 36000))
39 39 ) No newline at end of file
@@ -1,39 +1,39
1 1 import os
2 2 import paho.mqtt.client as mqtt
3 3 from radarsys import settings
4 4 from radarsys.socketconfig import sio as sio
5 5 import numpy as np
6 6
7 7 def on_connect(mqtt_client, userdata, flags, rc):
8 8 if rc == 0:
9 print('Connected successfully')
9 # print('Connected successfully')
10 10 mqtt_client.subscribe('atrad/test3')
11 11 else:
12 12 print('Bad connection. Code:', rc)
13 13
14 14 def maxima_temp(trs):
15 15 np_array = [np.array(i) for i in trs]
16 16 temps = [max(i[i<40]) for i in np_array]
17 17 return max(temps)
18 18
19 19 def on_message(mqtt_client, userdata, msg):
20 20 # print(f'Received message on topic: {msg.topic} with payload: {msg.payload}', flush=True)
21 21 trsi = [[],[],[],[]]
22 22 mensaje = str(msg.payload)
23 23 datos = [i for i in mensaje[21:-1].split("*")]
24 24 status=''.join([datos[i][3] for i in range(3)])
25 25 for trs,i in zip(datos,[0,1,2,3]) :
26 26 trsi[i]= [int(i) for i in trs[1:-1].split(",")]
27 27 potencias = [trsi[0][34],trsi[0][36],trsi[2][32],trsi[2][34]]
28 28 tmax = maxima_temp(trsi)
29 29 sio.emit('test', data={'time':mensaje[2:21],'num':trsi[0][0],'pow':potencias,'tmax':str(tmax),'status':status})
30 30
31 31 client = mqtt.Client()
32 32 client.on_connect = on_connect
33 33 client.on_message = on_message
34 34 client.username_pw_set(os.environ.get('MQTT_USER_ATRAD', 'atrad'), os.environ.get('MQTT_PASSWORD_ATRAD', 'atrad'))
35 35 client.connect(
36 36 host=os.environ.get('MQTT_SERVER', '10.10.10.200'),
37 37 port=int(settings.os.environ.get('MQTT_PORT', 1883)),
38 38 keepalive=int(os.environ.get('MQTT_KEEPALIVE', 36000))
39 39 ) No newline at end of file
@@ -1,19 +1,103
1 1 from django.core.management.base import BaseCommand
2
2 from apps.main.models import Campaign, Location
3 from datetime import datetime,timedelta
4 from apps.main.views import radar_start
5 from django.shortcuts import render, redirect,get_object_or_404, HttpResponse
6 from django.urls import reverse
7 from django.utils.timezone import is_aware
8 from django.contrib import messages
9 from django.http import HttpResponseRedirect
10 from apps.main.views import experiment_start
11 from apps.main.models import Experiment, Configuration
3 12
4 13 class Command(BaseCommand):
5 14 """
6 15 Restart experiment every night at 05:00 am.
7 16 Example:
8 17 manage.py restart_experiment
9 18 """
10 19 def handle(self, *args, **options):
11 print("Hola")
20 print("")
21 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
22 end_date__gte=datetime.now()).order_by('-start_date')
23
24 if campaigns:
25
26 for campaign in campaigns:
27 print(campaign.name)
28 print(campaign.start_date)
29 print(campaign.end_date)
30 print(campaign.experiments.all()[0].id)
31 print("STATUS: ",campaign.experiments.all()[0].status)
32
33 radar=campaign.get_experiments_by_radar(radar=None)
34 radar_id=radar[0]["id"]
35 print(radar_id)
36
37 now = datetime.now()
38 if now<campaign.end_date and now >campaign.start_date:
39 print("La campaΓ±a",campaign.name ,"se ejecuta!",flush=True)
40 radar_start_scheduler(campaign.id,radar_id)
41
42 else:
43 copy_campaigns=Campaign.objects.all()
44 print("-------------Deteniendo procesos-------------")
45 for campaign in copy_campaigns:
46 print(campaign.name)
47 print(campaign.start_date)
48 print(campaign.end_date)
49 print("ID: ",campaign.experiments.all()[0].id)
50 print("STATUS: ",campaign.experiments.all()[0].status)
51 print("----,,,---")
52 radar=campaign.get_experiments_by_radar(radar=None)
53 radar_id=radar[0]["id"]
54
55 if campaign.experiments.all()[0].status !=1:
56 print("Estoy en :",campaign.experiments.all()[0].status)
57 print("Con ID: ",campaign.experiments.all()[0].id)
58 print("\n\n")
59 a=radar_stop_scheduler(campaign.id,radar_id,campaign.experiments.all()[0].id)
60 print("RETURN", a)
61
62
63 def radar_start_scheduler(id_camp,id_radar):
64 print("-------------------")
65 campaign = get_object_or_404(Campaign, pk=id_camp)
66 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
67 now = datetime.now()
68
69 for exp in experiments:
70 exp = get_object_or_404(Experiment, pk=exp.id)
12 71
13 # def main():
14 # print("Hola")
72 if exp.status == 2:
73 print('Experiment {} already runnnig'.format(exp))
74 else:
75 exp.status = exp.start()
76 if exp.status == 0:
77 print('Experiment {} not start'.format(exp))
78 if exp.status == 2:
79 print('Experiment {} started'.format(exp))
80 exp.save()
15 81
16 # if __name__=='__main__':
17 # main()
82 def radar_stop_scheduler(id_camp,id_radar,id_experiment):
83 print("-------------------")
84 '''
85 Stop experiments's devices
86 DDS-JARS-RC-CGS-ABS
87 '''
88 exp=get_object_or_404(Experiment,pk=id_experiment)
18 89
90 if exp.status == 2:
91 confs = Configuration.objects.filter(experiment=id_experiment,type = 0).order_by('device__device_type__sequence')
92 confs = confs.exclude(device__device_type__name='cgs')
93 try:
94 for conf in confs:
95 print("Estoy en conf_scheduler")
96 print(conf)
97 conf.stop_device()
98 exp.status= 1
99 except:
100 exp.status= 0
101 exp.save()
19 102
103 return exp.status No newline at end of file
@@ -1,829 +1,828
1 1
2 2 import os
3 3 import json
4 4 import requests
5 5 import time
6 6 from datetime import datetime
7 7
8 8 try:
9 9 from polymorphic.models import PolymorphicModel
10 10 except:
11 11 from polymorphic import PolymorphicModel
12 12
13 13 from django.template.base import kwarg_re
14 14 from django.db import models
15 15 from django.urls import reverse
16 16 from django.core.validators import MinValueValidator, MaxValueValidator
17 17 from django.shortcuts import get_object_or_404
18 18 from django.contrib.auth.models import User
19 19 from django.db.models.signals import post_save
20 20 from django.dispatch import receiver
21 21
22 22 from apps.main.utils import Params
23 23 from apps.rc.utils import RCFile
24 24 from apps.jars.utils import RacpFile
25 25 from devices.dds import api as dds_api
26 26 from devices.dds import data as dds_data
27 27
28 28
29 29 DEV_PORTS = {
30 30 'rc' : 2000,
31 31 'dds' : 2000,
32 32 'jars' : 2000,
33 33 'usrp' : 2000,
34 34 'cgs' : 8080,
35 35 'abs' : 8080,
36 36 'dds_rest': 80
37 37 }
38 38
39 39 RADAR_STATES = (
40 40 (0, 'No connected'),
41 41 (1, 'Connected'),
42 42 (2, 'Configured'),
43 43 (3, 'Running'),
44 44 (4, 'Scheduled'),
45 45 )
46 46
47 47 EXPERIMENT_TYPE = (
48 48 (0, 'RAW_DATA'),
49 49 (1, 'PDATA'),
50 50 )
51 51
52 52 DECODE_TYPE = (
53 53 (0, 'None'),
54 54 (1, 'TimeDomain'),
55 55 (2, 'FreqDomain'),
56 56 (3, 'InvFreqDomain'),
57 57 )
58 58
59 59 DEV_STATES = (
60 60 (0, 'No connected'),
61 61 (1, 'Connected'),
62 62 (2, 'Configured'),
63 63 (3, 'Running'),
64 64 (4, 'Unknown'),
65 65 )
66 66
67 67 DEV_TYPES = (
68 68 ('', 'Select a device type'),
69 69 ('rc', 'Radar Controller'),
70 70 ('dds', 'Direct Digital Synthesizer'),
71 71 ('jars', 'Jicamarca Radar Acquisition System'),
72 72 ('usrp', 'Universal Software Radio Peripheral'),
73 73 ('cgs', 'Clock Generator System'),
74 74 ('abs', 'Automatic Beam Switching'),
75 75 ('dds_rest', 'Direct Digital Synthesizer_REST'),
76 76 ('atrad', 'Transmitter ATRAD'),
77 77 )
78 78
79 79 EXP_STATES = (
80 80 (0,'Error'), #RED
81 81 (1,'Cancelled'), #YELLOW
82 82 (2,'Running'), #GREEN
83 83 (3,'Scheduled'), #BLUE
84 84 (4,'Unknown'), #WHITE
85 85 )
86 86
87 87 CONF_TYPES = (
88 88 (0, 'Active'),
89 89 (1, 'Historical'),
90 90 )
91 91
92 92 class Profile(models.Model):
93 93 user = models.OneToOneField(User, on_delete=models.CASCADE)
94 94 theme = models.CharField(max_length=30, default='spacelab')
95 95
96 96
97 97 @receiver(post_save, sender=User)
98 98 def create_user_profile(sender, instance, created, **kwargs):
99 99 if created:
100 100 Profile.objects.create(user=instance)
101 101
102 102 @receiver(post_save, sender=User)
103 103 def save_user_profile(sender, instance, **kwargs):
104 104 instance.profile.save()
105 105
106 106
107 107 class Location(models.Model):
108 108
109 109 name = models.CharField(max_length = 30)
110 110 description = models.TextField(blank=True, null=True)
111 111
112 112 class Meta:
113 113 db_table = 'db_location'
114 114
115 115 def __str__(self):
116 116 return u'%s' % self.name
117 117
118 118 def get_absolute_url(self):
119 119 return reverse('url_location', args=[str(self.id)])
120 120
121 121
122 122 class DeviceType(models.Model):
123 123
124 124 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'dds_rest')
125 125 sequence = models.PositiveSmallIntegerField(default=55)
126 126 description = models.TextField(blank=True, null=True)
127 127
128 128 class Meta:
129 129 db_table = 'db_device_types'
130 130
131 131 def __str__(self):
132 132 return u'%s' % self.get_name_display()
133 133
134 134 class Device(models.Model):
135 135
136 136 device_type = models.ForeignKey('DeviceType', on_delete=models.CASCADE)
137 137 location = models.ForeignKey('Location', on_delete=models.CASCADE)
138 138 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
139 139 port_address = models.PositiveSmallIntegerField(default=2000)
140 140 description = models.TextField(blank=True, null=True)
141 141 status = models.PositiveSmallIntegerField(default=4, choices=DEV_STATES)
142 142 conf_active = models.PositiveIntegerField(default=0, verbose_name='Current configuration')
143 143
144 144 class Meta:
145 145 db_table = 'db_devices'
146 146
147 147 def __str__(self):
148 148 ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
149 149
150 150 return ret
151 151
152 152 @property
153 153 def name(self):
154 154 return str(self)
155 155
156 156 def get_status(self):
157 157 return self.status
158 158
159 159 @property
160 160 def status_color(self):
161 161 color = 'muted'
162 162 if self.status == 0:
163 163 color = "danger"
164 164 elif self.status == 1:
165 165 color = "warning"
166 166 elif self.status == 2:
167 167 color = "info"
168 168 elif self.status == 3:
169 169 color = "success"
170 170
171 171 return color
172 172
173 173 def url(self, path=None):
174 174
175 175 if path:
176 176 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
177 177 else:
178 178 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
179 179
180 180 def get_absolute_url(self):
181 181 return reverse('url_device', args=[str(self.id)])
182 182
183 183 def get_absolute_url_edit(self):
184 184 return reverse('url_edit_device', args=[str(self.id)])
185 185
186 186 def get_absolute_url_delete(self):
187 187 return reverse('url_delete_device', args=[str(self.id)])
188 188
189 189 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
190 190
191 191 if self.device_type.name=='dds':
192 192 try:
193 193 answer = dds_api.change_ip(ip = self.ip_address,
194 194 port = self.port_address,
195 195 new_ip = ip_address,
196 196 mask = mask,
197 197 gateway = gateway)
198 198 if answer[0]=='1':
199 199 self.message = '25|DDS - {}'.format(answer)
200 200 self.ip_address = ip_address
201 201 self.save()
202 202 else:
203 203 self.message = '30|DDS - {}'.format(answer)
204 204 return False
205 205 except Exception as e:
206 206 self.message = '40|{}'.format(str(e))
207 207 return False
208 208
209 209 elif self.device_type.name=='rc':
210 210 headers = {'content-type': "application/json",
211 211 'cache-control': "no-cache"}
212 212
213 213 ip = [int(x) for x in ip_address.split('.')]
214 214 dns = [int(x) for x in dns.split('.')]
215 215 gateway = [int(x) for x in gateway.split('.')]
216 216 subnet = [int(x) for x in mask.split('.')]
217 217
218 218 payload = {
219 219 "ip": ip,
220 220 "dns": dns,
221 221 "gateway": gateway,
222 222 "subnet": subnet
223 223 }
224 224
225 225 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
226 226 try:
227 227 answer = req.json()
228 228 if answer['changeip']=='ok':
229 229 self.message = '25|IP succesfully changed'
230 230 self.ip_address = ip_address
231 231 self.save()
232 232 else:
233 233 self.message = '30|An error ocuur when changing IP'
234 234 except Exception as e:
235 235 self.message = '40|{}'.format(str(e))
236 236 else:
237 237 self.message = 'Not implemented'
238 238 return False
239 239
240 240 return True
241 241
242 242
243 243 class Campaign(models.Model):
244 244
245 245 template = models.BooleanField(default=False)
246 246 name = models.CharField(max_length=60, unique=True)
247 247 start_date = models.DateTimeField(blank=True, null=True)
248 248 end_date = models.DateTimeField(blank=True, null=True)
249 249 tags = models.CharField(max_length=40, blank=True, null=True)
250 250 description = models.TextField(blank=True, null=True)
251 251 experiments = models.ManyToManyField('Experiment', blank=True)
252 252 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
253 253
254 254 class Meta:
255 255 db_table = 'db_campaigns'
256 256 ordering = ('name',)
257 257
258 258 def __str__(self):
259 259 if self.template:
260 260 return u'{} (template)'.format(self.name)
261 261 else:
262 262 return u'{}'.format(self.name)
263 263
264 264 def jsonify(self):
265 265
266 266 data = {}
267 267
268 268 ignored = ('template')
269 269
270 270 for field in self._meta.fields:
271 271 if field.name in ignored:
272 272 continue
273 273 data[field.name] = field.value_from_object(self)
274 274
275 275 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
276 276 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
277 277
278 278 return data
279 279
280 280 def parms_to_dict(self):
281 281
282 282 params = Params({})
283 283 params.add(self.jsonify(), 'campaigns')
284 284
285 285 for exp in Experiment.objects.filter(campaign = self):
286 286 params.add(exp.jsonify(), 'experiments')
287 287 configurations = Configuration.objects.filter(experiment=exp, type=0)
288 288
289 289 for conf in configurations:
290 290 params.add(conf.jsonify(), 'configurations')
291 291 if conf.device.device_type.name=='rc':
292 292 for line in conf.get_lines():
293 293 params.add(line.jsonify(), 'lines')
294 294
295 295 return params.data
296 296
297 297 def dict_to_parms(self, parms, CONF_MODELS):
298 298
299 299 experiments = Experiment.objects.filter(campaign = self)
300 300
301 301 if experiments:
302 302 for experiment in experiments:
303 303 experiment.delete()
304 304
305 305 for id_exp in parms['experiments']['allIds']:
306 306 exp_parms = parms['experiments']['byId'][id_exp]
307 307 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
308 308 exp = Experiment(name='{}'.format(dum))
309 309 exp.save()
310 310 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
311 311 self.experiments.add(exp)
312 312
313 313 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
314 314
315 315 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
316 316 self.start_date = camp_parms['start_date']
317 317 self.end_date = camp_parms['end_date']
318 318 self.tags = camp_parms['tags']
319 319 self.save()
320 320
321 321 return self
322 322
323 323 def get_experiments_by_radar(self, radar=None):
324 324
325 325 ret = []
326 326 if radar:
327 327 locations = Location.objects.filter(pk=radar)
328 328 else:
329 329 locations = set([e.location for e in self.experiments.all()])
330 330
331 331 for loc in locations:
332 332 dum = {}
333 333 dum['name'] = loc.name
334 334 dum['id'] = loc.pk
335 335 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
336 336 ret.append(dum)
337
338 337 return ret
339 338
340 339 def get_absolute_url(self):
341 340 return reverse('url_campaign', args=[str(self.id)])
342 341
343 342 def get_absolute_url_edit(self):
344 343 return reverse('url_edit_campaign', args=[str(self.id)])
345 344
346 345 def get_absolute_url_delete(self):
347 346 return reverse('url_delete_campaign', args=[str(self.id)])
348 347
349 348 def get_absolute_url_export(self):
350 349 return reverse('url_export_campaign', args=[str(self.id)])
351 350
352 351 def get_absolute_url_import(self):
353 352 return reverse('url_import_campaign', args=[str(self.id)])
354 353
355 354
356 355 class RunningExperiment(models.Model):
357 356 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
358 357 running_experiment = models.ManyToManyField('Experiment', blank = True)
359 358 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
360 359
361 360
362 361 class Experiment(models.Model):
363 362
364 363 template = models.BooleanField(default=False)
365 364 name = models.CharField(max_length=40, default='', unique=True)
366 365 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
367 366 freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
368 367 start_time = models.TimeField(default='00:00:00')
369 368 end_time = models.TimeField(default='23:59:59')
370 369 task = models.CharField(max_length=36, default='', blank=True, null=True)
371 370 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
372 371 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
373 372 hash = models.CharField(default='', max_length=64, null=True, blank=True)
374 373
375 374 class Meta:
376 375 db_table = 'db_experiments'
377 376 ordering = ('template', 'name')
378 377
379 378 def __str__(self):
380 379 if self.template:
381 380 return u'%s (template)' % (self.name)
382 381 else:
383 382 return u'%s' % (self.name)
384 383
385 384 def jsonify(self):
386 385
387 386 data = {}
388 387
389 388 ignored = ('template')
390 389
391 390 for field in self._meta.fields:
392 391 if field.name in ignored:
393 392 continue
394 393 data[field.name] = field.value_from_object(self)
395 394
396 395 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
397 396 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
398 397 data['location'] = self.location.name
399 398 data['configurations'] = ['{}'.format(conf.pk) for
400 399 conf in Configuration.objects.filter(experiment=self, type=0)]
401 400
402 401 return data
403 402
404 403 @property
405 404 def radar_system(self):
406 405 return self.location
407 406
408 407 def clone(self, **kwargs):
409 408
410 409 confs = Configuration.objects.filter(experiment=self, type=0)
411 410 self.pk = None
412 411 self.name = '{}_{:%y%m%d%H%M%S}'.format(self.name, datetime.now())
413 412 for attr, value in kwargs.items():
414 413 setattr(self, attr, value)
415 414
416 415 self.save()
417 416
418 417 for conf in confs:
419 418 conf.clone(experiment=self, template=False)
420 419
421 420 return self
422 421
423 422 def start(self):
424 423 '''
425 424 Configure and start experiments's devices
426 425 ABS-CGS-DDS-RC-JARS
427 426 '''
428 427
429 428 confs = []
430 429 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
431 430 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix]
432 431 if rc_mix:
433 432 for conf in allconfs:
434 433 if conf.device.device_type.name == 'rc' and not conf.mix:
435 434 continue
436 435 confs.append(conf)
437 436 else:
438 437 confs = allconfs
439 438
440 439 print("confs: ",confs)
441 440 #try:
442 441 for conf in confs:
443 442 print("conf->",conf)
444 443 conf.stop_device()
445 444 conf.write_device()
446 445 conf.device.conf_active = conf.pk
447 446 conf.device.save()
448 447 conf.start_device()
449 448 time.sleep(1)
450 449 #except:
451 450 #return 0
452 451 return 2
453 452
454 453
455 454 def stop(self):
456 455 '''
457 456 Stop experiments's devices
458 457 DDS-JARS-RC-CGS-ABS
459 458 '''
460 459
461 460 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
462 461 confs = confs.exclude(device__device_type__name='cgs')
463 462 try:
464 463 for conf in confs:
465 464 conf.stop_device()
466 465 except:
467 466 return 0
468 467 return 1
469 468
470 469 def get_status(self):
471 470
472 471 if self.status == 3:
473 472 return
474 473
475 474 confs = Configuration.objects.filter(experiment=self, type=0)
476 475
477 476 for conf in confs:
478 477 conf.status_device()
479 478
480 479 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
481 480
482 481 if total==2*confs.count():
483 482 status = 1
484 483 elif total == 3*confs.count():
485 484 status = 2
486 485 else:
487 486 status = 0
488 487
489 488 self.status = status
490 489 self.save()
491 490
492 491 def status_color(self):
493 492 color = 'muted'
494 493 if self.status == 0:
495 494 color = "danger"
496 495 elif self.status == 1:
497 496 color = "warning"
498 497 elif self.status == 2:
499 498 color = "success"
500 499 elif self.status == 3:
501 500 color = "info"
502 501
503 502 return color
504 503
505 504 def parms_to_dict(self):
506 505
507 506 params = Params({})
508 507 params.add(self.jsonify(), 'experiments')
509 508
510 509 configurations = Configuration.objects.filter(experiment=self, type=0)
511 510
512 511 for conf in configurations:
513 512 params.add(conf.jsonify(), 'configurations')
514 513 if conf.device.device_type.name=='rc':
515 514 for line in conf.get_lines():
516 515 params.add(line.jsonify(), 'lines')
517 516
518 517 return params.data
519 518
520 519 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
521 520
522 521 configurations = Configuration.objects.filter(experiment=self)
523 522
524 523 if id_exp is not None:
525 524 exp_parms = parms['experiments']['byId'][id_exp]
526 525 else:
527 526 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
528 527
529 528 if configurations:
530 529 for configuration in configurations:
531 530 configuration.delete()
532 531
533 532 for id_conf in exp_parms['configurations']:
534 533 conf_parms = parms['configurations']['byId'][id_conf]
535 534 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
536 535 model = CONF_MODELS[conf_parms['device_type']]
537 536 conf = model(
538 537 experiment = self,
539 538 device = device,
540 539 )
541 540 conf.dict_to_parms(parms, id=id_conf)
542 541
543 542
544 543 location, created = Location.objects.get_or_create(name=exp_parms['location'])
545 544 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
546 545 self.location = location
547 546 self.start_time = exp_parms['start_time']
548 547 self.end_time = exp_parms['end_time']
549 548 self.save()
550 549
551 550 return self
552 551
553 552 def get_absolute_url(self):
554 553 return reverse('url_experiment', args=[str(self.id)])
555 554
556 555 def get_absolute_url_edit(self):
557 556 return reverse('url_edit_experiment', args=[str(self.id)])
558 557
559 558 def get_absolute_url_delete(self):
560 559 return reverse('url_delete_experiment', args=[str(self.id)])
561 560
562 561 def get_absolute_url_import(self):
563 562 return reverse('url_import_experiment', args=[str(self.id)])
564 563
565 564 def get_absolute_url_export(self):
566 565 return reverse('url_export_experiment', args=[str(self.id)])
567 566
568 567 def get_absolute_url_start(self):
569 568 return reverse('url_start_experiment', args=[str(self.id)])
570 569
571 570 def get_absolute_url_stop(self):
572 571 return reverse('url_stop_experiment', args=[str(self.id)])
573 572
574 573
575 574 class Configuration(PolymorphicModel):
576 575
577 576 template = models.BooleanField(default=False)
578 577 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
579 578 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
580 579 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=True, null=True)
581 580 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
582 581 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
583 582 created_date = models.DateTimeField(auto_now_add=True)
584 583 programmed_date = models.DateTimeField(auto_now=True)
585 584 parameters = models.TextField(default='{}')
586 585 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
587 586 hash = models.CharField(default='', max_length=64, null=True, blank=True)
588 587 message = ""
589 588
590 589 class Meta:
591 590 db_table = 'db_configurations'
592 591 ordering = ('device__device_type__name',)
593 592
594 593 def __str__(self):
595 594
596 595 ret = u'{} '.format(self.device.device_type.name.upper())
597 596
598 597 if 'mix' in [f.name for f in self._meta.get_fields()]:
599 598 if self.mix:
600 599 ret = '{} MIX '.format(self.device.device_type.name.upper())
601 600
602 601 if 'label' in [f.name for f in self._meta.get_fields()]:
603 602 ret += '{}'.format(self.label)
604 603
605 604 if self.template:
606 605 ret += ' (template)'
607 606
608 607 return ret
609 608
610 609 @property
611 610 def name(self):
612 611
613 612 return str(self)
614 613
615 614 def jsonify(self):
616 615
617 616 data = {}
618 617
619 618 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
620 619 'created_date', 'programmed_date', 'template', 'device',
621 620 'experiment')
622 621
623 622 for field in self._meta.fields:
624 623 if field.name in ignored:
625 624 continue
626 625 data[field.name] = field.value_from_object(self)
627 626
628 627 data['device_type'] = self.device.device_type.name
629 628
630 629 if self.device.device_type.name == 'rc':
631 630 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
632 631 data['delays'] = self.get_delays()
633 632 data['pulses'] = self.get_pulses()
634 633
635 634 elif self.device.device_type.name == 'jars':
636 635 data['decode_type'] = DECODE_TYPE[self.decode_data][1]
637 636
638 637 elif self.device.device_type.name == 'dds':
639 638 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
640 639 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
641 640 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
642 641 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
643 642
644 643 elif self.device.device_type.name == 'dds_rest':
645 644 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
646 645 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
647 646 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
648 647 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
649 648 data['delta_frequency_Mhz'] = float(data['delta_frequency_Mhz'] or 0.00)
650 649 data['update_clock_Mhz'] = float(data['update_clock_Mhz'] or 0.00)
651 650 data['ramp_rate_clock_Mhz'] = float(data['ramp_rate_clock_Mhz'] or 0.0)
652 651 return data
653 652
654 653 def clone(self, **kwargs):
655 654
656 655 self.pk = None
657 656 self.id = None
658 657 for attr, value in kwargs.items():
659 658 setattr(self, attr, value)
660 659
661 660 self.save()
662 661
663 662 return self
664 663
665 664 def parms_to_dict(self):
666 665
667 666 params = Params({})
668 667 params.add(self.jsonify(), 'configurations')
669 668
670 669 if self.device.device_type.name=='rc':
671 670 for line in self.get_lines():
672 671 params.add(line.jsonify(), 'lines')
673 672
674 673 return params.data
675 674
676 675 def parms_to_text(self):
677 676
678 677 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
679 678
680 679
681 680 def parms_to_binary(self):
682 681
683 682 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
684 683
685 684
686 685 def dict_to_parms(self, parameters, id=None):
687 686
688 687 params = Params(parameters)
689 688
690 689 if id:
691 690 data = params.get_conf(id_conf=id)
692 691 else:
693 692 data = params.get_conf(dtype=self.device.device_type.name)
694 693
695 694 if data['device_type']=='rc':
696 695 self.clean_lines()
697 696 lines = data.pop('lines', None)
698 697 for line_id in lines:
699 698 pass
700 699
701 700 for key, value in data.items():
702 701 if key not in ('id', 'device_type'):
703 702 setattr(self, key, value)
704 703
705 704 self.save()
706 705
707 706
708 707 def export_to_file(self, format="json"):
709 708
710 709 content_type = ''
711 710
712 711 if format == 'racp':
713 712 content_type = 'text/plain'
714 713 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
715 714 content = self.parms_to_text(file_format = 'racp')
716 715
717 716 if format == 'text':
718 717 content_type = 'text/plain'
719 718 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
720 719 content = self.parms_to_text()
721 720
722 721 if format == 'binary':
723 722 content_type = 'application/octet-stream'
724 723 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
725 724 content = self.parms_to_binary()
726 725
727 726 if not content_type:
728 727 content_type = 'application/json'
729 728 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
730 729 content = json.dumps(self.parms_to_dict(), indent=2)
731 730
732 731 fields = {'content_type':content_type,
733 732 'filename':filename,
734 733 'content':content
735 734 }
736 735
737 736 return fields
738 737
739 738 def import_from_file(self, fp):
740 739
741 740 parms = {}
742 741
743 742 path, ext = os.path.splitext(fp.name)
744 743
745 744 if ext == '.json':
746 745 parms = json.load(fp)
747 746
748 747 if ext == '.dds':
749 748 lines = fp.readlines()
750 749 parms = dds_data.text_to_dict(lines)
751 750
752 751 if ext == '.racp':
753 752 if self.device.device_type.name == 'jars':
754 753 parms = RacpFile(fp).to_dict()
755 754 parms['filter_parms'] = json.loads(self.filter_parms)
756 755 return parms
757 756 parms = RCFile(fp).to_dict()
758 757
759 758 return parms
760 759
761 760 def status_device(self):
762 761
763 762 self.message = 'Function not implemented'
764 763 return False
765 764
766 765
767 766 def stop_device(self):
768 767
769 768 self.message = 'Function not implemented'
770 769 return False
771 770
772 771
773 772 def start_device(self):
774 773
775 774 self.message = 'Function not implemented'
776 775 return False
777 776
778 777
779 778 def write_device(self, parms):
780 779
781 780 self.message = 'Function not implemented'
782 781 return False
783 782
784 783 def write_device_mqtt(self, parms):
785 784
786 785 self.message = 'Function not implemented'
787 786 return False
788 787
789 788 def read_device(self):
790 789
791 790 self.message = 'Function not implemented'
792 791 return False
793 792
794 793
795 794 def get_absolute_url(self):
796 795 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
797 796
798 797 def get_absolute_url_edit(self):
799 798 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
800 799
801 800 def get_absolute_url_delete(self):
802 801 return reverse('url_delete_dev_conf', args=[str(self.id)])
803 802
804 803 def get_absolute_url_import(self):
805 804 return reverse('url_import_dev_conf', args=[str(self.id)])
806 805
807 806 def get_absolute_url_export(self):
808 807 return reverse('url_export_dev_conf', args=[str(self.id)])
809 808
810 809 def get_absolute_url_write(self):
811 810 return reverse('url_write_dev_conf', args=[str(self.id)])
812 811
813 812 def get_absolute_url_write_mqtt(self):
814 813 return reverse('url_write_mqtt_dev_conf', args=[str(self.id)])
815 814
816 815 def get_absolute_url_read(self):
817 816 return reverse('url_read_dev_conf', args=[str(self.id)])
818 817
819 818 def get_absolute_url_start(self):
820 819 return reverse('url_start_dev_conf', args=[str(self.id)])
821 820
822 821 def get_absolute_url_stop(self):
823 822 return reverse('url_stop_dev_conf', args=[str(self.id)])
824 823
825 824 def get_absolute_url_stop_mqtt(self):
826 825 return reverse('url_stop_mqtt_dev_conf', args=[str(self.id)])
827 826
828 827 def get_absolute_url_status(self):
829 828 return reverse('url_status_dev_conf', args=[str(self.id)])
@@ -1,62 +1,62
1 1 import os
2 2 import paho.mqtt.client as mqtt
3 3 from radarsys import settings
4 4 from radarsys.socketconfig import sio as sio
5 5
6 6
7 7 lista_ack=[
8 8 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128
9 9 ]
10 10
11 11
12 12
13 13 def on_connect(mqtt_client, userdata, flags, rc):
14 14 if rc == 0:
15 print('Connected successfully')
15 #print('Connected successfully')
16 16 mqtt_client.subscribe(os.environ.get('TOPIC_ABS_ACK','abs/beams_ack'))
17 17 else:
18 18 print('Bad connection. Code:', rc)
19 19
20 20 def on_message(mqtt_client, userdata, msg):
21 21 # print(f'Received message on topic: {msg.topic} with payload: {msg.payload}', flush=True)
22 22 # message= str(msg.payload)
23 23 # sio.emit('abs_ws',data={'msg':message})
24 24 #print("HOLA",flush=True)
25 25 # message=msg.payload[1]
26 26 # print("HOLAAA ",message,flush=True)
27 27 # #lista_ack.remove(msg.payload)
28 28 # print("LISTA ",lista_ack)
29 29 global lista_ack
30 30 global lista_ack_dismatching
31 31 message= str(msg.payload)
32 32 message=message[2:len(message)-1]
33 33 if(message=="UPDATE"):
34 34 print("UUPDATE")
35 35 sio.emit('beams_ack',data={'msg':lista_ack})
36 36 print(lista_ack,flush=True)
37 37 lista_ack=[
38 38 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128
39 39 ]
40 40 else:
41 41 message=int(message)
42 42 if(message<=64):
43 43 # print(message,"\t MATCH",flush=True)
44 44 lista_ack.remove(message+64)
45 45
46 46 elif(message>64):
47 47 # print(message,"\t DISMATCH",flush=True)
48 48 lista_ack.remove(message-64)
49 49 else:
50 50 print(len(message))
51 51
52 52
53 53
54 54 client = mqtt.Client()
55 55 client.on_connect = on_connect
56 56 client.on_message = on_message
57 57 client.username_pw_set(os.environ.get('MQTT_USER', 'abs'), os.environ.get('MQTT_PASSWORD', 'abs'))
58 58 client.connect(
59 59 host=os.environ.get('MQTT_SERVER', '10.10.10.200'),
60 60 port=int(settings.os.environ.get('MQTT_PORT', 1883)),
61 61 keepalive=int(os.environ.get('MQTT_KEEPALIVE', 60000))
62 62 ) No newline at end of file
@@ -1,2110 +1,2110
1 1 import ast
2 2 import json
3 3 import hashlib
4 4 from datetime import datetime, timedelta
5 5
6 6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7 7 from django.utils.safestring import mark_safe
8 8 from django.http import HttpResponseRedirect
9 9 from django.urls import reverse
10 10 from django.db.models import Q
11 11 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
12 12 from django.contrib import messages
13 13 from django.http.request import QueryDict
14 14 from django.contrib.auth.decorators import login_required, user_passes_test
15 15
16 16 from django.utils.timezone import is_aware
17 17
18 18 try:
19 19 from urllib.parse import urlencode
20 20 except ImportError:
21 21 from urllib import urlencode
22 22
23 23 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
24 24 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
25 25
26 26 from apps.rc.forms import RCConfigurationForm, RCLineCode, RCMixConfigurationForm
27 27 from apps.dds.forms import DDSConfigurationForm
28 28 from apps.jars.forms import JARSConfigurationForm
29 29 from apps.cgs.forms import CGSConfigurationForm
30 30 from apps.abs.forms import ABSConfigurationForm
31 31 from apps.usrp.forms import USRPConfigurationForm
32 32 from apps.dds_rest.forms import DDSRestConfigurationForm
33 33 from apps.atrad.forms import ATRADConfigurationForm
34 34 from .utils import Params
35 35
36 36 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment, DEV_STATES
37 37 from apps.cgs.models import CGSConfiguration
38 38 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
39 39 from apps.usrp.models import USRPConfiguration
40 40 from apps.abs.models import ABSConfiguration, ABSBeam
41 41 from apps.rc.models import RCConfiguration, RCLine, RCLineType, RCClock
42 42 from apps.dds.models import DDSConfiguration
43 43 from apps.dds_rest.models import DDSRestConfiguration
44 44 from apps.atrad.models import ATRADConfiguration
45 45
46 46 #from .tasks import task_start
47 47 from radarsys.celery import app
48 48
49 49
50 50 from .mqtt import client as mqtt_client
51 51 from radarsys.socketconfig import sio as sio
52 52
53 53 #comentario test
54 54 CONF_FORMS = {
55 55 'rc': RCConfigurationForm,
56 56 'dds': DDSConfigurationForm,
57 57 'dds_rest': DDSRestConfigurationForm,
58 58 'jars': JARSConfigurationForm,
59 59 'cgs': CGSConfigurationForm,
60 60 'abs': ABSConfigurationForm,
61 61 'usrp': USRPConfigurationForm,
62 62 'atrad': ATRADConfigurationForm,
63 63 }
64 64
65 65 CONF_MODELS = {
66 66 'rc': RCConfiguration,
67 67 'dds': DDSConfiguration,
68 68 'dds_rest': DDSRestConfiguration,
69 69 'jars': JARSConfiguration,
70 70 'cgs': CGSConfiguration,
71 71 'abs': ABSConfiguration,
72 72 'usrp': USRPConfiguration,
73 73 'atrad': ATRADConfiguration,
74 74 }
75 75
76 76 MIX_MODES = {
77 77 '0': 'P',
78 78 '1': 'S',
79 79 }
80 80
81 81 MIX_OPERATIONS = {
82 82 '0': 'OR',
83 83 '1': 'XOR',
84 84 '2': 'AND',
85 85 '3': 'NAND',
86 86 }
87 87
88 88
89 89 def is_developer(user):
90 90
91 91 groups = [str(g.name) for g in user.groups.all()]
92 92 return 'Developer' in groups or user.is_staff
93 93
94 94
95 95 def is_operator(user):
96 96
97 97 groups = [str(g.name) for g in user.groups.all()]
98 98 return 'Operator' in groups or user.is_staff
99 99
100 100
101 101 def has_been_modified(model):
102 102
103 103 prev_hash = model.hash
104 104 new_hash = hashlib.sha256(str(model.parms_to_dict).encode()).hexdigest()
105 105 if prev_hash != new_hash:
106 106 model.hash = new_hash
107 107 model.save()
108 108 return True
109 109 return False
110 110
111 111
112 112 def index(request):
113 113 kwargs = {'no_sidebar': True}
114 114
115 115 return render(request, 'index.html', kwargs)
116 116
117 117
118 118 def locations(request):
119 119
120 120 page = request.GET.get('page')
121 121 order = ('name',)
122 122
123 123 kwargs = get_paginator(Location, page, order)
124 124
125 125 kwargs['keys'] = ['name', 'description']
126 126 kwargs['title'] = 'Radar System'
127 127 kwargs['suptitle'] = 'List'
128 128 kwargs['no_sidebar'] = True
129 129
130 130 return render(request, 'base_list.html', kwargs)
131 131
132 132
133 133 def location(request, id_loc):
134 134
135 135 location = get_object_or_404(Location, pk=id_loc)
136 136
137 137 kwargs = {}
138 138 kwargs['location'] = location
139 139 kwargs['location_keys'] = ['name', 'description']
140 140
141 141 kwargs['title'] = 'Location'
142 142 kwargs['suptitle'] = 'Details'
143 143
144 144 return render(request, 'location.html', kwargs)
145 145
146 146
147 147 @login_required
148 148 def location_new(request):
149 149
150 150 if request.method == 'GET':
151 151 form = LocationForm()
152 152
153 153 if request.method == 'POST':
154 154 form = LocationForm(request.POST)
155 155
156 156 if form.is_valid():
157 157 form.save()
158 158 return redirect('url_locations')
159 159
160 160 kwargs = {}
161 161 kwargs['form'] = form
162 162 kwargs['title'] = 'Radar System'
163 163 kwargs['suptitle'] = 'New'
164 164 kwargs['button'] = 'Create'
165 165
166 166 return render(request, 'base_edit.html', kwargs)
167 167
168 168
169 169 @login_required
170 170 def location_edit(request, id_loc):
171 171
172 172 location = get_object_or_404(Location, pk=id_loc)
173 173
174 174 if request.method == 'GET':
175 175 form = LocationForm(instance=location)
176 176
177 177 if request.method == 'POST':
178 178 form = LocationForm(request.POST, instance=location)
179 179
180 180 if form.is_valid():
181 181 form.save()
182 182 return redirect('url_locations')
183 183
184 184 kwargs = {}
185 185 kwargs['form'] = form
186 186 kwargs['title'] = 'Location'
187 187 kwargs['suptitle'] = 'Edit'
188 188 kwargs['button'] = 'Update'
189 189
190 190 return render(request, 'base_edit.html', kwargs)
191 191
192 192
193 193 @login_required
194 194 def location_delete(request, id_loc):
195 195
196 196 location = get_object_or_404(Location, pk=id_loc)
197 197
198 198 if request.method == 'POST':
199 199
200 200 if is_developer(request.user):
201 201 location.delete()
202 202 return redirect('url_locations')
203 203
204 204 messages.error(request, 'Not enough permission to delete this object')
205 205 return redirect(location.get_absolute_url())
206 206
207 207 kwargs = {
208 208 'title': 'Delete',
209 209 'suptitle': 'Location',
210 210 'object': location,
211 211 'delete': True
212 212 }
213 213
214 214 return render(request, 'confirm.html', kwargs)
215 215
216 216
217 217 def devices(request):
218 218
219 219 page = request.GET.get('page')
220 220 order = ('location', 'device_type')
221 221
222 222 filters = request.GET.copy()
223 223 kwargs = get_paginator(Device, page, order, filters)
224 224 form = FilterForm(initial=request.GET, extra_fields=['tags'])
225 225
226 226 kwargs['keys'] = ['device_type', 'location',
227 227 'ip_address', 'port_address', 'actions']
228 228 kwargs['title'] = 'Device'
229 229 kwargs['suptitle'] = 'List'
230 230 kwargs['no_sidebar'] = True
231 231 kwargs['form'] = form
232 232 kwargs['add_url'] = reverse('url_add_device')
233 233 filters.pop('page', None)
234 234 kwargs['q'] = urlencode(filters)
235 235 kwargs['menu_devices'] = 'active'
236 236 return render(request, 'base_list.html', kwargs)
237 237
238 238
239 239 def device(request, id_dev):
240 240
241 241 device = get_object_or_404(Device, pk=id_dev)
242 242
243 243 kwargs = {}
244 244 kwargs['device'] = device
245 245 kwargs['device_keys'] = ['device_type',
246 246 'ip_address', 'port_address', 'description']
247 247
248 248 kwargs['title'] = 'Device'
249 249 kwargs['suptitle'] = 'Details'
250 250 kwargs['menu_devices'] = 'active'
251 251
252 252 return render(request, 'device.html', kwargs)
253 253
254 254
255 255 @login_required
256 256 def device_new(request):
257 257
258 258 if request.method == 'GET':
259 259 form = DeviceForm()
260 260
261 261 if request.method == 'POST':
262 262 form = DeviceForm(request.POST)
263 263
264 264 if form.is_valid():
265 265 form.save()
266 266 return redirect('url_devices')
267 267
268 268 kwargs = {}
269 269 kwargs['form'] = form
270 270 kwargs['title'] = 'Device'
271 271 kwargs['suptitle'] = 'New_2'
272 272 kwargs['button'] = 'Create'
273 273 kwargs['menu_devices'] = 'active'
274 274
275 275 return render(request, 'base_edit.html', kwargs)
276 276
277 277
278 278 @login_required
279 279 def device_edit(request, id_dev):
280 280
281 281 device = get_object_or_404(Device, pk=id_dev)
282 282
283 283 if request.method == 'GET':
284 284 form = DeviceForm(instance=device)
285 285
286 286 if request.method == 'POST':
287 287 form = DeviceForm(request.POST, instance=device)
288 288
289 289 if form.is_valid():
290 290 form.save()
291 291 return redirect(device.get_absolute_url())
292 292
293 293 kwargs = {}
294 294 kwargs['form'] = form
295 295 kwargs['title'] = 'Device'
296 296 kwargs['suptitle'] = 'Edit'
297 297 kwargs['button'] = 'Update'
298 298 kwargs['menu_devices'] = 'active'
299 299
300 300 return render(request, 'base_edit.html', kwargs)
301 301
302 302
303 303 @login_required
304 304 def device_delete(request, id_dev):
305 305
306 306 device = get_object_or_404(Device, pk=id_dev)
307 307
308 308 if request.method == 'POST':
309 309
310 310 if is_developer(request.user):
311 311 device.delete()
312 312 return redirect('url_devices')
313 313
314 314 messages.error(request, 'Not enough permission to delete this object')
315 315 return redirect(device.get_absolute_url())
316 316
317 317 kwargs = {
318 318 'title': 'Delete',
319 319 'suptitle': 'Device',
320 320 'object': device,
321 321 'delete': True
322 322 }
323 323 kwargs['menu_devices'] = 'active'
324 324
325 325 return render(request, 'confirm.html', kwargs)
326 326
327 327
328 328 @login_required
329 329 def device_change_ip(request, id_dev):
330 330
331 331 device = get_object_or_404(Device, pk=id_dev)
332 332
333 333 if request.method == 'POST':
334 334
335 335 if is_developer(request.user):
336 336 device.change_ip(**request.POST.dict())
337 337
338 338 print(device.ip_address, device.message)
339 339
340 340 level, message = device.message.split('|')
341 341 messages.add_message(request, level, message)
342 342 else:
343 343 messages.error(
344 344 request, 'Not enough permission to delete this object')
345 345 return redirect(device.get_absolute_url())
346 346
347 347 kwargs = {
348 348 'title': 'Device',
349 349 'suptitle': 'Change IP',
350 350 'object': device,
351 351 'previous': device.get_absolute_url(),
352 352 'form': ChangeIpForm(initial={'ip_address': device.ip_address}),
353 353 'message': ' ',
354 354 }
355 355 kwargs['menu_devices'] = 'active'
356 356
357 357 return render(request, 'confirm.html', kwargs)
358 358
359 359
360 360 def campaigns(request):
361 361
362 362 page = request.GET.get('page')
363 363 order = ('-start_date',)
364 364 filters = request.GET.copy()
365 365
366 366 kwargs = get_paginator(Campaign, page, order, filters)
367 367
368 368 form = FilterForm(initial=request.GET, extra_fields=[
369 369 'range_date', 'tags', 'template'])
370 370 kwargs['keys'] = ['name', 'start_date', 'end_date', 'actions']
371 371 kwargs['title'] = 'Campaign'
372 372 kwargs['suptitle'] = 'List'
373 373 kwargs['no_sidebar'] = True
374 374 kwargs['form'] = form
375 375 kwargs['add_url'] = reverse('url_add_campaign')
376 376 filters.pop('page', None)
377 377 kwargs['q'] = urlencode(filters)
378 378 kwargs['menu_campaigns'] = 'active'
379 379
380 380 return render(request, 'base_list.html', kwargs)
381 381
382 382
383 383 def campaign(request, id_camp):
384 384
385 385 campaign = get_object_or_404(Campaign, pk=id_camp)
386 386 experiments = Experiment.objects.filter(campaign=campaign)
387 387
388 388 form = CampaignForm(instance=campaign)
389 389
390 390 kwargs = {}
391 391 kwargs['campaign'] = campaign
392 392 kwargs['campaign_keys'] = ['template', 'name',
393 393 'start_date', 'end_date', 'tags', 'description']
394 394
395 395 kwargs['experiments'] = experiments
396 396 kwargs['experiment_keys'] = [
397 397 'name', 'radar_system', 'start_time', 'end_time']
398 398
399 399 kwargs['title'] = 'Campaign'
400 400 kwargs['suptitle'] = 'Details'
401 401
402 402 kwargs['form'] = form
403 403 kwargs['button'] = 'Add Experiment'
404 404 kwargs['menu_campaigns'] = 'active'
405 405
406 406 return render(request, 'campaign.html', kwargs)
407 407
408 408
409 409 @login_required
410 410 def campaign_new(request):
411 411
412 412 kwargs = {}
413 413
414 414 if request.method == 'GET':
415 415
416 416 if 'template' in request.GET:
417 417 if request.GET['template'] == '0':
418 418 form = NewForm(initial={'create_from': 2},
419 419 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
420 420 else:
421 421 kwargs['button'] = 'Create'
422 422 kwargs['experiments'] = Configuration.objects.filter(
423 423 experiment=request.GET['template'])
424 424 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
425 425 camp = Campaign.objects.get(pk=request.GET['template'])
426 426 form = CampaignForm(instance=camp,
427 427 initial={'name': '{}_{:%Y%m%d%H%M%S}'.format(camp.name, datetime.now()),
428 428 'template': False})
429 429 elif 'blank' in request.GET:
430 430 kwargs['button'] = 'Create'
431 431 form = CampaignForm()
432 432 else:
433 433 form = NewForm()
434 434
435 435 if request.method == 'POST':
436 436 kwargs['button'] = 'Create'
437 437 post = request.POST.copy()
438 438 experiments = []
439 439
440 440 for id_exp in post.getlist('experiments'):
441 441 exp = Experiment.objects.get(pk=id_exp)
442 442 new_exp = exp.clone(template=False)
443 443 experiments.append(new_exp)
444 444
445 445 post.setlist('experiments', [])
446 446
447 447 form = CampaignForm(post)
448 448
449 449 if form.is_valid():
450 450 campaign = form.save(commit=False)
451 451 campaign.author = request.user
452 452 campaign.save()
453 453 for exp in experiments:
454 454 campaign.experiments.add(exp)
455 455
456 456 return redirect('url_campaign', id_camp=campaign.id)
457 457
458 458 kwargs['form'] = form
459 459 kwargs['title'] = 'Campaign'
460 460 kwargs['suptitle'] = 'New'
461 461 kwargs['menu_campaigns'] = 'active'
462 462
463 463 return render(request, 'campaign_edit.html', kwargs)
464 464
465 465
466 466 @login_required
467 467 def campaign_edit(request, id_camp):
468 468
469 469 campaign = get_object_or_404(Campaign, pk=id_camp)
470 470
471 471 if request.method == 'GET':
472 472 form = CampaignForm(instance=campaign)
473 473
474 474 if request.method == 'POST':
475 475 exps = campaign.experiments.all().values_list('pk', flat=True)
476 476 post = request.POST.copy()
477 477 new_exps = post.getlist('experiments')
478 478 post.setlist('experiments', [])
479 479 form = CampaignForm(post, instance=campaign)
480 480
481 481 if form.is_valid():
482 482 camp = form.save()
483 483 for id_exp in new_exps:
484 484 if int(id_exp) in exps:
485 485 exps.pop(id_exp)
486 486 else:
487 487 exp = Experiment.objects.get(pk=id_exp)
488 488 if exp.template:
489 489 camp.experiments.add(exp.clone(template=False))
490 490 else:
491 491 camp.experiments.add(exp)
492 492
493 493 for id_exp in exps:
494 494 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
495 495
496 496 return redirect('url_campaign', id_camp=id_camp)
497 497
498 498 kwargs = {}
499 499 kwargs['form'] = form
500 500 kwargs['title'] = 'Campaign'
501 501 kwargs['suptitle'] = 'Edit'
502 502 kwargs['button'] = 'Update'
503 503 kwargs['menu_campaigns'] = 'active'
504 504
505 505 return render(request, 'campaign_edit.html', kwargs)
506 506
507 507
508 508 @login_required
509 509 def campaign_delete(request, id_camp):
510 510
511 511 campaign = get_object_or_404(Campaign, pk=id_camp)
512 512
513 513 if request.method == 'POST':
514 514 if is_developer(request.user):
515 515
516 516 for exp in campaign.experiments.all():
517 517 for conf in Configuration.objects.filter(experiment=exp):
518 518 conf.delete()
519 519 exp.delete()
520 520 campaign.delete()
521 521
522 522 return redirect('url_campaigns')
523 523
524 524 messages.error(request, 'Not enough permission to delete this object')
525 525 return redirect(campaign.get_absolute_url())
526 526
527 527 kwargs = {
528 528 'title': 'Delete',
529 529 'suptitle': 'Campaign',
530 530 'object': campaign,
531 531 'delete': True
532 532 }
533 533 kwargs['menu_campaigns'] = 'active'
534 534
535 535 return render(request, 'confirm.html', kwargs)
536 536
537 537
538 538 @login_required
539 539 def campaign_export(request, id_camp):
540 540
541 541 campaign = get_object_or_404(Campaign, pk=id_camp)
542 542 content = campaign.parms_to_dict()
543 543 content_type = 'application/json'
544 544 filename = '%s_%s.json' % (campaign.name, campaign.id)
545 545
546 546 response = HttpResponse(content_type=content_type)
547 547 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
548 548 response.write(json.dumps(content, indent=2))
549 549
550 550 return response
551 551
552 552
553 553 @login_required
554 554 def campaign_import(request, id_camp):
555 555
556 556 campaign = get_object_or_404(Campaign, pk=id_camp)
557 557
558 558 if request.method == 'GET':
559 559 file_form = UploadFileForm()
560 560
561 561 if request.method == 'POST':
562 562 file_form = UploadFileForm(request.POST, request.FILES)
563 563
564 564 if file_form.is_valid():
565 565 new_camp = campaign.dict_to_parms(
566 566 json.load(request.FILES['file']), CONF_MODELS)
567 567 messages.success(
568 568 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
569 569 return redirect(new_camp.get_absolute_url_edit())
570 570
571 571 messages.error(request, "Could not import parameters from file")
572 572
573 573 kwargs = {}
574 574 kwargs['title'] = 'Campaign'
575 575 kwargs['form'] = file_form
576 576 kwargs['suptitle'] = 'Importing file'
577 577 kwargs['button'] = 'Import'
578 578 kwargs['menu_campaigns'] = 'active'
579 579
580 580 return render(request, 'campaign_import.html', kwargs)
581 581
582 582
583 583 def experiments(request):
584 584
585 585 page = request.GET.get('page')
586 586 order = ('location',)
587 587 filters = request.GET.copy()
588 588
589 589 if 'my experiments' in filters:
590 590 filters.pop('my experiments', None)
591 591 filters['mine'] = request.user.id
592 592
593 593 kwargs = get_paginator(Experiment, page, order, filters)
594 594
595 595 fields = ['tags', 'template']
596 596 if request.user.is_authenticated:
597 597 fields.append('my experiments')
598 598
599 599 form = FilterForm(initial=request.GET, extra_fields=fields)
600 600
601 601 kwargs['keys'] = ['name', 'radar_system',
602 602 'start_time', 'end_time', 'actions']
603 603 kwargs['title'] = 'Experiment'
604 604 kwargs['suptitle'] = 'List'
605 605 kwargs['no_sidebar'] = True
606 606 kwargs['form'] = form
607 607 kwargs['add_url'] = reverse('url_add_experiment')
608 608 filters = request.GET.copy()
609 609 filters.pop('page', None)
610 610 kwargs['q'] = urlencode(filters)
611 611 kwargs['menu_experiments'] = 'active'
612 612
613 613 return render(request, 'base_list.html', kwargs)
614 614
615 615
616 616 def experiment(request, id_exp):
617 617
618 618 experiment = get_object_or_404(Experiment, pk=id_exp)
619 619
620 620 configurations = Configuration.objects.filter(
621 621 experiment=experiment, type=0)
622 622
623 623 kwargs = {}
624 624
625 625 kwargs['experiment_keys'] = ['template', 'radar_system',
626 626 'name', 'freq', 'start_time', 'end_time']
627 627 kwargs['experiment'] = experiment
628 628 kwargs['configuration_keys'] = ['name', 'device__ip_address',
629 629 'device__port_address', 'device__status']
630 630 kwargs['configurations'] = configurations
631 631 kwargs['title'] = 'Experiment'
632 632 kwargs['suptitle'] = 'Details'
633 633 kwargs['button'] = 'Add Configuration'
634 634 kwargs['menu_experiments'] = 'active'
635 635
636 636 ###### SIDEBAR ######
637 637 kwargs.update(sidebar(experiment=experiment))
638 638
639 639 return render(request, 'experiment.html', kwargs)
640 640
641 641
642 642 @login_required
643 643 def experiment_new(request, id_camp=None):
644 644
645 645 if not is_developer(request.user):
646 646 messages.error(
647 647 request, 'Developer required, to create new Experiments')
648 648 return redirect('index')
649 649 kwargs = {}
650 650
651 651 if request.method == 'GET':
652 652 if 'template' in request.GET:
653 653 if request.GET['template'] == '0':
654 654 form = NewForm(initial={'create_from': 2},
655 655 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
656 656 else:
657 657 kwargs['button'] = 'Create'
658 658 kwargs['configurations'] = Configuration.objects.filter(
659 659 experiment=request.GET['template'])
660 660 kwargs['configuration_keys'] = ['name', 'device__name',
661 661 'device__ip_address', 'device__port_address']
662 662 exp = Experiment.objects.get(pk=request.GET['template'])
663 663 form = ExperimentForm(instance=exp,
664 664 initial={'name': '{}_{:%y%m%d}'.format(exp.name, datetime.now()),
665 665 'template': False})
666 666 elif 'blank' in request.GET:
667 667 kwargs['button'] = 'Create'
668 668 form = ExperimentForm()
669 669 else:
670 670 form = NewForm()
671 671
672 672 if request.method == 'POST':
673 673 form = ExperimentForm(request.POST)
674 674 if form.is_valid():
675 675 experiment = form.save(commit=False)
676 676 experiment.author = request.user
677 677 experiment.save()
678 678
679 679 if 'template' in request.GET:
680 680 configurations = Configuration.objects.filter(
681 681 experiment=request.GET['template'], type=0)
682 682 for conf in configurations:
683 683 conf.clone(experiment=experiment, template=False)
684 684
685 685 return redirect('url_experiment', id_exp=experiment.id)
686 686
687 687 kwargs['form'] = form
688 688 kwargs['title'] = 'Experiment'
689 689 kwargs['suptitle'] = 'New'
690 690 kwargs['menu_experiments'] = 'active'
691 691
692 692 return render(request, 'experiment_edit.html', kwargs)
693 693
694 694
695 695 @login_required
696 696 def experiment_edit(request, id_exp):
697 697
698 698 experiment = get_object_or_404(Experiment, pk=id_exp)
699 699
700 700 if request.method == 'GET':
701 701 form = ExperimentForm(instance=experiment)
702 702
703 703 if request.method == 'POST':
704 704 form = ExperimentForm(request.POST, instance=experiment)
705 705
706 706 if form.is_valid():
707 707 experiment = form.save()
708 708 return redirect('url_experiment', id_exp=experiment.id)
709 709
710 710 kwargs = {}
711 711 kwargs['form'] = form
712 712 kwargs['title'] = 'Experiment'
713 713 kwargs['suptitle'] = 'Edit'
714 714 kwargs['button'] = 'Update'
715 715 kwargs['menu_experiments'] = 'active'
716 716
717 717 return render(request, 'experiment_edit.html', kwargs)
718 718
719 719
720 720 @login_required
721 721 def experiment_delete(request, id_exp):
722 722
723 723 experiment = get_object_or_404(Experiment, pk=id_exp)
724 724
725 725 if request.method == 'POST':
726 726 if is_developer(request.user):
727 727 for conf in Configuration.objects.filter(experiment=experiment):
728 728 conf.delete()
729 729 experiment.delete()
730 730 return redirect('url_experiments')
731 731
732 732 messages.error(request, 'Not enough permission to delete this object')
733 733 return redirect(experiment.get_absolute_url())
734 734
735 735 kwargs = {
736 736 'title': 'Delete',
737 737 'suptitle': 'Experiment',
738 738 'object': experiment,
739 739 'delete': True
740 740 }
741 741
742 742 return render(request, 'confirm.html', kwargs)
743 743
744 744
745 745 @login_required
746 746 def experiment_export(request, id_exp):
747 747
748 748 experiment = get_object_or_404(Experiment, pk=id_exp)
749 749 content = experiment.parms_to_dict()
750 750 content_type = 'application/json'
751 751 filename = '%s_%s.json' % (experiment.name, experiment.id)
752 752
753 753 response = HttpResponse(content_type=content_type)
754 754 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
755 755 response.write(json.dumps(content, indent=2))
756 756
757 757 return response
758 758
759 759
760 760 @login_required
761 761 def experiment_import(request, id_exp):
762 762
763 763 experiment = get_object_or_404(Experiment, pk=id_exp)
764 764 configurations = Configuration.objects.filter(experiment=experiment)
765 765
766 766 if request.method == 'GET':
767 767 file_form = UploadFileForm()
768 768
769 769 if request.method == 'POST':
770 770 file_form = UploadFileForm(request.POST, request.FILES)
771 771
772 772 if file_form.is_valid():
773 773 new_exp = experiment.dict_to_parms(
774 774 json.load(request.FILES['file']), CONF_MODELS)
775 775 messages.success(
776 776 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
777 777 return redirect(new_exp.get_absolute_url_edit())
778 778
779 779 messages.error(request, "Could not import parameters from file")
780 780
781 781 kwargs = {}
782 782 kwargs['title'] = 'Experiment'
783 783 kwargs['form'] = file_form
784 784 kwargs['suptitle'] = 'Importing file'
785 785 kwargs['button'] = 'Import'
786 786 kwargs['menu_experiments'] = 'active'
787 787
788 788 kwargs.update(sidebar(experiment=experiment))
789 789
790 790 return render(request, 'experiment_import.html', kwargs)
791 791
792 792
793 793 @login_required
794 794 def experiment_start(request, id_exp):
795 795
796 796 exp = get_object_or_404(Experiment, pk=id_exp)
797 797
798 798 if exp.status == 2:
799 799 messages.warning(request, 'Experiment {} already runnnig'.format(exp))
800 800 else:
801 801 exp.status = exp.start()
802 802 if exp.status == 0:
803 803 messages.error(request, 'Experiment {} not start'.format(exp))
804 804 if exp.status == 2:
805 805 messages.success(request, 'Experiment {} started'.format(exp))
806 806
807 807 exp.save()
808 808
809 809 return redirect(exp.get_absolute_url())
810 810
811 811
812 812 @login_required
813 813 def experiment_stop(request, id_exp):
814 814
815 815 exp = get_object_or_404(Experiment, pk=id_exp)
816 816
817 817 if exp.status == 2:
818 818 exp.status = exp.stop()
819 819 exp.save()
820 820 messages.success(request, 'Experiment {} stopped'.format(exp))
821 821 else:
822 822 messages.error(request, 'Experiment {} not running'.format(exp))
823 823
824 824 return redirect(exp.get_absolute_url())
825 825
826 826
827 827 def experiment_status(request, id_exp):
828 828
829 829 exp = get_object_or_404(Experiment, pk=id_exp)
830 830
831 831 exp.get_status()
832 832
833 833 return redirect(exp.get_absolute_url())
834 834
835 835
836 836 @login_required
837 837 def experiment_mix(request, id_exp):
838 838
839 839 experiment = get_object_or_404(Experiment, pk=id_exp)
840 840 rc_confs = [conf for conf in RCConfiguration.objects.filter(
841 841 experiment=id_exp,
842 842 type=0,
843 843 mix=False)]
844 844
845 845 if len(rc_confs) < 2:
846 846 messages.warning(
847 847 request, 'You need at least two RC Configurations to make a mix')
848 848 return redirect(experiment.get_absolute_url())
849 849
850 850 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True, type=0)
851 851
852 852 if mix_confs:
853 853 mix = mix_confs[0]
854 854 else:
855 855 mix = RCConfiguration(experiment=experiment,
856 856 device=rc_confs[0].device,
857 857 ipp=rc_confs[0].ipp,
858 858 clock_in=rc_confs[0].clock_in,
859 859 clock_divider=rc_confs[0].clock_divider,
860 860 mix=True,
861 861 parameters='')
862 862 mix.save()
863 863
864 864 line_type = RCLineType.objects.get(name='mix')
865 865 print("VIew obteniendo len getlines")
866 866 print(len(rc_confs[0].get_lines()))
867 867 for i in range(len(rc_confs[0].get_lines())):
868 868 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
869 869 line.save()
870 870
871 871 initial = {'name': mix.name,
872 872 'result': parse_mix_result(mix.parameters),
873 873 'delay': 0,
874 874 'mask': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
875 875 }
876 876
877 877 if request.method == 'GET':
878 878 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
879 879
880 880 if request.method == 'POST':
881 881 result = mix.parameters
882 882
883 883 if '{}|'.format(request.POST['experiment']) in result:
884 884 messages.error(request, 'Configuration already added')
885 885 else:
886 886 if 'operation' in request.POST:
887 887 operation = MIX_OPERATIONS[request.POST['operation']]
888 888 else:
889 889 operation = ' '
890 890
891 891 mode = MIX_MODES[request.POST['mode']]
892 892
893 893 if result:
894 894 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
895 895 request.POST['experiment'],
896 896 mode,
897 897 operation,
898 898 float(
899 899 request.POST['delay']),
900 900 parse_mask(
901 901 request.POST.getlist('mask'))
902 902 )
903 903 else:
904 904 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
905 905 mode,
906 906 operation,
907 907 float(request.POST['delay']),
908 908 parse_mask(
909 909 request.POST.getlist('mask'))
910 910 )
911 911
912 912 mix.parameters = result
913 913 mix.save()
914 914 mix.update_pulses()
915 915
916 916 initial['result'] = parse_mix_result(result)
917 917 initial['name'] = mix.name
918 918
919 919 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
920 920
921 921 kwargs = {
922 922 'title': 'Experiment',
923 923 'suptitle': 'Mix Configurations',
924 924 'form': form,
925 925 'extra_button': 'Delete',
926 926 'button': 'Add',
927 927 'cancel': 'Back',
928 928 'previous': experiment.get_absolute_url(),
929 929 'id_exp': id_exp,
930 930
931 931 }
932 932 kwargs['menu_experiments'] = 'active'
933 933
934 934 return render(request, 'experiment_mix.html', kwargs)
935 935
936 936
937 937 @login_required
938 938 def experiment_mix_delete(request, id_exp):
939 939
940 940 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True, type=0)
941 941 values = conf.parameters.split('-')
942 942 conf.parameters = '-'.join(values[:-1])
943 943 conf.save()
944 944
945 945 return redirect('url_mix_experiment', id_exp=id_exp)
946 946
947 947
948 948 def experiment_summary(request, id_exp):
949 949
950 950 experiment = get_object_or_404(Experiment, pk=id_exp)
951 951 configurations = Configuration.objects.filter(
952 952 experiment=experiment, type=0)
953 953
954 954 kwargs = {}
955 955 kwargs['experiment_keys'] = ['radar_system',
956 956 'name', 'freq', 'start_time', 'end_time']
957 957 kwargs['experiment'] = experiment
958 958 kwargs['configurations'] = []
959 959 kwargs['title'] = 'Experiment Summary'
960 960 kwargs['suptitle'] = 'Details'
961 961 kwargs['button'] = 'Verify Parameters'
962 962
963 963 c_vel = 3.0*(10**8) # m/s
964 964 ope_freq = experiment.freq*(10**6) # 1/s
965 965 radar_lambda = c_vel/ope_freq # m
966 966 kwargs['radar_lambda'] = radar_lambda
967 967
968 968 ipp = None
969 969 nsa = 1
970 970 code_id = 0
971 971 tx_line = {}
972 972
973 973 for configuration in configurations.filter(device__device_type__name = 'rc'):
974 974
975 975 if configuration.mix:
976 976 continue
977 977 conf = {'conf': configuration}
978 978 conf['keys'] = []
979 979 conf['NTxs'] = configuration.ntx
980 980 conf['keys'].append('NTxs')
981 981 ipp = configuration.ipp
982 982 conf['IPP'] = ipp
983 983 conf['keys'].append('IPP')
984 984 lines = configuration.get_lines(line_type__name='tx')
985 985
986 986 for tx_line in lines:
987 987 tx_params = json.loads(tx_line.params)
988 988 conf[tx_line.get_name()] = '{} Km'.format(tx_params['pulse_width'])
989 989 conf['keys'].append(tx_line.get_name())
990 990 delays = tx_params['delays']
991 991 if delays not in ('', '0'):
992 992 n = len(delays.split(','))
993 993 taus = '{} Taus: {}'.format(n, delays)
994 994 else:
995 995 taus = '-'
996 996 conf['Taus ({})'.format(tx_line.get_name())] = taus
997 997 conf['keys'].append('Taus ({})'.format(tx_line.get_name()))
998 998 for code_line in configuration.get_lines(line_type__name='codes'):
999 999 code_params = json.loads(code_line.params)
1000 1000 code_id = code_params['code']
1001 1001 if tx_line.pk == int(code_params['TX_ref']):
1002 1002 conf['Code ({})'.format(tx_line.get_name())] = '{}:{}'.format(RCLineCode.objects.get(pk=code_params['code']),
1003 1003 '-'.join(code_params['codes']))
1004 1004 conf['keys'].append('Code ({})'.format(tx_line.get_name()))
1005 1005
1006 1006 for windows_line in configuration.get_lines(line_type__name='windows'):
1007 1007 win_params = json.loads(windows_line.params)
1008 1008 if tx_line.pk == int(win_params['TX_ref']):
1009 1009 windows = ''
1010 1010 nsa = win_params['params'][0]['number_of_samples']
1011 1011 for i, params in enumerate(win_params['params']):
1012 1012 windows += 'W{}: Ho={first_height} km DH={resolution} km NSA={number_of_samples}<br>'.format(
1013 1013 i, **params)
1014 1014 conf['Window'] = mark_safe(windows)
1015 1015 conf['keys'].append('Window')
1016 1016
1017 1017 kwargs['configurations'].append(conf)
1018 1018
1019 1019 for configuration in configurations.filter(device__device_type__name = 'jars'):
1020 1020
1021 1021 conf = {'conf': configuration}
1022 1022 conf['keys'] = []
1023 1023 conf['Type of Data'] = EXPERIMENT_TYPE[configuration.exp_type][1]
1024 1024 conf['keys'].append('Type of Data')
1025 1025 channels_number = configuration.channels_number
1026 1026 exp_type = configuration.exp_type
1027 1027 fftpoints = configuration.fftpoints
1028 1028 filter_parms = json.loads(configuration.filter_parms)
1029 1029 spectral_number = configuration.spectral_number
1030 1030 acq_profiles = configuration.acq_profiles
1031 1031 cohe_integr = configuration.cohe_integr
1032 1032 profiles_block = configuration.profiles_block
1033 1033
1034 1034 conf['Num of Profiles'] = acq_profiles
1035 1035 conf['keys'].append('Num of Profiles')
1036 1036
1037 1037 conf['Prof per Block'] = profiles_block
1038 1038 conf['keys'].append('Prof per Block')
1039 1039
1040 1040 conf['Blocks per File'] = configuration.raw_data_blocks
1041 1041 conf['keys'].append('Blocks per File')
1042 1042
1043 1043 if exp_type == 0: # Short
1044 1044 bytes_ = 2
1045 1045 b = nsa*2*bytes_*channels_number
1046 1046 else: # Float
1047 1047 bytes_ = 4
1048 1048 channels = channels_number + spectral_number
1049 1049 b = nsa*2*bytes_*fftpoints*channels
1050 1050
1051 1051 codes_num = 7
1052 1052 if code_id == 2:
1053 1053 codes_num = 7
1054 1054 elif code_id == 12:
1055 1055 codes_num = 15
1056 1056
1057 1057 #Jars filter values:
1058 1058
1059 1059 clock = float(filter_parms['clock'])
1060 1060 filter_2 = int(filter_parms['cic_2'])
1061 1061 filter_5 = int(filter_parms['cic_5'])
1062 1062 filter_fir = int(filter_parms['fir'])
1063 1063 Fs_MHz = clock/(filter_2*filter_5*filter_fir)
1064 1064
1065 1065 #Jars values:
1066 1066 if ipp is not None:
1067 1067 IPP_units = ipp/0.15*Fs_MHz
1068 1068 IPP_us = IPP_units / Fs_MHz
1069 1069 IPP_s = IPP_units / (Fs_MHz * (10**6))
1070 1070 Ts = 1/(Fs_MHz*(10**6))
1071 1071
1072 1072 Va = radar_lambda/(4*Ts*cohe_integr)
1073 1073 rate_bh = ((nsa-codes_num)*channels_number*2 *
1074 1074 bytes_/IPP_us)*(36*(10**8)/cohe_integr)
1075 1075 rate_gh = rate_bh/(1024*1024*1024)
1076 1076
1077 1077 conf['Time per Block'] = IPP_s * profiles_block * cohe_integr
1078 1078 conf['keys'].append('Time per Block')
1079 1079 conf['Acq time'] = IPP_s * acq_profiles
1080 1080 conf['keys'].append('Acq time')
1081 1081 conf['Data rate'] = str(rate_gh)+" (GB/h)"
1082 1082 conf['keys'].append('Data rate')
1083 1083 conf['Va (m/s)'] = Va
1084 1084 conf['keys'].append('Va (m/s)')
1085 1085 conf['Vrange (m/s)'] = 3/(2*IPP_s*cohe_integr)
1086 1086 conf['keys'].append('Vrange (m/s)')
1087 1087
1088 1088 kwargs['configurations'].append(conf)
1089 1089 kwargs['menu_experiments'] = 'active'
1090 1090
1091 1091 ###### SIDEBAR ######
1092 1092 kwargs.update(sidebar(experiment=experiment))
1093 1093
1094 1094 return render(request, 'experiment_summary.html', kwargs)
1095 1095
1096 1096
1097 1097 @login_required
1098 1098 def experiment_verify(request, id_exp):
1099 1099
1100 1100 experiment = get_object_or_404(Experiment, pk=id_exp)
1101 1101 experiment_data = experiment.parms_to_dict()
1102 1102 configurations = Configuration.objects.filter(
1103 1103 experiment=experiment, type=0)
1104 1104
1105 1105 kwargs = {}
1106 1106
1107 1107 kwargs['experiment_keys'] = ['template',
1108 1108 'radar_system', 'name', 'start_time', 'end_time']
1109 1109 kwargs['experiment'] = experiment
1110 1110
1111 1111 kwargs['configuration_keys'] = ['name', 'device__ip_address',
1112 1112 'device__port_address', 'device__status']
1113 1113 kwargs['configurations'] = configurations
1114 1114 kwargs['experiment_data'] = experiment_data
1115 1115
1116 1116 kwargs['title'] = 'Verify Experiment'
1117 1117 kwargs['suptitle'] = 'Parameters'
1118 1118
1119 1119 kwargs['button'] = 'Update'
1120 1120
1121 1121 jars_conf = False
1122 1122 rc_conf = False
1123 1123 dds_conf = False
1124 1124
1125 1125 for configuration in configurations:
1126 1126 #-------------------- JARS -----------------------:
1127 1127 if configuration.device.device_type.name == 'jars':
1128 1128 jars_conf = True
1129 1129 jars = configuration
1130 1130 kwargs['jars_conf'] = jars_conf
1131 1131 filter_parms = json.loads(jars.filter_parms)
1132 1132 kwargs['filter_parms'] = filter_parms
1133 1133 #--Sampling Frequency
1134 1134 clock = filter_parms['clock']
1135 1135 filter_2 = filter_parms['cic_2']
1136 1136 filter_5 = filter_parms['cic_5']
1137 1137 filter_fir = filter_parms['fir']
1138 1138 samp_freq_jars = clock/filter_2/filter_5/filter_fir
1139 1139
1140 1140 kwargs['samp_freq_jars'] = samp_freq_jars
1141 1141 kwargs['jars'] = configuration
1142 1142
1143 1143 #--------------------- RC ----------------------:
1144 1144 if configuration.device.device_type.name == 'rc' and not configuration.mix:
1145 1145 rc_conf = True
1146 1146 rc = configuration
1147 1147
1148 1148 rc_parms = configuration.parms_to_dict()
1149 1149
1150 1150 win_lines = rc.get_lines(line_type__name='windows')
1151 1151 if win_lines:
1152 1152 dh = json.loads(win_lines[0].params)['params'][0]['resolution']
1153 1153 #--Sampling Frequency
1154 1154 samp_freq_rc = 0.15/dh
1155 1155 kwargs['samp_freq_rc'] = samp_freq_rc
1156 1156
1157 1157 kwargs['rc_conf'] = rc_conf
1158 1158 kwargs['rc'] = configuration
1159 1159
1160 1160 #-------------------- DDS ----------------------:
1161 1161 if configuration.device.device_type.name == 'dds':
1162 1162 dds_conf = True
1163 1163 dds = configuration
1164 1164 dds_parms = configuration.parms_to_dict()
1165 1165
1166 1166 kwargs['dds_conf'] = dds_conf
1167 1167 kwargs['dds'] = configuration
1168 1168
1169 1169 #------------Validation------------:
1170 1170 #Clock
1171 1171 if dds_conf and rc_conf and jars_conf:
1172 1172 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) and float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1173 1173 messages.warning(request, "Devices don't have the same clock.")
1174 1174 elif rc_conf and jars_conf:
1175 1175 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']):
1176 1176 messages.warning(request, "Devices don't have the same clock.")
1177 1177 elif rc_conf and dds_conf:
1178 1178 if float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1179 1179 messages.warning(request, "Devices don't have the same clock.")
1180 1180 if float(samp_freq_rc) != float(dds_parms['configurations']['byId'][str(dds.pk)]['frequencyA']):
1181 1181 messages.warning(
1182 1182 request, "Devices don't have the same Frequency A.")
1183 1183
1184 1184 #------------POST METHOD------------:
1185 1185 if request.method == 'POST':
1186 1186 if request.POST['suggest_clock']:
1187 1187 try:
1188 1188 suggest_clock = float(request.POST['suggest_clock'])
1189 1189 except:
1190 1190 messages.warning(request, "Invalid value in CLOCK IN.")
1191 1191 return redirect('url_verify_experiment', id_exp=experiment.id)
1192 1192 else:
1193 1193 suggest_clock = ""
1194 1194 if suggest_clock:
1195 1195 if rc_conf:
1196 1196 rc.clock_in = suggest_clock
1197 1197 rc.save()
1198 1198 if jars_conf:
1199 1199 filter_parms = jars.filter_parms
1200 1200 filter_parms = ast.literal_eval(filter_parms)
1201 1201 filter_parms['clock'] = suggest_clock
1202 1202 jars.filter_parms = json.dumps(filter_parms)
1203 1203 jars.save()
1204 1204 kwargs['filter_parms'] = filter_parms
1205 1205 if dds_conf:
1206 1206 dds.clock = suggest_clock
1207 1207 dds.save()
1208 1208
1209 1209 if request.POST['suggest_frequencyA']:
1210 1210 try:
1211 1211 suggest_frequencyA = float(request.POST['suggest_frequencyA'])
1212 1212 except:
1213 1213 messages.warning(request, "Invalid value in FREQUENCY A.")
1214 1214 return redirect('url_verify_experiment', id_exp=experiment.id)
1215 1215 else:
1216 1216 suggest_frequencyA = ""
1217 1217 if suggest_frequencyA:
1218 1218 if jars_conf:
1219 1219 filter_parms = jars.filter_parms
1220 1220 filter_parms = ast.literal_eval(filter_parms)
1221 1221 filter_parms['fch'] = suggest_frequencyA
1222 1222 jars.filter_parms = json.dumps(filter_parms)
1223 1223 jars.save()
1224 1224 kwargs['filter_parms'] = filter_parms
1225 1225 if dds_conf:
1226 1226 dds.frequencyA_Mhz = request.POST['suggest_frequencyA']
1227 1227 dds.save()
1228 1228
1229 1229 kwargs['menu_experiments'] = 'active'
1230 1230 kwargs.update(sidebar(experiment=experiment))
1231 1231 return render(request, 'experiment_verify.html', kwargs)
1232 1232
1233 1233
1234 1234 def parse_mix_result(s):
1235 1235
1236 1236 values = s.split('-')
1237 1237 html = 'EXP MOD OPE DELAY MASK\r\n'
1238 1238
1239 1239 if not values or values[0] in ('', ' '):
1240 1240 return mark_safe(html)
1241 1241
1242 1242 for i, value in enumerate(values):
1243 1243 if not value:
1244 1244 continue
1245 1245 pk, mode, operation, delay, mask = value.split('|')
1246 1246 conf = RCConfiguration.objects.get(pk=pk)
1247 1247 if i == 0:
1248 1248 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1249 1249 conf.name,
1250 1250 mode,
1251 1251 ' ',
1252 1252 delay,
1253 1253 mask)
1254 1254 else:
1255 1255 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1256 1256 conf.name,
1257 1257 mode,
1258 1258 operation,
1259 1259 delay,
1260 1260 mask)
1261 1261
1262 1262 return mark_safe(html)
1263 1263
1264 1264
1265 1265 def parse_mask(l):
1266 1266
1267 1267 values = []
1268 1268
1269 1269 for x in range(16):
1270 1270 if '{}'.format(x) in l:
1271 1271 values.append(1)
1272 1272 else:
1273 1273 values.append(0)
1274 1274
1275 1275 values.reverse()
1276 1276
1277 1277 return int(''.join([str(x) for x in values]), 2)
1278 1278
1279 1279
1280 1280 def dev_confs(request):
1281 1281
1282 1282 page = request.GET.get('page')
1283 1283 order = ('-programmed_date', )
1284 1284 filters = request.GET.copy()
1285 1285 if 'my configurations' in filters:
1286 1286 filters.pop('my configurations', None)
1287 1287 filters['mine'] = request.user.id
1288 1288 kwargs = get_paginator(Configuration, page, order, filters)
1289 1289 fields = ['tags', 'template', 'historical']
1290 1290 if request.user.is_authenticated:
1291 1291 fields.append('my configurations')
1292 1292 form = FilterForm(initial=request.GET, extra_fields=fields)
1293 1293 kwargs['keys'] = ['name', 'experiment',
1294 1294 'type', 'programmed_date', 'actions']
1295 1295 kwargs['title'] = 'Configuration'
1296 1296 kwargs['suptitle'] = 'List'
1297 1297 kwargs['no_sidebar'] = True
1298 1298 kwargs['form'] = form
1299 1299 kwargs['add_url'] = reverse('url_add_dev_conf', args=[0])
1300 1300 filters = request.GET.copy()
1301 1301 filters.pop('page', None)
1302 1302 kwargs['q'] = urlencode(filters)
1303 1303 kwargs['menu_configurations'] = 'active'
1304 1304
1305 1305 return render(request, 'base_list.html', kwargs)
1306 1306
1307 1307
1308 1308 def dev_conf(request, id_conf):
1309 1309
1310 1310 conf = get_object_or_404(Configuration, pk=id_conf)
1311 1311
1312 1312 return redirect(conf.get_absolute_url())
1313 1313
1314 1314
1315 1315 @login_required
1316 1316 def dev_conf_new(request, id_exp=0, id_dev=0):
1317 1317
1318 1318 if not is_developer(request.user):
1319 1319 messages.error(
1320 1320 request, 'Developer required, to create new configurations')
1321 1321 return redirect('index')
1322 1322
1323 1323 initial = {}
1324 1324 kwargs = {}
1325 1325
1326 1326 if id_exp != 0:
1327 1327 initial['experiment'] = id_exp
1328 1328
1329 1329 if id_dev != 0:
1330 1330 initial['device'] = id_dev
1331 1331
1332 1332 if request.method == 'GET':
1333 1333
1334 1334 if id_dev:
1335 1335 kwargs['button'] = 'Create'
1336 1336 device = Device.objects.get(pk=id_dev)
1337 1337 DevConfForm = CONF_FORMS[device.device_type.name]
1338 1338 initial['name'] = request.GET['name']
1339 1339 form = DevConfForm(initial=initial)
1340 1340 else:
1341 1341 if 'template' in request.GET:
1342 1342 if request.GET['template'] == '0':
1343 1343 choices = [(conf.pk, '{}'.format(conf))
1344 1344 for conf in Configuration.objects.filter(template=True)]
1345 1345 form = NewForm(initial={'create_from': 2},
1346 1346 template_choices=choices)
1347 1347 else:
1348 1348 kwargs['button'] = 'Create'
1349 1349 conf = Configuration.objects.get(
1350 1350 pk=request.GET['template'])
1351 1351 id_dev = conf.device.pk
1352 1352 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1353 1353 form = DevConfForm(instance=conf,
1354 1354 initial={'name': '{}_{:%y%m%d}'.format(conf.name, datetime.now()),
1355 1355 'template': False,
1356 1356 'experiment': id_exp})
1357 1357 elif 'blank' in request.GET:
1358 1358 kwargs['button'] = 'Create'
1359 1359 form = ConfigurationForm(initial=initial)
1360 1360 else:
1361 1361 form = NewForm()
1362 1362
1363 1363 if request.method == 'POST':
1364 1364
1365 1365 device = Device.objects.get(pk=request.POST['device'])
1366 1366 DevConfForm = CONF_FORMS[device.device_type.name]
1367 1367
1368 1368 form = DevConfForm(request.POST)
1369 1369 kwargs['button'] = 'Create'
1370 1370 if form.is_valid():
1371 1371 conf = form.save(commit=False)
1372 1372 conf.author = request.user
1373 1373 conf.save()
1374 1374
1375 1375 if 'template' in request.GET and conf.device.device_type.name == 'rc':
1376 1376 lines = RCLine.objects.filter(
1377 1377 rc_configuration=request.GET['template'])
1378 1378 for line in lines:
1379 1379 line.clone(rc_configuration=conf)
1380 1380
1381 1381 new_lines = conf.get_lines()
1382 1382 for line in new_lines:
1383 1383 line_params = json.loads(line.params)
1384 1384 if 'TX_ref' in line_params:
1385 1385 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
1386 1386 line_params['TX_ref'] = ['{}'.format(
1387 1387 l.pk) for l in new_lines if l.get_name() == ref_line.get_name()][0]
1388 1388 line.params = json.dumps(line_params)
1389 1389 line.save()
1390 1390 elif conf.device.device_type.name == 'rc':
1391 1391 clk = RCClock(rc_configuration=conf)
1392 1392 clk.save()
1393 1393
1394 1394 return redirect('url_dev_conf', id_conf=conf.pk)
1395 1395
1396 1396 kwargs['id_exp'] = id_exp
1397 1397 kwargs['form'] = form
1398 1398 kwargs['title'] = 'Configuration'
1399 1399 kwargs['suptitle'] = 'New'
1400 1400 kwargs['menu_configurations'] = 'active'
1401 1401
1402 1402 if id_dev != 0:
1403 1403 device = Device.objects.get(pk=id_dev)
1404 1404 kwargs['device'] = device.device_type.name
1405 1405 print(id_exp)
1406 1406 return render(request, 'dev_conf_edit.html', kwargs)
1407 1407
1408 1408
1409 1409 @login_required
1410 1410 def dev_conf_edit(request, id_conf):
1411 1411
1412 1412 conf = get_object_or_404(Configuration, pk=id_conf)
1413 1413
1414 1414 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1415 1415
1416 1416 if request.method == 'GET':
1417 1417 form = DevConfForm(instance=conf)
1418 1418
1419 1419 if request.method == 'POST':
1420 1420 form = DevConfForm(request.POST, instance=conf)
1421 1421
1422 1422 if form.is_valid():
1423 1423 form.save()
1424 1424 return redirect('url_dev_conf', id_conf=id_conf)
1425 1425
1426 1426 kwargs = {}
1427 1427 kwargs['form'] = form
1428 1428 kwargs['title'] = 'Device Configuration'
1429 1429 kwargs['suptitle'] = 'Edit'
1430 1430 kwargs['button'] = 'Update'
1431 1431 kwargs['menu_configurations'] = 'active'
1432 1432
1433 1433 ###### SIDEBAR ######
1434 1434 kwargs.update(sidebar(conf=conf))
1435 1435
1436 1436 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1437 1437
1438 1438
1439 1439 @login_required
1440 1440 def dev_conf_start(request, id_conf):
1441 1441
1442 1442 conf = get_object_or_404(Configuration, pk=id_conf)
1443 1443
1444 1444 if conf.start_device():
1445 1445 messages.success(request, conf.message)
1446 1446 else:
1447 1447 messages.error(request, conf.message)
1448 1448
1449 1449 #conf.status_device()
1450 1450
1451 1451 return redirect(conf.get_absolute_url())
1452 1452
1453 1453
1454 1454 @login_required
1455 1455 def dev_conf_stop(request, id_conf):
1456 1456
1457 1457 conf = get_object_or_404(Configuration, pk=id_conf)
1458 1458
1459 1459 if conf.stop_device():
1460 1460 messages.success(request, conf.message)
1461 1461 else:
1462 1462 messages.error(request, conf.message)
1463 1463
1464 1464 #conf.status_device()
1465 1465
1466 1466 return redirect(conf.get_absolute_url())
1467 1467
1468 1468 @login_required
1469 1469 def dev_conf_stop_mqtt(request, id_conf):
1470 1470
1471 1471 conf = get_object_or_404(Configuration, pk=id_conf)
1472 1472
1473 1473 if conf.stop_device_mqtt():
1474 1474 messages.success(request, conf.message)
1475 1475 else:
1476 1476 messages.error(request, conf.message)
1477 1477
1478 1478 #conf.status_device()
1479 1479
1480 1480 return redirect(conf.get_absolute_url())
1481 1481
1482 1482 @login_required
1483 1483 def dev_conf_status(request, id_conf):
1484 1484
1485 1485 conf = get_object_or_404(Configuration, pk=id_conf)
1486 1486
1487 1487 conf_active = Configuration.objects.filter(pk=conf.device.conf_active).first()
1488 1488 if conf_active!=conf:
1489 1489 url = '#' if conf_active is None else conf_active.get_absolute_url()
1490 1490 label = 'None' if conf_active is None else conf_active.label
1491 1491 messages.warning(
1492 1492 request,
1493 1493 mark_safe('The current configuration has not been written to device, the active configuration is <a href="{}">{}</a>'.format(
1494 1494 url,
1495 1495 label
1496 1496 ))
1497 1497 )
1498 1498
1499 1499 return redirect(conf.get_absolute_url())
1500 1500
1501 1501 if conf.status_device():
1502 1502 messages.success(request, conf.message)
1503 1503 else:
1504 1504 messages.error(request, conf.message)
1505 1505
1506 1506 return redirect(conf.get_absolute_url())
1507 1507
1508 1508
1509 1509 @login_required
1510 1510 def dev_conf_reset(request, id_conf):
1511 1511
1512 1512 conf = get_object_or_404(Configuration, pk=id_conf)
1513 1513
1514 1514 if conf.reset_device():
1515 1515 messages.success(request, conf.message)
1516 1516 else:
1517 1517 messages.error(request, conf.message)
1518 1518
1519 1519 return redirect(conf.get_absolute_url())
1520 1520
1521 1521
1522 1522 @login_required
1523 1523 def dev_conf_write(request, id_conf):
1524 1524
1525 1525 conf = get_object_or_404(Configuration, pk=id_conf)
1526 1526
1527 1527 if request.method == 'POST':
1528 1528 if conf.write_device():
1529 1529 conf.device.conf_active = conf.pk
1530 1530 conf.device.save()
1531 1531 messages.success(request, conf.message)
1532 1532 if has_been_modified(conf):
1533 1533 conf.clone(type=1, template=False)
1534 1534 else:
1535 1535 messages.error(request, conf.message)
1536 1536
1537 1537 return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1538 1538
1539 1539 kwargs = {
1540 1540 'title': 'Write Configuration',
1541 1541 'suptitle': conf.label,
1542 1542 'message': 'Are you sure yo want to write this {} configuration?'.format(conf.device),
1543 1543 'delete': False
1544 1544 }
1545 1545 kwargs['menu_configurations'] = 'active'
1546 1546
1547 1547 return render(request, 'confirm.html', kwargs)
1548 1548
1549 1549
1550 1550 @login_required
1551 1551 def dev_conf_write_mqtt(request,id_conf):
1552 1552
1553 1553 conf = get_object_or_404(Configuration, pk=id_conf)
1554 1554 beams = ABSBeam.objects.filter(abs_conf=conf)
1555 1555
1556 1556 if request.method == 'POST':
1557 1557 if conf.write_device_mqtt():
1558 1558 conf.device.conf_active = conf.pk
1559 1559 conf.device.save()
1560 1560 messages.success(request, conf.message)
1561 1561 if has_been_modified(conf):
1562 1562 conf.clone(type=1, template=False)
1563 1563 else:
1564 1564 messages.error(request, conf.message)
1565 1565 print("return",flush=True)
1566 1566 #return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1567 1567
1568 1568 module_messages = json.loads(conf.module_messages)
1569 1569 kwargs = {}
1570 1570 kwargs['connected_modules'] = str(conf.connected_modules())+'/64'
1571 1571 kwargs['dev_conf'] = conf
1572 1572
1573 1573 if conf.operation_mode == 0:
1574 1574 kwargs['dev_conf_keys'] = ['label', 'operation_mode']
1575 1575 else:
1576 1576 kwargs['dev_conf_keys'] = ['label', 'operation_mode', 'operation_value']
1577 1577
1578 1578 kwargs['title'] = 'ABS Configuration'
1579 1579 kwargs['suptitle'] = 'Details'
1580 1580 kwargs['button'] = 'Edit Configuration'
1581 1581
1582 1582 if conf.active_beam != 0:
1583 1583 kwargs['active_beam'] = int(conf.active_beam)
1584 1584
1585 1585
1586 1586 kwargs['beams'] = beams
1587 1587 # kwargs['modules_status'] = all_status
1588 1588 # kwargs['color_status'] = color_status
1589 1589
1590 1590
1591 1591 kwargs['module_messages'] = module_messages
1592 1592
1593 1593 ###### SIDEBAR ######
1594 1594 kwargs.update(sidebar(conf=conf))
1595 1595
1596 1596
1597 1597 return render(request, 'abs_conf_mqtt.html',kwargs)
1598 1598
1599 1599 kwargs = {
1600 1600 'title': 'MQTT Write Configuration',
1601 1601 'suptitle': conf.label,
1602 1602 'message': 'Are you sure yo want to write through MQTT this {} configuration?'.format(conf.device),
1603 1603 'delete': False
1604 1604 }
1605 1605 kwargs['menu_configurations'] = 'active'
1606 1606 print("Confirm",flush=True)
1607 1607 return render(request, 'confirm.html', kwargs)
1608 1608
1609 1609
1610 1610 @login_required
1611 1611 def dev_conf_read(request, id_conf):
1612 1612
1613 1613 conf = get_object_or_404(Configuration, pk=id_conf)
1614 1614
1615 1615 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1616 1616
1617 1617 if request.method == 'GET':
1618 1618
1619 1619 parms = conf.read_device()
1620 1620 #conf.status_device()
1621 1621
1622 1622 if not parms:
1623 1623 messages.error(request, conf.message)
1624 1624 return redirect(conf.get_absolute_url())
1625 1625
1626 1626 form = DevConfForm(initial=parms, instance=conf)
1627 1627
1628 1628 if request.method == 'POST':
1629 1629 form = DevConfForm(request.POST, instance=conf)
1630 1630
1631 1631 if form.is_valid():
1632 1632 form.save()
1633 1633 return redirect(conf.get_absolute_url())
1634 1634
1635 1635 messages.error(request, "Parameters could not be saved")
1636 1636
1637 1637 kwargs = {}
1638 1638 kwargs['id_dev'] = conf.id
1639 1639 kwargs['form'] = form
1640 1640 kwargs['title'] = 'Device Configuration'
1641 1641 kwargs['suptitle'] = 'Parameters read from device'
1642 1642 kwargs['button'] = 'Save'
1643 1643
1644 1644 ###### SIDEBAR ######
1645 1645 kwargs.update(sidebar(conf=conf))
1646 1646
1647 1647 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1648 1648
1649 1649
1650 1650 @login_required
1651 1651 def dev_conf_import(request, id_conf):
1652 1652
1653 1653 conf = get_object_or_404(Configuration, pk=id_conf)
1654 1654 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1655 1655
1656 1656 if request.method == 'GET':
1657 1657 file_form = UploadFileForm()
1658 1658
1659 1659 if request.method == 'POST':
1660 1660 file_form = UploadFileForm(request.POST, request.FILES)
1661 1661
1662 1662 if file_form.is_valid():
1663 1663
1664 1664 data = conf.import_from_file(request.FILES['file'])
1665 1665 parms = Params(data=data).get_conf(
1666 1666 dtype=conf.device.device_type.name)
1667 1667
1668 1668 if parms:
1669 1669
1670 1670 form = DevConfForm(initial=parms, instance=conf)
1671 1671
1672 1672 kwargs = {}
1673 1673 kwargs['id_dev'] = conf.id
1674 1674 kwargs['form'] = form
1675 1675 kwargs['title'] = 'Device Configuration'
1676 1676 kwargs['suptitle'] = 'Parameters imported'
1677 1677 kwargs['button'] = 'Save'
1678 1678 kwargs['action'] = conf.get_absolute_url_edit()
1679 1679 kwargs['previous'] = conf.get_absolute_url()
1680 1680
1681 1681 ###### SIDEBAR ######
1682 1682 kwargs.update(sidebar(conf=conf))
1683 1683
1684 1684 messages.success(
1685 1685 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
1686 1686
1687 1687 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1688 1688
1689 1689 messages.error(request, "Could not import parameters from file")
1690 1690
1691 1691 kwargs = {}
1692 1692 kwargs['id_dev'] = conf.id
1693 1693 kwargs['title'] = 'Device Configuration'
1694 1694 kwargs['form'] = file_form
1695 1695 kwargs['suptitle'] = 'Importing file'
1696 1696 kwargs['button'] = 'Import'
1697 1697 kwargs['menu_configurations'] = 'active'
1698 1698
1699 1699 kwargs.update(sidebar(conf=conf))
1700 1700
1701 1701 return render(request, 'dev_conf_import.html', kwargs)
1702 1702
1703 1703
1704 1704 @login_required
1705 1705 def dev_conf_export(request, id_conf):
1706 1706
1707 1707 conf = get_object_or_404(Configuration, pk=id_conf)
1708 1708
1709 1709 if request.method == 'GET':
1710 1710 file_form = DownloadFileForm(conf.device.device_type.name)
1711 1711
1712 1712 if request.method == 'POST':
1713 1713 file_form = DownloadFileForm(
1714 1714 conf.device.device_type.name, request.POST)
1715 1715
1716 1716 if file_form.is_valid():
1717 1717 fields = conf.export_to_file(
1718 1718 format=file_form.cleaned_data['format'])
1719 1719 if not fields['content']:
1720 1720 messages.error(request, conf.message)
1721 1721 return redirect(conf.get_absolute_url_export())
1722 1722 response = HttpResponse(content_type=fields['content_type'])
1723 1723 response['Content-Disposition'] = 'attachment; filename="%s"' % fields['filename']
1724 1724 response.write(fields['content'])
1725 1725
1726 1726 return response
1727 1727
1728 1728 messages.error(request, "Could not export parameters")
1729 1729
1730 1730 kwargs = {}
1731 1731 kwargs['id_dev'] = conf.id
1732 1732 kwargs['title'] = 'Device Configuration'
1733 1733 kwargs['form'] = file_form
1734 1734 kwargs['suptitle'] = 'Exporting file'
1735 1735 kwargs['button'] = 'Export'
1736 1736 kwargs['menu_configurations'] = 'active'
1737 1737
1738 1738 return render(request, 'dev_conf_export.html', kwargs)
1739 1739
1740 1740
1741 1741 @login_required
1742 1742 def dev_conf_delete(request, id_conf):
1743 1743
1744 1744 conf = get_object_or_404(Configuration, pk=id_conf)
1745 1745
1746 1746 if request.method == 'POST':
1747 1747 if is_developer(request.user):
1748 1748 conf.delete()
1749 1749 return redirect('url_dev_confs')
1750 1750
1751 1751 messages.error(request, 'Not enough permission to delete this object')
1752 1752 return redirect(conf.get_absolute_url())
1753 1753
1754 1754 kwargs = {
1755 1755 'title': 'Delete',
1756 1756 'suptitle': 'Configuration',
1757 1757 'object': conf,
1758 1758 'delete': True
1759 1759 }
1760 1760 kwargs['menu_configurations'] = 'active'
1761 1761
1762 1762 return render(request, 'confirm.html', kwargs)
1763 1763
1764 1764
1765 1765 def sidebar(**kwargs):
1766 1766
1767 1767 side_data = {}
1768 1768
1769 1769 conf = kwargs.get('conf', None)
1770 1770 experiment = kwargs.get('experiment', None)
1771 1771
1772 1772 if not experiment:
1773 1773 experiment = conf.experiment
1774 1774
1775 1775 if experiment:
1776 1776 side_data['experiment'] = experiment
1777 1777 campaign = experiment.campaign_set.all()
1778 1778 if campaign:
1779 1779 side_data['campaign'] = campaign[0]
1780 1780 experiments = campaign[0].experiments.all().order_by('name')
1781 1781 else:
1782 1782 experiments = [experiment]
1783 1783 configurations = experiment.configuration_set.filter(type=0)
1784 1784 side_data['side_experiments'] = experiments
1785 1785 side_data['side_configurations'] = configurations.order_by(
1786 1786 'device__device_type__name')
1787 1787
1788 1788 return side_data
1789 1789
1790 1790 def get_paginator(model, page, order, filters={}, n=8):
1791 1791 kwargs = {}
1792 1792 query = Q()
1793 1793 if isinstance(filters, QueryDict):
1794 1794 filters = filters.dict()
1795 1795 copy_filters=filters.copy()
1796 1796 [filters.pop(key) for key in copy_filters.keys() if copy_filters[key] in (' ', ' ')]
1797 1797 filters.pop('page', None)
1798 1798
1799 1799 fields = [f.name for f in model._meta.get_fields()]
1800 1800
1801 1801 if 'template' in copy_filters:
1802 1802 filters['template'] = True
1803 1803 if 'historical' in copy_filters:
1804 1804 filters.pop('historical')
1805 1805 filters['type'] = 1
1806 1806 elif 'type' in fields:
1807 1807 filters['type'] = 0
1808 1808 if 'start_date' in copy_filters:
1809 1809 filters['start_date__gte'] =filters.pop('start_date')
1810 1810 if 'end_date' in copy_filters:
1811 1811 filters['start_date__lte'] =filters.pop('end_date')
1812 1812 if 'tags' in copy_filters:
1813 1813 tags =filters.pop('tags')
1814 1814 if 'tags' in fields:
1815 1815 query = query | Q(tags__icontains=tags)
1816 1816 if 'label' in fields:
1817 1817 query = query | Q(label__icontains=tags)
1818 1818 if 'location' in fields:
1819 1819 query = query | Q(location__name__icontains=tags)
1820 1820 if 'device' in fields:
1821 1821 query = query | Q(device__device_type__name__icontains=tags)
1822 1822 query = query | Q(device__location__name__icontains=tags)
1823 1823 if 'device_type' in fields:
1824 1824 query = query | Q(device_type__name__icontains=tags)
1825 1825
1826 1826 if 'mine' in copy_filters:
1827 1827 filters['author_id'] =filters['mine']
1828 1828 filters.pop('mine')
1829 1829 object_list = model.objects.filter(query, **filters).order_by(*order)
1830 1830 paginator = Paginator(object_list, n)
1831 1831
1832 1832 try:
1833 1833 objects = paginator.page(page)
1834 1834 except PageNotAnInteger:
1835 1835 objects = paginator.page(1)
1836 1836 except EmptyPage:
1837 1837 objects = paginator.page(paginator.num_pages)
1838 1838
1839 1839 kwargs['objects'] = objects
1840 1840 kwargs['offset'] = (int(page)-1)*n if page else 0
1841 1841
1842 1842 return kwargs
1843 1843
1844 1844 # def get_paginator(model, page, order, filters={}, n=8):
1845 1845 # kwargs = {}
1846 1846 # query = Q()
1847 1847 # if isinstance(filters, QueryDict):
1848 1848 # filters = filters.dict()
1849 1849 # [filters.pop(key) for key in filters.keys() if filters[key] in ('', ' ')]
1850 1850 # filters.pop('page', None)
1851 1851
1852 1852 # fields = [f.name for f in model._meta.get_fields()]
1853 1853
1854 1854 # if 'template' in filters:
1855 1855 # filters['template'] = True
1856 1856 # if 'historical' in filters:
1857 1857 # filters.pop('historical')
1858 1858 # filters['type'] = 1
1859 1859 # elif 'type' in fields:
1860 1860 # filters['type'] = 0
1861 1861 # if 'start_date' in filters:
1862 1862 # filters['start_date__gte'] = filters.pop('start_date')
1863 1863 # if 'end_date' in filters:
1864 1864 # filters['start_date__lte'] = filters.pop('end_date')
1865 1865 # if 'tags' in filters:
1866 1866 # tags = filters.pop('tags')
1867 1867 # if 'tags' in fields:
1868 1868 # query = query | Q(tags__icontains=tags)
1869 1869 # if 'label' in fields:
1870 1870 # query = query | Q(label__icontains=tags)
1871 1871 # if 'location' in fields:
1872 1872 # query = query | Q(location__name__icontains=tags)
1873 1873 # if 'device' in fields:
1874 1874 # query = query | Q(device__device_type__name__icontains=tags)
1875 1875 # query = query | Q(device__location__name__icontains=tags)
1876 1876 # if 'device_type' in fields:
1877 1877 # query = query | Q(device_type__name__icontains=tags)
1878 1878
1879 1879 # if 'mine' in filters:
1880 1880 # filters['author_id'] = filters['mine']
1881 1881 # filters.pop('mine')
1882 1882 # object_list = model.objects.filter(query, **filters).order_by(*order)
1883 1883 # paginator = Paginator(object_list, n)
1884 1884
1885 1885 # try:
1886 1886 # objects = paginator.page(page)
1887 1887 # except PageNotAnInteger:
1888 1888 # objects = paginator.page(1)
1889 1889 # except EmptyPage:
1890 1890 # objects = paginator.page(paginator.num_pages)
1891 1891
1892 1892 # kwargs['objects'] = objects
1893 1893 # kwargs['offset'] = (int(page)-1)*n if page else 0
1894 1894
1895 1895 # return kwargs
1896 1896
1897 1897
1898 1898 def operation(request, id_camp=None):
1899 1899
1900 1900 kwargs = {}
1901 1901 kwargs['title'] = 'Radars Operation'
1902 1902 kwargs['no_sidebar'] = True
1903 1903 kwargs['menu_operation'] = 'active'
1904 1904 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1905 1905 end_date__gte=datetime.now()).order_by('-start_date')
1906 1906
1907 1907 if id_camp:
1908 1908 campaign = get_object_or_404(Campaign, pk=id_camp)
1909 1909 form = OperationForm(
1910 1910 initial={'campaign': campaign.id}, campaigns=campaigns)
1911 1911 kwargs['campaign'] = campaign
1912 1912 else:
1913 1913 # form = OperationForm(campaigns=campaigns)
1914 1914 kwargs['campaigns'] = campaigns
1915 1915 return render(request, 'operation.html', kwargs)
1916 1916
1917 1917 #---Experiment
1918 1918 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1919 1919 kwargs['experiment_keys'] = keys[1:]
1920 1920 kwargs['experiments'] = experiments
1921 1921 #---Radar
1922 1922 kwargs['locations'] = campaign.get_experiments_by_radar()
1923 1923 kwargs['form'] = form
1924 1924
1925 1925 return render(request, 'operation.html', kwargs)
1926 1926
1927 1927
1928 1928 @login_required
1929 1929 def radar_start(request, id_camp, id_radar):
1930
1930 print("Boton presionados",flush=True)
1931 1931 campaign = get_object_or_404(Campaign, pk=id_camp)
1932 1932 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1933 1933 now = datetime.now()
1934 1934
1935 1935 for exp in experiments:
1936 1936 #app.control.revoke(exp.task)
1937 1937 print("----------------------")
1938 print("status:->", exp.status)
1938 print("status:->", exp.status,flush=True)
1939 1939 start = datetime.combine(datetime.now().date(), exp.start_time)
1940 1940 end = datetime.combine(datetime.now().date(), exp.end_time)
1941 print("start exp: ",exp.start_time)
1942 print("end exp: ",exp.end_time)
1943
1944 print("start comb: ",start)
1945 print("end comb: ",end)
1946 print(is_aware(start))
1947 print("start camp",campaign.start_date)
1948 print("end camp",campaign.end_date)
1949 print(is_aware(campaign.start_date))
1941 print("start exp: ",exp.start_time,flush=True)
1942 print("end exp: ",exp.end_time,flush=True)
1943
1944 print("start comb: ",start,flush=True)
1945 print("end comb: ",end,flush=True)
1946 print(is_aware(start),flush=True)
1947 print("start camp",campaign.start_date,flush=True)
1948 print("end camp",campaign.end_date,flush=True)
1949 print(is_aware(campaign.start_date),flush=True)
1950 1950 if end < start:
1951 1951 end += timedelta(1)
1952 1952
1953 1953 if exp.status == 2:
1954 1954 messages.warning(
1955 1955 request, 'Experiment {} already running'.format(exp))
1956 1956 #continue
1957 1957
1958 1958 if exp.status == 3:
1959 1959 messages.warning(
1960 1960 request, 'Experiment {} already programmed'.format(exp))
1961 1961 #continue
1962 1962
1963 1963 if exp.status == 1:
1964 1964 messages.warning(
1965 1965 request, 'Experiment {} stopped'.format(exp))
1966 1966 #continue
1967 1967
1968 1968 if start > campaign.end_date:
1969 1969 messages.warning(
1970 1970 request, 'Experiment {} out of date'.format(exp))
1971 1971
1972 1972 #app.control.revoke(exp.task)
1973 print("Llego luego del revoke")
1973 print("Llego luego del revoke",flush=True)
1974 1974 if now >= start and now <= end:
1975 1975
1976 print("Caso now > start and < end -- (1)")
1976 print("Caso now > start and < end -- (1)",flush=True)
1977 1977
1978 1978 # -------------------------------------------
1979 1979
1980 1980 # task = task_start.delay(exp.id)
1981 1981 # exp.task = task.id
1982 1982 # exp.status = task.get()
1983 1983 # -------------------------------------------
1984 1984
1985 1985 #exp.status = task.wait()
1986 1986
1987 1987 if exp.status == 0:
1988 1988 messages.error(request, 'Experiment {} not start'.format(exp))
1989 1989 if exp.status == 2:
1990 1990 messages.success(request, 'Experiment {} started'.format(exp))
1991 1991 elif now < start:
1992 1992 print("Caso now <= start -- (2)",exp.pk)
1993 1993 #task = task_start.apply_async((exp.pk, ), eta=start)#start+timedelta(hours=5))
1994 1994 # task = task_start.apply_async((exp.pk, ), eta=start+timedelta(hours=5))#)
1995 1995 # exp.task = task.id
1996 1996 # exp.status = 3
1997 1997 messages.success(request, 'Experiment {} programmed to start at {}'.format(exp, start))
1998 1998 else:
1999 1999 print("Caso now > end -- (3)")
2000 2000 exp.status = 4
2001 2001 messages.warning(
2002 2002 request, 'Experiment {} out of date'.format(exp))
2003 2003
2004 2004 exp.save()
2005 2005
2006 2006 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2007 2007
2008 2008
2009 2009 @login_required
2010 2010 def radar_stop(request, id_camp, id_radar):
2011 2011
2012 2012 campaign = get_object_or_404(Campaign, pk=id_camp)
2013 2013 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
2014 2014 print("Ingreso en stop radar_stop")
2015 2015 #for exp in experiments:
2016 2016
2017 2017 # if exp.task:
2018 2018 # print("Ingreso antes de revoke stop")
2019 2019 # app.control.revoke(exp.task)
2020 2020
2021 2021
2022 2022 # if exp.status == 2: #status 2 es started
2023 2023 # print("llama a exp.stop")
2024 2024 # exp.stop()
2025 2025 # messages.warning(request, 'Experiment {} stopped'.format(exp))
2026 2026 # exp.status = 1
2027 2027 # exp.save()
2028 2028
2029 2029 #return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2030 2030
2031 2031
2032 2032 @login_required
2033 2033 def radar_refresh(request, id_camp, id_radar):
2034 2034
2035 2035 campaign = get_object_or_404(Campaign, pk=id_camp)
2036 2036 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
2037 2037
2038 2038 i = app.control.inspect()
2039 2039 print("inspect",i)
2040 2040 print(i.scheduled())
2041 2041 print(i.scheduled().values())
2042 2042 scheduled = list(i.scheduled().values())[0]
2043 2043 revoked = list(i.revoked().values())[0]
2044 2044
2045 2045 # for exp in experiments:
2046 2046 # if exp.task in revoked:
2047 2047 # exp.status = 1
2048 2048 # elif exp.task in [t['request']['id'] for t in scheduled if 'task_stop' in t['request']['name']]:
2049 2049 # exp.status = 2
2050 2050 # elif exp.task in [t['request']['id'] for t in scheduled if 'task_start' in t['request']['name']]:
2051 2051 # exp.status = 3
2052 2052 # else:
2053 2053 # exp.status = 4
2054 2054 # exp.save()
2055 2055 # return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2056 2056
2057 2057 #@login_required
2058 2058 # def revoke_tasks(request, id_camp):
2059 2059
2060 2060 # i = app.control.inspect()
2061 2061 # scheduled = list(i.scheduled().values())[0]
2062 2062 # revoked = list(i.revoked().values())[0]
2063 2063
2064 2064 # for t in scheduled:
2065 2065 # if t['request']['id'] in revoked:
2066 2066 # continue
2067 2067 # app.control.revoke(t['request']['id'])
2068 2068 # exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
2069 2069 # eta = t['eta']
2070 2070 # #task = t['request']['name'].split('.')[-1]
2071 2071 # messages.warning(request, 'Scheduled {} at {} for experiment {} revoked'.format(task, eta, exp.name))
2072 2072
2073 2073 # return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2074 2074
2075 2075 # @login_required
2076 2076 # def show_tasks(request, id_camp):
2077 2077
2078 2078 # i = app.control.inspect()
2079 2079 # scheduled = list(i.scheduled().values())[0]
2080 2080 # revoked = list(i.revoked().values())[0]
2081 2081
2082 2082 # for t in scheduled:
2083 2083 # if t['request']['id'] in revoked:
2084 2084 # continue
2085 2085 # exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
2086 2086 # eta = t['eta']
2087 2087 # #task = t['request']['name'].split('.')[-1]
2088 2088 # #messages.success(request, 'Task {} scheduled at {} for experiment {}'.format(task, eta, exp.name))
2089 2089
2090 2090 # return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
2091 2091
2092 2092 def real_time(request):
2093 2093
2094 2094 graphic_path = "/home/fiorella/Pictures/catwbeanie.jpg"
2095 2095
2096 2096 kwargs = {}
2097 2097 kwargs['title'] = 'CLAIRE'
2098 2098 kwargs['suptitle'] = 'Real Time'
2099 2099 kwargs['no_sidebar'] = True
2100 2100 kwargs['graphic_path'] = graphic_path
2101 2101 kwargs['graphic1_path'] = 'http://www.bluemaize.net/im/girls-accessories/shark-beanie-11.jpg'
2102 2102
2103 2103 return render(request, 'real_time.html', kwargs)
2104 2104
2105 2105 def theme(request, theme):
2106 2106
2107 2107 user = request.user
2108 2108 user.profile.theme = theme
2109 2109 user.save()
2110 2110 return redirect('index')
General Comments 0
You need to be logged in to leave comments. Login now