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