##// END OF EJS Templates
Update code for django 1.10, python 3 and latest third party packages, review operation view ...
Juan C. Espinoza -
r172:a641bec15a9b
parent child
Show More

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

1 NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,13 +1,15
1 1 from django.conf.urls import url
2 2
3 import views
4
3 5 urlpatterns = (
4 url(r'^(?P<id_conf>-?\d+)/$', 'apps.abs.views.abs_conf', name='url_abs_conf'),
5 url(r'^(?P<id_conf>-?\d+)/edit/$', 'apps.abs.views.abs_conf_edit', name='url_edit_abs_conf'),
6 url(r'^(?P<id_conf>-?\d+)/read/$', 'apps.main.views.dev_conf_read', name='url_read_abs_conf'),
7 url(r'^(?P<id_conf>-?\d+)/import/$', 'apps.main.views.dev_conf_import', name='url_import_abs_conf'),
8 url(r'^(?P<id_conf>-?\d+)/export/$', 'apps.main.views.dev_conf_export', name='url_export_abs_conf'),
9 url(r'^(?P<id_conf>-?\d+)/plot/$', 'apps.abs.views.plot_patterns', name='url_plot_abs_patterns'),
10 url(r'^(?P<id_conf>-?\d+)/add_beam/$', 'apps.abs.views.add_beam', name='url_add_abs_beam'),
11 url(r'^(?P<id_conf>-?\d+)/beam/(?P<id_beam>-?\d+)/delete/$', 'apps.abs.views.remove_beam', name='url_remove_abs_beam'),
12 url(r'^(?P<id_conf>-?\d+)/beam/(?P<id_beam>-?\d+)/edit/$', 'apps.abs.views.edit_beam', name='url_edit_abs_beam'),
6 url(r'^(?P<id_conf>-?\d+)/$', views.abs_conf, name='url_abs_conf'),
7 url(r'^(?P<id_conf>-?\d+)/edit/$', views.abs_conf_edit, name='url_edit_abs_conf'),
8 url(r'^(?P<id_conf>-?\d+)/read/$', views.dev_conf_read, name='url_read_abs_conf'),
9 url(r'^(?P<id_conf>-?\d+)/import/$', views.dev_conf_import, name='url_import_abs_conf'),
10 url(r'^(?P<id_conf>-?\d+)/export/$', views.dev_conf_export, name='url_export_abs_conf'),
11 url(r'^(?P<id_conf>-?\d+)/plot/$', views.plot_patterns, name='url_plot_abs_patterns'),
12 url(r'^(?P<id_conf>-?\d+)/add_beam/$', views.add_beam, name='url_add_abs_beam'),
13 url(r'^(?P<id_conf>-?\d+)/beam/(?P<id_beam>-?\d+)/delete/$', views.remove_beam, name='url_remove_abs_beam'),
14 url(r'^(?P<id_conf>-?\d+)/beam/(?P<id_beam>-?\d+)/edit/$', views.edit_beam, name='url_edit_abs_beam'),
13 15 )
@@ -1,25 +1,25
1 1 {% extends "base.html" %}
2 2 {% load bootstrap3 %}
3 3 {% block mainactive %}active{% endblock %}
4 4
5 5 {% block content-title %}SIR{% endblock %}
6 6 {% block content-suptitle %}Authetication{% endblock %}
7 7
8 8 {% block content %}
9 9 <div class='col-md-8'>
10 <form class="form" method="post" action="{% url 'django.contrib.auth.views.login' %}">
10 <form class="form" method="post" action="{% url 'url_login' %}">
11 11 {% csrf_token %}
12 12 {% bootstrap_form form %}
13 13 <input type="hidden" name="next" value="{{ next }}" />
14 14 {% buttons %}
15 15 <button type="submit" class="btn btn-primary">Login</button>
16 16 {% endbuttons %}
17 17 </form>
18 18 </div>
19 19 {% endblock %}
20 20
21 21 {% block messages%}
22 22 {% endblock %}
23 23
24 24 {% block sidebar%}
25 25 {% endblock %}
@@ -1,7 +1,7
1 from django.conf.urls import patterns, url
1 from django.conf.urls import url
2 2 from django.contrib.auth import views as auth_views
3 3
4 urlpatterns = patterns('',
5 url(r'^logout/$', 'django.contrib.auth.views.logout', {'next_page': '/'}),
6 url(r'^login/$', auth_views.login, {'template_name': 'login.html'}),
4 urlpatterns = (
5 url(r'^logout/$', auth_views.logout, {'next_page': '/'}, name='url_logout'),
6 url(r'^login/$', auth_views.login, {'template_name': 'login.html'}, name='url_login'),
7 7 )
@@ -1,182 +1,179
1 1 from django.db import models
2 2 from apps.main.models import Configuration
3 3 from django.core.validators import MinValueValidator, MaxValueValidator
4 4
5
6 from apps.main.models import Device, Experiment
7
8 from files import read_json_file
5 from .files import read_json_file
9 6 # Create your models here. validators=[MinValueValidator(62.5e6), MaxValueValidator(450e6)]
10 7
11 8 class CGSConfiguration(Configuration):
12 9
13 10 freq0 = models.PositiveIntegerField(verbose_name='Frequency 0',validators=[MaxValueValidator(450e6)], default = 60)
14 11 freq1 = models.PositiveIntegerField(verbose_name='Frequency 1',validators=[MaxValueValidator(450e6)], default = 60)
15 12 freq2 = models.PositiveIntegerField(verbose_name='Frequency 2',validators=[MaxValueValidator(450e6)], default = 60)
16 13 freq3 = models.PositiveIntegerField(verbose_name='Frequency 3',validators=[MaxValueValidator(450e6)], default = 60)
17 14
18 15 def verify_frequencies(self):
19 16
20 17 return True
21 18
22 19
23 20 def update_from_file(self, fp):
24 21
25 22 kwargs = read_json_file(fp)
26 23
27 24 if not kwargs:
28 25 return False
29 26
30 27 self.freq0 = kwargs['freq0']
31 28 self.freq1 = kwargs['freq1']
32 29 self.freq2 = kwargs['freq2']
33 30 self.freq3 = kwargs['freq3']
34 31
35 32 return True
36 33
37 34 def parms_to_dict(self):
38 35
39 36 parameters = {}
40 37
41 38 parameters['device_id'] = self.device.id
42 39
43 40 if self.freq0 == None or self.freq0 == '':
44 41 parameters['freq0'] = 0
45 42 else:
46 43 parameters['freq0'] = self.freq0
47 44
48 45 if self.freq1 == None or self.freq1 == '':
49 46 parameters['freq1'] = 0
50 47 else:
51 48 parameters['freq1'] = self.freq1
52 49
53 50 if self.freq2 == None or self.freq2 == '':
54 51 parameters['freq2'] = 0
55 52 else:
56 53 parameters['freq2'] = self.freq2
57 54
58 55 if self.freq3 == None or self.freq3 == '':
59 56 parameters['freq3'] = 0
60 57 else:
61 58 parameters['freq3'] = self.freq3
62 59
63 60 return parameters
64 61
65 62
66 63 def dict_to_parms(self, parameters):
67 64
68 65 self.freq0 = parameters['freq0']
69 66 self.freq1 = parameters['freq1']
70 67 self.freq2 = parameters['freq2']
71 68 self.freq3 = parameters['freq3']
72 69
73 70
74 71 def status_device(self):
75 72
76 73 import requests
77 74
78 75 ip=self.device.ip_address
79 76 port=self.device.port_address
80 77
81 78 route = "http://" + str(ip) + ":" + str(port) + "/status/ad9548"
82 79 try:
83 80 r = requests.get(route,timeout=0.5)
84 81 except:
85 82 self.device.status = 0
86 83 self.device.save()
87 84 return self.device.status
88 85
89 86 response = str(r.text)
90 87 response = response.split(";")
91 88 icon = response[0]
92 89 status = response[-1]
93 90
94 print icon, status
91 #print(icon, status)
95 92 #"icon" could be: "alert" or "okay"
96 93 if "alert" in icon:
97 94 if "Starting Up" in status: #No Esta conectado
98 95 self.device.status = 0
99 96 else:
100 97 self.device.status = 1
101 98 elif "okay" in icon:
102 99 self.device.status = 3
103 100 else:
104 101 self.device.status = 1
105 102
106 103 self.message = status
107 104 self.device.save()
108 105
109 106
110 107 return self.device.status
111 108
112 109
113 110 def read_device(self):
114 111
115 112 import requests
116 113
117 114 ip=self.device.ip_address
118 115 port=self.device.port_address
119 116
120 117 route = "http://" + str(ip) + ":" + str(port) + "/frequencies/"
121 118 try:
122 119 frequencies = requests.get(route,timeout=0.5)
123 120
124 121 except:
125 122 self.message = "Could not read CGS parameters from this device"
126 123 return None
127 124
128 125 frequencies = frequencies.json()
129 126 frequencies = frequencies.get("Frecuencias")
130 127 f0 = frequencies.get("f0")
131 128 f1 = frequencies.get("f1")
132 129 f2 = frequencies.get("f2")
133 130 f3 = frequencies.get("f3")
134 131
135 132 parms = {'freq0': f0,
136 133 'freq1': f1,
137 134 'freq2': f2,
138 135 'freq3': f3}
139 136
140 137 self.message = ""
141 138 return parms
142 139
143 140
144 141 def write_device(self):
145 142
146 143 import requests
147 144
148 145 ip=self.device.ip_address
149 146 port=self.device.port_address
150 147
151 148 #---Frequencies from form
152 149 f0 = self.freq0
153 150 f1 = self.freq1
154 151 f2 = self.freq2
155 152 f3 = self.freq3
156 153 post_data = {"f0":f0, "f1":f1, "f2":f2, "f3":f3}
157 154 route = "http://" + str(ip) + ":" + str(port) + "/frequencies/"
158 155
159 156 try:
160 157 r = requests.post(route, post_data, timeout=0.5)
161 158 except:
162 159 self.message = "Could not write CGS parameters"
163 160 return None
164 161
165 162 text = r.text
166 163 text = text.split(',')
167 164
168 165 if len(text)>1:
169 166 title = text[0]
170 167 status = text[1]
171 168 if title == "okay":
172 169 self.message = status
173 170 return 3
174 171 else:
175 172 self.message = title + ", " + status
176 173 return 1
177 174
178 175 return 1
179 176
180 177
181 178 class Meta:
182 179 db_table = 'cgs_configurations'
@@ -1,14 +1,8
1 1 from django.conf.urls import url
2 2
3 from apps.cgs import views
4
3 5 urlpatterns = (
4 url(r'^(?P<id_conf>-?\d+)/$', 'apps.cgs.views.cgs_conf', name='url_cgs_conf'),
5 url(r'^(?P<id_conf>-?\d+)/edit/$', 'apps.cgs.views.cgs_conf_edit', name='url_edit_cgs_conf'),
6 #url(r'^(?P<id_conf>-?\d+)/(?P<message>-?\d+)/$', 'apps.cgs.views.cgs_conf', name='url_cgs_conf'),
7 # url(r'^(?P<id_conf>-?\d+)/edit/$', 'apps.cgs.views.cgs_conf_edit', name='url_edit_cgs_conf'),
8 # url(r'^(?P<id_conf>-?\d+)/write/$', 'apps.cgs.views.cgs_conf_write', name='url_write_cgs_conf'),
9 # url(r'^(?P<id_conf>-?\d+)/read/$', 'apps.cgs.views.cgs_conf_read', name='url_read_cgs_conf'),
10 # url(r'^(?P<id_conf>-?\d+)/import/$', 'apps.cgs.views.cgs_conf_import', name='url_import_cgs_conf'),
11 # url(r'^(?P<id_conf>-?\d+)/export/$', 'apps.cgs.views.cgs_conf_export', name='url_export_cgs_conf'),
12 #url(r'^(?P<id_conf>-?\d+)/export/$', 'apps.main.views.dev_conf_export', name='url_export_cgs_conf'),
6 url(r'^(?P<id_conf>-?\d+)/$', views.cgs_conf, name='url_cgs_conf'),
7 url(r'^(?P<id_conf>-?\d+)/edit/$', views.cgs_conf_edit, name='url_edit_cgs_conf'),
13 8 )
14
@@ -1,322 +1,322
1 1 from django.shortcuts import redirect, render, get_object_or_404
2 2 from django.contrib import messages
3 3 from django.http import HttpResponse
4 4
5 from apps.main.models import Experiment, Configuration
5 from apps.main.models import Experiment
6 6 from .models import CGSConfiguration
7 7
8 8 from .forms import CGSConfigurationForm, UploadFileForm
9 9 from apps.main.views import sidebar
10 10
11 11 import requests
12 12 import json
13 13 #from __builtin__ import None
14 14 # Create your views here.
15 15
16 16 def cgs_conf(request, id_conf):
17 17
18 18 conf = get_object_or_404(CGSConfiguration, pk=id_conf)
19 19
20 20 ip=conf.device.ip_address
21 21 port=conf.device.port_address
22 22
23 23 kwargs = {}
24 24
25 25 kwargs['status'] = conf.device.get_status_display()
26 26
27 27 #if request.method=='GET':
28 28 #r: response = icon, status
29 29 # try:
30 30 # route = "http://" + str(ip) + ":" + str(port) + "/status/ad9548"
31 31 # r = requests.get(route)
32 32 # response = str(r.text)
33 33 # response = response.split(";")
34 34 # icon = response[0]
35 35 # status = response[-1]
36 36 #print r.text
37 37 #"icon" could be: "alert" or "okay"
38 38 # Si hay alerta pero esta conectado
39 39 # if "alert" in icon:
40 40 # if "Starting Up" in status: #No Esta conectado
41 41 # kwargs['connected'] = False
42 42 # else:
43 43 # kwargs['connected'] = True
44 44 # elif "okay" in icon:
45 45 # kwargs['connected'] = True
46 46 # else:
47 47 # kwargs['connected'] = False
48 48
49 49 # except:
50 50 # kwargs['connected'] = False
51 51 # status = "The Device is not connected."
52 52
53 53 #if not kwargs['connected']:
54 54 # messages.error(request, message=status)
55 55
56 56 kwargs['dev_conf'] = conf
57 57 kwargs['dev_conf_keys'] = ['name',
58 58 'freq0', 'freq1',
59 59 'freq2', 'freq3']
60 60
61 61 kwargs['title'] = 'CGS Configuration'
62 62 kwargs['suptitle'] = 'Details'
63 63
64 64 kwargs['button'] = 'Edit Configuration'
65 65
66 66 kwargs['no_play'] = True
67 67
68 68 ###### SIDEBAR ######
69 69 kwargs.update(sidebar(conf=conf))
70 70
71 71 return render(request, 'cgs_conf.html', kwargs)
72 72
73 73 def cgs_conf_edit(request, id_conf):
74 74
75 75 conf = get_object_or_404(CGSConfiguration, pk=id_conf)
76 76
77 77 if request.method=='GET':
78 78 form = CGSConfigurationForm(instance=conf)
79 79
80 80 if request.method=='POST':
81 81 form = CGSConfigurationForm(request.POST, instance=conf)
82 82
83 83 if form.is_valid():
84 84 if conf.freq0 == None: conf.freq0 = 0
85 85 if conf.freq1 == None: conf.freq1 = 0
86 86 if conf.freq2 == None: conf.freq2 = 0
87 87 if conf.freq3 == None: conf.freq3 = 0
88 88
89 89 conf = form.save(commit=False)
90 90
91 91 if conf.verify_frequencies():
92 92 conf.save()
93 93 return redirect('url_cgs_conf', id_conf=conf.id)
94 94
95 95 ##ERRORS
96 96
97 97 kwargs = {}
98 98 kwargs['id_dev'] = conf.id
99 99 kwargs['form'] = form
100 100 kwargs['title'] = 'Device Configuration'
101 101 kwargs['suptitle'] = 'Edit'
102 102 kwargs['button'] = 'Save'
103 103
104 104 return render(request, 'cgs_conf_edit.html', kwargs)
105 105 #
106 106 # def cgs_conf_write(request, id_conf):
107 107 #
108 108 # conf = get_object_or_404(CGSConfiguration, pk=id_conf)
109 109 # ip=conf.device.ip_address
110 110 # port=conf.device.port_address
111 111 #
112 112 # #Frequencies from form
113 113 # f0 = conf.freq0
114 114 # f1 = conf.freq1
115 115 # f2 = conf.freq2
116 116 # f3 = conf.freq3
117 117 #
118 118 # try:
119 119 # post_data = {"f0":f0, "f1":f1, "f2":f2, "f3":f3}
120 120 # route = "http://" + str(ip) + ":" + str(port) + "/frequencies/"
121 121 # r = requests.post(route, post_data)
122 122 # text = r.text
123 123 # text = text.split(',')
124 124 #
125 125 # try:
126 126 # if len(text)>1:
127 127 # title = text[0]
128 128 # status = text[1]
129 129 # status_ok = r.status_code
130 130 # if title == "okay":
131 131 # messages.success(request, status)
132 132 # else:
133 133 # messages.error(request, status)
134 134 #
135 135 # else:
136 136 # title = text[0]
137 137 # messages.error(request, title)
138 138 #
139 139 # except:
140 140 # messages.error(request, "An hardware error was found.")
141 141 #
142 142 # except:
143 143 # messages.error(request, "Could not write parameters.")
144 144 #
145 145 #
146 146 #
147 147 #
148 148 # return redirect('url_cgs_conf', id_conf=conf.id)
149 149 #
150 150 # def cgs_conf_read(request, id_conf):
151 151 #
152 152 # conf = get_object_or_404(CGSConfiguration, pk=id_conf)
153 153 #
154 154 # ip=conf.device.ip_address
155 155 # port=conf.device.port_address
156 156 #
157 157 # if request.method=='POST':
158 158 # form = CGSConfigurationForm(request.POST, instance=conf)
159 159 #
160 160 # if form.is_valid():
161 161 # cgs_model = form.save(commit=False)
162 162 #
163 163 # if cgs_model.verify_frequencies():
164 164 #
165 165 # cgs_model.save()
166 166 # return redirect('url_cgs_conf', id_conf=conf.id)
167 167 #
168 168 # messages.error(request, "Parameters could not be saved. Invalid parameters")
169 169 #
170 170 # data = {}
171 171 #
172 172 #
173 173 # if request.method=='GET':
174 174 # #r: response = icon, status
175 175 # route = "http://" + str(ip) + ":" + str(port) + "/status/ad9548"
176 176 # try:
177 177 # r = requests.get(route)
178 178 # response = str(r.text)
179 179 # response = response.split(";")
180 180 # icon = response[0]
181 181 # status = response[-1]
182 182 # print r.text
183 183 # #"icon" could be: "alert" or "okay"
184 184 # if "okay" in icon:
185 185 # messages.success(request, status)
186 186 # else:
187 187 # messages.error(request, status)
188 188 # #Get Frequencies
189 189 # route = "http://" + str(ip) + ":" + str(port) + "/frequencies/"
190 190 # #frequencies = requests.get('http://10.10.10.175:8080/frequencies/')
191 191 # frequencies = requests.get(route)
192 192 # frequencies = frequencies.json()
193 193 # frequencies = frequencies.get("Frecuencias")
194 194 # f0 = frequencies.get("f0")
195 195 # f1 = frequencies.get("f1")
196 196 # f2 = frequencies.get("f2")
197 197 # f3 = frequencies.get("f3")
198 198 # print f0,f1,f2,f3
199 199 #
200 200 #
201 201 # if not response:
202 202 # messages.error(request, "Could not read parameters from Device")
203 203 # return redirect('url_cgs_conf', id_conf=conf.id)
204 204 #
205 205 # data = {'experiment' : conf.experiment.id,
206 206 # 'device' : conf.device.id,
207 207 # 'freq0' : f0,
208 208 # 'freq1' : f1,
209 209 # 'freq2' : f2,
210 210 # 'freq3' : f3,
211 211 # }
212 212 # except:
213 213 # messages.error(request, "Could not read parameters from Device")
214 214 # data = {'experiment' : conf.experiment.id,
215 215 # 'device' : conf.device.id,
216 216 # 'freq0' : None,
217 217 # 'freq1' : None,
218 218 # 'freq2' : None,
219 219 # 'freq3' : None,
220 220 # }
221 221 # return redirect('url_cgs_conf', id_conf=conf.id)
222 222 #
223 223 # form = CGSConfigurationForm(initial = data)
224 224 #
225 225 # kwargs = {}
226 226 # kwargs['id_dev'] = conf.id
227 227 # kwargs['form'] = form
228 228 # kwargs['title'] = 'Device Configuration'
229 229 # kwargs['suptitle'] = 'Parameters read from device'
230 230 # kwargs['button'] = 'Save'
231 231 #
232 232 # ###### SIDEBAR ######
233 233 # kwargs.update(sidebar(conf))
234 234 #
235 235 # return render(request, 'cgs_conf_edit.html', kwargs)
236 236 #
237 237 # def cgs_conf_import(request, id_conf):
238 238 #
239 239 # conf = get_object_or_404(CGSConfiguration, pk=id_conf)
240 240 #
241 241 # if request.method == 'POST':
242 242 # file_form = UploadFileForm(request.POST, request.FILES)
243 243 #
244 244 # if file_form.is_valid():
245 245 #
246 246 # try:
247 247 # if conf.update_from_file(request.FILES['file']):
248 248 #
249 249 # try:
250 250 # conf.full_clean()
251 251 # except ValidationError as e:
252 252 # messages.error(request, e)
253 253 # else:
254 254 # conf.save()
255 255 #
256 256 # messages.success(request, "Parameters imported from file: '%s'." %request.FILES['file'].name)
257 257 # #messages.warning(request,"")
258 258 # return redirect('url_cgs_conf', id_conf=conf.id)
259 259 # except:
260 260 # messages.error(request, "No JSON object could be decoded.")
261 261 #
262 262 # messages.error(request, "Could not import parameters from file")
263 263 #
264 264 # else:
265 265 # file_form = UploadFileForm(initial={'title': '.json'})
266 266 #
267 267 #
268 268 # kwargs = {}
269 269 # kwargs['id_dev'] = conf.id
270 270 # kwargs['title'] = 'Device Configuration'
271 271 # kwargs['form'] = file_form
272 272 # kwargs['suptitle'] = 'Importing file'
273 273 # kwargs['button'] = 'Import'
274 274 #
275 275 # kwargs.update(sidebar(conf))
276 276 #
277 277 # return render(request, 'cgs_conf_import.html', kwargs)
278 278 #
279 279 # def handle_uploaded_file(f):
280 280 #
281 281 # data = {'freq0' : 62500000,
282 282 # 'freq1' : 62500000,
283 283 # 'freq2' : 62500000,
284 284 # 'freq3' : 62500000,
285 285 # }
286 286 #
287 287 # return data
288 288 #
289 289 # def cgs_conf_export(request, id_conf):
290 290 #
291 291 # conf = get_object_or_404(CGSConfiguration, pk=id_conf)
292 292 # ip=conf.device.ip_address
293 293 # port=conf.device.port_address
294 294 #
295 295 # #if request.method=='GET':
296 296 # # data = {"Frequencies": [
297 297 # # ["freq0", conf.freq0],
298 298 # # ["freq1", conf.freq1],
299 299 # # ["freq2", conf.freq2],
300 300 # # ["freq3", conf.freq3]
301 301 # # ]}
302 302 # # json_data = json.dumps(data)
303 303 # # conf.parameters = json_data
304 304 # # response = HttpResponse(conf.parameters, content_type="application/json")
305 305 # # response['Content-Disposition'] = 'attachment; filename="data.json"'
306 306 #
307 307 # # return response
308 308 #
309 309 # kwargs = {}
310 310 # kwargs['dev_conf'] = conf
311 311 # kwargs['dev_conf_keys'] = ['experiment', 'device',
312 312 # 'freq0', 'freq1',
313 313 # 'freq2', 'freq3']
314 314 #
315 315 # kwargs['title'] = 'CGS Configuration'
316 316 # kwargs['suptitle'] = 'Details'
317 317 #
318 318 # kwargs['button'] = 'Edit Configuration'
319 319 #
320 320 # ###### SIDEBAR ######
321 321 # kwargs.update(sidebar(conf))
322 322 # return render(request, 'cgs_conf.html', kwargs)
@@ -1,230 +1,229
1 1 from django.db import models
2 2 from apps.main.models import Configuration
3 3 # Create your models here.
4 4
5 5 from django.core.validators import MinValueValidator, MaxValueValidator
6 6 from django.core.exceptions import ValidationError
7 7
8 8 from devices.dds import api, data
9 9
10 10 ENABLE_TYPE = (
11 11 (False, 'Disabled'),
12 12 (True, 'Enabled'),
13 13 )
14 14 MOD_TYPES = (
15 15 (0, 'Single Tone'),
16 16 (1, 'FSK'),
17 17 (2, 'Ramped FSK'),
18 18 (3, 'Chirp'),
19 19 (4, 'BPSK'),
20 20 )
21 21
22 22 class DDSConfiguration(Configuration):
23 23
24 24 DDS_NBITS = 48
25 25
26 26 clock = models.FloatField(verbose_name='Clock In (MHz)',validators=[MinValueValidator(5), MaxValueValidator(75)], null=True, default=60)
27 27 multiplier = models.PositiveIntegerField(verbose_name='Multiplier',validators=[MinValueValidator(1), MaxValueValidator(20)], default=4)
28 28
29 29 frequencyA_Mhz = models.DecimalField(verbose_name='Frequency A (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16, null=True, default=49.9200)
30 30 frequencyA = models.BigIntegerField(verbose_name='Frequency A (Decimal)',validators=[MinValueValidator(0), MaxValueValidator(2**DDS_NBITS-1)], blank=True, null=True)
31 31
32 32 frequencyB_Mhz = models.DecimalField(verbose_name='Frequency B (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16, blank=True, null=True)
33 33 frequencyB = models.BigIntegerField(verbose_name='Frequency B (Decimal)',validators=[MinValueValidator(0), MaxValueValidator(2**DDS_NBITS-1)], blank=True, null=True)
34 34
35 35 phaseA_degrees = models.FloatField(verbose_name='Phase A (Degrees)', validators=[MinValueValidator(0), MaxValueValidator(360)], default=0)
36 36
37 37 phaseB_degrees = models.FloatField(verbose_name='Phase B (Degrees)', validators=[MinValueValidator(0), MaxValueValidator(360)], blank=True, null=True)
38 38
39 39 modulation = models.PositiveIntegerField(verbose_name='Modulation Type', choices = MOD_TYPES, default = 0)
40 40
41 41 amplitude_enabled = models.BooleanField(verbose_name='Amplitude Control', choices=ENABLE_TYPE, default=False)
42 42
43 43 amplitudeI = models.PositiveIntegerField(verbose_name='Amplitude CH1',validators=[MinValueValidator(0), MaxValueValidator(2**12-1)], blank=True, null=True)
44 44 amplitudeQ = models.PositiveIntegerField(verbose_name='Amplitude CH2',validators=[MinValueValidator(0), MaxValueValidator(2**12-1)], blank=True, null=True)
45 45
46 46
47 47 def get_nbits(self):
48 48
49 49 return self.DDS_NBITS
50 50
51 51 def clean(self):
52 52
53 53 if self.modulation in [1,2,3]:
54 54 if self.frequencyB is None or self.frequencyB_Mhz is None:
55 55 raise ValidationError({
56 56 'frequencyB': 'Frequency modulation has to be defined when FSK or Chirp modulation is selected'
57 57 })
58 58
59 59 if self.modulation in [4,]:
60 60 if self.phaseB_degrees is None:
61 61 raise ValidationError({
62 62 'phaseB': 'Phase modulation has to be defined when BPSK modulation is selected'
63 63 })
64 64
65 65 self.frequencyA_Mhz = data.binary_to_freq(self.frequencyA, self.clock*self.multiplier)
66 66 self.frequencyB_Mhz = data.binary_to_freq(self.frequencyB, self.clock*self.multiplier)
67 67
68 68 def verify_frequencies(self):
69 69
70 70 return True
71 71
72 72 def parms_to_dict(self):
73 73
74 74 parameters = {}
75 75
76 76 parameters['device_id'] = self.device.id
77 77
78 78 parameters['clock'] = float(self.clock)
79 79 parameters['multiplier'] = int(self.multiplier)
80 80
81 81 parameters['frequencyA'] = int(self.frequencyA)
82 82 parameters['frequencyA_Mhz'] = float(self.frequencyA_Mhz)
83 83
84 84 parameters['phaseA'] = data.phase_to_binary(self.phaseA_degrees)
85 85 parameters['phaseA_degrees'] = float(self.phaseA_degrees)
86 86
87 87 parameters['modulation'] = int(self.modulation)
88 88 parameters['amplitude_enabled'] = bool(self.amplitude_enabled)
89 89
90 90 if self.frequencyB:
91 91 parameters['frequencyB'] = int(self.frequencyB)
92 92 parameters['frequencyB_Mhz'] = float(self.frequencyB_Mhz)
93 93 else:
94 94 parameters['frequencyB'] = 0
95 95 parameters['frequencyB_Mhz'] = 0
96 96
97 97 if self.phaseB_degrees:
98 98 parameters['phaseB_degrees'] = float(self.phaseB_degrees)
99 99 parameters['phaseB'] = data.phase_to_binary(self.phaseB_degrees)
100 100 else:
101 101 parameters['phaseB_degrees'] = 0
102 102 parameters['phaseB'] = 0
103 103
104 104 if self.amplitudeI:
105 105 parameters['amplitudeI'] = int(self.amplitudeI)
106 106 else:
107 107 parameters['amplitudeI'] = 0
108 108
109 109 if self.amplitudeQ:
110 110 parameters['amplitudeQ'] = int(self.amplitudeQ)
111 111 else:
112 112 parameters['amplitudeQ'] = 0
113 113
114 114 return parameters
115 115
116 116 def parms_to_text(self):
117 117
118 118 my_dict = self.parms_to_dict()
119 119
120 120 text = data.dict_to_text(my_dict)
121 121
122 122 return text
123 123
124 124 def dict_to_parms(self, parameters):
125 125
126 126 self.clock = parameters['clock']
127 127 self.multiplier = parameters['multiplier']
128 128 self.frequencyA = parameters['frequencyA']
129 129 self.frequencyB = parameters['frequencyB']
130 130 self.frequencyA_Mhz = parameters['frequencyA_Mhz']
131 131 self.frequencyB_Mhz = parameters['frequencyB_Mhz']
132 132 self.phaseA_degrees = parameters['phaseA_degrees']
133 133 self.phaseB_degrees = parameters['phaseB_degrees']
134 134 self.modulation = parameters['modulation']
135 135 self.amplitude_enabled = parameters['amplitude_enabled']
136 136
137 137 def import_from_file(self, fp):
138 138
139 139 import os, json
140 140
141 141 parms = {}
142 142
143 143 path, ext = os.path.splitext(fp.name)
144 144
145 145 if ext == '.json':
146 146 parms = json.load(fp)
147 147
148 148 if ext == '.dds':
149 149 lines = fp.readlines()
150 150 parms = data.text_to_dict(lines)
151 151
152 152 return parms
153 153
154 154 def status_device(self):
155 155
156 156 answer = api.status(ip = self.device.ip_address,
157 157 port = self.device.port_address)
158 158
159 159 self.device.status = int(answer[0])
160 160 self.message = answer[2:]
161 161
162 162 self.device.save()
163 163
164 164 return self.device.status
165 165
166 166 def reset_device(self):
167 167
168 168 answer = api.reset(ip = self.device.ip_address,
169 169 port = self.device.port_address)
170 170
171 171 if answer[0] != "1":
172 172 self.message = answer[0:]
173 173 return 0
174 174
175 175 self.message = answer[2:]
176 176 return 1
177 177
178 178 def stop_device(self):
179 179
180 180 answer = api.disable_rf(ip = self.device.ip_address,
181 181 port = self.device.port_address)
182 182
183 183 if answer[0] != "1":
184 184 self.message = answer[0:]
185 185 return 0
186 186
187 187 self.message = answer[2:]
188 188 return 1
189 189
190 190 def start_device(self):
191 191
192 192 answer = api.enable_rf(ip = self.device.ip_address,
193 193 port = self.device.port_address)
194 194
195 195 if answer[0] != "1":
196 196 self.message = answer[0:]
197 197 return 0
198 198
199 199 self.message = answer[2:]
200 200 return 1
201 201
202 202 def read_device(self):
203 203
204 204 parms = api.read_config(ip = self.device.ip_address,
205 205 port = self.device.port_address)
206 206
207 207 if not parms:
208 208 self.message = "Could not read DDS parameters from this device"
209 209 return parms
210 210
211 211 self.message = ""
212 212 return parms
213 213
214 214
215 215 def write_device(self):
216 216
217 217 answer = api.write_config(ip = self.device.ip_address,
218 218 port = self.device.port_address,
219 219 parms = self.parms_to_dict())
220 220
221 221 if answer[0] != "1":
222 222 self.message = answer[0:]
223 223 return 0
224 224
225 225 self.message = answer[2:]
226 226 return 1
227 227
228 228 class Meta:
229 229 db_table = 'dds_configurations'
230 No newline at end of file
@@ -1,14 +1,9
1 1 from django.conf.urls import url
2 2
3 from apps.dds import views
4
3 5 urlpatterns = (
4 url(r'^(?P<id_conf>-?\d+)/$', 'apps.dds.views.dds_conf', name='url_dds_conf'),
5 url(r'^(?P<id_conf>-?\d+)/(?P<message>-?\d+)/$', 'apps.dds.views.dds_conf', name='url_dds_conf'),
6 url(r'^(?P<id_conf>-?\d+)/edit/$', 'apps.dds.views.dds_conf_edit', name='url_edit_dds_conf'),
7 # url(r'^(?P<id_conf>-?\d+)/write/$', 'apps.dds.views.dds_conf_write', name='url_write_dds_conf'),
8 # url(r'^(?P<id_conf>-?\d+)/read/$', 'apps.dds.views.dds_conf_read', name='url_read_dds_conf'),
9 # url(r'^(?P<id_conf>-?\d+)/import/$', 'apps.dds.views.dds_conf_import', name='url_import_dds_conf'),
10 # url(r'^(?P<id_conf>-?\d+)/export/$', 'apps.dds.views.dds_conf_export', name='url_export_dds_conf'),
11 # url(r'^(?P<id_conf>-?\d+)/start/$', 'apps.dds.views.dds_conf_start', name='url_start_dds_conf'),
12 # url(r'^(?P<id_conf>-?\d+)/stop/$', 'apps.dds.views.dds_conf_stop', name='url_stop_dds_conf'),
13 # url(r'^(?P<id_conf>-?\d+)/status/$', 'apps.dds.views.dds_conf_status', name='url_status_dds_conf'),
6 url(r'^(?P<id_conf>-?\d+)/$', views.dds_conf, name='url_dds_conf'),
7 url(r'^(?P<id_conf>-?\d+)/(?P<message>-?\d+)/$', views.dds_conf, name='url_dds_conf'),
8 url(r'^(?P<id_conf>-?\d+)/edit/$', views.dds_conf_edit, name='url_edit_dds_conf'),
14 9 )
@@ -1,2 +1,2
1 [{"fields": {"name": "49_920MHz_clock60MHz_F0MHz_12_25_2", "clock": "60", "mult": 5, "fch": 49.92, "fch_decimal": 721554505, "filter_fir": 6, "filter_2": 10, "filter_5": 1, "speed": 0}, "model": "jars.jarsfilter", "pk": 1},
1 [{"fields": {"name": "49_920MHz_clock60MHz_F0MHz_12_25_2", "clock": "60", "mult": 5, "fch": 49.92, "fch_decimal": 721554505, "filter_fir": 6, "filter_2": 10, "filter_5": 1, "speed": 0}, "model": "jars.jarsfilter", "pk": 1}
2 2 ]
1 NO CONTENT: modified file
@@ -1,11 +1,13
1 1 from django.conf.urls import url
2 2
3 from apps.jars import views
4
3 5 urlpatterns = (
4 url(r'^(?P<id_conf>-?\d+)/$', 'apps.jars.views.jars_conf', name='url_jars_conf'),
5 url(r'^(?P<id_conf>-?\d+)/edit/$', 'apps.jars.views.jars_conf_edit', name='url_edit_jars_conf'),
6 url(r'^(?P<conf_id>-?\d+)/new_filter/$', 'apps.jars.views.new_filter', name='url_new_jars_filter'),
7 url(r'^(?P<conf_id>-?\d+)/view_filter/(?P<filter_id>-?\d+)/$', 'apps.jars.views.view_filter', name='url_jars_filter'),
8 url(r'^(?P<conf_id>-?\d+)/view_filter/(?P<filter_id>-?\d+)/edit$', 'apps.jars.views.edit_filter', name='url_edit_jars_filter'),
9 url(r'^(?P<conf_id>-?\d+)/import/$', 'apps.jars.views.import_file', name='url_import_jars_conf'),
10 url(r'^(?P<conf_id>-?\d+)/read/$', 'apps.jars.views.read_conf', name='url_read_jars_conf'),
6 url(r'^(?P<id_conf>-?\d+)/$', views.jars_conf, name='url_jars_conf'),
7 url(r'^(?P<id_conf>-?\d+)/edit/$', views.jars_conf_edit, name='url_edit_jars_conf'),
8 url(r'^(?P<conf_id>-?\d+)/new_filter/$', views.new_filter, name='url_new_jars_filter'),
9 url(r'^(?P<conf_id>-?\d+)/view_filter/(?P<filter_id>-?\d+)/$', views.view_filter, name='url_jars_filter'),
10 url(r'^(?P<conf_id>-?\d+)/view_filter/(?P<filter_id>-?\d+)/edit$', views.edit_filter, name='url_edit_jars_filter'),
11 url(r'^(?P<conf_id>-?\d+)/import/$', views.import_file, name='url_import_jars_conf'),
12 url(r'^(?P<conf_id>-?\d+)/read/$', views.read_conf, name='url_read_jars_conf'),
11 13 )
@@ -1,164 +1,163
1 1
2 2 import ast
3 3 import json
4 4 from itertools import chain
5 5
6 6 from django import forms
7 7 from django.utils.safestring import mark_safe
8 from django.utils.encoding import force_unicode
9 8 from django.utils.html import conditional_escape
10 9
11 10
12 11 class SpectralWidget(forms.widgets.TextInput):
13 12
14 13 def render(self, label, value, attrs=None):
15 14
16 15 disabled = 'disabled' if attrs.get('disabled', False) else ''
17 16 name = attrs.get('name', label)
18 17 if '[' in value:
19 18 if value[len(value)-1] == ",":
20 19 value = ast.literal_eval(value)
21 20 else:
22 21 value = value + ","
23 22 value = ast.literal_eval(value)
24 23
25 24 codes = value
26 25 if not isinstance(value, list):
27 26 text=''
28 27 #lista = []
29 28 #if len(value) > 1:
30 29 for val in value:
31 30 text = text+str(val)+','
32 31 #lista.append(val)
33 32 codes=text
34 33 else:
35 34 codes=''
36 35
37 36 html = '''<textarea rows="5" {0} class="form-control" id="id_{1}" name="{2}" style="white-space:nowrap; overflow:scroll;">{3}</textarea>
38 37 <input type="text" class="col-md-1 col-no-padding" id="num1" value=0>
39 38 <input type="text" class="col-md-1 col-no-padding" id="num2" value=0>
40 39 <button type="button" class="button" id="add_spectral_button"> Add </button>
41 40 <button type="button" class="button" id="delete_spectral_button"> Delete </button>
42 41 <button type="button" class="button pull-right" id="cross_spectral_button"> Cross </button>
43 42 <button type="button" class="button pull-right" id="self_spectral_button"> Self </button>
44 43 <button type="button" class="button pull-right" id="all_spectral_button"> All </button>
45 44 '''.format(disabled, label, name, codes)
46 45
47 46 script = '''
48 47 <script type="text/javascript">
49 48 $(document).ready(function () {{
50 49
51 50 var spectral_number1 = $("#num1").val();
52 51 var spectral_number2 = $("#num2").val();
53 52
54 53
55 54 $("#all_spectral_button").click(function(){{
56 55 var sequence1 = selfSpectral()
57 56 var sequence2 = crossSpectral()
58 57 $("#id_spectral").val(sequence1+sequence2)
59 58 updateSpectralNumber()
60 59 }});
61 60
62 61
63 62 $("#add_spectral_button").click(function(){{
64 63 var spectral_comb = $("#id_spectral").val();
65 64 var spectral_number1 = $("#num1").val();
66 65 var spectral_number2 = $("#num2").val();
67 66 var str = spectral_number1+", "+spectral_number2;
68 67 //not to duplicate
69 68 var n = spectral_comb.search(str);
70 69 if (n==-1){
71 70 $("#id_spectral").val(spectral_comb+"["+$("#num1").val()+", "+$("#num2").val()+"],")
72 71 }
73 72 updateSpectralNumber()
74 73 }});
75 74
76 75
77 76 $("#self_spectral_button").click(function(){{
78 77 var sequence = selfSpectral()
79 78 $("#id_spectral").val(sequence)
80 79
81 80 updateSpectralNumber()
82 81 }});
83 82
84 83 $("#cross_spectral_button").click(function(){{
85 84 var sequence = crossSpectral()
86 85 $("#id_spectral").val(sequence)
87 86
88 87 updateSpectralNumber()
89 88 }});
90 89
91 90
92 91 function selfSpectral() {
93 92 var channels = $("#id_channels").val();
94 93 var n = (channels.length)-1;
95 94 var num = parseInt(channels[n]);
96 95 sequence = ""
97 96 for (i = 0; i < num; i++) {
98 97 sequence = sequence + "[" + i.toString() + ", " + i.toString() + "],"
99 98 }
100 99 return sequence
101 100 }
102 101
103 102
104 103 function crossSpectral() {
105 104 var channels = $("#id_channels").val();
106 105 var n = (channels.length)-1;
107 106 var num = parseInt(channels[n]);
108 107 sequence = ""
109 108 for (i = 0; i < num; i++) {
110 109 for (j = i+1; j < num; j++) {
111 110 sequence = sequence + "[" + i.toString() + ", " + j.toString() + "],"
112 111 }
113 112 }
114 113 return sequence
115 114 }
116 115
117 116
118 117 function updateSpectralNumber(){
119 118 var spectral_comb = $("#id_spectral").val();
120 119 var num = spectral_comb.length;
121 120 var cont = 0
122 121 for (i = 0; i < num; i++) {
123 122 if (spectral_comb[i] == "]"){
124 123 cont = cont + 1
125 124 }
126 125 }
127 126 $("#id_spectral_number").val(cont)
128 127 }
129 128
130 129
131 130 $("#delete_spectral_button").click(function(){{
132 131 var spectral_comb = $("#id_spectral").val();
133 132 var spectral_number1 = $("#num1").val();
134 133 var spectral_number2 = $("#num2").val();
135 134 var str = spectral_number1+", "+spectral_number2;
136 135 var n = spectral_comb.search(str);
137 136 if (n==-1){
138 137
139 138 }
140 139 else {
141 140 n= spectral_comb.length;
142 141 if (n<8){
143 142 var tuple = "["+$("#num1").val()+", "+$("#num2").val()+"],"
144 143 var txt = spectral_comb.replace(tuple,'');
145 144 }
146 145 else {
147 146 var tuple = ",["+$("#num1").val()+", "+$("#num2").val()+"]"
148 147 var txt = spectral_comb.replace(tuple,'');
149 148 }
150 149 $("#id_spectral").val(txt)
151 150
152 151 var tuple = "["+$("#num1").val()+", "+$("#num2").val()+"],"
153 152 var txt = spectral_comb.replace(tuple,'');
154 153 $("#id_spectral").val(txt)
155 154 }
156 155 updateSpectralNumber()
157 156 }});
158 157
159 158
160 159 }});
161 160 </script>
162 161 '''
163 162
164 163 return mark_safe(html+script)
@@ -1,10 +1,11
1 1 [
2 {"fields": {"name": "JRO Imaging", "description": ""}, "model": "main.location", "pk": 1},
2 {"fields": {"name": "JRO", "description": ""}, "model": "main.location", "pk": 1},
3 3 {"fields": {"name": "JASMET", "description": ""}, "model": "main.location", "pk": 2},
4 4 {"fields": {"name": "SOUSY", "description": ""}, "model": "main.location", "pk": 3},
5 5 {"fields": {"name": "JULIA", "description": ""}, "model": "main.location", "pk": 4},
6 6 {"fields": {"name": "rc", "description": ""}, "model": "main.devicetype", "pk": 1},
7 7 {"fields": {"name": "dds", "description": ""}, "model": "main.devicetype", "pk": 2},
8 8 {"fields": {"name": "cgs", "description": ""}, "model": "main.devicetype", "pk": 3},
9 {"fields": {"name": "jars", "description": ""}, "model": "main.devicetype", "pk": 4}
9 {"fields": {"name": "jars", "description": ""}, "model": "main.devicetype", "pk": 4},
10 {"fields": {"name": "abs", "description": ""}, "model": "main.devicetype", "pk": 5}
10 11 ]
@@ -1,190 +1,182
1 1 from django import forms
2 2 from django.utils.safestring import mark_safe
3
4 from .models import DeviceType, Device, Experiment, Campaign, Configuration, Location
3 from .models import Device, Experiment, Campaign, Location
4 from apps.main.models import Configuration
5 5
6 6 FILE_FORMAT = (
7 7 ('json', 'json'),
8 8 )
9 9
10 10 DDS_FILE_FORMAT = (
11 11 ('json', 'json'),
12 12 ('text', 'dds')
13 13 )
14 14
15 15 RC_FILE_FORMAT = (
16 16 ('json', 'json'),
17 17 ('text', 'racp'),
18 18 ('binary', 'dat'),
19 19 )
20 20
21 21 def add_empty_choice(choices, pos=0, label='-----'):
22 22 if len(choices)>0:
23 23 choices = list(choices)
24 24 choices.insert(0, (0, label))
25 25 return choices
26 26 else:
27 27 return [(0, label)]
28 28
29 29 class DatepickerWidget(forms.widgets.TextInput):
30 30 def render(self, name, value, attrs=None):
31 31 input_html = super(DatepickerWidget, self).render(name, value, attrs)
32 32 html = '<div class="input-group date">'+input_html+'<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span></div>'
33 33 return mark_safe(html)
34 34
35 35 class DateRangepickerWidget(forms.widgets.TextInput):
36 36 def render(self, name, value, attrs=None):
37 37 start = attrs['start_date']
38 38 end = attrs['end_date']
39 39 html = '''<div class="col-md-5 input-group date" style="float:inherit">
40 40 <input class="form-control" id="id_start_date" name="start_date" placeholder="Start" title="" type="text" value="{}">
41 41 <span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
42 42 </div>
43 43 <div class="col-md-5 col-md-offset-2 input-group date" style="float:inherit">
44 44 <input class="form-control" id="id_end_date" name="end_date" placeholder="End" title="" type="text" value="{}">
45 45 <span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
46 46 </div>'''.format(start, end)
47 47 return mark_safe(html)
48 48
49 49 class TimepickerWidget(forms.widgets.TextInput):
50 50 def render(self, name, value, attrs=None):
51 51 input_html = super(TimepickerWidget, self).render(name, value, attrs)
52 52 html = '<div class="input-group time">'+input_html+'<span class="input-group-addon"><i class="glyphicon glyphicon-time"></i></span></div>'
53 53 return mark_safe(html)
54 54
55 55 class CampaignForm(forms.ModelForm):
56 56
57 57 experiments = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(),
58 58 queryset=Experiment.objects.filter(template=True),
59 59 required=False)
60 60
61 61 def __init__(self, *args, **kwargs):
62 62 super(CampaignForm, self).__init__(*args, **kwargs)
63 63 self.fields['start_date'].widget = DatepickerWidget(self.fields['start_date'].widget.attrs)
64 64 self.fields['end_date'].widget = DatepickerWidget(self.fields['end_date'].widget.attrs)
65 65 self.fields['description'].widget.attrs = {'rows': 2}
66 66
67 67 if self.instance.pk:
68 68 self.fields['experiments'].queryset |= self.instance.experiments.all()
69 69
70 70 class Meta:
71 71 model = Campaign
72 72 exclude = ['']
73 73
74 74
75 75 class ExperimentForm(forms.ModelForm):
76 76
77 77 def __init__(self, *args, **kwargs):
78 78 super(ExperimentForm, self).__init__(*args, **kwargs)
79 79 self.fields['start_time'].widget = TimepickerWidget(self.fields['start_time'].widget.attrs)
80 80 self.fields['end_time'].widget = TimepickerWidget(self.fields['end_time'].widget.attrs)
81 81
82 82 class Meta:
83 83 model = Experiment
84 84 exclude = ['status']
85 85
86 86 class LocationForm(forms.ModelForm):
87 87 class Meta:
88 88 model = Location
89 89 exclude = ['']
90 90
91 91 class DeviceForm(forms.ModelForm):
92 92 class Meta:
93 93 model = Device
94 94 exclude = ['status']
95 95
96 96 class ConfigurationForm(forms.ModelForm):
97 97
98 98 def __init__(self, *args, **kwargs):
99 99 super(ConfigurationForm, self).__init__(*args, **kwargs)
100 100
101 101 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
102 102 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
103 103
104 104 class Meta:
105 105 model = Configuration
106 106 exclude = ['type', 'created_date', 'programmed_date', 'parameters']
107 107
108 class DeviceTypeForm(forms.Form):
109 device_type = forms.ChoiceField(choices=add_empty_choice(DeviceType.objects.all().order_by('name').values_list('id', 'name')))
108 #class DeviceTypeForm(forms.Form):
109 # device_type = forms.ChoiceField(choices=add_empty_choice(DeviceType.objects.all().order_by('name').values_list('id', 'name')))
110 110
111 111
112 112 class UploadFileForm(forms.Form):
113 113
114 114 file = forms.FileField()
115 115
116 116 class DownloadFileForm(forms.Form):
117 117
118 118 format = forms.ChoiceField(choices= ((0, 'json'),) )
119 119
120 120 def __init__(self, device_type, *args, **kwargs):
121 121
122 122 super(DownloadFileForm, self).__init__(*args, **kwargs)
123 123
124 124 self.fields['format'].choices = FILE_FORMAT
125 125
126 126 if device_type == 'dds':
127 127 self.fields['format'].choices = DDS_FILE_FORMAT
128 128
129 129 if device_type == 'rc':
130 130 self.fields['format'].choices = RC_FILE_FORMAT
131 131
132 132 class OperationForm(forms.Form):
133 # today = datetime.today()
134 # -----Campaigns from this month------[:5]
133
135 134 campaign = forms.ChoiceField(label="Campaign")
136 135
137 136 def __init__(self, *args, **kwargs):
138 137
139 if 'length' not in kwargs.keys():
140 length = None
141 else:
142 length = kwargs['length']
143
144 kwargs.pop('length')
145
138 campaigns = kwargs.pop('campaigns')
146 139 super(OperationForm, self).__init__(*args, **kwargs)
147 self.fields['campaign'].choices=Campaign.objects.all().order_by('-start_date').values_list('id', 'name')[:length]
140 self.fields['campaign'].choices=add_empty_choice(campaigns.values_list('id', 'name'))
148 141
149 142
150 143 class OperationSearchForm(forms.Form):
151 144 # -----ALL Campaigns------
152 145 campaign = forms.ChoiceField(label="Campaign")
153 146
154 147 def __init__(self, *args, **kwargs):
155 148 super(OperationSearchForm, self).__init__(*args, **kwargs)
156 149 self.fields['campaign'].choices=Campaign.objects.all().order_by('-start_date').values_list('id', 'name')
157 150
158 151
159 152 class NewForm(forms.Form):
160 153
161 154 create_from = forms.ChoiceField(choices=((0, '-----'),
162 155 (1, 'Empty (blank)'),
163 156 (2, 'Template')))
164 157 choose_template = forms.ChoiceField()
165 158
166 159 def __init__(self, *args, **kwargs):
167 160
168 161 template_choices = kwargs.pop('template_choices', [])
169 162 super(NewForm, self).__init__(*args, **kwargs)
170 163 self.fields['choose_template'].choices = add_empty_choice(template_choices)
171 164
172 165
173 166 class FilterForm(forms.Form):
174 167
175 168 def __init__(self, *args, **kwargs):
176 169 extra_fields = kwargs.pop('extra_fields', [])
177 170 super(FilterForm, self).__init__(*args, **kwargs)
178 171
179 172 for field in extra_fields:
180 173 if 'range_date' in field:
181 174 self.fields[field] = forms.CharField(required=False)
182 175 self.fields[field].widget = DateRangepickerWidget()
183 176 if 'initial' in kwargs:
184 177 self.fields[field].widget.attrs = {'start_date':kwargs['initial'].get('start_date', ''),
185 178 'end_date':kwargs['initial'].get('end_date', '')}
186 179 elif 'template' in field:
187 180 self.fields['template'] = forms.BooleanField(required=False)
188 181 else:
189 182 self.fields[field] = forms.CharField(required=False)
190 No newline at end of file
@@ -1,612 +1,616
1 1 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
2 2 from datetime import datetime
3 3
4 4 from django.db import models
5 from polymorphic import PolymorphicModel
5 from polymorphic.models import PolymorphicModel
6 6
7 7 from django.core.urlresolvers import reverse
8 8
9 9
10 10 CONF_STATES = (
11 11 (0, 'Disconnected'),
12 12 (1, 'Connected'),
13 13 (2, 'Running'),
14 14 )
15 15
16 16 EXP_STATES = (
17 17 (0,'Error'), #RED
18 18 (1,'Configured'), #BLUE
19 19 (2,'Running'), #GREEN
20 20 (3,'Waiting'), #YELLOW
21 21 (4,'Not Configured'), #WHITE
22 22 )
23 23
24 24 CONF_TYPES = (
25 25 (0, 'Active'),
26 26 (1, 'Historical'),
27 27 )
28 28
29 29 DEV_STATES = (
30 30 (0, 'No connected'),
31 31 (1, 'Connected'),
32 32 (2, 'Configured'),
33 33 (3, 'Running'),
34 34 )
35 35
36 36 DEV_TYPES = (
37 37 ('', 'Select a device type'),
38 38 ('rc', 'Radar Controller'),
39 39 ('rc_mix', 'Radar Controller (Mix)'),
40 40 ('dds', 'Direct Digital Synthesizer'),
41 41 ('jars', 'Jicamarca Radar Acquisition System'),
42 42 ('usrp', 'Universal Software Radio Peripheral'),
43 43 ('cgs', 'Clock Generator System'),
44 44 ('abs', 'Automatic Beam Switching'),
45 45 )
46 46
47 47 DEV_PORTS = {
48 48 'rc' : 2000,
49 49 'rc_mix': 2000,
50 50 'dds' : 2000,
51 51 'jars' : 2000,
52 52 'usrp' : 2000,
53 53 'cgs' : 8080,
54 54 'abs' : 8080
55 55 }
56 56
57 57 RADAR_STATES = (
58 58 (0, 'No connected'),
59 59 (1, 'Connected'),
60 60 (2, 'Configured'),
61 61 (3, 'Running'),
62 62 (4, 'Scheduled'),
63 63 )
64 64 # Create your models here.
65 65
66 66 class Location(models.Model):
67 67
68 68 name = models.CharField(max_length = 30)
69 69 description = models.TextField(blank=True, null=True)
70 70
71 71 class Meta:
72 72 db_table = 'db_location'
73 73
74 def __unicode__(self):
74 def __str__(self):
75 75 return u'%s' % self.name
76 76
77 77 def get_absolute_url(self):
78 78 return reverse('url_location', args=[str(self.id)])
79 79
80 80
81 81 class DeviceType(models.Model):
82 82
83 83 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc')
84 84 description = models.TextField(blank=True, null=True)
85 85
86 86 class Meta:
87 87 db_table = 'db_device_types'
88 88
89 def __unicode__(self):
89 def __str__(self):
90 90 return u'%s' % self.get_name_display()
91 91
92 92 class Device(models.Model):
93 93
94 94 device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
95 95 location = models.ForeignKey(Location, on_delete=models.CASCADE)
96 96
97 97 name = models.CharField(max_length=40, default='')
98 98 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
99 99 port_address = models.PositiveSmallIntegerField(default=2000)
100 100 description = models.TextField(blank=True, null=True)
101 101 status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES)
102 102
103 103 class Meta:
104 104 db_table = 'db_devices'
105 105
106 def __unicode__(self):
106 def __str__(self):
107 107 return u'[{}]: {}'.format(self.device_type.name.upper(),
108 108 self.name)
109 109
110 110 def get_status(self):
111 111 return self.status
112 112
113 113 @property
114 114 def status_color(self):
115 115 color = 'muted'
116 116 if self.status == 0:
117 117 color = "danger"
118 118 elif self.status == 1:
119 119 color = "warning"
120 120 elif self.status == 2:
121 121 color = "info"
122 122 elif self.status == 3:
123 123 color = "success"
124 124
125 125 return color
126 126
127 127 def get_absolute_url(self):
128 128 return reverse('url_device', args=[str(self.id)])
129 129
130 130
131 131 class Campaign(models.Model):
132 132
133 133 template = models.BooleanField(default=False)
134 134 name = models.CharField(max_length=60, unique=True)
135 135 start_date = models.DateTimeField(blank=True, null=True)
136 136 end_date = models.DateTimeField(blank=True, null=True)
137 137 tags = models.CharField(max_length=40)
138 138 description = models.TextField(blank=True, null=True)
139 139 experiments = models.ManyToManyField('Experiment', blank=True)
140 140
141 141 class Meta:
142 142 db_table = 'db_campaigns'
143 143 ordering = ('name',)
144 144
145 def __unicode__(self):
145 def __str__(self):
146 146 if self.template:
147 147 return u'{} (template)'.format(self.name)
148 148 else:
149 149 return u'{}'.format(self.name)
150 150
151
152 151 def parms_to_dict(self):
153 152
154 153 import json
155 154
156 155 parameters = {}
157 156 exp_parameters = {}
158 157 experiments = Experiment.objects.filter(campaign = self)
159 158
160 159 i=1
161 160 for experiment in experiments:
162 161 exp_parameters['experiment-'+str(i)] = json.loads(experiment.parms_to_dict())
163 162 i += 1
164 163
165 164
166 165 parameters['experiments'] = exp_parameters
167 166 parameters['end_date'] = self.end_date.strftime("%Y-%m-%d")
168 167 parameters['start_date'] = self.start_date.strftime("%Y-%m-%d")
169 parameters['campaign'] = self.__unicode__()
168 parameters['campaign'] = self.__str__()
170 169 parameters['tags'] =self.tags
171 170
172 171 parameters = json.dumps(parameters, indent=2, sort_keys=False)
173 172
174 173 return parameters
175 174
176 175 def import_from_file(self, fp):
177 176
178 177 import os, json
179 178
180 179 parms = {}
181 180
182 181 path, ext = os.path.splitext(fp.name)
183 182
184 183 if ext == '.json':
185 parms = json.load(fp)
184 parms = json.loads(fp.read())
186 185
187 186 return parms
188 187
189 188 def dict_to_parms(self, parms, CONF_MODELS):
190 189
191 190 experiments = Experiment.objects.filter(campaign = self)
192 191 configurations = Configuration.objects.filter(experiment = experiments)
193 192
194 193 if configurations:
195 194 for configuration in configurations:
196 195 configuration.delete()
197 196
198 197 if experiments:
199 198 for experiment in experiments:
200 199 experiment.delete()
201 200
202 201 for parms_exp in parms['experiments']:
203 202 location = Location.objects.get(name = parms['experiments'][parms_exp]['radar'])
204 203 new_exp = Experiment(
205 204 name = parms['experiments'][parms_exp]['experiment'],
206 205 location = location,
207 206 start_time = parms['experiments'][parms_exp]['start_time'],
208 207 end_time = parms['experiments'][parms_exp]['end_time'],
209 208 )
210 209 new_exp.save()
211 210 new_exp.dict_to_parms(parms['experiments'][parms_exp],CONF_MODELS)
212 211 new_exp.save()
213 212
214 213 self.name = parms['campaign']
215 214 self.start_date = parms['start_date']
216 215 self.end_date = parms['end_date']
217 216 self.tags = parms['tags']
218 217 self.experiments.add(new_exp)
219 218 self.save()
220 219
221 220 return self
222 221
222 def get_experiments_by_location(self):
223
224 ret = []
225 locations = set([e.location for e in self.experiments.all()])
226 for loc in locations:
227 dum = {}
228 dum['name'] = loc.name
229 dum['id'] = loc.pk
230 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
231 ret.append(dum)
232
233 return ret
234
223 235 def get_absolute_url(self):
224 236 return reverse('url_campaign', args=[str(self.id)])
225 237
226 238 def get_absolute_url_edit(self):
227 239 return reverse('url_edit_campaign', args=[str(self.id)])
228 240
229 241 def get_absolute_url_export(self):
230 242 return reverse('url_export_campaign', args=[str(self.id)])
231 243
232 244 def get_absolute_url_import(self):
233 245 return reverse('url_import_campaign', args=[str(self.id)])
234 246
235 247
236 248
237 249 class RunningExperiment(models.Model):
238 250 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
239 251 running_experiment = models.ManyToManyField('Experiment', blank = True)
240 252 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
241 253
242 254
243 255 class Experiment(models.Model):
244 256
245 257 template = models.BooleanField(default=False)
246 258 name = models.CharField(max_length=40, default='', unique=True)
247 259 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
248 260 start_time = models.TimeField(default='00:00:00')
249 261 end_time = models.TimeField(default='23:59:59')
250 262 status = models.PositiveSmallIntegerField(default=0, choices=EXP_STATES)
251 263
252 264 class Meta:
253 265 db_table = 'db_experiments'
254 266 ordering = ('template', 'name')
255 267
256 def __unicode__(self):
268 def __str__(self):
257 269 if self.template:
258 270 return u'%s (template)' % (self.name)
259 271 else:
260 272 return u'%s' % (self.name)
261 273
262 274 @property
263 275 def radar_system(self):
264 276 return self.location
265 277
266 278 def clone(self, **kwargs):
267 279
268 280 confs = Configuration.objects.filter(experiment=self, type=0)
269 281 self.pk = None
270 282 self.name = '{} [{:%Y/%m/%d}]'.format(self.name, datetime.now())
271 283 for attr, value in kwargs.items():
272 284 setattr(self, attr, value)
273 285
274 286 self.save()
275 287
276 288 for conf in confs:
277 289 conf.clone(experiment=self, template=False)
278 290
279 291 return self
280 292
281 293 def get_status(self):
282 294 configurations = Configuration.objects.filter(experiment=self)
283 295 exp_status=[]
284 296 for conf in configurations:
285 print conf.status_device()
286 297 exp_status.append(conf.status_device())
287 298
288 299 if not exp_status: #No Configuration
289 300 self.status = 4
290 301 self.save()
291 302 return
292 303
293 304 total = 1
294 305 for e_s in exp_status:
295 306 total = total*e_s
296 307
297 308 if total == 0: #Error
298 309 status = 0
299 310 elif total == (3**len(exp_status)): #Running
300 311 status = 2
301 312 else:
302 313 status = 1 #Configurated
303 314
304 315 self.status = status
305 316 self.save()
306 317
307 318 def status_color(self):
308 319 color = 'muted'
309 320 if self.status == 0:
310 321 color = "danger"
311 322 elif self.status == 1:
312 323 color = "info"
313 324 elif self.status == 2:
314 325 color = "success"
315 326 elif self.status == 3:
316 327 color = "warning"
317 328
318 329 return color
319 330
320 331 def get_absolute_url(self):
321 332 return reverse('url_experiment', args=[str(self.id)])
322 333
323 334 def parms_to_dict(self):
324 335
325 336 import json
326 337
327 338 configurations = Configuration.objects.filter(experiment=self)
328 339 conf_parameters = {}
329 340 parameters={}
330 341
331 342 for configuration in configurations:
332 343 if 'cgs' in configuration.device.device_type.name:
333 344 conf_parameters['cgs'] = configuration.parms_to_dict()
334 345 if 'dds' in configuration.device.device_type.name:
335 346 conf_parameters['dds'] = configuration.parms_to_dict()
336 347 if 'rc' in configuration.device.device_type.name:
337 348 conf_parameters['rc'] = configuration.parms_to_dict()
338 349 if 'jars' in configuration.device.device_type.name:
339 350 conf_parameters['jars'] = configuration.parms_to_dict()
340 351 if 'usrp' in configuration.device.device_type.name:
341 352 conf_parameters['usrp'] = configuration.parms_to_dict()
342 353 if 'abs' in configuration.device.device_type.name:
343 354 conf_parameters['abs'] = configuration.parms_to_dict()
344 355
345 356 parameters['configurations'] = conf_parameters
346 357 parameters['end_time'] = self.end_time.strftime("%H:%M:%S")
347 358 parameters['start_time'] = self.start_time.strftime("%H:%M:%S")
348 359 parameters['radar'] = self.radar_system.name
349 360 parameters['experiment'] = self.name
350 361 parameters = json.dumps(parameters, indent=2)
351 362
352 363 return parameters
353 364
354 365 def import_from_file(self, fp):
355 366
356 367 import os, json
357 368
358 369 parms = {}
359 370
360 371 path, ext = os.path.splitext(fp.name)
361 372
362 373 if ext == '.json':
363 parms = json.load(fp)
374 parms = json.loads(fp.read().decode('utf-8'))
364 375
365 376 return parms
366 377
367 378 def dict_to_parms(self, parms, CONF_MODELS):
368 379
369 380 configurations = Configuration.objects.filter(experiment=self)
370 381
371 382 if configurations:
372 383 for configuration in configurations:
373 384 configuration.delete()
374 385
375 386 for conf_type in parms['configurations']:
376 387 #--For ABS Device:
377 388 #--For USRP Device:
378 389 #--For JARS Device:
379 390 if conf_type == 'jars':
380 391 device = get_object_or_404(Device, pk=parms['configurations']['jars']['device_id'])
381 392 DevConfModel = CONF_MODELS[conf_type]
382 393 confjars_form = DevConfModel(
383 394 experiment = self,
384 395 name = 'JARS',
385 396 device=device,
386 397 )
387 398 confjars_form.dict_to_parms(parms['configurations']['jars'])
388 399 confjars_form.save()
389 400 #--For RC Device:
390 401 if conf_type == 'rc':
391 402 device = get_object_or_404(Device, pk=parms['configurations']['rc']['device_id'])
392 403 DevConfModel = CONF_MODELS[conf_type]
393 404 confrc_form = DevConfModel(
394 405 experiment = self,
395 406 name = 'RC',
396 407 device=device,
397 408 )
398 409 confrc_form.dict_to_parms(parms['configurations']['rc'])
399 410 confrc_form.save()
400 411 #--For DDS Device:
401 412 if conf_type == 'dds':
402 413 device = get_object_or_404(Device, pk=parms['configurations']['dds']['device_id'])
403 414 DevConfModel = CONF_MODELS[conf_type]
404 415 confdds_form = DevConfModel(
405 416 experiment = self,
406 417 name = 'DDS',
407 418 device=device,
408 419 )
409 420 confdds_form.dict_to_parms(parms['configurations']['dds'])
410 421 confdds_form.save()
411 422 #--For CGS Device:
412 423 if conf_type == 'cgs':
413 424 device = get_object_or_404(Device, pk=parms['configurations']['cgs']['device_id'])
414 425 DevConfModel = CONF_MODELS[conf_type]
415 426 confcgs_form = DevConfModel(
416 427 experiment = self,
417 428 name = 'CGS',
418 429 device=device,
419 430 )
420 431 confcgs_form.dict_to_parms(parms['configurations']['cgs'])
421 432 confcgs_form.save()
422 433
423 434 location = Location.objects.get(name = parms['radar'])
424 435 self.name = parms['experiment']
425 436 self.location = location
426 437 self.start_time = parms['start_time']
427 438 self.end_time = parms['end_time']
428 439 self.save()
429 440
430 441 return self
431 442
432 443 def get_absolute_url_edit(self):
433 444 return reverse('url_edit_experiment', args=[str(self.id)])
434 445
435 446 def get_absolute_url_import(self):
436 447 return reverse('url_import_experiment', args=[str(self.id)])
437 448
438 449 def get_absolute_url_export(self):
439 450 return reverse('url_export_experiment', args=[str(self.id)])
440 451
441 452
442 453 class Configuration(PolymorphicModel):
443 454
444 455 template = models.BooleanField(default=False)
445 456
446 457 name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
447 458
448 459 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
449 460 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
450 461
451 462 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
452 463
453 464 created_date = models.DateTimeField(auto_now_add=True)
454 465 programmed_date = models.DateTimeField(auto_now=True)
455 466
456 467 parameters = models.TextField(default='{}')
457 468
458 469 message = ""
459 470
460 471 class Meta:
461 472 db_table = 'db_configurations'
462 473
463 def __unicode__(self):
474 def __str__(self):
464 475
465 476 device = '{}:'.format(self.device.device_type.name.upper())
466 477
467 if 'mix' in self._meta.get_all_field_names():
478 if 'mix' in [f.name for f in self._meta.get_fields()]:
468 479 if self.mix:
469 480 device = '{} MIXED:'.format(self.device.device_type.name.upper())
470 481
471 482 if self.template:
472 483 return u'{} {} (template)'.format(device, self.name)
473 484 else:
474 485 return u'{} {}'.format(device, self.name)
475 486
476 487 def clone(self, **kwargs):
477 488
478 489 self.pk = None
479 490 self.id = None
480 491 for attr, value in kwargs.items():
481 492 setattr(self, attr, value)
482 493
483 494 self.save()
484 495
485 496 return self
486 497
487 498 def parms_to_dict(self):
488 499
489 500 parameters = {}
490 501
491 502 for key in self.__dict__.keys():
492 503 parameters[key] = getattr(self, key)
493 504
494 505 return parameters
495 506
496 507 def parms_to_text(self):
497 508
498 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
509 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
499 510
500 return ''
501 511
502 512 def parms_to_binary(self):
503 513
504 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
514 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
505 515
506 return ''
507 516
508 517 def dict_to_parms(self, parameters):
509 518
510 519 if type(parameters) != type({}):
511 520 return
512 521
513 522 for key in parameters.keys():
514 523 setattr(self, key, parameters[key])
515 524
516 525 def export_to_file(self, format="json"):
517 526
518 527 import json
519 528
520 529 content_type = ''
521 530
522 531 if format == 'text':
523 532 content_type = 'text/plain'
524 533 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
525 534 content = self.parms_to_text()
526 535
527 536 if format == 'binary':
528 537 content_type = 'application/octet-stream'
529 538 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
530 539 content = self.parms_to_binary()
531 540
532 541 if not content_type:
533 542 content_type = 'application/json'
534 543 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
535 544 content = json.dumps(self.parms_to_dict(), indent=2)
536 545
537 546 fields = {'content_type':content_type,
538 547 'filename':filename,
539 548 'content':content
540 549 }
541 550
542 551 return fields
543 552
544 553 def import_from_file(self, fp):
545 554
546 555 import os, json
547 556
548 557 parms = {}
549 558
550 559 path, ext = os.path.splitext(fp.name)
551 560
552 561 if ext == '.json':
553 562 parms = json.load(fp)
554 563
555 564 return parms
556 565
557 566 def status_device(self):
558 567
559 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
568 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
560 569
561 return None
562 570
563 571 def stop_device(self):
564 572
565 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
573 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
566 574
567 return None
568 575
569 576 def start_device(self):
570 577
571 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
578 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
572 579
573 return None
574 580
575 581 def write_device(self, parms):
576 582
577 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
583 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
578 584
579 return None
580 585
581 586 def read_device(self):
582 587
583 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
588 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
584 589
585 return None
586 590
587 591 def get_absolute_url(self):
588 592 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
589 593
590 594 def get_absolute_url_edit(self):
591 595 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
592 596
593 597 def get_absolute_url_import(self):
594 598 return reverse('url_import_dev_conf', args=[str(self.id)])
595 599
596 600 def get_absolute_url_export(self):
597 601 return reverse('url_export_dev_conf', args=[str(self.id)])
598 602
599 603 def get_absolute_url_write(self):
600 604 return reverse('url_write_dev_conf', args=[str(self.id)])
601 605
602 606 def get_absolute_url_read(self):
603 607 return reverse('url_read_dev_conf', args=[str(self.id)])
604 608
605 609 def get_absolute_url_start(self):
606 610 return reverse('url_start_dev_conf', args=[str(self.id)])
607 611
608 612 def get_absolute_url_stop(self):
609 613 return reverse('url_stop_dev_conf', args=[str(self.id)])
610 614
611 615 def get_absolute_url_status(self):
612 616 return reverse('url_status_dev_conf', args=[str(self.id)])
@@ -1,152 +1,152
1 1 <!DOCTYPE html>
2 2 {% load static %}
3 3 <html lang="en">
4 4 <head>
5 5 <meta charset="utf-8">
6 6 <title>{% block title %}Jicamarca Integrated Radar System:::::{% endblock %}</title>
7 7 <meta name="description" content="">
8 8 <meta name="author" content="">
9 9 <meta name="viewport" content="width=device-width, initial-scale=1">
10 10 {# bootstrap_css #}
11 11 <link href="{% static 'css/bootstrap-flatly.min.css' %}" media="all" rel="stylesheet">
12 12 <style type="text/css">
13 13 body {padding-top: 60px}
14 14 .logo {padding-top: 5px; height: 50px}
15 15 .clickable-row {cursor: pointer;}
16 16 .col-no-padding { padding-left:0;}
17 17 .gi-2x{font-size: 2em;}
18 18 .gi-3x{font-size: 3em;}
19 19 .gi-4x{font-size: 4em;}
20 20 .gi-5x{font-size: 5em;}
21 21 </style>
22 22 <!--[if lt IE 9]>
23 23 <script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
24 24 <![endif]-->
25 25 <script src="{% static 'js/jquery.min.js' %}"></script>
26 26 {% block extra-head %}
27 27 {% endblock %}
28 28 </head>
29 29
30 30 <body>
31 31
32 32 {% block main_menu %}
33 33 <nav class="navbar navbar-default navbar-fixed-top" role="banner">
34 34 <div class="container-fluid">
35 35 <div class="navbar-header">
36 36 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navigationbar">
37 37 <span class="sr-only">Toggle navigation</span>
38 38 <span class="icon-bar"></span>
39 39 <span class="icon-bar"></span>
40 40 <span class="icon-bar"></span>
41 41 </button>
42 42 <a class="navbar-brand" href="{% url 'index' %}" style="padding-top:1px"><img class="logo" alt="JRO" src="{% static "images/logo-jro-color-trans.png" %}"></a>
43 43 </div>
44 44 <div class="collapse navbar-collapse" id="navigationbar">
45 45 <ul class="nav navbar-nav">
46 46 <li class=" dropdown {% block operation-active %}{% endblock %}"><a href="{% url 'url_operation'%}">Operation</a>
47 47 </li>
48 48 <li class=" dropdown {% block new-active %}{% endblock %}">
49 49 <a href="#" class="dropdown-toggle" data-toggle="dropdown">New<span class="caret"></span></a>
50 50 <ul class="dropdown-menu" role="menu">
51 51 <li><a href="{% url 'url_add_campaign' %}">Campaign</a></li>
52 52 <li><a href="{% url 'url_add_experiment' %}">Experiment</a></li>
53 53 <li><a href="{% url 'url_add_dev_conf' 0%}">Device Configuration</a></li>
54 54 <li><a href="{% url 'url_add_device'%}">Device</a></li>
55 55 <li><a href="{% url 'url_add_location'%}">Radar System</a></li>
56 56 </ul>
57 57 </li>
58 58 <li class=" dropdown {% block search-active %}{% endblock %}">
59 59 <a href="#" class="dropdown-toggle" data-toggle="dropdown">Search<span class="caret"></span></a>
60 60 <ul class="dropdown-menu" role="menu">
61 61 <li><a href="{% url 'url_campaigns' %}">Campaigns</a></li>
62 62 <li><a href="{% url 'url_experiments' %}">Experiments</a></li>
63 63 <li><a href="{% url 'url_dev_confs' %}">Configurations</a></li>
64 64 <li><a href="{% url 'url_devices' %}">Devices</a></li>
65 65 <li><a href="{% url 'url_locations' %}">Radar Systems</a></li>
66 66 </ul>
67 67 </li>
68 68 </ul>
69 69 <ul class="nav navbar-nav navbar-right">
70 70 <li class="nav-divider"></li>
71 71 {% if user.is_authenticated %}
72 72 <li class="dropdown">
73 73 <a href="#" class="dropdown-toggle" data-toggle="dropdown">Hi {{ user.username }}<span class="caret"></span></a>
74 74 <ul class="dropdown-menu" role="menu">
75 75 <li><a href="#">Control Panel</a></li>
76 <li><a href="{% url 'django.contrib.auth.views.logout' %}">Logout</a></li>
76 <li><a href="{% url 'url_logout' %}">Logout</a></li>
77 77 </ul>
78 78 </li>
79 79 {% else %}
80 <li><a href="{% url 'django.contrib.auth.views.login' %}?next={{request.get_full_path}}">Login</a></li>
80 <li><a href="{% url 'url_login' %}?next={{request.get_full_path}}">Login</a></li>
81 81 {% endif %}
82 82 </ul>
83 83 </div>
84 84 </div>
85 85 </nav>
86 86 <div style="clear: both;"></div>
87 87 {% endblock %}
88 88
89 89 <div class="container">
90 90 <div id="page" class="row" style="min-height:600px">
91 91
92 92 {% if no_sidebar %}
93 93 <div class="col-md-0 hidden-xs hidden-sm" role="complementary">
94 94
95 95 {% else %}
96 96 <div class="col-md-3 hidden-xs hidden-sm" role="complementary">
97 97 {% endif %}
98 98 <br><br>
99 99 <div id="sidebar">
100 100 {% block sidebar%}
101 101 {% endblock %}
102 102 </div>
103 103 </div>
104 104
105 105 {% if no_sidebar %}
106 106 <div class="col-md-12 col-xs-12" role="main">
107 107 {% else %}
108 108 <div class="col-md-9 col-xs-12" role="main">
109 109 {% endif %}
110 110 <div class="page-header">
111 111 <h1>{% block content-title %}{% endblock %} <small>{% block content-suptitle %}{% endblock %}</small></h1>
112 112 </div>
113 113 {% block messages %}
114 114 {% if messages %}
115 115 {% for message in messages %}
116 116 <div class="alert alert-{% if message.tags %}{% if 'error' in message.tags %}danger{% else %}{{ message.tags }}{% endif %}{% else %}info{% endif %} alert-dismissible" role="alert">
117 117 <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
118 118 <strong>{{message.tags|title}}!</strong> {{ message }}
119 119 </div>
120 120 {% endfor %}
121 121 {% endif %}
122 122 {% endblock %}
123 123
124 124 {% block content %}
125 125 {% endblock %}
126 126
127 127 </div>
128 128
129 129
130 130 </div><!--/row-->
131 131 </div> <!-- container -->
132 132
133 133 <div id="debug">{{debug}}</div>
134 134
135 135 {% block footer %}
136 136 <footer class="footer">
137 137 <div class="container">
138 138 <p><hr></p>
139 139 <p>
140 140 &copy; <a href="http://jro.igp.gob.pe">Jicamarca Radio Observatory</a> - {% now "Y" %}
141 141 </p>
142 142 </div>
143 143 </footer>
144 144 {% endblock %}
145 145
146 146 {# bootstrap_javascript jquery=True #}
147 147
148 148 <script src="{% static 'js/bootstrap.min.js' %}"></script>
149 149 {% block extra-js %}
150 150 {% endblock%}
151 151 </body>
152 152 </html>
@@ -1,151 +1,128
1 1 {% extends "base.html" %}
2 2 {% load bootstrap3 %}
3 3 {% load static %}
4 4 {% load main_tags %}
5 5 {% block extra-head %}
6 6 <link href="{% static 'css/bootstrap-datetimepicker.min.css' %}" media="screen" rel="stylesheet">
7 7 {% endblock %}
8 8
9 {% block camp-active %}active{% endblock %}
9 {% block operation-active %}active{% endblock %}
10 10
11 {% block content-title %}{{title}}{% endblock %}
12 {% block content-suptitle %}{{suptitle}}{% endblock %}
13 11
14 12 {% block content %}
15 13
16 <!-- Not Empty-->
17 {% if details %}
18
19 <form class="form" method="post" action="">
20 {% csrf_token %}
21
22 14 {% bootstrap_form form layout='horizontal' size='medium' %}
23 15 <div style="clear: both;"></div>
24 <br>
25 <!-- For deep search -->
26 {% if search_button == True %}
27 <button id="button-1" type="button" class="btn btn-primary pull-right">{{button}}</button>
28 {% endif %}
29 <br>
30 <br>
31 </form>
32 <br>
33 <br>
34 16
35 {% endif %}
17 {% if campaign %}
18
36 19 <div class="clearfix"></div>
37 20 <h2>Radar Systems</h2>
38 21 <br>
39 22 <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true" >
40 23
41 24 {% for location in locations %}
42 25
43 26 <div class="panel panel-default">
44 27 <div class="panel-heading" role="tab" id="headingTwo">
45 28 <h4 class="panel-title">
46 29
47 30 <a class="collapsed" role="button" data-toggle="collapse" href="#collapseTwo-{{ location.id }}" aria-expanded="false" aria-controls="collapseTwo">
48 {{location.name}}: Experiments
31 {{location.name}}
49 32 <span>
50 33 </span>
51 34 </a>
52 35
53 36 <button type="button" name="bt_play" class="btn btn-primary pull-right btn-xs" data-url="{% url 'url_radar_play' campaign.id location.id %}" style="margin-left: 10px">
54 37 <span class="glyphicon glyphicon-play" aria-hidden="true"></span>
55 38 </button>
56 39 <button type="button" name="bt_stop" class="btn btn-primary pull-right btn-xs" data-url="{% url 'url_radar_stop' campaign.id location.id %}" aria-label="Left Align" style="margin-left: 10px">
57 40 <span class="glyphicon glyphicon-stop" aria-hidden="true"></span>
58 41 </button>
59 42 <button type="button" name="bt_refresh" class="btn btn-primary pull-right btn-xs" data-url="{% url 'url_radar_refresh' campaign.id location.id %}" aria-label="Left Align" style="margin-left: 10px">
60 43 <span class="glyphicon glyphicon-refresh" aria-hidden="true"></span>
61 44 </button>
62 45 </h4>
63 46 </div>
64 47
65 48 <div id="collapseTwo-{{ location.id }}" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingTwo">
66 49 <div class="panel-body">
67 50 <table class="table table-hover">
68 51 <tr>
69 52 <th>#</th>
70 53 {% for header in experiment_keys %}
71 54 <th>{{ header|title }}</th>
72 55 {% endfor%}
73 56 </tr>
74 57
75 {% for item in experiments %}
58 {% for item in location.experiments %}
76 59 {% if location.name in item.location.name %}
77 60
78 61 <tr class="clickable-row" data-href="{% url 'url_experiment' item.id %}" >
79 62 <td>{{ forloop.counter }}</td>
80 63 {% for key in experiment_keys %}
81 64 {% if 'status' in key %}
82 65 <td class="text-{{item.status_color}}">{{ item|value:key }}</td>
83 66 {% else %}
84 67 <td>{{ item|value:key }}</td>
85 68 {% endif %}
86 69 {% endfor %}
87 70 </tr>
88 71 {% endif %}
89 72 {% endfor %}
90 73 </table>
91 74 </div>
92 75 </div>
93 76 </div>
94 77 {% endfor %}
95 78 </div>
96 79
97
80 {% endif %}
98 81
99 82 {% endblock %}
100 83
101 84
102 85
103 86 {% block extra-js%}
104 87 <script type="text/javascript">
105 88
106 89 //--------For PLAY Button-------
107 90 $("#accordion").on("click", "button[name=bt_play]", function(){
108 91 //alert($(this).data('url'));
109 92 document.location = $(this).data('url');
110 93 });
111 94
112 95 //--------For STOP Button-------
113 96 $("#accordion").on("click", "button[name=bt_stop]", function(){
114 97 //alert($(this).data('url'));
115 98 document.location = $(this).data('url');
116 99 });
117 100
118 101 //--------For REFRESH Button-------
119 102 $("#accordion").on("click", "button[name=bt_refresh]", function(){
120 103 document.location = $(this).data('url');
121 104 });
122 105
123 106 $(".clickable-row").click(function() {
124 107 document.location = $(this).data("href");
125 108 });
126 109
127 110 {% if search_button == True %}
128 111 $(document).ready(function() {
129 112 $("#id_campaign").change(function() {
130 113 var id_camp = document.getElementById("id_campaign").value;
131 114 //alert(id_camp);
132 115 document.location = "{% url 'url_operation'%}"+String(id_camp);
133 116 });
134 117 });
135 118 {% else %}
136 119 $(document).ready(function() {
137 120 $("#id_campaign").change(function() {
138 var id_camp = document.getElementById("id_campaign").value;
139 //alert(id_camp);
140 document.location = "{% url 'url_operation_search'%}"+String(id_camp);
121 document.location = "{% url 'url_operation'%}"+$(this).val();
141 122 });
142 123 });
143 124 {% endif %}
144 125
145 $("#button-1").click(function() {
146 document.location = "{% url 'url_operation_search' %}";
147 });
148
149 126
150 127 </script>
151 128 {% endblock %}
1 NO CONTENT: modified file
@@ -1,59 +1,61
1 1 from django.conf.urls import url
2 2
3 urlpatterns = (
4 url(r'^location/new/$', 'apps.main.views.location_new', name='url_add_location'),
5 url(r'^location/$', 'apps.main.views.locations', name='url_locations'),
6 url(r'^location/(?P<id_loc>-?\d+)/$', 'apps.main.views.location', name='url_location'),
7 url(r'^location/(?P<id_loc>-?\d+)/edit/$', 'apps.main.views.location_edit', name='url_edit_location'),
8 url(r'^location/(?P<id_loc>-?\d+)/delete/$', 'apps.main.views.location_delete', name='url_delete_location'),
9
10 url(r'^device/new/$', 'apps.main.views.device_new', name='url_add_device'),
11 url(r'^device/$', 'apps.main.views.devices', name='url_devices'),
12 url(r'^device/(?P<id_dev>-?\d+)/$', 'apps.main.views.device', name='url_device'),
13 url(r'^device/(?P<id_dev>-?\d+)/edit/$', 'apps.main.views.device_edit', name='url_edit_device'),
14 url(r'^device/(?P<id_dev>-?\d+)/delete/$', 'apps.main.views.device_delete', name='url_delete_device'),
15
16 url(r'^campaign/new/$', 'apps.main.views.campaign_new', name='url_add_campaign'),
17 url(r'^campaign/$', 'apps.main.views.campaigns', name='url_campaigns'),
18 url(r'^campaign/(?P<id_camp>-?\d+)/$', 'apps.main.views.campaign', name='url_campaign'),
19 url(r'^campaign/(?P<id_camp>-?\d+)/edit/$', 'apps.main.views.campaign_edit', name='url_edit_campaign'),
20 url(r'^campaign/(?P<id_camp>-?\d+)/delete/$', 'apps.main.views.campaign_delete', name='url_delete_campaign'),
21 url(r'^campaign/(?P<id_camp>-?\d+)/export/$', 'apps.main.views.campaign_export', name='url_export_campaign'),
22 url(r'^campaign/(?P<id_camp>-?\d+)/import/$', 'apps.main.views.campaign_import', name='url_import_campaign'),
23
24 url(r'^experiment/new/$', 'apps.main.views.experiment_new', name='url_add_experiment'),
25 url(r'^experiment/$', 'apps.main.views.experiments', name='url_experiments'),
26 url(r'^experiment/(?P<id_exp>-?\d+)/$', 'apps.main.views.experiment', name='url_experiment'),
27 url(r'^experiment/(?P<id_exp>-?\d+)/edit/$', 'apps.main.views.experiment_edit', name='url_edit_experiment'),
28 url(r'^experiment/(?P<id_exp>-?\d+)/delete/$', 'apps.main.views.experiment_delete', name='url_delete_experiment'),
29 url(r'^experiment/(?P<id_exp>-?\d+)/export/$', 'apps.main.views.experiment_export', name='url_export_experiment'),
30 url(r'^experiment/(?P<id_exp>-?\d+)/import/$', 'apps.main.views.experiment_import', name='url_import_experiment'),
31 url(r'^experiment/(?P<id_exp>-?\d+)/mix/$', 'apps.main.views.experiment_mix', name='url_mix_experiment'),
32 url(r'^experiment/(?P<id_exp>-?\d+)/mix/delete/$', 'apps.main.views.experiment_mix_delete', name='url_delete_mix_experiment'),
33 url(r'^experiment/(?P<id_exp>-?\d+)/summary/$', 'apps.main.views.experiment_summary', name='url_sum_experiment'),
34 url(r'^experiment/(?P<id_exp>-?\d+)/verify/$', 'apps.main.views.experiment_verify', name='url_verify_experiment'),
35
36 url(r'^experiment/(?P<id_exp>-?\d+)/new_dev_conf/$', 'apps.main.views.dev_conf_new', name='url_add_dev_conf'),
37 url(r'^experiment/(?P<id_exp>-?\d+)/new_dev_conf/(?P<id_dev>-?\d+)/$', 'apps.main.views.dev_conf_new', name='url_add_dev_conf'),
38 url(r'^dev_conf/$', 'apps.main.views.dev_confs', name='url_dev_confs'),
39 url(r'^dev_conf/(?P<id_conf>-?\d+)/$', 'apps.main.views.dev_conf', name='url_dev_conf'),
40 url(r'^dev_conf/(?P<id_conf>-?\d+)/edit/$', 'apps.main.views.dev_conf_edit', name='url_edit_dev_conf'),
41 url(r'^dev_conf/(?P<id_conf>-?\d+)/delete/$', 'apps.main.views.dev_conf_delete', name='url_delete_dev_conf'),
42
43 url(r'^dev_conf/(?P<id_conf>-?\d+)/write/$', 'apps.main.views.dev_conf_write', name='url_write_dev_conf'),
44 url(r'^dev_conf/(?P<id_conf>-?\d+)/read/$', 'apps.main.views.dev_conf_read', name='url_read_dev_conf'),
45 url(r'^dev_conf/(?P<id_conf>-?\d+)/import/$', 'apps.main.views.dev_conf_import', name='url_import_dev_conf'),
46 url(r'^dev_conf/(?P<id_conf>-?\d+)/export/$', 'apps.main.views.dev_conf_export', name='url_export_dev_conf'),
47 url(r'^dev_conf/(?P<id_conf>-?\d+)/start/$', 'apps.main.views.dev_conf_start', name='url_start_dev_conf'),
48 url(r'^dev_conf/(?P<id_conf>-?\d+)/stop/$', 'apps.main.views.dev_conf_stop', name='url_stop_dev_conf'),
49 url(r'^dev_conf/(?P<id_conf>-?\d+)/status/$', 'apps.main.views.dev_conf_status', name='url_status_dev_conf'),
50
51 url(r'^operation/$', 'apps.main.views.operation', name='url_operation'),
52 url(r'^operation/(?P<id_camp>-?\d+)/$', 'apps.main.views.operation', name='url_operation'),
53 url(r'^operation/search/$', 'apps.main.views.operation_search', name='url_operation_search'),
54 url(r'^operation/search/(?P<id_camp>-?\d+)/$', 'apps.main.views.operation_search', name='url_operation_search'),
55 url(r'^operation/(?P<id_camp>-?\d+)/radar/(?P<id_radar>-?\d+)/play/$', 'apps.main.views.radar_play', name='url_radar_play'),
56 url(r'^operation/(?P<id_camp>-?\d+)/radar/(?P<id_radar>-?\d+)/stop/$', 'apps.main.views.radar_stop', name='url_radar_stop'),
57 url(r'^operation/(?P<id_camp>-?\d+)/radar/(?P<id_radar>-?\d+)/refresh/$', 'apps.main.views.radar_refresh', name='url_radar_refresh'),
3 from apps.main import views
58 4
5 urlpatterns = (
6 url(r'^$', views.index, name='index'),
7 url(r'^location/new/$', views.location_new, name='url_add_location'),
8 url(r'^location/$', views.locations, name='url_locations'),
9 url(r'^location/(?P<id_loc>-?\d+)/$', views.location, name='url_location'),
10 url(r'^location/(?P<id_loc>-?\d+)/edit/$', views.location_edit, name='url_edit_location'),
11 url(r'^location/(?P<id_loc>-?\d+)/delete/$', views.location_delete, name='url_delete_location'),
12
13 url(r'^device/new/$', views.device_new, name='url_add_device'),
14 url(r'^device/$', views.devices, name='url_devices'),
15 url(r'^device/(?P<id_dev>-?\d+)/$', views.device, name='url_device'),
16 url(r'^device/(?P<id_dev>-?\d+)/edit/$', views.device_edit, name='url_edit_device'),
17 url(r'^device/(?P<id_dev>-?\d+)/delete/$', views.device_delete, name='url_delete_device'),
18
19 url(r'^campaign/new/$', views.campaign_new, name='url_add_campaign'),
20 url(r'^campaign/$', views.campaigns, name='url_campaigns'),
21 url(r'^campaign/(?P<id_camp>-?\d+)/$', views.campaign, name='url_campaign'),
22 url(r'^campaign/(?P<id_camp>-?\d+)/edit/$', views.campaign_edit, name='url_edit_campaign'),
23 url(r'^campaign/(?P<id_camp>-?\d+)/delete/$', views.campaign_delete, name='url_delete_campaign'),
24 url(r'^campaign/(?P<id_camp>-?\d+)/export/$', views.campaign_export, name='url_export_campaign'),
25 url(r'^campaign/(?P<id_camp>-?\d+)/import/$', views.campaign_import, name='url_import_campaign'),
26
27 url(r'^experiment/new/$', views.experiment_new, name='url_add_experiment'),
28 url(r'^experiment/$', views.experiments, name='url_experiments'),
29 url(r'^experiment/(?P<id_exp>-?\d+)/$', views.experiment, name='url_experiment'),
30 url(r'^experiment/(?P<id_exp>-?\d+)/edit/$', views.experiment_edit, name='url_edit_experiment'),
31 url(r'^experiment/(?P<id_exp>-?\d+)/delete/$', views.experiment_delete, name='url_delete_experiment'),
32 url(r'^experiment/(?P<id_exp>-?\d+)/export/$', views.experiment_export, name='url_export_experiment'),
33 url(r'^experiment/(?P<id_exp>-?\d+)/import/$', views.experiment_import, name='url_import_experiment'),
34 url(r'^experiment/(?P<id_exp>-?\d+)/mix/$', views.experiment_mix, name='url_mix_experiment'),
35 url(r'^experiment/(?P<id_exp>-?\d+)/mix/delete/$', views.experiment_mix_delete, name='url_delete_mix_experiment'),
36 url(r'^experiment/(?P<id_exp>-?\d+)/summary/$', views.experiment_summary, name='url_sum_experiment'),
37 url(r'^experiment/(?P<id_exp>-?\d+)/verify/$', views.experiment_verify, name='url_verify_experiment'),
38
39 url(r'^experiment/(?P<id_exp>-?\d+)/new_dev_conf/$', views.dev_conf_new, name='url_add_dev_conf'),
40 url(r'^experiment/(?P<id_exp>-?\d+)/new_dev_conf/(?P<id_dev>-?\d+)/$', views.dev_conf_new, name='url_add_dev_conf'),
41 url(r'^dev_conf/$', views.dev_confs, name='url_dev_confs'),
42 url(r'^dev_conf/(?P<id_conf>-?\d+)/$', views.dev_conf, name='url_dev_conf'),
43 url(r'^dev_conf/(?P<id_conf>-?\d+)/edit/$', views.dev_conf_edit, name='url_edit_dev_conf'),
44 url(r'^dev_conf/(?P<id_conf>-?\d+)/delete/$', views.dev_conf_delete, name='url_delete_dev_conf'),
45
46 url(r'^dev_conf/(?P<id_conf>-?\d+)/write/$', views.dev_conf_write, name='url_write_dev_conf'),
47 url(r'^dev_conf/(?P<id_conf>-?\d+)/read/$', views.dev_conf_read, name='url_read_dev_conf'),
48 url(r'^dev_conf/(?P<id_conf>-?\d+)/import/$', views.dev_conf_import, name='url_import_dev_conf'),
49 url(r'^dev_conf/(?P<id_conf>-?\d+)/export/$', views.dev_conf_export, name='url_export_dev_conf'),
50 url(r'^dev_conf/(?P<id_conf>-?\d+)/start/$', views.dev_conf_start, name='url_start_dev_conf'),
51 url(r'^dev_conf/(?P<id_conf>-?\d+)/stop/$', views.dev_conf_stop, name='url_stop_dev_conf'),
52 url(r'^dev_conf/(?P<id_conf>-?\d+)/status/$', views.dev_conf_status, name='url_status_dev_conf'),
53
54 url(r'^operation/$', views.operation, name='url_operation'),
55 url(r'^operation/(?P<id_camp>-?\d+)/$', views.operation, name='url_operation'),
56 url(r'^operation/search/$', views.operation_search, name='url_operation_search'),
57 url(r'^operation/search/(?P<id_camp>-?\d+)/$', views.operation_search, name='url_operation_search'),
58 url(r'^operation/(?P<id_camp>-?\d+)/radar/(?P<id_radar>-?\d+)/play/$', views.radar_play, name='url_radar_play'),
59 url(r'^operation/(?P<id_camp>-?\d+)/radar/(?P<id_radar>-?\d+)/stop/$', views.radar_stop, name='url_radar_stop'),
60 url(r'^operation/(?P<id_camp>-?\d+)/radar/(?P<id_radar>-?\d+)/refresh/$', views.radar_refresh, name='url_radar_refresh'),
59 61 )
@@ -1,1629 +1,1589
1 1 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
2 2 from django.utils.safestring import mark_safe
3 3 from django.http import HttpResponseRedirect
4 4 from django.core.urlresolvers import reverse
5 5 from django.db.models import Q
6 6 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
7 7 from django.contrib import messages
8 from django.http.request import QueryDict
8 9 from datetime import datetime
9 import urllib
10
11 try:
12 from urllib.parse import urlencode
13 except ImportError:
14 from urllib import urlencode
10 15
11 16 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
12 17 from .forms import OperationSearchForm, FilterForm
13 from apps.cgs.forms import CGSConfigurationForm
18
19 from apps.rc.forms import RCConfigurationForm
20 from apps.dds.forms import DDSConfigurationForm
14 21 from apps.jars.forms import JARSConfigurationForm
15 from apps.usrp.forms import USRPConfigurationForm
22 from apps.cgs.forms import CGSConfigurationForm
16 23 from apps.abs.forms import ABSConfigurationForm
17 from apps.rc.forms import RCConfigurationForm, RCMixConfigurationForm
18 from apps.dds.forms import DDSConfigurationForm
24 from apps.usrp.forms import USRPConfigurationForm
19 25
20 26 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment
21 27 from apps.cgs.models import CGSConfiguration
22 28 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
23 29 from apps.usrp.models import USRPConfiguration
24 30 from apps.abs.models import ABSConfiguration
25 31 from apps.rc.models import RCConfiguration, RCLine, RCLineType
26 32 from apps.dds.models import DDSConfiguration
27 33 from django.http.request import QueryDict
28 34 #from __builtin__ import False
29 35
30 36 # Create your views here.
31 37
32 38 CONF_FORMS = {
33 39 'rc': RCConfigurationForm,
34 40 'dds': DDSConfigurationForm,
35 41 'jars': JARSConfigurationForm,
36 42 'cgs': CGSConfigurationForm,
37 43 'abs': ABSConfigurationForm,
38 44 'usrp': USRPConfigurationForm,
39 45 }
40 46
41 47 CONF_MODELS = {
42 48 'rc': RCConfiguration,
43 49 'dds': DDSConfiguration,
44 50 'jars': JARSConfiguration,
45 51 'cgs': CGSConfiguration,
46 52 'abs': ABSConfiguration,
47 53 'usrp': USRPConfiguration,
48 54 }
49 55
50 56 MIX_MODES = {
51 57 '0': 'P',
52 58 '1': 'S',
53 59 }
54 60
55 61 MIX_OPERATIONS = {
56 62 '0': 'OR',
57 63 '1': 'XOR',
58 64 '2': 'AND',
59 65 '3': 'NAND',
60 66 }
61 67
62 68
63 69 def index(request):
64 70 kwargs = {}
65 71
66 72 return render(request, 'index.html', kwargs)
67 73
68 74
69 75 def locations(request):
70 76
71 77 page = request.GET.get('page')
72 78 order = ('name',)
73 79
74 80 kwargs = get_paginator(Location, page, order)
75 81
76 82 kwargs['keys'] = ['name', 'description']
77 83 kwargs['title'] = 'Radar System'
78 84 kwargs['suptitle'] = 'List'
79 85
80 86 return render(request, 'base_list.html', kwargs)
81 87
82 88
83 89 def location(request, id_loc):
84 90
85 91 location = get_object_or_404(Location, pk=id_loc)
86 92
87 93 kwargs = {}
88 94 kwargs['location'] = location
89 95 kwargs['location_keys'] = ['name', 'description']
90 96
91 97 kwargs['title'] = 'Location'
92 98 kwargs['suptitle'] = 'Details'
93 99
94 100 return render(request, 'location.html', kwargs)
95 101
96 102
97 103 def location_new(request):
98 104
99 105 if request.method == 'GET':
100 106 form = LocationForm()
101 107
102 108 if request.method == 'POST':
103 109 form = LocationForm(request.POST)
104 110
105 111 if form.is_valid():
106 112 form.save()
107 113 return redirect('url_locations')
108 114
109 115 kwargs = {}
110 116 kwargs['form'] = form
111 117 kwargs['title'] = 'Radar System'
112 118 kwargs['suptitle'] = 'New'
113 119 kwargs['button'] = 'Create'
114 120
115 121 return render(request, 'base_edit.html', kwargs)
116 122
117 123
118 124 def location_edit(request, id_loc):
119 125
120 126 location = get_object_or_404(Location, pk=id_loc)
121 127
122 128 if request.method=='GET':
123 129 form = LocationForm(instance=location)
124 130
125 131 if request.method=='POST':
126 132 form = LocationForm(request.POST, instance=location)
127 133
128 134 if form.is_valid():
129 135 form.save()
130 136 return redirect('url_locations')
131 137
132 138 kwargs = {}
133 139 kwargs['form'] = form
134 140 kwargs['title'] = 'Location'
135 141 kwargs['suptitle'] = 'Edit'
136 142 kwargs['button'] = 'Update'
137 143
138 144 return render(request, 'base_edit.html', kwargs)
139 145
140 146
141 147 def location_delete(request, id_loc):
142 148
143 149 location = get_object_or_404(Location, pk=id_loc)
144 150
145 151 if request.method=='POST':
146 152
147 153 if request.user.is_staff:
148 154 location.delete()
149 155 return redirect('url_locations')
150 156
151 157 messages.error(request, 'Not enough permission to delete this object')
152 158 return redirect(location.get_absolute_url())
153 159
154 160 kwargs = {
155 161 'title': 'Delete',
156 162 'suptitle': 'Location',
157 163 'object': location,
158 164 'previous': location.get_absolute_url(),
159 165 'delete': True
160 166 }
161 167
162 168 return render(request, 'confirm.html', kwargs)
163 169
164 170
165 171 def devices(request):
166 172
167 173 page = request.GET.get('page')
168 174 order = ('device_type', 'name')
169 175
170 176 kwargs = get_paginator(Device, page, order)
171 177 kwargs['keys'] = ['name', 'ip_address', 'port_address', 'device_type']
172 178 kwargs['title'] = 'Device'
173 179 kwargs['suptitle'] = 'List'
174 180
175 181 return render(request, 'base_list.html', kwargs)
176 182
177 183
178 184 def device(request, id_dev):
179 185
180 186 device = get_object_or_404(Device, pk=id_dev)
181 187
182 188 kwargs = {}
183 189 kwargs['device'] = device
184 190 kwargs['device_keys'] = ['device_type', 'name', 'ip_address', 'port_address', 'description']
185 191
186 192 kwargs['title'] = 'Device'
187 193 kwargs['suptitle'] = 'Details'
188 194
189 195 return render(request, 'device.html', kwargs)
190 196
191 197
192 198 def device_new(request):
193 199
194 200 if request.method == 'GET':
195 201 form = DeviceForm()
196 202
197 203 if request.method == 'POST':
198 204 form = DeviceForm(request.POST)
199 205
200 206 if form.is_valid():
201 207 form.save()
202 208 return redirect('url_devices')
203 209
204 210 kwargs = {}
205 211 kwargs['form'] = form
206 212 kwargs['title'] = 'Device'
207 213 kwargs['suptitle'] = 'New'
208 214 kwargs['button'] = 'Create'
209 215
210 216 return render(request, 'base_edit.html', kwargs)
211 217
212 218
213 219 def device_edit(request, id_dev):
214 220
215 221 device = get_object_or_404(Device, pk=id_dev)
216 222
217 223 if request.method=='GET':
218 224 form = DeviceForm(instance=device)
219 225
220 226 if request.method=='POST':
221 227 form = DeviceForm(request.POST, instance=device)
222 228
223 229 if form.is_valid():
224 230 form.save()
225 231 return redirect(device.get_absolute_url())
226 232
227 233 kwargs = {}
228 234 kwargs['form'] = form
229 235 kwargs['title'] = 'Device'
230 236 kwargs['suptitle'] = 'Edit'
231 237 kwargs['button'] = 'Update'
232 238
233 239 return render(request, 'base_edit.html', kwargs)
234 240
235 241
236 242 def device_delete(request, id_dev):
237 243
238 244 device = get_object_or_404(Device, pk=id_dev)
239 245
240 246 if request.method=='POST':
241 247
242 248 if request.user.is_staff:
243 249 device.delete()
244 250 return redirect('url_devices')
245 251
246 252 messages.error(request, 'Not enough permission to delete this object')
247 253 return redirect(device.get_absolute_url())
248 254
249 255 kwargs = {
250 256 'title': 'Delete',
251 257 'suptitle': 'Device',
252 258 'object': device,
253 259 'previous': device.get_absolute_url(),
254 260 'delete': True
255 261 }
256 262
257 263 return render(request, 'confirm.html', kwargs)
258 264
259 265
260 266 def campaigns(request):
261 267
262 268 page = request.GET.get('page')
263 269 order = ('start_date',)
264 270 filters = request.GET.copy()
265 271
266 272 kwargs = get_paginator(Campaign, page, order, filters)
267 273
268 274 form = FilterForm(initial=request.GET, extra_fields=['range_date', 'tags','template'])
269 275 kwargs['keys'] = ['name', 'start_date', 'end_date']
270 276 kwargs['title'] = 'Campaign'
271 277 kwargs['suptitle'] = 'List'
272 278 kwargs['form'] = form
273 279 filters.pop('page', None)
274 kwargs['q'] = urllib.urlencode(filters)
280 kwargs['q'] = urlencode(filters)
275 281
276 282 return render(request, 'base_list.html', kwargs)
277 283
278 284
279 285 def campaign(request, id_camp):
280 286
281 287 campaign = get_object_or_404(Campaign, pk=id_camp)
282 288 experiments = Experiment.objects.filter(campaign=campaign)
283 289
284 290 form = CampaignForm(instance=campaign)
285 291
286 292 kwargs = {}
287 293 kwargs['campaign'] = campaign
288 294 kwargs['campaign_keys'] = ['template', 'name', 'start_date', 'end_date', 'tags', 'description']
289 295
290 296 kwargs['experiments'] = experiments
291 297 kwargs['experiment_keys'] = ['name', 'radar_system', 'start_time', 'end_time']
292 298
293 299 kwargs['title'] = 'Campaign'
294 300 kwargs['suptitle'] = 'Details'
295 301
296 302 kwargs['form'] = form
297 303 kwargs['button'] = 'Add Experiment'
298 304
299 305 return render(request, 'campaign.html', kwargs)
300 306
301 307
302 308 def campaign_new(request):
303 309
304 310 kwargs = {}
305 311
306 312 if request.method == 'GET':
307 313
308 314 if 'template' in request.GET:
309 315 if request.GET['template']=='0':
310 316 form = NewForm(initial={'create_from':2},
311 317 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
312 318 else:
313 319 kwargs['button'] = 'Create'
314 320 kwargs['experiments'] = Configuration.objects.filter(experiment=request.GET['template'])
315 321 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
316 322 camp = Campaign.objects.get(pk=request.GET['template'])
317 323 form = CampaignForm(instance=camp,
318 324 initial={'name':'{} [{:%Y/%m/%d}]'.format(camp.name, datetime.now()),
319 325 'template':False})
320 326 elif 'blank' in request.GET:
321 327 kwargs['button'] = 'Create'
322 328 form = CampaignForm()
323 329 else:
324 330 form = NewForm()
325 331
326 332 if request.method == 'POST':
327 333 kwargs['button'] = 'Create'
328 334 post = request.POST.copy()
329 335 experiments = []
330 336
331 337 for id_exp in post.getlist('experiments'):
332 338 exp = Experiment.objects.get(pk=id_exp)
333 339 new_exp = exp.clone(template=False)
334 340 experiments.append(new_exp)
335 341
336 342 post.setlist('experiments', [])
337 343
338 344 form = CampaignForm(post)
339 345
340 346 if form.is_valid():
341 347 campaign = form.save()
342 348 for exp in experiments:
343 349 campaign.experiments.add(exp)
344 350 campaign.save()
345 351 return redirect('url_campaign', id_camp=campaign.id)
346 352
347 353 kwargs['form'] = form
348 354 kwargs['title'] = 'Campaign'
349 355 kwargs['suptitle'] = 'New'
350 356
351 357 return render(request, 'campaign_edit.html', kwargs)
352 358
353 359
354 360 def campaign_edit(request, id_camp):
355 361
356 362 campaign = get_object_or_404(Campaign, pk=id_camp)
357 363
358 364 if request.method=='GET':
359 365 form = CampaignForm(instance=campaign)
360 366
361 367 if request.method=='POST':
362 368 exps = campaign.experiments.all().values_list('pk', flat=True)
363 369 post = request.POST.copy()
364 370 new_exps = post.getlist('experiments')
365 371 post.setlist('experiments', [])
366 372 form = CampaignForm(post, instance=campaign)
367 373
368 374 if form.is_valid():
369 375 camp = form.save()
370 376 for id_exp in new_exps:
371 377 if int(id_exp) in exps:
372 378 exps.pop(id_exp)
373 379 else:
374 380 exp = Experiment.objects.get(pk=id_exp)
375 381 if exp.template:
376 382 camp.experiments.add(exp.clone(template=False))
377 383 else:
378 384 camp.experiments.add(exp)
379 385
380 386 for id_exp in exps:
381 387 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
382 388
383 389 return redirect('url_campaign', id_camp=id_camp)
384 390
385 391 kwargs = {}
386 392 kwargs['form'] = form
387 393 kwargs['title'] = 'Campaign'
388 394 kwargs['suptitle'] = 'Edit'
389 395 kwargs['button'] = 'Update'
390 396
391 397 return render(request, 'campaign_edit.html', kwargs)
392 398
393 399
394 400 def campaign_delete(request, id_camp):
395 401
396 402 campaign = get_object_or_404(Campaign, pk=id_camp)
397 403
398 404 if request.method=='POST':
399 405 if request.user.is_staff:
400 406
401 407 for exp in campaign.experiments.all():
402 408 for conf in Configuration.objects.filter(experiment=exp):
403 409 conf.delete()
404 410 exp.delete()
405 411 campaign.delete()
406 412
407 413 return redirect('url_campaigns')
408 414
409 415 messages.error(request, 'Not enough permission to delete this object')
410 416 return redirect(campaign.get_absolute_url())
411 417
412 418 kwargs = {
413 419 'title': 'Delete',
414 420 'suptitle': 'Campaign',
415 421 'object': campaign,
416 422 'previous': campaign.get_absolute_url(),
417 423 'delete': True
418 424 }
419 425
420 426 return render(request, 'confirm.html', kwargs)
421 427
422 428 def campaign_export(request, id_camp):
423 429
424 430 campaign = get_object_or_404(Campaign, pk=id_camp)
425 431 content = campaign.parms_to_dict()
426 432 content_type = 'application/json'
427 433 filename = '%s_%s.json' %(campaign.name, campaign.id)
428 434
429 435 response = HttpResponse(content_type=content_type)
430 436 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
431 437 response.write(content)
432 438
433 439 return response
434 440
435 441
436 442 def campaign_import(request, id_camp):
437 443
438 444 campaign = get_object_or_404(Campaign, pk=id_camp)
439 445
440 446 if request.method == 'GET':
441 447 file_form = UploadFileForm()
442 448
443 449 if request.method == 'POST':
444 450 file_form = UploadFileForm(request.POST, request.FILES)
445 451
446 452 if file_form.is_valid():
447 453
448 454 parms = campaign.import_from_file(request.FILES['file'])
449 455
450 456 if parms:
451 457 parms['name'] = parms['campaign']
452 458
453 459 new_camp = campaign.dict_to_parms(parms, CONF_MODELS)
454 460
455 461 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
456 462
457 463 return redirect(new_camp.get_absolute_url_edit())
458 464
459 465 messages.error(request, "Could not import parameters from file")
460 466
461 467 kwargs = {}
462 468 kwargs['title'] = 'Campaign'
463 469 kwargs['form'] = file_form
464 470 kwargs['suptitle'] = 'Importing file'
465 471 kwargs['button'] = 'Import'
466 472
467 473 return render(request, 'campaign_import.html', kwargs)
468 474
469 475
470 476 def experiments(request):
471 477
472 478 page = request.GET.get('page')
473 479 order = ('location',)
474 480 filters = request.GET.copy()
475 481
476 482 kwargs = get_paginator(Experiment, page, order, filters)
477 483
478 484 form = FilterForm(initial=request.GET, extra_fields=['tags','template'])
479 485
480 486 kwargs['keys'] = ['name', 'radar_system', 'start_time', 'end_time']
481 487 kwargs['title'] = 'Experiment'
482 488 kwargs['suptitle'] = 'List'
483 489 kwargs['form'] = form
484 490 filters.pop('page', None)
485 kwargs['q'] = urllib.urlencode(filters)
491 kwargs['q'] = urlencode(filters)
486 492
487 493 return render(request, 'base_list.html', kwargs)
488 494
489 495
490 496 def experiment(request, id_exp):
491 497
492 498 experiment = get_object_or_404(Experiment, pk=id_exp)
493 499
494 500 configurations = Configuration.objects.filter(experiment=experiment, type=0)
495 501
496 502 kwargs = {}
497 503
498 504 kwargs['experiment_keys'] = ['template', 'radar_system', 'name', 'start_time', 'end_time']
499 505 kwargs['experiment'] = experiment
500 506
501 507 kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status']
502 508 kwargs['configurations'] = configurations
503 509
504 510 kwargs['title'] = 'Experiment'
505 511 kwargs['suptitle'] = 'Details'
506 512
507 513 kwargs['button'] = 'Add Configuration'
508 514
509 515 ###### SIDEBAR ######
510 516 kwargs.update(sidebar(experiment=experiment))
511 517
512 518 return render(request, 'experiment.html', kwargs)
513 519
514 520
515 521 def experiment_new(request, id_camp=None):
516 522
517 523 kwargs = {}
518 524
519 525 if request.method == 'GET':
520 526 if 'template' in request.GET:
521 527 if request.GET['template']=='0':
522 528 form = NewForm(initial={'create_from':2},
523 529 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
524 530 else:
525 531 kwargs['button'] = 'Create'
526 532 kwargs['configurations'] = Configuration.objects.filter(experiment=request.GET['template'])
527 533 kwargs['configuration_keys'] = ['name', 'device__name', 'device__ip_address', 'device__port_address']
528 534 exp=Experiment.objects.get(pk=request.GET['template'])
529 535 form = ExperimentForm(instance=exp,
530 536 initial={'name': '{} [{:%Y/%m/%d}]'.format(exp.name, datetime.now()),
531 537 'template': False})
532 538 elif 'blank' in request.GET:
533 539 kwargs['button'] = 'Create'
534 540 form = ExperimentForm()
535 541 else:
536 542 form = NewForm()
537 543
538 544 if request.method == 'POST':
539 545 form = ExperimentForm(request.POST)
540 print form.data
541 546 if form.is_valid():
542 547 experiment = form.save()
543 548
544 549 if 'template' in request.GET:
545 550 configurations = Configuration.objects.filter(experiment=request.GET['template'], type=0)
546 551 for conf in configurations:
547 552 conf.clone(experiment=experiment, template=False)
548 553
549 554 return redirect('url_experiment', id_exp=experiment.id)
550 555
551 556 kwargs['form'] = form
552 557 kwargs['title'] = 'Experiment'
553 558 kwargs['suptitle'] = 'New'
554 559
555 560 return render(request, 'experiment_edit.html', kwargs)
556 561
557 562
558 563 def experiment_edit(request, id_exp):
559 564
560 565 experiment = get_object_or_404(Experiment, pk=id_exp)
561 566
562 567 if request.method == 'GET':
563 568 form = ExperimentForm(instance=experiment)
564 569
565 570 if request.method=='POST':
566 571 form = ExperimentForm(request.POST, instance=experiment)
567 572
568 573 if form.is_valid():
569 574 experiment = form.save()
570 575 return redirect('url_experiment', id_exp=experiment.id)
571 576
572 577 kwargs = {}
573 578 kwargs['form'] = form
574 579 kwargs['title'] = 'Experiment'
575 580 kwargs['suptitle'] = 'Edit'
576 581 kwargs['button'] = 'Update'
577 582
578 583 return render(request, 'experiment_edit.html', kwargs)
579 584
580 585
581 586 def experiment_delete(request, id_exp):
582 587
583 588 experiment = get_object_or_404(Experiment, pk=id_exp)
584 589
585 590 if request.method=='POST':
586 591 if request.user.is_staff:
587 592 for conf in Configuration.objects.filter(experiment=experiment):
588 593 conf.delete()
589 594 experiment.delete()
590 595 return redirect('url_experiments')
591 596
592 597 messages.error(request, 'Not enough permission to delete this object')
593 598 return redirect(experiment.get_absolute_url())
594 599
595 600 kwargs = {
596 601 'title': 'Delete',
597 602 'suptitle': 'Experiment',
598 603 'object': experiment,
599 604 'previous': experiment.get_absolute_url(),
600 605 'delete': True
601 606 }
602 607
603 608 return render(request, 'confirm.html', kwargs)
604 609
605 610
606 611 def experiment_export(request, id_exp):
607 612
608 613 experiment = get_object_or_404(Experiment, pk=id_exp)
609 614 content = experiment.parms_to_dict()
610 615 content_type = 'application/json'
611 616 filename = '%s_%s.json' %(experiment.name, experiment.id)
612 617
613 618 response = HttpResponse(content_type=content_type)
614 619 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
615 620 response.write(content)
616 621
617 622 return response
618 623
619 624 def experiment_import(request, id_exp):
620 625
621 626 experiment = get_object_or_404(Experiment, pk=id_exp)
622 627 configurations = Configuration.objects.filter(experiment=experiment)
623 628
624 629 if request.method == 'GET':
625 630 file_form = UploadFileForm()
626 631
627 632 if request.method == 'POST':
628 633 file_form = UploadFileForm(request.POST, request.FILES)
629 634
630 635 if file_form.is_valid():
631 636
632 637 parms = experiment.import_from_file(request.FILES['file'])
633 638
634 639 if parms:
635 640
636 641 new_exp = experiment.dict_to_parms(parms, CONF_MODELS)
637 642
638 643 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
639 644
640 645 return redirect(new_exp.get_absolute_url_edit())
641 646
642 647 messages.error(request, "Could not import parameters from file")
643 648
644 649 kwargs = {}
645 650 kwargs['title'] = 'Experiment'
646 651 kwargs['form'] = file_form
647 652 kwargs['suptitle'] = 'Importing file'
648 653 kwargs['button'] = 'Import'
649 654
650 655 kwargs.update(sidebar(experiment=experiment))
651 656
652 657 return render(request, 'experiment_import.html', kwargs)
653 658
654 659 def experiment_mix(request, id_exp):
655 660
656 661 experiment = get_object_or_404(Experiment, pk=id_exp)
657 662 rc_confs = [conf for conf in RCConfiguration.objects.filter(experiment=id_exp,
658 663 mix=False)]
659 664
660 665 if len(rc_confs)<2:
661 666 messages.warning(request, 'You need at least two RC Configurations to make a mix')
662 667 return redirect(experiment.get_absolute_url())
663 668
664 669 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True)
665 670
666 671 if mix_confs:
667 672 mix = mix_confs[0]
668 673 else:
669 674 mix = RCConfiguration(experiment=experiment,
670 675 device=rc_confs[0].device,
671 676 ipp=rc_confs[0].ipp,
672 677 clock_in=rc_confs[0].clock_in,
673 678 clock_divider=rc_confs[0].clock_divider,
674 679 mix=True,
675 680 parameters='')
676 681 mix.save()
677 682
678 683 line_type = RCLineType.objects.get(name='mix')
679 684 for i in range(len(rc_confs[0].get_lines())):
680 685 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
681 686 line.save()
682 687
683 688 initial = {'name': mix.name,
684 689 'result': parse_mix_result(mix.parameters),
685 690 'delay': 0,
686 691 'mask': [0,1,2,3,4,5,6,7]
687 692 }
688 693
689 694 if request.method=='GET':
690 695 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
691 696
692 697 if request.method=='POST':
693 698 result = mix.parameters
694 699
695 700 if '{}|'.format(request.POST['experiment']) in result:
696 701 messages.error(request, 'Configuration already added')
697 702 else:
698 703 if 'operation' in request.POST:
699 704 operation = MIX_OPERATIONS[request.POST['operation']]
700 705 else:
701 706 operation = ' '
702 707
703 708 mode = MIX_MODES[request.POST['mode']]
704 709
705 710 if result:
706 711 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
707 712 request.POST['experiment'],
708 713 mode,
709 714 operation,
710 715 float(request.POST['delay']),
711 716 parse_mask(request.POST.getlist('mask'))
712 717 )
713 718 else:
714 719 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
715 720 mode,
716 721 operation,
717 722 float(request.POST['delay']),
718 723 parse_mask(request.POST.getlist('mask'))
719 724 )
720 725
721 726 mix.parameters = result
722 727 mix.name = request.POST['name']
723 728 mix.save()
724 729 mix.update_pulses()
725 730
726 731 initial['result'] = parse_mix_result(result)
727 732 initial['name'] = mix.name
728 733
729 734 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
730 735
731 736
732 737 kwargs = {
733 738 'title': 'Experiment',
734 739 'suptitle': 'Mix Configurations',
735 740 'form' : form,
736 741 'extra_button': 'Delete',
737 742 'button': 'Add',
738 743 'cancel': 'Back',
739 744 'previous': experiment.get_absolute_url(),
740 745 'id_exp':id_exp,
741 746
742 747 }
743 748
744 749 return render(request, 'experiment_mix.html', kwargs)
745 750
746 751
747 752 def experiment_mix_delete(request, id_exp):
748 753
749 754 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True)
750 755 values = conf.parameters.split('-')
751 756 conf.parameters = '-'.join(values[:-1])
752 757 conf.save()
753 758
754 759 return redirect('url_mix_experiment', id_exp=id_exp)
755 760
756 761
757 762 def experiment_summary(request, id_exp):
758 763
759 764 import json
760 765 import ast
761 766
762 767 experiment = get_object_or_404(Experiment, pk=id_exp)
763 768 experiment_data = json.loads(experiment.parms_to_dict())
764 769 configurations = Configuration.objects.filter(experiment=experiment, type=0)
765 770
766 771 kwargs = {}
767 772
768 773 kwargs['experiment_keys'] = ['template', 'radar_system', 'name', 'start_time', 'end_time']
769 774 kwargs['experiment'] = experiment
770 775
771 776 kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status']
772 777 kwargs['configurations'] = configurations
773 778 kwargs['experiment_data'] = experiment_data
774 779
775 780 kwargs['title'] = 'Experiment Summary'
776 781 kwargs['suptitle'] = 'Details'
777 782
778 783 kwargs['button'] = 'Verify Parameters'
779 784
780 785 jars_conf = False
781 786 rc_conf = False
782 787
783 788 for configuration in configurations:
784 789 #-------------------- JARS -----------------------:
785 790 if configuration.device.device_type.name == 'jars':
786 791 jars_conf = True
787 792 kwargs['jars_conf'] = jars_conf
788 793 kwargs['exp_type'] = EXPERIMENT_TYPE[configuration.exp_type][1]
789 794 channels_number = configuration.channels_number
790 795 exp_type = configuration.exp_type
791 796 fftpoints = configuration.fftpoints
792 797 filter_parms = configuration.filter_parms
793 798 filter_parms = ast.literal_eval(filter_parms)
794 799 spectral_number = configuration.spectral_number
795 800
796 801 #--------------------- RC ----------------------:
797 802 if configuration.device.device_type.name == 'rc':
798 803 rc_conf = True
799 804 kwargs['rc_conf'] = rc_conf
800 805 rc_lines = experiment_data['configurations']['rc']['lines']
801 806 ipp = configuration.ipp
802 807 if experiment_data['configurations']['rc']['mix'] == 'True':
803 808 tx = ''
804 809 code = ''
805 810 window = ''
806 811 else:
807 812 code = rc_lines[3]['code']
808 813
809 814 window_data = rc_lines[6]['params'][0]
810 815 h0 = str(window_data['first_height'])
811 816 dh = str(window_data['resolution'])
812 817 nsa = str(window_data['number_of_samples'])
813 818 window = 'Ho='+h0+'km\nDH='+dh+'km\nNSA='+nsa
814 819
815 820 tx = ''
816 821 if float(rc_lines[1]['delays']) == 0:
817 822 tx = rc_lines[2]['pulse_width']
818 823 elif float(rc_lines[2]['delays']) == 0:
819 824 tx = rc_lines[1]['pulse_width']
820 825 else:
821 826 tx = rc_lines[1]['pulse_width']+' | '+rc_lines[2]['pulse_width']
822 827
823 828 kwargs['tx'] = tx
824 829 kwargs['code'] = code
825 830 kwargs['window'] = window
826 831
827 832 #-------------------- DDS -----------------------:
828 833 if configuration.device.device_type.name == 'dds':
829 834 dds_conf = True
830 835 kwargs['dds_conf'] = dds_conf
831 836
832 837 #------ RC & JARS ------:
833 838 ipp = 937.5 #
834 839 nsa = 200#
835 840 dh = 1.5 #
836 841 channels_number = 5 #
837 842
838 843 if rc_conf and jars_conf:
839 844 if exp_type == 0: #Short
840 845 bytes = 2
841 846 b = nsa*2*bytes*channels_number
842 847 else: #Float
843 848 bytes = 4
844 849 channels = channels_number + spectral_number
845 850 b = nsa*2*bytes*fftpoints*channels
846 851
847 852 ipps = (ipp*pow(10,-6))/0.15
848 853 GB = 1048576.0*1024.0
849 854 Hour = 3600
850 855 rate = b/ipps
851 856 rate = rate *(1/GB)*(Hour)
852 857 kwargs['rate'] = str(rate)+" GB/h"
853 858 else:
854 859 kwargs['rate'] = ''
855 860
856 861 ###### SIDEBAR ######
857 862 kwargs.update(sidebar(experiment=experiment))
858 863
859 864 return render(request, 'experiment_summary.html', kwargs)
860 865
861 866 def experiment_verify(request, id_exp):
862 867
863 868 import json
864 869 import ast
865 870
866 871 experiment = get_object_or_404(Experiment, pk=id_exp)
867 872 experiment_data = json.loads(experiment.parms_to_dict())
868 873 configurations = Configuration.objects.filter(experiment=experiment, type=0)
869 874
870 875 kwargs = {}
871 876
872 877 kwargs['experiment_keys'] = ['template', 'radar_system', 'name', 'start_time', 'end_time']
873 878 kwargs['experiment'] = experiment
874 879
875 880 kwargs['configuration_keys'] = ['name', 'device__ip_address', 'device__port_address', 'device__status']
876 881 kwargs['configurations'] = configurations
877 882 kwargs['experiment_data'] = experiment_data
878 883
879 884 kwargs['title'] = 'Verify Experiment'
880 885 kwargs['suptitle'] = 'Parameters'
881 886
882 887 kwargs['button'] = 'Update'
883 888
884 889 jars_conf = False
885 890 rc_conf = False
886 891 dds_conf = False
887 892
888 893 for configuration in configurations:
889 894 #-------------------- JARS -----------------------:
890 895 if configuration.device.device_type.name == 'jars':
891 896 jars_conf = True
892 897 kwargs['jars_conf'] = jars_conf
893 898 filter_parms = configuration.filter_parms
894 899 filter_parms = ast.literal_eval(filter_parms)
895 900 kwargs['filter_parms'] = filter_parms
896 901 #--Sampling Frequency
897 902 clock = filter_parms['clock']
898 903 filter_2 = filter_parms['filter_2']
899 904 filter_5 = filter_parms['filter_5']
900 905 filter_fir = filter_parms['filter_fir']
901 906 samp_freq_jars = clock/filter_2/filter_5/filter_fir
902 907
903 908 kwargs['samp_freq_jars'] = samp_freq_jars
904 909 kwargs['jars'] = configuration
905 910
906 911 #--------------------- RC ----------------------:
907 912 if configuration.device.device_type.name == 'rc':
908 913 rc_conf = True
909 914 rc_parms = configuration.parms_to_dict()
910 915 if rc_parms['mix'] == 'True':
911 916 pass
912 917 else:
913 918 rc_lines = rc_parms['lines']
914 919 dh = rc_lines[6]['params'][0]['resolution']
915 920 #--Sampling Frequency
916 921 samp_freq_rc = 0.15/dh
917 922 kwargs['samp_freq_rc'] = samp_freq_rc
918 923
919 924 kwargs['rc_conf'] = rc_conf
920 925 kwargs['rc'] = configuration
921 926
922 927 #-------------------- DDS ----------------------:
923 928 if configuration.device.device_type.name == 'dds':
924 929 dds_conf = True
925 930 dds_parms = configuration.parms_to_dict()
926 931
927 932 kwargs['dds_conf'] = dds_conf
928 933 kwargs['dds'] = configuration
929 934
930 935
931 936 #------------Validation------------:
932 937 #Clock
933 938 if dds_conf and rc_conf and jars_conf:
934 939 if filter_parms['clock'] != rc_parms['clock_in'] and rc_parms['clock_in'] != dds_parms['clock']:
935 940 messages.warning(request, "Devices don't have the same clock.")
936 941 elif rc_conf and jars_conf:
937 942 if filter_parms['clock'] != rc_parms['clock_in']:
938 943 messages.warning(request, "Devices don't have the same clock.")
939 944 elif rc_conf and dds_conf:
940 945 if rc_parms['clock_in'] != dds_parms['clock']:
941 946 messages.warning(request, "Devices don't have the same clock.")
942 947 if float(samp_freq_rc) != float(dds_parms['frequencyA']):
943 948 messages.warning(request, "Devices don't have the same Frequency A.")
944 949
945 950
946 951
947 952 ###### SIDEBAR ######
948 953 kwargs.update(sidebar(experiment=experiment))
949 954
950 955
951 956
952 957
953 958
954 959 return render(request, 'experiment_verify.html', kwargs)
955 960
956 961
957 962 def parse_mix_result(s):
958 963
959 964 values = s.split('-')
960 965 html = 'EXP MOD OPE DELAY MASK\r\n'
961 966
962 967 if not values or values[0] in ('', ' '):
963 968 return mark_safe(html)
964 969
965 970 for i, value in enumerate(values):
966 971 if not value:
967 972 continue
968 973 pk, mode, operation, delay, mask = value.split('|')
969 974 conf = RCConfiguration.objects.get(pk=pk)
970 975 if i==0:
971 976 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
972 977 conf.name,
973 978 mode,
974 979 ' ',
975 980 delay,
976 981 mask)
977 982 else:
978 983 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
979 984 conf.name,
980 985 mode,
981 986 operation,
982 987 delay,
983 988 mask)
984 989
985 990 return mark_safe(html)
986 991
987 992 def parse_mask(l):
988 993
989 994 values = []
990 995
991 996 for x in range(8):
992 997 if '{}'.format(x) in l:
993 998 values.append(1)
994 999 else:
995 1000 values.append(0)
996 1001
997 1002 values.reverse()
998 1003
999 1004 return int(''.join([str(x) for x in values]), 2)
1000 1005
1001 1006
1002 1007 def dev_confs(request):
1003 1008
1004 1009
1005 1010 page = request.GET.get('page')
1006 1011 order = ('type', 'device__device_type', 'experiment')
1007 1012 filters = request.GET.copy()
1008 1013
1009 1014 kwargs = get_paginator(Configuration, page, order, filters)
1010 1015
1011 1016 form = FilterForm(initial=request.GET, extra_fields=['tags','template'])
1012 1017 kwargs['keys'] = ['name', 'experiment', 'type', 'programmed_date']
1013 1018 kwargs['title'] = 'Configuration'
1014 1019 kwargs['suptitle'] = 'List'
1015 1020 kwargs['form'] = form
1016 1021 filters.pop('page', None)
1017 kwargs['q'] = urllib.urlencode(filters)
1022 kwargs['q'] = urlencode(filters)
1018 1023
1019 1024 return render(request, 'base_list.html', kwargs)
1020 1025
1021 1026
1022 1027 def dev_conf(request, id_conf):
1023 1028
1024 1029 conf = get_object_or_404(Configuration, pk=id_conf)
1025 1030
1026 1031 return redirect(conf.get_absolute_url())
1027 1032
1028 1033
1029 1034 def dev_conf_new(request, id_exp=0, id_dev=0):
1030 1035
1031 1036 initial = {}
1032 1037 kwargs = {}
1033 1038
1034 if id_exp<>0:
1039 if id_exp!=0:
1035 1040 initial['experiment'] = id_exp
1036 1041
1037 if id_dev<>0:
1042 if id_dev!=0:
1038 1043 initial['device'] = id_dev
1039 1044
1040 1045 if request.method == 'GET':
1041 1046
1042 1047 if id_dev:
1043 1048 kwargs['button'] = 'Create'
1044 1049 device = Device.objects.get(pk=id_dev)
1045 1050 DevConfForm = CONF_FORMS[device.device_type.name]
1046 1051 initial['name'] = request.GET['name']
1047 1052 form = DevConfForm(initial=initial)
1048 1053 else:
1049 1054 if 'template' in request.GET:
1050 1055 if request.GET['template']=='0':
1051 1056 choices = [(conf.pk, '{}'.format(conf)) for conf in Configuration.objects.filter(template=True)]
1052 1057 form = NewForm(initial={'create_from':2},
1053 1058 template_choices=choices)
1054 1059 else:
1055 1060 kwargs['button'] = 'Create'
1056 1061 conf = Configuration.objects.get(pk=request.GET['template'])
1057 1062 id_dev = conf.device.pk
1058 1063 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1059 1064 form = DevConfForm(instance=conf,
1060 1065 initial={'name': '{} [{:%Y/%m/%d}]'.format(conf.name, datetime.now()),
1061 1066 'template': False,
1062 1067 'experiment':id_exp})
1063 1068 elif 'blank' in request.GET:
1064 1069 kwargs['button'] = 'Create'
1065 1070 form = ConfigurationForm(initial=initial)
1066 1071 else:
1067 1072 form = NewForm()
1068 1073
1069 1074 if request.method == 'POST':
1070 1075
1071 1076 device = Device.objects.get(pk=request.POST['device'])
1072 1077 DevConfForm = CONF_FORMS[device.device_type.name]
1073 1078
1074 1079 form = DevConfForm(request.POST)
1075 1080 kwargs['button'] = 'Create'
1076 1081 if form.is_valid():
1077 1082 conf = form.save()
1078 1083
1079 1084 if 'template' in request.GET and conf.device.device_type.name=='rc':
1080 1085 lines = RCLine.objects.filter(rc_configuration=request.GET['template'])
1081 1086 for line in lines:
1082 1087 line.clone(rc_configuration=conf)
1083 1088
1084 1089 if conf.device.device_type.name=='jars':
1085 1090 conf.add_parms_to_filter()
1086 1091
1087 1092 return redirect('url_dev_conf', id_conf=conf.pk)
1088 1093
1089 1094 kwargs['id_exp'] = id_exp
1090 1095 kwargs['form'] = form
1091 1096 kwargs['title'] = 'Configuration'
1092 1097 kwargs['suptitle'] = 'New'
1093 1098
1094 1099
1095 1100 if id_dev != 0:
1096 1101 device = Device.objects.get(pk=id_dev)
1097 1102 kwargs['device'] = device.device_type.name
1098 1103
1099 1104 return render(request, 'dev_conf_edit.html', kwargs)
1100 1105
1101 1106
1102 1107 def dev_conf_edit(request, id_conf):
1103 1108
1104 1109 conf = get_object_or_404(Configuration, pk=id_conf)
1105 1110
1106 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1107 1111 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1108 1112
1109 dev_conf = DevConfModel.objects.get(pk=id_conf)
1110
1111 1113 if request.method=='GET':
1112 form = DevConfForm(instance=dev_conf)
1114 form = DevConfForm(instance=conf)
1113 1115
1114 1116 if request.method=='POST':
1115 form = DevConfForm(request.POST, instance=dev_conf)
1117 form = DevConfForm(request.POST, instance=conf)
1116 1118
1117 1119 if form.is_valid():
1118 1120 form.save()
1119 1121 return redirect('url_dev_conf', id_conf=id_conf)
1120 1122
1121 1123 kwargs = {}
1122 1124 kwargs['form'] = form
1123 1125 kwargs['title'] = 'Device Configuration'
1124 1126 kwargs['suptitle'] = 'Edit'
1125 1127 kwargs['button'] = 'Update'
1126 1128
1127 1129 ###### SIDEBAR ######
1128 1130 kwargs.update(sidebar(conf=conf))
1129 1131
1130 1132 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1131 1133
1132 1134
1133 1135 def dev_conf_start(request, id_conf):
1134 1136
1135 1137 conf = get_object_or_404(Configuration, pk=id_conf)
1136 1138
1137 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1138
1139 conf = DevConfModel.objects.get(pk=id_conf)
1140
1141 1139 if conf.start_device():
1142 1140 messages.success(request, conf.message)
1143 1141 else:
1144 1142 messages.error(request, conf.message)
1145 1143
1146 1144 conf.status_device()
1147 1145
1148 1146 return redirect(conf.get_absolute_url())
1149 1147
1150 1148
1151 1149 def dev_conf_stop(request, id_conf):
1152 1150
1153 1151 conf = get_object_or_404(Configuration, pk=id_conf)
1154 1152
1155 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1156
1157 conf = DevConfModel.objects.get(pk=id_conf)
1158
1159 1153 if conf.stop_device():
1160 1154 messages.success(request, conf.message)
1161 1155 else:
1162 1156 messages.error(request, conf.message)
1163 1157
1164 1158 conf.status_device()
1165 1159
1166 1160 return redirect(conf.get_absolute_url())
1167 1161
1168 1162
1169 1163 def dev_conf_status(request, id_conf):
1170 1164
1171 1165 conf = get_object_or_404(Configuration, pk=id_conf)
1172 1166
1173 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1174
1175 conf = DevConfModel.objects.get(pk=id_conf)
1176
1177 1167 if conf.status_device():
1178 1168 messages.success(request, conf.message)
1179 1169 else:
1180 1170 messages.error(request, conf.message)
1181 1171
1182 1172 return redirect(conf.get_absolute_url())
1183 1173
1184 1174
1185 1175 def dev_conf_write(request, id_conf):
1186 1176
1187 1177 conf = get_object_or_404(Configuration, pk=id_conf)
1188 1178
1189 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1190
1191 conf = DevConfModel.objects.get(pk=id_conf)
1192
1193 1179 answer = conf.write_device()
1194 1180 conf.status_device()
1195 1181
1196 1182 if answer:
1197 1183 messages.success(request, conf.message)
1198 1184
1199 1185 #Creating a historical configuration
1200 1186 conf.clone(type=1, template=False)
1201 1187
1202 1188 #Original configuration
1203 1189 conf = DevConfModel.objects.get(pk=id_conf)
1204 1190 else:
1205 1191 messages.error(request, conf.message)
1206 1192
1207 1193 return redirect(conf.get_absolute_url())
1208 1194
1209 1195
1210 1196 def dev_conf_read(request, id_conf):
1211 1197
1212 1198 conf = get_object_or_404(Configuration, pk=id_conf)
1213 1199
1214 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1215 1200 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1216 1201
1217 conf = DevConfModel.objects.get(pk=id_conf)
1218
1219 1202 if request.method=='GET':
1220 1203
1221 1204 parms = conf.read_device()
1222 1205 conf.status_device()
1223 1206
1224 1207 if not parms:
1225 1208 messages.error(request, conf.message)
1226 1209 return redirect(conf.get_absolute_url())
1227 1210
1228 1211 form = DevConfForm(initial=parms, instance=conf)
1229 1212
1230 1213 if request.method=='POST':
1231 1214 form = DevConfForm(request.POST, instance=conf)
1232 1215
1233 1216 if form.is_valid():
1234 1217 form.save()
1235 1218 return redirect(conf.get_absolute_url())
1236 1219
1237 1220 messages.error(request, "Parameters could not be saved")
1238 1221
1239 1222 kwargs = {}
1240 1223 kwargs['id_dev'] = conf.id
1241 1224 kwargs['form'] = form
1242 1225 kwargs['title'] = 'Device Configuration'
1243 1226 kwargs['suptitle'] = 'Parameters read from device'
1244 1227 kwargs['button'] = 'Save'
1245 1228
1246 1229 ###### SIDEBAR ######
1247 1230 kwargs.update(sidebar(conf=conf))
1248 1231
1249 1232 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
1250 1233
1251 1234
1252 1235 def dev_conf_import(request, id_conf):
1253 1236
1254 1237 conf = get_object_or_404(Configuration, pk=id_conf)
1255
1256 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1257 1238 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1258 conf = DevConfModel.objects.get(pk=id_conf)
1259 1239
1260 1240 if request.method == 'GET':
1261 1241 file_form = UploadFileForm()
1262 1242
1263 1243 if request.method == 'POST':
1264 1244 file_form = UploadFileForm(request.POST, request.FILES)
1265 1245
1266 1246 if file_form.is_valid():
1267 1247
1268 1248 parms = conf.import_from_file(request.FILES['file'])
1269 1249
1270 1250 if parms:
1271 1251 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
1272 1252 form = DevConfForm(initial=parms, instance=conf)
1273 1253
1274 1254 kwargs = {}
1275 1255 kwargs['id_dev'] = conf.id
1276 1256 kwargs['form'] = form
1277 1257 kwargs['title'] = 'Device Configuration'
1278 1258 kwargs['suptitle'] = 'Parameters imported'
1279 1259 kwargs['button'] = 'Save'
1280 1260 kwargs['action'] = conf.get_absolute_url_edit()
1281 1261 kwargs['previous'] = conf.get_absolute_url()
1282 1262
1283 1263 ###### SIDEBAR ######
1284 1264 kwargs.update(sidebar(conf=conf))
1285 1265
1286 1266 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1287 1267
1288 1268 messages.error(request, "Could not import parameters from file")
1289 1269
1290 1270 kwargs = {}
1291 1271 kwargs['id_dev'] = conf.id
1292 1272 kwargs['title'] = 'Device Configuration'
1293 1273 kwargs['form'] = file_form
1294 1274 kwargs['suptitle'] = 'Importing file'
1295 1275 kwargs['button'] = 'Import'
1296 1276
1297 1277 kwargs.update(sidebar(conf=conf))
1298 1278
1299 1279 return render(request, 'dev_conf_import.html', kwargs)
1300 1280
1301 1281
1302 1282 def dev_conf_export(request, id_conf):
1303 1283
1304 1284 conf = get_object_or_404(Configuration, pk=id_conf)
1305 1285
1306 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1307
1308 conf = DevConfModel.objects.get(pk=id_conf)
1309
1310 1286 if request.method == 'GET':
1311 1287 file_form = DownloadFileForm(conf.device.device_type.name)
1312 1288
1313 1289 if request.method == 'POST':
1314 1290 file_form = DownloadFileForm(conf.device.device_type.name, request.POST)
1315 1291
1316 1292 if file_form.is_valid():
1317 1293 fields = conf.export_to_file(format = file_form.cleaned_data['format'])
1318 1294
1319 1295 response = HttpResponse(content_type=fields['content_type'])
1320 1296 response['Content-Disposition'] = 'attachment; filename="%s"' %fields['filename']
1321 1297 response.write(fields['content'])
1322 1298
1323 1299 return response
1324 1300
1325 1301 messages.error(request, "Could not export parameters")
1326 1302
1327 1303 kwargs = {}
1328 1304 kwargs['id_dev'] = conf.id
1329 1305 kwargs['title'] = 'Device Configuration'
1330 1306 kwargs['form'] = file_form
1331 1307 kwargs['suptitle'] = 'Exporting file'
1332 1308 kwargs['button'] = 'Export'
1333 1309
1334 1310 return render(request, 'dev_conf_export.html', kwargs)
1335 1311
1336 1312
1337 1313 def dev_conf_delete(request, id_conf):
1338 1314
1339 1315 conf = get_object_or_404(Configuration, pk=id_conf)
1340 1316
1341 1317 if request.method=='POST':
1342 1318 if request.user.is_staff:
1343 1319 conf.delete()
1344 1320 return redirect('url_dev_confs')
1345 1321
1346 1322 messages.error(request, 'Not enough permission to delete this object')
1347 1323 return redirect(conf.get_absolute_url())
1348 1324
1349 1325 kwargs = {
1350 1326 'title': 'Delete',
1351 1327 'suptitle': 'Experiment',
1352 1328 'object': conf,
1353 1329 'previous': conf.get_absolute_url(),
1354 1330 'delete': True
1355 1331 }
1356 1332
1357 1333 return render(request, 'confirm.html', kwargs)
1358 1334
1359 1335
1360 1336 def sidebar(**kwargs):
1361 1337
1362 1338 side_data = {}
1363 1339
1364 1340 conf = kwargs.get('conf', None)
1365 1341 experiment = kwargs.get('experiment', None)
1366 1342
1367 1343 if not experiment:
1368 1344 experiment = conf.experiment
1369 1345
1370 1346 if experiment:
1371 1347 side_data['experiment'] = experiment
1372 1348 campaign = experiment.campaign_set.all()
1373 1349 if campaign:
1374 1350 side_data['campaign'] = campaign[0]
1375 1351 experiments = campaign[0].experiments.all()
1376 1352 else:
1377 1353 experiments = [experiment]
1378 1354 configurations = experiment.configuration_set.filter(type=0)
1379 1355 side_data['side_experiments'] = experiments
1380 1356 side_data['side_configurations'] = configurations
1381 1357
1382 1358 return side_data
1383 1359
1384 1360 def get_paginator(model, page, order, filters={}, n=10):
1385 1361
1386 1362 kwargs = {}
1387 1363 query = Q()
1388 1364 if isinstance(filters, QueryDict):
1389 1365 filters = filters.dict()
1390 1366 [filters.pop(key) for key in filters.keys() if filters[key] in ('', ' ')]
1391 1367 filters.pop('page', None)
1392 1368
1393 1369 if 'start_date' in filters:
1394 1370 filters['start_date__gte'] = filters.pop('start_date')
1395 1371 if 'end_date' in filters:
1396 1372 filters['start_date__lte'] = filters.pop('end_date')
1397 1373 if 'tags' in filters:
1398 1374 tags = filters.pop('tags')
1399 1375 if 'tags' in model._meta.get_all_field_names():
1400 1376 query = query | Q(tags__icontains=tags)
1401 1377 if 'name' in model._meta.get_all_field_names():
1402 1378 query = query | Q(name__icontains=tags)
1403 1379 if 'location' in model._meta.get_all_field_names():
1404 1380 query = query | Q(location__name__icontains=tags)
1405 1381 if 'device' in model._meta.get_all_field_names():
1406 1382 query = query | Q(device__name__icontains=tags)
1407 1383
1408 1384 object_list = model.objects.filter(query, **filters).order_by(*order)
1409 1385 paginator = Paginator(object_list, n)
1410 1386
1411 1387 try:
1412 1388 objects = paginator.page(page)
1413 1389 except PageNotAnInteger:
1414 1390 objects = paginator.page(1)
1415 1391 except EmptyPage:
1416 1392 objects = paginator.page(paginator.num_pages)
1417 1393
1418 1394 kwargs['objects'] = objects
1419 1395 kwargs['offset'] = (int(page)-1)*n if page else 0
1420 1396
1421 1397 return kwargs
1422 1398
1423 1399 def operation(request, id_camp=None):
1424 1400
1425 if not id_camp:
1426 campaigns = Campaign.objects.all().order_by('-start_date')
1427
1428 if not campaigns:
1429 1401 kwargs = {}
1430 kwargs['title'] = 'No Campaigns'
1431 kwargs['suptitle'] = 'Empty'
1432 return render(request, 'operation.html', kwargs)
1402 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1403 end_date__gte=datetime.now()).order_by('-start_date')
1433 1404
1434 id_camp = campaigns[0].id
1435 1405
1406 if id_camp:
1436 1407 campaign = get_object_or_404(Campaign, pk = id_camp)
1408 form = OperationForm(initial={'campaign': campaign.id}, campaigns=campaigns)
1409 kwargs['campaign'] = campaign
1410 else:
1411 form = OperationForm(campaigns=campaigns)
1412 kwargs['form'] = form
1413 return render(request, 'operation.html', kwargs)
1437 1414
1438 if request.method=='GET':
1439 form = OperationForm(initial={'campaign': campaign.id}, length = 5)
1440 1415
1441 if request.method=='POST':
1442 form = OperationForm(request.POST, initial={'campaign':campaign.id}, length = 5)
1443 1416
1444 if form.is_valid():
1445 return redirect('url_operation', id_camp=campaign.id)
1446 #locations = Location.objects.filter(experiment__campaign__pk = campaign.id).distinct()
1447 experiments = Experiment.objects.filter(campaign__pk=campaign.id)
1448 #for exs in experiments:
1449 # exs.get_status()
1450 locations= Location.objects.filter(experiment=experiments).distinct()
1451 #experiments = [Experiment.objects.filter(location__pk=location.id).filter(campaign__pk=campaign.id) for location in locations]
1452 kwargs = {}
1453 #---Campaign
1454 kwargs['campaign'] = campaign
1455 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
1456 1417 #---Experiment
1457 1418 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1458 1419 kwargs['experiment_keys'] = keys[1:]
1459 1420 kwargs['experiments'] = experiments
1460 1421 #---Radar
1461 kwargs['locations'] = locations
1422 kwargs['locations'] = campaign.get_experiments_by_location()
1423 print kwargs['locations']
1462 1424 #---Else
1463 1425 kwargs['title'] = 'Campaign'
1464 1426 kwargs['suptitle'] = campaign.name
1465 1427 kwargs['form'] = form
1466 kwargs['button'] = 'Search'
1467 kwargs['details'] = True
1468 kwargs['search_button'] = True
1469 1428
1470 1429 return render(request, 'operation.html', kwargs)
1471 1430
1472 1431
1473 1432 def operation_search(request, id_camp=None):
1474 1433
1475 1434
1476 1435 if not id_camp:
1477 1436 campaigns = Campaign.objects.all().order_by('-start_date')
1478 1437
1479 1438 if not campaigns:
1480 1439 return render(request, 'operation.html', {})
1481 1440
1482 1441 id_camp = campaigns[0].id
1483 1442 campaign = get_object_or_404(Campaign, pk = id_camp)
1484 1443
1485 1444 if request.method=='GET':
1486 1445 form = OperationSearchForm(initial={'campaign': campaign.id})
1487 1446
1488 1447 if request.method=='POST':
1489 1448 form = OperationSearchForm(request.POST, initial={'campaign':campaign.id})
1490 1449
1491 1450 if form.is_valid():
1492 1451 return redirect('url_operation', id_camp=campaign.id)
1493 1452
1494 1453 #locations = Location.objects.filter(experiment__campaign__pk = campaign.id).distinct()
1495 1454 experiments = Experiment.objects.filter(campaign__pk=campaign.id)
1496 1455 #for exs in experiments:
1497 1456 # exs.get_status()
1498 1457 locations= Location.objects.filter(experiment=experiments).distinct()
1499 1458 form = OperationSearchForm(initial={'campaign': campaign.id})
1500 1459
1501 1460 kwargs = {}
1502 1461 #---Campaign
1503 1462 kwargs['campaign'] = campaign
1504 1463 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
1505 1464 #---Experiment
1506 1465 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1507 1466 kwargs['experiment_keys'] = keys[1:]
1508 1467 kwargs['experiments'] = experiments
1509 1468 #---Radar
1510 1469 kwargs['locations'] = locations
1511 1470 #---Else
1512 1471 kwargs['title'] = 'Campaign'
1513 1472 kwargs['suptitle'] = campaign.name
1514 1473 kwargs['form'] = form
1515 1474 kwargs['button'] = 'Select'
1516 1475 kwargs['details'] = True
1517 1476 kwargs['search_button'] = False
1518 1477
1519 1478 return render(request, 'operation.html', kwargs)
1520 1479
1521 1480
1522 1481 def radar_play(request, id_camp, id_radar):
1523 1482 campaign = get_object_or_404(Campaign, pk = id_camp)
1524 1483 radar = get_object_or_404(Location, pk = id_radar)
1525 1484 today = datetime.today()
1526 1485 now = today.time()
1527 1486
1528 1487 #--Clear Old Experiments From RunningExperiment Object
1529 1488 running_experiment = RunningExperiment.objects.filter(radar=radar)
1530 1489 if running_experiment:
1531 1490 running_experiment = running_experiment[0]
1532 1491 running_experiment.running_experiment.clear()
1533 1492 running_experiment.save()
1534 1493
1535 1494 #--If campaign datetime is ok:
1536 1495 if today >= campaign.start_date and today <= campaign.end_date:
1537 1496 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1538 1497 for exp in experiments:
1539 1498 #--If experiment time is ok:
1540 1499 if now >= exp.start_time and now <= exp.end_time:
1541 1500 configurations = Configuration.objects.filter(experiment = exp)
1542 1501 for conf in configurations:
1543 1502 if 'cgs' in conf.device.device_type.name:
1544 1503 conf.status_device()
1545 1504 else:
1546 1505 answer = conf.start_device()
1547 1506 conf.status_device()
1548 1507 #--Running Experiment
1549 1508 old_running_experiment = RunningExperiment.objects.filter(radar=radar)
1550 1509 #--If RunningExperiment element exists
1551 1510 if old_running_experiment:
1552 1511 old_running_experiment = old_running_experiment[0]
1553 1512 old_running_experiment.running_experiment.add(exp)
1554 1513 old_running_experiment.status = 3
1555 1514 old_running_experiment.save()
1556 1515 #--Create a new Running_Experiment Object
1557 1516 else:
1558 1517 new_running_experiment = RunningExperiment(
1559 1518 radar = radar,
1560 1519 status = 3,
1561 1520 )
1562 1521 new_running_experiment.save()
1563 1522 new_running_experiment.running_experiment.add(exp)
1564 1523 new_running_experiment.save()
1565 1524
1566 1525 if answer:
1567 1526 messages.success(request, conf.message)
1568 1527 exp.status=2
1569 1528 exp.save()
1570 1529 else:
1571 1530 messages.error(request, conf.message)
1572 1531 else:
1573 1532 if exp.status == 1 or exp.status == 3:
1574 1533 exp.status=3
1575 1534 exp.save()
1576 1535
1577 1536
1578 1537 route = request.META['HTTP_REFERER']
1579 1538 route = str(route)
1580 1539 if 'search' in route:
1581 1540 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1582 1541 else:
1583 1542 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1584 1543
1585 1544
1586 1545 def radar_stop(request, id_camp, id_radar):
1587 1546 campaign = get_object_or_404(Campaign, pk = id_camp)
1588 1547 radar = get_object_or_404(Location, pk = id_radar)
1589 1548 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1590 1549
1591 1550 for exp in experiments:
1592 1551 configurations = Configuration.objects.filter(experiment = exp)
1593 1552 for conf in configurations:
1594 1553 if 'cgs' in conf.device.device_type.name:
1595 1554 conf.status_device()
1596 1555 else:
1597 1556 answer = conf.stop_device()
1598 1557 conf.status_device()
1599 1558
1600 1559 if answer:
1601 1560 messages.success(request, conf.message)
1602 1561 exp.status=1
1603 1562 exp.save()
1604 1563 else:
1605 1564 messages.error(request, conf.message)
1606 1565
1607 1566
1608 1567 route = request.META['HTTP_REFERER']
1609 1568 route = str(route)
1610 1569 if 'search' in route:
1611 1570 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1612 1571 else:
1613 1572 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1614 1573
1615 1574
1616 1575 def radar_refresh(request, id_camp, id_radar):
1617 1576
1618 1577 campaign = get_object_or_404(Campaign, pk = id_camp)
1619 1578 radar = get_object_or_404(Location, pk = id_radar)
1620 1579 experiments = Experiment.objects.filter(campaign=campaign).filter(location=radar)
1621 1580 for exs in experiments:
1622 1581 exs.get_status()
1623 1582
1624 1583 route = request.META['HTTP_REFERER']
1625 1584 route = str(route)
1626 1585 if 'search' in route:
1627 1586 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
1628 1587 else:
1629 1588 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1589
@@ -1,5 +1,5
1 from django.conf.urls import patterns, url
1 from django.conf.urls import url
2 2
3 urlpatterns = patterns('apps.misc.views',
3 urlpatterns = (
4 4
5 5 )
@@ -1,384 +1,382
1 1 import os
2 2 import json
3 3
4 4 from django import forms
5 5 from django.utils.safestring import mark_safe
6 6 from apps.main.models import Device
7 7 from apps.main.forms import add_empty_choice
8 8 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
9 9 from .widgets import KmUnitWidget, KmUnitHzWidget, KmUnitDcWidget, UnitKmWidget, DefaultWidget, CodesWidget, HiddenWidget, HCheckboxSelectMultiple
10 10
11 11 def create_choices_from_model(model, conf_id, all_choice=False):
12 12
13 13 if model=='RCLine':
14 14 instance = RCConfiguration.objects.get(pk=conf_id)
15 15 choices = [(line.pk, line.get_name()) for line in instance.get_lines(line_type__name='tx')]
16 16 if all_choice:
17 17 choices = add_empty_choice(choices, label='All')
18 18 else:
19 19 instance = globals()[model]
20 20 choices = instance.objects.all().values_list('pk', 'name')
21 21
22 22 return choices
23 23
24 24
25 25 class ExtFileField(forms.FileField):
26 26 """
27 27 Same as forms.FileField, but you can specify a file extension whitelist.
28 28
29 29 >>> from django.core.files.uploadedfile import SimpleUploadedFile
30 30 >>>
31 31 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
32 32 >>>
33 33 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
34 34 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
35 35 >>>
36 36 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
37 37 Traceback (most recent call last):
38 38 ...
39 39 ValidationError: [u'Not allowed filetype!']
40 40 """
41 41 def __init__(self, *args, **kwargs):
42 42 extensions = kwargs.pop("extensions")
43 43 self.extensions = [i.lower() for i in extensions]
44 44
45 45 super(ExtFileField, self).__init__(*args, **kwargs)
46 46
47 47 def clean(self, *args, **kwargs):
48 48 data = super(ExtFileField, self).clean(*args, **kwargs)
49 49 filename = data.name
50 50 ext = os.path.splitext(filename)[1]
51 51 ext = ext.lower()
52 52 if ext not in self.extensions:
53 53 raise forms.ValidationError('Not allowed file type: %s' % ext)
54 54
55 55
56 56 class RCConfigurationForm(forms.ModelForm):
57 57
58 58 def __init__(self, *args, **kwargs):
59 59 super(RCConfigurationForm, self).__init__(*args, **kwargs)
60 60
61 61 instance = getattr(self, 'instance', None)
62 62
63 63 if instance and instance.pk:
64 64
65 65 devices = Device.objects.filter(device_type__name='rc')
66 66 if instance.experiment:
67 67 self.fields['experiment'].widget.attrs['read_only'] = True
68 68 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
69 69 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
70 70 self.fields['ipp'].widget = KmUnitHzWidget(attrs={'km2unit':instance.km2unit})
71 71 self.fields['clock'].widget.attrs['readonly'] = True
72 72
73 73 self.fields['time_before'].label = mark_safe(self.fields['time_before'].label)
74 74 self.fields['time_after'].label = mark_safe(self.fields['time_after'].label)
75 75
76 76 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
77 77 self.fields['experiment'].widget.attrs['readonly'] = True
78 78
79 79 class Meta:
80 80 model = RCConfiguration
81 81 exclude = ('type', 'parameters', 'status', 'total_units', 'mix')
82 82
83 83 def clean(self):
84 84 form_data = super(RCConfigurationForm, self).clean()
85 85
86 86 if 'clock_divider' in form_data:
87 87 if form_data['clock_divider']<1:
88 88 self.add_error('clock_divider', 'Invalid Value')
89 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 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 93 return form_data
94 94
95 95 def save(self):
96 96 conf = super(RCConfigurationForm, self).save()
97 97 conf.total_units = conf.ipp*conf.ntx*conf.km2unit
98 98 conf.save()
99 99 return conf
100 100
101 101
102 102 class RCMixConfigurationForm(forms.Form):
103 103
104 104 clock_in = forms.CharField(widget=forms.HiddenInput())
105 105 clock_divider = forms.CharField(widget=forms.HiddenInput())
106 106 name = forms.CharField()
107 107 experiment = forms.ChoiceField()
108 108 mode = forms.ChoiceField(widget=forms.RadioSelect(),
109 109 choices=[(0, 'Parallel'), (1, 'Sequence')],
110 110 initial=0)
111 111 operation = forms.ChoiceField(widget=forms.RadioSelect(),
112 112 choices=[(0, 'OR'), (1, 'XOR'), (2, 'AND'), (3, 'NAND')],
113 113 initial=1)
114 114 delay = forms.CharField()
115 115 mask = forms.MultipleChoiceField(choices=[(0, 'L1'),(1, 'L2'),(2, 'L3'),(3, 'L4'),(4, 'L5'),(5, 'L6'),(6, 'L7'),(7, 'L8')],
116 116 widget=HCheckboxSelectMultiple())
117 117 result = forms.CharField(required=False,
118 118 widget=forms.Textarea(attrs={'readonly':True, 'rows':5, 'class':'tabuled'}))
119 119
120 120 def __init__(self, *args, **kwargs):
121 121 confs = kwargs.pop('confs', [])
122 122 if confs:
123 123 km2unit = confs[0].km2unit
124 124 clock_in = confs[0].clock_in
125 125 clock_divider = confs[0].clock_divider
126 126 else:
127 127 km2unit = clock_in = clock_divider = 0
128 128 super(RCMixConfigurationForm, self).__init__(*args, **kwargs)
129 129 self.fields['experiment'].choices = [(conf.pk, '{} | {}'.format(conf.pk, conf.name)) for conf in confs]
130 130 self.fields['delay'].widget = KmUnitWidget(attrs = {'km2unit':km2unit})
131 131 self.fields['clock_in'].initial = clock_in
132 132 self.fields['clock_divider'].initial = clock_divider
133 133
134 134
135 135 class RCLineForm(forms.ModelForm):
136 136
137 137 def __init__(self, *args, **kwargs):
138 138 self.extra_fields = kwargs.pop('extra_fields', [])
139 139 super(RCLineForm, self).__init__(*args, **kwargs)
140 140
141 141 if 'initial' in kwargs and 'line_type' in kwargs['initial']:
142 142 line_type = RCLineType.objects.get(pk=kwargs['initial']['line_type'])
143 143
144 144 if 'code_id' in kwargs['initial']:
145 145 model_initial = kwargs['initial']['code_id']
146 146 else:
147 147 model_initial = 0
148 148
149 149 params = json.loads(line_type.params)
150 150
151 151 for label, value in self.extra_fields.items():
152 152 if label=='params':
153 153 continue
154 154
155 155 if 'model' in params[label]:
156 156 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
157 157 kwargs['initial']['rc_configuration']),
158 158 initial=model_initial)
159 159
160 160
161 161 else:
162 162 if label=='codes' and 'code_id' in kwargs['initial']:
163 163 self.fields[label] = forms.CharField(initial=RCLineCode.objects.get(pk=kwargs['initial']['code_id']).codes)
164 164 else:
165 165 self.fields[label] = forms.CharField(initial=value['value'])
166 166
167 167 if label=='codes':
168 168 self.fields[label].widget = CodesWidget()
169 169
170 170 if self.data:
171 171 line_type = RCLineType.objects.get(pk=self.data['line_type'])
172 172
173 173 if 'code_id' in self.data:
174 174 model_initial = self.data['code_id']
175 175 else:
176 176 model_initial = 0
177 177
178 178 params = json.loads(line_type.params)
179 179
180 180 for label, value in self.extra_fields.items():
181 181 if label=='params':
182 182 continue
183 183
184 184 if 'model' in params[label]:
185 185 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
186 186 self.data['rc_configuration']),
187 187 initial=model_initial)
188 188
189 189
190 190 else:
191 191 if label=='codes' and 'code' in self.data:
192 192 self.fields[label] = forms.CharField(initial=self.data['codes'])
193 193 else:
194 194 self.fields[label] = forms.CharField(initial=self.data[label])
195 195
196 196 if label=='codes':
197 197 self.fields[label].widget = CodesWidget()
198 198
199 199
200 200 class Meta:
201 201 model = RCLine
202 202 fields = ('rc_configuration', 'line_type', 'channel')
203 203 widgets = {
204 204 'channel': forms.HiddenInput(),
205 205 }
206 206
207 207
208 208 def clean(self):
209 209
210 210 form_data = self.cleaned_data
211 211 if 'code' in self.data and self.data['TX_ref']=="0":
212 212 self.add_error('TX_ref', 'Choose a valid TX reference')
213 213
214 214 if RCLineType.objects.get(pk=self.data['line_type']).name=='mix':
215 215 self.add_error('line_type', 'Invalid Line type')
216 216
217 217 return form_data
218 218
219 219
220 220 def save(self):
221 221 line = super(RCLineForm, self).save()
222 222
223 223 #auto add channel
224 224 line.channel = RCLine.objects.filter(rc_configuration=line.rc_configuration).count()-1
225 225
226 226 #auto add position for TX, TR & CODE
227 227 if line.line_type.name in ('tx', ):
228 228 line.position = RCLine.objects.filter(rc_configuration=line.rc_configuration, line_type=line.line_type).count()-1
229 229
230 230 #save extra fields in params
231 231 params = {}
232 232 for label, value in self.extra_fields.items():
233 233 if label=='params':
234 234 params['params'] = []
235 235 elif label=='codes':
236 236 params[label] = [s for s in self.data[label].split('\r\n') if s]
237 237 else:
238 238 params[label] = self.data[label]
239 239 line.params = json.dumps(params)
240 240 line.save()
241 241 return
242 242
243 243
244 244 class RCLineViewForm(forms.Form):
245 245
246 246 def __init__(self, *args, **kwargs):
247 247
248 248 extra_fields = kwargs.pop('extra_fields')
249 249 line = kwargs.pop('line')
250 250 subform = kwargs.pop('subform', False)
251 251 super(RCLineViewForm, self).__init__(*args, **kwargs)
252 252
253 253 if subform:
254 254 params = json.loads(line.line_type.params)['params']
255 255 else:
256 256 params = json.loads(line.line_type.params)
257 257
258 258 for label, value in extra_fields.items():
259 259
260 260 if label=='params':
261 261 continue
262 262 if 'ref' in label:
263 263 if value in (0, '0'):
264 264 value = 'All'
265 265 else:
266 266 value = RCLine.objects.get(pk=value).get_name()
267 267 elif label=='code':
268 268 value = RCLineCode.objects.get(pk=value).name
269 269
270 270 self.fields[label] = forms.CharField(initial=value)
271 271
272 272 if 'widget' in params[label]:
273 273 km2unit = line.rc_configuration.km2unit
274 274 if params[label]['widget']=='km':
275 275 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
276 276 elif params[label]['widget']=='unit':
277 277 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
278 278 elif params[label]['widget']=='dc':
279 279 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
280 280 elif params[label]['widget']=='codes':
281 281 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
282 282 else:
283 283 self.fields[label].widget = DefaultWidget(attrs={'disabled':True})
284 284
285 285
286 286 class RCLineEditForm(forms.ModelForm):
287 287
288 288 def __init__(self, *args, **kwargs):
289 289
290 290 extra_fields = kwargs.pop('extra_fields', [])
291 291 conf = kwargs.pop('conf', False)
292 292 line = kwargs.pop('line')
293 293 subform = kwargs.pop('subform', False)
294 294
295 295 super(RCLineEditForm, self).__init__(*args, **kwargs)
296 296
297 297 if subform is not False:
298 298 params = json.loads(line.line_type.params)['params']
299 299 count = subform
300 300 else:
301 301 params = json.loads(line.line_type.params)
302 302 count = -1
303 303
304 304 for label, value in extra_fields.items():
305 305
306 306 if label in ('params',):
307 307 continue
308 308 if 'help' in params[label]:
309 309 help_text = params[label]['help']
310 310 else:
311 311 help_text = ''
312 312
313 313 if 'model' in params[label]:
314 314 if line.line_type.name=='tr':
315 315 all_choice = True
316 316 else:
317 317 all_choice = False
318 318 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'], conf.id, all_choice=all_choice),
319 319 initial=value,
320 320 widget=forms.Select(attrs={'name':'%s|%s|%s' % (count, line.id, label)}),
321 321 help_text=help_text)
322 322
323 323 else:
324 324 self.fields[label] = forms.CharField(initial=value, help_text=help_text)
325 325
326 326 if label in ('code', ):
327 327 self.fields[label].widget = HiddenWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
328 328
329 329 elif 'widget' in params[label]:
330 330 km2unit = line.rc_configuration.km2unit
331 331 if params[label]['widget']=='km':
332 332 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
333 333 elif params[label]['widget']=='unit':
334 334 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
335 335 elif params[label]['widget']=='dc':
336 336 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
337 337 elif params[label]['widget']=='codes':
338 338 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
339 339 else:
340 340 self.fields[label].widget = DefaultWidget(attrs={'line':line, 'name':'%s|%s|%s' % (count, line.id, label)})
341 341
342 342
343 343 class Meta:
344 344 model = RCLine
345 345 exclude = ('rc_configuration', 'line_type', 'channel', 'position', 'params', 'pulses')
346 346
347 347
348 348 class RCSubLineEditForm(forms.Form):
349 349
350 350 def __init__(self, *args, **kwargs):
351 351 extra_fields = kwargs.pop('extra_fields')
352 352 count = kwargs.pop('count')
353 353 line = kwargs.pop('line')
354 354 super(RCSubLineEditForm, self).__init__(*args, **kwargs)
355 355 for label, value in extra_fields.items():
356 356 self.fields[label] = forms.CharField(initial=value,
357 357 widget=forms.TextInput(attrs={'name':'%s|%s|%s' % (count, line, label)}))
358 358
359 359
360 360 class RCImportForm(forms.Form):
361 361
362 362 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
363 363
364 364
365 365 class RCLineCodesForm(forms.ModelForm):
366 366
367 367 def __init__(self, *args, **kwargs):
368 368 super(RCLineCodesForm, self).__init__(*args, **kwargs)
369 369
370 370 if 'initial' in kwargs:
371 371 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
372 372 initial=kwargs['initial']['code'])
373 373 if 'instance' in kwargs:
374 374 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
375 375 initial=kwargs['instance'].pk)
376 376
377 377 self.fields['codes'].widget = CodesWidget()
378 378
379 379
380 380 class Meta:
381 381 model = RCLineCode
382 382 exclude = ('name',)
383
384 No newline at end of file
@@ -1,786 +1,786
1 1
2 2 import ast
3 3 import json
4 4 import numpy as np
5 5
6 from polymorphic import PolymorphicModel
7
8 6 from django.db import models
9 7 from django.core.urlresolvers import reverse
10 8 from django.core.validators import MinValueValidator, MaxValueValidator
11 9
12 10 from apps.main.models import Configuration
13 11 from devices.rc import api
14 12 from .utils import RCFile
15 13
16 14 # Create your models here.
17 15
18 16 LINE_TYPES = (
19 17 ('none', 'Not used'),
20 18 ('tr', 'Transmission/reception selector signal'),
21 19 ('tx', 'A modulating signal (Transmission pulse)'),
22 20 ('codes', 'BPSK modulating signal'),
23 21 ('windows', 'Sample window signal'),
24 22 ('sync', 'Synchronizing signal'),
25 23 ('flip', 'IPP related periodic signal'),
26 24 ('prog_pulses', 'Programmable pulse'),
27 25 ('mix', 'Mixed line'),
28 26 )
29 27
30 28
31 29 SAMPLING_REFS = (
32 30 ('none', 'No Reference'),
33 31 ('begin_baud', 'Begin of the first baud'),
34 32 ('first_baud', 'Middle of the first baud'),
35 33 ('sub_baud', 'Middle of the sub-baud')
36 34 )
37 35
38 36 DAT_CMDS = {
39 37 # Pulse Design commands
40 38 'DISABLE' : 0, # Disables pulse generation
41 39 'ENABLE' : 24, # Enables pulse generation
42 40 'DELAY_START' : 40, # Write delay status to memory
43 41 'FLIP_START' : 48, # Write flip status to memory
44 42 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
45 43 'TX_ONE' : 72, # Output '0' in line TX
46 44 'TX_ZERO' : 88, # Output '0' in line TX
47 45 'SW_ONE' : 104, # Output '0' in line SW
48 46 'SW_ZERO' : 112, # Output '1' in line SW
49 47 'RESTART': 120, # Restarts CR8 Firmware
50 48 'CONTINUE' : 253, # Function Unknown
51 49 # Commands available to new controllers
52 50 # 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.
53 51 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
54 52 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
55 53 'CLOCK_DIVIDER' : 8,
56 54 }
57 55
58 56
59 57 class RCConfiguration(Configuration):
60 58
61 59 ipp = models.FloatField(verbose_name='IPP [Km]', validators=[MinValueValidator(1), MaxValueValidator(9000)], default=300)
62 60 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(400)], default=1)
63 61 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
64 62 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
65 63 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
66 64 time_before = models.PositiveIntegerField(verbose_name='Time before [&mu;S]', default=12)
67 65 time_after = models.PositiveIntegerField(verbose_name='Time after [&mu;S]', default=1)
68 66 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
69 67 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
70 68 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
71 69 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
72 70 total_units = models.PositiveIntegerField(default=0)
73 71 mix = models.BooleanField(default=False)
74 72
75 73 class Meta:
76 74 db_table = 'rc_configurations'
77 75
78 76 def get_absolute_url_plot(self):
79 77 return reverse('url_plot_rc_pulses', args=[str(self.id)])
80 78
81 79 def get_absolute_url_import(self):
82 80 return reverse('url_import_rc_conf', args=[str(self.id)])
83 81
84 82 @property
85 83 def ipp_unit(self):
86 84
87 85 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
88 86
89 87 @property
90 88 def us2unit(self):
91 89
92 90 return self.clock_in/self.clock_divider
93 91
94 92 @property
95 93 def km2unit(self):
96 94
97 95 return 20./3*(self.clock_in/self.clock_divider)
98 96
99 97 def clone(self, **kwargs):
100 98
101 99 lines = self.get_lines()
102 100 self.pk = None
103 101 self.id = None
104 102 for attr, value in kwargs.items():
105 103 setattr(self, attr, value)
106 104 self.save()
107 105
108 106 for line in lines:
109 107 line.clone(rc_configuration=self)
110 108
111 109 return self
112 110
113 111 def get_lines(self, **kwargs):
114 112 '''
115 113 Retrieve configuration lines
116 114 '''
117 115
118 116 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
119 117
120 118
121 119 def clean_lines(self):
122 120 '''
123 121 '''
124 122
125 123 empty_line = RCLineType.objects.get(name='none')
126 124
127 125 for line in self.get_lines():
128 126 line.line_type = empty_line
129 127 line.params = '{}'
130 128 line.save()
131 129
132 130 def parms_to_dict(self):
133 131 '''
134 132 '''
135 133
136 134 ignored = ('parameters', 'type', 'polymorphic_ctype', 'configuration_ptr',
137 135 'created_date', 'programmed_date')
138 136
139 137 data = {}
140 138 for field in self._meta.fields:
141 139 if field.name in ignored:
142 140 continue
143 141 data[field.name] = '{}'.format(field.value_from_object(self))
144 142
145 143 data['device_id'] = data.pop('device')
146 144 data['lines'] = []
147 145
148 146 for line in self.get_lines():
149 147 line_data = json.loads(line.params)
150 148 if 'TX_ref' in line_data and line_data['TX_ref'] not in (0, '0'):
151 line_data['TX_ref'] = line.get_name()
149 line_data['TX_ref'] = RCLine.objects.get(pk=line_data['TX_ref']).get_name()
152 150 if 'code' in line_data:
153 151 line_data['code'] = RCLineCode.objects.get(pk=line_data['code']).name
154 152 line_data['type'] = line.line_type.name
155 153 line_data['name'] = line.get_name()
156 154 data['lines'].append(line_data)
157 155
158 156 data['delays'] = self.get_delays()
159 157 data['pulses'] = self.get_pulses()
160 158
161 159 return data
162 160
163 161 def dict_to_parms(self, data):
164 162 '''
165 163 '''
166 164
167 165 self.name = data['name']
168 166 self.ipp = float(data['ipp'])
169 167 self.ntx = int(data['ntx'])
170 168 self.clock_in = float(data['clock_in'])
171 169 self.clock_divider = int(data['clock_divider'])
172 170 self.clock = float(data['clock'])
173 171 self.time_before = data['time_before']
174 172 self.time_after = data['time_after']
175 173 self.sync = data['sync']
176 174 self.sampling_reference = data['sampling_reference']
177 175 self.total_units = self.ipp*self.ntx*self.km2unit
178 176 self.save()
179 177 self.clean_lines()
180 178
181 179 lines = []
182 180 positions = {'tx':0, 'tr':0}
183 181
184 182 for i, line_data in enumerate(data['lines']):
183 name = line_data.pop('name', '')
185 184 line_type = RCLineType.objects.get(name=line_data.pop('type'))
186 185 if line_type.name=='codes':
187 186 code = RCLineCode.objects.get(name=line_data['code'])
188 187 line_data['code'] = code.pk
189 188 line = RCLine.objects.filter(rc_configuration=self, channel=i)
190 189 if line:
191 190 line = line[0]
192 191 line.line_type = line_type
193 192 line.params = json.dumps(line_data)
194 193 else:
195 194 line = RCLine(rc_configuration=self, line_type=line_type,
196 195 params=json.dumps(line_data),
197 196 channel=i)
198 197
199 198 if line_type.name=='tx':
200 199 line.position = positions['tx']
201 200 positions['tx'] += 1
202 201
203 202 if line_type.name=='tr':
204 203 line.position = positions['tr']
205 204 positions['tr'] += 1
206 205
207 206 line.save()
208 207 lines.append(line)
209 208
210 209 for line, line_data in zip(lines, data['lines']):
211 210 if 'TX_ref' in line_data:
212 211 params = json.loads(line.params)
213 212 if line_data['TX_ref'] in (0, '0'):
214 213 params['TX_ref'] = '0'
215 214 else:
216 215 params['TX_ref'] = [l.pk for l in lines if l.line_type.name=='tx' and line_data['TX_ref'] in l.get_name()][0]
217 216 line.params = json.dumps(params)
218 217 line.save()
219 218
220 219
221 220 def get_delays(self):
222 221
223 222 pulses = [line.pulses_as_points() for line in self.get_lines()]
224 223 points = [tup for tups in pulses for tup in tups]
225 224 points = set([x for tup in points for x in tup])
226 225 points = list(points)
227 226 points.sort()
228 227
229 if points[0]<>0:
228 if points[0]!=0:
230 229 points.insert(0, 0)
231 230
232 231 return [points[i+1]-points[i] for i in range(len(points)-1)]
233 232
234 233
235 234 def get_pulses(self, binary=True):
236 235
237 236 pulses = [line.pulses_as_points() for line in self.get_lines()]
238 237 points = [tup for tups in pulses for tup in tups]
239 238 points = set([x for tup in points for x in tup])
240 239 points = list(points)
241 240 points.sort()
242 241
243 242 line_points = [line.pulses_as_points() for line in self.get_lines()]
244 243 line_points = [[(x, x+y) for x,y in tups] for tups in line_points]
245 244 line_points = [[t for x in tups for t in x] for tups in line_points]
246 245 states = [[1 if x in tups else 0 for tups in line_points] for x in points]
247 246
248 247 if binary:
249 248 states.reverse()
250 249 states = [int(''.join([str(x) for x in flips]), 2) for flips in states]
251 250
252 251 return states[:-1]
253 252
254 253 def add_cmd(self, cmd):
255 254
256 255 if cmd in DAT_CMDS:
257 256 return (255, DAT_CMDS[cmd])
258 257
259 258 def add_data(self, value):
260 259
261 260 return (254, value-1)
262 261
263 262 def parms_to_binary(self):
264 263 '''
265 264 Create "dat" stream to be send to CR
266 265 '''
267 266
268 267 data = []
269 268 # create header
270 269 data.append(self.add_cmd('DISABLE'))
271 270 data.append(self.add_cmd('CONTINUE'))
272 271 data.append(self.add_cmd('RESTART'))
273 272
274 273 if self.control_sw:
275 274 data.append(self.add_cmd('SW_ONE'))
276 275 else:
277 276 data.append(self.add_cmd('SW_ZERO'))
278 277
279 278 if self.control_tx:
280 279 data.append(self.add_cmd('TX_ONE'))
281 280 else:
282 281 data.append(self.add_cmd('TX_ZERO'))
283 282
284 283 # write divider
285 284 data.append(self.add_cmd('CLOCK_DIVIDER'))
286 285 data.append(self.add_data(self.clock_divider))
287 286
288 287 # write delays
289 288 data.append(self.add_cmd('DELAY_START'))
290 289 # first delay is always zero
291 290 data.append(self.add_data(1))
292 291
293 292 delays = self.get_delays()
294 293
295 294 for delay in delays:
296 295 while delay>252:
297 296 data.append(self.add_data(253))
298 297 delay -= 253
299 298 data.append(self.add_data(delay))
300 299
301 300 # write flips
302 301 data.append(self.add_cmd('FLIP_START'))
303 302
304 303 states = self.get_pulses(binary=False)
305 304
306 305 for flips, delay in zip(states, delays):
307 306 flips.reverse()
308 307 flip = int(''.join([str(x) for x in flips]), 2)
309 308 data.append(self.add_data(flip+1))
310 309 while delay>252:
311 310 data.append(self.add_data(1))
312 311 delay -= 253
313 312
314 313 # write sampling period
315 314 data.append(self.add_cmd('SAMPLING_PERIOD'))
316 315 wins = self.get_lines(line_type__name='windows')
317 316 if wins:
318 317 win_params = json.loads(wins[0].params)['params']
319 318 if win_params:
320 319 dh = int(win_params[0]['resolution']*self.km2unit)
321 320 else:
322 321 dh = 1
323 322 else:
324 323 dh = 1
325 324 data.append(self.add_data(dh))
326 325
327 326 # write enable
328 327 data.append(self.add_cmd('ENABLE'))
329 328
330 329 return '\n'.join(['{}'.format(x) for tup in data for x in tup])
331 330
332 331 def update_from_file(self, filename):
333 332 '''
334 333 Update instance from file
335 334 '''
336 335
337 336 f = RCFile(filename)
338 337 self.dict_to_parms(f.data)
339 338 self.update_pulses()
340 339
341 340 def update_pulses(self):
342 341
343 342 for line in self.get_lines():
344 343 line.update_pulses()
345 344
346 345 def plot_pulses(self, km=False):
347 346
348 347 import matplotlib.pyplot as plt
349 348 from bokeh.resources import CDN
350 349 from bokeh.embed import components
351 350 from bokeh.mpl import to_bokeh
352 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, PreviewSaveTool
351 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
353 352
354 353 lines = self.get_lines()
355 354
356 355 N = len(lines)
357 356 npoints = self.total_units/self.km2unit if km else self.total_units
358 357 fig = plt.figure(figsize=(10, 2+N*0.5))
359 358 ax = fig.add_subplot(111)
360 359 labels = ['IPP']
361 360
362 361 for i, line in enumerate(lines):
363 362 labels.append(line.get_name(channel=True))
364 363 l = ax.plot((0, npoints),(N-i-1, N-i-1))
365 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup<>(0,0)]
364 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
366 365 ax.broken_barh(points, (N-i-1, 0.5),
367 366 edgecolor=l[0].get_color(), facecolor='none')
368 367
369 368 n = 0
370 369 f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
371 370 for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
372 371 if n%f==0:
373 372 ax.text(x, N, '%s' % n, size=10)
374 373 n += 1
375 374
376 375
377 376 labels.reverse()
377 ax.set_yticks(range(len(labels)))
378 378 ax.set_yticklabels(labels)
379
380 379 ax.set_xlabel = 'Units'
381 380 plot = to_bokeh(fig, use_pandas=False)
382 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), PreviewSaveTool()]
381 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()]
382 plot.toolbar_location="above"
383 383
384 384 return components(plot, CDN)
385 385
386 386 def status_device(self):
387 387
388 388 return 0
389 389
390 390 def stop_device(self):
391 391
392 392 answer = api.disable(ip = self.device.ip_address,
393 393 port = self.device.port_address)
394 394
395 395 if answer[0] != "1":
396 396 self.message = answer[0:]
397 397 return 0
398 398
399 399 self.message = answer[2:]
400 400 return 1
401 401
402 402 def start_device(self):
403 403
404 404 answer = api.enable(ip = self.device.ip_address,
405 405 port = self.device.port_address)
406 406
407 407 if answer[0] != "1":
408 408 self.message = answer[0:]
409 409 return 0
410 410
411 411 self.message = answer[2:]
412 412 return 1
413 413
414 414 def write_device(self):
415 415 answer = api.write_config(ip = self.device.ip_address,
416 416 port = self.device.port_address,
417 417 parms = self.parms_to_dict())
418 418
419 419 if answer[0] != "1":
420 420 self.message = answer[0:]
421 421 return 0
422 422
423 423 self.message = answer[2:]
424 424 return 1
425 425
426 426
427 427 class RCLineCode(models.Model):
428 428
429 429 name = models.CharField(max_length=40)
430 430 bits_per_code = models.PositiveIntegerField(default=0)
431 431 number_of_codes = models.PositiveIntegerField(default=0)
432 432 codes = models.TextField(blank=True, null=True)
433 433
434 434 class Meta:
435 435 db_table = 'rc_line_codes'
436 436 ordering = ('name',)
437 437
438 def __unicode__(self):
438 def __str__(self):
439 439 return u'%s' % self.name
440 440
441 441
442 442 class RCLineType(models.Model):
443 443
444 444 name = models.CharField(choices=LINE_TYPES, max_length=40)
445 445 description = models.TextField(blank=True, null=True)
446 446 params = models.TextField(default='[]')
447 447
448 448 class Meta:
449 449 db_table = 'rc_line_types'
450 450
451 def __unicode__(self):
451 def __str__(self):
452 452 return u'%s - %s' % (self.name.upper(), self.get_name_display())
453 453
454 454
455 455 class RCLine(models.Model):
456 456
457 457 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
458 458 line_type = models.ForeignKey(RCLineType)
459 459 channel = models.PositiveIntegerField(default=0)
460 460 position = models.PositiveIntegerField(default=0)
461 461 params = models.TextField(default='{}')
462 462 pulses = models.TextField(default='')
463 463
464 464 class Meta:
465 465 db_table = 'rc_lines'
466 466 ordering = ['channel']
467 467
468 def __unicode__(self):
468 def __str__(self):
469 469 if self.rc_configuration:
470 470 return u'%s - %s' % (self.rc_configuration, self.get_name())
471 471
472 472 def clone(self, **kwargs):
473 473
474 474 self.pk = None
475 475
476 476 for attr, value in kwargs.items():
477 477 setattr(self, attr, value)
478 478
479 479 self.save()
480 480
481 481 return self
482 482
483 483 def get_name(self, channel=False):
484 484
485 485 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
486 486 s = ''
487 487
488 488 if self.line_type.name in ('tx',):
489 489 s = chars[self.position]
490 490 elif self.line_type.name in ('codes', 'windows', 'tr'):
491 491 if 'TX_ref' in json.loads(self.params):
492 492 pk = json.loads(self.params)['TX_ref']
493 493 if pk in (0, '0'):
494 494 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
495 495 else:
496 496 ref = RCLine.objects.get(pk=pk)
497 497 s = chars[ref.position]
498 498 s = '({})'.format(s)
499 499
500 500 s = '{}{}'.format(self.line_type.name.upper(), s)
501 501
502 502 if channel:
503 503 return '{} {}'.format(s, self.channel)
504 504 else:
505 505 return s
506 506
507 507 def get_lines(self, **kwargs):
508 508
509 509 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
510 510
511 511 def pulses_as_array(self):
512 512
513 513 y = np.zeros(self.rc_configuration.total_units)
514 514
515 515 for tup in ast.literal_eval(self.pulses):
516 516 y[tup[0]:tup[1]] = 1
517 517
518 518 return y.astype(np.int8)
519 519
520 520 def pulses_as_points(self, km=False):
521 521
522 522 if km:
523 523 unit2km = 1/self.rc_configuration.km2unit
524 524 return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
525 525 else:
526 526 return ast.literal_eval(self.pulses)
527 527
528 528 def get_win_ref(self, params, tx_id, km2unit):
529 529
530 530 ref = self.rc_configuration.sampling_reference
531 531 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
532 532
533 533 if codes:
534 534 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
535 535 else:
536 536 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
537 537
538 538 if ref=='first_baud':
539 539 return int(1 + (tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit)
540 540 elif ref=='sub_baud':
541 541 return int(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
542 542 else:
543 543 return 0
544 544
545 545 def update_pulses(self):
546 546 '''
547 547 Update pulses field
548 548 '''
549 549
550 550 km2unit = self.rc_configuration.km2unit
551 551 us2unit = self.rc_configuration.us2unit
552 552 ipp = self.rc_configuration.ipp
553 553 ntx = self.rc_configuration.ntx
554 554 ipp_u = int(ipp*km2unit)
555 555 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
556 556 y = []
557 557
558 558 if self.line_type.name=='tr':
559 559 tr_params = json.loads(self.params)
560 560
561 561 if tr_params['TX_ref'] in ('0', 0):
562 562 txs = self.get_lines(line_type__name='tx')
563 563 else:
564 564 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
565 565
566 566 for tx in txs:
567 567 params = json.loads(tx.params)
568 568
569 569 if float(params['pulse_width'])==0:
570 570 continue
571 571 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
572 572 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
573 573 before = 0
574 574 after = int(self.rc_configuration.time_after*us2unit)
575 575
576 576 y_tx = self.points(ntx, ipp_u, width,
577 577 delay=delays,
578 578 before=before,
579 579 after=after,
580 580 sync=self.rc_configuration.sync)
581 581
582 582 ranges = params['range'].split(',')
583 583
584 if len(ranges)>0 and ranges[0]<>'0':
584 if len(ranges)>0 and ranges[0]!='0':
585 585 y_tx = self.mask_ranges(y_tx, ranges)
586 586
587 587 tr_ranges = tr_params['range'].split(',')
588 588
589 if len(tr_ranges)>0 and tr_ranges[0]<>'0':
589 if len(tr_ranges)>0 and tr_ranges[0]!='0':
590 590 y_tx = self.mask_ranges(y_tx, tr_ranges)
591 591
592 592 y.extend(y_tx)
593 593
594 self.pulses = unicode(y)
594 self.pulses = str(y)
595 595 y = self.array_to_points(self.pulses_as_array())
596 596
597 597 elif self.line_type.name=='tx':
598 598 params = json.loads(self.params)
599 599 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
600 600 width = float(params['pulse_width'])*km2unit
601 601
602 602 if width>0:
603 603 before = int(self.rc_configuration.time_before*us2unit)
604 604 after = 0
605 605
606 606 y = self.points(ntx, ipp_u, width,
607 607 delay=delays,
608 608 before=before,
609 609 after=after,
610 610 sync=self.rc_configuration.sync)
611 611
612 612 ranges = params['range'].split(',')
613 613
614 if len(ranges)>0 and ranges[0]<>'0':
614 if len(ranges)>0 and ranges[0]!='0':
615 615 y = self.mask_ranges(y, ranges)
616 616
617 617 elif self.line_type.name=='flip':
618 618 n = float(json.loads(self.params)['number_of_flips'])
619 619 width = n*ipp*km2unit
620 620 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
621 621
622 622 elif self.line_type.name=='codes':
623 623 params = json.loads(self.params)
624 624 tx = RCLine.objects.get(pk=params['TX_ref'])
625 625 tx_params = json.loads(tx.params)
626 626 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
627 f = int(float(tx_params['pulse_width'])*km2unit)/len(params['codes'][0])
627 f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
628 628 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
629 629 codes = [self.array_to_points(code) for code in codes]
630 630 n = len(codes)
631 631
632 632 for i, tup in enumerate(tx.pulses_as_points()):
633 633 code = codes[i%n]
634 634 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
635 635
636 636 ranges = tx_params['range'].split(',')
637 if len(ranges)>0 and ranges[0]<>'0':
637 if len(ranges)>0 and ranges[0]!='0':
638 638 y = self.mask_ranges(y, ranges)
639 639
640 640 elif self.line_type.name=='sync':
641 641 params = json.loads(self.params)
642 642 n = ipp_u*ntx
643 643 if params['invert'] in ('1', 1):
644 644 y = [(n-1, n)]
645 645 else:
646 646 y = [(0, 1)]
647 647
648 648 elif self.line_type.name=='prog_pulses':
649 649 params = json.loads(self.params)
650 650 if int(params['periodic'])==0:
651 651 nntx = 1
652 652 nipp = ipp_u*ntx
653 653 else:
654 654 nntx = ntx
655 655 nipp = ipp_u
656 656
657 657 if 'params' in params and len(params['params'])>0:
658 658 for p in params['params']:
659 659 y_pp = self.points(nntx, nipp,
660 660 p['end']-p['begin'],
661 661 before=p['begin'])
662 662
663 663 y.extend(y_pp)
664 664
665 665 elif self.line_type.name=='windows':
666 666 params = json.loads(self.params)
667 667
668 668 if 'params' in params and len(params['params'])>0:
669 669 tr_params = json.loads(self.get_lines(line_type__name='tr')[0].params)
670 670 tr_ranges = tr_params['range'].split(',')
671 671 for p in params['params']:
672 672 y_win = self.points(ntx, ipp_u,
673 673 p['resolution']*p['number_of_samples']*km2unit,
674 674 before=int(self.rc_configuration.time_before*us2unit)+self.get_win_ref(p, params['TX_ref'], km2unit),
675 675 sync=self.rc_configuration.sync)
676 676
677 if len(tr_ranges)>0 and tr_ranges[0]<>'0':
677 if len(tr_ranges)>0 and tr_ranges[0]!='0':
678 678 y_win = self.mask_ranges(y_win, tr_ranges)
679 679
680 680 y.extend(y_win)
681 681
682 682 elif self.line_type.name=='mix':
683 683 values = self.rc_configuration.parameters.split('-')
684 684 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
685 685 modes = [value.split('|')[1] for value in values]
686 686 ops = [value.split('|')[2] for value in values]
687 687 delays = [value.split('|')[3] for value in values]
688 688 masks = [value.split('|')[4] for value in values]
689 689 mask = list('{:8b}'.format(int(masks[0])))
690 690 mask.reverse()
691 691 if mask[self.channel] in ('0', '', ' '):
692 692 y = np.zeros(confs[0].total_units, dtype=np.int8)
693 693 else:
694 694 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
695 695
696 696 for i in range(1, len(values)):
697 697 mask = list('{:8b}'.format(int(masks[i])))
698 698 mask.reverse()
699 699
700 700 if mask[self.channel] in ('0', '', ' '):
701 701 continue
702 702 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
703 703 delay = float(delays[i])*km2unit
704 704
705 705 if modes[i]=='P':
706 706 if delay>0:
707 707 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
708 708 y_temp = np.empty_like(Y)
709 709 y_temp[:delay] = 0
710 710 y_temp[delay:] = Y[:-delay]
711 711 elif delay+len(Y)>len(y):
712 712 y_new = np.zeros(delay+len(Y), dtype=np.int8)
713 713 y_new[:len(y)] = y
714 714 y = y_new
715 715 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
716 716 y_temp[-len(Y):] = Y
717 717 elif delay+len(Y)==len(y):
718 718 y_temp = np.zeros(delay+len(Y))
719 719 y_temp[-len(Y):] = Y
720 720 elif delay+len(Y)<len(y):
721 721 y_temp = np.zeros(len(y), dtype=np.int8)
722 722 y_temp[delay:delay+len(Y)] = Y
723 723
724 724 if ops[i]=='OR':
725 725 y = y | y_temp
726 726 elif ops[i]=='XOR':
727 727 y = y ^ y_temp
728 728 elif ops[i]=='AND':
729 729 y = y & y_temp
730 730 elif ops[i]=='NAND':
731 731 y = y & ~y_temp
732 732 else:
733 733 y = np.concatenate([y, Y])
734 734
735 735 total = len(y)
736 736 y = self.array_to_points(y)
737 737
738 738 else:
739 739 y = []
740 740
741 if self.rc_configuration.total_units <> total:
741 if self.rc_configuration.total_units != total:
742 742 self.rc_configuration.total_units = total
743 743 self.rc_configuration.save()
744 744
745 self.pulses = unicode(y)
745 self.pulses = str(y)
746 746 self.save()
747 747
748 748 @staticmethod
749 749 def array_to_points(X):
750 750
751 751 d = X[1:]-X[:-1]
752 752
753 753 up = np.where(d==1)[0]
754 754 if X[0]==1:
755 755 up = np.concatenate((np.array([-1]), up))
756 756 up += 1
757 757
758 758 dw = np.where(d==-1)[0]
759 759 if X[-1]==1:
760 760 dw = np.concatenate((dw, np.array([len(X)-1])))
761 761 dw += 1
762 762
763 763 return [(tup[0], tup[1]) for tup in zip(up, dw)]
764 764
765 765 @staticmethod
766 766 def mask_ranges(Y, ranges):
767 767
768 768 y = [(0, 0) for __ in Y]
769 769
770 770 for index in ranges:
771 771 if '-' in index:
772 772 args = [int(a) for a in index.split('-')]
773 773 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
774 774 else:
775 775 y[int(index-1)] = Y[int(index-1)]
776 776
777 777 return y
778 778
779 779 @staticmethod
780 780 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
781 781
782 782 delays = len(delay)
783 783
784 784 Y = [(ipp*x+before+delay[x%delays], ipp*x+width+before+delay[x%delays]+after) for x in range(ntx)]
785 785
786 786 return Y
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now