##// END OF EJS Templates
- Add sequence mode in mix configurations....
Juan C. Espinoza -
r116:a8c158fbcba1
parent child
Show More
@@ -1,1379 +1,1380
1 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
1 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
2 from django.utils.safestring import mark_safe
2 from django.utils.safestring import mark_safe
3 from django.http import HttpResponseRedirect
3 from django.http import HttpResponseRedirect
4 from django.core.urlresolvers import reverse
4 from django.core.urlresolvers import reverse
5 from django.contrib import messages
5 from django.contrib import messages
6 from datetime import datetime
6 from datetime import datetime
7
7
8 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
8 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
9 from .forms import OperationSearchForm
9 from .forms import OperationSearchForm
10 from apps.cgs.forms import CGSConfigurationForm
10 from apps.cgs.forms import CGSConfigurationForm
11 from apps.jars.forms import JARSConfigurationForm
11 from apps.jars.forms import JARSConfigurationForm
12 from apps.usrp.forms import USRPConfigurationForm
12 from apps.usrp.forms import USRPConfigurationForm
13 from apps.abs.forms import ABSConfigurationForm
13 from apps.abs.forms import ABSConfigurationForm
14 from apps.rc.forms import RCConfigurationForm, RCMixConfigurationForm
14 from apps.rc.forms import RCConfigurationForm, RCMixConfigurationForm
15 from apps.dds.forms import DDSConfigurationForm
15 from apps.dds.forms import DDSConfigurationForm
16
16
17 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment
17 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment
18 from apps.cgs.models import CGSConfiguration
18 from apps.cgs.models import CGSConfiguration
19 from apps.jars.models import JARSConfiguration
19 from apps.jars.models import JARSConfiguration
20 from apps.usrp.models import USRPConfiguration
20 from apps.usrp.models import USRPConfiguration
21 from apps.abs.models import ABSConfiguration
21 from apps.abs.models import ABSConfiguration
22 from apps.rc.models import RCConfiguration, RCLine, RCLineType
22 from apps.rc.models import RCConfiguration, RCLine, RCLineType
23 from apps.dds.models import DDSConfiguration
23 from apps.dds.models import DDSConfiguration
24
24
25 # Create your views here.
25 # Create your views here.
26
26
27 CONF_FORMS = {
27 CONF_FORMS = {
28 'rc': RCConfigurationForm,
28 'rc': RCConfigurationForm,
29 'rc_mix': RCMixConfigurationForm,
29 'rc_mix': RCMixConfigurationForm,
30 'dds': DDSConfigurationForm,
30 'dds': DDSConfigurationForm,
31 'jars': JARSConfigurationForm,
31 'jars': JARSConfigurationForm,
32 'cgs': CGSConfigurationForm,
32 'cgs': CGSConfigurationForm,
33 'abs': ABSConfigurationForm,
33 'abs': ABSConfigurationForm,
34 'usrp': USRPConfigurationForm,
34 'usrp': USRPConfigurationForm,
35 }
35 }
36
36
37 CONF_MODELS = {
37 CONF_MODELS = {
38 'rc': RCConfiguration,
38 'rc': RCConfiguration,
39 'dds': DDSConfiguration,
39 'dds': DDSConfiguration,
40 'jars': JARSConfiguration,
40 'jars': JARSConfiguration,
41 'cgs': CGSConfiguration,
41 'cgs': CGSConfiguration,
42 'abs': ABSConfiguration,
42 'abs': ABSConfiguration,
43 'usrp': USRPConfiguration,
43 'usrp': USRPConfiguration,
44 }
44 }
45
45
46 MIX_MODES = {
46 MIX_MODES = {
47 '0': 'P',
47 '0': 'P',
48 '1': 'S',
48 '1': 'S',
49 }
49 }
50
50
51 MIX_OPERATIONS = {
51 MIX_OPERATIONS = {
52 '0': 'OR',
52 '0': 'OR',
53 '1': 'XOR',
53 '1': 'XOR',
54 '2': 'AND',
54 '2': 'AND',
55 '3': 'NAND',
55 '3': 'NAND',
56 }
56 }
57
57
58
58
59 def index(request):
59 def index(request):
60 kwargs = {}
60 kwargs = {}
61
61
62 return render(request, 'index.html', kwargs)
62 return render(request, 'index.html', kwargs)
63
63
64
64
65 def locations(request):
65 def locations(request):
66
66
67 locations = Location.objects.all().order_by('name')
67 locations = Location.objects.all().order_by('name')
68
68
69 keys = ['id', 'name', 'description']
69 keys = ['id', 'name', 'description']
70
70
71 kwargs = {}
71 kwargs = {}
72 kwargs['location_keys'] = keys[1:]
72 kwargs['location_keys'] = keys[1:]
73 kwargs['locations'] = locations
73 kwargs['locations'] = locations
74 kwargs['title'] = 'Location'
74 kwargs['title'] = 'Location'
75 kwargs['suptitle'] = 'List'
75 kwargs['suptitle'] = 'List'
76 kwargs['button'] = 'New Location'
76 kwargs['button'] = 'New Location'
77
77
78 return render(request, 'locations.html', kwargs)
78 return render(request, 'locations.html', kwargs)
79
79
80
80
81 def location(request, id_loc):
81 def location(request, id_loc):
82
82
83 location = get_object_or_404(Location, pk=id_loc)
83 location = get_object_or_404(Location, pk=id_loc)
84
84
85 kwargs = {}
85 kwargs = {}
86 kwargs['location'] = location
86 kwargs['location'] = location
87 kwargs['location_keys'] = ['name', 'description']
87 kwargs['location_keys'] = ['name', 'description']
88
88
89 kwargs['title'] = 'Location'
89 kwargs['title'] = 'Location'
90 kwargs['suptitle'] = 'Details'
90 kwargs['suptitle'] = 'Details'
91
91
92 return render(request, 'location.html', kwargs)
92 return render(request, 'location.html', kwargs)
93
93
94
94
95 def location_new(request):
95 def location_new(request):
96
96
97 if request.method == 'GET':
97 if request.method == 'GET':
98 form = LocationForm()
98 form = LocationForm()
99
99
100 if request.method == 'POST':
100 if request.method == 'POST':
101 form = LocationForm(request.POST)
101 form = LocationForm(request.POST)
102
102
103 if form.is_valid():
103 if form.is_valid():
104 form.save()
104 form.save()
105 return redirect('url_locations')
105 return redirect('url_locations')
106
106
107 kwargs = {}
107 kwargs = {}
108 kwargs['form'] = form
108 kwargs['form'] = form
109 kwargs['title'] = 'Location'
109 kwargs['title'] = 'Location'
110 kwargs['suptitle'] = 'New'
110 kwargs['suptitle'] = 'New'
111 kwargs['button'] = 'Create'
111 kwargs['button'] = 'Create'
112
112
113 return render(request, 'location_edit.html', kwargs)
113 return render(request, 'location_edit.html', kwargs)
114
114
115
115
116 def location_edit(request, id_loc):
116 def location_edit(request, id_loc):
117
117
118 location = get_object_or_404(Location, pk=id_loc)
118 location = get_object_or_404(Location, pk=id_loc)
119
119
120 if request.method=='GET':
120 if request.method=='GET':
121 form = LocationForm(instance=location)
121 form = LocationForm(instance=location)
122
122
123 if request.method=='POST':
123 if request.method=='POST':
124 form = LocationForm(request.POST, instance=location)
124 form = LocationForm(request.POST, instance=location)
125
125
126 if form.is_valid():
126 if form.is_valid():
127 form.save()
127 form.save()
128 return redirect('url_locations')
128 return redirect('url_locations')
129
129
130 kwargs = {}
130 kwargs = {}
131 kwargs['form'] = form
131 kwargs['form'] = form
132 kwargs['title'] = 'Location'
132 kwargs['title'] = 'Location'
133 kwargs['suptitle'] = 'Edit'
133 kwargs['suptitle'] = 'Edit'
134 kwargs['button'] = 'Update'
134 kwargs['button'] = 'Update'
135
135
136 return render(request, 'location_edit.html', kwargs)
136 return render(request, 'location_edit.html', kwargs)
137
137
138
138
139 def location_delete(request, id_loc):
139 def location_delete(request, id_loc):
140
140
141 location = get_object_or_404(Location, pk=id_loc)
141 location = get_object_or_404(Location, pk=id_loc)
142
142
143 if request.method=='POST':
143 if request.method=='POST':
144
144
145 if request.user.is_staff:
145 if request.user.is_staff:
146 location.delete()
146 location.delete()
147 return redirect('url_locations')
147 return redirect('url_locations')
148
148
149 messages.error(request, 'Not enough permission to delete this object')
149 messages.error(request, 'Not enough permission to delete this object')
150 return redirect(location.get_absolute_url())
150 return redirect(location.get_absolute_url())
151
151
152 kwargs = {
152 kwargs = {
153 'title': 'Delete',
153 'title': 'Delete',
154 'suptitle': 'Location',
154 'suptitle': 'Location',
155 'object': location,
155 'object': location,
156 'previous': location.get_absolute_url(),
156 'previous': location.get_absolute_url(),
157 'delete': True
157 'delete': True
158 }
158 }
159
159
160 return render(request, 'confirm.html', kwargs)
160 return render(request, 'confirm.html', kwargs)
161
161
162
162
163 def devices(request):
163 def devices(request):
164
164
165 devices = Device.objects.all().order_by('device_type__name')
165 devices = Device.objects.all().order_by('device_type__name')
166
166
167 # keys = ['id', 'device_type__name', 'name', 'ip_address']
167 # keys = ['id', 'device_type__name', 'name', 'ip_address']
168 keys = ['id', 'name', 'ip_address', 'port_address', 'device_type']
168 keys = ['id', 'name', 'ip_address', 'port_address', 'device_type']
169
169
170 kwargs = {}
170 kwargs = {}
171 kwargs['device_keys'] = keys[1:]
171 kwargs['device_keys'] = keys[1:]
172 kwargs['devices'] = devices#.values(*keys)
172 kwargs['devices'] = devices#.values(*keys)
173 kwargs['title'] = 'Device'
173 kwargs['title'] = 'Device'
174 kwargs['suptitle'] = 'List'
174 kwargs['suptitle'] = 'List'
175 kwargs['button'] = 'New Device'
175 kwargs['button'] = 'New Device'
176
176
177 return render(request, 'devices.html', kwargs)
177 return render(request, 'devices.html', kwargs)
178
178
179
179
180 def device(request, id_dev):
180 def device(request, id_dev):
181
181
182 device = get_object_or_404(Device, pk=id_dev)
182 device = get_object_or_404(Device, pk=id_dev)
183
183
184 kwargs = {}
184 kwargs = {}
185 kwargs['device'] = device
185 kwargs['device'] = device
186 kwargs['device_keys'] = ['device_type', 'name', 'ip_address', 'port_address', 'description']
186 kwargs['device_keys'] = ['device_type', 'name', 'ip_address', 'port_address', 'description']
187
187
188 kwargs['title'] = 'Device'
188 kwargs['title'] = 'Device'
189 kwargs['suptitle'] = 'Details'
189 kwargs['suptitle'] = 'Details'
190
190
191 return render(request, 'device.html', kwargs)
191 return render(request, 'device.html', kwargs)
192
192
193
193
194 def device_new(request):
194 def device_new(request):
195
195
196 if request.method == 'GET':
196 if request.method == 'GET':
197 form = DeviceForm()
197 form = DeviceForm()
198
198
199 if request.method == 'POST':
199 if request.method == 'POST':
200 form = DeviceForm(request.POST)
200 form = DeviceForm(request.POST)
201
201
202 if form.is_valid():
202 if form.is_valid():
203 form.save()
203 form.save()
204 return redirect('url_devices')
204 return redirect('url_devices')
205
205
206 kwargs = {}
206 kwargs = {}
207 kwargs['form'] = form
207 kwargs['form'] = form
208 kwargs['title'] = 'Device'
208 kwargs['title'] = 'Device'
209 kwargs['suptitle'] = 'New'
209 kwargs['suptitle'] = 'New'
210 kwargs['button'] = 'Create'
210 kwargs['button'] = 'Create'
211
211
212 return render(request, 'device_edit.html', kwargs)
212 return render(request, 'device_edit.html', kwargs)
213
213
214
214
215 def device_edit(request, id_dev):
215 def device_edit(request, id_dev):
216
216
217 device = get_object_or_404(Device, pk=id_dev)
217 device = get_object_or_404(Device, pk=id_dev)
218
218
219 if request.method=='GET':
219 if request.method=='GET':
220 form = DeviceForm(instance=device)
220 form = DeviceForm(instance=device)
221
221
222 if request.method=='POST':
222 if request.method=='POST':
223 form = DeviceForm(request.POST, instance=device)
223 form = DeviceForm(request.POST, instance=device)
224
224
225 if form.is_valid():
225 if form.is_valid():
226 form.save()
226 form.save()
227 return redirect(device.get_absolute_url())
227 return redirect(device.get_absolute_url())
228
228
229 kwargs = {}
229 kwargs = {}
230 kwargs['form'] = form
230 kwargs['form'] = form
231 kwargs['title'] = 'Device'
231 kwargs['title'] = 'Device'
232 kwargs['suptitle'] = 'Edit'
232 kwargs['suptitle'] = 'Edit'
233 kwargs['button'] = 'Update'
233 kwargs['button'] = 'Update'
234
234
235 return render(request, 'device_edit.html', kwargs)
235 return render(request, 'device_edit.html', kwargs)
236
236
237
237
238 def device_delete(request, id_dev):
238 def device_delete(request, id_dev):
239
239
240 device = get_object_or_404(Device, pk=id_dev)
240 device = get_object_or_404(Device, pk=id_dev)
241
241
242 if request.method=='POST':
242 if request.method=='POST':
243
243
244 if request.user.is_staff:
244 if request.user.is_staff:
245 device.delete()
245 device.delete()
246 return redirect('url_devices')
246 return redirect('url_devices')
247
247
248 messages.error(request, 'Not enough permission to delete this object')
248 messages.error(request, 'Not enough permission to delete this object')
249 return redirect(device.get_absolute_url())
249 return redirect(device.get_absolute_url())
250
250
251 kwargs = {
251 kwargs = {
252 'title': 'Delete',
252 'title': 'Delete',
253 'suptitle': 'Device',
253 'suptitle': 'Device',
254 'object': device,
254 'object': device,
255 'previous': device.get_absolute_url(),
255 'previous': device.get_absolute_url(),
256 'delete': True
256 'delete': True
257 }
257 }
258
258
259 return render(request, 'confirm.html', kwargs)
259 return render(request, 'confirm.html', kwargs)
260
260
261
261
262 def campaigns(request):
262 def campaigns(request):
263
263
264 campaigns = Campaign.objects.all().order_by('start_date')
264 campaigns = Campaign.objects.all().order_by('start_date')
265
265
266 keys = ['id', 'name', 'start_date', 'end_date']
266 keys = ['id', 'name', 'start_date', 'end_date']
267
267
268 kwargs = {}
268 kwargs = {}
269 kwargs['campaign_keys'] = keys[1:]
269 kwargs['campaign_keys'] = keys[1:]
270 kwargs['campaigns'] = campaigns#.values(*keys)
270 kwargs['campaigns'] = campaigns#.values(*keys)
271 kwargs['title'] = 'Campaign'
271 kwargs['title'] = 'Campaign'
272 kwargs['suptitle'] = 'List'
272 kwargs['suptitle'] = 'List'
273 kwargs['button'] = 'New Campaign'
273 kwargs['button'] = 'New Campaign'
274
274
275 return render(request, 'campaigns.html', kwargs)
275 return render(request, 'campaigns.html', kwargs)
276
276
277
277
278 def campaign(request, id_camp):
278 def campaign(request, id_camp):
279
279
280 campaign = get_object_or_404(Campaign, pk=id_camp)
280 campaign = get_object_or_404(Campaign, pk=id_camp)
281 experiments = Experiment.objects.filter(campaign=campaign)
281 experiments = Experiment.objects.filter(campaign=campaign)
282
282
283 form = CampaignForm(instance=campaign)
283 form = CampaignForm(instance=campaign)
284
284
285 kwargs = {}
285 kwargs = {}
286 kwargs['campaign'] = campaign
286 kwargs['campaign'] = campaign
287 kwargs['campaign_keys'] = ['template', 'name', 'start_date', 'end_date', 'tags', 'description']
287 kwargs['campaign_keys'] = ['template', 'name', 'start_date', 'end_date', 'tags', 'description']
288
288
289 kwargs['experiments'] = experiments
289 kwargs['experiments'] = experiments
290 kwargs['experiment_keys'] = ['name', 'radar', 'start_time', 'end_time']
290 kwargs['experiment_keys'] = ['name', 'radar', 'start_time', 'end_time']
291
291
292 kwargs['title'] = 'Campaign'
292 kwargs['title'] = 'Campaign'
293 kwargs['suptitle'] = 'Details'
293 kwargs['suptitle'] = 'Details'
294
294
295 kwargs['form'] = form
295 kwargs['form'] = form
296 kwargs['button'] = 'Add Experiment'
296 kwargs['button'] = 'Add Experiment'
297
297
298 return render(request, 'campaign.html', kwargs)
298 return render(request, 'campaign.html', kwargs)
299
299
300
300
301 def campaign_new(request):
301 def campaign_new(request):
302
302
303 kwargs = {}
303 kwargs = {}
304
304
305 if request.method == 'GET':
305 if request.method == 'GET':
306
306
307 if 'template' in request.GET:
307 if 'template' in request.GET:
308 if request.GET['template']=='0':
308 if request.GET['template']=='0':
309 form = NewForm(initial={'create_from':2},
309 form = NewForm(initial={'create_from':2},
310 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
310 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
311 else:
311 else:
312 kwargs['button'] = 'Create'
312 kwargs['button'] = 'Create'
313 kwargs['experiments'] = Configuration.objects.filter(experiment=request.GET['template'])
313 kwargs['experiments'] = Configuration.objects.filter(experiment=request.GET['template'])
314 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
314 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
315 camp = Campaign.objects.get(pk=request.GET['template'])
315 camp = Campaign.objects.get(pk=request.GET['template'])
316 form = CampaignForm(instance=camp,
316 form = CampaignForm(instance=camp,
317 initial={'name':'{} [{:%Y/%m/%d}]'.format(camp.name, datetime.now()),
317 initial={'name':'{} [{:%Y/%m/%d}]'.format(camp.name, datetime.now()),
318 'template':False})
318 'template':False})
319 elif 'blank' in request.GET:
319 elif 'blank' in request.GET:
320 kwargs['button'] = 'Create'
320 kwargs['button'] = 'Create'
321 form = CampaignForm()
321 form = CampaignForm()
322 else:
322 else:
323 form = NewForm()
323 form = NewForm()
324
324
325 if request.method == 'POST':
325 if request.method == 'POST':
326 kwargs['button'] = 'Create'
326 kwargs['button'] = 'Create'
327 post = request.POST.copy()
327 post = request.POST.copy()
328 experiments = []
328 experiments = []
329
329
330 for id_exp in post.getlist('experiments'):
330 for id_exp in post.getlist('experiments'):
331 exp = Experiment.objects.get(pk=id_exp)
331 exp = Experiment.objects.get(pk=id_exp)
332 new_exp = exp.clone(template=False)
332 new_exp = exp.clone(template=False)
333 experiments.append(new_exp)
333 experiments.append(new_exp)
334
334
335 post.setlist('experiments', [])
335 post.setlist('experiments', [])
336
336
337 form = CampaignForm(post)
337 form = CampaignForm(post)
338
338
339 if form.is_valid():
339 if form.is_valid():
340 campaign = form.save()
340 campaign = form.save()
341 for exp in experiments:
341 for exp in experiments:
342 campaign.experiments.add(exp)
342 campaign.experiments.add(exp)
343 campaign.save()
343 campaign.save()
344 return redirect('url_campaign', id_camp=campaign.id)
344 return redirect('url_campaign', id_camp=campaign.id)
345
345
346 kwargs['form'] = form
346 kwargs['form'] = form
347 kwargs['title'] = 'Campaign'
347 kwargs['title'] = 'Campaign'
348 kwargs['suptitle'] = 'New'
348 kwargs['suptitle'] = 'New'
349
349
350 return render(request, 'campaign_edit.html', kwargs)
350 return render(request, 'campaign_edit.html', kwargs)
351
351
352
352
353 def campaign_edit(request, id_camp):
353 def campaign_edit(request, id_camp):
354
354
355 campaign = get_object_or_404(Campaign, pk=id_camp)
355 campaign = get_object_or_404(Campaign, pk=id_camp)
356
356
357 if request.method=='GET':
357 if request.method=='GET':
358 form = CampaignForm(instance=campaign)
358 form = CampaignForm(instance=campaign)
359
359
360 if request.method=='POST':
360 if request.method=='POST':
361 exps = campaign.experiments.all().values_list('pk', flat=True)
361 exps = campaign.experiments.all().values_list('pk', flat=True)
362 post = request.POST.copy()
362 post = request.POST.copy()
363 new_exps = post.getlist('experiments')
363 new_exps = post.getlist('experiments')
364 post.setlist('experiments', [])
364 post.setlist('experiments', [])
365 form = CampaignForm(post, instance=campaign)
365 form = CampaignForm(post, instance=campaign)
366
366
367 if form.is_valid():
367 if form.is_valid():
368 camp = form.save()
368 camp = form.save()
369 for id_exp in new_exps:
369 for id_exp in new_exps:
370 if int(id_exp) in exps:
370 if int(id_exp) in exps:
371 exps.pop(id_exp)
371 exps.pop(id_exp)
372 else:
372 else:
373 exp = Experiment.objects.get(pk=id_exp)
373 exp = Experiment.objects.get(pk=id_exp)
374 if exp.template:
374 if exp.template:
375 camp.experiments.add(exp.clone(template=False))
375 camp.experiments.add(exp.clone(template=False))
376 else:
376 else:
377 camp.experiments.add(exp)
377 camp.experiments.add(exp)
378
378
379 for id_exp in exps:
379 for id_exp in exps:
380 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
380 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
381
381
382 return redirect('url_campaign', id_camp=id_camp)
382 return redirect('url_campaign', id_camp=id_camp)
383
383
384 kwargs = {}
384 kwargs = {}
385 kwargs['form'] = form
385 kwargs['form'] = form
386 kwargs['title'] = 'Campaign'
386 kwargs['title'] = 'Campaign'
387 kwargs['suptitle'] = 'Edit'
387 kwargs['suptitle'] = 'Edit'
388 kwargs['button'] = 'Update'
388 kwargs['button'] = 'Update'
389
389
390 return render(request, 'campaign_edit.html', kwargs)
390 return render(request, 'campaign_edit.html', kwargs)
391
391
392
392
393 def campaign_delete(request, id_camp):
393 def campaign_delete(request, id_camp):
394
394
395 campaign = get_object_or_404(Campaign, pk=id_camp)
395 campaign = get_object_or_404(Campaign, pk=id_camp)
396
396
397 if request.method=='POST':
397 if request.method=='POST':
398 if request.user.is_staff:
398 if request.user.is_staff:
399
399
400 for exp in campaign.experiments.all():
400 for exp in campaign.experiments.all():
401 for conf in Configuration.objects.filter(experiment=exp):
401 for conf in Configuration.objects.filter(experiment=exp):
402 conf.delete()
402 conf.delete()
403 exp.delete()
403 exp.delete()
404 campaign.delete()
404 campaign.delete()
405
405
406 return redirect('url_campaigns')
406 return redirect('url_campaigns')
407
407
408 messages.error(request, 'Not enough permission to delete this object')
408 messages.error(request, 'Not enough permission to delete this object')
409 return redirect(campaign.get_absolute_url())
409 return redirect(campaign.get_absolute_url())
410
410
411 kwargs = {
411 kwargs = {
412 'title': 'Delete',
412 'title': 'Delete',
413 'suptitle': 'Campaign',
413 'suptitle': 'Campaign',
414 'object': campaign,
414 'object': campaign,
415 'previous': campaign.get_absolute_url(),
415 'previous': campaign.get_absolute_url(),
416 'delete': True
416 'delete': True
417 }
417 }
418
418
419 return render(request, 'confirm.html', kwargs)
419 return render(request, 'confirm.html', kwargs)
420
420
421 def campaign_export(request, id_camp):
421 def campaign_export(request, id_camp):
422
422
423 campaign = get_object_or_404(Campaign, pk=id_camp)
423 campaign = get_object_or_404(Campaign, pk=id_camp)
424 content = campaign.parms_to_dict()
424 content = campaign.parms_to_dict()
425 content_type = 'application/json'
425 content_type = 'application/json'
426 filename = '%s_%s.json' %(campaign.name, campaign.id)
426 filename = '%s_%s.json' %(campaign.name, campaign.id)
427
427
428 response = HttpResponse(content_type=content_type)
428 response = HttpResponse(content_type=content_type)
429 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
429 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
430 response.write(content)
430 response.write(content)
431
431
432 return response
432 return response
433
433
434
434
435 def campaign_import(request, id_camp):
435 def campaign_import(request, id_camp):
436
436
437 campaign = get_object_or_404(Campaign, pk=id_camp)
437 campaign = get_object_or_404(Campaign, pk=id_camp)
438
438
439 if request.method == 'GET':
439 if request.method == 'GET':
440 file_form = UploadFileForm()
440 file_form = UploadFileForm()
441
441
442 if request.method == 'POST':
442 if request.method == 'POST':
443 file_form = UploadFileForm(request.POST, request.FILES)
443 file_form = UploadFileForm(request.POST, request.FILES)
444
444
445 if file_form.is_valid():
445 if file_form.is_valid():
446
446
447 parms = campaign.import_from_file(request.FILES['file'])
447 parms = campaign.import_from_file(request.FILES['file'])
448
448
449 if parms:
449 if parms:
450 parms['name'] = parms['campaign']
450 parms['name'] = parms['campaign']
451
451
452 new_camp = campaign.dict_to_parms(parms, CONF_MODELS)
452 new_camp = campaign.dict_to_parms(parms, CONF_MODELS)
453
453
454 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
454 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
455
455
456 return redirect(new_camp.get_absolute_url_edit())
456 return redirect(new_camp.get_absolute_url_edit())
457
457
458 messages.error(request, "Could not import parameters from file")
458 messages.error(request, "Could not import parameters from file")
459
459
460 kwargs = {}
460 kwargs = {}
461 kwargs['title'] = 'Campaign'
461 kwargs['title'] = 'Campaign'
462 kwargs['form'] = file_form
462 kwargs['form'] = file_form
463 kwargs['suptitle'] = 'Importing file'
463 kwargs['suptitle'] = 'Importing file'
464 kwargs['button'] = 'Import'
464 kwargs['button'] = 'Import'
465
465
466 return render(request, 'campaign_import.html', kwargs)
466 return render(request, 'campaign_import.html', kwargs)
467
467
468
468
469 def experiments(request):
469 def experiments(request):
470
470
471 experiment_list = Experiment.objects.all()
471 experiment_list = Experiment.objects.all()
472
472
473 keys = ['id', 'name', 'start_time', 'end_time']
473 keys = ['id', 'name', 'start_time', 'end_time']
474
474
475 kwargs = {}
475 kwargs = {}
476
476
477 kwargs['experiment_keys'] = keys[1:]
477 kwargs['experiment_keys'] = keys[1:]
478 kwargs['experiments'] = experiment_list
478 kwargs['experiments'] = experiment_list
479
479
480 kwargs['title'] = 'Experiment'
480 kwargs['title'] = 'Experiment'
481 kwargs['suptitle'] = 'List'
481 kwargs['suptitle'] = 'List'
482 kwargs['button'] = 'New Experiment'
482 kwargs['button'] = 'New Experiment'
483
483
484 return render(request, 'experiments.html', kwargs)
484 return render(request, 'experiments.html', kwargs)
485
485
486
486
487 def experiment(request, id_exp):
487 def experiment(request, id_exp):
488
488
489 experiment = get_object_or_404(Experiment, pk=id_exp)
489 experiment = get_object_or_404(Experiment, pk=id_exp)
490
490
491 configurations = Configuration.objects.filter(experiment=experiment, type=0)
491 configurations = Configuration.objects.filter(experiment=experiment, type=0)
492
492
493 kwargs = {}
493 kwargs = {}
494
494
495 kwargs['experiment_keys'] = ['template', 'radar', 'name', 'start_time', 'end_time']
495 kwargs['experiment_keys'] = ['template', 'radar', 'name', 'start_time', 'end_time']
496 kwargs['experiment'] = experiment
496 kwargs['experiment'] = experiment
497
497
498 kwargs['configuration_keys'] = ['name', 'device__device_type', 'device__ip_address', 'device__port_address']
498 kwargs['configuration_keys'] = ['name', 'device__device_type', 'device__ip_address', 'device__port_address']
499 kwargs['configurations'] = configurations
499 kwargs['configurations'] = configurations
500
500
501 kwargs['title'] = 'Experiment'
501 kwargs['title'] = 'Experiment'
502 kwargs['suptitle'] = 'Details'
502 kwargs['suptitle'] = 'Details'
503
503
504 kwargs['button'] = 'Add Configuration'
504 kwargs['button'] = 'Add Configuration'
505
505
506 ###### SIDEBAR ######
506 ###### SIDEBAR ######
507 kwargs.update(sidebar(experiment=experiment))
507 kwargs.update(sidebar(experiment=experiment))
508
508
509 return render(request, 'experiment.html', kwargs)
509 return render(request, 'experiment.html', kwargs)
510
510
511
511
512 def experiment_new(request, id_camp=None):
512 def experiment_new(request, id_camp=None):
513
513
514 kwargs = {}
514 kwargs = {}
515
515
516 if request.method == 'GET':
516 if request.method == 'GET':
517 if 'template' in request.GET:
517 if 'template' in request.GET:
518 if request.GET['template']=='0':
518 if request.GET['template']=='0':
519 form = NewForm(initial={'create_from':2},
519 form = NewForm(initial={'create_from':2},
520 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
520 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
521 else:
521 else:
522 kwargs['button'] = 'Create'
522 kwargs['button'] = 'Create'
523 kwargs['configurations'] = Configuration.objects.filter(experiment=request.GET['template'])
523 kwargs['configurations'] = Configuration.objects.filter(experiment=request.GET['template'])
524 kwargs['configuration_keys'] = ['name', 'device__name', 'device__ip_address', 'device__port_address']
524 kwargs['configuration_keys'] = ['name', 'device__name', 'device__ip_address', 'device__port_address']
525 exp=Experiment.objects.get(pk=request.GET['template'])
525 exp=Experiment.objects.get(pk=request.GET['template'])
526 form = ExperimentForm(instance=exp,
526 form = ExperimentForm(instance=exp,
527 initial={'name': '{} [{:%Y/%m/%d}]'.format(exp.name, datetime.now()),
527 initial={'name': '{} [{:%Y/%m/%d}]'.format(exp.name, datetime.now()),
528 'template': False})
528 'template': False})
529 elif 'blank' in request.GET:
529 elif 'blank' in request.GET:
530 kwargs['button'] = 'Create'
530 kwargs['button'] = 'Create'
531 form = ExperimentForm()
531 form = ExperimentForm()
532 else:
532 else:
533 form = NewForm()
533 form = NewForm()
534
534
535 if request.method == 'POST':
535 if request.method == 'POST':
536 form = ExperimentForm(request.POST)
536 form = ExperimentForm(request.POST)
537 if form.is_valid():
537 if form.is_valid():
538 experiment = form.save()
538 experiment = form.save()
539
539
540 if 'template' in request.GET:
540 if 'template' in request.GET:
541 configurations = Configuration.objects.filter(experiment=request.GET['template'], type=0)
541 configurations = Configuration.objects.filter(experiment=request.GET['template'], type=0)
542 for conf in configurations:
542 for conf in configurations:
543 conf.clone(experiment=experiment, template=False)
543 conf.clone(experiment=experiment, template=False)
544
544
545 return redirect('url_experiment', id_exp=experiment.id)
545 return redirect('url_experiment', id_exp=experiment.id)
546
546
547 kwargs['form'] = form
547 kwargs['form'] = form
548 kwargs['title'] = 'Experiment'
548 kwargs['title'] = 'Experiment'
549 kwargs['suptitle'] = 'New'
549 kwargs['suptitle'] = 'New'
550
550
551 return render(request, 'experiment_edit.html', kwargs)
551 return render(request, 'experiment_edit.html', kwargs)
552
552
553
553
554 def experiment_edit(request, id_exp):
554 def experiment_edit(request, id_exp):
555
555
556 experiment = get_object_or_404(Experiment, pk=id_exp)
556 experiment = get_object_or_404(Experiment, pk=id_exp)
557
557
558 if request.method == 'GET':
558 if request.method == 'GET':
559 form = ExperimentForm(instance=experiment)
559 form = ExperimentForm(instance=experiment)
560
560
561 if request.method=='POST':
561 if request.method=='POST':
562 form = ExperimentForm(request.POST, instance=experiment)
562 form = ExperimentForm(request.POST, instance=experiment)
563
563
564 if form.is_valid():
564 if form.is_valid():
565 experiment = form.save()
565 experiment = form.save()
566 return redirect('url_experiment', id_exp=experiment.id)
566 return redirect('url_experiment', id_exp=experiment.id)
567
567
568 kwargs = {}
568 kwargs = {}
569 kwargs['form'] = form
569 kwargs['form'] = form
570 kwargs['title'] = 'Experiment'
570 kwargs['title'] = 'Experiment'
571 kwargs['suptitle'] = 'Edit'
571 kwargs['suptitle'] = 'Edit'
572 kwargs['button'] = 'Update'
572 kwargs['button'] = 'Update'
573
573
574 return render(request, 'experiment_edit.html', kwargs)
574 return render(request, 'experiment_edit.html', kwargs)
575
575
576
576
577 def experiment_delete(request, id_exp):
577 def experiment_delete(request, id_exp):
578
578
579 experiment = get_object_or_404(Experiment, pk=id_exp)
579 experiment = get_object_or_404(Experiment, pk=id_exp)
580
580
581 if request.method=='POST':
581 if request.method=='POST':
582 if request.user.is_staff:
582 if request.user.is_staff:
583 for conf in Configuration.objects.filter(experiment=experiment):
583 for conf in Configuration.objects.filter(experiment=experiment):
584 conf.delete()
584 conf.delete()
585 experiment.delete()
585 experiment.delete()
586 return redirect('url_experiments')
586 return redirect('url_experiments')
587
587
588 messages.error(request, 'Not enough permission to delete this object')
588 messages.error(request, 'Not enough permission to delete this object')
589 return redirect(experiment.get_absolute_url())
589 return redirect(experiment.get_absolute_url())
590
590
591 kwargs = {
591 kwargs = {
592 'title': 'Delete',
592 'title': 'Delete',
593 'suptitle': 'Experiment',
593 'suptitle': 'Experiment',
594 'object': experiment,
594 'object': experiment,
595 'previous': experiment.get_absolute_url(),
595 'previous': experiment.get_absolute_url(),
596 'delete': True
596 'delete': True
597 }
597 }
598
598
599 return render(request, 'confirm.html', kwargs)
599 return render(request, 'confirm.html', kwargs)
600
600
601
601
602 def experiment_export(request, id_exp):
602 def experiment_export(request, id_exp):
603
603
604 experiment = get_object_or_404(Experiment, pk=id_exp)
604 experiment = get_object_or_404(Experiment, pk=id_exp)
605 content = experiment.parms_to_dict()
605 content = experiment.parms_to_dict()
606 content_type = 'application/json'
606 content_type = 'application/json'
607 filename = '%s_%s.json' %(experiment.name, experiment.id)
607 filename = '%s_%s.json' %(experiment.name, experiment.id)
608
608
609 response = HttpResponse(content_type=content_type)
609 response = HttpResponse(content_type=content_type)
610 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
610 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
611 response.write(content)
611 response.write(content)
612
612
613 return response
613 return response
614
614
615 def experiment_import(request, id_exp):
615 def experiment_import(request, id_exp):
616
616
617 experiment = get_object_or_404(Experiment, pk=id_exp)
617 experiment = get_object_or_404(Experiment, pk=id_exp)
618 configurations = Configuration.objects.filter(experiment=experiment)
618 configurations = Configuration.objects.filter(experiment=experiment)
619
619
620 if request.method == 'GET':
620 if request.method == 'GET':
621 file_form = UploadFileForm()
621 file_form = UploadFileForm()
622
622
623 if request.method == 'POST':
623 if request.method == 'POST':
624 file_form = UploadFileForm(request.POST, request.FILES)
624 file_form = UploadFileForm(request.POST, request.FILES)
625
625
626 if file_form.is_valid():
626 if file_form.is_valid():
627
627
628 parms = experiment.import_from_file(request.FILES['file'])
628 parms = experiment.import_from_file(request.FILES['file'])
629
629
630 if parms:
630 if parms:
631
631
632 new_exp = experiment.dict_to_parms(parms, CONF_MODELS)
632 new_exp = experiment.dict_to_parms(parms, CONF_MODELS)
633
633
634 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
634 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
635
635
636 return redirect(new_exp.get_absolute_url_edit())
636 return redirect(new_exp.get_absolute_url_edit())
637
637
638 messages.error(request, "Could not import parameters from file")
638 messages.error(request, "Could not import parameters from file")
639
639
640 kwargs = {}
640 kwargs = {}
641 kwargs['title'] = 'Experiment'
641 kwargs['title'] = 'Experiment'
642 kwargs['form'] = file_form
642 kwargs['form'] = file_form
643 kwargs['suptitle'] = 'Importing file'
643 kwargs['suptitle'] = 'Importing file'
644 kwargs['button'] = 'Import'
644 kwargs['button'] = 'Import'
645
645
646 kwargs.update(sidebar(experiment=experiment))
646 kwargs.update(sidebar(experiment=experiment))
647
647
648 return render(request, 'experiment_import.html', kwargs)
648 return render(request, 'experiment_import.html', kwargs)
649
649
650 def experiment_mix(request, id_exp):
650 def experiment_mix(request, id_exp):
651
651
652 experiment = get_object_or_404(Experiment, pk=id_exp)
652 experiment = get_object_or_404(Experiment, pk=id_exp)
653 rc_confs = [conf for conf in RCConfiguration.objects.filter(experiment=id_exp,
653 rc_confs = [conf for conf in RCConfiguration.objects.filter(experiment=id_exp,
654 mix=False)]
654 mix=False)]
655
655
656 if len(rc_confs)<2:
656 if len(rc_confs)<2:
657 messages.warning(request, 'You need at least two RC Configurations to make a mix')
657 messages.warning(request, 'You need at least two RC Configurations to make a mix')
658 return redirect(experiment.get_absolute_url())
658 return redirect(experiment.get_absolute_url())
659
659
660 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True)
660 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True)
661
661
662 if mix_confs:
662 if mix_confs:
663 mix = mix_confs[0]
663 mix = mix_confs[0]
664 else:
664 else:
665 mix = RCConfiguration(experiment=experiment,
665 mix = RCConfiguration(experiment=experiment,
666 device=rc_confs[0].device,
666 device=rc_confs[0].device,
667 ipp=rc_confs[0].ipp,
667 ipp=rc_confs[0].ipp,
668 clock_in=rc_confs[0].clock_in,
668 clock_in=rc_confs[0].clock_in,
669 clock_divider=rc_confs[0].clock_divider,
669 clock_divider=rc_confs[0].clock_divider,
670 mix=True,
670 mix=True,
671 parameters='')
671 parameters='')
672 mix.save()
672 mix.save()
673
673
674 line_type = RCLineType.objects.get(name='mix')
674 line_type = RCLineType.objects.get(name='mix')
675 for i in range(len(rc_confs[0].get_lines())):
675 for i in range(len(rc_confs[0].get_lines())):
676 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
676 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
677 line.save()
677 line.save()
678
678
679 initial = {'name': mix.name,
679 initial = {'name': mix.name,
680 'result': parse_mix_result(mix.parameters),
680 'result': parse_mix_result(mix.parameters),
681 'delay': 0,
681 'delay': 0,
682 'mask': [0,1,2,3,4,5,6,7]
682 'mask': [0,1,2,3,4,5,6,7]
683 }
683 }
684
684
685 if request.method=='GET':
685 if request.method=='GET':
686 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
686 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
687
687
688 if request.method=='POST':
688 if request.method=='POST':
689 result = mix.parameters
689 result = mix.parameters
690
690
691 if '{}|'.format(request.POST['experiment']) in result:
691 if '{}|'.format(request.POST['experiment']) in result:
692 messages.error(request, 'Configuration already added')
692 messages.error(request, 'Configuration already added')
693 else:
693 else:
694 if 'operation' in request.POST:
694 if 'operation' in request.POST:
695 operation = MIX_OPERATIONS[request.POST['operation']]
695 operation = MIX_OPERATIONS[request.POST['operation']]
696 else:
696 else:
697 operation = '---'
697 operation = ' '
698
698
699 mode = MIX_MODES[request.POST['mode']]
699 mode = MIX_MODES[request.POST['mode']]
700
700
701 if result:
701 if result:
702 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
702 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
703 request.POST['experiment'],
703 request.POST['experiment'],
704 mode,
704 mode,
705 operation,
705 operation,
706 float(request.POST['delay']),
706 float(request.POST['delay']),
707 parse_mask(request.POST.getlist('mask'))
707 parse_mask(request.POST.getlist('mask'))
708 )
708 )
709 else:
709 else:
710 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
710 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
711 mode,
711 mode,
712 operation,
712 operation,
713 float(request.POST['delay']),
713 float(request.POST['delay']),
714 parse_mask(request.POST.getlist('mask'))
714 parse_mask(request.POST.getlist('mask'))
715 )
715 )
716
716
717 mix.parameters = result
717 mix.parameters = result
718 mix.name = request.POST['name']
718 mix.name = request.POST['name']
719 mix.save()
719 mix.save()
720 mix.update_pulses()
720 mix.update_pulses()
721
721
722 initial['result'] = parse_mix_result(result)
722 initial['result'] = parse_mix_result(result)
723 initial['name'] = mix.name
723 initial['name'] = mix.name
724
724
725 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
725 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
726
726
727
727
728 kwargs = {
728 kwargs = {
729 'title': 'Experiment',
729 'title': 'Experiment',
730 'suptitle': 'Mix Configurations',
730 'suptitle': 'Mix Configurations',
731 'form' : form,
731 'form' : form,
732 'extra_button': 'Delete',
732 'extra_button': 'Delete',
733 'button': 'Add',
733 'button': 'Add',
734 'cancel': 'Back',
734 'cancel': 'Back',
735 'previous': experiment.get_absolute_url(),
735 'previous': experiment.get_absolute_url(),
736 'id_exp':id_exp,
736 'id_exp':id_exp,
737
737
738 }
738 }
739
739
740 return render(request, 'experiment_mix.html', kwargs)
740 return render(request, 'experiment_mix.html', kwargs)
741
741
742
742
743 def experiment_mix_delete(request, id_exp):
743 def experiment_mix_delete(request, id_exp):
744
744
745 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True)
745 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True)
746 values = conf.parameters.split('-')
746 values = conf.parameters.split('-')
747 conf.parameters = '-'.join(values[:-1])
747 conf.parameters = '-'.join(values[:-1])
748 conf.save()
748 conf.save()
749
749
750 return redirect('url_mix_experiment', id_exp=id_exp)
750 return redirect('url_mix_experiment', id_exp=id_exp)
751
751
752
752
753 def parse_mix_result(s):
753 def parse_mix_result(s):
754
754
755 values = s.split('-')
755 values = s.split('-')
756 html = 'EXP MOD OPE DELAY MASK\r\n'
756 html = 'EXP MOD OPE DELAY MASK\r\n'
757
757
758 if not values or values[0] in ('', ' '):
758 if not values or values[0] in ('', ' '):
759 return mark_safe(html)
759 return mark_safe(html)
760
760
761 for i, value in enumerate(values):
761 for i, value in enumerate(values):
762 if not value:
762 if not value:
763 continue
763 continue
764 pk, mode, operation, delay, mask = value.split('|')
764 pk, mode, operation, delay, mask = value.split('|')
765 conf = RCConfiguration.objects.get(pk=pk)
765 conf = RCConfiguration.objects.get(pk=pk)
766 if i==0:
766 if i==0:
767 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
767 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
768 conf.name,
768 conf.name,
769 mode,
769 mode,
770 '---',
770 ' ',
771 delay,
771 delay,
772 mask)
772 mask)
773 else:
773 else:
774 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
774 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
775 conf.name,
775 conf.name,
776 mode,
776 mode,
777 operation,
777 operation,
778 delay,
778 delay,
779 mask)
779 mask)
780
780
781 return mark_safe(html)
781 return mark_safe(html)
782
782
783 def parse_mask(l):
783 def parse_mask(l):
784
784
785 values = []
785 values = []
786
786
787 for x in range(8):
787 for x in range(8):
788 if '{}'.format(x) in l:
788 if '{}'.format(x) in l:
789 values.append(1)
789 values.append(1)
790 else:
790 else:
791 values.append(0)
791 values.append(0)
792
792
793 values.reverse()
793 values.reverse()
794
794
795 return int(''.join([str(x) for x in values]), 2)
795 return int(''.join([str(x) for x in values]), 2)
796
796
797
797
798 def dev_confs(request):
798 def dev_confs(request):
799
799
800 configurations = Configuration.objects.all().order_by('type', 'device__device_type', 'experiment')
800 configurations = Configuration.objects.all().order_by('type', 'device__device_type', 'experiment')
801
801
802 kwargs = {}
802 kwargs = {}
803
803
804 kwargs['configuration_keys'] = ['device', 'name', 'experiment', 'type', 'programmed_date']
804 kwargs['configuration_keys'] = ['device', 'name', 'experiment', 'type', 'programmed_date']
805 kwargs['configurations'] = configurations
805 kwargs['configurations'] = configurations
806
806
807 kwargs['title'] = 'Configuration'
807 kwargs['title'] = 'Configuration'
808 kwargs['suptitle'] = 'List'
808 kwargs['suptitle'] = 'List'
809
809
810 return render(request, 'dev_confs.html', kwargs)
810 return render(request, 'dev_confs.html', kwargs)
811
811
812
812
813 def dev_conf(request, id_conf):
813 def dev_conf(request, id_conf):
814
814
815 conf = get_object_or_404(Configuration, pk=id_conf)
815 conf = get_object_or_404(Configuration, pk=id_conf)
816
816
817 return redirect(conf.get_absolute_url())
817 return redirect(conf.get_absolute_url())
818
818
819
819
820 def dev_conf_new(request, id_exp=0, id_dev=0):
820 def dev_conf_new(request, id_exp=0, id_dev=0):
821
821
822 initial = {}
822 initial = {}
823 kwargs = {}
823 kwargs = {}
824
824
825 if id_exp<>0:
825 if id_exp<>0:
826 initial['experiment'] = id_exp
826 initial['experiment'] = id_exp
827
827
828 if id_dev<>0:
828 if id_dev<>0:
829 initial['device'] = id_dev
829 initial['device'] = id_dev
830
830
831 if request.method == 'GET':
831 if request.method == 'GET':
832
832
833 if id_dev:
833 if id_dev:
834 kwargs['button'] = 'Create'
834 kwargs['button'] = 'Create'
835 device = Device.objects.get(pk=id_dev)
835 device = Device.objects.get(pk=id_dev)
836 DevConfForm = CONF_FORMS[device.device_type.name]
836 DevConfForm = CONF_FORMS[device.device_type.name]
837 initial['name'] = request.GET['name']
837 initial['name'] = request.GET['name']
838 form = DevConfForm(initial=initial)
838 form = DevConfForm(initial=initial)
839 else:
839 else:
840 if 'template' in request.GET:
840 if 'template' in request.GET:
841 if request.GET['template']=='0':
841 if request.GET['template']=='0':
842 form = NewForm(initial={'create_from':2},
842 form = NewForm(initial={'create_from':2},
843 template_choices=Configuration.objects.filter(template=True).values_list('id', 'name'))
843 template_choices=Configuration.objects.filter(template=True).values_list('id', 'name'))
844 else:
844 else:
845 kwargs['button'] = 'Create'
845 kwargs['button'] = 'Create'
846 conf = Configuration.objects.get(pk=request.GET['template'])
846 conf = Configuration.objects.get(pk=request.GET['template'])
847 DevConfForm = CONF_FORMS[conf.device.device_type.name]
847 DevConfForm = CONF_FORMS[conf.device.device_type.name]
848 form = DevConfForm(instance=conf,
848 form = DevConfForm(instance=conf,
849 initial={'name': '{} [{:%Y/%m/%d}]'.format(conf.name, datetime.now()),
849 initial={'name': '{} [{:%Y/%m/%d}]'.format(conf.name, datetime.now()),
850 'template': False})
850 'template': False,
851 'experiment':id_exp})
851 elif 'blank' in request.GET:
852 elif 'blank' in request.GET:
852 kwargs['button'] = 'Create'
853 kwargs['button'] = 'Create'
853 form = ConfigurationForm(initial=initial)
854 form = ConfigurationForm(initial=initial)
854 else:
855 else:
855 form = NewForm()
856 form = NewForm()
856
857
857 if request.method == 'POST':
858 if request.method == 'POST':
858
859
859 device = Device.objects.get(pk=request.POST['device'])
860 device = Device.objects.get(pk=request.POST['device'])
860 DevConfForm = CONF_FORMS[device.device_type.name]
861 DevConfForm = CONF_FORMS[device.device_type.name]
861
862
862 form = DevConfForm(request.POST)
863 form = DevConfForm(request.POST)
863
864
864 if form.is_valid():
865 if form.is_valid():
865 conf = form.save()
866 conf = form.save()
866
867
867 if 'template' in request.GET and conf.device.device_type.name=='rc':
868 if 'template' in request.GET and conf.device.device_type.name=='rc':
868 lines = RCLine.objects.filter(rc_configuration=request.GET['template'])
869 lines = RCLine.objects.filter(rc_configuration=request.GET['template'])
869 for line in lines:
870 for line in lines:
870 line.clone(rc_configuration=conf)
871 line.clone(rc_configuration=conf)
871
872
872 return redirect('url_dev_conf', id_conf=conf.pk)
873 return redirect('url_dev_conf', id_conf=conf.pk)
873
874
874
875
875 kwargs['id_exp'] = id_exp
876 kwargs['id_exp'] = id_exp
876 kwargs['form'] = form
877 kwargs['form'] = form
877 kwargs['title'] = 'Configuration'
878 kwargs['title'] = 'Configuration'
878 kwargs['suptitle'] = 'New'
879 kwargs['suptitle'] = 'New'
879
880
880
881
881 if id_dev != 0:
882 if id_dev != 0:
882 device = Device.objects.get(pk=id_dev)
883 device = Device.objects.get(pk=id_dev)
883 if 'dds' in device.device_type.name:
884 if 'dds' in device.device_type.name:
884 kwargs['dds_device'] = True
885 kwargs['dds_device'] = True
885
886
886 return render(request, 'dev_conf_edit.html', kwargs)
887 return render(request, 'dev_conf_edit.html', kwargs)
887
888
888
889
889 def dev_conf_edit(request, id_conf):
890 def dev_conf_edit(request, id_conf):
890
891
891 conf = get_object_or_404(Configuration, pk=id_conf)
892 conf = get_object_or_404(Configuration, pk=id_conf)
892
893
893 DevConfModel = CONF_MODELS[conf.device.device_type.name]
894 DevConfModel = CONF_MODELS[conf.device.device_type.name]
894 DevConfForm = CONF_FORMS[conf.device.device_type.name]
895 DevConfForm = CONF_FORMS[conf.device.device_type.name]
895
896
896 dev_conf = DevConfModel.objects.get(pk=id_conf)
897 dev_conf = DevConfModel.objects.get(pk=id_conf)
897
898
898 if request.method=='GET':
899 if request.method=='GET':
899 form = DevConfForm(instance=dev_conf)
900 form = DevConfForm(instance=dev_conf)
900
901
901 if request.method=='POST':
902 if request.method=='POST':
902 form = DevConfForm(request.POST, instance=dev_conf)
903 form = DevConfForm(request.POST, instance=dev_conf)
903
904
904 if form.is_valid():
905 if form.is_valid():
905 form.save()
906 form.save()
906 return redirect('url_dev_conf', id_conf=id_conf)
907 return redirect('url_dev_conf', id_conf=id_conf)
907
908
908 kwargs = {}
909 kwargs = {}
909 kwargs['form'] = form
910 kwargs['form'] = form
910 kwargs['title'] = 'Device Configuration'
911 kwargs['title'] = 'Device Configuration'
911 kwargs['suptitle'] = 'Edit'
912 kwargs['suptitle'] = 'Edit'
912 kwargs['button'] = 'Update'
913 kwargs['button'] = 'Update'
913
914
914 ###### SIDEBAR ######
915 ###### SIDEBAR ######
915 kwargs.update(sidebar(conf=conf))
916 kwargs.update(sidebar(conf=conf))
916
917
917 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
918 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
918
919
919
920
920 def dev_conf_start(request, id_conf):
921 def dev_conf_start(request, id_conf):
921
922
922 conf = get_object_or_404(Configuration, pk=id_conf)
923 conf = get_object_or_404(Configuration, pk=id_conf)
923
924
924 DevConfModel = CONF_MODELS[conf.device.device_type.name]
925 DevConfModel = CONF_MODELS[conf.device.device_type.name]
925
926
926 conf = DevConfModel.objects.get(pk=id_conf)
927 conf = DevConfModel.objects.get(pk=id_conf)
927
928
928 if conf.start_device():
929 if conf.start_device():
929 messages.success(request, conf.message)
930 messages.success(request, conf.message)
930 else:
931 else:
931 messages.error(request, conf.message)
932 messages.error(request, conf.message)
932
933
933 conf.status_device()
934 conf.status_device()
934
935
935 return redirect(conf.get_absolute_url())
936 return redirect(conf.get_absolute_url())
936
937
937
938
938 def dev_conf_stop(request, id_conf):
939 def dev_conf_stop(request, id_conf):
939
940
940 conf = get_object_or_404(Configuration, pk=id_conf)
941 conf = get_object_or_404(Configuration, pk=id_conf)
941
942
942 DevConfModel = CONF_MODELS[conf.device.device_type.name]
943 DevConfModel = CONF_MODELS[conf.device.device_type.name]
943
944
944 conf = DevConfModel.objects.get(pk=id_conf)
945 conf = DevConfModel.objects.get(pk=id_conf)
945
946
946 if conf.stop_device():
947 if conf.stop_device():
947 messages.success(request, conf.message)
948 messages.success(request, conf.message)
948 else:
949 else:
949 messages.error(request, conf.message)
950 messages.error(request, conf.message)
950
951
951 conf.status_device()
952 conf.status_device()
952
953
953 return redirect(conf.get_absolute_url())
954 return redirect(conf.get_absolute_url())
954
955
955
956
956 def dev_conf_status(request, id_conf):
957 def dev_conf_status(request, id_conf):
957
958
958 conf = get_object_or_404(Configuration, pk=id_conf)
959 conf = get_object_or_404(Configuration, pk=id_conf)
959
960
960 DevConfModel = CONF_MODELS[conf.device.device_type.name]
961 DevConfModel = CONF_MODELS[conf.device.device_type.name]
961
962
962 conf = DevConfModel.objects.get(pk=id_conf)
963 conf = DevConfModel.objects.get(pk=id_conf)
963
964
964 if conf.status_device():
965 if conf.status_device():
965 messages.success(request, conf.message)
966 messages.success(request, conf.message)
966 else:
967 else:
967 messages.error(request, conf.message)
968 messages.error(request, conf.message)
968
969
969 return redirect(conf.get_absolute_url())
970 return redirect(conf.get_absolute_url())
970
971
971
972
972 def dev_conf_write(request, id_conf):
973 def dev_conf_write(request, id_conf):
973
974
974 conf = get_object_or_404(Configuration, pk=id_conf)
975 conf = get_object_or_404(Configuration, pk=id_conf)
975
976
976 DevConfModel = CONF_MODELS[conf.device.device_type.name]
977 DevConfModel = CONF_MODELS[conf.device.device_type.name]
977
978
978 conf = DevConfModel.objects.get(pk=id_conf)
979 conf = DevConfModel.objects.get(pk=id_conf)
979
980
980 answer = conf.write_device()
981 answer = conf.write_device()
981 conf.status_device()
982 conf.status_device()
982
983
983 if answer:
984 if answer:
984 messages.success(request, conf.message)
985 messages.success(request, conf.message)
985
986
986 #Creating a historical configuration
987 #Creating a historical configuration
987 conf.clone(type=0, template=False)
988 conf.clone(type=0, template=False)
988
989
989 #Original configuration
990 #Original configuration
990 conf = DevConfModel.objects.get(pk=id_conf)
991 conf = DevConfModel.objects.get(pk=id_conf)
991 else:
992 else:
992 messages.error(request, conf.message)
993 messages.error(request, conf.message)
993
994
994 return redirect(conf.get_absolute_url())
995 return redirect(conf.get_absolute_url())
995
996
996
997
997 def dev_conf_read(request, id_conf):
998 def dev_conf_read(request, id_conf):
998
999
999 conf = get_object_or_404(Configuration, pk=id_conf)
1000 conf = get_object_or_404(Configuration, pk=id_conf)
1000
1001
1001 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1002 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1002 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1003 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1003
1004
1004 conf = DevConfModel.objects.get(pk=id_conf)
1005 conf = DevConfModel.objects.get(pk=id_conf)
1005
1006
1006 if request.method=='GET':
1007 if request.method=='GET':
1007
1008
1008 parms = conf.read_device()
1009 parms = conf.read_device()
1009 conf.status_device()
1010 conf.status_device()
1010
1011
1011 if not parms:
1012 if not parms:
1012 messages.error(request, conf.message)
1013 messages.error(request, conf.message)
1013 return redirect(conf.get_absolute_url())
1014 return redirect(conf.get_absolute_url())
1014
1015
1015 form = DevConfForm(initial=parms, instance=conf)
1016 form = DevConfForm(initial=parms, instance=conf)
1016
1017
1017 if request.method=='POST':
1018 if request.method=='POST':
1018 form = DevConfForm(request.POST, instance=conf)
1019 form = DevConfForm(request.POST, instance=conf)
1019
1020
1020 if form.is_valid():
1021 if form.is_valid():
1021 form.save()
1022 form.save()
1022 return redirect(conf.get_absolute_url())
1023 return redirect(conf.get_absolute_url())
1023
1024
1024 messages.error(request, "Parameters could not be saved")
1025 messages.error(request, "Parameters could not be saved")
1025
1026
1026 kwargs = {}
1027 kwargs = {}
1027 kwargs['id_dev'] = conf.id
1028 kwargs['id_dev'] = conf.id
1028 kwargs['form'] = form
1029 kwargs['form'] = form
1029 kwargs['title'] = 'Device Configuration'
1030 kwargs['title'] = 'Device Configuration'
1030 kwargs['suptitle'] = 'Parameters read from device'
1031 kwargs['suptitle'] = 'Parameters read from device'
1031 kwargs['button'] = 'Save'
1032 kwargs['button'] = 'Save'
1032
1033
1033 ###### SIDEBAR ######
1034 ###### SIDEBAR ######
1034 kwargs.update(sidebar(conf=conf))
1035 kwargs.update(sidebar(conf=conf))
1035
1036
1036 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
1037 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
1037
1038
1038
1039
1039 def dev_conf_import(request, id_conf):
1040 def dev_conf_import(request, id_conf):
1040
1041
1041 conf = get_object_or_404(Configuration, pk=id_conf)
1042 conf = get_object_or_404(Configuration, pk=id_conf)
1042
1043
1043 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1044 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1044 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1045 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1045 conf = DevConfModel.objects.get(pk=id_conf)
1046 conf = DevConfModel.objects.get(pk=id_conf)
1046
1047
1047 if request.method == 'GET':
1048 if request.method == 'GET':
1048 file_form = UploadFileForm()
1049 file_form = UploadFileForm()
1049
1050
1050 if request.method == 'POST':
1051 if request.method == 'POST':
1051 file_form = UploadFileForm(request.POST, request.FILES)
1052 file_form = UploadFileForm(request.POST, request.FILES)
1052
1053
1053 if file_form.is_valid():
1054 if file_form.is_valid():
1054
1055
1055 parms = conf.import_from_file(request.FILES['file'])
1056 parms = conf.import_from_file(request.FILES['file'])
1056
1057
1057 if parms:
1058 if parms:
1058 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
1059 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
1059 form = DevConfForm(initial=parms, instance=conf)
1060 form = DevConfForm(initial=parms, instance=conf)
1060
1061
1061 kwargs = {}
1062 kwargs = {}
1062 kwargs['id_dev'] = conf.id
1063 kwargs['id_dev'] = conf.id
1063 kwargs['form'] = form
1064 kwargs['form'] = form
1064 kwargs['title'] = 'Device Configuration'
1065 kwargs['title'] = 'Device Configuration'
1065 kwargs['suptitle'] = 'Parameters imported'
1066 kwargs['suptitle'] = 'Parameters imported'
1066 kwargs['button'] = 'Save'
1067 kwargs['button'] = 'Save'
1067 kwargs['action'] = conf.get_absolute_url_edit()
1068 kwargs['action'] = conf.get_absolute_url_edit()
1068 kwargs['previous'] = conf.get_absolute_url()
1069 kwargs['previous'] = conf.get_absolute_url()
1069
1070
1070 ###### SIDEBAR ######
1071 ###### SIDEBAR ######
1071 kwargs.update(sidebar(conf=conf))
1072 kwargs.update(sidebar(conf=conf))
1072
1073
1073 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1074 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1074
1075
1075 messages.error(request, "Could not import parameters from file")
1076 messages.error(request, "Could not import parameters from file")
1076
1077
1077 kwargs = {}
1078 kwargs = {}
1078 kwargs['id_dev'] = conf.id
1079 kwargs['id_dev'] = conf.id
1079 kwargs['title'] = 'Device Configuration'
1080 kwargs['title'] = 'Device Configuration'
1080 kwargs['form'] = file_form
1081 kwargs['form'] = file_form
1081 kwargs['suptitle'] = 'Importing file'
1082 kwargs['suptitle'] = 'Importing file'
1082 kwargs['button'] = 'Import'
1083 kwargs['button'] = 'Import'
1083
1084
1084 kwargs.update(sidebar(conf=conf))
1085 kwargs.update(sidebar(conf=conf))
1085
1086
1086 return render(request, 'dev_conf_import.html', kwargs)
1087 return render(request, 'dev_conf_import.html', kwargs)
1087
1088
1088
1089
1089 def dev_conf_export(request, id_conf):
1090 def dev_conf_export(request, id_conf):
1090
1091
1091 conf = get_object_or_404(Configuration, pk=id_conf)
1092 conf = get_object_or_404(Configuration, pk=id_conf)
1092
1093
1093 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1094 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1094
1095
1095 conf = DevConfModel.objects.get(pk=id_conf)
1096 conf = DevConfModel.objects.get(pk=id_conf)
1096
1097
1097 if request.method == 'GET':
1098 if request.method == 'GET':
1098 file_form = DownloadFileForm(conf.device.device_type.name)
1099 file_form = DownloadFileForm(conf.device.device_type.name)
1099
1100
1100 if request.method == 'POST':
1101 if request.method == 'POST':
1101 file_form = DownloadFileForm(conf.device.device_type.name, request.POST)
1102 file_form = DownloadFileForm(conf.device.device_type.name, request.POST)
1102
1103
1103 if file_form.is_valid():
1104 if file_form.is_valid():
1104 fields = conf.export_to_file(format = file_form.cleaned_data['format'])
1105 fields = conf.export_to_file(format = file_form.cleaned_data['format'])
1105
1106
1106 response = HttpResponse(content_type=fields['content_type'])
1107 response = HttpResponse(content_type=fields['content_type'])
1107 response['Content-Disposition'] = 'attachment; filename="%s"' %fields['filename']
1108 response['Content-Disposition'] = 'attachment; filename="%s"' %fields['filename']
1108 response.write(fields['content'])
1109 response.write(fields['content'])
1109
1110
1110 return response
1111 return response
1111
1112
1112 messages.error(request, "Could not export parameters")
1113 messages.error(request, "Could not export parameters")
1113
1114
1114 kwargs = {}
1115 kwargs = {}
1115 kwargs['id_dev'] = conf.id
1116 kwargs['id_dev'] = conf.id
1116 kwargs['title'] = 'Device Configuration'
1117 kwargs['title'] = 'Device Configuration'
1117 kwargs['form'] = file_form
1118 kwargs['form'] = file_form
1118 kwargs['suptitle'] = 'Exporting file'
1119 kwargs['suptitle'] = 'Exporting file'
1119 kwargs['button'] = 'Export'
1120 kwargs['button'] = 'Export'
1120
1121
1121 return render(request, 'dev_conf_export.html', kwargs)
1122 return render(request, 'dev_conf_export.html', kwargs)
1122
1123
1123
1124
1124 def dev_conf_delete(request, id_conf):
1125 def dev_conf_delete(request, id_conf):
1125
1126
1126 conf = get_object_or_404(Configuration, pk=id_conf)
1127 conf = get_object_or_404(Configuration, pk=id_conf)
1127
1128
1128 if request.method=='POST':
1129 if request.method=='POST':
1129 if request.user.is_staff:
1130 if request.user.is_staff:
1130 conf.delete()
1131 conf.delete()
1131 return redirect('url_dev_confs')
1132 return redirect('url_dev_confs')
1132
1133
1133 messages.error(request, 'Not enough permission to delete this object')
1134 messages.error(request, 'Not enough permission to delete this object')
1134 return redirect(conf.get_absolute_url())
1135 return redirect(conf.get_absolute_url())
1135
1136
1136 kwargs = {
1137 kwargs = {
1137 'title': 'Delete',
1138 'title': 'Delete',
1138 'suptitle': 'Experiment',
1139 'suptitle': 'Experiment',
1139 'object': conf,
1140 'object': conf,
1140 'previous': conf.get_absolute_url(),
1141 'previous': conf.get_absolute_url(),
1141 'delete': True
1142 'delete': True
1142 }
1143 }
1143
1144
1144 return render(request, 'confirm.html', kwargs)
1145 return render(request, 'confirm.html', kwargs)
1145
1146
1146
1147
1147 def sidebar(**kwargs):
1148 def sidebar(**kwargs):
1148
1149
1149 side_data = {}
1150 side_data = {}
1150
1151
1151 conf = kwargs.get('conf', None)
1152 conf = kwargs.get('conf', None)
1152 experiment = kwargs.get('experiment', None)
1153 experiment = kwargs.get('experiment', None)
1153
1154
1154 if not experiment:
1155 if not experiment:
1155 experiment = conf.experiment
1156 experiment = conf.experiment
1156
1157
1157 if experiment:
1158 if experiment:
1158 side_data['experiment'] = experiment
1159 side_data['experiment'] = experiment
1159 campaign = experiment.campaign_set.all()
1160 campaign = experiment.campaign_set.all()
1160 if campaign:
1161 if campaign:
1161 side_data['campaign'] = campaign[0]
1162 side_data['campaign'] = campaign[0]
1162 experiments = campaign[0].experiments.all()
1163 experiments = campaign[0].experiments.all()
1163 else:
1164 else:
1164 experiments = [experiment]
1165 experiments = [experiment]
1165 configurations = experiment.configuration_set.filter(type=0)
1166 configurations = experiment.configuration_set.filter(type=0)
1166 side_data['side_experiments'] = experiments
1167 side_data['side_experiments'] = experiments
1167 side_data['side_configurations'] = configurations
1168 side_data['side_configurations'] = configurations
1168
1169
1169 return side_data
1170 return side_data
1170
1171
1171
1172
1172 def operation(request, id_camp=None):
1173 def operation(request, id_camp=None):
1173
1174
1174 if not id_camp:
1175 if not id_camp:
1175 campaigns = Campaign.objects.all().order_by('-start_date')
1176 campaigns = Campaign.objects.all().order_by('-start_date')
1176
1177
1177 if not campaigns:
1178 if not campaigns:
1178 kwargs = {}
1179 kwargs = {}
1179 kwargs['title'] = 'No Campaigns'
1180 kwargs['title'] = 'No Campaigns'
1180 kwargs['suptitle'] = 'Empty'
1181 kwargs['suptitle'] = 'Empty'
1181 return render(request, 'operation.html', kwargs)
1182 return render(request, 'operation.html', kwargs)
1182
1183
1183 id_camp = campaigns[0].id
1184 id_camp = campaigns[0].id
1184
1185
1185 campaign = get_object_or_404(Campaign, pk = id_camp)
1186 campaign = get_object_or_404(Campaign, pk = id_camp)
1186
1187
1187 if request.method=='GET':
1188 if request.method=='GET':
1188 form = OperationForm(initial={'campaign': campaign.id}, length = 5)
1189 form = OperationForm(initial={'campaign': campaign.id}, length = 5)
1189
1190
1190 if request.method=='POST':
1191 if request.method=='POST':
1191 form = OperationForm(request.POST, initial={'campaign':campaign.id}, length = 5)
1192 form = OperationForm(request.POST, initial={'campaign':campaign.id}, length = 5)
1192
1193
1193 if form.is_valid():
1194 if form.is_valid():
1194 return redirect('url_operation', id_camp=campaign.id)
1195 return redirect('url_operation', id_camp=campaign.id)
1195 #locations = Location.objects.filter(experiment__campaign__pk = campaign.id).distinct()
1196 #locations = Location.objects.filter(experiment__campaign__pk = campaign.id).distinct()
1196 experiments = Experiment.objects.filter(campaign__pk=campaign.id)
1197 experiments = Experiment.objects.filter(campaign__pk=campaign.id)
1197 #for exs in experiments:
1198 #for exs in experiments:
1198 # exs.get_status()
1199 # exs.get_status()
1199 locations= Location.objects.filter(experiment=experiments).distinct()
1200 locations= Location.objects.filter(experiment=experiments).distinct()
1200 #experiments = [Experiment.objects.filter(location__pk=location.id).filter(campaign__pk=campaign.id) for location in locations]
1201 #experiments = [Experiment.objects.filter(location__pk=location.id).filter(campaign__pk=campaign.id) for location in locations]
1201 kwargs = {}
1202 kwargs = {}
1202 #---Campaign
1203 #---Campaign
1203 kwargs['campaign'] = campaign
1204 kwargs['campaign'] = campaign
1204 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
1205 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
1205 #---Experiment
1206 #---Experiment
1206 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1207 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1207 kwargs['experiment_keys'] = keys[1:]
1208 kwargs['experiment_keys'] = keys[1:]
1208 kwargs['experiments'] = experiments
1209 kwargs['experiments'] = experiments
1209 #---Radar
1210 #---Radar
1210 kwargs['locations'] = locations
1211 kwargs['locations'] = locations
1211 #---Else
1212 #---Else
1212 kwargs['title'] = 'Campaign'
1213 kwargs['title'] = 'Campaign'
1213 kwargs['suptitle'] = campaign.name
1214 kwargs['suptitle'] = campaign.name
1214 kwargs['form'] = form
1215 kwargs['form'] = form
1215 kwargs['button'] = 'Search'
1216 kwargs['button'] = 'Search'
1216 kwargs['details'] = True
1217 kwargs['details'] = True
1217 kwargs['search_button'] = True
1218 kwargs['search_button'] = True
1218
1219
1219 return render(request, 'operation.html', kwargs)
1220 return render(request, 'operation.html', kwargs)
1220
1221
1221
1222
1222 def operation_search(request, id_camp=None):
1223 def operation_search(request, id_camp=None):
1223
1224
1224
1225
1225 if not id_camp:
1226 if not id_camp:
1226 campaigns = Campaign.objects.all().order_by('-start_date')
1227 campaigns = Campaign.objects.all().order_by('-start_date')
1227
1228
1228 if not campaigns:
1229 if not campaigns:
1229 return render(request, 'operation.html', {})
1230 return render(request, 'operation.html', {})
1230
1231
1231 id_camp = campaigns[0].id
1232 id_camp = campaigns[0].id
1232 campaign = get_object_or_404(Campaign, pk = id_camp)
1233 campaign = get_object_or_404(Campaign, pk = id_camp)
1233
1234
1234 if request.method=='GET':
1235 if request.method=='GET':
1235 form = OperationSearchForm(initial={'campaign': campaign.id})
1236 form = OperationSearchForm(initial={'campaign': campaign.id})
1236
1237
1237 if request.method=='POST':
1238 if request.method=='POST':
1238 form = OperationSearchForm(request.POST, initial={'campaign':campaign.id})
1239 form = OperationSearchForm(request.POST, initial={'campaign':campaign.id})
1239
1240
1240 if form.is_valid():
1241 if form.is_valid():
1241 return redirect('url_operation', id_camp=campaign.id)
1242 return redirect('url_operation', id_camp=campaign.id)
1242
1243
1243 #locations = Location.objects.filter(experiment__campaign__pk = campaign.id).distinct()
1244 #locations = Location.objects.filter(experiment__campaign__pk = campaign.id).distinct()
1244 experiments = Experiment.objects.filter(campaign__pk=campaign.id)
1245 experiments = Experiment.objects.filter(campaign__pk=campaign.id)
1245 #for exs in experiments:
1246 #for exs in experiments:
1246 # exs.get_status()
1247 # exs.get_status()
1247 locations= Location.objects.filter(experiment=experiments).distinct()
1248 locations= Location.objects.filter(experiment=experiments).distinct()
1248 form = OperationSearchForm(initial={'campaign': campaign.id})
1249 form = OperationSearchForm(initial={'campaign': campaign.id})
1249
1250
1250 kwargs = {}
1251 kwargs = {}
1251 #---Campaign
1252 #---Campaign
1252 kwargs['campaign'] = campaign
1253 kwargs['campaign'] = campaign
1253 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
1254 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
1254 #---Experiment
1255 #---Experiment
1255 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1256 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1256 kwargs['experiment_keys'] = keys[1:]
1257 kwargs['experiment_keys'] = keys[1:]
1257 kwargs['experiments'] = experiments
1258 kwargs['experiments'] = experiments
1258 #---Radar
1259 #---Radar
1259 kwargs['locations'] = locations
1260 kwargs['locations'] = locations
1260 #---Else
1261 #---Else
1261 kwargs['title'] = 'Campaign'
1262 kwargs['title'] = 'Campaign'
1262 kwargs['suptitle'] = campaign.name
1263 kwargs['suptitle'] = campaign.name
1263 kwargs['form'] = form
1264 kwargs['form'] = form
1264 kwargs['button'] = 'Select'
1265 kwargs['button'] = 'Select'
1265 kwargs['details'] = True
1266 kwargs['details'] = True
1266 kwargs['search_button'] = False
1267 kwargs['search_button'] = False
1267
1268
1268 return render(request, 'operation.html', kwargs)
1269 return render(request, 'operation.html', kwargs)
1269
1270
1270
1271
1271 def radar_play(request, id_camp, id_radar):
1272 def radar_play(request, id_camp, id_radar):
1272 campaign = get_object_or_404(Campaign, pk = id_camp)
1273 campaign = get_object_or_404(Campaign, pk = id_camp)
1273 radar = get_object_or_404(Location, pk = id_radar)
1274 radar = get_object_or_404(Location, pk = id_radar)
1274 today = datetime.today()
1275 today = datetime.today()
1275 now = today.time()
1276 now = today.time()
1276
1277
1277 #--Clear Old Experiments From RunningExperiment Object
1278 #--Clear Old Experiments From RunningExperiment Object
1278 running_experiment = RunningExperiment.objects.filter(radar=radar)
1279 running_experiment = RunningExperiment.objects.filter(radar=radar)
1279 if running_experiment:
1280 if running_experiment:
1280 running_experiment = running_experiment[0]
1281 running_experiment = running_experiment[0]
1281 running_experiment.running_experiment.clear()
1282 running_experiment.running_experiment.clear()
1282 running_experiment.save()
1283 running_experiment.save()
1283
1284
1284 #--If campaign datetime is ok:
1285 #--If campaign datetime is ok:
1285 if today >= campaign.start_date and today <= campaign.end_date:
1286 if today >= campaign.start_date and today <= campaign.end_date:
1286 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1287 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1287 for exp in experiments:
1288 for exp in experiments:
1288 #--If experiment time is ok:
1289 #--If experiment time is ok:
1289 if now >= exp.start_time and now <= exp.end_time:
1290 if now >= exp.start_time and now <= exp.end_time:
1290 configurations = Configuration.objects.filter(experiment = exp)
1291 configurations = Configuration.objects.filter(experiment = exp)
1291 for conf in configurations:
1292 for conf in configurations:
1292 if 'cgs' in conf.device.device_type.name:
1293 if 'cgs' in conf.device.device_type.name:
1293 conf.status_device()
1294 conf.status_device()
1294 else:
1295 else:
1295 answer = conf.start_device()
1296 answer = conf.start_device()
1296 conf.status_device()
1297 conf.status_device()
1297 #--Running Experiment
1298 #--Running Experiment
1298 old_running_experiment = RunningExperiment.objects.filter(radar=radar)
1299 old_running_experiment = RunningExperiment.objects.filter(radar=radar)
1299 #--If RunningExperiment element exists
1300 #--If RunningExperiment element exists
1300 if old_running_experiment:
1301 if old_running_experiment:
1301 old_running_experiment = old_running_experiment[0]
1302 old_running_experiment = old_running_experiment[0]
1302 old_running_experiment.running_experiment.add(exp)
1303 old_running_experiment.running_experiment.add(exp)
1303 old_running_experiment.status = 3
1304 old_running_experiment.status = 3
1304 old_running_experiment.save()
1305 old_running_experiment.save()
1305 #--Create a new Running_Experiment Object
1306 #--Create a new Running_Experiment Object
1306 else:
1307 else:
1307 new_running_experiment = RunningExperiment(
1308 new_running_experiment = RunningExperiment(
1308 radar = radar,
1309 radar = radar,
1309 status = 3,
1310 status = 3,
1310 )
1311 )
1311 new_running_experiment.save()
1312 new_running_experiment.save()
1312 new_running_experiment.running_experiment.add(exp)
1313 new_running_experiment.running_experiment.add(exp)
1313 new_running_experiment.save()
1314 new_running_experiment.save()
1314
1315
1315 if answer:
1316 if answer:
1316 messages.success(request, conf.message)
1317 messages.success(request, conf.message)
1317 exp.status=2
1318 exp.status=2
1318 exp.save()
1319 exp.save()
1319 else:
1320 else:
1320 messages.error(request, conf.message)
1321 messages.error(request, conf.message)
1321 else:
1322 else:
1322 if exp.status == 1 or exp.status == 3:
1323 if exp.status == 1 or exp.status == 3:
1323 exp.status=3
1324 exp.status=3
1324 exp.save()
1325 exp.save()
1325
1326
1326
1327
1327 route = request.META['HTTP_REFERER']
1328 route = request.META['HTTP_REFERER']
1328 route = str(route)
1329 route = str(route)
1329 if 'search' in route:
1330 if 'search' in route:
1330 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1331 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1331 else:
1332 else:
1332 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1333 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1333
1334
1334
1335
1335 def radar_stop(request, id_camp, id_radar):
1336 def radar_stop(request, id_camp, id_radar):
1336 campaign = get_object_or_404(Campaign, pk = id_camp)
1337 campaign = get_object_or_404(Campaign, pk = id_camp)
1337 radar = get_object_or_404(Location, pk = id_radar)
1338 radar = get_object_or_404(Location, pk = id_radar)
1338 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1339 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1339
1340
1340 for exp in experiments:
1341 for exp in experiments:
1341 configurations = Configuration.objects.filter(experiment = exp)
1342 configurations = Configuration.objects.filter(experiment = exp)
1342 for conf in configurations:
1343 for conf in configurations:
1343 if 'cgs' in conf.device.device_type.name:
1344 if 'cgs' in conf.device.device_type.name:
1344 conf.status_device()
1345 conf.status_device()
1345 else:
1346 else:
1346 answer = conf.stop_device()
1347 answer = conf.stop_device()
1347 conf.status_device()
1348 conf.status_device()
1348
1349
1349 if answer:
1350 if answer:
1350 messages.success(request, conf.message)
1351 messages.success(request, conf.message)
1351 exp.status=1
1352 exp.status=1
1352 exp.save()
1353 exp.save()
1353 else:
1354 else:
1354 messages.error(request, conf.message)
1355 messages.error(request, conf.message)
1355
1356
1356
1357
1357 route = request.META['HTTP_REFERER']
1358 route = request.META['HTTP_REFERER']
1358 route = str(route)
1359 route = str(route)
1359 if 'search' in route:
1360 if 'search' in route:
1360 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1361 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1361 else:
1362 else:
1362 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1363 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1363
1364
1364
1365
1365 def radar_refresh(request, id_camp, id_radar):
1366 def radar_refresh(request, id_camp, id_radar):
1366
1367
1367 campaign = get_object_or_404(Campaign, pk = id_camp)
1368 campaign = get_object_or_404(Campaign, pk = id_camp)
1368 radar = get_object_or_404(Location, pk = id_radar)
1369 radar = get_object_or_404(Location, pk = id_radar)
1369 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1370 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1370 for exs in experiments:
1371 for exs in experiments:
1371 exs.get_status()
1372 exs.get_status()
1372
1373
1373 route = request.META['HTTP_REFERER']
1374 route = request.META['HTTP_REFERER']
1374 route = str(route)
1375 route = str(route)
1375 if 'search' in route:
1376 if 'search' in route:
1376 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1377 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1377 else:
1378 else:
1378 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1379 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1379
1380
@@ -1,372 +1,378
1 import os
1 import os
2 import ast
2 import ast
3 import json
3 import json
4
4
5 from django import forms
5 from django import forms
6 from django.utils.safestring import mark_safe
6 from django.utils.safestring import mark_safe
7 from apps.main.models import Device
7 from apps.main.models import Device
8 from apps.main.forms import add_empty_choice
8 from apps.main.forms import add_empty_choice
9 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
9 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
10 from .widgets import KmUnitWidget, KmUnitHzWidget, KmUnitDcWidget, UnitKmWidget, DefaultWidget, CodesWidget, HiddenWidget, HCheckboxSelectMultiple
10 from .widgets import KmUnitWidget, KmUnitHzWidget, KmUnitDcWidget, UnitKmWidget, DefaultWidget, CodesWidget, HiddenWidget, HCheckboxSelectMultiple
11
11
12 def create_choices_from_model(model, conf_id, all=False):
12 def create_choices_from_model(model, conf_id, all=False):
13
13
14 if model=='RCLine':
14 if model=='RCLine':
15 instance = RCConfiguration.objects.get(pk=conf_id)
15 instance = RCConfiguration.objects.get(pk=conf_id)
16 choices = [(line.pk, line.get_name()) for line in instance.get_lines(line_type__name='tx')]
16 choices = [(line.pk, line.get_name()) for line in instance.get_lines(line_type__name='tx')]
17 choices = add_empty_choice(choices, label='All')
17 choices = add_empty_choice(choices, label='All')
18 else:
18 else:
19 instance = globals()[model]
19 instance = globals()[model]
20 choices = instance.objects.all().values_list('pk', 'name')
20 choices = instance.objects.all().values_list('pk', 'name')
21
21
22 return choices
22 return choices
23
23
24
24
25 class ExtFileField(forms.FileField):
25 class ExtFileField(forms.FileField):
26 """
26 """
27 Same as forms.FileField, but you can specify a file extension whitelist.
27 Same as forms.FileField, but you can specify a file extension whitelist.
28
28
29 >>> from django.core.files.uploadedfile import SimpleUploadedFile
29 >>> from django.core.files.uploadedfile import SimpleUploadedFile
30 >>>
30 >>>
31 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
31 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
32 >>>
32 >>>
33 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
33 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
34 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
34 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
35 >>>
35 >>>
36 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
36 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
37 Traceback (most recent call last):
37 Traceback (most recent call last):
38 ...
38 ...
39 ValidationError: [u'Not allowed filetype!']
39 ValidationError: [u'Not allowed filetype!']
40 """
40 """
41 def __init__(self, *args, **kwargs):
41 def __init__(self, *args, **kwargs):
42 extensions = kwargs.pop("extensions")
42 extensions = kwargs.pop("extensions")
43 self.extensions = [i.lower() for i in extensions]
43 self.extensions = [i.lower() for i in extensions]
44
44
45 super(ExtFileField, self).__init__(*args, **kwargs)
45 super(ExtFileField, self).__init__(*args, **kwargs)
46
46
47 def clean(self, *args, **kwargs):
47 def clean(self, *args, **kwargs):
48 data = super(ExtFileField, self).clean(*args, **kwargs)
48 data = super(ExtFileField, self).clean(*args, **kwargs)
49 filename = data.name
49 filename = data.name
50 ext = os.path.splitext(filename)[1]
50 ext = os.path.splitext(filename)[1]
51 ext = ext.lower()
51 ext = ext.lower()
52 if ext not in self.extensions:
52 if ext not in self.extensions:
53 raise forms.ValidationError('Not allowed file type: %s' % ext)
53 raise forms.ValidationError('Not allowed file type: %s' % ext)
54
54
55
55
56 class RCConfigurationForm(forms.ModelForm):
56 class RCConfigurationForm(forms.ModelForm):
57
57
58 def __init__(self, *args, **kwargs):
58 def __init__(self, *args, **kwargs):
59 super(RCConfigurationForm, self).__init__(*args, **kwargs)
59 super(RCConfigurationForm, self).__init__(*args, **kwargs)
60
60
61 instance = getattr(self, 'instance', None)
61 instance = getattr(self, 'instance', None)
62
62
63 if instance and instance.pk:
63 if instance and instance.pk:
64
64
65 devices = Device.objects.filter(device_type__name='rc')
65 devices = Device.objects.filter(device_type__name='rc')
66 if instance.experiment:
66 if instance.experiment:
67 self.fields['experiment'].widget.attrs['read_only'] = True
67 self.fields['experiment'].widget.attrs['read_only'] = True
68 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
68 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
69 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
69 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
70 self.fields['ipp'].widget = KmUnitHzWidget(attrs={'km2unit':instance.km2unit})
70 self.fields['ipp'].widget = KmUnitHzWidget(attrs={'km2unit':instance.km2unit})
71 self.fields['clock'].widget.attrs['readonly'] = True
71 self.fields['clock'].widget.attrs['readonly'] = True
72
72
73 self.fields['time_before'].label = mark_safe(self.fields['time_before'].label)
73 self.fields['time_before'].label = mark_safe(self.fields['time_before'].label)
74 self.fields['time_after'].label = mark_safe(self.fields['time_after'].label)
74 self.fields['time_after'].label = mark_safe(self.fields['time_after'].label)
75
75
76 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
76 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
77 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
77 self.fields['experiment'].widget.attrs['readonly'] = True
78
78
79 class Meta:
79 class Meta:
80 model = RCConfiguration
80 model = RCConfiguration
81 exclude = ('type', 'parameters', 'status', 'total_units', 'mix')
81 exclude = ('type', 'parameters', 'status', 'total_units', 'mix')
82
82
83 def clean(self):
83 def clean(self):
84 form_data = super(RCConfigurationForm, self).clean()
84 form_data = super(RCConfigurationForm, self).clean()
85
85
86 if 'clock_divider' in form_data:
86 if 'clock_divider' in form_data:
87 if form_data['clock_divider']<1:
87 if form_data['clock_divider']<1:
88 self.add_error('clock_divider', 'Invalid Value')
88 self.add_error('clock_divider', 'Invalid Value')
89 else:
89 else:
90 if form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))%10<>0:
90 if form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))%10<>0:
91 self.add_error('ipp', 'Invalid IPP units={}'.format(form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))))
91 self.add_error('ipp', 'Invalid IPP units={}'.format(form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))))
92
92
93 return form_data
93 return form_data
94
94
95 def save(self):
96 conf = super(RCConfigurationForm, self).save()
97 conf.total_units = conf.ipp*conf.ntx*conf.km2unit
98 conf.save()
99 return conf
100
95
101
96 class RCMixConfigurationForm(forms.Form):
102 class RCMixConfigurationForm(forms.Form):
97
103
98 clock_in = forms.CharField(widget=forms.HiddenInput())
104 clock_in = forms.CharField(widget=forms.HiddenInput())
99 clock_divider = forms.CharField(widget=forms.HiddenInput())
105 clock_divider = forms.CharField(widget=forms.HiddenInput())
100 name = forms.CharField()
106 name = forms.CharField()
101 experiment = forms.ChoiceField()
107 experiment = forms.ChoiceField()
102 mode = forms.ChoiceField(widget=forms.RadioSelect(),
108 mode = forms.ChoiceField(widget=forms.RadioSelect(),
103 choices=[(0, 'Parallel'), (1, 'Sequence')],
109 choices=[(0, 'Parallel'), (1, 'Sequence')],
104 initial=0)
110 initial=0)
105 operation = forms.ChoiceField(widget=forms.RadioSelect(),
111 operation = forms.ChoiceField(widget=forms.RadioSelect(),
106 choices=[(0, 'OR'), (1, 'XOR'), (2, 'AND'), (3, 'NAND')],
112 choices=[(0, 'OR'), (1, 'XOR'), (2, 'AND'), (3, 'NAND')],
107 initial=1)
113 initial=1)
108 delay = forms.CharField()
114 delay = forms.CharField()
109 mask = forms.MultipleChoiceField(choices=[(0, 'L1'),(1, 'L2'),(2, 'L3'),(3, 'L4'),(4, 'L5'),(5, 'L6'),(6, 'L7'),(7, 'L8')],
115 mask = forms.MultipleChoiceField(choices=[(0, 'L1'),(1, 'L2'),(2, 'L3'),(3, 'L4'),(4, 'L5'),(5, 'L6'),(6, 'L7'),(7, 'L8')],
110 widget=HCheckboxSelectMultiple())
116 widget=HCheckboxSelectMultiple())
111 result = forms.CharField(required=False,
117 result = forms.CharField(required=False,
112 widget=forms.Textarea(attrs={'readonly':True, 'rows':5, 'class':'tabuled'}))
118 widget=forms.Textarea(attrs={'readonly':True, 'rows':5, 'class':'tabuled'}))
113
119
114 def __init__(self, *args, **kwargs):
120 def __init__(self, *args, **kwargs):
115 confs = kwargs.pop('confs', [])
121 confs = kwargs.pop('confs', [])
116 if confs:
122 if confs:
117 km2unit = confs[0].km2unit
123 km2unit = confs[0].km2unit
118 clock_in = confs[0].clock_in
124 clock_in = confs[0].clock_in
119 clock_divider = confs[0].clock_divider
125 clock_divider = confs[0].clock_divider
120 else:
126 else:
121 km2unit = clock_in = clock_divider = 0
127 km2unit = clock_in = clock_divider = 0
122 super(RCMixConfigurationForm, self).__init__(*args, **kwargs)
128 super(RCMixConfigurationForm, self).__init__(*args, **kwargs)
123 self.fields['experiment'].choices = [(conf.pk, '{} | {}'.format(conf.pk, conf.name)) for conf in confs]
129 self.fields['experiment'].choices = [(conf.pk, '{} | {}'.format(conf.pk, conf.name)) for conf in confs]
124 self.fields['delay'].widget = KmUnitWidget(attrs = {'km2unit':km2unit})
130 self.fields['delay'].widget = KmUnitWidget(attrs = {'km2unit':km2unit})
125 self.fields['clock_in'].initial = clock_in
131 self.fields['clock_in'].initial = clock_in
126 self.fields['clock_divider'].initial = clock_divider
132 self.fields['clock_divider'].initial = clock_divider
127
133
128
134
129 class RCLineForm(forms.ModelForm):
135 class RCLineForm(forms.ModelForm):
130
136
131 def __init__(self, *args, **kwargs):
137 def __init__(self, *args, **kwargs):
132 self.extra_fields = kwargs.pop('extra_fields', [])
138 self.extra_fields = kwargs.pop('extra_fields', [])
133 super(RCLineForm, self).__init__(*args, **kwargs)
139 super(RCLineForm, self).__init__(*args, **kwargs)
134
140
135 if 'initial' in kwargs and 'line_type' in kwargs['initial']:
141 if 'initial' in kwargs and 'line_type' in kwargs['initial']:
136 line_type = RCLineType.objects.get(pk=kwargs['initial']['line_type'])
142 line_type = RCLineType.objects.get(pk=kwargs['initial']['line_type'])
137
143
138 if 'code_id' in kwargs['initial']:
144 if 'code_id' in kwargs['initial']:
139 model_initial = kwargs['initial']['code_id']
145 model_initial = kwargs['initial']['code_id']
140 else:
146 else:
141 model_initial = 0
147 model_initial = 0
142
148
143 params = json.loads(line_type.params)
149 params = json.loads(line_type.params)
144
150
145 for label, value in self.extra_fields.items():
151 for label, value in self.extra_fields.items():
146 if label=='params':
152 if label=='params':
147 continue
153 continue
148
154
149 if 'model' in params[label]:
155 if 'model' in params[label]:
150 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
156 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
151 kwargs['initial']['rc_configuration']),
157 kwargs['initial']['rc_configuration']),
152 initial=model_initial)
158 initial=model_initial)
153
159
154
160
155 else:
161 else:
156 if label=='codes' and 'code_id' in kwargs['initial']:
162 if label=='codes' and 'code_id' in kwargs['initial']:
157 self.fields[label] = forms.CharField(initial=RCLineCode.objects.get(pk=kwargs['initial']['code_id']).codes)
163 self.fields[label] = forms.CharField(initial=RCLineCode.objects.get(pk=kwargs['initial']['code_id']).codes)
158 else:
164 else:
159 self.fields[label] = forms.CharField(initial=value['value'])
165 self.fields[label] = forms.CharField(initial=value['value'])
160
166
161 if label=='codes':
167 if label=='codes':
162 self.fields[label].widget = CodesWidget()
168 self.fields[label].widget = CodesWidget()
163
169
164 if self.data:
170 if self.data:
165 line_type = RCLineType.objects.get(pk=self.data['line_type'])
171 line_type = RCLineType.objects.get(pk=self.data['line_type'])
166
172
167 if 'code_id' in self.data:
173 if 'code_id' in self.data:
168 model_initial = self.data['code_id']
174 model_initial = self.data['code_id']
169 else:
175 else:
170 model_initial = 0
176 model_initial = 0
171
177
172 params = json.loads(line_type.params)
178 params = json.loads(line_type.params)
173
179
174 for label, value in self.extra_fields.items():
180 for label, value in self.extra_fields.items():
175 if label=='params':
181 if label=='params':
176 continue
182 continue
177
183
178 if 'model' in params[label]:
184 if 'model' in params[label]:
179 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
185 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
180 self.data['rc_configuration']),
186 self.data['rc_configuration']),
181 initial=model_initial)
187 initial=model_initial)
182
188
183
189
184 else:
190 else:
185 if label=='codes' and 'code' in self.data:
191 if label=='codes' and 'code' in self.data:
186 self.fields[label] = forms.CharField(initial=self.data['codes'])
192 self.fields[label] = forms.CharField(initial=self.data['codes'])
187 else:
193 else:
188 self.fields[label] = forms.CharField(initial=self.data[label])
194 self.fields[label] = forms.CharField(initial=self.data[label])
189
195
190 if label=='codes':
196 if label=='codes':
191 self.fields[label].widget = CodesWidget()
197 self.fields[label].widget = CodesWidget()
192
198
193
199
194 class Meta:
200 class Meta:
195 model = RCLine
201 model = RCLine
196 fields = ('rc_configuration', 'line_type', 'channel')
202 fields = ('rc_configuration', 'line_type', 'channel')
197 widgets = {
203 widgets = {
198 'channel': forms.HiddenInput(),
204 'channel': forms.HiddenInput(),
199 }
205 }
200
206
201
207
202 def clean(self):
208 def clean(self):
203
209
204 form_data = self.cleaned_data
210 form_data = self.cleaned_data
205 if 'code' in self.data and self.data['TX_ref']=="0":
211 if 'code' in self.data and self.data['TX_ref']=="0":
206 self.add_error('TX_ref', 'Choose a valid TX reference')
212 self.add_error('TX_ref', 'Choose a valid TX reference')
207
213
208 return form_data
214 return form_data
209
215
210
216
211 def save(self):
217 def save(self):
212 line = super(RCLineForm, self).save()
218 line = super(RCLineForm, self).save()
213
219
214 #auto add channel
220 #auto add channel
215 line.channel = RCLine.objects.filter(rc_configuration=line.rc_configuration).count()-1
221 line.channel = RCLine.objects.filter(rc_configuration=line.rc_configuration).count()-1
216
222
217 #auto add position for TX, TR & CODE
223 #auto add position for TX, TR & CODE
218 if line.line_type.name in ('tx', ):
224 if line.line_type.name in ('tx', ):
219 line.position = RCLine.objects.filter(rc_configuration=line.rc_configuration, line_type=line.line_type).count()-1
225 line.position = RCLine.objects.filter(rc_configuration=line.rc_configuration, line_type=line.line_type).count()-1
220
226
221 #save extra fields in params
227 #save extra fields in params
222 params = {}
228 params = {}
223 for label, value in self.extra_fields.items():
229 for label, value in self.extra_fields.items():
224 if label=='params':
230 if label=='params':
225 params['params'] = []
231 params['params'] = []
226 elif label=='codes':
232 elif label=='codes':
227 params[label] = [s for s in self.data[label].split('\r\n') if s]
233 params[label] = [s for s in self.data[label].split('\r\n') if s]
228 else:
234 else:
229 params[label] = self.data[label]
235 params[label] = self.data[label]
230 line.params = json.dumps(params)
236 line.params = json.dumps(params)
231 line.save()
237 line.save()
232 return
238 return
233
239
234
240
235 class RCLineViewForm(forms.Form):
241 class RCLineViewForm(forms.Form):
236
242
237 def __init__(self, *args, **kwargs):
243 def __init__(self, *args, **kwargs):
238
244
239 extra_fields = kwargs.pop('extra_fields')
245 extra_fields = kwargs.pop('extra_fields')
240 line = kwargs.pop('line')
246 line = kwargs.pop('line')
241 subform = kwargs.pop('subform', False)
247 subform = kwargs.pop('subform', False)
242 super(RCLineViewForm, self).__init__(*args, **kwargs)
248 super(RCLineViewForm, self).__init__(*args, **kwargs)
243
249
244 if subform:
250 if subform:
245 params = json.loads(line.line_type.params)['params']
251 params = json.loads(line.line_type.params)['params']
246 else:
252 else:
247 params = json.loads(line.line_type.params)
253 params = json.loads(line.line_type.params)
248
254
249 for label, value in extra_fields.items():
255 for label, value in extra_fields.items():
250
256
251 if label=='params':
257 if label=='params':
252 continue
258 continue
253 if 'ref' in label:
259 if 'ref' in label:
254 if value in (0, '0'):
260 if value in (0, '0'):
255 value = 'All'
261 value = 'All'
256 else:
262 else:
257 value = RCLine.objects.get(pk=value).get_name()
263 value = RCLine.objects.get(pk=value).get_name()
258 elif label=='code':
264 elif label=='code':
259 value = RCLineCode.objects.get(pk=value).name
265 value = RCLineCode.objects.get(pk=value).name
260
266
261 self.fields[label] = forms.CharField(initial=value)
267 self.fields[label] = forms.CharField(initial=value)
262
268
263 if 'widget' in params[label]:
269 if 'widget' in params[label]:
264 km2unit = line.rc_configuration.km2unit
270 km2unit = line.rc_configuration.km2unit
265 if params[label]['widget']=='km':
271 if params[label]['widget']=='km':
266 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
272 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
267 elif params[label]['widget']=='unit':
273 elif params[label]['widget']=='unit':
268 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
274 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
269 elif params[label]['widget']=='dc':
275 elif params[label]['widget']=='dc':
270 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
276 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
271 elif params[label]['widget']=='codes':
277 elif params[label]['widget']=='codes':
272 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
278 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
273 else:
279 else:
274 self.fields[label].widget = DefaultWidget(attrs={'disabled':True})
280 self.fields[label].widget = DefaultWidget(attrs={'disabled':True})
275
281
276
282
277 class RCLineEditForm(forms.ModelForm):
283 class RCLineEditForm(forms.ModelForm):
278
284
279 def __init__(self, *args, **kwargs):
285 def __init__(self, *args, **kwargs):
280
286
281 extra_fields = kwargs.pop('extra_fields', [])
287 extra_fields = kwargs.pop('extra_fields', [])
282 conf = kwargs.pop('conf', False)
288 conf = kwargs.pop('conf', False)
283 line = kwargs.pop('line')
289 line = kwargs.pop('line')
284 subform = kwargs.pop('subform', False)
290 subform = kwargs.pop('subform', False)
285
291
286 super(RCLineEditForm, self).__init__(*args, **kwargs)
292 super(RCLineEditForm, self).__init__(*args, **kwargs)
287
293
288 if subform is not False:
294 if subform is not False:
289 params = json.loads(line.line_type.params)['params']
295 params = json.loads(line.line_type.params)['params']
290 count = subform
296 count = subform
291 else:
297 else:
292 params = json.loads(line.line_type.params)
298 params = json.loads(line.line_type.params)
293 count = -1
299 count = -1
294
300
295 for label, value in extra_fields.items():
301 for label, value in extra_fields.items():
296
302
297 if label in ('params',):
303 if label in ('params',):
298 continue
304 continue
299 if 'help' in params[label]:
305 if 'help' in params[label]:
300 help_text = params[label]['help']
306 help_text = params[label]['help']
301 else:
307 else:
302 help_text = ''
308 help_text = ''
303
309
304 if 'model' in params[label]:
310 if 'model' in params[label]:
305 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'], conf.id),
311 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'], conf.id),
306 initial=value,
312 initial=value,
307 widget=forms.Select(attrs={'name':'%s|%s|%s' % (count, line.id, label)}),
313 widget=forms.Select(attrs={'name':'%s|%s|%s' % (count, line.id, label)}),
308 help_text=help_text)
314 help_text=help_text)
309
315
310 else:
316 else:
311
317
312 self.fields[label] = forms.CharField(initial=value, help_text=help_text)
318 self.fields[label] = forms.CharField(initial=value, help_text=help_text)
313
319
314 if label in ('code', ):
320 if label in ('code', ):
315 self.fields[label].widget = HiddenWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
321 self.fields[label].widget = HiddenWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
316
322
317 elif 'widget' in params[label]:
323 elif 'widget' in params[label]:
318 km2unit = line.rc_configuration.km2unit
324 km2unit = line.rc_configuration.km2unit
319 if params[label]['widget']=='km':
325 if params[label]['widget']=='km':
320 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
326 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
321 elif params[label]['widget']=='unit':
327 elif params[label]['widget']=='unit':
322 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
328 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
323 elif params[label]['widget']=='dc':
329 elif params[label]['widget']=='dc':
324 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
330 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
325 elif params[label]['widget']=='codes':
331 elif params[label]['widget']=='codes':
326 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
332 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
327 else:
333 else:
328 self.fields[label].widget = DefaultWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
334 self.fields[label].widget = DefaultWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
329
335
330
336
331 class Meta:
337 class Meta:
332 model = RCLine
338 model = RCLine
333 exclude = ('rc_configuration', 'line_type', 'channel', 'position', 'params', 'pulses')
339 exclude = ('rc_configuration', 'line_type', 'channel', 'position', 'params', 'pulses')
334
340
335
341
336 class RCSubLineEditForm(forms.Form):
342 class RCSubLineEditForm(forms.Form):
337
343
338 def __init__(self, *args, **kwargs):
344 def __init__(self, *args, **kwargs):
339 extra_fields = kwargs.pop('extra_fields')
345 extra_fields = kwargs.pop('extra_fields')
340 count = kwargs.pop('count')
346 count = kwargs.pop('count')
341 line = kwargs.pop('line')
347 line = kwargs.pop('line')
342 super(RCSubLineEditForm, self).__init__(*args, **kwargs)
348 super(RCSubLineEditForm, self).__init__(*args, **kwargs)
343 for label, value in extra_fields.items():
349 for label, value in extra_fields.items():
344 self.fields[label] = forms.CharField(initial=value,
350 self.fields[label] = forms.CharField(initial=value,
345 widget=forms.TextInput(attrs={'name':'%s|%s|%s' % (count, line, label)}))
351 widget=forms.TextInput(attrs={'name':'%s|%s|%s' % (count, line, label)}))
346
352
347
353
348 class RCImportForm(forms.Form):
354 class RCImportForm(forms.Form):
349
355
350 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
356 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
351
357
352
358
353 class RCLineCodesForm(forms.ModelForm):
359 class RCLineCodesForm(forms.ModelForm):
354
360
355 def __init__(self, *args, **kwargs):
361 def __init__(self, *args, **kwargs):
356 super(RCLineCodesForm, self).__init__(*args, **kwargs)
362 super(RCLineCodesForm, self).__init__(*args, **kwargs)
357
363
358 if 'initial' in kwargs:
364 if 'initial' in kwargs:
359 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
365 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
360 initial=kwargs['initial']['code'])
366 initial=kwargs['initial']['code'])
361 if 'instance' in kwargs:
367 if 'instance' in kwargs:
362 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
368 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
363 initial=kwargs['instance'].pk)
369 initial=kwargs['instance'].pk)
364
370
365 self.fields['codes'].widget = CodesWidget()
371 self.fields['codes'].widget = CodesWidget()
366
372
367
373
368 class Meta:
374 class Meta:
369 model = RCLineCode
375 model = RCLineCode
370 exclude = ('name',)
376 exclude = ('name',)
371
377
372 No newline at end of file
378
@@ -1,762 +1,773
1
1
2 import ast
2 import ast
3 import json
3 import json
4 import numpy as np
4 import numpy as np
5
5
6 from polymorphic import PolymorphicModel
6 from polymorphic import PolymorphicModel
7
7
8 from django.db import models
8 from django.db import models
9 from django.core.urlresolvers import reverse
9 from django.core.urlresolvers import reverse
10 from django.core.validators import MinValueValidator, MaxValueValidator
10 from django.core.validators import MinValueValidator, MaxValueValidator
11
11
12 from apps.main.models import Configuration
12 from apps.main.models import Configuration
13 from devices.rc import api
13 from devices.rc import api
14 from .utils import RCFile
14 from .utils import RCFile
15
15
16 # Create your models here.
16 # Create your models here.
17
17
18 LINE_TYPES = (
18 LINE_TYPES = (
19 ('none', 'Not used'),
19 ('none', 'Not used'),
20 ('tr', 'Transmission/reception selector signal'),
20 ('tr', 'Transmission/reception selector signal'),
21 ('tx', 'A modulating signal (Transmission pulse)'),
21 ('tx', 'A modulating signal (Transmission pulse)'),
22 ('codes', 'BPSK modulating signal'),
22 ('codes', 'BPSK modulating signal'),
23 ('windows', 'Sample window signal'),
23 ('windows', 'Sample window signal'),
24 ('sync', 'Synchronizing signal'),
24 ('sync', 'Synchronizing signal'),
25 ('flip', 'IPP related periodic signal'),
25 ('flip', 'IPP related periodic signal'),
26 ('prog_pulses', 'Programmable pulse'),
26 ('prog_pulses', 'Programmable pulse'),
27 ('mix', 'Mixed line'),
27 ('mix', 'Mixed line'),
28 )
28 )
29
29
30
30
31 SAMPLING_REFS = (
31 SAMPLING_REFS = (
32 ('none', 'No Reference'),
32 ('none', 'No Reference'),
33 ('first_baud', 'Middle of the first baud'),
33 ('first_baud', 'Middle of the first baud'),
34 ('sub_baud', 'Middle of the sub-baud')
34 ('sub_baud', 'Middle of the sub-baud')
35 )
35 )
36
36
37 DAT_CMDS = {
37 DAT_CMDS = {
38 # Pulse Design commands
38 # Pulse Design commands
39 'DISABLE' : 0, # Disables pulse generation
39 'DISABLE' : 0, # Disables pulse generation
40 'ENABLE' : 24, # Enables pulse generation
40 'ENABLE' : 24, # Enables pulse generation
41 'DELAY_START' : 40, # Write delay status to memory
41 'DELAY_START' : 40, # Write delay status to memory
42 'FLIP_START' : 48, # Write flip status to memory
42 'FLIP_START' : 48, # Write flip status to memory
43 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
43 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
44 'TX_ONE' : 72, # Output '0' in line TX
44 'TX_ONE' : 72, # Output '0' in line TX
45 'TX_ZERO' : 88, # Output '0' in line TX
45 'TX_ZERO' : 88, # Output '0' in line TX
46 'SW_ONE' : 104, # Output '0' in line SW
46 'SW_ONE' : 104, # Output '0' in line SW
47 'SW_ZERO' : 112, # Output '1' in line SW
47 'SW_ZERO' : 112, # Output '1' in line SW
48 'RESTART': 120, # Restarts CR8 Firmware
48 'RESTART': 120, # Restarts CR8 Firmware
49 'CONTINUE' : 253, # Function Unknown
49 'CONTINUE' : 253, # Function Unknown
50 # Commands available to new controllers
50 # Commands available to new controllers
51 # In Pulse Design Executable, the clock divisor code is written as 12 at the start, but it should be written as code 22(below) just before the final enable.
51 # In Pulse Design Executable, the clock divisor code is written as 12 at the start, but it should be written as code 22(below) just before the final enable.
52 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
52 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
53 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
53 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
54 'CLOCK_DIVIDER' : 8,
54 'CLOCK_DIVIDER' : 8,
55 }
55 }
56
56
57
57
58 class RCConfiguration(Configuration):
58 class RCConfiguration(Configuration):
59
59
60 ipp = models.FloatField(verbose_name='Inter pulse period [Km]', validators=[MinValueValidator(1), MaxValueValidator(9000)], default=300)
60 ipp = models.FloatField(verbose_name='Inter pulse period [Km]', validators=[MinValueValidator(1), MaxValueValidator(9000)], default=300)
61 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(300)], default=1)
61 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(300)], default=1)
62 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
62 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
63 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
63 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
64 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
64 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
65 time_before = models.PositiveIntegerField(verbose_name='Time before [&mu;S]', default=12)
65 time_before = models.PositiveIntegerField(verbose_name='Time before [&mu;S]', default=12)
66 time_after = models.PositiveIntegerField(verbose_name='Time after [&mu;S]', default=1)
66 time_after = models.PositiveIntegerField(verbose_name='Time after [&mu;S]', default=1)
67 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
67 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
68 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
68 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
69 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
69 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
70 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
70 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
71 total_units = models.PositiveIntegerField(default=0)
71 total_units = models.PositiveIntegerField(default=0)
72 mix = models.BooleanField(default=False)
72 mix = models.BooleanField(default=False)
73
73
74 class Meta:
74 class Meta:
75 db_table = 'rc_configurations'
75 db_table = 'rc_configurations'
76
76
77
77
78 def __unicode__(self):
78 def __unicode__(self):
79
79
80 if self.mix:
80 if self.mix:
81 return u'[MIXED]: %s' % self.name
81 return u'[MIXED]: %s' % self.name
82 else:
82 else:
83 return u'[%s]: %s' % (self.device.name, self.name)
83 return u'[%s]: %s' % (self.device.name, self.name)
84
84
85 def get_absolute_url_plot(self):
85 def get_absolute_url_plot(self):
86 return reverse('url_plot_rc_pulses', args=[str(self.id)])
86 return reverse('url_plot_rc_pulses', args=[str(self.id)])
87
87
88 def get_absolute_url_import(self):
88 def get_absolute_url_import(self):
89 return reverse('url_import_rc_conf', args=[str(self.id)])
89 return reverse('url_import_rc_conf', args=[str(self.id)])
90
90
91 @property
91 @property
92 def ipp_unit(self):
92 def ipp_unit(self):
93
93
94 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
94 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
95
95
96 @property
96 @property
97 def us2unit(self):
97 def us2unit(self):
98
98
99 return self.clock_in/self.clock_divider
99 return self.clock_in/self.clock_divider
100
100
101 @property
101 @property
102 def km2unit(self):
102 def km2unit(self):
103
103
104 return 20./3*(self.clock_in/self.clock_divider)
104 return 20./3*(self.clock_in/self.clock_divider)
105
105
106 def clone(self, **kwargs):
106 def clone(self, **kwargs):
107
107
108 lines = self.get_lines()
108 lines = self.get_lines()
109 self.pk = None
109 self.pk = None
110 self.id = None
110 self.id = None
111 for attr, value in kwargs.items():
111 for attr, value in kwargs.items():
112 setattr(self, attr, value)
112 setattr(self, attr, value)
113 self.save()
113 self.save()
114
114
115 for line in lines:
115 for line in lines:
116 line.clone(rc_configuration=self)
116 line.clone(rc_configuration=self)
117
117
118 return self
118 return self
119
119
120 def get_lines(self, **kwargs):
120 def get_lines(self, **kwargs):
121 '''
121 '''
122 Retrieve configuration lines
122 Retrieve configuration lines
123 '''
123 '''
124
124
125 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
125 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
126
126
127
127
128 def clean_lines(self):
128 def clean_lines(self):
129 '''
129 '''
130 '''
130 '''
131
131
132 empty_line = RCLineType.objects.get(name='none')
132 empty_line = RCLineType.objects.get(name='none')
133
133
134 for line in self.get_lines():
134 for line in self.get_lines():
135 line.line_type = empty_line
135 line.line_type = empty_line
136 line.params = '{}'
136 line.params = '{}'
137 line.save()
137 line.save()
138
138
139 def parms_to_dict(self):
139 def parms_to_dict(self):
140 '''
140 '''
141 '''
141 '''
142
142
143 ignored = ('parameters', 'type', 'polymorphic_ctype', 'configuration_ptr',
143 ignored = ('parameters', 'type', 'polymorphic_ctype', 'configuration_ptr',
144 'created_date', 'programmed_date')
144 'created_date', 'programmed_date')
145
145
146 data = {}
146 data = {}
147 for field in self._meta.fields:
147 for field in self._meta.fields:
148 if field.name in ignored:
148 if field.name in ignored:
149 continue
149 continue
150 data[field.name] = '{}'.format(field.value_from_object(self))
150 data[field.name] = '{}'.format(field.value_from_object(self))
151
151
152 data['lines'] = []
152 data['lines'] = []
153
153
154 for line in self.get_lines():
154 for line in self.get_lines():
155 line_data = json.loads(line.params)
155 line_data = json.loads(line.params)
156 if 'TX_ref' in line_data and line_data['TX_ref'] not in (0, '0'):
156 if 'TX_ref' in line_data and line_data['TX_ref'] not in (0, '0'):
157 line_data['TX_ref'] = RCLine.objects.get(pk=line_data['TX_ref']).get_name()
157 line_data['TX_ref'] = RCLine.objects.get(pk=line_data['TX_ref']).get_name()
158 if 'code' in line_data:
158 if 'code' in line_data:
159 line_data['code'] = RCLineCode.objects.get(pk=line_data['code']).name
159 line_data['code'] = RCLineCode.objects.get(pk=line_data['code']).name
160 line_data['type'] = line.line_type.name
160 line_data['type'] = line.line_type.name
161 data['lines'].append(line_data)
161 data['lines'].append(line_data)
162
162
163 data['delays'] = self.get_delays()
163 data['delays'] = self.get_delays()
164 data['pulses'] = self.get_pulses()
164 data['pulses'] = self.get_pulses()
165
165
166 return data
166 return data
167
167
168 def dict_to_parms(self, data):
168 def dict_to_parms(self, data):
169 '''
169 '''
170 '''
170 '''
171
171
172 self.name = data['name']
172 self.name = data['name']
173 self.ipp = data['ipp']
173 self.ipp = data['ipp']
174 self.ntx = data['ntx']
174 self.ntx = data['ntx']
175 self.clock_in = data['clock_in']
175 self.clock_in = data['clock_in']
176 self.clock_divider = data['clock_divider']
176 self.clock_divider = data['clock_divider']
177 self.clock = data['clock']
177 self.clock = data['clock']
178 self.time_before = data['time_before']
178 self.time_before = data['time_before']
179 self.time_after = data['time_after']
179 self.time_after = data['time_after']
180 self.sync = data['sync']
180 self.sync = data['sync']
181 self.sampling_reference = data['sampling_reference']
181 self.sampling_reference = data['sampling_reference']
182 self.save()
182 self.save()
183 self.clean_lines()
183 self.clean_lines()
184
184
185 lines = []
185 lines = []
186 positions = {'tx':0, 'tr':0}
186 positions = {'tx':0, 'tr':0}
187
187
188 for i, line_data in enumerate(data['lines']):
188 for i, line_data in enumerate(data['lines']):
189 line_type = RCLineType.objects.get(name=line_data.pop('type'))
189 line_type = RCLineType.objects.get(name=line_data.pop('type'))
190 if line_type.name=='codes':
190 if line_type.name=='codes':
191 code = RCLineCode.objects.get(name=line_data['code'])
191 code = RCLineCode.objects.get(name=line_data['code'])
192 line_data['code'] = code.pk
192 line_data['code'] = code.pk
193 line = RCLine.objects.filter(rc_configuration=self, channel=i)
193 line = RCLine.objects.filter(rc_configuration=self, channel=i)
194 if line:
194 if line:
195 line = line[0]
195 line = line[0]
196 line.line_type = line_type
196 line.line_type = line_type
197 line.params = json.dumps(line_data)
197 line.params = json.dumps(line_data)
198 else:
198 else:
199 line = RCLine(rc_configuration=self, line_type=line_type,
199 line = RCLine(rc_configuration=self, line_type=line_type,
200 params=json.dumps(line_data),
200 params=json.dumps(line_data),
201 channel=i)
201 channel=i)
202
202
203 if line_type.name=='tx':
203 if line_type.name=='tx':
204 line.position = positions['tx']
204 line.position = positions['tx']
205 positions['tx'] += 1
205 positions['tx'] += 1
206
206
207 if line_type.name=='tr':
207 if line_type.name=='tr':
208 line.position = positions['tr']
208 line.position = positions['tr']
209 positions['tr'] += 1
209 positions['tr'] += 1
210
210
211 line.save()
211 line.save()
212 lines.append(line)
212 lines.append(line)
213
213
214 for line, line_data in zip(lines, data['lines']):
214 for line, line_data in zip(lines, data['lines']):
215 if 'TX_ref' in line_data:
215 if 'TX_ref' in line_data:
216 params = json.loads(line.params)
216 params = json.loads(line.params)
217 if line_data['TX_ref'] in (0, '0'):
217 if line_data['TX_ref'] in (0, '0'):
218 params['TX_ref'] = '0'
218 params['TX_ref'] = '0'
219 else:
219 else:
220 params['TX_ref'] = [l.pk for l in lines if l.line_type.name=='tx' and line_data['TX_ref'] in l.get_name()][0]
220 params['TX_ref'] = [l.pk for l in lines if l.line_type.name=='tx' and line_data['TX_ref'] in l.get_name()][0]
221 line.params = json.dumps(params)
221 line.params = json.dumps(params)
222 line.save()
222 line.save()
223
223
224
224
225 def get_delays(self):
225 def get_delays(self):
226
226
227 pulses = [line.pulses_as_points() for line in self.get_lines()]
227 pulses = [line.pulses_as_points() for line in self.get_lines()]
228 points = [tup for tups in pulses for tup in tups]
228 points = [tup for tups in pulses for tup in tups]
229 points = set([x for tup in points for x in tup])
229 points = set([x for tup in points for x in tup])
230 points = list(points)
230 points = list(points)
231 points.sort()
231 points.sort()
232
232
233 if points[0]<>0:
233 if points[0]<>0:
234 points.insert(0, 0)
234 points.insert(0, 0)
235
235
236 return [points[i+1]-points[i] for i in range(len(points)-1)]
236 return [points[i+1]-points[i] for i in range(len(points)-1)]
237
237
238
238
239 def get_pulses(self, binary=True):
239 def get_pulses(self, binary=True):
240
240
241 pulses = [line.pulses_as_points() for line in self.get_lines()]
241 pulses = [line.pulses_as_points() for line in self.get_lines()]
242 points = [tup for tups in pulses for tup in tups]
242 points = [tup for tups in pulses for tup in tups]
243 points = set([x for tup in points for x in tup])
243 points = set([x for tup in points for x in tup])
244 points = list(points)
244 points = list(points)
245 points.sort()
245 points.sort()
246
246
247 line_points = [line.pulses_as_points() for line in self.get_lines()]
247 line_points = [line.pulses_as_points() for line in self.get_lines()]
248 line_points = [[(x, x+y) for x,y in tups] for tups in line_points]
248 line_points = [[(x, x+y) for x,y in tups] for tups in line_points]
249 line_points = [[t for x in tups for t in x] for tups in line_points]
249 line_points = [[t for x in tups for t in x] for tups in line_points]
250 states = [[1 if x in tups else 0 for tups in line_points] for x in points]
250 states = [[1 if x in tups else 0 for tups in line_points] for x in points]
251
251
252 if binary:
252 if binary:
253 states.reverse()
253 states.reverse()
254 states = [int(''.join([str(x) for x in flips]), 2) for flips in states]
254 states = [int(''.join([str(x) for x in flips]), 2) for flips in states]
255
255
256 return states[:-1]
256 return states[:-1]
257
257
258 def add_cmd(self, cmd):
258 def add_cmd(self, cmd):
259
259
260 if cmd in DAT_CMDS:
260 if cmd in DAT_CMDS:
261 return (255, DAT_CMDS[cmd])
261 return (255, DAT_CMDS[cmd])
262
262
263 def add_data(self, value):
263 def add_data(self, value):
264
264
265 return (254, value-1)
265 return (254, value-1)
266
266
267 def parms_to_binary(self):
267 def parms_to_binary(self):
268 '''
268 '''
269 Create "dat" stream to be send to CR
269 Create "dat" stream to be send to CR
270 '''
270 '''
271
271
272 data = []
272 data = []
273 # create header
273 # create header
274 data.append(self.add_cmd('DISABLE'))
274 data.append(self.add_cmd('DISABLE'))
275 data.append(self.add_cmd('CONTINUE'))
275 data.append(self.add_cmd('CONTINUE'))
276 data.append(self.add_cmd('RESTART'))
276 data.append(self.add_cmd('RESTART'))
277
277
278 if self.control_sw:
278 if self.control_sw:
279 data.append(self.add_cmd('SW_ONE'))
279 data.append(self.add_cmd('SW_ONE'))
280 else:
280 else:
281 data.append(self.add_cmd('SW_ZERO'))
281 data.append(self.add_cmd('SW_ZERO'))
282
282
283 if self.control_tx:
283 if self.control_tx:
284 data.append(self.add_cmd('TX_ONE'))
284 data.append(self.add_cmd('TX_ONE'))
285 else:
285 else:
286 data.append(self.add_cmd('TX_ZERO'))
286 data.append(self.add_cmd('TX_ZERO'))
287
287
288 # write divider
288 # write divider
289 data.append(self.add_cmd('CLOCK_DIVIDER'))
289 data.append(self.add_cmd('CLOCK_DIVIDER'))
290 data.append(self.add_data(self.clock_divider))
290 data.append(self.add_data(self.clock_divider))
291
291
292 # write delays
292 # write delays
293 data.append(self.add_cmd('DELAY_START'))
293 data.append(self.add_cmd('DELAY_START'))
294 # first delay is always zero
294 # first delay is always zero
295 data.append(self.add_data(1))
295 data.append(self.add_data(1))
296
296
297 delays = self.get_delays()
297 delays = self.get_delays()
298
298
299 for delay in delays:
299 for delay in delays:
300 while delay>252:
300 while delay>252:
301 data.append(self.add_data(253))
301 data.append(self.add_data(253))
302 delay -= 253
302 delay -= 253
303 data.append(self.add_data(delay))
303 data.append(self.add_data(delay))
304
304
305 # write flips
305 # write flips
306 data.append(self.add_cmd('FLIP_START'))
306 data.append(self.add_cmd('FLIP_START'))
307
307
308 states = self.get_pulses(binary=False)
308 states = self.get_pulses(binary=False)
309
309
310 for flips, delay in zip(states, delays):
310 for flips, delay in zip(states, delays):
311 flips.reverse()
311 flips.reverse()
312 flip = int(''.join([str(x) for x in flips]), 2)
312 flip = int(''.join([str(x) for x in flips]), 2)
313 data.append(self.add_data(flip+1))
313 data.append(self.add_data(flip+1))
314 while delay>252:
314 while delay>252:
315 data.append(self.add_data(1))
315 data.append(self.add_data(1))
316 delay -= 253
316 delay -= 253
317
317
318 # write sampling period
318 # write sampling period
319 data.append(self.add_cmd('SAMPLING_PERIOD'))
319 data.append(self.add_cmd('SAMPLING_PERIOD'))
320 wins = self.get_lines(line_type__name='windows')
320 wins = self.get_lines(line_type__name='windows')
321 if wins:
321 if wins:
322 win_params = json.loads(wins[0].params)['params']
322 win_params = json.loads(wins[0].params)['params']
323 if win_params:
323 if win_params:
324 dh = int(win_params[0]['resolution']*self.km2unit)
324 dh = int(win_params[0]['resolution']*self.km2unit)
325 else:
325 else:
326 dh = 1
326 dh = 1
327 else:
327 else:
328 dh = 1
328 dh = 1
329 data.append(self.add_data(dh))
329 data.append(self.add_data(dh))
330
330
331 # write enable
331 # write enable
332 data.append(self.add_cmd('ENABLE'))
332 data.append(self.add_cmd('ENABLE'))
333
333
334 return '\n'.join(['{}'.format(x) for tup in data for x in tup])
334 return '\n'.join(['{}'.format(x) for tup in data for x in tup])
335
335
336 def update_from_file(self, filename):
336 def update_from_file(self, filename):
337 '''
337 '''
338 Update instance from file
338 Update instance from file
339 '''
339 '''
340
340
341 f = RCFile(filename)
341 f = RCFile(filename)
342 self.dict_to_parms(f.data)
342 self.dict_to_parms(f.data)
343 self.update_pulses()
343 self.update_pulses()
344
344
345 def update_pulses(self):
345 def update_pulses(self):
346
346
347 for line in self.get_lines():
347 for line in self.get_lines():
348 line.update_pulses()
348 line.update_pulses()
349
349
350 def plot_pulses(self):
350 def plot_pulses(self):
351
351
352 import matplotlib.pyplot as plt
352 import matplotlib.pyplot as plt
353 from bokeh.resources import CDN
353 from bokeh.resources import CDN
354 from bokeh.embed import components
354 from bokeh.embed import components
355 from bokeh.mpl import to_bokeh
355 from bokeh.mpl import to_bokeh
356 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, PreviewSaveTool
356 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, PreviewSaveTool
357
357
358 lines = self.get_lines()
358 lines = self.get_lines()
359
359
360 N = len(lines)
360 N = len(lines)
361 fig = plt.figure(figsize=(10, 2+N*0.5))
361 fig = plt.figure(figsize=(10, 2+N*0.5))
362 ax = fig.add_subplot(111)
362 ax = fig.add_subplot(111)
363 labels = []
363 labels = []
364
364
365 for i, line in enumerate(lines):
365 for i, line in enumerate(lines):
366 labels.append(line.get_name())
366 labels.append(line.get_name())
367 l = ax.plot((0, self.total_units),(N-i-1, N-i-1))
367 l = ax.plot((0, self.total_units),(N-i-1, N-i-1))
368 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points() if tup<>(0,0)]
368 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points() if tup<>(0,0)]
369 ax.broken_barh(points, (N-i-1, 0.5),
369 ax.broken_barh(points, (N-i-1, 0.5),
370 edgecolor=l[0].get_color(), facecolor='none')
370 edgecolor=l[0].get_color(), facecolor='none')
371
371
372 labels.reverse()
372 labels.reverse()
373 ax.set_yticklabels(labels)
373 ax.set_yticklabels(labels)
374 plot = to_bokeh(fig, use_pandas=False)
374 ax.set_xlabel = 'Units'
375 plot = to_bokeh(fig, use_pandas=False)
375 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), PreviewSaveTool()]
376 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), PreviewSaveTool()]
376
377
377 return components(plot, CDN)
378 return components(plot, CDN)
378
379
379 def status_device(self):
380 def status_device(self):
380
381
381 return 0
382 return 0
382
383
383 def stop_device(self):
384 def stop_device(self):
384
385
385 answer = api.disable(ip = self.device.ip_address,
386 answer = api.disable(ip = self.device.ip_address,
386 port = self.device.port_address)
387 port = self.device.port_address)
387
388
388 if answer[0] != "1":
389 if answer[0] != "1":
389 self.message = answer[0:]
390 self.message = answer[0:]
390 return 0
391 return 0
391
392
392 self.message = answer[2:]
393 self.message = answer[2:]
393 return 1
394 return 1
394
395
395 def start_device(self):
396 def start_device(self):
396
397
397 answer = api.enable(ip = self.device.ip_address,
398 answer = api.enable(ip = self.device.ip_address,
398 port = self.device.port_address)
399 port = self.device.port_address)
399
400
400 if answer[0] != "1":
401 if answer[0] != "1":
401 self.message = answer[0:]
402 self.message = answer[0:]
402 return 0
403 return 0
403
404
404 self.message = answer[2:]
405 self.message = answer[2:]
405 return 1
406 return 1
406
407
407 def write_device(self):
408 def write_device(self):
408 answer = api.write_config(ip = self.device.ip_address,
409 answer = api.write_config(ip = self.device.ip_address,
409 port = self.device.port_address,
410 port = self.device.port_address,
410 parms = self.parms_to_dict())
411 parms = self.parms_to_dict())
411
412
412 if answer[0] != "1":
413 if answer[0] != "1":
413 self.message = answer[0:]
414 self.message = answer[0:]
414 return 0
415 return 0
415
416
416 self.message = answer[2:]
417 self.message = answer[2:]
417 return 1
418 return 1
418
419
419
420
420 class RCLineCode(models.Model):
421 class RCLineCode(models.Model):
421
422
422 name = models.CharField(max_length=40)
423 name = models.CharField(max_length=40)
423 bits_per_code = models.PositiveIntegerField(default=0)
424 bits_per_code = models.PositiveIntegerField(default=0)
424 number_of_codes = models.PositiveIntegerField(default=0)
425 number_of_codes = models.PositiveIntegerField(default=0)
425 codes = models.TextField(blank=True, null=True)
426 codes = models.TextField(blank=True, null=True)
426
427
427 class Meta:
428 class Meta:
428 db_table = 'rc_line_codes'
429 db_table = 'rc_line_codes'
429 ordering = ('name',)
430 ordering = ('name',)
430
431
431 def __unicode__(self):
432 def __unicode__(self):
432 return u'%s' % self.name
433 return u'%s' % self.name
433
434
434
435
435 class RCLineType(models.Model):
436 class RCLineType(models.Model):
436
437
437 name = models.CharField(choices=LINE_TYPES, max_length=40)
438 name = models.CharField(choices=LINE_TYPES, max_length=40)
438 description = models.TextField(blank=True, null=True)
439 description = models.TextField(blank=True, null=True)
439 params = models.TextField(default='[]')
440 params = models.TextField(default='[]')
440
441
441 class Meta:
442 class Meta:
442 db_table = 'rc_line_types'
443 db_table = 'rc_line_types'
443
444
444 def __unicode__(self):
445 def __unicode__(self):
445 return u'%s - %s' % (self.name.upper(), self.get_name_display())
446 return u'%s - %s' % (self.name.upper(), self.get_name_display())
446
447
447
448
448 class RCLine(models.Model):
449 class RCLine(models.Model):
449
450
450 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
451 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
451 line_type = models.ForeignKey(RCLineType)
452 line_type = models.ForeignKey(RCLineType)
452 channel = models.PositiveIntegerField(default=0)
453 channel = models.PositiveIntegerField(default=0)
453 position = models.PositiveIntegerField(default=0)
454 position = models.PositiveIntegerField(default=0)
454 params = models.TextField(default='{}')
455 params = models.TextField(default='{}')
455 pulses = models.TextField(default='')
456 pulses = models.TextField(default='')
456
457
457 class Meta:
458 class Meta:
458 db_table = 'rc_lines'
459 db_table = 'rc_lines'
459 ordering = ['channel']
460 ordering = ['channel']
460
461
461 def __unicode__(self):
462 def __unicode__(self):
462 if self.rc_configuration:
463 if self.rc_configuration:
463 return u'%s - %s' % (self.rc_configuration, self.get_name())
464 return u'%s - %s' % (self.rc_configuration, self.get_name())
464
465
465 def clone(self, **kwargs):
466 def clone(self, **kwargs):
466
467
467 self.pk = None
468 self.pk = None
468
469
469 for attr, value in kwargs.items():
470 for attr, value in kwargs.items():
470 setattr(self, attr, value)
471 setattr(self, attr, value)
471
472
472 self.save()
473 self.save()
473
474
474 return self
475 return self
475
476
476 def get_name(self):
477 def get_name(self):
477
478
478 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
479 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
479 s = ''
480 s = ''
480
481
481 if self.line_type.name in ('tx',):
482 if self.line_type.name in ('tx',):
482 s = chars[self.position]
483 s = chars[self.position]
483 elif self.line_type.name in ('codes', 'windows', 'tr'):
484 elif self.line_type.name in ('codes', 'windows', 'tr'):
484 if 'TX_ref' in json.loads(self.params):
485 if 'TX_ref' in json.loads(self.params):
485 pk = json.loads(self.params)['TX_ref']
486 pk = json.loads(self.params)['TX_ref']
486 if pk in (0, '0'):
487 if pk in (0, '0'):
487 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
488 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
488 else:
489 else:
489 ref = RCLine.objects.get(pk=pk)
490 ref = RCLine.objects.get(pk=pk)
490 s = chars[ref.position]
491 s = chars[ref.position]
491 s = '({})'.format(s)
492 s = '({})'.format(s)
492 if s:
493 if s:
493 return '{}{} {}'.format(self.line_type.name.upper(), s, self.channel)
494 return '{}{} {}'.format(self.line_type.name.upper(), s, self.channel)
494 else:
495 else:
495 return '{} {}'.format(self.line_type.name.upper(), self.channel)
496 return '{} {}'.format(self.line_type.name.upper(), self.channel)
496
497
497 def get_lines(self, **kwargs):
498 def get_lines(self, **kwargs):
498
499
499 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
500 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
500
501
501 def pulses_as_array(self):
502 def pulses_as_array(self):
502
503
503 y = np.zeros(self.rc_configuration.total_units)
504 y = np.zeros(self.rc_configuration.total_units)
504
505
505 for tup in ast.literal_eval(self.pulses):
506 for tup in ast.literal_eval(self.pulses):
506 y[tup[0]:tup[1]] = 1
507 y[tup[0]:tup[1]] = 1
507
508
508 return y.astype(np.int8)
509 return y.astype(np.int8)
509
510
510 def pulses_as_points(self):
511 def pulses_as_points(self):
511
512
512 return ast.literal_eval(self.pulses)
513 return ast.literal_eval(self.pulses)
513
514
514 def get_win_ref(self, params, tx_id, km2unit):
515 def get_win_ref(self, params, tx_id, km2unit):
515
516
516 ref = self.rc_configuration.sampling_reference
517 ref = self.rc_configuration.sampling_reference
517 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
518 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
518
519
519 if codes:
520 if codes:
520 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
521 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
521 else:
522 else:
522 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
523 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
523
524
524 if ref=='first_baud':
525 if ref=='first_baud':
525 return int(1 + (tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit)
526 return int(1 + (tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit)
526 elif ref=='sub_baud':
527 elif ref=='sub_baud':
527 return int(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
528 return int(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
528 else:
529 else:
529 return 0
530 return 0
530
531
531 def update_pulses(self):
532 def update_pulses(self):
532 '''
533 '''
533 Update pulses field
534 Update pulses field
534 '''
535 '''
535
536
536 km2unit = self.rc_configuration.km2unit
537 km2unit = self.rc_configuration.km2unit
537 us2unit = self.rc_configuration.us2unit
538 us2unit = self.rc_configuration.us2unit
538 ipp = self.rc_configuration.ipp
539 ipp = self.rc_configuration.ipp
539 ntx = self.rc_configuration.ntx
540 ntx = self.rc_configuration.ntx
540 ipp_u = int(ipp*km2unit)
541 ipp_u = int(ipp*km2unit)
541 total = ipp_u*ntx
542 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
542 y = []
543 y = []
543
544
544 if self.line_type.name=='tr':
545 if self.line_type.name=='tr':
545 tr_params = json.loads(self.params)
546 tr_params = json.loads(self.params)
546
547
547 if tr_params['TX_ref'] in ('0', 0):
548 if tr_params['TX_ref'] in ('0', 0):
548 txs = self.get_lines(line_type__name='tx')
549 txs = self.get_lines(line_type__name='tx')
549 else:
550 else:
550 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
551 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
551
552
552 for tx in txs:
553 for tx in txs:
553 params = json.loads(tx.params)
554 params = json.loads(tx.params)
554 if float(params['pulse_width'])==0:
555 if float(params['pulse_width'])==0:
555 continue
556 continue
556 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
557 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
557 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
558 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
558 before = 0
559 before = 0
559 after = int(self.rc_configuration.time_after*us2unit)
560 after = int(self.rc_configuration.time_after*us2unit)
560
561
561 y_tx = self.points(ntx, ipp_u, width,
562 y_tx = self.points(ntx, ipp_u, width,
562 delay=delays,
563 delay=delays,
563 before=before,
564 before=before,
564 after=after,
565 after=after,
565 sync=self.rc_configuration.sync)
566 sync=self.rc_configuration.sync)
566
567
567 ranges = params['range'].split(',')
568 ranges = params['range'].split(',')
568
569
569 if len(ranges)>0 and ranges[0]<>'0':
570 if len(ranges)>0 and ranges[0]<>'0':
570 y_tx = self.mask_ranges(y_tx, ranges)
571 y_tx = self.mask_ranges(y_tx, ranges)
571
572
572 tr_ranges = tr_params['range'].split(',')
573 tr_ranges = tr_params['range'].split(',')
573
574
574 if len(tr_ranges)>0 and tr_ranges[0]<>'0':
575 if len(tr_ranges)>0 and tr_ranges[0]<>'0':
575 y_tx = self.mask_ranges(y_tx, tr_ranges)
576 y_tx = self.mask_ranges(y_tx, tr_ranges)
576
577
577 y.extend(y_tx)
578 y.extend(y_tx)
578
579
580 self.pulses = unicode(y)
581 y = self.array_to_points(self.pulses_as_array())
582
579 elif self.line_type.name=='tx':
583 elif self.line_type.name=='tx':
580 params = json.loads(self.params)
584 params = json.loads(self.params)
581 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
585 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
582 width = float(params['pulse_width'])*km2unit
586 width = float(params['pulse_width'])*km2unit
583
587
584 if width>0:
588 if width>0:
585 before = int(self.rc_configuration.time_before*us2unit)
589 before = int(self.rc_configuration.time_before*us2unit)
586 after = 0
590 after = 0
587
591
588 y = self.points(ntx, ipp_u, width,
592 y = self.points(ntx, ipp_u, width,
589 delay=delays,
593 delay=delays,
590 before=before,
594 before=before,
591 after=after,
595 after=after,
592 sync=self.rc_configuration.sync)
596 sync=self.rc_configuration.sync)
593
597
594 ranges = params['range'].split(',')
598 ranges = params['range'].split(',')
595
599
596 if len(ranges)>0 and ranges[0]<>'0':
600 if len(ranges)>0 and ranges[0]<>'0':
597 y = self.mask_ranges(y, ranges)
601 y = self.mask_ranges(y, ranges)
598
602
599 elif self.line_type.name=='flip':
603 elif self.line_type.name=='flip':
600 n = float(json.loads(self.params)['number_of_flips'])
604 n = float(json.loads(self.params)['number_of_flips'])
601 width = n*ipp*km2unit
605 width = n*ipp*km2unit
602 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
606 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
603
607
604 elif self.line_type.name=='codes':
608 elif self.line_type.name=='codes':
605 params = json.loads(self.params)
609 params = json.loads(self.params)
606 tx = RCLine.objects.get(pk=params['TX_ref'])
610 tx = RCLine.objects.get(pk=params['TX_ref'])
607 tx_params = json.loads(tx.params)
611 tx_params = json.loads(tx.params)
608 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
612 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
609 f = int(float(tx_params['pulse_width'])*km2unit)/len(params['codes'][0])
613 f = int(float(tx_params['pulse_width'])*km2unit)/len(params['codes'][0])
610 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
614 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
611 codes = [self.array_to_points(code) for code in codes]
615 codes = [self.array_to_points(code) for code in codes]
612 n = len(codes)
616 n = len(codes)
613
617
614 for i, tup in enumerate(tx.pulses_as_points()):
618 for i, tup in enumerate(tx.pulses_as_points()):
615 code = codes[i%n]
619 code = codes[i%n]
616 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
620 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
617
621
618 ranges = tx_params['range'].split(',')
622 ranges = tx_params['range'].split(',')
619 if len(ranges)>0 and ranges[0]<>'0':
623 if len(ranges)>0 and ranges[0]<>'0':
620 y = self.mask_ranges(y, ranges)
624 y = self.mask_ranges(y, ranges)
621
625
622 elif self.line_type.name=='sync':
626 elif self.line_type.name=='sync':
623 params = json.loads(self.params)
627 params = json.loads(self.params)
624 n = ipp_u*ntx
628 n = ipp_u*ntx
625 if params['invert'] in ('1', 1):
629 if params['invert'] in ('1', 1):
626 y = [(n-1, n)]
630 y = [(n-1, n)]
627 else:
631 else:
628 y = [(0, 1)]
632 y = [(0, 1)]
629
633
630 elif self.line_type.name=='prog_pulses':
634 elif self.line_type.name=='prog_pulses':
631 params = json.loads(self.params)
635 params = json.loads(self.params)
632 if int(params['periodic'])==0:
636 if int(params['periodic'])==0:
633 nntx = 1
637 nntx = 1
634 nipp = ipp_u*ntx
638 nipp = ipp_u*ntx
635 else:
639 else:
636 nntx = ntx
640 nntx = ntx
637 nipp = ipp_u
641 nipp = ipp_u
638
642
639 if 'params' in params and len(params['params'])>0:
643 if 'params' in params and len(params['params'])>0:
640 for p in params['params']:
644 for p in params['params']:
641 y_pp = self.points(nntx, nipp,
645 y_pp = self.points(nntx, nipp,
642 p['end']-p['begin'],
646 p['end']-p['begin'],
643 before=p['begin'])
647 before=p['begin'])
644
648
645 y.extend(y_pp)
649 y.extend(y_pp)
646
650
647 elif self.line_type.name=='windows':
651 elif self.line_type.name=='windows':
648 params = json.loads(self.params)
652 params = json.loads(self.params)
649
653
650 if 'params' in params and len(params['params'])>0:
654 if 'params' in params and len(params['params'])>0:
651 tr_params = json.loads(self.get_lines(line_type__name='tr')[0].params)
655 tr_params = json.loads(self.get_lines(line_type__name='tr')[0].params)
652 tr_ranges = tr_params['range'].split(',')
656 tr_ranges = tr_params['range'].split(',')
653 for p in params['params']:
657 for p in params['params']:
654 y_win = self.points(ntx, ipp_u,
658 y_win = self.points(ntx, ipp_u,
655 p['resolution']*p['number_of_samples']*km2unit,
659 p['resolution']*p['number_of_samples']*km2unit,
656 before=int(self.rc_configuration.time_before*us2unit)+self.get_win_ref(p, params['TX_ref'], km2unit),
660 before=int(self.rc_configuration.time_before*us2unit)+self.get_win_ref(p, params['TX_ref'], km2unit),
657 sync=self.rc_configuration.sync)
661 sync=self.rc_configuration.sync)
658
662
659 if len(tr_ranges)>0 and tr_ranges[0]<>'0':
663 if len(tr_ranges)>0 and tr_ranges[0]<>'0':
660 y_win = self.mask_ranges(y_win, tr_ranges)
664 y_win = self.mask_ranges(y_win, tr_ranges)
661
665
662 y.extend(y_win)
666 y.extend(y_win)
663
667
664 elif self.line_type.name=='mix':
668 elif self.line_type.name=='mix':
665 values = self.rc_configuration.parameters.split('-')
669 values = self.rc_configuration.parameters.split('-')
666 confs = RCConfiguration.objects.filter(pk__in=[value.split('|')[0] for value in values])
670 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
667 modes = [value.split('|')[1] for value in values]
671 modes = [value.split('|')[1] for value in values]
668 ops = [value.split('|')[2] for value in values]
672 ops = [value.split('|')[2] for value in values]
669 delays = [value.split('|')[3] for value in values]
673 delays = [value.split('|')[3] for value in values]
670 masks = [value.split('|')[4] for value in values]
674 masks = [value.split('|')[4] for value in values]
671 mask = list('{:8b}'.format(int(masks[0])))
675 mask = list('{:8b}'.format(int(masks[0])))
672 mask.reverse()
676 mask.reverse()
673 if mask[self.channel] in ('0', '', ' '):
677 if mask[self.channel] in ('0', '', ' '):
674 y = np.zeros(total, dtype=np.int8)
678 y = np.zeros(confs[0].total_units, dtype=np.int8)
675 else:
679 else:
676 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
680 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
677
681
678 for i in range(1, len(values)):
682 for i in range(1, len(values)):
679 mask = list('{:8b}'.format(int(masks[i])))
683 mask = list('{:8b}'.format(int(masks[i])))
680 mask.reverse()
684 mask.reverse()
681
685
682 if mask[self.channel] in ('0', '', ' '):
686 if mask[self.channel] in ('0', '', ' '):
683 continue
687 continue
684 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
688 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
685 delay = float(delays[i])*km2unit
689 delay = float(delays[i])*km2unit
686
690
687 if delay>0:
691 if modes[i]=='P':
688 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
692 if delay>0:
689 y_temp = np.empty_like(Y)
693 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
690 y_temp[:delay] = 0
694 y_temp = np.empty_like(Y)
691 y_temp[delay:] = Y[:-delay]
695 y_temp[:delay] = 0
692 elif delay+len(Y)>len(y):
696 y_temp[delay:] = Y[:-delay]
693 y_new = np.zeros(delay+len(Y), dtype=np.int8)
697 elif delay+len(Y)>len(y):
694 y_new[:len(y)] = y
698 y_new = np.zeros(delay+len(Y), dtype=np.int8)
695 y = y_new
699 y_new[:len(y)] = y
696 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
700 y = y_new
697 y_temp[-len(Y):] = Y
701 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
698 elif delay+len(Y)==len(y):
702 y_temp[-len(Y):] = Y
699 y_temp = np.zeros(delay+len(Y))
703 elif delay+len(Y)==len(y):
700 y_temp[-len(Y):] = Y
704 y_temp = np.zeros(delay+len(Y))
701
705 y_temp[-len(Y):] = Y
702 if ops[i]=='OR':
706 elif delay+len(Y)<len(y):
703 y = y | y_temp
707 y_temp = np.zeros(len(y), dtype=np.int8)
704 elif ops[i]=='XOR':
708 y_temp[delay:delay+len(Y)] = Y
705 y = y ^ y_temp
709
706 elif ops[i]=='AND':
710 if ops[i]=='OR':
707 y = y & y_temp
711 y = y | y_temp
708 elif ops[i]=='NAND':
712 elif ops[i]=='XOR':
709 y = y & ~y_temp
713 y = y ^ y_temp
714 elif ops[i]=='AND':
715 y = y & y_temp
716 elif ops[i]=='NAND':
717 y = y & ~y_temp
718 else:
719 print len(y), len(Y)
720 y = np.concatenate([y, Y])
710
721
711 total = len(y)
722 total = len(y)
712 y = self.array_to_points(y)
723 y = self.array_to_points(y)
713
724
714 else:
725 else:
715 y = []
726 y = []
716
727
717 if self.rc_configuration.total_units <> total:
728 if self.rc_configuration.total_units <> total:
718 self.rc_configuration.total_units = total
729 self.rc_configuration.total_units = total
719 self.rc_configuration.save()
730 self.rc_configuration.save()
720
731
721 self.pulses = y
732 self.pulses = unicode(y)
722 self.save()
733 self.save()
723
734
724 @staticmethod
735 @staticmethod
725 def array_to_points(X):
736 def array_to_points(X):
726
737
727 d = X[1:]-X[:-1]
738 d = X[1:]-X[:-1]
728
739
729 up = np.where(d==1)[0]
740 up = np.where(d==1)[0]
730 if X[0]==1:
741 if X[0]==1:
731 up = np.concatenate((np.array([-1]), up))
742 up = np.concatenate((np.array([-1]), up))
732 up += 1
743 up += 1
733
744
734 dw = np.where(d==-1)[0]
745 dw = np.where(d==-1)[0]
735 if X[-1]==1:
746 if X[-1]==1:
736 dw = np.concatenate((dw, np.array([len(X)-1])))
747 dw = np.concatenate((dw, np.array([len(X)-1])))
737 dw += 1
748 dw += 1
738
749
739 return [(tup[0], tup[1]) for tup in zip(up, dw)]
750 return [(tup[0], tup[1]) for tup in zip(up, dw)]
740
751
741 @staticmethod
752 @staticmethod
742 def mask_ranges(Y, ranges):
753 def mask_ranges(Y, ranges):
743
754
744 y = [(0, 0) for __ in Y]
755 y = [(0, 0) for __ in Y]
745
756
746 for index in ranges:
757 for index in ranges:
747 if '-' in index:
758 if '-' in index:
748 args = [int(a) for a in index.split('-')]
759 args = [int(a) for a in index.split('-')]
749 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
760 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
750 else:
761 else:
751 y[int(index-1)] = Y[int(index-1)]
762 y[int(index-1)] = Y[int(index-1)]
752
763
753 return y
764 return y
754
765
755 @staticmethod
766 @staticmethod
756 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
767 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
757
768
758 delays = len(delay)
769 delays = len(delay)
759
770
760 Y = [(ipp*x+before+delay[x%delays], ipp*x+width+before+delay[x%delays]+after) for x in range(ntx)]
771 Y = [(ipp*x+before+delay[x%delays], ipp*x+width+before+delay[x%delays]+after) for x in range(ntx)]
761
772
762 return Y No newline at end of file
773 return Y
@@ -1,20 +1,24
1 {% extends "dev_conf.html" %}
1 {% extends "dev_conf.html" %}
2 {% load static %}
2 {% load static %}
3 {% load bootstrap3 %}
3 {% load bootstrap3 %}
4 {% load main_tags %}
4 {% load main_tags %}
5
5
6 {% block extra-head %}
6 {% block extra-head %}
7 <link href="http://cdn.pydata.org/bokeh/release/bokeh-0.11.1.min.css" rel="stylesheet" type="text/css">
7 <link href="http://cdn.pydata.org/bokeh/release/bokeh-0.11.1.min.css" rel="stylesheet" type="text/css">
8 {% endblock %}
8 {% endblock %}
9
9
10 {% block content %}
10 {% block content %}
11 <div id="div_plot">{{div}}</div>
11 <div id="div_plot">{{div}}</div>
12 <br>
13 <div class="col-md-2">1 Km =</div><div class="col-md-3">{{units}} Units</div>
14 <br>
15 <div class="col-md-2">1 Unit=</div><div class="col-md-3">{{kms}} Km</div>
12 {% endblock %}
16 {% endblock %}
13
17
14 {% block extra-js%}
18 {% block extra-js%}
15
19
16 <script src="{% static 'js/bokeh-0.11.1.min.js' %}"></script>
20 <script src="{% static 'js/bokeh-0.11.1.min.js' %}"></script>
17
21
18 {{script}}
22 {{script}}
19
23
20 {% endblock %} No newline at end of file
24 {% endblock %}
@@ -1,370 +1,372
1
1
2 import json
2 import json
3
3
4 from django.contrib import messages
4 from django.contrib import messages
5 from django.utils.safestring import mark_safe
5 from django.utils.safestring import mark_safe
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7
7
8 from apps.main.models import Configuration, Experiment, Device
8 from apps.main.models import Configuration, Experiment, Device
9 from apps.main.views import sidebar
9 from apps.main.views import sidebar
10
10
11 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
11 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
12 from .forms import RCConfigurationForm, RCLineForm, RCLineViewForm, RCLineEditForm, RCImportForm, RCLineCodesForm
12 from .forms import RCConfigurationForm, RCLineForm, RCLineViewForm, RCLineEditForm, RCImportForm, RCLineCodesForm
13
13
14
14
15 def conf(request, conf_id):
15 def conf(request, conf_id):
16
16
17 conf = get_object_or_404(RCConfiguration, pk=conf_id)
17 conf = get_object_or_404(RCConfiguration, pk=conf_id)
18
18
19 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
19 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
20
20
21 for line in lines:
21 for line in lines:
22 params = json.loads(line.params)
22 params = json.loads(line.params)
23 line.form = RCLineViewForm(extra_fields=params, line=line)
23 line.form = RCLineViewForm(extra_fields=params, line=line)
24 if 'params' in params:
24 if 'params' in params:
25 line.subforms = [RCLineViewForm(extra_fields=fields, line=line, subform=True) for fields in params['params']]
25 line.subforms = [RCLineViewForm(extra_fields=fields, line=line, subform=True) for fields in params['params']]
26
26
27 kwargs = {}
27 kwargs = {}
28 kwargs['dev_conf'] = conf
28 kwargs['dev_conf'] = conf
29 kwargs['rc_lines'] = lines
29 kwargs['rc_lines'] = lines
30 kwargs['dev_conf_keys'] = ['name', 'ipp_unit', 'ntx', 'clock_in', 'clock_divider', 'clock',
30 kwargs['dev_conf_keys'] = ['name', 'ipp_unit', 'ntx', 'clock_in', 'clock_divider', 'clock',
31 'time_before', 'time_after', 'sync', 'sampling_reference', 'control_tx', 'control_sw']
31 'time_before', 'time_after', 'sync', 'sampling_reference', 'control_tx', 'control_sw']
32
32
33 kwargs['title'] = 'RC Configuration'
33 kwargs['title'] = 'RC Configuration'
34 kwargs['suptitle'] = 'Details'
34 kwargs['suptitle'] = 'Details'
35
35
36 kwargs['button'] = 'Edit Configuration'
36 kwargs['button'] = 'Edit Configuration'
37 ###### SIDEBAR ######
37 ###### SIDEBAR ######
38 kwargs.update(sidebar(conf=conf))
38 kwargs.update(sidebar(conf=conf))
39
39
40 return render(request, 'rc_conf.html', kwargs)
40 return render(request, 'rc_conf.html', kwargs)
41
41
42
42
43 def conf_edit(request, conf_id):
43 def conf_edit(request, conf_id):
44
44
45 conf = get_object_or_404(RCConfiguration, pk=conf_id)
45 conf = get_object_or_404(RCConfiguration, pk=conf_id)
46
46
47 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
47 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
48
48
49 for line in lines:
49 for line in lines:
50 params = json.loads(line.params)
50 params = json.loads(line.params)
51 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
51 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
52 line.subform = False
52 line.subform = False
53
53
54 if 'params' in params:
54 if 'params' in params:
55 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
55 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
56 line.subform = True
56 line.subform = True
57
57
58 if request.method=='GET':
58 if request.method=='GET':
59
59
60 form = RCConfigurationForm(instance=conf)
60 form = RCConfigurationForm(instance=conf)
61
61
62 elif request.method=='POST':
62 elif request.method=='POST':
63
63
64 line_data = {}
64 line_data = {}
65 conf_data = {}
65 conf_data = {}
66 extras = []
66 extras = []
67
67
68 #classified post fields
68 #classified post fields
69 for label,value in request.POST.items():
69 for label,value in request.POST.items():
70 if label=='csrfmiddlewaretoken':
70 if label=='csrfmiddlewaretoken':
71 continue
71 continue
72
72
73 if label.count('|')==0:
73 if label.count('|')==0:
74 conf_data[label] = value
74 conf_data[label] = value
75 continue
75 continue
76
76
77 elif label.split('|')[0]<>'-1':
77 elif label.split('|')[0]<>'-1':
78 extras.append(label)
78 extras.append(label)
79 continue
79 continue
80
80
81 x, pk, name = label.split('|')
81 x, pk, name = label.split('|')
82
82
83 if name=='codes':
83 if name=='codes':
84 value = [s for s in value.split('\r\n') if s]
84 value = [s for s in value.split('\r\n') if s]
85
85
86 if pk in line_data:
86 if pk in line_data:
87 line_data[pk][name] = value
87 line_data[pk][name] = value
88 else:
88 else:
89 line_data[pk] = {name:value}
89 line_data[pk] = {name:value}
90
90
91 #update conf
91 #update conf
92 form = RCConfigurationForm(conf_data, instance=conf)
92 form = RCConfigurationForm(conf_data, instance=conf)
93
93
94 if form.is_valid():
94 if form.is_valid():
95
95
96 form.save()
96 form.save()
97
97
98 #update lines fields
98 #update lines fields
99 extras.sort()
99 extras.sort()
100 for label in extras:
100 for label in extras:
101 x, pk, name = label.split('|')
101 x, pk, name = label.split('|')
102 if pk not in line_data:
102 if pk not in line_data:
103 line_data[pk] = {}
103 line_data[pk] = {}
104 if 'params' not in line_data[pk]:
104 if 'params' not in line_data[pk]:
105 line_data[pk]['params'] = []
105 line_data[pk]['params'] = []
106 if len(line_data[pk]['params'])<int(x)+1:
106 if len(line_data[pk]['params'])<int(x)+1:
107 line_data[pk]['params'].append({})
107 line_data[pk]['params'].append({})
108 line_data[pk]['params'][int(x)][name] = float(request.POST[label])
108 line_data[pk]['params'][int(x)][name] = float(request.POST[label])
109
109
110 for pk, params in line_data.items():
110 for pk, params in line_data.items():
111 line = RCLine.objects.get(pk=pk)
111 line = RCLine.objects.get(pk=pk)
112 if line.line_type.name in ('windows', 'prog_pulses'):
112 if line.line_type.name in ('windows', 'prog_pulses'):
113 if 'params' not in params:
113 if 'params' not in params:
114 params['params'] = []
114 params['params'] = []
115 line.params = json.dumps(params)
115 line.params = json.dumps(params)
116 line.save()
116 line.save()
117
117
118 #update pulses field
118 #update pulses field
119 conf.update_pulses()
119 conf.update_pulses()
120
120
121 messages.success(request, 'RC Configuration successfully updated')
121 messages.success(request, 'RC Configuration successfully updated')
122
122
123 return redirect(conf.get_absolute_url())
123 return redirect(conf.get_absolute_url())
124
124
125 kwargs = {}
125 kwargs = {}
126 kwargs['dev_conf'] = conf
126 kwargs['dev_conf'] = conf
127 kwargs['form'] = form
127 kwargs['form'] = form
128 kwargs['rc_lines'] = lines
128 kwargs['rc_lines'] = lines
129 kwargs['edit'] = True
129 kwargs['edit'] = True
130
130
131 kwargs['title'] = 'RC Configuration'
131 kwargs['title'] = 'RC Configuration'
132 kwargs['suptitle'] = 'Edit'
132 kwargs['suptitle'] = 'Edit'
133 kwargs['button'] = 'Update'
133 kwargs['button'] = 'Update'
134 kwargs['previous'] = conf.get_absolute_url()
134 kwargs['previous'] = conf.get_absolute_url()
135
135
136 return render(request, 'rc_conf_edit.html', kwargs)
136 return render(request, 'rc_conf_edit.html', kwargs)
137
137
138
138
139 def add_line(request, conf_id, line_type_id=None, code_id=None):
139 def add_line(request, conf_id, line_type_id=None, code_id=None):
140
140
141 conf = get_object_or_404(RCConfiguration, pk=conf_id)
141 conf = get_object_or_404(RCConfiguration, pk=conf_id)
142
142
143 if request.method=='GET':
143 if request.method=='GET':
144 if line_type_id:
144 if line_type_id:
145 line_type = get_object_or_404(RCLineType, pk=line_type_id)
145 line_type = get_object_or_404(RCLineType, pk=line_type_id)
146
146
147 if code_id:
147 if code_id:
148 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id, 'code_id': code_id},
148 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id, 'code_id': code_id},
149 extra_fields=json.loads(line_type.params))
149 extra_fields=json.loads(line_type.params))
150 else:
150 else:
151 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id},
151 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id},
152 extra_fields=json.loads(line_type.params))
152 extra_fields=json.loads(line_type.params))
153 else:
153 else:
154 line_type = {'id':0}
154 line_type = {'id':0}
155 form = RCLineForm(initial={'rc_configuration':conf_id})
155 form = RCLineForm(initial={'rc_configuration':conf_id})
156
156
157 if request.method=='POST':
157 if request.method=='POST':
158
158
159 line_type = get_object_or_404(RCLineType, pk=line_type_id)
159 line_type = get_object_or_404(RCLineType, pk=line_type_id)
160 form = RCLineForm(request.POST,
160 form = RCLineForm(request.POST,
161 extra_fields=json.loads(line_type.params))
161 extra_fields=json.loads(line_type.params))
162
162
163 if form.is_valid():
163 if form.is_valid():
164 form.save()
164 form.save()
165 form.instance.update_pulses()
165 form.instance.update_pulses()
166 return redirect('url_edit_rc_conf', conf.id)
166 return redirect('url_edit_rc_conf', conf.id)
167
167
168 kwargs = {}
168 kwargs = {}
169 kwargs['form'] = form
169 kwargs['form'] = form
170 kwargs['title'] = 'RC Configuration'
170 kwargs['title'] = 'RC Configuration'
171 kwargs['suptitle'] = 'Add Line'
171 kwargs['suptitle'] = 'Add Line'
172 kwargs['button'] = 'Add'
172 kwargs['button'] = 'Add'
173 kwargs['previous'] = conf.get_absolute_url_edit()
173 kwargs['previous'] = conf.get_absolute_url_edit()
174 kwargs['dev_conf'] = conf
174 kwargs['dev_conf'] = conf
175 kwargs['line_type'] = line_type
175 kwargs['line_type'] = line_type
176
176
177 return render(request, 'rc_add_line.html', kwargs)
177 return render(request, 'rc_add_line.html', kwargs)
178
178
179 def edit_codes(request, conf_id, line_id, code_id=None):
179 def edit_codes(request, conf_id, line_id, code_id=None):
180
180
181 conf = get_object_or_404(RCConfiguration, pk=conf_id)
181 conf = get_object_or_404(RCConfiguration, pk=conf_id)
182 line = get_object_or_404(RCLine, pk=line_id)
182 line = get_object_or_404(RCLine, pk=line_id)
183 params = json.loads(line.params)
183 params = json.loads(line.params)
184
184
185 if request.method=='GET':
185 if request.method=='GET':
186 if code_id:
186 if code_id:
187 code = get_object_or_404(RCLineCode, pk=code_id)
187 code = get_object_or_404(RCLineCode, pk=code_id)
188 form = RCLineCodesForm(instance=code)
188 form = RCLineCodesForm(instance=code)
189 else:
189 else:
190 initial = {'code': params['code'],
190 initial = {'code': params['code'],
191 'codes': params['codes'] if 'codes' in params else [],
191 'codes': params['codes'] if 'codes' in params else [],
192 'number_of_codes': len(params['codes']) if 'codes' in params else 0,
192 'number_of_codes': len(params['codes']) if 'codes' in params else 0,
193 'bits_per_code': len(params['codes'][0]) if 'codes' in params else 0,
193 'bits_per_code': len(params['codes'][0]) if 'codes' in params else 0,
194 }
194 }
195 form = RCLineCodesForm(initial=initial)
195 form = RCLineCodesForm(initial=initial)
196
196
197 if request.method=='POST':
197 if request.method=='POST':
198 form = RCLineCodesForm(request.POST)
198 form = RCLineCodesForm(request.POST)
199 if form.is_valid():
199 if form.is_valid():
200 params['code'] = request.POST['code']
200 params['code'] = request.POST['code']
201 params['codes'] = [s for s in request.POST['codes'].split('\r\n') if s]
201 params['codes'] = [s for s in request.POST['codes'].split('\r\n') if s]
202 line.params = json.dumps(params)
202 line.params = json.dumps(params)
203 line.save()
203 line.save()
204 messages.success(request, 'Line: "%s" has been updated.' % line)
204 messages.success(request, 'Line: "%s" has been updated.' % line)
205 return redirect('url_edit_rc_conf', conf.id)
205 return redirect('url_edit_rc_conf', conf.id)
206
206
207 kwargs = {}
207 kwargs = {}
208 kwargs['form'] = form
208 kwargs['form'] = form
209 kwargs['title'] = line
209 kwargs['title'] = line
210 kwargs['suptitle'] = 'Edit'
210 kwargs['suptitle'] = 'Edit'
211 kwargs['button'] = 'Update'
211 kwargs['button'] = 'Update'
212 kwargs['dev_conf'] = conf
212 kwargs['dev_conf'] = conf
213 kwargs['previous'] = conf.get_absolute_url_edit()
213 kwargs['previous'] = conf.get_absolute_url_edit()
214 kwargs['line'] = line
214 kwargs['line'] = line
215
215
216 return render(request, 'rc_edit_codes.html', kwargs)
216 return render(request, 'rc_edit_codes.html', kwargs)
217
217
218 def add_subline(request, conf_id, line_id):
218 def add_subline(request, conf_id, line_id):
219
219
220 conf = get_object_or_404(RCConfiguration, pk=conf_id)
220 conf = get_object_or_404(RCConfiguration, pk=conf_id)
221 line = get_object_or_404(RCLine, pk=line_id)
221 line = get_object_or_404(RCLine, pk=line_id)
222
222
223 if request.method == 'POST':
223 if request.method == 'POST':
224 if line:
224 if line:
225 params = json.loads(line.params)
225 params = json.loads(line.params)
226 subparams = json.loads(line.line_type.params)
226 subparams = json.loads(line.line_type.params)
227 if 'params' in subparams:
227 if 'params' in subparams:
228 dum = {}
228 dum = {}
229 for key, value in subparams['params'].items():
229 for key, value in subparams['params'].items():
230 dum[key] = value['value']
230 dum[key] = value['value']
231 params['params'].append(dum)
231 params['params'].append(dum)
232 line.params = json.dumps(params)
232 line.params = json.dumps(params)
233 line.save()
233 line.save()
234 return redirect('url_edit_rc_conf', conf.id)
234 return redirect('url_edit_rc_conf', conf.id)
235
235
236 kwargs = {}
236 kwargs = {}
237
237
238 kwargs['title'] = 'Add new'
238 kwargs['title'] = 'Add new'
239 kwargs['suptitle'] = '%s to %s' % (line.line_type.name, line)
239 kwargs['suptitle'] = '%s to %s' % (line.line_type.name, line)
240
240
241 return render(request, 'confirm.html', kwargs)
241 return render(request, 'confirm.html', kwargs)
242
242
243 def remove_line(request, conf_id, line_id):
243 def remove_line(request, conf_id, line_id):
244
244
245 conf = get_object_or_404(RCConfiguration, pk=conf_id)
245 conf = get_object_or_404(RCConfiguration, pk=conf_id)
246 line = get_object_or_404(RCLine, pk=line_id)
246 line = get_object_or_404(RCLine, pk=line_id)
247
247
248 if request.method == 'POST':
248 if request.method == 'POST':
249 if line:
249 if line:
250 try:
250 try:
251 channel = line.channel
251 channel = line.channel
252 line.delete()
252 line.delete()
253 for ch in range(channel+1, RCLine.objects.filter(rc_configuration=conf).count()+1):
253 for ch in range(channel+1, RCLine.objects.filter(rc_configuration=conf).count()+1):
254 l = RCLine.objects.get(rc_configuration=conf, channel=ch)
254 l = RCLine.objects.get(rc_configuration=conf, channel=ch)
255 l.channel = l.channel-1
255 l.channel = l.channel-1
256 l.save()
256 l.save()
257 messages.success(request, 'Line: "%s" has been deleted.' % line)
257 messages.success(request, 'Line: "%s" has been deleted.' % line)
258 except:
258 except:
259 messages.error(request, 'Unable to delete line: "%s".' % line)
259 messages.error(request, 'Unable to delete line: "%s".' % line)
260
260
261 return redirect('url_edit_rc_conf', conf.id)
261 return redirect('url_edit_rc_conf', conf.id)
262
262
263 kwargs = {}
263 kwargs = {}
264
264
265 kwargs['object'] = line
265 kwargs['object'] = line
266 kwargs['delete_view'] = True
266 kwargs['delete_view'] = True
267 kwargs['title'] = 'Confirm delete'
267 kwargs['title'] = 'Confirm delete'
268 kwargs['previous'] = conf.get_absolute_url_edit()
268 kwargs['previous'] = conf.get_absolute_url_edit()
269 return render(request, 'confirm.html', kwargs)
269 return render(request, 'confirm.html', kwargs)
270
270
271
271
272 def remove_subline(request, conf_id, line_id, subline_id):
272 def remove_subline(request, conf_id, line_id, subline_id):
273
273
274 conf = get_object_or_404(RCConfiguration, pk=conf_id)
274 conf = get_object_or_404(RCConfiguration, pk=conf_id)
275 line = get_object_or_404(RCLine, pk=line_id)
275 line = get_object_or_404(RCLine, pk=line_id)
276
276
277 if request.method == 'POST':
277 if request.method == 'POST':
278 if line:
278 if line:
279 params = json.loads(line.params)
279 params = json.loads(line.params)
280 params['params'].remove(params['params'][int(subline_id)-1])
280 params['params'].remove(params['params'][int(subline_id)-1])
281 line.params = json.dumps(params)
281 line.params = json.dumps(params)
282 line.save()
282 line.save()
283
283
284 return redirect('url_edit_rc_conf', conf.id)
284 return redirect('url_edit_rc_conf', conf.id)
285
285
286 kwargs = {}
286 kwargs = {}
287
287
288 kwargs['object'] = line
288 kwargs['object'] = line
289 kwargs['object_name'] = line.line_type.name
289 kwargs['object_name'] = line.line_type.name
290 kwargs['delete_view'] = True
290 kwargs['delete_view'] = True
291 kwargs['title'] = 'Confirm delete'
291 kwargs['title'] = 'Confirm delete'
292
292
293 return render(request, 'confirm.html', kwargs)
293 return render(request, 'confirm.html', kwargs)
294
294
295
295
296 def update_lines_position(request, conf_id):
296 def update_lines_position(request, conf_id):
297
297
298 conf = get_object_or_404(RCConfiguration, pk=conf_id)
298 conf = get_object_or_404(RCConfiguration, pk=conf_id)
299
299
300 if request.method=='POST':
300 if request.method=='POST':
301 ch = 0
301 ch = 0
302 for item in request.POST['items'].split('&'):
302 for item in request.POST['items'].split('&'):
303 line = RCLine.objects.get(pk=item.split('=')[-1])
303 line = RCLine.objects.get(pk=item.split('=')[-1])
304 line.channel = ch
304 line.channel = ch
305 line.save()
305 line.save()
306 ch += 1
306 ch += 1
307
307
308 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
308 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
309
309
310 for line in lines:
310 for line in lines:
311 params = json.loads(line.params)
311 params = json.loads(line.params)
312 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
312 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
313
313
314 if 'params' in params:
314 if 'params' in params:
315 line.subform = True
315 line.subform = True
316 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
316 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
317
317
318 html = render(request, 'rc_lines.html', {'dev_conf':conf, 'rc_lines':lines, 'edit':True})
318 html = render(request, 'rc_lines.html', {'dev_conf':conf, 'rc_lines':lines, 'edit':True})
319 data = {'html': html.content}
319 data = {'html': html.content}
320
320
321 return HttpResponse(json.dumps(data), content_type="application/json")
321 return HttpResponse(json.dumps(data), content_type="application/json")
322 return redirect('url_edit_rc_conf', conf.id)
322 return redirect('url_edit_rc_conf', conf.id)
323
323
324
324
325 def import_file(request, conf_id):
325 def import_file(request, conf_id):
326
326
327 conf = get_object_or_404(RCConfiguration, pk=conf_id)
327 conf = get_object_or_404(RCConfiguration, pk=conf_id)
328 if request.method=='POST':
328 if request.method=='POST':
329 form = RCImportForm(request.POST, request.FILES)
329 form = RCImportForm(request.POST, request.FILES)
330 if form.is_valid():
330 if form.is_valid():
331 try:
331 try:
332 conf.update_from_file(request.FILES['file_name'])
332 conf.update_from_file(request.FILES['file_name'])
333 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
333 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
334 return redirect(conf.get_absolute_url_edit())
334 return redirect(conf.get_absolute_url_edit())
335
335
336 except Exception as e:
336 except Exception as e:
337 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], e))
337 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], e))
338
338
339 else:
339 else:
340 messages.warning(request, 'Your current configuration will be replaced')
340 messages.warning(request, 'Your current configuration will be replaced')
341 form = RCImportForm()
341 form = RCImportForm()
342
342
343 kwargs = {}
343 kwargs = {}
344 kwargs['form'] = form
344 kwargs['form'] = form
345 kwargs['title'] = 'RC Configuration'
345 kwargs['title'] = 'RC Configuration'
346 kwargs['suptitle'] = 'Import file'
346 kwargs['suptitle'] = 'Import file'
347 kwargs['button'] = 'Upload'
347 kwargs['button'] = 'Upload'
348 kwargs['previous'] = conf.get_absolute_url()
348 kwargs['previous'] = conf.get_absolute_url()
349
349
350 return render(request, 'rc_import.html', kwargs)
350 return render(request, 'rc_import.html', kwargs)
351
351
352
352
353 def plot_pulses(request, conf_id):
353 def plot_pulses(request, conf_id):
354
354
355 conf = get_object_or_404(RCConfiguration, pk=conf_id)
355 conf = get_object_or_404(RCConfiguration, pk=conf_id)
356
356
357 script, div = conf.plot_pulses()
357 script, div = conf.plot_pulses()
358
358
359 kwargs = {}
359 kwargs = {}
360
360
361 kwargs['title'] = 'RC Pulses'
361 kwargs['title'] = 'RC Pulses'
362 kwargs['suptitle'] = conf.name
362 kwargs['suptitle'] = conf.name
363 kwargs['div'] = mark_safe(div)
363 kwargs['div'] = mark_safe(div)
364 kwargs['script'] = mark_safe(script)
364 kwargs['script'] = mark_safe(script)
365 kwargs['units'] = conf.km2unit
366 kwargs['kms'] = 1/conf.km2unit
365
367
366 if 'json' in request.GET:
368 if 'json' in request.GET:
367 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
369 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
368 else:
370 else:
369 return render(request, 'rc_pulses.html', kwargs)
371 return render(request, 'rc_pulses.html', kwargs)
370
372
@@ -1,275 +1,279
1
1
2 import ast
2 import ast
3 import json
3 import json
4 from itertools import chain
4 from itertools import chain
5
5
6 from django import forms
6 from django import forms
7 from django.utils.safestring import mark_safe
7 from django.utils.safestring import mark_safe
8 from django.utils.encoding import force_unicode
8 from django.utils.encoding import force_unicode
9 from django.utils.html import conditional_escape
9 from django.utils.html import conditional_escape
10
10
11
11
12 class KmUnitWidget(forms.widgets.TextInput):
12 class KmUnitWidget(forms.widgets.TextInput):
13
13
14 def render(self, label, value, attrs=None):
14 def render(self, label, value, attrs=None):
15
15
16 if isinstance(value, (int, float)):
16 if isinstance(value, (int, float)):
17 unit = int(value*attrs['km2unit'])
17 unit = int(value*attrs['km2unit'])
18 elif isinstance(value, basestring):
18 elif isinstance(value, basestring):
19 units = []
19 units = []
20 values = [s for s in value.split(',') if s]
20 values = [s for s in value.split(',') if s]
21 for val in values:
21 for val in values:
22 units.append('{0:.0f}'.format(float(val)*attrs['km2unit']))
22 units.append('{0:.0f}'.format(float(val)*attrs['km2unit']))
23
23
24 unit = ','.join(units)
24 unit = ','.join(units)
25
25
26 disabled = 'disabled' if attrs.get('disabled', False) else ''
26 disabled = 'disabled' if attrs.get('disabled', False) else ''
27 name = attrs.get('name', label)
27 name = attrs.get('name', label)
28
28
29 if 'line' in attrs:
29 if 'line' in attrs:
30 label += '_{0}'.format(attrs['line'].pk)
30 label += '_{0}'.format(attrs['line'].pk)
31
31
32 html = '<div class="col-md-12 col-no-padding"><div class="col-md-5 col-no-padding"><input type="text" {0} class="form-control" id="id_{1}" name="{2}" value="{3}"></div><div class="col-md-1 col-no-padding">Km</div><div class="col-md-5 col-no-padding"><input type="text" {4} class="form-control" id="id_{5}_unit" value="{6}"></div><div class="col-md-1 col-no-padding">Units</div></div><br>'.format(disabled, label, name, value, disabled, label, unit)
32 html = '''<div class="col-md-12 col-no-padding">
33 <div class="col-md-5 col-no-padding"><input type="number" step="any" {0} class="form-control" id="id_{1}" name="{2}" value="{3}"></div>
34 <div class="col-md-1 col-no-padding">Km</div>
35 <div class="col-md-5 col-no-padding"><input type="number" {4} class="form-control" id="id_{5}_unit" value="{6}"></div>
36 <div class="col-md-1 col-no-padding">Units</div></div><br>'''.format(disabled, label, name, value, disabled, label, unit)
33
37
34 script = '''<script type="text/javascript">
38 script = '''<script type="text/javascript">
35 $(document).ready(function () {{
39 $(document).ready(function () {{
36
40
37 km_fields.push("id_{label}");
41 km_fields.push("id_{label}");
38 unit_fields.push("id_{label}_unit");
42 unit_fields.push("id_{label}_unit");
39
43
40 $("#id_{label}").change(function() {{
44 $("#id_{label}").change(function() {{
41 $("#id_{label}_unit").val(Math.round(str2unit($(this).val())));
45 $("#id_{label}_unit").val(Math.round(str2unit($(this).val())));
42 $("#id_{label}").val(str2km($("#id_{label}_unit").val()));
46 $("#id_{label}").val(str2km($("#id_{label}_unit").val()));
43 }});
47 }});
44 $("#id_{label}_unit").change(function() {{
48 $("#id_{label}_unit").change(function() {{
45 $(this).val(Math.round(parseFloat($(this).val())));
49 $(this).val(Math.round(parseFloat($(this).val())));
46 $("#id_{label}").val(str2km($(this).val()));
50 $("#id_{label}").val(str2km($(this).val()));
47 }});
51 }});
48 }});
52 }});
49 </script>'''.format(label=label)
53 </script>'''.format(label=label)
50
54
51 if disabled:
55 if disabled:
52 return mark_safe(html)
56 return mark_safe(html)
53 else:
57 else:
54 return mark_safe(html+script)
58 return mark_safe(html+script)
55
59
56
60
57 class UnitKmWidget(forms.widgets.TextInput):
61 class UnitKmWidget(forms.widgets.TextInput):
58
62
59 def render(self, label, value, attrs=None):
63 def render(self, label, value, attrs=None):
60
64
61 if isinstance(value, (int, float)):
65 if isinstance(value, (int, float)):
62 km = value/attrs['km2unit']
66 km = value/attrs['km2unit']
63 elif isinstance(value, basestring):
67 elif isinstance(value, basestring):
64 kms = []
68 kms = []
65 values = [s for s in value.split(',') if s]
69 values = [s for s in value.split(',') if s]
66 for val in values:
70 for val in values:
67 kms.append('{0:.0f}'.format(float(val)/attrs['km2unit']))
71 kms.append('{0:.0f}'.format(float(val)/attrs['km2unit']))
68
72
69 km = ','.join(kms)
73 km = ','.join(kms)
70
74
71 disabled = 'disabled' if attrs.get('disabled', False) else ''
75 disabled = 'disabled' if attrs.get('disabled', False) else ''
72 name = attrs.get('name', label)
76 name = attrs.get('name', label)
73
77
74 if 'line' in attrs:
78 if 'line' in attrs:
75 label += '_{0}'.format(attrs['line'].pk)
79 label += '_{0}'.format(attrs['line'].pk)
76
80
77 html = '''<div class="col-md-12 col-no-padding">
81 html = '''<div class="col-md-12 col-no-padding">
78 <div class="col-md-5 col-no-padding"><input type="number" {0} class="form-control" id="id_{1}_unit" name="{2}" value="{3}"></div>
82 <div class="col-md-5 col-no-padding"><input type="number" {0} class="form-control" id="id_{1}_unit" name="{2}" value="{3}"></div>
79 <div class="col-md-1 col-no-padding">Units</div>
83 <div class="col-md-1 col-no-padding">Units</div>
80 <div class="col-md-5 col-no-padding"><input type="number" {4} class="form-control" id="id_{5}" value="{6}"></div>
84 <div class="col-md-5 col-no-padding"><input type="number" step="any" {4} class="form-control" id="id_{5}" value="{6}"></div>
81 <div class="col-md-1 col-no-padding">Km</div></div>'''.format(disabled, label, name, value, disabled, label, km)
85 <div class="col-md-1 col-no-padding">Km</div></div>'''.format(disabled, label, name, value, disabled, label, km)
82
86
83 script = '''<script type="text/javascript">
87 script = '''<script type="text/javascript">
84 $(document).ready(function () {{
88 $(document).ready(function () {{
85
89
86 km_fields.push("id_{label}");
90 km_fields.push("id_{label}");
87 unit_fields.push("id_{label}_unit");
91 unit_fields.push("id_{label}_unit");
88
92
89 $("#id_{label}").change(function() {{
93 $("#id_{label}").change(function() {{
90 $("#id_{label}_unit").val(str2unit($(this).val()));
94 $("#id_{label}_unit").val(str2unit($(this).val()));
91 }});
95 }});
92 $("#id_{label}_unit").change(function() {{
96 $("#id_{label}_unit").change(function() {{
93 $("#id_{label}").val(str2km($(this).val()));
97 $("#id_{label}").val(str2km($(this).val()));
94 }});
98 }});
95 }});
99 }});
96 </script>'''.format(label=label)
100 </script>'''.format(label=label)
97
101
98 if disabled:
102 if disabled:
99 return mark_safe(html)
103 return mark_safe(html)
100 else:
104 else:
101 return mark_safe(html+script)
105 return mark_safe(html+script)
102
106
103
107
104 class KmUnitHzWidget(forms.widgets.TextInput):
108 class KmUnitHzWidget(forms.widgets.TextInput):
105
109
106 def render(self, label, value, attrs=None):
110 def render(self, label, value, attrs=None):
107
111
108 unit = float(value)*attrs['km2unit']
112 unit = float(value)*attrs['km2unit']
109 if unit%10==0:
113 if unit%10==0:
110 unit = int(unit)
114 unit = int(unit)
111 hz = 150000*float(value)**-1
115 hz = 150000*float(value)**-1
112
116
113 disabled = 'disabled' if attrs.get('disabled', False) else ''
117 disabled = 'disabled' if attrs.get('disabled', False) else ''
114 name = attrs.get('name', label)
118 name = attrs.get('name', label)
115
119
116 if 'line' in attrs:
120 if 'line' in attrs:
117 label += '_{0}'.format(attrs['line'].pk)
121 label += '_{0}'.format(attrs['line'].pk)
118
122
119 html = '''<div class="col-md-12 col-no-padding">
123 html = '''<div class="col-md-12 col-no-padding">
120 <div class="col-md-3 col-no-padding"><input type="number" {0} class="form-control" id="id_{1}" name="{2}" value="{3}"></div>
124 <div class="col-md-3 col-no-padding"><input type="number" step="any" {0} class="form-control" id="id_{1}" name="{2}" value="{3}"></div>
121 <div class="col-md-1 col-no-padding">Km</div>
125 <div class="col-md-1 col-no-padding">Km</div>
122 <div class="col-md-3 col-no-padding"><input type="number" {4} class="form-control" id="id_{1}_unit" value="{5}"></div>
126 <div class="col-md-3 col-no-padding"><input type="number" {4} class="form-control" id="id_{1}_unit" value="{5}"></div>
123 <div class="col-md-1 col-no-padding">Units</div>
127 <div class="col-md-1 col-no-padding">Units</div>
124 <div class="col-md-3 col-no-padding"><input type="number" {4} class="form-control" id="id_{1}_hz" value="{6}"></div>
128 <div class="col-md-3 col-no-padding"><input type="number" step="any" {4} class="form-control" id="id_{1}_hz" value="{6}"></div>
125 <div class="col-md-1 col-no-padding">Hz</div>
129 <div class="col-md-1 col-no-padding">Hz</div>
126 </div>'''.format(disabled, label, name, value, disabled, unit, hz)
130 </div>'''.format(disabled, label, name, value, disabled, unit, hz)
127
131
128 script = '''<script type="text/javascript">
132 script = '''<script type="text/javascript">
129 $(document).ready(function () {{
133 $(document).ready(function () {{
130 km_fields.push("id_{label}");
134 km_fields.push("id_{label}");
131 unit_fields.push("id_{label}_unit");
135 unit_fields.push("id_{label}_unit");
132 $("#id_{label}").change(function() {{
136 $("#id_{label}").change(function() {{
133 $("#id_{label}_unit").val(str2unit($(this).val()));
137 $("#id_{label}_unit").val(str2unit($(this).val()));
134 $("#id_{label}_hz").val(str2hz($(this).val()));
138 $("#id_{label}_hz").val(str2hz($(this).val()));
135 updateDc();
139 updateDc();
136 }});
140 }});
137 $("#id_{label}_unit").change(function() {{
141 $("#id_{label}_unit").change(function() {{
138 $(this).val(Math.round(parseFloat($(this).val())/10)*10);
142 $(this).val(Math.round(parseFloat($(this).val())/10)*10);
139 $("#id_{label}").val(str2km($(this).val()));
143 $("#id_{label}").val(str2km($(this).val()));
140 $("#id_{label}_hz").val(str2hz($("#id_{label}").val()));
144 $("#id_{label}_hz").val(str2hz($("#id_{label}").val()));
141 updateDc();
145 updateDc();
142 }});
146 }});
143 $("#id_{label}_hz").change(function() {{
147 $("#id_{label}_hz").change(function() {{
144 $("#id_{label}").val(str2hz($(this).val()));
148 $("#id_{label}").val(str2hz($(this).val()));
145 $("#id_{label}_unit").val(str2unit($("#id_{label}").val()));
149 $("#id_{label}_unit").val(str2unit($("#id_{label}").val()));
146 updateDc();
150 updateDc();
147 }});
151 }});
148 }});
152 }});
149 </script>'''.format(label=label)
153 </script>'''.format(label=label)
150
154
151 if disabled:
155 if disabled:
152 return mark_safe(html)
156 return mark_safe(html)
153 else:
157 else:
154 return mark_safe(html+script)
158 return mark_safe(html+script)
155
159
156
160
157 class KmUnitDcWidget(forms.widgets.TextInput):
161 class KmUnitDcWidget(forms.widgets.TextInput):
158
162
159 def render(self, label, value, attrs=None):
163 def render(self, label, value, attrs=None):
160
164
161 unit = int(float(value)*attrs['km2unit'])
165 unit = int(float(value)*attrs['km2unit'])
162
166
163 disabled = 'disabled' if attrs.get('disabled', False) else ''
167 disabled = 'disabled' if attrs.get('disabled', False) else ''
164 name = attrs.get('name', label)
168 name = attrs.get('name', label)
165
169
166 label += '_{0}'.format(attrs['line'].pk)
170 label += '_{0}'.format(attrs['line'].pk)
167
171
168 dc = float(json.loads(attrs['line'].params)['pulse_width'])*100/attrs['line'].rc_configuration.ipp
172 dc = float(json.loads(attrs['line'].params)['pulse_width'])*100/attrs['line'].rc_configuration.ipp
169
173
170 html = '''<div class="col-md-12 col-no-padding">
174 html = '''<div class="col-md-12 col-no-padding">
171 <div class="col-md-3 col-no-padding"><input type="number" {0} class="form-control" id="id_{1}" name="{2}" value="{3}"></div>
175 <div class="col-md-3 col-no-padding"><input type="number" step="any" {0} class="form-control" id="id_{1}" name="{2}" value="{3}"></div>
172 <div class="col-md-1 col-no-padding">Km</div>
176 <div class="col-md-1 col-no-padding">Km</div>
173 <div class="col-md-3 col-no-padding"><input type="number" {4} class="form-control" id="id_{1}_unit" value="{5}"></div>
177 <div class="col-md-3 col-no-padding"><input type="number" {4} class="form-control" id="id_{1}_unit" value="{5}"></div>
174 <div class="col-md-1 col-no-padding">Units</div>
178 <div class="col-md-1 col-no-padding">Units</div>
175 <div class="col-md-3 col-no-padding"><input type="number" {4} class="form-control" id="id_{1}_dc" value="{6}"></div>
179 <div class="col-md-3 col-no-padding"><input type="number" step="any" {4} class="form-control" id="id_{1}_dc" value="{6}"></div>
176 <div class="col-md-1 col-no-padding">DC[%]</div>
180 <div class="col-md-1 col-no-padding">DC[%]</div>
177 </div>'''.format(disabled, label, name, value, disabled, unit, dc)
181 </div>'''.format(disabled, label, name, value, disabled, unit, dc)
178
182
179 script = '''<script type="text/javascript">
183 script = '''<script type="text/javascript">
180 $(document).ready(function () {{
184 $(document).ready(function () {{
181 km_fields.push("id_{label}");
185 km_fields.push("id_{label}");
182 unit_fields.push("id_{label}_unit");
186 unit_fields.push("id_{label}_unit");
183 dc_fields.push("id_{label}");
187 dc_fields.push("id_{label}");
184 $("#id_{label}").change(function() {{
188 $("#id_{label}").change(function() {{
185 $("#id_{label}_unit").val(str2unit($(this).val()));
189 $("#id_{label}_unit").val(str2unit($(this).val()));
186 $("#id_{label}_dc").val(str2dc($("#id_{label}").val()));
190 $("#id_{label}_dc").val(str2dc($("#id_{label}").val()));
187 }});
191 }});
188 $("#id_{label}_unit").change(function() {{
192 $("#id_{label}_unit").change(function() {{
189 $("#id_{label}").val(str2km($(this).val()));
193 $("#id_{label}").val(str2km($(this).val()));
190 $("#id_{label}_dc").val(str2dc($("#id_{label}").val()));
194 $("#id_{label}_dc").val(str2dc($("#id_{label}").val()));
191 }});
195 }});
192
196
193 $("#id_{label}_dc").change(function() {{
197 $("#id_{label}_dc").change(function() {{
194 $("#id_{label}").val(parseFloat($(this).val())*100/parseFloat($("#id_ipp").val()));
198 $("#id_{label}").val(parseFloat($(this).val())*100/parseFloat($("#id_ipp").val()));
195 $("#id_{label}_unit").val(str2unit($("#id_{label}").val()));
199 $("#id_{label}_unit").val(str2unit($("#id_{label}").val()));
196 }});
200 }});
197 }});
201 }});
198 </script>'''.format(label=label)
202 </script>'''.format(label=label)
199
203
200 if disabled:
204 if disabled:
201 return mark_safe(html)
205 return mark_safe(html)
202 else:
206 else:
203 return mark_safe(html+script)
207 return mark_safe(html+script)
204
208
205
209
206 class DefaultWidget(forms.widgets.TextInput):
210 class DefaultWidget(forms.widgets.TextInput):
207
211
208 def render(self, label, value, attrs=None):
212 def render(self, label, value, attrs=None):
209
213
210 disabled = 'disabled' if attrs.get('disabled', False) else ''
214 disabled = 'disabled' if attrs.get('disabled', False) else ''
211 name = attrs.get('name', label)
215 name = attrs.get('name', label)
212
216
213 html = '<div class="col-md-12 col-no-padding"><div class="col-md-5 col-no-padding"><input {0} type="text" class="form-control" id="id_{1}" name="{2}" value="{3}"></div></div>'.format(disabled, label, name, value)
217 html = '<div class="col-md-12 col-no-padding"><div class="col-md-5 col-no-padding"><input {0} type="text" class="form-control" id="id_{1}" name="{2}" value="{3}"></div></div>'.format(disabled, label, name, value)
214
218
215 return mark_safe(html)
219 return mark_safe(html)
216
220
217
221
218 class HiddenWidget(forms.widgets.HiddenInput):
222 class HiddenWidget(forms.widgets.HiddenInput):
219
223
220 def render(self, label, value, attrs=None):
224 def render(self, label, value, attrs=None):
221
225
222 disabled = 'disabled' if attrs.get('disabled', False) else ''
226 disabled = 'disabled' if attrs.get('disabled', False) else ''
223 name = self.attrs.get('name', label)
227 name = self.attrs.get('name', label)
224
228
225 html = '<input {0} type="hidden" class="form-control" id="id_{1}" name="{2}" value="{3}">'.format(disabled, label, name, value)
229 html = '<input {0} type="hidden" class="form-control" id="id_{1}" name="{2}" value="{3}">'.format(disabled, label, name, value)
226
230
227 return mark_safe(html)
231 return mark_safe(html)
228
232
229
233
230 class CodesWidget(forms.widgets.Textarea):
234 class CodesWidget(forms.widgets.Textarea):
231
235
232 def render(self, label, value, attrs=None):
236 def render(self, label, value, attrs=None):
233
237
234 disabled = 'disabled' if attrs.get('disabled', False) else ''
238 disabled = 'disabled' if attrs.get('disabled', False) else ''
235 name = attrs.get('name', label)
239 name = attrs.get('name', label)
236
240
237 if '[' in value:
241 if '[' in value:
238 value = ast.literal_eval(value)
242 value = ast.literal_eval(value)
239
243
240 if isinstance(value, list):
244 if isinstance(value, list):
241 codes = '\r\n'.join(value)
245 codes = '\r\n'.join(value)
242 else:
246 else:
243 codes = value
247 codes = value
244
248
245 html = '<textarea rows="5" {0} class="form-control" id="id_{1}" name="{2}" style="white-space:nowrap; overflow:scroll;">{3}</textarea>'.format(disabled, label, name, codes)
249 html = '<textarea rows="5" {0} class="form-control" id="id_{1}" name="{2}" style="white-space:nowrap; overflow:scroll;">{3}</textarea>'.format(disabled, label, name, codes)
246
250
247 return mark_safe(html)
251 return mark_safe(html)
248
252
249 class HCheckboxSelectMultiple(forms.CheckboxSelectMultiple):
253 class HCheckboxSelectMultiple(forms.CheckboxSelectMultiple):
250
254
251 def render(self, name, value, attrs=None, choices=()):
255 def render(self, name, value, attrs=None, choices=()):
252
256
253 if value is None: value = []
257 if value is None: value = []
254 has_id = attrs and 'id' in attrs
258 has_id = attrs and 'id' in attrs
255 final_attrs = self.build_attrs(attrs, name=name)
259 final_attrs = self.build_attrs(attrs, name=name)
256 output = [u'<br><ul>']
260 output = [u'<br><ul>']
257 # Normalize to strings
261 # Normalize to strings
258 str_values = set([force_unicode(v) for v in value])
262 str_values = set([force_unicode(v) for v in value])
259 for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
263 for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
260 # If an ID attribute was given, add a numeric index as a suffix,
264 # If an ID attribute was given, add a numeric index as a suffix,
261 # so that the checkboxes don't all have the same ID attribute.
265 # so that the checkboxes don't all have the same ID attribute.
262 if has_id:
266 if has_id:
263 final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i))
267 final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i))
264 label_for = u' for="%s"' % final_attrs['id']
268 label_for = u' for="%s"' % final_attrs['id']
265 else:
269 else:
266 label_for = ''
270 label_for = ''
267
271
268 cb = forms.CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
272 cb = forms.CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
269 option_value = force_unicode(option_value)
273 option_value = force_unicode(option_value)
270 rendered_cb = cb.render(name, option_value)
274 rendered_cb = cb.render(name, option_value)
271 option_label = conditional_escape(force_unicode(option_label))
275 option_label = conditional_escape(force_unicode(option_label))
272 output.append(u'<span><label%s>%s %s</label></span>' % (label_for, rendered_cb, option_label))
276 output.append(u'<span><label%s>%s %s</label></span>' % (label_for, rendered_cb, option_label))
273 output.append(u'</div><br>')
277 output.append(u'</div><br>')
274 return mark_safe(u'\n'.join(output))
278 return mark_safe(u'\n'.join(output))
275 No newline at end of file
279
General Comments 0
You need to be logged in to leave comments. Login now