##// END OF EJS Templates
Actualizacion de la app RC a python3 y django 2, antes del merge con cambios
gonzalesluisfrancisco -
r341:cb29d2ed7f9e merge
parent child
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -0,0 +1,463
1 {% extends "dev_conf_edit.html" %}
2 {% load bootstrap4 %}
3 {% load static %}
4 {% load main_tags %}
5
6 {% block dds_rest%}
7
8 {% bootstrap_field form.template layout='horizontal' size='medium' %}
9 {% bootstrap_field form.device layout='horizontal' size='medium' %}
10 {% bootstrap_field form.label layout='horizontal' size='medium' %}
11 {% bootstrap_field form.experiment layout='horizontal' size='medium' %}
12
13 {% bootstrap_field form.clock layout='horizontal' size='medium' %}
14 {% bootstrap_field form.multiplier layout='horizontal' size='medium' %}
15
16 <div style="display: flex; justify-content: flex-end">
17 <div class="form-check">
18 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_fA" value="" >Mostrar Decimal</label>
19 </div>
20 </div>
21 {% bootstrap_field form.frequencyA_Mhz layout='horizontal' size='medium' %}
22 <div id='id_row_fAbin'>
23 {% bootstrap_field form.frequencyA layout='horizontal' size='medium' %}
24 <div style="display: flex; justify-content: flex-end">
25 <small type="text" id="id_aux_fAbin" class="form-text text-muted">1000 0000 </small>
26 </div>
27 <br>
28 </div>
29
30 <div style="display: flex; justify-content: flex-end">
31 <div class="form-check">
32 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_fB" value="" >Mostrar Decimal</label>
33 </div>
34 </div>
35 {% bootstrap_field form.frequencyB_Mhz layout='horizontal' size='medium' %}
36 <div id='id_row_fBbin'>
37 {% bootstrap_field form.frequencyB layout='horizontal' size='medium' %}
38 <div style="display: flex; justify-content: flex-end">
39 <small type="text" id="id_aux_fBbin" class="form-text text-muted">1000 0000 </small>
40 </div>
41 <br>
42 </div>
43
44 <div style="display: flex; justify-content: flex-end">
45 <div class="form-check">
46 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_df" value="" >Mostrar Decimal</label>
47 </div>
48 </div>
49 {% bootstrap_field form.delta_frequency_Mhz layout='horizontal' size='medium' %}
50 <div id='id_row_dfbin'>
51 {% bootstrap_field form.delta_frequency layout='horizontal' size='medium' %}
52 <div style="display: flex; justify-content: flex-end">
53 <small type="text" id="id_aux_deltabin" class="form-text text-muted">1000 0000 </small>
54 </div>
55 <br>
56 </div>
57
58 <div style="display: flex; justify-content: flex-end">
59 <div class="form-check">
60 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_ramp" value="" >Mostrar Decimal</label>
61 </div>
62 </div>
63 <div class="form-group row">
64 <label class="col-md-3 col-form-label" for="id_ramp_rate_clock_us">Ramp rate clock(us)</label>
65 <div class="col-md-9">
66 <input type="number" name="ramp_rate_clock_us" step="1e-16" class="form-control" placeHolder="Ramp rate clock(us)" title id="id_ramp_rate_clock_us">
67 </div>
68 </div>
69 <div id='id_row_rampbin'>
70 {% bootstrap_field form.ramp_rate_clock_Mhz layout='horizontal' size='medium' %}
71 {% bootstrap_field form.ramp_rate_clock layout='horizontal' size='medium' %}
72 <div style="display: flex; justify-content: flex-end">
73 <small type="text" id="id_aux_rampbin" class="form-text text-muted">1000 0000 </small>
74 </div>
75 <br>
76 </div>
77
78 <div style="display: flex; justify-content: flex-end">
79 <div class="form-check">
80 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_phaseA" value="" >Mostrar Decimal</label>
81 </div>
82 </div>
83 {% bootstrap_field form.phaseA_degrees layout='horizontal' size='medium' %}
84 <div id='id_row_phaseA'>
85 <div style="display: flex; justify-content: flex-end">
86 <small type="text" id="id_aux_phaseAdec" class="form-text text-muted">9282 </small>
87 </div>
88 <div style="display: flex; justify-content: flex-end">
89 <small type="text" id="id_aux_phaseAbin" class="form-text text-muted">1000 0000 </small>
90 </div>
91 <br>
92 </div>
93
94 <div style="display: flex; justify-content: flex-end">
95 <div class="form-check">
96 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_phaseB" value="" >Mostrar Decimal</label>
97 </div>
98 </div>
99 {% bootstrap_field form.phaseB_degrees layout='horizontal' size='medium' %}
100 <div id='id_row_phaseB'>
101 <div style="display: flex; justify-content: flex-end">
102 <small type="text" id="id_aux_phaseBdec" class="form-text text-muted">9876 </small>
103 </div>
104 <div style="display: flex; justify-content: flex-end">
105 <small type="text" id="id_aux_phaseBbin" class="form-text text-muted">1000 0000 </small>
106 </div>
107 <br>
108 </div>
109
110 {% bootstrap_field form.modulation layout='horizontal' size='medium' %}
111 {% bootstrap_field form.amplitude_enabled layout='horizontal' size='medium' %}
112
113 {% bootstrap_field form.amplitudeI layout='horizontal' size='medium' %}
114 {% bootstrap_field form.amplitudeQ layout='horizontal' size='medium' %}
115
116
117 {% endblock %}
118
119 {% block extra-js%}
120 <script src="{% static 'js/dds_conversion.js' %}"></script>
121 <script type="text/javascript">
122 $("#id_row_fAbin").hide();
123 $("#id_chkbin_fA").on('change', function() {
124 hidefA();
125 });
126
127 $("#id_row_fBbin").hide();
128 $("#id_chkbin_fB").on('change', function() {
129 hidefB();
130 });
131
132 $("#id_row_dfbin").hide();
133 $("#id_chkbin_df").on('change', function() {
134 hidedf();
135 });
136
137 $("#id_row_rampbin").hide();
138 $("#id_chkbin_ramp").on('change', function() {
139 hideramp();
140 });
141
142 $("#id_row_phaseA").hide();
143 $("#id_chkbin_phaseA").on('change', function() {
144 hidephaseA();
145 });
146
147 $("#id_row_phaseB").hide();
148 $("#id_chkbin_phaseB").on('change', function() {
149 hidephaseB();
150 });
151
152 $("#id_clock").on('change', function() {
153 updateFrequencies();
154 });
155
156 $("#id_multiplier").on('change', function() {
157 updateFrequencies();
158 });
159
160 $("#id_frequencyA_Mhz").on('change', function() {
161 updateBinaryFrequencies();
162 });
163
164 $("#id_frequencyA").on('change', function() {
165 updateFrequencies();
166 });
167
168 $("#id_frequencyB_Mhz").on('change', function() {
169 updateBinaryFrequencies();
170 });
171
172 $("#id_frequencyB").on('change', function() {
173 updateFrequencies();
174 });
175
176 $("#id_delta_frequency").on('change', function() {
177 updateFrequencyDelta();
178 });
179
180 $("#id_delta_frequency_Mhz").on('change', function() {
181 updateBinaryFrequencyDelta();
182 });
183
184 $("#id_ramp_rate_clock").on('change', function() {
185 updateFrequencyRamp();
186 });
187
188 $("#id_ramp_rate_clock_us").on('change', function() {
189 updateFrequencyMhzRamp();
190 });
191
192 $("#id_ramp_rate_clock_Mhz").on('change', function() {
193 updateBinaryFrequencyRamp();
194 });
195
196 $("#id_phaseA_degrees").on('change', function() {
197 updatephaseAbindec();
198 });
199
200 $("#id_phaseB_degrees").on('change', function() {
201 updatephaseBbindec();
202 });
203
204 function updateBinaryFrequencies() {
205
206 var clock = $("#id_clock").val();
207 var multiplier = $("#id_multiplier").val();
208 var freq = $("#id_frequencyA_Mhz").val();
209 var freq_mod = $("#id_frequencyB_Mhz").val();
210
211 var mclock = clock*multiplier;
212
213 var freq_bin = freq2Binary(mclock, freq);
214 var freq_mod_bin = freq2Binary(mclock, freq_mod);
215
216 $("#id_frequencyA").val(freq_bin);
217 $("#id_frequencyB").val(freq_mod_bin);
218
219 freq = binary2Freq(mclock, freq_bin);
220 freq_mod = binary2Freq(mclock, freq_mod_bin);
221
222 $("#id_frequencyA_Mhz").val(freq);
223 $("#id_frequencyB_Mhz").val(freq_mod);
224
225 }
226
227 function updateFrequencies() {
228 console.log("Ingreso a updateFrequencies");
229 var clock = $("#id_clock").val();
230 var multiplier = $("#id_multiplier").val();
231 var freq_bin = $("#id_frequencyA").val();
232 var freq_mod_bin = $("#id_frequencyB").val();
233 var freqdelta_bin = $("#id_delta_frequency").val();
234 var freqramp_bin = $("#id_ramp_rate_clock").val();
235
236 var mclock = clock*multiplier;
237
238 var freq = binary2Freq(mclock, freq_bin);
239 var freq_mod = binary2Freq(mclock, freq_mod_bin);
240 var freqdelta = binary2FreqDelta(mclock, freqdelta_bin);
241 var freq_ramp = binary2Ramp(mclock, freqramp_bin);
242
243 $("#id_frequencyA_Mhz").val(freq);
244 $("#id_frequencyB_Mhz").val(freq_mod);
245 $("#id_delta_frequency_Mhz").val(freqdelta);
246 $("#id_ramp_rate_clock_Mhz").val(freq_ramp);
247 }
248
249 function updateFrequencyDelta() {
250 console.log("Ingreso a updateFrequencyDelta");
251 var clock = $("#id_clock").val();
252 var multiplier = $("#id_multiplier").val();
253 var freq_bin = $("#id_delta_frequency").val();
254
255 var mclock = clock*multiplier;
256
257 var freq = binary2FreqDelta(mclock, freq_bin);
258 console.log(freq);
259 $("#id_delta_frequency_Mhz").val(freq);
260 }
261
262 function updateBinaryFrequencyDelta() {
263 console.log("Ingreso a updateBInaryFrequencyDelta");
264 var clock = $("#id_clock").val();
265 var multiplier = $("#id_multiplier").val();
266 var freq = $("#id_delta_frequency_Mhz").val();
267 console.log(clock);
268 console.log(multiplier);
269 console.log(freq);
270
271 var mclock = clock*multiplier;
272 console.log(mclock);
273
274 var freq_bin = freqDelta2Binary(mclock, freq);
275
276 console.log(freq_bin);
277 $("#id_delta_frequency").val(freq_bin);
278
279 document.getElementById("id_aux_deltabin").innerHTML = numToString(parseInt(freq_bin, 10), 2, 48).match(/.{1,4}/g).join(' ');
280 }
281
282 function updateFrequencyRamp() {
283 console.log("Ingreso a updateFrequencyRamp");
284 var clock = $("#id_clock").val();
285 var multiplier = $("#id_multiplier").val();
286 var freq_bin = $("#id_ramp_rate_clock").val();
287
288 var mclock = clock*multiplier;
289
290 var freq = binary2Ramp(mclock, freq_bin);
291 console.log(freq);
292 $("#id_ramp_rate_clock_Mhz").val(freq);
293 }
294
295 function updateBinaryFrequencyRamp() {
296 console.log("Ingreso a updateBInaryFrequencyRamp");
297 var clock = $("#id_clock").val();
298 var multiplier = $("#id_multiplier").val();
299 var freq = $("#id_ramp_rate_clock_Mhz").val();
300
301 var mclock = clock*multiplier;
302
303 var freq_bin = freqRamp2Binary(mclock, freq);
304 console.log(freq_bin);
305 $("#id_ramp_rate_clock").val(freq_bin);
306 }
307
308 function updateFrequencyMhzRamp() {
309 console.log("Ingreso a updateFrequencyMhzRamp");
310 var step_us = $("#id_ramp_rate_clock_us").val();
311
312 var freq = us2Ramp(step_us);
313 console.log(freq);
314 $("#id_ramp_rate_clock_Mhz").val(freq);
315 updateBinaryFrequencyRamp();
316 }
317
318 function hidefA() {
319 var checkbox = $("#id_chkbin_fA");
320 var freq_bin = $("#id_row_fAbin");
321 var val_freq = $("#id_frequencyA");
322
323 console.log("Ingreso a hidefA");
324 if (checkbox.is(':checked')) {
325 freq_bin.show();
326 console.log(val_freq.val());
327 document.getElementById("id_aux_fAbin").innerHTML = numToString(parseInt(val_freq.val(), 10), 2, 48).match(/.{1,4}/g).join(' ');
328 }
329 else{
330 freq_bin.hide();
331 }
332 }
333
334 function hidefB() {
335 var checkbox = $("#id_chkbin_fB");
336 var freq_bin = $("#id_row_fBbin");
337 var val_freq = $("#id_frequencyB");
338
339 console.log("Ingreso a hidefB");
340 if (checkbox.is(':checked')) {
341 freq_bin.show();
342 console.log(val_freq.val());
343 document.getElementById("id_aux_fBbin").innerHTML = numToString(parseInt(val_freq.val(), 10), 2, 48).match(/.{1,4}/g).join(' ');
344 }
345 else{
346 freq_bin.hide();
347 }
348 }
349
350 function hidedf() {
351 var checkbox = $("#id_chkbin_df");
352 var freq_bin = $("#id_row_dfbin");
353 var val_freq = $("#id_delta_frequency");
354
355 console.log("Ingreso a hidedf");
356 if (checkbox.is(':checked')) {
357 freq_bin.show();
358 console.log(val_freq.val());
359 document.getElementById("id_aux_deltabin").innerHTML = numToString(parseInt(val_freq.val(), 10), 2, 48).match(/.{1,4}/g).join(' ');
360 }
361 else{
362 freq_bin.hide();
363 }
364 }
365
366 function hideramp() {
367 var checkbox = $("#id_chkbin_ramp");
368 var freq_bin = $("#id_row_rampbin");
369 var val_freq = $("#id_ramp_rate_clock");
370
371 console.log("Ingreso a hideramp");
372 if (checkbox.is(':checked')) {
373 freq_bin.show();
374 console.log(val_freq.val());
375 document.getElementById("id_aux_rampbin").innerHTML = numToString(parseInt(val_freq.val(), 10), 2, 20).match(/.{1,4}/g).join(' ');
376 }
377 else{
378 freq_bin.hide();
379 }
380 }
381
382 function hidephaseA() {
383 var checkbox = $("#id_chkbin_phaseA");
384 var freq_bin = $("#id_row_phaseA");
385 var phase_degree = $("#id_phaseA_degrees");
386
387 console.log("Ingreso a hidephaseA");
388 if (checkbox.is(':checked')) {
389 freq_bin.show();
390 console.log(phase_degree.val());
391 var phase_degree_dec = parseInt(phase_degree.val()*((2**14)/360.0),10);
392 console.log(phase_degree_dec);
393 document.getElementById("id_aux_phaseAdec").innerHTML = numToString(phase_degree_dec, 10, 5).match(/.{1,4}/g).join(' ');
394 document.getElementById("id_aux_phaseAbin").innerHTML = numToString(parseInt(phase_degree_dec, 10), 2, 14).match(/.{1,4}/g).join(' ');
395
396 }
397 else{
398 freq_bin.hide();
399 }
400 }
401
402 function hidephaseB() {
403 var checkbox = $("#id_chkbin_phaseB");
404 var freq_bin = $("#id_row_phaseB");
405 var phase_degree = $("#id_phaseB_degrees");
406
407 console.log("Ingreso a hidephaseB");
408 if (checkbox.is(':checked')) {
409 freq_bin.show();
410 console.log(phase_degree.val());
411 var phase_degree_dec = parseInt(phase_degree.val()*((2**14)/360.0),10);
412 console.log(phase_degree_dec);
413 document.getElementById("id_aux_phaseBdec").innerHTML = numToString(phase_degree_dec, 10, 5).match(/.{1,4}/g).join(' ');
414 document.getElementById("id_aux_phaseBbin").innerHTML = numToString(parseInt(phase_degree_dec, 10), 2, 14).match(/.{1,4}/g).join(' ');
415
416 }
417 else{
418 freq_bin.hide();
419 }
420 }
421
422 function updatephaseAbindec() {
423 var freq_bin = $("#id_row_phaseA");
424 var phase_degree = $("#id_phaseA_degrees");
425
426 console.log("Ingreso a cupdatephaseAbindec");
427 console.log(phase_degree.val());
428 var phase_degree_dec = parseInt(phase_degree.val()*((2**14)/360.0),10);
429 console.log(phase_degree_dec);
430 document.getElementById("id_aux_phaseAdec").innerHTML = numToString(phase_degree_dec, 10, 5).match(/.{1,4}/g).join(' ');
431 document.getElementById("id_aux_phaseAbin").innerHTML = numToString(parseInt(phase_degree_dec, 10), 2, 14).match(/.{1,4}/g).join(' ');
432
433 }
434
435 function updatephaseBbindec() {
436 var freq_bin = $("#id_row_phaseB");
437 var phase_degree = $("#id_phaseB_degrees");
438
439 console.log("Ingreso a cupdatephaseBbindec");
440 console.log(phase_degree.val());
441 var phase_degree_dec = parseInt(phase_degree.val()*((2**14)/360.0),10);
442 console.log(phase_degree_dec);
443 document.getElementById("id_aux_phaseBdec").innerHTML = numToString(phase_degree_dec, 10, 5).match(/.{1,4}/g).join(' ');
444 document.getElementById("id_aux_phaseBbin").innerHTML = numToString(parseInt(phase_degree_dec, 10), 2, 14).match(/.{1,4}/g).join(' ');
445
446 }
447
448 function padStart(string, length, char) {
449 return length > 0 ?
450 padStart(char + string, --length, char) :
451 string;
452 }
453
454 function numToString(num, radix, length = num.length) {
455 const numString = num.toString(radix);
456 return numString.length === length ?
457 numString :
458 padStart(numString, length - numString.length, "0")
459 }
460
461 console.log(numToString(parseInt("37529996894754", 10), 2, 48));
462 </script>
463 {% endblock %} No newline at end of file
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,12 +1,12
1 REDIS_HOST=radarsys-redis
1 REDIS_HOST=radarsys-redis
2 REDIS_PORT=6379
2 REDIS_PORT=6379
3 POSTGRES_PORT_5432_TCP_ADDR=radarsys-postgres
3 POSTGRES_PORT_5432_TCP_ADDR=radarsys-postgres
4 POSTGRES_PORT_5432_TCP_PORT=5432
4 POSTGRES_PORT_5432_TCP_PORT=5432
5 DB_NAME=radarsys
5 DB_NAME=radarsys
6 DB_USER=docker
6 DB_USER=docker
7 DB_PASSWORD=docker
7 DB_PASSWORD=docker
8 PGDATA=/var/lib/postgresql/data
8 PGDATA=/var/lib/postgresql/data
9 LC_ALL=C.UTF-8
9 LC_ALL=C.UTF-8
10 TZ=America/Lima
10 TZ=America/Lima
11 DOCKER_DATA=/Volumes/dockers/radarsys/
11 DOCKER_DATA=/data/dockers/radarsys/
12 LOCAL_IP=192.168.1.128
12 LOCAL_IP=192.168.1.128
@@ -1,1005 +1,1005
1 from django.db import models
1 from django.db import models
2 from apps.main.models import Configuration , User
2 from apps.main.models import Configuration , User
3 from django.urls import reverse
3 from django.urls import reverse
4 from celery.execute import send_task
4 from celery.execute import send_task
5 from datetime import datetime
5 from datetime import datetime
6 import ast
6 import ast
7 import socket
7 import socket
8 import json
8 import json
9 import requests
9 import requests
10 import struct
10 import struct
11 import os, sys, time
11 import os, sys, time
12
12
13 antenna_default = json.dumps({
13 antenna_default = json.dumps({
14 "antenna_up": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
14 "antenna_up": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
15 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
15 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
16 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
16 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
17 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
17 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
18 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
18 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
19 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
19 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
20 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
20 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
21 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0]
21 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0]
22 ]
22 ]
23 ,
23 ,
24 "antenna_down": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
24 "antenna_down": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
25 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
25 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
26 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
26 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
27 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
27 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
28 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
28 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
29 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
29 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
30 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
30 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
31 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0]],
31 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0]],
32 })
32 })
33
33
34
34
35 tx_default = json.dumps({
35 tx_default = json.dumps({
36 "up": [[1,1,1,1,0,0,0,0],
36 "up": [[1,1,1,1,0,0,0,0],
37 [1,1,1,1,0,0,0,0],
37 [1,1,1,1,0,0,0,0],
38 [1,1,1,1,0,0,0,0],
38 [1,1,1,1,0,0,0,0],
39 [1,1,1,1,0,0,0,0],
39 [1,1,1,1,0,0,0,0],
40 [0,0,0,0,1,1,1,1],
40 [0,0,0,0,1,1,1,1],
41 [0,0,0,0,1,1,1,1],
41 [0,0,0,0,1,1,1,1],
42 [0,0,0,0,1,1,1,1],
42 [0,0,0,0,1,1,1,1],
43 [0,0,0,0,1,1,1,1]],
43 [0,0,0,0,1,1,1,1]],
44
44
45 "down": [[1,1,1,1,0,0,0,0],
45 "down": [[1,1,1,1,0,0,0,0],
46 [1,1,1,1,0,0,0,0],
46 [1,1,1,1,0,0,0,0],
47 [1,1,1,1,0,0,0,0],
47 [1,1,1,1,0,0,0,0],
48 [1,1,1,1,0,0,0,0],
48 [1,1,1,1,0,0,0,0],
49 [0,0,0,0,1,1,1,1],
49 [0,0,0,0,1,1,1,1],
50 [0,0,0,0,1,1,1,1],
50 [0,0,0,0,1,1,1,1],
51 [0,0,0,0,1,1,1,1],
51 [0,0,0,0,1,1,1,1],
52 [0,0,0,0,1,1,1,1]],
52 [0,0,0,0,1,1,1,1]],
53 })
53 })
54
54
55 rx_default = json.dumps({
55 rx_default = json.dumps({
56 "up": [[1,1,1,1,0,0,0,0],
56 "up": [[1,1,1,1,0,0,0,0],
57 [1,1,1,1,0,0,0,0],
57 [1,1,1,1,0,0,0,0],
58 [1,1,1,1,0,0,0,0],
58 [1,1,1,1,0,0,0,0],
59 [1,1,1,1,0,0,0,0],
59 [1,1,1,1,0,0,0,0],
60 [0,0,0,0,1,1,1,1],
60 [0,0,0,0,1,1,1,1],
61 [0,0,0,0,1,1,1,1],
61 [0,0,0,0,1,1,1,1],
62 [0,0,0,0,1,1,1,1],
62 [0,0,0,0,1,1,1,1],
63 [0,0,0,0,1,1,1,1]],
63 [0,0,0,0,1,1,1,1]],
64
64
65 "down": [[1,1,1,1,0,0,0,0],
65 "down": [[1,1,1,1,0,0,0,0],
66 [1,1,1,1,0,0,0,0],
66 [1,1,1,1,0,0,0,0],
67 [1,1,1,1,0,0,0,0],
67 [1,1,1,1,0,0,0,0],
68 [1,1,1,1,0,0,0,0],
68 [1,1,1,1,0,0,0,0],
69 [0,0,0,0,1,1,1,1],
69 [0,0,0,0,1,1,1,1],
70 [0,0,0,0,1,1,1,1],
70 [0,0,0,0,1,1,1,1],
71 [0,0,0,0,1,1,1,1],
71 [0,0,0,0,1,1,1,1],
72 [0,0,0,0,1,1,1,1]],
72 [0,0,0,0,1,1,1,1]],
73 })
73 })
74
74
75 status_default = '0000000000000000000000000000000000000000000000000000000000000000'
75 status_default = '0000000000000000000000000000000000000000000000000000000000000000'
76 default_messages = {}
76 default_messages = {}
77
77
78 for i in range(1,65):
78 for i in range(1,65):
79 default_messages[str(i)] = "Module "+str(i)
79 default_messages[str(i)] = "Module "+str(i)
80
80
81
81
82 ues_default = json.dumps({
82 ues_default = json.dumps({
83 "up": [0.533333,0.00000,1.06667,0.00000],
83 "up": [0.533333,0.00000,1.06667,0.00000],
84 "down": [0.533333,0.00000,1.06667,0.00000]
84 "down": [0.533333,0.00000,1.06667,0.00000]
85 })
85 })
86
86
87 onlyrx_default = json.dumps({
87 onlyrx_default = json.dumps({
88 "up": False,
88 "up": False,
89 "down": False
89 "down": False
90 })
90 })
91
91
92 def up_convertion(cadena):
92 def up_convertion(cadena):
93 valores = []
93 valores = []
94 for c in cadena:
94 for c in cadena:
95 if c == 1.0: valores=valores+['000']
95 if c == 1.0: valores=valores+['000']
96 if c == 2.0: valores=valores+['001']
96 if c == 2.0: valores=valores+['001']
97 if c == 3.0: valores=valores+['010']
97 if c == 3.0: valores=valores+['010']
98 if c == 0.0: valores=valores+['011']
98 if c == 0.0: valores=valores+['011']
99 if c == 0.5: valores=valores+['100']
99 if c == 0.5: valores=valores+['100']
100 if c == 1.5: valores=valores+['101']
100 if c == 1.5: valores=valores+['101']
101 if c == 2.5: valores=valores+['110']
101 if c == 2.5: valores=valores+['110']
102 if c == 3.5: valores=valores+['111']
102 if c == 3.5: valores=valores+['111']
103
103
104 return valores
104 return valores
105
105
106 def up_conv_bits(value):
106 def up_conv_bits(value):
107
107
108 if value == 1.0: bits="000"
108 if value == 1.0: bits="000"
109 if value == 2.0: bits="001"
109 if value == 2.0: bits="001"
110 if value == 3.0: bits="010"
110 if value == 3.0: bits="010"
111 if value == 0.0: bits="011"
111 if value == 0.0: bits="011"
112 if value == 0.5: bits="100"
112 if value == 0.5: bits="100"
113 if value == 1.5: bits="101"
113 if value == 1.5: bits="101"
114 if value == 2.5: bits="110"
114 if value == 2.5: bits="110"
115 if value == 3.5: bits="111"
115 if value == 3.5: bits="111"
116
116
117 return bits
117 return bits
118
118
119 def down_convertion(cadena):
119 def down_convertion(cadena):
120 valores = []
120 valores = []
121 for c in cadena:
121 for c in cadena:
122 if c == 1.0: valores=valores+['000']
122 if c == 1.0: valores=valores+['000']
123 if c == 2.0: valores=valores+['001']
123 if c == 2.0: valores=valores+['001']
124 if c == 3.0: valores=valores+['010']
124 if c == 3.0: valores=valores+['010']
125 if c == 0.0: valores=valores+['011']
125 if c == 0.0: valores=valores+['011']
126 if c == 0.5: valores=valores+['100']
126 if c == 0.5: valores=valores+['100']
127 if c == 1.5: valores=valores+['101']
127 if c == 1.5: valores=valores+['101']
128 if c == 2.5: valores=valores+['110']
128 if c == 2.5: valores=valores+['110']
129 if c == 3.5: valores=valores+['111']
129 if c == 3.5: valores=valores+['111']
130
130
131 return valores
131 return valores
132
132
133 def down_conv_bits(value):
133 def down_conv_bits(value):
134
134
135 if value == 1.0: bits="000"
135 if value == 1.0: bits="000"
136 if value == 2.0: bits="001"
136 if value == 2.0: bits="001"
137 if value == 3.0: bits="010"
137 if value == 3.0: bits="010"
138 if value == 0.0: bits="011"
138 if value == 0.0: bits="011"
139 if value == 0.5: bits="100"
139 if value == 0.5: bits="100"
140 if value == 1.5: bits="101"
140 if value == 1.5: bits="101"
141 if value == 2.5: bits="110"
141 if value == 2.5: bits="110"
142 if value == 3.5: bits="111"
142 if value == 3.5: bits="111"
143
143
144 return bits
144 return bits
145
145
146 def up_conv_value(bits):
146 def up_conv_value(bits):
147
147
148 if bits == "000": value=1.0
148 if bits == "000": value=1.0
149 if bits == "001": value=2.0
149 if bits == "001": value=2.0
150 if bits == "010": value=3.0
150 if bits == "010": value=3.0
151 if bits == "011": value=0.0
151 if bits == "011": value=0.0
152 if bits == "100": value=0.5
152 if bits == "100": value=0.5
153 if bits == "101": value=1.5
153 if bits == "101": value=1.5
154 if bits == "110": value=2.5
154 if bits == "110": value=2.5
155 if bits == "111": value=3.5
155 if bits == "111": value=3.5
156
156
157 return value
157 return value
158
158
159 def down_conv_value(bits):
159 def down_conv_value(bits):
160
160
161 if bits == "000": value=1.0
161 if bits == "000": value=1.0
162 if bits == "001": value=2.0
162 if bits == "001": value=2.0
163 if bits == "010": value=3.0
163 if bits == "010": value=3.0
164 if bits == "011": value=0.0
164 if bits == "011": value=0.0
165 if bits == "100": value=0.5
165 if bits == "100": value=0.5
166 if bits == "101": value=1.5
166 if bits == "101": value=1.5
167 if bits == "110": value=2.5
167 if bits == "110": value=2.5
168 if bits == "111": value=3.5
168 if bits == "111": value=3.5
169
169
170 return value
170 return value
171
171
172 def ip2position(module_number):
172 def ip2position(module_number):
173 j=0
173 j=0
174 i=0
174 i=0
175 for x in range(0,module_number-1):
175 for x in range(0,module_number-1):
176 j=j+1
176 j=j+1
177 if j==8:
177 if j==8:
178 i=i+1
178 i=i+1
179 j=0
179 j=0
180
180
181 pos = [i,j]
181 pos = [i,j]
182 return pos
182 return pos
183
183
184
184
185 def fromBinary2Char(binary_string):
185 def fromBinary2Char(binary_string):
186 number = int(binary_string, 2)
186 number = int(binary_string, 2)
187 #Plus 33 to avoid more than 1 characters values such as: '\x01'-'\x1f'
187 #Plus 33 to avoid more than 1 characters values such as: '\x01'-'\x1f'
188 number = number + 33
188 number = number + 33
189 char = chr(number)
189 char = chr(number)
190 return char
190 return char
191
191
192 def fromChar2Binary(char):
192 def fromChar2Binary(char):
193 number = ord(char) - 33
193 number = ord(char) - 33
194 #Minus 33 to get the real value
194 #Minus 33 to get the real value
195 bits = bin(number)[2:]
195 bits = bin(number)[2:]
196 #To ensure we have a string with 6bits
196 #To ensure we have a string with 6bits
197 if len(bits) < 6:
197 if len(bits) < 6:
198 bits = bits.zfill(6)
198 bits = bits.zfill(6)
199 return bits
199 return bits
200
200
201 OPERATION_MODES = (
201 OPERATION_MODES = (
202 (0, 'Manual'),
202 (0, 'Manual'),
203 (1, 'Automatic'),
203 (1, 'Automatic'),
204 )
204 )
205
205
206 class ABSConfiguration(Configuration):
206 class ABSConfiguration(Configuration):
207 active_beam = models.PositiveSmallIntegerField(verbose_name='Active Beam', default=0)
207 active_beam = models.PositiveSmallIntegerField(verbose_name='Active Beam', default=0)
208 module_status = models.CharField(verbose_name='Module Status', max_length=10000, default=status_default)
208 module_status = models.CharField(verbose_name='Module Status', max_length=10000, default=status_default)
209 operation_mode = models.PositiveSmallIntegerField(verbose_name='Operation Mode', choices=OPERATION_MODES, default = 0)
209 operation_mode = models.PositiveSmallIntegerField(verbose_name='Operation Mode', choices=OPERATION_MODES, default = 0)
210 operation_value = models.FloatField(verbose_name='Periodic (seconds)', default="10", null=True, blank=True)
210 operation_value = models.FloatField(verbose_name='Periodic (seconds)', default="10", null=True, blank=True)
211 module_messages = models.CharField(verbose_name='Modules Messages', max_length=10000, default=json.dumps(default_messages))
211 module_messages = models.CharField(verbose_name='Modules Messages', max_length=10000, default=json.dumps(default_messages))
212
212
213 class Meta:
213 class Meta:
214 db_table = 'abs_configurations'
214 db_table = 'abs_configurations'
215
215
216 def get_absolute_url_plot(self):
216 def get_absolute_url_plot(self):
217 return reverse('url_plot_abs_patterns', args=[str(self.id)])
217 return reverse('url_plot_abs_patterns', args=[str(self.id)])
218
218
219
219
220 def parms_to_dict(self):
220 def parms_to_dict(self):
221
221
222 parameters = {}
222 parameters = {}
223
223
224 parameters['device_id'] = self.device.id
224 parameters['device_id'] = self.device.id
225 parameters['label'] = self.label
225 parameters['label'] = self.label
226 parameters['device_type'] = self.device.device_type.name
226 parameters['device_type'] = self.device.device_type.name
227 parameters['beams'] = {}
227 parameters['beams'] = {}
228
228
229 beams = ABSBeam.objects.filter(abs_conf=self)
229 beams = ABSBeam.objects.filter(abs_conf=self)
230 b=1
230 b=1
231 for beam in beams:
231 for beam in beams:
232 #absbeam = ABSBeam.objects.get(pk=beams[beam])
232 #absbeam = ABSBeam.objects.get(pk=beams[beam])
233 parameters['beams']['beam'+str(b)] = beam.parms_to_dict()#absbeam.parms_to_dict()
233 parameters['beams']['beam'+str(b)] = beam.parms_to_dict()#absbeam.parms_to_dict()
234 b+=1
234 b+=1
235
235
236 return parameters
236 return parameters
237
237
238
238
239 def dict_to_parms(self, parameters):
239 def dict_to_parms(self, parameters):
240
240
241 self.label = parameters['label']
241 self.label = parameters['label']
242
242
243 absbeams = ABSBeam.objects.filter(abs_conf=self)
243 absbeams = ABSBeam.objects.filter(abs_conf=self)
244 beams = parameters['beams']
244 beams = parameters['beams']
245
245
246 if absbeams:
246 if absbeams:
247 beams_number = len(beams)
247 beams_number = len(beams)
248 absbeams_number = len(absbeams)
248 absbeams_number = len(absbeams)
249 if beams_number==absbeams_number:
249 if beams_number==absbeams_number:
250 i = 1
250 i = 1
251 for absbeam in absbeams:
251 for absbeam in absbeams:
252 absbeam.dict_to_parms(beams['beam'+str(i)])
252 absbeam.dict_to_parms(beams['beam'+str(i)])
253 i = i+1
253 i = i+1
254 elif beams_number > absbeams_number:
254 elif beams_number > absbeams_number:
255 i = 1
255 i = 1
256 for absbeam in absbeams:
256 for absbeam in absbeams:
257 absbeam.dict_to_parms(beams['beam'+str(i)])
257 absbeam.dict_to_parms(beams['beam'+str(i)])
258 i=i+1
258 i=i+1
259 for x in range(i,beams_number+1):
259 for x in range(i,beams_number+1):
260 new_beam = ABSBeam(
260 new_beam = ABSBeam(
261 name =beams['beam'+str(i)]['name'],
261 name =beams['beam'+str(i)]['name'],
262 antenna =json.dumps(beams['beam'+str(i)]['antenna']),
262 antenna =json.dumps(beams['beam'+str(i)]['antenna']),
263 abs_conf = self,
263 abs_conf = self,
264 tx =json.dumps(beams['beam'+str(i)]['tx']),
264 tx =json.dumps(beams['beam'+str(i)]['tx']),
265 rx =json.dumps(beams['beam'+str(i)]['rx']),
265 rx =json.dumps(beams['beam'+str(i)]['rx']),
266 ues =json.dumps(beams['beam'+str(i)]['ues']),
266 ues =json.dumps(beams['beam'+str(i)]['ues']),
267 only_rx =json.dumps(beams['beam'+str(i)]['only_rx'])
267 only_rx =json.dumps(beams['beam'+str(i)]['only_rx'])
268 )
268 )
269 new_beam.save()
269 new_beam.save()
270 i=i+1
270 i=i+1
271 else: #beams_number < absbeams_number:
271 else: #beams_number < absbeams_number:
272 i = 1
272 i = 1
273 for absbeam in absbeams:
273 for absbeam in absbeams:
274 if i <= beams_number:
274 if i <= beams_number:
275 absbeam.dict_to_parms(beams['beam'+str(i)])
275 absbeam.dict_to_parms(beams['beam'+str(i)])
276 i=i+1
276 i=i+1
277 else:
277 else:
278 absbeam.delete()
278 absbeam.delete()
279 else:
279 else:
280 for beam in beams:
280 for beam in beams:
281 new_beam = ABSBeam(
281 new_beam = ABSBeam(
282 name =beams[beam]['name'],
282 name =beams[beam]['name'],
283 antenna =json.dumps(beams[beam]['antenna']),
283 antenna =json.dumps(beams[beam]['antenna']),
284 abs_conf = self,
284 abs_conf = self,
285 tx =json.dumps(beams[beam]['tx']),
285 tx =json.dumps(beams[beam]['tx']),
286 rx =json.dumps(beams[beam]['rx']),
286 rx =json.dumps(beams[beam]['rx']),
287 ues =json.dumps(beams[beam]['ues']),
287 ues =json.dumps(beams[beam]['ues']),
288 only_rx =json.dumps(beams[beam]['only_rx'])
288 only_rx =json.dumps(beams[beam]['only_rx'])
289 )
289 )
290 new_beam.save()
290 new_beam.save()
291
291
292
292
293
293
294 def update_from_file(self, parameters):
294 def update_from_file(self, parameters):
295
295
296 self.dict_to_parms(parameters)
296 self.dict_to_parms(parameters)
297 self.save()
297 self.save()
298
298
299
299
300 def get_beams(self, **kwargs):
300 def get_beams(self, **kwargs):
301 '''
301 '''
302 This function returns ABS Configuration beams
302 This function returns ABS Configuration beams
303 '''
303 '''
304 return ABSBeam.objects.filter(abs_conf=self.pk, **kwargs)
304 return ABSBeam.objects.filter(abs_conf=self.pk, **kwargs)
305
305
306 def clone(self, **kwargs):
306 def clone(self, **kwargs):
307
307
308 beams = self.get_beams()
308 beams = self.get_beams()
309 self.pk = None
309 self.pk = None
310 self.id = None
310 self.id = None
311 for attr, value in kwargs.items():
311 for attr, value in kwargs.items():
312 setattr(self, attr, value)
312 setattr(self, attr, value)
313 self.save()
313 self.save()
314
314
315 for beam in beams:
315 for beam in beams:
316 beam.clone(abs_conf=self)
316 beam.clone(abs_conf=self)
317
317
318 #-----For Active Beam-----
318 #-----For Active Beam-----
319 new_beams = ABSBeam.objects.filter(abs_conf=self)
319 new_beams = ABSBeam.objects.filter(abs_conf=self)
320 self.active_beam = new_beams[0].id
320 self.active_beam = new_beams[0].id
321 self.save()
321 self.save()
322 #-----For Active Beam-----
322 #-----For Active Beam-----
323 #-----For Device Status---
323 #-----For Device Status---
324 self.device.status = 3
324 self.device.status = 3
325 self.device.save()
325 self.device.save()
326 #-----For Device Status---
326 #-----For Device Status---
327
327
328 return self
328 return self
329
329
330
330
331 def start_device(self):
331 def start_device(self):
332
332
333 if self.device.status == 3:
333 if self.device.status == 3:
334
334
335 try:
335 try:
336 #self.write_device()
336 #self.write_device()
337 send_task('task_change_beam', [self.id],)
337 send_task('task_change_beam', [self.id],)
338 self.message = 'ABS running'
338 self.message = 'ABS running'
339
339
340 except Exception as e:
340 except Exception as e:
341 self.message = str(e)
341 self.message = str(e)
342 return False
342 return False
343
343
344 return True
344 return True
345
345
346 else:
346 else:
347 self.message = 'Please, select Write ABS Device first.'
347 self.message = 'Please, select Write ABS Device first.'
348 return False
348 return False
349
349
350
350
351 def stop_device(self):
351 def stop_device(self):
352
352
353 self.device.status = 2
353 self.device.status = 2
354 self.device.save()
354 self.device.save()
355 self.message = 'ABS has been stopped.'
355 self.message = 'ABS has been stopped.'
356 self.save()
356 self.save()
357
357
358 return True
358 return True
359
359
360
360
361 def write_device(self):
361 def write_device(self):
362
362
363 """
363 """
364 This function sends the beams list to every abs module.
364 This function sends the beams list to every abs module.
365 It needs 'module_conf' function
365 It needs 'module_conf' function
366 """
366 """
367 print("Write")
367 print("Write")
368 beams = ABSBeam.objects.filter(abs_conf=self)
368 beams = ABSBeam.objects.filter(abs_conf=self)
369 nbeams = len(beams)
369 nbeams = len(beams)
370
370
371 # Se manda a cero RC para poder realizar cambio de beam
371 # Se manda a cero RC para poder realizar cambio de beam
372 if self.experiment is None:
372 if self.experiment is None:
373 confs = []
373 confs = []
374 else:
374 else:
375 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
375 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
376 confdds = ''
376 confdds = ''
377 confjars = ''
377 confjars = ''
378 confrc = ''
378 confrc = ''
379 #TO STOP DEVICES: DDS-JARS-RC
379 #TO STOP DEVICES: DDS-JARS-RC
380 for i in range(0,len(confs)):
380 for i in range(0,len(confs)):
381 if i==0:
381 if i==0:
382 for conf in confs:
382 for conf in confs:
383 if conf.device.device_type.name == 'dds':
383 if conf.device.device_type.name == 'dds':
384 confdds = conf
384 confdds = conf
385 confdds.stop_device()
385 confdds.stop_device()
386 break
386 break
387 if i==1:
387 if i==1:
388 for conf in confs:
388 for conf in confs:
389 if conf.device.device_type.name == 'jars':
389 if conf.device.device_type.name == 'jars':
390 confjars = conf
390 confjars = conf
391 confjars.stop_device()
391 confjars.stop_device()
392 break
392 break
393 if i==2:
393 if i==2:
394 for conf in confs:
394 for conf in confs:
395 if conf.device.device_type.name == 'rc':
395 if conf.device.device_type.name == 'rc':
396 confrc = conf
396 confrc = conf
397 confrc.stop_device()
397 confrc.stop_device()
398 break
398 break
399
399
400 '''
400 '''
401 if self.connected_modules() == 0 :
401 if self.connected_modules() == 0 :
402 print("No encuentra modulos")
402 print("No encuentra modulos")
403 self.message = "No ABS Module detected."
403 self.message = "No ABS Module detected."
404 return False
404 return False
405 '''
405 '''
406 #-------------Write each abs module-----------
406 #-------------Write each abs module-----------
407
407
408 if beams:
408 if beams:
409 block_id = 0
409 block_id = 0
410 message = 'SNDF{:03d}{:02d}{:02d}'.format(nbeams, nbeams, block_id)
410 message = 'SNDF{:03d}{:02d}{:02d}'.format(nbeams, nbeams, block_id)
411 for i, status in enumerate(self.module_status):
411 for i, status in enumerate(self.module_status):
412 message += ''.join([fromBinary2Char(beam.module_6bits(i)) for beam in beams])
412 message += ''.join([fromBinary2Char(beam.module_6bits(i)) for beam in beams])
413 status = ['0'] * 64
413 status = ['0'] * 64
414 n = 0
414 n = 0
415 print("Llega una antes entrar a multicast")
415 print("Llega una antes entrar a multicast")
416 sock = self.send_multicast(message)
416 sock = self.send_multicast(message)
417
417
418 while True:
418 while True:
419 #for i in range(32):
419 #for i in range(32):
420 try:
420 try:
421 data, address = sock.recvfrom(1024)
421 data, address = sock.recvfrom(1024)
422 print (address, data)
422 print (address, data)
423
423
424 if data == '1':
424 if data == '1':
425 status[int(address[0][10:])-1] = '3'
425 status[int(address[0][10:])-1] = '3'
426 elif data == '0':
426 elif data == '0':
427 status[int(address[0][10:])-1] = '1'
427 status[int(address[0][10:])-1] = '1'
428 except socket.timeout:
428 except socket.timeout:
429 print('Timeout')
429 print('Timeout')
430 break
430 break
431 except Exception as e:
431 except Exception as e:
432 print ('Error {}'.format(e))
432 print ('Error {}'.format(e))
433 n += 1
433 n += 1
434 sock.close()
434 sock.close()
435 else:
435 else:
436 self.message = "ABS Configuration does not have beams"
436 self.message = "ABS Configuration does not have beams"
437 print('No beams')
437 print('No beams')
438 #Start DDS-RC-JARS
438 #Start DDS-RC-JARS
439 if confdds:
439 if confdds:
440 confdds.start_device()
440 confdds.start_device()
441 if confrc:
441 if confrc:
442 #print confrc
442 #print confrc
443 confrc.start_device()
443 confrc.start_device()
444 if confjars:
444 if confjars:
445 confjars.start_device()
445 confjars.start_device()
446 return False
446 return False
447
447
448 if n == 64:
448 if n == 64:
449 self.message = "Could not write ABS Modules"
449 self.message = "Could not write ABS Modules"
450 self.device.status = 0
450 self.device.status = 0
451 self.module_status = ''.join(status)
451 self.module_status = ''.join(status)
452 self.save()
452 self.save()
453 print('Could not write ABS')
453 print('Could not write ABS')
454 #Start DDS-RC-JARS
454 #Start DDS-RC-JARS
455 if confdds:
455 if confdds:
456 confdds.start_device()
456 confdds.start_device()
457 if confrc:
457 if confrc:
458 #print confrc
458 #print confrc
459 confrc.start_device()
459 confrc.start_device()
460 if confjars:
460 if confjars:
461 confjars.start_device()
461 confjars.start_device()
462 return False
462 return False
463 else:
463 else:
464 self.message = "ABS Beams List have been sent to ABS Modules"
464 self.message = "ABS Beams List have been sent to ABS Modules"
465 print('ABS beams list sent')
465 print('ABS beams list sent')
466 self.active_beam = beams[0].pk
466 self.active_beam = beams[0].pk
467
467
468 #Start DDS-RC-JARS
468 #Start DDS-RC-JARS
469 if confdds:
469 if confdds:
470 confdds.start_device()
470 confdds.start_device()
471 if confrc:
471 if confrc:
472 #print confrc
472 #print confrc
473 confrc.start_device()
473 confrc.start_device()
474 if confjars:
474 if confjars:
475 confjars.start_device()
475 confjars.start_device()
476
476
477 print('Inicia intento de salvar device.status')
477 print('Inicia intento de salvar device.status')
478 self.device.status = 3
478 self.device.status = 3
479 self.module_status = ''.join(status)
479 self.module_status = ''.join(status)
480 self.save()
480 self.save()
481 print('Estatus salvado')
481 print('Estatus salvado')
482 conf_active = ABSActive.objects.get_or_create(pk=1)
482 conf_active, __ = ABSActive.objects.get_or_create(pk=1)
483 conf_active.conf = self
483 conf_active.conf = self
484 conf_active.save()
484 conf_active.save()
485 return True
485 return True
486
486
487
487
488 def read_module(self, module):
488 def read_module(self, module):
489
489
490 """
490 """
491 Read out-bits (up-down) of 1 abs module NOT for Configuration
491 Read out-bits (up-down) of 1 abs module NOT for Configuration
492 """
492 """
493
493
494 ip_address = self.device.ip_address
494 ip_address = self.device.ip_address
495 ip_address = ip_address.split('.')
495 ip_address = ip_address.split('.')
496 module_seq = (ip_address[0],ip_address[1],ip_address[2])
496 module_seq = (ip_address[0],ip_address[1],ip_address[2])
497 dot = '.'
497 dot = '.'
498 module_ip = dot.join(module_seq)+'.'+str(module)
498 module_ip = dot.join(module_seq)+'.'+str(module)
499 module_port = self.device.port_address
499 module_port = self.device.port_address
500 read_route = 'http://'+module_ip+':'+str(module_port)+'/read'
500 read_route = 'http://'+module_ip+':'+str(module_port)+'/read'
501
501
502 module_status = json.loads(self.module_status)
502 module_status = json.loads(self.module_status)
503 print(read_route)
503 print(read_route)
504
504
505 module_bits = ''
505 module_bits = ''
506
506
507 try:
507 try:
508 r_read = requests.get(read_route, timeout=0.5)
508 r_read = requests.get(read_route, timeout=0.5)
509 answer = r_read.json()
509 answer = r_read.json()
510 module_bits = answer['allbits']
510 module_bits = answer['allbits']
511 except:
511 except:
512 return {}
512 return {}
513
513
514 return module_bits
514 return module_bits
515
515
516 def read_device(self):
516 def read_device(self):
517
517
518 parms = {}
518 parms = {}
519 # Reads active modules.
519 # Reads active modules.
520 module_status = json.loads(self.module_status)
520 module_status = json.loads(self.module_status)
521 total = 0
521 total = 0
522 for status in module_status:
522 for status in module_status:
523 if module_status[status] != 0:
523 if module_status[status] != 0:
524 module_bits = self.read_module(int(status))
524 module_bits = self.read_module(int(status))
525 bits={}
525 bits={}
526 if module_bits:
526 if module_bits:
527 bits = (str(module_bits['um2']) + str(module_bits['um1']) + str(module_bits['um0']) +
527 bits = (str(module_bits['um2']) + str(module_bits['um1']) + str(module_bits['um0']) +
528 str(module_bits['dm2']) + str(module_bits['dm1']) + str(module_bits['dm0']) )
528 str(module_bits['dm2']) + str(module_bits['dm1']) + str(module_bits['dm0']) )
529 parms[str(status)] = bits
529 parms[str(status)] = bits
530
530
531 total +=1
531 total +=1
532
532
533 if total==0:
533 if total==0:
534 self.message = "No ABS Module detected. Please select 'Status'."
534 self.message = "No ABS Module detected. Please select 'Status'."
535 return False
535 return False
536
536
537
537
538
538
539 self.message = "ABS Modules have been read"
539 self.message = "ABS Modules have been read"
540 #monitoreo_tx = JROABSClnt_01CeCnMod000000MNTR10
540 #monitoreo_tx = JROABSClnt_01CeCnMod000000MNTR10
541 return parms
541 return parms
542
542
543
543
544 def connected_modules(self):
544 def connected_modules(self):
545 """
545 """
546 This function returns the number of connected abs-modules without updating.
546 This function returns the number of connected abs-modules without updating.
547 """
547 """
548 num = 0
548 num = 0
549 print(self.module_status)
549 print(self.module_status)
550 for i, status in enumerate(self.module_status):
550 for i, status in enumerate(self.module_status):
551 if status != '0':
551 if status != '0':
552 num += 1
552 num += 1
553 #print('status {}:{}'.format(i+1, status))
553 #print('status {}:{}'.format(i+1, status))
554 return num
554 return num
555
555
556 def send_multicast(self, message):
556 def send_multicast(self, message):
557 #print("Send multicast")
557 #print("Send multicast")
558 multicast_group = ('224.3.29.71', 10000)
558 multicast_group = ('224.3.29.71', 10000)
559 # Create the datagram socket
559 # Create the datagram socket
560 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
560 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
561 sock.settimeout(1)
561 sock.settimeout(1)
562 local_ip = os.environ.get('LOCAL_IP', '192.168.2.128')
562 local_ip = os.environ.get('LOCAL_IP', '192.168.2.128')
563 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip))
563 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip))
564 sock.sendto(message.encode(), multicast_group)
564 sock.sendto(message.encode(), multicast_group)
565 print('Sending ' + message)
565 print('Sending ' + message)
566 return sock
566 return sock
567
567
568 def status_device(self):
568 def status_device(self):
569 """
569 """
570 This function returns the status of all abs-modules as one.
570 This function returns the status of all abs-modules as one.
571 If at least one module is connected, its answer is "1"
571 If at least one module is connected, its answer is "1"
572 """
572 """
573 print ('Status device')
573 print ('Status device')
574 print (self.active_beam)
574 print (self.active_beam)
575 beams = ABSBeam.objects.filter(abs_conf=self)
575 beams = ABSBeam.objects.filter(abs_conf=self)
576 #print beams[self.active_beam-1].module_6bits(0)
576 #print beams[self.active_beam-1].module_6bits(0)
577 active = ABSActive.objects.get(pk=1)
577 active = ABSActive.objects.get(pk=1)
578 if active.conf != self:
578 if active.conf != self:
579 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_url()
579 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_url()
580 self.message += "\n"
580 self.message += "\n"
581 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
581 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
582
582
583 return False
583 return False
584
584
585 sock = self.send_multicast('MNTR')
585 sock = self.send_multicast('MNTR')
586
586
587 n = 0
587 n = 0
588 status = ['0'] * 64
588 status = ['0'] * 64
589
589
590 while True:
590 while True:
591 #for i in range(32):
591 #for i in range(32):
592 #if True:
592 #if True:
593 try:
593 try:
594 print("Recibiendo")
594 print("Recibiendo")
595 address = None
595 address = None
596 data, address = sock.recvfrom(2)
596 data, address = sock.recvfrom(2)
597 print (address, data)
597 print (address, data)
598 print("!!!!")
598 print("!!!!")
599 data = data.decode()
599 data = data.decode()
600 aux_mon = "1"
600 aux_mon = "1"
601 aux_expected = aux_mon
601 aux_expected = aux_mon
602 if(len(data)==2):
602 if(len(data)==2):
603 print ("data[1]: ")
603 print ("data[1]: ")
604 print (data[1])
604 print (data[1])
605 aux_mon = fromChar2Binary(data[1])
605 aux_mon = fromChar2Binary(data[1])
606 print (aux_mon)
606 print (aux_mon)
607 aux_i = (str(address[0]).split('.'))[3]
607 aux_i = (str(address[0]).split('.'))[3]
608 print (aux_i)
608 print (aux_i)
609 print ('Active beam')
609 print ('Active beam')
610 beam_active = ABSBeam.objects.get(pk=self.active_beam)
610 beam_active = ABSBeam.objects.get(pk=self.active_beam)
611 print (beam_active)
611 print (beam_active)
612 aux_expected = beam_active.module_6bits(int(aux_i)-1)
612 aux_expected = beam_active.module_6bits(int(aux_i)-1)
613 print (aux_expected)
613 print (aux_expected)
614
614
615 print ("data[0]: ")
615 print ("data[0]: ")
616 print (data[0])
616 print (data[0])
617
617
618 if data[0] == '1':
618 if data[0] == '1':
619 status[int(address[0][10:])-1] = '3'
619 status[int(address[0][10:])-1] = '3'
620 if aux_mon == aux_expected:
620 if aux_mon == aux_expected:
621 print ('Es igual')
621 print ('Es igual')
622 else:
622 else:
623 print ('Es diferente')
623 print ('Es diferente')
624 status[int(address[0][10:])-1] = '2'
624 status[int(address[0][10:])-1] = '2'
625
625
626 elif data[0] == '0':
626 elif data[0] == '0':
627 status[int(address[0][10:])-1] = '1'
627 status[int(address[0][10:])-1] = '1'
628 n += 1
628 n += 1
629 print('Module: {} connected'.format(address))
629 print('Module: {} connected'.format(address))
630 except socket.timeout:
630 except socket.timeout:
631 print('Timeout')
631 print('Timeout')
632 break
632 break
633 except:
633 except:
634 print('Module: {} error'.format(address))
634 print('Module: {} error'.format(address))
635 pass
635 pass
636
636
637 sock.close()
637 sock.close()
638
638
639 if n > 0:
639 if n > 0:
640 self.message = 'ABS modules Status have been updated.'
640 self.message = 'ABS modules Status have been updated.'
641 self.device.status = 1
641 self.device.status = 1
642 else:
642 else:
643 self.device.status = 0
643 self.device.status = 0
644 self.message = 'No ABS module is connected.'
644 self.message = 'No ABS module is connected.'
645 self.module_status = ''.join(status)
645 self.module_status = ''.join(status)
646 self.save()
646 self.save()
647
647
648 return self.device.status
648 return self.device.status
649
649
650
650
651 def send_beam(self, beam_pos):
651 def send_beam(self, beam_pos):
652 """
652 """
653 This function connects to a multicast group and sends the beam number
653 This function connects to a multicast group and sends the beam number
654 to all abs modules.
654 to all abs modules.
655 """
655 """
656 print ('Send beam')
656 print ('Send beam')
657 print (self.active_beam)
657 print (self.active_beam)
658 beams = ABSBeam.objects.filter(abs_conf=self)
658 beams = ABSBeam.objects.filter(abs_conf=self)
659 #print beams[self.active_beam-1].module_6bits(0)
659 #print beams[self.active_beam-1].module_6bits(0)
660 active = ABSActive.objects.get(pk=1)
660 active = ABSActive.objects.get(pk=1)
661 if active.conf != self:
661 if active.conf != self:
662 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_url()
662 self.message = 'La configuracion actual es la del siguiente enlace %s.' % active.conf.get_absolute_url()
663 self.message += "\n"
663 self.message += "\n"
664 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
664 self.message += 'Se debe realizar un write en esta configuracion para luego obtener un status valido.'
665
665
666 return False
666 return False
667
667
668 # Se manda a cero RC para poder realizar cambio de beam
668 # Se manda a cero RC para poder realizar cambio de beam
669 if self.experiment is None:
669 if self.experiment is None:
670 confs = []
670 confs = []
671 else:
671 else:
672 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
672 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
673 confdds = ''
673 confdds = ''
674 confjars = ''
674 confjars = ''
675 confrc = ''
675 confrc = ''
676 #TO STOP DEVICES: DDS-JARS-RC
676 #TO STOP DEVICES: DDS-JARS-RC
677 for i in range(0,len(confs)):
677 for i in range(0,len(confs)):
678 if i==0:
678 if i==0:
679 for conf in confs:
679 for conf in confs:
680 if conf.device.device_type.name == 'dds':
680 if conf.device.device_type.name == 'dds':
681 confdds = conf
681 confdds = conf
682 confdds.stop_device()
682 confdds.stop_device()
683 break
683 break
684 if i==1:
684 if i==1:
685 for conf in confs:
685 for conf in confs:
686 if conf.device.device_type.name == 'jars':
686 if conf.device.device_type.name == 'jars':
687 confjars = conf
687 confjars = conf
688 confjars.stop_device()
688 confjars.stop_device()
689 break
689 break
690 if i==2:
690 if i==2:
691 for conf in confs:
691 for conf in confs:
692 if conf.device.device_type.name == 'rc':
692 if conf.device.device_type.name == 'rc':
693 confrc = conf
693 confrc = conf
694 confrc.stop_device()
694 confrc.stop_device()
695 break
695 break
696 if beam_pos > 0:
696 if beam_pos > 0:
697 beam_pos = beam_pos - 1
697 beam_pos = beam_pos - 1
698 else:
698 else:
699 beam_pos = 0
699 beam_pos = 0
700
700
701 #El indice del apunte debe ser menor que el numero total de apuntes
701 #El indice del apunte debe ser menor que el numero total de apuntes
702 #El servidor tcp en el embebido comienza a contar desde 0
702 #El servidor tcp en el embebido comienza a contar desde 0
703 status = ['0'] * 64
703 status = ['0'] * 64
704 message = 'CHGB{}'.format(beam_pos)
704 message = 'CHGB{}'.format(beam_pos)
705 sock = self.send_multicast(message)
705 sock = self.send_multicast(message)
706 while True:
706 while True:
707 #for i in range(32):
707 #for i in range(32):
708 try:
708 try:
709 data, address = sock.recvfrom(1024)
709 data, address = sock.recvfrom(1024)
710 print (address, data)
710 print (address, data)
711 data = data.decode()
711 data = data.decode()
712 if data == '1':
712 if data == '1':
713 status[int(address[0][10:])-1] = '3'
713 status[int(address[0][10:])-1] = '3'
714 elif data == '0':
714 elif data == '0':
715 status[int(address[0][10:])-1] = '1'
715 status[int(address[0][10:])-1] = '1'
716 except socket.timeout:
716 except socket.timeout:
717 print('Timeout')
717 print('Timeout')
718 break
718 break
719 except Exception as e:
719 except Exception as e:
720 print ('Error {}'.format(e))
720 print ('Error {}'.format(e))
721 pass
721 pass
722
722
723 sock.close()
723 sock.close()
724
724
725 #Start DDS-RC-JARS
725 #Start DDS-RC-JARS
726 if confdds:
726 if confdds:
727 confdds.start_device()
727 confdds.start_device()
728 if confrc:
728 if confrc:
729 #print confrc
729 #print confrc
730 confrc.start_device()
730 confrc.start_device()
731 if confjars:
731 if confjars:
732 confjars.start_device()
732 confjars.start_device()
733
733
734 self.message = "ABS Beam has been changed"
734 self.message = "ABS Beam has been changed"
735 self.module_status = ''.join(status)
735 self.module_status = ''.join(status)
736 self.save()
736 self.save()
737 return True
737 return True
738
738
739
739
740 def get_absolute_url_import(self):
740 def get_absolute_url_import(self):
741 return reverse('url_import_abs_conf', args=[str(self.id)])
741 return reverse('url_import_abs_conf', args=[str(self.id)])
742
742
743 class ABSActive(models.Model):
743 class ABSActive(models.Model):
744 conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration', on_delete=models.CASCADE)
744 conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration', on_delete=models.CASCADE)
745
745
746 class Meta:
746 class Meta:
747 db_table = 'abs_absactive'
747 db_table = 'abs_absactive'
748
748
749 class ABSBeam(models.Model):
749 class ABSBeam(models.Model):
750
750
751 name = models.CharField(max_length=60, default='Beam')
751 name = models.CharField(max_length=60, default='Beam')
752 antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default)
752 antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default)
753 abs_conf = models.ForeignKey('ABSConfiguration', null=True,
753 abs_conf = models.ForeignKey('ABSConfiguration', null=True,
754 verbose_name='ABS Configuration', on_delete=models.CASCADE)
754 verbose_name='ABS Configuration', on_delete=models.CASCADE)
755 tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default)
755 tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default)
756 rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default)
756 rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default)
757 s_time = models.TimeField(verbose_name='Star Time', default='00:00:00')
757 s_time = models.TimeField(verbose_name='Star Time', default='00:00:00')
758 e_time = models.TimeField(verbose_name='End Time', default='23:59:59')
758 e_time = models.TimeField(verbose_name='End Time', default='23:59:59')
759 ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default)
759 ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default)
760 only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default)
760 only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default)
761
761
762 class Meta:
762 class Meta:
763 db_table = 'abs_beams'
763 db_table = 'abs_beams'
764
764
765 def __unicode__(self):
765 def __unicode__(self):
766 return u'%s' % (self.name)
766 return u'%s' % (self.name)
767
767
768 def parms_to_dict(self):
768 def parms_to_dict(self):
769
769
770 parameters = {}
770 parameters = {}
771 parameters['name'] = self.name
771 parameters['name'] = self.name
772 parameters['antenna'] = ast.literal_eval(self.antenna)
772 parameters['antenna'] = ast.literal_eval(self.antenna)
773 parameters['abs_conf'] = self.abs_conf.name
773 parameters['abs_conf'] = self.abs_conf.name
774 parameters['tx'] = ast.literal_eval(self.tx)
774 parameters['tx'] = ast.literal_eval(self.tx)
775 parameters['rx'] = ast.literal_eval(self.rx)
775 parameters['rx'] = ast.literal_eval(self.rx)
776 parameters['s_time'] = self.s_time.strftime("%H:%M:%S")
776 parameters['s_time'] = self.s_time.strftime("%H:%M:%S")
777 parameters['e_time'] = self.e_time.strftime("%H:%M:%S")
777 parameters['e_time'] = self.e_time.strftime("%H:%M:%S")
778 parameters['ues'] = ast.literal_eval(self.ues)
778 parameters['ues'] = ast.literal_eval(self.ues)
779 parameters['only_rx'] = json.loads(self.only_rx)
779 parameters['only_rx'] = json.loads(self.only_rx)
780
780
781 return parameters
781 return parameters
782
782
783 def dict_to_parms(self, parameters):
783 def dict_to_parms(self, parameters):
784
784
785 self.name = parameters['name']
785 self.name = parameters['name']
786 self.antenna = json.dumps(parameters['antenna'])
786 self.antenna = json.dumps(parameters['antenna'])
787 #self.abs_conf = parameters['abs_conf']
787 #self.abs_conf = parameters['abs_conf']
788 self.tx = json.dumps(parameters['tx'])
788 self.tx = json.dumps(parameters['tx'])
789 self.rx = json.dumps(parameters['rx'])
789 self.rx = json.dumps(parameters['rx'])
790 #self.s_time = parameters['s_time']
790 #self.s_time = parameters['s_time']
791 #self.e_time = parameters['e_time']
791 #self.e_time = parameters['e_time']
792 self.ues = json.dumps(parameters['ues'])
792 self.ues = json.dumps(parameters['ues'])
793 self.only_rx = json.dumps(parameters['only_rx'])
793 self.only_rx = json.dumps(parameters['only_rx'])
794 self.save()
794 self.save()
795
795
796
796
797 def clone(self, **kwargs):
797 def clone(self, **kwargs):
798
798
799 self.pk = None
799 self.pk = None
800 self.id = None
800 self.id = None
801 for attr, value in kwargs.items():
801 for attr, value in kwargs.items():
802 setattr(self, attr, value)
802 setattr(self, attr, value)
803
803
804 self.save()
804 self.save()
805
805
806 return self
806 return self
807
807
808
808
809 def module_6bits(self, module):
809 def module_6bits(self, module):
810 """
810 """
811 This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module
811 This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module
812 """
812 """
813 module += 1
813 module += 1
814 if module > 64:
814 if module > 64:
815 beam_bits = ""
815 beam_bits = ""
816 return beam_bits
816 return beam_bits
817
817
818 data = ast.literal_eval(self.antenna)
818 data = ast.literal_eval(self.antenna)
819 up_data = data['antenna_up']
819 up_data = data['antenna_up']
820 down_data = data['antenna_down']
820 down_data = data['antenna_down']
821
821
822 pos = ip2position(module)
822 pos = ip2position(module)
823 up_value = up_data[pos[0]][pos[1]]
823 up_value = up_data[pos[0]][pos[1]]
824 down_value = down_data[pos[0]][pos[1]]
824 down_value = down_data[pos[0]][pos[1]]
825
825
826 up_bits = up_conv_bits(up_value)
826 up_bits = up_conv_bits(up_value)
827 down_bits = down_conv_bits(down_value)
827 down_bits = down_conv_bits(down_value)
828 beam_bits = up_bits+down_bits
828 beam_bits = up_bits+down_bits
829
829
830 return beam_bits
830 return beam_bits
831
831
832
832
833 @property
833 @property
834 def get_upvalues(self):
834 def get_upvalues(self):
835 """
835 """
836 This function reads antenna pattern and show the up-value of one abs module
836 This function reads antenna pattern and show the up-value of one abs module
837 """
837 """
838
838
839 data = ast.literal_eval(self.antenna)
839 data = ast.literal_eval(self.antenna)
840 up_data = data['antenna_up']
840 up_data = data['antenna_up']
841
841
842 up_values = []
842 up_values = []
843 for data in up_data:
843 for data in up_data:
844 for i in range(0,8):
844 for i in range(0,8):
845 up_values.append(data[i])
845 up_values.append(data[i])
846
846
847 return up_values
847 return up_values
848
848
849 @property
849 @property
850 def antenna_upvalues(self):
850 def antenna_upvalues(self):
851 """
851 """
852 This function reads antenna pattern and show the up - values of one abs beam
852 This function reads antenna pattern and show the up - values of one abs beam
853 in a particular order
853 in a particular order
854 """
854 """
855 data = ast.literal_eval(self.antenna)
855 data = ast.literal_eval(self.antenna)
856 up_data = data['antenna_up']
856 up_data = data['antenna_up']
857
857
858 return up_data
858 return up_data
859
859
860 @property
860 @property
861 def antenna_downvalues(self):
861 def antenna_downvalues(self):
862 """
862 """
863 This function reads antenna pattern and show the down - values of one abs beam
863 This function reads antenna pattern and show the down - values of one abs beam
864 in a particular order
864 in a particular order
865 """
865 """
866 data = ast.literal_eval(self.antenna)
866 data = ast.literal_eval(self.antenna)
867 down_data = data['antenna_down']
867 down_data = data['antenna_down']
868
868
869 return down_data
869 return down_data
870
870
871 @property
871 @property
872 def get_downvalues(self):
872 def get_downvalues(self):
873 """
873 """
874 This function reads antenna pattern and show the down-value of one abs module
874 This function reads antenna pattern and show the down-value of one abs module
875 """
875 """
876
876
877 data = ast.literal_eval(self.antenna)
877 data = ast.literal_eval(self.antenna)
878 down_data = data['antenna_down']
878 down_data = data['antenna_down']
879
879
880 down_values = []
880 down_values = []
881 for data in down_data:
881 for data in down_data:
882 for i in range(0,8):
882 for i in range(0,8):
883 down_values.append(data[i])
883 down_values.append(data[i])
884
884
885 return down_values
885 return down_values
886
886
887 @property
887 @property
888 def get_up_ues(self):
888 def get_up_ues(self):
889 """
889 """
890 This function shows the up-ues-value of one beam
890 This function shows the up-ues-value of one beam
891 """
891 """
892 data = ast.literal_eval(self.ues)
892 data = ast.literal_eval(self.ues)
893 up_ues = data['up']
893 up_ues = data['up']
894
894
895 return up_ues
895 return up_ues
896
896
897 @property
897 @property
898 def get_down_ues(self):
898 def get_down_ues(self):
899 """
899 """
900 This function shows the down-ues-value of one beam
900 This function shows the down-ues-value of one beam
901 """
901 """
902 data = ast.literal_eval(self.ues)
902 data = ast.literal_eval(self.ues)
903 down_ues = data['down']
903 down_ues = data['down']
904
904
905 return down_ues
905 return down_ues
906
906
907 @property
907 @property
908 def get_up_onlyrx(self):
908 def get_up_onlyrx(self):
909 """
909 """
910 This function shows the up-onlyrx-value of one beam
910 This function shows the up-onlyrx-value of one beam
911 """
911 """
912 data = json.loads(self.only_rx)
912 data = json.loads(self.only_rx)
913 up_onlyrx = data['up']
913 up_onlyrx = data['up']
914
914
915 return up_onlyrx
915 return up_onlyrx
916
916
917 @property
917 @property
918 def get_down_onlyrx(self):
918 def get_down_onlyrx(self):
919 """
919 """
920 This function shows the down-onlyrx-value of one beam
920 This function shows the down-onlyrx-value of one beam
921 """
921 """
922 data = json.loads(self.only_rx)
922 data = json.loads(self.only_rx)
923 down_onlyrx = data['down']
923 down_onlyrx = data['down']
924
924
925 return down_onlyrx
925 return down_onlyrx
926
926
927 @property
927 @property
928 def get_tx(self):
928 def get_tx(self):
929 """
929 """
930 This function shows the tx-values of one beam
930 This function shows the tx-values of one beam
931 """
931 """
932 data = json.loads(self.tx)
932 data = json.loads(self.tx)
933
933
934 return data
934 return data
935
935
936 @property
936 @property
937 def get_uptx(self):
937 def get_uptx(self):
938 """
938 """
939 This function shows the up-tx-values of one beam
939 This function shows the up-tx-values of one beam
940 """
940 """
941 data = json.loads(self.tx)
941 data = json.loads(self.tx)
942 up_data = data['up']
942 up_data = data['up']
943
943
944 up_values = []
944 up_values = []
945 for data in up_data:
945 for data in up_data:
946 for i in range(0,8):
946 for i in range(0,8):
947 up_values.append(data[i])
947 up_values.append(data[i])
948
948
949 return up_values
949 return up_values
950
950
951 @property
951 @property
952 def get_downtx(self):
952 def get_downtx(self):
953 """
953 """
954 This function shows the down-tx-values of one beam
954 This function shows the down-tx-values of one beam
955 """
955 """
956 data = json.loads(self.tx)
956 data = json.loads(self.tx)
957 down_data = data['down']
957 down_data = data['down']
958
958
959 down_values = []
959 down_values = []
960 for data in down_data:
960 for data in down_data:
961 for i in range(0,8):
961 for i in range(0,8):
962 down_values.append(data[i])
962 down_values.append(data[i])
963
963
964 return down_values
964 return down_values
965
965
966
966
967
967
968 @property
968 @property
969 def get_rx(self):
969 def get_rx(self):
970 """
970 """
971 This function shows the rx-values of one beam
971 This function shows the rx-values of one beam
972 """
972 """
973 data = json.loads(self.rx)
973 data = json.loads(self.rx)
974
974
975 return data
975 return data
976
976
977 @property
977 @property
978 def get_uprx(self):
978 def get_uprx(self):
979 """
979 """
980 This function shows the up-rx-values of one beam
980 This function shows the up-rx-values of one beam
981 """
981 """
982 data = json.loads(self.rx)
982 data = json.loads(self.rx)
983 up_data = data['up']
983 up_data = data['up']
984
984
985 up_values = []
985 up_values = []
986 for data in up_data:
986 for data in up_data:
987 for i in range(0,8):
987 for i in range(0,8):
988 up_values.append(data[i])
988 up_values.append(data[i])
989
989
990 return up_values
990 return up_values
991
991
992 @property
992 @property
993 def get_downrx(self):
993 def get_downrx(self):
994 """
994 """
995 This function shows the down-rx-values of one beam
995 This function shows the down-rx-values of one beam
996 """
996 """
997 data = json.loads(self.rx)
997 data = json.loads(self.rx)
998 down_data = data['down']
998 down_data = data['down']
999
999
1000 down_values = []
1000 down_values = []
1001 for data in down_data:
1001 for data in down_data:
1002 for i in range(0,8):
1002 for i in range(0,8):
1003 down_values.append(data[i])
1003 down_values.append(data[i])
1004
1004
1005 return down_values
1005 return down_values
@@ -1,274 +1,305
1 import ast
1 import ast
2 import json
2 import json
3 import requests
3 import requests
4 import numpy as np
4 import numpy as np
5 from base64 import b64encode
5 from base64 import b64encode
6 from struct import pack
6 from struct import pack
7
7
8 from django.urls import reverse
8 from django.urls import reverse
9 from django.db import models
9 from django.db import models
10 from apps.main.models import Configuration
10 from apps.main.models import Configuration
11 from apps.main.utils import Params
11 from apps.main.utils import Params
12 # Create your models here.
12 # Create your models here.
13
13
14 from django.core.validators import MinValueValidator, MaxValueValidator
14 from django.core.validators import MinValueValidator, MaxValueValidator
15 from django.core.exceptions import ValidationError
15 from django.core.exceptions import ValidationError
16
16
17 from devices.dds_rest import api, data
17 from devices.dds_rest import api, data
18
18
19 ENABLE_TYPE = (
19 ENABLE_TYPE = (
20 (False, 'Disabled'),
20 (False, 'Disabled'),
21 (True, 'Enabled'),
21 (True, 'Enabled'),
22 )
22 )
23 MOD_TYPES = (
23 MOD_TYPES = (
24 (0, 'Single Tone'),
24 (0, 'Single Tone'),
25 (1, 'FSK'),
25 (1, 'FSK'),
26 (2, 'Ramped FSK'),
26 (2, 'Ramped FSK'),
27 (3, 'Chirp'),
27 (3, 'Chirp'),
28 (4, 'BPSK'),
28 (4, 'BPSK'),
29 )
29 )
30
30
31 class DDSRestConfiguration(Configuration):
31 class DDSRestConfiguration(Configuration):
32
32
33 DDS_NBITS = 48
33 DDS_NBITS = 48
34
34
35 clock = models.FloatField(verbose_name='Clock In (MHz)',validators=[MinValueValidator(5), MaxValueValidator(75)], null=True, default=60)
35 clock = models.FloatField(verbose_name='Clock In (MHz)',validators=[MinValueValidator(5), MaxValueValidator(75)], null=True, default=60)
36 multiplier = models.PositiveIntegerField(verbose_name='Multiplier',validators=[MinValueValidator(1), MaxValueValidator(20)], default=4)
36 multiplier = models.PositiveIntegerField(verbose_name='Multiplier',validators=[MinValueValidator(1), MaxValueValidator(20)], default=4)
37
37
38 frequencyA_Mhz = models.DecimalField(verbose_name='Frequency A (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16, null=True, default=49.9200)
38 frequencyA_Mhz = models.DecimalField(verbose_name='Frequency A (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16, null=True, default=49.9200)
39 frequencyA = models.BigIntegerField(verbose_name='Frequency A (Decimal)',validators=[MinValueValidator(0), MaxValueValidator(2**DDS_NBITS-1)], blank=True, null=True)
39 frequencyA = models.BigIntegerField(verbose_name='Frequency A (Decimal)',validators=[MinValueValidator(0), MaxValueValidator(2**DDS_NBITS-1)], blank=True, null=True)
40
40
41 frequencyB_Mhz = models.DecimalField(verbose_name='Frequency B (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16, blank=True, null=True)
41 frequencyB_Mhz = models.DecimalField(verbose_name='Frequency B (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16, blank=True, null=True)
42 frequencyB = models.BigIntegerField(verbose_name='Frequency B (Decimal)',validators=[MinValueValidator(0), MaxValueValidator(2**DDS_NBITS-1)], blank=True, null=True)
42 frequencyB = models.BigIntegerField(verbose_name='Frequency B (Decimal)',validators=[MinValueValidator(0), MaxValueValidator(2**DDS_NBITS-1)], blank=True, null=True)
43
43
44 delta_frequency_Mhz = models.DecimalField(verbose_name='Delta frequency (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16, blank=True, null=True)
44 delta_frequency_Mhz = models.DecimalField(verbose_name='Delta frequency (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16, blank=True, null=True)
45 delta_frequency = models.BigIntegerField(verbose_name='Delta frequency (Decimal)',validators=[MinValueValidator(0), MaxValueValidator(2**DDS_NBITS-1)], blank=True, null=True)
45 delta_frequency = models.BigIntegerField(verbose_name='Delta frequency (Decimal)',validators=[MinValueValidator(0), MaxValueValidator(2**DDS_NBITS-1)], blank=True, null=True)
46
46
47 update_clock_Mhz = models.DecimalField(verbose_name='Update clock (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16, blank=True, null=True)
47 update_clock_Mhz = models.DecimalField(verbose_name='Update clock (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16, blank=True, null=True)
48 update_clock = models.BigIntegerField(verbose_name='Update clock (Decimal)',validators=[MinValueValidator(0), MaxValueValidator(2**32-1)], blank=True, null=True)
48 update_clock = models.BigIntegerField(verbose_name='Update clock (Decimal)',validators=[MinValueValidator(0), MaxValueValidator(2**32-1)], blank=True, null=True)
49
49
50 ramp_rate_clock_Mhz = models.DecimalField(verbose_name='Ramp rate clock (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16, blank=True, null=True)
50 ramp_rate_clock_Mhz = models.DecimalField(verbose_name='Ramp rate clock (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16, blank=True, null=True)
51 ramp_rate_clock = models.BigIntegerField(verbose_name='Ramp rate clock (Decimal)',validators=[MinValueValidator(0), MaxValueValidator(2**18-1)], blank=True, null=True)
51 ramp_rate_clock = models.BigIntegerField(verbose_name='Ramp rate clock (Decimal)',validators=[MinValueValidator(0), MaxValueValidator(2**18-1)], blank=True, null=True)
52
52
53 phaseA_degrees = models.FloatField(verbose_name='Phase A (Degrees)', validators=[MinValueValidator(0), MaxValueValidator(360)], default=0)
53 phaseA_degrees = models.FloatField(verbose_name='Phase A (Degrees)', validators=[MinValueValidator(0), MaxValueValidator(360)], default=0)
54
54
55 phaseB_degrees = models.FloatField(verbose_name='Phase B (Degrees)', validators=[MinValueValidator(0), MaxValueValidator(360)], blank=True, null=True)
55 phaseB_degrees = models.FloatField(verbose_name='Phase B (Degrees)', validators=[MinValueValidator(0), MaxValueValidator(360)], blank=True, null=True)
56
56
57 modulation = models.PositiveIntegerField(verbose_name='Modulation Type', choices = MOD_TYPES, default = 0)
57 modulation = models.PositiveIntegerField(verbose_name='Modulation Type', choices = MOD_TYPES, default = 0)
58
58
59 amplitude_enabled = models.BooleanField(verbose_name='Amplitude Control', choices=ENABLE_TYPE, default=False)
59 amplitude_enabled = models.BooleanField(verbose_name='Amplitude Control', choices=ENABLE_TYPE, default=False)
60
60
61 amplitudeI = models.PositiveIntegerField(verbose_name='Amplitude CH1',validators=[MinValueValidator(0), MaxValueValidator(2**12-1)], blank=True, null=True)
61 amplitudeI = models.PositiveIntegerField(verbose_name='Amplitude CH1',validators=[MinValueValidator(0), MaxValueValidator(2**12-1)], blank=True, null=True)
62 amplitudeQ = models.PositiveIntegerField(verbose_name='Amplitude CH2',validators=[MinValueValidator(0), MaxValueValidator(2**12-1)], blank=True, null=True)
62 amplitudeQ = models.PositiveIntegerField(verbose_name='Amplitude CH2',validators=[MinValueValidator(0), MaxValueValidator(2**12-1)], blank=True, null=True)
63
63
64
64
65 def get_nbits(self):
65 def get_nbits(self):
66
66
67 return self.DDS_NBITS
67 return self.DDS_NBITS
68
68
69 def clean(self):
69 def clean(self):
70
70
71 if self.modulation in [1,2,3]:
71 if self.modulation in [1,2,3]:
72 if self.frequencyB is None or self.frequencyB_Mhz is None:
72 if self.frequencyB is None or self.frequencyB_Mhz is None:
73 raise ValidationError({
73 raise ValidationError({
74 'frequencyB': 'Frequency modulation has to be defined when FSK or Chirp modulation is selected'
74 'frequencyB': 'Frequency modulation has to be defined when FSK or Chirp modulation is selected'
75 })
75 })
76
76
77 if self.modulation in [4,]:
77 if self.modulation in [4,]:
78 if self.phaseB_degrees is None:
78 if self.phaseB_degrees is None:
79 raise ValidationError({
79 raise ValidationError({
80 'phaseB': 'Phase modulation has to be defined when BPSK modulation is selected'
80 'phaseB': 'Phase modulation has to be defined when BPSK modulation is selected'
81 })
81 })
82
82
83 self.frequencyA_Mhz = data.binary_to_freq(self.frequencyA, self.clock*self.multiplier)
83 self.frequencyA_Mhz = data.binary_to_freq(self.frequencyA, self.clock*self.multiplier)
84 self.frequencyB_Mhz = data.binary_to_freq(self.frequencyB, self.clock*self.multiplier)
84 self.frequencyB_Mhz = data.binary_to_freq(self.frequencyB, self.clock*self.multiplier)
85
85
86 def verify_frequencies(self):
86 def verify_frequencies(self):
87
87
88 return True
88 return True
89
89
90 def parms_to_text(self):
90 def parms_to_text(self):
91
91
92 my_dict = self.parms_to_dict()['configurations']['byId'][str(self.id)]
92 my_dict = self.parms_to_dict()['configurations']['byId'][str(self.id)]
93
93
94 text = data.dict_to_text(my_dict)
94 text = data.dict_to_text(my_dict)
95
95
96 return text
96 return text
97
97
98 def status_device(self):
98 def status_device(self):
99 print("Status ")
99 print("Status ")
100 try:
100 try:
101 self.device.status = 0
101 self.device.status = 0
102 payload = self.request('status')
102 payload = self.request('status')
103 if payload['status']=='generating RF':
103 if payload['status']=='generating RF':
104 self.device.status = 3
104 self.device.status = 3
105 elif payload['status']=='no generating RF':
105 elif payload['status']=='no generating RF':
106 self.device.status = 2
106 self.device.status = 2
107 else:
107 else:
108 self.device.status = 1
108 self.device.status = 1
109 self.device.save()
109 self.device.save()
110 self.message = 'DDS REST status: {}'.format(payload['status'])
110 self.message = 'DDS REST status: {}'.format(payload['status'])
111 return False
111 return False
112 except Exception as e:
112 except Exception as e:
113 if 'No route to host' not in str(e):
113 if 'No route to host' not in str(e):
114 self.device.status = 4
114 self.device.status = 4
115 self.device.save()
115 self.device.save()
116 self.message = 'DDS REST status: {}'.format(str(e))
116 self.message = 'DDS REST status: {}'.format(str(e))
117 return False
117 return False
118
118
119 self.device.save()
119 self.device.save()
120 return True
120 return True
121
121
122 def reset_device(self):
122 def reset_device(self):
123
123
124 answer = api.reset(ip = self.device.ip_address,
124 try:
125 port = self.device.port_address)
125 payload = self.request('reset', 'post')
126
126 if payload['reset']=='ok':
127 if answer[0] != "1":
127 self.message = 'DDS REST restarted OK'
128 self.message = 'DDS - {}'.format(answer[2:])
128 self.device.status = 2
129 return 0
129 self.device.save()
130 else:
131 self.message = 'DDS REST restart fail'
132 self.device.status = 4
133 self.device.save()
134 except Exception as e:
135 self.message = 'DDS REST reset: {}'.format(str(e))
136 return False
130
137
131 self.message = 'DDS - {}'.format(answer[2:])
138 return True
132 return 1
133
139
134 def stop_device(self):
140 def stop_device(self):
135
141
136 try:
142 try:
137 answer = api.disable_rf(ip = self.device.ip_address,
143 payload = self.request('stop', 'post',data=json.dumps({'_rf_enable':0}))
138 port = self.device.port_address)
144 self.message = 'DDS REST: {}'.format(payload['stop'])
139
145 if payload['stop']=='ok':
140 return self.status_device()
146 self.device.status = 2
141
147 self.device.save()
148 else:
149 self.device.status = 4
150 self.device.save()
151 return False
142 except Exception as e:
152 except Exception as e:
143 self.message = str(e)
153 if 'No route to host' not in str(e):
154 self.device.status = 4
155 else:
156 self.device.status = 0
157 self.message = 'DDS REST stop: {}'.format(str(e))
158 self.device.save()
144 return False
159 return False
145
160
161 return True
162
146 def start_device(self):
163 def start_device(self):
147
164
148 try:
165 try:
149 answer = api.enable_rf(ip = self.device.ip_address,
166 payload = self.request('start', 'post',data=json.dumps({'_rf_enable':1}))
150 port = self.device.port_address)
167 self.message = 'DDS REST start: {}'.format(payload['start'])
151
168 if payload['start']=='ok':
152 return self.status_device()
169 self.device.status = 3
153
170 self.device.save()
171 else:
172 self.device.status = 2
173 self.device.save()
174 return False
154 except Exception as e:
175 except Exception as e:
155 self.message = str(e)
176 if 'No route to host' not in str(e):
177 self.device.status = 4
178 else:
179 self.device.status = 0
180 self.message = 'DDS REST start: {}'.format(str(e))
181 self.device.save()
156 return False
182 return False
157
183
184 return True
185
158 def read_device(self):
186 def read_device(self):
159
187
160 parms = api.read_config(ip = self.device.ip_address,
188 parms = self.request('read')
161 port = self.device.port_address)
189 print(parms)
162 if not parms:
190 if not parms:
163 self.message = "Could not read DDS parameters from this device"
191 self.message = "Could not read DDS REST parameters from this device"
164 return parms
192 return parms
165
193
166 self.message = ""
194 self.message = ""
167 return parms
195 return parms
168
196
169 def arma_control(self,l_clock,l_multiplier,l_modulation):
197 def arma_control(self,l_clock,l_multiplier,l_modulation):
170 sysclock = l_clock*l_multiplier
198 sysclock = l_clock*l_multiplier
171 pll_range = 0
199 pll_range = 0
172 if(sysclock>=200):
200 if(sysclock>=200):
173 pll_range = 1
201 pll_range = 1
174 l_control = ((l_modulation<<9)+(pll_range<<22)+(l_multiplier<<16)).to_bytes(4,'little')
202 l_control = ((l_modulation<<9)+(pll_range<<22)+(l_multiplier<<16)).to_bytes(4,'little')
175 return l_control
203 return l_control
176
204
177 def conv_phase(self,l_phase):
205 def conv_phase(self,l_phase):
178
206
179 l_phase_2B = int((l_phase*(2**14)/360)).to_bytes(2,'little')
207 l_phase_2B = int((l_phase*(2**14)/360)).to_bytes(2,'little')
180 return l_phase_2B
208 return l_phase_2B
181
209
182 def arma_data_write(self):
210 def arma_data_write(self):
183 #clock = RCClock.objects.get(rc_configuration=self)
211 #clock = RCClock.objects.get(rc_configuration=self)
184 clock = self.clock
212 clock = self.clock
185 print(clock)
213 print(clock)
186 multiplier = self.multiplier
214 multiplier = self.multiplier
187 print(multiplier)
215 print(multiplier)
188 frequencyA_Mhz = self.frequencyA_Mhz
216 frequencyA_Mhz = self.frequencyA_Mhz
189 print(frequencyA_Mhz)
217 print(frequencyA_Mhz)
190 frequencyA = self.frequencyA
218 frequencyA = self.frequencyA
191 print(frequencyA)
219 print(frequencyA)
192 frequencyB_Mhz = self.frequencyB_Mhz
220 frequencyB_Mhz = self.frequencyB_Mhz
193 print(frequencyB_Mhz)
221 print(frequencyB_Mhz)
194 frequencyB = self.frequencyB
222 frequencyB = self.frequencyB
195 print(frequencyB)
223 print(frequencyB)
196 phaseA_degrees = self.phaseA_degrees or 0
224 phaseA_degrees = self.phaseA_degrees or 0
197 print(phaseA_degrees)
225 print(phaseA_degrees)
198 phaseB_degrees = self.phaseB_degrees or 0
226 phaseB_degrees = self.phaseB_degrees or 0
199 print(phaseB_degrees)
227 print(phaseB_degrees)
200 modulation = self.modulation or 0
228 modulation = self.modulation or 0
201 print(modulation)
229 print(modulation)
202 amplitude_enabled = self.amplitude_enabled or 0
230 amplitude_enabled = self.amplitude_enabled or 0
203 print(amplitude_enabled)
231 print(amplitude_enabled)
204 amplitudeI = self.amplitudeI or 0
232 amplitudeI = self.amplitudeI or 0
205 print(amplitudeI)
233 print(amplitudeI)
206 amplitudeQ = self.amplitudeQ or 0
234 amplitudeQ = self.amplitudeQ or 0
207 print(amplitudeQ)
235 print(amplitudeQ)
208 delta_frequency = self.delta_frequency or 0
236 delta_frequency = self.delta_frequency or 0
209 print(delta_frequency)
237 print(delta_frequency)
210 update_clock = self.update_clock or 0
238 update_clock = self.update_clock or 0
211 print(update_clock)
239 print(update_clock)
212 ramp_rate_clock = self.ramp_rate_clock or 0
240 ramp_rate_clock = self.ramp_rate_clock or 0
213 print(ramp_rate_clock)
241 print(ramp_rate_clock)
214
242 osrr = 0
243 qdac = 0
215 control = self.arma_control(clock,multiplier,modulation)
244 control = self.arma_control(clock,multiplier,modulation)
216 phase1 = self.conv_phase(phaseA_degrees)
245 phase1 = self.conv_phase(phaseA_degrees)
217 phase2 = self.conv_phase(phaseB_degrees)
246 phase2 = self.conv_phase(phaseB_degrees)
218
247
219 cadena_json = {'clock': (b64encode(pack('<f',clock))).decode("UTF-8"),\
248 cadena_json = {'clock': (b64encode(pack('<f',clock))).decode("UTF-8"),\
220 'multiplier': (b64encode(pack('<B',multiplier))).decode("UTF-8"),\
249 'multiplier': (b64encode(pack('<B',multiplier))).decode("UTF-8"),\
221 'frequencyA': (b64encode((frequencyA).to_bytes(6,'little'))).decode("UTF-8"),\
250 'frequencyA': (b64encode((frequencyA).to_bytes(6,'little'))).decode("UTF-8"),\
222 'frequencyB': (b64encode((frequencyB).to_bytes(6,'little'))).decode("UTF-8"),\
251 'frequencyB': (b64encode((frequencyB).to_bytes(6,'little'))).decode("UTF-8"),\
223 'delta_frequency': (b64encode((delta_frequency).to_bytes(6,'little'))).decode("UTF-8"),\
252 'delta_frequency': (b64encode((delta_frequency).to_bytes(6,'little'))).decode("UTF-8"),\
224 'update_clock': (b64encode((update_clock).to_bytes(4,'little'))).decode("UTF-8"),\
253 'update_clock': (b64encode((update_clock).to_bytes(4,'little'))).decode("UTF-8"),\
225 'ramp_rate_clock': (b64encode((ramp_rate_clock).to_bytes(3,'little'))).decode("UTF-8"),\
254 'ramp_rate_clock': (b64encode((ramp_rate_clock).to_bytes(3,'little'))).decode("UTF-8"),\
226 'control': (b64encode(control)).decode("UTF-8"),\
255 'control': (b64encode(control)).decode("UTF-8"),\
227 'amplitudeI': (b64encode((amplitudeI).to_bytes(2,'little'))).decode("UTF-8"),\
256 'amplitudeI': (b64encode((amplitudeI).to_bytes(2,'little'))).decode("UTF-8"),\
228 'amplitudeQ': (b64encode((amplitudeQ).to_bytes(2,'little'))).decode("UTF-8"),\
257 'amplitudeQ': (b64encode((amplitudeQ).to_bytes(2,'little'))).decode("UTF-8"),\
229 '_phase1': (b64encode((phase1))).decode("UTF-8"),\
258 '_phase1': (b64encode((phase1))).decode("UTF-8"),\
230 '_phase2': (b64encode((phase2))).decode("UTF-8")
259 '_phase2': (b64encode((phase2))).decode("UTF-8"),\
260 'osrr': (b64encode((osrr).to_bytes(1,'little'))).decode("UTF-8"),\
261 'qdac': (b64encode((qdac).to_bytes(2,'little'))).decode("UTF-8")
231 }
262 }
232 return cadena_json
263 return cadena_json
233
264
234 def write_device(self, raw=False):
265 def write_device(self, raw=False):
235 print("Ingreso a write")
266 print("Ingreso a write")
236 try:
267 try:
237
268
238 if not raw:
269 if not raw:
239 data = self.arma_data_write()
270 data = self.arma_data_write()
240 print(data)
271 print(data)
241 payload = self.request('write', 'post', data=json.dumps(data))
272 payload = self.request('write', 'post', data=json.dumps(data))
242 print(payload)
273 print(payload)
243 if payload['write'] == 'ok':
274 if payload['write'] == 'ok':
244 self.device.status = 3
275 self.device.status = 3
245 self.device.save()
276 self.device.save()
246 self.message = 'DDS Rest write configured and started'
277 self.message = 'DDS Rest write configured and started'
247 else:
278 else:
248 self.message = payload['programming']
279 self.message = payload['programming']
249 if payload['programming'] == 'fail':
280 if payload['programming'] == 'fail':
250 self.message = 'DDS Rest write: error programming DDS chip'
281 self.message = 'DDS Rest write: error programming DDS chip'
251 if raw:
282 if raw:
252 return b64encode(data)
283 return b64encode(data)
253
284
254
285
255 except Exception as e:
286 except Exception as e:
256 if 'No route to host' not in str(e):
287 if 'No route to host' not in str(e):
257 self.device.status = 4
288 self.device.status = 4
258 else:
289 else:
259 self.device.status = 0
290 self.device.status = 0
260 self.message = 'DDS Rest write: {}'.format(str(e))
291 self.message = 'DDS Rest write: {}'.format(str(e))
261 self.device.save()
292 self.device.save()
262 return False
293 return False
263
294
264 return True
295 return True
265
296
266 def request(self, cmd, method='get', **kwargs):
297 def request(self, cmd, method='get', **kwargs):
267 print("Ingreso a request")
298 print("Ingreso a request")
268 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
299 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
269 payload = req.json()
300 payload = req.json()
270
301
271 return payload
302 return payload
272
303
273 class Meta:
304 class Meta:
274 db_table = 'ddsrest_configurations'
305 db_table = 'ddsrest_configurations'
@@ -1,463 +1,576
1 {% extends "dev_conf_edit.html" %}
1 {% extends "dev_conf_edit.html" %}
2 {% load bootstrap4 %}
2 {% load bootstrap4 %}
3 {% load static %}
3 {% load static %}
4 {% load main_tags %}
4 {% load main_tags %}
5
5
6 {% block dds_rest%}
6 {% block dds_rest%}
7
7
8 {% bootstrap_field form.template layout='horizontal' size='medium' %}
8 {% bootstrap_field form.template layout='horizontal' size='medium' %}
9 {% bootstrap_field form.device layout='horizontal' size='medium' %}
9 {% bootstrap_field form.device layout='horizontal' size='medium' %}
10 {% bootstrap_field form.label layout='horizontal' size='medium' %}
10 {% bootstrap_field form.label layout='horizontal' size='medium' %}
11 {% bootstrap_field form.experiment layout='horizontal' size='medium' %}
11 {% bootstrap_field form.experiment layout='horizontal' size='medium' %}
12
12
13 {% bootstrap_field form.clock layout='horizontal' size='medium' %}
13 {% bootstrap_field form.clock layout='horizontal' size='medium' %}
14 {% bootstrap_field form.multiplier layout='horizontal' size='medium' %}
14 {% bootstrap_field form.multiplier layout='horizontal' size='medium' %}
15
15
16 <div style="display: flex; justify-content: flex-end">
16 <div style="display: flex; justify-content: flex-end">
17 <div class="form-check">
17 <div class="form-check">
18 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_fA" value="" >Mostrar Decimal</label>
18 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_fA" value="" >Mostrar Decimal</label>
19 </div>
19 </div>
20 </div>
20 </div>
21 {% bootstrap_field form.frequencyA_Mhz layout='horizontal' size='medium' %}
21 {% bootstrap_field form.frequencyA_Mhz layout='horizontal' size='medium' %}
22 <div id='id_row_fAbin'>
22 <div id='id_row_fAbin'>
23 {% bootstrap_field form.frequencyA layout='horizontal' size='medium' %}
23 {% bootstrap_field form.frequencyA layout='horizontal' size='medium' %}
24 <div style="display: flex; justify-content: flex-end">
24 <div style="display: flex; justify-content: flex-end">
25 <small type="text" id="id_aux_fAbin" class="form-text text-muted">1000 0000 </small>
25 <small type="text" id="id_aux_fAbin" class="form-text text-muted">1000 0000 </small>
26 </div>
26 </div>
27 <br>
27 <br>
28 </div>
28 </div>
29
29
30 <div style="display: flex; justify-content: flex-end">
30 <div style="display: flex; justify-content: flex-end">
31 <div class="form-check">
31 <div class="form-check">
32 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_fB" value="" >Mostrar Decimal</label>
32 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_fB" value="" >Mostrar Decimal</label>
33 </div>
33 </div>
34 </div>
34 </div>
35 {% bootstrap_field form.frequencyB_Mhz layout='horizontal' size='medium' %}
35 {% bootstrap_field form.frequencyB_Mhz layout='horizontal' size='medium' %}
36 <div id='id_row_fBbin'>
36 <div id='id_row_fBbin'>
37 {% bootstrap_field form.frequencyB layout='horizontal' size='medium' %}
37 {% bootstrap_field form.frequencyB layout='horizontal' size='medium' %}
38 <div style="display: flex; justify-content: flex-end">
38 <div style="display: flex; justify-content: flex-end">
39 <small type="text" id="id_aux_fBbin" class="form-text text-muted">1000 0000 </small>
39 <small type="text" id="id_aux_fBbin" class="form-text text-muted">1000 0000 </small>
40 </div>
40 </div>
41 <br>
41 <br>
42 </div>
42 </div>
43
43
44 <div style="display: flex; justify-content: flex-end">
44 <div style="display: flex; justify-content: flex-end">
45 <div class="form-check">
45 <div class="form-check">
46 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_df" value="" >Mostrar Decimal</label>
46 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_df" value="" >Mostrar Decimal</label>
47 </div>
47 </div>
48 </div>
48 </div>
49 {% bootstrap_field form.delta_frequency_Mhz layout='horizontal' size='medium' %}
49 {% bootstrap_field form.delta_frequency_Mhz layout='horizontal' size='medium' %}
50 <div id='id_row_dfbin'>
50 <div id='id_row_dfbin'>
51 {% bootstrap_field form.delta_frequency layout='horizontal' size='medium' %}
51 {% bootstrap_field form.delta_frequency layout='horizontal' size='medium' %}
52 <div style="display: flex; justify-content: flex-end">
52 <div style="display: flex; justify-content: flex-end">
53 <small type="text" id="id_aux_deltabin" class="form-text text-muted">1000 0000 </small>
53 <small type="text" id="id_aux_deltabin" class="form-text text-muted">1000 0000 </small>
54 </div>
54 </div>
55 <br>
55 <br>
56 </div>
56 </div>
57
57
58 <div style="display: flex; justify-content: flex-end">
58 <div style="display: flex; justify-content: flex-end">
59 <div class="form-check">
59 <div class="form-check">
60 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_ramp" value="" >Mostrar Decimal</label>
60 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_ramp" value="" >Mostrar Decimal</label>
61 </div>
61 </div>
62 </div>
62 </div>
63 <div class="form-group row">
63 <div class="form-group row">
64 <label class="col-md-3 col-form-label" for="id_ramp_rate_clock_us">Ramp rate clock(us)</label>
64 <label class="col-md-3 col-form-label" for="id_ramp_rate_clock_us">Ramp rate clock(us)</label>
65 <div class="col-md-9">
65 <div class="col-md-9">
66 <input type="number" name="ramp_rate_clock_us" step="1e-16" class="form-control" placeHolder="Ramp rate clock(us)" title id="id_ramp_rate_clock_us">
66 <input type="number" name="ramp_rate_clock_us" step="1e-16" class="form-control" placeHolder="Ramp rate clock(us)" title id="id_ramp_rate_clock_us">
67 </div>
67 </div>
68 </div>
68 </div>
69 <div id='id_row_rampbin'>
69 <div id='id_row_rampbin'>
70 {% bootstrap_field form.ramp_rate_clock_Mhz layout='horizontal' size='medium' %}
70 {% bootstrap_field form.ramp_rate_clock_Mhz layout='horizontal' size='medium' %}
71 {% bootstrap_field form.ramp_rate_clock layout='horizontal' size='medium' %}
71 {% bootstrap_field form.ramp_rate_clock layout='horizontal' size='medium' %}
72 <div style="display: flex; justify-content: flex-end">
72 <div style="display: flex; justify-content: flex-end">
73 <small type="text" id="id_aux_rampbin" class="form-text text-muted">1000 0000 </small>
73 <small type="text" id="id_aux_rampbin" class="form-text text-muted">1000 0000 </small>
74 </div>
74 </div>
75 <br>
75 <br>
76 </div>
76 </div>
77
77
78 <div style="display: flex; justify-content: flex-end">
78 <div style="display: flex; justify-content: flex-end">
79 <div class="form-check">
79 <div class="form-check">
80 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_phaseA" value="" >Mostrar Decimal</label>
80 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_phaseA" value="" >Mostrar Decimal</label>
81 </div>
81 </div>
82 </div>
82 </div>
83 {% bootstrap_field form.phaseA_degrees layout='horizontal' size='medium' %}
83 {% bootstrap_field form.phaseA_degrees layout='horizontal' size='medium' %}
84 <div id='id_row_phaseA'>
84 <div id='id_row_phaseA'>
85 <div style="display: flex; justify-content: flex-end">
85 <div style="display: flex; justify-content: flex-end">
86 <small type="text" id="id_aux_phaseAdec" class="form-text text-muted">9282 </small>
86 <small type="text" id="id_aux_phaseAdec" class="form-text text-muted">9282 </small>
87 </div>
87 </div>
88 <div style="display: flex; justify-content: flex-end">
88 <div style="display: flex; justify-content: flex-end">
89 <small type="text" id="id_aux_phaseAbin" class="form-text text-muted">1000 0000 </small>
89 <small type="text" id="id_aux_phaseAbin" class="form-text text-muted">1000 0000 </small>
90 </div>
90 </div>
91 <br>
91 <br>
92 </div>
92 </div>
93
93
94 <div style="display: flex; justify-content: flex-end">
94 <div style="display: flex; justify-content: flex-end">
95 <div class="form-check">
95 <div class="form-check">
96 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_phaseB" value="" >Mostrar Decimal</label>
96 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_phaseB" value="" >Mostrar Decimal</label>
97 </div>
97 </div>
98 </div>
98 </div>
99 {% bootstrap_field form.phaseB_degrees layout='horizontal' size='medium' %}
99 {% bootstrap_field form.phaseB_degrees layout='horizontal' size='medium' %}
100 <div id='id_row_phaseB'>
100 <div id='id_row_phaseB'>
101 <div style="display: flex; justify-content: flex-end">
101 <div style="display: flex; justify-content: flex-end">
102 <small type="text" id="id_aux_phaseBdec" class="form-text text-muted">9876 </small>
102 <small type="text" id="id_aux_phaseBdec" class="form-text text-muted">9876 </small>
103 </div>
103 </div>
104 <div style="display: flex; justify-content: flex-end">
104 <div style="display: flex; justify-content: flex-end">
105 <small type="text" id="id_aux_phaseBbin" class="form-text text-muted">1000 0000 </small>
105 <small type="text" id="id_aux_phaseBbin" class="form-text text-muted">1000 0000 </small>
106 </div>
106 </div>
107 <br>
107 <br>
108 </div>
108 </div>
109
109
110 {% bootstrap_field form.modulation layout='horizontal' size='medium' %}
110 {% bootstrap_field form.modulation layout='horizontal' size='medium' %}
111 {% bootstrap_field form.amplitude_enabled layout='horizontal' size='medium' %}
111 {% bootstrap_field form.amplitude_enabled layout='horizontal' size='medium' %}
112
112
113 <div style="display: flex; justify-content: flex-end">
114 <div class="form-check">
115 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_amplitudeI" value="" >Mostrar Decimal</label>
116 </div>
117 </div>
113 {% bootstrap_field form.amplitudeI layout='horizontal' size='medium' %}
118 {% bootstrap_field form.amplitudeI layout='horizontal' size='medium' %}
119 <div id='id_row_amplitudeI'>
120 <div style="display: flex; justify-content: flex-end">
121 <small type="text" id="id_aux_amplitudeIdec" class="form-text text-muted">35 </small>
122 </div>
123 <div style="display: flex; justify-content: flex-end">
124 <small type="text" id="id_aux_amplitudeIbin" class="form-text text-muted">0000 0000 0010 </small>
125 </div>
126 <br>
127 </div>
128
129 <div style="display: flex; justify-content: flex-end">
130 <div class="form-check">
131 <label class="form-check-label" ><input type="checkbox" class="form-check-input" id="id_chkbin_amplitudeQ" value="" >Mostrar Decimal</label>
132 </div>
133 </div>
114 {% bootstrap_field form.amplitudeQ layout='horizontal' size='medium' %}
134 {% bootstrap_field form.amplitudeQ layout='horizontal' size='medium' %}
135 <div id='id_row_amplitudeQ'>
136 <div style="display: flex; justify-content: flex-end">
137 <small type="text" id="id_aux_amplitudeQdec" class="form-text text-muted">40 </small>
138 </div>
139 <div style="display: flex; justify-content: flex-end">
140 <small type="text" id="id_aux_amplitudeQbin" class="form-text text-muted">0000 1010 1000 </small>
141 </div>
142 <br>
143 </div>
115
144
116
145
117 {% endblock %}
146 {% endblock %}
118
147
119 {% block extra-js%}
148 {% block extra-js%}
120 <script src="{% static 'js/dds_conversion.js' %}"></script>
149 <script src="{% static 'js/dds_conversion.js' %}"></script>
121 <script type="text/javascript">
150 <script type="text/javascript">
122 $("#id_row_fAbin").hide();
151 $("#id_row_fAbin").hide();
123 $("#id_chkbin_fA").on('change', function() {
152 $("#id_chkbin_fA").on('change', function() {
124 hidefA();
153 hidefA();
125 });
154 });
126
155
127 $("#id_row_fBbin").hide();
156 $("#id_row_fBbin").hide();
128 $("#id_chkbin_fB").on('change', function() {
157 $("#id_chkbin_fB").on('change', function() {
129 hidefB();
158 hidefB();
130 });
159 });
131
160
132 $("#id_row_dfbin").hide();
161 $("#id_row_dfbin").hide();
133 $("#id_chkbin_df").on('change', function() {
162 $("#id_chkbin_df").on('change', function() {
134 hidedf();
163 hidedf();
135 });
164 });
136
165
137 $("#id_row_rampbin").hide();
166 $("#id_row_rampbin").hide();
138 $("#id_chkbin_ramp").on('change', function() {
167 $("#id_chkbin_ramp").on('change', function() {
139 hideramp();
168 hideramp();
140 });
169 });
141
170
142 $("#id_row_phaseA").hide();
171 $("#id_row_phaseA").hide();
143 $("#id_chkbin_phaseA").on('change', function() {
172 $("#id_chkbin_phaseA").on('change', function() {
144 hidephaseA();
173 hidephaseA();
145 });
174 });
146
175
147 $("#id_row_phaseB").hide();
176 $("#id_row_phaseB").hide();
148 $("#id_chkbin_phaseB").on('change', function() {
177 $("#id_chkbin_phaseB").on('change', function() {
149 hidephaseB();
178 hidephaseB();
150 });
179 });
151
180
181 $("#id_row_amplitudeI").hide();
182 $("#id_chkbin_amplitudeI").on('change', function() {
183 hideamplitudeI();
184 });
185
186 $("#id_row_amplitudeQ").hide();
187 $("#id_chkbin_amplitudeQ").on('change', function() {
188 hideamplitudeQ();
189 });
190
152 $("#id_clock").on('change', function() {
191 $("#id_clock").on('change', function() {
153 updateFrequencies();
192 updateFrequencies();
154 });
193 });
155
194
156 $("#id_multiplier").on('change', function() {
195 $("#id_multiplier").on('change', function() {
157 updateFrequencies();
196 updateFrequencies();
158 });
197 });
159
198
160 $("#id_frequencyA_Mhz").on('change', function() {
199 $("#id_frequencyA_Mhz").on('change', function() {
161 updateBinaryFrequencies();
200 updateBinaryFrequencies();
162 });
201 });
163
202
164 $("#id_frequencyA").on('change', function() {
203 $("#id_frequencyA").on('change', function() {
165 updateFrequencies();
204 updateFrequencies();
166 });
205 });
167
206
168 $("#id_frequencyB_Mhz").on('change', function() {
207 $("#id_frequencyB_Mhz").on('change', function() {
169 updateBinaryFrequencies();
208 updateBinaryFrequencies();
170 });
209 });
171
210
172 $("#id_frequencyB").on('change', function() {
211 $("#id_frequencyB").on('change', function() {
173 updateFrequencies();
212 updateFrequencies();
174 });
213 });
175
214
176 $("#id_delta_frequency").on('change', function() {
215 $("#id_delta_frequency").on('change', function() {
177 updateFrequencyDelta();
216 updateFrequencyDelta();
178 });
217 });
179
218
180 $("#id_delta_frequency_Mhz").on('change', function() {
219 $("#id_delta_frequency_Mhz").on('change', function() {
181 updateBinaryFrequencyDelta();
220 updateBinaryFrequencyDelta();
182 });
221 });
183
222
184 $("#id_ramp_rate_clock").on('change', function() {
223 $("#id_ramp_rate_clock").on('change', function() {
185 updateFrequencyRamp();
224 updateFrequencyRamp();
186 });
225 });
187
226
188 $("#id_ramp_rate_clock_us").on('change', function() {
227 $("#id_ramp_rate_clock_us").on('change', function() {
189 updateFrequencyMhzRamp();
228 updateFrequencyMhzRamp();
190 });
229 });
191
230
192 $("#id_ramp_rate_clock_Mhz").on('change', function() {
231 $("#id_ramp_rate_clock_Mhz").on('change', function() {
193 updateBinaryFrequencyRamp();
232 updateBinaryFrequencyRamp();
194 });
233 });
195
234
196 $("#id_phaseA_degrees").on('change', function() {
235 $("#id_phaseA_degrees").on('change', function() {
197 updatephaseAbindec();
236 updatephaseAbindec();
198 });
237 });
199
238
200 $("#id_phaseB_degrees").on('change', function() {
239 $("#id_phaseB_degrees").on('change', function() {
201 updatephaseBbindec();
240 updatephaseBbindec();
202 });
241 });
203
242
243 $("#id_amplitudeI").on('change', function() {
244 updateamplitudeIindec();
245 });
246
247 $("#id_amplitudeQ").on('change', function() {
248 updateamplitudeQindec();
249 });
250
204 function updateBinaryFrequencies() {
251 function updateBinaryFrequencies() {
205
252
206 var clock = $("#id_clock").val();
253 var clock = $("#id_clock").val();
207 var multiplier = $("#id_multiplier").val();
254 var multiplier = $("#id_multiplier").val();
208 var freq = $("#id_frequencyA_Mhz").val();
255 var freq = $("#id_frequencyA_Mhz").val();
209 var freq_mod = $("#id_frequencyB_Mhz").val();
256 var freq_mod = $("#id_frequencyB_Mhz").val();
210
257
211 var mclock = clock*multiplier;
258 var mclock = clock*multiplier;
212
259
213 var freq_bin = freq2Binary(mclock, freq);
260 var freq_bin = freq2Binary(mclock, freq);
214 var freq_mod_bin = freq2Binary(mclock, freq_mod);
261 var freq_mod_bin = freq2Binary(mclock, freq_mod);
215
262
216 $("#id_frequencyA").val(freq_bin);
263 $("#id_frequencyA").val(freq_bin);
217 $("#id_frequencyB").val(freq_mod_bin);
264 $("#id_frequencyB").val(freq_mod_bin);
218
265
219 freq = binary2Freq(mclock, freq_bin);
266 freq = binary2Freq(mclock, freq_bin);
220 freq_mod = binary2Freq(mclock, freq_mod_bin);
267 freq_mod = binary2Freq(mclock, freq_mod_bin);
221
268
222 $("#id_frequencyA_Mhz").val(freq);
269 $("#id_frequencyA_Mhz").val(freq);
223 $("#id_frequencyB_Mhz").val(freq_mod);
270 $("#id_frequencyB_Mhz").val(freq_mod);
224
271
225 }
272 }
226
273
227 function updateFrequencies() {
274 function updateFrequencies() {
228 console.log("Ingreso a updateFrequencies");
275 console.log("Ingreso a updateFrequencies");
229 var clock = $("#id_clock").val();
276 var clock = $("#id_clock").val();
230 var multiplier = $("#id_multiplier").val();
277 var multiplier = $("#id_multiplier").val();
231 var freq_bin = $("#id_frequencyA").val();
278 var freq_bin = $("#id_frequencyA").val();
232 var freq_mod_bin = $("#id_frequencyB").val();
279 var freq_mod_bin = $("#id_frequencyB").val();
233 var freqdelta_bin = $("#id_delta_frequency").val();
280 var freqdelta_bin = $("#id_delta_frequency").val();
234 var freqramp_bin = $("#id_ramp_rate_clock").val();
281 var freqramp_bin = $("#id_ramp_rate_clock").val();
235
282
236 var mclock = clock*multiplier;
283 var mclock = clock*multiplier;
237
284
238 var freq = binary2Freq(mclock, freq_bin);
285 var freq = binary2Freq(mclock, freq_bin);
239 var freq_mod = binary2Freq(mclock, freq_mod_bin);
286 var freq_mod = binary2Freq(mclock, freq_mod_bin);
240 var freqdelta = binary2FreqDelta(mclock, freqdelta_bin);
287 var freqdelta = binary2FreqDelta(mclock, freqdelta_bin);
241 var freq_ramp = binary2Ramp(mclock, freqramp_bin);
288 var freq_ramp = binary2Ramp(mclock, freqramp_bin);
242
289
243 $("#id_frequencyA_Mhz").val(freq);
290 $("#id_frequencyA_Mhz").val(freq);
244 $("#id_frequencyB_Mhz").val(freq_mod);
291 $("#id_frequencyB_Mhz").val(freq_mod);
245 $("#id_delta_frequency_Mhz").val(freqdelta);
292 $("#id_delta_frequency_Mhz").val(freqdelta);
246 $("#id_ramp_rate_clock_Mhz").val(freq_ramp);
293 $("#id_ramp_rate_clock_Mhz").val(freq_ramp);
247 }
294 }
248
295
249 function updateFrequencyDelta() {
296 function updateFrequencyDelta() {
250 console.log("Ingreso a updateFrequencyDelta");
297 console.log("Ingreso a updateFrequencyDelta");
251 var clock = $("#id_clock").val();
298 var clock = $("#id_clock").val();
252 var multiplier = $("#id_multiplier").val();
299 var multiplier = $("#id_multiplier").val();
253 var freq_bin = $("#id_delta_frequency").val();
300 var freq_bin = $("#id_delta_frequency").val();
254
301
255 var mclock = clock*multiplier;
302 var mclock = clock*multiplier;
256
303
257 var freq = binary2FreqDelta(mclock, freq_bin);
304 var freq = binary2FreqDelta(mclock, freq_bin);
258 console.log(freq);
305 console.log(freq);
259 $("#id_delta_frequency_Mhz").val(freq);
306 $("#id_delta_frequency_Mhz").val(freq);
260 }
307 }
261
308
262 function updateBinaryFrequencyDelta() {
309 function updateBinaryFrequencyDelta() {
263 console.log("Ingreso a updateBInaryFrequencyDelta");
310 console.log("Ingreso a updateBInaryFrequencyDelta");
264 var clock = $("#id_clock").val();
311 var clock = $("#id_clock").val();
265 var multiplier = $("#id_multiplier").val();
312 var multiplier = $("#id_multiplier").val();
266 var freq = $("#id_delta_frequency_Mhz").val();
313 var freq = $("#id_delta_frequency_Mhz").val();
267 console.log(clock);
314 console.log(clock);
268 console.log(multiplier);
315 console.log(multiplier);
269 console.log(freq);
316 console.log(freq);
270
317
271 var mclock = clock*multiplier;
318 var mclock = clock*multiplier;
272 console.log(mclock);
319 console.log(mclock);
273
320
274 var freq_bin = freqDelta2Binary(mclock, freq);
321 var freq_bin = freqDelta2Binary(mclock, freq);
275
322
276 console.log(freq_bin);
323 console.log(freq_bin);
277 $("#id_delta_frequency").val(freq_bin);
324 $("#id_delta_frequency").val(freq_bin);
278
325
279 document.getElementById("id_aux_deltabin").innerHTML = numToString(parseInt(freq_bin, 10), 2, 48).match(/.{1,4}/g).join(' ');
326 document.getElementById("id_aux_deltabin").innerHTML = numToString(parseInt(freq_bin, 10), 2, 48).match(/.{1,4}/g).join(' ');
280 }
327 }
281
328
282 function updateFrequencyRamp() {
329 function updateFrequencyRamp() {
283 console.log("Ingreso a updateFrequencyRamp");
330 console.log("Ingreso a updateFrequencyRamp");
284 var clock = $("#id_clock").val();
331 var clock = $("#id_clock").val();
285 var multiplier = $("#id_multiplier").val();
332 var multiplier = $("#id_multiplier").val();
286 var freq_bin = $("#id_ramp_rate_clock").val();
333 var freq_bin = $("#id_ramp_rate_clock").val();
287
334
288 var mclock = clock*multiplier;
335 var mclock = clock*multiplier;
289
336
290 var freq = binary2Ramp(mclock, freq_bin);
337 var freq = binary2Ramp(mclock, freq_bin);
291 console.log(freq);
338 console.log(freq);
292 $("#id_ramp_rate_clock_Mhz").val(freq);
339 $("#id_ramp_rate_clock_Mhz").val(freq);
293 }
340 }
294
341
295 function updateBinaryFrequencyRamp() {
342 function updateBinaryFrequencyRamp() {
296 console.log("Ingreso a updateBInaryFrequencyRamp");
343 console.log("Ingreso a updateBInaryFrequencyRamp");
297 var clock = $("#id_clock").val();
344 var clock = $("#id_clock").val();
298 var multiplier = $("#id_multiplier").val();
345 var multiplier = $("#id_multiplier").val();
299 var freq = $("#id_ramp_rate_clock_Mhz").val();
346 var freq = $("#id_ramp_rate_clock_Mhz").val();
300
347
301 var mclock = clock*multiplier;
348 var mclock = clock*multiplier;
302
349
303 var freq_bin = freqRamp2Binary(mclock, freq);
350 var freq_bin = freqRamp2Binary(mclock, freq);
304 console.log(freq_bin);
351 console.log(freq_bin);
305 $("#id_ramp_rate_clock").val(freq_bin);
352 $("#id_ramp_rate_clock").val(freq_bin);
306 }
353 }
307
354
308 function updateFrequencyMhzRamp() {
355 function updateFrequencyMhzRamp() {
309 console.log("Ingreso a updateFrequencyMhzRamp");
356 console.log("Ingreso a updateFrequencyMhzRamp");
310 var step_us = $("#id_ramp_rate_clock_us").val();
357 var step_us = $("#id_ramp_rate_clock_us").val();
311
358
312 var freq = us2Ramp(step_us);
359 var freq = us2Ramp(step_us);
313 console.log(freq);
360 console.log(freq);
314 $("#id_ramp_rate_clock_Mhz").val(freq);
361 $("#id_ramp_rate_clock_Mhz").val(freq);
315 updateBinaryFrequencyRamp();
362 updateBinaryFrequencyRamp();
316 }
363 }
317
364
318 function hidefA() {
365 function hidefA() {
319 var checkbox = $("#id_chkbin_fA");
366 var checkbox = $("#id_chkbin_fA");
320 var freq_bin = $("#id_row_fAbin");
367 var freq_bin = $("#id_row_fAbin");
321 var val_freq = $("#id_frequencyA");
368 var val_freq = $("#id_frequencyA");
322
369
323 console.log("Ingreso a hidefA");
370 console.log("Ingreso a hidefA");
324 if (checkbox.is(':checked')) {
371 if (checkbox.is(':checked')) {
325 freq_bin.show();
372 freq_bin.show();
326 console.log(val_freq.val());
373 console.log(val_freq.val());
327 document.getElementById("id_aux_fAbin").innerHTML = numToString(parseInt(val_freq.val(), 10), 2, 48).match(/.{1,4}/g).join(' ');
374 document.getElementById("id_aux_fAbin").innerHTML = numToString(parseInt(val_freq.val(), 10), 2, 48).match(/.{1,4}/g).join(' ');
328 }
375 }
329 else{
376 else{
330 freq_bin.hide();
377 freq_bin.hide();
331 }
378 }
332 }
379 }
333
380
334 function hidefB() {
381 function hidefB() {
335 var checkbox = $("#id_chkbin_fB");
382 var checkbox = $("#id_chkbin_fB");
336 var freq_bin = $("#id_row_fBbin");
383 var freq_bin = $("#id_row_fBbin");
337 var val_freq = $("#id_frequencyB");
384 var val_freq = $("#id_frequencyB");
338
385
339 console.log("Ingreso a hidefB");
386 console.log("Ingreso a hidefB");
340 if (checkbox.is(':checked')) {
387 if (checkbox.is(':checked')) {
341 freq_bin.show();
388 freq_bin.show();
342 console.log(val_freq.val());
389 console.log(val_freq.val());
343 document.getElementById("id_aux_fBbin").innerHTML = numToString(parseInt(val_freq.val(), 10), 2, 48).match(/.{1,4}/g).join(' ');
390 document.getElementById("id_aux_fBbin").innerHTML = numToString(parseInt(val_freq.val(), 10), 2, 48).match(/.{1,4}/g).join(' ');
344 }
391 }
345 else{
392 else{
346 freq_bin.hide();
393 freq_bin.hide();
347 }
394 }
348 }
395 }
349
396
350 function hidedf() {
397 function hidedf() {
351 var checkbox = $("#id_chkbin_df");
398 var checkbox = $("#id_chkbin_df");
352 var freq_bin = $("#id_row_dfbin");
399 var freq_bin = $("#id_row_dfbin");
353 var val_freq = $("#id_delta_frequency");
400 var val_freq = $("#id_delta_frequency");
354
401
355 console.log("Ingreso a hidedf");
402 console.log("Ingreso a hidedf");
356 if (checkbox.is(':checked')) {
403 if (checkbox.is(':checked')) {
357 freq_bin.show();
404 freq_bin.show();
358 console.log(val_freq.val());
405 console.log(val_freq.val());
359 document.getElementById("id_aux_deltabin").innerHTML = numToString(parseInt(val_freq.val(), 10), 2, 48).match(/.{1,4}/g).join(' ');
406 document.getElementById("id_aux_deltabin").innerHTML = numToString(parseInt(val_freq.val(), 10), 2, 48).match(/.{1,4}/g).join(' ');
360 }
407 }
361 else{
408 else{
362 freq_bin.hide();
409 freq_bin.hide();
363 }
410 }
364 }
411 }
365
412
366 function hideramp() {
413 function hideramp() {
367 var checkbox = $("#id_chkbin_ramp");
414 var checkbox = $("#id_chkbin_ramp");
368 var freq_bin = $("#id_row_rampbin");
415 var freq_bin = $("#id_row_rampbin");
369 var val_freq = $("#id_ramp_rate_clock");
416 var val_freq = $("#id_ramp_rate_clock");
370
417
371 console.log("Ingreso a hideramp");
418 console.log("Ingreso a hideramp");
372 if (checkbox.is(':checked')) {
419 if (checkbox.is(':checked')) {
373 freq_bin.show();
420 freq_bin.show();
374 console.log(val_freq.val());
421 console.log(val_freq.val());
375 document.getElementById("id_aux_rampbin").innerHTML = numToString(parseInt(val_freq.val(), 10), 2, 20).match(/.{1,4}/g).join(' ');
422 document.getElementById("id_aux_rampbin").innerHTML = numToString(parseInt(val_freq.val(), 10), 2, 20).match(/.{1,4}/g).join(' ');
376 }
423 }
377 else{
424 else{
378 freq_bin.hide();
425 freq_bin.hide();
379 }
426 }
380 }
427 }
381
428
382 function hidephaseA() {
429 function hidephaseA() {
383 var checkbox = $("#id_chkbin_phaseA");
430 var checkbox = $("#id_chkbin_phaseA");
384 var freq_bin = $("#id_row_phaseA");
431 var freq_bin = $("#id_row_phaseA");
385 var phase_degree = $("#id_phaseA_degrees");
432 var phase_degree = $("#id_phaseA_degrees");
386
433
387 console.log("Ingreso a hidephaseA");
434 console.log("Ingreso a hidephaseA");
388 if (checkbox.is(':checked')) {
435 if (checkbox.is(':checked')) {
389 freq_bin.show();
436 freq_bin.show();
390 console.log(phase_degree.val());
437 console.log(phase_degree.val());
391 var phase_degree_dec = parseInt(phase_degree.val()*((2**14)/360.0),10);
438 var phase_degree_dec = parseInt(phase_degree.val()*((2**14-1)/360.0),10);
392 console.log(phase_degree_dec);
439 console.log(phase_degree_dec);
393 document.getElementById("id_aux_phaseAdec").innerHTML = numToString(phase_degree_dec, 10, 5).match(/.{1,4}/g).join(' ');
440 document.getElementById("id_aux_phaseAdec").innerHTML = numToString(phase_degree_dec, 10, 5).match(/.{1,4}/g).join(' ');
394 document.getElementById("id_aux_phaseAbin").innerHTML = numToString(parseInt(phase_degree_dec, 10), 2, 14).match(/.{1,4}/g).join(' ');
441 document.getElementById("id_aux_phaseAbin").innerHTML = numToString(parseInt(phase_degree_dec, 10), 2, 14).match(/.{1,4}/g).join(' ');
395
442
396 }
443 }
397 else{
444 else{
398 freq_bin.hide();
445 freq_bin.hide();
399 }
446 }
400 }
447 }
401
448
402 function hidephaseB() {
449 function hidephaseB() {
403 var checkbox = $("#id_chkbin_phaseB");
450 var checkbox = $("#id_chkbin_phaseB");
404 var freq_bin = $("#id_row_phaseB");
451 var freq_bin = $("#id_row_phaseB");
405 var phase_degree = $("#id_phaseB_degrees");
452 var phase_degree = $("#id_phaseB_degrees");
406
453
407 console.log("Ingreso a hidephaseB");
454 console.log("Ingreso a hidephaseB");
408 if (checkbox.is(':checked')) {
455 if (checkbox.is(':checked')) {
409 freq_bin.show();
456 freq_bin.show();
410 console.log(phase_degree.val());
457 console.log(phase_degree.val());
411 var phase_degree_dec = parseInt(phase_degree.val()*((2**14)/360.0),10);
458 var phase_degree_dec = parseInt(phase_degree.val()*((2**14-1)/360.0),10);
412 console.log(phase_degree_dec);
459 console.log(phase_degree_dec);
413 document.getElementById("id_aux_phaseBdec").innerHTML = numToString(phase_degree_dec, 10, 5).match(/.{1,4}/g).join(' ');
460 document.getElementById("id_aux_phaseBdec").innerHTML = numToString(phase_degree_dec, 10, 5).match(/.{1,4}/g).join(' ');
414 document.getElementById("id_aux_phaseBbin").innerHTML = numToString(parseInt(phase_degree_dec, 10), 2, 14).match(/.{1,4}/g).join(' ');
461 document.getElementById("id_aux_phaseBbin").innerHTML = numToString(parseInt(phase_degree_dec, 10), 2, 14).match(/.{1,4}/g).join(' ');
415
462
416 }
463 }
417 else{
464 else{
418 freq_bin.hide();
465 freq_bin.hide();
419 }
466 }
420 }
467 }
421
468
469 function hideamplitudeI() {
470 var checkbox = $("#id_chkbin_amplitudeI");
471 var freq_bin = $("#id_row_amplitudeI");
472 var phase_degree = $("#id_amplitudeI");
473
474 console.log("Ingreso a hideamplitudeI");
475 if (checkbox.is(':checked')) {
476 freq_bin.show();
477 console.log(phase_degree.val());
478 var phase_degree_dec = parseInt(phase_degree.val()*((2**12-1)/100.0),10);
479 console.log(phase_degree_dec);
480 document.getElementById("id_aux_amplitudeIdec").innerHTML = numToString(phase_degree_dec, 10, 4).match(/.{1,4}/g).join(' ');
481 document.getElementById("id_aux_amplitudeIbin").innerHTML = numToString(parseInt(phase_degree_dec, 10), 2, 12).match(/.{1,4}/g).join(' ');
482
483 }
484 else{
485 freq_bin.hide();
486 }
487 }
488
489 function hideamplitudeQ() {
490 var checkbox = $("#id_chkbin_amplitudeQ");
491 var freq_bin = $("#id_row_amplitudeQ");
492 var phase_degree = $("#id_amplitudeQ");
493
494 console.log("Ingreso a hideamplitudeQ");
495 if (checkbox.is(':checked')) {
496 freq_bin.show();
497 console.log(phase_degree.val());
498 var phase_degree_dec = parseInt(phase_degree.val()*((2**12-1)/100.0),10);
499 console.log(phase_degree_dec);
500 document.getElementById("id_aux_amplitudeQdec").innerHTML = numToString(phase_degree_dec, 10, 4).match(/.{1,4}/g).join(' ');
501 document.getElementById("id_aux_amplitudeQbin").innerHTML = numToString(parseInt(phase_degree_dec, 10), 2, 12).match(/.{1,4}/g).join(' ');
502
503 }
504 else{
505 freq_bin.hide();
506 }
507 }
508
422 function updatephaseAbindec() {
509 function updatephaseAbindec() {
423 var freq_bin = $("#id_row_phaseA");
510 var freq_bin = $("#id_row_phaseA");
424 var phase_degree = $("#id_phaseA_degrees");
511 var phase_degree = $("#id_phaseA_degrees");
425
512
426 console.log("Ingreso a cupdatephaseAbindec");
513 console.log("Ingreso a updatephaseAbindec");
427 console.log(phase_degree.val());
514 console.log(phase_degree.val());
428 var phase_degree_dec = parseInt(phase_degree.val()*((2**14)/360.0),10);
515 var phase_degree_dec = parseInt(phase_degree.val()*((2**14-1)/360.0),10);
429 console.log(phase_degree_dec);
516 console.log(phase_degree_dec);
430 document.getElementById("id_aux_phaseAdec").innerHTML = numToString(phase_degree_dec, 10, 5).match(/.{1,4}/g).join(' ');
517 document.getElementById("id_aux_phaseAdec").innerHTML = numToString(phase_degree_dec, 10, 5).match(/.{1,4}/g).join(' ');
431 document.getElementById("id_aux_phaseAbin").innerHTML = numToString(parseInt(phase_degree_dec, 10), 2, 14).match(/.{1,4}/g).join(' ');
518 document.getElementById("id_aux_phaseAbin").innerHTML = numToString(parseInt(phase_degree_dec, 10), 2, 14).match(/.{1,4}/g).join(' ');
432
519
433 }
520 }
434
521
435 function updatephaseBbindec() {
522 function updatephaseBbindec() {
436 var freq_bin = $("#id_row_phaseB");
523 var freq_bin = $("#id_row_phaseB");
437 var phase_degree = $("#id_phaseB_degrees");
524 var phase_degree = $("#id_phaseB_degrees");
438
525
439 console.log("Ingreso a cupdatephaseBbindec");
526 console.log("Ingreso a updatephaseBbindec");
440 console.log(phase_degree.val());
527 console.log(phase_degree.val());
441 var phase_degree_dec = parseInt(phase_degree.val()*((2**14)/360.0),10);
528 var phase_degree_dec = parseInt(phase_degree.val()*((2**14-1)/360.0),10);
442 console.log(phase_degree_dec);
529 console.log(phase_degree_dec);
443 document.getElementById("id_aux_phaseBdec").innerHTML = numToString(phase_degree_dec, 10, 5).match(/.{1,4}/g).join(' ');
530 document.getElementById("id_aux_phaseBdec").innerHTML = numToString(phase_degree_dec, 10, 5).match(/.{1,4}/g).join(' ');
444 document.getElementById("id_aux_phaseBbin").innerHTML = numToString(parseInt(phase_degree_dec, 10), 2, 14).match(/.{1,4}/g).join(' ');
531 document.getElementById("id_aux_phaseBbin").innerHTML = numToString(parseInt(phase_degree_dec, 10), 2, 14).match(/.{1,4}/g).join(' ');
445
532
446 }
533 }
447
534
535 // Para ingresar amplitud CH1 como porcentaje y devuelve en decimal y binario
536 function updateamplitudeIindec() {
537 var freq_bin = $("#id_row_amplitudeI");
538 var phase_degree = $("#id_amplitudeI");
539
540 console.log("Ingreso a updateamplitudeIindec");
541 console.log(phase_degree.val());
542 var phase_degree_dec = parseInt(phase_degree.val()*((2**12-1)/100.0),10);
543 console.log(phase_degree_dec);
544 document.getElementById("id_aux_amplitudeIdec").innerHTML = numToString(phase_degree_dec, 10, 4).match(/.{1,4}/g).join(' ');
545 document.getElementById("id_aux_amplitudeIbin").innerHTML = numToString(parseInt(phase_degree_dec, 10), 2, 12).match(/.{1,4}/g).join(' ');
546 }
547
548 // Para ingresar amplitud CH1 como porcentaje y devuelve en decimal y binario
549 function updateamplitudeQindec() {
550 var freq_bin = $("#id_row_amplitudeQ");
551 var phase_degree = $("#id_amplitudeQ");
552
553 console.log("Ingreso a updateamplitudeQindec");
554 console.log(phase_degree.val());
555 var phase_degree_dec = parseInt(phase_degree.val()*((2**12-1)/100.0),10);
556 console.log(phase_degree_dec);
557 document.getElementById("id_aux_amplitudeQdec").innerHTML = numToString(phase_degree_dec, 10, 4).match(/.{1,4}/g).join(' ');
558 document.getElementById("id_aux_amplitudeQbin").innerHTML = numToString(parseInt(phase_degree_dec, 10), 2, 12).match(/.{1,4}/g).join(' ');
559 }
560
448 function padStart(string, length, char) {
561 function padStart(string, length, char) {
449 return length > 0 ?
562 return length > 0 ?
450 padStart(char + string, --length, char) :
563 padStart(char + string, --length, char) :
451 string;
564 string;
452 }
565 }
453
566
454 function numToString(num, radix, length = num.length) {
567 function numToString(num, radix, length = num.length) {
455 const numString = num.toString(radix);
568 const numString = num.toString(radix);
456 return numString.length === length ?
569 return numString.length === length ?
457 numString :
570 numString :
458 padStart(numString, length - numString.length, "0")
571 padStart(numString, length - numString.length, "0")
459 }
572 }
460
573
461 console.log(numToString(parseInt("37529996894754", 10), 2, 48));
574 console.log(numToString(parseInt("37529996894754", 10), 2, 48));
462 </script>
575 </script>
463 {% endblock %} No newline at end of file
576 {% endblock %}
@@ -1,130 +1,138
1 [
1 [
2 {
2 {
3 "fields": {
3 "fields": {
4 "name": "JRO",
4 "name": "JRO",
5 "description": ""
5 "description": ""
6 },
6 },
7 "model": "main.location",
7 "model": "main.location",
8 "pk": 1
8 "pk": 1
9 },
9 },
10 {
10 {
11 "fields": {
11 "fields": {
12 "name": "JASMET",
12 "name": "JASMET",
13 "description": ""
13 "description": ""
14 },
14 },
15 "model": "main.location",
15 "model": "main.location",
16 "pk": 2
16 "pk": 2
17 },
17 },
18 {
18 {
19 "fields": {
19 "fields": {
20 "name": "SOUSY",
20 "name": "SOUSY",
21 "description": ""
21 "description": ""
22 },
22 },
23 "model": "main.location",
23 "model": "main.location",
24 "pk": 3
24 "pk": 3
25 },
25 },
26 {
26 {
27 "fields": {
27 "fields": {
28 "name": "JULIA",
28 "name": "JULIA",
29 "description": ""
29 "description": ""
30 },
30 },
31 "model": "main.location",
31 "model": "main.location",
32 "pk": 4
32 "pk": 4
33 },
33 },
34 {
34 {
35 "fields": {
35 "fields": {
36 "name": "CLAIRE",
36 "name": "CLAIRE",
37 "description": ""
37 "description": ""
38 },
38 },
39 "model": "main.location",
39 "model": "main.location",
40 "pk": 5
40 "pk": 5
41 },
41 },
42 {
42 {
43 "fields": {
43 "fields": {
44 "name": "IDI",
44 "name": "IDI",
45 "description": ""
45 "description": ""
46 },
46 },
47 "model": "main.location",
47 "model": "main.location",
48 "pk": 6
48 "pk": 6
49 },
49 },
50 {
50 {
51 "fields": {
51 "fields": {
52 "name": "rc",
52 "name": "rc",
53 "description": ""
53 "description": ""
54 },
54 },
55 "model": "main.devicetype",
55 "model": "main.devicetype",
56 "pk": 1
56 "pk": 1
57 },
57 },
58 {
58 {
59 "fields": {
59 "fields": {
60 "name": "dds",
60 "name": "dds",
61 "description": ""
61 "description": ""
62 },
62 },
63 "model": "main.devicetype",
63 "model": "main.devicetype",
64 "pk": 2
64 "pk": 2
65 },
65 },
66 {
66 {
67 "fields": {
67 "fields": {
68 "name": "cgs",
68 "name": "cgs",
69 "description": ""
69 "description": ""
70 },
70 },
71 "model": "main.devicetype",
71 "model": "main.devicetype",
72 "pk": 3
72 "pk": 3
73 },
73 },
74 {
74 {
75 "fields": {
75 "fields": {
76 "name": "jars",
76 "name": "jars",
77 "description": ""
77 "description": ""
78 },
78 },
79 "model": "main.devicetype",
79 "model": "main.devicetype",
80 "pk": 4
80 "pk": 4
81 },
81 },
82 {
82 {
83 "fields": {
83 "fields": {
84 "name": "abs",
84 "name": "abs",
85 "description": ""
85 "description": ""
86 },
86 },
87 "model": "main.devicetype",
87 "model": "main.devicetype",
88 "pk": 5
88 "pk": 5
89 },
89 },
90 {
90 {
91 "fields": {
91 "fields": {
92 "name": "dds_rest",
93 "description": ""
94 },
95 "model": "main.devicetype",
96 "pk": 6
97 },
98 {
99 "fields": {
92 "name": "Operator"
100 "name": "Operator"
93 },
101 },
94 "model": "auth.group",
102 "model": "auth.group",
95 "pk": 1
103 "pk": 1
96 },
104 },
97 {
105 {
98 "fields": {
106 "fields": {
99 "name": "Developer"
107 "name": "Developer"
100 },
108 },
101 "model": "auth.group",
109 "model": "auth.group",
102 "pk": 2
110 "pk": 2
103 },
111 },
104 {
112 {
105 "fields": {
113 "fields": {
106 "password": "pbkdf2_sha256$24000$6RRL7xETgdgN$ORRPhrITZKzTTZHCm8T+Er6ght415kYKeU7QP3rry5M=",
114 "password": "pbkdf2_sha256$24000$6RRL7xETgdgN$ORRPhrITZKzTTZHCm8T+Er6ght415kYKeU7QP3rry5M=",
107 "last_login": null,
115 "last_login": null,
108 "is_superuser": true,
116 "is_superuser": true,
109 "username": "admin",
117 "username": "admin",
110 "first_name": "Administrador",
118 "first_name": "Administrador",
111 "last_name": "IDI",
119 "last_name": "IDI",
112 "email": "admin@admin.com",
120 "email": "admin@admin.com",
113 "is_staff": true,
121 "is_staff": true,
114 "is_active": true,
122 "is_active": true,
115 "date_joined": "2017-01-12T16:10:24.383",
123 "date_joined": "2017-01-12T16:10:24.383",
116 "groups": [],
124 "groups": [],
117 "user_permissions": []
125 "user_permissions": []
118 },
126 },
119 "model": "auth.user",
127 "model": "auth.user",
120 "pk": 1
128 "pk": 1
121 },
129 },
122 {
130 {
123 "fields": {
131 "fields": {
124 "user": 1,
132 "user": 1,
125 "theme": "spacelab"
133 "theme": "spacelab"
126 },
134 },
127 "model": "main.profile",
135 "model": "main.profile",
128 "pk": 1
136 "pk": 1
129 }
137 }
130 ]
138 ]
@@ -1,142 +1,219
1
1
2 :root{
2 :root{
3 --primary: #0200AE;
3 --primary: #0200AE;
4 --dark-primary: #000080;
4 --dark-primary: #000080;
5 --light-primary: rgb(0, 0, 179, .7);
5 --light-primary: rgb(0, 0, 179, .7);
6 --secondary: #6F6F6F;
6 --secondary: #6F6F6F;
7 --tertiary: #0099FF;
7 --tertiary: #0099FF;
8 --color-txt: #333;
8 --color-txt: #333;
9 --bg-main: rgba(80, 80, 80, .8);
9 --bg-main: rgba(80, 80, 80, .8);
10 --bg-invert: rgba(0, 0, 0, .2);
10 --bg-invert: rgba(0, 0, 0, .2);
11 --bg-sections: #f9f9f9;
11 --bg-sections: #f9f9f9;
12 --bd-sections: 1px solid #D9D9D9;
12 --bd-sections: 1px solid #D9D9D9;
13 --fs-nav: .875em;
13 --fs-nav: .875em;
14 --fs-trail: .87rem;
14 --fs-trail: .87rem;
15 --hover-nav: rgba(0, 0, 0, 0.3);
15 --hover-nav: rgba(0, 0, 0, 0.3);
16 --fg-nav: #2068A0;
16 --fg-nav: #2068A0;
17 --bs-nav: rgba(43, 43, 43, .4);
17 --bs-nav: rgba(43, 43, 43, .4);
18 --bs-input: rgba(0, 113, 184, 0.5);
18 --bs-input: rgba(0, 113, 184, 0.5);
19 --bd-input: rgba(56, 181, 230, 0.75);
19 --bd-input: rgba(56, 181, 230, 0.75);
20 --bd-item: 1px solid #C9C9C9;
20 --bd-item: 1px solid #C9C9C9;
21 --bx-shadow: 0 2px 5px 0 var(--bs-nav);
21 --bx-shadow: 0 2px 5px 0 var(--bs-nav);
22 }
22 }
23
23
24 body {
24 body {
25 color: #444;
25 color: #444;
26 font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
26 font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
27 font-size: 14px;
27 font-size: 14px;
28 }
28 }
29
29
30 main {
30 main {
31 min-width: 100%;
31 min-width: 100%;
32 min-height: 400px;
32 min-height: 400px;
33 }
33 }
34
34
35 a:link { -webkit-tap-highlight-color: var(--tertiary); }
35 a:link { -webkit-tap-highlight-color: var(--tertiary); }
36
36
37 .titulo {
37 .titulo {
38 color: #898989;
38 color: #898989;
39 font-size: 2rem;
39 font-size: 2rem;
40 font-family: 'Dosis', Arial, Verdana, serif;
40 font-family: 'Dosis', Arial, Verdana, serif;
41 }
41 }
42
42
43 .titulo:after {
43 .titulo:after {
44 display: flex;
44 display: flex;
45 width: 60px;
45 width: 60px;
46 border-bottom: 3px solid #48C7EC;
46 border-bottom: 3px solid #48C7EC;
47 content: '';
47 content: '';
48 padding-top: .5rem;
48 padding-top: .5rem;
49 margin: 0;
49 margin: 0;
50 }
50 }
51
51
52 #sidebar a {
52 #sidebar a {
53 color: gray;
53 color: gray;
54 padding: 0.1rem;
54 padding: 0.1rem;
55 }
55 }
56
56
57 #sidebar h5 {
57 #sidebar h5 {
58 color:#333;
58 color:#333;
59 }
59 }
60
60
61 .text-blue {
61 .text-blue {
62 color: #003A8E;
62 color: #003A8E;
63 }
63 }
64
64
65 .text-skyblue {
65 .text-skyblue {
66 color: #00addc;
66 color: #00addc;
67 }
67 }
68
68
69 .nopadding {
69 .nopadding {
70 padding: 0px !important;
70 padding: 0px !important;
71 }
71 }
72
72
73 .nomargin {
73 .nomargin {
74 margin: 0px !important;
74 margin: 0px !important;
75 }
75 }
76
76
77 .legend {
77 .legend {
78 list-style: none;
78 list-style: none;
79 padding-left: 1rem;
79 padding-left: 1rem;
80 padding-top: 1rem;
80 padding-top: 1rem;
81 }
81 }
82
82
83 .legend span {
83 .legend span {
84 padding-left: 1em;
84 padding-left: 1em;
85 }
85 }
86
86
87 #loader {
87 #loader {
88 margin-top: 40px;
88 margin-top: 40px;
89 color: var(--tertiary);
89 color: var(--tertiary);
90 }
90 }
91
91
92 #plot {
92 #plot {
93 margin-top: 2em;
93 margin-top: 2em;
94 margin-bottom: 2em;
94 margin-bottom: 2em;
95 }
95 }
96
96
97 /* Change Buttons Bootstrap */
97 /* Change Buttons Bootstrap */
98 .btn-primary {
98 .btn-primary {
99 color: #fff;
99 color: #fff;
100 background-color: #00addc !important;
100 background-color: #00addc !important;
101 border-color: #00addc !important;
101 border-color: #00addc !important;
102 }
102 }
103
103
104 .btn-primary:hover {
104 .btn-primary:hover {
105 color: #fff;
105 color: #fff;
106 background-color: #23527c !important;
106 background-color: #23527c !important;
107 border-color: #23527c !important;
107 border-color: #23527c !important;
108 }
108 }
109
109
110 .card-text {
110 .card-text {
111 font-size: 0.8rem;
111 font-size: 0.8rem;
112 }
112 }
113
113
114 .tools-date {
114 .tools-date {
115 font-size: 0.8rem;
115 font-size: 0.8rem;
116 }
116 }
117
117
118 /*------------------------------------------------*/
119
120 .panel {
121 margin-bottom: 20px;
122 background-color: #fafafa;
123 border: 1px solid transparent;
124 border-radius: 4px;
125 -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
126 box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
127 }
128 .panel-body {
129 padding: 15px;
130 }
131 .panel-heading {
132 padding: 10px 15px;
133 border-bottom: 1px solid transparent;
134 border-top-left-radius: 3px;
135 border-top-right-radius: 3px;
136 }
137
138 .panel-title {
139 margin-top: 0;
140 margin-bottom: 0;
141
142
143 }
144
145 .panel-footer {
146 padding: 10px 15px;
147 background-color: #fafafa;
148 border-top: 1px solid #fafafa;
149 border-bottom-right-radius: 3px;
150 border-bottom-left-radius: 3px;
151 }
152
153 .panel-group {
154 margin-bottom: 20px;
155 }
156 .panel-group .panel {
157 margin-bottom: 0;
158 border-radius: 4px;
159 }
160 .panel-group .panel + .panel {
161 margin-top: 5px;
162 }
163 .panel-group .panel-heading {
164 border-bottom: 0;
165 }
166 .panel-group .panel-heading + .panel-collapse > .panel-body,
167
168 .panel-group .panel-footer {
169 border-top: 0;
170 }
171 .panel-group .panel-footer + .panel-collapse .panel-body {
172 border-bottom: 1px solid #fafafa;
173 }
174 .panel-default {
175 border-color: #fafafa;
176 }
177 .panel-default > .panel-heading {
178
179 background-color: #fafafa;
180 border-color: #fafafa;
181 }
182 .panel-default > .panel-heading + .panel-collapse > .panel-body {
183 border-top-color: #fafafa;
184 }
185 .panel-default > .panel-heading .badge {
186 color: #fafafa;
187 background-color: #fafafa;
188 }
189 .panel-default > .panel-footer + .panel-collapse > .panel-body {
190 border-bottom-color: #fafafa;
191 }
192
193
118 /* cards */
194 /* cards */
119
195
120 @media (min-width: 480px) {
196 @media (min-width: 480px) {
121 .card-columns {
197 .card-columns {
122 column-count: 2;
198 column-count: 2;
123 }
199 }
124 }
200 }
125
201
126 @media (min-width: 768px) {
202 @media (min-width: 768px) {
127 .card-columns {
203 .card-columns {
128 column-count: 3;
204 column-count: 3;
129 }
205 }
130 }
206 }
131
207
132 @media (min-width: 1180px) {
208 @media (min-width: 1180px) {
133 .card-columns {
209 .card-columns {
134 column-count: 4;
210 column-count: 4;
135 }
211 }
136 }
212 }
137
213
138 @media (min-width: 1380px) {
214 @media (min-width: 1380px) {
139 .card-columns {
215 .card-columns {
140 column-count: 5;
216 column-count: 5;
141 }
217 }
142 }
218 }
219
@@ -1,129 +1,130
1 <!DOCTYPE html>
1 <!DOCTYPE html>
2 {% load static %}
2 {% load static %}
3 {% load bootstrap4 %}
3 {% load bootstrap4 %}
4 <html lang="en">
4 <html lang="en">
5 <head>
5 <head>
6 <meta charset="utf-8">
6 <meta charset="utf-8">
7 <title>{% block title %}Jicamarca Integrated Radar System:::::{% endblock %}</title>
7 <title>{% block title %}Jicamarca Integrated Radar System:::::{% endblock %}</title>
8 <meta name="description" content="">
8 <meta name="description" content="">
9 <meta name="author" content="">
9 <meta name="author" content="">
10 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
10 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
11 {# bootstrap_css #}
11 {# bootstrap_css #}
12
12
13 <link href="{% static 'css/fontawesome.css' %}" rel="stylesheet">
13 <link href="{% static 'css/fontawesome.css' %}" rel="stylesheet">
14 <link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
14 <link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
15 <link href="{% static 'css/style.css' %}" rel="stylesheet">
15 <link href="{% static 'css/style.css' %}" rel="stylesheet">
16 <link href="{% static 'css/header.css' %}" rel="stylesheet">
16 <link href="{% static 'css/header.css' %}" rel="stylesheet">
17 <link href="{% static 'css/footer.css' %}" rel="stylesheet">
17 <link href="{% static 'css/footer.css' %}" rel="stylesheet">
18 <link rel="shortcut icon" href="{% static 'images/favicon.ico' %}" />
18 <link rel="shortcut icon" href="{% static 'images/favicon.ico' %}" />
19
19
20
20
21 <!--link href="{% static '' %}css/bootstrap-{{theme}}.min.css" media="all" rel="stylesheet"-->
21 <!--link href="{% static '' %}css/bootstrap-{{theme}}.min.css" media="all" rel="stylesheet"-->
22 <!-- <link href="{% static 'css/bootcards-desktop.min.css' %}" media="all" rel="stylesheet"> -->
22 <!-- <link href="{% static 'css/bootcards-desktop.min.css' %}" media="all" rel="stylesheet"> -->
23 <link href="{% static 'css/font-awesome.min.css' %}" media="all" rel="stylesheet"-->
23 <link href="{% static 'css/font-awesome.min.css' %}" media="all" rel="stylesheet"-->
24 <!--link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"-->
24 <!--link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"-->
25
25
26 <!-- Bootcards CSS for iOS: >
26 <!-- Bootcards CSS for iOS: >
27 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootcards/1.0.0/css/bootcards-ios.min.css"-->
27 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootcards/1.0.0/css/bootcards-ios.min.css"-->
28
28
29 <!-- Bootcards CSS for Android: >
29 <!-- Bootcards CSS for Android: >
30 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootcards/1.0.0/css/bootcards-android.min.css"-->
30 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootcards/1.0.0/css/bootcards-android.min.css"-->
31
31
32 <!-- Bootcards CSS for desktop: >
32 <!-- Bootcards CSS for desktop: >
33 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootcards/1.0.0/css/bootcards-desktop.min.css"-->
33 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootcards/1.0.0/css/bootcards-desktop.min.css"-->
34
34
35 <style type="text/css">
35 <style type="text/css">
36 .logo {padding-top: 5px; height: 50px}
36 .logo {padding-top: 5px; height: 50px}
37 .clickable-row {cursor: pointer;}
37 .clickable-row {cursor: pointer;}
38 .col-no-padding { padding-left:0;}
38 .col-no-padding { padding-left:0;}
39 .gi-2x{font-size: 2em;}
39 .gi-2x{font-size: 2em;}
40 .gi-3x{font-size: 3em;}
40 .gi-3x{font-size: 3em;}
41 .gi-4x{font-size: 4em;}
41 .gi-4x{font-size: 4em;}
42 .gi-5x{font-size: 5em;}
42 .gi-5x{font-size: 5em;}
43 </style>
43 </style>
44 <script src="{% static 'js/jquery.min.js' %}"></script>
44 {% block extra-head %}{% endblock %}
45 {% block extra-head %}{% endblock %}
45 </head>
46 </head>
46
47
47 <body>
48 <body>
48
49
49 {% include "header_igp.html" %}
50 {% include "header_igp.html" %}
50
51
51 <div style="clear: both;"></div>
52 <div style="clear: both;"></div>
52
53
53 <div class="container">
54 <div class="container">
54 <div id="page" class="row" style="min-height:600px">
55 <div id="page" class="row" style="min-height:600px">
55
56
56 {% if no_sidebar %}
57 {% if no_sidebar %}
57 <div class="col-md-0 hidden-xs hidden-sm" role="complementary"></div>
58 <div class="col-md-0 hidden-xs hidden-sm" role="complementary"></div>
58
59
59 {% else %}
60 {% else %}
60 <div class="col-md-3 hidden-xs hidden-sm" role="complementary">
61 <div class="col-md-3 hidden-xs hidden-sm" role="complementary">
61 <br><br>
62 <br><br>
62 <div id="sidebar">
63 <div id="sidebar">
63 {% block sidebar%}
64 {% block sidebar%}
64 {% include "sidebar_devices.html" %}
65 {% include "sidebar_devices.html" %}
65 {% endblock %}
66 {% endblock %}
66 </div>
67 </div>
67 </div>
68 </div>
68 {% endif %}
69 {% endif %}
69
70
70
71
71 {% if no_sidebar %}
72 {% if no_sidebar %}
72 <div class="col-md-12 col-xs-12" role="main">
73 <div class="col-md-12 col-xs-12" role="main">
73 {% else %}
74 {% else %}
74 <div class="col-md-9 col-xs-12" role="main">
75 <div class="col-md-9 col-xs-12" role="main">
75 {% endif %}
76 {% endif %}
76
77
77 <div class="page-header">
78 <div class="page-header">
78 <h1>{% block content-title %}{% endblock %} <small>{% block content-suptitle %}{% endblock %}</small></h1>
79 <h1>{% block content-title %}{% endblock %} <small>{% block content-suptitle %}{% endblock %}</small></h1>
79 </div>
80 </div>
80 {% block messages %}
81 {% block messages %}
81 {% if messages %}
82 {% if messages %}
82 {% for message in messages %}
83 {% for message in messages %}
83 <div class="alert alert-{% if message.tags %}{% if 'error' in message.tags %}danger{% else %}{{ message.tags }}{% endif %}{% else %}info{% endif %} alert-dismissible" role="alert">
84 <div class="alert alert-{% if message.tags %}{% if 'error' in message.tags %}danger{% else %}{{ message.tags }}{% endif %}{% else %}info{% endif %} alert-dismissible" role="alert">
84 <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
85 <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
85 <strong>{{message.tags|title}}!</strong> {{ message }}
86 <strong>{{message.tags|title}}!</strong> {{ message }}
86 </div>
87 </div>
87 {% endfor %}
88 {% endfor %}
88 {% endif %}
89 {% endif %}
89 {% endblock %}
90 {% endblock %}
90
91
91 {% block content %}
92 {% block content %}
92 {% endblock %}
93 {% endblock %}
93
94
94 </div>
95 </div>
95
96
96
97
97 </div><!--/row-->
98 </div><!--/row-->
98 </div> <!-- container -->
99 </div> <!-- container -->
99
100
100 {% include "footer_igp.html" %}
101 {% include "footer_igp.html" %}
101
102
102
103
103
104
104 <!-- This part put block modal which is used to change parameters of my plot -->
105 <!-- This part put block modal which is used to change parameters of my plot -->
105 {% block modal %}{% endblock modal %}
106 {% block modal %}{% endblock modal %}
106 {% block debug %}<div class="row">{{debug}}</div>{% endblock debug %}
107 {% block debug %}<div class="row">{{debug}}</div>{% endblock debug %}
107 <!-- Optional JavaScript -->
108 <!-- Optional JavaScript -->
108 <!-- jQuery first, then Popper.js, then Bootstrap JS -->
109 <!-- jQuery first, then Popper.js, then Bootstrap JS -->
109 {# % bootstrap_javascript jquery='slim' % #}
110 {# % bootstrap_javascript jquery='slim' % #}
110 <script src="{% static 'js/jquery-3.3.1.slim.min.js' %}"></script>
111 <script src="{% static 'js/jquery-3.3.1.slim.min.js' %}"></script>
111 <script src="{% static 'js/popper.min.js' %}"></script>
112 <script src="{% static 'js/popper.min.js' %}"></script>
112 <script src="{% static 'js/moment.min.js' %}"></script>
113 <script src="{% static 'js/moment.min.js' %}"></script>
113 <script src="{% static 'js/bootstrap.min.js' %}"></script>
114 <script src="{% static 'js/bootstrap.min.js' %}"></script>
114 <script src="{% static 'js/plotly-latest.min.js' %}"></script>
115 <script src="{% static 'js/plotly-latest.min.js' %}"></script>
115
116
116 <!-- Here we put the script from the type of plot that we recibe -->
117 <!-- Here we put the script from the type of plot that we recibe -->
117 <script>
118 <script>
118 $("#menu-toggle").click(function (e) {
119 $("#menu-toggle").click(function (e) {
119 e.preventDefault();
120 e.preventDefault();
120 $("#wrapper").toggleClass("toggled");
121 $("#wrapper").toggleClass("toggled");
121 });
122 });
122 </script>
123 </script>
123 {% block extra-js %}
124 {% block extra-js %}
124 {% endblock%}
125 {% endblock%}
125
126
126
127
127
128
128 </body>
129 </body>
129 </html>
130 </html>
@@ -1,418 +1,427
1 import os
1 import os
2 import json
2 import json
3
3
4 from django import forms
4 from django import forms
5 from django.utils.safestring import mark_safe
5 from django.utils.safestring import mark_safe
6 from apps.main.models import Device
6 from apps.main.models import Device
7 from apps.main.forms import add_empty_choice
7 from apps.main.forms import add_empty_choice
8 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode, RCClock
8 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode, RCClock
9 from .widgets import KmUnitWidget, KmUnitHzWidget, KmUnitDcWidget, UnitKmWidget, DefaultWidget, CodesWidget, HiddenWidget, HCheckboxSelectMultiple
9 from .widgets import KmUnitWidget, KmUnitHzWidget, KmUnitDcWidget, UnitKmWidget, DefaultWidget, CodesWidget, HiddenWidget, HCheckboxSelectMultiple
10
10
11 def create_choices_from_model(model, conf_id, all_choice=False):
11 def create_choices_from_model(model, conf_id, all_choice=False):
12
12
13 if model=='RCLine':
13 if model=='RCLine':
14 instance = RCConfiguration.objects.get(pk=conf_id)
14 instance = RCConfiguration.objects.get(pk=conf_id)
15 choices = [(line.pk, line.get_name()) for line in instance.get_lines(line_type__name='tx')]
15 choices = [(line.pk, line.get_name()) for line in instance.get_lines(line_type__name='tx')]
16 if all_choice:
16 if all_choice:
17 choices = add_empty_choice(choices, label='All')
17 choices = add_empty_choice(choices, label='All')
18 else:
18 else:
19 instance = globals()[model]
19 instance = globals()[model]
20 choices = instance.objects.all().values_list('pk', 'name')
20 choices = instance.objects.all().values_list('pk', 'name')
21
21
22 return choices
22 return choices
23
23
24
24
25 class ExtFileField(forms.FileField):
25 class ExtFileField(forms.FileField):
26 """
26 """
27 Same as forms.FileField, but you can specify a file extension whitelist.
27 Same as forms.FileField, but you can specify a file extension whitelist.
28
28
29 >>> from django.core.files.uploadedfile import SimpleUploadedFile
29 >>> from django.core.files.uploadedfile import SimpleUploadedFile
30 >>>
30 >>>
31 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
31 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
32 >>>
32 >>>
33 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
33 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
34 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
34 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
35 >>>
35 >>>
36 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
36 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
37 Traceback (most recent call last):
37 Traceback (most recent call last):
38 ...
38 ...
39 ValidationError: [u'Not allowed filetype!']
39 ValidationError: [u'Not allowed filetype!']
40 """
40 """
41 def __init__(self, *args, **kwargs):
41 def __init__(self, *args, **kwargs):
42 extensions = kwargs.pop("extensions")
42 extensions = kwargs.pop("extensions")
43 self.extensions = [i.lower() for i in extensions]
43 self.extensions = [i.lower() for i in extensions]
44
44
45 super(ExtFileField, self).__init__(*args, **kwargs)
45 super(ExtFileField, self).__init__(*args, **kwargs)
46
46
47 def clean(self, *args, **kwargs):
47 def clean(self, *args, **kwargs):
48 data = super(ExtFileField, self).clean(*args, **kwargs)
48 data = super(ExtFileField, self).clean(*args, **kwargs)
49 filename = data.name
49 filename = data.name
50 ext = os.path.splitext(filename)[1]
50 ext = os.path.splitext(filename)[1]
51 ext = ext.lower()
51 ext = ext.lower()
52 if ext not in self.extensions:
52 if ext not in self.extensions:
53 raise forms.ValidationError('Not allowed file type: %s' % ext)
53 raise forms.ValidationError('Not allowed file type: %s' % ext)
54
54
55
55
56 class RCConfigurationForm(forms.ModelForm):
56 class RCConfigurationForm(forms.ModelForm):
57
57
58 def __init__(self, *args, **kwargs):
58 def __init__(self, *args, **kwargs):
59 super(RCConfigurationForm, self).__init__(*args, **kwargs)
59 super(RCConfigurationForm, self).__init__(*args, **kwargs)
60
60
61 instance = getattr(self, 'instance', None)
61 instance = getattr(self, 'instance', None)
62
62
63 if instance and instance.pk:
63 if instance and instance.pk:
64
64
65 devices = Device.objects.filter(device_type__name='rc')
65 devices = Device.objects.filter(device_type__name='rc')
66 if instance.experiment:
66 if instance.experiment:
67 self.fields['experiment'].widget.attrs['read_only'] = True
67 self.fields['experiment'].widget.attrs['read_only'] = True
68 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
68 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
69 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
69 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
70 self.fields['ipp'].widget = KmUnitHzWidget(attrs={'km2unit':instance.km2unit})
70 self.fields['ipp'].widget = KmUnitHzWidget(attrs={'km2unit':instance.km2unit})
71 self.fields['clock'].widget.attrs['readonly'] = True
71 self.fields['clock'].widget.attrs['readonly'] = True
72
72
73 self.fields['time_before'].label = mark_safe(self.fields['time_before'].label)
73 self.fields['time_before'].label = mark_safe(self.fields['time_before'].label)
74 self.fields['time_after'].label = mark_safe(self.fields['time_after'].label)
74 self.fields['time_after'].label = mark_safe(self.fields['time_after'].label)
75
75
76 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
76 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
77 self.fields['experiment'].widget.attrs['readonly'] = True
77 self.fields['experiment'].widget.attrs['readonly'] = True
78
78
79 class Meta:
79 class Meta:
80 model = RCConfiguration
80 model = RCConfiguration
81 exclude = ('type', 'parameters', 'status', 'total_units', 'mix', 'author', 'hash', 'clock_in')
81 exclude = ('type', 'parameters', 'status', 'total_units', 'mix', 'author', 'hash', 'clock_in')
82
82
83 def clean(self):
83 def clean(self):
84 form_data = super(RCConfigurationForm, self).clean()
84 form_data = super(RCConfigurationForm, self).clean()
85
85
86 if 'clock_divider' in form_data:
86 if 'clock_divider' in form_data:
87 if form_data['clock_divider']<1:
87 if form_data['clock_divider']<1:
88 self.add_error('clock_divider', 'Invalid Value')
88 self.add_error('clock_divider', 'Invalid Value')
89 #else:
89 #else:
90 # if form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))%10!=0:
90 # if form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))%10!=0:
91 # self.add_error('ipp', 'Invalid IPP units={}'.format(form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))))
91 # self.add_error('ipp', 'Invalid IPP units={}'.format(form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))))
92
92
93 return form_data
93 return form_data
94
94
95 def save(self, *args, **kwargs):
95 def save(self, *args, **kwargs):
96 conf = super(RCConfigurationForm, self).save(*args, **kwargs)
96 conf = super(RCConfigurationForm, self).save(*args, **kwargs)
97 clk = RCClock.objects.filter(rc_configuration=conf).first()
97 clk = RCClock.objects.filter(rc_configuration=conf).first()
98 if clk:
98 if clk:
99 conf.clock_in = clk.frequency
99 conf.clock_in = clk.frequency
100 conf.total_units = conf.ipp*conf.ntx*conf.km2unit
100 conf.total_units = conf.ipp*conf.ntx*conf.km2unit
101 conf.save()
101 conf.save()
102 return conf
102 return conf
103
103
104
104
105 class RCMixConfigurationForm(forms.Form):
105 class RCMixConfigurationForm(forms.Form):
106
106
107 clock_in = forms.CharField(widget=forms.HiddenInput())
107 clock_in = forms.CharField(widget=forms.HiddenInput())
108 clock_divider = forms.CharField(widget=forms.HiddenInput())
108 clock_divider = forms.CharField(widget=forms.HiddenInput())
109 name = forms.CharField()
109 name = forms.CharField()
110 experiment = forms.ChoiceField()
110 experiment = forms.ChoiceField()
111 mode = forms.ChoiceField(widget=forms.RadioSelect(),
111 mode = forms.ChoiceField(widget=forms.RadioSelect(),
112 choices=[(0, 'Parallel'), (1, 'Sequence')],
112 choices=[(0, 'Parallel'), (1, 'Sequence')],
113 initial=0)
113 initial=0)
114 operation = forms.ChoiceField(widget=forms.RadioSelect(),
114 operation = forms.ChoiceField(widget=forms.RadioSelect(),
115 choices=[(0, 'OR'), (1, 'XOR'), (2, 'AND'), (3, 'NAND')],
115 choices=[(0, 'OR'), (1, 'XOR'), (2, 'AND'), (3, 'NAND')],
116 initial=1)
116 initial=1)
117 delay = forms.CharField()
117 delay = forms.CharField()
118 mask = forms.MultipleChoiceField(
118 mask = forms.MultipleChoiceField(
119 choices=[(0, 'L1'),(1, 'L2'),(2, 'L3'),(3, 'L4'),(4, 'L5'),(5, 'L6'),(6, 'L7'),(7, 'L8'),
119 choices=[(0, 'L1'),(1, 'L2'),(2, 'L3'),(3, 'L4'),(4, 'L5'),(5, 'L6'),(6, 'L7'),(7, 'L8'),
120 (8, 'L9'),(9, 'L10'),(10, 'L11'),(11, 'L12'),(12, 'L13'),(13, 'L14'),(14, 'L15'),(15, 'L16')],
120 (8, 'L9'),(9, 'L10'),(10, 'L11'),(11, 'L12'),(12, 'L13'),(13, 'L14'),(14, 'L15'),(15, 'L16')],
121 widget=HCheckboxSelectMultiple())
121 widget=HCheckboxSelectMultiple())
122 result = forms.CharField(required=False,
122 result = forms.CharField(required=False,
123 widget=forms.Textarea(attrs={'readonly':True, 'rows':5, 'class':'tabuled'}))
123 widget=forms.Textarea(attrs={'readonly':True, 'rows':5, 'class':'tabuled'}))
124
124
125 def __init__(self, *args, **kwargs):
125 def __init__(self, *args, **kwargs):
126 confs = kwargs.pop('confs', [])
126 confs = kwargs.pop('confs', [])
127 if confs:
127 if confs:
128 km2unit = confs[0].km2unit
128 km2unit = confs[0].km2unit
129 clock_in = confs[0].clock_in
129 clock_in = confs[0].clock_in
130 clock_divider = confs[0].clock_divider
130 clock_divider = confs[0].clock_divider
131 else:
131 else:
132 km2unit = clock_in = clock_divider = 0
132 km2unit = clock_in = clock_divider = 0
133 super(RCMixConfigurationForm, self).__init__(*args, **kwargs)
133 super(RCMixConfigurationForm, self).__init__(*args, **kwargs)
134 self.fields['experiment'].choices = [(conf.pk, '{} | {}'.format(conf.pk, conf.name)) for conf in confs]
134 self.fields['experiment'].choices = [(conf.pk, '{} | {}'.format(conf.pk, conf.name)) for conf in confs]
135 self.fields['delay'].widget = KmUnitWidget(attrs = {'km2unit':km2unit})
135 self.fields['delay'].widget = KmUnitWidget(attrs = {'km2unit':km2unit})
136 self.fields['clock_in'].initial = clock_in
136 self.fields['clock_in'].initial = clock_in
137 self.fields['clock_divider'].initial = clock_divider
137 self.fields['clock_divider'].initial = clock_divider
138
138
139
139
140 class RCLineForm(forms.ModelForm):
140 class RCLineForm(forms.ModelForm):
141
141
142 def __init__(self, *args, **kwargs):
142 def __init__(self, *args, **kwargs):
143 self.extra_fields = kwargs.pop('extra_fields', [])
143 self.extra_fields = kwargs.pop('extra_fields', [])
144 super(RCLineForm, self).__init__(*args, **kwargs)
144 super(RCLineForm, self).__init__(*args, **kwargs)
145
145
146 if 'initial' in kwargs and 'line_type' in kwargs['initial']:
146 if 'initial' in kwargs and 'line_type' in kwargs['initial']:
147 line_type = RCLineType.objects.get(pk=kwargs['initial']['line_type'])
147 line_type = RCLineType.objects.get(pk=kwargs['initial']['line_type'])
148
148
149 if 'code_id' in kwargs['initial']:
149 if 'code_id' in kwargs['initial']:
150 model_initial = kwargs['initial']['code_id']
150 model_initial = kwargs['initial']['code_id']
151 else:
151 else:
152 model_initial = 0
152 model_initial = 0
153
153
154 params = json.loads(line_type.params)
154 params = json.loads(line_type.params)
155
155
156 for label, value in self.extra_fields.items():
156 for label, value in self.extra_fields.items():
157 if label=='params':
157 if label=='params':
158 continue
158 continue
159
159
160 if 'model' in params[label]:
160 if 'model' in params[label]:
161 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
161 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
162 kwargs['initial']['rc_configuration']),
162 kwargs['initial']['rc_configuration']),
163 initial=model_initial)
163 initial=model_initial)
164
164
165
165
166 else:
166 else:
167 if label=='codes' and 'code_id' in kwargs['initial']:
167 if label=='codes' and 'code_id' in kwargs['initial']:
168 self.fields[label] = forms.CharField(initial=RCLineCode.objects.get(pk=kwargs['initial']['code_id']).codes)
168 self.fields[label] = forms.CharField(initial=RCLineCode.objects.get(pk=kwargs['initial']['code_id']).codes)
169 else:
169 else:
170 self.fields[label] = forms.CharField(initial=value['value'])
170 self.fields[label] = forms.CharField(initial=value['value'])
171
171
172 if label=='codes':
172 if label=='codes':
173 self.fields[label].widget = CodesWidget()
173 self.fields[label].widget = CodesWidget()
174
174
175 if self.data:
175 if self.data:
176 line_type = RCLineType.objects.get(pk=self.data['line_type'])
176 line_type = RCLineType.objects.get(pk=self.data['line_type'])
177
177
178 if 'code_id' in self.data:
178 if 'code_id' in self.data:
179 model_initial = self.data['code_id']
179 model_initial = self.data['code_id']
180 else:
180 else:
181 model_initial = 0
181 model_initial = 0
182
182
183 params = json.loads(line_type.params)
183 params = json.loads(line_type.params)
184
184
185 for label, value in self.extra_fields.items():
185 for label, value in self.extra_fields.items():
186 if label=='params':
186 if label=='params':
187 continue
187 continue
188
188
189 if 'model' in params[label]:
189 if 'model' in params[label]:
190 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
190 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
191 self.data['rc_configuration']),
191 self.data['rc_configuration']),
192 initial=model_initial)
192 initial=model_initial)
193
193
194
194
195 else:
195 else:
196 if label=='codes' and 'code' in self.data:
196 if label=='codes' and 'code' in self.data:
197 self.fields[label] = forms.CharField(initial=self.data['codes'])
197 self.fields[label] = forms.CharField(initial=self.data['codes'])
198 else:
198 else:
199 self.fields[label] = forms.CharField(initial=self.data[label])
199 self.fields[label] = forms.CharField(initial=self.data[label])
200
200
201 if label=='codes':
201 if label=='codes':
202 self.fields[label].widget = CodesWidget()
202 self.fields[label].widget = CodesWidget()
203
203
204
204
205 class Meta:
205 class Meta:
206 model = RCLine
206 model = RCLine
207 fields = ('rc_configuration', 'line_type', 'channel')
207 fields = ('rc_configuration', 'line_type', 'channel')
208 widgets = {
208 widgets = {
209 'channel': forms.HiddenInput(),
209 'channel': forms.HiddenInput(),
210 }
210 }
211
211
212
212
213 def clean(self):
213 def clean(self):
214
214
215 form_data = self.cleaned_data
215 form_data = self.cleaned_data
216 if 'code' in self.data and self.data['TX_ref']=="0":
216 if 'code' in self.data and self.data['TX_ref']=="0":
217 self.add_error('TX_ref', 'Choose a valid TX reference')
217 self.add_error('TX_ref', 'Choose a valid TX reference')
218
218
219 if RCLineType.objects.get(pk=self.data['line_type']).name=='mix':
219 if RCLineType.objects.get(pk=self.data['line_type']).name=='mix':
220 self.add_error('line_type', 'Invalid Line type')
220 self.add_error('line_type', 'Invalid Line type')
221
221
222 return form_data
222 return form_data
223
223
224
224
225 def save(self):
225 def save(self):
226 line = super(RCLineForm, self).save()
226 line = super(RCLineForm, self).save()
227
227
228 #auto add channel
228 #auto add channel
229 line.channel = RCLine.objects.filter(rc_configuration=line.rc_configuration).count()-1
229 line.channel = RCLine.objects.filter(rc_configuration=line.rc_configuration).count()-1
230
230
231 #auto add position for TX, TR & CODE
231 #auto add position for TX, TR & CODE
232 if line.line_type.name in ('tx', ):
232 if line.line_type.name in ('tx', ):
233 line.position = RCLine.objects.filter(rc_configuration=line.rc_configuration, line_type=line.line_type).count()-1
233 line.position = RCLine.objects.filter(rc_configuration=line.rc_configuration, line_type=line.line_type).count()-1
234
234
235 #save extra fields in params
235 #save extra fields in params
236 params = {}
236 params = {}
237 for label, value in self.extra_fields.items():
237 for label, value in self.extra_fields.items():
238 if label=='params':
238 if label=='params':
239 params['params'] = []
239 params['params'] = []
240 elif label=='codes':
240 elif label=='codes':
241 params[label] = [s for s in self.data[label].split('\r\n') if s]
241 params[label] = [s for s in self.data[label].split('\r\n') if s]
242 else:
242 else:
243 params[label] = self.data[label]
243 params[label] = self.data[label]
244 line.params = json.dumps(params)
244 line.params = json.dumps(params)
245 line.save()
245 line.save()
246 return
246 return
247
247
248
248
249 class RCLineViewForm(forms.Form):
249 class RCLineViewForm(forms.Form):
250
250
251 def __init__(self, *args, **kwargs):
251 def __init__(self, *args, **kwargs):
252
252
253 extra_fields = kwargs.pop('extra_fields')
253 extra_fields = kwargs.pop('extra_fields')
254 line = kwargs.pop('line')
254 line = kwargs.pop('line')
255 subform = kwargs.pop('subform', False)
255 subform = kwargs.pop('subform', False)
256 super(RCLineViewForm, self).__init__(*args, **kwargs)
256 super(RCLineViewForm, self).__init__(*args, **kwargs)
257
257
258 if subform:
258 if subform:
259 params = json.loads(line.line_type.params)['params']
259 params = json.loads(line.line_type.params)['params']
260 else:
260 else:
261 params = json.loads(line.line_type.params)
261 params = json.loads(line.line_type.params)
262
262
263 for label, value in extra_fields.items():
263 for label, value in extra_fields.items():
264
264
265 if label=='params':
265 if label=='params':
266 continue
266 continue
267 if 'ref' in label:
267 if 'ref' in label:
268 if value in (0, '0'):
268 if value in (0, '0'):
269 value = 'All'
269 value = 'All'
270 else:
270 else:
271 value = RCLine.objects.get(pk=value).get_name()
271 value = RCLine.objects.get(pk=value).get_name()
272 elif label=='code':
272 elif label=='code':
273 value = RCLineCode.objects.get(pk=value).name
273 value = RCLineCode.objects.get(pk=value).name
274
274
275 self.fields[label] = forms.CharField(initial=value)
275 self.fields[label] = forms.CharField(initial=value)
276
276
277 if 'widget' in params[label]:
277 if 'widget' in params[label]:
278 km2unit = line.rc_configuration.km2unit
278 km2unit = line.rc_configuration.km2unit
279 if params[label]['widget']=='km':
279 if params[label]['widget']=='km':
280 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
280 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
281 elif params[label]['widget']=='unit':
281 elif params[label]['widget']=='unit':
282 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
282 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
283 elif params[label]['widget']=='dc':
283 elif params[label]['widget']=='dc':
284 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
284 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
285 elif params[label]['widget']=='codes':
285 elif params[label]['widget']=='codes':
286 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
286 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
287 else:
287 else:
288 self.fields[label].widget = DefaultWidget(attrs={'disabled':True})
288 self.fields[label].widget = DefaultWidget(attrs={'disabled':True})
289
289
290
290
291 class RCLineEditForm(forms.ModelForm):
291 class RCLineEditForm(forms.ModelForm):
292
292
293 def __init__(self, *args, **kwargs):
293 def __init__(self, *args, **kwargs):
294 print("RCLineEditForm")
294
295
295 extra_fields = kwargs.pop('extra_fields', [])
296 extra_fields = kwargs.pop('extra_fields', [])
296 conf = kwargs.pop('conf', False)
297 conf = kwargs.pop('conf', False)
297 line = kwargs.pop('line')
298 line = kwargs.pop('line')
298 subform = kwargs.pop('subform', False)
299 subform = kwargs.pop('subform', False)
299
300
300 super(RCLineEditForm, self).__init__(*args, **kwargs)
301 super(RCLineEditForm, self).__init__(*args, **kwargs)
301
302
302 if subform is not False:
303 if subform is not False:
303 params = json.loads(line.line_type.params)['params']
304 params = json.loads(line.line_type.params)['params']
304 count = subform
305 count = subform
305 else:
306 else:
306 params = json.loads(line.line_type.params)
307 params = json.loads(line.line_type.params)
307 count = -1
308 count = -1
308
309
309 for label, value in extra_fields.items():
310 for label, value in extra_fields.items():
310
311
311 if label in ('params',):
312 if label in ('params',):
312 continue
313 continue
313 if 'help' in params[label]:
314 if 'help' in params[label]:
314 help_text = params[label]['help']
315 help_text = params[label]['help']
315 else:
316 else:
316 help_text = ''
317 help_text = ''
317
318
318 if 'model' in params[label]:
319 if 'model' in params[label]:
319 if line.line_type.name=='tr':
320 if line.line_type.name=='tr':
320 all_choice = True
321 all_choice = True
321 else:
322 else:
322 all_choice = False
323 all_choice = False
323 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'], conf.id, all_choice=all_choice),
324 #print("'name':'%s|%s|%s'" % (count, line.id, label))
325 aux_name = '%s|%s|%s' % (count, line.id, label)
326 print(aux_name)
327 print(label)
328
329 self.fields[aux_name] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'], conf.id, all_choice=all_choice),
324 initial=value,
330 initial=value,
325 widget=forms.Select(attrs={'name':'%s|%s|%s' % (count, line.id, label)}),
331 label=label,
332 widget=forms.Select(attrs={'name':'%s|%s|%s' % (count, line.id, label)}), #No trabaja con attrs esta versión de django 2.0 hacia adelante
333 #widget=forms.Select(attrs={'name':'HOLA'}), #No trabaja con attrs esta versión de django 2.0 hacia adelante
326 help_text=help_text)
334 help_text=help_text)
327
335
328 else:
336 else:
329 self.fields[label] = forms.CharField(initial=value, help_text=help_text)
337 self.fields[label] = forms.CharField(initial=value, help_text=help_text)
330
338
331 if label in ('code', ):
339 if label in ('code', ):
332 self.fields[label].widget = HiddenWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
340 self.fields[label].widget = HiddenWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
333
341
334 elif 'widget' in params[label]:
342 elif 'widget' in params[label]:
335 km2unit = line.rc_configuration.km2unit
343 km2unit = line.rc_configuration.km2unit
336 if params[label]['widget']=='km':
344 if params[label]['widget']=='km':
337 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
345 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
338 elif params[label]['widget']=='unit':
346 elif params[label]['widget']=='unit':
339 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
347 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
340 elif params[label]['widget']=='dc':
348 elif params[label]['widget']=='dc':
341 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
349 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
342 elif params[label]['widget']=='codes':
350 elif params[label]['widget']=='codes':
343 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
351 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
344 else:
352 else:
345 self.fields[label].widget = DefaultWidget(attrs={'line':line, 'name':'%s|%s|%s' % (count, line.id, label)})
353 self.fields[label].widget = DefaultWidget(attrs={'line':line, 'name':'%s|%s|%s' % (count, line.id, label)})
346
354
347
355
348 class Meta:
356 class Meta:
349 model = RCLine
357 model = RCLine
350 exclude = ('rc_configuration', 'line_type', 'channel', 'position', 'params', 'pulses')
358 exclude = ('rc_configuration', 'line_type', 'channel', 'position', 'params', 'pulses')
351
359
352
360
353 class RCSubLineEditForm(forms.Form):
361 class RCSubLineEditForm(forms.Form):
354
362
355 def __init__(self, *args, **kwargs):
363 def __init__(self, *args, **kwargs):
364 print("RCSubLineEditForm")
356 extra_fields = kwargs.pop('extra_fields')
365 extra_fields = kwargs.pop('extra_fields')
357 count = kwargs.pop('count')
366 count = kwargs.pop('count')
358 line = kwargs.pop('line')
367 line = kwargs.pop('line')
359 super(RCSubLineEditForm, self).__init__(*args, **kwargs)
368 super(RCSubLineEditForm, self).__init__(*args, **kwargs)
360 for label, value in extra_fields.items():
369 for label, value in extra_fields.items():
361 self.fields[label] = forms.CharField(initial=value,
370 self.fields[label] = forms.CharField(initial=value,
362 widget=forms.TextInput(attrs={'name':'%s|%s|%s' % (count, line, label)}))
371 widget=forms.TextInput(attrs={'name':'%s|%s|%s' % (count, line, label)}))
363
372
364
373
365 class RCImportForm(forms.Form):
374 class RCImportForm(forms.Form):
366
375
367 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
376 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
368
377
369
378
370 class RCLineCodesForm(forms.ModelForm):
379 class RCLineCodesForm(forms.ModelForm):
371
380
372 def __init__(self, *args, **kwargs):
381 def __init__(self, *args, **kwargs):
373 super(RCLineCodesForm, self).__init__(*args, **kwargs)
382 super(RCLineCodesForm, self).__init__(*args, **kwargs)
374
383
375 if 'initial' in kwargs:
384 if 'initial' in kwargs:
376 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
385 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
377 initial=kwargs['initial']['code'])
386 initial=kwargs['initial']['code'])
378 if 'instance' in kwargs:
387 if 'instance' in kwargs:
379 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
388 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
380 initial=kwargs['instance'].pk)
389 initial=kwargs['instance'].pk)
381
390
382 self.fields['codes'].widget = CodesWidget()
391 self.fields['codes'].widget = CodesWidget()
383
392
384
393
385 class Meta:
394 class Meta:
386 model = RCLineCode
395 model = RCLineCode
387 exclude = ('name',)
396 exclude = ('name',)
388
397
389 class RCClockForm(forms.ModelForm):
398 class RCClockForm(forms.ModelForm):
390
399
391 def __init__(self, *args, **kwargs):
400 def __init__(self, *args, **kwargs):
392 super(RCClockForm, self).__init__(*args, **kwargs)
401 super(RCClockForm, self).__init__(*args, **kwargs)
393
402
394 instance = getattr(self, 'instance', None)
403 instance = getattr(self, 'instance', None)
395
404
396 if instance is not None and instance.mode:
405 if instance is not None and instance.mode:
397 self.fields['multiplier'].widget.attrs['readonly'] = True
406 self.fields['multiplier'].widget.attrs['readonly'] = True
398 self.fields['divisor'].widget.attrs['readonly'] = True
407 self.fields['divisor'].widget.attrs['readonly'] = True
399 self.fields['reference'].widget.attrs['readonly'] = True
408 self.fields['reference'].widget.attrs['readonly'] = True
400
409
401
410
402 class Meta:
411 class Meta:
403 model = RCClock
412 model = RCClock
404 exclude = ('rc_configuration',)
413 exclude = ('rc_configuration',)
405
414
406 def clean(self):
415 def clean(self):
407
416
408 form_data = self.cleaned_data
417 form_data = self.cleaned_data
409
418
410 if form_data['mode'] is True and float(form_data['frequency']) not in (60., 55.):
419 if form_data['mode'] is True and float(form_data['frequency']) not in (60., 55.):
411 self.add_error('frequency', 'Only 60 and 55 are valid values in auto mode')
420 self.add_error('frequency', 'Only 60 and 55 are valid values in auto mode')
412 elif form_data['mode'] is False:
421 elif form_data['mode'] is False:
413 if form_data['reference']==0 and not 24<=form_data['multiplier']<=36:
422 if form_data['reference']==0 and not 24<=form_data['multiplier']<=36:
414 self.add_error('multiplier', 'For 25MHz, valid values are between 24 and 36')
423 self.add_error('multiplier', 'For 25MHz, valid values are between 24 and 36')
415 elif form_data['reference']==1 and not 60<=form_data['multiplier']<=90:
424 elif form_data['reference']==1 and not 60<=form_data['multiplier']<=90:
416 self.add_error('multiplier', 'For 10MHz, valid values are between 60 and 90')
425 self.add_error('multiplier', 'For 10MHz, valid values are between 60 and 90')
417
426
418 return form_data No newline at end of file
427 return form_data
@@ -1,1027 +1,1032
1
1
2
2
3 import ast
3 import ast
4 import json
4 import json
5 import requests
5 import requests
6 import numpy as np
6 import numpy as np
7 from base64 import b64encode
7 from base64 import b64encode
8 from struct import pack
8 from struct import pack
9
9
10 from django.db import models
10 from django.db import models
11 from django.urls import reverse
11 from django.urls import reverse
12 from django.core.validators import MinValueValidator, MaxValueValidator
12 from django.core.validators import MinValueValidator, MaxValueValidator
13
13
14 from apps.main.models import Configuration
14 from apps.main.models import Configuration
15 from apps.main.utils import Params
15 from apps.main.utils import Params
16 from devices.rc import api
16 from devices.rc import api
17 from apps.rc.utils import RCFile
17 from apps.rc.utils import RCFile
18
18
19
19
20 LINE_TYPES = (
20 LINE_TYPES = (
21 ('none', 'Not used'),
21 ('none', 'Not used'),
22 ('tr', 'Transmission/reception selector signal'),
22 ('tr', 'Transmission/reception selector signal'),
23 ('tx', 'A modulating signal (Transmission pulse)'),
23 ('tx', 'A modulating signal (Transmission pulse)'),
24 ('codes', 'BPSK modulating signal'),
24 ('codes', 'BPSK modulating signal'),
25 ('windows', 'Sample window signal'),
25 ('windows', 'Sample window signal'),
26 ('sync', 'Synchronizing signal'),
26 ('sync', 'Synchronizing signal'),
27 ('flip', 'IPP related periodic signal'),
27 ('flip', 'IPP related periodic signal'),
28 ('prog_pulses', 'Programmable pulse'),
28 ('prog_pulses', 'Programmable pulse'),
29 ('mix', 'Mixed line'),
29 ('mix', 'Mixed line'),
30 )
30 )
31
31
32
32
33 SAMPLING_REFS = (
33 SAMPLING_REFS = (
34 ('none', 'No Reference'),
34 ('none', 'No Reference'),
35 ('begin_baud', 'Begin of the first baud'),
35 ('begin_baud', 'Begin of the first baud'),
36 ('first_baud', 'Middle of the first baud'),
36 ('first_baud', 'Middle of the first baud'),
37 ('sub_baud', 'Middle of the sub-baud')
37 ('sub_baud', 'Middle of the sub-baud')
38 )
38 )
39
39
40 DAT_CMDS = {
40 DAT_CMDS = {
41 # Pulse Design commands
41 # Pulse Design commands
42 'DISABLE' : 0, # Disables pulse generation
42 'DISABLE' : 0, # Disables pulse generation
43 'ENABLE' : 24, # Enables pulse generation
43 'ENABLE' : 24, # Enables pulse generation
44 'DELAY_START' : 40, # Write delay status to memory
44 'DELAY_START' : 40, # Write delay status to memory
45 'FLIP_START' : 48, # Write flip status to memory
45 'FLIP_START' : 48, # Write flip status to memory
46 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
46 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
47 'TX_ONE' : 72, # Output '0' in line TX
47 'TX_ONE' : 72, # Output '0' in line TX
48 'TX_ZERO' : 88, # Output '0' in line TX
48 'TX_ZERO' : 88, # Output '0' in line TX
49 'SW_ONE' : 104, # Output '0' in line SW
49 'SW_ONE' : 104, # Output '0' in line SW
50 'SW_ZERO' : 112, # Output '1' in line SW
50 'SW_ZERO' : 112, # Output '1' in line SW
51 'RESTART': 120, # Restarts CR8 Firmware
51 'RESTART': 120, # Restarts CR8 Firmware
52 'CONTINUE' : 253, # Function Unknown
52 'CONTINUE' : 253, # Function Unknown
53 # Commands available to new controllers
53 # Commands available to new controllers
54 # 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.
54 # 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.
55 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
55 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
56 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
56 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
57 'CLOCK_DIVIDER' : 8,
57 'CLOCK_DIVIDER' : 8,
58 }
58 }
59
59
60 MAX_BITS = 8
60 MAX_BITS = 8
61
61
62 # Rotate left: 0b1001 --> 0b0011
62 # Rotate left: 0b1001 --> 0b0011
63 rol = lambda val, r_bits: \
63 rol = lambda val, r_bits: \
64 (val << r_bits%MAX_BITS) & (2**MAX_BITS-1) | \
64 (val << r_bits%MAX_BITS) & (2**MAX_BITS-1) | \
65 ((val & (2**MAX_BITS-1)) >> (MAX_BITS-(r_bits%MAX_BITS)))
65 ((val & (2**MAX_BITS-1)) >> (MAX_BITS-(r_bits%MAX_BITS)))
66
66
67 # Rotate right: 0b1001 --> 0b1100
67 # Rotate right: 0b1001 --> 0b1100
68 ror = lambda val, r_bits: \
68 ror = lambda val, r_bits: \
69 ((val & (2**MAX_BITS-1)) >> r_bits%MAX_BITS) | \
69 ((val & (2**MAX_BITS-1)) >> r_bits%MAX_BITS) | \
70 (val << (MAX_BITS-(r_bits%MAX_BITS)) & (2**MAX_BITS-1))
70 (val << (MAX_BITS-(r_bits%MAX_BITS)) & (2**MAX_BITS-1))
71
71
72
72
73 class RCConfiguration(Configuration):
73 class RCConfiguration(Configuration):
74
74
75 ipp = models.FloatField(verbose_name='IPP [Km]', validators=[MinValueValidator(1)], default=300)
75 ipp = models.FloatField(verbose_name='IPP [Km]', validators=[MinValueValidator(1)], default=300)
76 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1)], default=1)
76 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1)], default=1)
77 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
77 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
78 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
78 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
79 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
79 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
80 time_before = models.PositiveIntegerField(verbose_name='Time before [&mu;S]', default=12)
80 time_before = models.PositiveIntegerField(verbose_name='Time before [&mu;S]', default=12)
81 time_after = models.PositiveIntegerField(verbose_name='Time after [&mu;S]', default=1)
81 time_after = models.PositiveIntegerField(verbose_name='Time after [&mu;S]', default=1)
82 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
82 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
83 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
83 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
84 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
84 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
85 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
85 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
86 total_units = models.PositiveIntegerField(default=0)
86 total_units = models.PositiveIntegerField(default=0)
87 mix = models.BooleanField(default=False)
87 mix = models.BooleanField(default=False)
88
88
89 class Meta:
89 class Meta:
90 db_table = 'rc_configurations'
90 db_table = 'rc_configurations'
91
91
92 def get_absolute_url_plot(self):
92 def get_absolute_url_plot(self):
93 return reverse('url_plot_rc_pulses', args=[str(self.id)])
93 return reverse('url_plot_rc_pulses', args=[str(self.id)])
94
94
95 @property
95 @property
96 def ipp_unit(self):
96 def ipp_unit(self):
97
97
98 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
98 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
99
99
100 @property
100 @property
101 def us2unit(self):
101 def us2unit(self):
102
102
103 return self.clock_in/self.clock_divider
103 return self.clock_in/self.clock_divider
104
104
105 @property
105 @property
106 def km2unit(self):
106 def km2unit(self):
107
107
108 return 20./3*(self.clock_in/self.clock_divider)
108 return 20./3*(self.clock_in/self.clock_divider)
109
109
110 def clone(self, **kwargs):
110 def clone(self, **kwargs):
111
111
112 lines = self.get_lines()
112 lines = self.get_lines()
113 self.pk = None
113 self.pk = None
114 self.id = None
114 self.id = None
115 for attr, value in kwargs.items():
115 for attr, value in kwargs.items():
116 setattr(self, attr, value)
116 setattr(self, attr, value)
117 self.save()
117 self.save()
118
118
119 for line in lines:
119 for line in lines:
120 line.clone(rc_configuration=self)
120 line.clone(rc_configuration=self)
121
121
122 new_lines = self.get_lines()
122 new_lines = self.get_lines()
123 for line in new_lines:
123 for line in new_lines:
124 line_params = json.loads(line.params)
124 line_params = json.loads(line.params)
125 if 'TX_ref' in line_params and (line_params['TX_ref'] != '0'):
125 if 'TX_ref' in line_params and (line_params['TX_ref'] != '0'):
126 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
126 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
127 line_params['TX_ref'] = ['{}'.format(l.pk) for l in new_lines if l.get_name()==ref_line.get_name()][0]
127 line_params['TX_ref'] = ['{}'.format(l.pk) for l in new_lines if l.get_name()==ref_line.get_name()][0]
128 line.params = json.dumps(line_params)
128 line.params = json.dumps(line_params)
129 line.save()
129 line.save()
130
130
131 return self
131 return self
132
132
133 def get_lines(self, **kwargs):
133 def get_lines(self, **kwargs):
134 '''
134 '''
135 Retrieve configuration lines
135 Retrieve configuration lines
136 '''
136 '''
137
137
138 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
138 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
139
139
140
140
141 def clean_lines(self):
141 def clean_lines(self):
142 '''
142 '''
143 '''
143 '''
144
144
145 empty_line = RCLineType.objects.get(name='none')
145 empty_line = RCLineType.objects.get(name='none')
146
146
147 for line in self.get_lines():
147 for line in self.get_lines():
148 line.line_type = empty_line
148 line.line_type = empty_line
149 line.params = '{}'
149 line.params = '{}'
150 line.save()
150 line.save()
151
151
152 def dict_to_parms(self, params, id=None):
152 def dict_to_parms(self, params, id=None):
153 '''
153 '''
154 '''
154 '''
155
155
156 if id:
156 if id:
157 data = Params(params).get_conf(id_conf=id)
157 data = Params(params).get_conf(id_conf=id)
158 else:
158 else:
159 data = Params(params).get_conf(dtype='rc')
159 data = Params(params).get_conf(dtype='rc')
160
160
161 #print(data)
161 # self.name = data['name']
162 # self.name = data['name']
162 self.ipp = data['ipp']
163 self.ipp = data['ipp']
163 self.ntx = data['ntx']
164 self.ntx = data['ntx']
164 self.clock_in = data['clock_in']
165 self.clock_in = data['clock_in']
165 self.clock_divider = data['clock_divider']
166 self.clock_divider = data['clock_divider']
166 self.clock = data['clock']
167 self.clock = data['clock']
167 self.time_before = data['time_before']
168 self.time_before = data['time_before']
168 self.time_after = data['time_after']
169 self.time_after = data['time_after']
169 self.sync = data['sync']
170 self.sync = data['sync']
170 self.sampling_reference = data['sampling_reference']
171 self.sampling_reference = data['sampling_reference']
171 self.total_units = self.ipp*self.ntx*self.km2unit
172 self.total_units = self.ipp*self.ntx*self.km2unit
172 self.save()
173 self.save()
173 self.clean_lines()
174 self.clean_lines()
174
175
176 #print(params)
177
175 positions = {'tx':0, 'tr':0}
178 positions = {'tx':0, 'tr':0}
176 for i, id in enumerate(data['lines']):
179 for i, id in enumerate(data['lines']):
177 line_data = params['lines']['byId'][id]
180 line_data = params['lines']['byId'][id]
178 line_type = RCLineType.objects.get(name=line_data['line_type'])
181 line_type = RCLineType.objects.get(name=line_data['line_type'])
179 if line_type.name == 'codes':
182 if line_type.name == 'codes':
180 code = RCLineCode.objects.get(name=line_data['params']['code'])
183 code = RCLineCode.objects.get(name=line_data['params']['code'])
181 line_data['params']['code'] = code.pk
184 line_data['params']['code'] = code.pk
182 if line_type.name == 'tx':
185 if line_type.name == 'tx':
183 position = positions['tx']
186 position = positions['tx']
184 positions['tx'] += 1
187 positions['tx'] += 1
185 elif line_type.name == 'tr':
188 elif line_type.name == 'tr':
186 position = positions['tr']
189 position = positions['tr']
187 positions['tr'] += 1
190 positions['tr'] += 1
188 else:
191 else:
189 position = 0
192 position = 0
190 line, dum = RCLine.objects.update_or_create(
193 line, dum = RCLine.objects.update_or_create(
191 rc_configuration=self,
194 rc_configuration=self,
192 channel=i,
195 channel=i,
193 position=position,
196 position=position,
194 defaults={
197 defaults={
195 'line_type': line_type,
198 'line_type': line_type,
196 'params': json.dumps(line_data['params'])
199 'params': json.dumps(line_data['params'])
197 }
200 }
198 )
201 )
199
202
200 for i, line in enumerate(self.get_lines()):
203 for i, line in enumerate(self.get_lines()):
201 line_params = json.loads(line.params)
204 line_params = json.loads(line.params)
202 if 'TX_ref' in line_params:
205 if 'TX_ref' in line_params:
203 if line_params['TX_ref'] in (0, '0'):
206 if line_params['TX_ref'] in (0, '0'):
204 line_params['TX_ref'] = '0'
207 line_params['TX_ref'] = '0'
205 else:
208 else:
206 ref_id = '{}'.format(line_params['TX_ref'])
209 ref_id = '{}'.format(line_params['TX_ref'])
207 ref_line = params['lines']['byId'][ref_id]
210 ref_line = params['lines']['byId'][ref_id]
208 line_params['TX_ref'] = RCLine.objects.get(
211 line_params['TX_ref'] = RCLine.objects.get(
209 rc_configuration=self,
212 rc_configuration=self,
210 params=json.dumps(ref_line['params'])
213 params=json.dumps(ref_line['params'])
211 ).pk
214 ).pk
212 line.params = json.dumps(line_params)
215 line.params = json.dumps(line_params)
216 print(line.params)
213 line.save()
217 line.save()
214
218 print("Fin de dict to param")
215
219
216 def get_delays(self):
220 def get_delays(self):
217
221
218 pulses = [line.pulses_as_points() for line in self.get_lines()]
222 pulses = [line.pulses_as_points() for line in self.get_lines()]
219 points = [tup for tups in pulses for tup in tups]
223 points = [tup for tups in pulses for tup in tups]
220 points = set([x for tup in points for x in tup])
224 points = set([x for tup in points for x in tup])
221 points = list(points)
225 points = list(points)
222 points.sort()
226 points.sort()
223
227
224 if points[0]!=0:
228 if points[0]!=0:
225 points.insert(0, 0)
229 points.insert(0, 0)
226
230
227 return [points[i+1]-points[i] for i in range(len(points)-1)]
231 return [points[i+1]-points[i] for i in range(len(points)-1)]
228
232
229
233
230 def get_pulses(self, binary=True):
234 def get_pulses(self, binary=True):
231
235
232 pulses = [line.pulses_as_points() for line in self.get_lines()]
236 pulses = [line.pulses_as_points() for line in self.get_lines()]
233 tuples = [tup for tups in pulses for tup in tups]
237 tuples = [tup for tups in pulses for tup in tups]
234 points = set([x for tup in tuples for x in tup])
238 points = set([x for tup in tuples for x in tup])
235 points = list(points)
239 points = list(points)
236 points.sort()
240 points.sort()
237 states = []
241 states = []
238 last = [0 for x in pulses]
242 last = [0 for x in pulses]
239
243
240 for x in points:
244 for x in points:
241 dum = []
245 dum = []
242 for i, tups in enumerate(pulses):
246 for i, tups in enumerate(pulses):
243 ups = [tup[0] for tup in tups if tup!=(0,0)]
247 ups = [tup[0] for tup in tups if tup!=(0,0)]
244 dws = [tup[1] for tup in tups if tup!=(0,0)]
248 dws = [tup[1] for tup in tups if tup!=(0,0)]
245 if x in ups:
249 if x in ups:
246 dum.append(1)
250 dum.append(1)
247 elif x in dws:
251 elif x in dws:
248 dum.append(0)
252 dum.append(0)
249 else:
253 else:
250 dum.append(last[i])
254 dum.append(last[i])
251 states.append(dum)
255 states.append(dum)
252 last = dum
256 last = dum
253
257
254 if binary:
258 if binary:
255 ret = []
259 ret = []
256 for flips in states:
260 for flips in states:
257 flips.reverse()
261 flips.reverse()
258 ret.append(int(''.join([str(x) for x in flips]), 2))
262 ret.append(int(''.join([str(x) for x in flips]), 2))
259 states = ret
263 states = ret
260
264
261 return states[:-1]
265 return states[:-1]
262
266
263 def add_cmd(self, cmd):
267 def add_cmd(self, cmd):
264
268
265 if cmd in DAT_CMDS:
269 if cmd in DAT_CMDS:
266 return (255, DAT_CMDS[cmd])
270 return (255, DAT_CMDS[cmd])
267
271
268 def add_data(self, value):
272 def add_data(self, value):
269
273
270 return (254, value-1)
274 return (254, value-1)
271
275
272 def parms_to_binary(self, dat=True):
276 def parms_to_binary(self, dat=True):
273 '''
277 '''
274 Create "dat" stream to be send to CR
278 Create "dat" stream to be send to CR
275 '''
279 '''
276
280
277 data = bytearray()
281 data = bytearray()
278 # create header
282 # create header
279 data.extend(self.add_cmd('DISABLE'))
283 data.extend(self.add_cmd('DISABLE'))
280 data.extend(self.add_cmd('CONTINUE'))
284 data.extend(self.add_cmd('CONTINUE'))
281 data.extend(self.add_cmd('RESTART'))
285 data.extend(self.add_cmd('RESTART'))
282
286
283 if self.control_sw:
287 if self.control_sw:
284 data.extend(self.add_cmd('SW_ONE'))
288 data.extend(self.add_cmd('SW_ONE'))
285 else:
289 else:
286 data.extend(self.add_cmd('SW_ZERO'))
290 data.extend(self.add_cmd('SW_ZERO'))
287
291
288 if self.control_tx:
292 if self.control_tx:
289 data.extend(self.add_cmd('TX_ONE'))
293 data.extend(self.add_cmd('TX_ONE'))
290 else:
294 else:
291 data.extend(self.add_cmd('TX_ZERO'))
295 data.extend(self.add_cmd('TX_ZERO'))
292
296
293 # write divider
297 # write divider
294 data.extend(self.add_cmd('CLOCK_DIVIDER'))
298 data.extend(self.add_cmd('CLOCK_DIVIDER'))
295 data.extend(self.add_data(self.clock_divider))
299 data.extend(self.add_data(self.clock_divider))
296
300
297 # write delays
301 # write delays
298 data.extend(self.add_cmd('DELAY_START'))
302 data.extend(self.add_cmd('DELAY_START'))
299 # first delay is always zero
303 # first delay is always zero
300 data.extend(self.add_data(1))
304 data.extend(self.add_data(1))
301
305
302 delays = self.get_delays()
306 delays = self.get_delays()
303
307
304 for delay in delays:
308 for delay in delays:
305 while delay>252:
309 while delay>252:
306 data.extend(self.add_data(253))
310 data.extend(self.add_data(253))
307 delay -= 253
311 delay -= 253
308 data.extend(self.add_data(int(delay)))
312 data.extend(self.add_data(int(delay)))
309
313
310 # write flips
314 # write flips
311 data.extend(self.add_cmd('FLIP_START'))
315 data.extend(self.add_cmd('FLIP_START'))
312
316
313 states = self.get_pulses(binary=True)
317 states = self.get_pulses(binary=True)
314
318
315
319
316 last = 0
320 last = 0
317 for flip, delay in zip(states, delays):
321 for flip, delay in zip(states, delays):
318 data.extend(self.add_data((flip^last)+1))
322 data.extend(self.add_data((flip^last)+1))
319 last = flip
323 last = flip
320 while delay>252:
324 while delay>252:
321 data.extend(self.add_data(1))
325 data.extend(self.add_data(1))
322 delay -= 253
326 delay -= 253
323
327
324 # write sampling period
328 # write sampling period
325 data.extend(self.add_cmd('SAMPLING_PERIOD'))
329 data.extend(self.add_cmd('SAMPLING_PERIOD'))
326 wins = self.get_lines(line_type__name='windows')
330 wins = self.get_lines(line_type__name='windows')
327 if wins:
331 if wins:
328 win_params = json.loads(wins[0].params)['params']
332 win_params = json.loads(wins[0].params)['params']
329 if win_params:
333 if win_params:
330 dh = int(win_params[0]['resolution']*self.km2unit)
334 dh = int(win_params[0]['resolution']*self.km2unit)
331 else:
335 else:
332 dh = 1
336 dh = 1
333 else:
337 else:
334 dh = 1
338 dh = 1
335 data.extend(self.add_data(dh))
339 data.extend(self.add_data(dh))
336
340
337 # write enable
341 # write enable
338 data.extend(self.add_cmd('ENABLE'))
342 data.extend(self.add_cmd('ENABLE'))
339
343
340 if not dat:
344 if not dat:
341 return data
345 return data
342
346
343 return '\n'.join(['{}'.format(x) for x in data])
347 return '\n'.join(['{}'.format(x) for x in data])
344
348
345 def update_pulses(self):
349 def update_pulses(self):
346
350
347 for line in self.get_lines():
351 for line in self.get_lines():
348 line.update_pulses()
352 line.update_pulses()
349
353
350 def plot_pulses2(self, km=False):
354 def plot_pulses2(self, km=False):
351
355
352 import matplotlib
356 import matplotlib
353 matplotlib.use('Agg')
357 matplotlib.use('Agg')
354 import matplotlib.pyplot as plt
358 import matplotlib.pyplot as plt
355 from bokeh.resources import CDN
359 from bokeh.resources import CDN
356 from bokeh.embed import components
360 from bokeh.embed import components
357 from bokeh.mpl import to_bokeh
361 from bokeh.mpl import to_bokeh
358 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
362 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
359
363
360 lines = self.get_lines()
364 lines = self.get_lines()
361
365
362 N = len(lines)
366 N = len(lines)
363 npoints = self.total_units/self.km2unit if km else self.total_units
367 npoints = self.total_units/self.km2unit if km else self.total_units
364 fig = plt.figure(figsize=(12, 2+N*0.5))
368 fig = plt.figure(figsize=(12, 2+N*0.5))
365 ax = fig.add_subplot(111)
369 ax = fig.add_subplot(111)
366 labels = ['IPP']
370 labels = ['IPP']
367
371
368 for i, line in enumerate(lines):
372 for i, line in enumerate(lines):
369 labels.append(line.get_name(channel=True))
373 labels.append(line.get_name(channel=True))
370 l = ax.plot((0, npoints),(N-i-1, N-i-1))
374 l = ax.plot((0, npoints),(N-i-1, N-i-1))
371 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
375 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
372 ax.broken_barh(points, (N-i-1, 0.5),
376 ax.broken_barh(points, (N-i-1, 0.5),
373 edgecolor=l[0].get_color(), facecolor='none')
377 edgecolor=l[0].get_color(), facecolor='none')
374
378
375 n = 0
379 n = 0
376 f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
380 f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
377 for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
381 for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
378 if n%f==0:
382 if n%f==0:
379 ax.text(x, N, '%s' % n, size=10)
383 ax.text(x, N, '%s' % n, size=10)
380 n += 1
384 n += 1
381
385
382 labels.reverse()
386 labels.reverse()
383 ax.set_yticks(range(len(labels)))
387 ax.set_yticks(range(len(labels)))
384 ax.set_yticklabels(labels)
388 ax.set_yticklabels(labels)
385 ax.set_xlabel = 'Units'
389 ax.set_xlabel = 'Units'
386 plot = to_bokeh(fig, use_pandas=False)
390 plot = to_bokeh(fig, use_pandas=False)
387 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()]
391 plot.tools = [PanTool(dimensions="width"), WheelZoomTool(dimensions="width"), ResetTool(), SaveTool()]
388 plot.toolbar_location="above"
392 plot.toolbar_location="above"
389
393
390 return components(plot, CDN)
394 return components(plot, CDN)
391
395
392 def plot_pulses(self, km=False):
396 def plot_pulses(self, km=False):
393
397
394 from bokeh.plotting import figure
398 from bokeh.plotting import figure
395 from bokeh.resources import CDN
399 from bokeh.resources import CDN
396 from bokeh.embed import components
400 from bokeh.embed import components
397 from bokeh.models import FixedTicker, PrintfTickFormatter
401 from bokeh.models import FixedTicker, PrintfTickFormatter
398 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
402 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
399 from bokeh.models.sources import ColumnDataSource
403 from bokeh.models.sources import ColumnDataSource
400
404
401 lines = self.get_lines().reverse()
405 lines = self.get_lines().reverse()
402
406
403 N = len(lines)
407 N = len(lines)
404 npoints = self.total_units/self.km2unit if km else self.total_units
408 npoints = self.total_units/self.km2unit if km else self.total_units
405 ipp = self.ipp if km else self.ipp*self.km2unit
409 ipp = self.ipp if km else self.ipp*self.km2unit
406
410
407 hover = HoverTool(tooltips=[("Line", "@name"),
411 hover = HoverTool(tooltips=[("Line", "@name"),
408 ("IPP", "@ipp"),
412 ("IPP", "@ipp"),
409 ("X", "@left")])
413 ("X", "@left")])
410
414
411 tools = [PanTool(dimensions=['width']),
415 tools = [PanTool(dimensions="width"),
412 WheelZoomTool(dimensions=['width']),
416 WheelZoomTool(dimensions="width"),
413 hover, SaveTool()]
417 hover, SaveTool()]
414
418
415 plot = figure(width=1000,
419 plot = figure(width=1000,
416 height=40+N*50,
420 height=40+N*50,
417 y_range = (0, N),
421 y_range = (0, N),
418 tools=tools,
422 tools=tools,
419 toolbar_location='above',
423 toolbar_location='above',
420 toolbar_sticky=False,)
424 toolbar_sticky=False,)
421
425
422 plot.xaxis.axis_label = 'Km' if km else 'Units'
426 plot.xaxis.axis_label = 'Km' if km else 'Units'
423 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
427 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
424 plot.yaxis.axis_label = 'Pulses'
428 plot.yaxis.axis_label = 'Pulses'
425 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
429 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
426 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
430 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
427
431
428 for i, line in enumerate(lines):
432 for i, line in enumerate(lines):
429
433
430 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
434 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
431
435
432 source = ColumnDataSource(data = dict(
436 source = ColumnDataSource(data = dict(
433 bottom = [i for tup in points],
437 bottom = [i for tup in points],
434 top = [i+0.5 for tup in points],
438 top = [i+0.5 for tup in points],
435 left = [tup[0] for tup in points],
439 left = [tup[0] for tup in points],
436 right = [tup[1] for tup in points],
440 right = [tup[1] for tup in points],
437 ipp = [int(tup[0]/ipp) for tup in points],
441 ipp = [int(tup[0]/ipp) for tup in points],
438 name = [line.get_name() for tup in points]
442 name = [line.get_name() for tup in points]
439 ))
443 ))
440
444
441 plot.quad(
445 plot.quad(
442 bottom = 'bottom',
446 bottom = 'bottom',
443 top = 'top',
447 top = 'top',
444 left = 'left',
448 left = 'left',
445 right = 'right',
449 right = 'right',
446 source = source,
450 source = source,
447 fill_alpha = 0,
451 fill_alpha = 0,
448 #line_color = 'blue',
452 #line_color = 'blue',
449 )
453 )
450
454
451 plot.line([0, npoints], [i, i])#, color='blue')
455 plot.line([0, npoints], [i, i])#, color='blue')
452
456
453 return components(plot, CDN)
457 return components(plot, CDN)
454
458
455 def request(self, cmd, method='get', **kwargs):
459 def request(self, cmd, method='get', **kwargs):
456
460
457 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
461 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
458 payload = req.json()
462 payload = req.json()
459
463
460 return payload
464 return payload
461
465
462 def status_device(self):
466 def status_device(self):
463
467
464 try:
468 try:
465 self.device.status = 0
469 self.device.status = 0
466 payload = self.request('status')
470 payload = self.request('status')
467 if payload['status']=='enable':
471 if payload['status']=='enable':
468 self.device.status = 3
472 self.device.status = 3
469 elif payload['status']=='disable':
473 elif payload['status']=='disable':
470 self.device.status = 2
474 self.device.status = 2
471 else:
475 else:
472 self.device.status = 1
476 self.device.status = 1
473 self.device.save()
477 self.device.save()
474 self.message = 'RC status: {}'.format(payload['status'])
478 self.message = 'RC status: {}'.format(payload['status'])
475 return False
479 return False
476 except Exception as e:
480 except Exception as e:
477 if 'No route to host' not in str(e):
481 if 'No route to host' not in str(e):
478 self.device.status = 4
482 self.device.status = 4
479 self.device.save()
483 self.device.save()
480 self.message = 'RC status: {}'.format(str(e))
484 self.message = 'RC status: {}'.format(str(e))
481 return False
485 return False
482
486
483 self.device.save()
487 self.device.save()
484 return True
488 return True
485
489
486 def reset_device(self):
490 def reset_device(self):
487
491
488 try:
492 try:
489 payload = self.request('reset', 'post')
493 payload = self.request('reset', 'post')
490 if payload['reset']=='ok':
494 if payload['reset']=='ok':
491 self.message = 'RC restarted OK'
495 self.message = 'RC restarted OK'
492 self.device.status = 2
496 self.device.status = 2
493 self.device.save()
497 self.device.save()
494 else:
498 else:
495 self.message = 'RC restart fail'
499 self.message = 'RC restart fail'
496 self.device.status = 4
500 self.device.status = 4
497 self.device.save()
501 self.device.save()
498 except Exception as e:
502 except Exception as e:
499 self.message = 'RC reset: {}'.format(str(e))
503 self.message = 'RC reset: {}'.format(str(e))
500 return False
504 return False
501
505
502 return True
506 return True
503
507
504 def stop_device(self):
508 def stop_device(self):
505
509
506 try:
510 try:
507 payload = self.request('stop', 'post')
511 payload = self.request('stop', 'post')
508 self.message = 'RC stop: {}'.format(payload['stop'])
512 self.message = 'RC stop: {}'.format(payload['stop'])
509 if payload['stop']=='ok':
513 if payload['stop']=='ok':
510 self.device.status = 2
514 self.device.status = 2
511 self.device.save()
515 self.device.save()
512 else:
516 else:
513 self.device.status = 4
517 self.device.status = 4
514 self.device.save()
518 self.device.save()
515 return False
519 return False
516 except Exception as e:
520 except Exception as e:
517 if 'No route to host' not in str(e):
521 if 'No route to host' not in str(e):
518 self.device.status = 4
522 self.device.status = 4
519 else:
523 else:
520 self.device.status = 0
524 self.device.status = 0
521 self.message = 'RC stop: {}'.format(str(e))
525 self.message = 'RC stop: {}'.format(str(e))
522 self.device.save()
526 self.device.save()
523 return False
527 return False
524
528
525 return True
529 return True
526
530
527 def start_device(self):
531 def start_device(self):
528
532
529 try:
533 try:
530 payload = self.request('start', 'post')
534 payload = self.request('start', 'post')
531 self.message = 'RC start: {}'.format(payload['start'])
535 self.message = 'RC start: {}'.format(payload['start'])
532 if payload['start']=='ok':
536 if payload['start']=='ok':
533 self.device.status = 3
537 self.device.status = 3
534 self.device.save()
538 self.device.save()
535 else:
539 else:
536 return False
540 return False
537 except Exception as e:
541 except Exception as e:
538 if 'No route to host' not in str(e):
542 if 'No route to host' not in str(e):
539 self.device.status = 4
543 self.device.status = 4
540 else:
544 else:
541 self.device.status = 0
545 self.device.status = 0
542 self.message = 'RC start: {}'.format(str(e))
546 self.message = 'RC start: {}'.format(str(e))
543 self.device.save()
547 self.device.save()
544 return False
548 return False
545
549
546 return True
550 return True
547
551
548 def write_device(self, raw=False):
552 def write_device(self, raw=False):
549
553
550 if not raw:
554 if not raw:
551 clock = RCClock.objects.get(rc_configuration=self)
555 clock = RCClock.objects.get(rc_configuration=self)
552 if clock.mode:
556 if clock.mode:
553 data = {'default': clock.frequency}
557 data = {'default': clock.frequency}
554 else:
558 else:
555 data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
559 data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
556 payload = self.request('setfreq', 'post', data=json.dumps(data))
560 payload = self.request('setfreq', 'post', data=json.dumps(data))
557 if payload['command'] != 'ok':
561 if payload['command'] != 'ok':
558 self.message = 'RC write: {}'.format(payload['command'])
562 self.message = 'RC write: {}'.format(payload['command'])
559 else:
563 else:
560 self.message = payload['programming']
564 self.message = payload['programming']
561 if payload['programming'] == 'fail':
565 if payload['programming'] == 'fail':
562 self.message = 'RC write: error programming CGS chip'
566 self.message = 'RC write: error programming CGS chip'
563
567
564 values = []
568 values = []
565 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
569 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
566 while delay>65536:
570 while delay>65536:
567 values.append((pulse, 65535))
571 values.append((pulse, 65535))
568 delay -= 65536
572 delay -= 65536
569 values.append((pulse, delay-1))
573 values.append((pulse, delay-1))
570 data = bytearray()
574 data = bytearray()
571 #reset
575 #reset
572 data.extend((128, 0))
576 data.extend((128, 0))
573 #disable
577 #disable
574 data.extend((129, 0))
578 data.extend((129, 0))
575 #SW switch
579 #SW switch
576 if self.control_sw:
580 if self.control_sw:
577 data.extend((130, 2))
581 data.extend((130, 2))
578 else:
582 else:
579 data.extend((130, 0))
583 data.extend((130, 0))
580 #divider
584 #divider
581 data.extend((131, self.clock_divider-1))
585 data.extend((131, self.clock_divider-1))
582 #enable writing
586 #enable writing
583 data.extend((139, 62))
587 data.extend((139, 62))
584
588
585 last = 0
589 last = 0
586 for tup in values:
590 for tup in values:
587 vals = pack('<HH', last^tup[0], tup[1])
591 vals = pack('<HH', last^tup[0], tup[1])
588 last = tup[0]
592 last = tup[0]
589 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
593 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
590
594
591 #enable
595 #enable
592 data.extend((129, 1))
596 data.extend((129, 1))
593
597
594 if raw:
598 if raw:
595 return b64encode(data)
599 return b64encode(data)
596
600
597 try:
601 try:
598 payload = self.request('stop', 'post')
602 payload = self.request('stop', 'post')
599 payload = self.request('reset', 'post')
603 payload = self.request('reset', 'post')
600 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
604 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
601 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
605 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
602 n = len(data)
606 n = len(data)
603 x = 0
607 x = 0
604 #while x < n:
608 #while x < n:
605 payload = self.request('write', 'post', data=b64encode(data))
609 payload = self.request('write', 'post', data=b64encode(data))
606 # x += 1024
610 # x += 1024
607
611
608 if payload['write']=='ok':
612 if payload['write']=='ok':
609 self.device.status = 3
613 self.device.status = 3
610 self.device.save()
614 self.device.save()
611 self.message = 'RC configured and started'
615 self.message = 'RC configured and started'
612 else:
616 else:
613 self.device.status = 1
617 self.device.status = 1
614 self.device.save()
618 self.device.save()
615 self.message = 'RC write: {}'.format(payload['write'])
619 self.message = 'RC write: {}'.format(payload['write'])
616 return False
620 return False
617
621
618 #payload = self.request('start', 'post')
622 #payload = self.request('start', 'post')
619
623
620 except Exception as e:
624 except Exception as e:
621 if 'No route to host' not in str(e):
625 if 'No route to host' not in str(e):
622 self.device.status = 4
626 self.device.status = 4
623 else:
627 else:
624 self.device.status = 0
628 self.device.status = 0
625 self.message = 'RC write: {}'.format(str(e))
629 self.message = 'RC write: {}'.format(str(e))
626 self.device.save()
630 self.device.save()
627 return False
631 return False
628
632
629 return True
633 return True
630
634
631
635
632 def get_absolute_url_import(self):
636 def get_absolute_url_import(self):
633 return reverse('url_import_rc_conf', args=[str(self.id)])
637 return reverse('url_import_rc_conf', args=[str(self.id)])
634
638
635
639
636 class RCLineCode(models.Model):
640 class RCLineCode(models.Model):
637
641
638 name = models.CharField(max_length=40)
642 name = models.CharField(max_length=40)
639 bits_per_code = models.PositiveIntegerField(default=0)
643 bits_per_code = models.PositiveIntegerField(default=0)
640 number_of_codes = models.PositiveIntegerField(default=0)
644 number_of_codes = models.PositiveIntegerField(default=0)
641 codes = models.TextField(blank=True, null=True)
645 codes = models.TextField(blank=True, null=True)
642
646
643 class Meta:
647 class Meta:
644 db_table = 'rc_line_codes'
648 db_table = 'rc_line_codes'
645 ordering = ('name',)
649 ordering = ('name',)
646
650
647 def __str__(self):
651 def __str__(self):
648 return u'%s' % self.name
652 return u'%s' % self.name
649
653
650
654
651 class RCLineType(models.Model):
655 class RCLineType(models.Model):
652
656
653 name = models.CharField(choices=LINE_TYPES, max_length=40)
657 name = models.CharField(choices=LINE_TYPES, max_length=40)
654 description = models.TextField(blank=True, null=True)
658 description = models.TextField(blank=True, null=True)
655 params = models.TextField(default='[]')
659 params = models.TextField(default='[]')
656
660
657 class Meta:
661 class Meta:
658 db_table = 'rc_line_types'
662 db_table = 'rc_line_types'
659
663
660 def __str__(self):
664 def __str__(self):
661 return u'%s - %s' % (self.name.upper(), self.get_name_display())
665 return u'%s - %s' % (self.name.upper(), self.get_name_display())
662
666
663
667
664 class RCLine(models.Model):
668 class RCLine(models.Model):
665
669
666 rc_configuration = models.ForeignKey('RCConfiguration', on_delete=models.CASCADE)
670 rc_configuration = models.ForeignKey('RCConfiguration', on_delete=models.CASCADE)
667 line_type = models.ForeignKey('RCLineType',on_delete=models.CASCADE)
671 line_type = models.ForeignKey('RCLineType',on_delete=models.CASCADE)
668 channel = models.PositiveIntegerField(default=0)
672 channel = models.PositiveIntegerField(default=0)
669 position = models.PositiveIntegerField(default=0)
673 position = models.PositiveIntegerField(default=0)
670 params = models.TextField(default='{}')
674 params = models.TextField(default='{}')
671 pulses = models.TextField(default='')
675 pulses = models.TextField(default='')
672
676
673 class Meta:
677 class Meta:
674 db_table = 'rc_lines'
678 db_table = 'rc_lines'
675 ordering = ['channel']
679 ordering = ['channel']
676
680
677 def __str__(self):
681 def __str__(self):
678 if self.rc_configuration:
682 if self.rc_configuration:
679 return u'{}|{} - {}'.format(self.pk, self.get_name(), self.rc_configuration.name)
683 return u'{}|{} - {}'.format(self.pk, self.get_name(), self.rc_configuration.name)
680
684
681 def jsonify(self):
685 def jsonify(self):
682
686
683 data = {}
687 data = {}
684 data['params'] = json.loads(self.params)
688 data['params'] = json.loads(self.params)
685 data['id'] = '{}'.format(self.pk)
689 data['id'] = '{}'.format(self.pk)
686 data['line_type'] = self.line_type.name
690 data['line_type'] = self.line_type.name
687 data['name'] = self.get_name()
691 data['name'] = self.get_name()
688 if data['line_type']=='codes':
692 if data['line_type']=='codes':
689 data['params']['code'] = RCLineCode.objects.get(pk=data['params']['code']).name
693 data['params']['code'] = RCLineCode.objects.get(pk=data['params']['code']).name
690
694
691 return data
695 return data
692
696
693
697
694 def clone(self, **kwargs):
698 def clone(self, **kwargs):
695
699
696 self.pk = None
700 self.pk = None
697 self.id = None
701 self.id = None
698
702
699 for attr, value in kwargs.items():
703 for attr, value in kwargs.items():
700 setattr(self, attr, value)
704 setattr(self, attr, value)
701
705
702 self.save()
706 self.save()
703
707
704 return self
708 return self
705
709
706 def get_name(self, channel=False):
710 def get_name(self, channel=False):
707
711
708 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
712 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
709 s = ''
713 s = ''
710
714
711 if self.line_type.name in ('tx',):
715 if self.line_type.name in ('tx',):
712 s = chars[self.position]
716 s = chars[self.position]
713 elif self.line_type.name in ('codes', 'windows', 'tr'):
717 elif self.line_type.name in ('codes', 'windows', 'tr'):
714 if 'TX_ref' in json.loads(self.params):
718 if 'TX_ref' in json.loads(self.params):
715 pk = json.loads(self.params)['TX_ref']
719 pk = json.loads(self.params)['TX_ref']
716 if pk in (0, '0'):
720 if pk in (0, '0'):
717 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
721 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
718 else:
722 else:
719 ref = RCLine.objects.get(pk=pk)
723 ref = RCLine.objects.get(pk=pk)
720 s = chars[ref.position]
724 s = chars[ref.position]
721 s = '({})'.format(s)
725 s = '({})'.format(s)
722
726
723 s = '{}{}'.format(self.line_type.name.upper(), s)
727 s = '{}{}'.format(self.line_type.name.upper(), s)
724
728
725 if channel:
729 if channel:
726 return '{} {}'.format(s, self.channel)
730 return '{} {}'.format(s, self.channel)
727 else:
731 else:
728 return s
732 return s
729
733
730 def get_lines(self, **kwargs):
734 def get_lines(self, **kwargs):
731
735
732 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
736 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
733
737
734 def pulses_as_array(self):
738 def pulses_as_array(self):
735
739
736 y = np.zeros(self.rc_configuration.total_units)
740 y = np.zeros(self.rc_configuration.total_units)
737
741
738 for tup in ast.literal_eval(self.pulses):
742 for tup in ast.literal_eval(self.pulses):
739 y[tup[0]:tup[1]] = 1
743 y[tup[0]:tup[1]] = 1
740
744
741 return y.astype(np.int8)
745 return y.astype(np.int8)
742
746
743 def pulses_as_points(self, km=False):
747 def pulses_as_points(self, km=False):
744
748
745 if km:
749 if km:
746 unit2km = 1/self.rc_configuration.km2unit
750 unit2km = 1/self.rc_configuration.km2unit
747 return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
751 return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
748 else:
752 else:
749 return ast.literal_eval(self.pulses)
753 return ast.literal_eval(self.pulses)
750
754
751 def get_win_ref(self, params, tx_id, km2unit):
755 def get_win_ref(self, params, tx_id, km2unit):
752
756
753 ref = self.rc_configuration.sampling_reference
757 ref = self.rc_configuration.sampling_reference
754 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
758 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
755
759
756 if codes:
760 if codes:
757 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
761 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
758 else:
762 else:
759 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
763 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
760
764
761 if ref=='first_baud':
765 if ref=='first_baud':
762 return int(1 + round((tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit))
766 return int(1 + round((tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit))
763 elif ref=='sub_baud':
767 elif ref=='sub_baud':
764 return np.ceil(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
768 return np.ceil(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
765 else:
769 else:
766 return 0
770 return 0
767
771
768 def update_pulses(self):
772 def update_pulses(self):
769 '''
773 '''
770 Update pulses field
774 Update pulses field
771 '''
775 '''
772
776
773 km2unit = self.rc_configuration.km2unit
777 km2unit = self.rc_configuration.km2unit
774 us2unit = self.rc_configuration.us2unit
778 us2unit = self.rc_configuration.us2unit
775 ipp = self.rc_configuration.ipp
779 ipp = self.rc_configuration.ipp
776 ntx = int(self.rc_configuration.ntx)
780 ntx = int(self.rc_configuration.ntx)
777 ipp_u = int(ipp*km2unit)
781 ipp_u = int(ipp*km2unit)
778 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
782 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
779 y = []
783 y = []
780
784
781 if self.line_type.name=='tr':
785 if self.line_type.name=='tr':
782 tr_params = json.loads(self.params)
786 tr_params = json.loads(self.params)
783
787 #print(tr_params)
788 #print(tr_params['TX_ref'])
784 if tr_params['TX_ref'] in ('0', 0):
789 if tr_params['TX_ref'] in ('0', 0):
785 txs = self.get_lines(line_type__name='tx')
790 txs = self.get_lines(line_type__name='tx')
786 else:
791 else:
787 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
792 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
788
793
789 for tx in txs:
794 for tx in txs:
790 params = json.loads(tx.params)
795 params = json.loads(tx.params)
791
796
792 if float(params['pulse_width'])==0:
797 if float(params['pulse_width'])==0:
793 continue
798 continue
794 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
799 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
795 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
800 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
796 before = 0
801 before = 0
797 after = int(self.rc_configuration.time_after*us2unit)
802 after = int(self.rc_configuration.time_after*us2unit)
798
803
799 y_tx = self.points(ntx, ipp_u, width,
804 y_tx = self.points(ntx, ipp_u, width,
800 delay=delays,
805 delay=delays,
801 before=before,
806 before=before,
802 after=after,
807 after=after,
803 sync=self.rc_configuration.sync)
808 sync=self.rc_configuration.sync)
804
809
805 ranges = params['range'].split(',')
810 ranges = params['range'].split(',')
806
811
807 if len(ranges)>0 and ranges[0]!='0':
812 if len(ranges)>0 and ranges[0]!='0':
808 y_tx = self.mask_ranges(y_tx, ranges)
813 y_tx = self.mask_ranges(y_tx, ranges)
809
814
810 tr_ranges = tr_params['range'].split(',')
815 tr_ranges = tr_params['range'].split(',')
811
816
812 if len(tr_ranges)>0 and tr_ranges[0]!='0':
817 if len(tr_ranges)>0 and tr_ranges[0]!='0':
813 y_tx = self.mask_ranges(y_tx, tr_ranges)
818 y_tx = self.mask_ranges(y_tx, tr_ranges)
814
819
815 y.extend(y_tx)
820 y.extend(y_tx)
816
821
817 self.pulses = str(y)
822 self.pulses = str(y)
818 y = self.array_to_points(self.pulses_as_array())
823 y = self.array_to_points(self.pulses_as_array())
819
824
820 elif self.line_type.name=='tx':
825 elif self.line_type.name=='tx':
821 params = json.loads(self.params)
826 params = json.loads(self.params)
822 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
827 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
823 width = float(params['pulse_width'])*km2unit
828 width = float(params['pulse_width'])*km2unit
824
829
825 if width>0:
830 if width>0:
826 before = int(self.rc_configuration.time_before*us2unit)
831 before = int(self.rc_configuration.time_before*us2unit)
827 after = 0
832 after = 0
828
833
829 y = self.points(ntx, ipp_u, width,
834 y = self.points(ntx, ipp_u, width,
830 delay=delays,
835 delay=delays,
831 before=before,
836 before=before,
832 after=after,
837 after=after,
833 sync=self.rc_configuration.sync)
838 sync=self.rc_configuration.sync)
834
839
835 ranges = params['range'].split(',')
840 ranges = params['range'].split(',')
836
841
837 if len(ranges)>0 and ranges[0]!='0':
842 if len(ranges)>0 and ranges[0]!='0':
838 y = self.mask_ranges(y, ranges)
843 y = self.mask_ranges(y, ranges)
839
844
840 elif self.line_type.name=='flip':
845 elif self.line_type.name=='flip':
841 n = float(json.loads(self.params)['number_of_flips'])
846 n = float(json.loads(self.params)['number_of_flips'])
842 width = n*ipp*km2unit
847 width = n*ipp*km2unit
843 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
848 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
844
849
845 elif self.line_type.name=='codes':
850 elif self.line_type.name=='codes':
846 params = json.loads(self.params)
851 params = json.loads(self.params)
847 tx = RCLine.objects.get(pk=params['TX_ref'])
852 tx = RCLine.objects.get(pk=params['TX_ref'])
848 tx_params = json.loads(tx.params)
853 tx_params = json.loads(tx.params)
849 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
854 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
850 f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
855 f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
851 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
856 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
852 codes = [self.array_to_points(code) for code in codes]
857 codes = [self.array_to_points(code) for code in codes]
853 n = len(codes)
858 n = len(codes)
854
859
855 ranges = tx_params['range'].split(',')
860 ranges = tx_params['range'].split(',')
856 if len(ranges)>0 and ranges[0]!='0':
861 if len(ranges)>0 and ranges[0]!='0':
857 dum = self.mask_ranges(tx.pulses_as_points(), ranges)
862 dum = self.mask_ranges(tx.pulses_as_points(), ranges)
858 else:
863 else:
859 dum = tx.pulses_as_points()
864 dum = tx.pulses_as_points()
860
865
861 for i, tup in enumerate(dum):
866 for i, tup in enumerate(dum):
862 if tup==(0,0): continue
867 if tup==(0,0): continue
863 code = codes[i%n]
868 code = codes[i%n]
864 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
869 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
865
870
866 elif self.line_type.name=='sync':
871 elif self.line_type.name=='sync':
867 params = json.loads(self.params)
872 params = json.loads(self.params)
868 n = ipp_u*ntx
873 n = ipp_u*ntx
869 if params['invert'] in ('1', 1):
874 if params['invert'] in ('1', 1):
870 y = [(n-1, n)]
875 y = [(n-1, n)]
871 else:
876 else:
872 y = [(0, 1)]
877 y = [(0, 1)]
873
878
874 elif self.line_type.name=='prog_pulses':
879 elif self.line_type.name=='prog_pulses':
875 params = json.loads(self.params)
880 params = json.loads(self.params)
876 if int(params['periodic'])==0:
881 if int(params['periodic'])==0:
877 nntx = 1
882 nntx = 1
878 nipp = ipp_u*ntx
883 nipp = ipp_u*ntx
879 else:
884 else:
880 nntx = ntx
885 nntx = ntx
881 nipp = ipp_u
886 nipp = ipp_u
882
887
883 if 'params' in params and len(params['params'])>0:
888 if 'params' in params and len(params['params'])>0:
884 for p in params['params']:
889 for p in params['params']:
885 y_pp = self.points(nntx, nipp,
890 y_pp = self.points(nntx, nipp,
886 p['end']-p['begin'],
891 p['end']-p['begin'],
887 before=p['begin'])
892 before=p['begin'])
888
893
889 y.extend(y_pp)
894 y.extend(y_pp)
890
895
891 elif self.line_type.name=='windows':
896 elif self.line_type.name=='windows':
892 params = json.loads(self.params)
897 params = json.loads(self.params)
893 if 'params' in params and len(params['params'])>0:
898 if 'params' in params and len(params['params'])>0:
894 tx = RCLine.objects.get(pk=params['TX_ref'])
899 tx = RCLine.objects.get(pk=params['TX_ref'])
895 tx_params = json.loads(tx.params)
900 tx_params = json.loads(tx.params)
896 ranges = tx_params['range'].split(',')
901 ranges = tx_params['range'].split(',')
897 for p in params['params']:
902 for p in params['params']:
898 y_win = self.points(ntx, ipp_u,
903 y_win = self.points(ntx, ipp_u,
899 p['resolution']*p['number_of_samples']*km2unit,
904 p['resolution']*p['number_of_samples']*km2unit,
900 before=int(self.rc_configuration.time_before*us2unit)+p['first_height']*km2unit,
905 before=int(self.rc_configuration.time_before*us2unit)+p['first_height']*km2unit,
901 sync=self.rc_configuration.sync+self.get_win_ref(p, params['TX_ref'], km2unit))
906 sync=self.rc_configuration.sync+self.get_win_ref(p, params['TX_ref'], km2unit))
902
907
903
908
904 if len(ranges)>0 and ranges[0]!='0':
909 if len(ranges)>0 and ranges[0]!='0':
905 y_win = self.mask_ranges(y_win, ranges)
910 y_win = self.mask_ranges(y_win, ranges)
906
911
907 y.extend(y_win)
912 y.extend(y_win)
908
913
909 elif self.line_type.name=='mix':
914 elif self.line_type.name=='mix':
910 values = self.rc_configuration.parameters.split('-')
915 values = self.rc_configuration.parameters.split('-')
911 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
916 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
912 modes = [value.split('|')[1] for value in values]
917 modes = [value.split('|')[1] for value in values]
913 ops = [value.split('|')[2] for value in values]
918 ops = [value.split('|')[2] for value in values]
914 delays = [value.split('|')[3] for value in values]
919 delays = [value.split('|')[3] for value in values]
915 masks = [value.split('|')[4] for value in values]
920 masks = [value.split('|')[4] for value in values]
916 mask = list('{:8b}'.format(int(masks[0])))
921 mask = list('{:8b}'.format(int(masks[0])))
917 mask.reverse()
922 mask.reverse()
918 if mask[self.channel] in ('0', '', ' '):
923 if mask[self.channel] in ('0', '', ' '):
919 y = np.zeros(confs[0].total_units, dtype=np.int8)
924 y = np.zeros(confs[0].total_units, dtype=np.int8)
920 else:
925 else:
921 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
926 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
922
927
923 for i in range(1, len(values)):
928 for i in range(1, len(values)):
924 mask = list('{:8b}'.format(int(masks[i])))
929 mask = list('{:8b}'.format(int(masks[i])))
925 mask.reverse()
930 mask.reverse()
926
931
927 if mask[self.channel] in ('0', '', ' '):
932 if mask[self.channel] in ('0', '', ' '):
928 continue
933 continue
929 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
934 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
930 delay = float(delays[i])*km2unit
935 delay = float(delays[i])*km2unit
931
936
932 if modes[i]=='P':
937 if modes[i]=='P':
933 if delay>0:
938 if delay>0:
934 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
939 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
935 y_temp = np.empty_like(Y)
940 y_temp = np.empty_like(Y)
936 y_temp[:delay] = 0
941 y_temp[:delay] = 0
937 y_temp[delay:] = Y[:-delay]
942 y_temp[delay:] = Y[:-delay]
938 elif delay+len(Y)>len(y):
943 elif delay+len(Y)>len(y):
939 y_new = np.zeros(delay+len(Y), dtype=np.int8)
944 y_new = np.zeros(delay+len(Y), dtype=np.int8)
940 y_new[:len(y)] = y
945 y_new[:len(y)] = y
941 y = y_new
946 y = y_new
942 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
947 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
943 y_temp[-len(Y):] = Y
948 y_temp[-len(Y):] = Y
944 elif delay+len(Y)==len(y):
949 elif delay+len(Y)==len(y):
945 y_temp = np.zeros(delay+len(Y))
950 y_temp = np.zeros(delay+len(Y))
946 y_temp[-len(Y):] = Y
951 y_temp[-len(Y):] = Y
947 elif delay+len(Y)<len(y):
952 elif delay+len(Y)<len(y):
948 y_temp = np.zeros(len(y), dtype=np.int8)
953 y_temp = np.zeros(len(y), dtype=np.int8)
949 y_temp[delay:delay+len(Y)] = Y
954 y_temp[delay:delay+len(Y)] = Y
950 else:
955 else:
951 y_temp = Y.copy()
956 y_temp = Y.copy()
952
957
953 if ops[i]=='OR':
958 if ops[i]=='OR':
954 y = y | y_temp
959 y = y | y_temp
955 elif ops[i]=='XOR':
960 elif ops[i]=='XOR':
956 y = y ^ y_temp
961 y = y ^ y_temp
957 elif ops[i]=='AND':
962 elif ops[i]=='AND':
958 y = y & y_temp
963 y = y & y_temp
959 elif ops[i]=='NAND':
964 elif ops[i]=='NAND':
960 y = y & ~y_temp
965 y = y & ~y_temp
961 else:
966 else:
962 y = np.concatenate([y, Y])
967 y = np.concatenate([y, Y])
963
968
964 total = len(y)
969 total = len(y)
965 y = self.array_to_points(y)
970 y = self.array_to_points(y)
966
971
967 else:
972 else:
968 y = []
973 y = []
969
974
970 if self.rc_configuration.total_units != total:
975 if self.rc_configuration.total_units != total:
971 self.rc_configuration.total_units = total
976 self.rc_configuration.total_units = total
972 self.rc_configuration.save()
977 self.rc_configuration.save()
973
978
974 self.pulses = str(y)
979 self.pulses = str(y)
975 self.save()
980 self.save()
976
981
977 @staticmethod
982 @staticmethod
978 def array_to_points(X):
983 def array_to_points(X):
979
984
980 if X.size==0:
985 if X.size==0:
981 return []
986 return []
982
987
983 d = X[1:]-X[:-1]
988 d = X[1:]-X[:-1]
984
989
985 up = np.where(d==1)[0]
990 up = np.where(d==1)[0]
986 if X[0]==1:
991 if X[0]==1:
987 up = np.concatenate((np.array([-1]), up))
992 up = np.concatenate((np.array([-1]), up))
988 up += 1
993 up += 1
989
994
990 dw = np.where(d==-1)[0]
995 dw = np.where(d==-1)[0]
991 if X[-1]==1:
996 if X[-1]==1:
992 dw = np.concatenate((dw, np.array([len(X)-1])))
997 dw = np.concatenate((dw, np.array([len(X)-1])))
993 dw += 1
998 dw += 1
994
999
995 return [(tup[0], tup[1]) for tup in zip(up, dw)]
1000 return [(tup[0], tup[1]) for tup in zip(up, dw)]
996
1001
997 @staticmethod
1002 @staticmethod
998 def mask_ranges(Y, ranges):
1003 def mask_ranges(Y, ranges):
999
1004
1000 y = [(0, 0) for __ in Y]
1005 y = [(0, 0) for __ in Y]
1001
1006
1002 for index in ranges:
1007 for index in ranges:
1003 if '-' in index:
1008 if '-' in index:
1004 args = [int(a) for a in index.split('-')]
1009 args = [int(a) for a in index.split('-')]
1005 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
1010 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
1006 else:
1011 else:
1007 y[int(index)-1] = Y[int(index)-1]
1012 y[int(index)-1] = Y[int(index)-1]
1008
1013
1009 return y
1014 return y
1010
1015
1011 @staticmethod
1016 @staticmethod
1012 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
1017 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
1013
1018
1014 delays = len(delay)
1019 delays = len(delay)
1015
1020
1016 Y = [(int(ipp*x+before+delay[x%delays]+sync), int(ipp*x+width+before+delay[x%delays]+after+sync)) for x in range(ntx)]
1021 Y = [(int(ipp*x+before+delay[x%delays]+sync), int(ipp*x+width+before+delay[x%delays]+after+sync)) for x in range(ntx)]
1017
1022
1018 return Y
1023 return Y
1019
1024
1020 class RCClock(models.Model):
1025 class RCClock(models.Model):
1021
1026
1022 rc_configuration = models.ForeignKey('RCConfiguration', on_delete=models.CASCADE)
1027 rc_configuration = models.ForeignKey('RCConfiguration', on_delete=models.CASCADE)
1023 mode = models.BooleanField(default=True, choices=((True, 'Auto'), (False, 'Manual')))
1028 mode = models.BooleanField(default=True, choices=((True, 'Auto'), (False, 'Manual')))
1024 multiplier = models.PositiveIntegerField(default=60)
1029 multiplier = models.PositiveIntegerField(default=60)
1025 divisor = models.PositiveIntegerField(default=10)
1030 divisor = models.PositiveIntegerField(default=10)
1026 reference = models.PositiveSmallIntegerField(default=1, choices=((0, 'Internal (25MHz)'), (1, 'External (10MHz)')))
1031 reference = models.PositiveSmallIntegerField(default=1, choices=((0, 'Internal (25MHz)'), (1, 'External (10MHz)')))
1027 frequency = models.FloatField(default=60.0) No newline at end of file
1032 frequency = models.FloatField(default=60.0)
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now