##// END OF EJS Templates
Add compatibility with embed CGS in RC
Juan C. Espinoza -
r328:e61e12b2d8be
parent child
Show More
@@ -1,12 +1,12
1 REDIS_HOST=radarsys-redis
1 REDIS_HOST=radarsys-redis
2 REDIS_PORT=6379
2 REDIS_PORT=6379
3 POSTGRES_DB_NAME=radarsys
4 POSTGRES_PORT_5432_TCP_ADDR=radarsys-postgres
3 POSTGRES_PORT_5432_TCP_ADDR=radarsys-postgres
5 POSTGRES_PORT_5432_TCP_PORT=5432
4 POSTGRES_PORT_5432_TCP_PORT=5432
6 POSTGRES_USER=docker
5 DB_NAME=radarsys
7 POSTGRES_PASSWORD=docker
6 DB_USER=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=/Volumes/dockers/radarsys/
12 LOCAL_IP=192.168.1.128
12 LOCAL_IP=192.168.1.128
@@ -1,79 +1,81
1 {% extends "base.html" %}
1 {% extends "base.html" %}
2 {% load bootstrap3 %}
2 {% load bootstrap3 %}
3 {% load static %}
3 {% load static %}
4 {% load main_tags %}
4 {% load main_tags %}
5 {% block content-title %}{{title}}{% endblock %}
5 {% block content-title %}{{title}}{% endblock %}
6 {% block content-suptitle %}{{suptitle}}{% endblock %}
6 {% block content-suptitle %}{{suptitle}}{% endblock %}
7
7
8 {% block content %}
8 {% block content %}
9
9
10 {% block menu-actions %}
10 {% block menu-actions %}
11 <span class=" dropdown pull-right">
11 <span class=" dropdown pull-right">
12 <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-menu-hamburger gi-2x" aria-hidden="true"></span></a>
12 <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-menu-hamburger gi-2x" aria-hidden="true"></span></a>
13 <ul class="dropdown-menu" role="menu">
13 <ul class="dropdown-menu" role="menu">
14 <li><a href="{{ dev_conf.get_absolute_url_edit }}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</a></li>
14 <li><a href="{{ dev_conf.get_absolute_url_edit }}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</a></li>
15 <li><a href="{{ dev_conf.get_absolute_url_delete }}"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Delete</a></li>
15 <li><a href="{{ dev_conf.get_absolute_url_delete }}"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Delete</a></li>
16 <li><a href="{{ dev_conf.get_absolute_url_import }}"><span class="glyphicon glyphicon-import" aria-hidden="true"></span> Import </a></li>
16 <li><a href="{{ dev_conf.get_absolute_url_import }}"><span class="glyphicon glyphicon-import" aria-hidden="true"></span> Import </a></li>
17 <li><a href="{{ dev_conf.get_absolute_url_export }}"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Export </a></li>
17 <li><a href="{{ dev_conf.get_absolute_url_export }}"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Export </a></li>
18 {% block extra-menu-actions %}
18 {% block extra-menu-actions %}
19 {% endblock %}
19 {% endblock %}
20 <li><a>----------------</a></li>
20 <li><a>----------------</a></li>
21 <li><a href="{{ dev_conf.get_absolute_url_status }}"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> Status</a></li>
21 <li><a href="{{ dev_conf.get_absolute_url_status }}"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> Status</a></li>
22 {% if not no_play %}
22 {% if not no_play %}
23 {% if not only_stop %}
23 {% if not only_stop %}
24 <li><a href="{{ dev_conf.get_absolute_url_start}}"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Start</a></li>
24 <li><a href="{{ dev_conf.get_absolute_url_start}}"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Start</a></li>
25 {% endif %}
25 {% endif %}
26 <li><a href="{{ dev_conf.get_absolute_url_stop }}"><span class="glyphicon glyphicon-stop" aria-hidden="true"></span> Stop</a></li>
26 <li><a href="{{ dev_conf.get_absolute_url_stop }}"><span class="glyphicon glyphicon-stop" aria-hidden="true"></span> Stop</a></li>
27 {% endif %}
27 {% endif %}
28 <li><a href="{{ dev_conf.get_absolute_url_write }}"><span class="glyphicon glyphicon-download" aria-hidden="true"></span> Write</a></li>
28 <li><a href="{{ dev_conf.get_absolute_url_write }}"><span class="glyphicon glyphicon-download" aria-hidden="true"></span> Write</a></li>
29 {% if dev_conf.device.device_type.name != 'abs' %}
29 {% if dev_conf.device.device_type.name != 'abs' %}
30 <li><a href="{{ dev_conf.get_absolute_url_read }}"><span class="glyphicon glyphicon-upload" aria-hidden="true"></span> Read</a></li>
30 <li><a href="{{ dev_conf.get_absolute_url_read }}"><span class="glyphicon glyphicon-upload" aria-hidden="true"></span> Read</a></li>
31 {% endif %}
31 {% endif %}
32 </ul>
32 </ul>
33 </span>
33 </span>
34 {% endblock %}
34 {% endblock %}
35
35
36 {% block content-detail %}
36 <table class="table table-bordered">
37 <table class="table table-bordered">
37 <tr>
38 <tr>
38 <th>Status</th>
39 <th>Status</th>
39 <td class="text-{{dev_conf.device.status_color}}"><strong> {% if dev_conf.device.device_type.name == 'abs' %} {{connected_modules}} {% else %} {{dev_conf.device.get_status_display}}{% endif %}</strong></td>
40 <td class="text-{{dev_conf.device.status_color}}"><strong> {% if dev_conf.device.device_type.name == 'abs' %} {{connected_modules}} {% else %} {{dev_conf.device.get_status_display}}{% endif %}</strong></td>
40 </tr>
41 </tr>
41
42
42 {% for key in dev_conf_keys %}
43 {% for key in dev_conf_keys %}
43 <tr>
44 <tr>
44 <th>{% get_verbose_field_name dev_conf key %}</th>
45 <th>{% get_verbose_field_name dev_conf key %}</th>
45 <td>{{dev_conf|attr:key}}</td>
46 <td>{{dev_conf|attr:key}}</td>
46 </tr>
47 </tr>
47 {% endfor %}
48 {% endfor %}
48 </table>
49 </table>
50 {% endblock %}
49
51
50 {% block extra-content %}
52 {% block extra-content %}
51 {% endblock %}
53 {% endblock %}
52
54
53 {% endblock %}
55 {% endblock %}
54
56
55 {% block extra-js%}
57 {% block extra-js%}
56 <script type="text/javascript">
58 <script type="text/javascript">
57
59
58 $("#bt_edit").click(function() {
60 $("#bt_edit").click(function() {
59 document.location = "{{ dev_conf.get_absolute_url_edit }}";
61 document.location = "{{ dev_conf.get_absolute_url_edit }}";
60 });
62 });
61
63
62 $("#bt_read").click(function() {
64 $("#bt_read").click(function() {
63 document.location = "{{ dev_conf.get_absolute_url_read }}";
65 document.location = "{{ dev_conf.get_absolute_url_read }}";
64 });
66 });
65
67
66 $("#bt_write").click(function() {
68 $("#bt_write").click(function() {
67 document.location = "{{ dev_conf.get_absolute_url_write }}";
69 document.location = "{{ dev_conf.get_absolute_url_write }}";
68 });
70 });
69
71
70 $("#bt_import").click(function() {
72 $("#bt_import").click(function() {
71 document.location = "{{ dev_conf.get_absolute_url_import }}";
73 document.location = "{{ dev_conf.get_absolute_url_import }}";
72 });
74 });
73
75
74 $("#bt_export").click(function() {
76 $("#bt_export").click(function() {
75 document.location = "{{ dev_conf.get_absolute_url_export }}";
77 document.location = "{{ dev_conf.get_absolute_url_export }}";
76 });
78 });
77
79
78 </script>
80 </script>
79 {% endblock %}
81 {% endblock %}
@@ -1,1865 +1,1868
1 import ast
1 import ast
2 import json
2 import json
3 import hashlib
3 import hashlib
4 from datetime import datetime, timedelta
4 from datetime import datetime, timedelta
5
5
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7 from django.utils.safestring import mark_safe
7 from django.utils.safestring import mark_safe
8 from django.http import HttpResponseRedirect
8 from django.http import HttpResponseRedirect
9 from django.core.urlresolvers import reverse
9 from django.core.urlresolvers import reverse
10 from django.db.models import Q
10 from django.db.models import Q
11 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
11 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
12 from django.contrib import messages
12 from django.contrib import messages
13 from django.http.request import QueryDict
13 from django.http.request import QueryDict
14 from django.contrib.auth.decorators import login_required, user_passes_test
14 from django.contrib.auth.decorators import login_required, user_passes_test
15
15
16 try:
16 try:
17 from urllib.parse import urlencode
17 from urllib.parse import urlencode
18 except ImportError:
18 except ImportError:
19 from urllib import urlencode
19 from urllib import urlencode
20
20
21 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
21 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
22 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
22 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
23
23
24 from .tasks import task_start
24 from .tasks import task_start
25
25
26 from apps.rc.forms import RCConfigurationForm, RCLineCode, RCMixConfigurationForm
26 from apps.rc.forms import RCConfigurationForm, RCLineCode, RCMixConfigurationForm
27 from apps.dds.forms import DDSConfigurationForm
27 from apps.dds.forms import DDSConfigurationForm
28 from apps.jars.forms import JARSConfigurationForm
28 from apps.jars.forms import JARSConfigurationForm
29 from apps.cgs.forms import CGSConfigurationForm
29 from apps.cgs.forms import CGSConfigurationForm
30 from apps.abs.forms import ABSConfigurationForm
30 from apps.abs.forms import ABSConfigurationForm
31 from apps.usrp.forms import USRPConfigurationForm
31 from apps.usrp.forms import USRPConfigurationForm
32 from .utils import Params
32 from .utils import Params
33
33
34 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment, DEV_STATES
34 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment, DEV_STATES
35 from apps.cgs.models import CGSConfiguration
35 from apps.cgs.models import CGSConfiguration
36 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
36 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
37 from apps.usrp.models import USRPConfiguration
37 from apps.usrp.models import USRPConfiguration
38 from apps.abs.models import ABSConfiguration
38 from apps.abs.models import ABSConfiguration
39 from apps.rc.models import RCConfiguration, RCLine, RCLineType
39 from apps.rc.models import RCConfiguration, RCLine, RCLineType, RCClock
40 from apps.dds.models import DDSConfiguration
40 from apps.dds.models import DDSConfiguration
41
41
42 from radarsys.celery import app
42 from radarsys.celery import app
43
43
44
44
45 CONF_FORMS = {
45 CONF_FORMS = {
46 'rc': RCConfigurationForm,
46 'rc': RCConfigurationForm,
47 'dds': DDSConfigurationForm,
47 'dds': DDSConfigurationForm,
48 'jars': JARSConfigurationForm,
48 'jars': JARSConfigurationForm,
49 'cgs': CGSConfigurationForm,
49 'cgs': CGSConfigurationForm,
50 'abs': ABSConfigurationForm,
50 'abs': ABSConfigurationForm,
51 'usrp': USRPConfigurationForm,
51 'usrp': USRPConfigurationForm,
52 }
52 }
53
53
54 CONF_MODELS = {
54 CONF_MODELS = {
55 'rc': RCConfiguration,
55 'rc': RCConfiguration,
56 'dds': DDSConfiguration,
56 'dds': DDSConfiguration,
57 'jars': JARSConfiguration,
57 'jars': JARSConfiguration,
58 'cgs': CGSConfiguration,
58 'cgs': CGSConfiguration,
59 'abs': ABSConfiguration,
59 'abs': ABSConfiguration,
60 'usrp': USRPConfiguration,
60 'usrp': USRPConfiguration,
61 }
61 }
62
62
63 MIX_MODES = {
63 MIX_MODES = {
64 '0': 'P',
64 '0': 'P',
65 '1': 'S',
65 '1': 'S',
66 }
66 }
67
67
68 MIX_OPERATIONS = {
68 MIX_OPERATIONS = {
69 '0': 'OR',
69 '0': 'OR',
70 '1': 'XOR',
70 '1': 'XOR',
71 '2': 'AND',
71 '2': 'AND',
72 '3': 'NAND',
72 '3': 'NAND',
73 }
73 }
74
74
75
75
76 def is_developer(user):
76 def is_developer(user):
77
77
78 groups = [str(g.name) for g in user.groups.all()]
78 groups = [str(g.name) for g in user.groups.all()]
79 return 'Developer' in groups or user.is_staff
79 return 'Developer' in groups or user.is_staff
80
80
81
81
82 def is_operator(user):
82 def is_operator(user):
83
83
84 groups = [str(g.name) for g in user.groups.all()]
84 groups = [str(g.name) for g in user.groups.all()]
85 return 'Operator' in groups or user.is_staff
85 return 'Operator' in groups or user.is_staff
86
86
87
87
88 def has_been_modified(model):
88 def has_been_modified(model):
89
89
90 prev_hash = model.hash
90 prev_hash = model.hash
91 new_hash = hashlib.sha256(str(model.parms_to_dict)).hexdigest()
91 new_hash = hashlib.sha256(str(model.parms_to_dict)).hexdigest()
92 if prev_hash != new_hash:
92 if prev_hash != new_hash:
93 model.hash = new_hash
93 model.hash = new_hash
94 model.save()
94 model.save()
95 return True
95 return True
96 return False
96 return False
97
97
98
98
99 def index(request):
99 def index(request):
100 kwargs = {'no_sidebar': True}
100 kwargs = {'no_sidebar': True}
101
101
102 return render(request, 'index.html', kwargs)
102 return render(request, 'index.html', kwargs)
103
103
104
104
105 def locations(request):
105 def locations(request):
106
106
107 page = request.GET.get('page')
107 page = request.GET.get('page')
108 order = ('name',)
108 order = ('name',)
109
109
110 kwargs = get_paginator(Location, page, order)
110 kwargs = get_paginator(Location, page, order)
111
111
112 kwargs['keys'] = ['name', 'description']
112 kwargs['keys'] = ['name', 'description']
113 kwargs['title'] = 'Radar System'
113 kwargs['title'] = 'Radar System'
114 kwargs['suptitle'] = 'List'
114 kwargs['suptitle'] = 'List'
115 kwargs['no_sidebar'] = True
115 kwargs['no_sidebar'] = True
116
116
117 return render(request, 'base_list.html', kwargs)
117 return render(request, 'base_list.html', kwargs)
118
118
119
119
120 def location(request, id_loc):
120 def location(request, id_loc):
121
121
122 location = get_object_or_404(Location, pk=id_loc)
122 location = get_object_or_404(Location, pk=id_loc)
123
123
124 kwargs = {}
124 kwargs = {}
125 kwargs['location'] = location
125 kwargs['location'] = location
126 kwargs['location_keys'] = ['name', 'description']
126 kwargs['location_keys'] = ['name', 'description']
127
127
128 kwargs['title'] = 'Location'
128 kwargs['title'] = 'Location'
129 kwargs['suptitle'] = 'Details'
129 kwargs['suptitle'] = 'Details'
130
130
131 return render(request, 'location.html', kwargs)
131 return render(request, 'location.html', kwargs)
132
132
133
133
134 @login_required
134 @login_required
135 def location_new(request):
135 def location_new(request):
136
136
137 if request.method == 'GET':
137 if request.method == 'GET':
138 form = LocationForm()
138 form = LocationForm()
139
139
140 if request.method == 'POST':
140 if request.method == 'POST':
141 form = LocationForm(request.POST)
141 form = LocationForm(request.POST)
142
142
143 if form.is_valid():
143 if form.is_valid():
144 form.save()
144 form.save()
145 return redirect('url_locations')
145 return redirect('url_locations')
146
146
147 kwargs = {}
147 kwargs = {}
148 kwargs['form'] = form
148 kwargs['form'] = form
149 kwargs['title'] = 'Radar System'
149 kwargs['title'] = 'Radar System'
150 kwargs['suptitle'] = 'New'
150 kwargs['suptitle'] = 'New'
151 kwargs['button'] = 'Create'
151 kwargs['button'] = 'Create'
152
152
153 return render(request, 'base_edit.html', kwargs)
153 return render(request, 'base_edit.html', kwargs)
154
154
155
155
156 @login_required
156 @login_required
157 def location_edit(request, id_loc):
157 def location_edit(request, id_loc):
158
158
159 location = get_object_or_404(Location, pk=id_loc)
159 location = get_object_or_404(Location, pk=id_loc)
160
160
161 if request.method == 'GET':
161 if request.method == 'GET':
162 form = LocationForm(instance=location)
162 form = LocationForm(instance=location)
163
163
164 if request.method == 'POST':
164 if request.method == 'POST':
165 form = LocationForm(request.POST, instance=location)
165 form = LocationForm(request.POST, instance=location)
166
166
167 if form.is_valid():
167 if form.is_valid():
168 form.save()
168 form.save()
169 return redirect('url_locations')
169 return redirect('url_locations')
170
170
171 kwargs = {}
171 kwargs = {}
172 kwargs['form'] = form
172 kwargs['form'] = form
173 kwargs['title'] = 'Location'
173 kwargs['title'] = 'Location'
174 kwargs['suptitle'] = 'Edit'
174 kwargs['suptitle'] = 'Edit'
175 kwargs['button'] = 'Update'
175 kwargs['button'] = 'Update'
176
176
177 return render(request, 'base_edit.html', kwargs)
177 return render(request, 'base_edit.html', kwargs)
178
178
179
179
180 @login_required
180 @login_required
181 def location_delete(request, id_loc):
181 def location_delete(request, id_loc):
182
182
183 location = get_object_or_404(Location, pk=id_loc)
183 location = get_object_or_404(Location, pk=id_loc)
184
184
185 if request.method == 'POST':
185 if request.method == 'POST':
186
186
187 if is_developer(request.user):
187 if is_developer(request.user):
188 location.delete()
188 location.delete()
189 return redirect('url_locations')
189 return redirect('url_locations')
190
190
191 messages.error(request, 'Not enough permission to delete this object')
191 messages.error(request, 'Not enough permission to delete this object')
192 return redirect(location.get_absolute_url())
192 return redirect(location.get_absolute_url())
193
193
194 kwargs = {
194 kwargs = {
195 'title': 'Delete',
195 'title': 'Delete',
196 'suptitle': 'Location',
196 'suptitle': 'Location',
197 'object': location,
197 'object': location,
198 'delete': True
198 'delete': True
199 }
199 }
200
200
201 return render(request, 'confirm.html', kwargs)
201 return render(request, 'confirm.html', kwargs)
202
202
203
203
204 def devices(request):
204 def devices(request):
205
205
206 page = request.GET.get('page')
206 page = request.GET.get('page')
207 order = ('location', 'device_type')
207 order = ('location', 'device_type')
208
208
209 filters = request.GET.copy()
209 filters = request.GET.copy()
210 kwargs = get_paginator(Device, page, order, filters)
210 kwargs = get_paginator(Device, page, order, filters)
211 form = FilterForm(initial=request.GET, extra_fields=['tags'])
211 form = FilterForm(initial=request.GET, extra_fields=['tags'])
212
212
213 kwargs['keys'] = ['device_type', 'location',
213 kwargs['keys'] = ['device_type', 'location',
214 'ip_address', 'port_address', 'actions']
214 'ip_address', 'port_address', 'actions']
215 kwargs['title'] = 'Device'
215 kwargs['title'] = 'Device'
216 kwargs['suptitle'] = 'List'
216 kwargs['suptitle'] = 'List'
217 kwargs['no_sidebar'] = True
217 kwargs['no_sidebar'] = True
218 kwargs['form'] = form
218 kwargs['form'] = form
219 kwargs['add_url'] = reverse('url_add_device')
219 kwargs['add_url'] = reverse('url_add_device')
220 filters.pop('page', None)
220 filters.pop('page', None)
221 kwargs['q'] = urlencode(filters)
221 kwargs['q'] = urlencode(filters)
222 kwargs['menu_devices'] = 'active'
222 kwargs['menu_devices'] = 'active'
223 return render(request, 'base_list.html', kwargs)
223 return render(request, 'base_list.html', kwargs)
224
224
225
225
226 def device(request, id_dev):
226 def device(request, id_dev):
227
227
228 device = get_object_or_404(Device, pk=id_dev)
228 device = get_object_or_404(Device, pk=id_dev)
229
229
230 kwargs = {}
230 kwargs = {}
231 kwargs['device'] = device
231 kwargs['device'] = device
232 kwargs['device_keys'] = ['device_type',
232 kwargs['device_keys'] = ['device_type',
233 'ip_address', 'port_address', 'description']
233 'ip_address', 'port_address', 'description']
234
234
235 kwargs['title'] = 'Device'
235 kwargs['title'] = 'Device'
236 kwargs['suptitle'] = 'Details'
236 kwargs['suptitle'] = 'Details'
237 kwargs['menu_devices'] = 'active'
237 kwargs['menu_devices'] = 'active'
238
238
239 return render(request, 'device.html', kwargs)
239 return render(request, 'device.html', kwargs)
240
240
241
241
242 @login_required
242 @login_required
243 def device_new(request):
243 def device_new(request):
244
244
245 if request.method == 'GET':
245 if request.method == 'GET':
246 form = DeviceForm()
246 form = DeviceForm()
247
247
248 if request.method == 'POST':
248 if request.method == 'POST':
249 form = DeviceForm(request.POST)
249 form = DeviceForm(request.POST)
250
250
251 if form.is_valid():
251 if form.is_valid():
252 form.save()
252 form.save()
253 return redirect('url_devices')
253 return redirect('url_devices')
254
254
255 kwargs = {}
255 kwargs = {}
256 kwargs['form'] = form
256 kwargs['form'] = form
257 kwargs['title'] = 'Device'
257 kwargs['title'] = 'Device'
258 kwargs['suptitle'] = 'New'
258 kwargs['suptitle'] = 'New'
259 kwargs['button'] = 'Create'
259 kwargs['button'] = 'Create'
260 kwargs['menu_devices'] = 'active'
260 kwargs['menu_devices'] = 'active'
261
261
262 return render(request, 'base_edit.html', kwargs)
262 return render(request, 'base_edit.html', kwargs)
263
263
264
264
265 @login_required
265 @login_required
266 def device_edit(request, id_dev):
266 def device_edit(request, id_dev):
267
267
268 device = get_object_or_404(Device, pk=id_dev)
268 device = get_object_or_404(Device, pk=id_dev)
269
269
270 if request.method == 'GET':
270 if request.method == 'GET':
271 form = DeviceForm(instance=device)
271 form = DeviceForm(instance=device)
272
272
273 if request.method == 'POST':
273 if request.method == 'POST':
274 form = DeviceForm(request.POST, instance=device)
274 form = DeviceForm(request.POST, instance=device)
275
275
276 if form.is_valid():
276 if form.is_valid():
277 form.save()
277 form.save()
278 return redirect(device.get_absolute_url())
278 return redirect(device.get_absolute_url())
279
279
280 kwargs = {}
280 kwargs = {}
281 kwargs['form'] = form
281 kwargs['form'] = form
282 kwargs['title'] = 'Device'
282 kwargs['title'] = 'Device'
283 kwargs['suptitle'] = 'Edit'
283 kwargs['suptitle'] = 'Edit'
284 kwargs['button'] = 'Update'
284 kwargs['button'] = 'Update'
285 kwargs['menu_devices'] = 'active'
285 kwargs['menu_devices'] = 'active'
286
286
287 return render(request, 'base_edit.html', kwargs)
287 return render(request, 'base_edit.html', kwargs)
288
288
289
289
290 @login_required
290 @login_required
291 def device_delete(request, id_dev):
291 def device_delete(request, id_dev):
292
292
293 device = get_object_or_404(Device, pk=id_dev)
293 device = get_object_or_404(Device, pk=id_dev)
294
294
295 if request.method == 'POST':
295 if request.method == 'POST':
296
296
297 if is_developer(request.user):
297 if is_developer(request.user):
298 device.delete()
298 device.delete()
299 return redirect('url_devices')
299 return redirect('url_devices')
300
300
301 messages.error(request, 'Not enough permission to delete this object')
301 messages.error(request, 'Not enough permission to delete this object')
302 return redirect(device.get_absolute_url())
302 return redirect(device.get_absolute_url())
303
303
304 kwargs = {
304 kwargs = {
305 'title': 'Delete',
305 'title': 'Delete',
306 'suptitle': 'Device',
306 'suptitle': 'Device',
307 'object': device,
307 'object': device,
308 'delete': True
308 'delete': True
309 }
309 }
310 kwargs['menu_devices'] = 'active'
310 kwargs['menu_devices'] = 'active'
311
311
312 return render(request, 'confirm.html', kwargs)
312 return render(request, 'confirm.html', kwargs)
313
313
314
314
315 @login_required
315 @login_required
316 def device_change_ip(request, id_dev):
316 def device_change_ip(request, id_dev):
317
317
318 device = get_object_or_404(Device, pk=id_dev)
318 device = get_object_or_404(Device, pk=id_dev)
319
319
320 if request.method == 'POST':
320 if request.method == 'POST':
321
321
322 if is_developer(request.user):
322 if is_developer(request.user):
323 device.change_ip(**request.POST.dict())
323 device.change_ip(**request.POST.dict())
324 level, message = device.message.split('|')
324 level, message = device.message.split('|')
325 messages.add_message(request, level, message)
325 messages.add_message(request, level, message)
326 else:
326 else:
327 messages.error(
327 messages.error(
328 request, 'Not enough permission to delete this object')
328 request, 'Not enough permission to delete this object')
329 return redirect(device.get_absolute_url())
329 return redirect(device.get_absolute_url())
330
330
331 kwargs = {
331 kwargs = {
332 'title': 'Device',
332 'title': 'Device',
333 'suptitle': 'Change IP',
333 'suptitle': 'Change IP',
334 'object': device,
334 'object': device,
335 'previous': device.get_absolute_url(),
335 'previous': device.get_absolute_url(),
336 'form': ChangeIpForm(initial={'ip_address': device.ip_address}),
336 'form': ChangeIpForm(initial={'ip_address': device.ip_address}),
337 'message': ' ',
337 'message': ' ',
338 }
338 }
339 kwargs['menu_devices'] = 'active'
339 kwargs['menu_devices'] = 'active'
340
340
341 return render(request, 'confirm.html', kwargs)
341 return render(request, 'confirm.html', kwargs)
342
342
343
343
344 def campaigns(request):
344 def campaigns(request):
345
345
346 page = request.GET.get('page')
346 page = request.GET.get('page')
347 order = ('-start_date',)
347 order = ('-start_date',)
348 filters = request.GET.copy()
348 filters = request.GET.copy()
349
349
350 kwargs = get_paginator(Campaign, page, order, filters)
350 kwargs = get_paginator(Campaign, page, order, filters)
351
351
352 form = FilterForm(initial=request.GET, extra_fields=[
352 form = FilterForm(initial=request.GET, extra_fields=[
353 'range_date', 'tags', 'template'])
353 'range_date', 'tags', 'template'])
354 kwargs['keys'] = ['name', 'start_date', 'end_date', 'actions']
354 kwargs['keys'] = ['name', 'start_date', 'end_date', 'actions']
355 kwargs['title'] = 'Campaign'
355 kwargs['title'] = 'Campaign'
356 kwargs['suptitle'] = 'List'
356 kwargs['suptitle'] = 'List'
357 kwargs['no_sidebar'] = True
357 kwargs['no_sidebar'] = True
358 kwargs['form'] = form
358 kwargs['form'] = form
359 kwargs['add_url'] = reverse('url_add_campaign')
359 kwargs['add_url'] = reverse('url_add_campaign')
360 filters.pop('page', None)
360 filters.pop('page', None)
361 kwargs['q'] = urlencode(filters)
361 kwargs['q'] = urlencode(filters)
362 kwargs['menu_campaigns'] = 'active'
362 kwargs['menu_campaigns'] = 'active'
363
363
364 return render(request, 'base_list.html', kwargs)
364 return render(request, 'base_list.html', kwargs)
365
365
366
366
367 def campaign(request, id_camp):
367 def campaign(request, id_camp):
368
368
369 campaign = get_object_or_404(Campaign, pk=id_camp)
369 campaign = get_object_or_404(Campaign, pk=id_camp)
370 experiments = Experiment.objects.filter(campaign=campaign)
370 experiments = Experiment.objects.filter(campaign=campaign)
371
371
372 form = CampaignForm(instance=campaign)
372 form = CampaignForm(instance=campaign)
373
373
374 kwargs = {}
374 kwargs = {}
375 kwargs['campaign'] = campaign
375 kwargs['campaign'] = campaign
376 kwargs['campaign_keys'] = ['template', 'name',
376 kwargs['campaign_keys'] = ['template', 'name',
377 'start_date', 'end_date', 'tags', 'description']
377 'start_date', 'end_date', 'tags', 'description']
378
378
379 kwargs['experiments'] = experiments
379 kwargs['experiments'] = experiments
380 kwargs['experiment_keys'] = [
380 kwargs['experiment_keys'] = [
381 'name', 'radar_system', 'start_time', 'end_time']
381 'name', 'radar_system', 'start_time', 'end_time']
382
382
383 kwargs['title'] = 'Campaign'
383 kwargs['title'] = 'Campaign'
384 kwargs['suptitle'] = 'Details'
384 kwargs['suptitle'] = 'Details'
385
385
386 kwargs['form'] = form
386 kwargs['form'] = form
387 kwargs['button'] = 'Add Experiment'
387 kwargs['button'] = 'Add Experiment'
388 kwargs['menu_campaigns'] = 'active'
388 kwargs['menu_campaigns'] = 'active'
389
389
390 return render(request, 'campaign.html', kwargs)
390 return render(request, 'campaign.html', kwargs)
391
391
392
392
393 @login_required
393 @login_required
394 def campaign_new(request):
394 def campaign_new(request):
395
395
396 kwargs = {}
396 kwargs = {}
397
397
398 if request.method == 'GET':
398 if request.method == 'GET':
399
399
400 if 'template' in request.GET:
400 if 'template' in request.GET:
401 if request.GET['template'] == '0':
401 if request.GET['template'] == '0':
402 form = NewForm(initial={'create_from': 2},
402 form = NewForm(initial={'create_from': 2},
403 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
403 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
404 else:
404 else:
405 kwargs['button'] = 'Create'
405 kwargs['button'] = 'Create'
406 kwargs['experiments'] = Configuration.objects.filter(
406 kwargs['experiments'] = Configuration.objects.filter(
407 experiment=request.GET['template'])
407 experiment=request.GET['template'])
408 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
408 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
409 camp = Campaign.objects.get(pk=request.GET['template'])
409 camp = Campaign.objects.get(pk=request.GET['template'])
410 form = CampaignForm(instance=camp,
410 form = CampaignForm(instance=camp,
411 initial={'name': '{}_{:%Y%m%d}'.format(camp.name, datetime.now()),
411 initial={'name': '{}_{:%Y%m%d}'.format(camp.name, datetime.now()),
412 'template': False})
412 'template': False})
413 elif 'blank' in request.GET:
413 elif 'blank' in request.GET:
414 kwargs['button'] = 'Create'
414 kwargs['button'] = 'Create'
415 form = CampaignForm()
415 form = CampaignForm()
416 else:
416 else:
417 form = NewForm()
417 form = NewForm()
418
418
419 if request.method == 'POST':
419 if request.method == 'POST':
420 kwargs['button'] = 'Create'
420 kwargs['button'] = 'Create'
421 post = request.POST.copy()
421 post = request.POST.copy()
422 experiments = []
422 experiments = []
423
423
424 for id_exp in post.getlist('experiments'):
424 for id_exp in post.getlist('experiments'):
425 exp = Experiment.objects.get(pk=id_exp)
425 exp = Experiment.objects.get(pk=id_exp)
426 new_exp = exp.clone(template=False)
426 new_exp = exp.clone(template=False)
427 experiments.append(new_exp)
427 experiments.append(new_exp)
428
428
429 post.setlist('experiments', [])
429 post.setlist('experiments', [])
430
430
431 form = CampaignForm(post)
431 form = CampaignForm(post)
432
432
433 if form.is_valid():
433 if form.is_valid():
434 campaign = form.save(commit=False)
434 campaign = form.save(commit=False)
435 campaign.author = request.user
435 campaign.author = request.user
436 for exp in experiments:
436 for exp in experiments:
437 campaign.experiments.add(exp)
437 campaign.experiments.add(exp)
438 campaign.save()
438 campaign.save()
439 return redirect('url_campaign', id_camp=campaign.id)
439 return redirect('url_campaign', id_camp=campaign.id)
440
440
441 kwargs['form'] = form
441 kwargs['form'] = form
442 kwargs['title'] = 'Campaign'
442 kwargs['title'] = 'Campaign'
443 kwargs['suptitle'] = 'New'
443 kwargs['suptitle'] = 'New'
444 kwargs['menu_campaigns'] = 'active'
444 kwargs['menu_campaigns'] = 'active'
445
445
446 return render(request, 'campaign_edit.html', kwargs)
446 return render(request, 'campaign_edit.html', kwargs)
447
447
448
448
449 @login_required
449 @login_required
450 def campaign_edit(request, id_camp):
450 def campaign_edit(request, id_camp):
451
451
452 campaign = get_object_or_404(Campaign, pk=id_camp)
452 campaign = get_object_or_404(Campaign, pk=id_camp)
453
453
454 if request.method == 'GET':
454 if request.method == 'GET':
455 form = CampaignForm(instance=campaign)
455 form = CampaignForm(instance=campaign)
456
456
457 if request.method == 'POST':
457 if request.method == 'POST':
458 exps = campaign.experiments.all().values_list('pk', flat=True)
458 exps = campaign.experiments.all().values_list('pk', flat=True)
459 post = request.POST.copy()
459 post = request.POST.copy()
460 new_exps = post.getlist('experiments')
460 new_exps = post.getlist('experiments')
461 post.setlist('experiments', [])
461 post.setlist('experiments', [])
462 form = CampaignForm(post, instance=campaign)
462 form = CampaignForm(post, instance=campaign)
463
463
464 if form.is_valid():
464 if form.is_valid():
465 camp = form.save()
465 camp = form.save()
466 for id_exp in new_exps:
466 for id_exp in new_exps:
467 if int(id_exp) in exps:
467 if int(id_exp) in exps:
468 exps.pop(id_exp)
468 exps.pop(id_exp)
469 else:
469 else:
470 exp = Experiment.objects.get(pk=id_exp)
470 exp = Experiment.objects.get(pk=id_exp)
471 if exp.template:
471 if exp.template:
472 camp.experiments.add(exp.clone(template=False))
472 camp.experiments.add(exp.clone(template=False))
473 else:
473 else:
474 camp.experiments.add(exp)
474 camp.experiments.add(exp)
475
475
476 for id_exp in exps:
476 for id_exp in exps:
477 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
477 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
478
478
479 return redirect('url_campaign', id_camp=id_camp)
479 return redirect('url_campaign', id_camp=id_camp)
480
480
481 kwargs = {}
481 kwargs = {}
482 kwargs['form'] = form
482 kwargs['form'] = form
483 kwargs['title'] = 'Campaign'
483 kwargs['title'] = 'Campaign'
484 kwargs['suptitle'] = 'Edit'
484 kwargs['suptitle'] = 'Edit'
485 kwargs['button'] = 'Update'
485 kwargs['button'] = 'Update'
486 kwargs['menu_campaigns'] = 'active'
486 kwargs['menu_campaigns'] = 'active'
487
487
488 return render(request, 'campaign_edit.html', kwargs)
488 return render(request, 'campaign_edit.html', kwargs)
489
489
490
490
491 @login_required
491 @login_required
492 def campaign_delete(request, id_camp):
492 def campaign_delete(request, id_camp):
493
493
494 campaign = get_object_or_404(Campaign, pk=id_camp)
494 campaign = get_object_or_404(Campaign, pk=id_camp)
495
495
496 if request.method == 'POST':
496 if request.method == 'POST':
497 if is_developer(request.user):
497 if is_developer(request.user):
498
498
499 for exp in campaign.experiments.all():
499 for exp in campaign.experiments.all():
500 for conf in Configuration.objects.filter(experiment=exp):
500 for conf in Configuration.objects.filter(experiment=exp):
501 conf.delete()
501 conf.delete()
502 exp.delete()
502 exp.delete()
503 campaign.delete()
503 campaign.delete()
504
504
505 return redirect('url_campaigns')
505 return redirect('url_campaigns')
506
506
507 messages.error(request, 'Not enough permission to delete this object')
507 messages.error(request, 'Not enough permission to delete this object')
508 return redirect(campaign.get_absolute_url())
508 return redirect(campaign.get_absolute_url())
509
509
510 kwargs = {
510 kwargs = {
511 'title': 'Delete',
511 'title': 'Delete',
512 'suptitle': 'Campaign',
512 'suptitle': 'Campaign',
513 'object': campaign,
513 'object': campaign,
514 'delete': True
514 'delete': True
515 }
515 }
516 kwargs['menu_campaigns'] = 'active'
516 kwargs['menu_campaigns'] = 'active'
517
517
518 return render(request, 'confirm.html', kwargs)
518 return render(request, 'confirm.html', kwargs)
519
519
520
520
521 @login_required
521 @login_required
522 def campaign_export(request, id_camp):
522 def campaign_export(request, id_camp):
523
523
524 campaign = get_object_or_404(Campaign, pk=id_camp)
524 campaign = get_object_or_404(Campaign, pk=id_camp)
525 content = campaign.parms_to_dict()
525 content = campaign.parms_to_dict()
526 content_type = 'application/json'
526 content_type = 'application/json'
527 filename = '%s_%s.json' % (campaign.name, campaign.id)
527 filename = '%s_%s.json' % (campaign.name, campaign.id)
528
528
529 response = HttpResponse(content_type=content_type)
529 response = HttpResponse(content_type=content_type)
530 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
530 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
531 response.write(json.dumps(content, indent=2))
531 response.write(json.dumps(content, indent=2))
532
532
533 return response
533 return response
534
534
535
535
536 @login_required
536 @login_required
537 def campaign_import(request, id_camp):
537 def campaign_import(request, id_camp):
538
538
539 campaign = get_object_or_404(Campaign, pk=id_camp)
539 campaign = get_object_or_404(Campaign, pk=id_camp)
540
540
541 if request.method == 'GET':
541 if request.method == 'GET':
542 file_form = UploadFileForm()
542 file_form = UploadFileForm()
543
543
544 if request.method == 'POST':
544 if request.method == 'POST':
545 file_form = UploadFileForm(request.POST, request.FILES)
545 file_form = UploadFileForm(request.POST, request.FILES)
546
546
547 if file_form.is_valid():
547 if file_form.is_valid():
548 new_camp = campaign.dict_to_parms(
548 new_camp = campaign.dict_to_parms(
549 json.load(request.FILES['file']), CONF_MODELS)
549 json.load(request.FILES['file']), CONF_MODELS)
550 messages.success(
550 messages.success(
551 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
551 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
552 return redirect(new_camp.get_absolute_url_edit())
552 return redirect(new_camp.get_absolute_url_edit())
553
553
554 messages.error(request, "Could not import parameters from file")
554 messages.error(request, "Could not import parameters from file")
555
555
556 kwargs = {}
556 kwargs = {}
557 kwargs['title'] = 'Campaign'
557 kwargs['title'] = 'Campaign'
558 kwargs['form'] = file_form
558 kwargs['form'] = file_form
559 kwargs['suptitle'] = 'Importing file'
559 kwargs['suptitle'] = 'Importing file'
560 kwargs['button'] = 'Import'
560 kwargs['button'] = 'Import'
561 kwargs['menu_campaigns'] = 'active'
561 kwargs['menu_campaigns'] = 'active'
562
562
563 return render(request, 'campaign_import.html', kwargs)
563 return render(request, 'campaign_import.html', kwargs)
564
564
565
565
566 def experiments(request):
566 def experiments(request):
567
567
568 page = request.GET.get('page')
568 page = request.GET.get('page')
569 order = ('location',)
569 order = ('location',)
570 filters = request.GET.copy()
570 filters = request.GET.copy()
571
571
572 if 'my experiments' in filters:
572 if 'my experiments' in filters:
573 filters.pop('my experiments', None)
573 filters.pop('my experiments', None)
574 filters['mine'] = request.user.id
574 filters['mine'] = request.user.id
575
575
576 kwargs = get_paginator(Experiment, page, order, filters)
576 kwargs = get_paginator(Experiment, page, order, filters)
577
577
578 fields = ['tags', 'template']
578 fields = ['tags', 'template']
579 if request.user.is_authenticated:
579 if request.user.is_authenticated:
580 fields.append('my experiments')
580 fields.append('my experiments')
581
581
582 form = FilterForm(initial=request.GET, extra_fields=fields)
582 form = FilterForm(initial=request.GET, extra_fields=fields)
583
583
584 kwargs['keys'] = ['name', 'radar_system',
584 kwargs['keys'] = ['name', 'radar_system',
585 'start_time', 'end_time', 'actions']
585 'start_time', 'end_time', 'actions']
586 kwargs['title'] = 'Experiment'
586 kwargs['title'] = 'Experiment'
587 kwargs['suptitle'] = 'List'
587 kwargs['suptitle'] = 'List'
588 kwargs['no_sidebar'] = True
588 kwargs['no_sidebar'] = True
589 kwargs['form'] = form
589 kwargs['form'] = form
590 kwargs['add_url'] = reverse('url_add_experiment')
590 kwargs['add_url'] = reverse('url_add_experiment')
591 filters = request.GET.copy()
591 filters = request.GET.copy()
592 filters.pop('page', None)
592 filters.pop('page', None)
593 kwargs['q'] = urlencode(filters)
593 kwargs['q'] = urlencode(filters)
594 kwargs['menu_experiments'] = 'active'
594 kwargs['menu_experiments'] = 'active'
595
595
596 return render(request, 'base_list.html', kwargs)
596 return render(request, 'base_list.html', kwargs)
597
597
598
598
599 def experiment(request, id_exp):
599 def experiment(request, id_exp):
600
600
601 experiment = get_object_or_404(Experiment, pk=id_exp)
601 experiment = get_object_or_404(Experiment, pk=id_exp)
602
602
603 configurations = Configuration.objects.filter(
603 configurations = Configuration.objects.filter(
604 experiment=experiment, type=0)
604 experiment=experiment, type=0)
605
605
606 kwargs = {}
606 kwargs = {}
607
607
608 kwargs['experiment_keys'] = ['template', 'radar_system',
608 kwargs['experiment_keys'] = ['template', 'radar_system',
609 'name', 'freq', 'start_time', 'end_time']
609 'name', 'freq', 'start_time', 'end_time']
610 kwargs['experiment'] = experiment
610 kwargs['experiment'] = experiment
611 kwargs['configuration_keys'] = ['name', 'device__ip_address',
611 kwargs['configuration_keys'] = ['name', 'device__ip_address',
612 'device__port_address', 'device__status']
612 'device__port_address', 'device__status']
613 kwargs['configurations'] = configurations
613 kwargs['configurations'] = configurations
614 kwargs['title'] = 'Experiment'
614 kwargs['title'] = 'Experiment'
615 kwargs['suptitle'] = 'Details'
615 kwargs['suptitle'] = 'Details'
616 kwargs['button'] = 'Add Configuration'
616 kwargs['button'] = 'Add Configuration'
617 kwargs['menu_experiments'] = 'active'
617 kwargs['menu_experiments'] = 'active'
618
618
619 ###### SIDEBAR ######
619 ###### SIDEBAR ######
620 kwargs.update(sidebar(experiment=experiment))
620 kwargs.update(sidebar(experiment=experiment))
621
621
622 return render(request, 'experiment.html', kwargs)
622 return render(request, 'experiment.html', kwargs)
623
623
624
624
625 @login_required
625 @login_required
626 def experiment_new(request, id_camp=None):
626 def experiment_new(request, id_camp=None):
627
627
628 if not is_developer(request.user):
628 if not is_developer(request.user):
629 messages.error(
629 messages.error(
630 request, 'Developer required, to create new Experiments')
630 request, 'Developer required, to create new Experiments')
631 return redirect('index')
631 return redirect('index')
632 kwargs = {}
632 kwargs = {}
633
633
634 if request.method == 'GET':
634 if request.method == 'GET':
635 if 'template' in request.GET:
635 if 'template' in request.GET:
636 if request.GET['template'] == '0':
636 if request.GET['template'] == '0':
637 form = NewForm(initial={'create_from': 2},
637 form = NewForm(initial={'create_from': 2},
638 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
638 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
639 else:
639 else:
640 kwargs['button'] = 'Create'
640 kwargs['button'] = 'Create'
641 kwargs['configurations'] = Configuration.objects.filter(
641 kwargs['configurations'] = Configuration.objects.filter(
642 experiment=request.GET['template'])
642 experiment=request.GET['template'])
643 kwargs['configuration_keys'] = ['name', 'device__name',
643 kwargs['configuration_keys'] = ['name', 'device__name',
644 'device__ip_address', 'device__port_address']
644 'device__ip_address', 'device__port_address']
645 exp = Experiment.objects.get(pk=request.GET['template'])
645 exp = Experiment.objects.get(pk=request.GET['template'])
646 form = ExperimentForm(instance=exp,
646 form = ExperimentForm(instance=exp,
647 initial={'name': '{}_{:%y%m%d}'.format(exp.name, datetime.now()),
647 initial={'name': '{}_{:%y%m%d}'.format(exp.name, datetime.now()),
648 'template': False})
648 'template': False})
649 elif 'blank' in request.GET:
649 elif 'blank' in request.GET:
650 kwargs['button'] = 'Create'
650 kwargs['button'] = 'Create'
651 form = ExperimentForm()
651 form = ExperimentForm()
652 else:
652 else:
653 form = NewForm()
653 form = NewForm()
654
654
655 if request.method == 'POST':
655 if request.method == 'POST':
656 form = ExperimentForm(request.POST)
656 form = ExperimentForm(request.POST)
657 if form.is_valid():
657 if form.is_valid():
658 experiment = form.save(commit=False)
658 experiment = form.save(commit=False)
659 experiment.author = request.user
659 experiment.author = request.user
660 experiment.save()
660 experiment.save()
661
661
662 if 'template' in request.GET:
662 if 'template' in request.GET:
663 configurations = Configuration.objects.filter(
663 configurations = Configuration.objects.filter(
664 experiment=request.GET['template'], type=0)
664 experiment=request.GET['template'], type=0)
665 for conf in configurations:
665 for conf in configurations:
666 conf.clone(experiment=experiment, template=False)
666 conf.clone(experiment=experiment, template=False)
667
667
668 return redirect('url_experiment', id_exp=experiment.id)
668 return redirect('url_experiment', id_exp=experiment.id)
669
669
670 kwargs['form'] = form
670 kwargs['form'] = form
671 kwargs['title'] = 'Experiment'
671 kwargs['title'] = 'Experiment'
672 kwargs['suptitle'] = 'New'
672 kwargs['suptitle'] = 'New'
673 kwargs['menu_experiments'] = 'active'
673 kwargs['menu_experiments'] = 'active'
674
674
675 return render(request, 'experiment_edit.html', kwargs)
675 return render(request, 'experiment_edit.html', kwargs)
676
676
677
677
678 @login_required
678 @login_required
679 def experiment_edit(request, id_exp):
679 def experiment_edit(request, id_exp):
680
680
681 experiment = get_object_or_404(Experiment, pk=id_exp)
681 experiment = get_object_or_404(Experiment, pk=id_exp)
682
682
683 if request.method == 'GET':
683 if request.method == 'GET':
684 form = ExperimentForm(instance=experiment)
684 form = ExperimentForm(instance=experiment)
685
685
686 if request.method == 'POST':
686 if request.method == 'POST':
687 form = ExperimentForm(request.POST, instance=experiment)
687 form = ExperimentForm(request.POST, instance=experiment)
688
688
689 if form.is_valid():
689 if form.is_valid():
690 experiment = form.save()
690 experiment = form.save()
691 return redirect('url_experiment', id_exp=experiment.id)
691 return redirect('url_experiment', id_exp=experiment.id)
692
692
693 kwargs = {}
693 kwargs = {}
694 kwargs['form'] = form
694 kwargs['form'] = form
695 kwargs['title'] = 'Experiment'
695 kwargs['title'] = 'Experiment'
696 kwargs['suptitle'] = 'Edit'
696 kwargs['suptitle'] = 'Edit'
697 kwargs['button'] = 'Update'
697 kwargs['button'] = 'Update'
698 kwargs['menu_experiments'] = 'active'
698 kwargs['menu_experiments'] = 'active'
699
699
700 return render(request, 'experiment_edit.html', kwargs)
700 return render(request, 'experiment_edit.html', kwargs)
701
701
702
702
703 @login_required
703 @login_required
704 def experiment_delete(request, id_exp):
704 def experiment_delete(request, id_exp):
705
705
706 experiment = get_object_or_404(Experiment, pk=id_exp)
706 experiment = get_object_or_404(Experiment, pk=id_exp)
707
707
708 if request.method == 'POST':
708 if request.method == 'POST':
709 if is_developer(request.user):
709 if is_developer(request.user):
710 for conf in Configuration.objects.filter(experiment=experiment):
710 for conf in Configuration.objects.filter(experiment=experiment):
711 conf.delete()
711 conf.delete()
712 experiment.delete()
712 experiment.delete()
713 return redirect('url_experiments')
713 return redirect('url_experiments')
714
714
715 messages.error(request, 'Not enough permission to delete this object')
715 messages.error(request, 'Not enough permission to delete this object')
716 return redirect(experiment.get_absolute_url())
716 return redirect(experiment.get_absolute_url())
717
717
718 kwargs = {
718 kwargs = {
719 'title': 'Delete',
719 'title': 'Delete',
720 'suptitle': 'Experiment',
720 'suptitle': 'Experiment',
721 'object': experiment,
721 'object': experiment,
722 'delete': True
722 'delete': True
723 }
723 }
724
724
725 return render(request, 'confirm.html', kwargs)
725 return render(request, 'confirm.html', kwargs)
726
726
727
727
728 @login_required
728 @login_required
729 def experiment_export(request, id_exp):
729 def experiment_export(request, id_exp):
730
730
731 experiment = get_object_or_404(Experiment, pk=id_exp)
731 experiment = get_object_or_404(Experiment, pk=id_exp)
732 content = experiment.parms_to_dict()
732 content = experiment.parms_to_dict()
733 content_type = 'application/json'
733 content_type = 'application/json'
734 filename = '%s_%s.json' % (experiment.name, experiment.id)
734 filename = '%s_%s.json' % (experiment.name, experiment.id)
735
735
736 response = HttpResponse(content_type=content_type)
736 response = HttpResponse(content_type=content_type)
737 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
737 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
738 response.write(json.dumps(content, indent=2))
738 response.write(json.dumps(content, indent=2))
739
739
740 return response
740 return response
741
741
742
742
743 @login_required
743 @login_required
744 def experiment_import(request, id_exp):
744 def experiment_import(request, id_exp):
745
745
746 experiment = get_object_or_404(Experiment, pk=id_exp)
746 experiment = get_object_or_404(Experiment, pk=id_exp)
747 configurations = Configuration.objects.filter(experiment=experiment)
747 configurations = Configuration.objects.filter(experiment=experiment)
748
748
749 if request.method == 'GET':
749 if request.method == 'GET':
750 file_form = UploadFileForm()
750 file_form = UploadFileForm()
751
751
752 if request.method == 'POST':
752 if request.method == 'POST':
753 file_form = UploadFileForm(request.POST, request.FILES)
753 file_form = UploadFileForm(request.POST, request.FILES)
754
754
755 if file_form.is_valid():
755 if file_form.is_valid():
756 new_exp = experiment.dict_to_parms(
756 new_exp = experiment.dict_to_parms(
757 json.load(request.FILES['file']), CONF_MODELS)
757 json.load(request.FILES['file']), CONF_MODELS)
758 messages.success(
758 messages.success(
759 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
759 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
760 return redirect(new_exp.get_absolute_url_edit())
760 return redirect(new_exp.get_absolute_url_edit())
761
761
762 messages.error(request, "Could not import parameters from file")
762 messages.error(request, "Could not import parameters from file")
763
763
764 kwargs = {}
764 kwargs = {}
765 kwargs['title'] = 'Experiment'
765 kwargs['title'] = 'Experiment'
766 kwargs['form'] = file_form
766 kwargs['form'] = file_form
767 kwargs['suptitle'] = 'Importing file'
767 kwargs['suptitle'] = 'Importing file'
768 kwargs['button'] = 'Import'
768 kwargs['button'] = 'Import'
769 kwargs['menu_experiments'] = 'active'
769 kwargs['menu_experiments'] = 'active'
770
770
771 kwargs.update(sidebar(experiment=experiment))
771 kwargs.update(sidebar(experiment=experiment))
772
772
773 return render(request, 'experiment_import.html', kwargs)
773 return render(request, 'experiment_import.html', kwargs)
774
774
775
775
776 @login_required
776 @login_required
777 def experiment_start(request, id_exp):
777 def experiment_start(request, id_exp):
778
778
779 exp = get_object_or_404(Experiment, pk=id_exp)
779 exp = get_object_or_404(Experiment, pk=id_exp)
780
780
781 if exp.status == 2:
781 if exp.status == 2:
782 messages.warning(request, 'Experiment {} already runnnig'.format(exp))
782 messages.warning(request, 'Experiment {} already runnnig'.format(exp))
783 else:
783 else:
784 exp.status = exp.start()
784 exp.status = exp.start()
785 if exp.status == 0:
785 if exp.status == 0:
786 messages.error(request, 'Experiment {} not start'.format(exp))
786 messages.error(request, 'Experiment {} not start'.format(exp))
787 if exp.status == 2:
787 if exp.status == 2:
788 messages.success(request, 'Experiment {} started'.format(exp))
788 messages.success(request, 'Experiment {} started'.format(exp))
789
789
790 exp.save()
790 exp.save()
791
791
792 return redirect(exp.get_absolute_url())
792 return redirect(exp.get_absolute_url())
793
793
794
794
795 @login_required
795 @login_required
796 def experiment_stop(request, id_exp):
796 def experiment_stop(request, id_exp):
797
797
798 exp = get_object_or_404(Experiment, pk=id_exp)
798 exp = get_object_or_404(Experiment, pk=id_exp)
799
799
800 if exp.status == 2:
800 if exp.status == 2:
801 exp.status = exp.stop()
801 exp.status = exp.stop()
802 exp.save()
802 exp.save()
803 messages.success(request, 'Experiment {} stopped'.format(exp))
803 messages.success(request, 'Experiment {} stopped'.format(exp))
804 else:
804 else:
805 messages.error(request, 'Experiment {} not running'.format(exp))
805 messages.error(request, 'Experiment {} not running'.format(exp))
806
806
807 return redirect(exp.get_absolute_url())
807 return redirect(exp.get_absolute_url())
808
808
809
809
810 def experiment_status(request, id_exp):
810 def experiment_status(request, id_exp):
811
811
812 exp = get_object_or_404(Experiment, pk=id_exp)
812 exp = get_object_or_404(Experiment, pk=id_exp)
813
813
814 exp.get_status()
814 exp.get_status()
815
815
816 return redirect(exp.get_absolute_url())
816 return redirect(exp.get_absolute_url())
817
817
818
818
819 @login_required
819 @login_required
820 def experiment_mix(request, id_exp):
820 def experiment_mix(request, id_exp):
821
821
822 experiment = get_object_or_404(Experiment, pk=id_exp)
822 experiment = get_object_or_404(Experiment, pk=id_exp)
823 rc_confs = [conf for conf in RCConfiguration.objects.filter(
823 rc_confs = [conf for conf in RCConfiguration.objects.filter(
824 experiment=id_exp,
824 experiment=id_exp,
825 type=0,
825 type=0,
826 mix=False)]
826 mix=False)]
827
827
828 if len(rc_confs) < 2:
828 if len(rc_confs) < 2:
829 messages.warning(
829 messages.warning(
830 request, 'You need at least two RC Configurations to make a mix')
830 request, 'You need at least two RC Configurations to make a mix')
831 return redirect(experiment.get_absolute_url())
831 return redirect(experiment.get_absolute_url())
832
832
833 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True, type=0)
833 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True, type=0)
834
834
835 if mix_confs:
835 if mix_confs:
836 mix = mix_confs[0]
836 mix = mix_confs[0]
837 else:
837 else:
838 mix = RCConfiguration(experiment=experiment,
838 mix = RCConfiguration(experiment=experiment,
839 device=rc_confs[0].device,
839 device=rc_confs[0].device,
840 ipp=rc_confs[0].ipp,
840 ipp=rc_confs[0].ipp,
841 clock_in=rc_confs[0].clock_in,
841 clock_in=rc_confs[0].clock_in,
842 clock_divider=rc_confs[0].clock_divider,
842 clock_divider=rc_confs[0].clock_divider,
843 mix=True,
843 mix=True,
844 parameters='')
844 parameters='')
845 mix.save()
845 mix.save()
846
846
847 line_type = RCLineType.objects.get(name='mix')
847 line_type = RCLineType.objects.get(name='mix')
848 for i in range(len(rc_confs[0].get_lines())):
848 for i in range(len(rc_confs[0].get_lines())):
849 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
849 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
850 line.save()
850 line.save()
851
851
852 initial = {'name': mix.name,
852 initial = {'name': mix.name,
853 'result': parse_mix_result(mix.parameters),
853 'result': parse_mix_result(mix.parameters),
854 'delay': 0,
854 'delay': 0,
855 'mask': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
855 'mask': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
856 }
856 }
857
857
858 if request.method == 'GET':
858 if request.method == 'GET':
859 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
859 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
860
860
861 if request.method == 'POST':
861 if request.method == 'POST':
862 result = mix.parameters
862 result = mix.parameters
863
863
864 if '{}|'.format(request.POST['experiment']) in result:
864 if '{}|'.format(request.POST['experiment']) in result:
865 messages.error(request, 'Configuration already added')
865 messages.error(request, 'Configuration already added')
866 else:
866 else:
867 if 'operation' in request.POST:
867 if 'operation' in request.POST:
868 operation = MIX_OPERATIONS[request.POST['operation']]
868 operation = MIX_OPERATIONS[request.POST['operation']]
869 else:
869 else:
870 operation = ' '
870 operation = ' '
871
871
872 mode = MIX_MODES[request.POST['mode']]
872 mode = MIX_MODES[request.POST['mode']]
873
873
874 if result:
874 if result:
875 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
875 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
876 request.POST['experiment'],
876 request.POST['experiment'],
877 mode,
877 mode,
878 operation,
878 operation,
879 float(
879 float(
880 request.POST['delay']),
880 request.POST['delay']),
881 parse_mask(
881 parse_mask(
882 request.POST.getlist('mask'))
882 request.POST.getlist('mask'))
883 )
883 )
884 else:
884 else:
885 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
885 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
886 mode,
886 mode,
887 operation,
887 operation,
888 float(request.POST['delay']),
888 float(request.POST['delay']),
889 parse_mask(
889 parse_mask(
890 request.POST.getlist('mask'))
890 request.POST.getlist('mask'))
891 )
891 )
892
892
893 mix.parameters = result
893 mix.parameters = result
894 mix.save()
894 mix.save()
895 mix.update_pulses()
895 mix.update_pulses()
896
896
897 initial['result'] = parse_mix_result(result)
897 initial['result'] = parse_mix_result(result)
898 initial['name'] = mix.name
898 initial['name'] = mix.name
899
899
900 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
900 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
901
901
902 kwargs = {
902 kwargs = {
903 'title': 'Experiment',
903 'title': 'Experiment',
904 'suptitle': 'Mix Configurations',
904 'suptitle': 'Mix Configurations',
905 'form': form,
905 'form': form,
906 'extra_button': 'Delete',
906 'extra_button': 'Delete',
907 'button': 'Add',
907 'button': 'Add',
908 'cancel': 'Back',
908 'cancel': 'Back',
909 'previous': experiment.get_absolute_url(),
909 'previous': experiment.get_absolute_url(),
910 'id_exp': id_exp,
910 'id_exp': id_exp,
911
911
912 }
912 }
913 kwargs['menu_experiments'] = 'active'
913 kwargs['menu_experiments'] = 'active'
914
914
915 return render(request, 'experiment_mix.html', kwargs)
915 return render(request, 'experiment_mix.html', kwargs)
916
916
917
917
918 @login_required
918 @login_required
919 def experiment_mix_delete(request, id_exp):
919 def experiment_mix_delete(request, id_exp):
920
920
921 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True, type=0)
921 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True, type=0)
922 values = conf.parameters.split('-')
922 values = conf.parameters.split('-')
923 conf.parameters = '-'.join(values[:-1])
923 conf.parameters = '-'.join(values[:-1])
924 conf.save()
924 conf.save()
925
925
926 return redirect('url_mix_experiment', id_exp=id_exp)
926 return redirect('url_mix_experiment', id_exp=id_exp)
927
927
928
928
929 def experiment_summary(request, id_exp):
929 def experiment_summary(request, id_exp):
930
930
931 experiment = get_object_or_404(Experiment, pk=id_exp)
931 experiment = get_object_or_404(Experiment, pk=id_exp)
932 configurations = Configuration.objects.filter(
932 configurations = Configuration.objects.filter(
933 experiment=experiment, type=0)
933 experiment=experiment, type=0)
934
934
935 kwargs = {}
935 kwargs = {}
936 kwargs['experiment_keys'] = ['radar_system',
936 kwargs['experiment_keys'] = ['radar_system',
937 'name', 'freq', 'start_time', 'end_time']
937 'name', 'freq', 'start_time', 'end_time']
938 kwargs['experiment'] = experiment
938 kwargs['experiment'] = experiment
939 kwargs['configurations'] = []
939 kwargs['configurations'] = []
940 kwargs['title'] = 'Experiment Summary'
940 kwargs['title'] = 'Experiment Summary'
941 kwargs['suptitle'] = 'Details'
941 kwargs['suptitle'] = 'Details'
942 kwargs['button'] = 'Verify Parameters'
942 kwargs['button'] = 'Verify Parameters'
943
943
944 c_vel = 3.0*(10**8) # m/s
944 c_vel = 3.0*(10**8) # m/s
945 ope_freq = experiment.freq*(10**6) # 1/s
945 ope_freq = experiment.freq*(10**6) # 1/s
946 radar_lambda = c_vel/ope_freq # m
946 radar_lambda = c_vel/ope_freq # m
947 kwargs['radar_lambda'] = radar_lambda
947 kwargs['radar_lambda'] = radar_lambda
948
948
949 ipp = None
949 ipp = None
950 nsa = 1
950 nsa = 1
951 code_id = 0
951 code_id = 0
952 tx_line = {}
952 tx_line = {}
953
953
954 for configuration in configurations.filter(device__device_type__name = 'rc'):
954 for configuration in configurations.filter(device__device_type__name = 'rc'):
955
955
956 if configuration.mix:
956 if configuration.mix:
957 continue
957 continue
958 conf = {'conf': configuration}
958 conf = {'conf': configuration}
959 conf['keys'] = []
959 conf['keys'] = []
960 conf['NTxs'] = configuration.ntx
960 conf['NTxs'] = configuration.ntx
961 conf['keys'].append('NTxs')
961 conf['keys'].append('NTxs')
962 ipp = configuration.ipp
962 ipp = configuration.ipp
963 conf['IPP'] = ipp
963 conf['IPP'] = ipp
964 conf['keys'].append('IPP')
964 conf['keys'].append('IPP')
965 lines = configuration.get_lines(line_type__name='tx')
965 lines = configuration.get_lines(line_type__name='tx')
966
966
967 for tx_line in lines:
967 for tx_line in lines:
968 tx_params = json.loads(tx_line.params)
968 tx_params = json.loads(tx_line.params)
969 conf[tx_line.get_name()] = '{} Km'.format(tx_params['pulse_width'])
969 conf[tx_line.get_name()] = '{} Km'.format(tx_params['pulse_width'])
970 conf['keys'].append(tx_line.get_name())
970 conf['keys'].append(tx_line.get_name())
971 delays = tx_params['delays']
971 delays = tx_params['delays']
972 if delays not in ('', '0'):
972 if delays not in ('', '0'):
973 n = len(delays.split(','))
973 n = len(delays.split(','))
974 taus = '{} Taus: {}'.format(n, delays)
974 taus = '{} Taus: {}'.format(n, delays)
975 else:
975 else:
976 taus = '-'
976 taus = '-'
977 conf['Taus ({})'.format(tx_line.get_name())] = taus
977 conf['Taus ({})'.format(tx_line.get_name())] = taus
978 conf['keys'].append('Taus ({})'.format(tx_line.get_name()))
978 conf['keys'].append('Taus ({})'.format(tx_line.get_name()))
979 for code_line in configuration.get_lines(line_type__name='codes'):
979 for code_line in configuration.get_lines(line_type__name='codes'):
980 code_params = json.loads(code_line.params)
980 code_params = json.loads(code_line.params)
981 code_id = code_params['code']
981 code_id = code_params['code']
982 if tx_line.pk == int(code_params['TX_ref']):
982 if tx_line.pk == int(code_params['TX_ref']):
983 conf['Code ({})'.format(tx_line.get_name())] = '{}:{}'.format(RCLineCode.objects.get(pk=code_params['code']),
983 conf['Code ({})'.format(tx_line.get_name())] = '{}:{}'.format(RCLineCode.objects.get(pk=code_params['code']),
984 '-'.join(code_params['codes']))
984 '-'.join(code_params['codes']))
985 conf['keys'].append('Code ({})'.format(tx_line.get_name()))
985 conf['keys'].append('Code ({})'.format(tx_line.get_name()))
986
986
987 for windows_line in configuration.get_lines(line_type__name='windows'):
987 for windows_line in configuration.get_lines(line_type__name='windows'):
988 win_params = json.loads(windows_line.params)
988 win_params = json.loads(windows_line.params)
989 if tx_line.pk == int(win_params['TX_ref']):
989 if tx_line.pk == int(win_params['TX_ref']):
990 windows = ''
990 windows = ''
991 nsa = win_params['params'][0]['number_of_samples']
991 nsa = win_params['params'][0]['number_of_samples']
992 for i, params in enumerate(win_params['params']):
992 for i, params in enumerate(win_params['params']):
993 windows += 'W{}: Ho={first_height} km DH={resolution} km NSA={number_of_samples}<br>'.format(
993 windows += 'W{}: Ho={first_height} km DH={resolution} km NSA={number_of_samples}<br>'.format(
994 i, **params)
994 i, **params)
995 conf['Window'] = mark_safe(windows)
995 conf['Window'] = mark_safe(windows)
996 conf['keys'].append('Window')
996 conf['keys'].append('Window')
997
997
998 kwargs['configurations'].append(conf)
998 kwargs['configurations'].append(conf)
999
999
1000 for configuration in configurations.filter(device__device_type__name = 'jars'):
1000 for configuration in configurations.filter(device__device_type__name = 'jars'):
1001
1001
1002 conf = {'conf': configuration}
1002 conf = {'conf': configuration}
1003 conf['keys'] = []
1003 conf['keys'] = []
1004 conf['Type of Data'] = EXPERIMENT_TYPE[configuration.exp_type][1]
1004 conf['Type of Data'] = EXPERIMENT_TYPE[configuration.exp_type][1]
1005 conf['keys'].append('Type of Data')
1005 conf['keys'].append('Type of Data')
1006 channels_number = configuration.channels_number
1006 channels_number = configuration.channels_number
1007 exp_type = configuration.exp_type
1007 exp_type = configuration.exp_type
1008 fftpoints = configuration.fftpoints
1008 fftpoints = configuration.fftpoints
1009 filter_parms = json.loads(configuration.filter_parms)
1009 filter_parms = json.loads(configuration.filter_parms)
1010 spectral_number = configuration.spectral_number
1010 spectral_number = configuration.spectral_number
1011 acq_profiles = configuration.acq_profiles
1011 acq_profiles = configuration.acq_profiles
1012 cohe_integr = configuration.cohe_integr
1012 cohe_integr = configuration.cohe_integr
1013 profiles_block = configuration.profiles_block
1013 profiles_block = configuration.profiles_block
1014
1014
1015 conf['Num of Profiles'] = acq_profiles
1015 conf['Num of Profiles'] = acq_profiles
1016 conf['keys'].append('Num of Profiles')
1016 conf['keys'].append('Num of Profiles')
1017
1017
1018 conf['Prof per Block'] = profiles_block
1018 conf['Prof per Block'] = profiles_block
1019 conf['keys'].append('Prof per Block')
1019 conf['keys'].append('Prof per Block')
1020
1020
1021 conf['Blocks per File'] = configuration.raw_data_blocks
1021 conf['Blocks per File'] = configuration.raw_data_blocks
1022 conf['keys'].append('Blocks per File')
1022 conf['keys'].append('Blocks per File')
1023
1023
1024 if exp_type == 0: # Short
1024 if exp_type == 0: # Short
1025 bytes_ = 2
1025 bytes_ = 2
1026 b = nsa*2*bytes_*channels_number
1026 b = nsa*2*bytes_*channels_number
1027 else: # Float
1027 else: # Float
1028 bytes_ = 4
1028 bytes_ = 4
1029 channels = channels_number + spectral_number
1029 channels = channels_number + spectral_number
1030 b = nsa*2*bytes_*fftpoints*channels
1030 b = nsa*2*bytes_*fftpoints*channels
1031
1031
1032 codes_num = 7
1032 codes_num = 7
1033 if code_id == 2:
1033 if code_id == 2:
1034 codes_num = 7
1034 codes_num = 7
1035 elif code_id == 12:
1035 elif code_id == 12:
1036 codes_num = 15
1036 codes_num = 15
1037
1037
1038 #Jars filter values:
1038 #Jars filter values:
1039
1039
1040 clock = float(filter_parms['clock'])
1040 clock = float(filter_parms['clock'])
1041 filter_2 = int(filter_parms['cic_2'])
1041 filter_2 = int(filter_parms['cic_2'])
1042 filter_5 = int(filter_parms['cic_5'])
1042 filter_5 = int(filter_parms['cic_5'])
1043 filter_fir = int(filter_parms['fir'])
1043 filter_fir = int(filter_parms['fir'])
1044 Fs_MHz = clock/(filter_2*filter_5*filter_fir)
1044 Fs_MHz = clock/(filter_2*filter_5*filter_fir)
1045
1045
1046 #Jars values:
1046 #Jars values:
1047 if ipp is not None:
1047 if ipp is not None:
1048 IPP_units = ipp/0.15*Fs_MHz
1048 IPP_units = ipp/0.15*Fs_MHz
1049 IPP_us = IPP_units / Fs_MHz
1049 IPP_us = IPP_units / Fs_MHz
1050 IPP_s = IPP_units / (Fs_MHz * (10**6))
1050 IPP_s = IPP_units / (Fs_MHz * (10**6))
1051 Ts = 1/(Fs_MHz*(10**6))
1051 Ts = 1/(Fs_MHz*(10**6))
1052
1052
1053 Va = radar_lambda/(4*Ts*cohe_integr)
1053 Va = radar_lambda/(4*Ts*cohe_integr)
1054 rate_bh = ((nsa-codes_num)*channels_number*2 *
1054 rate_bh = ((nsa-codes_num)*channels_number*2 *
1055 bytes_/IPP_us)*(36*(10**8)/cohe_integr)
1055 bytes_/IPP_us)*(36*(10**8)/cohe_integr)
1056 rate_gh = rate_bh/(1024*1024*1024)
1056 rate_gh = rate_bh/(1024*1024*1024)
1057
1057
1058 conf['Time per Block'] = IPP_s * profiles_block * cohe_integr
1058 conf['Time per Block'] = IPP_s * profiles_block * cohe_integr
1059 conf['keys'].append('Time per Block')
1059 conf['keys'].append('Time per Block')
1060 conf['Acq time'] = IPP_s * acq_profiles
1060 conf['Acq time'] = IPP_s * acq_profiles
1061 conf['keys'].append('Acq time')
1061 conf['keys'].append('Acq time')
1062 conf['Data rate'] = str(rate_gh)+" (GB/h)"
1062 conf['Data rate'] = str(rate_gh)+" (GB/h)"
1063 conf['keys'].append('Data rate')
1063 conf['keys'].append('Data rate')
1064 conf['Va (m/s)'] = Va
1064 conf['Va (m/s)'] = Va
1065 conf['keys'].append('Va (m/s)')
1065 conf['keys'].append('Va (m/s)')
1066 conf['Vrange (m/s)'] = 3/(2*IPP_s*cohe_integr)
1066 conf['Vrange (m/s)'] = 3/(2*IPP_s*cohe_integr)
1067 conf['keys'].append('Vrange (m/s)')
1067 conf['keys'].append('Vrange (m/s)')
1068
1068
1069 kwargs['configurations'].append(conf)
1069 kwargs['configurations'].append(conf)
1070 kwargs['menu_experiments'] = 'active'
1070 kwargs['menu_experiments'] = 'active'
1071
1071
1072 ###### SIDEBAR ######
1072 ###### SIDEBAR ######
1073 kwargs.update(sidebar(experiment=experiment))
1073 kwargs.update(sidebar(experiment=experiment))
1074
1074
1075 return render(request, 'experiment_summary.html', kwargs)
1075 return render(request, 'experiment_summary.html', kwargs)
1076
1076
1077
1077
1078 @login_required
1078 @login_required
1079 def experiment_verify(request, id_exp):
1079 def experiment_verify(request, id_exp):
1080
1080
1081 experiment = get_object_or_404(Experiment, pk=id_exp)
1081 experiment = get_object_or_404(Experiment, pk=id_exp)
1082 experiment_data = experiment.parms_to_dict()
1082 experiment_data = experiment.parms_to_dict()
1083 configurations = Configuration.objects.filter(
1083 configurations = Configuration.objects.filter(
1084 experiment=experiment, type=0)
1084 experiment=experiment, type=0)
1085
1085
1086 kwargs = {}
1086 kwargs = {}
1087
1087
1088 kwargs['experiment_keys'] = ['template',
1088 kwargs['experiment_keys'] = ['template',
1089 'radar_system', 'name', 'start_time', 'end_time']
1089 'radar_system', 'name', 'start_time', 'end_time']
1090 kwargs['experiment'] = experiment
1090 kwargs['experiment'] = experiment
1091
1091
1092 kwargs['configuration_keys'] = ['name', 'device__ip_address',
1092 kwargs['configuration_keys'] = ['name', 'device__ip_address',
1093 'device__port_address', 'device__status']
1093 'device__port_address', 'device__status']
1094 kwargs['configurations'] = configurations
1094 kwargs['configurations'] = configurations
1095 kwargs['experiment_data'] = experiment_data
1095 kwargs['experiment_data'] = experiment_data
1096
1096
1097 kwargs['title'] = 'Verify Experiment'
1097 kwargs['title'] = 'Verify Experiment'
1098 kwargs['suptitle'] = 'Parameters'
1098 kwargs['suptitle'] = 'Parameters'
1099
1099
1100 kwargs['button'] = 'Update'
1100 kwargs['button'] = 'Update'
1101
1101
1102 jars_conf = False
1102 jars_conf = False
1103 rc_conf = False
1103 rc_conf = False
1104 dds_conf = False
1104 dds_conf = False
1105
1105
1106 for configuration in configurations:
1106 for configuration in configurations:
1107 #-------------------- JARS -----------------------:
1107 #-------------------- JARS -----------------------:
1108 if configuration.device.device_type.name == 'jars':
1108 if configuration.device.device_type.name == 'jars':
1109 jars_conf = True
1109 jars_conf = True
1110 jars = configuration
1110 jars = configuration
1111 kwargs['jars_conf'] = jars_conf
1111 kwargs['jars_conf'] = jars_conf
1112 filter_parms = json.loads(jars.filter_parms)
1112 filter_parms = json.loads(jars.filter_parms)
1113 kwargs['filter_parms'] = filter_parms
1113 kwargs['filter_parms'] = filter_parms
1114 #--Sampling Frequency
1114 #--Sampling Frequency
1115 clock = filter_parms['clock']
1115 clock = filter_parms['clock']
1116 filter_2 = filter_parms['cic_2']
1116 filter_2 = filter_parms['cic_2']
1117 filter_5 = filter_parms['cic_5']
1117 filter_5 = filter_parms['cic_5']
1118 filter_fir = filter_parms['fir']
1118 filter_fir = filter_parms['fir']
1119 samp_freq_jars = clock/filter_2/filter_5/filter_fir
1119 samp_freq_jars = clock/filter_2/filter_5/filter_fir
1120
1120
1121 kwargs['samp_freq_jars'] = samp_freq_jars
1121 kwargs['samp_freq_jars'] = samp_freq_jars
1122 kwargs['jars'] = configuration
1122 kwargs['jars'] = configuration
1123
1123
1124 #--------------------- RC ----------------------:
1124 #--------------------- RC ----------------------:
1125 if configuration.device.device_type.name == 'rc' and not configuration.mix:
1125 if configuration.device.device_type.name == 'rc' and not configuration.mix:
1126 rc_conf = True
1126 rc_conf = True
1127 rc = configuration
1127 rc = configuration
1128
1128
1129 rc_parms = configuration.parms_to_dict()
1129 rc_parms = configuration.parms_to_dict()
1130
1130
1131 win_lines = rc.get_lines(line_type__name='windows')
1131 win_lines = rc.get_lines(line_type__name='windows')
1132 if win_lines:
1132 if win_lines:
1133 dh = json.loads(win_lines[0].params)['params'][0]['resolution']
1133 dh = json.loads(win_lines[0].params)['params'][0]['resolution']
1134 #--Sampling Frequency
1134 #--Sampling Frequency
1135 samp_freq_rc = 0.15/dh
1135 samp_freq_rc = 0.15/dh
1136 kwargs['samp_freq_rc'] = samp_freq_rc
1136 kwargs['samp_freq_rc'] = samp_freq_rc
1137
1137
1138 kwargs['rc_conf'] = rc_conf
1138 kwargs['rc_conf'] = rc_conf
1139 kwargs['rc'] = configuration
1139 kwargs['rc'] = configuration
1140
1140
1141 #-------------------- DDS ----------------------:
1141 #-------------------- DDS ----------------------:
1142 if configuration.device.device_type.name == 'dds':
1142 if configuration.device.device_type.name == 'dds':
1143 dds_conf = True
1143 dds_conf = True
1144 dds = configuration
1144 dds = configuration
1145 dds_parms = configuration.parms_to_dict()
1145 dds_parms = configuration.parms_to_dict()
1146
1146
1147 kwargs['dds_conf'] = dds_conf
1147 kwargs['dds_conf'] = dds_conf
1148 kwargs['dds'] = configuration
1148 kwargs['dds'] = configuration
1149
1149
1150 #------------Validation------------:
1150 #------------Validation------------:
1151 #Clock
1151 #Clock
1152 if dds_conf and rc_conf and jars_conf:
1152 if dds_conf and rc_conf and jars_conf:
1153 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) and float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1153 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) and float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1154 messages.warning(request, "Devices don't have the same clock.")
1154 messages.warning(request, "Devices don't have the same clock.")
1155 elif rc_conf and jars_conf:
1155 elif rc_conf and jars_conf:
1156 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']):
1156 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']):
1157 messages.warning(request, "Devices don't have the same clock.")
1157 messages.warning(request, "Devices don't have the same clock.")
1158 elif rc_conf and dds_conf:
1158 elif rc_conf and dds_conf:
1159 if float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1159 if float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1160 messages.warning(request, "Devices don't have the same clock.")
1160 messages.warning(request, "Devices don't have the same clock.")
1161 if float(samp_freq_rc) != float(dds_parms['configurations']['byId'][str(dds.pk)]['frequencyA']):
1161 if float(samp_freq_rc) != float(dds_parms['configurations']['byId'][str(dds.pk)]['frequencyA']):
1162 messages.warning(
1162 messages.warning(
1163 request, "Devices don't have the same Frequency A.")
1163 request, "Devices don't have the same Frequency A.")
1164
1164
1165 #------------POST METHOD------------:
1165 #------------POST METHOD------------:
1166 if request.method == 'POST':
1166 if request.method == 'POST':
1167 if request.POST['suggest_clock']:
1167 if request.POST['suggest_clock']:
1168 try:
1168 try:
1169 suggest_clock = float(request.POST['suggest_clock'])
1169 suggest_clock = float(request.POST['suggest_clock'])
1170 except:
1170 except:
1171 messages.warning(request, "Invalid value in CLOCK IN.")
1171 messages.warning(request, "Invalid value in CLOCK IN.")
1172 return redirect('url_verify_experiment', id_exp=experiment.id)
1172 return redirect('url_verify_experiment', id_exp=experiment.id)
1173 else:
1173 else:
1174 suggest_clock = ""
1174 suggest_clock = ""
1175 if suggest_clock:
1175 if suggest_clock:
1176 if rc_conf:
1176 if rc_conf:
1177 rc.clock_in = suggest_clock
1177 rc.clock_in = suggest_clock
1178 rc.save()
1178 rc.save()
1179 if jars_conf:
1179 if jars_conf:
1180 filter_parms = jars.filter_parms
1180 filter_parms = jars.filter_parms
1181 filter_parms = ast.literal_eval(filter_parms)
1181 filter_parms = ast.literal_eval(filter_parms)
1182 filter_parms['clock'] = suggest_clock
1182 filter_parms['clock'] = suggest_clock
1183 jars.filter_parms = json.dumps(filter_parms)
1183 jars.filter_parms = json.dumps(filter_parms)
1184 jars.save()
1184 jars.save()
1185 kwargs['filter_parms'] = filter_parms
1185 kwargs['filter_parms'] = filter_parms
1186 if dds_conf:
1186 if dds_conf:
1187 dds.clock = suggest_clock
1187 dds.clock = suggest_clock
1188 dds.save()
1188 dds.save()
1189
1189
1190 if request.POST['suggest_frequencyA']:
1190 if request.POST['suggest_frequencyA']:
1191 try:
1191 try:
1192 suggest_frequencyA = float(request.POST['suggest_frequencyA'])
1192 suggest_frequencyA = float(request.POST['suggest_frequencyA'])
1193 except:
1193 except:
1194 messages.warning(request, "Invalid value in FREQUENCY A.")
1194 messages.warning(request, "Invalid value in FREQUENCY A.")
1195 return redirect('url_verify_experiment', id_exp=experiment.id)
1195 return redirect('url_verify_experiment', id_exp=experiment.id)
1196 else:
1196 else:
1197 suggest_frequencyA = ""
1197 suggest_frequencyA = ""
1198 if suggest_frequencyA:
1198 if suggest_frequencyA:
1199 if jars_conf:
1199 if jars_conf:
1200 filter_parms = jars.filter_parms
1200 filter_parms = jars.filter_parms
1201 filter_parms = ast.literal_eval(filter_parms)
1201 filter_parms = ast.literal_eval(filter_parms)
1202 filter_parms['fch'] = suggest_frequencyA
1202 filter_parms['fch'] = suggest_frequencyA
1203 jars.filter_parms = json.dumps(filter_parms)
1203 jars.filter_parms = json.dumps(filter_parms)
1204 jars.save()
1204 jars.save()
1205 kwargs['filter_parms'] = filter_parms
1205 kwargs['filter_parms'] = filter_parms
1206 if dds_conf:
1206 if dds_conf:
1207 dds.frequencyA_Mhz = request.POST['suggest_frequencyA']
1207 dds.frequencyA_Mhz = request.POST['suggest_frequencyA']
1208 dds.save()
1208 dds.save()
1209
1209
1210 kwargs['menu_experiments'] = 'active'
1210 kwargs['menu_experiments'] = 'active'
1211 kwargs.update(sidebar(experiment=experiment))
1211 kwargs.update(sidebar(experiment=experiment))
1212 return render(request, 'experiment_verify.html', kwargs)
1212 return render(request, 'experiment_verify.html', kwargs)
1213
1213
1214
1214
1215 def parse_mix_result(s):
1215 def parse_mix_result(s):
1216
1216
1217 values = s.split('-')
1217 values = s.split('-')
1218 html = 'EXP MOD OPE DELAY MASK\r\n'
1218 html = 'EXP MOD OPE DELAY MASK\r\n'
1219
1219
1220 if not values or values[0] in ('', ' '):
1220 if not values or values[0] in ('', ' '):
1221 return mark_safe(html)
1221 return mark_safe(html)
1222
1222
1223 for i, value in enumerate(values):
1223 for i, value in enumerate(values):
1224 if not value:
1224 if not value:
1225 continue
1225 continue
1226 pk, mode, operation, delay, mask = value.split('|')
1226 pk, mode, operation, delay, mask = value.split('|')
1227 conf = RCConfiguration.objects.get(pk=pk)
1227 conf = RCConfiguration.objects.get(pk=pk)
1228 if i == 0:
1228 if i == 0:
1229 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1229 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1230 conf.name,
1230 conf.name,
1231 mode,
1231 mode,
1232 ' ',
1232 ' ',
1233 delay,
1233 delay,
1234 mask)
1234 mask)
1235 else:
1235 else:
1236 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1236 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1237 conf.name,
1237 conf.name,
1238 mode,
1238 mode,
1239 operation,
1239 operation,
1240 delay,
1240 delay,
1241 mask)
1241 mask)
1242
1242
1243 return mark_safe(html)
1243 return mark_safe(html)
1244
1244
1245
1245
1246 def parse_mask(l):
1246 def parse_mask(l):
1247
1247
1248 values = []
1248 values = []
1249
1249
1250 for x in range(16):
1250 for x in range(16):
1251 if '{}'.format(x) in l:
1251 if '{}'.format(x) in l:
1252 values.append(1)
1252 values.append(1)
1253 else:
1253 else:
1254 values.append(0)
1254 values.append(0)
1255
1255
1256 values.reverse()
1256 values.reverse()
1257
1257
1258 return int(''.join([str(x) for x in values]), 2)
1258 return int(''.join([str(x) for x in values]), 2)
1259
1259
1260
1260
1261 def dev_confs(request):
1261 def dev_confs(request):
1262
1262
1263 page = request.GET.get('page')
1263 page = request.GET.get('page')
1264 order = ('programmed_date', )
1264 order = ('programmed_date', )
1265 filters = request.GET.copy()
1265 filters = request.GET.copy()
1266 if 'my configurations' in filters:
1266 if 'my configurations' in filters:
1267 filters.pop('my configurations', None)
1267 filters.pop('my configurations', None)
1268 filters['mine'] = request.user.id
1268 filters['mine'] = request.user.id
1269 kwargs = get_paginator(Configuration, page, order, filters)
1269 kwargs = get_paginator(Configuration, page, order, filters)
1270 fields = ['tags', 'template', 'historical']
1270 fields = ['tags', 'template', 'historical']
1271 if request.user.is_authenticated:
1271 if request.user.is_authenticated:
1272 fields.append('my configurations')
1272 fields.append('my configurations')
1273 form = FilterForm(initial=request.GET, extra_fields=fields)
1273 form = FilterForm(initial=request.GET, extra_fields=fields)
1274 kwargs['keys'] = ['name', 'experiment',
1274 kwargs['keys'] = ['name', 'experiment',
1275 'type', 'programmed_date', 'actions']
1275 'type', 'programmed_date', 'actions']
1276 kwargs['title'] = 'Configuration'
1276 kwargs['title'] = 'Configuration'
1277 kwargs['suptitle'] = 'List'
1277 kwargs['suptitle'] = 'List'
1278 kwargs['no_sidebar'] = True
1278 kwargs['no_sidebar'] = True
1279 kwargs['form'] = form
1279 kwargs['form'] = form
1280 kwargs['add_url'] = reverse('url_add_dev_conf', args=[0])
1280 kwargs['add_url'] = reverse('url_add_dev_conf', args=[0])
1281 filters = request.GET.copy()
1281 filters = request.GET.copy()
1282 filters.pop('page', None)
1282 filters.pop('page', None)
1283 kwargs['q'] = urlencode(filters)
1283 kwargs['q'] = urlencode(filters)
1284 kwargs['menu_configurations'] = 'active'
1284 kwargs['menu_configurations'] = 'active'
1285
1285
1286 return render(request, 'base_list.html', kwargs)
1286 return render(request, 'base_list.html', kwargs)
1287
1287
1288
1288
1289 def dev_conf(request, id_conf):
1289 def dev_conf(request, id_conf):
1290
1290
1291 conf = get_object_or_404(Configuration, pk=id_conf)
1291 conf = get_object_or_404(Configuration, pk=id_conf)
1292
1292
1293 return redirect(conf.get_absolute_url())
1293 return redirect(conf.get_absolute_url())
1294
1294
1295
1295
1296 @login_required
1296 @login_required
1297 def dev_conf_new(request, id_exp=0, id_dev=0):
1297 def dev_conf_new(request, id_exp=0, id_dev=0):
1298
1298
1299 if not is_developer(request.user):
1299 if not is_developer(request.user):
1300 messages.error(
1300 messages.error(
1301 request, 'Developer required, to create new configurations')
1301 request, 'Developer required, to create new configurations')
1302 return redirect('index')
1302 return redirect('index')
1303
1303
1304 initial = {}
1304 initial = {}
1305 kwargs = {}
1305 kwargs = {}
1306
1306
1307 if id_exp != 0:
1307 if id_exp != 0:
1308 initial['experiment'] = id_exp
1308 initial['experiment'] = id_exp
1309
1309
1310 if id_dev != 0:
1310 if id_dev != 0:
1311 initial['device'] = id_dev
1311 initial['device'] = id_dev
1312
1312
1313 if request.method == 'GET':
1313 if request.method == 'GET':
1314
1314
1315 if id_dev:
1315 if id_dev:
1316 kwargs['button'] = 'Create'
1316 kwargs['button'] = 'Create'
1317 device = Device.objects.get(pk=id_dev)
1317 device = Device.objects.get(pk=id_dev)
1318 DevConfForm = CONF_FORMS[device.device_type.name]
1318 DevConfForm = CONF_FORMS[device.device_type.name]
1319 initial['name'] = request.GET['name']
1319 initial['name'] = request.GET['name']
1320 form = DevConfForm(initial=initial)
1320 form = DevConfForm(initial=initial)
1321 else:
1321 else:
1322 if 'template' in request.GET:
1322 if 'template' in request.GET:
1323 if request.GET['template'] == '0':
1323 if request.GET['template'] == '0':
1324 choices = [(conf.pk, '{}'.format(conf))
1324 choices = [(conf.pk, '{}'.format(conf))
1325 for conf in Configuration.objects.filter(template=True)]
1325 for conf in Configuration.objects.filter(template=True)]
1326 form = NewForm(initial={'create_from': 2},
1326 form = NewForm(initial={'create_from': 2},
1327 template_choices=choices)
1327 template_choices=choices)
1328 else:
1328 else:
1329 kwargs['button'] = 'Create'
1329 kwargs['button'] = 'Create'
1330 conf = Configuration.objects.get(
1330 conf = Configuration.objects.get(
1331 pk=request.GET['template'])
1331 pk=request.GET['template'])
1332 id_dev = conf.device.pk
1332 id_dev = conf.device.pk
1333 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1333 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1334 form = DevConfForm(instance=conf,
1334 form = DevConfForm(instance=conf,
1335 initial={'name': '{}_{:%y%m%d}'.format(conf.name, datetime.now()),
1335 initial={'name': '{}_{:%y%m%d}'.format(conf.name, datetime.now()),
1336 'template': False,
1336 'template': False,
1337 'experiment': id_exp})
1337 'experiment': id_exp})
1338 elif 'blank' in request.GET:
1338 elif 'blank' in request.GET:
1339 kwargs['button'] = 'Create'
1339 kwargs['button'] = 'Create'
1340 form = ConfigurationForm(initial=initial)
1340 form = ConfigurationForm(initial=initial)
1341 else:
1341 else:
1342 form = NewForm()
1342 form = NewForm()
1343
1343
1344 if request.method == 'POST':
1344 if request.method == 'POST':
1345
1345
1346 device = Device.objects.get(pk=request.POST['device'])
1346 device = Device.objects.get(pk=request.POST['device'])
1347 DevConfForm = CONF_FORMS[device.device_type.name]
1347 DevConfForm = CONF_FORMS[device.device_type.name]
1348
1348
1349 form = DevConfForm(request.POST)
1349 form = DevConfForm(request.POST)
1350 kwargs['button'] = 'Create'
1350 kwargs['button'] = 'Create'
1351 if form.is_valid():
1351 if form.is_valid():
1352 conf = form.save(commit=False)
1352 conf = form.save(commit=False)
1353 conf.author = request.user
1353 conf.author = request.user
1354 conf.save()
1354 conf.save()
1355
1355
1356 if 'template' in request.GET and conf.device.device_type.name == 'rc':
1356 if 'template' in request.GET and conf.device.device_type.name == 'rc':
1357 lines = RCLine.objects.filter(
1357 lines = RCLine.objects.filter(
1358 rc_configuration=request.GET['template'])
1358 rc_configuration=request.GET['template'])
1359 for line in lines:
1359 for line in lines:
1360 line.clone(rc_configuration=conf)
1360 line.clone(rc_configuration=conf)
1361
1361
1362 new_lines = conf.get_lines()
1362 new_lines = conf.get_lines()
1363 for line in new_lines:
1363 for line in new_lines:
1364 line_params = json.loads(line.params)
1364 line_params = json.loads(line.params)
1365 if 'TX_ref' in line_params:
1365 if 'TX_ref' in line_params:
1366 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
1366 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
1367 line_params['TX_ref'] = ['{}'.format(
1367 line_params['TX_ref'] = ['{}'.format(
1368 l.pk) for l in new_lines if l.get_name() == ref_line.get_name()][0]
1368 l.pk) for l in new_lines if l.get_name() == ref_line.get_name()][0]
1369 line.params = json.dumps(line_params)
1369 line.params = json.dumps(line_params)
1370 line.save()
1370 line.save()
1371 elif conf.device.device_type.name == 'rc':
1372 clk = RCClock(rc_configuration=conf)
1373 clk.save()
1371
1374
1372 return redirect('url_dev_conf', id_conf=conf.pk)
1375 return redirect('url_dev_conf', id_conf=conf.pk)
1373
1376
1374 kwargs['id_exp'] = id_exp
1377 kwargs['id_exp'] = id_exp
1375 kwargs['form'] = form
1378 kwargs['form'] = form
1376 kwargs['title'] = 'Configuration'
1379 kwargs['title'] = 'Configuration'
1377 kwargs['suptitle'] = 'New'
1380 kwargs['suptitle'] = 'New'
1378 kwargs['menu_configurations'] = 'active'
1381 kwargs['menu_configurations'] = 'active'
1379
1382
1380 if id_dev != 0:
1383 if id_dev != 0:
1381 device = Device.objects.get(pk=id_dev)
1384 device = Device.objects.get(pk=id_dev)
1382 kwargs['device'] = device.device_type.name
1385 kwargs['device'] = device.device_type.name
1383
1386
1384 return render(request, 'dev_conf_edit.html', kwargs)
1387 return render(request, 'dev_conf_edit.html', kwargs)
1385
1388
1386
1389
1387 @login_required
1390 @login_required
1388 def dev_conf_edit(request, id_conf):
1391 def dev_conf_edit(request, id_conf):
1389
1392
1390 conf = get_object_or_404(Configuration, pk=id_conf)
1393 conf = get_object_or_404(Configuration, pk=id_conf)
1391
1394
1392 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1395 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1393
1396
1394 if request.method == 'GET':
1397 if request.method == 'GET':
1395 form = DevConfForm(instance=conf)
1398 form = DevConfForm(instance=conf)
1396
1399
1397 if request.method == 'POST':
1400 if request.method == 'POST':
1398 form = DevConfForm(request.POST, instance=conf)
1401 form = DevConfForm(request.POST, instance=conf)
1399
1402
1400 if form.is_valid():
1403 if form.is_valid():
1401 form.save()
1404 form.save()
1402 return redirect('url_dev_conf', id_conf=id_conf)
1405 return redirect('url_dev_conf', id_conf=id_conf)
1403
1406
1404 kwargs = {}
1407 kwargs = {}
1405 kwargs['form'] = form
1408 kwargs['form'] = form
1406 kwargs['title'] = 'Device Configuration'
1409 kwargs['title'] = 'Device Configuration'
1407 kwargs['suptitle'] = 'Edit'
1410 kwargs['suptitle'] = 'Edit'
1408 kwargs['button'] = 'Update'
1411 kwargs['button'] = 'Update'
1409 kwargs['menu_configurations'] = 'active'
1412 kwargs['menu_configurations'] = 'active'
1410
1413
1411 ###### SIDEBAR ######
1414 ###### SIDEBAR ######
1412 kwargs.update(sidebar(conf=conf))
1415 kwargs.update(sidebar(conf=conf))
1413
1416
1414 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1417 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1415
1418
1416
1419
1417 @login_required
1420 @login_required
1418 def dev_conf_start(request, id_conf):
1421 def dev_conf_start(request, id_conf):
1419
1422
1420 conf = get_object_or_404(Configuration, pk=id_conf)
1423 conf = get_object_or_404(Configuration, pk=id_conf)
1421
1424
1422 if conf.start_device():
1425 if conf.start_device():
1423 messages.success(request, conf.message)
1426 messages.success(request, conf.message)
1424 else:
1427 else:
1425 messages.error(request, conf.message)
1428 messages.error(request, conf.message)
1426
1429
1427 #conf.status_device()
1430 #conf.status_device()
1428
1431
1429 return redirect(conf.get_absolute_url())
1432 return redirect(conf.get_absolute_url())
1430
1433
1431
1434
1432 @login_required
1435 @login_required
1433 def dev_conf_stop(request, id_conf):
1436 def dev_conf_stop(request, id_conf):
1434
1437
1435 conf = get_object_or_404(Configuration, pk=id_conf)
1438 conf = get_object_or_404(Configuration, pk=id_conf)
1436
1439
1437 if conf.stop_device():
1440 if conf.stop_device():
1438 messages.success(request, conf.message)
1441 messages.success(request, conf.message)
1439 else:
1442 else:
1440 messages.error(request, conf.message)
1443 messages.error(request, conf.message)
1441
1444
1442 #conf.status_device()
1445 #conf.status_device()
1443
1446
1444 return redirect(conf.get_absolute_url())
1447 return redirect(conf.get_absolute_url())
1445
1448
1446
1449
1447 @login_required
1450 @login_required
1448 def dev_conf_status(request, id_conf):
1451 def dev_conf_status(request, id_conf):
1449
1452
1450 conf = get_object_or_404(Configuration, pk=id_conf)
1453 conf = get_object_or_404(Configuration, pk=id_conf)
1451
1454
1452 if conf.device.device_type.name == 'abs':
1455 if conf.device.device_type.name == 'abs':
1453 abs = request.user.profile.abs_active
1456 abs = request.user.profile.abs_active
1454 if abs<>conf:
1457 if abs<>conf:
1455 url = '#' if abs is None else abs.get_absolute_url()
1458 url = '#' if abs is None else abs.get_absolute_url()
1456 label = 'None' if abs is None else abs.label
1459 label = 'None' if abs is None else abs.label
1457 messages.warning(
1460 messages.warning(
1458 request,
1461 request,
1459 mark_safe('The current configuration has not been written in the modules, the active configuration is <a href="{}">{}</a>'.format(
1462 mark_safe('The current configuration has not been written in the modules, the active configuration is <a href="{}">{}</a>'.format(
1460 url,
1463 url,
1461 label
1464 label
1462 ))
1465 ))
1463 )
1466 )
1464 return redirect(conf.get_absolute_url())
1467 return redirect(conf.get_absolute_url())
1465
1468
1466 if conf.status_device():
1469 if conf.status_device():
1467 messages.success(request, conf.message)
1470 messages.success(request, conf.message)
1468 else:
1471 else:
1469 messages.error(request, conf.message)
1472 messages.error(request, conf.message)
1470
1473
1471 return redirect(conf.get_absolute_url())
1474 return redirect(conf.get_absolute_url())
1472
1475
1473
1476
1474 @login_required
1477 @login_required
1475 def dev_conf_reset(request, id_conf):
1478 def dev_conf_reset(request, id_conf):
1476
1479
1477 conf = get_object_or_404(Configuration, pk=id_conf)
1480 conf = get_object_or_404(Configuration, pk=id_conf)
1478
1481
1479 if conf.reset_device():
1482 if conf.reset_device():
1480 messages.success(request, conf.message)
1483 messages.success(request, conf.message)
1481 else:
1484 else:
1482 messages.error(request, conf.message)
1485 messages.error(request, conf.message)
1483
1486
1484 return redirect(conf.get_absolute_url())
1487 return redirect(conf.get_absolute_url())
1485
1488
1486
1489
1487 @login_required
1490 @login_required
1488 def dev_conf_write(request, id_conf):
1491 def dev_conf_write(request, id_conf):
1489
1492
1490 conf = get_object_or_404(Configuration, pk=id_conf)
1493 conf = get_object_or_404(Configuration, pk=id_conf)
1491
1494
1492 if conf.write_device():
1495 if conf.write_device():
1493 messages.success(request, conf.message)
1496 messages.success(request, conf.message)
1494 if has_been_modified(conf):
1497 if has_been_modified(conf):
1495 conf.clone(type=1, template=False)
1498 conf.clone(type=1, template=False)
1496 else:
1499 else:
1497 messages.error(request, conf.message)
1500 messages.error(request, conf.message)
1498
1501
1499 return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1502 return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1500
1503
1501
1504
1502 @login_required
1505 @login_required
1503 def dev_conf_read(request, id_conf):
1506 def dev_conf_read(request, id_conf):
1504
1507
1505 conf = get_object_or_404(Configuration, pk=id_conf)
1508 conf = get_object_or_404(Configuration, pk=id_conf)
1506
1509
1507 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1510 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1508
1511
1509 if request.method == 'GET':
1512 if request.method == 'GET':
1510
1513
1511 parms = conf.read_device()
1514 parms = conf.read_device()
1512 #conf.status_device()
1515 #conf.status_device()
1513
1516
1514 if not parms:
1517 if not parms:
1515 messages.error(request, conf.message)
1518 messages.error(request, conf.message)
1516 return redirect(conf.get_absolute_url())
1519 return redirect(conf.get_absolute_url())
1517
1520
1518 form = DevConfForm(initial=parms, instance=conf)
1521 form = DevConfForm(initial=parms, instance=conf)
1519
1522
1520 if request.method == 'POST':
1523 if request.method == 'POST':
1521 form = DevConfForm(request.POST, instance=conf)
1524 form = DevConfForm(request.POST, instance=conf)
1522
1525
1523 if form.is_valid():
1526 if form.is_valid():
1524 form.save()
1527 form.save()
1525 return redirect(conf.get_absolute_url())
1528 return redirect(conf.get_absolute_url())
1526
1529
1527 messages.error(request, "Parameters could not be saved")
1530 messages.error(request, "Parameters could not be saved")
1528
1531
1529 kwargs = {}
1532 kwargs = {}
1530 kwargs['id_dev'] = conf.id
1533 kwargs['id_dev'] = conf.id
1531 kwargs['form'] = form
1534 kwargs['form'] = form
1532 kwargs['title'] = 'Device Configuration'
1535 kwargs['title'] = 'Device Configuration'
1533 kwargs['suptitle'] = 'Parameters read from device'
1536 kwargs['suptitle'] = 'Parameters read from device'
1534 kwargs['button'] = 'Save'
1537 kwargs['button'] = 'Save'
1535
1538
1536 ###### SIDEBAR ######
1539 ###### SIDEBAR ######
1537 kwargs.update(sidebar(conf=conf))
1540 kwargs.update(sidebar(conf=conf))
1538
1541
1539 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1542 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1540
1543
1541
1544
1542 @login_required
1545 @login_required
1543 def dev_conf_import(request, id_conf):
1546 def dev_conf_import(request, id_conf):
1544
1547
1545 conf = get_object_or_404(Configuration, pk=id_conf)
1548 conf = get_object_or_404(Configuration, pk=id_conf)
1546 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1549 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1547
1550
1548 if request.method == 'GET':
1551 if request.method == 'GET':
1549 file_form = UploadFileForm()
1552 file_form = UploadFileForm()
1550
1553
1551 if request.method == 'POST':
1554 if request.method == 'POST':
1552 file_form = UploadFileForm(request.POST, request.FILES)
1555 file_form = UploadFileForm(request.POST, request.FILES)
1553
1556
1554 if file_form.is_valid():
1557 if file_form.is_valid():
1555
1558
1556 data = conf.import_from_file(request.FILES['file'])
1559 data = conf.import_from_file(request.FILES['file'])
1557 parms = Params(data=data).get_conf(
1560 parms = Params(data=data).get_conf(
1558 dtype=conf.device.device_type.name)
1561 dtype=conf.device.device_type.name)
1559
1562
1560 if parms:
1563 if parms:
1561
1564
1562 form = DevConfForm(initial=parms, instance=conf)
1565 form = DevConfForm(initial=parms, instance=conf)
1563
1566
1564 kwargs = {}
1567 kwargs = {}
1565 kwargs['id_dev'] = conf.id
1568 kwargs['id_dev'] = conf.id
1566 kwargs['form'] = form
1569 kwargs['form'] = form
1567 kwargs['title'] = 'Device Configuration'
1570 kwargs['title'] = 'Device Configuration'
1568 kwargs['suptitle'] = 'Parameters imported'
1571 kwargs['suptitle'] = 'Parameters imported'
1569 kwargs['button'] = 'Save'
1572 kwargs['button'] = 'Save'
1570 kwargs['action'] = conf.get_absolute_url_edit()
1573 kwargs['action'] = conf.get_absolute_url_edit()
1571 kwargs['previous'] = conf.get_absolute_url()
1574 kwargs['previous'] = conf.get_absolute_url()
1572
1575
1573 ###### SIDEBAR ######
1576 ###### SIDEBAR ######
1574 kwargs.update(sidebar(conf=conf))
1577 kwargs.update(sidebar(conf=conf))
1575
1578
1576 messages.success(
1579 messages.success(
1577 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
1580 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
1578
1581
1579 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1582 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1580
1583
1581 messages.error(request, "Could not import parameters from file")
1584 messages.error(request, "Could not import parameters from file")
1582
1585
1583 kwargs = {}
1586 kwargs = {}
1584 kwargs['id_dev'] = conf.id
1587 kwargs['id_dev'] = conf.id
1585 kwargs['title'] = 'Device Configuration'
1588 kwargs['title'] = 'Device Configuration'
1586 kwargs['form'] = file_form
1589 kwargs['form'] = file_form
1587 kwargs['suptitle'] = 'Importing file'
1590 kwargs['suptitle'] = 'Importing file'
1588 kwargs['button'] = 'Import'
1591 kwargs['button'] = 'Import'
1589 kwargs['menu_configurations'] = 'active'
1592 kwargs['menu_configurations'] = 'active'
1590
1593
1591 kwargs.update(sidebar(conf=conf))
1594 kwargs.update(sidebar(conf=conf))
1592
1595
1593 return render(request, 'dev_conf_import.html', kwargs)
1596 return render(request, 'dev_conf_import.html', kwargs)
1594
1597
1595
1598
1596 @login_required
1599 @login_required
1597 def dev_conf_export(request, id_conf):
1600 def dev_conf_export(request, id_conf):
1598
1601
1599 conf = get_object_or_404(Configuration, pk=id_conf)
1602 conf = get_object_or_404(Configuration, pk=id_conf)
1600
1603
1601 if request.method == 'GET':
1604 if request.method == 'GET':
1602 file_form = DownloadFileForm(conf.device.device_type.name)
1605 file_form = DownloadFileForm(conf.device.device_type.name)
1603
1606
1604 if request.method == 'POST':
1607 if request.method == 'POST':
1605 file_form = DownloadFileForm(
1608 file_form = DownloadFileForm(
1606 conf.device.device_type.name, request.POST)
1609 conf.device.device_type.name, request.POST)
1607
1610
1608 if file_form.is_valid():
1611 if file_form.is_valid():
1609 fields = conf.export_to_file(
1612 fields = conf.export_to_file(
1610 format=file_form.cleaned_data['format'])
1613 format=file_form.cleaned_data['format'])
1611 if not fields['content']:
1614 if not fields['content']:
1612 messages.error(request, conf.message)
1615 messages.error(request, conf.message)
1613 return redirect(conf.get_absolute_url_export())
1616 return redirect(conf.get_absolute_url_export())
1614 response = HttpResponse(content_type=fields['content_type'])
1617 response = HttpResponse(content_type=fields['content_type'])
1615 response['Content-Disposition'] = 'attachment; filename="%s"' % fields['filename']
1618 response['Content-Disposition'] = 'attachment; filename="%s"' % fields['filename']
1616 response.write(fields['content'])
1619 response.write(fields['content'])
1617
1620
1618 return response
1621 return response
1619
1622
1620 messages.error(request, "Could not export parameters")
1623 messages.error(request, "Could not export parameters")
1621
1624
1622 kwargs = {}
1625 kwargs = {}
1623 kwargs['id_dev'] = conf.id
1626 kwargs['id_dev'] = conf.id
1624 kwargs['title'] = 'Device Configuration'
1627 kwargs['title'] = 'Device Configuration'
1625 kwargs['form'] = file_form
1628 kwargs['form'] = file_form
1626 kwargs['suptitle'] = 'Exporting file'
1629 kwargs['suptitle'] = 'Exporting file'
1627 kwargs['button'] = 'Export'
1630 kwargs['button'] = 'Export'
1628 kwargs['menu_configurations'] = 'active'
1631 kwargs['menu_configurations'] = 'active'
1629
1632
1630 return render(request, 'dev_conf_export.html', kwargs)
1633 return render(request, 'dev_conf_export.html', kwargs)
1631
1634
1632
1635
1633 @login_required
1636 @login_required
1634 def dev_conf_delete(request, id_conf):
1637 def dev_conf_delete(request, id_conf):
1635
1638
1636 conf = get_object_or_404(Configuration, pk=id_conf)
1639 conf = get_object_or_404(Configuration, pk=id_conf)
1637
1640
1638 if request.method == 'POST':
1641 if request.method == 'POST':
1639 if is_developer(request.user):
1642 if is_developer(request.user):
1640 conf.delete()
1643 conf.delete()
1641 return redirect('url_dev_confs')
1644 return redirect('url_dev_confs')
1642
1645
1643 messages.error(request, 'Not enough permission to delete this object')
1646 messages.error(request, 'Not enough permission to delete this object')
1644 return redirect(conf.get_absolute_url())
1647 return redirect(conf.get_absolute_url())
1645
1648
1646 kwargs = {
1649 kwargs = {
1647 'title': 'Delete',
1650 'title': 'Delete',
1648 'suptitle': 'Configuration',
1651 'suptitle': 'Configuration',
1649 'object': conf,
1652 'object': conf,
1650 'delete': True
1653 'delete': True
1651 }
1654 }
1652 kwargs['menu_configurations'] = 'active'
1655 kwargs['menu_configurations'] = 'active'
1653
1656
1654 return render(request, 'confirm.html', kwargs)
1657 return render(request, 'confirm.html', kwargs)
1655
1658
1656
1659
1657 def sidebar(**kwargs):
1660 def sidebar(**kwargs):
1658
1661
1659 side_data = {}
1662 side_data = {}
1660
1663
1661 conf = kwargs.get('conf', None)
1664 conf = kwargs.get('conf', None)
1662 experiment = kwargs.get('experiment', None)
1665 experiment = kwargs.get('experiment', None)
1663
1666
1664 if not experiment:
1667 if not experiment:
1665 experiment = conf.experiment
1668 experiment = conf.experiment
1666
1669
1667 if experiment:
1670 if experiment:
1668 side_data['experiment'] = experiment
1671 side_data['experiment'] = experiment
1669 campaign = experiment.campaign_set.all()
1672 campaign = experiment.campaign_set.all()
1670 if campaign:
1673 if campaign:
1671 side_data['campaign'] = campaign[0]
1674 side_data['campaign'] = campaign[0]
1672 experiments = campaign[0].experiments.all().order_by('name')
1675 experiments = campaign[0].experiments.all().order_by('name')
1673 else:
1676 else:
1674 experiments = [experiment]
1677 experiments = [experiment]
1675 configurations = experiment.configuration_set.filter(type=0)
1678 configurations = experiment.configuration_set.filter(type=0)
1676 side_data['side_experiments'] = experiments
1679 side_data['side_experiments'] = experiments
1677 side_data['side_configurations'] = configurations.order_by(
1680 side_data['side_configurations'] = configurations.order_by(
1678 'device__device_type__name')
1681 'device__device_type__name')
1679
1682
1680 return side_data
1683 return side_data
1681
1684
1682
1685
1683 def get_paginator(model, page, order, filters={}, n=8):
1686 def get_paginator(model, page, order, filters={}, n=8):
1684
1687
1685 kwargs = {}
1688 kwargs = {}
1686 query = Q()
1689 query = Q()
1687 if isinstance(filters, QueryDict):
1690 if isinstance(filters, QueryDict):
1688 filters = filters.dict()
1691 filters = filters.dict()
1689 [filters.pop(key) for key in filters.keys() if filters[key] in ('', ' ')]
1692 [filters.pop(key) for key in filters.keys() if filters[key] in ('', ' ')]
1690 filters.pop('page', None)
1693 filters.pop('page', None)
1691
1694
1692 fields = [f.name for f in model._meta.get_fields()]
1695 fields = [f.name for f in model._meta.get_fields()]
1693
1696
1694 if 'template' in filters:
1697 if 'template' in filters:
1695 filters['template'] = True
1698 filters['template'] = True
1696 if 'historical' in filters:
1699 if 'historical' in filters:
1697 filters.pop('historical')
1700 filters.pop('historical')
1698 filters['type'] = 1
1701 filters['type'] = 1
1699 elif 'type' in fields:
1702 elif 'type' in fields:
1700 filters['type'] = 0
1703 filters['type'] = 0
1701 if 'start_date' in filters:
1704 if 'start_date' in filters:
1702 filters['start_date__gte'] = filters.pop('start_date')
1705 filters['start_date__gte'] = filters.pop('start_date')
1703 if 'end_date' in filters:
1706 if 'end_date' in filters:
1704 filters['start_date__lte'] = filters.pop('end_date')
1707 filters['start_date__lte'] = filters.pop('end_date')
1705 if 'tags' in filters:
1708 if 'tags' in filters:
1706 tags = filters.pop('tags')
1709 tags = filters.pop('tags')
1707 if 'tags' in fields:
1710 if 'tags' in fields:
1708 query = query | Q(tags__icontains=tags)
1711 query = query | Q(tags__icontains=tags)
1709 if 'label' in fields:
1712 if 'label' in fields:
1710 query = query | Q(label__icontains=tags)
1713 query = query | Q(label__icontains=tags)
1711 if 'location' in fields:
1714 if 'location' in fields:
1712 query = query | Q(location__name__icontains=tags)
1715 query = query | Q(location__name__icontains=tags)
1713 if 'device' in fields:
1716 if 'device' in fields:
1714 query = query | Q(device__device_type__name__icontains=tags)
1717 query = query | Q(device__device_type__name__icontains=tags)
1715 query = query | Q(device__location__name__icontains=tags)
1718 query = query | Q(device__location__name__icontains=tags)
1716 if 'device_type' in fields:
1719 if 'device_type' in fields:
1717 query = query | Q(device_type__name__icontains=tags)
1720 query = query | Q(device_type__name__icontains=tags)
1718
1721
1719 if 'mine' in filters:
1722 if 'mine' in filters:
1720 filters['author_id'] = filters['mine']
1723 filters['author_id'] = filters['mine']
1721 filters.pop('mine')
1724 filters.pop('mine')
1722 object_list = model.objects.filter(query, **filters).order_by(*order)
1725 object_list = model.objects.filter(query, **filters).order_by(*order)
1723 paginator = Paginator(object_list, n)
1726 paginator = Paginator(object_list, n)
1724
1727
1725 try:
1728 try:
1726 objects = paginator.page(page)
1729 objects = paginator.page(page)
1727 except PageNotAnInteger:
1730 except PageNotAnInteger:
1728 objects = paginator.page(1)
1731 objects = paginator.page(1)
1729 except EmptyPage:
1732 except EmptyPage:
1730 objects = paginator.page(paginator.num_pages)
1733 objects = paginator.page(paginator.num_pages)
1731
1734
1732 kwargs['objects'] = objects
1735 kwargs['objects'] = objects
1733 kwargs['offset'] = (int(page)-1)*n if page else 0
1736 kwargs['offset'] = (int(page)-1)*n if page else 0
1734
1737
1735 return kwargs
1738 return kwargs
1736
1739
1737
1740
1738 def operation(request, id_camp=None):
1741 def operation(request, id_camp=None):
1739
1742
1740 kwargs = {}
1743 kwargs = {}
1741 kwargs['title'] = 'Radars Operation'
1744 kwargs['title'] = 'Radars Operation'
1742 kwargs['no_sidebar'] = True
1745 kwargs['no_sidebar'] = True
1743 kwargs['menu_operation'] = 'active'
1746 kwargs['menu_operation'] = 'active'
1744 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1747 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1745 end_date__gte=datetime.now()).order_by('-start_date')
1748 end_date__gte=datetime.now()).order_by('-start_date')
1746
1749
1747 if id_camp:
1750 if id_camp:
1748 campaign = get_object_or_404(Campaign, pk=id_camp)
1751 campaign = get_object_or_404(Campaign, pk=id_camp)
1749 form = OperationForm(
1752 form = OperationForm(
1750 initial={'campaign': campaign.id}, campaigns=campaigns)
1753 initial={'campaign': campaign.id}, campaigns=campaigns)
1751 kwargs['campaign'] = campaign
1754 kwargs['campaign'] = campaign
1752 else:
1755 else:
1753 # form = OperationForm(campaigns=campaigns)
1756 # form = OperationForm(campaigns=campaigns)
1754 kwargs['campaigns'] = campaigns
1757 kwargs['campaigns'] = campaigns
1755 return render(request, 'operation.html', kwargs)
1758 return render(request, 'operation.html', kwargs)
1756
1759
1757 #---Experiment
1760 #---Experiment
1758 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1761 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1759 kwargs['experiment_keys'] = keys[1:]
1762 kwargs['experiment_keys'] = keys[1:]
1760 kwargs['experiments'] = experiments
1763 kwargs['experiments'] = experiments
1761 #---Radar
1764 #---Radar
1762 kwargs['locations'] = campaign.get_experiments_by_radar()
1765 kwargs['locations'] = campaign.get_experiments_by_radar()
1763 kwargs['form'] = form
1766 kwargs['form'] = form
1764
1767
1765 return render(request, 'operation.html', kwargs)
1768 return render(request, 'operation.html', kwargs)
1766
1769
1767
1770
1768 @login_required
1771 @login_required
1769 def radar_start(request, id_camp, id_radar):
1772 def radar_start(request, id_camp, id_radar):
1770
1773
1771 campaign = get_object_or_404(Campaign, pk=id_camp)
1774 campaign = get_object_or_404(Campaign, pk=id_camp)
1772 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1775 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1773 now = datetime.now()
1776 now = datetime.now()
1774 for exp in experiments:
1777 for exp in experiments:
1775 start = datetime.combine(datetime.now().date(), exp.start_time)
1778 start = datetime.combine(datetime.now().date(), exp.start_time)
1776 end = datetime.combine(datetime.now().date(), exp.end_time)
1779 end = datetime.combine(datetime.now().date(), exp.end_time)
1777 if end < start:
1780 if end < start:
1778 end += timedelta(1)
1781 end += timedelta(1)
1779
1782
1780 if exp.status == 2:
1783 if exp.status == 2:
1781 messages.warning(
1784 messages.warning(
1782 request, 'Experiment {} already running'.format(exp))
1785 request, 'Experiment {} already running'.format(exp))
1783 continue
1786 continue
1784
1787
1785 if exp.status == 3:
1788 if exp.status == 3:
1786 messages.warning(
1789 messages.warning(
1787 request, 'Experiment {} already programmed'.format(exp))
1790 request, 'Experiment {} already programmed'.format(exp))
1788 continue
1791 continue
1789
1792
1790 if start > campaign.end_date or start < campaign.start_date:
1793 if start > campaign.end_date or start < campaign.start_date:
1791 messages.warning(request, 'Experiment {} out of date'.format(exp))
1794 messages.warning(request, 'Experiment {} out of date'.format(exp))
1792 continue
1795 continue
1793
1796
1794 if now > start and now <= end:
1797 if now > start and now <= end:
1795 exp.status = 3
1798 exp.status = 3
1796 exp.save()
1799 exp.save()
1797 task = task_start.delay(exp.id)
1800 task = task_start.delay(exp.id)
1798 exp.status = task.wait()
1801 exp.status = task.wait()
1799 if exp.status == 0:
1802 if exp.status == 0:
1800 messages.error(request, 'Experiment {} not start'.format(exp))
1803 messages.error(request, 'Experiment {} not start'.format(exp))
1801 if exp.status == 2:
1804 if exp.status == 2:
1802 messages.success(request, 'Experiment {} started'.format(exp))
1805 messages.success(request, 'Experiment {} started'.format(exp))
1803 else:
1806 else:
1804 task = task_start.apply_async(
1807 task = task_start.apply_async(
1805 (exp.pk, ), eta=start+timedelta(hours=5))
1808 (exp.pk, ), eta=start+timedelta(hours=5))
1806 exp.task = task.id
1809 exp.task = task.id
1807 exp.status = 3
1810 exp.status = 3
1808 messages.success(
1811 messages.success(
1809 request, 'Experiment {} programmed to start at {}'.format(exp, start))
1812 request, 'Experiment {} programmed to start at {}'.format(exp, start))
1810
1813
1811 exp.save()
1814 exp.save()
1812
1815
1813 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1816 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1814
1817
1815
1818
1816 @login_required
1819 @login_required
1817 def radar_stop(request, id_camp, id_radar):
1820 def radar_stop(request, id_camp, id_radar):
1818
1821
1819 campaign = get_object_or_404(Campaign, pk=id_camp)
1822 campaign = get_object_or_404(Campaign, pk=id_camp)
1820 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1823 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1821
1824
1822 for exp in experiments:
1825 for exp in experiments:
1823
1826
1824 if exp.task:
1827 if exp.task:
1825 app.control.revoke(exp.task)
1828 app.control.revoke(exp.task)
1826 if exp.status == 2:
1829 if exp.status == 2:
1827 exp.stop()
1830 exp.stop()
1828 messages.warning(request, 'Experiment {} stopped'.format(exp))
1831 messages.warning(request, 'Experiment {} stopped'.format(exp))
1829 exp.status = 1
1832 exp.status = 1
1830 exp.save()
1833 exp.save()
1831
1834
1832 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1835 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1833
1836
1834
1837
1835 @login_required
1838 @login_required
1836 def radar_refresh(request, id_camp, id_radar):
1839 def radar_refresh(request, id_camp, id_radar):
1837
1840
1838 campaign = get_object_or_404(Campaign, pk=id_camp)
1841 campaign = get_object_or_404(Campaign, pk=id_camp)
1839 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1842 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1840
1843
1841 for exp in experiments:
1844 for exp in experiments:
1842 exp.get_status()
1845 exp.get_status()
1843
1846
1844 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1847 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1845
1848
1846
1849
1847 def real_time(request):
1850 def real_time(request):
1848
1851
1849 graphic_path = "/home/fiorella/Pictures/catwbeanie.jpg"
1852 graphic_path = "/home/fiorella/Pictures/catwbeanie.jpg"
1850
1853
1851 kwargs = {}
1854 kwargs = {}
1852 kwargs['title'] = 'CLAIRE'
1855 kwargs['title'] = 'CLAIRE'
1853 kwargs['suptitle'] = 'Real Time'
1856 kwargs['suptitle'] = 'Real Time'
1854 kwargs['no_sidebar'] = True
1857 kwargs['no_sidebar'] = True
1855 kwargs['graphic_path'] = graphic_path
1858 kwargs['graphic_path'] = graphic_path
1856 kwargs['graphic1_path'] = 'http://www.bluemaize.net/im/girls-accessories/shark-beanie-11.jpg'
1859 kwargs['graphic1_path'] = 'http://www.bluemaize.net/im/girls-accessories/shark-beanie-11.jpg'
1857
1860
1858 return render(request, 'real_time.html', kwargs)
1861 return render(request, 'real_time.html', kwargs)
1859
1862
1860 def theme(request, theme):
1863 def theme(request, theme):
1861
1864
1862 user = request.user
1865 user = request.user
1863 user.profile.theme = theme
1866 user.profile.theme = theme
1864 user.save()
1867 user.save()
1865 return redirect('index') No newline at end of file
1868 return redirect('index')
@@ -1,9 +1,10
1 from django.contrib import admin
1 from django.contrib import admin
2 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
2 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode, RCClock
3
3
4 # Register your models here.
4 # Register your models here.
5
5
6 admin.site.register(RCConfiguration)
6 admin.site.register(RCConfiguration)
7 admin.site.register(RCLine)
7 admin.site.register(RCLine)
8 admin.site.register(RCLineType)
8 admin.site.register(RCLineType)
9 admin.site.register(RCLineCode)
9 admin.site.register(RCLineCode)
10 admin.site.register(RCClock)
@@ -1,384 +1,415
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
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')
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 conf.total_units = conf.ipp*conf.ntx*conf.km2unit
97 conf.total_units = conf.ipp*conf.ntx*conf.km2unit
98 conf.save()
98 conf.save()
99 return conf
99 return conf
100
100
101
101
102 class RCMixConfigurationForm(forms.Form):
102 class RCMixConfigurationForm(forms.Form):
103
103
104 clock_in = forms.CharField(widget=forms.HiddenInput())
104 clock_in = forms.CharField(widget=forms.HiddenInput())
105 clock_divider = forms.CharField(widget=forms.HiddenInput())
105 clock_divider = forms.CharField(widget=forms.HiddenInput())
106 name = forms.CharField()
106 name = forms.CharField()
107 experiment = forms.ChoiceField()
107 experiment = forms.ChoiceField()
108 mode = forms.ChoiceField(widget=forms.RadioSelect(),
108 mode = forms.ChoiceField(widget=forms.RadioSelect(),
109 choices=[(0, 'Parallel'), (1, 'Sequence')],
109 choices=[(0, 'Parallel'), (1, 'Sequence')],
110 initial=0)
110 initial=0)
111 operation = forms.ChoiceField(widget=forms.RadioSelect(),
111 operation = forms.ChoiceField(widget=forms.RadioSelect(),
112 choices=[(0, 'OR'), (1, 'XOR'), (2, 'AND'), (3, 'NAND')],
112 choices=[(0, 'OR'), (1, 'XOR'), (2, 'AND'), (3, 'NAND')],
113 initial=1)
113 initial=1)
114 delay = forms.CharField()
114 delay = forms.CharField()
115 mask = forms.MultipleChoiceField(
115 mask = forms.MultipleChoiceField(
116 choices=[(0, 'L1'),(1, 'L2'),(2, 'L3'),(3, 'L4'),(4, 'L5'),(5, 'L6'),(6, 'L7'),(7, 'L8'),
116 choices=[(0, 'L1'),(1, 'L2'),(2, 'L3'),(3, 'L4'),(4, 'L5'),(5, 'L6'),(6, 'L7'),(7, 'L8'),
117 (8, 'L9'),(9, 'L10'),(10, 'L11'),(11, 'L12'),(12, 'L13'),(13, 'L14'),(14, 'L15'),(15, 'L16')],
117 (8, 'L9'),(9, 'L10'),(10, 'L11'),(11, 'L12'),(12, 'L13'),(13, 'L14'),(14, 'L15'),(15, 'L16')],
118 widget=HCheckboxSelectMultiple())
118 widget=HCheckboxSelectMultiple())
119 result = forms.CharField(required=False,
119 result = forms.CharField(required=False,
120 widget=forms.Textarea(attrs={'readonly':True, 'rows':5, 'class':'tabuled'}))
120 widget=forms.Textarea(attrs={'readonly':True, 'rows':5, 'class':'tabuled'}))
121
121
122 def __init__(self, *args, **kwargs):
122 def __init__(self, *args, **kwargs):
123 confs = kwargs.pop('confs', [])
123 confs = kwargs.pop('confs', [])
124 if confs:
124 if confs:
125 km2unit = confs[0].km2unit
125 km2unit = confs[0].km2unit
126 clock_in = confs[0].clock_in
126 clock_in = confs[0].clock_in
127 clock_divider = confs[0].clock_divider
127 clock_divider = confs[0].clock_divider
128 else:
128 else:
129 km2unit = clock_in = clock_divider = 0
129 km2unit = clock_in = clock_divider = 0
130 super(RCMixConfigurationForm, self).__init__(*args, **kwargs)
130 super(RCMixConfigurationForm, self).__init__(*args, **kwargs)
131 self.fields['experiment'].choices = [(conf.pk, '{} | {}'.format(conf.pk, conf.name)) for conf in confs]
131 self.fields['experiment'].choices = [(conf.pk, '{} | {}'.format(conf.pk, conf.name)) for conf in confs]
132 self.fields['delay'].widget = KmUnitWidget(attrs = {'km2unit':km2unit})
132 self.fields['delay'].widget = KmUnitWidget(attrs = {'km2unit':km2unit})
133 self.fields['clock_in'].initial = clock_in
133 self.fields['clock_in'].initial = clock_in
134 self.fields['clock_divider'].initial = clock_divider
134 self.fields['clock_divider'].initial = clock_divider
135
135
136
136
137 class RCLineForm(forms.ModelForm):
137 class RCLineForm(forms.ModelForm):
138
138
139 def __init__(self, *args, **kwargs):
139 def __init__(self, *args, **kwargs):
140 self.extra_fields = kwargs.pop('extra_fields', [])
140 self.extra_fields = kwargs.pop('extra_fields', [])
141 super(RCLineForm, self).__init__(*args, **kwargs)
141 super(RCLineForm, self).__init__(*args, **kwargs)
142
142
143 if 'initial' in kwargs and 'line_type' in kwargs['initial']:
143 if 'initial' in kwargs and 'line_type' in kwargs['initial']:
144 line_type = RCLineType.objects.get(pk=kwargs['initial']['line_type'])
144 line_type = RCLineType.objects.get(pk=kwargs['initial']['line_type'])
145
145
146 if 'code_id' in kwargs['initial']:
146 if 'code_id' in kwargs['initial']:
147 model_initial = kwargs['initial']['code_id']
147 model_initial = kwargs['initial']['code_id']
148 else:
148 else:
149 model_initial = 0
149 model_initial = 0
150
150
151 params = json.loads(line_type.params)
151 params = json.loads(line_type.params)
152
152
153 for label, value in self.extra_fields.items():
153 for label, value in self.extra_fields.items():
154 if label=='params':
154 if label=='params':
155 continue
155 continue
156
156
157 if 'model' in params[label]:
157 if 'model' in params[label]:
158 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
158 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
159 kwargs['initial']['rc_configuration']),
159 kwargs['initial']['rc_configuration']),
160 initial=model_initial)
160 initial=model_initial)
161
161
162
162
163 else:
163 else:
164 if label=='codes' and 'code_id' in kwargs['initial']:
164 if label=='codes' and 'code_id' in kwargs['initial']:
165 self.fields[label] = forms.CharField(initial=RCLineCode.objects.get(pk=kwargs['initial']['code_id']).codes)
165 self.fields[label] = forms.CharField(initial=RCLineCode.objects.get(pk=kwargs['initial']['code_id']).codes)
166 else:
166 else:
167 self.fields[label] = forms.CharField(initial=value['value'])
167 self.fields[label] = forms.CharField(initial=value['value'])
168
168
169 if label=='codes':
169 if label=='codes':
170 self.fields[label].widget = CodesWidget()
170 self.fields[label].widget = CodesWidget()
171
171
172 if self.data:
172 if self.data:
173 line_type = RCLineType.objects.get(pk=self.data['line_type'])
173 line_type = RCLineType.objects.get(pk=self.data['line_type'])
174
174
175 if 'code_id' in self.data:
175 if 'code_id' in self.data:
176 model_initial = self.data['code_id']
176 model_initial = self.data['code_id']
177 else:
177 else:
178 model_initial = 0
178 model_initial = 0
179
179
180 params = json.loads(line_type.params)
180 params = json.loads(line_type.params)
181
181
182 for label, value in self.extra_fields.items():
182 for label, value in self.extra_fields.items():
183 if label=='params':
183 if label=='params':
184 continue
184 continue
185
185
186 if 'model' in params[label]:
186 if 'model' in params[label]:
187 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
187 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
188 self.data['rc_configuration']),
188 self.data['rc_configuration']),
189 initial=model_initial)
189 initial=model_initial)
190
190
191
191
192 else:
192 else:
193 if label=='codes' and 'code' in self.data:
193 if label=='codes' and 'code' in self.data:
194 self.fields[label] = forms.CharField(initial=self.data['codes'])
194 self.fields[label] = forms.CharField(initial=self.data['codes'])
195 else:
195 else:
196 self.fields[label] = forms.CharField(initial=self.data[label])
196 self.fields[label] = forms.CharField(initial=self.data[label])
197
197
198 if label=='codes':
198 if label=='codes':
199 self.fields[label].widget = CodesWidget()
199 self.fields[label].widget = CodesWidget()
200
200
201
201
202 class Meta:
202 class Meta:
203 model = RCLine
203 model = RCLine
204 fields = ('rc_configuration', 'line_type', 'channel')
204 fields = ('rc_configuration', 'line_type', 'channel')
205 widgets = {
205 widgets = {
206 'channel': forms.HiddenInput(),
206 'channel': forms.HiddenInput(),
207 }
207 }
208
208
209
209
210 def clean(self):
210 def clean(self):
211
211
212 form_data = self.cleaned_data
212 form_data = self.cleaned_data
213 if 'code' in self.data and self.data['TX_ref']=="0":
213 if 'code' in self.data and self.data['TX_ref']=="0":
214 self.add_error('TX_ref', 'Choose a valid TX reference')
214 self.add_error('TX_ref', 'Choose a valid TX reference')
215
215
216 if RCLineType.objects.get(pk=self.data['line_type']).name=='mix':
216 if RCLineType.objects.get(pk=self.data['line_type']).name=='mix':
217 self.add_error('line_type', 'Invalid Line type')
217 self.add_error('line_type', 'Invalid Line type')
218
218
219 return form_data
219 return form_data
220
220
221
221
222 def save(self):
222 def save(self):
223 line = super(RCLineForm, self).save()
223 line = super(RCLineForm, self).save()
224
224
225 #auto add channel
225 #auto add channel
226 line.channel = RCLine.objects.filter(rc_configuration=line.rc_configuration).count()-1
226 line.channel = RCLine.objects.filter(rc_configuration=line.rc_configuration).count()-1
227
227
228 #auto add position for TX, TR & CODE
228 #auto add position for TX, TR & CODE
229 if line.line_type.name in ('tx', ):
229 if line.line_type.name in ('tx', ):
230 line.position = RCLine.objects.filter(rc_configuration=line.rc_configuration, line_type=line.line_type).count()-1
230 line.position = RCLine.objects.filter(rc_configuration=line.rc_configuration, line_type=line.line_type).count()-1
231
231
232 #save extra fields in params
232 #save extra fields in params
233 params = {}
233 params = {}
234 for label, value in self.extra_fields.items():
234 for label, value in self.extra_fields.items():
235 if label=='params':
235 if label=='params':
236 params['params'] = []
236 params['params'] = []
237 elif label=='codes':
237 elif label=='codes':
238 params[label] = [s for s in self.data[label].split('\r\n') if s]
238 params[label] = [s for s in self.data[label].split('\r\n') if s]
239 else:
239 else:
240 params[label] = self.data[label]
240 params[label] = self.data[label]
241 line.params = json.dumps(params)
241 line.params = json.dumps(params)
242 line.save()
242 line.save()
243 return
243 return
244
244
245
245
246 class RCLineViewForm(forms.Form):
246 class RCLineViewForm(forms.Form):
247
247
248 def __init__(self, *args, **kwargs):
248 def __init__(self, *args, **kwargs):
249
249
250 extra_fields = kwargs.pop('extra_fields')
250 extra_fields = kwargs.pop('extra_fields')
251 line = kwargs.pop('line')
251 line = kwargs.pop('line')
252 subform = kwargs.pop('subform', False)
252 subform = kwargs.pop('subform', False)
253 super(RCLineViewForm, self).__init__(*args, **kwargs)
253 super(RCLineViewForm, self).__init__(*args, **kwargs)
254
254
255 if subform:
255 if subform:
256 params = json.loads(line.line_type.params)['params']
256 params = json.loads(line.line_type.params)['params']
257 else:
257 else:
258 params = json.loads(line.line_type.params)
258 params = json.loads(line.line_type.params)
259
259
260 for label, value in extra_fields.items():
260 for label, value in extra_fields.items():
261
261
262 if label=='params':
262 if label=='params':
263 continue
263 continue
264 if 'ref' in label:
264 if 'ref' in label:
265 if value in (0, '0'):
265 if value in (0, '0'):
266 value = 'All'
266 value = 'All'
267 else:
267 else:
268 value = RCLine.objects.get(pk=value).get_name()
268 value = RCLine.objects.get(pk=value).get_name()
269 elif label=='code':
269 elif label=='code':
270 value = RCLineCode.objects.get(pk=value).name
270 value = RCLineCode.objects.get(pk=value).name
271
271
272 self.fields[label] = forms.CharField(initial=value)
272 self.fields[label] = forms.CharField(initial=value)
273
273
274 if 'widget' in params[label]:
274 if 'widget' in params[label]:
275 km2unit = line.rc_configuration.km2unit
275 km2unit = line.rc_configuration.km2unit
276 if params[label]['widget']=='km':
276 if params[label]['widget']=='km':
277 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
277 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
278 elif params[label]['widget']=='unit':
278 elif params[label]['widget']=='unit':
279 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
279 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
280 elif params[label]['widget']=='dc':
280 elif params[label]['widget']=='dc':
281 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
281 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
282 elif params[label]['widget']=='codes':
282 elif params[label]['widget']=='codes':
283 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
283 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
284 else:
284 else:
285 self.fields[label].widget = DefaultWidget(attrs={'disabled':True})
285 self.fields[label].widget = DefaultWidget(attrs={'disabled':True})
286
286
287
287
288 class RCLineEditForm(forms.ModelForm):
288 class RCLineEditForm(forms.ModelForm):
289
289
290 def __init__(self, *args, **kwargs):
290 def __init__(self, *args, **kwargs):
291
291
292 extra_fields = kwargs.pop('extra_fields', [])
292 extra_fields = kwargs.pop('extra_fields', [])
293 conf = kwargs.pop('conf', False)
293 conf = kwargs.pop('conf', False)
294 line = kwargs.pop('line')
294 line = kwargs.pop('line')
295 subform = kwargs.pop('subform', False)
295 subform = kwargs.pop('subform', False)
296
296
297 super(RCLineEditForm, self).__init__(*args, **kwargs)
297 super(RCLineEditForm, self).__init__(*args, **kwargs)
298
298
299 if subform is not False:
299 if subform is not False:
300 params = json.loads(line.line_type.params)['params']
300 params = json.loads(line.line_type.params)['params']
301 count = subform
301 count = subform
302 else:
302 else:
303 params = json.loads(line.line_type.params)
303 params = json.loads(line.line_type.params)
304 count = -1
304 count = -1
305
305
306 for label, value in extra_fields.items():
306 for label, value in extra_fields.items():
307
307
308 if label in ('params',):
308 if label in ('params',):
309 continue
309 continue
310 if 'help' in params[label]:
310 if 'help' in params[label]:
311 help_text = params[label]['help']
311 help_text = params[label]['help']
312 else:
312 else:
313 help_text = ''
313 help_text = ''
314
314
315 if 'model' in params[label]:
315 if 'model' in params[label]:
316 if line.line_type.name=='tr':
316 if line.line_type.name=='tr':
317 all_choice = True
317 all_choice = True
318 else:
318 else:
319 all_choice = False
319 all_choice = False
320 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'], conf.id, all_choice=all_choice),
320 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'], conf.id, all_choice=all_choice),
321 initial=value,
321 initial=value,
322 widget=forms.Select(attrs={'name':'%s|%s|%s' % (count, line.id, label)}),
322 widget=forms.Select(attrs={'name':'%s|%s|%s' % (count, line.id, label)}),
323 help_text=help_text)
323 help_text=help_text)
324
324
325 else:
325 else:
326 self.fields[label] = forms.CharField(initial=value, help_text=help_text)
326 self.fields[label] = forms.CharField(initial=value, help_text=help_text)
327
327
328 if label in ('code', ):
328 if label in ('code', ):
329 self.fields[label].widget = HiddenWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
329 self.fields[label].widget = HiddenWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
330
330
331 elif 'widget' in params[label]:
331 elif 'widget' in params[label]:
332 km2unit = line.rc_configuration.km2unit
332 km2unit = line.rc_configuration.km2unit
333 if params[label]['widget']=='km':
333 if params[label]['widget']=='km':
334 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
334 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
335 elif params[label]['widget']=='unit':
335 elif params[label]['widget']=='unit':
336 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
336 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
337 elif params[label]['widget']=='dc':
337 elif params[label]['widget']=='dc':
338 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
338 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
339 elif params[label]['widget']=='codes':
339 elif params[label]['widget']=='codes':
340 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
340 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
341 else:
341 else:
342 self.fields[label].widget = DefaultWidget(attrs={'line':line, 'name':'%s|%s|%s' % (count, line.id, label)})
342 self.fields[label].widget = DefaultWidget(attrs={'line':line, 'name':'%s|%s|%s' % (count, line.id, label)})
343
343
344
344
345 class Meta:
345 class Meta:
346 model = RCLine
346 model = RCLine
347 exclude = ('rc_configuration', 'line_type', 'channel', 'position', 'params', 'pulses')
347 exclude = ('rc_configuration', 'line_type', 'channel', 'position', 'params', 'pulses')
348
348
349
349
350 class RCSubLineEditForm(forms.Form):
350 class RCSubLineEditForm(forms.Form):
351
351
352 def __init__(self, *args, **kwargs):
352 def __init__(self, *args, **kwargs):
353 extra_fields = kwargs.pop('extra_fields')
353 extra_fields = kwargs.pop('extra_fields')
354 count = kwargs.pop('count')
354 count = kwargs.pop('count')
355 line = kwargs.pop('line')
355 line = kwargs.pop('line')
356 super(RCSubLineEditForm, self).__init__(*args, **kwargs)
356 super(RCSubLineEditForm, self).__init__(*args, **kwargs)
357 for label, value in extra_fields.items():
357 for label, value in extra_fields.items():
358 self.fields[label] = forms.CharField(initial=value,
358 self.fields[label] = forms.CharField(initial=value,
359 widget=forms.TextInput(attrs={'name':'%s|%s|%s' % (count, line, label)}))
359 widget=forms.TextInput(attrs={'name':'%s|%s|%s' % (count, line, label)}))
360
360
361
361
362 class RCImportForm(forms.Form):
362 class RCImportForm(forms.Form):
363
363
364 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
364 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
365
365
366
366
367 class RCLineCodesForm(forms.ModelForm):
367 class RCLineCodesForm(forms.ModelForm):
368
368
369 def __init__(self, *args, **kwargs):
369 def __init__(self, *args, **kwargs):
370 super(RCLineCodesForm, self).__init__(*args, **kwargs)
370 super(RCLineCodesForm, self).__init__(*args, **kwargs)
371
371
372 if 'initial' in kwargs:
372 if 'initial' in kwargs:
373 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
373 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
374 initial=kwargs['initial']['code'])
374 initial=kwargs['initial']['code'])
375 if 'instance' in kwargs:
375 if 'instance' in kwargs:
376 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
376 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
377 initial=kwargs['instance'].pk)
377 initial=kwargs['instance'].pk)
378
378
379 self.fields['codes'].widget = CodesWidget()
379 self.fields['codes'].widget = CodesWidget()
380
380
381
381
382 class Meta:
382 class Meta:
383 model = RCLineCode
383 model = RCLineCode
384 exclude = ('name',)
384 exclude = ('name',)
385
386 class RCClockForm(forms.ModelForm):
387
388 def __init__(self, *args, **kwargs):
389 super(RCClockForm, self).__init__(*args, **kwargs)
390
391 instance = getattr(self, 'instance', None)
392
393 if instance is not None and instance.mode:
394 self.fields['multiplier'].widget.attrs['readonly'] = True
395 self.fields['divisor'].widget.attrs['readonly'] = True
396 self.fields['reference'].widget.attrs['readonly'] = True
397
398
399 class Meta:
400 model = RCClock
401 exclude = ('rc_configuration',)
402
403 def clean(self):
404
405 form_data = self.cleaned_data
406
407 if form_data['mode'] is True and float(form_data['frequency']) not in (60., 55.):
408 self.add_error('frequency', 'Only 60 and 55 are valid values in auto mode')
409 elif form_data['mode'] is False:
410 if form_data['reference']==0 and not 24<=form_data['multiplier']<=36:
411 self.add_error('multiplier', 'For 25MHz, valid values are between 24 and 36')
412 elif form_data['reference']==1 and not 60<=form_data['multiplier']<=90:
413 self.add_error('multiplier', 'For 10MHz, valid values are between 60 and 90')
414
415 return form_data No newline at end of file
@@ -1,1004 +1,1027
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.core.urlresolvers import reverse
11 from django.core.urlresolvers 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 # self.name = data['name']
161 # self.name = data['name']
162 self.ipp = data['ipp']
162 self.ipp = data['ipp']
163 self.ntx = data['ntx']
163 self.ntx = data['ntx']
164 self.clock_in = data['clock_in']
164 self.clock_in = data['clock_in']
165 self.clock_divider = data['clock_divider']
165 self.clock_divider = data['clock_divider']
166 self.clock = data['clock']
166 self.clock = data['clock']
167 self.time_before = data['time_before']
167 self.time_before = data['time_before']
168 self.time_after = data['time_after']
168 self.time_after = data['time_after']
169 self.sync = data['sync']
169 self.sync = data['sync']
170 self.sampling_reference = data['sampling_reference']
170 self.sampling_reference = data['sampling_reference']
171 self.total_units = self.ipp*self.ntx*self.km2unit
171 self.total_units = self.ipp*self.ntx*self.km2unit
172 self.save()
172 self.save()
173 self.clean_lines()
173 self.clean_lines()
174
174
175 positions = {'tx':0, 'tr':0}
175 positions = {'tx':0, 'tr':0}
176 for i, id in enumerate(data['lines']):
176 for i, id in enumerate(data['lines']):
177 line_data = params['lines']['byId'][id]
177 line_data = params['lines']['byId'][id]
178 line_type = RCLineType.objects.get(name=line_data['line_type'])
178 line_type = RCLineType.objects.get(name=line_data['line_type'])
179 if line_type.name == 'codes':
179 if line_type.name == 'codes':
180 code = RCLineCode.objects.get(name=line_data['params']['code'])
180 code = RCLineCode.objects.get(name=line_data['params']['code'])
181 line_data['params']['code'] = code.pk
181 line_data['params']['code'] = code.pk
182 if line_type.name == 'tx':
182 if line_type.name == 'tx':
183 position = positions['tx']
183 position = positions['tx']
184 positions['tx'] += 1
184 positions['tx'] += 1
185 elif line_type.name == 'tr':
185 elif line_type.name == 'tr':
186 position = positions['tr']
186 position = positions['tr']
187 positions['tr'] += 1
187 positions['tr'] += 1
188 else:
188 else:
189 position = 0
189 position = 0
190 line, dum = RCLine.objects.update_or_create(
190 line, dum = RCLine.objects.update_or_create(
191 rc_configuration=self,
191 rc_configuration=self,
192 channel=i,
192 channel=i,
193 position=position,
193 position=position,
194 defaults={
194 defaults={
195 'line_type': line_type,
195 'line_type': line_type,
196 'params': json.dumps(line_data['params'])
196 'params': json.dumps(line_data['params'])
197 }
197 }
198 )
198 )
199
199
200 for i, line in enumerate(self.get_lines()):
200 for i, line in enumerate(self.get_lines()):
201 line_params = json.loads(line.params)
201 line_params = json.loads(line.params)
202 if 'TX_ref' in line_params:
202 if 'TX_ref' in line_params:
203 if line_params['TX_ref'] in (0, '0'):
203 if line_params['TX_ref'] in (0, '0'):
204 line_params['TX_ref'] = '0'
204 line_params['TX_ref'] = '0'
205 else:
205 else:
206 ref_id = '{}'.format(line_params['TX_ref'])
206 ref_id = '{}'.format(line_params['TX_ref'])
207 ref_line = params['lines']['byId'][ref_id]
207 ref_line = params['lines']['byId'][ref_id]
208 line_params['TX_ref'] = RCLine.objects.get(
208 line_params['TX_ref'] = RCLine.objects.get(
209 rc_configuration=self,
209 rc_configuration=self,
210 params=json.dumps(ref_line['params'])
210 params=json.dumps(ref_line['params'])
211 ).pk
211 ).pk
212 line.params = json.dumps(line_params)
212 line.params = json.dumps(line_params)
213 line.save()
213 line.save()
214
214
215
215
216 def get_delays(self):
216 def get_delays(self):
217
217
218 pulses = [line.pulses_as_points() for line in self.get_lines()]
218 pulses = [line.pulses_as_points() for line in self.get_lines()]
219 points = [tup for tups in pulses for tup in tups]
219 points = [tup for tups in pulses for tup in tups]
220 points = set([x for tup in points for x in tup])
220 points = set([x for tup in points for x in tup])
221 points = list(points)
221 points = list(points)
222 points.sort()
222 points.sort()
223
223
224 if points[0]!=0:
224 if points[0]!=0:
225 points.insert(0, 0)
225 points.insert(0, 0)
226
226
227 return [points[i+1]-points[i] for i in range(len(points)-1)]
227 return [points[i+1]-points[i] for i in range(len(points)-1)]
228
228
229
229
230 def get_pulses(self, binary=True):
230 def get_pulses(self, binary=True):
231
231
232 pulses = [line.pulses_as_points() for line in self.get_lines()]
232 pulses = [line.pulses_as_points() for line in self.get_lines()]
233 tuples = [tup for tups in pulses for tup in tups]
233 tuples = [tup for tups in pulses for tup in tups]
234 points = set([x for tup in tuples for x in tup])
234 points = set([x for tup in tuples for x in tup])
235 points = list(points)
235 points = list(points)
236 points.sort()
236 points.sort()
237 states = []
237 states = []
238 last = [0 for x in pulses]
238 last = [0 for x in pulses]
239
239
240 for x in points:
240 for x in points:
241 dum = []
241 dum = []
242 for i, tups in enumerate(pulses):
242 for i, tups in enumerate(pulses):
243 ups = [tup[0] for tup in tups if tup!=(0,0)]
243 ups = [tup[0] for tup in tups if tup!=(0,0)]
244 dws = [tup[1] for tup in tups if tup!=(0,0)]
244 dws = [tup[1] for tup in tups if tup!=(0,0)]
245 if x in ups:
245 if x in ups:
246 dum.append(1)
246 dum.append(1)
247 elif x in dws:
247 elif x in dws:
248 dum.append(0)
248 dum.append(0)
249 else:
249 else:
250 dum.append(last[i])
250 dum.append(last[i])
251 states.append(dum)
251 states.append(dum)
252 last = dum
252 last = dum
253
253
254 if binary:
254 if binary:
255 ret = []
255 ret = []
256 for flips in states:
256 for flips in states:
257 flips.reverse()
257 flips.reverse()
258 ret.append(int(''.join([str(x) for x in flips]), 2))
258 ret.append(int(''.join([str(x) for x in flips]), 2))
259 states = ret
259 states = ret
260
260
261 return states[:-1]
261 return states[:-1]
262
262
263 def add_cmd(self, cmd):
263 def add_cmd(self, cmd):
264
264
265 if cmd in DAT_CMDS:
265 if cmd in DAT_CMDS:
266 return (255, DAT_CMDS[cmd])
266 return (255, DAT_CMDS[cmd])
267
267
268 def add_data(self, value):
268 def add_data(self, value):
269
269
270 return (254, value-1)
270 return (254, value-1)
271
271
272 def parms_to_binary(self, dat=True):
272 def parms_to_binary(self, dat=True):
273 '''
273 '''
274 Create "dat" stream to be send to CR
274 Create "dat" stream to be send to CR
275 '''
275 '''
276
276
277 data = bytearray()
277 data = bytearray()
278 # create header
278 # create header
279 data.extend(self.add_cmd('DISABLE'))
279 data.extend(self.add_cmd('DISABLE'))
280 data.extend(self.add_cmd('CONTINUE'))
280 data.extend(self.add_cmd('CONTINUE'))
281 data.extend(self.add_cmd('RESTART'))
281 data.extend(self.add_cmd('RESTART'))
282
282
283 if self.control_sw:
283 if self.control_sw:
284 data.extend(self.add_cmd('SW_ONE'))
284 data.extend(self.add_cmd('SW_ONE'))
285 else:
285 else:
286 data.extend(self.add_cmd('SW_ZERO'))
286 data.extend(self.add_cmd('SW_ZERO'))
287
287
288 if self.control_tx:
288 if self.control_tx:
289 data.extend(self.add_cmd('TX_ONE'))
289 data.extend(self.add_cmd('TX_ONE'))
290 else:
290 else:
291 data.extend(self.add_cmd('TX_ZERO'))
291 data.extend(self.add_cmd('TX_ZERO'))
292
292
293 # write divider
293 # write divider
294 data.extend(self.add_cmd('CLOCK_DIVIDER'))
294 data.extend(self.add_cmd('CLOCK_DIVIDER'))
295 data.extend(self.add_data(self.clock_divider))
295 data.extend(self.add_data(self.clock_divider))
296
296
297 # write delays
297 # write delays
298 data.extend(self.add_cmd('DELAY_START'))
298 data.extend(self.add_cmd('DELAY_START'))
299 # first delay is always zero
299 # first delay is always zero
300 data.extend(self.add_data(1))
300 data.extend(self.add_data(1))
301
301
302 delays = self.get_delays()
302 delays = self.get_delays()
303
303
304 for delay in delays:
304 for delay in delays:
305 while delay>252:
305 while delay>252:
306 data.extend(self.add_data(253))
306 data.extend(self.add_data(253))
307 delay -= 253
307 delay -= 253
308 data.extend(self.add_data(int(delay)))
308 data.extend(self.add_data(int(delay)))
309
309
310 # write flips
310 # write flips
311 data.extend(self.add_cmd('FLIP_START'))
311 data.extend(self.add_cmd('FLIP_START'))
312
312
313 states = self.get_pulses(binary=True)
313 states = self.get_pulses(binary=True)
314
314
315
315
316 last = 0
316 last = 0
317 for flip, delay in zip(states, delays):
317 for flip, delay in zip(states, delays):
318 data.extend(self.add_data((flip^last)+1))
318 data.extend(self.add_data((flip^last)+1))
319 last = flip
319 last = flip
320 while delay>252:
320 while delay>252:
321 data.extend(self.add_data(1))
321 data.extend(self.add_data(1))
322 delay -= 253
322 delay -= 253
323
323
324 # write sampling period
324 # write sampling period
325 data.extend(self.add_cmd('SAMPLING_PERIOD'))
325 data.extend(self.add_cmd('SAMPLING_PERIOD'))
326 wins = self.get_lines(line_type__name='windows')
326 wins = self.get_lines(line_type__name='windows')
327 if wins:
327 if wins:
328 win_params = json.loads(wins[0].params)['params']
328 win_params = json.loads(wins[0].params)['params']
329 if win_params:
329 if win_params:
330 dh = int(win_params[0]['resolution']*self.km2unit)
330 dh = int(win_params[0]['resolution']*self.km2unit)
331 else:
331 else:
332 dh = 1
332 dh = 1
333 else:
333 else:
334 dh = 1
334 dh = 1
335 data.extend(self.add_data(dh))
335 data.extend(self.add_data(dh))
336
336
337 # write enable
337 # write enable
338 data.extend(self.add_cmd('ENABLE'))
338 data.extend(self.add_cmd('ENABLE'))
339
339
340 if not dat:
340 if not dat:
341 return data
341 return data
342
342
343 return '\n'.join(['{}'.format(x) for x in data])
343 return '\n'.join(['{}'.format(x) for x in data])
344
344
345 def update_pulses(self):
345 def update_pulses(self):
346
346
347 for line in self.get_lines():
347 for line in self.get_lines():
348 line.update_pulses()
348 line.update_pulses()
349
349
350 def plot_pulses2(self, km=False):
350 def plot_pulses2(self, km=False):
351
351
352 import matplotlib
352 import matplotlib
353 matplotlib.use('Agg')
353 matplotlib.use('Agg')
354 import matplotlib.pyplot as plt
354 import matplotlib.pyplot as plt
355 from bokeh.resources import CDN
355 from bokeh.resources import CDN
356 from bokeh.embed import components
356 from bokeh.embed import components
357 from bokeh.mpl import to_bokeh
357 from bokeh.mpl import to_bokeh
358 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
358 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
359
359
360 lines = self.get_lines()
360 lines = self.get_lines()
361
361
362 N = len(lines)
362 N = len(lines)
363 npoints = self.total_units/self.km2unit if km else self.total_units
363 npoints = self.total_units/self.km2unit if km else self.total_units
364 fig = plt.figure(figsize=(12, 2+N*0.5))
364 fig = plt.figure(figsize=(12, 2+N*0.5))
365 ax = fig.add_subplot(111)
365 ax = fig.add_subplot(111)
366 labels = ['IPP']
366 labels = ['IPP']
367
367
368 for i, line in enumerate(lines):
368 for i, line in enumerate(lines):
369 labels.append(line.get_name(channel=True))
369 labels.append(line.get_name(channel=True))
370 l = ax.plot((0, npoints),(N-i-1, N-i-1))
370 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)]
371 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),
372 ax.broken_barh(points, (N-i-1, 0.5),
373 edgecolor=l[0].get_color(), facecolor='none')
373 edgecolor=l[0].get_color(), facecolor='none')
374
374
375 n = 0
375 n = 0
376 f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
376 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):
377 for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
378 if n%f==0:
378 if n%f==0:
379 ax.text(x, N, '%s' % n, size=10)
379 ax.text(x, N, '%s' % n, size=10)
380 n += 1
380 n += 1
381
381
382 labels.reverse()
382 labels.reverse()
383 ax.set_yticks(range(len(labels)))
383 ax.set_yticks(range(len(labels)))
384 ax.set_yticklabels(labels)
384 ax.set_yticklabels(labels)
385 ax.set_xlabel = 'Units'
385 ax.set_xlabel = 'Units'
386 plot = to_bokeh(fig, use_pandas=False)
386 plot = to_bokeh(fig, use_pandas=False)
387 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()]
387 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()]
388 plot.toolbar_location="above"
388 plot.toolbar_location="above"
389
389
390 return components(plot, CDN)
390 return components(plot, CDN)
391
391
392 def plot_pulses(self, km=False):
392 def plot_pulses(self, km=False):
393
393
394 from bokeh.plotting import figure
394 from bokeh.plotting import figure
395 from bokeh.resources import CDN
395 from bokeh.resources import CDN
396 from bokeh.embed import components
396 from bokeh.embed import components
397 from bokeh.models import FixedTicker, PrintfTickFormatter
397 from bokeh.models import FixedTicker, PrintfTickFormatter
398 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
398 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
399 from bokeh.models.sources import ColumnDataSource
399 from bokeh.models.sources import ColumnDataSource
400
400
401 lines = self.get_lines().reverse()
401 lines = self.get_lines().reverse()
402
402
403 N = len(lines)
403 N = len(lines)
404 npoints = self.total_units/self.km2unit if km else self.total_units
404 npoints = self.total_units/self.km2unit if km else self.total_units
405 ipp = self.ipp if km else self.ipp*self.km2unit
405 ipp = self.ipp if km else self.ipp*self.km2unit
406
406
407 hover = HoverTool(tooltips=[("Line", "@name"),
407 hover = HoverTool(tooltips=[("Line", "@name"),
408 ("IPP", "@ipp"),
408 ("IPP", "@ipp"),
409 ("X", "@left")])
409 ("X", "@left")])
410
410
411 tools = [PanTool(dimensions=['width']),
411 tools = [PanTool(dimensions=['width']),
412 WheelZoomTool(dimensions=['width']),
412 WheelZoomTool(dimensions=['width']),
413 hover, SaveTool()]
413 hover, SaveTool()]
414
414
415 plot = figure(width=1000,
415 plot = figure(width=1000,
416 height=40+N*50,
416 height=40+N*50,
417 y_range = (0, N),
417 y_range = (0, N),
418 tools=tools,
418 tools=tools,
419 toolbar_location='above',
419 toolbar_location='above',
420 toolbar_sticky=False,)
420 toolbar_sticky=False,)
421
421
422 plot.xaxis.axis_label = 'Km' if km else 'Units'
422 plot.xaxis.axis_label = 'Km' if km else 'Units'
423 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
423 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
424 plot.yaxis.axis_label = 'Pulses'
424 plot.yaxis.axis_label = 'Pulses'
425 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
425 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
426 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
426 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
427
427
428 for i, line in enumerate(lines):
428 for i, line in enumerate(lines):
429
429
430 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
430 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
431
431
432 source = ColumnDataSource(data = dict(
432 source = ColumnDataSource(data = dict(
433 bottom = [i for tup in points],
433 bottom = [i for tup in points],
434 top = [i+0.5 for tup in points],
434 top = [i+0.5 for tup in points],
435 left = [tup[0] for tup in points],
435 left = [tup[0] for tup in points],
436 right = [tup[1] for tup in points],
436 right = [tup[1] for tup in points],
437 ipp = [int(tup[0]/ipp) for tup in points],
437 ipp = [int(tup[0]/ipp) for tup in points],
438 name = [line.get_name() for tup in points]
438 name = [line.get_name() for tup in points]
439 ))
439 ))
440
440
441 plot.quad(
441 plot.quad(
442 bottom = 'bottom',
442 bottom = 'bottom',
443 top = 'top',
443 top = 'top',
444 left = 'left',
444 left = 'left',
445 right = 'right',
445 right = 'right',
446 source = source,
446 source = source,
447 fill_alpha = 0,
447 fill_alpha = 0,
448 #line_color = 'blue',
448 #line_color = 'blue',
449 )
449 )
450
450
451 plot.line([0, npoints], [i, i])#, color='blue')
451 plot.line([0, npoints], [i, i])#, color='blue')
452
452
453 return components(plot, CDN)
453 return components(plot, CDN)
454
454
455 def request(self, cmd, method='get', **kwargs):
455 def request(self, cmd, method='get', **kwargs):
456
456
457 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
457 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
458 payload = req.json()
458 payload = req.json()
459
459
460 return payload
460 return payload
461
461
462 def status_device(self):
462 def status_device(self):
463
463
464 try:
464 try:
465 self.device.status = 0
465 self.device.status = 0
466 payload = self.request('status')
466 payload = self.request('status')
467 if payload['status']=='enable':
467 if payload['status']=='enable':
468 self.device.status = 3
468 self.device.status = 3
469 elif payload['status']=='disable':
469 elif payload['status']=='disable':
470 self.device.status = 2
470 self.device.status = 2
471 else:
471 else:
472 self.device.status = 1
472 self.device.status = 1
473 self.device.save()
473 self.device.save()
474 self.message = 'RC status: {}'.format(payload['status'])
474 self.message = 'RC status: {}'.format(payload['status'])
475 return False
475 return False
476 except Exception as e:
476 except Exception as e:
477 if 'No route to host' not in str(e):
477 if 'No route to host' not in str(e):
478 self.device.status = 4
478 self.device.status = 4
479 self.device.save()
479 self.device.save()
480 self.message = 'RC status: {}'.format(str(e))
480 self.message = 'RC status: {}'.format(str(e))
481 return False
481 return False
482
482
483 self.device.save()
483 self.device.save()
484 return True
484 return True
485
485
486 def reset_device(self):
486 def reset_device(self):
487
487
488 try:
488 try:
489 payload = self.request('reset', 'post')
489 payload = self.request('reset', 'post')
490 if payload['reset']=='ok':
490 if payload['reset']=='ok':
491 self.message = 'RC restarted OK'
491 self.message = 'RC restarted OK'
492 self.device.status = 2
492 self.device.status = 2
493 self.device.save()
493 self.device.save()
494 else:
494 else:
495 self.message = 'RC restart fail'
495 self.message = 'RC restart fail'
496 self.device.status = 4
496 self.device.status = 4
497 self.device.save()
497 self.device.save()
498 except Exception as e:
498 except Exception as e:
499 self.message = 'RC reset: {}'.format(str(e))
499 self.message = 'RC reset: {}'.format(str(e))
500 return False
500 return False
501
501
502 return True
502 return True
503
503
504 def stop_device(self):
504 def stop_device(self):
505
505
506 try:
506 try:
507 payload = self.request('stop', 'post')
507 payload = self.request('stop', 'post')
508 self.message = 'RC stop: {}'.format(payload['stop'])
508 self.message = 'RC stop: {}'.format(payload['stop'])
509 if payload['stop']=='ok':
509 if payload['stop']=='ok':
510 self.device.status = 2
510 self.device.status = 2
511 self.device.save()
511 self.device.save()
512 else:
512 else:
513 self.device.status = 4
513 self.device.status = 4
514 self.device.save()
514 self.device.save()
515 return False
515 return False
516 except Exception as e:
516 except Exception as e:
517 if 'No route to host' not in str(e):
517 if 'No route to host' not in str(e):
518 self.device.status = 4
518 self.device.status = 4
519 else:
519 else:
520 self.device.status = 0
520 self.device.status = 0
521 self.message = 'RC stop: {}'.format(str(e))
521 self.message = 'RC stop: {}'.format(str(e))
522 self.device.save()
522 self.device.save()
523 return False
523 return False
524
524
525 return True
525 return True
526
526
527 def start_device(self):
527 def start_device(self):
528
528
529 try:
529 try:
530 payload = self.request('start', 'post')
530 payload = self.request('start', 'post')
531 self.message = 'RC start: {}'.format(payload['start'])
531 self.message = 'RC start: {}'.format(payload['start'])
532 if payload['start']=='ok':
532 if payload['start']=='ok':
533 self.device.status = 3
533 self.device.status = 3
534 self.device.save()
534 self.device.save()
535 else:
535 else:
536 return False
536 return False
537 except Exception as e:
537 except Exception as e:
538 if 'No route to host' not in str(e):
538 if 'No route to host' not in str(e):
539 self.device.status = 4
539 self.device.status = 4
540 else:
540 else:
541 self.device.status = 0
541 self.device.status = 0
542 self.message = 'RC start: {}'.format(str(e))
542 self.message = 'RC start: {}'.format(str(e))
543 self.device.save()
543 self.device.save()
544 return False
544 return False
545
545
546 return True
546 return True
547
547
548 def write_device(self, raw=False):
548 def write_device(self, raw=False):
549
549
550 if not raw:
551 clock = RCClock.objects.get(rc_configuration=self)
552 if clock.mode:
553 data = {'default': clock.frequency}
554 else:
555 data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
556 payload = self.request('setfreq', 'post', data=json.dumps(data))
557 if payload['command'] <> 'ok':
558 self.message = 'RC write: {}'.format(payload['command'])
559 else:
560 self.message = payload['programming']
561 if payload['programming'] == 'fail':
562 self.message = 'RC write: error programming CGS chip'
563
550 values = []
564 values = []
551 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
565 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
552 while delay>65536:
566 while delay>65536:
553 values.append((pulse, 65535))
567 values.append((pulse, 65535))
554 delay -= 65536
568 delay -= 65536
555 values.append((pulse, delay-1))
569 values.append((pulse, delay-1))
556 data = bytearray()
570 data = bytearray()
557 #reset
571 #reset
558 data.extend((128, 0))
572 data.extend((128, 0))
559 #disable
573 #disable
560 data.extend((129, 0))
574 data.extend((129, 0))
561 #SW switch
575 #SW switch
562 if self.control_sw:
576 if self.control_sw:
563 data.extend((130, 2))
577 data.extend((130, 2))
564 else:
578 else:
565 data.extend((130, 0))
579 data.extend((130, 0))
566 #divider
580 #divider
567 data.extend((131, self.clock_divider-1))
581 data.extend((131, self.clock_divider-1))
568 #enable writing
582 #enable writing
569 data.extend((139, 62))
583 data.extend((139, 62))
570
584
571 last = 0
585 last = 0
572 for tup in values:
586 for tup in values:
573 vals = pack('<HH', last^tup[0], tup[1])
587 vals = pack('<HH', last^tup[0], tup[1])
574 last = tup[0]
588 last = tup[0]
575 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
589 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
576
590
577 #enable
591 #enable
578 data.extend((129, 1))
592 data.extend((129, 1))
579
593
580 if raw:
594 if raw:
581 return b64encode(data)
595 return b64encode(data)
582
596
583 try:
597 try:
584 payload = self.request('stop', 'post')
598 payload = self.request('stop', 'post')
585 payload = self.request('reset', 'post')
599 payload = self.request('reset', 'post')
586 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
600 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
587 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
601 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
588 n = len(data)
602 n = len(data)
589 x = 0
603 x = 0
590 #while x < n:
604 #while x < n:
591 payload = self.request('write', 'post', data=b64encode(data))
605 payload = self.request('write', 'post', data=b64encode(data))
592 # x += 1024
606 # x += 1024
593
607
594 if payload['write']=='ok':
608 if payload['write']=='ok':
595 self.device.status = 3
609 self.device.status = 3
596 self.device.save()
610 self.device.save()
597 self.message = 'RC configured and started'
611 self.message = 'RC configured and started'
598 else:
612 else:
599 self.device.status = 1
613 self.device.status = 1
600 self.device.save()
614 self.device.save()
601 self.message = 'RC write: {}'.format(payload['write'])
615 self.message = 'RC write: {}'.format(payload['write'])
602 return False
616 return False
603
617
604 #payload = self.request('start', 'post')
618 #payload = self.request('start', 'post')
605
619
606 except Exception as e:
620 except Exception as e:
607 if 'No route to host' not in str(e):
621 if 'No route to host' not in str(e):
608 self.device.status = 4
622 self.device.status = 4
609 else:
623 else:
610 self.device.status = 0
624 self.device.status = 0
611 self.message = 'RC write: {}'.format(str(e))
625 self.message = 'RC write: {}'.format(str(e))
612 self.device.save()
626 self.device.save()
613 return False
627 return False
614
628
615 return True
629 return True
616
630
617
631
618 def get_absolute_url_import(self):
632 def get_absolute_url_import(self):
619 return reverse('url_import_rc_conf', args=[str(self.id)])
633 return reverse('url_import_rc_conf', args=[str(self.id)])
620
634
621
635
622 class RCLineCode(models.Model):
636 class RCLineCode(models.Model):
623
637
624 name = models.CharField(max_length=40)
638 name = models.CharField(max_length=40)
625 bits_per_code = models.PositiveIntegerField(default=0)
639 bits_per_code = models.PositiveIntegerField(default=0)
626 number_of_codes = models.PositiveIntegerField(default=0)
640 number_of_codes = models.PositiveIntegerField(default=0)
627 codes = models.TextField(blank=True, null=True)
641 codes = models.TextField(blank=True, null=True)
628
642
629 class Meta:
643 class Meta:
630 db_table = 'rc_line_codes'
644 db_table = 'rc_line_codes'
631 ordering = ('name',)
645 ordering = ('name',)
632
646
633 def __str__(self):
647 def __str__(self):
634 return u'%s' % self.name
648 return u'%s' % self.name
635
649
636
650
637 class RCLineType(models.Model):
651 class RCLineType(models.Model):
638
652
639 name = models.CharField(choices=LINE_TYPES, max_length=40)
653 name = models.CharField(choices=LINE_TYPES, max_length=40)
640 description = models.TextField(blank=True, null=True)
654 description = models.TextField(blank=True, null=True)
641 params = models.TextField(default='[]')
655 params = models.TextField(default='[]')
642
656
643 class Meta:
657 class Meta:
644 db_table = 'rc_line_types'
658 db_table = 'rc_line_types'
645
659
646 def __str__(self):
660 def __str__(self):
647 return u'%s - %s' % (self.name.upper(), self.get_name_display())
661 return u'%s - %s' % (self.name.upper(), self.get_name_display())
648
662
649
663
650 class RCLine(models.Model):
664 class RCLine(models.Model):
651
665
652 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
666 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
653 line_type = models.ForeignKey(RCLineType)
667 line_type = models.ForeignKey(RCLineType)
654 channel = models.PositiveIntegerField(default=0)
668 channel = models.PositiveIntegerField(default=0)
655 position = models.PositiveIntegerField(default=0)
669 position = models.PositiveIntegerField(default=0)
656 params = models.TextField(default='{}')
670 params = models.TextField(default='{}')
657 pulses = models.TextField(default='')
671 pulses = models.TextField(default='')
658
672
659 class Meta:
673 class Meta:
660 db_table = 'rc_lines'
674 db_table = 'rc_lines'
661 ordering = ['channel']
675 ordering = ['channel']
662
676
663 def __str__(self):
677 def __str__(self):
664 if self.rc_configuration:
678 if self.rc_configuration:
665 return u'{}|{} - {}'.format(self.pk, self.get_name(), self.rc_configuration.name)
679 return u'{}|{} - {}'.format(self.pk, self.get_name(), self.rc_configuration.name)
666
680
667 def jsonify(self):
681 def jsonify(self):
668
682
669 data = {}
683 data = {}
670 data['params'] = json.loads(self.params)
684 data['params'] = json.loads(self.params)
671 data['id'] = '{}'.format(self.pk)
685 data['id'] = '{}'.format(self.pk)
672 data['line_type'] = self.line_type.name
686 data['line_type'] = self.line_type.name
673 data['name'] = self.get_name()
687 data['name'] = self.get_name()
674 if data['line_type']=='codes':
688 if data['line_type']=='codes':
675 data['params']['code'] = RCLineCode.objects.get(pk=data['params']['code']).name
689 data['params']['code'] = RCLineCode.objects.get(pk=data['params']['code']).name
676
690
677 return data
691 return data
678
692
679
693
680 def clone(self, **kwargs):
694 def clone(self, **kwargs):
681
695
682 self.pk = None
696 self.pk = None
683 self.id = None
697 self.id = None
684
698
685 for attr, value in kwargs.items():
699 for attr, value in kwargs.items():
686 setattr(self, attr, value)
700 setattr(self, attr, value)
687
701
688 self.save()
702 self.save()
689
703
690 return self
704 return self
691
705
692 def get_name(self, channel=False):
706 def get_name(self, channel=False):
693
707
694 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
708 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
695 s = ''
709 s = ''
696
710
697 if self.line_type.name in ('tx',):
711 if self.line_type.name in ('tx',):
698 s = chars[self.position]
712 s = chars[self.position]
699 elif self.line_type.name in ('codes', 'windows', 'tr'):
713 elif self.line_type.name in ('codes', 'windows', 'tr'):
700 if 'TX_ref' in json.loads(self.params):
714 if 'TX_ref' in json.loads(self.params):
701 pk = json.loads(self.params)['TX_ref']
715 pk = json.loads(self.params)['TX_ref']
702 if pk in (0, '0'):
716 if pk in (0, '0'):
703 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
717 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
704 else:
718 else:
705 ref = RCLine.objects.get(pk=pk)
719 ref = RCLine.objects.get(pk=pk)
706 s = chars[ref.position]
720 s = chars[ref.position]
707 s = '({})'.format(s)
721 s = '({})'.format(s)
708
722
709 s = '{}{}'.format(self.line_type.name.upper(), s)
723 s = '{}{}'.format(self.line_type.name.upper(), s)
710
724
711 if channel:
725 if channel:
712 return '{} {}'.format(s, self.channel)
726 return '{} {}'.format(s, self.channel)
713 else:
727 else:
714 return s
728 return s
715
729
716 def get_lines(self, **kwargs):
730 def get_lines(self, **kwargs):
717
731
718 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
732 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
719
733
720 def pulses_as_array(self):
734 def pulses_as_array(self):
721
735
722 y = np.zeros(self.rc_configuration.total_units)
736 y = np.zeros(self.rc_configuration.total_units)
723
737
724 for tup in ast.literal_eval(self.pulses):
738 for tup in ast.literal_eval(self.pulses):
725 y[tup[0]:tup[1]] = 1
739 y[tup[0]:tup[1]] = 1
726
740
727 return y.astype(np.int8)
741 return y.astype(np.int8)
728
742
729 def pulses_as_points(self, km=False):
743 def pulses_as_points(self, km=False):
730
744
731 if km:
745 if km:
732 unit2km = 1/self.rc_configuration.km2unit
746 unit2km = 1/self.rc_configuration.km2unit
733 return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
747 return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
734 else:
748 else:
735 return ast.literal_eval(self.pulses)
749 return ast.literal_eval(self.pulses)
736
750
737 def get_win_ref(self, params, tx_id, km2unit):
751 def get_win_ref(self, params, tx_id, km2unit):
738
752
739 ref = self.rc_configuration.sampling_reference
753 ref = self.rc_configuration.sampling_reference
740 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
754 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
741
755
742 if codes:
756 if codes:
743 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
757 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
744 else:
758 else:
745 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
759 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
746
760
747 if ref=='first_baud':
761 if ref=='first_baud':
748 return int(1 + round((tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit))
762 return int(1 + round((tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit))
749 elif ref=='sub_baud':
763 elif ref=='sub_baud':
750 return np.ceil(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
764 return np.ceil(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
751 else:
765 else:
752 return 0
766 return 0
753
767
754 def update_pulses(self):
768 def update_pulses(self):
755 '''
769 '''
756 Update pulses field
770 Update pulses field
757 '''
771 '''
758
772
759 km2unit = self.rc_configuration.km2unit
773 km2unit = self.rc_configuration.km2unit
760 us2unit = self.rc_configuration.us2unit
774 us2unit = self.rc_configuration.us2unit
761 ipp = self.rc_configuration.ipp
775 ipp = self.rc_configuration.ipp
762 ntx = int(self.rc_configuration.ntx)
776 ntx = int(self.rc_configuration.ntx)
763 ipp_u = int(ipp*km2unit)
777 ipp_u = int(ipp*km2unit)
764 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
778 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
765 y = []
779 y = []
766
780
767 if self.line_type.name=='tr':
781 if self.line_type.name=='tr':
768 tr_params = json.loads(self.params)
782 tr_params = json.loads(self.params)
769
783
770 if tr_params['TX_ref'] in ('0', 0):
784 if tr_params['TX_ref'] in ('0', 0):
771 txs = self.get_lines(line_type__name='tx')
785 txs = self.get_lines(line_type__name='tx')
772 else:
786 else:
773 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
787 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
774
788
775 for tx in txs:
789 for tx in txs:
776 params = json.loads(tx.params)
790 params = json.loads(tx.params)
777
791
778 if float(params['pulse_width'])==0:
792 if float(params['pulse_width'])==0:
779 continue
793 continue
780 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
794 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
781 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
795 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
782 before = 0
796 before = 0
783 after = int(self.rc_configuration.time_after*us2unit)
797 after = int(self.rc_configuration.time_after*us2unit)
784
798
785 y_tx = self.points(ntx, ipp_u, width,
799 y_tx = self.points(ntx, ipp_u, width,
786 delay=delays,
800 delay=delays,
787 before=before,
801 before=before,
788 after=after,
802 after=after,
789 sync=self.rc_configuration.sync)
803 sync=self.rc_configuration.sync)
790
804
791 ranges = params['range'].split(',')
805 ranges = params['range'].split(',')
792
806
793 if len(ranges)>0 and ranges[0]!='0':
807 if len(ranges)>0 and ranges[0]!='0':
794 y_tx = self.mask_ranges(y_tx, ranges)
808 y_tx = self.mask_ranges(y_tx, ranges)
795
809
796 tr_ranges = tr_params['range'].split(',')
810 tr_ranges = tr_params['range'].split(',')
797
811
798 if len(tr_ranges)>0 and tr_ranges[0]!='0':
812 if len(tr_ranges)>0 and tr_ranges[0]!='0':
799 y_tx = self.mask_ranges(y_tx, tr_ranges)
813 y_tx = self.mask_ranges(y_tx, tr_ranges)
800
814
801 y.extend(y_tx)
815 y.extend(y_tx)
802
816
803 self.pulses = str(y)
817 self.pulses = str(y)
804 y = self.array_to_points(self.pulses_as_array())
818 y = self.array_to_points(self.pulses_as_array())
805
819
806 elif self.line_type.name=='tx':
820 elif self.line_type.name=='tx':
807 params = json.loads(self.params)
821 params = json.loads(self.params)
808 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
822 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
809 width = float(params['pulse_width'])*km2unit
823 width = float(params['pulse_width'])*km2unit
810
824
811 if width>0:
825 if width>0:
812 before = int(self.rc_configuration.time_before*us2unit)
826 before = int(self.rc_configuration.time_before*us2unit)
813 after = 0
827 after = 0
814
828
815 y = self.points(ntx, ipp_u, width,
829 y = self.points(ntx, ipp_u, width,
816 delay=delays,
830 delay=delays,
817 before=before,
831 before=before,
818 after=after,
832 after=after,
819 sync=self.rc_configuration.sync)
833 sync=self.rc_configuration.sync)
820
834
821 ranges = params['range'].split(',')
835 ranges = params['range'].split(',')
822
836
823 if len(ranges)>0 and ranges[0]!='0':
837 if len(ranges)>0 and ranges[0]!='0':
824 y = self.mask_ranges(y, ranges)
838 y = self.mask_ranges(y, ranges)
825
839
826 elif self.line_type.name=='flip':
840 elif self.line_type.name=='flip':
827 n = float(json.loads(self.params)['number_of_flips'])
841 n = float(json.loads(self.params)['number_of_flips'])
828 width = n*ipp*km2unit
842 width = n*ipp*km2unit
829 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
843 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
830
844
831 elif self.line_type.name=='codes':
845 elif self.line_type.name=='codes':
832 params = json.loads(self.params)
846 params = json.loads(self.params)
833 tx = RCLine.objects.get(pk=params['TX_ref'])
847 tx = RCLine.objects.get(pk=params['TX_ref'])
834 tx_params = json.loads(tx.params)
848 tx_params = json.loads(tx.params)
835 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
849 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
836 f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
850 f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
837 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
851 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
838 codes = [self.array_to_points(code) for code in codes]
852 codes = [self.array_to_points(code) for code in codes]
839 n = len(codes)
853 n = len(codes)
840
854
841 ranges = tx_params['range'].split(',')
855 ranges = tx_params['range'].split(',')
842 if len(ranges)>0 and ranges[0]!='0':
856 if len(ranges)>0 and ranges[0]!='0':
843 dum = self.mask_ranges(tx.pulses_as_points(), ranges)
857 dum = self.mask_ranges(tx.pulses_as_points(), ranges)
844 else:
858 else:
845 dum = tx.pulses_as_points()
859 dum = tx.pulses_as_points()
846
860
847 for i, tup in enumerate(dum):
861 for i, tup in enumerate(dum):
848 if tup==(0,0): continue
862 if tup==(0,0): continue
849 code = codes[i%n]
863 code = codes[i%n]
850 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
864 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
851
865
852 elif self.line_type.name=='sync':
866 elif self.line_type.name=='sync':
853 params = json.loads(self.params)
867 params = json.loads(self.params)
854 n = ipp_u*ntx
868 n = ipp_u*ntx
855 if params['invert'] in ('1', 1):
869 if params['invert'] in ('1', 1):
856 y = [(n-1, n)]
870 y = [(n-1, n)]
857 else:
871 else:
858 y = [(0, 1)]
872 y = [(0, 1)]
859
873
860 elif self.line_type.name=='prog_pulses':
874 elif self.line_type.name=='prog_pulses':
861 params = json.loads(self.params)
875 params = json.loads(self.params)
862 if int(params['periodic'])==0:
876 if int(params['periodic'])==0:
863 nntx = 1
877 nntx = 1
864 nipp = ipp_u*ntx
878 nipp = ipp_u*ntx
865 else:
879 else:
866 nntx = ntx
880 nntx = ntx
867 nipp = ipp_u
881 nipp = ipp_u
868
882
869 if 'params' in params and len(params['params'])>0:
883 if 'params' in params and len(params['params'])>0:
870 for p in params['params']:
884 for p in params['params']:
871 y_pp = self.points(nntx, nipp,
885 y_pp = self.points(nntx, nipp,
872 p['end']-p['begin'],
886 p['end']-p['begin'],
873 before=p['begin'])
887 before=p['begin'])
874
888
875 y.extend(y_pp)
889 y.extend(y_pp)
876
890
877 elif self.line_type.name=='windows':
891 elif self.line_type.name=='windows':
878 params = json.loads(self.params)
892 params = json.loads(self.params)
879 if 'params' in params and len(params['params'])>0:
893 if 'params' in params and len(params['params'])>0:
880 tx = RCLine.objects.get(pk=params['TX_ref'])
894 tx = RCLine.objects.get(pk=params['TX_ref'])
881 tx_params = json.loads(tx.params)
895 tx_params = json.loads(tx.params)
882 ranges = tx_params['range'].split(',')
896 ranges = tx_params['range'].split(',')
883 for p in params['params']:
897 for p in params['params']:
884 y_win = self.points(ntx, ipp_u,
898 y_win = self.points(ntx, ipp_u,
885 p['resolution']*p['number_of_samples']*km2unit,
899 p['resolution']*p['number_of_samples']*km2unit,
886 before=int(self.rc_configuration.time_before*us2unit)+p['first_height']*km2unit,
900 before=int(self.rc_configuration.time_before*us2unit)+p['first_height']*km2unit,
887 sync=self.rc_configuration.sync+self.get_win_ref(p, params['TX_ref'], km2unit))
901 sync=self.rc_configuration.sync+self.get_win_ref(p, params['TX_ref'], km2unit))
888
902
889
903
890 if len(ranges)>0 and ranges[0]!='0':
904 if len(ranges)>0 and ranges[0]!='0':
891 y_win = self.mask_ranges(y_win, ranges)
905 y_win = self.mask_ranges(y_win, ranges)
892
906
893 y.extend(y_win)
907 y.extend(y_win)
894
908
895 elif self.line_type.name=='mix':
909 elif self.line_type.name=='mix':
896 values = self.rc_configuration.parameters.split('-')
910 values = self.rc_configuration.parameters.split('-')
897 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
911 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
898 modes = [value.split('|')[1] for value in values]
912 modes = [value.split('|')[1] for value in values]
899 ops = [value.split('|')[2] for value in values]
913 ops = [value.split('|')[2] for value in values]
900 delays = [value.split('|')[3] for value in values]
914 delays = [value.split('|')[3] for value in values]
901 masks = [value.split('|')[4] for value in values]
915 masks = [value.split('|')[4] for value in values]
902 mask = list('{:8b}'.format(int(masks[0])))
916 mask = list('{:8b}'.format(int(masks[0])))
903 mask.reverse()
917 mask.reverse()
904 if mask[self.channel] in ('0', '', ' '):
918 if mask[self.channel] in ('0', '', ' '):
905 y = np.zeros(confs[0].total_units, dtype=np.int8)
919 y = np.zeros(confs[0].total_units, dtype=np.int8)
906 else:
920 else:
907 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
921 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
908
922
909 for i in range(1, len(values)):
923 for i in range(1, len(values)):
910 mask = list('{:8b}'.format(int(masks[i])))
924 mask = list('{:8b}'.format(int(masks[i])))
911 mask.reverse()
925 mask.reverse()
912
926
913 if mask[self.channel] in ('0', '', ' '):
927 if mask[self.channel] in ('0', '', ' '):
914 continue
928 continue
915 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
929 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
916 delay = float(delays[i])*km2unit
930 delay = float(delays[i])*km2unit
917
931
918 if modes[i]=='P':
932 if modes[i]=='P':
919 if delay>0:
933 if delay>0:
920 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
934 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
921 y_temp = np.empty_like(Y)
935 y_temp = np.empty_like(Y)
922 y_temp[:delay] = 0
936 y_temp[:delay] = 0
923 y_temp[delay:] = Y[:-delay]
937 y_temp[delay:] = Y[:-delay]
924 elif delay+len(Y)>len(y):
938 elif delay+len(Y)>len(y):
925 y_new = np.zeros(delay+len(Y), dtype=np.int8)
939 y_new = np.zeros(delay+len(Y), dtype=np.int8)
926 y_new[:len(y)] = y
940 y_new[:len(y)] = y
927 y = y_new
941 y = y_new
928 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
942 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
929 y_temp[-len(Y):] = Y
943 y_temp[-len(Y):] = Y
930 elif delay+len(Y)==len(y):
944 elif delay+len(Y)==len(y):
931 y_temp = np.zeros(delay+len(Y))
945 y_temp = np.zeros(delay+len(Y))
932 y_temp[-len(Y):] = Y
946 y_temp[-len(Y):] = Y
933 elif delay+len(Y)<len(y):
947 elif delay+len(Y)<len(y):
934 y_temp = np.zeros(len(y), dtype=np.int8)
948 y_temp = np.zeros(len(y), dtype=np.int8)
935 y_temp[delay:delay+len(Y)] = Y
949 y_temp[delay:delay+len(Y)] = Y
936 else:
950 else:
937 y_temp = Y.copy()
951 y_temp = Y.copy()
938
952
939 if ops[i]=='OR':
953 if ops[i]=='OR':
940 y = y | y_temp
954 y = y | y_temp
941 elif ops[i]=='XOR':
955 elif ops[i]=='XOR':
942 y = y ^ y_temp
956 y = y ^ y_temp
943 elif ops[i]=='AND':
957 elif ops[i]=='AND':
944 y = y & y_temp
958 y = y & y_temp
945 elif ops[i]=='NAND':
959 elif ops[i]=='NAND':
946 y = y & ~y_temp
960 y = y & ~y_temp
947 else:
961 else:
948 y = np.concatenate([y, Y])
962 y = np.concatenate([y, Y])
949
963
950 total = len(y)
964 total = len(y)
951 y = self.array_to_points(y)
965 y = self.array_to_points(y)
952
966
953 else:
967 else:
954 y = []
968 y = []
955
969
956 if self.rc_configuration.total_units != total:
970 if self.rc_configuration.total_units != total:
957 self.rc_configuration.total_units = total
971 self.rc_configuration.total_units = total
958 self.rc_configuration.save()
972 self.rc_configuration.save()
959
973
960 self.pulses = str(y)
974 self.pulses = str(y)
961 self.save()
975 self.save()
962
976
963 @staticmethod
977 @staticmethod
964 def array_to_points(X):
978 def array_to_points(X):
965
979
966 if X.size==0:
980 if X.size==0:
967 return []
981 return []
968
982
969 d = X[1:]-X[:-1]
983 d = X[1:]-X[:-1]
970
984
971 up = np.where(d==1)[0]
985 up = np.where(d==1)[0]
972 if X[0]==1:
986 if X[0]==1:
973 up = np.concatenate((np.array([-1]), up))
987 up = np.concatenate((np.array([-1]), up))
974 up += 1
988 up += 1
975
989
976 dw = np.where(d==-1)[0]
990 dw = np.where(d==-1)[0]
977 if X[-1]==1:
991 if X[-1]==1:
978 dw = np.concatenate((dw, np.array([len(X)-1])))
992 dw = np.concatenate((dw, np.array([len(X)-1])))
979 dw += 1
993 dw += 1
980
994
981 return [(tup[0], tup[1]) for tup in zip(up, dw)]
995 return [(tup[0], tup[1]) for tup in zip(up, dw)]
982
996
983 @staticmethod
997 @staticmethod
984 def mask_ranges(Y, ranges):
998 def mask_ranges(Y, ranges):
985
999
986 y = [(0, 0) for __ in Y]
1000 y = [(0, 0) for __ in Y]
987
1001
988 for index in ranges:
1002 for index in ranges:
989 if '-' in index:
1003 if '-' in index:
990 args = [int(a) for a in index.split('-')]
1004 args = [int(a) for a in index.split('-')]
991 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
1005 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
992 else:
1006 else:
993 y[int(index)-1] = Y[int(index)-1]
1007 y[int(index)-1] = Y[int(index)-1]
994
1008
995 return y
1009 return y
996
1010
997 @staticmethod
1011 @staticmethod
998 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
1012 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
999
1013
1000 delays = len(delay)
1014 delays = len(delay)
1001
1015
1002 Y = [(int(ipp*x+before+delay[x%delays]+sync), int(ipp*x+width+before+delay[x%delays]+after+sync)) for x in range(ntx)]
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)]
1003
1017
1004 return Y
1018 return Y
1019
1020 class RCClock(models.Model):
1021
1022 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
1023 mode = models.BooleanField(default=True, choices=((True, 'Auto'), (False, 'Manual')))
1024 multiplier = models.PositiveIntegerField(default=60)
1025 divisor = models.PositiveIntegerField(default=10)
1026 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
@@ -1,120 +1,161
1 var km_fields = [];
1 var km_fields = [];
2 var unit_fields = [];
2 var unit_fields = [];
3 var dc_fields = [];
3 var dc_fields = [];
4
4
5
5
6 function str2hz(s){
6 function str2hz(s){
7
7
8 return 150000*Math.pow(parseFloat(s), -1);
8 return 150000*Math.pow(parseFloat(s), -1);
9 }
9 }
10
10
11
11
12 function str2unit(s){
12 function str2unit(s){
13 var km2unit = (20/3)*(parseFloat($('#id_clock_in').val())/parseFloat($('#id_clock_divider').val()));
13 var km2unit = (20/3)*(parseFloat($('#id_clock_in').val())/parseFloat($('#id_clock_divider').val()));
14 var ret = "";
14 var ret = "";
15 values = s.split(",");
15 values = s.split(",");
16 for (i=0; i<values.length; i++) {
16 for (i=0; i<values.length; i++) {
17 ret += Math.round(parseFloat(values[i])*km2unit);
17 ret += Math.round(parseFloat(values[i])*km2unit);
18 ret += ",";
18 ret += ",";
19 }
19 }
20 return ret.substring(0, ret.length-1);
20 return ret.substring(0, ret.length-1);
21 }
21 }
22
22
23
23
24 function str2int(s){
24 function str2int(s){
25 var ret = "";
25 var ret = "";
26 values = s.split(",");
26 values = s.split(",");
27 for (i=0; i<values.length; i++) {
27 for (i=0; i<values.length; i++) {
28 ret += Math.round(parseFloat(values[i]));
28 ret += Math.round(parseFloat(values[i]));
29 ret += ",";
29 ret += ",";
30 }
30 }
31 return ret.substring(0, ret.length-1);
31 return ret.substring(0, ret.length-1);
32 }
32 }
33
33
34
34
35 function str2km(s){
35 function str2km(s){
36 var km2unit = (20/3)*(parseFloat($('#id_clock_in').val())/parseFloat($('#id_clock_divider').val()));
36 var km2unit = (20/3)*(parseFloat($('#id_clock_in').val())/parseFloat($('#id_clock_divider').val()));
37 var ret = "";
37 var ret = "";
38 values = s.split(",");
38 values = s.split(",");
39 for (i=0; i<values.length; i++) {
39 for (i=0; i<values.length; i++) {
40 ret += parseFloat(values[i])/km2unit;
40 ret += parseFloat(values[i])/km2unit;
41 ret += ",";
41 ret += ",";
42 }
42 }
43 return ret.substring(0, ret.length-1);
43 return ret.substring(0, ret.length-1);
44 }
44 }
45
45
46 function str2dc(s){
46 function str2dc(s){
47
47
48 return parseFloat(s)*100/parseFloat($('#id_ipp').val())
48 return parseFloat(s)*100/parseFloat($('#id_ipp').val())
49 }
49 }
50
50
51
51
52 function updateUnits() {
52 function updateUnits() {
53
53
54 for (j=0; j<km_fields.length; j++){
54 for (j=0; j<km_fields.length; j++){
55 label_unit = "#"+km_fields[j]+"_unit";
55 label_unit = "#"+km_fields[j]+"_unit";
56 label = "#"+km_fields[j];
56 label = "#"+km_fields[j];
57 $(label_unit).val(str2unit($(label).val()));
57 $(label_unit).val(str2unit($(label).val()));
58 }
58 }
59 }
59 }
60
60
61
61
62 function updateDc() {
62 function updateDc() {
63
63
64 for (j=0; j<dc_fields.length; j++){
64 for (j=0; j<dc_fields.length; j++){
65 label_dc = "#"+dc_fields[j]+"_dc";
65 label_dc = "#"+dc_fields[j]+"_dc";
66 label = "#"+dc_fields[j];
66 label = "#"+dc_fields[j];
67 $(label_dc).val(str2dc($(label).val()));
67 $(label_dc).val(str2dc($(label).val()));
68 }
68 }
69 }
69 }
70
70
71
71
72 function updateWindows(label) {
72 function updateWindows(label) {
73
73
74 if (label.indexOf("first_height")>0){
74 if (label.indexOf("first_height")>0){
75 llabel = label.replace("first_height", "last_height");
75 llabel = label.replace("first_height", "last_height");
76 rlabel = label.replace("first_height", "resolution");
76 rlabel = label.replace("first_height", "resolution");
77 nlabel = label.replace("first_height", "number_of_samples");
77 nlabel = label.replace("first_height", "number_of_samples");
78 value = parseFloat($(label).val())+parseFloat($(rlabel).val())*(parseInt($(nlabel).val())-1);
78 value = parseFloat($(label).val())+parseFloat($(rlabel).val())*(parseInt($(nlabel).val())-1);
79 $(llabel).val(value);
79 $(llabel).val(value);
80 }
80 }
81
81
82 if (label.indexOf("resolution")>0){
82 if (label.indexOf("resolution")>0){
83 llabel = label.replace("resolution", "last_height");
83 llabel = label.replace("resolution", "last_height");
84 flabel = label.replace("resolution", "first_height");
84 flabel = label.replace("resolution", "first_height");
85 nlabel = label.replace("resolution", "number_of_samples");
85 nlabel = label.replace("resolution", "number_of_samples");
86 value = parseFloat($(flabel).val())+parseFloat($(label).val())*(parseInt($(nlabel).val())-1);
86 value = parseFloat($(flabel).val())+parseFloat($(label).val())*(parseInt($(nlabel).val())-1);
87 $(llabel).val(value);
87 $(llabel).val(value);
88 }
88 }
89
89
90 if (label.indexOf("number_of_samples")>0){
90 if (label.indexOf("number_of_samples")>0){
91 llabel = label.replace("number_of_samples", "last_height");
91 llabel = label.replace("number_of_samples", "last_height");
92 rlabel = label.replace("number_of_samples", "resolution");
92 rlabel = label.replace("number_of_samples", "resolution");
93 flabel = label.replace("number_of_samples", "first_height");
93 flabel = label.replace("number_of_samples", "first_height");
94 value = parseFloat($(flabel).val())+parseFloat($(rlabel).val())*(parseInt($(label).val())-1);
94 value = parseFloat($(flabel).val())+parseFloat($(rlabel).val())*(parseInt($(label).val())-1);
95 $(llabel).val(value);
95 $(llabel).val(value);
96 }
96 }
97
97
98 if (label.indexOf("last_height")>0){
98 if (label.indexOf("last_height")>0){
99 flabel = label.replace("last_height", "first_height");
99 flabel = label.replace("last_height", "first_height");
100 rlabel = label.replace("last_height", "resolution");
100 rlabel = label.replace("last_height", "resolution");
101 nlabel = label.replace("last_height", "number_of_samples");
101 nlabel = label.replace("last_height", "number_of_samples");
102
102
103 nvalue = Math.round((parseFloat($(label).val())-parseFloat($(flabel).val()))/parseFloat($(rlabel).val()))+1;
103 nvalue = Math.round((parseFloat($(label).val())-parseFloat($(flabel).val()))/parseFloat($(rlabel).val()))+1;
104 $(nlabel).val(nvalue);
104 $(nlabel).val(nvalue);
105 value = parseFloat($(flabel).val())+parseFloat($(rlabel).val())*(nvalue-1);
105 value = parseFloat($(flabel).val())+parseFloat($(rlabel).val())*(nvalue-1);
106 $(label).val(value);
106 $(label).val(value);
107 }
107 }
108
108
109 }
109 }
110
110
111 $("#id_clock_in").change(function() {
111 function updateClock() {
112 $("#id_clock").val(parseFloat($('#id_clock_in').val())/parseFloat($('#id_clock_divider').val()));
112 if ($("#id_reference").val()==0){
113 var ref = 25;
114 }else{
115 var ref = 10;
116 }
117 $("#id_frequency").val(parseFloat($('#id_multiplier').val())*ref/parseFloat($('#id_divisor').val()));
118 $("#id_clock").val(parseFloat($('#id_frequency').val())/parseFloat($('#id_clock_divider').val()));
119 updateUnits();
120 }
121
122
123 $("#id_frequency").change(function() {
124 $("#id_clock").val(parseFloat($('#id_frequency').val())/parseFloat($('#id_clock_divider').val()));
113 updateUnits();
125 updateUnits();
114 });
126 });
115
127
116 $("#id_clock_divider").change(function() {
128 $("#id_clock_divider").change(function() {
117 $("#id_clock").val(parseFloat($('#id_clock_in').val())/parseFloat($('#id_clock_divider').val()));
129 $("#id_clock").val(parseFloat($('#id_frequency').val())/parseFloat($('#id_clock_divider').val()));
118 updateUnits();
130 updateUnits();
119 });
131 });
120
132
133 $("#id_mode").change(function() {
134 if ($("#id_mode").val()=="False"){
135 $('#id_multiplier').removeProp("readonly");
136 $('#id_divisor').removeProp("readonly");
137 $('#id_reference').removeProp("readonly");
138 $('#id_frequency').prop("readonly", true);
139 updateClock();
140 }else{
141 $('#id_frequency').removeProp("readonly");
142 $('#id_multiplier').prop("readonly", true);
143 $('#id_divisor').prop("readonly", true);
144 $('#id_reference').prop("readonly", true);
145 $('#id_reference').val(1)
146 $('#id_frequency').val(60);
147 $("#id_clock").val(parseFloat($('#id_frequency').val())/parseFloat($('#id_clock_divider').val()));
148 }
149 });
150
151 $("#id_multiplier").change(function() {
152 updateClock();
153 });
154
155 $("#id_divisor").change(function() {
156 updateClock();
157 });
158
159 $("#id_reference").change(function() {
160 updateClock();
161 }); No newline at end of file
@@ -1,27 +1,61
1 {% extends "dev_conf.html" %}
1 {% extends "dev_conf.html" %}
2 {% load static %}
2 {% load static %}
3 {% load bootstrap3 %}
3 {% load bootstrap3 %}
4 {% load main_tags %}
4 {% load main_tags %}
5
5
6 {% block extra-menu-actions %}
6 {% block extra-menu-actions %}
7 <li><a href="{{ dev_conf.get_absolute_url_plot }}" target="_blank"><span class="glyphicon glyphicon-picture" aria-hidden="true"></span> View Pulses </a></li>
7 <li><a href="{{ dev_conf.get_absolute_url_plot }}" target="_blank"><span class="glyphicon glyphicon-picture" aria-hidden="true"></span> View Pulses </a></li>
8 {% endblock %}
8 {% endblock %}
9
9
10 {% block content-detail %}
11
12 <h2>Clock</h2>
13 <table class="table table-bordered">
14 <tr>
15 <th>Mode</th>
16 <td>{{clock.get_mode_display}}</td>
17 </tr>
18 <tr>
19 <th>Reference</th>
20 <td>{{clock.get_reference_display}}</td>
21 </tr>
22 <tr>
23 <th>Frequency</th>
24 <td>{{clock.frequency}}</td>
25 </tr>
26 </table>
27 <div class="clearfix"></div>
28 <h2>RC</h2>
29 <table class="table table-bordered">
30 <tr>
31 <th>Status</th>
32 <td class="text-{{dev_conf.device.status_color}}"><strong>{{dev_conf.device.get_status_display}}</strong></td>
33 </tr>
34
35 {% for key in dev_conf_keys %}
36 <tr>
37 <th>{% get_verbose_field_name dev_conf key %}</th>
38 <td>{{dev_conf|attr:key}}</td>
39 </tr>
40 {% endfor %}
41 </table>
42 {% endblock %}
43
10 {% block extra-content %}
44 {% block extra-content %}
11
45
12 <div class="clearfix"></div>
46 <div class="clearfix"></div>
13 <h2>RC Lines</h2>
47 <h2>RC Lines</h2>
14 <br>
48 <br>
15 <div class="panel-group" id="div_lines" role="tablist" aria-multiselectable="true">
49 <div class="panel-group" id="div_lines" role="tablist" aria-multiselectable="true">
16 {% include "rc_lines.html" %}
50 {% include "rc_lines.html" %}
17 </div>
51 </div>
18
52
19 {% endblock extra-content%}
53 {% endblock extra-content%}
20
54
21 {% block extra-js%}
55 {% block extra-js%}
22 <script type="text/javascript">
56 <script type="text/javascript">
23 $("#bt_toggle").click(function() {
57 $("#bt_toggle").click(function() {
24 $(".panel-collapse").collapse('toggle')
58 $(".panel-collapse").collapse('toggle')
25 });
59 });
26 </script>
60 </script>
27 {% endblock %} No newline at end of file
61 {% endblock %}
@@ -1,77 +1,81
1 {% extends "dev_conf_edit.html" %}
1 {% extends "dev_conf_edit.html" %}
2 {% load bootstrap3 %}
2 {% load bootstrap3 %}
3 {% load static %}
3 {% load static %}
4
4
5 {% block extra-head %}
5 {% block extra-head %}
6 <style type="text/css">
6 <style type="text/css">
7 /* show the move cursor as the user moves the mouse over the panel header.*/
7 /* show the move cursor as the user moves the mouse over the panel header.*/
8 .panel-default { cursor: move; }
8 .panel-default { cursor: move; }
9 </style>
9 </style>
10 <script src="{% static 'js/jquery-ui.min.js' %}"></script>
10 <script src="{% static 'js/jquery-ui.min.js' %}"></script>
11
11
12 {% endblock %}
12 {% endblock %}
13
13
14 {% block content %}
14 {% block content %}
15 <form class="form" method="post">
15 <form class="form" method="post">
16 {% csrf_token %}
16 {% csrf_token %}
17 <h2>Clock</h2>
18 {% bootstrap_form form_clock layout='horizontal' size='medium' %}
19 <div style="clear: both;"></div>
20 <h2>RC</h2>
17 {% bootstrap_form form layout='horizontal' size='medium' %}
21 {% bootstrap_form form layout='horizontal' size='medium' %}
18 <div style="clear: both;"></div>
22 <div style="clear: both;"></div>
19 <h2>RC Lines</h2><hr>
23 <h2>RC Lines</h2>
20 <div class="panel-group" id="div_lines" role="tablist" aria-multiselectable="true">
24 <div class="panel-group" id="div_lines" role="tablist" aria-multiselectable="true">
21 {% include "rc_lines.html" %}
25 {% include "rc_lines.html" %}
22 </div>
26 </div>
23 <div style="clear: both;"></div>
27 <div style="clear: both;"></div>
24 <br>
28 <br>
25 <div class="pull-right">
29 <div class="pull-right">
26 <button type="button" class="btn btn-primary" onclick="{% if previous %}window.location.replace('{{ previous }}');{% else %}history.go(-1);{% endif %}">Cancel</button>
30 <button type="button" class="btn btn-primary" onclick="{% if previous %}window.location.replace('{{ previous }}');{% else %}history.go(-1);{% endif %}">Cancel</button>
27 <button type="button" class="btn btn-primary" id="bt_add_line">Add Line</button>
31 <button type="button" class="btn btn-primary" id="bt_add_line">Add Line</button>
28 <button type="submit" class="btn btn-primary">{{button}}</button>
32 <button type="submit" class="btn btn-primary">{{button}}</button>
29 </div>
33 </div>
30 </form>
34 </form>
31 {% endblock %}
35 {% endblock %}
32
36
33 {% block extra-js%}
37 {% block extra-js%}
34
38
35 <script src="{% static 'js/cr.js' %}"></script>
39 <script src="{% static 'js/cr.js' %}"></script>
36
40
37 <script type="text/javascript">
41 <script type="text/javascript">
38
42
39 $("#div_lines").on("click", "button[name=bt_remove_line]", function(){
43 $("#div_lines").on("click", "button[name=bt_remove_line]", function(){
40 document.location = "/rc/{{dev_conf.id}}/line/"+$(this).val()+"/delete/";
44 document.location = "/rc/{{dev_conf.id}}/line/"+$(this).val()+"/delete/";
41 });
45 });
42
46
43 $("#div_lines").on("click", "button[name=bt_remove_subline]", function(){
47 $("#div_lines").on("click", "button[name=bt_remove_subline]", function(){
44 document.location = $(this).data('url');
48 document.location = $(this).data('url');
45 });
49 });
46
50
47 $("#div_lines").on("click", "button[name=bt_add_subline]", function(){
51 $("#div_lines").on("click", "button[name=bt_add_subline]", function(){
48 document.location = "/rc/{{dev_conf.id}}/line/"+$(this).val()+"/add_subline/";
52 document.location = "/rc/{{dev_conf.id}}/line/"+$(this).val()+"/add_subline/";
49 });
53 });
50
54
51 $("#div_lines").on("click", "button[name=bt_edit_codes]", function(){
55 $("#div_lines").on("click", "button[name=bt_edit_codes]", function(){
52 document.location = "/rc/{{dev_conf.id}}/line/"+$(this).val()+"/codes/";
56 document.location = "/rc/{{dev_conf.id}}/line/"+$(this).val()+"/codes/";
53 });
57 });
54
58
55 $("#bt_add_line").click(function() {
59 $("#bt_add_line").click(function() {
56 document.location = "{% url 'url_add_rc_line' dev_conf.id%}";
60 document.location = "{% url 'url_add_rc_line' dev_conf.id%}";
57 });
61 });
58
62
59 $(".panel-group").sortable({
63 $(".panel-group").sortable({
60 //placeholder: "ui-state-highlight",
64 //placeholder: "ui-state-highlight",
61 update: function( event, ui ) {
65 update: function( event, ui ) {
62 var sorted = $( ".panel-group" ).sortable( "serialize", { key: "item" } );
66 var sorted = $( ".panel-group" ).sortable( "serialize", { key: "item" } );
63 var url = "{% url 'url_update_rc_lines_position' dev_conf.id %}";
67 var url = "{% url 'url_update_rc_lines_position' dev_conf.id %}";
64 var csrf_token = "{{csrf_token}}";
68 var csrf_token = "{{csrf_token}}";
65 $.post( url, { 'items': sorted, 'csrfmiddlewaretoken': csrf_token }, function(data){
69 $.post( url, { 'items': sorted, 'csrfmiddlewaretoken': csrf_token }, function(data){
66 $("#div_lines").html(data.html);
70 $("#div_lines").html(data.html);
67 });
71 });
68 }
72 }
69 });
73 });
70
74
71 $("#bt_toggle").click(function() {
75 $("#bt_toggle").click(function() {
72 $(".panel-collapse").collapse('toggle')
76 $(".panel-collapse").collapse('toggle')
73 });
77 });
74
78
75 </script>
79 </script>
76 {% endblock %}
80 {% endblock %}
77 No newline at end of file
81
@@ -1,407 +1,417
1
1
2 import json
2 import json
3
3
4 from django.contrib import messages
4 from django.contrib import messages
5 from django.utils.safestring import mark_safe
5 from django.utils.safestring import mark_safe
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7 from django.contrib.auth.decorators import login_required
7 from django.contrib.auth.decorators import login_required
8
8
9 from apps.main.models import Experiment, Device
9 from apps.main.models import Experiment, Device
10 from apps.main.views import sidebar
10 from apps.main.views import sidebar
11
11
12 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
12 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode, RCClock
13 from .forms import RCConfigurationForm, RCLineForm, RCLineViewForm, RCLineEditForm, RCImportForm, RCLineCodesForm
13 from .forms import RCConfigurationForm, RCLineForm, RCLineViewForm, RCLineEditForm, RCImportForm, RCLineCodesForm, RCClockForm
14
14
15
15
16 def conf(request, conf_id):
16 def conf(request, conf_id):
17
17
18 conf = get_object_or_404(RCConfiguration, pk=conf_id)
18 conf = get_object_or_404(RCConfiguration, pk=conf_id)
19
19
20 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
20 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
21 clk = RCClock.objects.get(rc_configuration=conf)
21
22
22 for line in lines:
23 for line in lines:
23 params = json.loads(line.params)
24 params = json.loads(line.params)
24 line.form = RCLineViewForm(extra_fields=params, line=line)
25 line.form = RCLineViewForm(extra_fields=params, line=line)
25 if 'params' in params:
26 if 'params' in params:
26 line.subforms = [RCLineViewForm(extra_fields=fields, line=line, subform=True) for fields in params['params']]
27 line.subforms = [RCLineViewForm(extra_fields=fields, line=line, subform=True) for fields in params['params']]
27
28
28 kwargs = {}
29 kwargs = {}
30 kwargs['clock'] = clk
29 kwargs['dev_conf'] = conf
31 kwargs['dev_conf'] = conf
30 kwargs['rc_lines'] = lines
32 kwargs['rc_lines'] = lines
31 kwargs['dev_conf_keys'] = ['ipp_unit', 'ntx', 'clock_in', 'clock_divider', 'clock',
33 kwargs['dev_conf_keys'] = ['ipp_unit', 'ntx', 'clock_divider', 'clock',
32 'time_before', 'time_after', 'sync', 'sampling_reference',
34 'time_before', 'time_after', 'sync', 'sampling_reference',
33 'control_tx', 'control_sw']
35 'control_tx', 'control_sw']
34
36
35 kwargs['title'] = 'Configuration'
37 kwargs['title'] = 'Configuration'
36 kwargs['suptitle'] = 'Detail'
38 kwargs['suptitle'] = 'Detail'
37
39
38 kwargs['button'] = 'Edit Configuration'
40 kwargs['button'] = 'Edit Configuration'
39 ###### SIDEBAR ######
41 ###### SIDEBAR ######
40 kwargs.update(sidebar(conf=conf))
42 kwargs.update(sidebar(conf=conf))
41
43
42 return render(request, 'rc_conf.html', kwargs)
44 return render(request, 'rc_conf.html', kwargs)
43
45
44 @login_required
46 @login_required
45 def conf_edit(request, conf_id):
47 def conf_edit(request, conf_id):
46
48
47 conf = get_object_or_404(RCConfiguration, pk=conf_id)
49 conf = get_object_or_404(RCConfiguration, pk=conf_id)
48
50 clock = RCClock.objects.get(rc_configuration=conf)
49 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
51 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
50
52
51 for line in lines:
53 for line in lines:
52 params = json.loads(line.params)
54 params = json.loads(line.params)
53 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
55 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
54 line.subform = False
56 line.subform = False
55
57
56 if 'params' in params:
58 if 'params' in params:
57 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
59 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
58 line.subform = True
60 line.subform = True
59
61
60 if request.method=='GET':
62 if request.method=='GET':
61
63
62 form = RCConfigurationForm(instance=conf)
64 form = RCConfigurationForm(instance=conf)
65 form_clock = RCClockForm(instance=clock)
63
66
64 elif request.method=='POST':
67 elif request.method=='POST':
65
68
66 line_data = {}
69 line_data = {}
67 conf_data = {}
70 conf_data = {}
71 clock_data = {}
68 extras = []
72 extras = []
69
73
70 #classified post fields
74 #classified post fields
71 for label,value in request.POST.items():
75 for label,value in request.POST.items():
72 if label=='csrfmiddlewaretoken':
76 if label=='csrfmiddlewaretoken':
73 continue
77 continue
74
78
75 if label.count('|')==0:
79 if label.count('|')==0:
76 conf_data[label] = value
80 if label in ('mode', 'multiplier', 'divisor', 'reference', 'frequency'):
81 clock_data[label] = value
82 else:
83 conf_data[label] = value
77 continue
84 continue
78
85
79 elif label.split('|')[0]!='-1':
86 elif label.split('|')[0]!='-1':
80 extras.append(label)
87 extras.append(label)
81 continue
88 continue
82
89
83 x, pk, name = label.split('|')
90 x, pk, name = label.split('|')
84
91
85 if name=='codes':
92 if name=='codes':
86 value = [s for s in value.split('\r\n') if s]
93 value = [s for s in value.split('\r\n') if s]
87
94
88 if pk in line_data:
95 if pk in line_data:
89 line_data[pk][name] = value
96 line_data[pk][name] = value
90 else:
97 else:
91 line_data[pk] = {name:value}
98 line_data[pk] = {name:value}
92
99
93 #update conf
100 #update conf
101
102 form_clock = RCClockForm(clock_data, instance=clock)
94 form = RCConfigurationForm(conf_data, instance=conf)
103 form = RCConfigurationForm(conf_data, instance=conf)
95
104
96 if form.is_valid():
105 if form_clock.is_valid() and form.is_valid():
97
106 form_clock.save()
98 form.save()
107 form.save()
99
108
100 #update lines fields
109 #update lines fields
101 extras.sort()
110 extras.sort()
102 for label in extras:
111 for label in extras:
103 x, pk, name = label.split('|')
112 x, pk, name = label.split('|')
104 if pk not in line_data:
113 if pk not in line_data:
105 line_data[pk] = {}
114 line_data[pk] = {}
106 if 'params' not in line_data[pk]:
115 if 'params' not in line_data[pk]:
107 line_data[pk]['params'] = []
116 line_data[pk]['params'] = []
108 if len(line_data[pk]['params'])<int(x)+1:
117 if len(line_data[pk]['params'])<int(x)+1:
109 line_data[pk]['params'].append({})
118 line_data[pk]['params'].append({})
110 line_data[pk]['params'][int(x)][name] = float(request.POST[label])
119 line_data[pk]['params'][int(x)][name] = float(request.POST[label])
111
120
112 for pk, params in line_data.items():
121 for pk, params in line_data.items():
113 line = RCLine.objects.get(pk=pk)
122 line = RCLine.objects.get(pk=pk)
114 if line.line_type.name in ('windows', 'prog_pulses'):
123 if line.line_type.name in ('windows', 'prog_pulses'):
115 if 'params' not in params:
124 if 'params' not in params:
116 params['params'] = []
125 params['params'] = []
117 line.params = json.dumps(params)
126 line.params = json.dumps(params)
118 line.save()
127 line.save()
119
128
120 #update pulses field
129 #update pulses field
121 conf.update_pulses()
130 conf.update_pulses()
122
131
123 messages.success(request, 'RC Configuration successfully updated')
132 messages.success(request, 'RC Configuration successfully updated')
124
133
125 return redirect(conf.get_absolute_url())
134 return redirect(conf.get_absolute_url())
126
135
127 kwargs = {}
136 kwargs = {}
128 kwargs['dev_conf'] = conf
137 kwargs['dev_conf'] = conf
129 kwargs['form'] = form
138 kwargs['form'] = form
139 kwargs['form_clock'] = form_clock
130 kwargs['rc_lines'] = lines
140 kwargs['rc_lines'] = lines
131 kwargs['edit'] = True
141 kwargs['edit'] = True
132
142
133 kwargs['title'] = 'RC Configuration'
143 kwargs['title'] = 'RC Configuration'
134 kwargs['suptitle'] = 'Edit'
144 kwargs['suptitle'] = 'Edit'
135 kwargs['button'] = 'Update'
145 kwargs['button'] = 'Update'
136
146
137 return render(request, 'rc_conf_edit.html', kwargs)
147 return render(request, 'rc_conf_edit.html', kwargs)
138
148
139
149
140 def add_line(request, conf_id, line_type_id=None, code_id=None):
150 def add_line(request, conf_id, line_type_id=None, code_id=None):
141
151
142 conf = get_object_or_404(RCConfiguration, pk=conf_id)
152 conf = get_object_or_404(RCConfiguration, pk=conf_id)
143
153
144 if request.method=='GET':
154 if request.method=='GET':
145 if line_type_id:
155 if line_type_id:
146 line_type = get_object_or_404(RCLineType, pk=line_type_id)
156 line_type = get_object_or_404(RCLineType, pk=line_type_id)
147
157
148 if code_id:
158 if code_id:
149 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id, 'code_id': code_id},
159 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id, 'code_id': code_id},
150 extra_fields=json.loads(line_type.params))
160 extra_fields=json.loads(line_type.params))
151 else:
161 else:
152 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id},
162 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id},
153 extra_fields=json.loads(line_type.params))
163 extra_fields=json.loads(line_type.params))
154 else:
164 else:
155 line_type = {'id':0}
165 line_type = {'id':0}
156 form = RCLineForm(initial={'rc_configuration':conf_id})
166 form = RCLineForm(initial={'rc_configuration':conf_id})
157
167
158 if request.method=='POST':
168 if request.method=='POST':
159
169
160 line_type = get_object_or_404(RCLineType, pk=line_type_id)
170 line_type = get_object_or_404(RCLineType, pk=line_type_id)
161 form = RCLineForm(request.POST,
171 form = RCLineForm(request.POST,
162 extra_fields=json.loads(line_type.params))
172 extra_fields=json.loads(line_type.params))
163
173
164 if form.is_valid():
174 if form.is_valid():
165 form.save()
175 form.save()
166 form.instance.update_pulses()
176 form.instance.update_pulses()
167 return redirect('url_edit_rc_conf', conf.id)
177 return redirect('url_edit_rc_conf', conf.id)
168
178
169 kwargs = {}
179 kwargs = {}
170 kwargs['form'] = form
180 kwargs['form'] = form
171 kwargs['title'] = 'RC Configuration'
181 kwargs['title'] = 'RC Configuration'
172 kwargs['suptitle'] = 'Add Line'
182 kwargs['suptitle'] = 'Add Line'
173 kwargs['button'] = 'Add'
183 kwargs['button'] = 'Add'
174 kwargs['previous'] = conf.get_absolute_url_edit()
184 kwargs['previous'] = conf.get_absolute_url_edit()
175 kwargs['dev_conf'] = conf
185 kwargs['dev_conf'] = conf
176 kwargs['line_type'] = line_type
186 kwargs['line_type'] = line_type
177
187
178 return render(request, 'rc_add_line.html', kwargs)
188 return render(request, 'rc_add_line.html', kwargs)
179
189
180 def edit_codes(request, conf_id, line_id, code_id=None):
190 def edit_codes(request, conf_id, line_id, code_id=None):
181
191
182 conf = get_object_or_404(RCConfiguration, pk=conf_id)
192 conf = get_object_or_404(RCConfiguration, pk=conf_id)
183 line = get_object_or_404(RCLine, pk=line_id)
193 line = get_object_or_404(RCLine, pk=line_id)
184 params = json.loads(line.params)
194 params = json.loads(line.params)
185
195
186 if request.method=='GET':
196 if request.method=='GET':
187 if code_id:
197 if code_id:
188 code = get_object_or_404(RCLineCode, pk=code_id)
198 code = get_object_or_404(RCLineCode, pk=code_id)
189 form = RCLineCodesForm(instance=code)
199 form = RCLineCodesForm(instance=code)
190 else:
200 else:
191 initial = {'code': params['code'],
201 initial = {'code': params['code'],
192 'codes': params['codes'] if 'codes' in params else [],
202 'codes': params['codes'] if 'codes' in params else [],
193 'number_of_codes': len(params['codes']) if 'codes' in params else 0,
203 'number_of_codes': len(params['codes']) if 'codes' in params else 0,
194 'bits_per_code': len(params['codes'][0]) if 'codes' in params else 0,
204 'bits_per_code': len(params['codes'][0]) if 'codes' in params else 0,
195 }
205 }
196 form = RCLineCodesForm(initial=initial)
206 form = RCLineCodesForm(initial=initial)
197
207
198 if request.method=='POST':
208 if request.method=='POST':
199 form = RCLineCodesForm(request.POST)
209 form = RCLineCodesForm(request.POST)
200 if form.is_valid():
210 if form.is_valid():
201 params['code'] = request.POST['code']
211 params['code'] = request.POST['code']
202 params['codes'] = [s for s in request.POST['codes'].split('\r\n') if s]
212 params['codes'] = [s for s in request.POST['codes'].split('\r\n') if s]
203 line.params = json.dumps(params)
213 line.params = json.dumps(params)
204 line.save()
214 line.save()
205 messages.success(request, 'Line: "%s" has been updated.' % line)
215 messages.success(request, 'Line: "%s" has been updated.' % line)
206 return redirect('url_edit_rc_conf', conf.id)
216 return redirect('url_edit_rc_conf', conf.id)
207
217
208 kwargs = {}
218 kwargs = {}
209 kwargs['form'] = form
219 kwargs['form'] = form
210 kwargs['title'] = line
220 kwargs['title'] = line
211 kwargs['suptitle'] = 'Edit'
221 kwargs['suptitle'] = 'Edit'
212 kwargs['button'] = 'Update'
222 kwargs['button'] = 'Update'
213 kwargs['dev_conf'] = conf
223 kwargs['dev_conf'] = conf
214 kwargs['previous'] = conf.get_absolute_url_edit()
224 kwargs['previous'] = conf.get_absolute_url_edit()
215 kwargs['line'] = line
225 kwargs['line'] = line
216
226
217 return render(request, 'rc_edit_codes.html', kwargs)
227 return render(request, 'rc_edit_codes.html', kwargs)
218
228
219 def add_subline(request, conf_id, line_id):
229 def add_subline(request, conf_id, line_id):
220
230
221 conf = get_object_or_404(RCConfiguration, pk=conf_id)
231 conf = get_object_or_404(RCConfiguration, pk=conf_id)
222 line = get_object_or_404(RCLine, pk=line_id)
232 line = get_object_or_404(RCLine, pk=line_id)
223
233
224 if request.method == 'POST':
234 if request.method == 'POST':
225 if line:
235 if line:
226 params = json.loads(line.params)
236 params = json.loads(line.params)
227 subparams = json.loads(line.line_type.params)
237 subparams = json.loads(line.line_type.params)
228 if 'params' in subparams:
238 if 'params' in subparams:
229 dum = {}
239 dum = {}
230 for key, value in subparams['params'].items():
240 for key, value in subparams['params'].items():
231 dum[key] = value['value']
241 dum[key] = value['value']
232 params['params'].append(dum)
242 params['params'].append(dum)
233 line.params = json.dumps(params)
243 line.params = json.dumps(params)
234 line.save()
244 line.save()
235 return redirect('url_edit_rc_conf', conf.id)
245 return redirect('url_edit_rc_conf', conf.id)
236
246
237 kwargs = {}
247 kwargs = {}
238
248
239 kwargs['title'] = 'Add new'
249 kwargs['title'] = 'Add new'
240 kwargs['suptitle'] = '%s to %s' % (line.line_type.name, line)
250 kwargs['suptitle'] = '%s to %s' % (line.line_type.name, line)
241
251
242 return render(request, 'confirm.html', kwargs)
252 return render(request, 'confirm.html', kwargs)
243
253
244 def remove_line(request, conf_id, line_id):
254 def remove_line(request, conf_id, line_id):
245
255
246 conf = get_object_or_404(RCConfiguration, pk=conf_id)
256 conf = get_object_or_404(RCConfiguration, pk=conf_id)
247 line = get_object_or_404(RCLine, pk=line_id)
257 line = get_object_or_404(RCLine, pk=line_id)
248
258
249 if request.method == 'POST':
259 if request.method == 'POST':
250 if line:
260 if line:
251 try:
261 try:
252 channel = line.channel
262 channel = line.channel
253 line.delete()
263 line.delete()
254 for ch in range(channel+1, RCLine.objects.filter(rc_configuration=conf).count()+1):
264 for ch in range(channel+1, RCLine.objects.filter(rc_configuration=conf).count()+1):
255 l = RCLine.objects.get(rc_configuration=conf, channel=ch)
265 l = RCLine.objects.get(rc_configuration=conf, channel=ch)
256 l.channel = l.channel-1
266 l.channel = l.channel-1
257 l.save()
267 l.save()
258 messages.success(request, 'Line: "%s" has been deleted.' % line)
268 messages.success(request, 'Line: "%s" has been deleted.' % line)
259 except:
269 except:
260 messages.error(request, 'Unable to delete line: "%s".' % line)
270 messages.error(request, 'Unable to delete line: "%s".' % line)
261
271
262 return redirect('url_edit_rc_conf', conf.id)
272 return redirect('url_edit_rc_conf', conf.id)
263
273
264 kwargs = {}
274 kwargs = {}
265
275
266 kwargs['object'] = line
276 kwargs['object'] = line
267 kwargs['delete'] = True
277 kwargs['delete'] = True
268 kwargs['title'] = 'Delete'
278 kwargs['title'] = 'Delete'
269 kwargs['suptitle'] = 'Line'
279 kwargs['suptitle'] = 'Line'
270 kwargs['previous'] = conf.get_absolute_url_edit()
280 kwargs['previous'] = conf.get_absolute_url_edit()
271 return render(request, 'confirm.html', kwargs)
281 return render(request, 'confirm.html', kwargs)
272
282
273
283
274 def remove_subline(request, conf_id, line_id, subline_id):
284 def remove_subline(request, conf_id, line_id, subline_id):
275
285
276 conf = get_object_or_404(RCConfiguration, pk=conf_id)
286 conf = get_object_or_404(RCConfiguration, pk=conf_id)
277 line = get_object_or_404(RCLine, pk=line_id)
287 line = get_object_or_404(RCLine, pk=line_id)
278
288
279 if request.method == 'POST':
289 if request.method == 'POST':
280 if line:
290 if line:
281 params = json.loads(line.params)
291 params = json.loads(line.params)
282 params['params'].remove(params['params'][int(subline_id)-1])
292 params['params'].remove(params['params'][int(subline_id)-1])
283 line.params = json.dumps(params)
293 line.params = json.dumps(params)
284 line.save()
294 line.save()
285
295
286 return redirect('url_edit_rc_conf', conf.id)
296 return redirect('url_edit_rc_conf', conf.id)
287
297
288 kwargs = {}
298 kwargs = {}
289
299
290 kwargs['object'] = line
300 kwargs['object'] = line
291 kwargs['object_name'] = line.line_type.name
301 kwargs['object_name'] = line.line_type.name
292 kwargs['delete_view'] = True
302 kwargs['delete_view'] = True
293 kwargs['title'] = 'Confirm delete'
303 kwargs['title'] = 'Confirm delete'
294
304
295 return render(request, 'confirm.html', kwargs)
305 return render(request, 'confirm.html', kwargs)
296
306
297
307
298 def update_lines_position(request, conf_id):
308 def update_lines_position(request, conf_id):
299
309
300 conf = get_object_or_404(RCConfiguration, pk=conf_id)
310 conf = get_object_or_404(RCConfiguration, pk=conf_id)
301
311
302 if request.method=='POST':
312 if request.method=='POST':
303 ch = 0
313 ch = 0
304 for item in request.POST['items'].split('&'):
314 for item in request.POST['items'].split('&'):
305 line = RCLine.objects.get(pk=item.split('=')[-1])
315 line = RCLine.objects.get(pk=item.split('=')[-1])
306 line.channel = ch
316 line.channel = ch
307 line.save()
317 line.save()
308 ch += 1
318 ch += 1
309
319
310 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
320 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
311
321
312 for line in lines:
322 for line in lines:
313 params = json.loads(line.params)
323 params = json.loads(line.params)
314 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
324 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
315
325
316 if 'params' in params:
326 if 'params' in params:
317 line.subform = True
327 line.subform = True
318 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
328 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
319
329
320 html = render(request, 'rc_lines.html', {'dev_conf':conf, 'rc_lines':lines, 'edit':True})
330 html = render(request, 'rc_lines.html', {'dev_conf':conf, 'rc_lines':lines, 'edit':True})
321 data = {'html': html.content.decode('utf8')}
331 data = {'html': html.content.decode('utf8')}
322
332
323 return HttpResponse(json.dumps(data), content_type="application/json")
333 return HttpResponse(json.dumps(data), content_type="application/json")
324 return redirect('url_edit_rc_conf', conf.id)
334 return redirect('url_edit_rc_conf', conf.id)
325
335
326
336
327 def import_file(request, conf_id):
337 def import_file(request, conf_id):
328
338
329 conf = get_object_or_404(RCConfiguration, pk=conf_id)
339 conf = get_object_or_404(RCConfiguration, pk=conf_id)
330 if request.method=='POST':
340 if request.method=='POST':
331 form = RCImportForm(request.POST, request.FILES)
341 form = RCImportForm(request.POST, request.FILES)
332 if form.is_valid():
342 if form.is_valid():
333 try:
343 try:
334 data = conf.import_from_file(request.FILES['file_name'])
344 data = conf.import_from_file(request.FILES['file_name'])
335 conf.dict_to_parms(data)
345 conf.dict_to_parms(data)
336 conf.update_pulses()
346 conf.update_pulses()
337 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
347 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
338 return redirect(conf.get_absolute_url_edit())
348 return redirect(conf.get_absolute_url_edit())
339
349
340 except Exception as e:
350 except Exception as e:
341 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
351 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
342 else:
352 else:
343 messages.warning(request, 'Your current configuration will be replaced')
353 messages.warning(request, 'Your current configuration will be replaced')
344 form = RCImportForm()
354 form = RCImportForm()
345
355
346 kwargs = {}
356 kwargs = {}
347 kwargs['form'] = form
357 kwargs['form'] = form
348 kwargs['title'] = 'RC Configuration'
358 kwargs['title'] = 'RC Configuration'
349 kwargs['suptitle'] = 'Import file'
359 kwargs['suptitle'] = 'Import file'
350 kwargs['button'] = 'Upload'
360 kwargs['button'] = 'Upload'
351 kwargs['previous'] = conf.get_absolute_url()
361 kwargs['previous'] = conf.get_absolute_url()
352
362
353 return render(request, 'rc_import.html', kwargs)
363 return render(request, 'rc_import.html', kwargs)
354
364
355
365
356 def plot_pulses(request, conf_id):
366 def plot_pulses(request, conf_id):
357
367
358 conf = get_object_or_404(RCConfiguration, pk=conf_id)
368 conf = get_object_or_404(RCConfiguration, pk=conf_id)
359 km = True if 'km' in request.GET else False
369 km = True if 'km' in request.GET else False
360
370
361 script, div = conf.plot_pulses(km=km)
371 script, div = conf.plot_pulses(km=km)
362
372
363 kwargs = {}
373 kwargs = {}
364 kwargs['no_sidebar'] = True
374 kwargs['no_sidebar'] = True
365 kwargs['title'] = 'RC Pulses'
375 kwargs['title'] = 'RC Pulses'
366 kwargs['suptitle'] = conf.name
376 kwargs['suptitle'] = conf.name
367 kwargs['div'] = mark_safe(div)
377 kwargs['div'] = mark_safe(div)
368 kwargs['script'] = mark_safe(script)
378 kwargs['script'] = mark_safe(script)
369 kwargs['units'] = conf.km2unit
379 kwargs['units'] = conf.km2unit
370 kwargs['kms'] = 1/conf.km2unit
380 kwargs['kms'] = 1/conf.km2unit
371
381
372 if km:
382 if km:
373 kwargs['km_selected'] = True
383 kwargs['km_selected'] = True
374
384
375 if 'json' in request.GET:
385 if 'json' in request.GET:
376 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
386 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
377 else:
387 else:
378 return render(request, 'rc_pulses.html', kwargs)
388 return render(request, 'rc_pulses.html', kwargs)
379
389
380 def plot_pulses2(request, conf_id):
390 def plot_pulses2(request, conf_id):
381
391
382 conf = get_object_or_404(RCConfiguration, pk=conf_id)
392 conf = get_object_or_404(RCConfiguration, pk=conf_id)
383 km = True if 'km' in request.GET else False
393 km = True if 'km' in request.GET else False
384
394
385 script, div = conf.plot_pulses2(km=km)
395 script, div = conf.plot_pulses2(km=km)
386
396
387 kwargs = {}
397 kwargs = {}
388 kwargs['no_sidebar'] = True
398 kwargs['no_sidebar'] = True
389 kwargs['title'] = 'RC Pulses'
399 kwargs['title'] = 'RC Pulses'
390 kwargs['suptitle'] = conf.name
400 kwargs['suptitle'] = conf.name
391 kwargs['div'] = mark_safe(div)
401 kwargs['div'] = mark_safe(div)
392 kwargs['script'] = mark_safe(script)
402 kwargs['script'] = mark_safe(script)
393 kwargs['units'] = conf.km2unit
403 kwargs['units'] = conf.km2unit
394 kwargs['kms'] = 1/conf.km2unit
404 kwargs['kms'] = 1/conf.km2unit
395
405
396 if km:
406 if km:
397 kwargs['km_selected'] = True
407 kwargs['km_selected'] = True
398
408
399 if 'json' in request.GET:
409 if 'json' in request.GET:
400 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
410 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
401 else:
411 else:
402 return render(request, 'rc_pulses.html', kwargs)
412 return render(request, 'rc_pulses.html', kwargs)
403
413
404 def conf_raw(request, conf_id):
414 def conf_raw(request, conf_id):
405 conf = get_object_or_404(RCConfiguration, pk=conf_id)
415 conf = get_object_or_404(RCConfiguration, pk=conf_id)
406 raw = conf.write_device(raw=True)
416 raw = conf.write_device(raw=True)
407 return HttpResponse(raw, content_type='application/json') No newline at end of file
417 return HttpResponse(raw, content_type='application/json')
@@ -1,5 +1,9
1 #!/bin/env bash
1 #!/bin/bash
2 echo "Creating database..."
2 set -e
3 psql -U postgres -c "CREATE USER $POSTGRES_USER WITH PASSWORD '$POSTGRES_PASSWORD';"
3
4 psql -U postgres -c "CREATE DATABASE $POSTGRES_DB_NAME;"
4 echo "Creating database & user"
5 psql -U postgres -c "GRANT ALL PRIVILEGES ON DATABASE $POSTGRES_DB_NAME to $POSTGRES_USER;"
5 psql -v --username "postgres" --dbname "postgres" <<-EOSQL
6 CREATE USER $DB_USER WITH PASSWORD '$DB_PASSWORD';
7 CREATE DATABASE $DB_NAME;
8 GRANT ALL PRIVILEGES ON DATABASE $DB_NAME TO $DB_USER;
9 EOSQL
@@ -1,141 +1,141
1 """
1 """
2 Django settings for radarsys project.
2 Django settings for radarsys project.
3
3
4 Generated by 'django-admin startproject' using Django 1.8.6.
4 Generated by 'django-admin startproject' using Django 1.8.6.
5
5
6 For more information on this file, see
6 For more information on this file, see
7 https://docs.djangoproject.com/en/1.8/topics/settings/
7 https://docs.djangoproject.com/en/1.8/topics/settings/
8
8
9 For the full list of settings and their values, see
9 For the full list of settings and their values, see
10 https://docs.djangoproject.com/en/1.8/ref/settings/
10 https://docs.djangoproject.com/en/1.8/ref/settings/
11 """
11 """
12
12
13 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
13 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
14 import os
14 import os
15
15
16 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
16 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17
17
18 # Quick-start development settings - unsuitable for production
18 # Quick-start development settings - unsuitable for production
19 # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
19 # See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
20
20
21 # SECURITY WARNING: keep the secret key used in production secret!
21 # SECURITY WARNING: keep the secret key used in production secret!
22 SECRET_KEY = 'xshb$k5fc-+j16)cvyffj&9u__0q3$l!hieh#+tbzqg)*f^km0'
22 SECRET_KEY = 'xshb$k5fc-+j16)cvyffj&9u__0q3$l!hieh#+tbzqg)*f^km0'
23
23
24 # SECURITY WARNING: don't run with debug turned on in production!
24 # SECURITY WARNING: don't run with debug turned on in production!
25 DEBUG = True
25 DEBUG = True
26
26
27 ALLOWED_HOSTS = ['*']
27 ALLOWED_HOSTS = ['*']
28
28
29 # Application definition
29 # Application definition
30
30
31 INSTALLED_APPS = (
31 INSTALLED_APPS = (
32 'django.contrib.admin',
32 'django.contrib.admin',
33 'django.contrib.auth',
33 'django.contrib.auth',
34 'django.contrib.contenttypes',
34 'django.contrib.contenttypes',
35 'django.contrib.sessions',
35 'django.contrib.sessions',
36 'django.contrib.messages',
36 'django.contrib.messages',
37 'django.contrib.staticfiles',
37 'django.contrib.staticfiles',
38 'bootstrap3',
38 'bootstrap3',
39 'polymorphic',
39 'polymorphic',
40 'apps.accounts',
40 'apps.accounts',
41 'apps.main',
41 'apps.main',
42 'apps.misc',
42 'apps.misc',
43 'apps.rc',
43 'apps.rc',
44 'apps.dds',
44 'apps.dds',
45 'apps.jars',
45 'apps.jars',
46 'apps.usrp',
46 'apps.usrp',
47 'apps.abs',
47 'apps.abs',
48 'apps.cgs',
48 'apps.cgs',
49 )
49 )
50
50
51 MIDDLEWARE_CLASSES = (
51 MIDDLEWARE_CLASSES = (
52 'django.contrib.sessions.middleware.SessionMiddleware',
52 'django.contrib.sessions.middleware.SessionMiddleware',
53 'django.middleware.common.CommonMiddleware',
53 'django.middleware.common.CommonMiddleware',
54 'django.middleware.csrf.CsrfViewMiddleware',
54 'django.middleware.csrf.CsrfViewMiddleware',
55 'django.contrib.auth.middleware.AuthenticationMiddleware',
55 'django.contrib.auth.middleware.AuthenticationMiddleware',
56 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
56 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
57 'django.contrib.messages.middleware.MessageMiddleware',
57 'django.contrib.messages.middleware.MessageMiddleware',
58 'django.middleware.clickjacking.XFrameOptionsMiddleware',
58 'django.middleware.clickjacking.XFrameOptionsMiddleware',
59 'django.middleware.security.SecurityMiddleware',
59 'django.middleware.security.SecurityMiddleware',
60 )
60 )
61
61
62 ROOT_URLCONF = 'radarsys.urls'
62 ROOT_URLCONF = 'radarsys.urls'
63
63
64 TEMPLATES = [
64 TEMPLATES = [
65 {
65 {
66 'BACKEND': 'django.template.backends.django.DjangoTemplates',
66 'BACKEND': 'django.template.backends.django.DjangoTemplates',
67 'DIRS': [os.path.join(BASE_DIR, "templates").replace('\\', '/'),],
67 'DIRS': [os.path.join(BASE_DIR, "templates").replace('\\', '/'),],
68 'APP_DIRS': True,
68 'APP_DIRS': True,
69 'OPTIONS': {
69 'OPTIONS': {
70 'context_processors': [
70 'context_processors': [
71 'django.template.context_processors.debug',
71 'django.template.context_processors.debug',
72 'django.template.context_processors.request',
72 'django.template.context_processors.request',
73 'django.contrib.auth.context_processors.auth',
73 'django.contrib.auth.context_processors.auth',
74 'django.contrib.messages.context_processors.messages',
74 'django.contrib.messages.context_processors.messages',
75 'apps.main.processors.radarsys_globals',
75 'apps.main.processors.radarsys_globals',
76 ],
76 ],
77 },
77 },
78 },
78 },
79 ]
79 ]
80
80
81 WSGI_APPLICATION = 'radarsys.wsgi.application'
81 WSGI_APPLICATION = 'radarsys.wsgi.application'
82
82
83
83
84 # Database
84 # Database
85 # https://docs.djangoproject.com/en/1.8/ref/settings/#databases
85 # https://docs.djangoproject.com/en/1.8/ref/settings/#databases
86
86
87 DATABASES = {
87 DATABASES = {
88 # 'default': {
88 # 'default': {
89 # 'ENGINE': 'django.db.backends.sqlite3',
89 # 'ENGINE': 'django.db.backends.sqlite3',
90 # 'NAME': 'radarsys.sqlite',
90 # 'NAME': 'radarsys.sqlite',
91 # }
91 # }
92 'default': {
92 'default': {
93 'ENGINE': 'django.db.backends.postgresql_psycopg2',
93 'ENGINE': 'django.db.backends.postgresql_psycopg2',
94 'NAME': os.environ.get('POSTGRES_DB_NAME', 'radarsys'),
94 'NAME': os.environ.get('DB_NAME', 'radarsys'),
95 'USER': os.environ.get('POSTGRES_USER', 'docker'),
95 'USER': os.environ.get('DB_USER', 'docker'),
96 'PASSWORD': os.environ.get('POSTGRES_PASSWORD', 'docker'),
96 'PASSWORD': os.environ.get('DB_PASSWORD', 'docker'),
97 'HOST': os.environ.get('POSTGRES_PORT_5432_TCP_ADDR', 'postgres'),
97 'HOST': os.environ.get('POSTGRES_PORT_5432_TCP_ADDR', 'localhost'),
98 'PORT': os.environ.get('POSTGRES_PORT_5432_TCP_PORT', ''),
98 'PORT': os.environ.get('POSTGRES_PORT_5432_TCP_PORT', '5400'),
99 }
99 }
100 }
100 }
101
101
102 # Internationalization
102 # Internationalization
103 # https://docs.djangoproject.com/en/1.8/topics/i18n/
103 # https://docs.djangoproject.com/en/1.8/topics/i18n/
104
104
105 LANGUAGE_CODE = 'en-us'
105 LANGUAGE_CODE = 'en-us'
106
106
107 TIME_ZONE = os.environ.get('TZ', 'UTC')
107 TIME_ZONE = os.environ.get('TZ', 'America/Lima')
108
108
109 USE_I18N = True
109 USE_I18N = True
110
110
111 USE_L10N = True
111 USE_L10N = True
112
112
113 USE_TZ = False
113 USE_TZ = False
114
114
115 # Static files (CSS, JavaScript, Images)
115 # Static files (CSS, JavaScript, Images)
116 # https://docs.djangoproject.com/en/1.8/howto/static-files/
116 # https://docs.djangoproject.com/en/1.8/howto/static-files/
117
117
118 MEDIA_URL = '/media/'
118 MEDIA_URL = '/media/'
119 MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
119 MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
120
120
121 STATIC_URL = '/static/'
121 STATIC_URL = '/static/'
122 STATIC_ROOT = os.path.join(BASE_DIR, 'static')
122 STATIC_ROOT = os.path.join(BASE_DIR, 'static')
123
123
124 STATICFILES_FINDERS = (
124 STATICFILES_FINDERS = (
125 'django.contrib.staticfiles.finders.FileSystemFinder',
125 'django.contrib.staticfiles.finders.FileSystemFinder',
126 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
126 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
127 )
127 )
128
128
129 # Celery stuff
129 # Celery stuff
130 REDIS_HOST = os.environ.get('REDIS_HOST', '127.0.0.1')
130 REDIS_HOST = os.environ.get('REDIS_HOST', '127.0.0.1')
131 REDIS_PORT = os.environ.get('REDIS_PORT', 6379)
131 REDIS_PORT = os.environ.get('REDIS_PORT', 6300)
132
132
133 BROKER_TRANSPORT = 'redis'
133 BROKER_TRANSPORT = 'redis'
134 BROKER_URL = 'redis://{}:{}/0'.format(REDIS_HOST, REDIS_PORT)
134 BROKER_URL = 'redis://{}:{}/0'.format(REDIS_HOST, REDIS_PORT)
135
135
136 CELERY_RESULT_BACKEND = 'redis://{}:{}/0'.format(REDIS_HOST, REDIS_PORT)
136 CELERY_RESULT_BACKEND = 'redis://{}:{}/0'.format(REDIS_HOST, REDIS_PORT)
137 CELERY_BROKER_TRANSPORT = BROKER_URL
137 CELERY_BROKER_TRANSPORT = BROKER_URL
138 CELERY_ACCEPT_CONTENT = ['application/json']
138 CELERY_ACCEPT_CONTENT = ['application/json']
139 CELERY_TASK_SERIALIZER = 'json'
139 CELERY_TASK_SERIALIZER = 'json'
140 CELERY_RESULT_SERIALIZER = 'json'
140 CELERY_RESULT_SERIALIZER = 'json'
141 CELERY_ENABLE_UTC = False No newline at end of file
141 CELERY_ENABLE_UTC = False
General Comments 0
You need to be logged in to leave comments. Login now