##// END OF EJS Templates
Update Views y several improvements
Juan C. Espinoza -
r316:0d39f71bbf42
parent child
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,12 +1,12
1 1 REDIS_HOST=radarsys-redis
2 2 REDIS_PORT=6379
3 3 POSTGRES_DB_NAME=radarsys
4 4 POSTGRES_PORT_5432_TCP_ADDR=radarsys-postgres
5 5 POSTGRES_PORT_5432_TCP_PORT=5432
6 6 POSTGRES_USER=docker
7 7 POSTGRES_PASSWORD=docker
8 8 PGDATA=/var/lib/postgresql/data
9 9 LC_ALL=C.UTF-8
10 10 TZ=America/Lima
11 DOCKER_DATA=/data/dockers/radarsys/
11 DOCKER_DATA=/Volumes/dockers/radarsys/
12 12 LOCAL_IP=192.168.1.128
@@ -1,6 +1,7
1 1 migrations/
2 2 .DS_Store
3 3 *.sqlite
4 4 .vscode/
5 5 *.pyc
6 6 .env
7 remove_migrations.py
@@ -1,73 +1,75
1 1 from django import forms
2 2 from .models import ABSConfiguration, ABSBeam
3 3 from .widgets import UpDataWidget, DownDataWidget, EditUpDataWidget, EditDownDataWidget
4 4 from apps.main.models import Configuration
5 5 import os
6 6
7 7 class ABSConfigurationForm(forms.ModelForm):
8 8 def __init__(self, *args, **kwargs):
9 9 super(ABSConfigurationForm, self).__init__(*args, **kwargs)
10 10
11 11 class Meta:
12 12 model = ABSConfiguration
13 exclude = ('type', 'status', 'parameters', 'active_beam', 'module_status', 'module_messages', 'module_mode')
13 exclude = ('type', 'status', 'parameters', 'active_beam',
14 'module_status', 'module_messages', 'module_mode',
15 'author', 'hash')
14 16
15 17
16 18 class ABSBeamAddForm(forms.Form):
17 19
18 20 up_data = forms.CharField(widget=UpDataWidget, label='')
19 21 down_data = forms.CharField(widget=DownDataWidget, label='')
20 22
21 23 def __init__(self, *args, **kwargs):
22 24 super(ABSBeamAddForm, self).__init__(*args, **kwargs)
23 25
24 26
25 27
26 28 class ABSBeamEditForm(forms.Form):
27 29
28 30 up_data = forms.CharField(widget=EditUpDataWidget, label='')
29 31 down_data = forms.CharField(widget=EditDownDataWidget, label='')
30 32
31 33 def __init__(self, *args, **kwargs):
32 34 super(ABSBeamEditForm, self).__init__(*args, **kwargs)
33 35
34 36 if 'initial' in kwargs:
35 37 if 'beam' in self.initial:
36 38 self.fields['up_data'].initial = self.initial['beam']
37 39 self.fields['down_data'].initial = self.initial['beam']
38 40
39 41
40 42 class ExtFileField(forms.FileField):
41 43 """
42 44 Same as forms.FileField, but you can specify a file extension whitelist.
43 45
44 46 >>> from django.core.files.uploadedfile import SimpleUploadedFile
45 47 >>>
46 48 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
47 49 >>>
48 50 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
49 51 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
50 52 >>>
51 53 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
52 54 Traceback (most recent call last):
53 55 ...
54 56 ValidationError: [u'Not allowed filetype!']
55 57 """
56 58 def __init__(self, *args, **kwargs):
57 59 extensions = kwargs.pop("extensions")
58 60 self.extensions = [i.lower() for i in extensions]
59 61
60 62 super(ExtFileField, self).__init__(*args, **kwargs)
61 63
62 64 def clean(self, *args, **kwargs):
63 65 data = super(ExtFileField, self).clean(*args, **kwargs)
64 66 filename = data.name
65 67 ext = os.path.splitext(filename)[1]
66 68 ext = ext.lower()
67 69 if ext not in self.extensions:
68 70 raise forms.ValidationError('Not allowed file type: %s' % ext)
69 71
70 72
71 73 class ABSImportForm(forms.Form):
72 74
73 75 file_name = ExtFileField(extensions=['.json'])
@@ -1,864 +1,864
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 parameters['name'] = self.name
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 self.name = parameters['name']
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 if beams:
381 381 message = 'SNDF{:02d}'.format(nbeams)
382 382 for i, status in enumerate(self.module_status):
383 383 message += ''.join([fromBinary2Char(beam.module_6bits(i)) for beam in beams])
384 384 status = ['0'] * 64
385 385 n = 0
386 386
387 387 sock = self.send_multicast(message)
388 388
389 389 for i in range(64):
390 390 try:
391 391 data, address = sock.recvfrom(1024)
392 392 if data == '1':
393 393 status[int(address[0][10:])-1] = '3'
394 394 elif data == '0':
395 395 status[int(address[0][10:])-1] = '1'
396 396 except:
397 397 n += 1
398 398 sock.close()
399 399 else:
400 400 self.message = "ABS Configuration does not have beams"
401 401 return False
402 402
403 403 if n == 64:
404 404 self.message = "Could not write ABS Modules"
405 405 self.device.status = 0
406 406 self.module_status = ''.join(status)
407 407 self.save()
408 408 return False
409 409 else:
410 410 self.message = "ABS Beams List have been sent to ABS Modules"
411 411 self.active_beam = beams[0].pk
412 412
413 413 self.device.status = 3
414 414 self.module_status = ''.join(status)
415 415 self.save()
416 416 return True
417 417
418 418
419 419 def read_module(self, module):
420 420
421 421 """
422 422 Read out-bits (up-down) of 1 abs module NOT for Configuration
423 423 """
424 424
425 425 ip_address = self.device.ip_address
426 426 ip_address = ip_address.split('.')
427 427 module_seq = (ip_address[0],ip_address[1],ip_address[2])
428 428 dot = '.'
429 429 module_ip = dot.join(module_seq)+'.'+str(module)
430 430 module_port = self.device.port_address
431 431 read_route = 'http://'+module_ip+':'+str(module_port)+'/read'
432 432
433 433 module_status = json.loads(self.module_status)
434 434 print(read_route)
435 435
436 436 module_bits = ''
437 437
438 438 try:
439 439 r_read = requests.get(read_route, timeout=0.5)
440 440 answer = r_read.json()
441 441 module_bits = answer['allbits']
442 442 except:
443 443 return {}
444 444
445 445 return module_bits
446 446
447 447 def read_device(self):
448 448
449 449 parms = {}
450 450 # Reads active modules.
451 451 module_status = json.loads(self.module_status)
452 452 total = 0
453 453 for status in module_status:
454 454 if module_status[status] != 0:
455 455 module_bits = self.read_module(int(status))
456 456 bits={}
457 457 if module_bits:
458 458 bits = (str(module_bits['um2']) + str(module_bits['um1']) + str(module_bits['um0']) +
459 459 str(module_bits['dm2']) + str(module_bits['dm1']) + str(module_bits['dm0']) )
460 460 parms[str(status)] = bits
461 461
462 462 total +=1
463 463
464 464 if total==0:
465 465 self.message = "No ABS Module detected. Please select 'Status'."
466 466 return False
467 467
468 468
469 469
470 470 self.message = "ABS Modules have been read"
471 471 #monitoreo_tx = JROABSClnt_01CeCnMod000000MNTR10
472 472 return parms
473 473
474 474
475 475 def connected_modules(self):
476 476 """
477 477 This function returns the number of connected abs-modules without updating.
478 478 """
479 479 num = 0
480 480 print(self.module_status)
481 481 for i, status in enumerate(self.module_status):
482 482 if status != '0':
483 483 num += 1
484 484 print('status {}:{}'.format(i+1, status))
485 485 return num
486 486
487 487 def send_multicast(self, message):
488 488
489 489 multicast_group = ('224.3.29.71', 10000)
490 490 # Create the datagram socket
491 491 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
492 492 sock.settimeout(0.01)
493 493 local_ip = os.environ.get('LOCAL_IP', '127.0.0.1')
494 494 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip))
495 495 sent = sock.sendto(message, multicast_group)
496 496 print('Sending ' + message)
497 497 return sock
498 498
499 499 def status_device(self):
500 500 """
501 501 This function returns the status of all abs-modules as one.
502 502 If at least one module is connected, its answer is "1"
503 503 """
504 504
505 505 sock = self.send_multicast('MNTR')
506 506
507 507 n = 0
508 508 status = ['0'] * 64
509 509 for i in range(64):
510 510 try:
511 511 data, address = sock.recvfrom(1024)
512 512 if data == '1':
513 513 status[int(address[0][10:])-1] = '3'
514 514 elif data == '0':
515 515 status[int(address[0][10:])-1] = '1'
516 516 n += 1
517 517 print('Module: {} connected'.format(address))
518 518 except:
519 519 pass
520 520 sock.close()
521 521
522 522 if n > 0:
523 523 self.message = 'ABS modules Status have been updated.'
524 524 self.device.status = 1
525 525 else:
526 526 self.device.status = 0
527 527 self.message = 'No ABS module is connected.'
528 528 self.module_status = ''.join(status)
529 529 self.save()
530 530
531 531 return self.device.status
532 532
533 533
534 534 def send_beam(self, beam_pos):
535 535 """
536 536 This function connects to a multicast group and sends the beam number
537 537 to all abs modules.
538 538 """
539 539
540 540 # Se manda a cero RC para poder realizar cambio de beam
541 541 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
542 542 confdds = ''
543 543 confjars = ''
544 544 confrc = ''
545 545
546 546 #TO STOP DEVICES: DDS-JARS-RC
547 547 for i in range(0,len(confs)):
548 548 if i==0:
549 549 for conf in confs:
550 550 if conf.device.device_type.name == 'dds':
551 551 confdds = conf
552 552 confdds.stop_device()
553 553 break
554 554 if i==1:
555 555 for conf in confs:
556 556 if conf.device.device_type.name == 'jars':
557 557 confjars = conf
558 558 confjars.stop_device()
559 559 break
560 560 if i==2:
561 561 for conf in confs:
562 562 if conf.device.device_type.name == 'rc':
563 563 confrc = conf
564 564 confrc.stop_device()
565 565 break
566 566
567 567 if beam_pos > 0:
568 568 beam_pos = beam_pos - 1
569 569 else:
570 570 beam_pos = 0
571 571
572 572 #El indice del apunte debe ser menor que el numero total de apuntes
573 573 #El servidor tcp en el embebido comienza a contar desde 0
574 574 status = ['0'] * 64
575 575 message = 'CHGB{}'.format(beam_pos)
576 576 sock = self.send_multicast(message)
577 577
578 578 for i in range(64):
579 579 try:
580 580 data, address = sock.recvfrom(1024)
581 581 print address, data
582 582 if data == '1':
583 583 status[int(address[0][10:])-1] = '3'
584 584 elif data == '0':
585 585 status[int(address[0][10:])-1] = '1'
586 586 except:
587 587 pass
588 588
589 589 sock.close()
590 590
591 591 #Start DDS-RC-JARS
592 592 if confdds:
593 593 confdds.start_device()
594 594 if confrc:
595 595 #print confrc
596 596 confrc.start_device()
597 597 if confjars:
598 598 confjars.start_device()
599 599
600 600 self.message = "ABS Beam has been changed"
601 601 self.module_status = ''.join(status)
602 602 self.save()
603 603 return True
604 604
605 605
606 606 def get_absolute_url_import(self):
607 607 return reverse('url_import_abs_conf', args=[str(self.id)])
608 608
609 609
610 610 class ABSBeam(models.Model):
611 611
612 612 name = models.CharField(max_length=60, default='Beam')
613 613 antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default)
614 614 abs_conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration')
615 615 tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default)
616 616 rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default)
617 617 s_time = models.TimeField(verbose_name='Star Time', default='00:00:00')
618 618 e_time = models.TimeField(verbose_name='End Time', default='23:59:59')
619 619 ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default)
620 620 only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default)
621 621
622 622 class Meta:
623 623 db_table = 'abs_beams'
624 624
625 625 def __unicode__(self):
626 626 return u'%s' % (self.name)
627 627
628 628 def parms_to_dict(self):
629 629
630 630 parameters = {}
631 631 parameters['name'] = self.name
632 632 parameters['antenna'] = ast.literal_eval(self.antenna)
633 633 parameters['abs_conf'] = self.abs_conf.name
634 634 parameters['tx'] = ast.literal_eval(self.tx)
635 635 parameters['rx'] = ast.literal_eval(self.rx)
636 636 parameters['s_time'] = self.s_time.strftime("%H:%M:%S")
637 637 parameters['e_time'] = self.e_time.strftime("%H:%M:%S")
638 638 parameters['ues'] = ast.literal_eval(self.ues)
639 639 parameters['only_rx'] = json.loads(self.only_rx)
640 640
641 641 return parameters
642 642
643 643 def dict_to_parms(self, parameters):
644 644
645 645 self.name = parameters['name']
646 646 self.antenna = json.dumps(parameters['antenna'])
647 647 #self.abs_conf = parameters['abs_conf']
648 648 self.tx = json.dumps(parameters['tx'])
649 649 self.rx = json.dumps(parameters['rx'])
650 650 #self.s_time = parameters['s_time']
651 651 #self.e_time = parameters['e_time']
652 652 self.ues = json.dumps(parameters['ues'])
653 653 self.only_rx = json.dumps(parameters['only_rx'])
654 654 self.save()
655 655
656 656
657 657 def clone(self, **kwargs):
658 658
659 659 self.pk = None
660 660 self.id = None
661 661 for attr, value in kwargs.items():
662 662 setattr(self, attr, value)
663 663
664 664 self.save()
665 665
666 666 return self
667 667
668 668
669 669 def module_6bits(self, module):
670 670 """
671 671 This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module
672 672 """
673 673 if module > 64:
674 674 beam_bits = ""
675 675 return beam_bits
676 676
677 677 data = ast.literal_eval(self.antenna)
678 678 up_data = data['antenna_up']
679 679 down_data = data['antenna_down']
680 680
681 681 pos = ip2position(module)
682 682 up_value = up_data[pos[0]][pos[1]]
683 683 down_value = down_data[pos[0]][pos[1]]
684 684
685 685 up_bits = up_conv_bits(up_value)
686 686 down_bits = down_conv_bits(down_value)
687 687 beam_bits = up_bits+down_bits
688 688
689 689 return beam_bits
690 690
691 691
692 692 @property
693 693 def get_upvalues(self):
694 694 """
695 695 This function reads antenna pattern and show the up-value of one abs module
696 696 """
697 697
698 698 data = ast.literal_eval(self.antenna)
699 699 up_data = data['antenna_up']
700 700
701 701 up_values = []
702 702 for data in up_data:
703 703 for i in range(0,8):
704 704 up_values.append(data[i])
705 705
706 706 return up_values
707 707
708 708 @property
709 709 def antenna_upvalues(self):
710 710 """
711 711 This function reads antenna pattern and show the up - values of one abs beam
712 712 in a particular order
713 713 """
714 714 data = ast.literal_eval(self.antenna)
715 715 up_data = data['antenna_up']
716 716
717 717 return up_data
718 718
719 719 @property
720 720 def antenna_downvalues(self):
721 721 """
722 722 This function reads antenna pattern and show the down - values of one abs beam
723 723 in a particular order
724 724 """
725 725 data = ast.literal_eval(self.antenna)
726 726 down_data = data['antenna_down']
727 727
728 728 return down_data
729 729
730 730 @property
731 731 def get_downvalues(self):
732 732 """
733 733 This function reads antenna pattern and show the down-value of one abs module
734 734 """
735 735
736 736 data = ast.literal_eval(self.antenna)
737 737 down_data = data['antenna_down']
738 738
739 739 down_values = []
740 740 for data in down_data:
741 741 for i in range(0,8):
742 742 down_values.append(data[i])
743 743
744 744 return down_values
745 745
746 746 @property
747 747 def get_up_ues(self):
748 748 """
749 749 This function shows the up-ues-value of one beam
750 750 """
751 751 data = ast.literal_eval(self.ues)
752 752 up_ues = data['up']
753 753
754 754 return up_ues
755 755
756 756 @property
757 757 def get_down_ues(self):
758 758 """
759 759 This function shows the down-ues-value of one beam
760 760 """
761 761 data = ast.literal_eval(self.ues)
762 762 down_ues = data['down']
763 763
764 764 return down_ues
765 765
766 766 @property
767 767 def get_up_onlyrx(self):
768 768 """
769 769 This function shows the up-onlyrx-value of one beam
770 770 """
771 771 data = json.loads(self.only_rx)
772 772 up_onlyrx = data['up']
773 773
774 774 return up_onlyrx
775 775
776 776 @property
777 777 def get_down_onlyrx(self):
778 778 """
779 779 This function shows the down-onlyrx-value of one beam
780 780 """
781 781 data = json.loads(self.only_rx)
782 782 down_onlyrx = data['down']
783 783
784 784 return down_onlyrx
785 785
786 786 @property
787 787 def get_tx(self):
788 788 """
789 789 This function shows the tx-values of one beam
790 790 """
791 791 data = json.loads(self.tx)
792 792
793 793 return data
794 794
795 795 @property
796 796 def get_uptx(self):
797 797 """
798 798 This function shows the up-tx-values of one beam
799 799 """
800 800 data = json.loads(self.tx)
801 801 up_data = data['up']
802 802
803 803 up_values = []
804 804 for data in up_data:
805 805 for i in range(0,8):
806 806 up_values.append(data[i])
807 807
808 808 return up_values
809 809
810 810 @property
811 811 def get_downtx(self):
812 812 """
813 813 This function shows the down-tx-values of one beam
814 814 """
815 815 data = json.loads(self.tx)
816 816 down_data = data['down']
817 817
818 818 down_values = []
819 819 for data in down_data:
820 820 for i in range(0,8):
821 821 down_values.append(data[i])
822 822
823 823 return down_values
824 824
825 825
826 826
827 827 @property
828 828 def get_rx(self):
829 829 """
830 830 This function shows the rx-values of one beam
831 831 """
832 832 data = json.loads(self.rx)
833 833
834 834 return data
835 835
836 836 @property
837 837 def get_uprx(self):
838 838 """
839 839 This function shows the up-rx-values of one beam
840 840 """
841 841 data = json.loads(self.rx)
842 842 up_data = data['up']
843 843
844 844 up_values = []
845 845 for data in up_data:
846 846 for i in range(0,8):
847 847 up_values.append(data[i])
848 848
849 849 return up_values
850 850
851 851 @property
852 852 def get_downrx(self):
853 853 """
854 854 This function shows the down-rx-values of one beam
855 855 """
856 856 data = json.loads(self.rx)
857 857 down_data = data['down']
858 858
859 859 down_values = []
860 860 for data in down_data:
861 861 for i in range(0,8):
862 862 down_values.append(data[i])
863 863
864 864 return down_values
@@ -1,476 +1,342
1 {% extends "dev_conf.html" %} {% load static %} {% load bootstrap3 %} {% load main_tags %}
1 {% extends "dev_conf.html" %} {% load static %} {% load bootstrap3 %} {% load main_tags %}
2 2 {% block extra-head %}
3 3 <style>
4 4 .abs {
5 border: 2px solid #00334d;
6 vertical-align: center;
5 width: auto;
7 6 display: inline-block;
8 }
9
10 .abs tr:nth-child(1) {
11 border-bottom: 1px dashed #00334d;
12 }
13
14 .abs tr {
15 border-bottom: 0px solid #00334d;
7 text-align: center;
16 8 }
17 9
18 10 .abs td {
19 border-right: 1px dashed #00334d;
20 text-align: center;
21 padding: 5px;
11 padding: 4px;
22 12 }
23 13
14 .module td {
15 padding: 4px 15px 4px 15px;
16 font-weight: bold;
17 border: 1px solid
18 }
24 19
25 20 .legend {
26 21 margin-left: 15px;
27 22 display: inline-block;
28 border: 2px solid #00334d;
23 border: 2px solid;
29 24 vertical-align: top;
30 25 }
31 26
32 27 .legend th {
33 border-bottom: 1px dashed #00334d;
28 border-bottom: 1px dashed;
34 29 font-weight: bold;
35 30 vertical-align: center;
36 31 text-align: center;
37 32 }
38 33
39 34 .legend td {
40 35 padding: 2px;
41 36 text-align: center;
42 37 }
43 38
44
45 .north {
46 border: 2px solid #00334d;
47 vertical-align: center;
48 font-weight: bold;
49 }
50
51 .north tr {
52 border: 1px solid #ffffff;
53
54 }
55
56 .north td {
57 border: 2px solid #e2e2e7;
58 text-align: center;
59 padding: 1px 15px 1px 15px;
60 }
61
62 .north tr:nth-child(even) td:nth-child(n) {
63 border-bottom: 12px solid #e2e2e7;
64 }
65
66 .north td:nth-child(n) {
67 border-right: 12px solid #e2e2e7;
68 }
69
70 .north td:nth-last-child(4n+1) {
71 border-right: 2px solid #e2e2e7;
72 }
73
74 .north tr:nth-last-child(1) td:nth-child(n) {
75 border-bottom: 3px solid #e2e2e7;
76 }
77
78 .east {
79 border: 2px solid #00334d;
80 vertical-align: center;
81 font-weight: bold;
82 }
83
84 .east tr {
85 border: 1px solid #ffffff;
86 }
87
88 .east td {
89 border: 2px solid #e2e2e7;
90 text-align: center;
91 padding: 1px 15px 1px 15px;
92 }
93
94 .east tr:nth-child(even) td:nth-child(n) {
95 border-bottom: 12px solid #e2e2e7;
96 }
97
98 .east td:nth-child(n) {
99 border-right: 12px solid #e2e2e7;
100 }
101
102 .east td:nth-last-child(4n+1) {
103 border-right: 2px solid #e2e2e7;
104 }
105
106 .east tr:nth-last-child(1) td:nth-child(n) {
107 border-bottom: 3px solid #e2e2e7;
108 }
109
110 .west {
111 border: 2px solid #00334d;
112 vertical-align: center;
113 font-weight: bold;
114 }
115
116 .west tr {
117 border: 1px solid #ffffff;
118 }
119
120 .west td {
121 border: 2px solid #e2e2e7;
122 text-align: center;
123 padding: 1px 15px 1px 15px;
124 }
125
126 .west tr:nth-child(even) td:nth-child(n) {
127 border-bottom: 12px solid #e2e2e7;
128 }
129
130 .west td:nth-child(n) {
131 border-right: 12px solid #e2e2e7;
132 }
133
134 .west td:nth-last-child(4n+1) {
135 border-right: 2px solid #e2e2e7;
136 }
137
138 .west tr:nth-last-child(1) td:nth-child(n) {
139 border-bottom: 3px solid #e2e2e7;
140 }
141
142 .south {
143 border: 2px solid #00334d;
144 vertical-align: center;
145 font-weight: bold;
146 }
147
148 .south tr {
149 border: 1px solid #ffffff;
150 }
151
152 .south td {
153 border: 2px solid #e2e2e7;
154 text-align: center;
155 padding: 1px 15px 1px 15px;
156 }
157
158 .south tr:nth-child(even) td:nth-child(n) {
159 border-bottom: 12px solid #e2e2e7;
160 }
161
162 .south td:nth-child(n) {
163 border-right: 12px solid #e2e2e7;
164 }
165
166 .south td:nth-last-child(4n+1) {
167 border-right: 2px solid #e2e2e7;
168 }
169
170 .south tr:nth-last-child(1) td:nth-child(n) {
171 border-bottom: 3px solid #e2e2e7;
172 }
173 39 </style>
174 40 {% endblock %}
175 41 {% block extra-menu-actions %}
176 42 <li>
177 43 <a href="{{ dev_conf.get_absolute_url_plot }}" target="_blank">
178 44 <span class="glyphicon glyphicon-picture" aria-hidden="true"></span> View Patterns </a>
179 45 </li>
180 {% endblock %}
46 {% endblock %}
181 47 {% block extra-content %}
182 48 {% if beams %}
183 49 <h4>Beams:</h4>
184 50 <div class="container">
185 51 <ul class="nav nav-pills">
186 52 {% for beam in beams %}
187 53 <li {%if beam.pk == active_beam %} class="active" {% endif %}>
188 54 <a data-toggle="pill" href="#menu{{forloop.counter}}">{{forloop.counter}}</a>
189 55 </li>
190 56 {% endfor %}
191 57 </ul>
192 58
193 59 <div class="tab-content">
194 60 {% for beam in beams %}
195 61 <div id="menu{{forloop.counter}}" class="tab-pane fade {%if beam.pk == active_beam %}active in{% endif %}">
196 62 <h3>{%if beam.pk == active_beam %}Active Beam: {%endif%}{{beam.name}}</h3>
197 63 <table id="abs_pattern{{forloop.counter}}" class="abs">
198 64 <tr>
199 65 <td>
200 66 <b>North Quarter</b>
201 <table class="north ">
67 <table class="module">
202 68 <tr>
203 69 <td {%if beam.pk == active_beam %} {{color_status.1}} t{%endif%} itle='{{module_messages.1}}'>{{beam.get_upvalues.0}}</td>
204 70 <td {%if beam.pk == active_beam %} {{color_status.2}} t{%endif%} itle='{{module_messages.2}}'>{{beam.get_upvalues.1}}</td>
205 71 <td {%if beam.pk == active_beam %} {{color_status.3}} t{%endif%} itle='{{module_messages.3}}'>{{beam.get_upvalues.2}}</td>
206 72 <td {%if beam.pk == active_beam %} {{color_status.4}} t{%endif%} itle='{{module_messages.4}}'>{{beam.get_upvalues.3}}</td>
207 73 </tr>
208 74 <tr>
209 75 <td {%if beam.pk == active_beam %} {{color_status.1}} t{%endif%} itle='{{module_messages.1}}'>{{beam.get_downvalues.0}}</td>
210 76 <td {%if beam.pk == active_beam %} {{color_status.2}} t{%endif%} itle='{{module_messages.2}}'>{{beam.get_downvalues.1}}</td>
211 77 <td {%if beam.pk == active_beam %} {{color_status.3}} t{%endif%} itle='{{module_messages.3}}'>{{beam.get_downvalues.2}}</td>
212 78 <td {%if beam.pk == active_beam %} {{color_status.4}} t{%endif%} itle='{{module_messages.4}}'>{{beam.get_downvalues.3}}</td>
213 79 </tr>
214 80 <tr>
215 81 <td {%if beam.pk == active_beam %} {{color_status.9}} t{%endif%} itle='{{module_messages.9}}'>{{beam.get_upvalues.8}}</td>
216 82 <td {%if beam.pk == active_beam %} {{color_status.10}} {%endif%} title='{{module_messages.10}}'>{{beam.get_upvalues.9}}</td>
217 83 <td {%if beam.pk == active_beam %} {{color_status.11}} {%endif%} title='{{module_messages.11}}'>{{beam.get_upvalues.10}}</td>
218 84 <td {%if beam.pk == active_beam %} {{color_status.12}} {%endif%} title='{{module_messages.12}}'>{{beam.get_upvalues.11}}</td>
219 85 </tr>
220 86 <tr>
221 87 <td {%if beam.pk == active_beam %} {{color_status.9}} t{%endif%} itle='{{module_messages.9}}'>{{beam.get_downvalues.8}}</td>
222 88 <td {%if beam.pk == active_beam %} {{color_status.10}} {%endif%} title='{{module_messages.10}}'>{{beam.get_downvalues.9}}</td>
223 89 <td {%if beam.pk == active_beam %} {{color_status.11}} {%endif%} title='{{module_messages.11}}'>{{beam.get_downvalues.10}}</td>
224 90 <td {%if beam.pk == active_beam %} {{color_status.12}} {%endif%} title='{{module_messages.12}}'>{{beam.get_downvalues.11}}</td>
225 91 </tr>
226 92 <tr>
227 93 <td {%if beam.pk == active_beam %} {{color_status.17}} {%endif%} title='{{module_messages.17}}'>{{beam.get_upvalues.16}}</td>
228 94 <td {%if beam.pk == active_beam %} {{color_status.18}} {%endif%} title='{{module_messages.18}}'>{{beam.get_upvalues.17}}</td>
229 95 <td {%if beam.pk == active_beam %} {{color_status.19}} {%endif%} title='{{module_messages.19}}'>{{beam.get_upvalues.18}}</td>
230 96 <td {%if beam.pk == active_beam %} {{color_status.20}} {%endif%} title='{{module_messages.20}}'>{{beam.get_upvalues.19}}</td>
231 97 </tr>
232 98 <tr>
233 99 <td {%if beam.pk == active_beam %} {{color_status.17}} {%endif%} title='{{module_messages.17}}'>{{beam.get_downvalues.16}}</td>
234 100 <td {%if beam.pk == active_beam %} {{color_status.18}} {%endif%} title='{{module_messages.18}}'>{{beam.get_downvalues.17}}</td>
235 101 <td {%if beam.pk == active_beam %} {{color_status.19}} {%endif%} title='{{module_messages.19}}'>{{beam.get_downvalues.18}}</td>
236 102 <td {%if beam.pk == active_beam %} {{color_status.20}} {%endif%} title='{{module_messages.20}}'>{{beam.get_downvalues.19}}</td>
237 103 </tr>
238 104 <tr>
239 105 <td {%if beam.pk == active_beam %} {{color_status.25}} {%endif%} title='{{module_messages.25}}'>{{beam.get_upvalues.24}}</td>
240 106 <td {%if beam.pk == active_beam %} {{color_status.26}} {%endif%} title='{{module_messages.26}}'>{{beam.get_upvalues.25}}</td>
241 107 <td {%if beam.pk == active_beam %} {{color_status.27}} {%endif%} title='{{module_messages.27}}'>{{beam.get_upvalues.26}}</td>
242 108 <td {%if beam.pk == active_beam %} {{color_status.28}} {%endif%} title='{{module_messages.28}}'>{{beam.get_upvalues.27}}</td>
243 109 </tr>
244 110 <tr>
245 111 <td {%if beam.pk == active_beam %} {{color_status.25}} {%endif%} title='{{module_messages.25}}'>{{beam.get_downvalues.24}}</td>
246 112 <td {%if beam.pk == active_beam %} {{color_status.26}} {%endif%} title='{{module_messages.26}}'>{{beam.get_downvalues.25}}</td>
247 113 <td {%if beam.pk == active_beam %} {{color_status.27}} {%endif%} title='{{module_messages.27}}'>{{beam.get_downvalues.26}}</td>
248 114 <td {%if beam.pk == active_beam %} {{color_status.28}} {%endif%} title='{{module_messages.28}}'>{{beam.get_downvalues.27}}</td>
249 115 </tr>
250 116 </table>
251 117 </td>
252 118 <td>
253 119 <b>East Quarter</b>
254 <table class="east ">
120 <table class="module">
255 121 <tr>
256 122 <td {%if beam.pk == active_beam %} {{color_status.5}} t{%endif%} itle='{{module_messages.5}}'>{{beam.get_upvalues.4}}</td>
257 123 <td {%if beam.pk == active_beam %} {{color_status.6}} t{%endif%} itle='{{module_messages.6}}'>{{beam.get_upvalues.5}}</td>
258 124 <td {%if beam.pk == active_beam %} {{color_status.7}} t{%endif%} itle='{{module_messages.7}}'>{{beam.get_upvalues.6}}</td>
259 125 <td {%if beam.pk == active_beam %} {{color_status.8}} t{%endif%} itle='{{module_messages.8}}'>{{beam.get_upvalues.7}}</td>
260 126 </tr>
261 127 <tr>
262 128 <td {%if beam.pk == active_beam %} {{color_status.5}} t{%endif%} itle='{{module_messages.5}}'>{{beam.get_downvalues.4}}</td>
263 129 <td {%if beam.pk == active_beam %} {{color_status.6}} t{%endif%} itle='{{module_messages.6}}'>{{beam.get_downvalues.5}}</td>
264 130 <td {%if beam.pk == active_beam %} {{color_status.7}} t{%endif%} itle='{{module_messages.7}}'>{{beam.get_downvalues.6}}</td>
265 131 <td {%if beam.pk == active_beam %} {{color_status.8}} t{%endif%} itle='{{module_messages.8}}'>{{beam.get_downvalues.7}}</td>
266 132 </tr>
267 133 <tr>
268 134 <td {%if beam.pk == active_beam %} {{color_status.13}} {%endif%} title='{{module_messages.13}}'>{{beam.get_upvalues.12}}</td>
269 135 <td {%if beam.pk == active_beam %} {{color_status.14}} {%endif%} title='{{module_messages.14}}'>{{beam.get_upvalues.13}}</td>
270 136 <td {%if beam.pk == active_beam %} {{color_status.15}} {%endif%} title='{{module_messages.15}}'>{{beam.get_upvalues.14}}</td>
271 137 <td {%if beam.pk == active_beam %} {{color_status.16}} {%endif%} title='{{module_messages.16}}'>{{beam.get_upvalues.15}}</td>
272 138 </tr>
273 139 <tr>
274 140 <td {%if beam.pk == active_beam %} {{color_status.13}} {%endif%} title='{{module_messages.13}}'>{{beam.get_downvalues.12}}</td>
275 141 <td {%if beam.pk == active_beam %} {{color_status.14}} {%endif%} title='{{module_messages.14}}'>{{beam.get_downvalues.13}}</td>
276 142 <td {%if beam.pk == active_beam %} {{color_status.15}} {%endif%} title='{{module_messages.15}}'>{{beam.get_downvalues.14}}</td>
277 143 <td {%if beam.pk == active_beam %} {{color_status.16}} {%endif%} title='{{module_messages.16}}'>{{beam.get_downvalues.15}}</td>
278 144 </tr>
279 145 <tr>
280 146 <td {%if beam.pk == active_beam %} {{color_status.21}} {%endif%} title='{{module_messages.21}}'>{{beam.get_upvalues.20}}</td>
281 147 <td {%if beam.pk == active_beam %} {{color_status.22}} {%endif%} title='{{module_messages.22}}'>{{beam.get_upvalues.21}}</td>
282 148 <td {%if beam.pk == active_beam %} {{color_status.23}} {%endif%} title='{{module_messages.23}}'>{{beam.get_upvalues.22}}</td>
283 149 <td {%if beam.pk == active_beam %} {{color_status.24}} {%endif%} title='{{module_messages.24}}'>{{beam.get_upvalues.23}}</td>
284 150 </tr>
285 151 <tr>
286 152 <td {%if beam.pk == active_beam %} {{color_status.21}} {%endif%} title='{{module_messages.21}}'>{{beam.get_downvalues.20}}</td>
287 153 <td {%if beam.pk == active_beam %} {{color_status.22}} {%endif%} title='{{module_messages.22}}'>{{beam.get_downvalues.21}}</td>
288 154 <td {%if beam.pk == active_beam %} {{color_status.23}} {%endif%} title='{{module_messages.23}}'>{{beam.get_downvalues.22}}</td>
289 155 <td {%if beam.pk == active_beam %} {{color_status.24}} {%endif%} title='{{module_messages.24}}'>{{beam.get_downvalues.23}}</td>
290 156 </tr>
291 157 <tr>
292 158 <td {%if beam.pk == active_beam %} {{color_status.29}} {%endif%} title='{{module_messages.29}}'>{{beam.get_upvalues.28}}</td>
293 159 <td {%if beam.pk == active_beam %} {{color_status.30}} {%endif%} title='{{module_messages.30}}'>{{beam.get_upvalues.29}}</td>
294 160 <td {%if beam.pk == active_beam %} {{color_status.31}} {%endif%} title='{{module_messages.31}}'>{{beam.get_upvalues.30}}</td>
295 161 <td {%if beam.pk == active_beam %} {{color_status.32}} {%endif%} title='{{module_messages.32}}'>{{beam.get_upvalues.31}}</td>
296 162 </tr>
297 163 <tr>
298 164 <td {%if beam.pk == active_beam %} {{color_status.29}} {%endif%} title='{{module_messages.29}}'>{{beam.get_downvalues.28}}</td>
299 165 <td {%if beam.pk == active_beam %} {{color_status.30}} {%endif%} title='{{module_messages.30}}'>{{beam.get_downvalues.29}}</td>
300 166 <td {%if beam.pk == active_beam %} {{color_status.31}} {%endif%} title='{{module_messages.31}}'>{{beam.get_downvalues.30}}</td>
301 167 <td {%if beam.pk == active_beam %} {{color_status.32}} {%endif%} title='{{module_messages.32}}'>{{beam.get_downvalues.31}}</td>
302 168 </tr>
303 169 </table>
304 170 </td>
305 171 </tr>
306 172 <tr>
307 173 <td>
308 174 <b>West Quarter</b>
309 <table class="west ">
175 <table class="module">
310 176 <tr>
311 177 <td {%if beam.pk == active_beam %} {{color_status.33}} {%endif%} title='{{module_messages.33}}'>{{beam.get_upvalues.32}}</td>
312 178 <td {%if beam.pk == active_beam %} {{color_status.34}} {%endif%} title='{{module_messages.34}}'>{{beam.get_upvalues.33}}</td>
313 179 <td {%if beam.pk == active_beam %} {{color_status.35}} {%endif%} title='{{module_messages.35}}'>{{beam.get_upvalues.34}}</td>
314 180 <td {%if beam.pk == active_beam %} {{color_status.36}} {%endif%} title='{{module_messages.36}}'>{{beam.get_upvalues.35}}</td>
315 181 </tr>
316 182 <tr>
317 183 <td {%if beam.pk == active_beam %} {{color_status.33}} {%endif%} title='{{module_messages.33}}'>{{beam.get_downvalues.32}}</td>
318 184 <td {%if beam.pk == active_beam %} {{color_status.34}} {%endif%} title='{{module_messages.34}}'>{{beam.get_downvalues.33}}</td>
319 185 <td {%if beam.pk == active_beam %} {{color_status.35}} {%endif%} title='{{module_messages.35}}'>{{beam.get_downvalues.34}}</td>
320 186 <td {%if beam.pk == active_beam %} {{color_status.36}} {%endif%} title='{{module_messages.36}}'>{{beam.get_downvalues.35}}</td>
321 187 </tr>
322 188 <tr>
323 189 <td {%if beam.pk == active_beam %} {{color_status.41}} {%endif%} title='{{module_messages.41}}'>{{beam.get_upvalues.40}}</td>
324 190 <td {%if beam.pk == active_beam %} {{color_status.42}} {%endif%} title='{{module_messages.42}}'>{{beam.get_upvalues.41}}</td>
325 191 <td {%if beam.pk == active_beam %} {{color_status.43}} {%endif%} title='{{module_messages.43}}'>{{beam.get_upvalues.42}}</td>
326 192 <td {%if beam.pk == active_beam %} {{color_status.44}} {%endif%} title='{{module_messages.44}}'>{{beam.get_upvalues.43}}</td>
327 193 </tr>
328 194 <tr>
329 195 <td {%if beam.pk == active_beam %} {{color_status.41}} {%endif%} title='{{module_messages.41}}'>{{beam.get_downvalues.40}}</td>
330 196 <td {%if beam.pk == active_beam %} {{color_status.42}} {%endif%} title='{{module_messages.42}}'>{{beam.get_downvalues.41}}</td>
331 197 <td {%if beam.pk == active_beam %} {{color_status.43}} {%endif%} title='{{module_messages.43}}'>{{beam.get_downvalues.42}}</td>
332 198 <td {%if beam.pk == active_beam %} {{color_status.44}} {%endif%} title='{{module_messages.44}}'>{{beam.get_downvalues.43}}</td>
333 199 </tr>
334 200 <tr>
335 201 <td {%if beam.pk == active_beam %} {{color_status.49}} {%endif%} title='{{module_messages.49}}'>{{beam.get_upvalues.48}}</td>
336 202 <td {%if beam.pk == active_beam %} {{color_status.50}} {%endif%} title='{{module_messages.50}}'>{{beam.get_upvalues.49}}</td>
337 203 <td {%if beam.pk == active_beam %} {{color_status.51}} {%endif%} title='{{module_messages.51}}'>{{beam.get_upvalues.50}}</td>
338 204 <td {%if beam.pk == active_beam %} {{color_status.52}} {%endif%} title='{{module_messages.52}}'>{{beam.get_upvalues.51}}</td>
339 205 </tr>
340 206 <tr>
341 207 <td {%if beam.pk == active_beam %} {{color_status.49}} {%endif%} title='{{module_messages.49}}'>{{beam.get_downvalues.48}}</td>
342 208 <td {%if beam.pk == active_beam %} {{color_status.50}} {%endif%} title='{{module_messages.50}}'>{{beam.get_downvalues.49}}</td>
343 209 <td {%if beam.pk == active_beam %} {{color_status.51}} {%endif%} title='{{module_messages.51}}'>{{beam.get_downvalues.50}}</td>
344 210 <td {%if beam.pk == active_beam %} {{color_status.52}} {%endif%} title='{{module_messages.52}}'>{{beam.get_downvalues.51}}</td>
345 211 </tr>
346 212 <tr>
347 213 <td {%if beam.pk == active_beam %} {{color_status.57}} {%endif%} title='{{module_messages.57}}'>{{beam.get_upvalues.56}}</td>
348 214 <td {%if beam.pk == active_beam %} {{color_status.58}} {%endif%} title='{{module_messages.58}}'>{{beam.get_upvalues.57}}</td>
349 215 <td {%if beam.pk == active_beam %} {{color_status.59}} {%endif%} title='{{module_messages.59}}'>{{beam.get_upvalues.58}}</td>
350 216 <td {%if beam.pk == active_beam %} {{color_status.60}} {%endif%} title='{{module_messages.60}}'>{{beam.get_upvalues.59}}</td>
351 217 </tr>
352 218 <tr>
353 219 <td {%if beam.pk == active_beam %} {{color_status.57}} {%endif%} title='{{module_messages.57}}'>{{beam.get_downvalues.56}}</td>
354 220 <td {%if beam.pk == active_beam %} {{color_status.58}} {%endif%} title='{{module_messages.58}}'>{{beam.get_downvalues.57}}</td>
355 221 <td {%if beam.pk == active_beam %} {{color_status.59}} {%endif%} title='{{module_messages.59}}'>{{beam.get_downvalues.58}}</td>
356 222 <td {%if beam.pk == active_beam %} {{color_status.60}} {%endif%} title='{{module_messages.60}}'>{{beam.get_downvalues.59}}</td>
357 223 </tr>
358 224 </table>
359 225 </td>
360 226 <td>
361 227 <b>South Quarter</b>
362 <table class="south ">
228 <table class="module">
363 229 <tr>
364 230 <td {%if beam.pk == active_beam %} {{color_status.37}} {%endif%} title='{{module_messages.37}}'>{{beam.get_upvalues.36}}</td>
365 231 <td {%if beam.pk == active_beam %} {{color_status.38}} {%endif%} title='{{module_messages.38}}'>{{beam.get_upvalues.37}}</td>
366 232 <td {%if beam.pk == active_beam %} {{color_status.39}} {%endif%} title='{{module_messages.39}}'>{{beam.get_upvalues.38}}</td>
367 233 <td {%if beam.pk == active_beam %} {{color_status.40}} {%endif%} title='{{module_messages.40}}'>{{beam.get_upvalues.39}}</td>
368 234 </tr>
369 235 <tr>
370 236 <td {%if beam.pk == active_beam %} {{color_status.37}} {%endif%} title='{{module_messages.37}}'>{{beam.get_downvalues.36}}</td>
371 237 <td {%if beam.pk == active_beam %} {{color_status.38}} {%endif%} title='{{module_messages.38}}'>{{beam.get_downvalues.37}}</td>
372 238 <td {%if beam.pk == active_beam %} {{color_status.39}} {%endif%} title='{{module_messages.39}}'>{{beam.get_downvalues.38}}</td>
373 239 <td {%if beam.pk == active_beam %} {{color_status.40}} {%endif%} title='{{module_messages.40}}'>{{beam.get_downvalues.39}}</td>
374 240 </tr>
375 241 <tr>
376 242 <td {%if beam.pk == active_beam %} {{color_status.45}} {%endif%} title='{{module_messages.45}}'>{{beam.get_upvalues.44}}</td>
377 243 <td {%if beam.pk == active_beam %} {{color_status.46}} {%endif%} title='{{module_messages.46}}'>{{beam.get_upvalues.45}}</td>
378 244 <td {%if beam.pk == active_beam %} {{color_status.47}} {%endif%} title='{{module_messages.47}}'>{{beam.get_upvalues.46}}</td>
379 245 <td {%if beam.pk == active_beam %} {{color_status.48}} {%endif%} title='{{module_messages.48}}'>{{beam.get_upvalues.47}}</td>
380 246 </tr>
381 247 <tr>
382 248 <td {%if beam.pk == active_beam %} {{color_status.45}} {%endif%} title='{{module_messages.45}}'>{{beam.get_downvalues.44}}</td>
383 249 <td {%if beam.pk == active_beam %} {{color_status.46}} {%endif%} title='{{module_messages.46}}'>{{beam.get_downvalues.45}}</td>
384 250 <td {%if beam.pk == active_beam %} {{color_status.47}} {%endif%} title='{{module_messages.47}}'>{{beam.get_downvalues.46}}</td>
385 251 <td {%if beam.pk == active_beam %} {{color_status.48}} {%endif%} title='{{module_messages.48}}'>{{beam.get_downvalues.47}}</td>
386 252 </tr>
387 253 <tr>
388 254 <td {%if beam.pk == active_beam %} {{color_status.53}} {%endif%} title='{{module_messages.53}}'>{{beam.get_upvalues.52}}</td>
389 255 <td {%if beam.pk == active_beam %} {{color_status.54}} {%endif%} title='{{module_messages.54}}'>{{beam.get_upvalues.53}}</td>
390 256 <td {%if beam.pk == active_beam %} {{color_status.55}} {%endif%} title='{{module_messages.55}}'>{{beam.get_upvalues.54}}</td>
391 257 <td {%if beam.pk == active_beam %} {{color_status.56}} {%endif%} title='{{module_messages.56}}'>{{beam.get_upvalues.55}}</td>
392 258 </tr>
393 259 <tr>
394 260 <td {%if beam.pk == active_beam %} {{color_status.53}} {%endif%} title='{{module_messages.53}}'>{{beam.get_downvalues.52}}</td>
395 261 <td {%if beam.pk == active_beam %} {{color_status.54}} {%endif%} title='{{module_messages.54}}'>{{beam.get_downvalues.53}}</td>
396 262 <td {%if beam.pk == active_beam %} {{color_status.55}} {%endif%} title='{{module_messages.55}}'>{{beam.get_downvalues.54}}</td>
397 263 <td {%if beam.pk == active_beam %} {{color_status.56}} {%endif%} title='{{module_messages.56}}'>{{beam.get_downvalues.55}}</td>
398 264 </tr>
399 265 <tr>
400 266 <td {%if beam.pk == active_beam %} {{color_status.61}} {%endif%} title='{{module_messages.61}}'>{{beam.get_upvalues.60}}</td>
401 267 <td {%if beam.pk == active_beam %} {{color_status.62}} {%endif%} title='{{module_messages.62}}'>{{beam.get_upvalues.61}}</td>
402 268 <td {%if beam.pk == active_beam %} {{color_status.63}} {%endif%} title='{{module_messages.63}}'>{{beam.get_upvalues.62}}</td>
403 269 <td {%if beam.pk == active_beam %} {{color_status.64}} {%endif%} title='{{module_messages.64}}'>{{beam.get_upvalues.63}}</td>
404 270 </tr>
405 271 <tr>
406 272 <td {%if beam.pk == active_beam %} {{color_status.61}} {%endif%} title='{{module_messages.61}}'>{{beam.get_downvalues.60}}</td>
407 273 <td {%if beam.pk == active_beam %} {{color_status.62}} {%endif%} title='{{module_messages.62}}'>{{beam.get_downvalues.61}}</td>
408 274 <td {%if beam.pk == active_beam %} {{color_status.63}} {%endif%} title='{{module_messages.63}}'>{{beam.get_downvalues.62}}</td>
409 275 <td {%if beam.pk == active_beam %} {{color_status.64}} {%endif%} title='{{module_messages.64}}'>{{beam.get_downvalues.63}}</td>
410 276 </tr>
411 277 </table>
412 278 </td>
413 279 </tr>
414 280 </table>
415 281
416 282 {% if beam.id == active_beam %}
417 283 <table class="legend">
418 284 <tr>
419 285 <th colspan="2">Legend</th>
420 286 </tr>
421 287 <tr>
422 288 <td class="text-danger">
423 289 <i>RED</i>
424 290 </td>
425 291 <td>Disconnected</td>
426 292 </tr>
427 293 <tr>
428 294 <td class="text-warning">
429 295 <i>ORANGE</i>
430 296 </td>
431 297 <td>Connected</td>
432 298 </tr>
433 299 <tr>
434 300 <td class="text-success">
435 301 <i>GREEN</i>
436 302 </td>
437 303 <td>Running
438 304 </td>
439 305 </tr>
440 306 </table>
441 307 {% else %}
442 308 <div style="vertical-align: top; display:inline-block;">
443 309 <button id="send_beam{{forloop.counter}}" type="button" class="btn btn-default">
444 310 <span class="glyphicon glyphicon-export" aria-hidden="true"></span>
445 311 Change Beam</button>
446 312 </div>
447 313 {% endif %}
448 314 </div>
449 315 {% endfor %}
450 316 </div>
451 317 </div>
452 318
453 319
454 320 {% else %}
455 321 <p style="color:#b4bcc2; margin-left: 5%;">
456 322 <i>No Beams...</i>
457 323 </p>
458 324 {% endif %} {% endblock extra-content %} {% block extra-js%}
459 325 <script>
460 326 $(document).ready(function () {
461 327
462 328 {% for beam in beams %}
463 329
464 330 {% if dev_conf.operation_mode == 1 %}
465 331 $("#send_beam{{forloop.counter}}").prop('disabled', true)
466 332 {% else %}
467 333 $("#send_beam{{forloop.counter}}").click(function () {
468 334 document.location = "{% url 'url_send_beam' dev_conf.id beam.id %}";
469 335 });
470 336 {% endif %}
471 337
472 338 {% endfor %}
473 339
474 340
475 341 });
476 342 </script> {% endblock %} No newline at end of file
@@ -1,406 +1,406
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 8
9 9 from datetime import datetime
10 10 from time import sleep
11 11 import os
12 12 import io
13 13
14 14 from apps.main.models import Device, Configuration, Experiment
15 15 from apps.main.views import sidebar
16 16
17 17 from .models import ABSConfiguration, ABSBeam
18 18 from .forms import ABSConfigurationForm, ABSBeamEditForm, ABSBeamAddForm, ABSImportForm
19 19
20 20 from .utils.overJroShow import overJroShow
21 21 from .utils.OverJRO import OverJRO
22 22 # Create your views here.
23 23 import json, ast
24 24
25 25
26 26 def get_values_from_form(form_data):
27 27
28 28 sublistup = []
29 29 sublistdown = []
30 30 subtxlistup = []
31 31 subtxlistdown = []
32 32 subrxlistup = []
33 33 subrxlistdown = []
34 34
35 35 up_values_list = []
36 36 down_values_list = []
37 37 up_txvalues_list = []
38 38 down_txvalues_list = []
39 39 up_rxvalues_list = []
40 40 down_rxvalues_list = []
41 41
42 42 values_list = {}
43 43 cont = 1
44 44
45 45 for i in range(1,65):
46 46 x = float(form_data['abs_up'+str(i)])
47 47 y = float(form_data['abs_down'+str(i)])
48 48 sublistup.append(x)
49 49 sublistdown.append(y)
50 50
51 51 if str(i) in form_data.getlist('uptx_checks'):
52 52 subtxlistup.append(1)
53 53 else:
54 54 subtxlistup.append(0)
55 55 if str(i) in form_data.getlist('downtx_checks'):
56 56 subtxlistdown.append(1)
57 57 else:
58 58 subtxlistdown.append(0)
59 59
60 60 if str(i) in form_data.getlist('uprx_checks'):
61 61 subrxlistup.append(1)
62 62 else:
63 63 subrxlistup.append(0)
64 64 if str(i) in form_data.getlist('downrx_checks'):
65 65 subrxlistdown.append(1)
66 66 else:
67 67 subrxlistdown.append(0)
68 68
69 69 cont = cont+1
70 70
71 71 if cont == 9:
72 72 up_values_list.append(sublistup)
73 73 down_values_list.append(sublistdown)
74 74 sublistup = []
75 75 sublistdown = []
76 76
77 77 up_txvalues_list.append(subtxlistup)
78 78 down_txvalues_list.append(subtxlistdown)
79 79 subtxlistup = []
80 80 subtxlistdown = []
81 81 up_rxvalues_list.append(subrxlistup)
82 82 down_rxvalues_list.append(subrxlistdown)
83 83 subrxlistup = []
84 84 subrxlistdown = []
85 85 cont = 1
86 86
87 87
88 88 list_uesup = []
89 89 list_uesdown = []
90 90 for i in range(1,5):
91 91 if form_data['ues_up'+str(i)] == '':
92 92 list_uesup.append(0.0)
93 93 else:
94 94 list_uesup.append(float(form_data['ues_up'+str(i)]))
95 95
96 96 if form_data['ues_down'+str(i)] == '':
97 97 list_uesdown.append(0.0)
98 98 else:
99 99 list_uesdown.append(float(form_data['ues_down'+str(i)]))
100 100
101 101 onlyrx_list = form_data.getlist('onlyrx')
102 102 only_rx = {}
103 103 if '1' in onlyrx_list:
104 104 only_rx['up'] = True
105 105 else:
106 106 only_rx['up'] = False
107 107 if '2' in onlyrx_list:
108 108 only_rx['down'] = True
109 109 else:
110 110 only_rx['down'] = False
111 111
112 112 antenna = {'antenna_up': up_values_list, 'antenna_down': down_values_list}
113 113 tx = {'up': up_txvalues_list, 'down': down_txvalues_list}
114 114 rx = {'up': up_rxvalues_list, 'down': down_rxvalues_list}
115 115 ues = {'up': list_uesup, 'down': list_uesdown}
116 116 name = str(form_data['beam_name'])
117 117
118 118 beam_data = {'name': name, 'antenna': antenna, 'tx': tx, 'rx': rx, 'ues': ues, 'only_rx': only_rx}
119 119
120 120 return beam_data
121 121
122 122
123 123 def abs_conf(request, id_conf):
124 124
125 125 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
126 126 beams = ABSBeam.objects.filter(abs_conf=conf)
127 127 #------------Colors for Active Beam:-------------
128 128 all_status = {}
129 129 module_messages = json.loads(conf.module_messages)
130 130
131 131 color_status = {}
132 132 for i, status in enumerate(conf.module_status):
133 133 if status == '3': #Running background-color: #00cc00;
134 134 all_status['{}'.format(i+1)] = 2
135 135 color_status['{}'.format(i+1)] = 'class=text-success'#'bgcolor=#00cc00'
136 136 elif status == '1': #Connected background-color: #ee902c;
137 137 all_status['{}'.format(i+1)] = 1
138 138 color_status['{}'.format(i+1)] = 'class=text-warning'#'bgcolor=#ee902c'
139 139 else: #Disconnected background-color: #ff0000;
140 140 all_status['{}'.format(i+1)] = 0
141 141 color_status['{}'.format(i+1)] = 'class=text-danger'#'bgcolor=#FF0000'
142 142 #------------------------------------------------
143 143
144 144 kwargs = {}
145 145 kwargs['connected_modules'] = str(conf.connected_modules())+'/64'
146 146 kwargs['dev_conf'] = conf
147 147
148 148 if conf.operation_mode == 0:
149 kwargs['dev_conf_keys'] = ['name', 'operation_mode']
149 kwargs['dev_conf_keys'] = ['label', 'operation_mode']
150 150 else:
151 kwargs['dev_conf_keys'] = ['name', 'operation_mode', 'operation_value']
151 kwargs['dev_conf_keys'] = ['label', 'operation_mode', 'operation_value']
152 152
153 153 kwargs['title'] = 'ABS Configuration'
154 154 kwargs['suptitle'] = 'Details'
155 155 kwargs['button'] = 'Edit Configuration'
156 156
157 157 if conf.active_beam != 0:
158 158 kwargs['active_beam'] = int(conf.active_beam)
159 159
160 160 kwargs['beams'] = beams
161 161 kwargs['modules_status'] = all_status
162 162 kwargs['color_status'] = color_status
163 163 kwargs['module_messages'] = module_messages
164 164 ###### SIDEBAR ######
165 165 kwargs.update(sidebar(conf=conf))
166 166
167 167 return render(request, 'abs_conf.html', kwargs)
168 168
169 169
170 170 def abs_conf_edit(request, id_conf):
171 171
172 172 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
173 173
174 174 beams = ABSBeam.objects.filter(abs_conf=conf)
175 175
176 176 if request.method=='GET':
177 177 form = ABSConfigurationForm(instance=conf)
178 178
179 179 if request.method=='POST':
180 180 form = ABSConfigurationForm(request.POST, instance=conf)
181 181
182 182 if form.is_valid():
183 183 conf = form.save(commit=False)
184 184 conf.save()
185 185 return redirect('url_abs_conf', id_conf=conf.id)
186 186
187 187 ###### SIDEBAR ######
188 188 kwargs = {}
189 189
190 190 kwargs['dev_conf'] = conf
191 191 #kwargs['id_dev'] = conf.id
192 192 kwargs['id_conf'] = conf.id
193 193 kwargs['form'] = form
194 194 kwargs['abs_beams'] = beams
195 195 kwargs['title'] = 'Device Configuration'
196 196 kwargs['suptitle'] = 'Edit'
197 197 kwargs['button'] = 'Save'
198 198
199 199 kwargs['edit'] = True
200 200
201 201 return render(request, 'abs_conf_edit.html', kwargs)
202 202
203 203
204 204 def import_file(request, id_conf):
205 205
206 206 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
207 207 if request.method=='POST':
208 208 form = ABSImportForm(request.POST, request.FILES)
209 209 if form.is_valid():
210 210 try:
211 211 parms = conf.import_from_file(request.FILES['file_name'])
212 212
213 213 if parms:
214 214 conf.update_from_file(parms)
215 215 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
216 216 return redirect(conf.get_absolute_url_edit())
217 217
218 218 except Exception as e:
219 219 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], e))
220 220
221 221 else:
222 222 messages.warning(request, 'Your current configuration will be replaced')
223 223 form = ABSImportForm()
224 224
225 225 kwargs = {}
226 226 kwargs['form'] = form
227 227 kwargs['title'] = 'ABS Configuration'
228 228 kwargs['suptitle'] = 'Import file'
229 229 kwargs['button'] = 'Upload'
230 230 kwargs['previous'] = conf.get_absolute_url()
231 231
232 232 return render(request, 'abs_import.html', kwargs)
233 233
234 234
235 235 def send_beam(request, id_conf, id_beam):
236 236
237 237 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
238 238 beam = get_object_or_404(ABSBeam, pk=id_beam)
239 239 beams_list = ABSBeam.objects.filter(abs_conf=conf)
240 240 conf.active_beam = id_beam
241 241
242 242 i = 0
243 243 for b in beams_list:
244 244 if b.id == int(id_beam):
245 245 break
246 246 else:
247 247 i += 1
248 248 beam_pos = i + 1 #Estandarizar
249 249 print '%s Position: %s' % (beam.name, str(beam_pos))
250 250 conf.send_beam(beam_pos)
251 251
252 252 return redirect('url_abs_conf', conf.id)
253 253
254 254
255 255 def add_beam(request, id_conf):
256 256
257 257 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
258 258 confs = Configuration.objects.all()
259 259
260 260 if request.method=='GET':
261 261 form = ABSBeamAddForm()
262 262
263 263 if request.method=='POST':
264 264 form = ABSBeamAddForm(request.POST)
265 265
266 266 beam_data = get_values_from_form(request.POST)
267 267
268 268 new_beam = ABSBeam(
269 269 name = beam_data['name'],
270 270 antenna = json.dumps(beam_data['antenna']),
271 271 abs_conf = conf,
272 272 tx = json.dumps(beam_data['tx']),
273 273 rx = json.dumps(beam_data['rx']),
274 274 ues = json.dumps(beam_data['ues']),
275 275 only_rx = json.dumps(beam_data['only_rx'])
276 276 )
277 277 new_beam.save()
278 278 messages.success(request, 'Beam: "%s" has been added.' % new_beam.name)
279 279
280 280 return redirect('url_edit_abs_conf', conf.id)
281 281
282 282 ###### SIDEBAR ######
283 283 kwargs = {}
284 284
285 285 #kwargs['dev_conf'] = conf.device
286 286 #kwargs['id_dev'] = conf.device
287 287 kwargs['id_conf'] = conf.id
288 288 kwargs['form'] = form
289 289 kwargs['title'] = 'ABS Beams'
290 290 kwargs['suptitle'] = 'Add Beam'
291 291 kwargs['button'] = 'Add'
292 292 kwargs['no_sidebar'] = True
293 293
294 294 #kwargs['previous'] = conf.get_absolute_url_edit()
295 295 kwargs['edit'] = True
296 296
297 297 return render(request, 'abs_add_beam.html', kwargs)
298 298
299 299
300 300 def edit_beam(request, id_conf, id_beam):
301 301
302 302 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
303 303 beam = get_object_or_404(ABSBeam, pk=id_beam)
304 304
305 305 if request.method=='GET':
306 306 form = ABSBeamEditForm(initial={'beam': beam})
307 307
308 308 if request.method=='POST':
309 309 form = ABSBeamEditForm(request.POST)
310 310
311 311 beam_data = get_values_from_form(request.POST)
312 312
313 313 beam.dict_to_parms(beam_data)
314 314 beam.save()
315 315
316 316 messages.success(request, 'Beam: "%s" has been updated.' % beam.name)
317 317
318 318 return redirect('url_edit_abs_conf', conf.id)
319 319
320 320 ###### SIDEBAR ######
321 321 kwargs = {}
322 322
323 323 kwargs['id_conf'] = conf.id
324 324 kwargs['form'] = form
325 325 kwargs['title'] = 'ABS Beams'
326 326 kwargs['suptitle'] = 'Edit Beam'
327 327 kwargs['button'] = 'Save'
328 328 kwargs['no_sidebar'] = True
329 329
330 330 #kwargs['previous'] = conf.get_absolute_url_edit()
331 331 kwargs['edit'] = True
332 332
333 333 return render(request, 'abs_edit_beam.html', kwargs)
334 334
335 335
336 336
337 337 def remove_beam(request, id_conf, id_beam):
338 338
339 339 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
340 340 beam = get_object_or_404(ABSBeam, pk=id_beam)
341 341
342 342 if request.method=='POST':
343 343 if beam:
344 344 try:
345 345 beam.remove_beamfromlist()
346 346 beam.delete()
347 347 messages.success(request, 'Beam: "%s" has been deleted.' % beam)
348 348 except:
349 349 messages.error(request, 'Unable to delete beam: "%s".' % beam)
350 350
351 351 return redirect('url_edit_abs_conf', conf.id)
352 352
353 353 ###### SIDEBAR ######
354 354 kwargs = {}
355 355
356 356 kwargs['object'] = beam
357 357 kwargs['delete'] = True
358 358 kwargs['title'] = 'Delete'
359 359 kwargs['suptitle'] = 'Beam'
360 360 kwargs['previous'] = conf.get_absolute_url_edit()
361 361 return render(request, 'confirm.html', kwargs)
362 362
363 363
364 364
365 365 def plot_patterns(request, id_conf, id_beam=None):
366 366
367 367 kwargs = {}
368 368 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
369 369 beams = ABSBeam.objects.filter(abs_conf=conf)
370 370
371 371 if id_beam:
372 372 beam = get_object_or_404(ABSBeam, pk=id_beam)
373 373 kwargs['beam'] = beam
374 374
375 375 ###### SIDEBAR ######
376 376
377 377 kwargs['dev_conf'] = conf.device
378 378 kwargs['id_dev'] = conf.device
379 379 kwargs['id_conf'] = conf.id
380 380 kwargs['abs_beams'] = beams
381 381 kwargs['title'] = 'ABS Patterns'
382 382 kwargs['suptitle'] = conf.name
383 383 kwargs['no_sidebar'] = True
384 384
385 385 return render(request, 'abs_patterns.html', kwargs)
386 386
387 387
388 388 def plot_pattern(request, id_conf, id_beam, antenna):
389 389
390 390 if antenna=='down':
391 391 sleep(3)
392 392
393 393 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
394 394 beam = get_object_or_404(ABSBeam, pk=id_beam)
395 395 just_rx = 1 if json.loads(beam.only_rx)[antenna] else 0
396 396 phases = json.loads(beam.antenna)['antenna_{}'.format(antenna)]
397 397 gain_tx = json.loads(beam.tx)[antenna]
398 398 gain_rx = json.loads(beam.rx)[antenna]
399 399 ues = json.loads(beam.ues)[antenna]
400 400 newOverJro = overJroShow(beam.name)
401 401 fig = newOverJro.plotPattern2(datetime.today(), phases, gain_tx, gain_rx, ues, just_rx)
402 402 buf = io.BytesIO()
403 403 fig.savefig(buf, format='png')
404 404 response = HttpResponse(buf.getvalue(), content_type='image/png')
405 405 return response
406 406 No newline at end of file
@@ -1,33 +1,32
1 1 from django import forms
2 2 from apps.main.models import Device
3 3 from .models import CGSConfiguration
4 4
5 5 class CGSConfigurationForm(forms.ModelForm):
6 6
7 7 def __init__(self, *args, **kwargs):
8 8 #request = kwargs.pop('request')
9 9 super(CGSConfigurationForm, self).__init__(*args, **kwargs)
10 10
11 11 instance = getattr(self, 'instance', None)
12 12
13 13 if instance and instance.pk:
14 14
15 15 devices = Device.objects.filter(device_type__name='cgs')
16 16
17 17 if instance.experiment:
18 18 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
19 19
20 20 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
21 21
22 22 def clean(self):
23 23 return
24 24
25 25 class Meta:
26 26 model = CGSConfiguration
27 exclude = ('type', 'parameters', 'status')
28 #fields = ('experiment', 'device', 'freq0', 'freq1', 'freq2', 'freq3')
27 exclude = ('type', 'parameters', 'status', 'author', 'hash')
29 28
30 29
31 30 class UploadFileForm(forms.Form):
32 31 title = forms.CharField(label='Extension Type', widget=forms.TextInput(attrs={'readonly':'readonly'}))
33 32 file = forms.FileField()
@@ -1,27 +1,27
1 1 from django import forms
2 2 from apps.main.models import Device
3 3 from .models import DDSConfiguration
4 4
5 5 # from django.core.validators import MinValueValidator, MaxValueValidator
6 6
7 7 class DDSConfigurationForm(forms.ModelForm):
8 8
9 9 def __init__(self, *args, **kwargs):
10 10
11 11 super(DDSConfigurationForm, self).__init__(*args, **kwargs)
12 12
13 13 instance = getattr(self, 'instance', None)
14 14
15 15 if instance and instance.pk:
16 16
17 17 devices = Device.objects.filter(device_type__name='dds')
18 18
19 19 #if instance.experiment:
20 20 # self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
21 21
22 22 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
23 23
24 24
25 25 class Meta:
26 26 model = DDSConfiguration
27 exclude = ('type', 'parameters', 'status') No newline at end of file
27 exclude = ('type', 'parameters', 'status', 'author', 'hash') No newline at end of file
@@ -1,74 +1,74
1 1 # Create your views here.
2 2 from django.shortcuts import redirect, render, get_object_or_404
3 3
4 4 # from apps.main.models import Experiment, Configuration
5 5 from apps.main.views import sidebar
6 6
7 7 from .models import DDSConfiguration
8 8 from .forms import DDSConfigurationForm
9 9 # Create your views here.
10 10
11 11 def dds_conf(request, id_conf):
12 12
13 13 conf = get_object_or_404(DDSConfiguration, pk=id_conf)
14 14
15 15 kwargs = {}
16 16
17 17 kwargs['status'] = conf.device.get_status_display()
18 18
19 19 # if not kwargs['connected']:
20 20 # messages.error(request, message=answer)
21 21
22 22 kwargs['dev_conf'] = conf
23 kwargs['dev_conf_keys'] = ['name',
23 kwargs['dev_conf_keys'] = [
24 24 'clock',
25 25 'multiplier',
26 26 'frequencyA_Mhz',
27 27 'frequencyA',
28 28 'frequencyB_Mhz',
29 29 'frequencyB',
30 30 'phaseA_degrees',
31 31 'phaseB_degrees',
32 32 'modulation',
33 33 'amplitude_enabled',
34 34 'amplitudeI',
35 35 'amplitudeQ']
36 36
37 37 kwargs['title'] = 'DDS Configuration'
38 38 kwargs['suptitle'] = 'Details'
39 39
40 40 kwargs['button'] = 'Edit Configuration'
41 41
42 42 ###### SIDEBAR ######
43 43 kwargs.update(sidebar(conf=conf))
44 44
45 45 return render(request, 'dds_conf.html', kwargs)
46 46
47 47 def dds_conf_edit(request, id_conf):
48 48
49 49 conf = get_object_or_404(DDSConfiguration, pk=id_conf)
50 50
51 51 if request.method=='GET':
52 52 form = DDSConfigurationForm(instance=conf)
53 53
54 54 if request.method=='POST':
55 55 form = DDSConfigurationForm(request.POST, instance=conf)
56 56
57 57 if form.is_valid():
58 58 conf = form.save(commit=False)
59 59
60 60 if conf.verify_frequencies():
61 61
62 62 conf.save()
63 63 return redirect('url_dds_conf', id_conf=conf.id)
64 64
65 65 ##ERRORS
66 66
67 67 kwargs = {}
68 68 kwargs['id_dev'] = conf.id
69 69 kwargs['form'] = form
70 70 kwargs['title'] = 'Device Configuration'
71 71 kwargs['suptitle'] = 'Edit'
72 72 kwargs['button'] = 'Save'
73 73
74 74 return render(request, 'dds_conf_edit.html', kwargs)
@@ -1,7 +1,7
1 1 from django.contrib import admin
2 from .models import JARSConfiguration, JARSfilter
2 from .models import JARSConfiguration, JARSFilter
3 3
4 4 # Register your models here.
5 5
6 6 admin.site.register(JARSConfiguration)
7 admin.site.register(JARSfilter)
7 admin.site.register(JARSFilter)
@@ -1,3 +1,30
1 [{"fields": {"name": "49_92MHz_clock60MHz_F1KHz_12_25_2", "clock": 60, "mult": 5, "fch": 49.92, "fch_decimal": 721554506, "filter_fir": 2, "filter_2": 12, "filter_5": 25}, "model": "jars.jarsfilter", "pk": 1},
2 {"fields": {"name": "49_920MHz_clock60MHz_F1MHz_10_1_6", "clock": 60, "mult": 5, "fch": 49.92, "fch_decimal": 721554506, "filter_fir": 6, "filter_2": 10, "filter_5": 1}, "model": "jars.jarsfilter", "pk": 2}
3 ]
1 [
2 {
3 "fields": {
4 "name": "49_92MHz_clock60MHz_F1KHz_12_25_2",
5 "clock": 60,
6 "multiplier": 5,
7 "frequency": 49.92,
8 "f_decimal": 721554506,
9 "fir": 2,
10 "cic_2": 12,
11 "cic_5": 25
12 },
13 "model": "jars.jarsfilter",
14 "pk": 1
15 },
16 {
17 "fields": {
18 "name": "49_920MHz_clock60MHz_F1MHz_10_1_6",
19 "clock": 60,
20 "multiplier": 5,
21 "frequency": 49.92,
22 "f_decimal": 721554506,
23 "fir": 6,
24 "cic_2": 10,
25 "cic_5": 1
26 },
27 "model": "jars.jarsfilter",
28 "pk": 2
29 }
30 ] No newline at end of file
@@ -1,115 +1,102
1 1 import os
2 2
3 3 from django import forms
4 4 from apps.main.models import Device, Experiment
5 from .models import JARSConfiguration, JARSfilter
5 from .models import JARSConfiguration, JARSFilter
6 6 from .widgets import SpectralWidget
7 7 from apps.main.forms import add_empty_choice
8 8
9 9 def create_choices_from_model(model, filter_id=None):
10 10
11 11 #instance = globals()[model]
12 12 choices = model.objects.all().values_list('pk', 'name')
13 13 choices = add_empty_choice(choices)
14 14 return choices
15 15
16 16 class JARSConfigurationForm(forms.ModelForm):
17 17 def __init__(self, *args, **kwargs):
18 18 super(JARSConfigurationForm, self).__init__(*args, **kwargs)
19 19 instance = getattr(self, 'instance', None)
20 20
21 21 if instance and instance.pk:
22 22 devices = Device.objects.filter(device_type__name='jars')
23
24 #if instance.experiment:
25 # experiments = Experiment.objects.filter(pk=instance.experiment.id)
26 # self.fields['experiment'].widget.choices = [(experiment.id, experiment) for experiment in experiments]
27
28 23 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
29 #self.fields['spectral'].widget = SpectralWidget()
30 24 self.fields['spectral_number'].widget.attrs['readonly'] = True
31 25 self.fields['spectral'].widget = SpectralWidget()
32 26
33 #-------------JARS Configuration needs an Experiment-----------------
34 #def clean(self):
35 # cleaned_data = super(JARSConfigurationForm, self).clean()
36 # experiment = cleaned_data.get('experiment')
37 # if not experiment:
38 # msg = "Error: Jars Configuration needs an Experiment"
39 # self.add_error('experiment', msg)
40
41 27 class Meta:
42 28 model = JARSConfiguration
43 exclude = ('type', 'parameters', 'status', 'filter_parms')
44
29 exclude = ('type', 'parameters', 'status', 'filter_parms', 'author', 'hash', 'filter')
45 30
46 class JARSfilterForm(forms.ModelForm):
31 class JARSFilterForm(forms.ModelForm):
47 32 def __init__(self, *args, **kwargs):
48 super(JARSfilterForm, self).__init__(*args, **kwargs)
33 super(JARSFilterForm, self).__init__(*args, **kwargs)
49 34 instance = getattr(self, 'instance', None)
50 35
51 self.fields['fch_decimal'].widget.attrs['readonly'] = True
36 self.fields['f_decimal'].widget.attrs['readonly'] = True
52 37
53 38 if 'initial' in kwargs:
54 if 'filter_id' not in kwargs['initial']:
55 self.fields.pop('name')
56 else:
57 self.fields['name'] = forms.ChoiceField(choices=create_choices_from_model(JARSfilter))
58 filter_id = kwargs['initial']['filter_id']
59
60 if filter_id == 0:
61 for value in self.fields:
62 if value != 'name':
63 self.fields.pop(value)
64 self.fields['name'].label = "Filter Template Name"
65 else:
66 self.fields['name'] = forms.ChoiceField(choices=create_choices_from_model(JARSfilter, kwargs['initial']['filter_id']))
67 jars_filter = JARSfilter.objects.get(pk=kwargs['initial']['filter_id'])
68 labels = [f.name for f in jars_filter._meta.get_fields()]
69
70 for label in ['id']:
71 labels.remove(label)
72 for label in labels:
73 self.fields['name'].initial = kwargs['initial']['filter_id']
74 self.fields[label].initial = getattr(jars_filter,label)
75 self.fields['name'].label = "Filter Template Name"
39 self.fields['filter_template'] = forms.ChoiceField(
40 choices=create_choices_from_model(JARSFilter),
41 initial = kwargs['initial']['id']
42 )
43 # self.fields['name'].initial = kwargs['initial']['id']
44
45 # filter_id = kwargs['initial']['filter_id']
46
47 # if filter_id == 0:
48 # for value in self.fields:
49 # if value != 'name':
50 # self.fields.pop(value)
51 # self.fields['name'].label = "Filter Template Name"
52 # else:
53 # self.fields['name'] = forms.ChoiceField(choices=create_choices_from_model(JARSFilter, kwargs['initial']['filter_id']))
54 # jars_filter = JARSFilter.objects.get(pk=kwargs['initial']['filter_id'])
55 # labels = [f.name for f in jars_filter._meta.get_fields()]
56
57 # for label in ['id']:
58 # labels.remove(label)
59 # for label in labels:
60 # self.fields['name'].initial = kwargs['initial']['filter_id']
61 # self.fields[label].initial = getattr(jars_filter,label)
62 # self.fields['name'].label = "Filter Template Name"
76 63
77 64 class Meta:
78 model = JARSfilter
79 exclude = ('type', 'parameters', 'status')
65 model = JARSFilter
66 exclude = ('name', )
80 67
81 68
82 69 class ExtFileField(forms.FileField):
83 70 """
84 71 Same as forms.FileField, but you can specify a file extension whitelist.
85 72
86 73 >>> from django.core.files.uploadedfile import SimpleUploadedFile
87 74 >>>
88 75 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
89 76 >>>
90 77 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
91 78 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
92 79 >>>
93 80 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
94 81 Traceback (most recent call last):
95 82 ...
96 83 ValidationError: [u'Not allowed filetype!']
97 84 """
98 85 def __init__(self, *args, **kwargs):
99 86 extensions = kwargs.pop("extensions")
100 87 self.extensions = [i.lower() for i in extensions]
101 88
102 89 super(ExtFileField, self).__init__(*args, **kwargs)
103 90
104 91 def clean(self, *args, **kwargs):
105 92 data = super(ExtFileField, self).clean(*args, **kwargs)
106 93 filename = data.name
107 94 ext = os.path.splitext(filename)[1]
108 95 ext = ext.lower()
109 96 if ext not in self.extensions:
110 97 raise forms.ValidationError('Not allowed file type: %s' % ext)
111 98
112 99
113 100 class JARSImportForm(forms.Form):
114 101
115 102 file_name = ExtFileField(extensions=['.racp','.json'])
@@ -1,335 +1,389
1 1 import json
2 2 import requests
3 3
4 4 from django.db import models
5 5 from django.core.validators import MinValueValidator, MaxValueValidator
6 6 from django.core.urlresolvers import reverse
7 7
8 8 from apps.main.models import Configuration
9 9 from apps.main.utils import Params
10 10 from .utils import create_jarsfiles
11 11
12 12 # Create your models here.
13 13
14 14 EXPERIMENT_TYPE = (
15 (0, 'RAW_DATA'),
16 (1, 'PDATA'),
17 )
15 (0, 'RAW_DATA'),
16 (1, 'PDATA'),
17 )
18 18
19 19 DATA_TYPE = (
20 (0, 'SHORT'),
21 (1, 'FLOAT'),
22 )
20 (0, 'SHORT'),
21 (1, 'FLOAT'),
22 )
23 23
24 24 DECODE_TYPE = (
25 (0, 'None'),
26 (1, 'TimeDomain'),
27 (2, 'FreqDomain'),
28 (3, 'InvFreqDomain'),
29 )
25 (0, 'None'),
26 (1, 'TimeDomain'),
27 (2, 'FreqDomain'),
28 (3, 'InvFreqDomain'),
29 )
30 30
31 class JARSfilter(models.Model):
31 FILTER = '{"id":1, "clock": 60, "multiplier": 5, "frequency": 49.92, "f_decimal": 721554506, "fir": 2, "cic_2": 12, "cic_5": 25}'
32
33 class JARSFilter(models.Model):
32 34
33 35 JARS_NBITS = 32
34 36
35 name = models.CharField(max_length=60, unique=True, default='')
36 clock = models.FloatField(verbose_name='Clock In (MHz)',validators=[MinValueValidator(5), MaxValueValidator(75)], null=True, default=60)
37 mult = models.PositiveIntegerField(verbose_name='Multiplier',validators=[MinValueValidator(1), MaxValueValidator(20)], default=5)
38 fch = models.FloatField(verbose_name='Frequency (MHz)', validators=[MaxValueValidator(150)], null=True, default=49.9200)
39 fch_decimal = models.BigIntegerField(verbose_name='Frequency (Decimal)',validators=[MinValueValidator(-9223372036854775808), MaxValueValidator(2**JARS_NBITS-1)], null=True, default=721554505)
40 filter_2 = models.PositiveIntegerField(verbose_name='Filter 2',validators=[MinValueValidator(2), MaxValueValidator(100)], default = 10)
41 filter_5 = models.PositiveIntegerField(verbose_name='Filter 5',validators=[MinValueValidator(1), MaxValueValidator(100)], default = 1)
42 filter_fir = models.PositiveIntegerField(verbose_name='FIR Filter',validators=[MinValueValidator(1), MaxValueValidator(100)], default = 6)
37 name = models.CharField(verbose_name='Name', max_length=60, unique=True, default='')
38 clock = models.FloatField(verbose_name='Clock In (MHz)', validators=[
39 MinValueValidator(5), MaxValueValidator(75)], null=True, default=60)
40 multiplier = models.PositiveIntegerField(verbose_name='Multiplier', validators=[
41 MinValueValidator(1), MaxValueValidator(20)], default=5)
42 frequency = models.FloatField(verbose_name='Frequency (MHz)', validators=[
43 MaxValueValidator(150)], null=True, default=49.9200)
44 f_decimal = models.BigIntegerField(verbose_name='Frequency (Decimal)', validators=[
45 MinValueValidator(-9223372036854775808), MaxValueValidator(2**JARS_NBITS-1)], null=True, default=721554505)
46 cic_2 = models.PositiveIntegerField(verbose_name='CIC2', validators=[
47 MinValueValidator(2), MaxValueValidator(100)], default=10)
48 scale_cic_2 = models.PositiveIntegerField(verbose_name='Scale CIC2', validators=[
49 MinValueValidator(0), MaxValueValidator(6)], default=1)
50 cic_5 = models.PositiveIntegerField(verbose_name='CIC5', validators=[
51 MinValueValidator(1), MaxValueValidator(100)], default=1)
52 scale_cic_5 = models.PositiveIntegerField(verbose_name='Scale CIC5', validators=[
53 MinValueValidator(0), MaxValueValidator(20)], default=5)
54 fir = models.PositiveIntegerField(verbose_name='FIR', validators=[
55 MinValueValidator(1), MaxValueValidator(100)], default=6)
56 scale_fir = models.PositiveIntegerField(verbose_name='Scale FIR', validators=[
57 MinValueValidator(0), MaxValueValidator(7)], default=3)
58 number_taps = models.PositiveIntegerField(verbose_name='Number of taps', validators=[
59 MinValueValidator(1), MaxValueValidator(256)], default=4)
60 taps = models.CharField(verbose_name='Taps', max_length=256, default='')
43 61
44 62 class Meta:
45 63 db_table = 'jars_filters'
46 64
47 65 def __unicode__(self):
48 66 return u'%s' % (self.name)
49 67
68 def jsonify(self):
69
70 data = {}
71 ignored = ()
72
73 for field in self._meta.fields:
74 if field.name in ignored:
75 continue
76 data[field.name] = field.value_from_object(self)
77
78 return data
79
50 80 def parms_to_dict(self):
51 81
52 82 parameters = {}
53 83
54 #parameters['name'] = self.name
55 parameters['clock'] = float(self.clock)
56 parameters['mult'] = int(self.mult)
57 parameters['fch'] = float(self.fch)
58 parameters['fch_decimal'] = int(self.fch)
59 parameters['filter_fir'] = int(self.filter_fir)
60 parameters['filter_2'] = int(self.filter_2)
61 parameters['filter_5'] = int(self.filter_5)
84 parameters['name'] = self.name
85 parameters['clock'] = float(self.clock)
86 parameters['multiplier'] = int(self.multiplier)
87 parameters['frequency'] = float(self.frequency)
88 parameters['f_decimal'] = int(self.frequency)
89 parameters['fir'] = int(self.fir)
90 parameters['cic_2'] = int(self.cic_2)
91 parameters['cic_5'] = int(self.cic_5)
62 92
63 93 return parameters
64 94
65 95 def dict_to_parms(self, parameters):
66 96
67 #self.name = parameters['name']
68 self.clock = parameters['clock']
69 self.mult = parameters['mult']
70 self.fch = parameters['fch']
71 self.fch_decimal = parameters['fch_decimal']
72 self.filter_fir = parameters['filter_fir']
73 self.filter_2 = parameters['filter_2']
74 self.filter_5 = parameters['filter_5']
97 self.name = parameters['name']
98 self.clock = parameters['clock']
99 self.multiplier = parameters['multiplier']
100 self.frequency = parameters['frequency']
101 self.f_decimal = parameters['f_decimal']
102 self.fir = parameters['fir']
103 self.cic_2 = parameters['cic_2']
104 self.cic_5 = parameters['cic_5']
75 105
76 106
77 107 class JARSConfiguration(Configuration):
78 108
79 ADC_RESOLUTION = 8
109 ADC_RESOLUTION = 8
80 110 PCI_DIO_BUSWIDTH = 32
81 HEADER_VERSION = 1103
82 BEGIN_ON_START = True
83 REFRESH_RATE = 1
84
85 exp_type = models.PositiveIntegerField(verbose_name='Experiment Type', choices=EXPERIMENT_TYPE, default=0)
86 cards_number = models.PositiveIntegerField(verbose_name='Number of Cards', validators=[MinValueValidator(1), MaxValueValidator(4)], default = 1)
87 channels_number = models.PositiveIntegerField(verbose_name='Number of Channels', validators=[MinValueValidator(1), MaxValueValidator(8)], default = 5)
88 channels = models.CharField(verbose_name='Channels', max_length=15, default = '1,2,3,4,5')
89 data_type = models.PositiveIntegerField(verbose_name='Data Type', choices=DATA_TYPE, default=0)
90 raw_data_blocks = models.PositiveIntegerField(verbose_name='Raw Data Blocks', validators=[MaxValueValidator(5000)], default=60)
91 profiles_block = models.PositiveIntegerField(verbose_name='Profiles Per Block', default=400)
92 acq_profiles = models.PositiveIntegerField(verbose_name='Acquired Profiles', default=400)
93 ftp_interval = models.PositiveIntegerField(verbose_name='FTP Interval', default=60)
94 fftpoints = models.PositiveIntegerField(verbose_name='FFT Points',default=16)
95 cohe_integr_str = models.PositiveIntegerField(verbose_name='Coh. Int. Stride',validators=[MinValueValidator(1)], default=30)
96 cohe_integr = models.PositiveIntegerField(verbose_name='Coherent Integrations',validators=[MinValueValidator(1)], default=30)
97 incohe_integr = models.PositiveIntegerField(verbose_name='Incoherent Integrations',validators=[MinValueValidator(1)], default=30)
98 decode_data = models.PositiveIntegerField(verbose_name='Decode Data', choices=DECODE_TYPE, default=0)
99 post_coh_int = models.BooleanField(verbose_name='Post Coherent Integration', default=False)
100 spectral_number = models.PositiveIntegerField(verbose_name='# Spectral Combinations',validators=[MinValueValidator(1)], default=1)
101 spectral = models.CharField(verbose_name='Combinations', max_length=5000, default = '[0, 0],')
102 create_directory = models.BooleanField(verbose_name='Create Directory Per Day', default=True)
103 include_expname = models.BooleanField(verbose_name='Experiment Name in Directory', default=False)
111 HEADER_VERSION = 1103
112 BEGIN_ON_START = True
113 REFRESH_RATE = 1
114
115 exp_type = models.PositiveIntegerField(
116 verbose_name='Experiment Type', choices=EXPERIMENT_TYPE, default=0)
117 cards_number = models.PositiveIntegerField(verbose_name='Number of Cards', validators=[
118 MinValueValidator(1), MaxValueValidator(4)], default=1)
119 channels_number = models.PositiveIntegerField(verbose_name='Number of Channels', validators=[
120 MinValueValidator(1), MaxValueValidator(8)], default=5)
121 channels = models.CharField(
122 verbose_name='Channels', max_length=15, default='1,2,3,4,5')
123 data_type = models.PositiveIntegerField(
124 verbose_name='Data Type', choices=DATA_TYPE, default=0)
125 raw_data_blocks = models.PositiveIntegerField(
126 verbose_name='Raw Data Blocks', validators=[MaxValueValidator(5000)], default=60)
127 profiles_block = models.PositiveIntegerField(
128 verbose_name='Profiles Per Block', default=400)
129 acq_profiles = models.PositiveIntegerField(
130 verbose_name='Acquired Profiles', default=400)
131 ftp_interval = models.PositiveIntegerField(
132 verbose_name='FTP Interval', default=60)
133 fftpoints = models.PositiveIntegerField(
134 verbose_name='FFT Points', default=16)
135 cohe_integr_str = models.PositiveIntegerField(
136 verbose_name='Coh. Int. Stride', validators=[MinValueValidator(1)], default=30)
137 cohe_integr = models.PositiveIntegerField(
138 verbose_name='Coherent Integrations', validators=[MinValueValidator(1)], default=30)
139 incohe_integr = models.PositiveIntegerField(
140 verbose_name='Incoherent Integrations', validators=[MinValueValidator(1)], default=30)
141 decode_data = models.PositiveIntegerField(
142 verbose_name='Decode Data', choices=DECODE_TYPE, default=0)
143 post_coh_int = models.BooleanField(
144 verbose_name='Post Coherent Integration', default=False)
145 spectral_number = models.PositiveIntegerField(
146 verbose_name='# Spectral Combinations', validators=[MinValueValidator(1)], default=1)
147 spectral = models.CharField(
148 verbose_name='Combinations', max_length=5000, default='[0, 0],')
149 create_directory = models.BooleanField(
150 verbose_name='Create Directory Per Day', default=True)
151 include_expname = models.BooleanField(
152 verbose_name='Experiment Name in Directory', default=False)
104 153 #view_raw_data = models.BooleanField(verbose_name='View Raw Data', default=True)
105 save_ch_dc = models.BooleanField(verbose_name='Save Channels DC', default=True)
106 save_data = models.BooleanField(verbose_name='Save Data', default=True)
107 filter_parms = models.CharField(max_length=10000, default='{"clock": 60, "mult": 5, "fch": 49.92, "fch_decimal": 721554506, "filter_fir": 2, "filter_2": 12, "filter_5": 25}')
154 save_ch_dc = models.BooleanField(
155 verbose_name='Save Channels DC', default=True)
156 save_data = models.BooleanField(verbose_name='Save Data', default=True)
157 filter_parms = models.CharField(
158 max_length=10000, default=FILTER)
159 filter = models.ForeignKey(
160 'JARSFilter', verbose_name='Filter', null=True, blank=True, on_delete=models.CASCADE)
108 161
109 162 class Meta:
110 163 db_table = 'jars_configurations'
111 164
112 165 def filter_resolution(self):
113 filter_parms = eval(self.filter_parms)
114 if filter_parms.__class__.__name__=='str':
115 filter_parms = eval(filter_parms)
116
117 filter_clock = float(filter_parms['clock'])
118 filter_2 = filter_parms['filter_2']
119 filter_5 = filter_parms['filter_5']
120 filter_fir = filter_parms['filter_fir']
121
122 resolution = round((filter_clock/(filter_2*filter_5*filter_fir)),2)
166 filter_parms = json.loads(self.filter_parms)
167 clock = float(filter_parms['clock'])
168 cic_2 = filter_parms['cic_2']
169 cic_5 = filter_parms['cic_5']
170 fir = filter_parms['fir']
171 resolution = round((clock/(cic_2*cic_5*fir)), 2)
123 172 return resolution
124 173
125 174 def dict_to_parms(self, params, id=None):
126
175
127 176 if id is not None:
128 177 data = Params(params).get_conf(id_conf=id)
129 178 else:
130 179 data = Params(params).get_conf(dtype='jars')
131 180 data['filter_parms'] = params['filter_parms']
132
133 self.name = data['name']
134 self.exp_type = data['exp_type']
181
182 # self.name = data['name']
183 self.exp_type = data['exp_type']
135 184 #----PDATA----
136 185 if self.exp_type == 1:
137 self.incohe_integr = data['incohe_integr']
186 self.incohe_integr = data['incohe_integr']
138 187 self.spectral_number = data['spectral_number']
139 self.spectral = data['spectral']
140 self.fftpoints = data['fftpoints']
141 self.save_ch_dc = data['save_ch_dc']
188 self.spectral = data['spectral']
189 self.fftpoints = data['fftpoints']
190 self.save_ch_dc = data['save_ch_dc']
142 191 else:
143 192 self.raw_data_blocks = data['raw_data_blocks']
144 #----PDATA----
145 self.cards_number = data['cards_number']
193 #----PDATA----
194 self.cards_number = data['cards_number']
146 195 self.channels_number = data['channels_number']
147 self.channels = data['channels']
148 self.data_type = data['data_type']
149 self.profiles_block = data['profiles_block']
150 self.acq_profiles = data['acq_profiles']
151 self.ftp_interval = data['ftp_interval']
196 self.channels = data['channels']
197 self.data_type = data['data_type']
198 self.profiles_block = data['profiles_block']
199 self.acq_profiles = data['acq_profiles']
200 self.ftp_interval = data['ftp_interval']
152 201 self.cohe_integr_str = data['cohe_integr_str']
153 self.cohe_integr = data['cohe_integr']
202 self.cohe_integr = data['cohe_integr']
154 203 #----DECODE----
155 self.decode_data = data['decode_data']
156 self.post_coh_int = data['post_coh_int']
204 self.decode_data = data['decode_data']
205 self.post_coh_int = data['post_coh_int']
157 206 #----DECODE----
158 207 self.create_directory = data['create_directory']
159 self.include_expname = data['include_expname']
160 self.save_data = data['save_data']
161 self.filter_parms = json.dumps(data['filter_parms'])
162
208 self.include_expname = data['include_expname']
209 self.save_data = data['save_data']
210 self.filter_parms = json.dumps(data['filter_parms'])
211
163 212 self.save()
164 213
165 214 def parms_to_text(self, file_format='jars'):
166 215
167 216 data = self.experiment.parms_to_dict()
168 217
169 218 for key in data['configurations']['allIds']:
170 219 if data['configurations']['byId'][key]['device_type'] in ('dds', 'cgs'):
171 220 data['configurations']['allIds'].remove(key)
172 221 data['configurations']['byId'].pop(key)
173 222 elif data['configurations']['byId'][key]['device_type'] == 'jars':
174 data['configurations']['byId'][key] = self.parms_to_dict()['configurations']['byId'][str(self.pk)]
223 data['configurations']['byId'][key] = self.parms_to_dict(
224 )['configurations']['byId'][str(self.pk)]
175 225 elif data['configurations']['byId'][key]['device_type'] == 'rc':
176 226 data['configurations']['byId'][key]['pulses'] = ''
177 227 data['configurations']['byId'][key]['delays'] = ''
178 rc_ids = [pk for pk in data['configurations']['allIds'] if data['configurations']['byId'][pk]['device_type']=='rc']
179 mix_ids = [pk for pk in rc_ids if data['configurations']['byId'][pk]['mix']]
180
228 rc_ids = [pk for pk in data['configurations']['allIds']
229 if data['configurations']['byId'][pk]['device_type'] == 'rc']
230 mix_ids = [pk for pk in rc_ids if data['configurations']
231 ['byId'][pk]['mix']]
232
181 233 if mix_ids:
182 234 params = data['configurations']['byId'][mix_ids[0]]['parameters']
183 rc = data['configurations']['byId'][params.split('-')[0].split('|')[0]]
235 rc = data['configurations']['byId'][params.split(
236 '-')[0].split('|')[0]]
184 237 rc['mix'] = True
185 238 data['configurations']['byId'][rc['id']] = rc
186 elif len(rc_ids)==0:
239 elif len(rc_ids) == 0:
187 240 self.message = 'File needs RC configuration'
188 241 return ''
189 242
190 243 json_data = json.dumps(data)
191 244 racp_file, filter_file = create_jarsfiles(json_data)
192 if file_format=='racp':
245 if file_format == 'racp':
193 246 return racp_file
194 247
195 248 return filter_file
196 249
197 250 def request(self, cmd, method='get', **kwargs):
198 251
199 252 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
200 253 payload = req.json()
201 254 return payload
202 255
203 256 def status_device(self):
204 257
205 258 try:
206 259 payload = self.request('status',
207 260 params={'name': self.experiment.name})
208 261 self.device.status = payload['status']
209 262 self.device.save()
210 263 self.message = payload['message']
211 264 except Exception as e:
212 265 self.device.status = 0
213 266 self.message = str(e)
214 267 self.device.save()
215 268 return False
216 269
217 270 return True
218 271
219 272 def stop_device(self):
220 273
221 274 try:
222 275 payload = self.request('stop', 'post')
223 276 self.device.status = payload['status']
224 277 self.device.save()
225 278 self.message = payload['message']
226 279 except Exception as e:
227 280 self.device.status = 0
228 281 self.message = str(e)
229 282 self.device.save()
230 283 return False
231 284
232 285 return True
233 286
234 287 def read_device(self):
235 288
236 289 try:
237 payload = self.request('read', params={'name': self.experiment.name})
290 payload = self.request(
291 'read', params={'name': self.experiment.name})
238 292 self.message = 'Configuration loaded'
239 293 except:
240 294 self.device.status = 0
241 295 self.device.save()
242 296 self.message = 'Could not read JARS configuration.'
243 297 return False
244 298
245 299 return payload
246 300
247 301 def write_device(self):
248 302
249 303 if self.device.status == 3:
250 304 self.message = 'Could not configure device. Software Acquisition is running'
251 305 return False
252 306
253 307 data = self.experiment.parms_to_dict()
254 308
255 309 for key in data['configurations']['allIds']:
256 310 if data['configurations']['byId'][key]['device_type'] in ('dds', 'cgs'):
257 311 data['configurations']['allIds'].remove(key)
258 312 data['configurations']['byId'].pop(key)
259 313 elif data['configurations']['byId'][key]['device_type'] == 'rc':
260 314 data['configurations']['byId'][key]['pulses'] = ''
261 315 data['configurations']['byId'][key]['delays'] = ''
262 rc_ids = [pk for pk in data['configurations']['allIds'] if data['configurations']['byId'][pk]['device_type']=='rc']
263 if len(rc_ids)==0:
316 rc_ids = [pk for pk in data['configurations']['allIds']
317 if data['configurations']['byId'][pk]['device_type'] == 'rc']
318 if len(rc_ids) == 0:
264 319 self.message = 'Missing RC configuration'
265 320 return False
266 321
267 322 json_data = json.dumps(data)
268
323
269 324 try:
270 325 payload = self.request('write', 'post', json=json_data)
271 326 self.device.status = payload['status']
272 327 self.message = payload['message']
273 328 self.device.save()
274 329 if self.device.status == 1:
275 330 return False
276 331
277 332 except Exception as e:
278 333 self.device.status = 0
279 334 self.message = str(e)
280 335 self.device.save()
281 336 return False
282 337
283 338 return True
284 339
285 340 def start_device(self):
286 341
287 342 try:
288 343 payload = self.request('start', 'post',
289 344 json={'name': self.experiment.name})
290 345 self.device.status = payload['status']
291 346 self.message = payload['message']
292 347 self.device.save()
293 348 if self.device.status == 1:
294 349 return False
295 350
296 351 except Exception as e:
297 352 self.device.status = 0
298 353 self.message = str(e)
299 354 self.device.save()
300 355 return False
301 356
302 357 return True
303 358
304
305 359 def get_log(self):
306 360
307 361 payload = None
308 362
309 363 try:
310 payload = requests.get(self.device.url('get_log'), params={'name':self.experiment.name})
364 payload = requests.get(self.device.url('get_log'), params={
365 'name': self.experiment.name})
311 366 except:
312 367 self.device.status = 0
313 368 self.device.save()
314 369 self.message = 'Jars API is not running.'
315 370 return False
316
371
317 372 self.message = 'Jars API is running'
318 373
319 374 return payload
320 375
321
322 376 def update_from_file(self, filename):
323 377
324 378 f = JARSFile(filename)
325 379 self.dict_to_parms(f.data)
326 380 self.save()
327 381
328 382 def get_absolute_url_import(self):
329 383 return reverse('url_import_jars_conf', args=[str(self.id)])
330 384
331 385 def get_absolute_url_read(self):
332 386 return reverse('url_read_jars_conf', args=[str(self.id)])
333 387
334 388 def get_absolute_url_log(self):
335 389 return reverse('url_get_jars_log', args=[str(self.id)])
@@ -1,30 +1,29
1 $("#id_fch").change(function() {
1 $("#id_frequency").change(function() {
2 2 updateParameters()
3 3 });
4 4
5 5 $("#id_clock").change(function() {
6 6 updateParameters()
7 7 });
8 8
9 $("#id_mult").change(function() {
9 $("#id_multiplier").change(function() {
10 10 updateParameters()
11 11 });
12 12
13 13 function updateParameters(){
14 var fclock = $("#id_clock").val(); // clock frequency (MHz)
15 var fch = $("#id_fch").val(); // RF frequency (MHz)
16 var m_dds = $("#id_mult").val(); // DDS multiplier
14 var clock = $("#id_clock").val(); // clock frequency (MHz)
15 var fch = $("#id_frequency").val(); // RF frequency (MHz)
16 var m_dds = $("#id_multiplier").val(); // DDS multiplier
17 17
18 if (Math.abs(fch) < fclock/2){ // Si se cumple nyquist
19 var nco = Math.pow(2,32)*((fch/fclock)%1);
18 if (Math.abs(fch) < clock/2){ // Si se cumple nyquist
19 var nco = Math.pow(2,32)*((fch/clock)%1);
20 20 //var nco_i = Math.round(nco/m_dds)*m_dds;
21 21 var nco_i = Math.round(nco)
22 22 }
23 23 else {
24 nco = Math.pow(2,32)*(fclock-fch)/(fclock);
24 nco = Math.pow(2,32)*(clock-fch)/(clock);
25 25 //nco_i = Math.round(nco/m_dds)*m_dds;
26 26 var nco_i = Math.round(nco)
27 27 }
28 fch_decimal = $("#id_fch_decimal")
29 $(fch_decimal).val(nco_i)
28 $("#id_f_decimal").val(nco_i)
30 29 }
@@ -1,19 +1,25
1 1 {% extends "dev_conf.html" %}
2 2 {% load static %}
3 3 {% load bootstrap3 %}
4 4 {% load main_tags %}
5 5
6 6 {% block extra-menu-actions %}
7 <li><a href="{{ dev_conf.get_absolute_url_log }}"><span class="glyphicon glyphicon-save-file" aria-hidden="true"></span> Get Log File</a></li>
7 <li><a href="{{ dev_conf.get_absolute_url_log }}"><span class="glyphicon glyphicon-save-file" aria-hidden="true"></span>
8 Get Log File</a></li>
8 9 {% endblock %}
9 10
10 11 {% block extra-content %}
11 12
12 13 <div class="clearfix"></div>
13 <h2>JARS filter: {{resolution}}</h2>
14 <hr>
15 <div class="panel-group" id="div_lines" role="tablist" aria-multiselectable="true">
16 {% include "jars_filter.html" %}
17 </div>
14 <h2>Filter: {{resolution}}</h2>
15 <br>
16 <table class="table table-bordered">
17 {% for key in filter_keys %}
18 <tr>
19 <th>{% get_verbose_field_name filter_obj key %}</th>
20 <td>{{filter|attr:key}}</td>
21 </tr>
22 {% endfor %}
23 </table>
18 24
19 {% endblock extra-content%}
25 {% endblock extra-content%} No newline at end of file
@@ -1,32 +1,40
1 1 {% extends "dev_conf_edit.html" %}
2 2 {% load bootstrap3 %}
3 3 {% load static %}
4 4 {% load main_tags %}
5 5
6 6 {% block content %}
7 7 <form class="form" method="post">
8 8 {% csrf_token %}
9 9 {% bootstrap_form form layout='horizontal' size='medium' %}
10 10 <div style="clear: both;"></div>
11 <h2>JARS filter</h2>
12 <hr>
13 <div class="panel-group" id="div_lines" role="tablist" aria-multiselectable="true">
14 {% include "jars_filter_edit.html" %}
11 <h2>Filter <small>{{filter_name}}</small></h2>
12 <br>
13 {% bootstrap_form filter_form layout='horizontal' size='medium' %}
14 <div style="clear: both;"></div>
15 <br>
16 <div class="pull-right">
17 <button type="button" class="btn btn-primary" onclick="{% if previous %}window.location.replace('{{ previous }}');{% else %}history.go(-1);{% endif %}">Cancel</button>
18 <button type="submit" class="btn btn-primary">{{button}}</button>
15 19 </div>
20
16 21 <div style="clear: both;"></div>
17 22 <br>
18 23 </form>
19 24 {% endblock %}
20 25
21
22 26 {% block extra-js%}
23 27 <script src="{% static 'js/jars.js' %}"></script>
24
28 <script src="{% static 'js/filters.js' %}"></script>
25 29 <script type="text/javascript">
26 30
27 $("#bt_cancel").click(function() {
31 $("#bt_cancel").click(function () {
28 32 document.location = "{% url 'url_jars_conf' id_dev %}";
29 });
33 });
34
35 $("#id_filter_template").change(function () {
36 document.location = "{% url 'url_change_jars_filter' id_dev %}" + $("#id_filter_template").val();
37 });
30 38
31 39 </script>
32 {% endblock %}
40 {% endblock %} No newline at end of file
@@ -1,240 +1,194
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.http import HttpResponse
6 6
7 7 from apps.main.models import Device
8 8 from apps.main.views import sidebar
9 9
10 from .models import JARSConfiguration, JARSfilter
11 from .forms import JARSConfigurationForm, JARSfilterForm, JARSImportForm
10 from .models import JARSConfiguration, JARSFilter
11 from .forms import JARSConfigurationForm, JARSFilterForm, JARSImportForm
12 12
13 13 import json
14 14 # Create your views here.
15 15
16 16 def jars_conf(request, id_conf):
17 17
18 18 conf = get_object_or_404(JARSConfiguration, pk=id_conf)
19 19
20 filter_parms = eval(conf.filter_parms)
21 if filter_parms.__class__.__name__=='str':
22 filter_parms = eval(filter_parms)
20 filter_parms = json.loads(conf.filter_parms)
23 21
24 22 kwargs = {}
25 23 kwargs['filter'] = filter_parms
26 kwargs['filter_keys'] = ['clock', 'mult', 'fch', 'fch_decimal',
27 'filter_fir', 'filter_2', 'filter_5']
24 kwargs['filter_obj'] = JARSFilter.objects.get(pk=1)
25 kwargs['filter_keys'] = ['clock', 'multiplier', 'frequency', 'f_decimal',
26 'cic_2', 'scale_cic_2', 'cic_5', 'scale_cic_5', 'fir',
27 'scale_fir', 'number_taps', 'taps']
28 28
29 filter_resolution=conf.filter_resolution()
29 filter_resolution = conf.filter_resolution()
30 30 kwargs['resolution'] = '{} (MHz)'.format(filter_resolution)
31 31 if filter_resolution < 1:
32 32 kwargs['resolution'] = '{} (kHz)'.format(filter_resolution*1000)
33 33
34 34 kwargs['status'] = conf.device.get_status_display()
35
36
37 35 kwargs['dev_conf'] = conf
38 kwargs['dev_conf_keys'] = ['name',
39 'cards_number', 'channels_number', 'channels',
36 kwargs['dev_conf_keys'] = ['cards_number', 'channels_number', 'channels',
40 37 'ftp_interval', 'data_type','acq_profiles',
41 38 'profiles_block', 'raw_data_blocks', 'ftp_interval',
42 39 'cohe_integr_str', 'cohe_integr', 'decode_data', 'post_coh_int',
43 40 'incohe_integr', 'fftpoints', 'spectral_number',
44 41 'spectral', 'create_directory', 'include_expname',
45 42 'save_ch_dc', 'save_data']
46 43
47 44 if conf.exp_type == 0:
48 45 for field in ['incohe_integr','fftpoints','spectral_number', 'spectral', 'save_ch_dc']:
49 46 kwargs['dev_conf_keys'].remove(field)
50 47
51 48 if conf.decode_data == 0:
52 49 kwargs['dev_conf_keys'].remove('decode_data')
53 50 kwargs['dev_conf_keys'].remove('post_coh_int')
54 51
55 52 kwargs['title'] = 'JARS Configuration'
56 53 kwargs['suptitle'] = 'Details'
57 54
58 kwargs['button'] = 'Edit Configuration'
59
60 #kwargs['no_play'] = True
61
62 #kwargs['only_stop'] = True
63
64 55 ###### SIDEBAR ######
65 56 kwargs.update(sidebar(conf=conf))
66 57
67 58 return render(request, 'jars_conf.html', kwargs)
68 59
69 60 def jars_conf_edit(request, id_conf):
70 61
71 62 conf = get_object_or_404(JARSConfiguration, pk=id_conf)
72 63
73 filter_parms = eval(conf.filter_parms)
74 if filter_parms.__class__.__name__=='str':
75 filter_parms = eval(filter_parms)
76
64 filter_parms = json.loads(conf.filter_parms)
65
77 66 if request.method=='GET':
78 67 form = JARSConfigurationForm(instance=conf)
79 filter_form = JARSfilterForm(initial=filter_parms)
68 filter_form = JARSFilterForm(initial=filter_parms)
80 69
81 70 if request.method=='POST':
82 71 form = JARSConfigurationForm(request.POST, instance=conf)
83 filter_form = JARSfilterForm(request.POST)
72 filter_form = JARSFilterForm(request.POST)
84 73
85 74 if filter_form.is_valid():
86 jars_filter = filter_form.cleaned_data
87 try:
88 jars_filter.pop('name')
89 except:
90 pass
75 jars_filter = filter_form.cleaned_data
76 jars_filter['id'] = request.POST['filter_template']
77 else:
78 messages.error(request, filter_form.errors)
91 79
92 80 if form.is_valid():
93 81 conf = form.save(commit=False)
94 82 conf.filter_parms = json.dumps(jars_filter)
95 83 conf.save()
96 84 return redirect('url_jars_conf', id_conf=conf.id)
97 85
98 86 kwargs = {}
99 87
100 88 kwargs['id_dev'] = conf.id
101 89 kwargs['form'] = form
102 90 kwargs['filter_form'] = filter_form
91 kwargs['filter_name'] = JARSFilter.objects.get(pk=filter_parms['id']).name
103 92 kwargs['title'] = 'Device Configuration'
104 93 kwargs['suptitle'] = 'Edit'
105 94 kwargs['button'] = 'Save'
106 95
107 96 return render(request, 'jars_conf_edit.html', kwargs)
108 97
109 98 def import_file(request, conf_id):
110 99
111 100 conf = get_object_or_404(JARSConfiguration, pk=conf_id)
112 101 if request.method=='POST':
113 102 form = JARSImportForm(request.POST, request.FILES)
114 103 if form.is_valid():
115 104 try:
116 105 data = conf.import_from_file(request.FILES['file_name'])
117 106 conf.dict_to_parms(data)
118 107 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
119 108 return redirect(conf.get_absolute_url_edit())
120 109
121 110 except Exception as e:
122 111 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
123 112 else:
124 113 messages.warning(request, 'Your current configuration will be replaced')
125 114 form = JARSImportForm()
126 115
127 116 kwargs = {}
128 117 kwargs['form'] = form
129 118 kwargs['title'] = 'JARS Configuration'
130 119 kwargs['suptitle'] = 'Import file'
131 120 kwargs['button'] = 'Upload'
132 121 kwargs['previous'] = conf.get_absolute_url()
133 122
134 123 return render(request, 'jars_import.html', kwargs)
135 124
136 125 def read_conf(request, conf_id):
137 126
138 127 conf = get_object_or_404(JARSConfiguration, pk=conf_id)
139 128 #filter = get_object_or_404(JARSfilter, pk=filter_id)
140 129
141 130 if request.method=='GET':
142 131
143 132 parms = conf.read_device()
144 133 conf.status_device()
145 134
146 135 if not parms:
147 136 messages.error(request, conf.message)
148 137 return redirect(conf.get_absolute_url())
149 138
150 139 form = JARSConfigurationForm(initial=parms, instance=conf)
151 140
152 141 if request.method=='POST':
153 142 form = JARSConfigurationForm(request.POST, instance=conf)
154 143
155 144 if form.is_valid():
156 145 form.save()
157 146 return redirect(conf.get_absolute_url())
158 147
159 148 messages.error(request, "Parameters could not be saved")
160 149
161 150 kwargs = {}
162 151 kwargs['id_dev'] = conf.id
163 152 kwargs['filter_id'] = conf.filter.id
164 153 kwargs['form'] = form
165 154 kwargs['title'] = 'Device Configuration'
166 155 kwargs['suptitle'] = 'Parameters read from device'
167 156 kwargs['button'] = 'Save'
168 157
169 158 ###### SIDEBAR ######
170 159 kwargs.update(sidebar(conf=conf))
171 160
172 161 return render(request, 'jars_conf_edit.html', kwargs)
173 162
174
175
176 def change_filter(request, conf_id, filter_id=None):
163 def change_filter(request, conf_id, filter_id):
177 164
178 165 conf = get_object_or_404(JARSConfiguration, pk=conf_id)
166 filter = get_object_or_404(JARSFilter, pk=filter_id)
167 conf.filter_parms = json.dumps(filter.jsonify())
168 conf.save()
179 169
180 if filter_id:
181 if filter_id.__class__.__name__ not in ['int', 'float']:
182 filter_id = eval(filter_id)
183
184 if filter_id == 0:
185 return redirect('url_change_jars_filter', conf_id=conf.id)
186
187 if request.method=='GET':
188 if not filter_id:
189 form = JARSfilterForm(initial={'filter_id': 0})
190 else:
191 form = JARSfilterForm(initial={'filter_id': filter_id})
192
193 if request.method=='POST':
194 form = JARSfilterForm(request.POST)
195 if form.is_valid():
196 jars_filter = form.cleaned_data
197 try:
198 jars_filter.pop('name')
199 except:
200 pass
201 conf.filter_parms = json.dumps(jars_filter)
202 conf.save()
203 return redirect('url_edit_jars_conf', id_conf=conf.id)
204 else:
205 messages.error(request, "Select a Filter Template")
206 return redirect('url_change_jars_filter', conf_id=conf.id)
207
208 kwargs = {}
209 kwargs['title'] = 'JARS Configuration'
210 kwargs['suptitle'] = 'Change Filter'
211 kwargs['form'] = form
212 kwargs['button'] = 'Change'
213 kwargs['conf_id'] = conf.id
214 kwargs['filter_id'] = filter_id
215 return render(request, 'change_jars_filter.html', kwargs)
216
170 return redirect('url_edit_jars_conf', id_conf=conf.id)
217 171
218 172 def get_log(request, conf_id):
219 173
220 174 conf = get_object_or_404(JARSConfiguration, pk=conf_id)
221 175 response = conf.get_log()
222 176
223 177 if not response:
224 178 message = conf.message
225 179 messages.error(request, message)
226 180 return redirect('url_jars_conf', id_conf=conf.id)
227 181
228 182 try:
229 183 message = response.json()['message']
230 184 messages.error(request, message)
231 185 return redirect('url_jars_conf', id_conf=conf.id)
232 186 except Exception as e:
233 187 message = 'Restarting Report.txt has been downloaded successfully.'
234 188
235 189 content = response
236 190 filename = 'Log_%s_%s.txt' %(conf.experiment.name, conf.experiment.id)
237 191 response = HttpResponse(content,content_type='text/plain')
238 192 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
239 193
240 194 return response
@@ -1,168 +1,165
1 1
2 2 import ast
3 3 import json
4 4 from itertools import chain
5 5
6 6 from django import forms
7 7 from django.utils.safestring import mark_safe
8 8 from django.utils.html import conditional_escape
9 9
10 10
11 11 class SpectralWidget(forms.widgets.TextInput):
12 12
13 13 def render(self, label, value, attrs=None):
14 14
15 15 readonly = 'readonly' if attrs.get('readonly', False) else ''
16 16 name = attrs.get('name', label)
17 print 'ESTO!'
18 print value
19 17 if value == None:
20 18 value = '[0, 0],'
21 print readonly
22 19 if '[' in value:
23 20 if value[len(value)-1] == ",":
24 21 value = ast.literal_eval(value)
25 22 else:
26 23 value = value + ","
27 24 value = ast.literal_eval(value)
28 25
29 26 codes = value
30 27 if not isinstance(value, list):
31 28 text=''
32 29 #lista = []
33 30 #if len(value) > 1:
34 31 for val in value:
35 32 text = text+str(val)+','
36 33 #lista.append(val)
37 34 codes=text
38 35 else:
39 36 codes=''
40 37
41 38 html = '''<textarea rows="5" {0} class="form-control" id="id_{1}" name="{2}" style="white-space:nowrap; overflow:scroll;">{3}</textarea>
42 39 <input type="text" class="col-md-1 col-no-padding" id="num1" value=0>
43 40 <input type="text" class="col-md-1 col-no-padding" id="num2" value=0>
44 41 <button type="button" class="button" id="add_spectral_button"> Add </button>
45 42 <button type="button" class="button" id="delete_spectral_button"> Delete </button>
46 43 <button type="button" class="button pull-right" id="cross_spectral_button"> Cross </button>
47 44 <button type="button" class="button pull-right" id="self_spectral_button"> Self </button>
48 45 <button type="button" class="button pull-right" id="all_spectral_button"> All </button>
49 46 '''.format(readonly, label, name, codes)
50 47
51 48 script = '''
52 49 <script type="text/javascript">
53 50 $(document).ready(function () {{
54 51
55 52 var spectral_number1 = $("#num1").val();
56 53 var spectral_number2 = $("#num2").val();
57 54
58 55
59 56 $("#all_spectral_button").click(function(){{
60 57 var sequence1 = selfSpectral()
61 58 var sequence2 = crossSpectral()
62 59 $("#id_spectral").val(sequence1+sequence2)
63 60 updateSpectralNumber()
64 61 }});
65 62
66 63
67 64 $("#add_spectral_button").click(function(){{
68 65 var spectral_comb = $("#id_spectral").val();
69 66 var spectral_number1 = $("#num1").val();
70 67 var spectral_number2 = $("#num2").val();
71 68 var str = spectral_number1+", "+spectral_number2;
72 69 //not to duplicate
73 70 var n = spectral_comb.search(str);
74 71 if (n==-1){
75 72 $("#id_spectral").val(spectral_comb+"["+$("#num1").val()+", "+$("#num2").val()+"],")
76 73 }
77 74 updateSpectralNumber()
78 75 }});
79 76
80 77
81 78 $("#self_spectral_button").click(function(){{
82 79 var sequence = selfSpectral()
83 80 $("#id_spectral").val(sequence)
84 81
85 82 updateSpectralNumber()
86 83 }});
87 84
88 85 $("#cross_spectral_button").click(function(){{
89 86 var sequence = crossSpectral()
90 87 $("#id_spectral").val(sequence)
91 88
92 89 updateSpectralNumber()
93 90 }});
94 91
95 92
96 93 function selfSpectral() {
97 94 var channels = $("#id_channels").val();
98 95 var n = (channels.length)-1;
99 96 var num = parseInt(channels[n]);
100 97 sequence = ""
101 98 for (i = 0; i < num; i++) {
102 99 sequence = sequence + "[" + i.toString() + ", " + i.toString() + "],"
103 100 }
104 101 return sequence
105 102 }
106 103
107 104
108 105 function crossSpectral() {
109 106 var channels = $("#id_channels").val();
110 107 var n = (channels.length)-1;
111 108 var num = parseInt(channels[n]);
112 109 sequence = ""
113 110 for (i = 0; i < num; i++) {
114 111 for (j = i+1; j < num; j++) {
115 112 sequence = sequence + "[" + i.toString() + ", " + j.toString() + "],"
116 113 }
117 114 }
118 115 return sequence
119 116 }
120 117
121 118
122 119 function updateSpectralNumber(){
123 120 var spectral_comb = $("#id_spectral").val();
124 121 var num = spectral_comb.length;
125 122 var cont = 0
126 123 for (i = 0; i < num; i++) {
127 124 if (spectral_comb[i] == "]"){
128 125 cont = cont + 1
129 126 }
130 127 }
131 128 $("#id_spectral_number").val(cont)
132 129 }
133 130
134 131
135 132 $("#delete_spectral_button").click(function(){{
136 133 var spectral_comb = $("#id_spectral").val();
137 134 var spectral_number1 = $("#num1").val();
138 135 var spectral_number2 = $("#num2").val();
139 136 var str = spectral_number1+", "+spectral_number2;
140 137 var n = spectral_comb.search(str);
141 138 if (n==-1){
142 139
143 140 }
144 141 else {
145 142 n= spectral_comb.length;
146 143 if (n<8){
147 144 var tuple = "["+$("#num1").val()+", "+$("#num2").val()+"],"
148 145 var txt = spectral_comb.replace(tuple,'');
149 146 }
150 147 else {
151 148 var tuple = ",["+$("#num1").val()+", "+$("#num2").val()+"]"
152 149 var txt = spectral_comb.replace(tuple,'');
153 150 }
154 151 $("#id_spectral").val(txt)
155 152
156 153 var tuple = "["+$("#num1").val()+", "+$("#num2").val()+"],"
157 154 var txt = spectral_comb.replace(tuple,'');
158 155 $("#id_spectral").val(txt)
159 156 }
160 157 updateSpectralNumber()
161 158 }});
162 159
163 160
164 161 }});
165 162 </script>
166 163 '''
167 164
168 165 return mark_safe(html+script)
@@ -1,13 +1,122
1 1 [
2 {"fields": {"name": "JRO", "description": ""}, "model": "main.location", "pk": 1},
3 {"fields": {"name": "JASMET", "description": ""}, "model": "main.location", "pk": 2},
4 {"fields": {"name": "SOUSY", "description": ""}, "model": "main.location", "pk": 3},
5 {"fields": {"name": "JULIA", "description": ""}, "model": "main.location", "pk": 4},
6 {"fields": {"name": "CLAIRE", "description": ""}, "model": "main.location", "pk": 4},
7 {"fields": {"name": "rc", "description": ""}, "model": "main.devicetype", "pk": 1},
8 {"fields": {"name": "dds", "description": ""}, "model": "main.devicetype", "pk": 2},
9 {"fields": {"name": "cgs", "description": ""}, "model": "main.devicetype", "pk": 3},
10 {"fields": {"name": "jars", "description": ""}, "model": "main.devicetype", "pk": 4},
11 {"fields": {"name": "abs", "description": ""}, "model": "main.devicetype", "pk": 5},
12 {"fields": {"password": "pbkdf2_sha256$24000$6RRL7xETgdgN$ORRPhrITZKzTTZHCm8T+Er6ght415kYKeU7QP3rry5M=", "last_login": null, "is_superuser": true, "username": "admin", "first_name": "", "last_name": "", "email": "admin@admin.com", "is_staff": true, "is_active": true, "date_joined": "2017-01-12T16:10:24.383", "groups": [], "user_permissions": []}, "model": "auth.user", "pk": 1}
13 ]
2 {
3 "fields": {
4 "name": "JRO",
5 "description": ""
6 },
7 "model": "main.location",
8 "pk": 1
9 },
10 {
11 "fields": {
12 "name": "JASMET",
13 "description": ""
14 },
15 "model": "main.location",
16 "pk": 2
17 },
18 {
19 "fields": {
20 "name": "SOUSY",
21 "description": ""
22 },
23 "model": "main.location",
24 "pk": 3
25 },
26 {
27 "fields": {
28 "name": "JULIA",
29 "description": ""
30 },
31 "model": "main.location",
32 "pk": 4
33 },
34 {
35 "fields": {
36 "name": "CLAIRE",
37 "description": ""
38 },
39 "model": "main.location",
40 "pk": 5
41 },
42 {
43 "fields": {
44 "name": "IDI",
45 "description": ""
46 },
47 "model": "main.location",
48 "pk": 6
49 },
50 {
51 "fields": {
52 "name": "rc",
53 "description": ""
54 },
55 "model": "main.devicetype",
56 "pk": 1
57 },
58 {
59 "fields": {
60 "name": "dds",
61 "description": ""
62 },
63 "model": "main.devicetype",
64 "pk": 2
65 },
66 {
67 "fields": {
68 "name": "cgs",
69 "description": ""
70 },
71 "model": "main.devicetype",
72 "pk": 3
73 },
74 {
75 "fields": {
76 "name": "jars",
77 "description": ""
78 },
79 "model": "main.devicetype",
80 "pk": 4
81 },
82 {
83 "fields": {
84 "name": "abs",
85 "description": ""
86 },
87 "model": "main.devicetype",
88 "pk": 5
89 },
90 {
91 "fields": {
92 "name": "Operator"
93 },
94 "model": "auth.group",
95 "pk": 1
96 },
97 {
98 "fields": {
99 "name": "Developer"
100 },
101 "model": "auth.group",
102 "pk": 2
103 },
104 {
105 "fields": {
106 "password": "pbkdf2_sha256$24000$6RRL7xETgdgN$ORRPhrITZKzTTZHCm8T+Er6ght415kYKeU7QP3rry5M=",
107 "last_login": null,
108 "is_superuser": true,
109 "username": "admin",
110 "first_name": "Administrador",
111 "last_name": "IDI",
112 "email": "admin@admin.com",
113 "is_staff": true,
114 "is_active": true,
115 "date_joined": "2017-01-12T16:10:24.383",
116 "groups": [],
117 "user_permissions": []
118 },
119 "model": "auth.user",
120 "pk": 1
121 }
122 ] No newline at end of file
@@ -1,202 +1,202
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):
37 37 input_html = super(DatepickerWidget, self).render(name, value, attrs)
38 38 html = '<div class="input-group date">'+input_html+'<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span></div>'
39 39 return mark_safe(html)
40 40
41 41 class DateRangepickerWidget(forms.widgets.TextInput):
42 42 def render(self, name, value, attrs=None):
43 43 start = attrs['start_date']
44 44 end = attrs['end_date']
45 45 html = '''<div class="col-md-6 input-group date" style="float:inherit">
46 46 <input class="form-control" id="id_start_date" name="start_date" placeholder="Start" title="" type="text" value="{}">
47 47 <span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
48 48 </div>
49 49 <div class="col-md-6 input-group date" style="float:inherit">
50 50 <input class="form-control" id="id_end_date" name="end_date" placeholder="End" title="" type="text" value="{}">
51 51 <span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
52 52 </div>'''.format(start, end)
53 53 return mark_safe(html)
54 54
55 55 class TimepickerWidget(forms.widgets.TextInput):
56 56 def render(self, name, value, attrs=None):
57 57 input_html = super(TimepickerWidget, self).render(name, value, attrs)
58 58 html = '<div class="input-group time">'+input_html+'<span class="input-group-addon"><i class="glyphicon glyphicon-time"></i></span></div>'
59 59 return mark_safe(html)
60 60
61 61 class CampaignForm(forms.ModelForm):
62 62
63 63 experiments = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(),
64 64 queryset=Experiment.objects.filter(template=True),
65 65 required=False)
66 66
67 67 def __init__(self, *args, **kwargs):
68 68 super(CampaignForm, self).__init__(*args, **kwargs)
69 69 self.fields['start_date'].widget = DatepickerWidget(self.fields['start_date'].widget.attrs)
70 70 self.fields['end_date'].widget = DatepickerWidget(self.fields['end_date'].widget.attrs)
71 71 self.fields['description'].widget.attrs = {'rows': 2}
72 72
73 73 if self.instance.pk:
74 74 self.fields['experiments'].queryset |= self.instance.experiments.all()
75 75
76 76 class Meta:
77 77 model = Campaign
78 exclude = ['']
78 exclude = ['author']
79 79
80 80
81 81 class ExperimentForm(forms.ModelForm):
82 82
83 83 def __init__(self, *args, **kwargs):
84 84 super(ExperimentForm, self).__init__(*args, **kwargs)
85 85 self.fields['start_time'].widget = TimepickerWidget(self.fields['start_time'].widget.attrs)
86 86 self.fields['end_time'].widget = TimepickerWidget(self.fields['end_time'].widget.attrs)
87 87
88 def save(self):
89 exp = super(ExperimentForm, self).save()
88 def save(self, *args, **kwargs):
89 exp = super(ExperimentForm, self).save(*args, **kwargs)
90 90 exp.name = exp.name.replace(' ', '')
91 91 exp.save()
92 92 return exp
93 93
94 94 class Meta:
95 95 model = Experiment
96 exclude = ['task', 'status']
96 exclude = ['task', 'status', 'author', 'hash']
97 97
98 98 class LocationForm(forms.ModelForm):
99 99 class Meta:
100 100 model = Location
101 101 exclude = ['']
102 102
103 103 class DeviceForm(forms.ModelForm):
104 104 class Meta:
105 105 model = Device
106 106 exclude = ['status']
107 107
108 108 class ConfigurationForm(forms.ModelForm):
109 109
110 110 def __init__(self, *args, **kwargs):
111 111 super(ConfigurationForm, self).__init__(*args, **kwargs)
112 112
113 113 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
114 114 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
115 115
116 116 class Meta:
117 117 model = Configuration
118 exclude = ['type', 'created_date', 'programmed_date', 'parameters']
118 exclude = ['type', 'created_date', 'programmed_date', 'parameters', 'author', 'hash']
119 119
120 120 class UploadFileForm(forms.Form):
121 121
122 122 file = forms.FileField()
123 123
124 124 class DownloadFileForm(forms.Form):
125 125
126 126 format = forms.ChoiceField(choices= ((0, 'json'),) )
127 127
128 128 def __init__(self, device_type, *args, **kwargs):
129 129
130 130 super(DownloadFileForm, self).__init__(*args, **kwargs)
131 131
132 132 self.fields['format'].choices = FILE_FORMAT
133 133
134 134 if device_type == 'dds':
135 135 self.fields['format'].choices = DDS_FILE_FORMAT
136 136
137 137 if device_type == 'rc':
138 138 self.fields['format'].choices = RC_FILE_FORMAT
139 139
140 140 if device_type == 'jars':
141 141 self.fields['format'].choices = JARS_FILE_FORMAT
142 142
143 143 class OperationForm(forms.Form):
144 144
145 145 campaign = forms.ChoiceField(label="Campaign")
146 146
147 147 def __init__(self, *args, **kwargs):
148 148
149 149 campaigns = kwargs.pop('campaigns')
150 150 super(OperationForm, self).__init__(*args, **kwargs)
151 151 self.fields['campaign'].label = 'Current Campaigns'
152 152 self.fields['campaign'].choices = add_empty_choice(campaigns.values_list('id', 'name'))
153 153
154 154
155 155 class OperationSearchForm(forms.Form):
156 156 # -----ALL Campaigns------
157 157 campaign = forms.ChoiceField(label="Campaign")
158 158
159 159 def __init__(self, *args, **kwargs):
160 160 super(OperationSearchForm, self).__init__(*args, **kwargs)
161 161 self.fields['campaign'].choices=Campaign.objects.all().order_by('-start_date').values_list('id', 'name')
162 162
163 163
164 164 class NewForm(forms.Form):
165 165
166 166 create_from = forms.ChoiceField(choices=((0, '-----'),
167 167 (1, 'Empty (blank)'),
168 168 (2, 'Template')))
169 169 choose_template = forms.ChoiceField()
170 170
171 171 def __init__(self, *args, **kwargs):
172 172
173 173 template_choices = kwargs.pop('template_choices', [])
174 174 super(NewForm, self).__init__(*args, **kwargs)
175 175 self.fields['choose_template'].choices = add_empty_choice(template_choices)
176 176
177 177
178 178 class FilterForm(forms.Form):
179 179
180 180 def __init__(self, *args, **kwargs):
181 181 extra_fields = kwargs.pop('extra_fields', [])
182 182 super(FilterForm, self).__init__(*args, **kwargs)
183 183
184 184 for field in extra_fields:
185 185 if 'range_date' in field:
186 186 self.fields[field] = forms.CharField(required=False)
187 187 self.fields[field].widget = DateRangepickerWidget()
188 188 if 'initial' in kwargs:
189 189 self.fields[field].widget.attrs = {'start_date':kwargs['initial'].get('start_date', ''),
190 190 'end_date':kwargs['initial'].get('end_date', '')}
191 elif field in ('template', 'historical'):
191 elif field in ('template', 'historical') or 'my ' in field:
192 192 self.fields[field] = forms.BooleanField(required=False)
193 193 else:
194 194 self.fields[field] = forms.CharField(required=False)
195 195
196 196 class ChangeIpForm(forms.Form):
197 197
198 198 ip_address = forms.GenericIPAddressField()
199 199 mask = forms.GenericIPAddressField(initial='255.255.255.0')
200 200 gateway = forms.GenericIPAddressField(initial='0.0.0.0')
201 201 dns = forms.GenericIPAddressField(initial='0.0.0.0')
202 202
@@ -1,761 +1,794
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.core.urlresolvers import reverse
16 16 from django.core.validators import MinValueValidator, MaxValueValidator
17 17 from django.shortcuts import get_object_or_404
18 from django.contrib.auth.models import User
18 19
19 20 from apps.main.utils import Params
20 21 from apps.rc.utils import RCFile
21 22 from apps.jars.utils import RacpFile
22 23 from devices.dds import api as dds_api
23 24 from devices.dds import data as dds_data
24 25
25 26
26 27 DEV_PORTS = {
27 28 'rc' : 2000,
28 29 'dds' : 2000,
29 30 'jars' : 2000,
30 31 'usrp' : 2000,
31 32 'cgs' : 8080,
32 33 'abs' : 8080
33 34 }
34 35
35 36 RADAR_STATES = (
36 37 (0, 'No connected'),
37 38 (1, 'Connected'),
38 39 (2, 'Configured'),
39 40 (3, 'Running'),
40 41 (4, 'Scheduled'),
41 42 )
42 43
43 44 EXPERIMENT_TYPE = (
44 45 (0, 'RAW_DATA'),
45 46 (1, 'PDATA'),
46 47 )
47 48
48 49 DECODE_TYPE = (
49 50 (0, 'None'),
50 51 (1, 'TimeDomain'),
51 52 (2, 'FreqDomain'),
52 53 (3, 'InvFreqDomain'),
53 54 )
54 55
55 56 DEV_STATES = (
56 57 (0, 'No connected'),
57 58 (1, 'Connected'),
58 59 (2, 'Configured'),
59 60 (3, 'Running'),
60 61 (4, 'Unknown'),
61 62 )
62 63
63 64 DEV_TYPES = (
64 65 ('', 'Select a device type'),
65 66 ('rc', 'Radar Controller'),
66 67 ('dds', 'Direct Digital Synthesizer'),
67 68 ('jars', 'Jicamarca Radar Acquisition System'),
68 69 ('usrp', 'Universal Software Radio Peripheral'),
69 70 ('cgs', 'Clock Generator System'),
70 71 ('abs', 'Automatic Beam Switching'),
71 72 )
72 73
73 74 EXP_STATES = (
74 75 (0,'Error'), #RED
75 76 (1,'Configured'), #BLUE
76 77 (2,'Running'), #GREEN
77 78 (3,'Scheduled'), #YELLOW
78 79 (4,'Not Configured'), #WHITE
79 80 )
80 81
81 82 CONF_TYPES = (
82 83 (0, 'Active'),
83 84 (1, 'Historical'),
84 85 )
85 86
86 87 class Location(models.Model):
87 88
88 89 name = models.CharField(max_length = 30)
89 90 description = models.TextField(blank=True, null=True)
90 91
91 92 class Meta:
92 93 db_table = 'db_location'
93 94
94 95 def __str__(self):
95 96 return u'%s' % self.name
96 97
97 98 def get_absolute_url(self):
98 99 return reverse('url_location', args=[str(self.id)])
99 100
100 101
101 102 class DeviceType(models.Model):
102 103
103 104 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc')
104 105 sequence = models.PositiveSmallIntegerField(default=1000)
105 106 description = models.TextField(blank=True, null=True)
106 107
107 108 class Meta:
108 109 db_table = 'db_device_types'
109 110
110 111 def __str__(self):
111 112 return u'%s' % self.get_name_display()
112 113
113 114 class Device(models.Model):
114 115
115 116 device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
116 117 location = models.ForeignKey(Location, on_delete=models.CASCADE)
117
118 name = models.CharField(max_length=40, default='')
119 118 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
120 119 port_address = models.PositiveSmallIntegerField(default=2000)
121 120 description = models.TextField(blank=True, null=True)
122 121 status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES)
123 122
124 123 class Meta:
125 124 db_table = 'db_devices'
126 125
127 126 def __str__(self):
128 return u'[{}]: {}'.format(self.device_type.name.upper(),
129 self.name)
127 ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
128
129 return ret
130
131 @property
132 def name(self):
133 return str(self)
130 134
131 135 def get_status(self):
132 136 return self.status
133 137
134 138 @property
135 139 def status_color(self):
136 140 color = 'muted'
137 141 if self.status == 0:
138 142 color = "danger"
139 143 elif self.status == 1:
140 144 color = "warning"
141 145 elif self.status == 2:
142 146 color = "info"
143 147 elif self.status == 3:
144 148 color = "success"
145 149
146 150 return color
147 151
148 152 def url(self, path=None):
149 153
150 154 if path:
151 155 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
152 156 else:
153 157 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
154 158
155 159 def get_absolute_url(self):
156
157 160 return reverse('url_device', args=[str(self.id)])
158 161
162 def get_absolute_url_edit(self):
163 return reverse('url_edit_device', args=[str(self.id)])
164
165 def get_absolute_url_delete(self):
166 return reverse('url_delete_device', args=[str(self.id)])
167
159 168 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
160 169
161 170 if self.device_type.name=='dds':
162 171 try:
163 172 answer = dds_api.change_ip(ip = self.ip_address,
164 173 port = self.port_address,
165 174 new_ip = ip_address,
166 175 mask = mask,
167 176 gateway = gateway)
168 177 if answer[0]=='1':
169 178 self.message = '25|DDS - {}'.format(answer)
170 179 self.ip_address = ip_address
171 180 self.save()
172 181 else:
173 182 self.message = '30|DDS - {}'.format(answer)
174 183 return False
175 184 except Exception as e:
176 185 self.message = '40|{}'.format(str(e))
177 186 return False
178 187
179 188 elif self.device_type.name=='rc':
180 189 headers = {'content-type': "application/json",
181 190 'cache-control': "no-cache"}
182 191
183 192 ip = [int(x) for x in ip_address.split('.')]
184 193 dns = [int(x) for x in dns.split('.')]
185 194 gateway = [int(x) for x in gateway.split('.')]
186 195 subnet = [int(x) for x in mask.split('.')]
187 196
188 197 payload = {
189 198 "ip": ip,
190 199 "dns": dns,
191 200 "gateway": gateway,
192 201 "subnet": subnet
193 202 }
194 203
195 204 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
196 205 try:
197 206 answer = req.json()
198 207 if answer['changeip']=='ok':
199 208 self.message = '25|IP succesfully changed'
200 209 self.ip_address = ip_address
201 210 self.save()
202 211 else:
203 212 self.message = '30|An error ocuur when changing IP'
204 213 except Exception as e:
205 214 self.message = '40|{}'.format(str(e))
206 215 else:
207 216 self.message = 'Not implemented'
208 217 return False
209 218
210 219 return True
211 220
212 221
213 222 class Campaign(models.Model):
214 223
215 224 template = models.BooleanField(default=False)
216 225 name = models.CharField(max_length=60, unique=True)
217 226 start_date = models.DateTimeField(blank=True, null=True)
218 227 end_date = models.DateTimeField(blank=True, null=True)
219 tags = models.CharField(max_length=40)
228 tags = models.CharField(max_length=40, blank=True, null=True)
220 229 description = models.TextField(blank=True, null=True)
221 230 experiments = models.ManyToManyField('Experiment', blank=True)
222
231 author = models.ForeignKey(User, null=True, blank=True)
232
223 233 class Meta:
224 234 db_table = 'db_campaigns'
225 235 ordering = ('name',)
226 236
227 237 def __str__(self):
228 238 if self.template:
229 239 return u'{} (template)'.format(self.name)
230 240 else:
231 241 return u'{}'.format(self.name)
232 242
233 243 def jsonify(self):
234 244
235 245 data = {}
236 246
237 247 ignored = ('template')
238 248
239 249 for field in self._meta.fields:
240 250 if field.name in ignored:
241 251 continue
242 252 data[field.name] = field.value_from_object(self)
243 253
244 254 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
245 255 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
246 256
247 257 return data
248 258
249 259 def parms_to_dict(self):
250 260
251 261 params = Params({})
252 262 params.add(self.jsonify(), 'campaigns')
253 263
254 264 for exp in Experiment.objects.filter(campaign = self):
255 265 params.add(exp.jsonify(), 'experiments')
256 266 configurations = Configuration.objects.filter(experiment=exp, type=0)
257 267
258 268 for conf in configurations:
259 269 params.add(conf.jsonify(), 'configurations')
260 270 if conf.device.device_type.name=='rc':
261 271 for line in conf.get_lines():
262 272 params.add(line.jsonify(), 'lines')
263 273
264 274 return params.data
265 275
266 276 def dict_to_parms(self, parms, CONF_MODELS):
267 277
268 278 experiments = Experiment.objects.filter(campaign = self)
269 279
270 280 if experiments:
271 281 for experiment in experiments:
272 282 experiment.delete()
273 283
274 284 for id_exp in parms['experiments']['allIds']:
275 285 exp_parms = parms['experiments']['byId'][id_exp]
276 286 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
277 287 exp = Experiment(name='{}'.format(dum))
278 288 exp.save()
279 289 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
280 290 self.experiments.add(exp)
281 291
282 292 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
283 293
284 294 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
285 295 self.start_date = camp_parms['start_date']
286 296 self.end_date = camp_parms['end_date']
287 297 self.tags = camp_parms['tags']
288 298 self.save()
289 299
290 300 return self
291 301
292 302 def get_experiments_by_radar(self, radar=None):
293 303
294 304 ret = []
295 305 if radar:
296 306 locations = Location.objects.filter(pk=radar)
297 307 else:
298 308 locations = set([e.location for e in self.experiments.all()])
299 309
300 310 for loc in locations:
301 311 dum = {}
302 312 dum['name'] = loc.name
303 313 dum['id'] = loc.pk
304 314 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
305 315 ret.append(dum)
306 316
307 317 return ret
308 318
309 319 def get_absolute_url(self):
310 320 return reverse('url_campaign', args=[str(self.id)])
311 321
312 322 def get_absolute_url_edit(self):
313 323 return reverse('url_edit_campaign', args=[str(self.id)])
314 324
325 def get_absolute_url_delete(self):
326 return reverse('url_delete_campaign', args=[str(self.id)])
327
315 328 def get_absolute_url_export(self):
316 329 return reverse('url_export_campaign', args=[str(self.id)])
317 330
318 331 def get_absolute_url_import(self):
319 332 return reverse('url_import_campaign', args=[str(self.id)])
320 333
321 334
322
323 335 class RunningExperiment(models.Model):
324 336 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
325 337 running_experiment = models.ManyToManyField('Experiment', blank = True)
326 338 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
327 339
328 340
329 341 class Experiment(models.Model):
330 342
331 343 template = models.BooleanField(default=False)
332 344 name = models.CharField(max_length=40, default='', unique=True)
333 345 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
334 346 freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
335 347 start_time = models.TimeField(default='00:00:00')
336 348 end_time = models.TimeField(default='23:59:59')
337 349 task = models.CharField(max_length=36, default='', blank=True, null=True)
338 350 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
351 author = models.ForeignKey(User, null=True, blank=True)
352 hash = models.CharField(default='', max_length=64, null=True, blank=True)
339 353
340 354 class Meta:
341 355 db_table = 'db_experiments'
342 356 ordering = ('template', 'name')
343 357
344 358 def __str__(self):
345 359 if self.template:
346 return u'%s (template)' % (self.name)
360 return u'%s (template)' % (self.name[:8])
347 361 else:
348 return u'%s' % (self.name)
362 return u'%s' % (self.name[:10])
349 363
350 364 def jsonify(self):
351 365
352 366 data = {}
353 367
354 368 ignored = ('template')
355 369
356 370 for field in self._meta.fields:
357 371 if field.name in ignored:
358 372 continue
359 373 data[field.name] = field.value_from_object(self)
360 374
361 375 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
362 376 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
363 377 data['location'] = self.location.name
364 378 data['configurations'] = ['{}'.format(conf.pk) for
365 379 conf in Configuration.objects.filter(experiment=self, type=0)]
366 380
367 381 return data
368 382
369 383 @property
370 384 def radar_system(self):
371 385 return self.location
372 386
373 387 def clone(self, **kwargs):
374 388
375 389 confs = Configuration.objects.filter(experiment=self, type=0)
376 390 self.pk = None
377 self.name = '{} [{:%Y-%m-%d}]'.format(self.name, datetime.now())
391 self.name = '{}_{:%y%m%d}'.format(self.name, datetime.now())
378 392 for attr, value in kwargs.items():
379 393 setattr(self, attr, value)
380 394
381 395 self.save()
382 396
383 397 for conf in confs:
384 398 conf.clone(experiment=self, template=False)
385 399
386 400 return self
387 401
388 402 def start(self):
389 403 '''
390 404 Configure and start experiments's devices
391 405 ABS-CGS-DDS-RC-JARS
392 406 '''
393 407
394 408 result = 2
395 409 confs = []
396 410 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
397 411 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix]
398 412 if rc_mix:
399 413 for conf in allconfs:
400 414 if conf.device.device_type.name == 'rc' and not conf.mix:
401 415 continue
402 416 confs.append(conf)
403 417 else:
404 418 confs = allconfs
405 419 #Only Configured Devices.
406 420 for conf in confs:
407 421 if conf.device.status in (0, 4):
408 422 result = 0
409 423 return result
410 424 for conf in confs:
411 425 conf.stop_device()
412 426 conf.write_device()
413 427 conf.start_device()
414 428 time.sleep(1)
415 429
416 430 return result
417 431
418 432
419 433 def stop(self):
420 434 '''
421 435 Stop experiments's devices
422 436 DDS-JARS-RC-CGS-ABS
423 437 '''
424 438
425 439 result = 1
426 440
427 441 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
428 442 confs=confs.exclude(device__device_type__name='cgs')
429 443 for conf in confs:
430 444 if conf.device.status in (0, 4):
431 445 result = 0
432 446 continue
433 447 conf.stop_device()
434 448
435 449 return result
436 450
437 451
438 452 def get_status(self):
439 453
440 454 if self.status == 3:
441 455 return
442 456
443 457 confs = Configuration.objects.filter(experiment=self, type=0)
444 458
445 459 for conf in confs:
446 460 conf.status_device()
447 461
448 462 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
449 463
450 464 if total==2*confs.count():
451 465 status = 1
452 466 elif total == 3*confs.count():
453 467 status = 2
454 468 else:
455 469 status = 0
456 470
457 471 self.status = status
458 472 self.save()
459 473
460 474 def status_color(self):
461 475 color = 'muted'
462 476 if self.status == 0:
463 477 color = "danger"
464 478 elif self.status == 1:
465 479 color = "info"
466 480 elif self.status == 2:
467 481 color = "success"
468 482 elif self.status == 3:
469 483 color = "warning"
470 484
471 485 return color
472 486
473 487 def parms_to_dict(self):
474 488
475 489 params = Params({})
476 490 params.add(self.jsonify(), 'experiments')
477 491
478 492 configurations = Configuration.objects.filter(experiment=self, type=0)
479 493
480 494 for conf in configurations:
481 495 params.add(conf.jsonify(), 'configurations')
482 496 if conf.device.device_type.name=='rc':
483 497 for line in conf.get_lines():
484 498 params.add(line.jsonify(), 'lines')
485 499
486 500 return params.data
487 501
488 502 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
489 503
490 504 configurations = Configuration.objects.filter(experiment=self)
491 505
492 506 if id_exp is not None:
493 507 exp_parms = parms['experiments']['byId'][id_exp]
494 508 else:
495 509 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
496 510
497 511 if configurations:
498 512 for configuration in configurations:
499 513 configuration.delete()
500 514
501 515 for id_conf in exp_parms['configurations']:
502 516 conf_parms = parms['configurations']['byId'][id_conf]
503 517 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
504 518 model = CONF_MODELS[conf_parms['device_type']]
505 519 conf = model(
506 520 experiment = self,
507 521 device = device,
508 522 )
509 523 conf.dict_to_parms(parms, id=id_conf)
510 524
511 525
512 526 location, created = Location.objects.get_or_create(name=exp_parms['location'])
513 527 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
514 528 self.location = location
515 529 self.start_time = exp_parms['start_time']
516 530 self.end_time = exp_parms['end_time']
517 531 self.save()
518 532
519 533 return self
520 534
521 535 def get_absolute_url(self):
522 536 return reverse('url_experiment', args=[str(self.id)])
523 537
524 538 def get_absolute_url_edit(self):
525 539 return reverse('url_edit_experiment', args=[str(self.id)])
526 540
541 def get_absolute_url_delete(self):
542 return reverse('url_delete_experiment', args=[str(self.id)])
543
527 544 def get_absolute_url_import(self):
528 545 return reverse('url_import_experiment', args=[str(self.id)])
529 546
530 547 def get_absolute_url_export(self):
531 548 return reverse('url_export_experiment', args=[str(self.id)])
532 549
533 550 def get_absolute_url_start(self):
534 551 return reverse('url_start_experiment', args=[str(self.id)])
535 552
536 553 def get_absolute_url_stop(self):
537 554 return reverse('url_stop_experiment', args=[str(self.id)])
538 555
539 556
540 557 class Configuration(PolymorphicModel):
541 558
542 559 template = models.BooleanField(default=False)
543 name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
560 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
561 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=True, null=True)
544 562 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
545 563 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
546 564 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
547 565 created_date = models.DateTimeField(auto_now_add=True)
548 566 programmed_date = models.DateTimeField(auto_now=True)
549 567 parameters = models.TextField(default='{}')
568 author = models.ForeignKey(User, null=True, blank=True)
569 hash = models.CharField(default='', max_length=64, null=True, blank=True)
550 570 message = ""
551 571
552 572 class Meta:
553 573 db_table = 'db_configurations'
574 ordering = ('device__device_type__name',)
554 575
555 576 def __str__(self):
556 577
557 device = '{}:'.format(self.device.device_type.name.upper())
578 ret = u'{} '.format(self.device.device_type.name.upper())
558 579
559 580 if 'mix' in [f.name for f in self._meta.get_fields()]:
560 581 if self.mix:
561 device = '{} MIXED:'.format(self.device.device_type.name.upper())
582 ret = '{} MIX '.format(self.device.device_type.name.upper())
583
584 if 'label' in [f.name for f in self._meta.get_fields()]:
585 ret += '{}'.format(self.label[:8])
562 586
587 #ret += '[ {} ]'.format(self.device.location.name)
563 588 if self.template:
564 return u'{} {} (template)'.format(device, self.name)
565 else:
566 return u'{} {}'.format(device, self.name)
589 ret += ' (template)'
590
591 return ret
592
593 @property
594 def name(self):
595
596 return str(self)
567 597
568 598 def jsonify(self):
569 599
570 600 data = {}
571 601
572 602 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
573 603 'created_date', 'programmed_date', 'template', 'device',
574 604 'experiment')
575 605
576 606 for field in self._meta.fields:
577 607 if field.name in ignored:
578 608 continue
579 609 data[field.name] = field.value_from_object(self)
580 610
581 611 data['device_type'] = self.device.device_type.name
582 612
583 613 if self.device.device_type.name == 'rc':
584 614 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
585 615 data['delays'] = self.get_delays()
586 616 data['pulses'] = self.get_pulses()
587 617
588 618 elif self.device.device_type.name == 'jars':
589 619 data['decode_type'] = DECODE_TYPE[self.decode_data][1]
590 620
591 621 elif self.device.device_type.name == 'dds':
592 622 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
593 623 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
594 624 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
595 625 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
596 626
597 627 return data
598 628
599 629 def clone(self, **kwargs):
600 630
601 631 self.pk = None
602 632 self.id = None
603 633 for attr, value in kwargs.items():
604 634 setattr(self, attr, value)
605 635
606 636 self.save()
607 637
608 638 return self
609 639
610 640 def parms_to_dict(self):
611 641
612 642 params = Params({})
613 643 params.add(self.jsonify(), 'configurations')
614 644
615 645 if self.device.device_type.name=='rc':
616 646 for line in self.get_lines():
617 647 params.add(line.jsonify(), 'lines')
618 648
619 649 return params.data
620 650
621 651 def parms_to_text(self):
622 652
623 653 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
624 654
625 655
626 656 def parms_to_binary(self):
627 657
628 658 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
629 659
630 660
631 661 def dict_to_parms(self, parameters, id=None):
632 662
633 663 params = Params(parameters)
634 664
635 665 if id:
636 666 data = params.get_conf(id_conf=id)
637 667 else:
638 668 data = params.get_conf(dtype=self.device.device_type.name)
639 669
640 670 if data['device_type']=='rc':
641 671 self.clean_lines()
642 672 lines = data.pop('lines', None)
643 673 for line_id in lines:
644 674 pass
645 675
646 676 for key, value in data.items():
647 677 if key not in ('id', 'device_type'):
648 678 setattr(self, key, value)
649 679
650 680 self.save()
651 681
652 682
653 683 def export_to_file(self, format="json"):
654 684
655 685 content_type = ''
656 686
657 687 if format == 'racp':
658 688 content_type = 'text/plain'
659 689 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
660 690 content = self.parms_to_text(file_format = 'racp')
661 691
662 692 if format == 'text':
663 693 content_type = 'text/plain'
664 694 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
665 695 content = self.parms_to_text()
666 696
667 697 if format == 'binary':
668 698 content_type = 'application/octet-stream'
669 699 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
670 700 content = self.parms_to_binary()
671 701
672 702 if not content_type:
673 703 content_type = 'application/json'
674 704 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
675 705 content = json.dumps(self.parms_to_dict(), indent=2)
676 706
677 707 fields = {'content_type':content_type,
678 708 'filename':filename,
679 709 'content':content
680 710 }
681 711
682 712 return fields
683 713
684 714 def import_from_file(self, fp):
685 715
686 716 parms = {}
687 717
688 718 path, ext = os.path.splitext(fp.name)
689 719
690 720 if ext == '.json':
691 721 parms = json.load(fp)
692 722
693 723 if ext == '.dds':
694 724 lines = fp.readlines()
695 725 parms = dds_data.text_to_dict(lines)
696 726
697 727 if ext == '.racp':
698 728 if self.device.device_type.name == 'jars':
699 729 parms = RacpFile(fp).to_dict()
700 730 parms['filter_parms'] = json.loads(self.filter_parms)
701 731 return parms
702 732 parms = RCFile(fp).to_dict()
703 733
704 734 return parms
705 735
706 736 def status_device(self):
707 737
708 738 self.message = 'Function not implemented'
709 739 return False
710 740
711 741
712 742 def stop_device(self):
713 743
714 744 self.message = 'Function not implemented'
715 745 return False
716 746
717 747
718 748 def start_device(self):
719 749
720 750 self.message = 'Function not implemented'
721 751 return False
722 752
723 753
724 754 def write_device(self, parms):
725 755
726 756 self.message = 'Function not implemented'
727 757 return False
728 758
729 759
730 760 def read_device(self):
731 761
732 762 self.message = 'Function not implemented'
733 763 return False
734 764
735 765
736 766 def get_absolute_url(self):
737 767 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
738 768
739 769 def get_absolute_url_edit(self):
740 770 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
741 771
772 def get_absolute_url_delete(self):
773 return reverse('url_delete_dev_conf', args=[str(self.id)])
774
742 775 def get_absolute_url_import(self):
743 776 return reverse('url_import_dev_conf', args=[str(self.id)])
744 777
745 778 def get_absolute_url_export(self):
746 779 return reverse('url_export_dev_conf', args=[str(self.id)])
747 780
748 781 def get_absolute_url_write(self):
749 782 return reverse('url_write_dev_conf', args=[str(self.id)])
750 783
751 784 def get_absolute_url_read(self):
752 785 return reverse('url_read_dev_conf', args=[str(self.id)])
753 786
754 787 def get_absolute_url_start(self):
755 788 return reverse('url_start_dev_conf', args=[str(self.id)])
756 789
757 790 def get_absolute_url_stop(self):
758 791 return reverse('url_stop_dev_conf', args=[str(self.id)])
759 792
760 793 def get_absolute_url_status(self):
761 794 return reverse('url_status_dev_conf', args=[str(self.id)])
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now