##// END OF EJS Templates
Main files have been fixed...
Fiorella Quino -
r267:8b30609ce30a
parent child
Show More
@@ -1,759 +1,761
1 1
2 2 import os
3 3 import json
4 4 import requests
5 5 import time
6 6 from datetime import datetime
7 7
8 8 try:
9 9 from polymorphic.models import PolymorphicModel
10 10 except:
11 11 from polymorphic import PolymorphicModel
12 12
13 13 from django.template.base import kwarg_re
14 14 from django.db import models
15 15 from django.core.urlresolvers import reverse
16 16 from django.core.validators import MinValueValidator, MaxValueValidator
17 17 from django.shortcuts import get_object_or_404
18 18
19 19 from apps.main.utils import Params
20 20 from apps.rc.utils import RCFile
21 21 from devices.dds import api as dds_api
22 22 from devices.dds import data as dds_data
23 23
24 24
25 25 DEV_PORTS = {
26 26 'rc' : 2000,
27 27 'dds' : 2000,
28 28 'jars' : 2000,
29 29 'usrp' : 2000,
30 30 'cgs' : 8080,
31 31 'abs' : 8080
32 32 }
33 33
34 34 RADAR_STATES = (
35 35 (0, 'No connected'),
36 36 (1, 'Connected'),
37 37 (2, 'Configured'),
38 38 (3, 'Running'),
39 39 (4, 'Scheduled'),
40 40 )
41 41
42 42 EXPERIMENT_TYPE = (
43 43 (0, 'RAW_DATA'),
44 44 (1, 'PDATA'),
45 45 )
46 46
47 47 DECODE_TYPE = (
48 48 (0, 'None'),
49 49 (1, 'TimeDomain'),
50 50 (2, 'FreqDomain'),
51 51 (3, 'InvFreqDomain'),
52 52 )
53 53
54 54 DEV_STATES = (
55 55 (0, 'No connected'),
56 56 (1, 'Connected'),
57 57 (2, 'Configured'),
58 58 (3, 'Running'),
59 59 (4, 'Unknown'),
60 60 )
61 61
62 62 DEV_TYPES = (
63 63 ('', 'Select a device type'),
64 64 ('rc', 'Radar Controller'),
65 65 ('dds', 'Direct Digital Synthesizer'),
66 66 ('jars', 'Jicamarca Radar Acquisition System'),
67 67 ('usrp', 'Universal Software Radio Peripheral'),
68 68 ('cgs', 'Clock Generator System'),
69 69 ('abs', 'Automatic Beam Switching'),
70 70 )
71 71
72 72 EXP_STATES = (
73 73 (0,'Error'), #RED
74 74 (1,'Configured'), #BLUE
75 75 (2,'Running'), #GREEN
76 76 (3,'Scheduled'), #YELLOW
77 77 (4,'Not Configured'), #WHITE
78 78 )
79 79
80 80 CONF_TYPES = (
81 81 (0, 'Active'),
82 82 (1, 'Historical'),
83 83 )
84 84
85 85 class Location(models.Model):
86 86
87 87 name = models.CharField(max_length = 30)
88 88 description = models.TextField(blank=True, null=True)
89 89
90 90 class Meta:
91 91 db_table = 'db_location'
92 92
93 93 def __str__(self):
94 94 return u'%s' % self.name
95 95
96 96 def get_absolute_url(self):
97 97 return reverse('url_location', args=[str(self.id)])
98 98
99 99
100 100 class DeviceType(models.Model):
101 101
102 102 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc')
103 103 sequence = models.PositiveSmallIntegerField(default=1000)
104 104 description = models.TextField(blank=True, null=True)
105 105
106 106 class Meta:
107 107 db_table = 'db_device_types'
108 108
109 109 def __str__(self):
110 110 return u'%s' % self.get_name_display()
111 111
112 112 class Device(models.Model):
113 113
114 114 device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
115 115 location = models.ForeignKey(Location, on_delete=models.CASCADE)
116 116
117 117 name = models.CharField(max_length=40, default='')
118 118 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
119 119 port_address = models.PositiveSmallIntegerField(default=2000)
120 120 description = models.TextField(blank=True, null=True)
121 121 status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES)
122 122
123 123 class Meta:
124 124 db_table = 'db_devices'
125 125
126 126 def __str__(self):
127 127 return u'[{}]: {}'.format(self.device_type.name.upper(),
128 128 self.name)
129 129
130 130 def get_status(self):
131 131 return self.status
132 132
133 133 @property
134 134 def status_color(self):
135 135 color = 'muted'
136 136 if self.status == 0:
137 137 color = "danger"
138 138 elif self.status == 1:
139 139 color = "warning"
140 140 elif self.status == 2:
141 141 color = "info"
142 142 elif self.status == 3:
143 143 color = "success"
144 144
145 145 return color
146 146
147 147 def url(self, path=None):
148 148
149 149 if path:
150 150 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
151 151 else:
152 152 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
153 153
154 154 def get_absolute_url(self):
155 155
156 156 return reverse('url_device', args=[str(self.id)])
157 157
158 158 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
159 159
160 160 if self.device_type.name=='dds':
161 161 try:
162 162 answer = dds_api.change_ip(ip = self.ip_address,
163 163 port = self.port_address,
164 164 new_ip = ip_address,
165 165 mask = mask,
166 166 gateway = gateway)
167 167 if answer[0]=='1':
168 168 self.message = '25|DDS - {}'.format(answer)
169 169 self.ip_address = ip_address
170 170 self.save()
171 171 else:
172 172 self.message = '30|DDS - {}'.format(answer)
173 173 return False
174 174 except Exception as e:
175 175 self.message = '40|{}'.format(str(e))
176 176 return False
177 177
178 178 elif self.device_type.name=='rc':
179 179 headers = {'content-type': "application/json",
180 180 'cache-control': "no-cache"}
181 181
182 182 ip = [int(x) for x in ip_address.split('.')]
183 183 dns = [int(x) for x in dns.split('.')]
184 184 gateway = [int(x) for x in gateway.split('.')]
185 185 subnet = [int(x) for x in mask.split('.')]
186 186
187 187 payload = {
188 188 "ip": ip,
189 189 "dns": dns,
190 190 "gateway": gateway,
191 191 "subnet": subnet
192 192 }
193 193
194 194 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
195 195 try:
196 196 answer = req.json()
197 197 if answer['changeip']=='ok':
198 198 self.message = '25|IP succesfully changed'
199 199 self.ip_address = ip_address
200 200 self.save()
201 201 else:
202 202 self.message = '30|An error ocuur when changing IP'
203 203 except Exception as e:
204 204 self.message = '40|{}'.format(str(e))
205 205 else:
206 206 self.message = 'Not implemented'
207 207 return False
208 208
209 209 return True
210 210
211 211
212 212 class Campaign(models.Model):
213 213
214 214 template = models.BooleanField(default=False)
215 215 name = models.CharField(max_length=60, unique=True)
216 216 start_date = models.DateTimeField(blank=True, null=True)
217 217 end_date = models.DateTimeField(blank=True, null=True)
218 218 tags = models.CharField(max_length=40)
219 219 description = models.TextField(blank=True, null=True)
220 220 experiments = models.ManyToManyField('Experiment', blank=True)
221 221
222 222 class Meta:
223 223 db_table = 'db_campaigns'
224 224 ordering = ('name',)
225 225
226 226 def __str__(self):
227 227 if self.template:
228 228 return u'{} (template)'.format(self.name)
229 229 else:
230 230 return u'{}'.format(self.name)
231 231
232 232 def jsonify(self):
233 233
234 234 data = {}
235 235
236 236 ignored = ('template')
237 237
238 238 for field in self._meta.fields:
239 239 if field.name in ignored:
240 240 continue
241 241 data[field.name] = field.value_from_object(self)
242 242
243 243 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
244 244 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
245 245
246 246 return data
247 247
248 248 def parms_to_dict(self):
249 249
250 250 params = Params()
251 251 params.add(self.jsonify(), 'campaigns')
252 252
253 253 for exp in Experiment.objects.filter(campaign = self):
254 254 params.add(exp.jsonify(), 'experiments')
255 255 configurations = Configuration.objects.filter(experiment=exp, type=0)
256 256
257 257 for conf in configurations:
258 258 params.add(conf.jsonify(), 'configurations')
259 259 if conf.device.device_type.name=='rc':
260 260 for line in conf.get_lines():
261 261 params.add(line.jsonify(), 'lines')
262 262
263 263 return params.data
264 264
265 265 def dict_to_parms(self, parms, CONF_MODELS):
266 266
267 267 experiments = Experiment.objects.filter(campaign = self)
268 268
269 269 if experiments:
270 270 for experiment in experiments:
271 271 experiment.delete()
272 272
273 273 for id_exp in parms['experiments']['allIds']:
274 274 exp_parms = parms['experiments']['byId'][id_exp]
275 275 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
276 276 exp = Experiment(name='{}'.format(dum))
277 277 exp.save()
278 278 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
279 279 self.experiments.add(exp)
280 280
281 281 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
282 282
283 283 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
284 284 self.start_date = camp_parms['start_date']
285 285 self.end_date = camp_parms['end_date']
286 286 self.tags = camp_parms['tags']
287 287 self.save()
288 288
289 289 return self
290 290
291 def get_experiments_by_radar(self, radar=None):
291 def get_experiments_by_radar(self, radar=None):
292 292
293 293 ret = []
294 294 if radar:
295 295 locations = Location.objects.filter(pk=radar)
296 296 else:
297 297 locations = set([e.location for e in self.experiments.all()])
298 298
299 299 for loc in locations:
300 300 dum = {}
301 301 dum['name'] = loc.name
302 302 dum['id'] = loc.pk
303 303 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
304 304 ret.append(dum)
305 305
306 306 return ret
307 307
308 308 def get_absolute_url(self):
309 309 return reverse('url_campaign', args=[str(self.id)])
310 310
311 311 def get_absolute_url_edit(self):
312 312 return reverse('url_edit_campaign', args=[str(self.id)])
313 313
314 314 def get_absolute_url_export(self):
315 315 return reverse('url_export_campaign', args=[str(self.id)])
316 316
317 317 def get_absolute_url_import(self):
318 318 return reverse('url_import_campaign', args=[str(self.id)])
319 319
320 320
321 321
322 322 class RunningExperiment(models.Model):
323 323 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
324 324 running_experiment = models.ManyToManyField('Experiment', blank = True)
325 325 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
326 326
327 327
328 328 class Experiment(models.Model):
329 329
330 330 template = models.BooleanField(default=False)
331 331 name = models.CharField(max_length=40, default='', unique=True)
332 332 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
333 freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
333 334 start_time = models.TimeField(default='00:00:00')
334 335 end_time = models.TimeField(default='23:59:59')
335 336 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
336 337
337 338 class Meta:
338 339 db_table = 'db_experiments'
339 340 ordering = ('template', 'name')
340 341
341 342 def __str__(self):
342 343 if self.template:
343 344 return u'%s (template)' % (self.name)
344 345 else:
345 346 return u'%s' % (self.name)
346 347
347 348 def jsonify(self):
348 349
349 350 data = {}
350 351
351 352 ignored = ('template')
352 353
353 354 for field in self._meta.fields:
354 355 if field.name in ignored:
355 356 continue
356 357 data[field.name] = field.value_from_object(self)
357 358
358 359 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
359 360 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
360 361 data['location'] = self.location.name
361 362 data['configurations'] = ['{}'.format(conf.pk) for
362 363 conf in Configuration.objects.filter(experiment=self)]
363 364
364 365 return data
365 366
366 367 @property
367 368 def radar_system(self):
368 369 return self.location
369 370
370 371 def clone(self, **kwargs):
371 372
372 373 confs = Configuration.objects.filter(experiment=self, type=0)
373 374 self.pk = None
374 375 self.name = '{} [{:%Y/%m/%d}]'.format(self.name, datetime.now())
375 376 for attr, value in kwargs.items():
376 377 setattr(self, attr, value)
377 378
378 379 self.save()
379 380
380 381 for conf in confs:
381 382 conf.clone(experiment=self, template=False)
382 383
383 384 return self
384 385
385 386 def start(self):
386 387 '''
387 388 Configure and start experiments's devices
388 389 ABS-CGS-DDS-RC-JARS
389 390 '''
390 391
391 392 result = 2
392 393
393 394 confs = Configuration.objects.filter(experiment=self).filter(type = 0).order_by('-device__device_type__sequence')
394 395 #Only Configured Devices.
395 396 for conf in confs:
396 397 dev_status = conf.device.status
397 398 if dev_status in [0,4]:
398 399 result = 0
399 400 return result
400 401 else:
401 402 if conf.device.device_type.name != 'jars':
402 403 conf.write_device()
403 404 time.sleep(1)
404 405 print conf.device.name+' has started...'
405 406 else:
406 407 conf.stop_device()
407 408 conf.write_device()
408 409 conf.start_device()
409 410 print conf.device.name+' has started...'
410 411
411 412 return result
412 413
413 414
414 415 def stop(self):
415 416 '''
416 417 Stop experiments's devices
417 418 DDS-JARS-RC-CGS-ABS
418 419 '''
419 420
420 421 result = 1
421 422
422 423 confs = Configuration.objects.filter(experiment=self).filter(type = 0).order_by('device__device_type__sequence')
423 424
424 425 for conf in confs:
425 426 dev_status = conf.device.status
426 427 if dev_status in [0,4]:
427 428 result = 0
428 429 return result
429 430
430 431 #Stop Device
431 432 confs=confs.exclude(device__device_type__name='cgs')
432 433 for conf in confs:
433 434 if conf.device.device_type.name != 'rc':
434 435 conf.stop_device()
435 436 else:
436 437 conf.reset_device()
437 438 print conf.device.name+' has stopped...'
438 439
439 440 return result
440 441
441 442
442 443 def get_status(self):
443 444
444 445 confs = Configuration.objects.filter(experiment=self)
445 446
446 447 for conf in confs:
447 448 conf.status_device()
448 449
449 450 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
450 451
451 452 if total==2*confs.count():
452 453 status = 1
453 454 elif total == 3*confs.count():
454 455 status = 2
455 456 else:
456 457 status = 0
457 458
458 459 if self.status<>3:
459 460 self.status = status
460 461 self.save()
461 462
462 463 def status_color(self):
463 464 color = 'muted'
464 465 if self.status == 0:
465 466 color = "danger"
466 467 elif self.status == 1:
467 468 color = "info"
468 469 elif self.status == 2:
469 470 color = "success"
470 471 elif self.status == 3:
471 472 color = "warning"
472 473
473 474 return color
474 475
475 476 def parms_to_dict(self):
476 477
477 478 params = Params()
478 479 params.add(self.jsonify(), 'experiments')
479 480
480 481 configurations = Configuration.objects.filter(experiment=self, type=0)
481 482
482 483 for conf in configurations:
483 484 params.add(conf.jsonify(), 'configurations')
484 485 if conf.device.device_type.name=='rc':
485 486 for line in conf.get_lines():
486 487 params.add(line.jsonify(), 'lines')
487 488
488 489 return params.data
489 490
490 491 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
491 492
492 493 configurations = Configuration.objects.filter(experiment=self)
493 494
494 495 if id_exp is not None:
495 496 exp_parms = parms['experiments']['byId'][id_exp]
496 497 else:
497 498 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
498 499
499 500 if configurations:
500 501 for configuration in configurations:
501 502 configuration.delete()
502 503
503 504 for id_conf in exp_parms['configurations']:
504 505 conf_parms = parms['configurations']['byId'][id_conf]
505 506 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
506 507 model = CONF_MODELS[conf_parms['device_type']]
507 508 conf = model(
508 509 experiment = self,
509 510 device = device,
510 511 )
511 512 conf.dict_to_parms(parms, id=id_conf)
512 513
513 514
514 515 location, created = Location.objects.get_or_create(name=exp_parms['location'])
515 516 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
516 517 self.location = location
517 518 self.start_time = exp_parms['start_time']
518 519 self.end_time = exp_parms['end_time']
519 520 self.save()
520 521
521 522 return self
522 523
523 524 def get_absolute_url(self):
524 525 return reverse('url_experiment', args=[str(self.id)])
525 526
526 527 def get_absolute_url_edit(self):
527 528 return reverse('url_edit_experiment', args=[str(self.id)])
528 529
529 530 def get_absolute_url_import(self):
530 531 return reverse('url_import_experiment', args=[str(self.id)])
531 532
532 533 def get_absolute_url_export(self):
533 534 return reverse('url_export_experiment', args=[str(self.id)])
534 535
535 536 def get_absolute_url_start(self):
536 537 return reverse('url_start_experiment', args=[str(self.id)])
537 538
538 539 def get_absolute_url_stop(self):
539 540 return reverse('url_stop_experiment', args=[str(self.id)])
540 541
541 542
542 543 class Configuration(PolymorphicModel):
543 544
544 545 template = models.BooleanField(default=False)
545 546
546 547 name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
547 548
548 549 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
549 550 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
550 551
551 552 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
552 553
553 554 created_date = models.DateTimeField(auto_now_add=True)
554 555 programmed_date = models.DateTimeField(auto_now=True)
555 556
556 557 parameters = models.TextField(default='{}')
557 558
558 559 message = ""
559 560
560 561 class Meta:
561 562 db_table = 'db_configurations'
562 563
563 564 def __str__(self):
564 565
565 566 device = '{}:'.format(self.device.device_type.name.upper())
566 567
567 568 if 'mix' in [f.name for f in self._meta.get_fields()]:
568 569 if self.mix:
569 570 device = '{} MIXED:'.format(self.device.device_type.name.upper())
570 571
571 572 if self.template:
572 573 return u'{} {} (template)'.format(device, self.name)
573 574 else:
574 575 return u'{} {}'.format(device, self.name)
575 576
576 577 def jsonify(self):
577 578
578 579 data = {}
579 580
580 581 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
581 582 'created_date', 'programmed_date', 'template', 'device',
582 583 'experiment')
583 584
584 585 for field in self._meta.fields:
585 586 if field.name in ignored:
586 587 continue
587 588 data[field.name] = field.value_from_object(self)
588 589
589 590 data['device_type'] = self.device.device_type.name
590 591
591 592 if self.device.device_type.name == 'rc':
592 593 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
593 594 data['delays'] = self.get_delays()
594 595 data['pulses'] = self.get_pulses()
595 596
596 597 elif self.device.device_type.name == 'jars':
597 598 data['decode_type'] = DECODE_TYPE[self.decode_data][1]
598 599
599 600 elif self.device.device_type.name == 'dds':
600 601 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
601 602 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
602 603 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
603 604 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
604 605
605 606 return data
606 607
607 608 def clone(self, **kwargs):
608 609
609 610 self.pk = None
610 611 self.id = None
611 612 for attr, value in kwargs.items():
612 613 setattr(self, attr, value)
613 614
614 615 self.save()
615 616
616 617 return self
617 618
618 619 def parms_to_dict(self):
619 620
620 621 params = Params()
621 622 params.add(self.jsonify(), 'configurations')
622 623
623 624 if self.device.device_type.name=='rc':
624 625 for line in self.get_lines():
625 626 params.add(line.jsonify(), 'lines')
626 627
627 628 return params.data
628 629
629 630 def parms_to_text(self):
630 631
631 632 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
632 633
633 634
634 635 def parms_to_binary(self):
635 636
636 637 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
637 638
638 639
639 640 def dict_to_parms(self, parameters, id=None):
640 641
641 642 params = Params(parameters)
642 643
643 644 if id:
644 645 data = params.get_conf(id_conf=id)
645 646 else:
646 647 data = params.get_conf(dtype=self.device.device_type.name)
647 648
648 649 if data['device_type']=='rc':
649 650 self.clean_lines()
650 651 lines = data.pop('lines', None)
651 652 for line_id in lines:
652 653 pass
653 654
654 655 for key, value in data.items():
655 656 if key not in ('id', 'device_type'):
656 657 setattr(self, key, value)
657 658
658 659 self.save()
659 660
660 def export_to_file(self, format="json"):
661
662 def export_to_file(self, format="json"):
661 663
662 664 content_type = ''
663 665
664 666 if format == 'text':
665 667 content_type = 'text/plain'
666 668 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
667 669 content = self.parms_to_text()
668 670
669 671 if format == 'binary':
670 672 content_type = 'application/octet-stream'
671 673 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
672 674 content = self.parms_to_binary()
673 675
674 676 if not content_type:
675 677 content_type = 'application/json'
676 678 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
677 679 content = json.dumps(self.parms_to_dict(), indent=2)
678 680
679 681 fields = {'content_type':content_type,
680 682 'filename':filename,
681 683 'content':content
682 684 }
683 685
684 686 return fields
685 687
686 def import_from_file(self, fp):
688 def import_from_file(self, fp):
687 689
688 690 parms = {}
689 691
690 692 path, ext = os.path.splitext(fp.name)
691 693
692 694 if ext == '.json':
693 695 parms = json.load(fp)
694 696
695 697 if ext == '.dds':
696 698 lines = fp.readlines()
697 699 parms = dds_data.text_to_dict(lines)
698 700
699 701 if ext == '.racp':
700 702 parms = RCFile(fp).to_dict()
701 703
702 704 return parms
703 705
704 706 def status_device(self):
705 707
706 708 self.message = 'Function not implemented'
707 709 return False
708 710
709 711
710 712 def stop_device(self):
711 713
712 714 self.message = 'Function not implemented'
713 715 return False
714 716
715 717
716 718 def start_device(self):
717 719
718 720 self.message = 'Function not implemented'
719 721 return False
720 722
721 723
722 724 def write_device(self, parms):
723 725
724 726 self.message = 'Function not implemented'
725 727 return False
726 728
727 729
728 730 def read_device(self):
729 731
730 732 self.message = 'Function not implemented'
731 733 return False
732 734
733 735
734 736 def get_absolute_url(self):
735 737 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
736 738
737 739 def get_absolute_url_edit(self):
738 740 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
739 741
740 742 def get_absolute_url_import(self):
741 743 return reverse('url_import_dev_conf', args=[str(self.id)])
742 744
743 745 def get_absolute_url_export(self):
744 746 return reverse('url_export_dev_conf', args=[str(self.id)])
745 747
746 748 def get_absolute_url_write(self):
747 749 return reverse('url_write_dev_conf', args=[str(self.id)])
748 750
749 751 def get_absolute_url_read(self):
750 752 return reverse('url_read_dev_conf', args=[str(self.id)])
751 753
752 754 def get_absolute_url_start(self):
753 755 return reverse('url_start_dev_conf', args=[str(self.id)])
754 756
755 757 def get_absolute_url_stop(self):
756 758 return reverse('url_stop_dev_conf', args=[str(self.id)])
757 759
758 760 def get_absolute_url_status(self):
759 761 return reverse('url_status_dev_conf', args=[str(self.id)])
@@ -1,103 +1,109
1 1 {% extends "base.html" %}
2 2 {% load bootstrap3 %}
3 3 {% load static %}
4 4 {% load main_tags %}
5 5 {% block extra-head %}
6 6 <link href="{% static 'css/bootstrap-datetimepicker.min.css' %}" media="screen" rel="stylesheet">
7 7 {% endblock %}
8 8
9 9 {% block exp-active %}active{% endblock %}
10 10
11 11 {% block content-title %}{{title}}{% endblock %}
12 12 {% block content-suptitle %}{{suptitle}}{% endblock %}
13 13
14 14 {% block content %}
15 15
16 16 <table class="table table-bordered">
17 17 {% for key in experiment_keys %}
18 18 <tr><th>{{key|title}}</th><td>{{experiment|attr:key}}</td></tr>
19 19 {% endfor %}
20 <tr><th>Lambda (m)</th><td>{{radar_lambda}}</td></tr>
20 21 </table>
21 22
22 23
23 24 {% for configuration in configurations %}
24 25
25 26 <div class="">
26 27 <h4 class="panel-title"><b> {{configuration}}</b></h4>
27 28 <br>
28 29 </div>
29
30 {% if configuration.device.device_type.name == 'dds' %}
31 <table class="table table-bordered">
30
31 {% if configuration.device.device_type.name == 'dds' %}
32 <table class="table table-bordered">
32 33 <tr><th>Frequency A (Mhz)</th><td>{{configuration.frequencyA_Mhz}}</td></tr>
33 <tr><th>Multiplier</th><td>{{configuration.multiplier}}</td></tr>
34 <tr><th>Multiplier</th><td>{{configuration.multiplier}}</td></tr>
34 35 </table>
35 36 {% endif %}
36 37
37 {% if configuration.device.device_type.name == 'rc' %}
38 {% if configuration.device.device_type.name == 'rc' %}
38 39
39 40 <table class="table table-bordered">
40 41 <!--<h4 class="panel-title"> </h4>-->
41 42 <tr><th>NTXs</th><td>{{configuration.ntx}}</td></tr>
42 43 <tr><th>IPP(km)</th><td>{{configuration.ipp}}</td></tr>
43
44 <tr><th>DC</th><td>{{duty_cycle}}%</td></tr>
45
44 46 {% for tx_line in configuration.tx_lines %}
45 47 <tr><th colspan="2">{{tx_line.name}}</th></tr>
46 48 <tr><th>Width(km)</th><td>{{tx_line.width}}</td></tr>
47 <tr><th>Taus</th><td>{{tx_line.taus}}</td></tr>
48 <tr><th>codes</th><td>{{tx_line.codes}}</td></tr>
49 <tr><th>Sample Windows</th><td>{{tx_line.windows}}</td></tr>
49 <tr><th>Taus</th><td>{{tx_line.taus}}</td></tr>
50 <tr><th>codes</th><td>{{tx_line.codes}}</td></tr>
51 <tr><th>Sample Windows</th><td>{{tx_line.windows}}</td></tr>
50 52 {% endfor %}
51
53
52 54 </table>
53 55 {% endif %}
54 56
55 {% if configuration.device.device_type.name == 'jars' %}
57 {% if configuration.device.device_type.name == 'jars' %}
56 58
57 59 <table class="table table-bordered">
58 60 <!--<h4 class="panel-title"> JARS </h4>-->
59 61 <tr><th>Data Type</th><td>{{exp_type}}</td></tr>
60 62 <tr><th># Channels</th><td>{{configuration.channels_number}}</td></tr>
61 63 <tr><th>Coh Int</th><td>{{configuration.cohe_integr}}</td></tr>
62 64 <tr><th>FFT Points</th><td>{{configuration.fftpoints}}</td></tr>
63 65 {% if exp_type == 'PDATA'%}
64 66 <tr><th>Inc Int</th><td>{{configuration.incohe_integr}}</td></tr>
65 67 <tr><th>Spec. Comb.</th><td>{{configuration.spectral}}</td></tr>
66 68 {% endif %}
67 69 <tr><th>Acq Prof</th><td>{{configuration.acq_profiles}}</td></tr>
68 70 <tr><th>Prof x Block</th><td>{{configuration.profiles_block}}</td></tr>
69 71 <tr><th>Block x File</th><td>{{ configuration.raw_data_blocks }}</td></tr>
70 <tr><th>Rate (MB/h)</th><td>{{ rate }}</td></tr>
72 <tr><th>Time per Block (s)</th><td>{{ time_per_block }}</td></tr>
73 <tr><th>Acqtime (s)</th><td>{{ acqtime }}</td></tr>
74 <tr><th>Rate </th><td>{{ rate_bh }} || {{ rate_gh }}</td></tr>
75 <tr><th>Va (m/s)</th><td>{{ va }}</td></tr>
76 <tr><th>Vrange (m/s)</th><td>{{ vrange }}</td></tr>
71 77 </table>
72 78 {% endif %}
73 79
74 80 {% endfor %}
75 81
76 82 <div class="pull-right">
77 83 <button type="button" class="btn btn-primary" id="bt_back">Back</button>
78 84 <button type="button" class="btn btn-primary" id="bt_verify">Verify Parameters</button>
79 85 </div>
80 86
81 87 {% endblock %}
82 88
83 89 {% block sidebar%}
84 90 {% include "sidebar_devices.html" %}
85 91 {% endblock %}
86 92
87 93 {% block extra-js%}
88 94 <script type="text/javascript">
89 95
90 96 $(".clickable-row").click(function() {
91 97 document.location = $(this).data("href");
92 98 });
93 99
94 100 $("#bt_back").click(function() {
95 101 document.location = "{% url 'url_experiment' experiment.id%}";
96 102 });
97 103
98 104 $("#bt_verify").click(function() {
99 105 document.location = "{% url 'url_verify_experiment' experiment.id%}";
100 106 });
101 107
102 108 </script>
103 109 {% endblock %}
@@ -1,1712 +1,1710
1 1 import ast
2 2 import json
3 3 from datetime import datetime
4 4
5 5 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
6 6 from django.utils.safestring import mark_safe
7 7 from django.http import HttpResponseRedirect
8 8 from django.core.urlresolvers import reverse
9 9 from django.db.models import Q
10 10 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
11 11 from django.contrib import messages
12 12 from django.http.request import QueryDict
13 13
14 14 try:
15 15 from urllib.parse import urlencode
16 16 except ImportError:
17 17 from urllib import urlencode
18 18
19 19 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
20 20 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
21 21
22 22 from .tasks import task_start, task_stop, task_status
23 23
24 24 from apps.rc.forms import RCConfigurationForm, RCLineCode, RCMixConfigurationForm
25 25 from apps.dds.forms import DDSConfigurationForm
26 26 from apps.jars.forms import JARSConfigurationForm
27 27 from apps.cgs.forms import CGSConfigurationForm
28 28 from apps.abs.forms import ABSConfigurationForm
29 29 from apps.usrp.forms import USRPConfigurationForm
30 30
31 31 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment, DEV_STATES
32 32 from apps.cgs.models import CGSConfiguration
33 33 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
34 34 from apps.usrp.models import USRPConfiguration
35 35 from apps.abs.models import ABSConfiguration
36 36 from apps.rc.models import RCConfiguration, RCLine, RCLineType
37 37 from apps.dds.models import DDSConfiguration
38 38
39 39 from django.contrib.auth.decorators import login_required
40 40 from django.contrib.auth.decorators import user_passes_test
41 41 from django.contrib.admin.views.decorators import staff_member_required
42 42
43 43 CONF_FORMS = {
44 44 'rc': RCConfigurationForm,
45 45 'dds': DDSConfigurationForm,
46 46 'jars': JARSConfigurationForm,
47 47 'cgs': CGSConfigurationForm,
48 48 'abs': ABSConfigurationForm,
49 49 'usrp': USRPConfigurationForm,
50 50 }
51 51
52 52 CONF_MODELS = {
53 53 'rc': RCConfiguration,
54 54 'dds': DDSConfiguration,
55 55 'jars': JARSConfiguration,
56 56 'cgs': CGSConfiguration,
57 57 'abs': ABSConfiguration,
58 58 'usrp': USRPConfiguration,
59 59 }
60 60
61 61 MIX_MODES = {
62 62 '0': 'P',
63 63 '1': 'S',
64 64 }
65 65
66 66 MIX_OPERATIONS = {
67 67 '0': 'OR',
68 68 '1': 'XOR',
69 69 '2': 'AND',
70 70 '3': 'NAND',
71 71 }
72 72
73 73 def index(request):
74 74 kwargs = {'no_sidebar':True}
75 75
76 76 return render(request, 'index.html', kwargs)
77 77
78 78
79 79 def locations(request):
80 80
81 81 page = request.GET.get('page')
82 82 order = ('name',)
83 83
84 84 kwargs = get_paginator(Location, page, order)
85 85
86 86 kwargs['keys'] = ['name', 'description']
87 87 kwargs['title'] = 'Radar System'
88 88 kwargs['suptitle'] = 'List'
89 89 kwargs['no_sidebar'] = True
90 90
91 91 return render(request, 'base_list.html', kwargs)
92 92
93 93
94 94 def location(request, id_loc):
95 95
96 96 location = get_object_or_404(Location, pk=id_loc)
97 97
98 98 kwargs = {}
99 99 kwargs['location'] = location
100 100 kwargs['location_keys'] = ['name', 'description']
101 101
102 102 kwargs['title'] = 'Location'
103 103 kwargs['suptitle'] = 'Details'
104 104
105 105 return render(request, 'location.html', kwargs)
106 106
107 107
108 108 @user_passes_test(lambda u:u.is_staff)
109 109 def location_new(request):
110 110
111 111 if request.method == 'GET':
112 112 form = LocationForm()
113 113
114 114 if request.method == 'POST':
115 115 form = LocationForm(request.POST)
116 116
117 117 if form.is_valid():
118 118 form.save()
119 119 return redirect('url_locations')
120 120
121 121 kwargs = {}
122 122 kwargs['form'] = form
123 123 kwargs['title'] = 'Radar System'
124 124 kwargs['suptitle'] = 'New'
125 125 kwargs['button'] = 'Create'
126 126
127 127 return render(request, 'base_edit.html', kwargs)
128 128
129 129
130 130 @user_passes_test(lambda u:u.is_staff)
131 131 def location_edit(request, id_loc):
132 132
133 133 location = get_object_or_404(Location, pk=id_loc)
134 134
135 135 if request.method=='GET':
136 136 form = LocationForm(instance=location)
137 137
138 138 if request.method=='POST':
139 139 form = LocationForm(request.POST, instance=location)
140 140
141 141 if form.is_valid():
142 142 form.save()
143 143 return redirect('url_locations')
144 144
145 145 kwargs = {}
146 146 kwargs['form'] = form
147 147 kwargs['title'] = 'Location'
148 148 kwargs['suptitle'] = 'Edit'
149 149 kwargs['button'] = 'Update'
150 150
151 151 return render(request, 'base_edit.html', kwargs)
152 152
153 153
154 154 @user_passes_test(lambda u:u.is_staff)
155 155 def location_delete(request, id_loc):
156 156
157 157 location = get_object_or_404(Location, pk=id_loc)
158 158
159 159 if request.method=='POST':
160 160
161 161 if request.user.is_staff:
162 162 location.delete()
163 163 return redirect('url_locations')
164 164
165 165 messages.error(request, 'Not enough permission to delete this object')
166 166 return redirect(location.get_absolute_url())
167 167
168 168 kwargs = {
169 169 'title': 'Delete',
170 170 'suptitle': 'Location',
171 171 'object': location,
172 172 'previous': location.get_absolute_url(),
173 173 'delete': True
174 174 }
175 175
176 176 return render(request, 'confirm.html', kwargs)
177 177
178 178
179 179 def devices(request):
180 180
181 181 page = request.GET.get('page')
182 182 order = ('device_type', 'name')
183 183
184 184 kwargs = get_paginator(Device, page, order)
185 185 kwargs['keys'] = ['name', 'ip_address', 'port_address', 'device_type']
186 186 kwargs['title'] = 'Device'
187 187 kwargs['suptitle'] = 'List'
188 188 kwargs['no_sidebar'] = True
189 189
190 190 return render(request, 'base_list.html', kwargs)
191 191
192 192
193 193 def device(request, id_dev):
194 194
195 195 device = get_object_or_404(Device, pk=id_dev)
196 196
197 197 kwargs = {}
198 198 kwargs['device'] = device
199 199 kwargs['device_keys'] = ['device_type', 'name', 'ip_address', 'port_address', 'description']
200 200
201 201 kwargs['title'] = 'Device'
202 202 kwargs['suptitle'] = 'Details'
203 203
204 204 return render(request, 'device.html', kwargs)
205 205
206 206
207 207 @user_passes_test(lambda u:u.is_staff)
208 208 def device_new(request):
209 209
210 210 if request.method == 'GET':
211 211 form = DeviceForm()
212 212
213 213 if request.method == 'POST':
214 214 form = DeviceForm(request.POST)
215 215
216 216 if form.is_valid():
217 217 form.save()
218 218 return redirect('url_devices')
219 219
220 220 kwargs = {}
221 221 kwargs['form'] = form
222 222 kwargs['title'] = 'Device'
223 223 kwargs['suptitle'] = 'New'
224 224 kwargs['button'] = 'Create'
225 225
226 226 return render(request, 'base_edit.html', kwargs)
227 227
228 228
229 229 @user_passes_test(lambda u:u.is_staff)
230 230 def device_edit(request, id_dev):
231 231
232 232 device = get_object_or_404(Device, pk=id_dev)
233 233
234 234 if request.method=='GET':
235 235 form = DeviceForm(instance=device)
236 236
237 237 if request.method=='POST':
238 238 form = DeviceForm(request.POST, instance=device)
239 239
240 240 if form.is_valid():
241 241 form.save()
242 242 return redirect(device.get_absolute_url())
243 243
244 244 kwargs = {}
245 245 kwargs['form'] = form
246 246 kwargs['title'] = 'Device'
247 247 kwargs['suptitle'] = 'Edit'
248 248 kwargs['button'] = 'Update'
249 249
250 250 return render(request, 'base_edit.html', kwargs)
251 251
252 252
253 253 @user_passes_test(lambda u:u.is_staff)
254 254 def device_delete(request, id_dev):
255 255
256 256 device = get_object_or_404(Device, pk=id_dev)
257 257
258 258 if request.method=='POST':
259 259
260 260 if request.user.is_staff:
261 261 device.delete()
262 262 return redirect('url_devices')
263 263
264 264 messages.error(request, 'Not enough permission to delete this object')
265 265 return redirect(device.get_absolute_url())
266 266
267 267 kwargs = {
268 268 'title': 'Delete',
269 269 'suptitle': 'Device',
270 270 'object': device,
271 271 'previous': device.get_absolute_url(),
272 272 'delete': True
273 273 }
274 274
275 275 return render(request, 'confirm.html', kwargs)
276 276
277 277
278 278 @user_passes_test(lambda u:u.is_staff)
279 279 def device_change_ip(request, id_dev):
280 280
281 281 device = get_object_or_404(Device, pk=id_dev)
282 282
283 283 if request.method=='POST':
284 284
285 285 if request.user.is_staff:
286 286 device.change_ip(**request.POST.dict())
287 287 level, message = device.message.split('|')
288 288 messages.add_message(request, level, message)
289 289 else:
290 290 messages.error(request, 'Not enough permission to delete this object')
291 291 return redirect(device.get_absolute_url())
292 292
293 293 kwargs = {
294 294 'title': 'Device',
295 295 'suptitle': 'Change IP',
296 296 'object': device,
297 297 'previous': device.get_absolute_url(),
298 298 'form': ChangeIpForm(initial={'ip_address':device.ip_address}),
299 299 'message' : ' ',
300 300 }
301 301
302 302 return render(request, 'confirm.html', kwargs)
303 303
304 304
305 305 def campaigns(request):
306 306
307 307 page = request.GET.get('page')
308 308 order = ('start_date',)
309 309 filters = request.GET.copy()
310 310
311 311 kwargs = get_paginator(Campaign, page, order, filters)
312 312
313 313 form = FilterForm(initial=request.GET, extra_fields=['range_date', 'tags','template'])
314 314 kwargs['keys'] = ['name', 'start_date', 'end_date']
315 315 kwargs['title'] = 'Campaign'
316 316 kwargs['suptitle'] = 'List'
317 317 kwargs['no_sidebar'] = True
318 318 kwargs['form'] = form
319 319 filters.pop('page', None)
320 320 kwargs['q'] = urlencode(filters)
321 321
322 322 return render(request, 'base_list.html', kwargs)
323 323
324 324
325 325 def campaign(request, id_camp):
326 326
327 327 campaign = get_object_or_404(Campaign, pk=id_camp)
328 328 experiments = Experiment.objects.filter(campaign=campaign)
329 329
330 330 form = CampaignForm(instance=campaign)
331 331
332 332 kwargs = {}
333 333 kwargs['campaign'] = campaign
334 334 kwargs['campaign_keys'] = ['template', 'name', 'start_date', 'end_date', 'tags', 'description']
335 335
336 336 kwargs['experiments'] = experiments
337 337 kwargs['experiment_keys'] = ['name', 'radar_system', 'start_time', 'end_time']
338 338
339 339 kwargs['title'] = 'Campaign'
340 340 kwargs['suptitle'] = 'Details'
341 341
342 342 kwargs['form'] = form
343 343 kwargs['button'] = 'Add Experiment'
344 344
345 345 return render(request, 'campaign.html', kwargs)
346 346
347 347
348 348 @user_passes_test(lambda u:u.is_staff)
349 349 def campaign_new(request):
350 350
351 351 kwargs = {}
352 352
353 353 if request.method == 'GET':
354 354
355 355 if 'template' in request.GET:
356 356 if request.GET['template']=='0':
357 357 form = NewForm(initial={'create_from':2},
358 358 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
359 359 else:
360 360 kwargs['button'] = 'Create'
361 361 kwargs['experiments'] = Configuration.objects.filter(experiment=request.GET['template'])
362 362 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
363 363 camp = Campaign.objects.get(pk=request.GET['template'])
364 364 form = CampaignForm(instance=camp,
365 365 initial={'name':'{} [{:%Y/%m/%d}]'.format(camp.name, datetime.now()),
366 366 'template':False})
367 367 elif 'blank' in request.GET:
368 368 kwargs['button'] = 'Create'
369 369 form = CampaignForm()
370 370 else:
371 371 form = NewForm()
372 372
373 373 if request.method == 'POST':
374 374 kwargs['button'] = 'Create'
375 375 post = request.POST.copy()
376 376 experiments = []
377 377
378 378 for id_exp in post.getlist('experiments'):
379 379 exp = Experiment.objects.get(pk=id_exp)
380 380 new_exp = exp.clone(template=False)
381 381 experiments.append(new_exp)
382 382
383 383 post.setlist('experiments', [])
384 384
385 385 form = CampaignForm(post)
386 386
387 387 if form.is_valid():
388 388 campaign = form.save()
389 389 for exp in experiments:
390 390 campaign.experiments.add(exp)
391 391 campaign.save()
392 392 return redirect('url_campaign', id_camp=campaign.id)
393 393
394 394 kwargs['form'] = form
395 395 kwargs['title'] = 'Campaign'
396 396 kwargs['suptitle'] = 'New'
397 397
398 398 return render(request, 'campaign_edit.html', kwargs)
399 399
400 400
401 401 @user_passes_test(lambda u:u.is_staff)
402 402 def campaign_edit(request, id_camp):
403 403
404 404 campaign = get_object_or_404(Campaign, pk=id_camp)
405 405
406 406 if request.method=='GET':
407 407 form = CampaignForm(instance=campaign)
408 408
409 409 if request.method=='POST':
410 410 exps = campaign.experiments.all().values_list('pk', flat=True)
411 411 post = request.POST.copy()
412 412 new_exps = post.getlist('experiments')
413 413 post.setlist('experiments', [])
414 414 form = CampaignForm(post, instance=campaign)
415 415
416 416 if form.is_valid():
417 417 camp = form.save()
418 418 for id_exp in new_exps:
419 419 if int(id_exp) in exps:
420 420 exps.pop(id_exp)
421 421 else:
422 422 exp = Experiment.objects.get(pk=id_exp)
423 423 if exp.template:
424 424 camp.experiments.add(exp.clone(template=False))
425 425 else:
426 426 camp.experiments.add(exp)
427 427
428 428 for id_exp in exps:
429 429 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
430 430
431 431 return redirect('url_campaign', id_camp=id_camp)
432 432
433 433 kwargs = {}
434 434 kwargs['form'] = form
435 435 kwargs['title'] = 'Campaign'
436 436 kwargs['suptitle'] = 'Edit'
437 437 kwargs['button'] = 'Update'
438 438
439 439 return render(request, 'campaign_edit.html', kwargs)
440 440
441 441
442 442 @user_passes_test(lambda u:u.is_staff)
443 443 def campaign_delete(request, id_camp):
444 444
445 445 campaign = get_object_or_404(Campaign, pk=id_camp)
446 446
447 447 if request.method=='POST':
448 448 if request.user.is_staff:
449 449
450 450 for exp in campaign.experiments.all():
451 451 for conf in Configuration.objects.filter(experiment=exp):
452 452 conf.delete()
453 453 exp.delete()
454 454 campaign.delete()
455 455
456 456 return redirect('url_campaigns')
457 457
458 458 messages.error(request, 'Not enough permission to delete this object')
459 459 return redirect(campaign.get_absolute_url())
460 460
461 461 kwargs = {
462 462 'title': 'Delete',
463 463 'suptitle': 'Campaign',
464 464 'object': campaign,
465 465 'previous': campaign.get_absolute_url(),
466 466 'delete': True
467 467 }
468 468
469 469 return render(request, 'confirm.html', kwargs)
470 470
471 471
472 472 @user_passes_test(lambda u:u.is_staff)
473 473 def campaign_export(request, id_camp):
474 474
475 475 campaign = get_object_or_404(Campaign, pk=id_camp)
476 476 content = campaign.parms_to_dict()
477 477 content_type = 'application/json'
478 478 filename = '%s_%s.json' %(campaign.name, campaign.id)
479 479
480 480 response = HttpResponse(content_type=content_type)
481 481 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
482 482 response.write(json.dumps(content, indent=2))
483 483
484 484 return response
485 485
486 486
487 487 @user_passes_test(lambda u:u.is_staff)
488 488 def campaign_import(request, id_camp):
489 489
490 490 campaign = get_object_or_404(Campaign, pk=id_camp)
491 491
492 492 if request.method == 'GET':
493 493 file_form = UploadFileForm()
494 494
495 495 if request.method == 'POST':
496 496 file_form = UploadFileForm(request.POST, request.FILES)
497 497
498 498 if file_form.is_valid():
499 499 new_camp = campaign.dict_to_parms(json.load(request.FILES['file']), CONF_MODELS)
500 500 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
501 501 return redirect(new_camp.get_absolute_url_edit())
502 502
503 503 messages.error(request, "Could not import parameters from file")
504 504
505 505 kwargs = {}
506 506 kwargs['title'] = 'Campaign'
507 507 kwargs['form'] = file_form
508 508 kwargs['suptitle'] = 'Importing file'
509 509 kwargs['button'] = 'Import'
510 510
511 511 return render(request, 'campaign_import.html', kwargs)
512 512
513 513
514 514 def experiments(request):
515 515
516 516 page = request.GET.get('page')
517 517 order = ('location',)
518 518 filters = request.GET.copy()
519 519
520 520 kwargs = get_paginator(Experiment, page, order, filters)
521 521
522 522 form = FilterForm(initial=request.GET, extra_fields=['tags','template'])
523 523
524 524 kwargs['keys'] = ['name', 'radar_system', 'start_time', 'end_time']
525 525 kwargs['title'] = 'Experiment'
526 526 kwargs['suptitle'] = 'List'
527 527 kwargs['no_sidebar'] = True
528 528 kwargs['form'] = form
529 529 filters.pop('page', None)
530 530 kwargs['q'] = urlencode(filters)
531 531
532 532 return render(request, 'base_list.html', kwargs)
533 533
534 534
535 535 def experiment(request, id_exp):
536 536
537 537 experiment = get_object_or_404(Experiment, pk=id_exp)
538 538
539 539 configurations = Configuration.objects.filter(experiment=experiment, type=0)
540 540
541 541 kwargs = {}
542 542
543 543 kwargs['experiment_keys'] = ['template', 'radar_system', 'name', 'freq', 'start_time', 'end_time']
544 544 kwargs['experiment'] = experiment
545 545
546 546 kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status']
547 547 kwargs['configurations'] = configurations
548 548
549 549 kwargs['title'] = 'Experiment'
550 550 kwargs['suptitle'] = 'Details'
551 551
552 552 kwargs['button'] = 'Add Configuration'
553 553
554 554 ###### SIDEBAR ######
555 555 kwargs.update(sidebar(experiment=experiment))
556 556
557 557 return render(request, 'experiment.html', kwargs)
558 558
559 559
560 560 @user_passes_test(lambda u:u.is_staff)
561 561 def experiment_new(request, id_camp=None):
562 562
563 563 kwargs = {}
564 564
565 565 if request.method == 'GET':
566 566 if 'template' in request.GET:
567 567 if request.GET['template']=='0':
568 568 form = NewForm(initial={'create_from':2},
569 569 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
570 570 else:
571 571 kwargs['button'] = 'Create'
572 572 kwargs['configurations'] = Configuration.objects.filter(experiment=request.GET['template'])
573 573 kwargs['configuration_keys'] = ['name', 'device__name', 'device__ip_address', 'device__port_address']
574 574 exp=Experiment.objects.get(pk=request.GET['template'])
575 575 form = ExperimentForm(instance=exp,
576 576 initial={'name': '{}_{:%y%m%d}'.format(exp.name, datetime.now()),
577 577 'template': False})
578 578 elif 'blank' in request.GET:
579 579 kwargs['button'] = 'Create'
580 580 form = ExperimentForm()
581 581 else:
582 582 form = NewForm()
583 583
584 584 if request.method == 'POST':
585 585 form = ExperimentForm(request.POST)
586 586 if form.is_valid():
587 587 experiment = form.save()
588 588
589 589 if 'template' in request.GET:
590 590 configurations = Configuration.objects.filter(experiment=request.GET['template'], type=0)
591 591 for conf in configurations:
592 592 conf.clone(experiment=experiment, template=False)
593 593
594 594 return redirect('url_experiment', id_exp=experiment.id)
595 595
596 596 kwargs['form'] = form
597 597 kwargs['title'] = 'Experiment'
598 598 kwargs['suptitle'] = 'New'
599 599
600 600 return render(request, 'experiment_edit.html', kwargs)
601 601
602 602
603 603 @user_passes_test(lambda u:u.is_staff)
604 604 def experiment_edit(request, id_exp):
605 605
606 606 experiment = get_object_or_404(Experiment, pk=id_exp)
607 607
608 608 if request.method == 'GET':
609 609 form = ExperimentForm(instance=experiment)
610 610
611 611 if request.method=='POST':
612 612 form = ExperimentForm(request.POST, instance=experiment)
613 613
614 614 if form.is_valid():
615 615 experiment = form.save()
616 616 return redirect('url_experiment', id_exp=experiment.id)
617 617
618 618 kwargs = {}
619 619 kwargs['form'] = form
620 620 kwargs['title'] = 'Experiment'
621 621 kwargs['suptitle'] = 'Edit'
622 622 kwargs['button'] = 'Update'
623 623
624 624 return render(request, 'experiment_edit.html', kwargs)
625 625
626 626
627 627 @user_passes_test(lambda u:u.is_staff)
628 628 def experiment_delete(request, id_exp):
629 629
630 630 experiment = get_object_or_404(Experiment, pk=id_exp)
631 631
632 632 if request.method=='POST':
633 633 if request.user.is_staff:
634 634 for conf in Configuration.objects.filter(experiment=experiment):
635 635 conf.delete()
636 636 experiment.delete()
637 637 return redirect('url_experiments')
638 638
639 639 messages.error(request, 'Not enough permission to delete this object')
640 640 return redirect(experiment.get_absolute_url())
641 641
642 642 kwargs = {
643 643 'title': 'Delete',
644 644 'suptitle': 'Experiment',
645 645 'object': experiment,
646 646 'previous': experiment.get_absolute_url(),
647 647 'delete': True
648 648 }
649 649
650 650 return render(request, 'confirm.html', kwargs)
651 651
652 652
653 653 @user_passes_test(lambda u:u.is_staff)
654 654 def experiment_export(request, id_exp):
655 655
656 656 experiment = get_object_or_404(Experiment, pk=id_exp)
657 657 content = experiment.parms_to_dict()
658 658 content_type = 'application/json'
659 659 filename = '%s_%s.json' %(experiment.name, experiment.id)
660 660
661 661 response = HttpResponse(content_type=content_type)
662 662 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
663 663 response.write(json.dumps(content, indent=2))
664 664
665 665 return response
666 666
667 667
668 668 @user_passes_test(lambda u:u.is_staff)
669 669 def experiment_import(request, id_exp):
670 670
671 671 experiment = get_object_or_404(Experiment, pk=id_exp)
672 672 configurations = Configuration.objects.filter(experiment=experiment)
673 673
674 674 if request.method == 'GET':
675 675 file_form = UploadFileForm()
676 676
677 677 if request.method == 'POST':
678 678 file_form = UploadFileForm(request.POST, request.FILES)
679 679
680 680 if file_form.is_valid():
681 681 new_exp = experiment.dict_to_parms(json.load(request.FILES['file']), CONF_MODELS)
682 682 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
683 683 return redirect(new_exp.get_absolute_url_edit())
684 684
685 685 messages.error(request, "Could not import parameters from file")
686 686
687 687 kwargs = {}
688 688 kwargs['title'] = 'Experiment'
689 689 kwargs['form'] = file_form
690 690 kwargs['suptitle'] = 'Importing file'
691 691 kwargs['button'] = 'Import'
692 692
693 693 kwargs.update(sidebar(experiment=experiment))
694 694
695 695 return render(request, 'experiment_import.html', kwargs)
696 696
697 697
698 698 @user_passes_test(lambda u:u.is_staff)
699 699 def experiment_start(request, id_exp):
700 700
701 def experiment_start(request, id_exp):
702
703 701 exp = get_object_or_404(Experiment, pk=id_exp)
704 702
705 703 if exp.status == 2:
706 704 messages.warning(request, 'Experiment {} already runnnig'.format(exp))
707 705 else:
708 706 exp.status = exp.start()
709 707 if exp.status==0:
710 708 messages.error(request, 'Experiment {} not start'.format(exp))
711 709 if exp.status==2:
712 710 messages.success(request, 'Experiment {} started'.format(exp))
713 711
714 712 exp.save()
715 713
716 714 return redirect(exp.get_absolute_url())
717 715
718 716
719 717 @user_passes_test(lambda u:u.is_staff)
720 718 def experiment_stop(request, id_exp):
721 719
722 720 exp = get_object_or_404(Experiment, pk=id_exp)
723 721
724 722 if exp.status == 2:
725 723 exp.status = exp.stop()
726 724 exp.save()
727 725 messages.success(request, 'Experiment {} stopped'.format(exp))
728 726 else:
729 727 messages.error(request, 'Experiment {} not running'.format(exp))
730 728
731 729 return redirect(exp.get_absolute_url())
732 730
733 731
734 732 def experiment_status(request, id_exp):
735 733
736 734 exp = get_object_or_404(Experiment, pk=id_exp)
737 735
738 736 exp.get_status()
739 737
740 738 return redirect(exp.get_absolute_url())
741 739
742 740
743 741 @user_passes_test(lambda u:u.is_staff)
744 742 def experiment_mix(request, id_exp):
745 743
746 744 experiment = get_object_or_404(Experiment, pk=id_exp)
747 745 rc_confs = [conf for conf in RCConfiguration.objects.filter(experiment=id_exp,
748 746 mix=False)]
749 747
750 748 if len(rc_confs)<2:
751 749 messages.warning(request, 'You need at least two RC Configurations to make a mix')
752 750 return redirect(experiment.get_absolute_url())
753 751
754 752 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True)
755 753
756 754 if mix_confs:
757 755 mix = mix_confs[0]
758 756 else:
759 757 mix = RCConfiguration(experiment=experiment,
760 758 device=rc_confs[0].device,
761 759 ipp=rc_confs[0].ipp,
762 760 clock_in=rc_confs[0].clock_in,
763 761 clock_divider=rc_confs[0].clock_divider,
764 762 mix=True,
765 763 parameters='')
766 764 mix.save()
767 765
768 766 line_type = RCLineType.objects.get(name='mix')
769 767 for i in range(len(rc_confs[0].get_lines())):
770 768 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
771 769 line.save()
772 770
773 771 initial = {'name': mix.name,
774 772 'result': parse_mix_result(mix.parameters),
775 773 'delay': 0,
776 774 'mask': [0,1,2,3,4,5,6,7]
777 775 }
778 776
779 777 if request.method=='GET':
780 778 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
781 779
782 780 if request.method=='POST':
783 781 result = mix.parameters
784 782
785 783 if '{}|'.format(request.POST['experiment']) in result:
786 784 messages.error(request, 'Configuration already added')
787 785 else:
788 786 if 'operation' in request.POST:
789 787 operation = MIX_OPERATIONS[request.POST['operation']]
790 788 else:
791 789 operation = ' '
792 790
793 791 mode = MIX_MODES[request.POST['mode']]
794 792
795 793 if result:
796 794 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
797 795 request.POST['experiment'],
798 796 mode,
799 797 operation,
800 798 float(request.POST['delay']),
801 799 parse_mask(request.POST.getlist('mask'))
802 800 )
803 801 else:
804 802 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
805 803 mode,
806 804 operation,
807 805 float(request.POST['delay']),
808 806 parse_mask(request.POST.getlist('mask'))
809 807 )
810 808
811 809 mix.parameters = result
812 810 mix.name = request.POST['name']
813 811 mix.save()
814 812 mix.update_pulses()
815 813
816 814 initial['result'] = parse_mix_result(result)
817 815 initial['name'] = mix.name
818 816
819 817 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
820 818
821 819
822 820 kwargs = {
823 821 'title': 'Experiment',
824 822 'suptitle': 'Mix Configurations',
825 823 'form' : form,
826 824 'extra_button': 'Delete',
827 825 'button': 'Add',
828 826 'cancel': 'Back',
829 827 'previous': experiment.get_absolute_url(),
830 828 'id_exp':id_exp,
831 829
832 830 }
833 831
834 832 return render(request, 'experiment_mix.html', kwargs)
835 833
836 834
837 835 @user_passes_test(lambda u:u.is_staff)
838 836 def experiment_mix_delete(request, id_exp):
839 837
840 838 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True)
841 839 values = conf.parameters.split('-')
842 840 conf.parameters = '-'.join(values[:-1])
843 841 conf.save()
844 842
845 843 return redirect('url_mix_experiment', id_exp=id_exp)
846 844
847 845
848 846 def experiment_summary(request, id_exp):
849 847
850 848 experiment = get_object_or_404(Experiment, pk=id_exp)
851 849 configurations = Configuration.objects.filter(experiment=experiment, type=0)
852 850
853 851 kwargs = {}
854 852
855 853 kwargs['experiment_keys'] = ['radar_system', 'name', 'freq', 'start_time', 'end_time']
856 854 kwargs['experiment'] = experiment
857 855
858 856 kwargs['configurations'] = []
859 857
860 858 kwargs['title'] = 'Experiment Summary'
861 859 kwargs['suptitle'] = 'Details'
862 860
863 861 kwargs['button'] = 'Verify Parameters'
864 862
865 863 c_vel = 3.0*(10**8) #m/s
866 864 ope_freq = experiment.freq*(10**6) #1/s
867 865 radar_lambda = c_vel/ope_freq #m
868 866 kwargs['radar_lambda'] = radar_lambda
869 867
870 868 jars_conf = False
871 869 rc_conf = False
872 870 code_id = 0
873 871 tx_line = {}
874 872
875 873 for configuration in configurations:
876 874
877 875 #--------------------- RC ----------------------:
878 876 if configuration.device.device_type.name == 'rc':
879 877 if configuration.mix:
880 878 continue
881 879 rc_conf = True
882 880 ipp = configuration.ipp
883 881 lines = configuration.get_lines(line_type__name='tx')
884 882 configuration.tx_lines = []
885 883
886 884 for tx_line in lines:
887 885 if tx_line.get_name()[-1] == 'A':
888 886 txa_line = tx_line
889 887 txa_params = json.loads(txa_line.params)
890 888 line = {'name':tx_line.get_name()}
891 889 tx_params = json.loads(tx_line.params)
892 890 line['width'] = tx_params['pulse_width']
893 891 if line['width'] in (0, '0'):
894 892 continue
895 893 delays = tx_params['delays']
896 894
897 895 if delays not in ('', '0'):
898 896 n = len(delays.split(','))
899 897 line['taus'] = '{} Taus: {}'.format(n, delays)
900 898 else:
901 899 line['taus'] = '-'
902 900
903 901 for code_line in configuration.get_lines(line_type__name='codes'):
904 902 code_params = json.loads(code_line.params)
905 903 code_id = code_params['code']
906 904 if tx_line.pk==int(code_params['TX_ref']):
907 905 line['codes'] = '{}:{}'.format(RCLineCode.objects.get(pk=code_params['code']),
908 906 '-'.join(code_params['codes']))
909 907
910 908 for windows_line in configuration.get_lines(line_type__name='windows'):
911 909 win_params = json.loads(windows_line.params)
912 910 if tx_line.pk==int(win_params['TX_ref']):
913 911 windows = ''
914 912 nsa = win_params['params'][0]['number_of_samples']
915 913 for i, params in enumerate(win_params['params']):
916 914 windows += 'W{}: Ho={first_height} km DH={resolution} km NSA={number_of_samples}<br>'.format(i, **params)
917 915 line['windows'] = mark_safe(windows)
918 916
919 917 configuration.tx_lines.append(line)
920 918
921 919 if txa_line:
922 920 kwargs['duty_cycle'] = float(txa_params['pulse_width'])/ipp*100
923 921
924 922 #-------------------- JARS -----------------------:
925 923 if configuration.device.device_type.name == 'jars':
926 924 jars_conf = True
927 925 kwargs['exp_type'] = EXPERIMENT_TYPE[configuration.exp_type][1]
928 926 channels_number = configuration.channels_number
929 927 exp_type = configuration.exp_type
930 928 fftpoints = configuration.fftpoints
931 929 filter_parms = configuration.filter_parms
932 930 filter_parms = ast.literal_eval(filter_parms)
933 931 spectral_number = configuration.spectral_number
934 932 acq_profiles = configuration.acq_profiles
935 933 cohe_integr = configuration.cohe_integr
936 934 profiles_block = configuration.profiles_block
937 935
938 936 if filter_parms.__class__.__name__=='str':
939 937 filter_parms = eval(filter_parms)
940 938
941 939 kwargs['configurations'].append(configuration)
942 940
943 941
944 942 #------ RC & JARS ------:
945 943 if rc_conf and jars_conf:
946 944 #RC filter values:
947 945
948 946 if exp_type == 0: #Short
949 947 bytes_ = 2
950 948 b = nsa*2*bytes_*channels_number
951 949 else: #Float
952 950 bytes_ = 4
953 951 channels = channels_number + spectral_number
954 952 b = nsa*2*bytes_*fftpoints*channels
955 953
956 954 codes_num = 7
957 955 if code_id == 2:
958 956 codes_num = 7
959 957 elif code_id == 12:
960 958 codes_num = 15
961 959
962 960 #Jars filter values:
963 961 try:
964 962 clock = eval(filter_parms['clock'])
965 963 filter_2 = eval(filter_parms['filter_2'])
966 964 filter_5 = eval(filter_parms['filter_5'])
967 965 filter_fir = eval(filter_parms['filter_fir'])
968 966 except:
969 967 clock = float(filter_parms['clock'])
970 968 filter_2 = int(filter_parms['filter_2'])
971 969 filter_5 = int(filter_parms['filter_5'])
972 970 filter_fir = int(filter_parms['filter_fir'])
973 971 Fs_MHz = clock/(filter_2*filter_5*filter_fir)
974 972
975 973 #Jars values:
976 974 IPP_units = ipp/0.15*Fs_MHz
977 975 IPP_us = IPP_units / Fs_MHz
978 976 IPP_s = IPP_units / (Fs_MHz * (10**6))
979 977 Ts = 1/(Fs_MHz*(10**6))
980 978
981 979 #Values
982 980 Va = radar_lambda/(4*Ts*cohe_integr)
983 981 rate_bh = ((nsa-codes_num)*channels_number*2*bytes_/IPP_us)*(36*(10**8)/cohe_integr)
984 982 rate_gh = rate_bh/(1024*1024*1024)
985 983 kwargs['rate_bh'] = str(rate_bh) + " (Bytes/h)"
986 984 kwargs['rate_gh'] = str(rate_gh)+" (GBytes/h)"
987 985 kwargs['va'] = Va
988 986 kwargs['time_per_block'] = IPP_s * profiles_block * cohe_integr
989 987 kwargs['acqtime'] = IPP_s * acq_profiles
990 988 kwargs['vrange'] = 3/(2*IPP_s*cohe_integr)
991 989
992 990 else:
993 991 kwargs['rate_bh'] = ''
994 992 kwargs['rate_gh'] = ''
995 993 kwargs['va'] = ''
996 994 kwargs['time_per_block'] = ''
997 995 kwargs['acqtime'] = ''
998 996 kwargs['vrange'] = ''
999 997
1000 998 ###### SIDEBAR ######
1001 999 kwargs.update(sidebar(experiment=experiment))
1002 1000
1003 1001 return render(request, 'experiment_summary.html', kwargs)
1004 1002
1005 1003
1006 1004 @user_passes_test(lambda u:u.is_staff)
1007 1005 def experiment_verify(request, id_exp):
1008 1006
1009 1007 experiment = get_object_or_404(Experiment, pk=id_exp)
1010 1008 experiment_data = experiment.parms_to_dict()
1011 1009 configurations = Configuration.objects.filter(experiment=experiment, type=0)
1012 1010
1013 1011 kwargs = {}
1014 1012
1015 1013 kwargs['experiment_keys'] = ['template', 'radar_system', 'name', 'start_time', 'end_time']
1016 1014 kwargs['experiment'] = experiment
1017 1015
1018 1016 kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status']
1019 1017 kwargs['configurations'] = configurations
1020 1018 kwargs['experiment_data'] = experiment_data
1021 1019
1022 1020 kwargs['title'] = 'Verify Experiment'
1023 1021 kwargs['suptitle'] = 'Parameters'
1024 1022
1025 1023 kwargs['button'] = 'Update'
1026 1024
1027 1025 jars_conf = False
1028 1026 rc_conf = False
1029 1027 dds_conf = False
1030 1028
1031 1029 for configuration in configurations:
1032 1030 #-------------------- JARS -----------------------:
1033 1031 if configuration.device.device_type.name == 'jars':
1034 1032 jars_conf = True
1035 1033 jars = configuration
1036 1034 kwargs['jars_conf'] = jars_conf
1037 1035 filter_parms = jars.filter_parms
1038 1036 filter_parms = ast.literal_eval(filter_parms)
1039 1037 kwargs['filter_parms'] = filter_parms
1040 1038 #--Sampling Frequency
1041 1039 clock = eval(filter_parms['clock'])
1042 1040 filter_2 = eval(filter_parms['filter_2'])
1043 1041 filter_5 = eval(filter_parms['filter_5'])
1044 1042 filter_fir = eval(filter_parms['filter_fir'])
1045 1043 samp_freq_jars = clock/filter_2/filter_5/filter_fir
1046 1044
1047 1045 kwargs['samp_freq_jars'] = samp_freq_jars
1048 1046 kwargs['jars'] = configuration
1049 1047
1050 1048 #--------------------- RC ----------------------:
1051 1049 if configuration.device.device_type.name == 'rc' and not configuration.mix:
1052 1050 rc_conf = True
1053 1051 rc = configuration
1054 1052
1055 1053 rc_parms = configuration.parms_to_dict()
1056 1054
1057 1055 win_lines = rc.get_lines(line_type__name='windows')
1058 1056 if win_lines:
1059 1057 dh = json.loads(win_lines[0].params)['params'][0]['resolution']
1060 1058 #--Sampling Frequency
1061 1059 samp_freq_rc = 0.15/dh
1062 1060 kwargs['samp_freq_rc'] = samp_freq_rc
1063 1061
1064 1062 kwargs['rc_conf'] = rc_conf
1065 1063 kwargs['rc'] = configuration
1066 1064
1067 1065 #-------------------- DDS ----------------------:
1068 1066 if configuration.device.device_type.name == 'dds':
1069 1067 dds_conf = True
1070 1068 dds = configuration
1071 1069 dds_parms = configuration.parms_to_dict()
1072 1070
1073 1071 kwargs['dds_conf'] = dds_conf
1074 1072 kwargs['dds'] = configuration
1075 1073
1076 1074
1077 1075 #------------Validation------------:
1078 1076 #Clock
1079 1077 if dds_conf and rc_conf and jars_conf:
1080 1078 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']):
1081 1079 messages.warning(request, "Devices don't have the same clock.")
1082 1080 elif rc_conf and jars_conf:
1083 1081 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']):
1084 1082 messages.warning(request, "Devices don't have the same clock.")
1085 1083 elif rc_conf and dds_conf:
1086 1084 if float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1087 1085 messages.warning(request, "Devices don't have the same clock.")
1088 1086 if float(samp_freq_rc) != float(dds_parms['configurations']['byId'][str(dds.pk)]['frequencyA']):
1089 1087 messages.warning(request, "Devices don't have the same Frequency A.")
1090 1088
1091 1089
1092 1090 #------------POST METHOD------------:
1093 1091 if request.method == 'POST':
1094 1092 if request.POST['suggest_clock']:
1095 1093 try:
1096 1094 suggest_clock = float(request.POST['suggest_clock'])
1097 1095 except:
1098 1096 messages.warning(request, "Invalid value in CLOCK IN.")
1099 1097 return redirect('url_verify_experiment', id_exp=experiment.id)
1100 1098 else:
1101 1099 suggest_clock = ""
1102 1100 if suggest_clock:
1103 1101 if rc_conf:
1104 1102 rc.clock_in = suggest_clock
1105 1103 rc.save()
1106 1104 if jars_conf:
1107 1105 filter_parms = jars.filter_parms
1108 1106 filter_parms = ast.literal_eval(filter_parms)
1109 1107 filter_parms['clock'] = suggest_clock
1110 1108 jars.filter_parms = json.dumps(filter_parms)
1111 1109 jars.save()
1112 1110 kwargs['filter_parms'] = filter_parms
1113 1111 if dds_conf:
1114 1112 dds.clock = suggest_clock
1115 1113 dds.save()
1116 1114
1117 1115 if request.POST['suggest_frequencyA']:
1118 1116 try:
1119 1117 suggest_frequencyA = float(request.POST['suggest_frequencyA'])
1120 1118 except:
1121 1119 messages.warning(request, "Invalid value in FREQUENCY A.")
1122 1120 return redirect('url_verify_experiment', id_exp=experiment.id)
1123 1121 else:
1124 1122 suggest_frequencyA = ""
1125 1123 if suggest_frequencyA:
1126 1124 if jars_conf:
1127 1125 filter_parms = jars.filter_parms
1128 1126 filter_parms = ast.literal_eval(filter_parms)
1129 1127 filter_parms['fch'] = suggest_frequencyA
1130 1128 jars.filter_parms = json.dumps(filter_parms)
1131 1129 jars.save()
1132 1130 kwargs['filter_parms'] = filter_parms
1133 1131 if dds_conf:
1134 1132 dds.frequencyA_Mhz = request.POST['suggest_frequencyA']
1135 1133 dds.save()
1136 1134
1137 1135 ###### SIDEBAR ######
1138 1136 kwargs.update(sidebar(experiment=experiment))
1139 1137
1140 1138
1141 1139
1142 1140
1143 1141
1144 1142 return render(request, 'experiment_verify.html', kwargs)
1145 1143
1146 1144
1147 1145 #@user_passes_test(lambda u:u.is_staff)
1148 1146 def parse_mix_result(s):
1149 1147
1150 1148 values = s.split('-')
1151 1149 html = 'EXP MOD OPE DELAY MASK\r\n'
1152 1150
1153 1151 if not values or values[0] in ('', ' '):
1154 1152 return mark_safe(html)
1155 1153
1156 1154 for i, value in enumerate(values):
1157 1155 if not value:
1158 1156 continue
1159 1157 pk, mode, operation, delay, mask = value.split('|')
1160 1158 conf = RCConfiguration.objects.get(pk=pk)
1161 1159 if i==0:
1162 1160 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1163 1161 conf.name,
1164 1162 mode,
1165 1163 ' ',
1166 1164 delay,
1167 1165 mask)
1168 1166 else:
1169 1167 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1170 1168 conf.name,
1171 1169 mode,
1172 1170 operation,
1173 1171 delay,
1174 1172 mask)
1175 1173
1176 1174 return mark_safe(html)
1177 1175
1178 1176 def parse_mask(l):
1179 1177
1180 1178 values = []
1181 1179
1182 1180 for x in range(8):
1183 1181 if '{}'.format(x) in l:
1184 1182 values.append(1)
1185 1183 else:
1186 1184 values.append(0)
1187 1185
1188 1186 values.reverse()
1189 1187
1190 1188 return int(''.join([str(x) for x in values]), 2)
1191 1189
1192 1190
1193 1191 def dev_confs(request):
1194 1192
1195 1193
1196 1194 page = request.GET.get('page')
1197 1195 order = ('type', 'device__device_type', 'experiment')
1198 1196 filters = request.GET.copy()
1199 1197
1200 1198 kwargs = get_paginator(Configuration, page, order, filters)
1201 1199
1202 1200 form = FilterForm(initial=request.GET, extra_fields=['tags','template'])
1203 1201 kwargs['keys'] = ['name', 'experiment', 'type', 'programmed_date']
1204 1202 kwargs['title'] = 'Configuration'
1205 1203 kwargs['suptitle'] = 'List'
1206 1204 kwargs['no_sidebar'] = True
1207 1205 kwargs['form'] = form
1208 1206 filters.pop('page', None)
1209 1207 kwargs['q'] = urlencode(filters)
1210 1208
1211 1209 return render(request, 'base_list.html', kwargs)
1212 1210
1213 1211
1214 1212 def dev_conf(request, id_conf):
1215 1213
1216 1214 conf = get_object_or_404(Configuration, pk=id_conf)
1217 1215
1218 1216 return redirect(conf.get_absolute_url())
1219 1217
1220 1218
1221 1219 @user_passes_test(lambda u:u.is_staff)
1222 1220 def dev_conf_new(request, id_exp=0, id_dev=0):
1223 1221
1224 1222 initial = {}
1225 1223 kwargs = {}
1226 1224
1227 1225 if id_exp!=0:
1228 1226 initial['experiment'] = id_exp
1229 1227
1230 1228 if id_dev!=0:
1231 1229 initial['device'] = id_dev
1232 1230
1233 1231 if request.method == 'GET':
1234 1232
1235 1233 if id_dev:
1236 1234 kwargs['button'] = 'Create'
1237 1235 device = Device.objects.get(pk=id_dev)
1238 1236 DevConfForm = CONF_FORMS[device.device_type.name]
1239 1237 initial['name'] = request.GET['name']
1240 1238 form = DevConfForm(initial=initial)
1241 1239 else:
1242 1240 if 'template' in request.GET:
1243 1241 if request.GET['template']=='0':
1244 1242 choices = [(conf.pk, '{}'.format(conf)) for conf in Configuration.objects.filter(template=True)]
1245 1243 form = NewForm(initial={'create_from':2},
1246 1244 template_choices=choices)
1247 1245 else:
1248 1246 kwargs['button'] = 'Create'
1249 1247 conf = Configuration.objects.get(pk=request.GET['template'])
1250 1248 id_dev = conf.device.pk
1251 1249 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1252 1250 form = DevConfForm(instance=conf,
1253 1251 initial={'name': '{}_{:%y%m%d}'.format(conf.name, datetime.now()),
1254 1252 'template': False,
1255 1253 'experiment':id_exp})
1256 1254 elif 'blank' in request.GET:
1257 1255 kwargs['button'] = 'Create'
1258 1256 form = ConfigurationForm(initial=initial)
1259 1257 else:
1260 1258 form = NewForm()
1261 1259
1262 1260 if request.method == 'POST':
1263 1261
1264 1262 device = Device.objects.get(pk=request.POST['device'])
1265 1263 DevConfForm = CONF_FORMS[device.device_type.name]
1266 1264
1267 1265 form = DevConfForm(request.POST)
1268 1266 kwargs['button'] = 'Create'
1269 1267 if form.is_valid():
1270 1268 conf = form.save()
1271 1269
1272 1270 if 'template' in request.GET and conf.device.device_type.name=='rc':
1273 1271 lines = RCLine.objects.filter(rc_configuration=request.GET['template'])
1274 1272 for line in lines:
1275 1273 line.clone(rc_configuration=conf)
1276 1274
1277 1275 new_lines = conf.get_lines()
1278 1276 for line in new_lines:
1279 1277 line_params = json.loads(line.params)
1280 1278 if 'TX_ref' in line_params:
1281 1279 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
1282 1280 line_params['TX_ref'] = ['{}'.format(l.pk) for l in new_lines if l.get_name()==ref_line.get_name()][0]
1283 1281 line.params = json.dumps(line_params)
1284 1282 line.save()
1285 1283
1286 1284 if conf.device.device_type.name=='jars':
1287 1285 conf.add_parms_to_filter()
1288 1286
1289 1287 return redirect('url_dev_conf', id_conf=conf.pk)
1290 1288
1291 1289 kwargs['id_exp'] = id_exp
1292 1290 kwargs['form'] = form
1293 1291 kwargs['title'] = 'Configuration'
1294 1292 kwargs['suptitle'] = 'New'
1295 1293
1296 1294
1297 1295 if id_dev != 0:
1298 1296 device = Device.objects.get(pk=id_dev)
1299 1297 kwargs['device'] = device.device_type.name
1300 1298
1301 1299 return render(request, 'dev_conf_edit.html', kwargs)
1302 1300
1303 1301
1304 1302 @user_passes_test(lambda u:u.is_staff)
1305 1303 def dev_conf_edit(request, id_conf):
1306 1304
1307 1305 conf = get_object_or_404(Configuration, pk=id_conf)
1308 1306
1309 1307 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1310 1308
1311 1309 if request.method=='GET':
1312 1310 form = DevConfForm(instance=conf)
1313 1311
1314 1312 if request.method=='POST':
1315 1313 form = DevConfForm(request.POST, instance=conf)
1316 1314
1317 1315 if form.is_valid():
1318 1316 form.save()
1319 1317 return redirect('url_dev_conf', id_conf=id_conf)
1320 1318
1321 1319 kwargs = {}
1322 1320 kwargs['form'] = form
1323 1321 kwargs['title'] = 'Device Configuration'
1324 1322 kwargs['suptitle'] = 'Edit'
1325 1323 kwargs['button'] = 'Update'
1326 1324
1327 1325 ###### SIDEBAR ######
1328 1326 kwargs.update(sidebar(conf=conf))
1329 1327
1330 1328 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1331 1329
1332 1330
1333 1331 @user_passes_test(lambda u:u.is_staff)
1334 1332 def dev_conf_start(request, id_conf):
1335 1333
1336 1334 conf = get_object_or_404(Configuration, pk=id_conf)
1337 1335
1338 1336 if conf.start_device():
1339 1337 messages.success(request, conf.message)
1340 1338 else:
1341 1339 messages.error(request, conf.message)
1342 1340
1343 1341 #conf.status_device()
1344 1342
1345 1343 return redirect(conf.get_absolute_url())
1346 1344
1347 1345
1348 1346 @user_passes_test(lambda u:u.is_staff)
1349 1347 def dev_conf_stop(request, id_conf):
1350 1348
1351 1349 conf = get_object_or_404(Configuration, pk=id_conf)
1352 1350
1353 1351 if conf.stop_device():
1354 1352 messages.success(request, conf.message)
1355 1353 else:
1356 1354 messages.error(request, conf.message)
1357 1355
1358 1356 #conf.status_device()
1359 1357
1360 1358 return redirect(conf.get_absolute_url())
1361 1359
1362 1360
1363 1361 def dev_conf_status(request, id_conf):
1364 1362
1365 1363 conf = get_object_or_404(Configuration, pk=id_conf)
1366 1364
1367 1365 if conf.status_device():
1368 1366 messages.success(request, conf.message)
1369 1367 else:
1370 1368 messages.error(request, conf.message)
1371 1369
1372 1370 return redirect(conf.get_absolute_url())
1373 1371
1374 1372
1375 1373 @user_passes_test(lambda u:u.is_staff)
1376 1374 def dev_conf_reset(request, id_conf):
1377 1375
1378 1376 conf = get_object_or_404(Configuration, pk=id_conf)
1379 1377
1380 1378 if conf.reset_device():
1381 1379 messages.success(request, conf.message)
1382 1380 else:
1383 1381 messages.error(request, conf.message)
1384 1382
1385 1383 return redirect(conf.get_absolute_url())
1386 1384
1387 1385
1388 1386 @user_passes_test(lambda u:u.is_staff)
1389 1387 def dev_conf_write(request, id_conf):
1390 1388
1391 1389 conf = get_object_or_404(Configuration, pk=id_conf)
1392 1390
1393 1391 if conf.write_device():
1394 1392 messages.success(request, conf.message)
1395 1393 conf.clone(type=1, template=False)
1396 1394 else:
1397 1395 messages.error(request, conf.message)
1398 1396
1399 1397 return redirect(conf.get_absolute_url())
1400 1398
1401 1399
1402 1400 @user_passes_test(lambda u:u.is_staff)
1403 1401 def dev_conf_read(request, id_conf):
1404 1402
1405 1403 conf = get_object_or_404(Configuration, pk=id_conf)
1406 1404
1407 1405 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1408 1406
1409 1407 if request.method=='GET':
1410 1408
1411 1409 parms = conf.read_device()
1412 1410 #conf.status_device()
1413 1411
1414 1412 if not parms:
1415 1413 messages.error(request, conf.message)
1416 1414 return redirect(conf.get_absolute_url())
1417 1415
1418 1416 form = DevConfForm(initial=parms, instance=conf)
1419 1417
1420 1418 if request.method=='POST':
1421 1419 form = DevConfForm(request.POST, instance=conf)
1422 1420
1423 1421 if form.is_valid():
1424 1422 form.save()
1425 1423 return redirect(conf.get_absolute_url())
1426 1424
1427 1425 messages.error(request, "Parameters could not be saved")
1428 1426
1429 1427 kwargs = {}
1430 1428 kwargs['id_dev'] = conf.id
1431 1429 kwargs['form'] = form
1432 1430 kwargs['title'] = 'Device Configuration'
1433 1431 kwargs['suptitle'] = 'Parameters read from device'
1434 1432 kwargs['button'] = 'Save'
1435 1433
1436 1434 ###### SIDEBAR ######
1437 1435 kwargs.update(sidebar(conf=conf))
1438 1436
1439 1437 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
1440 1438
1441 1439
1442 1440 @user_passes_test(lambda u:u.is_staff)
1443 1441 def dev_conf_import(request, id_conf):
1444 1442
1445 1443 conf = get_object_or_404(Configuration, pk=id_conf)
1446 1444 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1447 1445
1448 1446 if request.method == 'GET':
1449 1447 file_form = UploadFileForm()
1450 1448
1451 1449 if request.method == 'POST':
1452 1450 file_form = UploadFileForm(request.POST, request.FILES)
1453 1451
1454 1452 if file_form.is_valid():
1455 1453
1456 1454 data = conf.import_from_file(request.FILES['file'])
1457 1455 parms = Params(data=data).get_conf(dtype=conf.device.device_type.name)
1458 1456
1459 1457 if parms:
1460 1458
1461 1459 form = DevConfForm(initial=parms, instance=conf)
1462 1460
1463 1461 kwargs = {}
1464 1462 kwargs['id_dev'] = conf.id
1465 1463 kwargs['form'] = form
1466 1464 kwargs['title'] = 'Device Configuration'
1467 1465 kwargs['suptitle'] = 'Parameters imported'
1468 1466 kwargs['button'] = 'Save'
1469 1467 kwargs['action'] = conf.get_absolute_url_edit()
1470 1468 kwargs['previous'] = conf.get_absolute_url()
1471 1469
1472 1470 ###### SIDEBAR ######
1473 1471 kwargs.update(sidebar(conf=conf))
1474 1472
1475 1473 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
1476 1474
1477 1475 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1478 1476
1479 1477 messages.error(request, "Could not import parameters from file")
1480 1478
1481 1479 kwargs = {}
1482 1480 kwargs['id_dev'] = conf.id
1483 1481 kwargs['title'] = 'Device Configuration'
1484 1482 kwargs['form'] = file_form
1485 1483 kwargs['suptitle'] = 'Importing file'
1486 1484 kwargs['button'] = 'Import'
1487 1485
1488 1486 kwargs.update(sidebar(conf=conf))
1489 1487
1490 1488 return render(request, 'dev_conf_import.html', kwargs)
1491 1489
1492 1490
1493 1491 @user_passes_test(lambda u:u.is_staff)
1494 1492 def dev_conf_export(request, id_conf):
1495 1493
1496 1494 conf = get_object_or_404(Configuration, pk=id_conf)
1497 1495
1498 1496 if request.method == 'GET':
1499 1497 file_form = DownloadFileForm(conf.device.device_type.name)
1500 1498
1501 1499 if request.method == 'POST':
1502 1500 file_form = DownloadFileForm(conf.device.device_type.name, request.POST)
1503 1501
1504 1502 if file_form.is_valid():
1505 1503 fields = conf.export_to_file(format = file_form.cleaned_data['format'])
1506 1504
1507 1505 response = HttpResponse(content_type=fields['content_type'])
1508 1506 response['Content-Disposition'] = 'attachment; filename="%s"' %fields['filename']
1509 1507 response.write(fields['content'])
1510 1508
1511 1509 return response
1512 1510
1513 1511 messages.error(request, "Could not export parameters")
1514 1512
1515 1513 kwargs = {}
1516 1514 kwargs['id_dev'] = conf.id
1517 1515 kwargs['title'] = 'Device Configuration'
1518 1516 kwargs['form'] = file_form
1519 1517 kwargs['suptitle'] = 'Exporting file'
1520 1518 kwargs['button'] = 'Export'
1521 1519
1522 1520 return render(request, 'dev_conf_export.html', kwargs)
1523 1521
1524 1522
1525 1523 @user_passes_test(lambda u:u.is_staff)
1526 1524 def dev_conf_delete(request, id_conf):
1527 1525
1528 1526 conf = get_object_or_404(Configuration, pk=id_conf)
1529 1527
1530 1528 if request.method=='POST':
1531 1529 if request.user.is_staff:
1532 1530 conf.delete()
1533 1531 return redirect('url_dev_confs')
1534 1532
1535 1533 messages.error(request, 'Not enough permission to delete this object')
1536 1534 return redirect(conf.get_absolute_url())
1537 1535
1538 1536 kwargs = {
1539 1537 'title': 'Delete',
1540 1538 'suptitle': 'Experiment',
1541 1539 'object': conf,
1542 1540 'previous': conf.get_absolute_url(),
1543 1541 'delete': True
1544 1542 }
1545 1543
1546 1544 return render(request, 'confirm.html', kwargs)
1547 1545
1548 1546
1549 1547 def sidebar(**kwargs):
1550 1548
1551 1549 side_data = {}
1552 1550
1553 1551 conf = kwargs.get('conf', None)
1554 1552 experiment = kwargs.get('experiment', None)
1555 1553
1556 1554 if not experiment:
1557 1555 experiment = conf.experiment
1558 1556
1559 1557 if experiment:
1560 1558 side_data['experiment'] = experiment
1561 1559 campaign = experiment.campaign_set.all()
1562 1560 if campaign:
1563 1561 side_data['campaign'] = campaign[0]
1564 1562 experiments = campaign[0].experiments.all()
1565 1563 else:
1566 1564 experiments = [experiment]
1567 1565 configurations = experiment.configuration_set.filter(type=0)
1568 1566 side_data['side_experiments'] = experiments
1569 1567 side_data['side_configurations'] = configurations
1570 1568
1571 1569 return side_data
1572 1570
1573 1571 def get_paginator(model, page, order, filters={}, n=10):
1574 1572
1575 1573 kwargs = {}
1576 1574 query = Q()
1577 1575 if isinstance(filters, QueryDict):
1578 1576 filters = filters.dict()
1579 1577 [filters.pop(key) for key in filters.keys() if filters[key] in ('', ' ')]
1580 1578 filters.pop('page', None)
1581 1579
1582 1580 if 'template' in filters:
1583 1581 filters['template'] = True
1584 1582 if 'start_date' in filters:
1585 1583 filters['start_date__gte'] = filters.pop('start_date')
1586 1584 if 'end_date' in filters:
1587 1585 filters['start_date__lte'] = filters.pop('end_date')
1588 1586 if 'tags' in filters:
1589 1587 tags = filters.pop('tags')
1590 1588 fields = [f.name for f in model._meta.get_fields()]
1591 1589
1592 1590 if 'tags' in fields:
1593 1591 query = query | Q(tags__icontains=tags)
1594 1592 if 'name' in fields:
1595 1593 query = query | Q(name__icontains=tags)
1596 1594 if 'location' in fields:
1597 1595 query = query | Q(location__name__icontains=tags)
1598 1596 if 'device' in fields:
1599 1597 query = query | Q(device__device_type__name__icontains=tags)
1600 1598
1601 1599 object_list = model.objects.filter(query, **filters).order_by(*order)
1602 1600 paginator = Paginator(object_list, n)
1603 1601
1604 1602 try:
1605 1603 objects = paginator.page(page)
1606 1604 except PageNotAnInteger:
1607 1605 objects = paginator.page(1)
1608 1606 except EmptyPage:
1609 1607 objects = paginator.page(paginator.num_pages)
1610 1608
1611 1609 kwargs['objects'] = objects
1612 1610 kwargs['offset'] = (int(page)-1)*n if page else 0
1613 1611
1614 1612 return kwargs
1615 1613
1616 1614 def operation(request, id_camp=None):
1617 1615
1618 1616 kwargs = {}
1619 1617 kwargs['title'] = 'Radars Operation'
1620 1618 kwargs['no_sidebar'] = True
1621 1619 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1622 1620 end_date__gte=datetime.now()).order_by('-start_date')
1623 1621
1624 1622
1625 1623 if id_camp:
1626 1624 campaign = get_object_or_404(Campaign, pk = id_camp)
1627 1625 form = OperationForm(initial={'campaign': campaign.id}, campaigns=campaigns)
1628 1626 kwargs['campaign'] = campaign
1629 1627 else:
1630 1628 form = OperationForm(campaigns=campaigns)
1631 1629 kwargs['form'] = form
1632 1630 return render(request, 'operation.html', kwargs)
1633 1631
1634 1632 #---Experiment
1635 1633 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1636 1634 kwargs['experiment_keys'] = keys[1:]
1637 1635 kwargs['experiments'] = experiments
1638 1636 #---Radar
1639 1637 kwargs['locations'] = campaign.get_experiments_by_radar()
1640 1638 kwargs['form'] = form
1641 1639
1642 1640 return render(request, 'operation.html', kwargs)
1643 1641
1644 1642
1645 1643 @login_required
1646 1644 def radar_start(request, id_camp, id_radar):
1647 1645
1648 1646 campaign = get_object_or_404(Campaign, pk = id_camp)
1649 1647 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1650 1648 now = datetime.utcnow()
1651 1649
1652 1650 for exp in experiments:
1653 1651 date = datetime.combine(datetime.now().date(), exp.start_time)
1654 1652
1655 1653 if exp.status == 2:
1656 1654 messages.warning(request, 'Experiment {} already running'.format(exp))
1657 1655 continue
1658 1656
1659 1657 if exp.status == 3:
1660 1658 messages.warning(request, 'Experiment {} already programmed'.format(exp))
1661 1659 continue
1662 1660
1663 1661 if date>campaign.end_date or date<campaign.start_date:
1664 1662 messages.warning(request, 'Experiment {} out of date'.format(exp))
1665 1663 continue
1666 1664
1667 1665 if now>=date:
1668 1666 task = task_start.delay(exp.pk)
1669 1667 exp.status = task.wait()
1670 1668 if exp.status==0:
1671 1669 messages.error(request, 'Experiment {} not start'.format(exp))
1672 1670 if exp.status==2:
1673 1671 messages.success(request, 'Experiment {} started'.format(exp))
1674 1672 else:
1675 1673 task = task_start.apply_async((exp.pk,), eta=date)
1676 1674 exp.status = 3
1677 1675 messages.success(request, 'Experiment {} programmed to start at {}'.format(exp, date))
1678 1676
1679 1677 exp.save()
1680 1678
1681 1679 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1682 1680
1683 1681
1684 1682 @login_required
1685 1683 def radar_stop(request, id_camp, id_radar):
1686 1684
1687 1685 campaign = get_object_or_404(Campaign, pk = id_camp)
1688 1686 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1689 1687
1690 1688 for exp in experiments:
1691 1689
1692 1690 if exp.status == 2:
1693 1691 task = task_stop.delay(exp.pk)
1694 1692 exp.status = task.wait()
1695 1693 messages.warning(request, 'Experiment {} stopped'.format(exp))
1696 1694 exp.save()
1697 1695 else:
1698 1696 messages.error(request, 'Experiment {} not running'.format(exp))
1699 1697
1700 1698 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1701 1699
1702 1700
1703 1701 @login_required
1704 1702 def radar_refresh(request, id_camp, id_radar):
1705 1703
1706 1704 campaign = get_object_or_404(Campaign, pk = id_camp)
1707 1705 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1708 1706
1709 1707 for exp in experiments:
1710 1708 exp.get_status()
1711 1709
1712 1710 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
General Comments 0
You need to be logged in to leave comments. Login now