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