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