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