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