##// END OF EJS Templates
Update RC model, RC api for testing...
Juan C. Espinoza -
r185:66e7f4294add
parent child
Show More
@@ -1,621 +1,633
1 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
1
2 2 from datetime import datetime
3 3
4 from django.db import models
4 try:
5 5 from polymorphic.models import PolymorphicModel
6 except:
7 from polymorphic import PolymorphicModel
6 8
9 from django.db import models
7 10 from django.core.urlresolvers import reverse
8
11 from django.shortcuts import get_object_or_404
9 12
10 13 CONF_STATES = (
11 14 (0, 'Disconnected'),
12 15 (1, 'Connected'),
13 16 (2, 'Running'),
14 17 )
15 18
16 19 EXP_STATES = (
17 20 (0,'Error'), #RED
18 21 (1,'Configured'), #BLUE
19 22 (2,'Running'), #GREEN
20 23 (3,'Waiting'), #YELLOW
21 24 (4,'Not Configured'), #WHITE
22 25 )
23 26
24 27 CONF_TYPES = (
25 28 (0, 'Active'),
26 29 (1, 'Historical'),
27 30 )
28 31
29 32 DEV_STATES = (
30 33 (0, 'No connected'),
31 34 (1, 'Connected'),
32 35 (2, 'Configured'),
33 36 (3, 'Running'),
37 (4, 'Unknown'),
34 38 )
35 39
36 40 DEV_TYPES = (
37 41 ('', 'Select a device type'),
38 42 ('rc', 'Radar Controller'),
39 43 ('rc_mix', 'Radar Controller (Mix)'),
40 44 ('dds', 'Direct Digital Synthesizer'),
41 45 ('jars', 'Jicamarca Radar Acquisition System'),
42 46 ('usrp', 'Universal Software Radio Peripheral'),
43 47 ('cgs', 'Clock Generator System'),
44 48 ('abs', 'Automatic Beam Switching'),
45 49 )
46 50
47 51 DEV_PORTS = {
48 52 'rc' : 2000,
49 53 'rc_mix': 2000,
50 54 'dds' : 2000,
51 55 'jars' : 2000,
52 56 'usrp' : 2000,
53 57 'cgs' : 8080,
54 58 'abs' : 8080
55 59 }
56 60
57 61 RADAR_STATES = (
58 62 (0, 'No connected'),
59 63 (1, 'Connected'),
60 64 (2, 'Configured'),
61 65 (3, 'Running'),
62 66 (4, 'Scheduled'),
63 67 )
64 68 # Create your models here.
65 69
66 70 class Location(models.Model):
67 71
68 72 name = models.CharField(max_length = 30)
69 73 description = models.TextField(blank=True, null=True)
70 74
71 75 class Meta:
72 76 db_table = 'db_location'
73 77
74 78 def __str__(self):
75 79 return u'%s' % self.name
76 80
77 81 def get_absolute_url(self):
78 82 return reverse('url_location', args=[str(self.id)])
79 83
80 84
81 85 class DeviceType(models.Model):
82 86
83 87 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc')
84 88 description = models.TextField(blank=True, null=True)
85 89
86 90 class Meta:
87 91 db_table = 'db_device_types'
88 92
89 93 def __str__(self):
90 94 return u'%s' % self.get_name_display()
91 95
92 96 class Device(models.Model):
93 97
94 98 device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
95 99 location = models.ForeignKey(Location, on_delete=models.CASCADE)
96 100
97 101 name = models.CharField(max_length=40, default='')
98 102 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
99 103 port_address = models.PositiveSmallIntegerField(default=2000)
100 104 description = models.TextField(blank=True, null=True)
101 105 status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES)
102 106
103 107 class Meta:
104 108 db_table = 'db_devices'
105 109
106 110 def __str__(self):
107 111 return u'[{}]: {}'.format(self.device_type.name.upper(),
108 112 self.name)
109 113
110 114 def get_status(self):
111 115 return self.status
112 116
113 117 @property
114 118 def status_color(self):
115 119 color = 'muted'
116 120 if self.status == 0:
117 121 color = "danger"
118 122 elif self.status == 1:
119 123 color = "warning"
120 124 elif self.status == 2:
121 125 color = "info"
122 126 elif self.status == 3:
123 127 color = "success"
124 128
125 129 return color
126 130
127 @property
128 def url(self):
131 def url(self, path=None):
129 132
133 if path:
134 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
135 else:
130 136 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
131 137
132 138 def get_absolute_url(self):
139
133 140 return reverse('url_device', args=[str(self.id)])
134 141
135 142
136 143 class Campaign(models.Model):
137 144
138 145 template = models.BooleanField(default=False)
139 146 name = models.CharField(max_length=60, unique=True)
140 147 start_date = models.DateTimeField(blank=True, null=True)
141 148 end_date = models.DateTimeField(blank=True, null=True)
142 149 tags = models.CharField(max_length=40)
143 150 description = models.TextField(blank=True, null=True)
144 151 experiments = models.ManyToManyField('Experiment', blank=True)
145 152
146 153 class Meta:
147 154 db_table = 'db_campaigns'
148 155 ordering = ('name',)
149 156
150 157 def __str__(self):
151 158 if self.template:
152 159 return u'{} (template)'.format(self.name)
153 160 else:
154 161 return u'{}'.format(self.name)
155 162
156 163 def parms_to_dict(self):
157 164
158 165 import json
159 166
160 167 parameters = {}
161 168 exp_parameters = {}
162 169 experiments = Experiment.objects.filter(campaign = self)
163 170
164 171 i=1
165 172 for experiment in experiments:
166 173 exp_parameters['experiment-'+str(i)] = json.loads(experiment.parms_to_dict())
167 174 i += 1
168 175
169 176
170 177 parameters['experiments'] = exp_parameters
171 178 parameters['end_date'] = self.end_date.strftime("%Y-%m-%d")
172 179 parameters['start_date'] = self.start_date.strftime("%Y-%m-%d")
173 180 parameters['campaign'] = self.__str__()
174 181 parameters['tags'] =self.tags
175 182
176 183 parameters = json.dumps(parameters, indent=2, sort_keys=False)
177 184
178 185 return parameters
179 186
180 187 def import_from_file(self, fp):
181 188
182 189 import os, json
183 190
184 191 parms = {}
185 192
186 193 path, ext = os.path.splitext(fp.name)
187 194
188 195 if ext == '.json':
189 196 parms = json.loads(fp.read())
190 197
191 198 return parms
192 199
193 200 def dict_to_parms(self, parms, CONF_MODELS):
194 201
195 202 experiments = Experiment.objects.filter(campaign = self)
196 203 configurations = Configuration.objects.filter(experiment = experiments)
197 204
198 205 if configurations:
199 206 for configuration in configurations:
200 207 configuration.delete()
201 208
202 209 if experiments:
203 210 for experiment in experiments:
204 211 experiment.delete()
205 212
206 213 for parms_exp in parms['experiments']:
207 214 location = Location.objects.get(name = parms['experiments'][parms_exp]['radar'])
208 215 new_exp = Experiment(
209 216 name = parms['experiments'][parms_exp]['experiment'],
210 217 location = location,
211 218 start_time = parms['experiments'][parms_exp]['start_time'],
212 219 end_time = parms['experiments'][parms_exp]['end_time'],
213 220 )
214 221 new_exp.save()
215 222 new_exp.dict_to_parms(parms['experiments'][parms_exp],CONF_MODELS)
216 223 new_exp.save()
217 224
218 225 self.name = parms['campaign']
219 226 self.start_date = parms['start_date']
220 227 self.end_date = parms['end_date']
221 228 self.tags = parms['tags']
222 229 self.experiments.add(new_exp)
223 230 self.save()
224 231
225 232 return self
226 233
227 234 def get_experiments_by_location(self):
228 235
229 236 ret = []
230 237 locations = set([e.location for e in self.experiments.all()])
231 238 for loc in locations:
232 239 dum = {}
233 240 dum['name'] = loc.name
234 241 dum['id'] = loc.pk
235 242 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
236 243 ret.append(dum)
237 244
238 245 return ret
239 246
240 247 def get_absolute_url(self):
241 248 return reverse('url_campaign', args=[str(self.id)])
242 249
243 250 def get_absolute_url_edit(self):
244 251 return reverse('url_edit_campaign', args=[str(self.id)])
245 252
246 253 def get_absolute_url_export(self):
247 254 return reverse('url_export_campaign', args=[str(self.id)])
248 255
249 256 def get_absolute_url_import(self):
250 257 return reverse('url_import_campaign', args=[str(self.id)])
251 258
252 259
253 260
254 261 class RunningExperiment(models.Model):
255 262 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
256 263 running_experiment = models.ManyToManyField('Experiment', blank = True)
257 264 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
258 265
259 266
260 267 class Experiment(models.Model):
261 268
262 269 template = models.BooleanField(default=False)
263 270 name = models.CharField(max_length=40, default='', unique=True)
264 271 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
265 272 start_time = models.TimeField(default='00:00:00')
266 273 end_time = models.TimeField(default='23:59:59')
267 274 status = models.PositiveSmallIntegerField(default=0, choices=EXP_STATES)
268 275
269 276 class Meta:
270 277 db_table = 'db_experiments'
271 278 ordering = ('template', 'name')
272 279
273 280 def __str__(self):
274 281 if self.template:
275 282 return u'%s (template)' % (self.name)
276 283 else:
277 284 return u'%s' % (self.name)
278 285
279 286 @property
280 287 def radar_system(self):
281 288 return self.location
282 289
283 290 def clone(self, **kwargs):
284 291
285 292 confs = Configuration.objects.filter(experiment=self, type=0)
286 293 self.pk = None
287 294 self.name = '{} [{:%Y/%m/%d}]'.format(self.name, datetime.now())
288 295 for attr, value in kwargs.items():
289 296 setattr(self, attr, value)
290 297
291 298 self.save()
292 299
293 300 for conf in confs:
294 301 conf.clone(experiment=self, template=False)
295 302
296 303 return self
297 304
298 305 def get_status(self):
299 306 configurations = Configuration.objects.filter(experiment=self)
300 307 exp_status=[]
301 308 for conf in configurations:
302 309 exp_status.append(conf.status_device())
303 310
304 311 if not exp_status: #No Configuration
305 312 self.status = 4
306 313 self.save()
307 314 return
308 315
309 316 total = 1
310 317 for e_s in exp_status:
311 318 total = total*e_s
312 319
313 320 if total == 0: #Error
314 321 status = 0
315 322 elif total == (3**len(exp_status)): #Running
316 323 status = 2
317 324 else:
318 325 status = 1 #Configurated
319 326
320 327 self.status = status
321 328 self.save()
322 329
323 330 def status_color(self):
324 331 color = 'muted'
325 332 if self.status == 0:
326 333 color = "danger"
327 334 elif self.status == 1:
328 335 color = "info"
329 336 elif self.status == 2:
330 337 color = "success"
331 338 elif self.status == 3:
332 339 color = "warning"
333 340
334 341 return color
335 342
336 343 def get_absolute_url(self):
337 344 return reverse('url_experiment', args=[str(self.id)])
338 345
339 346 def parms_to_dict(self):
340 347
341 348 import json
342 349
343 350 configurations = Configuration.objects.filter(experiment=self)
344 351 conf_parameters = {}
345 352 parameters={}
346 353
347 354 for configuration in configurations:
348 355 if 'cgs' in configuration.device.device_type.name:
349 356 conf_parameters['cgs'] = configuration.parms_to_dict()
350 357 if 'dds' in configuration.device.device_type.name:
351 358 conf_parameters['dds'] = configuration.parms_to_dict()
352 359 if 'rc' in configuration.device.device_type.name:
353 360 conf_parameters['rc'] = configuration.parms_to_dict()
354 361 if 'jars' in configuration.device.device_type.name:
355 362 conf_parameters['jars'] = configuration.parms_to_dict()
356 363 if 'usrp' in configuration.device.device_type.name:
357 364 conf_parameters['usrp'] = configuration.parms_to_dict()
358 365 if 'abs' in configuration.device.device_type.name:
359 366 conf_parameters['abs'] = configuration.parms_to_dict()
360 367
361 368 parameters['configurations'] = conf_parameters
362 369 parameters['end_time'] = self.end_time.strftime("%H:%M:%S")
363 370 parameters['start_time'] = self.start_time.strftime("%H:%M:%S")
364 371 parameters['radar'] = self.radar_system.name
365 372 parameters['experiment'] = self.name
366 373 parameters = json.dumps(parameters, indent=2)
367 374
368 375 return parameters
369 376
370 377 def import_from_file(self, fp):
371 378
372 379 import os, json
373 380
374 381 parms = {}
375 382
376 383 path, ext = os.path.splitext(fp.name)
377 384
378 385 if ext == '.json':
379 386 parms = json.loads(fp.read().decode('utf-8'))
380 387
381 388 return parms
382 389
383 390 def dict_to_parms(self, parms, CONF_MODELS):
384 391
385 392 configurations = Configuration.objects.filter(experiment=self)
386 393
387 394 if configurations:
388 395 for configuration in configurations:
389 396 configuration.delete()
390 397
391 398 for conf_type in parms['configurations']:
392 399 #--For ABS Device:
393 400 #--For USRP Device:
394 401 #--For JARS Device:
395 402 if conf_type == 'jars':
396 403 device = get_object_or_404(Device, pk=parms['configurations']['jars']['device_id'])
397 404 DevConfModel = CONF_MODELS[conf_type]
398 405 confjars_form = DevConfModel(
399 406 experiment = self,
400 407 name = 'JARS',
401 408 device=device,
402 409 )
403 410 confjars_form.dict_to_parms(parms['configurations']['jars'])
404 411 confjars_form.save()
405 412 #--For RC Device:
406 413 if conf_type == 'rc':
407 414 device = get_object_or_404(Device, pk=parms['configurations']['rc']['device_id'])
408 415 DevConfModel = CONF_MODELS[conf_type]
409 416 confrc_form = DevConfModel(
410 417 experiment = self,
411 418 name = 'RC',
412 419 device=device,
413 420 )
414 421 confrc_form.dict_to_parms(parms['configurations']['rc'])
415 422 confrc_form.save()
416 423 #--For DDS Device:
417 424 if conf_type == 'dds':
418 425 device = get_object_or_404(Device, pk=parms['configurations']['dds']['device_id'])
419 426 DevConfModel = CONF_MODELS[conf_type]
420 427 confdds_form = DevConfModel(
421 428 experiment = self,
422 429 name = 'DDS',
423 430 device=device,
424 431 )
425 432 confdds_form.dict_to_parms(parms['configurations']['dds'])
426 433 confdds_form.save()
427 434 #--For CGS Device:
428 435 if conf_type == 'cgs':
429 436 device = get_object_or_404(Device, pk=parms['configurations']['cgs']['device_id'])
430 437 DevConfModel = CONF_MODELS[conf_type]
431 438 confcgs_form = DevConfModel(
432 439 experiment = self,
433 440 name = 'CGS',
434 441 device=device,
435 442 )
436 443 confcgs_form.dict_to_parms(parms['configurations']['cgs'])
437 444 confcgs_form.save()
438 445
439 446 location = Location.objects.get(name = parms['radar'])
440 447 self.name = parms['experiment']
441 448 self.location = location
442 449 self.start_time = parms['start_time']
443 450 self.end_time = parms['end_time']
444 451 self.save()
445 452
446 453 return self
447 454
448 455 def get_absolute_url_edit(self):
449 456 return reverse('url_edit_experiment', args=[str(self.id)])
450 457
451 458 def get_absolute_url_import(self):
452 459 return reverse('url_import_experiment', args=[str(self.id)])
453 460
454 461 def get_absolute_url_export(self):
455 462 return reverse('url_export_experiment', args=[str(self.id)])
456 463
457 464
458 465 class Configuration(PolymorphicModel):
459 466
460 467 template = models.BooleanField(default=False)
461 468
462 469 name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
463 470
464 471 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
465 472 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
466 473
467 474 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
468 475
469 476 created_date = models.DateTimeField(auto_now_add=True)
470 477 programmed_date = models.DateTimeField(auto_now=True)
471 478
472 479 parameters = models.TextField(default='{}')
473 480
474 481 message = ""
475 482
476 483 class Meta:
477 484 db_table = 'db_configurations'
478 485
479 486 def __str__(self):
480 487
481 488 device = '{}:'.format(self.device.device_type.name.upper())
482 489
483 490 if 'mix' in [f.name for f in self._meta.get_fields()]:
484 491 if self.mix:
485 492 device = '{} MIXED:'.format(self.device.device_type.name.upper())
486 493
487 494 if self.template:
488 495 return u'{} {} (template)'.format(device, self.name)
489 496 else:
490 497 return u'{} {}'.format(device, self.name)
491 498
492 499 def clone(self, **kwargs):
493 500
494 501 self.pk = None
495 502 self.id = None
496 503 for attr, value in kwargs.items():
497 504 setattr(self, attr, value)
498 505
499 506 self.save()
500 507
501 508 return self
502 509
503 510 def parms_to_dict(self):
504 511
505 512 parameters = {}
506 513
507 514 for key in self.__dict__.keys():
508 515 parameters[key] = getattr(self, key)
509 516
510 517 return parameters
511 518
512 519 def parms_to_text(self):
513 520
514 521 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
515 522
516 523
517 524 def parms_to_binary(self):
518 525
519 526 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
520 527
521 528
522 529 def dict_to_parms(self, parameters):
523 530
524 531 if type(parameters) != type({}):
525 532 return
526 533
527 534 for key in parameters.keys():
528 535 setattr(self, key, parameters[key])
529 536
530 537 def export_to_file(self, format="json"):
531 538
532 539 import json
533 540
534 541 content_type = ''
535 542
536 543 if format == 'text':
537 544 content_type = 'text/plain'
538 545 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
539 546 content = self.parms_to_text()
540 547
541 548 if format == 'binary':
542 549 content_type = 'application/octet-stream'
543 550 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
544 551 content = self.parms_to_binary()
545 552
546 553 if not content_type:
547 554 content_type = 'application/json'
548 555 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
549 556 content = json.dumps(self.parms_to_dict(), indent=2)
550 557
551 558 fields = {'content_type':content_type,
552 559 'filename':filename,
553 560 'content':content
554 561 }
555 562
556 563 return fields
557 564
558 565 def import_from_file(self, fp):
559 566
560 567 import os, json
561 568
562 569 parms = {}
563 570
564 571 path, ext = os.path.splitext(fp.name)
565 572
566 573 if ext == '.json':
567 574 parms = json.load(fp)
568 575
569 576 return parms
570 577
571 578 def status_device(self):
572 579
573 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
580 self.message = 'Function not implemented'
581 return False
574 582
575 583
576 584 def stop_device(self):
577 585
578 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
586 self.message = 'Function not implemented'
587 return False
579 588
580 589
581 590 def start_device(self):
582 591
583 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
592 self.message = 'Function not implemented'
593 return False
584 594
585 595
586 596 def write_device(self, parms):
587 597
588 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
598 self.message = 'Function not implemented'
599 return False
589 600
590 601
591 602 def read_device(self):
592 603
593 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
604 self.message = 'Function not implemented'
605 return False
594 606
595 607
596 608 def get_absolute_url(self):
597 609 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
598 610
599 611 def get_absolute_url_edit(self):
600 612 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
601 613
602 614 def get_absolute_url_import(self):
603 615 return reverse('url_import_dev_conf', args=[str(self.id)])
604 616
605 617 def get_absolute_url_export(self):
606 618 return reverse('url_export_dev_conf', args=[str(self.id)])
607 619
608 620 def get_absolute_url_write(self):
609 621 return reverse('url_write_dev_conf', args=[str(self.id)])
610 622
611 623 def get_absolute_url_read(self):
612 624 return reverse('url_read_dev_conf', args=[str(self.id)])
613 625
614 626 def get_absolute_url_start(self):
615 627 return reverse('url_start_dev_conf', args=[str(self.id)])
616 628
617 629 def get_absolute_url_stop(self):
618 630 return reverse('url_stop_dev_conf', args=[str(self.id)])
619 631
620 632 def get_absolute_url_status(self):
621 633 return reverse('url_status_dev_conf', args=[str(self.id)])
@@ -1,1586 +1,1578
1 1 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
2 2 from django.utils.safestring import mark_safe
3 3 from django.http import HttpResponseRedirect
4 4 from django.core.urlresolvers import reverse
5 5 from django.db.models import Q
6 6 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
7 7 from django.contrib import messages
8 8 from django.http.request import QueryDict
9 9 from datetime import datetime
10 10
11 11 try:
12 12 from urllib.parse import urlencode
13 13 except ImportError:
14 14 from urllib import urlencode
15 15
16 16 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
17 17 from .forms import OperationSearchForm, FilterForm
18 18
19 19 from apps.rc.forms import RCConfigurationForm
20 20 from apps.dds.forms import DDSConfigurationForm
21 21 from apps.jars.forms import JARSConfigurationForm
22 22 from apps.cgs.forms import CGSConfigurationForm
23 23 from apps.abs.forms import ABSConfigurationForm
24 24 from apps.usrp.forms import USRPConfigurationForm
25 25
26 26 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment
27 27 from apps.cgs.models import CGSConfiguration
28 28 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
29 29 from apps.usrp.models import USRPConfiguration
30 30 from apps.abs.models import ABSConfiguration
31 31 from apps.rc.models import RCConfiguration, RCLine, RCLineType
32 32 from apps.dds.models import DDSConfiguration
33 33 from django.http.request import QueryDict
34 34 #from __builtin__ import False
35 35
36 36 # Create your views here.
37 37
38 38 CONF_FORMS = {
39 39 'rc': RCConfigurationForm,
40 40 'dds': DDSConfigurationForm,
41 41 'jars': JARSConfigurationForm,
42 42 'cgs': CGSConfigurationForm,
43 43 'abs': ABSConfigurationForm,
44 44 'usrp': USRPConfigurationForm,
45 45 }
46 46
47 47 CONF_MODELS = {
48 48 'rc': RCConfiguration,
49 49 'dds': DDSConfiguration,
50 50 'jars': JARSConfiguration,
51 51 'cgs': CGSConfiguration,
52 52 'abs': ABSConfiguration,
53 53 'usrp': USRPConfiguration,
54 54 }
55 55
56 56 MIX_MODES = {
57 57 '0': 'P',
58 58 '1': 'S',
59 59 }
60 60
61 61 MIX_OPERATIONS = {
62 62 '0': 'OR',
63 63 '1': 'XOR',
64 64 '2': 'AND',
65 65 '3': 'NAND',
66 66 }
67 67
68 68
69 69 def index(request):
70 70 kwargs = {}
71 71
72 72 return render(request, 'index.html', kwargs)
73 73
74 74
75 75 def locations(request):
76 76
77 77 page = request.GET.get('page')
78 78 order = ('name',)
79 79
80 80 kwargs = get_paginator(Location, page, order)
81 81
82 82 kwargs['keys'] = ['name', 'description']
83 83 kwargs['title'] = 'Radar System'
84 84 kwargs['suptitle'] = 'List'
85 85
86 86 return render(request, 'base_list.html', kwargs)
87 87
88 88
89 89 def location(request, id_loc):
90 90
91 91 location = get_object_or_404(Location, pk=id_loc)
92 92
93 93 kwargs = {}
94 94 kwargs['location'] = location
95 95 kwargs['location_keys'] = ['name', 'description']
96 96
97 97 kwargs['title'] = 'Location'
98 98 kwargs['suptitle'] = 'Details'
99 99
100 100 return render(request, 'location.html', kwargs)
101 101
102 102
103 103 def location_new(request):
104 104
105 105 if request.method == 'GET':
106 106 form = LocationForm()
107 107
108 108 if request.method == 'POST':
109 109 form = LocationForm(request.POST)
110 110
111 111 if form.is_valid():
112 112 form.save()
113 113 return redirect('url_locations')
114 114
115 115 kwargs = {}
116 116 kwargs['form'] = form
117 117 kwargs['title'] = 'Radar System'
118 118 kwargs['suptitle'] = 'New'
119 119 kwargs['button'] = 'Create'
120 120
121 121 return render(request, 'base_edit.html', kwargs)
122 122
123 123
124 124 def location_edit(request, id_loc):
125 125
126 126 location = get_object_or_404(Location, pk=id_loc)
127 127
128 128 if request.method=='GET':
129 129 form = LocationForm(instance=location)
130 130
131 131 if request.method=='POST':
132 132 form = LocationForm(request.POST, instance=location)
133 133
134 134 if form.is_valid():
135 135 form.save()
136 136 return redirect('url_locations')
137 137
138 138 kwargs = {}
139 139 kwargs['form'] = form
140 140 kwargs['title'] = 'Location'
141 141 kwargs['suptitle'] = 'Edit'
142 142 kwargs['button'] = 'Update'
143 143
144 144 return render(request, 'base_edit.html', kwargs)
145 145
146 146
147 147 def location_delete(request, id_loc):
148 148
149 149 location = get_object_or_404(Location, pk=id_loc)
150 150
151 151 if request.method=='POST':
152 152
153 153 if request.user.is_staff:
154 154 location.delete()
155 155 return redirect('url_locations')
156 156
157 157 messages.error(request, 'Not enough permission to delete this object')
158 158 return redirect(location.get_absolute_url())
159 159
160 160 kwargs = {
161 161 'title': 'Delete',
162 162 'suptitle': 'Location',
163 163 'object': location,
164 164 'previous': location.get_absolute_url(),
165 165 'delete': True
166 166 }
167 167
168 168 return render(request, 'confirm.html', kwargs)
169 169
170 170
171 171 def devices(request):
172 172
173 173 page = request.GET.get('page')
174 174 order = ('device_type', 'name')
175 175
176 176 kwargs = get_paginator(Device, page, order)
177 177 kwargs['keys'] = ['name', 'ip_address', 'port_address', 'device_type']
178 178 kwargs['title'] = 'Device'
179 179 kwargs['suptitle'] = 'List'
180 180
181 181 return render(request, 'base_list.html', kwargs)
182 182
183 183
184 184 def device(request, id_dev):
185 185
186 186 device = get_object_or_404(Device, pk=id_dev)
187 187
188 188 kwargs = {}
189 189 kwargs['device'] = device
190 190 kwargs['device_keys'] = ['device_type', 'name', 'ip_address', 'port_address', 'description']
191 191
192 192 kwargs['title'] = 'Device'
193 193 kwargs['suptitle'] = 'Details'
194 194
195 195 return render(request, 'device.html', kwargs)
196 196
197 197
198 198 def device_new(request):
199 199
200 200 if request.method == 'GET':
201 201 form = DeviceForm()
202 202
203 203 if request.method == 'POST':
204 204 form = DeviceForm(request.POST)
205 205
206 206 if form.is_valid():
207 207 form.save()
208 208 return redirect('url_devices')
209 209
210 210 kwargs = {}
211 211 kwargs['form'] = form
212 212 kwargs['title'] = 'Device'
213 213 kwargs['suptitle'] = 'New'
214 214 kwargs['button'] = 'Create'
215 215
216 216 return render(request, 'base_edit.html', kwargs)
217 217
218 218
219 219 def device_edit(request, id_dev):
220 220
221 221 device = get_object_or_404(Device, pk=id_dev)
222 222
223 223 if request.method=='GET':
224 224 form = DeviceForm(instance=device)
225 225
226 226 if request.method=='POST':
227 227 form = DeviceForm(request.POST, instance=device)
228 228
229 229 if form.is_valid():
230 230 form.save()
231 231 return redirect(device.get_absolute_url())
232 232
233 233 kwargs = {}
234 234 kwargs['form'] = form
235 235 kwargs['title'] = 'Device'
236 236 kwargs['suptitle'] = 'Edit'
237 237 kwargs['button'] = 'Update'
238 238
239 239 return render(request, 'base_edit.html', kwargs)
240 240
241 241
242 242 def device_delete(request, id_dev):
243 243
244 244 device = get_object_or_404(Device, pk=id_dev)
245 245
246 246 if request.method=='POST':
247 247
248 248 if request.user.is_staff:
249 249 device.delete()
250 250 return redirect('url_devices')
251 251
252 252 messages.error(request, 'Not enough permission to delete this object')
253 253 return redirect(device.get_absolute_url())
254 254
255 255 kwargs = {
256 256 'title': 'Delete',
257 257 'suptitle': 'Device',
258 258 'object': device,
259 259 'previous': device.get_absolute_url(),
260 260 'delete': True
261 261 }
262 262
263 263 return render(request, 'confirm.html', kwargs)
264 264
265 265
266 266 def campaigns(request):
267 267
268 268 page = request.GET.get('page')
269 269 order = ('start_date',)
270 270 filters = request.GET.copy()
271 271
272 272 kwargs = get_paginator(Campaign, page, order, filters)
273 273
274 274 form = FilterForm(initial=request.GET, extra_fields=['range_date', 'tags','template'])
275 275 kwargs['keys'] = ['name', 'start_date', 'end_date']
276 276 kwargs['title'] = 'Campaign'
277 277 kwargs['suptitle'] = 'List'
278 278 kwargs['form'] = form
279 279 filters.pop('page', None)
280 280 kwargs['q'] = urlencode(filters)
281 281
282 282 return render(request, 'base_list.html', kwargs)
283 283
284 284
285 285 def campaign(request, id_camp):
286 286
287 287 campaign = get_object_or_404(Campaign, pk=id_camp)
288 288 experiments = Experiment.objects.filter(campaign=campaign)
289 289
290 290 form = CampaignForm(instance=campaign)
291 291
292 292 kwargs = {}
293 293 kwargs['campaign'] = campaign
294 294 kwargs['campaign_keys'] = ['template', 'name', 'start_date', 'end_date', 'tags', 'description']
295 295
296 296 kwargs['experiments'] = experiments
297 297 kwargs['experiment_keys'] = ['name', 'radar_system', 'start_time', 'end_time']
298 298
299 299 kwargs['title'] = 'Campaign'
300 300 kwargs['suptitle'] = 'Details'
301 301
302 302 kwargs['form'] = form
303 303 kwargs['button'] = 'Add Experiment'
304 304
305 305 return render(request, 'campaign.html', kwargs)
306 306
307 307
308 308 def campaign_new(request):
309 309
310 310 kwargs = {}
311 311
312 312 if request.method == 'GET':
313 313
314 314 if 'template' in request.GET:
315 315 if request.GET['template']=='0':
316 316 form = NewForm(initial={'create_from':2},
317 317 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
318 318 else:
319 319 kwargs['button'] = 'Create'
320 320 kwargs['experiments'] = Configuration.objects.filter(experiment=request.GET['template'])
321 321 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
322 322 camp = Campaign.objects.get(pk=request.GET['template'])
323 323 form = CampaignForm(instance=camp,
324 324 initial={'name':'{} [{:%Y/%m/%d}]'.format(camp.name, datetime.now()),
325 325 'template':False})
326 326 elif 'blank' in request.GET:
327 327 kwargs['button'] = 'Create'
328 328 form = CampaignForm()
329 329 else:
330 330 form = NewForm()
331 331
332 332 if request.method == 'POST':
333 333 kwargs['button'] = 'Create'
334 334 post = request.POST.copy()
335 335 experiments = []
336 336
337 337 for id_exp in post.getlist('experiments'):
338 338 exp = Experiment.objects.get(pk=id_exp)
339 339 new_exp = exp.clone(template=False)
340 340 experiments.append(new_exp)
341 341
342 342 post.setlist('experiments', [])
343 343
344 344 form = CampaignForm(post)
345 345
346 346 if form.is_valid():
347 347 campaign = form.save()
348 348 for exp in experiments:
349 349 campaign.experiments.add(exp)
350 350 campaign.save()
351 351 return redirect('url_campaign', id_camp=campaign.id)
352 352
353 353 kwargs['form'] = form
354 354 kwargs['title'] = 'Campaign'
355 355 kwargs['suptitle'] = 'New'
356 356
357 357 return render(request, 'campaign_edit.html', kwargs)
358 358
359 359
360 360 def campaign_edit(request, id_camp):
361 361
362 362 campaign = get_object_or_404(Campaign, pk=id_camp)
363 363
364 364 if request.method=='GET':
365 365 form = CampaignForm(instance=campaign)
366 366
367 367 if request.method=='POST':
368 368 exps = campaign.experiments.all().values_list('pk', flat=True)
369 369 post = request.POST.copy()
370 370 new_exps = post.getlist('experiments')
371 371 post.setlist('experiments', [])
372 372 form = CampaignForm(post, instance=campaign)
373 373
374 374 if form.is_valid():
375 375 camp = form.save()
376 376 for id_exp in new_exps:
377 377 if int(id_exp) in exps:
378 378 exps.pop(id_exp)
379 379 else:
380 380 exp = Experiment.objects.get(pk=id_exp)
381 381 if exp.template:
382 382 camp.experiments.add(exp.clone(template=False))
383 383 else:
384 384 camp.experiments.add(exp)
385 385
386 386 for id_exp in exps:
387 387 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
388 388
389 389 return redirect('url_campaign', id_camp=id_camp)
390 390
391 391 kwargs = {}
392 392 kwargs['form'] = form
393 393 kwargs['title'] = 'Campaign'
394 394 kwargs['suptitle'] = 'Edit'
395 395 kwargs['button'] = 'Update'
396 396
397 397 return render(request, 'campaign_edit.html', kwargs)
398 398
399 399
400 400 def campaign_delete(request, id_camp):
401 401
402 402 campaign = get_object_or_404(Campaign, pk=id_camp)
403 403
404 404 if request.method=='POST':
405 405 if request.user.is_staff:
406 406
407 407 for exp in campaign.experiments.all():
408 408 for conf in Configuration.objects.filter(experiment=exp):
409 409 conf.delete()
410 410 exp.delete()
411 411 campaign.delete()
412 412
413 413 return redirect('url_campaigns')
414 414
415 415 messages.error(request, 'Not enough permission to delete this object')
416 416 return redirect(campaign.get_absolute_url())
417 417
418 418 kwargs = {
419 419 'title': 'Delete',
420 420 'suptitle': 'Campaign',
421 421 'object': campaign,
422 422 'previous': campaign.get_absolute_url(),
423 423 'delete': True
424 424 }
425 425
426 426 return render(request, 'confirm.html', kwargs)
427 427
428 428 def campaign_export(request, id_camp):
429 429
430 430 campaign = get_object_or_404(Campaign, pk=id_camp)
431 431 content = campaign.parms_to_dict()
432 432 content_type = 'application/json'
433 433 filename = '%s_%s.json' %(campaign.name, campaign.id)
434 434
435 435 response = HttpResponse(content_type=content_type)
436 436 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
437 437 response.write(content)
438 438
439 439 return response
440 440
441 441
442 442 def campaign_import(request, id_camp):
443 443
444 444 campaign = get_object_or_404(Campaign, pk=id_camp)
445 445
446 446 if request.method == 'GET':
447 447 file_form = UploadFileForm()
448 448
449 449 if request.method == 'POST':
450 450 file_form = UploadFileForm(request.POST, request.FILES)
451 451
452 452 if file_form.is_valid():
453 453
454 454 parms = campaign.import_from_file(request.FILES['file'])
455 455
456 456 if parms:
457 457 parms['name'] = parms['campaign']
458 458
459 459 new_camp = campaign.dict_to_parms(parms, CONF_MODELS)
460 460
461 461 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
462 462
463 463 return redirect(new_camp.get_absolute_url_edit())
464 464
465 465 messages.error(request, "Could not import parameters from file")
466 466
467 467 kwargs = {}
468 468 kwargs['title'] = 'Campaign'
469 469 kwargs['form'] = file_form
470 470 kwargs['suptitle'] = 'Importing file'
471 471 kwargs['button'] = 'Import'
472 472
473 473 return render(request, 'campaign_import.html', kwargs)
474 474
475 475
476 476 def experiments(request):
477 477
478 478 page = request.GET.get('page')
479 479 order = ('location',)
480 480 filters = request.GET.copy()
481 481
482 482 kwargs = get_paginator(Experiment, page, order, filters)
483 483
484 484 form = FilterForm(initial=request.GET, extra_fields=['tags','template'])
485 485
486 486 kwargs['keys'] = ['name', 'radar_system', 'start_time', 'end_time']
487 487 kwargs['title'] = 'Experiment'
488 488 kwargs['suptitle'] = 'List'
489 489 kwargs['form'] = form
490 490 filters.pop('page', None)
491 491 kwargs['q'] = urlencode(filters)
492 492
493 493 return render(request, 'base_list.html', kwargs)
494 494
495 495
496 496 def experiment(request, id_exp):
497 497
498 498 experiment = get_object_or_404(Experiment, pk=id_exp)
499 499
500 500 configurations = Configuration.objects.filter(experiment=experiment, type=0)
501 501
502 502 kwargs = {}
503 503
504 504 kwargs['experiment_keys'] = ['template', 'radar_system', 'name', 'start_time', 'end_time']
505 505 kwargs['experiment'] = experiment
506 506
507 507 kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status']
508 508 kwargs['configurations'] = configurations
509 509
510 510 kwargs['title'] = 'Experiment'
511 511 kwargs['suptitle'] = 'Details'
512 512
513 513 kwargs['button'] = 'Add Configuration'
514 514
515 515 ###### SIDEBAR ######
516 516 kwargs.update(sidebar(experiment=experiment))
517 517
518 518 return render(request, 'experiment.html', kwargs)
519 519
520 520
521 521 def experiment_new(request, id_camp=None):
522 522
523 523 kwargs = {}
524 524
525 525 if request.method == 'GET':
526 526 if 'template' in request.GET:
527 527 if request.GET['template']=='0':
528 528 form = NewForm(initial={'create_from':2},
529 529 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
530 530 else:
531 531 kwargs['button'] = 'Create'
532 532 kwargs['configurations'] = Configuration.objects.filter(experiment=request.GET['template'])
533 533 kwargs['configuration_keys'] = ['name', 'device__name', 'device__ip_address', 'device__port_address']
534 534 exp=Experiment.objects.get(pk=request.GET['template'])
535 535 form = ExperimentForm(instance=exp,
536 536 initial={'name': '{} [{:%Y/%m/%d}]'.format(exp.name, datetime.now()),
537 537 'template': False})
538 538 elif 'blank' in request.GET:
539 539 kwargs['button'] = 'Create'
540 540 form = ExperimentForm()
541 541 else:
542 542 form = NewForm()
543 543
544 544 if request.method == 'POST':
545 545 form = ExperimentForm(request.POST)
546 546 if form.is_valid():
547 547 experiment = form.save()
548 548
549 549 if 'template' in request.GET:
550 550 configurations = Configuration.objects.filter(experiment=request.GET['template'], type=0)
551 551 for conf in configurations:
552 552 conf.clone(experiment=experiment, template=False)
553 553
554 554 return redirect('url_experiment', id_exp=experiment.id)
555 555
556 556 kwargs['form'] = form
557 557 kwargs['title'] = 'Experiment'
558 558 kwargs['suptitle'] = 'New'
559 559
560 560 return render(request, 'experiment_edit.html', kwargs)
561 561
562 562
563 563 def experiment_edit(request, id_exp):
564 564
565 565 experiment = get_object_or_404(Experiment, pk=id_exp)
566 566
567 567 if request.method == 'GET':
568 568 form = ExperimentForm(instance=experiment)
569 569
570 570 if request.method=='POST':
571 571 form = ExperimentForm(request.POST, instance=experiment)
572 572
573 573 if form.is_valid():
574 574 experiment = form.save()
575 575 return redirect('url_experiment', id_exp=experiment.id)
576 576
577 577 kwargs = {}
578 578 kwargs['form'] = form
579 579 kwargs['title'] = 'Experiment'
580 580 kwargs['suptitle'] = 'Edit'
581 581 kwargs['button'] = 'Update'
582 582
583 583 return render(request, 'experiment_edit.html', kwargs)
584 584
585 585
586 586 def experiment_delete(request, id_exp):
587 587
588 588 experiment = get_object_or_404(Experiment, pk=id_exp)
589 589
590 590 if request.method=='POST':
591 591 if request.user.is_staff:
592 592 for conf in Configuration.objects.filter(experiment=experiment):
593 593 conf.delete()
594 594 experiment.delete()
595 595 return redirect('url_experiments')
596 596
597 597 messages.error(request, 'Not enough permission to delete this object')
598 598 return redirect(experiment.get_absolute_url())
599 599
600 600 kwargs = {
601 601 'title': 'Delete',
602 602 'suptitle': 'Experiment',
603 603 'object': experiment,
604 604 'previous': experiment.get_absolute_url(),
605 605 'delete': True
606 606 }
607 607
608 608 return render(request, 'confirm.html', kwargs)
609 609
610 610
611 611 def experiment_export(request, id_exp):
612 612
613 613 experiment = get_object_or_404(Experiment, pk=id_exp)
614 614 content = experiment.parms_to_dict()
615 615 content_type = 'application/json'
616 616 filename = '%s_%s.json' %(experiment.name, experiment.id)
617 617
618 618 response = HttpResponse(content_type=content_type)
619 619 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
620 620 response.write(content)
621 621
622 622 return response
623 623
624 624 def experiment_import(request, id_exp):
625 625
626 626 experiment = get_object_or_404(Experiment, pk=id_exp)
627 627 configurations = Configuration.objects.filter(experiment=experiment)
628 628
629 629 if request.method == 'GET':
630 630 file_form = UploadFileForm()
631 631
632 632 if request.method == 'POST':
633 633 file_form = UploadFileForm(request.POST, request.FILES)
634 634
635 635 if file_form.is_valid():
636 636
637 637 parms = experiment.import_from_file(request.FILES['file'])
638 638
639 639 if parms:
640 640
641 641 new_exp = experiment.dict_to_parms(parms, CONF_MODELS)
642 642
643 643 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
644 644
645 645 return redirect(new_exp.get_absolute_url_edit())
646 646
647 647 messages.error(request, "Could not import parameters from file")
648 648
649 649 kwargs = {}
650 650 kwargs['title'] = 'Experiment'
651 651 kwargs['form'] = file_form
652 652 kwargs['suptitle'] = 'Importing file'
653 653 kwargs['button'] = 'Import'
654 654
655 655 kwargs.update(sidebar(experiment=experiment))
656 656
657 657 return render(request, 'experiment_import.html', kwargs)
658 658
659 659 def experiment_mix(request, id_exp):
660 660
661 661 experiment = get_object_or_404(Experiment, pk=id_exp)
662 662 rc_confs = [conf for conf in RCConfiguration.objects.filter(experiment=id_exp,
663 663 mix=False)]
664 664
665 665 if len(rc_confs)<2:
666 666 messages.warning(request, 'You need at least two RC Configurations to make a mix')
667 667 return redirect(experiment.get_absolute_url())
668 668
669 669 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True)
670 670
671 671 if mix_confs:
672 672 mix = mix_confs[0]
673 673 else:
674 674 mix = RCConfiguration(experiment=experiment,
675 675 device=rc_confs[0].device,
676 676 ipp=rc_confs[0].ipp,
677 677 clock_in=rc_confs[0].clock_in,
678 678 clock_divider=rc_confs[0].clock_divider,
679 679 mix=True,
680 680 parameters='')
681 681 mix.save()
682 682
683 683 line_type = RCLineType.objects.get(name='mix')
684 684 for i in range(len(rc_confs[0].get_lines())):
685 685 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
686 686 line.save()
687 687
688 688 initial = {'name': mix.name,
689 689 'result': parse_mix_result(mix.parameters),
690 690 'delay': 0,
691 691 'mask': [0,1,2,3,4,5,6,7]
692 692 }
693 693
694 694 if request.method=='GET':
695 695 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
696 696
697 697 if request.method=='POST':
698 698 result = mix.parameters
699 699
700 700 if '{}|'.format(request.POST['experiment']) in result:
701 701 messages.error(request, 'Configuration already added')
702 702 else:
703 703 if 'operation' in request.POST:
704 704 operation = MIX_OPERATIONS[request.POST['operation']]
705 705 else:
706 706 operation = ' '
707 707
708 708 mode = MIX_MODES[request.POST['mode']]
709 709
710 710 if result:
711 711 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
712 712 request.POST['experiment'],
713 713 mode,
714 714 operation,
715 715 float(request.POST['delay']),
716 716 parse_mask(request.POST.getlist('mask'))
717 717 )
718 718 else:
719 719 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
720 720 mode,
721 721 operation,
722 722 float(request.POST['delay']),
723 723 parse_mask(request.POST.getlist('mask'))
724 724 )
725 725
726 726 mix.parameters = result
727 727 mix.name = request.POST['name']
728 728 mix.save()
729 729 mix.update_pulses()
730 730
731 731 initial['result'] = parse_mix_result(result)
732 732 initial['name'] = mix.name
733 733
734 734 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
735 735
736 736
737 737 kwargs = {
738 738 'title': 'Experiment',
739 739 'suptitle': 'Mix Configurations',
740 740 'form' : form,
741 741 'extra_button': 'Delete',
742 742 'button': 'Add',
743 743 'cancel': 'Back',
744 744 'previous': experiment.get_absolute_url(),
745 745 'id_exp':id_exp,
746 746
747 747 }
748 748
749 749 return render(request, 'experiment_mix.html', kwargs)
750 750
751 751
752 752 def experiment_mix_delete(request, id_exp):
753 753
754 754 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True)
755 755 values = conf.parameters.split('-')
756 756 conf.parameters = '-'.join(values[:-1])
757 757 conf.save()
758 758
759 759 return redirect('url_mix_experiment', id_exp=id_exp)
760 760
761 761
762 762 def experiment_summary(request, id_exp):
763 763
764 764 import json
765 765 import ast
766 766
767 767 experiment = get_object_or_404(Experiment, pk=id_exp)
768 768 experiment_data = json.loads(experiment.parms_to_dict())
769 769 configurations = Configuration.objects.filter(experiment=experiment, type=0)
770 770
771 771 kwargs = {}
772 772
773 773 kwargs['experiment_keys'] = ['template', 'radar_system', 'name', 'start_time', 'end_time']
774 774 kwargs['experiment'] = experiment
775 775
776 776 kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status']
777 777 kwargs['configurations'] = configurations
778 778 kwargs['experiment_data'] = experiment_data
779 779
780 780 kwargs['title'] = 'Experiment Summary'
781 781 kwargs['suptitle'] = 'Details'
782 782
783 783 kwargs['button'] = 'Verify Parameters'
784 784
785 785 jars_conf = False
786 786 rc_conf = False
787 787
788 788 for configuration in configurations:
789 789 #-------------------- JARS -----------------------:
790 790 if configuration.device.device_type.name == 'jars':
791 791 jars_conf = True
792 792 kwargs['jars_conf'] = jars_conf
793 793 kwargs['exp_type'] = EXPERIMENT_TYPE[configuration.exp_type][1]
794 794 channels_number = configuration.channels_number
795 795 exp_type = configuration.exp_type
796 796 fftpoints = configuration.fftpoints
797 797 filter_parms = configuration.filter_parms
798 798 filter_parms = ast.literal_eval(filter_parms)
799 799 spectral_number = configuration.spectral_number
800 800
801 801 #--------------------- RC ----------------------:
802 802 if configuration.device.device_type.name == 'rc':
803 803 rc_conf = True
804 804 kwargs['rc_conf'] = rc_conf
805 805 rc_lines = experiment_data['configurations']['rc']['lines']
806 806 ipp = configuration.ipp
807 807 if experiment_data['configurations']['rc']['mix'] == 'True':
808 808 tx = ''
809 809 code = ''
810 810 window = ''
811 811 else:
812 812 code = rc_lines[3]['code']
813 813
814 814 window_data = rc_lines[6]['params'][0]
815 815 h0 = str(window_data['first_height'])
816 816 dh = str(window_data['resolution'])
817 817 nsa = str(window_data['number_of_samples'])
818 818 window = 'Ho='+h0+'km\nDH='+dh+'km\nNSA='+nsa
819 819
820 820 tx = ''
821 821 if float(rc_lines[1]['delays']) == 0:
822 822 tx = rc_lines[2]['pulse_width']
823 823 elif float(rc_lines[2]['delays']) == 0:
824 824 tx = rc_lines[1]['pulse_width']
825 825 else:
826 826 tx = rc_lines[1]['pulse_width']+' | '+rc_lines[2]['pulse_width']
827 827
828 828 kwargs['tx'] = tx
829 829 kwargs['code'] = code
830 830 kwargs['window'] = window
831 831
832 832 #-------------------- DDS -----------------------:
833 833 if configuration.device.device_type.name == 'dds':
834 834 dds_conf = True
835 835 kwargs['dds_conf'] = dds_conf
836 836
837 837 #------ RC & JARS ------:
838 838 ipp = 937.5 #
839 839 nsa = 200#
840 840 dh = 1.5 #
841 841 channels_number = 5 #
842 842
843 843 if rc_conf and jars_conf:
844 844 if exp_type == 0: #Short
845 845 bytes = 2
846 846 b = nsa*2*bytes*channels_number
847 847 else: #Float
848 848 bytes = 4
849 849 channels = channels_number + spectral_number
850 850 b = nsa*2*bytes*fftpoints*channels
851 851
852 852 ipps = (ipp*pow(10,-6))/0.15
853 853 GB = 1048576.0*1024.0
854 854 Hour = 3600
855 855 rate = b/ipps
856 856 rate = rate *(1/GB)*(Hour)
857 857 kwargs['rate'] = str(rate)+" GB/h"
858 858 else:
859 859 kwargs['rate'] = ''
860 860
861 861 ###### SIDEBAR ######
862 862 kwargs.update(sidebar(experiment=experiment))
863 863
864 864 return render(request, 'experiment_summary.html', kwargs)
865 865
866 866 def experiment_verify(request, id_exp):
867 867
868 868 import json
869 869 import ast
870 870
871 871 experiment = get_object_or_404(Experiment, pk=id_exp)
872 872 experiment_data = json.loads(experiment.parms_to_dict())
873 873 configurations = Configuration.objects.filter(experiment=experiment, type=0)
874 874
875 875 kwargs = {}
876 876
877 877 kwargs['experiment_keys'] = ['template', 'radar_system', 'name', 'start_time', 'end_time']
878 878 kwargs['experiment'] = experiment
879 879
880 880 kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status']
881 881 kwargs['configurations'] = configurations
882 882 kwargs['experiment_data'] = experiment_data
883 883
884 884 kwargs['title'] = 'Verify Experiment'
885 885 kwargs['suptitle'] = 'Parameters'
886 886
887 887 kwargs['button'] = 'Update'
888 888
889 889 jars_conf = False
890 890 rc_conf = False
891 891 dds_conf = False
892 892
893 893 for configuration in configurations:
894 894 #-------------------- JARS -----------------------:
895 895 if configuration.device.device_type.name == 'jars':
896 896 jars_conf = True
897 897 kwargs['jars_conf'] = jars_conf
898 898 filter_parms = configuration.filter_parms
899 899 filter_parms = ast.literal_eval(filter_parms)
900 900 kwargs['filter_parms'] = filter_parms
901 901 #--Sampling Frequency
902 902 clock = filter_parms['clock']
903 903 filter_2 = filter_parms['filter_2']
904 904 filter_5 = filter_parms['filter_5']
905 905 filter_fir = filter_parms['filter_fir']
906 906 samp_freq_jars = clock/filter_2/filter_5/filter_fir
907 907
908 908 kwargs['samp_freq_jars'] = samp_freq_jars
909 909 kwargs['jars'] = configuration
910 910
911 911 #--------------------- RC ----------------------:
912 912 if configuration.device.device_type.name == 'rc':
913 913 rc_conf = True
914 914 rc_parms = configuration.parms_to_dict()
915 915 if rc_parms['mix'] == 'True':
916 916 pass
917 917 else:
918 918 rc_lines = rc_parms['lines']
919 919 dh = rc_lines[6]['params'][0]['resolution']
920 920 #--Sampling Frequency
921 921 samp_freq_rc = 0.15/dh
922 922 kwargs['samp_freq_rc'] = samp_freq_rc
923 923
924 924 kwargs['rc_conf'] = rc_conf
925 925 kwargs['rc'] = configuration
926 926
927 927 #-------------------- DDS ----------------------:
928 928 if configuration.device.device_type.name == 'dds':
929 929 dds_conf = True
930 930 dds_parms = configuration.parms_to_dict()
931 931
932 932 kwargs['dds_conf'] = dds_conf
933 933 kwargs['dds'] = configuration
934 934
935 935
936 936 #------------Validation------------:
937 937 #Clock
938 938 if dds_conf and rc_conf and jars_conf:
939 939 if filter_parms['clock'] != rc_parms['clock_in'] and rc_parms['clock_in'] != dds_parms['clock']:
940 940 messages.warning(request, "Devices don't have the same clock.")
941 941 elif rc_conf and jars_conf:
942 942 if filter_parms['clock'] != rc_parms['clock_in']:
943 943 messages.warning(request, "Devices don't have the same clock.")
944 944 elif rc_conf and dds_conf:
945 945 if rc_parms['clock_in'] != dds_parms['clock']:
946 946 messages.warning(request, "Devices don't have the same clock.")
947 947 if float(samp_freq_rc) != float(dds_parms['frequencyA']):
948 948 messages.warning(request, "Devices don't have the same Frequency A.")
949 949
950 950
951 951
952 952 ###### SIDEBAR ######
953 953 kwargs.update(sidebar(experiment=experiment))
954 954
955 955
956 956
957 957
958 958
959 959 return render(request, 'experiment_verify.html', kwargs)
960 960
961 961
962 962 def parse_mix_result(s):
963 963
964 964 values = s.split('-')
965 965 html = 'EXP MOD OPE DELAY MASK\r\n'
966 966
967 967 if not values or values[0] in ('', ' '):
968 968 return mark_safe(html)
969 969
970 970 for i, value in enumerate(values):
971 971 if not value:
972 972 continue
973 973 pk, mode, operation, delay, mask = value.split('|')
974 974 conf = RCConfiguration.objects.get(pk=pk)
975 975 if i==0:
976 976 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
977 977 conf.name,
978 978 mode,
979 979 ' ',
980 980 delay,
981 981 mask)
982 982 else:
983 983 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
984 984 conf.name,
985 985 mode,
986 986 operation,
987 987 delay,
988 988 mask)
989 989
990 990 return mark_safe(html)
991 991
992 992 def parse_mask(l):
993 993
994 994 values = []
995 995
996 996 for x in range(8):
997 997 if '{}'.format(x) in l:
998 998 values.append(1)
999 999 else:
1000 1000 values.append(0)
1001 1001
1002 1002 values.reverse()
1003 1003
1004 1004 return int(''.join([str(x) for x in values]), 2)
1005 1005
1006 1006
1007 1007 def dev_confs(request):
1008 1008
1009 1009
1010 1010 page = request.GET.get('page')
1011 1011 order = ('type', 'device__device_type', 'experiment')
1012 1012 filters = request.GET.copy()
1013 1013
1014 1014 kwargs = get_paginator(Configuration, page, order, filters)
1015 1015
1016 1016 form = FilterForm(initial=request.GET, extra_fields=['tags','template'])
1017 1017 kwargs['keys'] = ['name', 'experiment', 'type', 'programmed_date']
1018 1018 kwargs['title'] = 'Configuration'
1019 1019 kwargs['suptitle'] = 'List'
1020 1020 kwargs['form'] = form
1021 1021 filters.pop('page', None)
1022 1022 kwargs['q'] = urlencode(filters)
1023 1023
1024 1024 return render(request, 'base_list.html', kwargs)
1025 1025
1026 1026
1027 1027 def dev_conf(request, id_conf):
1028 1028
1029 1029 conf = get_object_or_404(Configuration, pk=id_conf)
1030 1030
1031 1031 return redirect(conf.get_absolute_url())
1032 1032
1033 1033
1034 1034 def dev_conf_new(request, id_exp=0, id_dev=0):
1035 1035
1036 1036 initial = {}
1037 1037 kwargs = {}
1038 1038
1039 1039 if id_exp!=0:
1040 1040 initial['experiment'] = id_exp
1041 1041
1042 1042 if id_dev!=0:
1043 1043 initial['device'] = id_dev
1044 1044
1045 1045 if request.method == 'GET':
1046 1046
1047 1047 if id_dev:
1048 1048 kwargs['button'] = 'Create'
1049 1049 device = Device.objects.get(pk=id_dev)
1050 1050 DevConfForm = CONF_FORMS[device.device_type.name]
1051 1051 initial['name'] = request.GET['name']
1052 1052 form = DevConfForm(initial=initial)
1053 1053 else:
1054 1054 if 'template' in request.GET:
1055 1055 if request.GET['template']=='0':
1056 1056 choices = [(conf.pk, '{}'.format(conf)) for conf in Configuration.objects.filter(template=True)]
1057 1057 form = NewForm(initial={'create_from':2},
1058 1058 template_choices=choices)
1059 1059 else:
1060 1060 kwargs['button'] = 'Create'
1061 1061 conf = Configuration.objects.get(pk=request.GET['template'])
1062 1062 id_dev = conf.device.pk
1063 1063 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1064 1064 form = DevConfForm(instance=conf,
1065 1065 initial={'name': '{} [{:%Y/%m/%d}]'.format(conf.name, datetime.now()),
1066 1066 'template': False,
1067 1067 'experiment':id_exp})
1068 1068 elif 'blank' in request.GET:
1069 1069 kwargs['button'] = 'Create'
1070 1070 form = ConfigurationForm(initial=initial)
1071 1071 else:
1072 1072 form = NewForm()
1073 1073
1074 1074 if request.method == 'POST':
1075 1075
1076 1076 device = Device.objects.get(pk=request.POST['device'])
1077 1077 DevConfForm = CONF_FORMS[device.device_type.name]
1078 1078
1079 1079 form = DevConfForm(request.POST)
1080 1080 kwargs['button'] = 'Create'
1081 1081 if form.is_valid():
1082 1082 conf = form.save()
1083 1083
1084 1084 if 'template' in request.GET and conf.device.device_type.name=='rc':
1085 1085 lines = RCLine.objects.filter(rc_configuration=request.GET['template'])
1086 1086 for line in lines:
1087 1087 line.clone(rc_configuration=conf)
1088 1088
1089 1089 if conf.device.device_type.name=='jars':
1090 1090 conf.add_parms_to_filter()
1091 1091
1092 1092 return redirect('url_dev_conf', id_conf=conf.pk)
1093 1093
1094 1094 kwargs['id_exp'] = id_exp
1095 1095 kwargs['form'] = form
1096 1096 kwargs['title'] = 'Configuration'
1097 1097 kwargs['suptitle'] = 'New'
1098 1098
1099 1099
1100 1100 if id_dev != 0:
1101 1101 device = Device.objects.get(pk=id_dev)
1102 1102 kwargs['device'] = device.device_type.name
1103 1103
1104 1104 return render(request, 'dev_conf_edit.html', kwargs)
1105 1105
1106 1106
1107 1107 def dev_conf_edit(request, id_conf):
1108 1108
1109 1109 conf = get_object_or_404(Configuration, pk=id_conf)
1110 1110
1111 1111 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1112 1112
1113 1113 if request.method=='GET':
1114 1114 form = DevConfForm(instance=conf)
1115 1115
1116 1116 if request.method=='POST':
1117 1117 form = DevConfForm(request.POST, instance=conf)
1118 1118
1119 1119 if form.is_valid():
1120 1120 form.save()
1121 1121 return redirect('url_dev_conf', id_conf=id_conf)
1122 1122
1123 1123 kwargs = {}
1124 1124 kwargs['form'] = form
1125 1125 kwargs['title'] = 'Device Configuration'
1126 1126 kwargs['suptitle'] = 'Edit'
1127 1127 kwargs['button'] = 'Update'
1128 1128
1129 1129 ###### SIDEBAR ######
1130 1130 kwargs.update(sidebar(conf=conf))
1131 1131
1132 1132 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1133 1133
1134 1134
1135 1135 def dev_conf_start(request, id_conf):
1136 1136
1137 1137 conf = get_object_or_404(Configuration, pk=id_conf)
1138 1138
1139 1139 if conf.start_device():
1140 1140 messages.success(request, conf.message)
1141 1141 else:
1142 1142 messages.error(request, conf.message)
1143 1143
1144 conf.status_device()
1144 #conf.status_device()
1145 1145
1146 1146 return redirect(conf.get_absolute_url())
1147 1147
1148 1148
1149 1149 def dev_conf_stop(request, id_conf):
1150 1150
1151 1151 conf = get_object_or_404(Configuration, pk=id_conf)
1152 1152
1153 1153 if conf.stop_device():
1154 1154 messages.success(request, conf.message)
1155 1155 else:
1156 1156 messages.error(request, conf.message)
1157 1157
1158 conf.status_device()
1158 #conf.status_device()
1159 1159
1160 1160 return redirect(conf.get_absolute_url())
1161 1161
1162 1162
1163 1163 def dev_conf_status(request, id_conf):
1164 1164
1165 1165 conf = get_object_or_404(Configuration, pk=id_conf)
1166 1166
1167 1167 if conf.status_device():
1168 1168 messages.success(request, conf.message)
1169 1169 else:
1170 1170 messages.error(request, conf.message)
1171 1171
1172 1172 return redirect(conf.get_absolute_url())
1173 1173
1174 1174
1175 1175 def dev_conf_write(request, id_conf):
1176 1176
1177 1177 conf = get_object_or_404(Configuration, pk=id_conf)
1178 1178
1179 answer = conf.write_device()
1180 conf.status_device()
1181
1182 if answer:
1179 if conf.write_device():
1183 1180 messages.success(request, conf.message)
1184
1185 #Creating a historical configuration
1186 1181 conf.clone(type=1, template=False)
1187
1188 #Original configuration
1189 conf = DevConfModel.objects.get(pk=id_conf)
1190 1182 else:
1191 1183 messages.error(request, conf.message)
1192 1184
1193 1185 return redirect(conf.get_absolute_url())
1194 1186
1195 1187
1196 1188 def dev_conf_read(request, id_conf):
1197 1189
1198 1190 conf = get_object_or_404(Configuration, pk=id_conf)
1199 1191
1200 1192 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1201 1193
1202 1194 if request.method=='GET':
1203 1195
1204 1196 parms = conf.read_device()
1205 conf.status_device()
1197 #conf.status_device()
1206 1198
1207 1199 if not parms:
1208 1200 messages.error(request, conf.message)
1209 1201 return redirect(conf.get_absolute_url())
1210 1202
1211 1203 form = DevConfForm(initial=parms, instance=conf)
1212 1204
1213 1205 if request.method=='POST':
1214 1206 form = DevConfForm(request.POST, instance=conf)
1215 1207
1216 1208 if form.is_valid():
1217 1209 form.save()
1218 1210 return redirect(conf.get_absolute_url())
1219 1211
1220 1212 messages.error(request, "Parameters could not be saved")
1221 1213
1222 1214 kwargs = {}
1223 1215 kwargs['id_dev'] = conf.id
1224 1216 kwargs['form'] = form
1225 1217 kwargs['title'] = 'Device Configuration'
1226 1218 kwargs['suptitle'] = 'Parameters read from device'
1227 1219 kwargs['button'] = 'Save'
1228 1220
1229 1221 ###### SIDEBAR ######
1230 1222 kwargs.update(sidebar(conf=conf))
1231 1223
1232 1224 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
1233 1225
1234 1226
1235 1227 def dev_conf_import(request, id_conf):
1236 1228
1237 1229 conf = get_object_or_404(Configuration, pk=id_conf)
1238 1230 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1239 1231
1240 1232 if request.method == 'GET':
1241 1233 file_form = UploadFileForm()
1242 1234
1243 1235 if request.method == 'POST':
1244 1236 file_form = UploadFileForm(request.POST, request.FILES)
1245 1237
1246 1238 if file_form.is_valid():
1247 1239
1248 1240 parms = conf.import_from_file(request.FILES['file'])
1249 1241
1250 1242 if parms:
1251 1243 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
1252 1244 form = DevConfForm(initial=parms, instance=conf)
1253 1245
1254 1246 kwargs = {}
1255 1247 kwargs['id_dev'] = conf.id
1256 1248 kwargs['form'] = form
1257 1249 kwargs['title'] = 'Device Configuration'
1258 1250 kwargs['suptitle'] = 'Parameters imported'
1259 1251 kwargs['button'] = 'Save'
1260 1252 kwargs['action'] = conf.get_absolute_url_edit()
1261 1253 kwargs['previous'] = conf.get_absolute_url()
1262 1254
1263 1255 ###### SIDEBAR ######
1264 1256 kwargs.update(sidebar(conf=conf))
1265 1257
1266 1258 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1267 1259
1268 1260 messages.error(request, "Could not import parameters from file")
1269 1261
1270 1262 kwargs = {}
1271 1263 kwargs['id_dev'] = conf.id
1272 1264 kwargs['title'] = 'Device Configuration'
1273 1265 kwargs['form'] = file_form
1274 1266 kwargs['suptitle'] = 'Importing file'
1275 1267 kwargs['button'] = 'Import'
1276 1268
1277 1269 kwargs.update(sidebar(conf=conf))
1278 1270
1279 1271 return render(request, 'dev_conf_import.html', kwargs)
1280 1272
1281 1273
1282 1274 def dev_conf_export(request, id_conf):
1283 1275
1284 1276 conf = get_object_or_404(Configuration, pk=id_conf)
1285 1277
1286 1278 if request.method == 'GET':
1287 1279 file_form = DownloadFileForm(conf.device.device_type.name)
1288 1280
1289 1281 if request.method == 'POST':
1290 1282 file_form = DownloadFileForm(conf.device.device_type.name, request.POST)
1291 1283
1292 1284 if file_form.is_valid():
1293 1285 fields = conf.export_to_file(format = file_form.cleaned_data['format'])
1294 1286
1295 1287 response = HttpResponse(content_type=fields['content_type'])
1296 1288 response['Content-Disposition'] = 'attachment; filename="%s"' %fields['filename']
1297 1289 response.write(fields['content'])
1298 1290
1299 1291 return response
1300 1292
1301 1293 messages.error(request, "Could not export parameters")
1302 1294
1303 1295 kwargs = {}
1304 1296 kwargs['id_dev'] = conf.id
1305 1297 kwargs['title'] = 'Device Configuration'
1306 1298 kwargs['form'] = file_form
1307 1299 kwargs['suptitle'] = 'Exporting file'
1308 1300 kwargs['button'] = 'Export'
1309 1301
1310 1302 return render(request, 'dev_conf_export.html', kwargs)
1311 1303
1312 1304
1313 1305 def dev_conf_delete(request, id_conf):
1314 1306
1315 1307 conf = get_object_or_404(Configuration, pk=id_conf)
1316 1308
1317 1309 if request.method=='POST':
1318 1310 if request.user.is_staff:
1319 1311 conf.delete()
1320 1312 return redirect('url_dev_confs')
1321 1313
1322 1314 messages.error(request, 'Not enough permission to delete this object')
1323 1315 return redirect(conf.get_absolute_url())
1324 1316
1325 1317 kwargs = {
1326 1318 'title': 'Delete',
1327 1319 'suptitle': 'Experiment',
1328 1320 'object': conf,
1329 1321 'previous': conf.get_absolute_url(),
1330 1322 'delete': True
1331 1323 }
1332 1324
1333 1325 return render(request, 'confirm.html', kwargs)
1334 1326
1335 1327
1336 1328 def sidebar(**kwargs):
1337 1329
1338 1330 side_data = {}
1339 1331
1340 1332 conf = kwargs.get('conf', None)
1341 1333 experiment = kwargs.get('experiment', None)
1342 1334
1343 1335 if not experiment:
1344 1336 experiment = conf.experiment
1345 1337
1346 1338 if experiment:
1347 1339 side_data['experiment'] = experiment
1348 1340 campaign = experiment.campaign_set.all()
1349 1341 if campaign:
1350 1342 side_data['campaign'] = campaign[0]
1351 1343 experiments = campaign[0].experiments.all()
1352 1344 else:
1353 1345 experiments = [experiment]
1354 1346 configurations = experiment.configuration_set.filter(type=0)
1355 1347 side_data['side_experiments'] = experiments
1356 1348 side_data['side_configurations'] = configurations
1357 1349
1358 1350 return side_data
1359 1351
1360 1352 def get_paginator(model, page, order, filters={}, n=10):
1361 1353
1362 1354 kwargs = {}
1363 1355 query = Q()
1364 1356 if isinstance(filters, QueryDict):
1365 1357 filters = filters.dict()
1366 1358 [filters.pop(key) for key in filters.keys() if filters[key] in ('', ' ')]
1367 1359 filters.pop('page', None)
1368 1360
1369 1361 if 'start_date' in filters:
1370 1362 filters['start_date__gte'] = filters.pop('start_date')
1371 1363 if 'end_date' in filters:
1372 1364 filters['start_date__lte'] = filters.pop('end_date')
1373 1365 if 'tags' in filters:
1374 1366 tags = filters.pop('tags')
1375 1367 if 'tags' in model._meta.get_all_field_names():
1376 1368 query = query | Q(tags__icontains=tags)
1377 1369 if 'name' in model._meta.get_all_field_names():
1378 1370 query = query | Q(name__icontains=tags)
1379 1371 if 'location' in model._meta.get_all_field_names():
1380 1372 query = query | Q(location__name__icontains=tags)
1381 1373 if 'device' in model._meta.get_all_field_names():
1382 1374 query = query | Q(device__name__icontains=tags)
1383 1375
1384 1376 object_list = model.objects.filter(query, **filters).order_by(*order)
1385 1377 paginator = Paginator(object_list, n)
1386 1378
1387 1379 try:
1388 1380 objects = paginator.page(page)
1389 1381 except PageNotAnInteger:
1390 1382 objects = paginator.page(1)
1391 1383 except EmptyPage:
1392 1384 objects = paginator.page(paginator.num_pages)
1393 1385
1394 1386 kwargs['objects'] = objects
1395 1387 kwargs['offset'] = (int(page)-1)*n if page else 0
1396 1388
1397 1389 return kwargs
1398 1390
1399 1391 def operation(request, id_camp=None):
1400 1392
1401 1393 kwargs = {}
1402 1394 kwargs['no_sidebar'] = True
1403 1395 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1404 1396 end_date__gte=datetime.now()).order_by('-start_date')
1405 1397
1406 1398
1407 1399 if id_camp:
1408 1400 campaign = get_object_or_404(Campaign, pk = id_camp)
1409 1401 form = OperationForm(initial={'campaign': campaign.id}, campaigns=campaigns)
1410 1402 kwargs['campaign'] = campaign
1411 1403 else:
1412 1404 form = OperationForm(campaigns=campaigns)
1413 1405 kwargs['form'] = form
1414 1406 return render(request, 'operation.html', kwargs)
1415 1407
1416 1408 #---Experiment
1417 1409 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1418 1410 kwargs['experiment_keys'] = keys[1:]
1419 1411 kwargs['experiments'] = experiments
1420 1412 #---Radar
1421 1413 kwargs['locations'] = campaign.get_experiments_by_location()
1422 1414 #---Else
1423 1415 kwargs['title'] = 'Campaign'
1424 1416 kwargs['suptitle'] = campaign.name
1425 1417 kwargs['form'] = form
1426 1418
1427 1419 return render(request, 'operation.html', kwargs)
1428 1420
1429 1421
1430 1422 def operation_search(request, id_camp=None):
1431 1423
1432 1424
1433 1425 if not id_camp:
1434 1426 campaigns = Campaign.objects.all().order_by('-start_date')
1435 1427
1436 1428 if not campaigns:
1437 1429 return render(request, 'operation.html', {})
1438 1430
1439 1431 id_camp = campaigns[0].id
1440 1432 campaign = get_object_or_404(Campaign, pk = id_camp)
1441 1433
1442 1434 if request.method=='GET':
1443 1435 form = OperationSearchForm(initial={'campaign': campaign.id})
1444 1436
1445 1437 if request.method=='POST':
1446 1438 form = OperationSearchForm(request.POST, initial={'campaign':campaign.id})
1447 1439
1448 1440 if form.is_valid():
1449 1441 return redirect('url_operation', id_camp=campaign.id)
1450 1442
1451 1443 #locations = Location.objects.filter(experiment__campaign__pk = campaign.id).distinct()
1452 1444 experiments = Experiment.objects.filter(campaign__pk=campaign.id)
1453 1445 #for exs in experiments:
1454 1446 # exs.get_status()
1455 1447 locations= Location.objects.filter(experiment=experiments).distinct()
1456 1448 form = OperationSearchForm(initial={'campaign': campaign.id})
1457 1449
1458 1450 kwargs = {}
1459 1451 #---Campaign
1460 1452 kwargs['campaign'] = campaign
1461 1453 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
1462 1454 #---Experiment
1463 1455 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1464 1456 kwargs['experiment_keys'] = keys[1:]
1465 1457 kwargs['experiments'] = experiments
1466 1458 #---Radar
1467 1459 kwargs['locations'] = locations
1468 1460 #---Else
1469 1461 kwargs['title'] = 'Campaign'
1470 1462 kwargs['suptitle'] = campaign.name
1471 1463 kwargs['form'] = form
1472 1464 kwargs['button'] = 'Select'
1473 1465 kwargs['details'] = True
1474 1466 kwargs['search_button'] = False
1475 1467
1476 1468 return render(request, 'operation.html', kwargs)
1477 1469
1478 1470
1479 1471 def radar_play(request, id_camp, id_radar):
1480 1472 campaign = get_object_or_404(Campaign, pk = id_camp)
1481 1473 radar = get_object_or_404(Location, pk = id_radar)
1482 1474 today = datetime.today()
1483 1475 now = today.time()
1484 1476
1485 1477 #--Clear Old Experiments From RunningExperiment Object
1486 1478 running_experiment = RunningExperiment.objects.filter(radar=radar)
1487 1479 if running_experiment:
1488 1480 running_experiment = running_experiment[0]
1489 1481 running_experiment.running_experiment.clear()
1490 1482 running_experiment.save()
1491 1483
1492 1484 #--If campaign datetime is ok:
1493 1485 if today >= campaign.start_date and today <= campaign.end_date:
1494 1486 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1495 1487 for exp in experiments:
1496 1488 #--If experiment time is ok:
1497 1489 if now >= exp.start_time and now <= exp.end_time:
1498 1490 configurations = Configuration.objects.filter(experiment = exp)
1499 1491 for conf in configurations:
1500 1492 if 'cgs' in conf.device.device_type.name:
1501 1493 conf.status_device()
1502 1494 else:
1503 1495 answer = conf.start_device()
1504 1496 conf.status_device()
1505 1497 #--Running Experiment
1506 1498 old_running_experiment = RunningExperiment.objects.filter(radar=radar)
1507 1499 #--If RunningExperiment element exists
1508 1500 if old_running_experiment:
1509 1501 old_running_experiment = old_running_experiment[0]
1510 1502 old_running_experiment.running_experiment.add(exp)
1511 1503 old_running_experiment.status = 3
1512 1504 old_running_experiment.save()
1513 1505 #--Create a new Running_Experiment Object
1514 1506 else:
1515 1507 new_running_experiment = RunningExperiment(
1516 1508 radar = radar,
1517 1509 status = 3,
1518 1510 )
1519 1511 new_running_experiment.save()
1520 1512 new_running_experiment.running_experiment.add(exp)
1521 1513 new_running_experiment.save()
1522 1514
1523 1515 if answer:
1524 1516 messages.success(request, conf.message)
1525 1517 exp.status=2
1526 1518 exp.save()
1527 1519 else:
1528 1520 messages.error(request, conf.message)
1529 1521 else:
1530 1522 if exp.status == 1 or exp.status == 3:
1531 1523 exp.status=3
1532 1524 exp.save()
1533 1525
1534 1526
1535 1527 route = request.META['HTTP_REFERER']
1536 1528 route = str(route)
1537 1529 if 'search' in route:
1538 1530 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1539 1531 else:
1540 1532 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1541 1533
1542 1534
1543 1535 def radar_stop(request, id_camp, id_radar):
1544 1536 campaign = get_object_or_404(Campaign, pk = id_camp)
1545 1537 radar = get_object_or_404(Location, pk = id_radar)
1546 1538 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1547 1539
1548 1540 for exp in experiments:
1549 1541 configurations = Configuration.objects.filter(experiment = exp)
1550 1542 for conf in configurations:
1551 1543 if 'cgs' in conf.device.device_type.name:
1552 1544 conf.status_device()
1553 1545 else:
1554 1546 answer = conf.stop_device()
1555 1547 conf.status_device()
1556 1548
1557 1549 if answer:
1558 1550 messages.success(request, conf.message)
1559 1551 exp.status=1
1560 1552 exp.save()
1561 1553 else:
1562 1554 messages.error(request, conf.message)
1563 1555
1564 1556
1565 1557 route = request.META['HTTP_REFERER']
1566 1558 route = str(route)
1567 1559 if 'search' in route:
1568 1560 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1569 1561 else:
1570 1562 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1571 1563
1572 1564
1573 1565 def radar_refresh(request, id_camp, id_radar):
1574 1566
1575 1567 campaign = get_object_or_404(Campaign, pk = id_camp)
1576 1568 radar = get_object_or_404(Location, pk = id_radar)
1577 1569 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1578 1570 for exs in experiments:
1579 1571 exs.get_status()
1580 1572
1581 1573 route = request.META['HTTP_REFERER']
1582 1574 route = str(route)
1583 1575 if 'search' in route:
1584 1576 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1585 1577 else:
1586 1578 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
@@ -1,878 +1,927
1 1
2 2 import ast
3 3 import json
4 4 import requests
5 5 import numpy as np
6 6 from base64 import b64encode
7 from struct import pack
7 8
8 9 from django.db import models
9 10 from django.core.urlresolvers import reverse
10 11 from django.core.validators import MinValueValidator, MaxValueValidator
11 12
12 13 from apps.main.models import Configuration
13 14 from devices.rc import api
14 15 from .utils import RCFile
15 16
16 17 # Create your models here.
17 18
18 19 LINE_TYPES = (
19 20 ('none', 'Not used'),
20 21 ('tr', 'Transmission/reception selector signal'),
21 22 ('tx', 'A modulating signal (Transmission pulse)'),
22 23 ('codes', 'BPSK modulating signal'),
23 24 ('windows', 'Sample window signal'),
24 25 ('sync', 'Synchronizing signal'),
25 26 ('flip', 'IPP related periodic signal'),
26 27 ('prog_pulses', 'Programmable pulse'),
27 28 ('mix', 'Mixed line'),
28 29 )
29 30
30 31
31 32 SAMPLING_REFS = (
32 33 ('none', 'No Reference'),
33 34 ('begin_baud', 'Begin of the first baud'),
34 35 ('first_baud', 'Middle of the first baud'),
35 36 ('sub_baud', 'Middle of the sub-baud')
36 37 )
37 38
38 39 DAT_CMDS = {
39 40 # Pulse Design commands
40 41 'DISABLE' : 0, # Disables pulse generation
41 42 'ENABLE' : 24, # Enables pulse generation
42 43 'DELAY_START' : 40, # Write delay status to memory
43 44 'FLIP_START' : 48, # Write flip status to memory
44 45 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
45 46 'TX_ONE' : 72, # Output '0' in line TX
46 47 'TX_ZERO' : 88, # Output '0' in line TX
47 48 'SW_ONE' : 104, # Output '0' in line SW
48 49 'SW_ZERO' : 112, # Output '1' in line SW
49 50 'RESTART': 120, # Restarts CR8 Firmware
50 51 'CONTINUE' : 253, # Function Unknown
51 52 # Commands available to new controllers
52 53 # In Pulse Design Executable, the clock divisor code is written as 12 at the start, but it should be written as code 22(below) just before the final enable.
53 54 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
54 55 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
55 56 'CLOCK_DIVIDER' : 8,
56 57 }
57 58
58 59
59 60 class RCConfiguration(Configuration):
60 61
61 62 ipp = models.FloatField(verbose_name='IPP [Km]', validators=[MinValueValidator(1), MaxValueValidator(9000)], default=300)
62 63 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(400)], default=1)
63 64 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
64 65 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
65 66 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
66 67 time_before = models.PositiveIntegerField(verbose_name='Time before [&mu;S]', default=12)
67 68 time_after = models.PositiveIntegerField(verbose_name='Time after [&mu;S]', default=1)
68 69 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
69 70 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
70 71 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
71 72 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
72 73 total_units = models.PositiveIntegerField(default=0)
73 74 mix = models.BooleanField(default=False)
74 75
75 76 class Meta:
76 77 db_table = 'rc_configurations'
77 78
78 79 def get_absolute_url_plot(self):
79 80 return reverse('url_plot_rc_pulses', args=[str(self.id)])
80 81
81 82 def get_absolute_url_import(self):
82 83 return reverse('url_import_rc_conf', args=[str(self.id)])
83 84
84 85 @property
85 86 def ipp_unit(self):
86 87
87 88 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
88 89
89 90 @property
90 91 def us2unit(self):
91 92
92 93 return self.clock_in/self.clock_divider
93 94
94 95 @property
95 96 def km2unit(self):
96 97
97 98 return 20./3*(self.clock_in/self.clock_divider)
98 99
99 100 def clone(self, **kwargs):
100 101
101 102 lines = self.get_lines()
102 103 self.pk = None
103 104 self.id = None
104 105 for attr, value in kwargs.items():
105 106 setattr(self, attr, value)
106 107 self.save()
107 108
108 109 for line in lines:
109 110 line.clone(rc_configuration=self)
110 111
111 112 return self
112 113
113 114 def get_lines(self, **kwargs):
114 115 '''
115 116 Retrieve configuration lines
116 117 '''
117 118
118 119 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
119 120
120 121
121 122 def clean_lines(self):
122 123 '''
123 124 '''
124 125
125 126 empty_line = RCLineType.objects.get(name='none')
126 127
127 128 for line in self.get_lines():
128 129 line.line_type = empty_line
129 130 line.params = '{}'
130 131 line.save()
131 132
132 133 def parms_to_dict(self):
133 134 '''
134 135 '''
135 136
136 137 ignored = ('parameters', 'type', 'polymorphic_ctype', 'configuration_ptr',
137 138 'created_date', 'programmed_date')
138 139
139 140 data = {}
140 141 for field in self._meta.fields:
141 142 if field.name in ignored:
142 143 continue
143 144 data[field.name] = '{}'.format(field.value_from_object(self))
144 145
145 146 data['device_id'] = data.pop('device')
146 147 data['lines'] = []
147 148
148 149 for line in self.get_lines():
149 150 line_data = json.loads(line.params)
150 151 if 'TX_ref' in line_data and line_data['TX_ref'] not in (0, '0'):
151 152 line_data['TX_ref'] = RCLine.objects.get(pk=line_data['TX_ref']).get_name()
152 153 if 'code' in line_data:
153 154 line_data['code'] = RCLineCode.objects.get(pk=line_data['code']).name
154 155 line_data['type'] = line.line_type.name
155 156 line_data['name'] = line.get_name()
156 157 data['lines'].append(line_data)
157 158
158 159 data['delays'] = self.get_delays()
159 160 data['pulses'] = self.get_pulses()
160 161
161 162 return data
162 163
163 164 def dict_to_parms(self, data):
164 165 '''
165 166 '''
166 167
167 168 self.name = data['name']
168 169 self.ipp = float(data['ipp'])
169 170 self.ntx = int(data['ntx'])
170 171 self.clock_in = float(data['clock_in'])
171 172 self.clock_divider = int(data['clock_divider'])
172 173 self.clock = float(data['clock'])
173 174 self.time_before = data['time_before']
174 175 self.time_after = data['time_after']
175 176 self.sync = data['sync']
176 177 self.sampling_reference = data['sampling_reference']
177 178 self.total_units = self.ipp*self.ntx*self.km2unit
178 179 self.save()
179 180 self.clean_lines()
180 181
181 182 lines = []
182 183 positions = {'tx':0, 'tr':0}
183 184
184 185 for i, line_data in enumerate(data['lines']):
185 186 name = line_data.pop('name', '')
186 187 line_type = RCLineType.objects.get(name=line_data.pop('type'))
187 188 if line_type.name=='codes':
188 189 code = RCLineCode.objects.get(name=line_data['code'])
189 190 line_data['code'] = code.pk
190 191 line = RCLine.objects.filter(rc_configuration=self, channel=i)
191 192 if line:
192 193 line = line[0]
193 194 line.line_type = line_type
194 195 line.params = json.dumps(line_data)
195 196 else:
196 197 line = RCLine(rc_configuration=self, line_type=line_type,
197 198 params=json.dumps(line_data),
198 199 channel=i)
199 200
200 201 if line_type.name=='tx':
201 202 line.position = positions['tx']
202 203 positions['tx'] += 1
203 204
204 205 if line_type.name=='tr':
205 206 line.position = positions['tr']
206 207 positions['tr'] += 1
207 208
208 209 line.save()
209 210 lines.append(line)
210 211
211 212 for line, line_data in zip(lines, data['lines']):
212 213 if 'TX_ref' in line_data:
213 214 params = json.loads(line.params)
214 215 if line_data['TX_ref'] in (0, '0'):
215 216 params['TX_ref'] = '0'
216 217 else:
217 218 params['TX_ref'] = [l.pk for l in lines if l.line_type.name=='tx' and line_data['TX_ref'] in l.get_name()][0]
218 219 line.params = json.dumps(params)
219 220 line.save()
220 221
221 222
222 223 def get_delays(self):
223 224
224 225 pulses = [line.pulses_as_points() for line in self.get_lines()]
225 226 points = [tup for tups in pulses for tup in tups]
226 227 points = set([x for tup in points for x in tup])
227 228 points = list(points)
228 229 points.sort()
229 230
230 231 if points[0]!=0:
231 232 points.insert(0, 0)
232 233
233 234 return [points[i+1]-points[i] for i in range(len(points)-1)]
234 235
235 236
236 237 def get_pulses(self, binary=True):
237 238
238 239 pulses = [line.pulses_as_points() for line in self.get_lines()]
239 240 points = [tup for tups in pulses for tup in tups]
240 241 points = set([x for tup in points for x in tup])
241 242 points = list(points)
242 243 points.sort()
243 244
244 245 line_points = [line.pulses_as_points() for line in self.get_lines()]
245 246 line_points = [[(x, x+y) for x,y in tups] for tups in line_points]
246 247 line_points = [[t for x in tups for t in x] for tups in line_points]
247 248 states = [[1 if x in tups else 0 for tups in line_points] for x in points]
248 249
249 250 if binary:
250 251 states.reverse()
251 252 states = [int(''.join([str(x) for x in flips]), 2) for flips in states]
252 253
253 254 return states[:-1]
254 255
255 256 def add_cmd(self, cmd):
256 257
257 258 if cmd in DAT_CMDS:
258 259 return (255, DAT_CMDS[cmd])
259 260
260 261 def add_data(self, value):
261 262
262 263 return (254, value-1)
263 264
264 265 def parms_to_binary(self, dat=True):
265 266 '''
266 267 Create "dat" stream to be send to CR
267 268 '''
268 269
269 270 data = bytearray()
270 271 # create header
271 272 data.extend(self.add_cmd('DISABLE'))
272 273 data.extend(self.add_cmd('CONTINUE'))
273 274 data.extend(self.add_cmd('RESTART'))
274 275
275 276 if self.control_sw:
276 277 data.extend(self.add_cmd('SW_ONE'))
277 278 else:
278 279 data.extend(self.add_cmd('SW_ZERO'))
279 280
280 281 if self.control_tx:
281 282 data.extend(self.add_cmd('TX_ONE'))
282 283 else:
283 284 data.extend(self.add_cmd('TX_ZERO'))
284 285
285 286 # write divider
286 287 data.extend(self.add_cmd('CLOCK_DIVIDER'))
287 288 data.extend(self.add_data(self.clock_divider))
288 289
289 290 # write delays
290 291 data.extend(self.add_cmd('DELAY_START'))
291 292 # first delay is always zero
292 293 data.extend(self.add_data(1))
293 294
294 295 delays = self.get_delays()
295 296
296 297 for delay in delays:
297 298 while delay>252:
298 299 data.extend(self.add_data(253))
299 300 delay -= 253
300 301 data.extend(self.add_data(int(delay)))
301 302
302 303 # write flips
303 304 data.extend(self.add_cmd('FLIP_START'))
304 305
305 306 states = self.get_pulses(binary=False)
306 307
307 308 for flips, delay in zip(states, delays):
308 309 flips.reverse()
309 310 flip = int(''.join([str(x) for x in flips]), 2)
310 311 data.extend(self.add_data(flip+1))
311 312 while delay>252:
312 313 data.extend(self.add_data(1))
313 314 delay -= 253
314 315
315 316 # write sampling period
316 317 data.extend(self.add_cmd('SAMPLING_PERIOD'))
317 318 wins = self.get_lines(line_type__name='windows')
318 319 if wins:
319 320 win_params = json.loads(wins[0].params)['params']
320 321 if win_params:
321 322 dh = int(win_params[0]['resolution']*self.km2unit)
322 323 else:
323 324 dh = 1
324 325 else:
325 326 dh = 1
326 327 data.extend(self.add_data(dh))
327 328
328 329 # write enable
329 330 data.extend(self.add_cmd('ENABLE'))
330 331
331 332 if not dat:
332 333 return data
333 334
334 335 return '\n'.join(['{}'.format(x) for x in data])
335 336
336 337
337 338 def update_from_file(self, filename):
338 339 '''
339 340 Update instance from file
340 341 '''
341 342
342 343 f = RCFile(filename)
343 344 self.dict_to_parms(f.data)
344 345 self.update_pulses()
345 346
346 347 def update_pulses(self):
347 348
348 349 for line in self.get_lines():
349 350 line.update_pulses()
350 351
351 352 def plot_pulses2(self, km=False):
352 353
353 354 import matplotlib.pyplot as plt
354 355 from bokeh.resources import CDN
355 356 from bokeh.embed import components
356 357 from bokeh.mpl import to_bokeh
357 358 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
358 359
359 360 lines = self.get_lines()
360 361
361 362 N = len(lines)
362 363 npoints = self.total_units/self.km2unit if km else self.total_units
363 364 fig = plt.figure(figsize=(12, 2+N*0.5))
364 365 ax = fig.add_subplot(111)
365 366 labels = ['IPP']
366 367
367 368 for i, line in enumerate(lines):
368 369 labels.append(line.get_name(channel=True))
369 370 l = ax.plot((0, npoints),(N-i-1, N-i-1))
370 371 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
371 372 ax.broken_barh(points, (N-i-1, 0.5),
372 373 edgecolor=l[0].get_color(), facecolor='none')
373 374
374 375 n = 0
375 376 f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
376 377 for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
377 378 if n%f==0:
378 379 ax.text(x, N, '%s' % n, size=10)
379 380 n += 1
380 381
381 382
382 383 labels.reverse()
383 384 ax.set_yticks(range(len(labels)))
384 385 ax.set_yticklabels(labels)
385 386 ax.set_xlabel = 'Units'
386 387 plot = to_bokeh(fig, use_pandas=False)
387 388 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()]
388 389 plot.toolbar_location="above"
389 390
390 391 return components(plot, CDN)
391 392
392 393 def plot_pulses(self, km=False):
393 394
394 395 from bokeh.plotting import figure
395 396 from bokeh.resources import CDN
396 397 from bokeh.embed import components
397 398 from bokeh.models import FixedTicker, PrintfTickFormatter
398 399 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
399 400 from bokeh.models.sources import ColumnDataSource
400 401
401 402 lines = self.get_lines().reverse()
402 403
403 404 N = len(lines)
404 405 npoints = self.total_units/self.km2unit if km else self.total_units
405 406 ipp = self.ipp if km else self.ipp*self.km2unit
406 407
407 408 hover = HoverTool(tooltips=[("Line", "@name"),
408 409 ("IPP", "@ipp"),
409 410 ("X", "@left")])
410 411
411 412 tools = [PanTool(dimensions=['width']),
412 413 WheelZoomTool(dimensions=['width']),
413 414 hover, SaveTool()]
414 415
415 416 plot = figure(width=1000,
416 417 height=40+N*50,
417 418 y_range = (0, N),
418 419 tools=tools,
419 420 toolbar_location='above',
420 421 toolbar_sticky=False,)
421 422
422 423 plot.xaxis.axis_label = 'Km' if km else 'Units'
423 424 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
424 425 plot.yaxis.axis_label = 'Pulses'
425 426 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
426 427 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
427 428
428 429 for i, line in enumerate(lines):
429 430
430 431 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
431 432
432 433 source = ColumnDataSource(data = dict(
433 434 bottom = [i for tup in points],
434 435 top = [i+0.5 for tup in points],
435 436 left = [tup[0] for tup in points],
436 437 right = [tup[1] for tup in points],
437 438 ipp = [int(tup[0]/ipp) for tup in points],
438 439 name = [line.get_name() for tup in points]
439 440 ))
440 441
441 442 plot.quad(
442 443 bottom = 'bottom',
443 444 top = 'top',
444 445 left = 'left',
445 446 right = 'right',
446 447 source = source,
447 448 fill_alpha = 0,
448 449 #line_color = 'blue',
449 450 )
450 451
451 452 plot.line([0, npoints], [i, i])#, color='blue')
452 453
453 454 return components(plot, CDN)
454 455
455 456 def status_device(self):
456 457
457 458 try:
458 req = requests.get(self.device.url)
459 req = requests.get(self.device.url('status'))
459 460 payload = req.json()
460 461 if payload['status']=='ok':
461 self.device.status = 3
462 else:
463 462 self.device.status = 1
464 except:
463 else:
464 self.device.status = 0
465 except Exception as e:
465 466 self.device.status = 0
467 self.message = str(e)
468 return False
466 469
467 470 self.device.save()
468
469 return self.device.status
471 return True
470 472
471 473
472 474 def reset_device(self):
473 475
474 payload = bytearray()
475 payload.extend(self.add_cmd('RESTART'))
476 data = b64encode(payload)
477 req = requests.put(self.device.url, data)
478
479 if data==req.text.encode('utf8'):
480 return 1
476 try:
477 req = requests.post(self.device.url('reset'))
478 if 'ok' in req.text:
479 self.message = 'RC restarted'
481 480 else:
482 return 0
481 self.message = 'RC restart not ok'
482 self.device.status = 4
483 self.device.save()
484 except Exception as e:
485 self.message = str(e)
486 return False
483 487
484 def stop_device(self):
488 return True
485 489
486 payload = bytearray()
487 payload.extend(self.add_cmd('DISABLE'))
488 data = b64encode(payload)
489 req = requests.put(self.device.url, data)
490 def stop_device(self):
490 491
491 if data==req.text.encode('utf8'):
492 return 1
492 try:
493 req = requests.post(self.device.url('stop'))
494 if 'ok' in req.text:
495 self.device.status = 2
496 self.device.save()
497 self.message = 'RC stopped'
493 498 else:
494 return 0
499 self.message = 'RC stop not ok'
500 self.device.status = 4
501 self.device.save()
502 return False
503 except Exception as e:
504 self.message = str(e)
505 return False
495 506
496 def start_device(self):
507 return True
497 508
498 payload = bytearray()
499 payload.extend(self.add_cmd('ENABLE'))
500 data = b64encode(payload)
501 req = requests.put(self.device.url, data)
509 def start_device(self):
502 510
503 if data==req.text.encode('utf8'):
504 return 1
511 try:
512 req = requests.post(self.device.url('start'))
513 if 'ok' in req.text:
514 self.device.status = 3
515 self.device.save()
516 self.message = 'RC running'
505 517 else:
506 return 0
518 self.message = 'RC start not ok'
519 return False
520 except Exception as e:
521 self.message = str(e)
522 return False
523
524 return True
507 525
508 526 def write_device(self):
509 527
510 data = b64encode(self.parms_to_binary(dat=False))
511 req = requests.put(self.device.url, data)
512 print(req.text)
513 if data==req.text.encode('utf8'):
514 return 1
528 values = zip(self.get_pulses(),
529 [x-1 for x in self.get_delays()])
530 payload = ''
531
532 for tup in values:
533 vals = pack('<HH', *tup)
534 payload += '\x05'+vals[0]+'\x04'+vals[1]+'\x05'+vals[2]+'\x05'+vals[3]
535
536 try:
537 ## reset
538 if not self.reset_device():
539 return False
540 ## stop
541 if not self.stop_device():
542 return False
543 ## write clock divider
544 req = requests.post(self.device.url('divisor'),
545 {'divisor': '{:d}'.format(self.clock_divider-1)})
546 if 'ok' not in req.text:
547 self.message = 'Error configuring RC clock divider'
548 return False
549 ## write pulses & delays
550 req = requests.post(self.device.url('write'), data=b64encode(payload))
551 if 'ok' in req.text:
552 self.device.status = 2
553 self.device.save()
554 self.message = 'RC configured'
515 555 else:
516 return 0
556 self.device.status = 4
557 self.device.save()
558 self.message = 'RC write not ok'
559 return False
560
561 except Exception as e:
562 self.message = str(e)
563 return False
564
565 return True
517 566
518 567
519 568 class RCLineCode(models.Model):
520 569
521 570 name = models.CharField(max_length=40)
522 571 bits_per_code = models.PositiveIntegerField(default=0)
523 572 number_of_codes = models.PositiveIntegerField(default=0)
524 573 codes = models.TextField(blank=True, null=True)
525 574
526 575 class Meta:
527 576 db_table = 'rc_line_codes'
528 577 ordering = ('name',)
529 578
530 579 def __str__(self):
531 580 return u'%s' % self.name
532 581
533 582
534 583 class RCLineType(models.Model):
535 584
536 585 name = models.CharField(choices=LINE_TYPES, max_length=40)
537 586 description = models.TextField(blank=True, null=True)
538 587 params = models.TextField(default='[]')
539 588
540 589 class Meta:
541 590 db_table = 'rc_line_types'
542 591
543 592 def __str__(self):
544 593 return u'%s - %s' % (self.name.upper(), self.get_name_display())
545 594
546 595
547 596 class RCLine(models.Model):
548 597
549 598 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
550 599 line_type = models.ForeignKey(RCLineType)
551 600 channel = models.PositiveIntegerField(default=0)
552 601 position = models.PositiveIntegerField(default=0)
553 602 params = models.TextField(default='{}')
554 603 pulses = models.TextField(default='')
555 604
556 605 class Meta:
557 606 db_table = 'rc_lines'
558 607 ordering = ['channel']
559 608
560 609 def __str__(self):
561 610 if self.rc_configuration:
562 611 return u'%s - %s' % (self.rc_configuration, self.get_name())
563 612
564 613 def clone(self, **kwargs):
565 614
566 615 self.pk = None
567 616
568 617 for attr, value in kwargs.items():
569 618 setattr(self, attr, value)
570 619
571 620 self.save()
572 621
573 622 return self
574 623
575 624 def get_name(self, channel=False):
576 625
577 626 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
578 627 s = ''
579 628
580 629 if self.line_type.name in ('tx',):
581 630 s = chars[self.position]
582 631 elif self.line_type.name in ('codes', 'windows', 'tr'):
583 632 if 'TX_ref' in json.loads(self.params):
584 633 pk = json.loads(self.params)['TX_ref']
585 634 if pk in (0, '0'):
586 635 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
587 636 else:
588 637 ref = RCLine.objects.get(pk=pk)
589 638 s = chars[ref.position]
590 639 s = '({})'.format(s)
591 640
592 641 s = '{}{}'.format(self.line_type.name.upper(), s)
593 642
594 643 if channel:
595 644 return '{} {}'.format(s, self.channel)
596 645 else:
597 646 return s
598 647
599 648 def get_lines(self, **kwargs):
600 649
601 650 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
602 651
603 652 def pulses_as_array(self):
604 653
605 654 y = np.zeros(self.rc_configuration.total_units)
606 655
607 656 for tup in ast.literal_eval(self.pulses):
608 657 y[tup[0]:tup[1]] = 1
609 658
610 659 return y.astype(np.int8)
611 660
612 661 def pulses_as_points(self, km=False):
613 662
614 663 if km:
615 664 unit2km = 1/self.rc_configuration.km2unit
616 665 return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
617 666 else:
618 667 return ast.literal_eval(self.pulses)
619 668
620 669 def get_win_ref(self, params, tx_id, km2unit):
621 670
622 671 ref = self.rc_configuration.sampling_reference
623 672 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
624 673
625 674 if codes:
626 675 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
627 676 else:
628 677 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
629 678
630 679 if ref=='first_baud':
631 680 return int(1 + (tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit)
632 681 elif ref=='sub_baud':
633 682 return int(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
634 683 else:
635 684 return 0
636 685
637 686 def update_pulses(self):
638 687 '''
639 688 Update pulses field
640 689 '''
641 690
642 691 km2unit = self.rc_configuration.km2unit
643 692 us2unit = self.rc_configuration.us2unit
644 693 ipp = self.rc_configuration.ipp
645 694 ntx = int(self.rc_configuration.ntx)
646 695 ipp_u = int(ipp*km2unit)
647 696 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
648 697 y = []
649 698
650 699 if self.line_type.name=='tr':
651 700 tr_params = json.loads(self.params)
652 701
653 702 if tr_params['TX_ref'] in ('0', 0):
654 703 txs = self.get_lines(line_type__name='tx')
655 704 else:
656 705 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
657 706
658 707 for tx in txs:
659 708 params = json.loads(tx.params)
660 709
661 710 if float(params['pulse_width'])==0:
662 711 continue
663 712 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
664 713 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
665 714 before = 0
666 715 after = int(self.rc_configuration.time_after*us2unit)
667 716
668 717 y_tx = self.points(ntx, ipp_u, width,
669 718 delay=delays,
670 719 before=before,
671 720 after=after,
672 721 sync=self.rc_configuration.sync)
673 722
674 723 ranges = params['range'].split(',')
675 724
676 725 if len(ranges)>0 and ranges[0]!='0':
677 726 y_tx = self.mask_ranges(y_tx, ranges)
678 727
679 728 tr_ranges = tr_params['range'].split(',')
680 729
681 730 if len(tr_ranges)>0 and tr_ranges[0]!='0':
682 731 y_tx = self.mask_ranges(y_tx, tr_ranges)
683 732
684 733 y.extend(y_tx)
685 734
686 735 self.pulses = str(y)
687 736 y = self.array_to_points(self.pulses_as_array())
688 737
689 738 elif self.line_type.name=='tx':
690 739 params = json.loads(self.params)
691 740 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
692 741 width = float(params['pulse_width'])*km2unit
693 742
694 743 if width>0:
695 744 before = int(self.rc_configuration.time_before*us2unit)
696 745 after = 0
697 746
698 747 y = self.points(ntx, ipp_u, width,
699 748 delay=delays,
700 749 before=before,
701 750 after=after,
702 751 sync=self.rc_configuration.sync)
703 752
704 753 ranges = params['range'].split(',')
705 754
706 755 if len(ranges)>0 and ranges[0]!='0':
707 756 y = self.mask_ranges(y, ranges)
708 757
709 758 elif self.line_type.name=='flip':
710 759 n = float(json.loads(self.params)['number_of_flips'])
711 760 width = n*ipp*km2unit
712 761 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
713 762
714 763 elif self.line_type.name=='codes':
715 764 params = json.loads(self.params)
716 765 tx = RCLine.objects.get(pk=params['TX_ref'])
717 766 tx_params = json.loads(tx.params)
718 767 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
719 768 f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
720 769 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
721 770 codes = [self.array_to_points(code) for code in codes]
722 771 n = len(codes)
723 772
724 773 for i, tup in enumerate(tx.pulses_as_points()):
725 774 code = codes[i%n]
726 775 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
727 776
728 777 ranges = tx_params['range'].split(',')
729 778 if len(ranges)>0 and ranges[0]!='0':
730 779 y = self.mask_ranges(y, ranges)
731 780
732 781 elif self.line_type.name=='sync':
733 782 params = json.loads(self.params)
734 783 n = ipp_u*ntx
735 784 if params['invert'] in ('1', 1):
736 785 y = [(n-1, n)]
737 786 else:
738 787 y = [(0, 1)]
739 788
740 789 elif self.line_type.name=='prog_pulses':
741 790 params = json.loads(self.params)
742 791 if int(params['periodic'])==0:
743 792 nntx = 1
744 793 nipp = ipp_u*ntx
745 794 else:
746 795 nntx = ntx
747 796 nipp = ipp_u
748 797
749 798 if 'params' in params and len(params['params'])>0:
750 799 for p in params['params']:
751 800 y_pp = self.points(nntx, nipp,
752 801 p['end']-p['begin'],
753 802 before=p['begin'])
754 803
755 804 y.extend(y_pp)
756 805
757 806 elif self.line_type.name=='windows':
758 807 params = json.loads(self.params)
759 808
760 809 if 'params' in params and len(params['params'])>0:
761 810 tr_params = json.loads(self.get_lines(line_type__name='tr')[0].params)
762 811 tr_ranges = tr_params['range'].split(',')
763 812 for p in params['params']:
764 813 y_win = self.points(ntx, ipp_u,
765 814 p['resolution']*p['number_of_samples']*km2unit,
766 815 before=int(self.rc_configuration.time_before*us2unit)+self.get_win_ref(p, params['TX_ref'], km2unit),
767 816 sync=self.rc_configuration.sync)
768 817
769 818 if len(tr_ranges)>0 and tr_ranges[0]!='0':
770 819 y_win = self.mask_ranges(y_win, tr_ranges)
771 820
772 821 y.extend(y_win)
773 822
774 823 elif self.line_type.name=='mix':
775 824 values = self.rc_configuration.parameters.split('-')
776 825 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
777 826 modes = [value.split('|')[1] for value in values]
778 827 ops = [value.split('|')[2] for value in values]
779 828 delays = [value.split('|')[3] for value in values]
780 829 masks = [value.split('|')[4] for value in values]
781 830 mask = list('{:8b}'.format(int(masks[0])))
782 831 mask.reverse()
783 832 if mask[self.channel] in ('0', '', ' '):
784 833 y = np.zeros(confs[0].total_units, dtype=np.int8)
785 834 else:
786 835 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
787 836
788 837 for i in range(1, len(values)):
789 838 mask = list('{:8b}'.format(int(masks[i])))
790 839 mask.reverse()
791 840
792 841 if mask[self.channel] in ('0', '', ' '):
793 842 continue
794 843 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
795 844 delay = float(delays[i])*km2unit
796 845
797 846 if modes[i]=='P':
798 847 if delay>0:
799 848 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
800 849 y_temp = np.empty_like(Y)
801 850 y_temp[:delay] = 0
802 851 y_temp[delay:] = Y[:-delay]
803 852 elif delay+len(Y)>len(y):
804 853 y_new = np.zeros(delay+len(Y), dtype=np.int8)
805 854 y_new[:len(y)] = y
806 855 y = y_new
807 856 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
808 857 y_temp[-len(Y):] = Y
809 858 elif delay+len(Y)==len(y):
810 859 y_temp = np.zeros(delay+len(Y))
811 860 y_temp[-len(Y):] = Y
812 861 elif delay+len(Y)<len(y):
813 862 y_temp = np.zeros(len(y), dtype=np.int8)
814 863 y_temp[delay:delay+len(Y)] = Y
815 864
816 865 if ops[i]=='OR':
817 866 y = y | y_temp
818 867 elif ops[i]=='XOR':
819 868 y = y ^ y_temp
820 869 elif ops[i]=='AND':
821 870 y = y & y_temp
822 871 elif ops[i]=='NAND':
823 872 y = y & ~y_temp
824 873 else:
825 874 y = np.concatenate([y, Y])
826 875
827 876 total = len(y)
828 877 y = self.array_to_points(y)
829 878
830 879 else:
831 880 y = []
832 881
833 882 if self.rc_configuration.total_units != total:
834 883 self.rc_configuration.total_units = total
835 884 self.rc_configuration.save()
836 885
837 886 self.pulses = str(y)
838 887 self.save()
839 888
840 889 @staticmethod
841 890 def array_to_points(X):
842 891
843 892 d = X[1:]-X[:-1]
844 893
845 894 up = np.where(d==1)[0]
846 895 if X[0]==1:
847 896 up = np.concatenate((np.array([-1]), up))
848 897 up += 1
849 898
850 899 dw = np.where(d==-1)[0]
851 900 if X[-1]==1:
852 901 dw = np.concatenate((dw, np.array([len(X)-1])))
853 902 dw += 1
854 903
855 904 return [(tup[0], tup[1]) for tup in zip(up, dw)]
856 905
857 906 @staticmethod
858 907 def mask_ranges(Y, ranges):
859 908
860 909 y = [(0, 0) for __ in Y]
861 910
862 911 for index in ranges:
863 912 if '-' in index:
864 913 args = [int(a) for a in index.split('-')]
865 914 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
866 915 else:
867 916 y[int(index-1)] = Y[int(index-1)]
868 917
869 918 return y
870 919
871 920 @staticmethod
872 921 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
873 922
874 923 delays = len(delay)
875 924
876 Y = [(ipp*x+before+delay[x%delays], ipp*x+width+before+delay[x%delays]+after) for x in range(ntx)]
925 Y = [(int(ipp*x+before+delay[x%delays]+sync), int(ipp*x+width+before+delay[x%delays]+after+sync)) for x in range(ntx)]
877 926
878 927 return Y
@@ -1,23 +1,23
1 1 from django.conf.urls import url
2 2
3 3 from apps.rc import views
4 4
5 5 urlpatterns = (
6 6 url(r'^(?P<conf_id>-?\d+)/$', views.conf, name='url_rc_conf'),
7 7 url(r'^(?P<conf_id>-?\d+)/import/$', views.import_file, name='url_import_rc_conf'),
8 8 url(r'^(?P<conf_id>-?\d+)/edit/$', views.conf_edit, name='url_edit_rc_conf'),
9 9 url(r'^(?P<conf_id>-?\d+)/plot/$', views.plot_pulses, name='url_plot_rc_pulses'),
10 url(r'^(?P<conf_id>-?\d+)/plot2/$', views.plot_pulses2, name='url_plot_rc_pulses'),
10 url(r'^(?P<conf_id>-?\d+)/plot2/$', views.plot_pulses2, name='url_plot_rc_pulses2'),
11 11 #url(r'^(?P<id_conf>-?\d+)/write/$', 'apps.main.views.dev_conf_write', name='url_write_rc_conf'),
12 12 #url(r'^(?P<id_conf>-?\d+)/read/$', 'apps.main.views.dev_conf_read', name='url_read_rc_conf'),
13 13
14 14 url(r'^(?P<conf_id>-?\d+)/add_line/$', views.add_line, name='url_add_rc_line'),
15 15 url(r'^(?P<conf_id>-?\d+)/add_line/(?P<line_type_id>-?\d+)/$', views.add_line, name='url_add_rc_line'),
16 16 url(r'^(?P<conf_id>-?\d+)/add_line/(?P<line_type_id>-?\d+)/code/(?P<code_id>-?\d+)/$', views.add_line, name='url_add_rc_line_code'),
17 17 url(r'^(?P<conf_id>-?\d+)/update_position/$', views.update_lines_position, name='url_update_rc_lines_position'),
18 18 url(r'^(?P<conf_id>-?\d+)/line/(?P<line_id>-?\d+)/delete/$', views.remove_line, name='url_remove_rc_line'),
19 19 url(r'^(?P<conf_id>-?\d+)/line/(?P<line_id>-?\d+)/add_subline/$', views.add_subline, name='url_add_rc_subline'),
20 20 url(r'^(?P<conf_id>-?\d+)/line/(?P<line_id>-?\d+)/codes/$', views.edit_codes, name='url_edit_rc_codes'),
21 21 url(r'^(?P<conf_id>-?\d+)/line/(?P<line_id>-?\d+)/codes/(?P<code_id>-?\d+)/$', views.edit_codes, name='url_edit_rc_codes'),
22 22 url(r'^(?P<conf_id>-?\d+)/line/(?P<line_id>-?\d+)/subline/(?P<subline_id>-?\d+)/delete/$', views.remove_subline, name='url_remove_rc_subline'),
23 23 )
@@ -1,134 +1,98
1 1 '''
2 Created on Dec 2, 2014
2 API to configure new Radar controller
3 3
4 @author: Miguel Urco
5
6 eth_device decorator is used to implement an api to ethernet devices.
7 When eth_device decorator is used it adds two parameters to any function (ip and port)
8
9 #Definition
10
11 @eth_device
12 def enable_rf()
13 cmd = "xxxxx"
14 payload = "xxxxxx"
15
16 return cmd, payload
17
18 #How to call this function:
19 answer = enable_rf(ip, port)
20 4
5 @author: Juan C. Espinoza
21 6 '''
22 7
23 from devices.jro_device import eth_device, IdClass
24
25 ID_CLASS = IdClass["rc"]
26
27 CMD_RESET =0X01
28 CMD_ENABLE =0X02
29 CMD_CHANGEIP =0X03
30 CMD_STATUS =0X04
31 CMD_DISABLE =0X02
32 CMD_ECHO =0XFE
8 import os
9 import json
10 import requests
11 from struct import pack
12 from base64 import b64encode
33 13
34 RC_CMD_RESET =0X10
35 RC_CMD_WRITE =0x50
36 RC_CMD_READ =0x8000
14 class RCApi(object):
37 15
38 @eth_device(ID_CLASS)
39 def reset():
16 def __init__(self, ip, port=80):
40 17
41 cmd = CMD_RESET
42 payload = ""
18 self.url = 'http://{}:{}/'.format(ip, port)
19 self.params = None
43 20
44 return cmd, payload
21 def load(self, filename):
45 22
46 @eth_device(ID_CLASS)
47 def change_ip(ip, mask="255.255.255.0", gateway="0.0.0.0"):
23 self.params = json.load(open(filename))
24 print 'RC Configuration: {}'.format(self.params['name'])
48 25
49 cmd = CMD_CHANGEIP
50 payload = ip + '/' + mask + '/' + gateway
26 def status(self):
51 27
52 return cmd, payload
28 url = os.path.join(self.url, 'status')
29 req = requests.get(url)
30 return req.json()
53 31
54 @eth_device(ID_CLASS)
55 def status():
32 def read(self):
56 33
57 cmd = CMD_STATUS
58 payload = ""
34 url = os.path.join(self.url, 'read')
35 req = requests.get(url)
36 return req.json()
59 37
60 return cmd, payload
38 def stop(self):
61 39
62 @eth_device(ID_CLASS)
63 def echo():
40 url = os.path.join(self.url, 'stop')
41 req = requests.post(url)
42 return req.json()
64 43
65 cmd = CMD_ECHO
66 payload = ""
44 def reset(self):
67 45
68 return cmd, payload
46 url = os.path.join(self.url, 'reset')
47 req = requests.post(url)
48 return req.json()
69 49
70 @eth_device(ID_CLASS)
71 def read_all_device():
50 def start(self):
72 51
73 payload = ""
52 url = os.path.join(self.url, 'start')
53 req = requests.post(url)
54 return req.json()
74 55
75 return CR_CMD_READ, payload
56 def write(self):
76 57
77 @eth_device(ID_CLASS)
78 def write_all_device(payload):
58 url_write = os.path.join(self.url, 'write')
59 url_divider = os.path.join(self.url, 'divisor')
79 60
80 return CR_CMD_WRITE, payload
61 values = zip(self.params['pulses'],
62 [x-1 for x in self.params['delays']])
63 payload = ''
81 64
82 def read_config(ip, port):
83 """
84 Output:
85 parms : Dictionary with keys
65 for tup in values:
66 vals = pack('<HH', *tup)
67 payload += '\x05'+vals[0]+'\x04'+vals[1]+'\x05'+vals[2]+'\x04'+vals[3]
86 68
87 """
88 payload = read_all_device(ip, port)
69 req = requests.post(url_divider,
70 data={'divisor':int(self.params['clock_divider'])-1})
89 71
90 return data.rc_str_to_dict(payload)
72 if 'ok' not in req.text:
73 print 'Error sending divider'
74 return False
91 75
92 def write_config(ip, port, parms):
93 """
94 Input:
95 ip :
96 port :
97 parms : Dictionary with keys
76 req = requests.post(url_write,
77 data=b64encode(payload))
78 return req.json()
98 79
99 """
100
101 payload = data.dict_to_rc_str(parms)
102
103 answer = write_all_device(ip, port, payload)
104
105 return answer
106
107 def __get_low_byte(valor):
108
109 return ord(valor & 0x00FF)
80 if __name__ == '__main__':
110 81
111 def __get_high_byte(valor):
82 ip = '10.10.10.100'
83 filename = '/home/jespinoza/Downloads/rc_150EEJ.json'
112 84
113 return ord((valor & 0xFF00) >> 8)
85 rc = RCApi(ip)
86 rc.load(filename)
114 87
115 @eth_device(ID_CLASS)
116 def write_ram_memory(vector_valores, vector_tiempos):
88 print rc.status()
89 print rc.reset()
90 print rc.stop()
91 print rc.write()
92 print rc.start()
117 93
118 l1 = len(vector_valores)
119 l2 = len(vector_tiempos)
120 94
121 cad = ""
122 95
123 for i in range(l1):
124 cad += ord(84) + __get_low_byte(vector_valores[i]) + ord(85) + __get_high_byte(vector_valores[i]) + \
125 ord(84) + __get_low_byte(vector_tiempos[i]) + ord(85) + __get_high_byte(vector_tiempos[i])
126 96
127 return RC_CMD_WRITE, cad
128 97
129 if __name__ == '__main__':
130 ip = "10.10.20.150"
131 port = 2000
132 98
133 print(status(ip, port))
134 print(read_config(ip, port))
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now