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