##// END OF EJS Templates
Juan C. Espinoza -
r317:3c0c2e8703c8 merge
parent child
Show More
@@ -1,864 +1,876
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 os, 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['label'] = self.label
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.label = parameters['label']
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 except:
399 except Exception as e:
400 print 'Error {}'.format(e)
397 401 n += 1
398 402 sock.close()
399 403 else:
400 404 self.message = "ABS Configuration does not have beams"
401 405 return False
402 406
403 407 if n == 64:
404 408 self.message = "Could not write ABS Modules"
405 409 self.device.status = 0
406 410 self.module_status = ''.join(status)
407 411 self.save()
408 412 return False
409 413 else:
410 414 self.message = "ABS Beams List have been sent to ABS Modules"
411 415 self.active_beam = beams[0].pk
412 416
413 417 self.device.status = 3
414 418 self.module_status = ''.join(status)
415 419 self.save()
416 420 return True
417 421
418 422
419 423 def read_module(self, module):
420 424
421 425 """
422 426 Read out-bits (up-down) of 1 abs module NOT for Configuration
423 427 """
424 428
425 429 ip_address = self.device.ip_address
426 430 ip_address = ip_address.split('.')
427 431 module_seq = (ip_address[0],ip_address[1],ip_address[2])
428 432 dot = '.'
429 433 module_ip = dot.join(module_seq)+'.'+str(module)
430 434 module_port = self.device.port_address
431 435 read_route = 'http://'+module_ip+':'+str(module_port)+'/read'
432 436
433 437 module_status = json.loads(self.module_status)
434 438 print(read_route)
435 439
436 440 module_bits = ''
437 441
438 442 try:
439 443 r_read = requests.get(read_route, timeout=0.5)
440 444 answer = r_read.json()
441 445 module_bits = answer['allbits']
442 446 except:
443 447 return {}
444 448
445 449 return module_bits
446 450
447 451 def read_device(self):
448 452
449 453 parms = {}
450 454 # Reads active modules.
451 455 module_status = json.loads(self.module_status)
452 456 total = 0
453 457 for status in module_status:
454 458 if module_status[status] != 0:
455 459 module_bits = self.read_module(int(status))
456 460 bits={}
457 461 if module_bits:
458 462 bits = (str(module_bits['um2']) + str(module_bits['um1']) + str(module_bits['um0']) +
459 463 str(module_bits['dm2']) + str(module_bits['dm1']) + str(module_bits['dm0']) )
460 464 parms[str(status)] = bits
461 465
462 466 total +=1
463 467
464 468 if total==0:
465 469 self.message = "No ABS Module detected. Please select 'Status'."
466 470 return False
467 471
468 472
469 473
470 474 self.message = "ABS Modules have been read"
471 475 #monitoreo_tx = JROABSClnt_01CeCnMod000000MNTR10
472 476 return parms
473 477
474 478
475 479 def connected_modules(self):
476 480 """
477 481 This function returns the number of connected abs-modules without updating.
478 482 """
479 483 num = 0
480 484 print(self.module_status)
481 485 for i, status in enumerate(self.module_status):
482 486 if status != '0':
483 487 num += 1
484 print('status {}:{}'.format(i+1, status))
488 #print('status {}:{}'.format(i+1, status))
485 489 return num
486 490
487 491 def send_multicast(self, message):
488 492
489 493 multicast_group = ('224.3.29.71', 10000)
490 494 # Create the datagram socket
491 495 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
492 sock.settimeout(0.01)
496 sock.settimeout(1)
497 # sock.bind((local_ip, 10000))
493 498 local_ip = os.environ.get('LOCAL_IP', '127.0.0.1')
499 local_ip = '192.168.1.128'
494 500 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip))
495 501 sent = sock.sendto(message, multicast_group)
496 502 print('Sending ' + message)
497 503 return sock
498 504
499 505 def status_device(self):
500 506 """
501 507 This function returns the status of all abs-modules as one.
502 508 If at least one module is connected, its answer is "1"
503 509 """
504 510
505 511 sock = self.send_multicast('MNTR')
506 512
507 513 n = 0
508 514 status = ['0'] * 64
509 for i in range(64):
515 for i in range(32):
516 #if True:
510 517 try:
518 address = None
511 519 data, address = sock.recvfrom(1024)
520 print address, data
512 521 if data == '1':
513 522 status[int(address[0][10:])-1] = '3'
514 523 elif data == '0':
515 524 status[int(address[0][10:])-1] = '1'
516 525 n += 1
517 526 print('Module: {} connected'.format(address))
518 527 except:
528 print('Module: {} error'.format(address))
519 529 pass
520 530 sock.close()
521 531
522 532 if n > 0:
523 533 self.message = 'ABS modules Status have been updated.'
524 534 self.device.status = 1
525 535 else:
526 536 self.device.status = 0
527 537 self.message = 'No ABS module is connected.'
528 538 self.module_status = ''.join(status)
529 539 self.save()
530 540
531 541 return self.device.status
532 542
533 543
534 544 def send_beam(self, beam_pos):
535 545 """
536 546 This function connects to a multicast group and sends the beam number
537 547 to all abs modules.
538 548 """
539 549
540 550 # Se manda a cero RC para poder realizar cambio de beam
541 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
551 if self.experiment is None:
552 confs = []
553 else:
554 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
542 555 confdds = ''
543 556 confjars = ''
544 557 confrc = ''
545
546 558 #TO STOP DEVICES: DDS-JARS-RC
547 559 for i in range(0,len(confs)):
548 560 if i==0:
549 561 for conf in confs:
550 562 if conf.device.device_type.name == 'dds':
551 563 confdds = conf
552 564 confdds.stop_device()
553 565 break
554 566 if i==1:
555 567 for conf in confs:
556 568 if conf.device.device_type.name == 'jars':
557 569 confjars = conf
558 570 confjars.stop_device()
559 571 break
560 572 if i==2:
561 573 for conf in confs:
562 574 if conf.device.device_type.name == 'rc':
563 575 confrc = conf
564 576 confrc.stop_device()
565 577 break
566
567 578 if beam_pos > 0:
568 579 beam_pos = beam_pos - 1
569 580 else:
570 581 beam_pos = 0
571 582
572 583 #El indice del apunte debe ser menor que el numero total de apuntes
573 584 #El servidor tcp en el embebido comienza a contar desde 0
574 585 status = ['0'] * 64
575 586 message = 'CHGB{}'.format(beam_pos)
576 587 sock = self.send_multicast(message)
577
578 for i in range(64):
588 for i in range(32):
579 589 try:
580 590 data, address = sock.recvfrom(1024)
581 591 print address, data
582 592 if data == '1':
583 593 status[int(address[0][10:])-1] = '3'
584 594 elif data == '0':
585 595 status[int(address[0][10:])-1] = '1'
586 except:
596 except Exception as e:
597 print 'Error {}'.format(e)
587 598 pass
588 599
589 600 sock.close()
590 601
591 602 #Start DDS-RC-JARS
592 603 if confdds:
593 604 confdds.start_device()
594 605 if confrc:
595 606 #print confrc
596 607 confrc.start_device()
597 608 if confjars:
598 609 confjars.start_device()
599 610
600 611 self.message = "ABS Beam has been changed"
601 612 self.module_status = ''.join(status)
602 613 self.save()
603 614 return True
604 615
605 616
606 617 def get_absolute_url_import(self):
607 618 return reverse('url_import_abs_conf', args=[str(self.id)])
608 619
609 620
610 621 class ABSBeam(models.Model):
611 622
612 623 name = models.CharField(max_length=60, default='Beam')
613 624 antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default)
614 625 abs_conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration')
615 626 tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default)
616 627 rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default)
617 628 s_time = models.TimeField(verbose_name='Star Time', default='00:00:00')
618 629 e_time = models.TimeField(verbose_name='End Time', default='23:59:59')
619 630 ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default)
620 631 only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default)
621 632
622 633 class Meta:
623 634 db_table = 'abs_beams'
624 635
625 636 def __unicode__(self):
626 637 return u'%s' % (self.name)
627 638
628 639 def parms_to_dict(self):
629 640
630 641 parameters = {}
631 642 parameters['name'] = self.name
632 643 parameters['antenna'] = ast.literal_eval(self.antenna)
633 644 parameters['abs_conf'] = self.abs_conf.name
634 645 parameters['tx'] = ast.literal_eval(self.tx)
635 646 parameters['rx'] = ast.literal_eval(self.rx)
636 647 parameters['s_time'] = self.s_time.strftime("%H:%M:%S")
637 648 parameters['e_time'] = self.e_time.strftime("%H:%M:%S")
638 649 parameters['ues'] = ast.literal_eval(self.ues)
639 650 parameters['only_rx'] = json.loads(self.only_rx)
640 651
641 652 return parameters
642 653
643 654 def dict_to_parms(self, parameters):
644 655
645 656 self.name = parameters['name']
646 657 self.antenna = json.dumps(parameters['antenna'])
647 658 #self.abs_conf = parameters['abs_conf']
648 659 self.tx = json.dumps(parameters['tx'])
649 660 self.rx = json.dumps(parameters['rx'])
650 661 #self.s_time = parameters['s_time']
651 662 #self.e_time = parameters['e_time']
652 663 self.ues = json.dumps(parameters['ues'])
653 664 self.only_rx = json.dumps(parameters['only_rx'])
654 665 self.save()
655 666
656 667
657 668 def clone(self, **kwargs):
658 669
659 670 self.pk = None
660 671 self.id = None
661 672 for attr, value in kwargs.items():
662 673 setattr(self, attr, value)
663 674
664 675 self.save()
665 676
666 677 return self
667 678
668 679
669 680 def module_6bits(self, module):
670 681 """
671 682 This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module
672 683 """
684 module += 1
673 685 if module > 64:
674 686 beam_bits = ""
675 687 return beam_bits
676 688
677 689 data = ast.literal_eval(self.antenna)
678 690 up_data = data['antenna_up']
679 691 down_data = data['antenna_down']
680 692
681 693 pos = ip2position(module)
682 694 up_value = up_data[pos[0]][pos[1]]
683 695 down_value = down_data[pos[0]][pos[1]]
684 696
685 697 up_bits = up_conv_bits(up_value)
686 698 down_bits = down_conv_bits(down_value)
687 699 beam_bits = up_bits+down_bits
688 700
689 701 return beam_bits
690 702
691 703
692 704 @property
693 705 def get_upvalues(self):
694 706 """
695 707 This function reads antenna pattern and show the up-value of one abs module
696 708 """
697 709
698 710 data = ast.literal_eval(self.antenna)
699 711 up_data = data['antenna_up']
700 712
701 713 up_values = []
702 714 for data in up_data:
703 715 for i in range(0,8):
704 716 up_values.append(data[i])
705 717
706 718 return up_values
707 719
708 720 @property
709 721 def antenna_upvalues(self):
710 722 """
711 723 This function reads antenna pattern and show the up - values of one abs beam
712 724 in a particular order
713 725 """
714 726 data = ast.literal_eval(self.antenna)
715 727 up_data = data['antenna_up']
716 728
717 729 return up_data
718 730
719 731 @property
720 732 def antenna_downvalues(self):
721 733 """
722 734 This function reads antenna pattern and show the down - values of one abs beam
723 735 in a particular order
724 736 """
725 737 data = ast.literal_eval(self.antenna)
726 738 down_data = data['antenna_down']
727 739
728 740 return down_data
729 741
730 742 @property
731 743 def get_downvalues(self):
732 744 """
733 745 This function reads antenna pattern and show the down-value of one abs module
734 746 """
735 747
736 748 data = ast.literal_eval(self.antenna)
737 749 down_data = data['antenna_down']
738 750
739 751 down_values = []
740 752 for data in down_data:
741 753 for i in range(0,8):
742 754 down_values.append(data[i])
743 755
744 756 return down_values
745 757
746 758 @property
747 759 def get_up_ues(self):
748 760 """
749 761 This function shows the up-ues-value of one beam
750 762 """
751 763 data = ast.literal_eval(self.ues)
752 764 up_ues = data['up']
753 765
754 766 return up_ues
755 767
756 768 @property
757 769 def get_down_ues(self):
758 770 """
759 771 This function shows the down-ues-value of one beam
760 772 """
761 773 data = ast.literal_eval(self.ues)
762 774 down_ues = data['down']
763 775
764 776 return down_ues
765 777
766 778 @property
767 779 def get_up_onlyrx(self):
768 780 """
769 781 This function shows the up-onlyrx-value of one beam
770 782 """
771 783 data = json.loads(self.only_rx)
772 784 up_onlyrx = data['up']
773 785
774 786 return up_onlyrx
775 787
776 788 @property
777 789 def get_down_onlyrx(self):
778 790 """
779 791 This function shows the down-onlyrx-value of one beam
780 792 """
781 793 data = json.loads(self.only_rx)
782 794 down_onlyrx = data['down']
783 795
784 796 return down_onlyrx
785 797
786 798 @property
787 799 def get_tx(self):
788 800 """
789 801 This function shows the tx-values of one beam
790 802 """
791 803 data = json.loads(self.tx)
792 804
793 805 return data
794 806
795 807 @property
796 808 def get_uptx(self):
797 809 """
798 810 This function shows the up-tx-values of one beam
799 811 """
800 812 data = json.loads(self.tx)
801 813 up_data = data['up']
802 814
803 815 up_values = []
804 816 for data in up_data:
805 817 for i in range(0,8):
806 818 up_values.append(data[i])
807 819
808 820 return up_values
809 821
810 822 @property
811 823 def get_downtx(self):
812 824 """
813 825 This function shows the down-tx-values of one beam
814 826 """
815 827 data = json.loads(self.tx)
816 828 down_data = data['down']
817 829
818 830 down_values = []
819 831 for data in down_data:
820 832 for i in range(0,8):
821 833 down_values.append(data[i])
822 834
823 835 return down_values
824 836
825 837
826 838
827 839 @property
828 840 def get_rx(self):
829 841 """
830 842 This function shows the rx-values of one beam
831 843 """
832 844 data = json.loads(self.rx)
833 845
834 846 return data
835 847
836 848 @property
837 849 def get_uprx(self):
838 850 """
839 851 This function shows the up-rx-values of one beam
840 852 """
841 853 data = json.loads(self.rx)
842 854 up_data = data['up']
843 855
844 856 up_values = []
845 857 for data in up_data:
846 858 for i in range(0,8):
847 859 up_values.append(data[i])
848 860
849 861 return up_values
850 862
851 863 @property
852 864 def get_downrx(self):
853 865 """
854 866 This function shows the down-rx-values of one beam
855 867 """
856 868 data = json.loads(self.rx)
857 869 down_data = data['down']
858 870
859 871 down_values = []
860 872 for data in down_data:
861 873 for i in range(0,8):
862 874 down_values.append(data[i])
863 875
864 876 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'] = ['label', 'operation_mode']
150 151 else:
151 152 kwargs['dev_conf_keys'] = ['label', '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 No newline at end of file
415
General Comments 0
You need to be logged in to leave comments. Login now