##// END OF EJS Templates
experiment menu edition
amorales -
r358:7dca11c69628
parent child
Show More
@@ -0,0 +1,4
1 On branch master
2 Your branch is up to date with 'origin/master'.
3
4 nothing to commit, working tree clean
@@ -1,177 +1,177
1 1 from django import forms
2 2 from django.utils.safestring import mark_safe
3 3 from apps.main.models import Device, Experiment, Campaign, Location, Configuration
4 4 from django.template.defaultfilters import default
5 5
6 6 FILE_FORMAT = (
7 7 ('json', 'json'),
8 8 )
9 9
10 10 def add_empty_choice(choices, pos=0, label='-----'):
11 11 if len(choices)>0:
12 12 choices = list(choices)
13 13 choices.insert(0, (0, label))
14 14 return choices
15 15 else:
16 16 return [(0, label)]
17 17
18 18 class DatepickerWidget(forms.widgets.TextInput):
19 19 def render(self, name, value, attrs=None, renderer=None):
20 20 input_html = super(DatepickerWidget, self).render(name, value, attrs)
21 21
22 22 html = '<div class="input-group date">'+input_html+'<span class="input-group-addon"><i class="far fa-calendar-alt"></i></span></div>'
23 23 return mark_safe(html)
24 24
25 25 class DateRangepickerWidget(forms.widgets.TextInput):
26 26 def render(self, name, value, attrs=None, renderer=None):
27 27 start = attrs['start_date']
28 28 end = attrs['end_date']
29 29 html = '''<div class="col-md-6 input-group date" style="float:inherit">
30 30 <input class="form-control" id="id_start_date" name="start_date" placeholder="Start" title="" type="text" value="{}">
31 31 <span class="input-group-addon"><i class="far fa-calendar-alt"></i></span>
32 32 </div>
33 33 <div class="col-md-6 input-group date" style="float:inherit">
34 34 <input class="form-control" id="id_end_date" name="end_date" placeholder="End" title="" type="text" value="{}">
35 35 <span class="input-group-addon"><i class="far fa-calendar-alt"></i></span>
36 36 </div>'''.format(start, end)
37 37 return mark_safe(html)
38 38
39 39 class TimepickerWidget(forms.widgets.TextInput):
40 40 def render(self, name, value, attrs=None, renderer=None):
41 41 input_html = super(TimepickerWidget, self).render(name, value, attrs)
42 42
43 43 html = '<div class="input-group time">'+input_html+'<span class="input-group-addon"><i class="far fa-clock"></i></span></div>'
44 44 return mark_safe(html)
45 45
46 46 class CampaignForm(forms.ModelForm):
47 47
48 48 experiments = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(),
49 49 queryset=Experiment.objects.filter(template=True),
50 50 required=False)
51 51
52 52 def __init__(self, *args, **kwargs):
53 53 super(CampaignForm, self).__init__(*args, **kwargs)
54 54 self.fields['start_date'].widget = DatepickerWidget(self.fields['start_date'].widget.attrs)
55 55 self.fields['end_date'].widget = DatepickerWidget(self.fields['end_date'].widget.attrs)
56 56 self.fields['description'].widget.attrs = {'rows': 2}
57 57
58 58 if self.instance.pk:
59 59 self.fields['experiments'].queryset |= self.instance.experiments.all()
60 60
61 61 class Meta:
62 62 model = Campaign
63 63 exclude = ['author']
64 64
65 65
66 66 class ExperimentForm(forms.ModelForm):
67 67
68 68 def __init__(self, *args, **kwargs):
69 69 super(ExperimentForm, self).__init__(*args, **kwargs)
70 self.fields['start_time'].widget = TimepickerWidget(self.fields['start_time'].widget.attrs)
71 self.fields['end_time'].widget = TimepickerWidget(self.fields['end_time'].widget.attrs)
70 #self.fields['start_time'].widget = TimepickerWidget(self.fields['start_time'].widget.attrs)
71 #self.fields['end_time'].widget = TimepickerWidget(self.fields['end_time'].widget.attrs)
72 72
73 73 def save(self, *args, **kwargs):
74 74 exp = super(ExperimentForm, self).save(*args, **kwargs)
75 75 exp.name = exp.name.replace(' ', '')
76 76 exp.save()
77 77 return exp
78 78
79 79 class Meta:
80 80 model = Experiment
81 81 exclude = ['task', 'status', 'author', 'hash']
82 82
83 83 class LocationForm(forms.ModelForm):
84 84 class Meta:
85 85 model = Location
86 86 exclude = ['']
87 87
88 88 class DeviceForm(forms.ModelForm):
89 89 class Meta:
90 90 model = Device
91 91 exclude = ['status']
92 92
93 93 class ConfigurationForm(forms.ModelForm):
94 94
95 95 def __init__(self, *args, **kwargs):
96 96 super(ConfigurationForm, self).__init__(*args, **kwargs)
97 97
98 98 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
99 99 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
100 100
101 101 class Meta:
102 102 model = Configuration
103 103 exclude = ['type', 'created_date', 'programmed_date', 'parameters', 'author', 'hash']
104 104
105 105 class UploadFileForm(forms.Form):
106 106
107 107 file = forms.FileField()
108 108
109 109 class DownloadFileForm(forms.Form):
110 110
111 111 format = forms.ChoiceField(choices= ((0, 'json'),) )
112 112
113 113 def __init__(self, device_type, *args, **kwargs):
114 114
115 115 super(DownloadFileForm, self).__init__(*args, **kwargs)
116 116
117 117 self.fields['format'].choices = FILE_FORMAT
118 118
119 119 class OperationForm(forms.Form):
120 120
121 121 campaign = forms.ChoiceField(label="Campaign")
122 122
123 123 def __init__(self, *args, **kwargs):
124 124
125 125 campaigns = kwargs.pop('campaigns')
126 126 super(OperationForm, self).__init__(*args, **kwargs)
127 127 self.fields['campaign'].label = 'Current Campaigns'
128 128 self.fields['campaign'].choices = add_empty_choice(campaigns.values_list('id', 'name'))
129 129
130 130
131 131 class OperationSearchForm(forms.Form):
132 132 # -----ALL Campaigns------
133 133 campaign = forms.ChoiceField(label="Campaign")
134 134
135 135 def __init__(self, *args, **kwargs):
136 136 super(OperationSearchForm, self).__init__(*args, **kwargs)
137 137 self.fields['campaign'].choices=Campaign.objects.all().order_by('-start_date').values_list('id', 'name')
138 138
139 139
140 140 class NewForm(forms.Form):
141 141
142 142 create_from = forms.ChoiceField(choices=((0, '-----'),
143 143 (1, 'Empty (blank)'),
144 144 (2, 'Template')))
145 145 choose_template = forms.ChoiceField()
146 146
147 147 def __init__(self, *args, **kwargs):
148 148
149 149 template_choices = kwargs.pop('template_choices', [])
150 150 super(NewForm, self).__init__(*args, **kwargs)
151 151 self.fields['choose_template'].choices = add_empty_choice(template_choices)
152 152
153 153
154 154 class FilterForm(forms.Form):
155 155
156 156 def __init__(self, *args, **kwargs):
157 157 extra_fields = kwargs.pop('extra_fields', [])
158 158 super(FilterForm, self).__init__(*args, **kwargs)
159 159
160 160 for field in extra_fields:
161 161 if 'range_date' in field:
162 162 self.fields[field] = forms.CharField(required=False)
163 163 self.fields[field].widget = DateRangepickerWidget()
164 164 if 'initial' in kwargs:
165 165 self.fields[field].widget.attrs = {'start_date':kwargs['initial'].get('start_date', ''),
166 166 'end_date':kwargs['initial'].get('end_date', '')}
167 167 elif field in ('template', 'historical') or 'my ' in field:
168 168 self.fields[field] = forms.BooleanField(required=False)
169 169 else:
170 170 self.fields[field] = forms.CharField(required=False)
171 171
172 172 class ChangeIpForm(forms.Form):
173 173
174 174 ip_address = forms.GenericIPAddressField()
175 175 mask = forms.GenericIPAddressField(initial='255.255.255.0')
176 176 gateway = forms.GenericIPAddressField(initial='0.0.0.0')
177 177 dns = forms.GenericIPAddressField(initial='0.0.0.0')
@@ -1,733 +1,733
1 1
2 2 import os
3 3 import json
4 4 import requests
5 5 import time
6 6 from datetime import datetime
7 7
8 8 try:
9 9 from polymorphic.models import PolymorphicModel
10 10 except:
11 11 from polymorphic import PolymorphicModel
12 12
13 13 from django.template.base import kwarg_re
14 14 from django.db import models
15 15 from django.urls import reverse
16 16 from django.core.validators import MinValueValidator, MaxValueValidator
17 17 from django.shortcuts import get_object_or_404
18 18 from django.contrib.auth.models import User
19 19 from django.db.models.signals import post_save
20 20 from django.dispatch import receiver
21 21
22 22 from apps.main.utils import Params
23 23
24
25 24 DEV_PORTS = {
26 25 'pedestal' : 80,
27 26 'pedestal_dev' : 80,
28 27 'generator' : 80,
29 28 'usrp_rx' : 2000,
30 29 'usrp_tx' : 2000,
31 30 }
32 31
33 32 RADAR_STATES = (
34 33 (0, 'No connected'),
35 34 (1, 'Connected'),
36 35 (2, 'Configured'),
37 36 (3, 'Running'),
38 37 (4, 'Scheduled'),
39 38 )
40 39
41 40 EXPERIMENT_TYPE = (
42 41 (0, 'RAW_DATA'),
43 42 (1, 'PDATA'),
44 43 )
45 44
46 45 DECODE_TYPE = (
47 46 (0, 'None'),
48 47 (1, 'TimeDomain'),
49 48 (2, 'FreqDomain'),
50 49 (3, 'InvFreqDomain'),
51 50 )
52 51
53 52 DEV_STATES = (
54 53 (0, 'Unknown'),
55 54 (1, 'Connected'),
56 55 (2, 'Configured'),
57 56 (3, 'Running'),
58 57 (4, 'Offline'),
59 58 )
60 59
61 60 DEV_TYPES = (
62 61 ('', 'Select a device type'),
63 62 ('pedestal', 'Pedestal Controller'),
64 63 ('pedestal_dev', 'Pedestal Controller Dev Mode'),
65 64 ('generator', 'Pulse Generator'),
66 65 ('usrp_rx', 'Universal Software Radio Peripheral Rx'),
67 66 ('usrp_tx', 'Universal Software Radio Peripheral Tx'),
68 67 )
69 68
70 69 EXP_STATES = (
71 70 (0,'Error'), #RED
72 71 (1,'Cancelled'), #YELLOW
73 72 (2,'Running'), #GREEN
74 73 (3,'Scheduled'), #BLUE
75 74 (4,'Unknown'), #WHITE
76 75 )
77 76
78 77 CONF_TYPES = (
79 78 (0, 'Active'),
80 79 (1, 'Historical'),
81 80 )
82 81
83 82 class Profile(models.Model):
84 83 user = models.OneToOneField(User, on_delete=models.CASCADE)
85 84 theme = models.CharField(max_length=30, default='spacelab')
86 85
87 86
88 87 @receiver(post_save, sender=User)
89 88 def create_user_profile(sender, instance, created, **kwargs):
90 89 if created:
91 90 Profile.objects.create(user=instance)
92 91
93 92 @receiver(post_save, sender=User)
94 93 def save_user_profile(sender, instance, **kwargs):
95 94 instance.profile.save()
96 95
97 96
98 97 class Location(models.Model):
99 98
100 99 name = models.CharField(max_length = 30)
101 100 description = models.TextField(blank=True, null=True)
102 101
103 102 class Meta:
104 103 db_table = 'db_location'
105 104
106 105 def __str__(self):
107 106 return u'%s' % self.name
108 107
109 108 def get_absolute_url(self):
110 109 return reverse('url_location', args=[str(self.id)])
111 110
112 111
113 112 class DeviceType(models.Model):
114 113
115 114 name = models.CharField(max_length = 15, choices = DEV_TYPES, default = 'pedestal')
116 115 sequence = models.PositiveSmallIntegerField(default=55)
117 116 description = models.TextField(blank=True, null=True)
118 117
119 118 class Meta:
120 119 db_table = 'db_device_types'
121 120
122 121 def __str__(self):
123 122 return u'%s' % self.name.title()
124 123
125 124 class Device(models.Model):
126 125
127 126 device_type = models.ForeignKey('DeviceType', on_delete=models.CASCADE)
128 127 location = models.ForeignKey('Location', on_delete=models.CASCADE)
129 128 ip_address = models.GenericIPAddressField(verbose_name = 'IP address', protocol='IPv4', default='0.0.0.0')
130 129 port_address = models.PositiveSmallIntegerField(default=2000)
131 130 description = models.TextField(blank=True, null=True)
132 131 status = models.PositiveSmallIntegerField(default=4, choices=DEV_STATES)
133 132 conf_active = models.PositiveIntegerField(default=0, verbose_name='Current configuration')
134 133
135 134 class Meta:
136 135 db_table = 'db_devices'
137 136
138 137 def __str__(self):
139 138 ret = self.device_type
140 139 #ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
141 140 return str(ret)
142 141
143 142 @property
144 143 def name(self):
145 144 return str(self)
146 145
147 146 def get_status(self):
148 147 return self.status
149 148
150 149 @property
151 150 def status_color(self):
152 151 color = 'muted'
153 152 if self.status == 0:
154 153 color = "danger"
155 154 elif self.status == 1:
156 155 color = "warning"
157 156 elif self.status == 2:
158 157 color = "info"
159 158 elif self.status == 3:
160 159 color = "success"
161 160
162 161 return color
163 162
164 163 def url(self, path=None):
165 164
166 165 if path:
167 166 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
168 167 else:
169 168 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
170 169
171 170 def get_absolute_url(self):
172 171 return reverse('url_device', args=[str(self.id)])
173 172
174 173 def get_absolute_url_edit(self):
175 174 return reverse('url_edit_device', args=[str(self.id)])
176 175
177 176 def get_absolute_url_delete(self):
178 177 return reverse('url_delete_device', args=[str(self.id)])
179 178
180 179 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
181 180
182 181 if self.device_type.name=='pedestal':
183 182 headers = {'content-type': "application/json",
184 183 'cache-control': "no-cache"}
185 184
186 185 ip = [int(x) for x in ip_address.split('.')]
187 186 dns = [int(x) for x in dns.split('.')]
188 187 gateway = [int(x) for x in gateway.split('.')]
189 188 subnet = [int(x) for x in mask.split('.')]
190 189
191 190 payload = {
192 191 "ip": ip,
193 192 "dns": dns,
194 193 "gateway": gateway,
195 194 "subnet": subnet
196 195 }
197 196
198 197 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
199 198 try:
200 199 answer = req.json()
201 200 if answer['changeip']=='ok':
202 201 self.message = '25|IP succesfully changed'
203 202 self.ip_address = ip_address
204 203 self.save()
205 204 else:
206 205 self.message = '30|An error ocuur when changing IP'
207 206 except Exception as e:
208 207 self.message = '40|{}'.format(str(e))
209 208 else:
210 209 self.message = 'Not implemented'
211 210 return False
212 211
213 212 return True
214 213
215 214
216 215 class Campaign(models.Model):
217 216
218 217 template = models.BooleanField(default=False)
219 218 name = models.CharField(max_length=60, unique=True)
220 219 start_date = models.DateTimeField(blank=True, null=True)
221 220 end_date = models.DateTimeField(blank=True, null=True)
222 221 tags = models.CharField(max_length=40, blank=True, null=True)
223 222 description = models.TextField(blank=True, null=True)
224 223 experiments = models.ManyToManyField('Experiment', blank=True)
225 224 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
226 225
227 226 class Meta:
228 227 db_table = 'db_campaigns'
229 228 ordering = ('name',)
230 229
231 230 def __str__(self):
232 231 if self.template:
233 232 return u'{} (template)'.format(self.name)
234 233 else:
235 234 return u'{}'.format(self.name)
236 235
237 236 def jsonify(self):
238 237
239 238 data = {}
240 239
241 240 ignored = ('template')
242 241
243 242 for field in self._meta.fields:
244 243 if field.name in ignored:
245 244 continue
246 245 data[field.name] = field.value_from_object(self)
247 246
248 247 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
249 248 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
250 249
251 250 return data
252 251
253 252 def parms_to_dict(self):
254 253
255 254 params = Params({})
256 255 params.add(self.jsonify(), 'campaigns')
257 256
258 257 for exp in Experiment.objects.filter(campaign = self):
259 258 params.add(exp.jsonify(), 'experiments')
260 259 configurations = Configuration.objects.filter(experiment=exp, type=0)
261 260
262 261 for conf in configurations:
263 262 params.add(conf.jsonify(), 'configurations')
264 263
265 264 return params.data
266 265
267 266 def dict_to_parms(self, parms, CONF_MODELS):
268 267
269 268 experiments = Experiment.objects.filter(campaign = self)
270 269
271 270 if experiments:
272 271 for experiment in experiments:
273 272 experiment.delete()
274 273
275 274 for id_exp in parms['experiments']['allIds']:
276 275 exp_parms = parms['experiments']['byId'][id_exp]
277 276 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
278 277 exp = Experiment(name='{}'.format(dum))
279 278 exp.save()
280 279 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
281 280 self.experiments.add(exp)
282 281
283 282 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
284 283
285 284 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
286 285 self.start_date = camp_parms['start_date']
287 286 self.end_date = camp_parms['end_date']
288 287 self.tags = camp_parms['tags']
289 288 self.save()
290 289
291 290 return self
292 291
293 292 def get_experiments_by_radar(self, radar=None):
294 293
295 294 ret = []
296 295 if radar:
297 296 locations = Location.objects.filter(pk=radar)
298 297 else:
299 298 locations = set([e.location for e in self.experiments.all()])
300 299
301 300 for loc in locations:
302 301 dum = {}
303 302 dum['name'] = loc.name
304 303 dum['id'] = loc.pk
305 304 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
306 305 ret.append(dum)
307 306
308 307 return ret
309 308
310 309 def get_absolute_url(self):
311 310 return reverse('url_campaign', args=[str(self.id)])
312 311
313 312 def get_absolute_url_edit(self):
314 313 return reverse('url_edit_campaign', args=[str(self.id)])
315 314
316 315 def get_absolute_url_delete(self):
317 316 return reverse('url_delete_campaign', args=[str(self.id)])
318 317
319 318 def get_absolute_url_export(self):
320 319 return reverse('url_export_campaign', args=[str(self.id)])
321 320
322 321 def get_absolute_url_import(self):
323 322 return reverse('url_import_campaign', args=[str(self.id)])
324 323
325 324
326 325 class RunningExperiment(models.Model):
327 326 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
328 327 running_experiment = models.ManyToManyField('Experiment', blank = True)
329 328 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
330 329
331 330
332 331 class Experiment(models.Model):
333
332
334 333 template = models.BooleanField(default=False)
335 334 name = models.CharField(max_length=40, default='', unique=True)
336 location = models.ForeignKey('Location', null=False, blank=False, on_delete=models.CASCADE, default='')
335 location = models.ForeignKey('Location', null=False, blank=False, on_delete=models.CASCADE, default=None)
337 336 #freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
338 start_time = models.TimeField(default='00:00:00')
339 end_time = models.TimeField(default='23:59:59')
337 #start_time = models.TimeField(default='00:00:00')
338 #end_time = models.TimeField(default='23:59:59')
339 pedestal = models.ForeignKey('pedestal.PedestalConfiguration', null=False, blank=False, on_delete=models.CASCADE, default=None, related_name = "pedestal_conf")
340 340 task = models.CharField(max_length=36, default='', blank=True, null=True)
341 341 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
342 342 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
343 343 hash = models.CharField(default='', max_length=64, null=True, blank=True)
344 344
345 345 class Meta:
346 346 db_table = 'db_experiments'
347 347 ordering = ('template', 'name')
348 348
349 349 def __str__(self):
350 350 if self.template:
351 351 return u'%s (template)' % (self.name)
352 352 else:
353 353 return u'%s' % (self.name)
354 354
355 355 def jsonify(self):
356 356
357 357 data = {}
358 358
359 359 ignored = ('template')
360 360
361 361 for field in self._meta.fields:
362 362 if field.name in ignored:
363 363 continue
364 364 data[field.name] = field.value_from_object(self)
365
365
366 366 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
367 367 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
368 368 data['location'] = self.location.name
369 369 data['configurations'] = ['{}'.format(conf.pk) for
370 370 conf in Configuration.objects.filter(experiment=self, type=0)]
371 371
372 372 return data
373 373
374 374 @property
375 375 def radar_system(self):
376 376 return self.location
377 377
378 378 def clone(self, **kwargs):
379 379
380 380 confs = Configuration.objects.filter(experiment=self, type=0)
381 381 self.pk = None
382 382 self.name = '{}_{:%y%m%d}'.format(self.name, datetime.now())
383 383 for attr, value in kwargs.items():
384 384 setattr(self, attr, value)
385 385
386 386 self.save()
387 387
388 388 for conf in confs:
389 389 conf.clone(experiment=self, template=False)
390 390
391 391 return self
392 392
393 393 def start(self):
394 394 '''
395 395 Configure and start experiments's devices
396 396 '''
397 397
398 398 confs = []
399 399 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
400 400 confs = allconfs
401 401
402 402 try:
403 403 for conf in confs:
404 404 conf.stop_device()
405 405 print("OK")
406 406 #conf.write_device()
407 407 conf.device.conf_active = conf.pk
408 408 conf.device.save()
409 409 conf.start_device()
410 410 print("OK")
411 411 time.sleep(1)
412 412 except:
413 413 return 0
414 414 return 2
415 415
416 416
417 417 def stop(self):
418 418 '''
419 419 Stop experiments's devices
420 420 PEDESTAL, PULSE GENERATOR & USRP's
421 421 '''
422 422
423 423 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
424 424 try:
425 425 for conf in confs:
426 426 conf.stop_device()
427 427 except:
428 428 return 0
429 429 return 1
430 430
431 431 def get_status(self):
432 432
433 433 if self.status == 3:
434 434 return
435 435
436 436 confs = Configuration.objects.filter(experiment=self, type=0)
437 437
438 438 for conf in confs:
439 439 conf.status_device()
440 440
441 441 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
442 442
443 443 if total==2*confs.count():
444 444 status = 1
445 445 elif total == 3*confs.count():
446 446 status = 2
447 447 else:
448 448 status = 0
449 449
450 450 self.status = status
451 451 self.save()
452 452
453 453 def status_color(self):
454 454 color = 'muted'
455 455 if self.status == 0:
456 456 color = "danger"
457 457 elif self.status == 1:
458 458 color = "warning"
459 459 elif self.status == 2:
460 460 color = "success"
461 461 elif self.status == 3:
462 462 color = "info"
463 463
464 464 return color
465 465
466 466 def parms_to_dict(self):
467 467
468 468 params = Params({})
469 469 params.add(self.jsonify(), 'experiments')
470 470
471 471 configurations = Configuration.objects.filter(experiment=self, type=0)
472 472
473 473 for conf in configurations:
474 474 params.add(conf.jsonify(), 'configurations')
475 475
476 476 return params.data
477 477
478 478 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
479 479
480 480 configurations = Configuration.objects.filter(experiment=self)
481 481
482 482 if id_exp is not None:
483 483 exp_parms = parms['experiments']['byId'][id_exp]
484 484 else:
485 485 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
486 486
487 487 if configurations:
488 488 for configuration in configurations:
489 489 configuration.delete()
490 490
491 491 for id_conf in exp_parms['configurations']:
492 492 conf_parms = parms['configurations']['byId'][id_conf]
493 493 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
494 494 model = CONF_MODELS[conf_parms['device_type']]
495 495 conf = model(
496 496 experiment = self,
497 497 device = device,
498 498 )
499 499 conf.dict_to_parms(parms, id=id_conf)
500 500
501
501
502 502 location, created = Location.objects.get_or_create(name=exp_parms['location'])
503 503 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
504 504 self.location = location
505 505 self.start_time = exp_parms['start_time']
506 506 self.end_time = exp_parms['end_time']
507 507 self.save()
508 508
509 509 return self
510 510
511 511 def get_absolute_url(self):
512 512 return reverse('url_experiment', args=[str(self.id)])
513 513
514 514 def get_absolute_url_edit(self):
515 515 return reverse('url_edit_experiment', args=[str(self.id)])
516 516
517 517 def get_absolute_url_delete(self):
518 518 return reverse('url_delete_experiment', args=[str(self.id)])
519 519
520 520 def get_absolute_url_import(self):
521 521 return reverse('url_import_experiment', args=[str(self.id)])
522 522
523 523 def get_absolute_url_export(self):
524 524 return reverse('url_export_experiment', args=[str(self.id)])
525 525
526 526 def get_absolute_url_start(self):
527 527 return reverse('url_start_experiment', args=[str(self.id)])
528 528
529 529 def get_absolute_url_stop(self):
530 530 return reverse('url_stop_experiment', args=[str(self.id)])
531 531
532 532
533 533 class Configuration(PolymorphicModel):
534 534
535 535 id = models.AutoField(primary_key=True)
536 536 template = models.BooleanField(default=False)
537 537 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
538 538 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
539 539 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=False, null=False)
540 540 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
541 541 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
542 542 created_date = models.DateTimeField(auto_now_add=True)
543 543 programmed_date = models.DateTimeField(auto_now=True)
544 544 parameters = models.TextField(default='{}')
545 545 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
546 546 hash = models.CharField(default='', max_length=64, null=True, blank=True)
547 547 message = ""
548 548
549 549 class Meta:
550 550 db_table = 'db_configurations'
551 551 ordering = ('device__device_type__name',)
552 552
553 553 def __str__(self):
554 554
555 555 ret = u'{} '.format(self.device.device_type.name.upper())
556 556
557 557 if 'mix' in [f.name for f in self._meta.get_fields()]:
558 558 if self.mix:
559 559 ret = '{} MIX '.format(self.device.device_type.name.upper())
560 560
561 561 if 'label' in [f.name for f in self._meta.get_fields()]:
562 562 ret += '{}'.format(self.label)
563 563
564 564 if self.template:
565 565 ret += ' (template)'
566 566
567 567 return ret
568 568
569 569 @property
570 570 def name(self):
571 571
572 572 return str(self)
573 573
574 574 def jsonify(self):
575 575
576 576 data = {}
577 577
578 578 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
579 579 'created_date', 'programmed_date', 'template', 'device',
580 580 'experiment')
581 581
582 582 for field in self._meta.fields:
583 583 if field.name in ignored:
584 584 continue
585 585 data[field.name] = field.value_from_object(self)
586 586
587 587 data['device_type'] = self.device.device_type.name
588 588 return data
589 589
590 590 def clone(self, **kwargs):
591 591
592 592 self.pk = None
593 593 self.id = None
594 594 for attr, value in kwargs.items():
595 595 setattr(self, attr, value)
596 596
597 597 self.save()
598 598
599 599 return self
600 600
601 601 def parms_to_dict(self):
602 602
603 603 params = Params({})
604 604 params.add(self.jsonify(), 'configurations')
605 605 return params.data
606 606
607 607 def parms_to_text(self):
608 608
609 609 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
610 610
611 611
612 612 def parms_to_binary(self):
613 613
614 614 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
615 615
616 616
617 617 def dict_to_parms(self, parameters, id=None):
618 618
619 619 params = Params(parameters)
620 620
621 621 if id:
622 622 data = params.get_conf(id_conf=id)
623 623 else:
624 624 data = params.get_conf(dtype=self.device.device_type.name)
625 625
626 626 for key, value in data.items():
627 627 if key not in ('id', 'device_type'):
628 628 setattr(self, key, value)
629 629
630 630 self.save()
631 631
632 632
633 633 def export_to_file(self, format="json"):
634 634
635 635 content_type = ''
636 636
637 637 if format == 'racp':
638 638 content_type = 'text/plain'
639 639 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
640 640 content = self.parms_to_text(file_format = 'racp')
641 641
642 642 if format == 'text':
643 643 content_type = 'text/plain'
644 644 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
645 645 content = self.parms_to_text()
646 646
647 647 if format == 'binary':
648 648 content_type = 'application/octet-stream'
649 649 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
650 650 content = self.parms_to_binary()
651 651
652 652 if not content_type:
653 653 content_type = 'application/json'
654 654 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
655 655 content = json.dumps(self.parms_to_dict(), indent=2)
656 656
657 657 fields = {'content_type':content_type,
658 658 'filename':filename,
659 659 'content':content
660 660 }
661 661
662 662 return fields
663 663
664 664 def import_from_file(self, fp):
665 665
666 666 parms = {}
667 667
668 668 path, ext = os.path.splitext(fp.name)
669 669
670 670 if ext == '.json':
671 671 parms = json.load(fp)
672 672
673 673 return parms
674 674
675 675 def status_device(self):
676 676
677 677 self.message = 'Function not implemented'
678 678 return False
679 679
680 680
681 681 def stop_device(self):
682 682
683 683 self.message = 'Function not implemented'
684 684 return False
685 685
686 686
687 687 def start_device(self):
688 688
689 689 self.message = 'Function not implemented'
690 690 return False
691 691
692 692
693 693 def write_device(self):
694 694
695 695 self.message = 'Function not implemented'
696 696 return False
697 697
698 698
699 699 def read_device(self):
700 700
701 701 self.message = 'Function not implemented'
702 702 return False
703 703
704 704
705 705 def get_absolute_url(self):
706 706 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
707 707
708 708 def get_absolute_url_edit(self):
709 709 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
710 710
711 711 def get_absolute_url_delete(self):
712 712 return reverse('url_delete_dev_conf', args=[str(self.id)])
713 713
714 714 def get_absolute_url_import(self):
715 715 return reverse('url_import_dev_conf', args=[str(self.id)])
716 716
717 717 def get_absolute_url_export(self):
718 718 return reverse('url_export_dev_conf', args=[str(self.id)])
719 719
720 720 def get_absolute_url_write(self):
721 721 return reverse('url_write_dev_conf', args=[str(self.id)])
722 722
723 723 def get_absolute_url_read(self):
724 724 return reverse('url_read_dev_conf', args=[str(self.id)])
725 725
726 726 def get_absolute_url_start(self):
727 727 return reverse('url_start_dev_conf', args=[str(self.id)])
728 728
729 729 def get_absolute_url_stop(self):
730 730 return reverse('url_stop_dev_conf', args=[str(self.id)])
731 731
732 732 def get_absolute_url_status(self):
733 733 return reverse('url_status_dev_conf', args=[str(self.id)])
@@ -1,105 +1,103
1 1 {% extends "base.html" %}
2 2 {% load bootstrap4 %}
3 3 {% load static %}
4 4 {% load main_tags %}
5 5 {% block extra-head %}
6 6 <link href="{% static 'css/bootstrap-datetimepicker.min.css' %}" media="screen" rel="stylesheet">
7 7 {% endblock %}
8 8 {% block content-title %}{{title}}{% endblock %}
9 9 {% block content-suptitle %}{{suptitle}}{% endblock %}
10 10
11 11 {% block content %}
12 12
13 13 {% block menu-actions %}
14 14 <span class=" dropdown pull-right">
15 15 <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="fas fa-bars" aria-hidden="true"></span></a>
16 16 <ul class="dropdown-menu" role="menu">
17 17 <li><a href="{% url 'url_edit_experiment' experiment.id %}"><span class="fa fa-pencil" aria-hidden="true"></span> Edit</a></li>
18 18 <li><a href="{% url 'url_delete_experiment' experiment.id %}"><span class="fa fa-times" aria-hidden="true"></span> Delete</a></li>
19 19 <li><a href="{{ experiment.get_absolute_url_import }}"><span class="fas fa-cloud-download-alt" aria-hidden="true"></span> Import </a></li>
20 20 <li><a href="{{ experiment.get_absolute_url_export }}"><span class="fas fa-cloud-upload-alt" aria-hidden="true"></span> Export </a></li>
21 21 <li><a>----------------</a></li>
22 22 <li><a href="{{ experiment.get_absolute_url_start}}"><span class="fa fa-play" aria-hidden="true"></span> Start</a></li>
23 23 <li><a href="{{ experiment.get_absolute_url_stop }}"><span class="fa fa-stop" aria-hidden="true"></span> Stop</a></li>
24 <li><a href="{% url 'url_mix_experiment' experiment.id %}"><span class="fa fa-random" aria-hidden="true"></span> Mix RC Configurations </a></li>
25 24 <li><a href="{% url 'url_add_dev_conf' experiment.id %}"><span class="fa fa-plus-circle" aria-hidden="true"></span> Add Configuration</a></li>
26 <li><a href="{% url 'url_sum_experiment' experiment.id %}"><span class="fa fa-list-alt" aria-hidden="true"></span> Summary</a></li>
27
25
28 26 </ul>
29 27 </span>
30 28 {% endblock %}
31 29
32 30 <table class="table table-bordered">
33 31 {% for key in experiment_keys %}
34 32 {% if key == 'freq' %}
35 33 <tr><th>Operating Freq. (MHz)</th><td>{{experiment|attr:key}}</td></tr>
36 34 {% else %}
37 35 <tr><th>{{key|title}}</th><td>{{experiment|attr:key}}</td></tr>
38 36 {% endif %}
39 37 {% endfor %}
40 38 </table>
41 39 <br>
42 40
43 41 <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
44 42
45 43 <div class="panel panel-default bootcards-summary">
46 44 <div class="panel-heading" role="tab">
47 45 <h4 class="panel-title">
48 46 Devices
49 47 </h4>
50 48 </div>
51 49 <div class="panel-body">
52 50
53 51 {% for item in configurations %}
54 52 <div class="col-xs-6 col-sm-4" style="padding-top:5px;padding-bottom:5px">
55 53 <a class="bootcards-summary-item" href="{{item.get_absolute_url}}"><br>
56 54 {% if item.device.device_type.name == 'cgs' %}
57 55 <i class="fa fa-2x fa-clock-o"></i>
58 56 {% elif item.device.device_type.name == 'rc' %}
59 57 <i class="fa fa-2x fa-microchip"></i>
60 58 {% elif item.device.device_type.name == 'abs' %}
61 59 <i class="fa fa-2x fa-podcast"></i>
62 60 {% elif item.device.device_type.name == 'jars' %}
63 61 <i class="fa fa-2x fa-desktop"></i>
64 62 {% elif item.device.device_type.name == 'dds' %}
65 63 <i class="fa fa-2x fa-bar-chart"></i>
66 64 {% else %}
67 65 <i class="fa fa-3x fa-puzzle-piece"></i>
68 66 {%endif%}
69 67 <h4>{{item}}<br><small>{{item.device.ip_address}}</small>
70 68 {%if item.pk != item.device.conf_active %}
71 69 <span class="label label-info">Configured</span>
72 70 {%else%}
73 71 <span class="label label-{{item.device.status_color}}">{{item.device.get_status_display}}</span>
74 72 {%endif%}
75 73 </h4>
76 74 </a>
77 75 </div>
78 76 {% endfor %}
79 77
80 78 </div>
81 79 </div>
82 80 </div>
83 81 {% endblock %}
84 82
85 83 {% block sidebar%}
86 84 {% include "sidebar_devices.html" %}
87 85 {% endblock %}
88 86
89 87 {% block extra-js%}
90 88 <script type="text/javascript">
91 89
92 90 $(".clickable-row").click(function() {
93 91 document.location = $(this).data("href");
94 92 });
95 93
96 94 $("#bt_edit").click(function() {
97 95 document.location = "{% url 'url_edit_experiment' experiment.id%}";
98 96 });
99 97
100 98 $("#bt_add_conf").click(function() {
101 99 document.location = "{% url 'url_add_dev_conf' experiment.id %}";
102 100 });
103 101
104 102 </script>
105 103 {% endblock %}
@@ -1,1920 +1,1918
1 1 import ast
2 2 import json
3 3 import hashlib
4 4 from datetime import datetime, timedelta
5 5
6 6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7 7 from django.utils.safestring import mark_safe
8 8 from django.http import HttpResponseRedirect
9 9 from django.urls import reverse
10 10 from django.db.models import Q
11 11 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
12 12 from django.contrib import messages
13 13 from django.http.request import QueryDict
14 14 from django.contrib.auth.decorators import login_required, user_passes_test
15 15
16 16 from django.utils.timezone import is_aware
17 17
18 18 try:
19 19 from urllib.parse import urlencode
20 20 except ImportError:
21 21 from urllib import urlencode
22 22
23 23 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
24 24 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
25 25
26 26 from apps.pedestal.forms import PedestalConfigurationForm
27 27 from apps.pedestal_dev.forms import PedestalDevConfigurationForm
28 28 from apps.generator.forms import GeneratorConfigurationForm
29 29 from apps.usrp_rx.forms import USRPRXConfigurationForm
30 30 from apps.usrp_tx.forms import USRPTXConfigurationForm
31 31 from .utils import Params
32 32
33 33 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment, DEV_STATES
34 34 from apps.pedestal.models import PedestalConfiguration
35 35 from apps.pedestal_dev.models import PedestalDevConfiguration
36 36 from apps.generator.models import GeneratorConfiguration
37 37 from apps.usrp_rx.models import USRPRXConfiguration
38 38 from apps.usrp_tx.models import USRPTXConfiguration
39 39
40 40
41 41 #comentario test
42 42 CONF_FORMS = {
43 43 'pedestal': PedestalConfigurationForm,
44 44 'pedestal_dev': PedestalDevConfigurationForm,
45 45 'generator': GeneratorConfigurationForm,
46 46 'usrp_rx': USRPRXConfigurationForm,
47 47 'usrp_tx': USRPTXConfigurationForm,
48 48 }
49 49
50 50 CONF_MODELS = {
51 51 'pedestal': PedestalConfiguration,
52 52 'pedestal_dev': PedestalDevConfiguration,
53 53 'generator': GeneratorConfiguration,
54 54 'usrp_rx': USRPRXConfiguration,
55 55 'usrp_tx': USRPTXConfiguration,
56 56 }
57 57
58 58 MIX_MODES = {
59 59 '0': 'P',
60 60 '1': 'S',
61 61 }
62 62
63 63 MIX_OPERATIONS = {
64 64 '0': 'OR',
65 65 '1': 'XOR',
66 66 '2': 'AND',
67 67 '3': 'NAND',
68 68 }
69 69
70 70
71 71 def is_developer(user):
72 72
73 73 groups = [str(g.name) for g in user.groups.all()]
74 74 return 'Developer' in groups or user.is_staff
75 75
76 76
77 77 def is_operator(user):
78 78
79 79 groups = [str(g.name) for g in user.groups.all()]
80 80 return 'Operator' in groups or user.is_staff
81 81
82 82
83 83 def has_been_modified(model):
84 84
85 85 prev_hash = model.hash
86 86 new_hash = hashlib.sha256(str(model.parms_to_dict).encode()).hexdigest()
87 87 if prev_hash != new_hash:
88 88 model.hash = new_hash
89 89 model.save()
90 90 return True
91 91 return False
92 92
93 93
94 94 def index(request):
95 95 kwargs = {'no_sidebar': True}
96 96
97 97 return render(request, 'index.html', kwargs)
98 98
99 99
100 100 def locations(request):
101 101
102 102 page = request.GET.get('page')
103 103 order = ('name',)
104 104
105 105 kwargs = get_paginator(Location, page, order)
106 106
107 107 kwargs['keys'] = ['name', 'description']
108 108 kwargs['title'] = 'Radar System'
109 109 kwargs['suptitle'] = 'List'
110 110 kwargs['no_sidebar'] = True
111 111
112 112 return render(request, 'base_list.html', kwargs)
113 113
114 114
115 115 def location(request, id_loc):
116 116
117 117 location = get_object_or_404(Location, pk=id_loc)
118 118
119 119 kwargs = {}
120 120 kwargs['location'] = location
121 121 kwargs['location_keys'] = ['name', 'description']
122 122
123 123 kwargs['title'] = 'Location'
124 124 kwargs['suptitle'] = 'Details'
125 125
126 126 return render(request, 'location.html', kwargs)
127 127
128 128
129 129 @login_required
130 130 def location_new(request):
131 131
132 132 if request.method == 'GET':
133 133 form = LocationForm()
134 134
135 135 if request.method == 'POST':
136 136 form = LocationForm(request.POST)
137 137
138 138 if form.is_valid():
139 139 form.save()
140 140 return redirect('url_locations')
141 141
142 142 kwargs = {}
143 143 kwargs['form'] = form
144 144 kwargs['title'] = 'Radar System'
145 145 kwargs['suptitle'] = 'New'
146 146 kwargs['button'] = 'Create'
147 147
148 148 return render(request, 'base_edit.html', kwargs)
149 149
150 150
151 151 @login_required
152 152 def location_edit(request, id_loc):
153 153
154 154 location = get_object_or_404(Location, pk=id_loc)
155 155
156 156 if request.method == 'GET':
157 157 form = LocationForm(instance=location)
158 158
159 159 if request.method == 'POST':
160 160 form = LocationForm(request.POST, instance=location)
161 161
162 162 if form.is_valid():
163 163 form.save()
164 164 return redirect('url_locations')
165 165
166 166 kwargs = {}
167 167 kwargs['form'] = form
168 168 kwargs['title'] = 'Location'
169 169 kwargs['suptitle'] = 'Edit'
170 170 kwargs['button'] = 'Update'
171 171
172 172 return render(request, 'base_edit.html', kwargs)
173 173
174 174
175 175 @login_required
176 176 def location_delete(request, id_loc):
177 177
178 178 location = get_object_or_404(Location, pk=id_loc)
179 179
180 180 if request.method == 'POST':
181 181
182 182 if is_developer(request.user):
183 183 location.delete()
184 184 return redirect('url_locations')
185 185
186 186 messages.error(request, 'Not enough permission to delete this object')
187 187 return redirect(location.get_absolute_url())
188 188
189 189 kwargs = {
190 190 'title': 'Delete',
191 191 'suptitle': 'Location',
192 192 'object': location,
193 193 'delete': True
194 194 }
195 195
196 196 return render(request, 'confirm.html', kwargs)
197 197
198 198
199 199 def devices(request):
200 200
201 201 page = request.GET.get('page')
202 202 order = ('location', 'device_type')
203 203
204 204 filters = request.GET.copy()
205 205 kwargs = get_paginator(Device, page, order, filters)
206 206 form = FilterForm(initial=request.GET, extra_fields=['tags'])
207 207
208 208 kwargs['keys'] = ['device_type', 'location',
209 209 'ip_address', 'port_address', 'actions']
210 210 kwargs['title'] = 'Device'
211 211 kwargs['suptitle'] = 'List'
212 212 kwargs['no_sidebar'] = True
213 213 kwargs['form'] = form
214 214 kwargs['add_url'] = reverse('url_add_device')
215 215 filters.pop('page', None)
216 216 kwargs['q'] = urlencode(filters)
217 217 kwargs['menu_devices'] = 'active'
218 218 return render(request, 'base_list.html', kwargs)
219 219
220 220
221 221 def device(request, id_dev):
222 222
223 223 device = get_object_or_404(Device, pk=id_dev)
224 224
225 225 kwargs = {}
226 226 kwargs['device'] = device
227 227 kwargs['device_keys'] = ['device_type',
228 228 'ip_address', 'port_address', 'description']
229 229
230 230 kwargs['title'] = 'Device'
231 231 kwargs['suptitle'] = 'Details'
232 232 kwargs['menu_devices'] = 'active'
233 233
234 234 return render(request, 'device.html', kwargs)
235 235
236 236
237 237 @login_required
238 238 def device_new(request):
239 239
240 240 if request.method == 'GET':
241 241 form = DeviceForm()
242 242
243 243 if request.method == 'POST':
244 244 form = DeviceForm(request.POST)
245 245
246 246 if form.is_valid():
247 247 form.save()
248 248 return redirect('url_devices')
249 249
250 250 kwargs = {}
251 251 kwargs['form'] = form
252 252 kwargs['title'] = 'Device'
253 253 kwargs['suptitle'] = 'New'
254 254 kwargs['button'] = 'Create'
255 255 kwargs['menu_devices'] = 'active'
256 256
257 257 return render(request, 'base_edit.html', kwargs)
258 258
259 259
260 260 @login_required
261 261 def device_edit(request, id_dev):
262 262
263 263 device = get_object_or_404(Device, pk=id_dev)
264 264
265 265 if request.method == 'GET':
266 266 form = DeviceForm(instance=device)
267 267
268 268 if request.method == 'POST':
269 269 form = DeviceForm(request.POST, instance=device)
270 270
271 271 if form.is_valid():
272 272 form.save()
273 273 return redirect(device.get_absolute_url())
274 274
275 275 kwargs = {}
276 276 kwargs['form'] = form
277 277 kwargs['title'] = 'Device'
278 278 kwargs['suptitle'] = 'Edit'
279 279 kwargs['button'] = 'Update'
280 280 kwargs['menu_devices'] = 'active'
281 281
282 282 return render(request, 'base_edit.html', kwargs)
283 283
284 284
285 285 @login_required
286 286 def device_delete(request, id_dev):
287 287
288 288 device = get_object_or_404(Device, pk=id_dev)
289 289
290 290 if request.method == 'POST':
291 291
292 292 if is_developer(request.user):
293 293 device.delete()
294 294 return redirect('url_devices')
295 295
296 296 messages.error(request, 'Not enough permission to delete this object')
297 297 return redirect(device.get_absolute_url())
298 298
299 299 kwargs = {
300 300 'title': 'Delete',
301 301 'suptitle': 'Device',
302 302 'object': device,
303 303 'delete': True
304 304 }
305 305 kwargs['menu_devices'] = 'active'
306 306
307 307 return render(request, 'confirm.html', kwargs)
308 308
309 309
310 310 @login_required
311 311 def device_change_ip(request, id_dev):
312 312
313 313 device = get_object_or_404(Device, pk=id_dev)
314 314
315 315 if request.method == 'POST':
316 316
317 317 if is_developer(request.user):
318 318 device.change_ip(**request.POST.dict())
319 319 level, message = device.message.split('|')
320 320 messages.add_message(request, level, message)
321 321 else:
322 322 messages.error(
323 323 request, 'Not enough permission to delete this object')
324 324 return redirect(device.get_absolute_url())
325 325
326 326 kwargs = {
327 327 'title': 'Device',
328 328 'suptitle': 'Change IP',
329 329 'object': device,
330 330 'previous': device.get_absolute_url(),
331 331 'form': ChangeIpForm(initial={'ip_address': device.ip_address}),
332 332 'message': ' ',
333 333 }
334 334 kwargs['menu_devices'] = 'active'
335 335
336 336 return render(request, 'confirm.html', kwargs)
337 337
338 338
339 339 def campaigns(request):
340 340
341 341 page = request.GET.get('page')
342 342 order = ('-start_date',)
343 343 filters = request.GET.copy()
344 344
345 345 kwargs = get_paginator(Campaign, page, order, filters)
346 346
347 347 form = FilterForm(initial=request.GET, extra_fields=[
348 348 'range_date', 'tags', 'template'])
349 349 kwargs['keys'] = ['name', 'start_date', 'end_date', 'actions']
350 350 kwargs['title'] = 'Campaign'
351 351 kwargs['suptitle'] = 'List'
352 352 kwargs['no_sidebar'] = True
353 353 kwargs['form'] = form
354 354 kwargs['add_url'] = reverse('url_add_campaign')
355 355 filters.pop('page', None)
356 356 kwargs['q'] = urlencode(filters)
357 357 kwargs['menu_campaigns'] = 'active'
358 358
359 359 return render(request, 'base_list.html', kwargs)
360 360
361 361
362 362 def campaign(request, id_camp):
363 363
364 364 campaign = get_object_or_404(Campaign, pk=id_camp)
365 365 experiments = Experiment.objects.filter(campaign=campaign)
366 366
367 367 form = CampaignForm(instance=campaign)
368 368
369 369 kwargs = {}
370 370 kwargs['campaign'] = campaign
371 371 kwargs['campaign_keys'] = ['template', 'name',
372 372 'start_date', 'end_date', 'tags', 'description']
373 373
374 374 kwargs['experiments'] = experiments
375 375 kwargs['experiment_keys'] = [
376 376 'name', 'radar_system', 'start_time', 'end_time']
377 377
378 378 kwargs['title'] = 'Campaign'
379 379 kwargs['suptitle'] = 'Details'
380 380
381 381 kwargs['form'] = form
382 382 kwargs['button'] = 'Add Experiment'
383 383 kwargs['menu_campaigns'] = 'active'
384 384
385 385 return render(request, 'campaign.html', kwargs)
386 386
387 387
388 388 @login_required
389 389 def campaign_new(request):
390 390
391 391 kwargs = {}
392 392
393 393 if request.method == 'GET':
394 394
395 395 if 'template' in request.GET:
396 396 if request.GET['template'] == '0':
397 397 form = NewForm(initial={'create_from': 2},
398 398 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
399 399 else:
400 400 kwargs['button'] = 'Create'
401 401 kwargs['experiments'] = Configuration.objects.filter(
402 402 experiment=request.GET['template'])
403 403 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
404 404 camp = Campaign.objects.get(pk=request.GET['template'])
405 405 form = CampaignForm(instance=camp,
406 406 initial={'name': '{}_{:%Y%m%d}'.format(camp.name, datetime.now()),
407 407 'template': False})
408 408 elif 'blank' in request.GET:
409 409 kwargs['button'] = 'Create'
410 410 form = CampaignForm()
411 411 else:
412 412 form = NewForm()
413 413
414 414 if request.method == 'POST':
415 415 kwargs['button'] = 'Create'
416 416 post = request.POST.copy()
417 417 experiments = []
418 418
419 419 for id_exp in post.getlist('experiments'):
420 420 exp = Experiment.objects.get(pk=id_exp)
421 421 new_exp = exp.clone(template=False)
422 422 experiments.append(new_exp)
423 423
424 424 post.setlist('experiments', [])
425 425
426 426 form = CampaignForm(post)
427 427
428 428 if form.is_valid():
429 429 campaign = form.save(commit=False)
430 430 campaign.author = request.user
431 431 for exp in experiments:
432 432 campaign.experiments.add(exp)
433 433 campaign.save()
434 434 return redirect('url_campaign', id_camp=campaign.id)
435 435
436 436 kwargs['form'] = form
437 437 kwargs['title'] = 'Campaign'
438 438 kwargs['suptitle'] = 'New'
439 439 kwargs['menu_campaigns'] = 'active'
440 440
441 441 return render(request, 'campaign_edit.html', kwargs)
442 442
443 443
444 444 @login_required
445 445 def campaign_edit(request, id_camp):
446 446
447 447 campaign = get_object_or_404(Campaign, pk=id_camp)
448 448
449 449 if request.method == 'GET':
450 450 form = CampaignForm(instance=campaign)
451 451
452 452 if request.method == 'POST':
453 453 exps = campaign.experiments.all().values_list('pk', flat=True)
454 454 post = request.POST.copy()
455 455 new_exps = post.getlist('experiments')
456 456 post.setlist('experiments', [])
457 457 form = CampaignForm(post, instance=campaign)
458 458
459 459 if form.is_valid():
460 460 camp = form.save()
461 461 for id_exp in new_exps:
462 462 if int(id_exp) in exps:
463 463 exps.pop(id_exp)
464 464 else:
465 465 exp = Experiment.objects.get(pk=id_exp)
466 466 if exp.template:
467 467 camp.experiments.add(exp.clone(template=False))
468 468 else:
469 469 camp.experiments.add(exp)
470 470
471 471 for id_exp in exps:
472 472 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
473 473
474 474 return redirect('url_campaign', id_camp=id_camp)
475 475
476 476 kwargs = {}
477 477 kwargs['form'] = form
478 478 kwargs['title'] = 'Campaign'
479 479 kwargs['suptitle'] = 'Edit'
480 480 kwargs['button'] = 'Update'
481 481 kwargs['menu_campaigns'] = 'active'
482 482
483 483 return render(request, 'campaign_edit.html', kwargs)
484 484
485 485
486 486 @login_required
487 487 def campaign_delete(request, id_camp):
488 488
489 489 campaign = get_object_or_404(Campaign, pk=id_camp)
490 490
491 491 if request.method == 'POST':
492 492 if is_developer(request.user):
493 493
494 494 for exp in campaign.experiments.all():
495 495 for conf in Configuration.objects.filter(experiment=exp):
496 496 conf.delete()
497 497 exp.delete()
498 498 campaign.delete()
499 499
500 500 return redirect('url_campaigns')
501 501
502 502 messages.error(request, 'Not enough permission to delete this object')
503 503 return redirect(campaign.get_absolute_url())
504 504
505 505 kwargs = {
506 506 'title': 'Delete',
507 507 'suptitle': 'Campaign',
508 508 'object': campaign,
509 509 'delete': True
510 510 }
511 511 kwargs['menu_campaigns'] = 'active'
512 512
513 513 return render(request, 'confirm.html', kwargs)
514 514
515 515
516 516 @login_required
517 517 def campaign_export(request, id_camp):
518 518
519 519 campaign = get_object_or_404(Campaign, pk=id_camp)
520 520 content = campaign.parms_to_dict()
521 521 content_type = 'application/json'
522 522 filename = '%s_%s.json' % (campaign.name, campaign.id)
523 523
524 524 response = HttpResponse(content_type=content_type)
525 525 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
526 526 response.write(json.dumps(content, indent=2))
527 527
528 528 return response
529 529
530 530
531 531 @login_required
532 532 def campaign_import(request, id_camp):
533 533
534 534 campaign = get_object_or_404(Campaign, pk=id_camp)
535 535
536 536 if request.method == 'GET':
537 537 file_form = UploadFileForm()
538 538
539 539 if request.method == 'POST':
540 540 file_form = UploadFileForm(request.POST, request.FILES)
541 541
542 542 if file_form.is_valid():
543 543 new_camp = campaign.dict_to_parms(
544 544 json.load(request.FILES['file']), CONF_MODELS)
545 545 messages.success(
546 546 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
547 547 return redirect(new_camp.get_absolute_url_edit())
548 548
549 549 messages.error(request, "Could not import parameters from file")
550 550
551 551 kwargs = {}
552 552 kwargs['title'] = 'Campaign'
553 553 kwargs['form'] = file_form
554 554 kwargs['suptitle'] = 'Importing file'
555 555 kwargs['button'] = 'Import'
556 556 kwargs['menu_campaigns'] = 'active'
557 557
558 558 return render(request, 'campaign_import.html', kwargs)
559 559
560 560
561 561 def experiments(request):
562 562
563 563 page = request.GET.get('page')
564 564 order = ('location',)
565 565 filters = request.GET.copy()
566 566
567 567 if 'my experiments' in filters:
568 568 filters.pop('my experiments', None)
569 569 filters['mine'] = request.user.id
570 570
571 571 kwargs = get_paginator(Experiment, page, order, filters)
572 572
573 573 fields = ['tags', 'template']
574 574 if request.user.is_authenticated:
575 575 fields.append('my experiments')
576 576
577 577 form = FilterForm(initial=request.GET, extra_fields=fields)
578 578
579 kwargs['keys'] = ['name', 'radar_system',
580 'start_time', 'end_time', 'actions']
579 kwargs['keys'] = ['name', 'radar_system', 'actions']
581 580 kwargs['title'] = 'Experiment'
582 581 kwargs['suptitle'] = 'List'
583 582 kwargs['no_sidebar'] = True
584 583 kwargs['form'] = form
585 584 kwargs['add_url'] = reverse('url_add_experiment')
586 585 filters = request.GET.copy()
587 586 filters.pop('page', None)
588 587 kwargs['q'] = urlencode(filters)
589 588 kwargs['menu_experiments'] = 'active'
590 589
591 590 return render(request, 'base_list.html', kwargs)
592 591
593 592
594 593 def experiment(request, id_exp):
595 594
596 595 experiment = get_object_or_404(Experiment, pk=id_exp)
597
596
598 597 configurations = Configuration.objects.filter(
599 598 experiment=experiment, type=0)
600 599
601 600 kwargs = {}
602 601
603 kwargs['experiment_keys'] = ['template', 'radar_system',
604 'name', 'start_time', 'end_time']
602 kwargs['experiment_keys'] = ['template', 'radar_system', 'name']
605 603 kwargs['experiment'] = experiment
606 604 kwargs['configuration_keys'] = ['name', 'device__ip_address',
607 605 'device__port_address', 'device__status']
608 606 kwargs['configurations'] = configurations
609 607 kwargs['title'] = 'Experiment'
610 608 kwargs['suptitle'] = 'Details'
611 609 kwargs['button'] = 'Add Configuration'
612 610 kwargs['menu_experiments'] = 'active'
613 611
614 612 ###### SIDEBAR ######
615 613 kwargs.update(sidebar(experiment=experiment))
616 614
617 615 return render(request, 'experiment.html', kwargs)
618 616
619 617
620 618 @login_required
621 619 def experiment_new(request, id_camp=None):
622 620
623 621 if not is_developer(request.user):
624 622 messages.error(
625 623 request, 'Developer required, to create new Experiments')
626 624 return redirect('index')
627 625 kwargs = {}
628 626
629 627 if request.method == 'GET':
630 628 if 'template' in request.GET:
631 629 if request.GET['template'] == '0':
632 630 form = NewForm(initial={'create_from': 2},
633 631 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
634 632 else:
635 633 kwargs['button'] = 'Create'
636 634 kwargs['configurations'] = Configuration.objects.filter(
637 635 experiment=request.GET['template'])
638 636 kwargs['configuration_keys'] = ['name', 'device__name',
639 637 'device__ip_address', 'device__port_address']
640 638 exp = Experiment.objects.get(pk=request.GET['template'])
641 639 form = ExperimentForm(instance=exp,
642 640 initial={'name': '{}_{:%y%m%d}'.format(exp.name, datetime.now()),
643 641 'template': False})
644 642 elif 'blank' in request.GET:
645 643 kwargs['button'] = 'Create'
646 644 form = ExperimentForm()
647 645 else:
648 646 form = NewForm()
649 647
650 648 if request.method == 'POST':
651 649 form = ExperimentForm(request.POST)
652 650 if form.is_valid():
653 651 experiment = form.save(commit=False)
654 652 experiment.author = request.user
655 653 experiment.save()
656 654
657 655 if 'template' in request.GET:
658 656 configurations = Configuration.objects.filter(
659 657 experiment=request.GET['template'], type=0)
660 658 for conf in configurations:
661 659 conf.clone(experiment=experiment, template=False)
662 660
663 661 return redirect('url_experiment', id_exp=experiment.id)
664 662
665 663 kwargs['form'] = form
666 664 kwargs['title'] = 'Experiment'
667 665 kwargs['suptitle'] = 'New'
668 666 kwargs['menu_experiments'] = 'active'
669 667
670 668 return render(request, 'experiment_edit.html', kwargs)
671 669
672 670
673 671 @login_required
674 672 def experiment_edit(request, id_exp):
675 673
676 674 experiment = get_object_or_404(Experiment, pk=id_exp)
677 675
678 676 if request.method == 'GET':
679 677 form = ExperimentForm(instance=experiment)
680 678
681 679 if request.method == 'POST':
682 680 form = ExperimentForm(request.POST, instance=experiment)
683 681
684 682 if form.is_valid():
685 683 experiment = form.save()
686 684 return redirect('url_experiment', id_exp=experiment.id)
687 685
688 686 kwargs = {}
689 687 kwargs['form'] = form
690 688 kwargs['title'] = 'Experiment'
691 689 kwargs['suptitle'] = 'Edit'
692 690 kwargs['button'] = 'Update'
693 691 kwargs['menu_experiments'] = 'active'
694 692
695 693 return render(request, 'experiment_edit.html', kwargs)
696 694
697 695
698 696 @login_required
699 697 def experiment_delete(request, id_exp):
700 698
701 699 experiment = get_object_or_404(Experiment, pk=id_exp)
702 700
703 701 if request.method == 'POST':
704 702 if is_developer(request.user):
705 703 for conf in Configuration.objects.filter(experiment=experiment):
706 704 conf.delete()
707 705 experiment.delete()
708 706 return redirect('url_experiments')
709 707
710 708 messages.error(request, 'Not enough permission to delete this object')
711 709 return redirect(experiment.get_absolute_url())
712 710
713 711 kwargs = {
714 712 'title': 'Delete',
715 713 'suptitle': 'Experiment',
716 714 'object': experiment,
717 715 'delete': True
718 716 }
719 717
720 718 return render(request, 'confirm.html', kwargs)
721 719
722 720
723 721 @login_required
724 722 def experiment_export(request, id_exp):
725 723
726 724 experiment = get_object_or_404(Experiment, pk=id_exp)
727 725 content = experiment.parms_to_dict()
728 726 content_type = 'application/json'
729 727 filename = '%s_%s.json' % (experiment.name, experiment.id)
730 728
731 729 response = HttpResponse(content_type=content_type)
732 730 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
733 731 response.write(json.dumps(content, indent=2))
734 732
735 733 return response
736 734
737 735
738 736 @login_required
739 737 def experiment_import(request, id_exp):
740 738
741 739 experiment = get_object_or_404(Experiment, pk=id_exp)
742 740 configurations = Configuration.objects.filter(experiment=experiment)
743 741
744 742 if request.method == 'GET':
745 743 file_form = UploadFileForm()
746 744
747 745 if request.method == 'POST':
748 746 file_form = UploadFileForm(request.POST, request.FILES)
749 747
750 748 if file_form.is_valid():
751 749 new_exp = experiment.dict_to_parms(
752 750 json.load(request.FILES['file']), CONF_MODELS)
753 751 messages.success(
754 752 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
755 753 return redirect(new_exp.get_absolute_url_edit())
756 754
757 755 messages.error(request, "Could not import parameters from file")
758 756
759 757 kwargs = {}
760 758 kwargs['title'] = 'Experiment'
761 759 kwargs['form'] = file_form
762 760 kwargs['suptitle'] = 'Importing file'
763 761 kwargs['button'] = 'Import'
764 762 kwargs['menu_experiments'] = 'active'
765 763
766 764 kwargs.update(sidebar(experiment=experiment))
767 765
768 766 return render(request, 'experiment_import.html', kwargs)
769 767
770 768
771 769 @login_required
772 770 def experiment_start(request, id_exp):
773 771
774 772 exp = get_object_or_404(Experiment, pk=id_exp)
775 773
776 774 if exp.status == 2:
777 775 messages.warning(request, 'Experiment {} already runnnig'.format(exp))
778 776 else:
779 777 exp.status = exp.start()
780 778 if exp.status == 0:
781 779 messages.error(request, 'Experiment {} not start'.format(exp))
782 780 if exp.status == 2:
783 781 messages.success(request, 'Experiment {} started'.format(exp))
784 782
785 783 exp.save()
786 784
787 785 return redirect(exp.get_absolute_url())
788 786
789 787
790 788 @login_required
791 789 def experiment_stop(request, id_exp):
792 790
793 791 exp = get_object_or_404(Experiment, pk=id_exp)
794 792
795 793 if exp.status == 2:
796 794 exp.status = exp.stop()
797 795 exp.save()
798 796 messages.success(request, 'Experiment {} stopped'.format(exp))
799 797 else:
800 798 messages.error(request, 'Experiment {} not running'.format(exp))
801 799
802 800 return redirect(exp.get_absolute_url())
803 801
804 802
805 803 def experiment_status(request, id_exp):
806 804
807 805 exp = get_object_or_404(Experiment, pk=id_exp)
808 806
809 807 exp.get_status()
810 808
811 809 return redirect(exp.get_absolute_url())
812 810
813 811
814 812 @login_required
815 813 def experiment_mix(request, id_exp):
816 814
817 815 experiment = get_object_or_404(Experiment, pk=id_exp)
818 816 rc_confs = [conf for conf in PedestalConfiguration.objects.filter(
819 817 experiment=id_exp,
820 818 type=0,
821 819 mix=False)]
822 820
823 821 if len(rc_confs) < 2:
824 822 messages.warning(
825 823 request, 'You need at least two RC Configurations to make a mix')
826 824 return redirect(experiment.get_absolute_url())
827 825
828 826 mix_confs = PedestalConfiguration.objects.filter(experiment=id_exp, mix=True, type=0)
829 827
830 828 if mix_confs:
831 829 mix = mix_confs[0]
832 830 else:
833 831 mix = PedestalConfiguration(experiment=experiment,
834 832 device=rc_confs[0].device,
835 833 ipp=rc_confs[0].ipp,
836 834 clock_in=rc_confs[0].clock_in,
837 835 clock_divider=rc_confs[0].clock_divider,
838 836 mix=True,
839 837 parameters='')
840 838 mix.save()
841 839
842 840 line_type = RCLineType.objects.get(name='mix')
843 841 print("VIew obteniendo len getlines")
844 842 print(len(rc_confs[0].get_lines()))
845 843 for i in range(len(rc_confs[0].get_lines())):
846 844 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
847 845 line.save()
848 846
849 847 initial = {'name': mix.name,
850 848 'result': parse_mix_result(mix.parameters),
851 849 'delay': 0,
852 850 'mask': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
853 851 }
854 852
855 853 if request.method == 'GET':
856 854 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
857 855
858 856 if request.method == 'POST':
859 857 result = mix.parameters
860 858
861 859 if '{}|'.format(request.POST['experiment']) in result:
862 860 messages.error(request, 'Configuration already added')
863 861 else:
864 862 if 'operation' in request.POST:
865 863 operation = MIX_OPERATIONS[request.POST['operation']]
866 864 else:
867 865 operation = ' '
868 866
869 867 mode = MIX_MODES[request.POST['mode']]
870 868
871 869 if result:
872 870 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
873 871 request.POST['experiment'],
874 872 mode,
875 873 operation,
876 874 float(
877 875 request.POST['delay']),
878 876 parse_mask(
879 877 request.POST.getlist('mask'))
880 878 )
881 879 else:
882 880 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
883 881 mode,
884 882 operation,
885 883 float(request.POST['delay']),
886 884 parse_mask(
887 885 request.POST.getlist('mask'))
888 886 )
889 887
890 888 mix.parameters = result
891 889 mix.save()
892 890 mix.update_pulses()
893 891
894 892 initial['result'] = parse_mix_result(result)
895 893 initial['name'] = mix.name
896 894
897 895 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
898 896
899 897 kwargs = {
900 898 'title': 'Experiment',
901 899 'suptitle': 'Mix Configurations',
902 900 'form': form,
903 901 'extra_button': 'Delete',
904 902 'button': 'Add',
905 903 'cancel': 'Back',
906 904 'previous': experiment.get_absolute_url(),
907 905 'id_exp': id_exp,
908 906
909 907 }
910 908 kwargs['menu_experiments'] = 'active'
911 909
912 910 return render(request, 'experiment_mix.html', kwargs)
913 911
914 912
915 913 @login_required
916 914 def experiment_mix_delete(request, id_exp):
917 915
918 916 conf = PedestalConfiguration.objects.get(experiment=id_exp, mix=True, type=0)
919 917 values = conf.parameters.split('-')
920 918 conf.parameters = '-'.join(values[:-1])
921 919 conf.save()
922 920
923 921 return redirect('url_mix_experiment', id_exp=id_exp)
924 922
925 923
926 924 def experiment_summary(request, id_exp):
927 925
928 926 experiment = get_object_or_404(Experiment, pk=id_exp)
929 927 configurations = Configuration.objects.filter(
930 928 experiment=experiment, type=0)
931 929
932 930 kwargs = {}
933 931 kwargs['experiment_keys'] = ['radar_system',
934 932 'name', 'freq', 'start_time', 'end_time']
935 933 kwargs['experiment'] = experiment
936 934 kwargs['configurations'] = []
937 935 kwargs['title'] = 'Experiment Summary'
938 936 kwargs['suptitle'] = 'Details'
939 937 kwargs['button'] = 'Verify Parameters'
940 938
941 939 c_vel = 3.0*(10**8) # m/s
942 940 ope_freq = experiment.freq*(10**6) # 1/s
943 941 radar_lambda = c_vel/ope_freq # m
944 942 kwargs['radar_lambda'] = radar_lambda
945 943
946 944 ipp = None
947 945 nsa = 1
948 946 code_id = 0
949 947 tx_line = {}
950 948
951 949 for configuration in configurations.filter(device__device_type__name = 'pedestal'):
952 950
953 951 if configuration.mix:
954 952 continue
955 953 conf = {'conf': configuration}
956 954 conf['keys'] = []
957 955 conf['NTxs'] = configuration.ntx
958 956 conf['keys'].append('NTxs')
959 957 ipp = configuration.ipp
960 958 conf['IPP'] = ipp
961 959 conf['keys'].append('IPP')
962 960 lines = configuration.get_lines(line_type__name='tx')
963 961
964 962 for tx_line in lines:
965 963 tx_params = json.loads(tx_line.params)
966 964 conf[tx_line.get_name()] = '{} Km'.format(tx_params['pulse_width'])
967 965 conf['keys'].append(tx_line.get_name())
968 966 delays = tx_params['delays']
969 967 if delays not in ('', '0'):
970 968 n = len(delays.split(','))
971 969 taus = '{} Taus: {}'.format(n, delays)
972 970 else:
973 971 taus = '-'
974 972 conf['Taus ({})'.format(tx_line.get_name())] = taus
975 973 conf['keys'].append('Taus ({})'.format(tx_line.get_name()))
976 974 for code_line in configuration.get_lines(line_type__name='codes'):
977 975 code_params = json.loads(code_line.params)
978 976 code_id = code_params['code']
979 977 if tx_line.pk == int(code_params['TX_ref']):
980 978 conf['Code ({})'.format(tx_line.get_name())] = '{}:{}'.format(RCLineCode.objects.get(pk=code_params['code']),
981 979 '-'.join(code_params['codes']))
982 980 conf['keys'].append('Code ({})'.format(tx_line.get_name()))
983 981
984 982 for windows_line in configuration.get_lines(line_type__name='windows'):
985 983 win_params = json.loads(windows_line.params)
986 984 if tx_line.pk == int(win_params['TX_ref']):
987 985 windows = ''
988 986 nsa = win_params['params'][0]['number_of_samples']
989 987 for i, params in enumerate(win_params['params']):
990 988 windows += 'W{}: Ho={first_height} km DH={resolution} km NSA={number_of_samples}<br>'.format(
991 989 i, **params)
992 990 conf['Window'] = mark_safe(windows)
993 991 conf['keys'].append('Window')
994 992
995 993 kwargs['configurations'].append(conf)
996 994
997 995 for configuration in configurations.filter(device__device_type__name = 'jars'):
998 996
999 997 conf = {'conf': configuration}
1000 998 conf['keys'] = []
1001 999 conf['Type of Data'] = EXPERIMENT_TYPE[configuration.exp_type][1]
1002 1000 conf['keys'].append('Type of Data')
1003 1001 channels_number = configuration.channels_number
1004 1002 exp_type = configuration.exp_type
1005 1003 fftpoints = configuration.fftpoints
1006 1004 filter_parms = json.loads(configuration.filter_parms)
1007 1005 spectral_number = configuration.spectral_number
1008 1006 acq_profiles = configuration.acq_profiles
1009 1007 cohe_integr = configuration.cohe_integr
1010 1008 profiles_block = configuration.profiles_block
1011 1009
1012 1010 conf['Num of Profiles'] = acq_profiles
1013 1011 conf['keys'].append('Num of Profiles')
1014 1012
1015 1013 conf['Prof per Block'] = profiles_block
1016 1014 conf['keys'].append('Prof per Block')
1017 1015
1018 1016 conf['Blocks per File'] = configuration.raw_data_blocks
1019 1017 conf['keys'].append('Blocks per File')
1020 1018
1021 1019 if exp_type == 0: # Short
1022 1020 bytes_ = 2
1023 1021 b = nsa*2*bytes_*channels_number
1024 1022 else: # Float
1025 1023 bytes_ = 4
1026 1024 channels = channels_number + spectral_number
1027 1025 b = nsa*2*bytes_*fftpoints*channels
1028 1026
1029 1027 codes_num = 7
1030 1028 if code_id == 2:
1031 1029 codes_num = 7
1032 1030 elif code_id == 12:
1033 1031 codes_num = 15
1034 1032
1035 1033 #Jars filter values:
1036 1034
1037 1035 clock = float(filter_parms['clock'])
1038 1036 filter_2 = int(filter_parms['cic_2'])
1039 1037 filter_5 = int(filter_parms['cic_5'])
1040 1038 filter_fir = int(filter_parms['fir'])
1041 1039 Fs_MHz = clock/(filter_2*filter_5*filter_fir)
1042 1040
1043 1041 #Jars values:
1044 1042 if ipp is not None:
1045 1043 IPP_units = ipp/0.15*Fs_MHz
1046 1044 IPP_us = IPP_units / Fs_MHz
1047 1045 IPP_s = IPP_units / (Fs_MHz * (10**6))
1048 1046 Ts = 1/(Fs_MHz*(10**6))
1049 1047
1050 1048 Va = radar_lambda/(4*Ts*cohe_integr)
1051 1049 rate_bh = ((nsa-codes_num)*channels_number*2 *
1052 1050 bytes_/IPP_us)*(36*(10**8)/cohe_integr)
1053 1051 rate_gh = rate_bh/(1024*1024*1024)
1054 1052
1055 1053 conf['Time per Block'] = IPP_s * profiles_block * cohe_integr
1056 1054 conf['keys'].append('Time per Block')
1057 1055 conf['Acq time'] = IPP_s * acq_profiles
1058 1056 conf['keys'].append('Acq time')
1059 1057 conf['Data rate'] = str(rate_gh)+" (GB/h)"
1060 1058 conf['keys'].append('Data rate')
1061 1059 conf['Va (m/s)'] = Va
1062 1060 conf['keys'].append('Va (m/s)')
1063 1061 conf['Vrange (m/s)'] = 3/(2*IPP_s*cohe_integr)
1064 1062 conf['keys'].append('Vrange (m/s)')
1065 1063
1066 1064 kwargs['configurations'].append(conf)
1067 1065 kwargs['menu_experiments'] = 'active'
1068 1066
1069 1067 ###### SIDEBAR ######
1070 1068 kwargs.update(sidebar(experiment=experiment))
1071 1069
1072 1070 return render(request, 'experiment_summary.html', kwargs)
1073 1071
1074 1072
1075 1073 @login_required
1076 1074 def experiment_verify(request, id_exp):
1077 1075
1078 1076 experiment = get_object_or_404(Experiment, pk=id_exp)
1079 1077 experiment_data = experiment.parms_to_dict()
1080 1078 configurations = Configuration.objects.filter(
1081 1079 experiment=experiment, type=0)
1082 1080
1083 1081 kwargs = {}
1084 1082
1085 1083 kwargs['experiment_keys'] = ['template',
1086 1084 'radar_system', 'name', 'start_time', 'end_time']
1087 1085 kwargs['experiment'] = experiment
1088 1086
1089 1087 kwargs['configuration_keys'] = ['name', 'device__ip_address',
1090 1088 'device__port_address', 'device__status']
1091 1089 kwargs['configurations'] = configurations
1092 1090 kwargs['experiment_data'] = experiment_data
1093 1091
1094 1092 kwargs['title'] = 'Verify Experiment'
1095 1093 kwargs['suptitle'] = 'Parameters'
1096 1094
1097 1095 kwargs['button'] = 'Update'
1098 1096
1099 1097 jars_conf = False
1100 1098 rc_conf = False
1101 1099 dds_conf = False
1102 1100
1103 1101 for configuration in configurations:
1104 1102 #-------------------- JARS -----------------------:
1105 1103 if configuration.device.device_type.name == 'jars':
1106 1104 jars_conf = True
1107 1105 jars = configuration
1108 1106 kwargs['jars_conf'] = jars_conf
1109 1107 filter_parms = json.loads(jars.filter_parms)
1110 1108 kwargs['filter_parms'] = filter_parms
1111 1109 #--Sampling Frequency
1112 1110 clock = filter_parms['clock']
1113 1111 filter_2 = filter_parms['cic_2']
1114 1112 filter_5 = filter_parms['cic_5']
1115 1113 filter_fir = filter_parms['fir']
1116 1114 samp_freq_jars = clock/filter_2/filter_5/filter_fir
1117 1115
1118 1116 kwargs['samp_freq_jars'] = samp_freq_jars
1119 1117 kwargs['jars'] = configuration
1120 1118
1121 1119 #--------------------- RC ----------------------:
1122 1120 if configuration.device.device_type.name == 'pedestal' and not configuration.mix:
1123 1121 rc_conf = True
1124 1122 rc = configuration
1125 1123
1126 1124 rc_parms = configuration.parms_to_dict()
1127 1125
1128 1126 win_lines = rc.get_lines(line_type__name='windows')
1129 1127 if win_lines:
1130 1128 dh = json.loads(win_lines[0].params)['params'][0]['resolution']
1131 1129 #--Sampling Frequency
1132 1130 samp_freq_rc = 0.15/dh
1133 1131 kwargs['samp_freq_rc'] = samp_freq_rc
1134 1132
1135 1133 kwargs['rc_conf'] = rc_conf
1136 1134 kwargs['rc'] = configuration
1137 1135
1138 1136 #-------------------- DDS ----------------------:
1139 1137 if configuration.device.device_type.name == 'dds':
1140 1138 dds_conf = True
1141 1139 dds = configuration
1142 1140 dds_parms = configuration.parms_to_dict()
1143 1141
1144 1142 kwargs['dds_conf'] = dds_conf
1145 1143 kwargs['dds'] = configuration
1146 1144
1147 1145 #------------Validation------------:
1148 1146 #Clock
1149 1147 if dds_conf and rc_conf and jars_conf:
1150 1148 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) and float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1151 1149 messages.warning(request, "Devices don't have the same clock.")
1152 1150 elif rc_conf and jars_conf:
1153 1151 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']):
1154 1152 messages.warning(request, "Devices don't have the same clock.")
1155 1153 elif rc_conf and dds_conf:
1156 1154 if float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1157 1155 messages.warning(request, "Devices don't have the same clock.")
1158 1156 if float(samp_freq_rc) != float(dds_parms['configurations']['byId'][str(dds.pk)]['frequencyA']):
1159 1157 messages.warning(
1160 1158 request, "Devices don't have the same Frequency A.")
1161 1159
1162 1160 #------------POST METHOD------------:
1163 1161 if request.method == 'POST':
1164 1162 if request.POST['suggest_clock']:
1165 1163 try:
1166 1164 suggest_clock = float(request.POST['suggest_clock'])
1167 1165 except:
1168 1166 messages.warning(request, "Invalid value in CLOCK IN.")
1169 1167 return redirect('url_verify_experiment', id_exp=experiment.id)
1170 1168 else:
1171 1169 suggest_clock = ""
1172 1170 if suggest_clock:
1173 1171 if rc_conf:
1174 1172 rc.clock_in = suggest_clock
1175 1173 rc.save()
1176 1174 if jars_conf:
1177 1175 filter_parms = jars.filter_parms
1178 1176 filter_parms = ast.literal_eval(filter_parms)
1179 1177 filter_parms['clock'] = suggest_clock
1180 1178 jars.filter_parms = json.dumps(filter_parms)
1181 1179 jars.save()
1182 1180 kwargs['filter_parms'] = filter_parms
1183 1181 if dds_conf:
1184 1182 dds.clock = suggest_clock
1185 1183 dds.save()
1186 1184
1187 1185 if request.POST['suggest_frequencyA']:
1188 1186 try:
1189 1187 suggest_frequencyA = float(request.POST['suggest_frequencyA'])
1190 1188 except:
1191 1189 messages.warning(request, "Invalid value in FREQUENCY A.")
1192 1190 return redirect('url_verify_experiment', id_exp=experiment.id)
1193 1191 else:
1194 1192 suggest_frequencyA = ""
1195 1193 if suggest_frequencyA:
1196 1194 if jars_conf:
1197 1195 filter_parms = jars.filter_parms
1198 1196 filter_parms = ast.literal_eval(filter_parms)
1199 1197 filter_parms['fch'] = suggest_frequencyA
1200 1198 jars.filter_parms = json.dumps(filter_parms)
1201 1199 jars.save()
1202 1200 kwargs['filter_parms'] = filter_parms
1203 1201 if dds_conf:
1204 1202 dds.frequencyA_Mhz = request.POST['suggest_frequencyA']
1205 1203 dds.save()
1206 1204
1207 1205 kwargs['menu_experiments'] = 'active'
1208 1206 kwargs.update(sidebar(experiment=experiment))
1209 1207 return render(request, 'experiment_verify.html', kwargs)
1210 1208
1211 1209
1212 1210 def parse_mix_result(s):
1213 1211
1214 1212 values = s.split('-')
1215 1213 html = 'EXP MOD OPE DELAY MASK\r\n'
1216 1214
1217 1215 if not values or values[0] in ('', ' '):
1218 1216 return mark_safe(html)
1219 1217
1220 1218 for i, value in enumerate(values):
1221 1219 if not value:
1222 1220 continue
1223 1221 pk, mode, operation, delay, mask = value.split('|')
1224 1222 conf = PedestalConfiguration.objects.get(pk=pk)
1225 1223 if i == 0:
1226 1224 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1227 1225 conf.name,
1228 1226 mode,
1229 1227 ' ',
1230 1228 delay,
1231 1229 mask)
1232 1230 else:
1233 1231 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1234 1232 conf.name,
1235 1233 mode,
1236 1234 operation,
1237 1235 delay,
1238 1236 mask)
1239 1237
1240 1238 return mark_safe(html)
1241 1239
1242 1240
1243 1241 def parse_mask(l):
1244 1242
1245 1243 values = []
1246 1244
1247 1245 for x in range(16):
1248 1246 if '{}'.format(x) in l:
1249 1247 values.append(1)
1250 1248 else:
1251 1249 values.append(0)
1252 1250
1253 1251 values.reverse()
1254 1252
1255 1253 return int(''.join([str(x) for x in values]), 2)
1256 1254
1257 1255
1258 1256 def dev_confs(request):
1259 1257
1260 1258 page = request.GET.get('page')
1261 1259 order = ('-programmed_date', )
1262 1260 filters = request.GET.copy()
1263 1261 if 'my configurations' in filters:
1264 1262 filters.pop('my configurations', None)
1265 1263 filters['mine'] = request.user.id
1266 1264 kwargs = get_paginator(Configuration, page, order, filters)
1267 1265 fields = ['tags', 'template', 'historical']
1268 1266 if request.user.is_authenticated:
1269 1267 fields.append('my configurations')
1270 1268 form = FilterForm(initial=request.GET, extra_fields=fields)
1271 1269 kwargs['keys'] = ['name', 'device', 'experiment',
1272 1270 'type', 'programmed_date', 'actions']
1273 1271 kwargs['title'] = 'Configuration'
1274 1272 kwargs['suptitle'] = 'List'
1275 1273 kwargs['no_sidebar'] = True
1276 1274 kwargs['form'] = form
1277 1275 kwargs['add_url'] = reverse('url_add_dev_conf', args=[0])
1278 1276 filters = request.GET.copy()
1279 1277 filters.pop('page', None)
1280 1278 kwargs['q'] = urlencode(filters)
1281 1279 kwargs['menu_configurations'] = 'active'
1282 1280
1283 1281 return render(request, 'base_list.html', kwargs)
1284 1282
1285 1283
1286 1284 def dev_conf(request, id_conf):
1287 1285
1288 1286 conf = get_object_or_404(Configuration, pk=id_conf)
1289 1287
1290 1288 return redirect(conf.get_absolute_url())
1291 1289
1292 1290
1293 1291 @login_required
1294 1292 def dev_conf_new(request, id_exp=0, id_dev=0):
1295 1293
1296 1294 if not is_developer(request.user):
1297 1295 messages.error(
1298 1296 request, 'Developer required, to create new configurations')
1299 1297 return redirect('index')
1300 1298
1301 1299 initial = {}
1302 1300 kwargs = {}
1303 1301
1304 1302 if id_exp != 0:
1305 1303 initial['experiment'] = id_exp
1306 1304
1307 1305 if id_dev != 0:
1308 1306 initial['device'] = id_dev
1309 1307
1310 1308 if request.method == 'GET':
1311 1309
1312 1310 if id_dev:
1313 1311 kwargs['button'] = 'Create'
1314 1312 device = Device.objects.get(pk=id_dev)
1315 1313 DevConfForm = CONF_FORMS[device.device_type.name]
1316 1314 initial['name'] = request.GET['name']
1317 1315 form = DevConfForm(initial=initial)
1318 1316 else:
1319 1317 if 'template' in request.GET:
1320 1318 if request.GET['template'] == '0':
1321 1319 choices = [(conf.pk, '{}'.format(conf))
1322 1320 for conf in Configuration.objects.filter(template=True)]
1323 1321 form = NewForm(initial={'create_from': 2},
1324 1322 template_choices=choices)
1325 1323 else:
1326 1324 kwargs['button'] = 'Create'
1327 1325 conf = Configuration.objects.get(
1328 1326 pk=request.GET['template'])
1329 1327 id_dev = conf.device.pk
1330 1328 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1331 1329 form = DevConfForm(instance=conf,
1332 1330 initial={'name': '{}_{:%y%m%d}'.format(conf.name, datetime.now()),
1333 1331 'template': False,
1334 1332 'experiment': id_exp})
1335 1333 elif 'blank' in request.GET:
1336 1334 kwargs['button'] = 'Create'
1337 1335 form = ConfigurationForm(initial=initial)
1338 1336 else:
1339 1337 form = NewForm()
1340 1338
1341 1339 if request.method == 'POST':
1342 1340
1343 1341 device = Device.objects.get(pk=request.POST['device'])
1344 1342 DevConfForm = CONF_FORMS[device.device_type.name]
1345 1343
1346 1344 form = DevConfForm(request.POST)
1347 1345 kwargs['button'] = 'Create'
1348 1346 if form.is_valid():
1349 1347 conf = form.save(commit=False)
1350 1348 conf.author = request.user
1351 1349 conf.save()
1352 1350 return redirect('url_dev_conf', id_conf=conf.pk)
1353 1351
1354 1352 kwargs['id_exp'] = id_exp
1355 1353 kwargs['form'] = form
1356 1354 kwargs['title'] = 'Configuration'
1357 1355 kwargs['suptitle'] = 'New'
1358 1356 kwargs['menu_configurations'] = 'active'
1359 1357
1360 1358 if id_dev != 0:
1361 1359 device = Device.objects.get(pk=id_dev)
1362 1360 kwargs['device'] = device.device_type.name
1363 1361 return render(request, 'dev_conf_edit.html', kwargs)
1364 1362
1365 1363
1366 1364 @login_required
1367 1365 def dev_conf_edit(request, id_conf):
1368 1366
1369 1367 conf = get_object_or_404(Configuration, pk=id_conf)
1370 1368
1371 1369 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1372 1370
1373 1371 if request.method == 'GET':
1374 1372 form = DevConfForm(instance=conf)
1375 1373
1376 1374 if request.method == 'POST':
1377 1375 form = DevConfForm(request.POST, instance=conf)
1378 1376
1379 1377 if form.is_valid():
1380 1378 form.save()
1381 1379 return redirect('url_dev_conf', id_conf=id_conf)
1382 1380
1383 1381 kwargs = {}
1384 1382 kwargs['form'] = form
1385 1383 kwargs['title'] = 'Device Configuration'
1386 1384 kwargs['suptitle'] = 'Edit'
1387 1385 kwargs['button'] = 'Update'
1388 1386 kwargs['menu_configurations'] = 'active'
1389 1387
1390 1388 ###### SIDEBAR ######
1391 1389 kwargs.update(sidebar(conf=conf))
1392 1390
1393 1391 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1394 1392
1395 1393
1396 1394 @login_required
1397 1395 def dev_conf_start(request, id_conf):
1398 1396
1399 1397 conf = get_object_or_404(Configuration, pk=id_conf)
1400 1398
1401 1399 if conf.start_device():
1402 1400 messages.success(request, conf.message)
1403 1401 else:
1404 1402 messages.error(request, conf.message)
1405 1403
1406 1404 #conf.status_device()
1407 1405
1408 1406 return redirect(conf.get_absolute_url())
1409 1407
1410 1408
1411 1409 @login_required
1412 1410 def dev_conf_stop(request, id_conf):
1413 1411
1414 1412 conf = get_object_or_404(Configuration, pk=id_conf)
1415 1413
1416 1414 if conf.stop_device():
1417 1415 messages.success(request, conf.message)
1418 1416 else:
1419 1417 messages.error(request, conf.message)
1420 1418
1421 1419 #conf.status_device()
1422 1420
1423 1421 return redirect(conf.get_absolute_url())
1424 1422
1425 1423
1426 1424 @login_required
1427 1425 def dev_conf_status(request, id_conf):
1428 1426
1429 1427 conf = get_object_or_404(Configuration, pk=id_conf)
1430 1428
1431 1429 conf_active = Configuration.objects.filter(pk=conf.device.conf_active).first()
1432 1430 if conf_active!=conf:
1433 1431 url = '#' if conf_active is None else conf_active.get_absolute_url()
1434 1432 label = 'None' if conf_active is None else conf_active.label
1435 1433 messages.warning(
1436 1434 request,
1437 1435 mark_safe('The current configuration has not been written to device, the active configuration is <a href="{}">{}</a>'.format(
1438 1436 url,
1439 1437 label
1440 1438 ))
1441 1439 )
1442 1440
1443 1441 return redirect(conf.get_absolute_url())
1444 1442
1445 1443 if conf.status_device():
1446 1444 messages.success(request, conf.message)
1447 1445 else:
1448 1446 messages.error(request, conf.message)
1449 1447
1450 1448 return redirect(conf.get_absolute_url())
1451 1449
1452 1450
1453 1451 @login_required
1454 1452 def dev_conf_reset(request, id_conf):
1455 1453
1456 1454 conf = get_object_or_404(Configuration, pk=id_conf)
1457 1455
1458 1456 if conf.reset_device():
1459 1457 messages.success(request, conf.message)
1460 1458 else:
1461 1459 messages.error(request, conf.message)
1462 1460
1463 1461 return redirect(conf.get_absolute_url())
1464 1462
1465 1463
1466 1464 @login_required
1467 1465 def dev_conf_write(request, id_conf):
1468 1466
1469 1467 conf = get_object_or_404(Configuration, pk=id_conf)
1470 1468
1471 1469 if request.method == 'POST':
1472 1470 if conf.write_device():
1473 1471 conf.device.conf_active = conf.pk
1474 1472 conf.device.save()
1475 1473 messages.success(request, conf.message)
1476 1474 if has_been_modified(conf):
1477 1475 conf.clone(type=1, template=False)
1478 1476 else:
1479 1477 messages.error(request, conf.message)
1480 1478
1481 1479 return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1482 1480
1483 1481 kwargs = {
1484 1482 'title': 'Write Configuration',
1485 1483 'suptitle': conf.label,
1486 1484 'message': 'Are you sure yo want to write this {} configuration?'.format(conf.device),
1487 1485 'delete': False
1488 1486 }
1489 1487 kwargs['menu_configurations'] = 'active'
1490 1488
1491 1489 return render(request, 'confirm.html', kwargs)
1492 1490
1493 1491
1494 1492 @login_required
1495 1493 def dev_conf_read(request, id_conf):
1496 1494
1497 1495 conf = get_object_or_404(Configuration, pk=id_conf)
1498 1496
1499 1497 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1500 1498
1501 1499 if request.method == 'GET':
1502 1500 parms = conf.read_device()
1503 1501 #conf.status_device()
1504 1502
1505 1503 if not parms:
1506 1504 messages.error(request, conf.message)
1507 1505 return redirect(conf.get_absolute_url())
1508 1506
1509 1507 form = DevConfForm(initial=parms, instance=conf)
1510 1508
1511 1509 if request.method == 'POST':
1512 1510 form = DevConfForm(request.POST, instance=conf)
1513 1511
1514 1512 if form.is_valid():
1515 1513 form.save()
1516 1514 return redirect(conf.get_absolute_url())
1517 1515
1518 1516 messages.error(request, "Parameters could not be saved")
1519 1517
1520 1518 kwargs = {}
1521 1519 kwargs['id_dev'] = conf.id
1522 1520 kwargs['form'] = form
1523 1521 kwargs['title'] = 'Device Configuration'
1524 1522 kwargs['suptitle'] = 'Parameters read from device'
1525 1523 kwargs['button'] = 'Save'
1526 1524
1527 1525 ###### SIDEBAR ######
1528 1526 kwargs.update(sidebar(conf=conf))
1529 1527
1530 1528 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1531 1529
1532 1530
1533 1531 @login_required
1534 1532 def dev_conf_import(request, id_conf):
1535 1533
1536 1534 conf = get_object_or_404(Configuration, pk=id_conf)
1537 1535 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1538 1536
1539 1537 if request.method == 'GET':
1540 1538 file_form = UploadFileForm()
1541 1539
1542 1540 if request.method == 'POST':
1543 1541 file_form = UploadFileForm(request.POST, request.FILES)
1544 1542
1545 1543 if file_form.is_valid():
1546 1544
1547 1545 data = conf.import_from_file(request.FILES['file'])
1548 1546 parms = Params(data=data).get_conf(
1549 1547 dtype=conf.device.device_type.name)
1550 1548
1551 1549 if parms:
1552 1550
1553 1551 form = DevConfForm(initial=parms, instance=conf)
1554 1552
1555 1553 kwargs = {}
1556 1554 kwargs['id_dev'] = conf.id
1557 1555 kwargs['form'] = form
1558 1556 kwargs['title'] = 'Device Configuration'
1559 1557 kwargs['suptitle'] = 'Parameters imported'
1560 1558 kwargs['button'] = 'Save'
1561 1559 kwargs['action'] = conf.get_absolute_url_edit()
1562 1560 kwargs['previous'] = conf.get_absolute_url()
1563 1561
1564 1562 ###### SIDEBAR ######
1565 1563 kwargs.update(sidebar(conf=conf))
1566 1564
1567 1565 messages.success(
1568 1566 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
1569 1567
1570 1568 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1571 1569
1572 1570 messages.error(request, "Could not import parameters from file")
1573 1571
1574 1572 kwargs = {}
1575 1573 kwargs['id_dev'] = conf.id
1576 1574 kwargs['title'] = 'Device Configuration'
1577 1575 kwargs['form'] = file_form
1578 1576 kwargs['suptitle'] = 'Importing file'
1579 1577 kwargs['button'] = 'Import'
1580 1578 kwargs['menu_configurations'] = 'active'
1581 1579
1582 1580 kwargs.update(sidebar(conf=conf))
1583 1581
1584 1582 return render(request, 'dev_conf_import.html', kwargs)
1585 1583
1586 1584
1587 1585 @login_required
1588 1586 def dev_conf_export(request, id_conf):
1589 1587
1590 1588 conf = get_object_or_404(Configuration, pk=id_conf)
1591 1589
1592 1590 if request.method == 'GET':
1593 1591 file_form = DownloadFileForm(conf.device.device_type.name)
1594 1592
1595 1593 if request.method == 'POST':
1596 1594 file_form = DownloadFileForm(
1597 1595 conf.device.device_type.name, request.POST)
1598 1596
1599 1597 if file_form.is_valid():
1600 1598 fields = conf.export_to_file(
1601 1599 format=file_form.cleaned_data['format'])
1602 1600 if not fields['content']:
1603 1601 messages.error(request, conf.message)
1604 1602 return redirect(conf.get_absolute_url_export())
1605 1603 response = HttpResponse(content_type=fields['content_type'])
1606 1604 response['Content-Disposition'] = 'attachment; filename="%s"' % fields['filename']
1607 1605 response.write(fields['content'])
1608 1606
1609 1607 return response
1610 1608
1611 1609 messages.error(request, "Could not export parameters")
1612 1610
1613 1611 kwargs = {}
1614 1612 kwargs['id_dev'] = conf.id
1615 1613 kwargs['title'] = 'Device Configuration'
1616 1614 kwargs['form'] = file_form
1617 1615 kwargs['suptitle'] = 'Exporting file'
1618 1616 kwargs['button'] = 'Export'
1619 1617 kwargs['menu_configurations'] = 'active'
1620 1618
1621 1619 return render(request, 'dev_conf_export.html', kwargs)
1622 1620
1623 1621
1624 1622 @login_required
1625 1623 def dev_conf_delete(request, id_conf):
1626 1624
1627 1625 conf = get_object_or_404(Configuration, pk=id_conf)
1628 1626
1629 1627 if request.method == 'POST':
1630 1628 if is_developer(request.user):
1631 1629 conf.delete()
1632 1630 return redirect('url_dev_confs')
1633 1631
1634 1632 messages.error(request, 'Not enough permission to delete this object')
1635 1633 return redirect(conf.get_absolute_url())
1636 1634
1637 1635 kwargs = {
1638 1636 'title': 'Delete',
1639 1637 'suptitle': 'Configuration',
1640 1638 'object': conf,
1641 1639 'delete': True
1642 1640 }
1643 1641 kwargs['menu_configurations'] = 'active'
1644 1642
1645 1643 return render(request, 'confirm.html', kwargs)
1646 1644
1647 1645
1648 1646 def sidebar(**kwargs):
1649 1647
1650 1648 side_data = {}
1651 1649
1652 1650 conf = kwargs.get('conf', None)
1653 1651 experiment = kwargs.get('experiment', None)
1654 1652
1655 1653 if not experiment:
1656 1654 experiment = conf.experiment
1657 1655
1658 1656 if experiment:
1659 1657 side_data['experiment'] = experiment
1660 1658 campaign = experiment.campaign_set.all()
1661 1659 if campaign:
1662 1660 side_data['campaign'] = campaign[0]
1663 1661 experiments = campaign[0].experiments.all().order_by('name')
1664 1662 else:
1665 1663 experiments = [experiment]
1666 1664 configurations = experiment.configuration_set.filter(type=0)
1667 1665 side_data['side_experiments'] = experiments
1668 1666 side_data['side_configurations'] = configurations.order_by(
1669 1667 'device__device_type__name')
1670 1668
1671 1669 return side_data
1672 1670
1673 1671
1674 1672 def get_paginator(model, page, order, filters={}, n=8):
1675 1673
1676 1674 kwargs = {}
1677 1675 query = Q()
1678 1676 if isinstance(filters, QueryDict):
1679 1677 filters = filters.dict()
1680 1678 [filters.pop(key) for key in list(filters) if filters[key] in ('', ' ')]
1681 1679 filters.pop('page', None)
1682 1680
1683 1681 fields = [f.name for f in model._meta.get_fields()]
1684 1682
1685 1683 if 'template' in filters:
1686 1684 filters['template'] = True
1687 1685 if 'historical' in filters:
1688 1686 filters.pop('historical')
1689 1687 filters['type'] = 1
1690 1688 elif 'type' in fields:
1691 1689 filters['type'] = 0
1692 1690 if 'start_date' in filters:
1693 1691 filters['start_date__gte'] = filters.pop('start_date')
1694 1692 if 'end_date' in filters:
1695 1693 filters['start_date__lte'] = filters.pop('end_date')
1696 1694 if 'tags' in filters:
1697 1695 tags = filters.pop('tags')
1698 1696 if 'tags' in fields:
1699 1697 query = query | Q(tags__icontains=tags)
1700 1698 if 'label' in fields:
1701 1699 query = query | Q(label__icontains=tags)
1702 1700 if 'location' in fields:
1703 1701 query = query | Q(location__name__icontains=tags)
1704 1702 if 'device' in fields:
1705 1703 query = query | Q(device__device_type__name__icontains=tags)
1706 1704 query = query | Q(device__location__name__icontains=tags)
1707 1705 if 'device_type' in fields:
1708 1706 query = query | Q(device_type__name__icontains=tags)
1709 1707
1710 1708 if 'mine' in filters:
1711 1709 filters['author_id'] = filters['mine']
1712 1710 filters.pop('mine')
1713 1711 object_list = model.objects.filter(query, **filters).order_by(*order)
1714 1712 paginator = Paginator(object_list, n)
1715 1713
1716 1714 try:
1717 1715 objects = paginator.page(page)
1718 1716 except PageNotAnInteger:
1719 1717 objects = paginator.page(1)
1720 1718 except EmptyPage:
1721 1719 objects = paginator.page(paginator.num_pages)
1722 1720
1723 1721 kwargs['objects'] = objects
1724 1722 kwargs['offset'] = (int(page)-1)*n if page else 0
1725 1723
1726 1724 return kwargs
1727 1725
1728 1726
1729 1727 def operation(request, id_camp=None):
1730 1728
1731 1729 kwargs = {}
1732 1730 kwargs['title'] = 'Radars Operation'
1733 1731 kwargs['no_sidebar'] = True
1734 1732 kwargs['menu_operation'] = 'active'
1735 1733 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1736 1734 end_date__gte=datetime.now()).order_by('-start_date')
1737 1735
1738 1736 if id_camp:
1739 1737 campaign = get_object_or_404(Campaign, pk=id_camp)
1740 1738 form = OperationForm(
1741 1739 initial={'campaign': campaign.id}, campaigns=campaigns)
1742 1740 kwargs['campaign'] = campaign
1743 1741 else:
1744 1742 # form = OperationForm(campaigns=campaigns)
1745 1743 kwargs['campaigns'] = campaigns
1746 1744 return render(request, 'operation.html', kwargs)
1747 1745
1748 1746 #---Experiment
1749 1747 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1750 1748 kwargs['experiment_keys'] = keys[1:]
1751 1749 kwargs['experiments'] = experiments
1752 1750 #---Radar
1753 1751 kwargs['locations'] = campaign.get_experiments_by_radar()
1754 1752 kwargs['form'] = form
1755 1753
1756 1754 return render(request, 'operation.html', kwargs)
1757 1755
1758 1756
1759 1757 @login_required
1760 1758 def radar_start(request, id_camp, id_radar):
1761 1759
1762 1760 campaign = get_object_or_404(Campaign, pk=id_camp)
1763 1761 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1764 1762 now = datetime.now()
1765 1763
1766 1764 for exp in experiments:
1767 1765 #app.control.revoke(exp.task)
1768 1766 print(exp.status)
1769 1767 start = datetime.combine(datetime.now().date(), exp.start_time)
1770 1768 end = datetime.combine(datetime.now().date(), exp.end_time)
1771 1769 print(exp.start_time)
1772 1770 print(exp.end_time)
1773 1771
1774 1772 print(start)
1775 1773 print(end)
1776 1774 print(is_aware(start))
1777 1775 print(campaign.start_date)
1778 1776 print(campaign.end_date)
1779 1777 print(is_aware(campaign.start_date))
1780 1778 if end < start:
1781 1779 end += timedelta(1)
1782 1780
1783 1781 if exp.status == 2:
1784 1782 messages.warning(
1785 1783 request, 'Experiment {} already running'.format(exp))
1786 1784 continue
1787 1785
1788 1786 if exp.status == 3:
1789 1787 messages.warning(
1790 1788 request, 'Experiment {} already programmed'.format(exp))
1791 1789 continue
1792 1790
1793 1791 if start > campaign.end_date or start < campaign.start_date:
1794 1792 messages.warning(request, 'Experiment {} out of date'.format(exp))
1795 1793 continue
1796 1794
1797 1795 app.control.revoke(exp.task)
1798 1796 print("Llego luego del revoke")
1799 1797 if now > start and now <= end:
1800 1798 print("Caso now >start and <end")
1801 1799 task = task_start.delay(exp.id)
1802 1800 exp.status = task.wait()
1803 1801 if exp.status == 0:
1804 1802 messages.error(request, 'Experiment {} not start'.format(exp))
1805 1803 if exp.status == 2:
1806 1804 messages.success(request, 'Experiment {} started'.format(exp))
1807 1805 else:
1808 1806 print("Caso now < start o >end")
1809 1807 task = task_start.apply_async((exp.pk, ), eta=start)#start+timedelta(hours=5))
1810 1808 exp.task = task.id
1811 1809 exp.status = 3
1812 1810 messages.success(request, 'Experiment {} programmed to start at {}'.format(exp, start))
1813 1811
1814 1812 exp.save()
1815 1813
1816 1814 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1817 1815
1818 1816
1819 1817 @login_required
1820 1818 def radar_stop(request, id_camp, id_radar):
1821 1819
1822 1820 campaign = get_object_or_404(Campaign, pk=id_camp)
1823 1821 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1824 1822 print("Ingreso en stop radar_stop")
1825 1823 for exp in experiments:
1826 1824
1827 1825 if exp.task:
1828 1826 print("Ingreso antes de revoke stop")
1829 1827 app.control.revoke(exp.task)
1830 1828
1831 1829
1832 1830 if exp.status == 2: #status 2 es started
1833 1831 print("llama a exp.stop")
1834 1832 exp.stop()
1835 1833 messages.warning(request, 'Experiment {} stopped'.format(exp))
1836 1834 exp.status = 1
1837 1835 exp.save()
1838 1836
1839 1837 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1840 1838
1841 1839
1842 1840 @login_required
1843 1841 def radar_refresh(request, id_camp, id_radar):
1844 1842
1845 1843 campaign = get_object_or_404(Campaign, pk=id_camp)
1846 1844 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1847 1845
1848 1846 i = app.control.inspect()
1849 1847 print(i)
1850 1848 print(i.scheduled())
1851 1849 print(i.scheduled().values())
1852 1850 scheduled = list(i.scheduled().values())[0]
1853 1851 revoked = list(i.revoked().values())[0]
1854 1852
1855 1853 for exp in experiments:
1856 1854 if exp.task in revoked:
1857 1855 exp.status = 1
1858 1856 elif exp.task in [t['request']['id'] for t in scheduled if 'task_stop' in t['request']['name']]:
1859 1857 exp.status = 2
1860 1858 elif exp.task in [t['request']['id'] for t in scheduled if 'task_start' in t['request']['name']]:
1861 1859 exp.status = 3
1862 1860 else:
1863 1861 exp.status = 4
1864 1862 exp.save()
1865 1863 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1866 1864
1867 1865 @login_required
1868 1866 def revoke_tasks(request, id_camp):
1869 1867
1870 1868 i = app.control.inspect()
1871 1869 scheduled = list(i.scheduled().values())[0]
1872 1870 revoked = list(i.revoked().values())[0]
1873 1871
1874 1872 for t in scheduled:
1875 1873 if t['request']['id'] in revoked:
1876 1874 continue
1877 1875 app.control.revoke(t['request']['id'])
1878 1876 exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
1879 1877 eta = t['eta']
1880 1878 task = t['request']['name'].split('.')[-1]
1881 1879 messages.warning(request, 'Scheduled {} at {} for experiment {} revoked'.format(task, eta, exp.name))
1882 1880
1883 1881 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1884 1882
1885 1883 @login_required
1886 1884 def show_tasks(request, id_camp):
1887 1885
1888 1886 i = app.control.inspect()
1889 1887 scheduled = list(i.scheduled().values())[0]
1890 1888 revoked = list(i.revoked().values())[0]
1891 1889
1892 1890 for t in scheduled:
1893 1891 if t['request']['id'] in revoked:
1894 1892 continue
1895 1893 exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
1896 1894 eta = t['eta']
1897 1895 task = t['request']['name'].split('.')[-1]
1898 1896 messages.success(request, 'Task {} scheduled at {} for experiment {}'.format(task, eta, exp.name))
1899 1897
1900 1898 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1901 1899
1902 1900 def real_time(request):
1903 1901
1904 1902 graphic_path = "/home/fiorella/Pictures/catwbeanie.jpg"
1905 1903
1906 1904 kwargs = {}
1907 1905 kwargs['title'] = 'CLAIRE'
1908 1906 kwargs['suptitle'] = 'Real Time'
1909 1907 kwargs['no_sidebar'] = True
1910 1908 kwargs['graphic_path'] = graphic_path
1911 1909 kwargs['graphic1_path'] = 'http://www.bluemaize.net/im/girls-accessories/shark-beanie-11.jpg'
1912 1910
1913 1911 return render(request, 'real_time.html', kwargs)
1914 1912
1915 1913 def theme(request, theme):
1916 1914
1917 1915 user = request.user
1918 1916 user.profile.theme = theme
1919 1917 user.save()
1920 1918 return redirect('index')
General Comments 0
You need to be logged in to leave comments. Login now