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