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