##// END OF EJS Templates
Update abs operations
jespinoza -
r313:9bf21dca53e0
parent child
Show More
@@ -1,864 +1,878
1 1 from django.db import models
2 2 from apps.main.models import Configuration
3 3 from django.core.urlresolvers import reverse
4 4 # Create your models here.
5 5 from celery.execute import send_task
6 6 from datetime import datetime
7 7 import ast
8 8 import socket
9 9 import json
10 10 import requests
11 11 import struct
12 12 import sys, time
13 13
14 14 import multiprocessing
15 15
16 16
17 17 antenna_default = json.dumps({
18 18 "antenna_up": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
19 19 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
20 20 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
21 21 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
22 22 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
23 23 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
24 24 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
25 25 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0]
26 26 ]
27 27 ,
28 28 "antenna_down": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
29 29 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
30 30 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
31 31 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
32 32 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
33 33 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
34 34 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
35 35 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0]],
36 36 })
37 37
38 38
39 39 tx_default = json.dumps({
40 40 "up": [[1,1,1,1,0,0,0,0],
41 41 [1,1,1,1,0,0,0,0],
42 42 [1,1,1,1,0,0,0,0],
43 43 [1,1,1,1,0,0,0,0],
44 44 [0,0,0,0,1,1,1,1],
45 45 [0,0,0,0,1,1,1,1],
46 46 [0,0,0,0,1,1,1,1],
47 47 [0,0,0,0,1,1,1,1]],
48 48
49 49 "down": [[1,1,1,1,0,0,0,0],
50 50 [1,1,1,1,0,0,0,0],
51 51 [1,1,1,1,0,0,0,0],
52 52 [1,1,1,1,0,0,0,0],
53 53 [0,0,0,0,1,1,1,1],
54 54 [0,0,0,0,1,1,1,1],
55 55 [0,0,0,0,1,1,1,1],
56 56 [0,0,0,0,1,1,1,1]],
57 57 })
58 58
59 59 rx_default = json.dumps({
60 60 "up": [[1,1,1,1,0,0,0,0],
61 61 [1,1,1,1,0,0,0,0],
62 62 [1,1,1,1,0,0,0,0],
63 63 [1,1,1,1,0,0,0,0],
64 64 [0,0,0,0,1,1,1,1],
65 65 [0,0,0,0,1,1,1,1],
66 66 [0,0,0,0,1,1,1,1],
67 67 [0,0,0,0,1,1,1,1]],
68 68
69 69 "down": [[1,1,1,1,0,0,0,0],
70 70 [1,1,1,1,0,0,0,0],
71 71 [1,1,1,1,0,0,0,0],
72 72 [1,1,1,1,0,0,0,0],
73 73 [0,0,0,0,1,1,1,1],
74 74 [0,0,0,0,1,1,1,1],
75 75 [0,0,0,0,1,1,1,1],
76 76 [0,0,0,0,1,1,1,1]],
77 77 })
78 78
79 79 status_default = '0000000000000000000000000000000000000000000000000000000000000000'
80 80 default_messages = {}
81 81
82 82 for i in range(1,65):
83 83 default_messages[str(i)] = "Module "+str(i)
84 84
85 85
86 86 ues_default = json.dumps({
87 87 "up": [0.533333,0.00000,1.06667,0.00000],
88 88 "down": [0.533333,0.00000,1.06667,0.00000]
89 89 })
90 90
91 91 onlyrx_default = json.dumps({
92 92 "up": False,
93 93 "down": False
94 94 })
95 95
96 96 def up_convertion(cadena):
97 97 valores = []
98 98 for c in cadena:
99 99 if c == 1.0: valores=valores+['000']
100 100 if c == 2.0: valores=valores+['001']
101 101 if c == 3.0: valores=valores+['010']
102 102 if c == 0.0: valores=valores+['011']
103 103 if c == 0.5: valores=valores+['100']
104 104 if c == 1.5: valores=valores+['101']
105 105 if c == 2.5: valores=valores+['110']
106 106 if c == 3.5: valores=valores+['111']
107 107
108 108 return valores
109 109
110 110 def up_conv_bits(value):
111 111
112 112 if value == 1.0: bits="000"
113 113 if value == 2.0: bits="001"
114 114 if value == 3.0: bits="010"
115 115 if value == 0.0: bits="011"
116 116 if value == 0.5: bits="100"
117 117 if value == 1.5: bits="101"
118 118 if value == 2.5: bits="110"
119 119 if value == 3.5: bits="111"
120 120
121 121 return bits
122 122
123 123 def down_convertion(cadena):
124 124 valores = []
125 125 for c in cadena:
126 126 if c == 1.0: valores=valores+['000']
127 127 if c == 2.0: valores=valores+['001']
128 128 if c == 3.0: valores=valores+['010']
129 129 if c == 0.0: valores=valores+['011']
130 130 if c == 0.5: valores=valores+['100']
131 131 if c == 1.5: valores=valores+['101']
132 132 if c == 2.5: valores=valores+['110']
133 133 if c == 3.5: valores=valores+['111']
134 134
135 135 return valores
136 136
137 137 def down_conv_bits(value):
138 138
139 139 if value == 1.0: bits="000"
140 140 if value == 2.0: bits="001"
141 141 if value == 3.0: bits="010"
142 142 if value == 0.0: bits="011"
143 143 if value == 0.5: bits="100"
144 144 if value == 1.5: bits="101"
145 145 if value == 2.5: bits="110"
146 146 if value == 3.5: bits="111"
147 147
148 148 return bits
149 149
150 150 def up_conv_value(bits):
151 151
152 152 if bits == "000": value=1.0
153 153 if bits == "001": value=2.0
154 154 if bits == "010": value=3.0
155 155 if bits == "011": value=0.0
156 156 if bits == "100": value=0.5
157 157 if bits == "101": value=1.5
158 158 if bits == "110": value=2.5
159 159 if bits == "111": value=3.5
160 160
161 161 return value
162 162
163 163 def down_conv_value(bits):
164 164
165 165 if bits == "000": value=1.0
166 166 if bits == "001": value=2.0
167 167 if bits == "010": value=3.0
168 168 if bits == "011": value=0.0
169 169 if bits == "100": value=0.5
170 170 if bits == "101": value=1.5
171 171 if bits == "110": value=2.5
172 172 if bits == "111": value=3.5
173 173
174 174 return value
175 175
176 176 def ip2position(module_number):
177 177 j=0
178 178 i=0
179 179 for x in range(0,module_number-1):
180 180 j=j+1
181 181 if j==8:
182 182 i=i+1
183 183 j=0
184 184
185 185 pos = [i,j]
186 186 return pos
187 187
188 188
189 189 def fromBinary2Char(binary_string):
190 190 number = int(binary_string, 2)
191 191 #Plus 33 to avoid more than 1 characters values such as: '\x01'-'\x1f'
192 192 number = number + 33
193 193 char = chr(number)
194 194 return char
195 195
196 196 def fromChar2Binary(char):
197 197 number = ord(char) - 33
198 198 #Minus 33 to get the real value
199 199 bits = bin(number)[2:]
200 200 #To ensure we have a string with 6bits
201 201 if len(bits) < 6:
202 202 bits = bits.zfill(6)
203 203 return bits
204 204
205 205 OPERATION_MODES = (
206 206 (0, 'Manual'),
207 207 (1, 'Automatic'),
208 208 )
209 209
210 210
211 211 class ABSConfiguration(Configuration):
212 212 active_beam = models.PositiveSmallIntegerField(verbose_name='Active Beam', default=0)
213 213 module_status = models.CharField(verbose_name='Module Status', max_length=10000, default=json.dumps(status_default))
214 214 operation_mode = models.PositiveSmallIntegerField(verbose_name='Operation Mode', choices=OPERATION_MODES, default = 0)
215 215 operation_value = models.FloatField(verbose_name='Periodic (seconds)', default="10", null=True, blank=True)
216 216 module_messages = models.CharField(verbose_name='Modules Messages', max_length=10000, default=json.dumps(default_messages))
217 217
218 218 class Meta:
219 219 db_table = 'abs_configurations'
220 220
221 221 def get_absolute_url_plot(self):
222 222 return reverse('url_plot_abs_patterns', args=[str(self.id)])
223 223
224 224
225 225 def parms_to_dict(self):
226 226
227 227 parameters = {}
228 228
229 229 parameters['device_id'] = self.device.id
230 230 parameters['name'] = self.name
231 231 parameters['device_type'] = self.device.device_type.name
232 232 parameters['beams'] = {}
233 233
234 234 beams = ABSBeam.objects.filter(abs_conf=self)
235 235 b=1
236 236 for beam in beams:
237 237 #absbeam = ABSBeam.objects.get(pk=beams[beam])
238 238 parameters['beams']['beam'+str(b)] = beam.parms_to_dict()#absbeam.parms_to_dict()
239 239 b+=1
240 240
241 241 return parameters
242 242
243 243
244 244 def dict_to_parms(self, parameters):
245 245
246 246 self.name = parameters['name']
247 247
248 248 absbeams = ABSBeam.objects.filter(abs_conf=self)
249 249 beams = parameters['beams']
250 250
251 251 if absbeams:
252 252 beams_number = len(beams)
253 253 absbeams_number = len(absbeams)
254 254 if 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 elif beams_number > absbeams_number:
260 260 i = 1
261 261 for absbeam in absbeams:
262 262 absbeam.dict_to_parms(beams['beam'+str(i)])
263 263 i=i+1
264 264 for x in range(i,beams_number+1):
265 265 new_beam = ABSBeam(
266 266 name =beams['beam'+str(i)]['name'],
267 267 antenna =json.dumps(beams['beam'+str(i)]['antenna']),
268 268 abs_conf = self,
269 269 tx =json.dumps(beams['beam'+str(i)]['tx']),
270 270 rx =json.dumps(beams['beam'+str(i)]['rx']),
271 271 ues =json.dumps(beams['beam'+str(i)]['ues']),
272 272 only_rx =json.dumps(beams['beam'+str(i)]['only_rx'])
273 273 )
274 274 new_beam.save()
275 275 i=i+1
276 276 else: #beams_number < absbeams_number:
277 277 i = 1
278 278 for absbeam in absbeams:
279 279 if i <= beams_number:
280 280 absbeam.dict_to_parms(beams['beam'+str(i)])
281 281 i=i+1
282 282 else:
283 283 absbeam.delete()
284 284 else:
285 285 for beam in beams:
286 286 new_beam = ABSBeam(
287 287 name =beams[beam]['name'],
288 288 antenna =json.dumps(beams[beam]['antenna']),
289 289 abs_conf = self,
290 290 tx =json.dumps(beams[beam]['tx']),
291 291 rx =json.dumps(beams[beam]['rx']),
292 292 ues =json.dumps(beams[beam]['ues']),
293 293 only_rx =json.dumps(beams[beam]['only_rx'])
294 294 )
295 295 new_beam.save()
296 296
297 297
298 298
299 299 def update_from_file(self, parameters):
300 300
301 301 self.dict_to_parms(parameters)
302 302 self.save()
303 303
304 304
305 305 def get_beams(self, **kwargs):
306 306 '''
307 307 This function returns ABS Configuration beams
308 308 '''
309 309 return ABSBeam.objects.filter(abs_conf=self.pk, **kwargs)
310 310
311 311 def clone(self, **kwargs):
312 312
313 313 beams = self.get_beams()
314 314 self.pk = None
315 315 self.id = None
316 316 for attr, value in kwargs.items():
317 317 setattr(self, attr, value)
318 318 self.save()
319 319
320 320 for beam in beams:
321 321 beam.clone(abs_conf=self)
322 322
323 323 #-----For Active Beam-----
324 324 new_beams = ABSBeam.objects.filter(abs_conf=self)
325 325 self.active_beam = new_beams[0].id
326 326 self.save()
327 327 #-----For Active Beam-----
328 328 #-----For Device Status---
329 329 self.device.status = 3
330 330 self.device.save()
331 331 #-----For Device Status---
332 332
333 333 return self
334 334
335 335
336 336 def start_device(self):
337 337
338 338 if self.device.status == 3:
339 339
340 340 try:
341 341 #self.write_device()
342 342 send_task('task_change_beam', [self.id],)
343 343 self.message = 'ABS running'
344 344
345 345 except Exception as e:
346 346 self.message = str(e)
347 347 return False
348 348
349 349 return True
350 350
351 351 else:
352 352 self.message = 'Please, select Write ABS Device first.'
353 353 return False
354 354
355 355
356 356 def stop_device(self):
357 357
358 358 self.device.status = 2
359 359 self.device.save()
360 360 self.message = 'ABS has been stopped.'
361 361 self.save()
362 362
363 363 return True
364 364
365 365
366 366 def write_device(self):
367 367
368 368 """
369 369 This function sends the beams list to every abs module.
370 370 It needs 'module_conf' function
371 371 """
372 372
373 373 beams = ABSBeam.objects.filter(abs_conf=self)
374 374 nbeams = len(beams)
375 375 if self.connected_modules() == 0 :
376 376 self.message = "No ABS Module detected."
377 377 return False
378 378
379 379 #-------------Write each abs module-----------
380
380 381 if beams:
381 message = 'SNDF{:02d}'.format(nbeams)
382 block_id = 0
383 message = 'SNDF{:03d}{:02d}{:02d}'.format(nbeams, nbeams, block_id)
382 384 for i, status in enumerate(self.module_status):
383 385 message += ''.join([fromBinary2Char(beam.module_6bits(i)) for beam in beams])
384 386 status = ['0'] * 64
385 387 n = 0
386 388
387 389 sock = self.send_multicast(message)
388 390
389 for i in range(64):
391 for i in range(32):
390 392 try:
391 393 data, address = sock.recvfrom(1024)
394 print address, data
392 395 if data == '1':
393 396 status[int(address[0][10:])-1] = '3'
394 397 elif data == '0':
395 398 status[int(address[0][10:])-1] = '1'
396 399 except:
397 400 n += 1
398 401 sock.close()
399 402 else:
400 403 self.message = "ABS Configuration does not have beams"
401 404 return False
402 405
403 406 if n == 64:
404 407 self.message = "Could not write ABS Modules"
405 408 self.device.status = 0
406 409 self.module_status = ''.join(status)
407 410 self.save()
408 411 return False
409 412 else:
410 413 self.message = "ABS Beams List have been sent to ABS Modules"
411 beams[0].set_as_activebeam()
414 self.active_beam = beams[0].pk
412 415
413 416 self.device.status = 3
414 417 self.module_status = ''.join(status)
415 418 self.save()
416 419 return True
417 420
418 421
419 422 def read_module(self, module):
420 423
421 424 """
422 425 Read out-bits (up-down) of 1 abs module NOT for Configuration
423 426 """
424 427
425 428 ip_address = self.device.ip_address
426 429 ip_address = ip_address.split('.')
427 430 module_seq = (ip_address[0],ip_address[1],ip_address[2])
428 431 dot = '.'
429 432 module_ip = dot.join(module_seq)+'.'+str(module)
430 433 module_port = self.device.port_address
431 434 read_route = 'http://'+module_ip+':'+str(module_port)+'/read'
432 435
433 436 module_status = json.loads(self.module_status)
434 437 print(read_route)
435 438
436 439 module_bits = ''
437 440
438 441 try:
439 442 r_read = requests.get(read_route, timeout=0.5)
440 443 answer = r_read.json()
441 444 module_bits = answer['allbits']
442 445 except:
443 446 return {}
444 447
445 448 return module_bits
446 449
447 450 def read_device(self):
448 451
449 452 parms = {}
450 453 # Reads active modules.
451 454 module_status = json.loads(self.module_status)
452 455 total = 0
453 456 for status in module_status:
454 457 if module_status[status] != 0:
455 458 module_bits = self.read_module(int(status))
456 459 bits={}
457 460 if module_bits:
458 461 bits = (str(module_bits['um2']) + str(module_bits['um1']) + str(module_bits['um0']) +
459 462 str(module_bits['dm2']) + str(module_bits['dm1']) + str(module_bits['dm0']) )
460 463 parms[str(status)] = bits
461 464
462 465 total +=1
463 466
464 467 if total==0:
465 468 self.message = "No ABS Module detected. Please select 'Status'."
466 469 return False
467 470
468 471
469 472
470 473 self.message = "ABS Modules have been read"
471 474 #monitoreo_tx = JROABSClnt_01CeCnMod000000MNTR10
472 475 return parms
473 476
474 477
475 478 def connected_modules(self):
476 479 """
477 480 This function returns the number of connected abs-modules without updating.
478 481 """
479 482 num = 0
480 483 print(self.module_status)
481 484 for i, status in enumerate(self.module_status):
482 485 if status != '0':
483 486 num += 1
484 print('status {}:{}'.format(i+1, status))
487 #print('status {}:{}'.format(i+1, status))
485 488 return num
486 489
487 490 def send_multicast(self, message):
488 491
489 492 multicast_group = ('224.3.29.71', 10000)
490 493 # Create the datagram socket
491 494 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
492 sock.settimeout(0.01)
493 local_ip = "0.0.0.0"
495 sock.settimeout(0.5)
496 local_ip = "192.168.1.128"
497 sock.bind((local_ip, 10000))
494 498 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip))
495 499 sent = sock.sendto(message, multicast_group)
496 500 print('Sending ' + message)
497 501 return sock
498 502
499 503 def status_device(self):
500 504 """
501 505 This function returns the status of all abs-modules as one.
502 506 If at least one module is connected, its answer is "1"
503 507 """
504 508
505 509 sock = self.send_multicast('MNTR')
506 510
507 511 n = 0
508 512 status = ['0'] * 64
509 for i in range(64):
513 for i in range(32):
514 #if True:
510 515 try:
511 516 data, address = sock.recvfrom(1024)
517 print address, data
512 518 if data == '1':
513 519 status[int(address[0][10:])-1] = '3'
514 520 elif data == '0':
515 521 status[int(address[0][10:])-1] = '1'
516 522 n += 1
517 523 print('Module: {} connected'.format(address))
518 524 except:
525 print('Module: {} error'.format(address))
519 526 pass
520 527 sock.close()
521 528
522 529 if n > 0:
523 530 self.message = 'ABS modules Status have been updated.'
524 531 self.device.status = 1
525 532 else:
526 533 self.device.status = 0
527 534 self.message = 'No ABS module is connected.'
528 535 self.module_status = ''.join(status)
529 536 self.save()
530 537
531 538 return self.device.status
532 539
533 540
534 541 def send_beam(self, beam_pos):
535 542 """
536 543 This function connects to a multicast group and sends the beam number
537 544 to all abs modules.
538 545 """
539 546
540 547 # Se manda a cero RC para poder realizar cambio de beam
548 if self.experiment is None:
549 confs = []
550 else:
541 551 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
542 552 confdds = ''
543 553 confjars = ''
544 554 confrc = ''
545
555 print 'Starting...', self.experiment
546 556 #TO STOP DEVICES: DDS-JARS-RC
547 557 for i in range(0,len(confs)):
558 print i
548 559 if i==0:
549 560 for conf in confs:
550 561 if conf.device.device_type.name == 'dds':
551 562 confdds = conf
552 563 confdds.stop_device()
553 564 break
554 565 if i==1:
555 566 for conf in confs:
556 567 if conf.device.device_type.name == 'jars':
557 568 confjars = conf
558 569 confjars.stop_device()
559 570 break
560 571 if i==2:
561 572 for conf in confs:
573 print conf
562 574 if conf.device.device_type.name == 'rc':
563 575 confrc = conf
564 576 confrc.stop_device()
565 577 break
566
578 print 'Stop devices'
567 579 if beam_pos > 0:
568 580 beam_pos = beam_pos - 1
569 581 else:
570 582 beam_pos = 0
571 583
572 584 #El indice del apunte debe ser menor que el numero total de apuntes
573 585 #El servidor tcp en el embebido comienza a contar desde 0
574 586 status = ['0'] * 64
575 587 message = 'CHGB{}'.format(beam_pos)
588 print 'Before send'
576 589 sock = self.send_multicast(message)
577
578 for i in range(64):
590 print 'Waiting'
591 for i in range(32):
579 592 try:
580 593 data, address = sock.recvfrom(1024)
581 594 print address, data
582 595 if data == '1':
583 596 status[int(address[0][10:])-1] = '3'
584 597 elif data == '0':
585 598 status[int(address[0][10:])-1] = '1'
586 599 except:
587 600 pass
588 601
589 602 sock.close()
590 603
591 604 #Start DDS-RC-JARS
592 605 if confdds:
593 606 confdds.start_device()
594 607 if confrc:
595 608 #print confrc
596 609 confrc.start_device()
597 610 if confjars:
598 611 confjars.start_device()
599 612
600 613 self.message = "ABS Beam has been changed"
601 614 self.module_status = ''.join(status)
602 615 self.save()
603 616 return True
604 617
605 618
606 619 def get_absolute_url_import(self):
607 620 return reverse('url_import_abs_conf', args=[str(self.id)])
608 621
609 622
610 623 class ABSBeam(models.Model):
611 624
612 625 name = models.CharField(max_length=60, default='Beam')
613 626 antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default)
614 627 abs_conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration')
615 628 tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default)
616 629 rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default)
617 630 s_time = models.TimeField(verbose_name='Star Time', default='00:00:00')
618 631 e_time = models.TimeField(verbose_name='End Time', default='23:59:59')
619 632 ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default)
620 633 only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default)
621 634
622 635 class Meta:
623 636 db_table = 'abs_beams'
624 637
625 638 def __unicode__(self):
626 639 return u'%s' % (self.name)
627 640
628 641 def parms_to_dict(self):
629 642
630 643 parameters = {}
631 644 parameters['name'] = self.name
632 645 parameters['antenna'] = ast.literal_eval(self.antenna)
633 646 parameters['abs_conf'] = self.abs_conf.name
634 647 parameters['tx'] = ast.literal_eval(self.tx)
635 648 parameters['rx'] = ast.literal_eval(self.rx)
636 649 parameters['s_time'] = self.s_time.strftime("%H:%M:%S")
637 650 parameters['e_time'] = self.e_time.strftime("%H:%M:%S")
638 651 parameters['ues'] = ast.literal_eval(self.ues)
639 652 parameters['only_rx'] = json.loads(self.only_rx)
640 653
641 654 return parameters
642 655
643 656 def dict_to_parms(self, parameters):
644 657
645 658 self.name = parameters['name']
646 659 self.antenna = json.dumps(parameters['antenna'])
647 660 #self.abs_conf = parameters['abs_conf']
648 661 self.tx = json.dumps(parameters['tx'])
649 662 self.rx = json.dumps(parameters['rx'])
650 663 #self.s_time = parameters['s_time']
651 664 #self.e_time = parameters['e_time']
652 665 self.ues = json.dumps(parameters['ues'])
653 666 self.only_rx = json.dumps(parameters['only_rx'])
654 667 self.save()
655 668
656 669
657 670 def clone(self, **kwargs):
658 671
659 672 self.pk = None
660 673 self.id = None
661 674 for attr, value in kwargs.items():
662 675 setattr(self, attr, value)
663 676
664 677 self.save()
665 678
666 679 return self
667 680
668 681
669 682 def module_6bits(self, module):
670 683 """
671 684 This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module
672 685 """
686 module += 1
673 687 if module > 64:
674 688 beam_bits = ""
675 689 return beam_bits
676 690
677 691 data = ast.literal_eval(self.antenna)
678 692 up_data = data['antenna_up']
679 693 down_data = data['antenna_down']
680 694
681 695 pos = ip2position(module)
682 696 up_value = up_data[pos[0]][pos[1]]
683 697 down_value = down_data[pos[0]][pos[1]]
684 698
685 699 up_bits = up_conv_bits(up_value)
686 700 down_bits = down_conv_bits(down_value)
687 701 beam_bits = up_bits+down_bits
688 702
689 703 return beam_bits
690 704
691 705
692 706 @property
693 707 def get_upvalues(self):
694 708 """
695 709 This function reads antenna pattern and show the up-value of one abs module
696 710 """
697 711
698 712 data = ast.literal_eval(self.antenna)
699 713 up_data = data['antenna_up']
700 714
701 715 up_values = []
702 716 for data in up_data:
703 717 for i in range(0,8):
704 718 up_values.append(data[i])
705 719
706 720 return up_values
707 721
708 722 @property
709 723 def antenna_upvalues(self):
710 724 """
711 725 This function reads antenna pattern and show the up - values of one abs beam
712 726 in a particular order
713 727 """
714 728 data = ast.literal_eval(self.antenna)
715 729 up_data = data['antenna_up']
716 730
717 731 return up_data
718 732
719 733 @property
720 734 def antenna_downvalues(self):
721 735 """
722 736 This function reads antenna pattern and show the down - values of one abs beam
723 737 in a particular order
724 738 """
725 739 data = ast.literal_eval(self.antenna)
726 740 down_data = data['antenna_down']
727 741
728 742 return down_data
729 743
730 744 @property
731 745 def get_downvalues(self):
732 746 """
733 747 This function reads antenna pattern and show the down-value of one abs module
734 748 """
735 749
736 750 data = ast.literal_eval(self.antenna)
737 751 down_data = data['antenna_down']
738 752
739 753 down_values = []
740 754 for data in down_data:
741 755 for i in range(0,8):
742 756 down_values.append(data[i])
743 757
744 758 return down_values
745 759
746 760 @property
747 761 def get_up_ues(self):
748 762 """
749 763 This function shows the up-ues-value of one beam
750 764 """
751 765 data = ast.literal_eval(self.ues)
752 766 up_ues = data['up']
753 767
754 768 return up_ues
755 769
756 770 @property
757 771 def get_down_ues(self):
758 772 """
759 773 This function shows the down-ues-value of one beam
760 774 """
761 775 data = ast.literal_eval(self.ues)
762 776 down_ues = data['down']
763 777
764 778 return down_ues
765 779
766 780 @property
767 781 def get_up_onlyrx(self):
768 782 """
769 783 This function shows the up-onlyrx-value of one beam
770 784 """
771 785 data = json.loads(self.only_rx)
772 786 up_onlyrx = data['up']
773 787
774 788 return up_onlyrx
775 789
776 790 @property
777 791 def get_down_onlyrx(self):
778 792 """
779 793 This function shows the down-onlyrx-value of one beam
780 794 """
781 795 data = json.loads(self.only_rx)
782 796 down_onlyrx = data['down']
783 797
784 798 return down_onlyrx
785 799
786 800 @property
787 801 def get_tx(self):
788 802 """
789 803 This function shows the tx-values of one beam
790 804 """
791 805 data = json.loads(self.tx)
792 806
793 807 return data
794 808
795 809 @property
796 810 def get_uptx(self):
797 811 """
798 812 This function shows the up-tx-values of one beam
799 813 """
800 814 data = json.loads(self.tx)
801 815 up_data = data['up']
802 816
803 817 up_values = []
804 818 for data in up_data:
805 819 for i in range(0,8):
806 820 up_values.append(data[i])
807 821
808 822 return up_values
809 823
810 824 @property
811 825 def get_downtx(self):
812 826 """
813 827 This function shows the down-tx-values of one beam
814 828 """
815 829 data = json.loads(self.tx)
816 830 down_data = data['down']
817 831
818 832 down_values = []
819 833 for data in down_data:
820 834 for i in range(0,8):
821 835 down_values.append(data[i])
822 836
823 837 return down_values
824 838
825 839
826 840
827 841 @property
828 842 def get_rx(self):
829 843 """
830 844 This function shows the rx-values of one beam
831 845 """
832 846 data = json.loads(self.rx)
833 847
834 848 return data
835 849
836 850 @property
837 851 def get_uprx(self):
838 852 """
839 853 This function shows the up-rx-values of one beam
840 854 """
841 855 data = json.loads(self.rx)
842 856 up_data = data['up']
843 857
844 858 up_values = []
845 859 for data in up_data:
846 860 for i in range(0,8):
847 861 up_values.append(data[i])
848 862
849 863 return up_values
850 864
851 865 @property
852 866 def get_downrx(self):
853 867 """
854 868 This function shows the down-rx-values of one beam
855 869 """
856 870 data = json.loads(self.rx)
857 871 down_data = data['down']
858 872
859 873 down_values = []
860 874 for data in down_data:
861 875 for i in range(0,8):
862 876 down_values.append(data[i])
863 877
864 878 return down_values
@@ -1,17 +1,18
1 1 from django.conf.urls import url
2 2
3 3 from apps.abs import views
4 4
5 5 urlpatterns = (
6 6 url(r'^(?P<id_conf>-?\d+)/$', views.abs_conf, name='url_abs_conf'),
7 7 url(r'^(?P<id_conf>-?\d+)/edit/$', views.abs_conf_edit, name='url_edit_abs_conf'),
8 url(r'^alert/$', views.abs_conf_alert, name='url_alert_abs_conf'),
8 9 url(r'^(?P<id_conf>-?\d+)/import/$', views.import_file, name='url_import_abs_conf'),
9 10 #url(r'^(?P<id_conf>-?\d+)/status/', views.abs_conf, {'status_request':True},name='url_status_abs_conf'),
10 11 url(r'^(?P<id_conf>-?\d+)/change_beam/(?P<id_beam>-?\d+)/$', views.send_beam, name='url_send_beam'),
11 12 url(r'^(?P<id_conf>-?\d+)/plot/$', views.plot_patterns, name='url_plot_abs_patterns'),
12 13 url(r'^(?P<id_conf>-?\d+)/plot/(?P<id_beam>-?\d+)/$', views.plot_patterns, name='url_plot_abs_patterns'),
13 14 url(r'^(?P<id_conf>-?\d+)/plot/(?P<id_beam>-?\d+)/(?P<antenna>[\w\-]+)/pattern.png$', views.plot_pattern, name='url_plot_beam'),
14 15 url(r'^(?P<id_conf>-?\d+)/add_beam/$', views.add_beam, name='url_add_abs_beam'),
15 16 url(r'^(?P<id_conf>-?\d+)/beam/(?P<id_beam>-?\d+)/delete/$', views.remove_beam, name='url_remove_abs_beam'),
16 17 url(r'^(?P<id_conf>-?\d+)/beam/(?P<id_beam>-?\d+)/edit/$', views.edit_beam, name='url_edit_abs_beam'),
17 18 )
@@ -1,406 +1,415
1 1 from django.shortcuts import render_to_response
2 2 from django.template import RequestContext
3 3 from django.shortcuts import redirect, render, get_object_or_404
4 4 from django.contrib import messages
5 5 from django.conf import settings
6 6 from django.http import HttpResponse
7 7 from django.core.urlresolvers import reverse
8 from django.views.decorators.csrf import csrf_exempt
8 9
9 10 from datetime import datetime
10 11 from time import sleep
11 12 import os
12 13 import io
13 14
14 15 from apps.main.models import Device, Configuration, Experiment
15 16 from apps.main.views import sidebar
16 17
17 18 from .models import ABSConfiguration, ABSBeam
18 19 from .forms import ABSConfigurationForm, ABSBeamEditForm, ABSBeamAddForm, ABSImportForm
19 20
20 21 from .utils.overJroShow import overJroShow
21 22 from .utils.OverJRO import OverJRO
22 23 # Create your views here.
23 24 import json, ast
24 25
25 26
26 27 def get_values_from_form(form_data):
27 28
28 29 sublistup = []
29 30 sublistdown = []
30 31 subtxlistup = []
31 32 subtxlistdown = []
32 33 subrxlistup = []
33 34 subrxlistdown = []
34 35
35 36 up_values_list = []
36 37 down_values_list = []
37 38 up_txvalues_list = []
38 39 down_txvalues_list = []
39 40 up_rxvalues_list = []
40 41 down_rxvalues_list = []
41 42
42 43 values_list = {}
43 44 cont = 1
44 45
45 46 for i in range(1,65):
46 47 x = float(form_data['abs_up'+str(i)])
47 48 y = float(form_data['abs_down'+str(i)])
48 49 sublistup.append(x)
49 50 sublistdown.append(y)
50 51
51 52 if str(i) in form_data.getlist('uptx_checks'):
52 53 subtxlistup.append(1)
53 54 else:
54 55 subtxlistup.append(0)
55 56 if str(i) in form_data.getlist('downtx_checks'):
56 57 subtxlistdown.append(1)
57 58 else:
58 59 subtxlistdown.append(0)
59 60
60 61 if str(i) in form_data.getlist('uprx_checks'):
61 62 subrxlistup.append(1)
62 63 else:
63 64 subrxlistup.append(0)
64 65 if str(i) in form_data.getlist('downrx_checks'):
65 66 subrxlistdown.append(1)
66 67 else:
67 68 subrxlistdown.append(0)
68 69
69 70 cont = cont+1
70 71
71 72 if cont == 9:
72 73 up_values_list.append(sublistup)
73 74 down_values_list.append(sublistdown)
74 75 sublistup = []
75 76 sublistdown = []
76 77
77 78 up_txvalues_list.append(subtxlistup)
78 79 down_txvalues_list.append(subtxlistdown)
79 80 subtxlistup = []
80 81 subtxlistdown = []
81 82 up_rxvalues_list.append(subrxlistup)
82 83 down_rxvalues_list.append(subrxlistdown)
83 84 subrxlistup = []
84 85 subrxlistdown = []
85 86 cont = 1
86 87
87 88
88 89 list_uesup = []
89 90 list_uesdown = []
90 91 for i in range(1,5):
91 92 if form_data['ues_up'+str(i)] == '':
92 93 list_uesup.append(0.0)
93 94 else:
94 95 list_uesup.append(float(form_data['ues_up'+str(i)]))
95 96
96 97 if form_data['ues_down'+str(i)] == '':
97 98 list_uesdown.append(0.0)
98 99 else:
99 100 list_uesdown.append(float(form_data['ues_down'+str(i)]))
100 101
101 102 onlyrx_list = form_data.getlist('onlyrx')
102 103 only_rx = {}
103 104 if '1' in onlyrx_list:
104 105 only_rx['up'] = True
105 106 else:
106 107 only_rx['up'] = False
107 108 if '2' in onlyrx_list:
108 109 only_rx['down'] = True
109 110 else:
110 111 only_rx['down'] = False
111 112
112 113 antenna = {'antenna_up': up_values_list, 'antenna_down': down_values_list}
113 114 tx = {'up': up_txvalues_list, 'down': down_txvalues_list}
114 115 rx = {'up': up_rxvalues_list, 'down': down_rxvalues_list}
115 116 ues = {'up': list_uesup, 'down': list_uesdown}
116 117 name = str(form_data['beam_name'])
117 118
118 119 beam_data = {'name': name, 'antenna': antenna, 'tx': tx, 'rx': rx, 'ues': ues, 'only_rx': only_rx}
119 120
120 121 return beam_data
121 122
122 123
123 124 def abs_conf(request, id_conf):
124 125
125 126 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
126 127 beams = ABSBeam.objects.filter(abs_conf=conf)
127 128 #------------Colors for Active Beam:-------------
128 129 all_status = {}
129 130 module_messages = json.loads(conf.module_messages)
130 131
131 132 color_status = {}
132 133 for i, status in enumerate(conf.module_status):
133 134 if status == '3': #Running background-color: #00cc00;
134 135 all_status['{}'.format(i+1)] = 2
135 136 color_status['{}'.format(i+1)] = 'class=text-success'#'bgcolor=#00cc00'
136 137 elif status == '1': #Connected background-color: #ee902c;
137 138 all_status['{}'.format(i+1)] = 1
138 139 color_status['{}'.format(i+1)] = 'class=text-warning'#'bgcolor=#ee902c'
139 140 else: #Disconnected background-color: #ff0000;
140 141 all_status['{}'.format(i+1)] = 0
141 142 color_status['{}'.format(i+1)] = 'class=text-danger'#'bgcolor=#FF0000'
142 143 #------------------------------------------------
143 144
144 145 kwargs = {}
145 146 kwargs['connected_modules'] = str(conf.connected_modules())+'/64'
146 147 kwargs['dev_conf'] = conf
147 148
148 149 if conf.operation_mode == 0:
149 150 kwargs['dev_conf_keys'] = ['name', 'operation_mode']
150 151 else:
151 152 kwargs['dev_conf_keys'] = ['name', 'operation_mode', 'operation_value']
152 153
153 154 kwargs['title'] = 'ABS Configuration'
154 155 kwargs['suptitle'] = 'Details'
155 156 kwargs['button'] = 'Edit Configuration'
156 157
157 158 if conf.active_beam != 0:
158 159 kwargs['active_beam'] = int(conf.active_beam)
159 160
160 161 kwargs['beams'] = beams
161 162 kwargs['modules_status'] = all_status
162 163 kwargs['color_status'] = color_status
163 164 kwargs['module_messages'] = module_messages
164 165 ###### SIDEBAR ######
165 166 kwargs.update(sidebar(conf=conf))
166 167
167 168 return render(request, 'abs_conf.html', kwargs)
168 169
169 170
170 171 def abs_conf_edit(request, id_conf):
171 172
172 173 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
173 174
174 175 beams = ABSBeam.objects.filter(abs_conf=conf)
175 176
176 177 if request.method=='GET':
177 178 form = ABSConfigurationForm(instance=conf)
178 179
179 180 if request.method=='POST':
180 181 form = ABSConfigurationForm(request.POST, instance=conf)
181 182
182 183 if form.is_valid():
183 184 conf = form.save(commit=False)
184 185 conf.save()
185 186 return redirect('url_abs_conf', id_conf=conf.id)
186 187
187 188 ###### SIDEBAR ######
188 189 kwargs = {}
189 190
190 191 kwargs['dev_conf'] = conf
191 192 #kwargs['id_dev'] = conf.id
192 193 kwargs['id_conf'] = conf.id
193 194 kwargs['form'] = form
194 195 kwargs['abs_beams'] = beams
195 196 kwargs['title'] = 'Device Configuration'
196 197 kwargs['suptitle'] = 'Edit'
197 198 kwargs['button'] = 'Save'
198 199
199 200 kwargs['edit'] = True
200 201
201 202 return render(request, 'abs_conf_edit.html', kwargs)
202 203
204 @csrf_exempt
205 def abs_conf_alert(request):
206
207 if request.method == 'POST':
208 print request.POST
209 return HttpResponse(json.dumps({'result':1}), content_type='application/json')
210 else:
211 return redirect('index')
212
203 213
204 214 def import_file(request, id_conf):
205 215
206 216 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
207 217 if request.method=='POST':
208 218 form = ABSImportForm(request.POST, request.FILES)
209 219 if form.is_valid():
210 220 try:
211 221 parms = conf.import_from_file(request.FILES['file_name'])
212 222
213 223 if parms:
214 224 conf.update_from_file(parms)
215 225 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
216 226 return redirect(conf.get_absolute_url_edit())
217 227
218 228 except Exception as e:
219 229 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], e))
220 230
221 231 else:
222 232 messages.warning(request, 'Your current configuration will be replaced')
223 233 form = ABSImportForm()
224 234
225 235 kwargs = {}
226 236 kwargs['form'] = form
227 237 kwargs['title'] = 'ABS Configuration'
228 238 kwargs['suptitle'] = 'Import file'
229 239 kwargs['button'] = 'Upload'
230 240 kwargs['previous'] = conf.get_absolute_url()
231 241
232 242 return render(request, 'abs_import.html', kwargs)
233 243
234 244
235 245 def send_beam(request, id_conf, id_beam):
236 246
237 247 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
238 248 beam = get_object_or_404(ABSBeam, pk=id_beam)
239 249 beams_list = ABSBeam.objects.filter(abs_conf=conf)
240 250 conf.active_beam = id_beam
241 251
242 252 i = 0
243 253 for b in beams_list:
244 254 if b.id == int(id_beam):
245 255 break
246 256 else:
247 257 i += 1
248 258 beam_pos = i + 1 #Estandarizar
249 259 print '%s Position: %s' % (beam.name, str(beam_pos))
250 260 conf.send_beam(beam_pos)
251 261
252 262 return redirect('url_abs_conf', conf.id)
253 263
254 264
255 265 def add_beam(request, id_conf):
256 266
257 267 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
258 268 confs = Configuration.objects.all()
259 269
260 270 if request.method=='GET':
261 271 form = ABSBeamAddForm()
262 272
263 273 if request.method=='POST':
264 274 form = ABSBeamAddForm(request.POST)
265 275
266 276 beam_data = get_values_from_form(request.POST)
267 277
268 278 new_beam = ABSBeam(
269 279 name = beam_data['name'],
270 280 antenna = json.dumps(beam_data['antenna']),
271 281 abs_conf = conf,
272 282 tx = json.dumps(beam_data['tx']),
273 283 rx = json.dumps(beam_data['rx']),
274 284 ues = json.dumps(beam_data['ues']),
275 285 only_rx = json.dumps(beam_data['only_rx'])
276 286 )
277 287 new_beam.save()
278 288 messages.success(request, 'Beam: "%s" has been added.' % new_beam.name)
279 289
280 290 return redirect('url_edit_abs_conf', conf.id)
281 291
282 292 ###### SIDEBAR ######
283 293 kwargs = {}
284 294
285 295 #kwargs['dev_conf'] = conf.device
286 296 #kwargs['id_dev'] = conf.device
287 297 kwargs['id_conf'] = conf.id
288 298 kwargs['form'] = form
289 299 kwargs['title'] = 'ABS Beams'
290 300 kwargs['suptitle'] = 'Add Beam'
291 301 kwargs['button'] = 'Add'
292 302 kwargs['no_sidebar'] = True
293 303
294 304 #kwargs['previous'] = conf.get_absolute_url_edit()
295 305 kwargs['edit'] = True
296 306
297 307 return render(request, 'abs_add_beam.html', kwargs)
298 308
299 309
300 310 def edit_beam(request, id_conf, id_beam):
301 311
302 312 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
303 313 beam = get_object_or_404(ABSBeam, pk=id_beam)
304 314
305 315 if request.method=='GET':
306 316 form = ABSBeamEditForm(initial={'beam': beam})
307 317
308 318 if request.method=='POST':
309 319 form = ABSBeamEditForm(request.POST)
310 320
311 321 beam_data = get_values_from_form(request.POST)
312 322
313 323 beam.dict_to_parms(beam_data)
314 324 beam.save()
315 325
316 326 messages.success(request, 'Beam: "%s" has been updated.' % beam.name)
317 327
318 328 return redirect('url_edit_abs_conf', conf.id)
319 329
320 330 ###### SIDEBAR ######
321 331 kwargs = {}
322 332
323 333 kwargs['id_conf'] = conf.id
324 334 kwargs['form'] = form
325 335 kwargs['title'] = 'ABS Beams'
326 336 kwargs['suptitle'] = 'Edit Beam'
327 337 kwargs['button'] = 'Save'
328 338 kwargs['no_sidebar'] = True
329 339
330 340 #kwargs['previous'] = conf.get_absolute_url_edit()
331 341 kwargs['edit'] = True
332 342
333 343 return render(request, 'abs_edit_beam.html', kwargs)
334 344
335 345
336 346
337 347 def remove_beam(request, id_conf, id_beam):
338 348
339 349 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
340 350 beam = get_object_or_404(ABSBeam, pk=id_beam)
341 351
342 352 if request.method=='POST':
343 353 if beam:
344 354 try:
345 beam.remove_beamfromlist()
346 355 beam.delete()
347 356 messages.success(request, 'Beam: "%s" has been deleted.' % beam)
348 357 except:
349 358 messages.error(request, 'Unable to delete beam: "%s".' % beam)
350 359
351 360 return redirect('url_edit_abs_conf', conf.id)
352 361
353 362 ###### SIDEBAR ######
354 363 kwargs = {}
355 364
356 365 kwargs['object'] = beam
357 366 kwargs['delete'] = True
358 367 kwargs['title'] = 'Delete'
359 368 kwargs['suptitle'] = 'Beam'
360 369 kwargs['previous'] = conf.get_absolute_url_edit()
361 370 return render(request, 'confirm.html', kwargs)
362 371
363 372
364 373
365 374 def plot_patterns(request, id_conf, id_beam=None):
366 375
367 376 kwargs = {}
368 377 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
369 378 beams = ABSBeam.objects.filter(abs_conf=conf)
370 379
371 380 if id_beam:
372 381 beam = get_object_or_404(ABSBeam, pk=id_beam)
373 382 kwargs['beam'] = beam
374 383
375 384 ###### SIDEBAR ######
376 385
377 386 kwargs['dev_conf'] = conf.device
378 387 kwargs['id_dev'] = conf.device
379 388 kwargs['id_conf'] = conf.id
380 389 kwargs['abs_beams'] = beams
381 390 kwargs['title'] = 'ABS Patterns'
382 391 kwargs['suptitle'] = conf.name
383 392 kwargs['no_sidebar'] = True
384 393
385 394 return render(request, 'abs_patterns.html', kwargs)
386 395
387 396
388 397 def plot_pattern(request, id_conf, id_beam, antenna):
389 398
390 399 if antenna=='down':
391 400 sleep(3)
392 401
393 402 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
394 403 beam = get_object_or_404(ABSBeam, pk=id_beam)
395 404 just_rx = 1 if json.loads(beam.only_rx)[antenna] else 0
396 405 phases = json.loads(beam.antenna)['antenna_{}'.format(antenna)]
397 406 gain_tx = json.loads(beam.tx)[antenna]
398 407 gain_rx = json.loads(beam.rx)[antenna]
399 408 ues = json.loads(beam.ues)[antenna]
400 409 newOverJro = overJroShow(beam.name)
401 410 fig = newOverJro.plotPattern2(datetime.today(), phases, gain_tx, gain_rx, ues, just_rx)
402 411 buf = io.BytesIO()
403 412 fig.savefig(buf, format='png')
404 413 response = HttpResponse(buf.getvalue(), content_type='image/png')
405 414 return response
406 415
General Comments 0
You need to be logged in to leave comments. Login now