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