##// END OF EJS Templates
Update main app (view to mix RC configurations)...
Juan C. Espinoza -
r106:039a10d0c909
parent child
Show More
@@ -1,154 +1,155
1 1 from django import forms
2 2 from django.utils.safestring import mark_safe
3 3
4 4 from .models import DeviceType, Device, Experiment, Campaign, Configuration, Location
5 5
6 6 FILE_FORMAT = (
7 7 ('json', 'json'),
8 8 )
9 9
10 10 DDS_FILE_FORMAT = (
11 11 ('json', 'json'),
12 12 ('text', 'dds')
13 13 )
14 14
15 15 RC_FILE_FORMAT = (
16 16 ('json', 'json'),
17 17 ('text', 'racp'),
18 18 ('binary', 'dat'),
19 19 )
20 20
21 21 def add_empty_choice(choices, pos=0, label='-----'):
22 22 if len(choices)>0:
23 23 choices = list(choices)
24 24 choices.insert(0, (0, label))
25 25 return choices
26 26 else:
27 27 return [(0, label)]
28 28
29 29 class DatepickerWidget(forms.widgets.TextInput):
30 30 def render(self, name, value, attrs=None):
31 31 input_html = super(DatepickerWidget, self).render(name, value, attrs)
32 32 html = '<div class="input-group date">'+input_html+'<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span></div>'
33 33 return mark_safe(html)
34 34
35 35 class TimepickerWidget(forms.widgets.TextInput):
36 36 def render(self, name, value, attrs=None):
37 37 input_html = super(TimepickerWidget, self).render(name, value, attrs)
38 38 html = '<div class="input-group time">'+input_html+'<span class="input-group-addon"><i class="glyphicon glyphicon-time"></i></span></div>'
39 39 return mark_safe(html)
40 40
41 41 class CampaignForm(forms.ModelForm):
42 42
43 43 experiments = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(),
44 44 queryset=Experiment.objects.filter(template=True),
45 45 required=False)
46 46
47 47 def __init__(self, *args, **kwargs):
48 48 super(CampaignForm, self).__init__(*args, **kwargs)
49 49 self.fields['start_date'].widget = DatepickerWidget(self.fields['start_date'].widget.attrs)
50 50 self.fields['end_date'].widget = DatepickerWidget(self.fields['end_date'].widget.attrs)
51 51 self.fields['description'].widget.attrs = {'rows': 2}
52 52
53 if self.instance:
53 if self.instance.pk:
54 54 self.fields['experiments'].queryset |= self.instance.experiments.all()
55 55
56 56 class Meta:
57 57 model = Campaign
58 58 exclude = ['']
59
59 60
60 61 class ExperimentForm(forms.ModelForm):
61 62
62 63 def __init__(self, *args, **kwargs):
63 64 super(ExperimentForm, self).__init__(*args, **kwargs)
64 65 self.fields['start_time'].widget = TimepickerWidget(self.fields['start_time'].widget.attrs)
65 66 self.fields['end_time'].widget = TimepickerWidget(self.fields['end_time'].widget.attrs)
66 67
67 68 class Meta:
68 69 model = Experiment
69 70 exclude = ['status']
70 71
71 72 class LocationForm(forms.ModelForm):
72 73 class Meta:
73 74 model = Location
74 75 exclude = ['']
75 76
76 77 class DeviceForm(forms.ModelForm):
77 78 class Meta:
78 79 model = Device
79 80 exclude = ['status']
80 81
81 82 class ConfigurationForm(forms.ModelForm):
82 83
83 84 def __init__(self, *args, **kwargs):
84 85 super(ConfigurationForm, self).__init__(*args, **kwargs)
85 86
86 87 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
87 88 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
88 89
89 90 class Meta:
90 91 model = Configuration
91 92 exclude = ['type', 'created_date', 'programmed_date', 'parameters']
92 93
93 94 class DeviceTypeForm(forms.Form):
94 95 device_type = forms.ChoiceField(choices=add_empty_choice(DeviceType.objects.all().order_by('name').values_list('id', 'name')))
95 96
96 97
97 98 class UploadFileForm(forms.Form):
98 99
99 100 file = forms.FileField()
100 101
101 102 class DownloadFileForm(forms.Form):
102 103
103 104 format = forms.ChoiceField(choices= ((0, 'json'),) )
104 105
105 106 def __init__(self, device_type, *args, **kwargs):
106 107
107 108 super(DownloadFileForm, self).__init__(*args, **kwargs)
108 109
109 110 self.fields['format'].choices = FILE_FORMAT
110 111
111 112 if device_type == 'dds':
112 113 self.fields['format'].choices = DDS_FILE_FORMAT
113 114
114 115 if device_type == 'rc':
115 116 self.fields['format'].choices = RC_FILE_FORMAT
116 117
117 118 class OperationForm(forms.Form):
118 119 # today = datetime.today()
119 120 # -----Campaigns from this month------[:5]
120 121 campaign = forms.ChoiceField(label="Campaign")
121 122
122 123 def __init__(self, *args, **kwargs):
123 124
124 125 if 'length' not in kwargs.keys():
125 126 length = None
126 127 else:
127 128 length = kwargs['length']
128 129
129 130 kwargs.pop('length')
130 131
131 132 super(OperationForm, self).__init__(*args, **kwargs)
132 133 self.fields['campaign'].choices=Campaign.objects.all().order_by('-start_date').values_list('id', 'name')[:length]
133 134
134 135 class OperationSearchForm(forms.Form):
135 136 # -----ALL Campaigns------
136 137 campaign = forms.ChoiceField(label="Campaign")
137 138
138 139 def __init__(self, *args, **kwargs):
139 140 super(OperationSearchForm, self).__init__(*args, **kwargs)
140 141 self.fields['campaign'].choices=Campaign.objects.all().order_by('-start_date').values_list('id', 'name')
141 142
142 143 class NewForm(forms.Form):
143 144
144 145 create_from = forms.ChoiceField(choices=((0, '-----'),
145 146 (1, 'Empty (blank)'),
146 147 (2, 'Template')))
147 148 choose_template = forms.ChoiceField()
148 149
149 150 def __init__(self, *args, **kwargs):
150 151
151 152 template_choices = kwargs.pop('template_choices', [])
152 153 super(NewForm, self).__init__(*args, **kwargs)
153 154 self.fields['choose_template'].choices = add_empty_choice(template_choices)
154 155 No newline at end of file
@@ -1,452 +1,449
1 1 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
2 2 from datetime import datetime
3 3
4 4 from django.db import models
5 5 from polymorphic import PolymorphicModel
6 6
7 7 from django.core.urlresolvers import reverse
8 8
9 9 CONF_STATES = (
10 10 (0, 'Disconnected'),
11 11 (1, 'Connected'),
12 12 (2, 'Running'),
13 13 )
14 14
15 15 EXP_STATES = (
16 16 (0,'Error'), #RED
17 17 (1,'Configurated'), #BLUE
18 18 (2,'Running'), #GREEN
19 19 (3,'Waiting'), #YELLOW
20 20 (4,'Not Configured'), #WHITE
21 21 )
22 22
23 23 CONF_TYPES = (
24 24 (0, 'Active'),
25 25 (1, 'Historical'),
26 26 )
27 27
28 28 DEV_STATES = (
29 29 (0, 'No connected'),
30 30 (1, 'Connected'),
31 31 (2, 'Configured'),
32 32 (3, 'Running'),
33 33 )
34 34
35 35 DEV_TYPES = (
36 36 ('', 'Select a device type'),
37 37 ('rc', 'Radar Controller'),
38 ('rc_mix', 'Radar Controller (Mix)'),
38 39 ('dds', 'Direct Digital Synthesizer'),
39 40 ('jars', 'Jicamarca Radar Acquisition System'),
40 41 ('usrp', 'Universal Software Radio Peripheral'),
41 42 ('cgs', 'Clock Generator System'),
42 43 ('abs', 'Automatic Beam Switching'),
43 44 )
44 45
45 46 DEV_PORTS = {
46 47 'rc' : 2000,
48 'rc_mix': 2000,
47 49 'dds' : 2000,
48 50 'jars' : 2000,
49 51 'usrp' : 2000,
50 52 'cgs' : 8080,
51 53 'abs' : 8080
52 54 }
53 55
54 56 RADAR_STATES = (
55 57 (0, 'No connected'),
56 58 (1, 'Connected'),
57 59 (2, 'Configured'),
58 60 (3, 'Running'),
59 61 (4, 'Scheduled'),
60 62 )
61 63 # Create your models here.
62 64
63 65 class Location(models.Model):
64 66
65 67 name = models.CharField(max_length = 30)
66 68 description = models.TextField(blank=True, null=True)
67 69
68 70 class Meta:
69 71 db_table = 'db_location'
70 72
71 73 def __unicode__(self):
72 74 return u'%s' % self.name
73 75
74 76 def get_absolute_url(self):
75 77 return reverse('url_device', args=[str(self.id)])
76 78
77 79
78 80 class DeviceType(models.Model):
79 81
80 82 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc')
81 83 description = models.TextField(blank=True, null=True)
82 84
83 85 class Meta:
84 86 db_table = 'db_device_types'
85 87
86 88 def __unicode__(self):
87 89 return u'%s' % self.get_name_display()
88 90
89 91 class Device(models.Model):
90 92
91 93 device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
92 94 location = models.ForeignKey(Location, on_delete=models.CASCADE)
93 95
94 96 name = models.CharField(max_length=40, default='')
95 97 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
96 98 port_address = models.PositiveSmallIntegerField(default=2000)
97 99 description = models.TextField(blank=True, null=True)
98 100 status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES)
99 101
100 102 class Meta:
101 103 db_table = 'db_devices'
102 104
103 105 def __unicode__(self):
104 106 return u'%s | %s' % (self.name, self.ip_address)
105 107
106 108 def get_status(self):
107 109 return self.status
108 110
109 111 def get_absolute_url(self):
110 112 return reverse('url_device', args=[str(self.id)])
111 113
112 114
113 115 class Campaign(models.Model):
114 116
115 117 template = models.BooleanField(default=False)
116 118 name = models.CharField(max_length=60, unique=True)
117 119 start_date = models.DateTimeField(blank=True, null=True)
118 120 end_date = models.DateTimeField(blank=True, null=True)
119 121 tags = models.CharField(max_length=40)
120 122 description = models.TextField(blank=True, null=True)
121 123 experiments = models.ManyToManyField('Experiment', blank=True)
122 124
123 125 class Meta:
124 126 db_table = 'db_campaigns'
125 127 ordering = ('name',)
126 128
127 129 def __unicode__(self):
128 130 return u'%s' % (self.name)
129 131
130 132 def get_absolute_url(self):
131 133 return reverse('url_campaign', args=[str(self.id)])
132 134
133 135 def parms_to_dict(self):
134 136
135 137 import json
136 138
137 139 parameters = {}
138 140 exp_parameters = {}
139 141 experiments = Experiment.objects.filter(campaign = self)
140 142
141 143 i=1
142 144 for experiment in experiments:
143 145 exp_parameters['experiment-'+str(i)] = json.loads(experiment.parms_to_dict())
144 146 i += 1
145 147
146 148
147 149 parameters['experimets'] =exp_parameters
148 150 parameters['end_date'] = self.end_date.strftime("%Y-%m-%d")
149 151 parameters['start_date'] = self.start_date.strftime("%Y-%m-%d")
150 152 parameters['campaign'] = self.__unicode__()
151 153
152 154 parameters = json.dumps(parameters, indent=2, sort_keys=False)
153 155
154 156 return parameters
155 157
156 158 def get_absolute_url_export(self):
157 159 return reverse('url_export_campaign', args=[str(self.id)])
158 160
159 161
160 162
161 163 class RunningExperiment(models.Model):
162 164 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
163 165 running_experiment = models.ManyToManyField('Experiment', blank = True)
164 166 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
165 167
166 168
167 169 class Experiment(models.Model):
168 170
169 171 template = models.BooleanField(default=False)
170 172 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
171 173 name = models.CharField(max_length=40, default='', unique=True)
172 174 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
173 175 start_time = models.TimeField(default='00:00:00')
174 176 end_time = models.TimeField(default='23:59:59')
175 177 status = models.PositiveSmallIntegerField(default=0, choices=EXP_STATES)
176 178
177 179 class Meta:
178 180 db_table = 'db_experiments'
179 181 ordering = ('template', 'name')
180 182
181 183 def __unicode__(self):
182 184 if self.template:
183 185 return u'%s (template)' % (self.name)
184 186 else:
185 187 return u'%s' % (self.name)
186 188
187 189 @property
188 190 def radar(self):
189 191 return self.location
190 192
191 193 def clone(self, **kwargs):
192 194
193 195 confs = Configuration.objects.filter(experiment=self, type=0)
194 196 self.pk = None
195 197 self.name = '{} [{:%Y/%m/%d}]'.format(self.name, datetime.now())
196 198 for attr, value in kwargs.items():
197 199 setattr(self, attr, value)
198 200
199 201 self.save()
200 202
201 203 for conf in confs:
202 204 conf.clone(experiment=self, template=False)
203 205
204 206 return self
205 207
206 208 def get_status(self):
207 209 configurations = Configuration.objects.filter(experiment=self)
208 210 exp_status=[]
209 211 for conf in configurations:
210 212 print conf.status_device()
211 213 exp_status.append(conf.status_device())
212 214
213 215 if not exp_status: #No Configuration
214 216 self.status = 4
215 217 self.save()
216 218 return
217 219
218 220 total = 1
219 221 for e_s in exp_status:
220 222 total = total*e_s
221 223
222 224 if total == 0: #Error
223 225 status = 0
224 226 elif total == (3**len(exp_status)): #Running
225 227 status = 2
226 228 else:
227 229 status = 1 #Configurated
228 230
229 231 self.status = status
230 232 self.save()
231 233
232 234 def status_color(self):
233 235 color = 'danger'
234 236 if self.status == 0:
235 237 color = "danger"
236 238 elif self.status == 1:
237 239 color = "info"
238 240 elif self.status == 2:
239 241 color = "success"
240 242 elif self.status == 3:
241 243 color = "warning"
242 244 else:
243 245 color = "muted"
244 246
245 247 return color
246 248
247 249 def get_absolute_url(self):
248 250 return reverse('url_experiment', args=[str(self.id)])
249 251
250 252 def parms_to_dict(self):
251 253
252 254 import json
253 255
254 256 configurations = Configuration.objects.filter(experiment=self)
255 257 conf_parameters = {}
256 258 parameters={}
257 259
258 260 for configuration in configurations:
259 261 if 'cgs' in configuration.device.device_type.name:
260 262 conf_parameters['cgs'] = configuration.parms_to_dict()
261 263 if 'dds' in configuration.device.device_type.name:
262 264 conf_parameters['dds'] = configuration.parms_to_dict()
263 265 if 'rc' in configuration.device.device_type.name:
264 266 conf_parameters['rc'] = configuration.parms_to_dict()
265 267 if 'jars' in configuration.device.device_type.name:
266 268 conf_parameters['jars'] = configuration.parms_to_dict()
267 269 if 'usrp' in configuration.device.device_type.name:
268 270 conf_parameters['usrp'] = configuration.parms_to_dict()
269 271 if 'abs' in configuration.device.device_type.name:
270 272 conf_parameters['abs'] = configuration.parms_to_dict()
271 273
272 274 parameters['configurations'] = conf_parameters
273 275 parameters['end_time'] = self.end_time.strftime("%Y-%m-%d")
274 276 parameters['start_time'] = self.start_time.strftime("%Y-%m-%d")
275 277 parameters['radar'] = self.radar.name
276 278 parameters['experiment'] = self.name
277 279 parameters = json.dumps(parameters, indent=2)
278 280 #parameters = json.dumps(parameters)
279 281
280 282 return parameters
281 283
282 284 def get_absolute_url_export(self):
283 285 return reverse('url_export_experiment', args=[str(self.id)])
284 286
285 287
286 288 class Configuration(PolymorphicModel):
287 289
288 290 template = models.BooleanField(default=False)
289 291
290 292 name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
291 293
292 294 experiment = models.ForeignKey('Experiment', null=True, blank=True, on_delete=models.CASCADE)
293 device = models.ForeignKey(Device, on_delete=models.CASCADE)
295 device = models.ForeignKey(Device, null=True, on_delete=models.CASCADE)
294 296
295 297 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
296 298
297 299 created_date = models.DateTimeField(auto_now_add=True)
298 300 programmed_date = models.DateTimeField(auto_now=True)
299 301
300 302 parameters = models.TextField(default='{}')
301 303
302 304 message = ""
303 305
304 306 class Meta:
305 307 db_table = 'db_configurations'
306 308
307 309 def __unicode__(self):
308
309 if self.experiment:
310 return u'[%s, %s]: %s' % (self.experiment.name,
311 self.device.name,
312 self.name)
313 else:
314 return u'%s' % self.device.name
310
311 return u'[%s]: %s' % (self.device.name, self.name)
315 312
316 313 def clone(self, **kwargs):
317 314
318 315 self.pk = None
319 316 self.id = None
320 317 for attr, value in kwargs.items():
321 318 setattr(self, attr, value)
322 319
323 320 self.save()
324 321
325 322 return self
326 323
327 324 def parms_to_dict(self):
328 325
329 326 parameters = {}
330 327
331 328 for key in self.__dict__.keys():
332 329 parameters[key] = getattr(self, key)
333 330
334 331 return parameters
335 332
336 333 def parms_to_text(self):
337 334
338 335 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
339 336
340 337 return ''
341 338
342 339 def parms_to_binary(self):
343 340
344 341 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
345 342
346 343 return ''
347 344
348 345 def dict_to_parms(self, parameters):
349 346
350 347 if type(parameters) != type({}):
351 348 return
352 349
353 350 for key in parameters.keys():
354 351 setattr(self, key, parameters[key])
355 352
356 353 def export_to_file(self, format="json"):
357 354
358 355 import json
359 356
360 357 content_type = ''
361 358
362 359 if format == 'text':
363 360 content_type = 'text/plain'
364 361 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
365 362 content = self.parms_to_text()
366 363
367 364 if format == 'binary':
368 365 content_type = 'application/octet-stream'
369 366 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
370 367 content = self.parms_to_binary()
371 368
372 369 if not content_type:
373 370 content_type = 'application/json'
374 371 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
375 372 content = json.dumps(self.parms_to_dict(), indent=2)
376 373
377 374 fields = {'content_type':content_type,
378 375 'filename':filename,
379 376 'content':content
380 377 }
381 378
382 379 return fields
383 380
384 381 def import_from_file(self, fp):
385 382
386 383 import os, json
387 384
388 385 parms = {}
389 386
390 387 path, ext = os.path.splitext(fp.name)
391 388
392 389 if ext == '.json':
393 390 parms = json.load(fp)
394 391
395 392 return parms
396 393
397 394 def status_device(self):
398 395
399 396 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
400 397
401 398 return None
402 399
403 400 def stop_device(self):
404 401
405 402 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
406 403
407 404 return None
408 405
409 406 def start_device(self):
410 407
411 408 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
412 409
413 410 return None
414 411
415 412 def write_device(self, parms):
416 413
417 414 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
418 415
419 416 return None
420 417
421 418 def read_device(self):
422 419
423 420 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
424 421
425 422 return None
426 423
427 424 def get_absolute_url(self):
428 425 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
429 426
430 427 def get_absolute_url_edit(self):
431 428 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
432 429
433 430 def get_absolute_url_import(self):
434 431 return reverse('url_import_dev_conf', args=[str(self.id)])
435 432
436 433 def get_absolute_url_export(self):
437 434 return reverse('url_export_dev_conf', args=[str(self.id)])
438 435
439 436 def get_absolute_url_write(self):
440 437 return reverse('url_write_dev_conf', args=[str(self.id)])
441 438
442 439 def get_absolute_url_read(self):
443 440 return reverse('url_read_dev_conf', args=[str(self.id)])
444 441
445 442 def get_absolute_url_start(self):
446 443 return reverse('url_start_dev_conf', args=[str(self.id)])
447 444
448 445 def get_absolute_url_stop(self):
449 446 return reverse('url_stop_dev_conf', args=[str(self.id)])
450 447
451 448 def get_absolute_url_status(self):
452 449 return reverse('url_status_dev_conf', args=[str(self.id)]) No newline at end of file
@@ -1,108 +1,107
1 1 {% extends "base.html" %}
2 2 {% load bootstrap3 %}
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
9 9 {% block camp-active %}active{% endblock %}
10 10
11 11 {% block content-title %}{{title}}{% endblock %}
12 12 {% block content-suptitle %}{{suptitle}}{% endblock %}
13 13
14 14 {% block content %}
15 15
16 16 {% block menu-actions %}
17 17 <span class=" dropdown pull-right">
18 18 <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-menu-hamburger gi-2x" aria-hidden="true"></span></a>
19 19 <ul class="dropdown-menu" role="menu">
20 20 <li><a href="{% url 'url_edit_campaign' campaign.id %}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</a></li>
21 <li><a href="{% url 'url_delete_campaign' campaign.id %}"><span class="glyphicon glyphicon-remove-sign" aria-hidden="true"></span> Delete</a></li>
21 <li><a href="{% url 'url_delete_campaign' campaign.id %}"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Delete</a></li>
22 22 <li><a href="{{ dev_conf.get_absolute_url_import }}"><span class="glyphicon glyphicon-import" aria-hidden="true"></span> Import </a></li>
23 23 <li><a href="{{ campaign.get_absolute_url_export }}"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Export </a></li>
24 24 {% block extra-menu-actions %}
25 25 {% endblock %}
26 <li><a>----------------</a></li>
27 <li><a href="#"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> Mix Experiments</a></li>
26 <li><a>----------------</a></li>
28 27 <!--<li><a href="{{ dev_conf.get_absolute_url_status }}"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> Status</a></li>
29 28 {% if not no_play %}
30 29 <li><a href="{{ dev_conf.get_absolute_url_start}}"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Start</a></li>
31 30 <li><a href="{{ dev_conf.get_absolute_url_stop }}"><span class="glyphicon glyphicon-stop" aria-hidden="true"></span> Stop</a></li>
32 31 {% endif %}
33 32 <li><a href="{{ dev_conf.get_absolute_url_write }}"><span class="glyphicon glyphicon-download" aria-hidden="true"></span> Write</a></li>
34 33 <li><a href="{{ dev_conf.get_absolute_url_read }}"><span class="glyphicon glyphicon-upload" aria-hidden="true"></span> Read</a></li>-->
35 34 </ul>
36 35 </span>
37 36 {% endblock %}
38 37
39 38 <table class="table table-bordered">
40 39 {% for key in campaign_keys %}
41 40 <tr><th>{{key|title}}</th><td>{{campaign|attr:key}}</td></tr>
42 41 {% endfor %}
43 42 </table>
44 43
45 44 <!--<button class="btn btn-primary pull-right" style="margin-left: 10px" id="bt_export">Export</button>-->
46 45 <!--<button class="btn btn-primary pull-right" style="margin-left: 10px" id="bt_edit">Edit</button>-->
47 46
48 47 <br></br>
49 48 <br></br>
50 49
51 50 <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
52 51
53 52 <div class="panel panel-default">
54 53 <div class="panel-heading" role="tab" id="headingTwo">
55 54 <h4 class="panel-title">
56 55 <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
57 56 Experiment List
58 57 </a>
59 58 </h4>
60 59 </div>
61 60
62 61 <div id="collapseTwo" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingTwo">
63 62 <div class="panel-body">
64 63 <table class="table table-hover">
65 64 <tr>
66 65 <th>#</th>
67 66 {% for header in experiment_keys %}
68 67 <th>{{ header|title }}</th>
69 68 {% endfor%}
70 69 </tr>
71 70 {% for item in experiments %}
72 71 <tr class="clickable-row" data-href="{% url 'url_experiment' item.id %}">
73 72 <td>{{ forloop.counter }}</td>
74 73 {% for key in experiment_keys %}
75 74 <td>{{ item|attr:key }}</td>
76 75 {% endfor %}
77 76 </tr>
78 77 {% endfor %}
79 78 </table>
80 79 </div>
81 80 </div>
82 81 </div>
83 82 </div>
84 83 <br>
85 84 <!--<button class="btn btn-primary pull-right" style="margin-left: 10px" id="bt_mix">Mix Experiments</button>-->
86 85 {% endblock %}
87 86
88 87 {% block sidebar%}
89 88 {% include "sidebar_devices.html" %}
90 89 {% endblock %}
91 90
92 91 {% block extra-js%}
93 92 <script type="text/javascript">
94 93
95 94 $(".clickable-row").click(function() {
96 95 document.location = $(this).data("href");
97 96 });
98 97
99 98 // $("#bt_edit").click(function() {
100 99 // document.location = "{% url 'url_edit_campaign' campaign.id %}";
101 100 // });
102 101
103 102 $("#bt_mix").click(function() {
104 103
105 104 });
106 105
107 106 </script>
108 107 {% endblock %} No newline at end of file
@@ -1,81 +1,82
1 1 {% extends "base.html" %}
2 2 {% load bootstrap3 %}
3 3 {% load static %}
4 4 {% load main_tags %}
5 5
6 6 {% block search-active %}active{% endblock %}
7 7
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="glyphicon glyphicon-menu-hamburger gi-2x" aria-hidden="true"></span></a>
16 16 <ul class="dropdown-menu" role="menu">
17 17 <li><a href="{{ dev_conf.get_absolute_url_edit }}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</a></li>
18 <li><a href="{% url 'url_delete_dev_conf' dev_conf.id %}"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Delete</a></li>
18 19 <li><a href="{{ dev_conf.get_absolute_url_import }}"><span class="glyphicon glyphicon-import" aria-hidden="true"></span> Import </a></li>
19 20 <li><a href="{{ dev_conf.get_absolute_url_export }}"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Export </a></li>
20 21 {% block extra-menu-actions %}
21 22 {% endblock %}
22 23 <li><a>----------------</a></li>
23 24 <li><a href="{{ dev_conf.get_absolute_url_status }}"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> Status</a></li>
24 25 {% if not no_play %}
25 26 <li><a href="{{ dev_conf.get_absolute_url_start}}"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Start</a></li>
26 27 <li><a href="{{ dev_conf.get_absolute_url_stop }}"><span class="glyphicon glyphicon-stop" aria-hidden="true"></span> Stop</a></li>
27 28 {% endif %}
28 29 <li><a href="{{ dev_conf.get_absolute_url_write }}"><span class="glyphicon glyphicon-download" aria-hidden="true"></span> Write</a></li>
29 30 <li><a href="{{ dev_conf.get_absolute_url_read }}"><span class="glyphicon glyphicon-upload" aria-hidden="true"></span> Read</a></li>
30 31 </ul>
31 32 </span>
32 33 {% endblock %}
33 34
34 35 <table class="table table-bordered">
35 36 <tr>
36 37 <th>Status</th>
37 38 <td>{%if status != "No connected" %} <span class="glyphicon glyphicon-ok-circle text-success" aria-hidden="true"></span> {{status}} {% else %} <span class="glyphicon glyphicon-remove-circle text-danger" aria-hidden="true"></span> {{status}} {% endif %}</td>
38 39 </tr>
39 40
40 41 {% for key in dev_conf_keys %}
41 42 <tr>
42 43 <th>{% get_verbose_field_name dev_conf key %}</th>
43 44 <td>{{dev_conf|attr:key}}</td>
44 45 </tr>
45 46 {% endfor %}
46 47 </table>
47 48
48 49 {% block extra-content %}
49 50 {% endblock %}
50 51
51 52 {% endblock %}
52 53
53 54 {% block sidebar%}
54 55 {% include "sidebar_devices.html" %}
55 56 {% endblock %}
56 57
57 58 {% block extra-js%}
58 59 <script type="text/javascript">
59 60
60 61 $("#bt_edit").click(function() {
61 62 document.location = "{{ dev_conf.get_absolute_url_edit }}";
62 63 });
63 64
64 65 $("#bt_read").click(function() {
65 66 document.location = "{{ dev_conf.get_absolute_url_read }}";
66 67 });
67 68
68 69 $("#bt_write").click(function() {
69 70 document.location = "{{ dev_conf.get_absolute_url_write }}";
70 71 });
71 72
72 73 $("#bt_import").click(function() {
73 74 document.location = "{{ dev_conf.get_absolute_url_import }}";
74 75 });
75 76
76 77 $("#bt_export").click(function() {
77 78 document.location = "{{ dev_conf.get_absolute_url_export }}";
78 79 });
79 80
80 81 </script>
81 82 {% endblock %} No newline at end of file
@@ -1,95 +1,95
1 1 {% extends "base.html" %}
2 2 {% load bootstrap3 %}
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
9 9 {% block exp-active %}active{% endblock %}
10 10
11 11 {% block content-title %}{{title}}{% endblock %}
12 12 {% block content-suptitle %}{{suptitle}}{% endblock %}
13 13
14 14 {% block content %}
15 15
16 16 {% block menu-actions %}
17 17 <span class=" dropdown pull-right">
18 18 <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-menu-hamburger gi-2x" aria-hidden="true"></span></a>
19 19 <ul class="dropdown-menu" role="menu">
20 20 <li><a href="{% url 'url_edit_experiment' experiment.id %}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</a></li>
21 <li><a href="{% url 'url_delete_experiment' experiment.id %}"><span class="glyphicon glyphicon-remove-sign" aria-hidden="true"></span> Delete</a></li>
21 <li><a href="{% url 'url_delete_experiment' experiment.id %}"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Delete</a></li>
22 22 <li><a href="{{ dev_conf.get_absolute_url_import }}"><span class="glyphicon glyphicon-import" aria-hidden="true"></span> Import </a></li>
23 23 <li><a href="{{ experiment.get_absolute_url_export }}"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Export </a></li>
24 24 {% block extra-menu-actions %}
25 25 {% endblock %}
26 26 <li><a>----------------</a></li>
27 <li><a href="#"><span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span> Add Configuration</a></li>
27 <li><a href="{% url 'url_mix_experiment' experiment.id %}"><span class="glyphicon glyphicon-random" aria-hidden="true"></span> Mix RC Configurations </a></li>
28 <li><a href="{% url 'url_add_dev_conf' experiment.id %}"><span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span> Add Configuration</a></li>
28 29 </ul>
29 30 </span>
30 31 {% endblock %}
31 32
32 33 <table class="table table-bordered">
33 34 {% for key in experiment_keys %}
34 35 <tr><th>{{key|title}}</th><td>{{experiment|attr:key}}</td></tr>
35 36 {% endfor %}
36 37 </table>
37 38 <br></br>
38 39 <br></br>
39 40
40 41 <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
41 42
42 43 <div class="panel panel-default">
43 44 <div class="panel-heading" role="tab" id="headingTwo">
44 45 <h4 class="panel-title">
45 46 <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseThree">
46 47 Device Configurations
47 48 </a>
48 49 </h4>
49 50 </div>
50 51 <div id="collapseTwo" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingTwo">
51 52 <div class="panel-body">
52 53 <table class="table table-hover">
53 54 <tr>
54 55 <th>#</th>
55 56 {% for key in configuration_keys %}
56 57 <th>{{ key|title }}</th>
57 58 {% endfor%}
58 59 </tr>
59 60 {% for item in configurations %}
60 61 <tr class="clickable-row" data-href="{{item.get_absolute_url}}">
61 62 <td>{{ forloop.counter }}</td>
62 63 {% for key in configuration_keys %}
63 64 <td>{{ item|value:key }}</td>
64 65 {% endfor %}
65 66 </tr>
66 67 {% endfor %}
67 </table>
68 <button class="btn btn-primary pull-right" id="bt_add_conf">{{button}}</button>
68 </table>
69 69 </div>
70 70 </div>
71 71 </div>
72 72 </div>
73 73 {% endblock %}
74 74
75 75 {% block sidebar%}
76 76 {% include "sidebar_devices.html" %}
77 77 {% endblock %}
78 78
79 79 {% block extra-js%}
80 80 <script type="text/javascript">
81 81
82 82 $(".clickable-row").click(function() {
83 83 document.location = $(this).data("href");
84 84 });
85 85
86 86 $("#bt_edit").click(function() {
87 87 document.location = "{% url 'url_edit_experiment' experiment.id%}";
88 88 });
89 89
90 90 $("#bt_add_conf").click(function() {
91 91 document.location = "{% url 'url_add_dev_conf' experiment.id %}";
92 92 });
93 93
94 94 </script>
95 95 {% endblock %} No newline at end of file
@@ -1,14 +1,26
1 1 {% extends "base_edit.html" %}
2 2 {% load bootstrap3 %}
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 <style type="text/css">
8 .tabuled {font-family: Courier New}
9 .check-inline {display: inline}
10 </style>
7 11 {% endblock %}
8 12
9 13 {% block extra-js%}
10 14 <script src="{% static 'js/moment.min.js' %}"></script>
11 15 <script src="{% static 'js/bootstrap-datetimepicker.min.js' %}"></script>
12 16 <script src="{% static 'js/cr.js' %}"></script>
13 17
18 <script type="text/javascript">
19
20 $("#bt_Delete").click(function() {
21 document.location = "{% url 'url_delete_mix_experiment' id_exp %}";
22 });
23
24 </script>
25
14 26 {% endblock %} No newline at end of file
@@ -1,36 +1,38
1 1 from django.template.defaulttags import register
2 2 from django.utils.safestring import mark_safe
3 3
4 4 @register.filter
5 5 def attr(instance, key):
6 6
7 7 display_key = "get_" + key + "_display"
8 8
9 9 if hasattr(instance, display_key):
10 10 return getattr(instance, display_key)()
11 11
12 12 if hasattr(instance, key):
13 13 return getattr(instance, key)
14 14
15 15 return instance.get(key)
16 16
17 17 @register.filter
18 18 def title(s):
19 19 return s.split('__')[-1].replace('_', ' ').title()
20 20
21 21 @register.filter
22 22 def value(instance, key):
23 23
24 24 item = instance
25 if key=='name':
26 return '%s' % item
25 27 for my_key in key.split("__"):
26 28 item = attr(item, my_key)
27 29
28 30 return item
29 31
30 32 @register.simple_tag
31 33 def get_verbose_field_name(instance, field_name):
32 34 """
33 35 Returns verbose_name for a field.
34 36 """
35 37
36 38 return mark_safe(instance._meta.get_field(field_name).verbose_name) No newline at end of file
@@ -1,53 +1,55
1 1 from django.conf.urls import url
2 2
3 3 urlpatterns = (
4 4 url(r'^location/new/$', 'apps.main.views.location_new', name='url_add_location'),
5 5 url(r'^location/$', 'apps.main.views.locations', name='url_locations'),
6 6 url(r'^location/(?P<id_loc>-?\d+)/$', 'apps.main.views.location', name='url_location'),
7 7 url(r'^location/(?P<id_loc>-?\d+)/edit/$', 'apps.main.views.location_edit', name='url_edit_location'),
8 8 url(r'^location/(?P<id_loc>-?\d+)/delete/$', 'apps.main.views.location_delete', name='url_delete_location'),
9 9
10 10 url(r'^device/new/$', 'apps.main.views.device_new', name='url_add_device'),
11 11 url(r'^device/$', 'apps.main.views.devices', name='url_devices'),
12 12 url(r'^device/(?P<id_dev>-?\d+)/$', 'apps.main.views.device', name='url_device'),
13 13 url(r'^device/(?P<id_dev>-?\d+)/edit/$', 'apps.main.views.device_edit', name='url_edit_device'),
14 14 url(r'^device/(?P<id_dev>-?\d+)/delete/$', 'apps.main.views.device_delete', name='url_delete_device'),
15 15
16 16 url(r'^campaign/new/$', 'apps.main.views.campaign_new', name='url_add_campaign'),
17 17 url(r'^campaign/$', 'apps.main.views.campaigns', name='url_campaigns'),
18 18 url(r'^campaign/(?P<id_camp>-?\d+)/$', 'apps.main.views.campaign', name='url_campaign'),
19 19 url(r'^campaign/(?P<id_camp>-?\d+)/edit/$', 'apps.main.views.campaign_edit', name='url_edit_campaign'),
20 20 url(r'^campaign/(?P<id_camp>-?\d+)/delete/$', 'apps.main.views.campaign_delete', name='url_delete_campaign'),
21 21 url(r'^campaign/(?P<id_camp>-?\d+)/export/$', 'apps.main.views.campaign_export', name='url_export_campaign'),
22 22
23 23 url(r'^experiment/new/$', 'apps.main.views.experiment_new', name='url_add_experiment'),
24 24 url(r'^experiment/$', 'apps.main.views.experiments', name='url_experiments'),
25 25 url(r'^experiment/(?P<id_exp>-?\d+)/$', 'apps.main.views.experiment', name='url_experiment'),
26 26 url(r'^experiment/(?P<id_exp>-?\d+)/edit/$', 'apps.main.views.experiment_edit', name='url_edit_experiment'),
27 27 url(r'^experiment/(?P<id_exp>-?\d+)/delete/$', 'apps.main.views.experiment_delete', name='url_delete_experiment'),
28 28 url(r'^experiment/(?P<id_exp>-?\d+)/export/$', 'apps.main.views.experiment_export', name='url_export_experiment'),
29 url(r'^experiment/(?P<id_exp>-?\d+)/mix/$', 'apps.main.views.experiment_mix', name='url_mix_experiment'),
30 url(r'^experiment/(?P<id_exp>-?\d+)/mix/delete/$', 'apps.main.views.experiment_mix_delete', name='url_delete_mix_experiment'),
29 31
30 32 url(r'^experiment/(?P<id_exp>-?\d+)/new_dev_conf/$', 'apps.main.views.dev_conf_new', name='url_add_dev_conf'),
31 33 url(r'^experiment/(?P<id_exp>-?\d+)/new_dev_conf/(?P<id_dev>-?\d+)/$', 'apps.main.views.dev_conf_new', name='url_add_dev_conf'),
32 34 url(r'^dev_conf/$', 'apps.main.views.dev_confs', name='url_dev_confs'),
33 35 url(r'^dev_conf/(?P<id_conf>-?\d+)/$', 'apps.main.views.dev_conf', name='url_dev_conf'),
34 36 url(r'^dev_conf/(?P<id_conf>-?\d+)/edit/$', 'apps.main.views.dev_conf_edit', name='url_edit_dev_conf'),
35 37 url(r'^dev_conf/(?P<id_conf>-?\d+)/delete/$', 'apps.main.views.dev_conf_delete', name='url_delete_dev_conf'),
36 38
37 39 url(r'^dev_conf/(?P<id_conf>-?\d+)/write/$', 'apps.main.views.dev_conf_write', name='url_write_dev_conf'),
38 40 url(r'^dev_conf/(?P<id_conf>-?\d+)/read/$', 'apps.main.views.dev_conf_read', name='url_read_dev_conf'),
39 41 url(r'^dev_conf/(?P<id_conf>-?\d+)/import/$', 'apps.main.views.dev_conf_import', name='url_import_dev_conf'),
40 42 url(r'^dev_conf/(?P<id_conf>-?\d+)/export/$', 'apps.main.views.dev_conf_export', name='url_export_dev_conf'),
41 43 url(r'^dev_conf/(?P<id_conf>-?\d+)/start/$', 'apps.main.views.dev_conf_start', name='url_start_dev_conf'),
42 44 url(r'^dev_conf/(?P<id_conf>-?\d+)/stop/$', 'apps.main.views.dev_conf_stop', name='url_stop_dev_conf'),
43 45 url(r'^dev_conf/(?P<id_conf>-?\d+)/status/$', 'apps.main.views.dev_conf_status', name='url_status_dev_conf'),
44 46
45 47 url(r'^operation/$', 'apps.main.views.operation', name='url_operation'),
46 48 url(r'^operation/(?P<id_camp>-?\d+)/$', 'apps.main.views.operation', name='url_operation'),
47 49 url(r'^operation/search/$', 'apps.main.views.operation_search', name='url_operation_search'),
48 50 url(r'^operation/search/(?P<id_camp>-?\d+)/$', 'apps.main.views.operation_search', name='url_operation_search'),
49 51 url(r'^operation/(?P<id_camp>-?\d+)/radar/(?P<id_radar>-?\d+)/play/$', 'apps.main.views.radar_play', name='url_radar_play'),
50 52 url(r'^operation/(?P<id_camp>-?\d+)/radar/(?P<id_radar>-?\d+)/stop/$', 'apps.main.views.radar_stop', name='url_radar_stop'),
51 53 url(r'^operation/(?P<id_camp>-?\d+)/radar/(?P<id_radar>-?\d+)/refresh/$', 'apps.main.views.radar_refresh', name='url_radar_refresh'),
52 54
53 55 )
@@ -1,1125 +1,1294
1 1 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
2 from django.utils.safestring import mark_safe
2 3 from django.http import HttpResponseRedirect
3 4 from django.core.urlresolvers import reverse
4 5 from django.contrib import messages
5 6 from datetime import datetime
6 7
7 8 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
8 9 from .forms import OperationSearchForm
9 10 from apps.cgs.forms import CGSConfigurationForm
10 11 from apps.jars.forms import JARSConfigurationForm
11 12 from apps.usrp.forms import USRPConfigurationForm
12 13 from apps.abs.forms import ABSConfigurationForm
13 from apps.rc.forms import RCConfigurationForm
14 from apps.rc.forms import RCConfigurationForm, RCMixConfigurationForm
14 15 from apps.dds.forms import DDSConfigurationForm
15 16
16 17 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment
17 18 from apps.cgs.models import CGSConfiguration
18 19 from apps.jars.models import JARSConfiguration
19 20 from apps.usrp.models import USRPConfiguration
20 21 from apps.abs.models import ABSConfiguration
21 from apps.rc.models import RCConfiguration
22 from apps.rc.models import RCConfiguration, RCLine, RCLineType
22 23 from apps.dds.models import DDSConfiguration
23 24
24 25 # Create your views here.
25 26
26 27 CONF_FORMS = {
27 28 'rc': RCConfigurationForm,
29 'rc_mix': RCMixConfigurationForm,
28 30 'dds': DDSConfigurationForm,
29 31 'jars': JARSConfigurationForm,
30 32 'cgs': CGSConfigurationForm,
31 33 'abs': ABSConfigurationForm,
32 34 'usrp': USRPConfigurationForm,
33 35 }
34 36
35 37 CONF_MODELS = {
36 38 'rc': RCConfiguration,
37 39 'dds': DDSConfiguration,
38 40 'jars': JARSConfiguration,
39 41 'cgs': CGSConfiguration,
40 42 'abs': ABSConfiguration,
41 43 'usrp': USRPConfiguration,
42 44 }
43 45
46 MIX_MODES = {
47 '0': 'OR',
48 '1': 'XOR',
49 '2': 'AND',
50 '3': 'NAND'
51 }
52
44 53
45 54 def index(request):
46 55 kwargs = {}
47 56
48 57 return render(request, 'index.html', kwargs)
49 58
50 59
51 60 def locations(request):
52 61
53 62 locations = Location.objects.all().order_by('name')
54 63
55 64 keys = ['id', 'name', 'description']
56 65
57 66 kwargs = {}
58 67 kwargs['location_keys'] = keys[1:]
59 68 kwargs['locations'] = locations
60 69 kwargs['title'] = 'Location'
61 70 kwargs['suptitle'] = 'List'
62 71 kwargs['button'] = 'New Location'
63 72
64 73 return render(request, 'locations.html', kwargs)
65 74
66 75
67 76 def location(request, id_loc):
68 77
69 78 location = get_object_or_404(Location, pk=id_loc)
70 79
71 80 kwargs = {}
72 81 kwargs['location'] = location
73 82 kwargs['location_keys'] = ['name', 'description']
74 83
75 84 kwargs['title'] = 'Location'
76 85 kwargs['suptitle'] = 'Details'
77 86
78 87 return render(request, 'location.html', kwargs)
79 88
80 89
81 90 def location_new(request):
82 91
83 92 if request.method == 'GET':
84 93 form = LocationForm()
85 94
86 95 if request.method == 'POST':
87 96 form = LocationForm(request.POST)
88 97
89 98 if form.is_valid():
90 99 form.save()
91 100 return redirect('url_locations')
92 101
93 102 kwargs = {}
94 103 kwargs['form'] = form
95 104 kwargs['title'] = 'Location'
96 105 kwargs['suptitle'] = 'New'
97 106 kwargs['button'] = 'Create'
98 107
99 108 return render(request, 'location_edit.html', kwargs)
100 109
101 110
102 111 def location_edit(request, id_loc):
103 112
104 113 location = get_object_or_404(Location, pk=id_loc)
105 114
106 115 if request.method=='GET':
107 116 form = LocationForm(instance=location)
108 117
109 118 if request.method=='POST':
110 119 form = LocationForm(request.POST, instance=location)
111 120
112 121 if form.is_valid():
113 122 form.save()
114 123 return redirect('url_locations')
115 124
116 125 kwargs = {}
117 126 kwargs['form'] = form
118 127 kwargs['title'] = 'Location'
119 128 kwargs['suptitle'] = 'Edit'
120 129 kwargs['button'] = 'Update'
121 130
122 131 return render(request, 'location_edit.html', kwargs)
123 132
124 133
125 134 def location_delete(request, id_loc):
126 135
127 136 location = get_object_or_404(Location, pk=id_loc)
128 137
129 138 if request.method=='POST':
130 139
131 140 if request.user.is_staff:
132 141 location.delete()
133 142 return redirect('url_locations')
134 143
135 144 messages.error(request, 'Not enough permission to delete this object')
136 145 return redirect(location.get_absolute_url())
137 146
138 147 kwargs = {
139 148 'title': 'Delete',
140 149 'suptitle': 'Location',
141 150 'object': location,
142 151 'previous': location.get_absolute_url(),
143 152 'delete': True
144 153 }
145 154
146 155 return render(request, 'confirm.html', kwargs)
147 156
148 157
149 158 def devices(request):
150 159
151 160 devices = Device.objects.all().order_by('device_type__name')
152 161
153 162 # keys = ['id', 'device_type__name', 'name', 'ip_address']
154 163 keys = ['id', 'name', 'ip_address', 'port_address', 'device_type']
155 164
156 165 kwargs = {}
157 166 kwargs['device_keys'] = keys[1:]
158 167 kwargs['devices'] = devices#.values(*keys)
159 168 kwargs['title'] = 'Device'
160 169 kwargs['suptitle'] = 'List'
161 170 kwargs['button'] = 'New Device'
162 171
163 172 return render(request, 'devices.html', kwargs)
164 173
165 174
166 175 def device(request, id_dev):
167 176
168 177 device = get_object_or_404(Device, pk=id_dev)
169 178
170 179 kwargs = {}
171 180 kwargs['device'] = device
172 181 kwargs['device_keys'] = ['device_type', 'name', 'ip_address', 'port_address', 'description']
173 182
174 183 kwargs['title'] = 'Device'
175 184 kwargs['suptitle'] = 'Details'
176 185
177 186 return render(request, 'device.html', kwargs)
178 187
179 188
180 189 def device_new(request):
181 190
182 191 if request.method == 'GET':
183 192 form = DeviceForm()
184 193
185 194 if request.method == 'POST':
186 195 form = DeviceForm(request.POST)
187 196
188 197 if form.is_valid():
189 198 form.save()
190 199 return redirect('url_devices')
191 200
192 201 kwargs = {}
193 202 kwargs['form'] = form
194 203 kwargs['title'] = 'Device'
195 204 kwargs['suptitle'] = 'New'
196 205 kwargs['button'] = 'Create'
197 206
198 207 return render(request, 'device_edit.html', kwargs)
199 208
200 209
201 210 def device_edit(request, id_dev):
202 211
203 212 device = get_object_or_404(Device, pk=id_dev)
204 213
205 214 if request.method=='GET':
206 215 form = DeviceForm(instance=device)
207 216
208 217 if request.method=='POST':
209 218 form = DeviceForm(request.POST, instance=device)
210 219
211 220 if form.is_valid():
212 221 form.save()
213 222 return redirect(device.get_absolute_url())
214 223
215 224 kwargs = {}
216 225 kwargs['form'] = form
217 226 kwargs['title'] = 'Device'
218 227 kwargs['suptitle'] = 'Edit'
219 228 kwargs['button'] = 'Update'
220 229
221 230 return render(request, 'device_edit.html', kwargs)
222 231
223 232
224 233 def device_delete(request, id_dev):
225 234
226 235 device = get_object_or_404(Device, pk=id_dev)
227 236
228 237 if request.method=='POST':
229 238
230 239 if request.user.is_staff:
231 240 device.delete()
232 241 return redirect('url_devices')
233 242
234 243 messages.error(request, 'Not enough permission to delete this object')
235 244 return redirect(device.get_absolute_url())
236 245
237 246 kwargs = {
238 247 'title': 'Delete',
239 248 'suptitle': 'Device',
240 249 'object': device,
241 250 'previous': device.get_absolute_url(),
242 251 'delete': True
243 252 }
244 253
245 254 return render(request, 'confirm.html', kwargs)
246 255
247 256
248 257 def campaigns(request):
249 258
250 259 campaigns = Campaign.objects.all().order_by('start_date')
251 260
252 261 keys = ['id', 'name', 'start_date', 'end_date']
253 262
254 263 kwargs = {}
255 264 kwargs['campaign_keys'] = keys[1:]
256 265 kwargs['campaigns'] = campaigns#.values(*keys)
257 266 kwargs['title'] = 'Campaign'
258 267 kwargs['suptitle'] = 'List'
259 268 kwargs['button'] = 'New Campaign'
260 269
261 270 return render(request, 'campaigns.html', kwargs)
262 271
263 272
264 273 def campaign(request, id_camp):
265 274
266 275 campaign = get_object_or_404(Campaign, pk=id_camp)
267 276 experiments = Experiment.objects.filter(campaign=campaign)
268 277
269 278 form = CampaignForm(instance=campaign)
270 279
271 280 kwargs = {}
272 281 kwargs['campaign'] = campaign
273 282 kwargs['campaign_keys'] = ['template', 'name', 'start_date', 'end_date', 'tags', 'description']
274 283
275 284 kwargs['experiments'] = experiments
276 285 kwargs['experiment_keys'] = ['name', 'radar', 'start_time', 'end_time']
277 286
278 287 kwargs['title'] = 'Campaign'
279 288 kwargs['suptitle'] = 'Details'
280 289
281 290 kwargs['form'] = form
282 291 kwargs['button'] = 'Add Experiment'
283 292
284 293 return render(request, 'campaign.html', kwargs)
285 294
286 295
287 296 def campaign_new(request):
288 297
289 298 kwargs = {}
290 299
291 300 if request.method == 'GET':
292 301
293 302 if 'template' in request.GET:
294 303 if request.GET['template']=='0':
295 304 form = NewForm(initial={'create_from':2},
296 305 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
297 306 else:
298 307 kwargs['button'] = 'Create'
299 308 kwargs['experiments'] = Configuration.objects.filter(experiment=request.GET['template'])
300 309 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
301 310 camp = Campaign.objects.get(pk=request.GET['template'])
302 311 form = CampaignForm(instance=camp,
303 312 initial={'name':'{} [{:%Y/%m/%d}]'.format(camp.name, datetime.now()),
304 313 'template':False})
305 314 elif 'blank' in request.GET:
306 315 kwargs['button'] = 'Create'
307 316 form = CampaignForm()
308 317 else:
309 318 form = NewForm()
310 319
311 320 if request.method == 'POST':
312 321 kwargs['button'] = 'Create'
313 322 post = request.POST.copy()
314 323 experiments = []
315 324
316 325 for id_exp in post.getlist('experiments'):
317 326 exp = Experiment.objects.get(pk=id_exp)
318 327 new_exp = exp.clone(template=False)
319 328 experiments.append(new_exp)
320 329
321 330 post.setlist('experiments', [])
322 331
323 332 form = CampaignForm(post)
324 333
325 334 if form.is_valid():
326 335 campaign = form.save()
327 336 for exp in experiments:
328 337 campaign.experiments.add(exp)
329 338 campaign.save()
330 339 return redirect('url_campaign', id_camp=campaign.id)
331 340
332 341 kwargs['form'] = form
333 342 kwargs['title'] = 'Campaign'
334 343 kwargs['suptitle'] = 'New'
335 344
336 345 return render(request, 'campaign_edit.html', kwargs)
337 346
338 347
339 348 def campaign_edit(request, id_camp):
340 349
341 350 campaign = get_object_or_404(Campaign, pk=id_camp)
342 351
343 352 if request.method=='GET':
344 353 form = CampaignForm(instance=campaign)
345 354
346 355 if request.method=='POST':
347 356 exps = campaign.experiments.all().values_list('pk', flat=True)
348 357 post = request.POST.copy()
349 358 new_exps = post.getlist('experiments')
350 359 post.setlist('experiments', [])
351 360 form = CampaignForm(post, instance=campaign)
352 361
353 362 if form.is_valid():
354 363 camp = form.save()
355 364 for id_exp in new_exps:
356 365 if int(id_exp) in exps:
357 366 exps.pop(id_exp)
358 367 else:
359 368 exp = Experiment.objects.get(pk=id_exp)
360 369 if exp.template:
361 370 camp.experiments.add(exp.clone(template=False))
362 371 else:
363 372 camp.experiments.add(exp)
364 373
365 374 for id_exp in exps:
366 375 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
367 376
368 377 return redirect('url_campaign', id_camp=id_camp)
369 378
370 379 kwargs = {}
371 380 kwargs['form'] = form
372 381 kwargs['title'] = 'Campaign'
373 382 kwargs['suptitle'] = 'Edit'
374 383 kwargs['button'] = 'Update'
375 384
376 385 return render(request, 'campaign_edit.html', kwargs)
377 386
378 387
379 388 def campaign_delete(request, id_camp):
380 389
381 390 campaign = get_object_or_404(Campaign, pk=id_camp)
382 391
383 392 if request.method=='POST':
384 393 if request.user.is_staff:
385 394
386 395 for exp in campaign.experiments.all():
387 396 for conf in Configuration.objects.filter(experiment=exp):
388 397 conf.delete()
389 398 exp.delete()
390 399 campaign.delete()
391 400
392 401 return redirect('url_campaigns')
393 402
394 403 messages.error(request, 'Not enough permission to delete this object')
395 404 return redirect(campaign.get_absolute_url())
396 405
397 406 kwargs = {
398 407 'title': 'Delete',
399 408 'suptitle': 'Campaign',
400 409 'object': campaign,
401 410 'previous': campaign.get_absolute_url(),
402 411 'delete': True
403 412 }
404 413
405 414 return render(request, 'confirm.html', kwargs)
406 415
407 416 def campaign_export(request, id_camp):
408 417
409 418 campaign = get_object_or_404(Campaign, pk=id_camp)
410 419 content = campaign.parms_to_dict()
411 420 content_type = 'application/json'
412 421 filename = '%s_%s.json' %(campaign.name, campaign.id)
413 422
414 423 response = HttpResponse(content_type=content_type)
415 424 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
416 425 response.write(content)
417 426
418 427 return response
419 428
420 429 def experiments(request):
421 430
422 431 experiment_list = Experiment.objects.all()
423 432
424 433 keys = ['id', 'name', 'start_time', 'end_time']
425 434
426 435 kwargs = {}
427 436
428 437 kwargs['experiment_keys'] = keys[1:]
429 438 kwargs['experiments'] = experiment_list
430 439
431 440 kwargs['title'] = 'Experiment'
432 441 kwargs['suptitle'] = 'List'
433 442 kwargs['button'] = 'New Experiment'
434 443
435 444 return render(request, 'experiments.html', kwargs)
436 445
437 446
438 447 def experiment(request, id_exp):
439 448
440 449 experiment = get_object_or_404(Experiment, pk=id_exp)
441 450
442 451 configurations = Configuration.objects.filter(experiment=experiment, type=0)
443 452
444 453 kwargs = {}
445 454
446 455 kwargs['experiment_keys'] = ['template', 'radar', 'name', 'start_time', 'end_time']
447 456 kwargs['experiment'] = experiment
448 457
449 kwargs['configuration_keys'] = ['device__name', 'device__device_type', 'device__ip_address', 'device__port_address']
458 kwargs['configuration_keys'] = ['name', 'device__device_type', 'device__ip_address', 'device__port_address']
450 459 kwargs['configurations'] = configurations
451 460
452 461 kwargs['title'] = 'Experiment'
453 462 kwargs['suptitle'] = 'Details'
454 463
455 464 kwargs['button'] = 'Add Configuration'
456 465
457 466 ###### SIDEBAR ######
458 467 kwargs.update(sidebar(experiment=experiment))
459 468
460 469 return render(request, 'experiment.html', kwargs)
461 470
462 471
463 472 def experiment_new(request, id_camp=None):
464 473
465 474 kwargs = {}
466 475
467 476 if request.method == 'GET':
468 477 if 'template' in request.GET:
469 478 if request.GET['template']=='0':
470 479 form = NewForm(initial={'create_from':2},
471 480 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
472 481 else:
473 482 kwargs['button'] = 'Create'
474 483 kwargs['configurations'] = Configuration.objects.filter(experiment=request.GET['template'])
475 484 kwargs['configuration_keys'] = ['name', 'device__name', 'device__ip_address', 'device__port_address']
476 485 exp=Experiment.objects.get(pk=request.GET['template'])
477 486 form = ExperimentForm(instance=exp,
478 487 initial={'name': '{} [{:%Y/%m/%d}]'.format(exp.name, datetime.now()),
479 488 'template': False})
480 489 elif 'blank' in request.GET:
481 490 kwargs['button'] = 'Create'
482 491 form = ExperimentForm()
483 492 else:
484 493 form = NewForm()
485 494
486 495 if request.method == 'POST':
487 496 form = ExperimentForm(request.POST)
488 497 if form.is_valid():
489 498 experiment = form.save()
490 499
491 500 if 'template' in request.GET:
492 501 configurations = Configuration.objects.filter(experiment=request.GET['template'], type=0)
493 502 for conf in configurations:
494 503 conf.clone(experiment=experiment, template=False)
495 504
496 505 return redirect('url_experiment', id_exp=experiment.id)
497 506
498 507 kwargs['form'] = form
499 508 kwargs['title'] = 'Experiment'
500 509 kwargs['suptitle'] = 'New'
501 510
502 511 return render(request, 'experiment_edit.html', kwargs)
503 512
504 513
505 514 def experiment_edit(request, id_exp):
506 515
507 516 experiment = get_object_or_404(Experiment, pk=id_exp)
508 517
509 518 if request.method == 'GET':
510 519 form = ExperimentForm(instance=experiment)
511 520
512 521 if request.method=='POST':
513 522 form = ExperimentForm(request.POST, instance=experiment)
514 523
515 524 if form.is_valid():
516 525 experiment = form.save()
517 526 return redirect('url_experiment', id_exp=experiment.id)
518 527
519 528 kwargs = {}
520 529 kwargs['form'] = form
521 530 kwargs['title'] = 'Experiment'
522 531 kwargs['suptitle'] = 'Edit'
523 532 kwargs['button'] = 'Update'
524 533
525 534 return render(request, 'experiment_edit.html', kwargs)
526 535
527 536
528 537 def experiment_delete(request, id_exp):
529 538
530 539 experiment = get_object_or_404(Experiment, pk=id_exp)
531 540
532 541 if request.method=='POST':
533 542 if request.user.is_staff:
534 543 for conf in Configuration.objects.filter(experiment=experiment):
535 544 conf.delete()
536 545 experiment.delete()
537 546 return redirect('url_experiments')
538 547
539 548 messages.error(request, 'Not enough permission to delete this object')
540 549 return redirect(experiment.get_absolute_url())
541 550
542 551 kwargs = {
543 552 'title': 'Delete',
544 553 'suptitle': 'Experiment',
545 554 'object': experiment,
546 555 'previous': experiment.get_absolute_url(),
547 556 'delete': True
548 557 }
549 558
550 559 return render(request, 'confirm.html', kwargs)
551 560
552 561
553 562 def experiment_export(request, id_exp):
554 563
555 564 experiment = get_object_or_404(Experiment, pk=id_exp)
556 565 content = experiment.parms_to_dict()
557 566 content_type = 'application/json'
558 567 filename = '%s_%s.json' %(experiment.name, experiment.id)
559 568
560 569 response = HttpResponse(content_type=content_type)
561 570 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
562 571 response.write(content)
563 572
564 573 return response
565 574
566 575
576 def experiment_mix(request, id_exp):
577
578 experiment = get_object_or_404(Experiment, pk=id_exp)
579 rc_confs = [conf for conf in RCConfiguration.objects.filter(experiment=id_exp,
580 mix=False)]
581
582 if len(rc_confs)<2:
583 messages.warning(request, 'You need at least two RC Configurations to make a mix')
584 return redirect(experiment.get_absolute_url())
585
586 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True)
587
588 if mix_confs:
589 mix = mix_confs[0]
590 else:
591 mix = RCConfiguration(experiment=experiment,
592 device=rc_confs[0].device,
593 ipp=rc_confs[0].ipp,
594 clock_in=rc_confs[0].clock_in,
595 clock_divider=rc_confs[0].clock_divider,
596 mix=True,
597 parameters='')
598 mix.save()
599
600 line_type = RCLineType.objects.get(name='mix')
601 for i in range(len(rc_confs[0].get_lines())):
602 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
603 line.save()
604
605 initial = {'name': mix.name,
606 'result': parse_mix_result(mix.parameters),
607 'delay': 0,
608 'mask': [0,1,2,3,4,5,6,7]
609 }
610
611 if request.method=='GET':
612 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
613
614 if request.method=='POST':
615
616 result = mix.parameters
617
618 if '{}|'.format(request.POST['experiment']) in result:
619 messages.error(request, 'Configuration already added')
620 else:
621 if result:
622 result = '{}-{}|{}|{}|{}'.format(mix.parameters,
623 request.POST['experiment'],
624 MIX_MODES[request.POST['operation']],
625 float(request.POST['delay']),
626 parse_mask(request.POST.getlist('mask'))
627 )
628 else:
629 result = '{}|{}|{}|{}'.format(request.POST['experiment'],
630 MIX_MODES[request.POST['operation']],
631 float(request.POST['delay']),
632 parse_mask(request.POST.getlist('mask'))
633 )
634
635 mix.parameters = result
636 mix.name = request.POST['name']
637 mix.save()
638 mix.update_pulses()
639
640
641 initial['result'] = parse_mix_result(result)
642 initial['name'] = mix.name
643
644 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
645
646
647 kwargs = {
648 'title': 'Experiment',
649 'suptitle': 'Mix Configurations',
650 'form' : form,
651 'extra_button': 'Delete',
652 'button': 'Add',
653 'cancel': 'Back',
654 'previous': experiment.get_absolute_url(),
655 'id_exp':id_exp,
656
657 }
658
659 return render(request, 'experiment_mix.html', kwargs)
660
661
662 def experiment_mix_delete(request, id_exp):
663
664 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True)
665 values = conf.parameters.split('-')
666 conf.parameters = '-'.join(values[:-1])
667 conf.save()
668
669 return redirect('url_mix_experiment', id_exp=id_exp)
670
671
672 def parse_mix_result(s):
673
674 values = s.split('-')
675 html = ''
676
677
678 for i, value in enumerate(values):
679 if not value:
680 continue
681 pk, mode, delay, mask = value.split('|')
682 conf = RCConfiguration.objects.get(pk=pk)
683 if i==0:
684 html += '{:20.18}{:4}{:9}km{:>6}\r\n'.format(
685 conf.name[:18],
686 '---',
687 delay,
688 mask)
689 else:
690 html += '{:20.18}{:4}{:9}km{:>6}\r\n'.format(
691 conf.name[:18],
692 mode,
693 delay,
694 mask)
695
696 return mark_safe(html)
697
698 def parse_mask(l):
699
700 values = []
701
702 for x in range(8):
703 if '{}'.format(x) in l:
704 values.append(1)
705 else:
706 values.append(0)
707
708 values.reverse()
709
710 return int(''.join([str(x) for x in values]), 2)
711
712
567 713 def dev_confs(request):
568 714
569 715 configurations = Configuration.objects.all().order_by('type', 'device__device_type', 'experiment')
570 716
571 717 kwargs = {}
572 718
573 kwargs['configuration_keys'] = ['device', 'experiment', 'type', 'programmed_date']
719 kwargs['configuration_keys'] = ['device', 'name', 'experiment', 'type', 'programmed_date']
574 720 kwargs['configurations'] = configurations
575 721
576 722 kwargs['title'] = 'Configuration'
577 723 kwargs['suptitle'] = 'List'
578 724
579 725 return render(request, 'dev_confs.html', kwargs)
580 726
581 727
582 728 def dev_conf(request, id_conf):
583 729
584 730 conf = get_object_or_404(Configuration, pk=id_conf)
585 731
586 732 return redirect(conf.get_absolute_url())
587 733
588 734
589 735 def dev_conf_new(request, id_exp=0, id_dev=0):
590 736
591 737 initial = {}
738 kwargs = {}
592 739
593 740 if id_exp<>0:
594 741 initial['experiment'] = id_exp
595 742
596 743 if id_dev<>0:
597 744 initial['device'] = id_dev
598 745
599 746 if request.method == 'GET':
600 if id_dev==0:
601 form = ConfigurationForm(initial=initial)
602 else:
747
748 if id_dev:
749 kwargs['button'] = 'Create'
603 750 device = Device.objects.get(pk=id_dev)
604 751 DevConfForm = CONF_FORMS[device.device_type.name]
605
752 initial['name'] = request.GET['name']
606 753 form = DevConfForm(initial=initial)
754 else:
755 if 'template' in request.GET:
756 if request.GET['template']=='0':
757 form = NewForm(initial={'create_from':2},
758 template_choices=Configuration.objects.filter(template=True).values_list('id', 'name'))
759 else:
760 kwargs['button'] = 'Create'
761 conf = Configuration.objects.get(pk=request.GET['template'])
762 DevConfForm = CONF_FORMS[conf.device.device_type.name]
763 form = DevConfForm(instance=conf,
764 initial={'name': '{} [{:%Y/%m/%d}]'.format(conf.name, datetime.now()),
765 'template': False})
766 elif 'blank' in request.GET:
767 kwargs['button'] = 'Create'
768 form = ConfigurationForm(initial=initial)
769 else:
770 form = NewForm()
607 771
608 772 if request.method == 'POST':
609 773
610 774 device = Device.objects.get(pk=request.POST['device'])
611 775 DevConfForm = CONF_FORMS[device.device_type.name]
612 776
613 777 form = DevConfForm(request.POST)
614 778
615 779 if form.is_valid():
616 dev_conf = form.save()
780 conf = form.save()
617 781
618 return redirect('url_dev_confs')
782 if 'template' in request.GET and conf.device.device_type.name=='rc':
783 lines = RCLine.objects.filter(rc_configuration=request.GET['template'])
784 for line in lines:
785 line.clone(rc_configuration=conf)
786
787 return redirect('url_dev_conf', id_conf=conf.pk)
619 788
620 kwargs = {}
789
621 790 kwargs['id_exp'] = id_exp
622 791 kwargs['form'] = form
623 792 kwargs['title'] = 'Configuration'
624 793 kwargs['suptitle'] = 'New'
625 kwargs['button'] = 'Create'
794
626 795
627 796 if id_dev != 0:
628 797 device = Device.objects.get(pk=id_dev)
629 798 if 'dds' in device.device_type.name:
630 799 kwargs['dds_device'] = True
631 800
632 801 return render(request, 'dev_conf_edit.html', kwargs)
633 802
634 803
635 804 def dev_conf_edit(request, id_conf):
636 805
637 806 conf = get_object_or_404(Configuration, pk=id_conf)
638 807
639 808 DevConfModel = CONF_MODELS[conf.device.device_type.name]
640 809 DevConfForm = CONF_FORMS[conf.device.device_type.name]
641 810
642 811 dev_conf = DevConfModel.objects.get(pk=id_conf)
643 812
644 813 if request.method=='GET':
645 814 form = DevConfForm(instance=dev_conf)
646 815
647 816 if request.method=='POST':
648 817 form = DevConfForm(request.POST, instance=dev_conf)
649 818
650 819 if form.is_valid():
651 820 form.save()
652 821 return redirect('url_dev_conf', id_conf=id_conf)
653 822
654 823 kwargs = {}
655 824 kwargs['form'] = form
656 825 kwargs['title'] = 'Device Configuration'
657 826 kwargs['suptitle'] = 'Edit'
658 827 kwargs['button'] = 'Update'
659 828
660 829 ###### SIDEBAR ######
661 830 kwargs.update(sidebar(conf=conf))
662 831
663 832 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
664 833
665 834
666 835 def dev_conf_start(request, id_conf):
667 836
668 837 conf = get_object_or_404(Configuration, pk=id_conf)
669 838
670 839 DevConfModel = CONF_MODELS[conf.device.device_type.name]
671 840
672 841 conf = DevConfModel.objects.get(pk=id_conf)
673 842
674 843 if conf.start_device():
675 844 messages.success(request, conf.message)
676 845 else:
677 846 messages.error(request, conf.message)
678 847
679 848 conf.status_device()
680 849
681 850 return redirect(conf.get_absolute_url())
682 851
683 852
684 853 def dev_conf_stop(request, id_conf):
685 854
686 855 conf = get_object_or_404(Configuration, pk=id_conf)
687 856
688 857 DevConfModel = CONF_MODELS[conf.device.device_type.name]
689 858
690 859 conf = DevConfModel.objects.get(pk=id_conf)
691 860
692 861 if conf.stop_device():
693 862 messages.success(request, conf.message)
694 863 else:
695 864 messages.error(request, conf.message)
696 865
697 866 conf.status_device()
698 867
699 868 return redirect(conf.get_absolute_url())
700 869
701 870
702 871 def dev_conf_status(request, id_conf):
703 872
704 873 conf = get_object_or_404(Configuration, pk=id_conf)
705 874
706 875 DevConfModel = CONF_MODELS[conf.device.device_type.name]
707 876
708 877 conf = DevConfModel.objects.get(pk=id_conf)
709 878
710 879 if conf.status_device():
711 880 messages.success(request, conf.message)
712 881 else:
713 882 messages.error(request, conf.message)
714 883
715 884 return redirect(conf.get_absolute_url())
716 885
717 886
718 887 def dev_conf_write(request, id_conf):
719 888
720 889 conf = get_object_or_404(Configuration, pk=id_conf)
721 890
722 891 DevConfModel = CONF_MODELS[conf.device.device_type.name]
723 892
724 893 conf = DevConfModel.objects.get(pk=id_conf)
725 894
726 895 answer = conf.write_device()
727 896 conf.status_device()
728 897
729 898 if answer:
730 899 messages.success(request, conf.message)
731 900
732 901 #Creating a historical configuration
733 902 conf.clone(type=0, template=False)
734 903
735 904 #Original configuration
736 905 conf = DevConfModel.objects.get(pk=id_conf)
737 906 else:
738 907 messages.error(request, conf.message)
739 908
740 909 return redirect(conf.get_absolute_url())
741 910
742 911
743 912 def dev_conf_read(request, id_conf):
744 913
745 914 conf = get_object_or_404(Configuration, pk=id_conf)
746 915
747 916 DevConfModel = CONF_MODELS[conf.device.device_type.name]
748 917 DevConfForm = CONF_FORMS[conf.device.device_type.name]
749 918
750 919 conf = DevConfModel.objects.get(pk=id_conf)
751 920
752 921 if request.method=='GET':
753 922
754 923 parms = conf.read_device()
755 924 conf.status_device()
756 925
757 926 if not parms:
758 927 messages.error(request, conf.message)
759 928 return redirect(conf.get_absolute_url())
760 929
761 930 form = DevConfForm(initial=parms, instance=conf)
762 931
763 932 if request.method=='POST':
764 933 form = DevConfForm(request.POST, instance=conf)
765 934
766 935 if form.is_valid():
767 936 form.save()
768 937 return redirect(conf.get_absolute_url())
769 938
770 939 messages.error(request, "Parameters could not be saved")
771 940
772 941 kwargs = {}
773 942 kwargs['id_dev'] = conf.id
774 943 kwargs['form'] = form
775 944 kwargs['title'] = 'Device Configuration'
776 945 kwargs['suptitle'] = 'Parameters read from device'
777 946 kwargs['button'] = 'Save'
778 947
779 948 ###### SIDEBAR ######
780 949 kwargs.update(sidebar(conf=conf))
781 950
782 951 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
783 952
784 953
785 954 def dev_conf_import(request, id_conf):
786 955
787 956 conf = get_object_or_404(Configuration, pk=id_conf)
788 957
789 958 DevConfModel = CONF_MODELS[conf.device.device_type.name]
790 959 DevConfForm = CONF_FORMS[conf.device.device_type.name]
791 960 conf = DevConfModel.objects.get(pk=id_conf)
792 961
793 962 if request.method == 'GET':
794 963 file_form = UploadFileForm()
795 964
796 965 if request.method == 'POST':
797 966 file_form = UploadFileForm(request.POST, request.FILES)
798 967
799 968 if file_form.is_valid():
800 969
801 970 parms = conf.import_from_file(request.FILES['file'])
802 971
803 972 if parms:
804 973 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
805 974 form = DevConfForm(initial=parms, instance=conf)
806 975
807 976 kwargs = {}
808 977 kwargs['id_dev'] = conf.id
809 978 kwargs['form'] = form
810 979 kwargs['title'] = 'Device Configuration'
811 980 kwargs['suptitle'] = 'Parameters imported'
812 981 kwargs['button'] = 'Save'
813 982 kwargs['action'] = conf.get_absolute_url_edit()
814 983 kwargs['previous'] = conf.get_absolute_url()
815 984
816 985 ###### SIDEBAR ######
817 986 kwargs.update(sidebar(conf=conf))
818 987
819 988 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
820 989
821 990 messages.error(request, "Could not import parameters from file")
822 991
823 992 kwargs = {}
824 993 kwargs['id_dev'] = conf.id
825 994 kwargs['title'] = 'Device Configuration'
826 995 kwargs['form'] = file_form
827 996 kwargs['suptitle'] = 'Importing file'
828 997 kwargs['button'] = 'Import'
829 998
830 999 kwargs.update(sidebar(conf=conf))
831 1000
832 1001 return render(request, 'dev_conf_import.html', kwargs)
833 1002
834 1003
835 1004 def dev_conf_export(request, id_conf):
836 1005
837 1006 conf = get_object_or_404(Configuration, pk=id_conf)
838 1007
839 1008 DevConfModel = CONF_MODELS[conf.device.device_type.name]
840 1009
841 1010 conf = DevConfModel.objects.get(pk=id_conf)
842 1011
843 1012 if request.method == 'GET':
844 1013 file_form = DownloadFileForm(conf.device.device_type.name)
845 1014
846 1015 if request.method == 'POST':
847 1016 file_form = DownloadFileForm(conf.device.device_type.name, request.POST)
848 1017
849 1018 if file_form.is_valid():
850 1019 fields = conf.export_to_file(format = file_form.cleaned_data['format'])
851 1020
852 1021 response = HttpResponse(content_type=fields['content_type'])
853 1022 response['Content-Disposition'] = 'attachment; filename="%s"' %fields['filename']
854 1023 response.write(fields['content'])
855 1024
856 1025 return response
857 1026
858 1027 messages.error(request, "Could not export parameters")
859 1028
860 1029 kwargs = {}
861 1030 kwargs['id_dev'] = conf.id
862 1031 kwargs['title'] = 'Device Configuration'
863 1032 kwargs['form'] = file_form
864 1033 kwargs['suptitle'] = 'Exporting file'
865 1034 kwargs['button'] = 'Export'
866 1035
867 1036 return render(request, 'dev_conf_export.html', kwargs)
868 1037
869 1038
870 1039 def dev_conf_delete(request, id_conf):
871 1040
872 1041 conf = get_object_or_404(Configuration, pk=id_conf)
873 1042
874 1043 if request.method=='POST':
875 1044 if request.user.is_staff:
876 1045 conf.delete()
877 1046 return redirect('url_dev_confs')
878 1047
879 1048 messages.error(request, 'Not enough permission to delete this object')
880 1049 return redirect(conf.get_absolute_url())
881 1050
882 1051 kwargs = {
883 1052 'title': 'Delete',
884 1053 'suptitle': 'Experiment',
885 1054 'object': conf,
886 1055 'previous': conf.get_absolute_url(),
887 1056 'delete': True
888 1057 }
889 1058
890 1059 return render(request, 'confirm.html', kwargs)
891 1060
892 1061
893 1062 def sidebar(**kwargs):
894 1063
895 1064 side_data = {}
896 1065
897 1066 conf = kwargs.get('conf', None)
898 1067 experiment = kwargs.get('experiment', None)
899 1068
900 1069 if not experiment:
901 1070 experiment = conf.experiment
902 1071
903 1072 if experiment:
904 1073 side_data['experiment'] = experiment
905 1074 campaign = experiment.campaign_set.all()
906 1075 if campaign:
907 1076 side_data['campaign'] = campaign[0]
908 1077 experiments = campaign[0].experiments.all()
909 1078 else:
910 1079 experiments = [experiment]
911 1080 configurations = experiment.configuration_set.filter(type=0)
912 1081 side_data['side_experiments'] = experiments
913 1082 side_data['side_configurations'] = configurations
914 1083
915 1084 return side_data
916 1085
917 1086
918 1087 def operation(request, id_camp=None):
919 1088
920 1089 if not id_camp:
921 1090 campaigns = Campaign.objects.all().order_by('-start_date')
922 1091
923 1092 if not campaigns:
924 1093 kwargs = {}
925 1094 kwargs['title'] = 'No Campaigns'
926 1095 kwargs['suptitle'] = 'Empty'
927 1096 return render(request, 'operation.html', kwargs)
928 1097
929 1098 id_camp = campaigns[0].id
930 1099
931 1100 campaign = get_object_or_404(Campaign, pk = id_camp)
932 1101
933 1102 if request.method=='GET':
934 1103 form = OperationForm(initial={'campaign': campaign.id}, length = 5)
935 1104
936 1105 if request.method=='POST':
937 1106 form = OperationForm(request.POST, initial={'campaign':campaign.id}, length = 5)
938 1107
939 1108 if form.is_valid():
940 1109 return redirect('url_operation', id_camp=campaign.id)
941 1110 #locations = Location.objects.filter(experiment__campaign__pk = campaign.id).distinct()
942 1111 experiments = Experiment.objects.filter(campaign__pk=campaign.id)
943 1112 #for exs in experiments:
944 1113 # exs.get_status()
945 1114 locations= Location.objects.filter(experiment=experiments).distinct()
946 1115 #experiments = [Experiment.objects.filter(location__pk=location.id).filter(campaign__pk=campaign.id) for location in locations]
947 1116 kwargs = {}
948 1117 #---Campaign
949 1118 kwargs['campaign'] = campaign
950 1119 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
951 1120 #---Experiment
952 1121 keys = ['id', 'name', 'start_time', 'end_time', 'status']
953 1122 kwargs['experiment_keys'] = keys[1:]
954 1123 kwargs['experiments'] = experiments
955 1124 #---Radar
956 1125 kwargs['locations'] = locations
957 1126 #---Else
958 1127 kwargs['title'] = 'Campaign'
959 1128 kwargs['suptitle'] = campaign.name
960 1129 kwargs['form'] = form
961 1130 kwargs['button'] = 'Search'
962 1131 kwargs['details'] = True
963 1132 kwargs['search_button'] = True
964 1133
965 1134 return render(request, 'operation.html', kwargs)
966 1135
967 1136
968 1137 def operation_search(request, id_camp=None):
969 1138
970 1139
971 1140 if not id_camp:
972 1141 campaigns = Campaign.objects.all().order_by('-start_date')
973 1142
974 1143 if not campaigns:
975 1144 return render(request, 'operation.html', {})
976 1145
977 1146 id_camp = campaigns[0].id
978 1147 campaign = get_object_or_404(Campaign, pk = id_camp)
979 1148
980 1149 if request.method=='GET':
981 1150 form = OperationSearchForm(initial={'campaign': campaign.id})
982 1151
983 1152 if request.method=='POST':
984 1153 form = OperationSearchForm(request.POST, initial={'campaign':campaign.id})
985 1154
986 1155 if form.is_valid():
987 1156 return redirect('url_operation', id_camp=campaign.id)
988 1157
989 1158 #locations = Location.objects.filter(experiment__campaign__pk = campaign.id).distinct()
990 1159 experiments = Experiment.objects.filter(campaign__pk=campaign.id)
991 1160 #for exs in experiments:
992 1161 # exs.get_status()
993 1162 locations= Location.objects.filter(experiment=experiments).distinct()
994 1163 form = OperationSearchForm(initial={'campaign': campaign.id})
995 1164
996 1165 kwargs = {}
997 1166 #---Campaign
998 1167 kwargs['campaign'] = campaign
999 1168 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
1000 1169 #---Experiment
1001 1170 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1002 1171 kwargs['experiment_keys'] = keys[1:]
1003 1172 kwargs['experiments'] = experiments
1004 1173 #---Radar
1005 1174 kwargs['locations'] = locations
1006 1175 #---Else
1007 1176 kwargs['title'] = 'Campaign'
1008 1177 kwargs['suptitle'] = campaign.name
1009 1178 kwargs['form'] = form
1010 1179 kwargs['button'] = 'Select'
1011 1180 kwargs['details'] = True
1012 1181 kwargs['search_button'] = False
1013 1182
1014 1183 return render(request, 'operation.html', kwargs)
1015 1184
1016 1185
1017 1186 def radar_play(request, id_camp, id_radar):
1018 1187 campaign = get_object_or_404(Campaign, pk = id_camp)
1019 1188 radar = get_object_or_404(Location, pk = id_radar)
1020 1189 today = datetime.today()
1021 1190 now = today.time()
1022 1191
1023 1192 #--Clear Old Experiments From RunningExperiment Object
1024 1193 running_experiment = RunningExperiment.objects.filter(radar=radar)
1025 1194 if running_experiment:
1026 1195 running_experiment = running_experiment[0]
1027 1196 running_experiment.running_experiment.clear()
1028 1197 running_experiment.save()
1029 1198
1030 1199 #--If campaign datetime is ok:
1031 1200 if today >= campaign.start_date and today <= campaign.end_date:
1032 1201 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1033 1202 for exp in experiments:
1034 1203 #--If experiment time is ok:
1035 1204 if now >= exp.start_time and now <= exp.end_time:
1036 1205 configurations = Configuration.objects.filter(experiment = exp)
1037 1206 for conf in configurations:
1038 1207 if 'cgs' in conf.device.device_type.name:
1039 1208 conf.status_device()
1040 1209 else:
1041 1210 answer = conf.start_device()
1042 1211 conf.status_device()
1043 1212 #--Running Experiment
1044 1213 old_running_experiment = RunningExperiment.objects.filter(radar=radar)
1045 1214 #--If RunningExperiment element exists
1046 1215 if old_running_experiment:
1047 1216 old_running_experiment = old_running_experiment[0]
1048 1217 old_running_experiment.running_experiment.add(exp)
1049 1218 old_running_experiment.status = 3
1050 1219 old_running_experiment.save()
1051 1220 #--Create a new Running_Experiment Object
1052 1221 else:
1053 1222 new_running_experiment = RunningExperiment(
1054 1223 radar = radar,
1055 1224 status = 3,
1056 1225 )
1057 1226 new_running_experiment.save()
1058 1227 new_running_experiment.running_experiment.add(exp)
1059 1228 new_running_experiment.save()
1060 1229
1061 1230 if answer:
1062 1231 messages.success(request, conf.message)
1063 1232 exp.status=2
1064 1233 exp.save()
1065 1234 else:
1066 1235 messages.error(request, conf.message)
1067 1236 else:
1068 1237 if exp.status == 1 or exp.status == 3:
1069 1238 exp.status=3
1070 1239 exp.save()
1071 1240
1072 1241
1073 1242 route = request.META['HTTP_REFERER']
1074 1243 route = str(route)
1075 1244 if 'search' in route:
1076 1245 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1077 1246 else:
1078 1247 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1079 1248
1080 1249
1081 1250 def radar_stop(request, id_camp, id_radar):
1082 1251 campaign = get_object_or_404(Campaign, pk = id_camp)
1083 1252 radar = get_object_or_404(Location, pk = id_radar)
1084 1253 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1085 1254
1086 1255 for exp in experiments:
1087 1256 configurations = Configuration.objects.filter(experiment = exp)
1088 1257 for conf in configurations:
1089 1258 if 'cgs' in conf.device.device_type.name:
1090 1259 conf.status_device()
1091 1260 else:
1092 1261 answer = conf.stop_device()
1093 1262 conf.status_device()
1094 1263
1095 1264 if answer:
1096 1265 messages.success(request, conf.message)
1097 1266 exp.status=1
1098 1267 exp.save()
1099 1268 else:
1100 1269 messages.error(request, conf.message)
1101 1270
1102 1271
1103 1272 route = request.META['HTTP_REFERER']
1104 1273 route = str(route)
1105 1274 if 'search' in route:
1106 1275 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1107 1276 else:
1108 1277 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1109 1278
1110 1279
1111 1280 def radar_refresh(request, id_camp, id_radar):
1112 1281
1113 1282 campaign = get_object_or_404(Campaign, pk = id_camp)
1114 1283 radar = get_object_or_404(Location, pk = id_radar)
1115 1284 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1116 1285 for exs in experiments:
1117 1286 exs.get_status()
1118 1287
1119 1288 route = request.META['HTTP_REFERER']
1120 1289 route = str(route)
1121 1290 if 'search' in route:
1122 1291 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1123 1292 else:
1124 1293 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1125 1294
General Comments 0
You need to be logged in to leave comments. Login now