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