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