##// 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
22
18
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 parameters['freq2'] = self.freq2
57
53 parameters['freq2'] = self.freq2
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
65
61
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
73
69
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 status = response[-1]
93
94 print icon, status
89 status = response[-1]
90
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
109
105
106
110 107 return self.device.status
111
112
108
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
143
139
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
159 try:
155
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 # status = response[-1]
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
49 # except:
48
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 #
118 # try:
117 #
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 #
125 # try:
124 #
125 # try:
126 126 # if len(text)>1:
127 127 # title = text[0]
128 128 # status = text[1]
129 # status_ok = r.status_code
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 #
145 #
146 #
147 #
144 #
145 #
146 #
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 #
172 #
171 #
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 # status = response[-1]
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 #
200 #
199 #
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 # messages.error(request, "Could not read parameters from Device")
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 #
267 #
266 #
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 # return render(request, 'cgs_conf.html', kwargs) No newline at end of file
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
46
45
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
214
213
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},
2 ] No newline at end of file
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 ]
@@ -1,273 +1,273
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 from django.core.urlresolvers import reverse
5 5 from devices.jars import api
6 6
7 7 from apps.rc.models import RCConfiguration
8 8
9 9 import json
10 10 # Create your models here.
11 11
12 12 EXPERIMENT_TYPE = (
13 13 (0, 'RAW_DATA'),
14 14 (1, 'PDATA'),
15 15 )
16 16
17 17 DATA_TYPE = (
18 18 (0, 'SHORT'),
19 19 (1, 'FLOAT'),
20 20 )
21 21
22 22 class JARSfilter(models.Model):
23
23
24 24 JARS_NBITS = 32
25
25
26 26 name = models.CharField(max_length=60, unique=True, default='')
27 27 clock = models.FloatField(verbose_name='Clock In (MHz)',validators=[MinValueValidator(5), MaxValueValidator(75)], null=True, default=60)
28 28 mult = models.PositiveIntegerField(verbose_name='Multiplier',validators=[MinValueValidator(1), MaxValueValidator(20)], default=5)
29 29 fch = models.DecimalField(verbose_name='Frequency (MHz)', validators=[MinValueValidator(0), MaxValueValidator(150)], max_digits=19, decimal_places=16, null=True, default=49.9200)
30 30 fch_decimal = models.BigIntegerField(verbose_name='Frequency (Decimal)',validators=[MinValueValidator(0), MaxValueValidator(2**JARS_NBITS-1)], null=True, default=721554505)
31 31 filter_fir = models.PositiveIntegerField(verbose_name='FIR Filter',validators=[MinValueValidator(1), MaxValueValidator(20)], default = 6)
32 32 filter_2 = models.PositiveIntegerField(verbose_name='Filter 2',validators=[MinValueValidator(1), MaxValueValidator(20)], default = 10)
33 33 filter_5 = models.PositiveIntegerField(verbose_name='Filter 5',validators=[MinValueValidator(1), MaxValueValidator(20)], default = 1)
34 34 speed = models.PositiveIntegerField(verbose_name='Speed',validators=[MinValueValidator(0), MaxValueValidator(100000)], default = 0)
35
35
36 36 class Meta:
37 37 db_table = 'jars_filters'
38
38
39 39 def __unicode__(self):
40 40 return u'%s' % (self.name)
41
41
42 42 def parms_to_dict(self):
43
43
44 44 parameters = {}
45
45
46 46 parameters['name'] = self.name
47 47 parameters['clock'] = float(self.clock)
48 48 parameters['mult'] = int(self.mult)
49 49 parameters['fch'] = float(self.fch)
50 50 parameters['fch_decimal'] = int(self.fch)
51 51 parameters['filter_fir'] = int(self.filter_fir)
52 52 parameters['filter_2'] = int(self.filter_2)
53 53 parameters['filter_5'] = int(self.filter_5)
54 54 parameters['speed'] = int(self.speed)
55
55
56 56 return parameters
57
57
58 58 def dict_to_parms(self, parameters):
59
59
60 60 self.name = parameters['name']
61 61 self.clock = parameters['clock']
62 62 self.mult = parameters['mult']
63 63 self.fch = parameters['fch']
64 64 self.fch_decimal = parameters['fch_decimal']
65 65 self.filter_fir = parameters['filter_fir']
66 66 self.filter_2 = parameters['filter_2']
67 67 self.filter_5 = parameters['filter_5']
68 68 self.speed = parameters['speed']
69
69
70 70
71 71 class JARSConfiguration(Configuration):
72
72
73 73 ADC_RESOLUTION = 8
74 74 PCI_DIO_BUSWIDTH = 32
75 75 HEADER_VERSION = 1103
76 76 BEGIN_ON_START = True
77 77 REFRESH_RATE = 1
78
78
79 79 #rc = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE, null=True)
80 80 exp_type = models.PositiveIntegerField(verbose_name='Experiment Type', choices=EXPERIMENT_TYPE, default=0)
81 81 cards_number = models.PositiveIntegerField(verbose_name='Number of Cards', validators=[MinValueValidator(1), MaxValueValidator(4)], default = 1)
82 82 channels_number = models.PositiveIntegerField(verbose_name='Number of Channels', validators=[MinValueValidator(1), MaxValueValidator(8)], default = 5)
83 83 channels = models.CharField(verbose_name='Channels', max_length=15, default = '1,2,3,4,5')
84 84 rd_directory = models.CharField(verbose_name='Raw Data Directory', max_length=200, default='', blank=True, null=True)
85 85 pd_directory = models.CharField(verbose_name='Process Data Directory', max_length=200, default='', blank=True, null=True)
86 86 #raw_data_blocks = models.PositiveIntegerField(verbose_name='Raw Data Blocks', validators=[MaxValueValidator(5000)], default=120)
87 87 data_type = models.PositiveIntegerField(verbose_name='Data Type', choices=DATA_TYPE, default=0)
88 88 acq_profiles = models.PositiveIntegerField(verbose_name='Acquired Profiles', validators=[MaxValueValidator(5000)], default=400)
89 89 profiles_block = models.PositiveIntegerField(verbose_name='Profiles Per Block', validators=[MaxValueValidator(5000)], default=400)
90 90 ftp_interval = models.PositiveIntegerField(verbose_name='FTP Interval', default=60)
91 91 fftpoints = models.PositiveIntegerField(verbose_name='FFT Points',default=16)
92 92 cohe_integr_str = models.PositiveIntegerField(verbose_name='Coh. Int. Stride',validators=[MinValueValidator(1)], default=30)
93 93 cohe_integr = models.PositiveIntegerField(verbose_name='Coherent Integrations',validators=[MinValueValidator(1)], default=30)
94 94 incohe_integr = models.PositiveIntegerField(verbose_name='Incoherent Integrations',validators=[MinValueValidator(1)], default=30)
95 95 filter = models.ForeignKey(JARSfilter, on_delete=models.CASCADE, null=True)
96 96 spectral_number = models.PositiveIntegerField(verbose_name='# Spectral Combinations',validators=[MinValueValidator(1)], default=1)
97 97 spectral = models.CharField(verbose_name='Combinations', max_length=5000, default = '[0, 0],')
98 98 create_directory = models.BooleanField(verbose_name='Create Directory Per Day', default=True)
99 99 include_expname = models.BooleanField(verbose_name='Experiment Name in Directory', default=True)
100 100 #acq_link = models.BooleanField(verbose_name='Acquisition Link', default=True)
101 101 #view_raw_data = models.BooleanField(verbose_name='View Raw Data', default=True)
102 102 save_ch_dc = models.BooleanField(verbose_name='Save Channels DC', default=True)
103 103 save_data = models.BooleanField(verbose_name='Save Data', default=True)
104 104 filter_parms = models.CharField(max_length=10000, default='{}')
105 105
106 106 class Meta:
107 107 db_table = 'jars_configurations'
108
108
109 109 def parms_to_dict(self):
110
110
111 111 parameters = {}
112
112
113 113 parameters['device_id'] = self.device.id
114 114 parameters['name'] = self.name
115 115 #parameters['rc'] = self.rc.name
116 116 parameters['exp_type'] = self.exp_type
117 117 parameters['exptype'] = EXPERIMENT_TYPE[self.exp_type][1]
118 118 parameters['cards_number'] = self.cards_number
119 119 parameters['channels_number'] = self.channels_number
120 120 parameters['channels'] = self.channels
121 121 parameters['rd_directory'] = self.rd_directory
122 122 #parameters['raw_data_blocks'] = self.raw_data_blocks
123 123 parameters['data_type'] = self.data_type
124 124 parameters['cohe_integr_str'] = self.cohe_integr_str
125 125 parameters['acq_profiles'] = self.acq_profiles
126 126 parameters['profiles_block'] = self.profiles_block
127 127 parameters['ftp_interval'] = self.ftp_interval
128 128 parameters['fftpoints'] = self.fftpoints
129 129 parameters['cohe_integr'] = self.cohe_integr
130 130 #parameters['incohe_integr'] = self.incohe_integr
131 131 parameters['filter'] = self.filter.name
132 132 parameters['filter_parms'] = self.filter_parms
133 133 #parameters['spectral_number'] = self.spectral_number
134 134 #parameters['spectral'] = self.spectral
135 135 parameters['create_directory'] = bool(self.create_directory)
136 136 parameters['include_expname'] = bool(self.include_expname)
137 137 #parameters['acq_link'] = bool(self.acq_link)
138 138 #parameters['view_raw_data'] = bool(self.view_raw_data)
139 139 parameters['save_ch_dc'] = bool(self.save_ch_dc)
140 140 parameters['save_data'] = bool(self.save_data)
141
141
142 142 if parameters['exptype'] == 'PDATA':
143 143 parameters['incohe_integr'] = self.incohe_integr
144 144 parameters['spectral_number'] = self.spectral_number
145 145 parameters['spectral'] = self.spectral
146 146 parameters['pd_directory'] = self.pd_directory
147
147
148 148 return parameters
149
149
150 150 def add_parms_to_filter(self):
151 151 self.filter_parms = self.filter.parms_to_dict()
152 152 self.save()
153
153
154 154 def dict_to_parms(self, parameters):
155
155
156 156 self.name = parameters['name']
157 157 self.device.id = int(parameters['device_id'])
158
158
159 159 self.exp_type = int(parameters['exp_type'])
160 if parameters['exptype'] == 'PDATA':
160 if parameters['exptype'] == 'PDATA':
161 161 self.incohe_integr = parameters['incohe_integr']
162 162 self.spectral_number = parameters['spectral_number']
163 163 self.spectral = parameters['spectral']
164 164 self.pd_directory = parameters['pd_directory']
165
165
166 166 self.cards_number = int(parameters['cards_number'])
167 167 self.channels_number = int(parameters['channels_number'])
168 168 self.channels = parameters['channels']
169 169 self.rd_directory = parameters['rd_directory']
170 170 #self.raw_data_blocks = parameters['raw_data_blocks']
171 171 self.data_type = parameters['data_type']
172 172 self.cohe_integr_str = parameters['cohe_integr_str']
173 173 self.acq_profiles = parameters['acq_profiles']
174 174 self.profiles_block = parameters['profiles_block']
175 175 self.ftp_interval = parameters['ftp_interval']
176 176 self.fftpoints = parameters['fftpoints']
177 177 self.cohe_integr = parameters['cohe_integr']
178
178
179 179 filter_name = parameters['filter']
180 180 self.filter = JARSfilter.objects.get(name=filter_name)
181 181 self.add_parms_to_filter()
182 182 self.filter_parms = parameters['filter_parms']
183
183
184 184 self.create_directory = bool(parameters['create_directory'])
185 185 self.include_expname = bool(parameters['include_expname'])
186 186 #self.acq_link = bool(parameters['acq_link'])
187 187 #self.view_raw_data = bool(parameters['view_raw_data'])
188 188 self.save_ch_dc = bool(parameters['save_ch_dc'])
189 189 self.save_data = bool(parameters['save_data'])
190
190
191 191 def status_device(self):
192
192
193 193 answer = api.status(self.device.ip_address,self.device.port_address)
194 194 self.device.status = int(answer[0])
195 195 self.message = answer[2:]
196 196 self.device.save()
197
197
198 198 return self.device.status
199
199
200 200 def stop_device(self):
201
201
202 202 answer = api.stop(self.device.ip_address,self.device.port_address)
203 203 self.device.status = int(answer[0])
204 204 self.message = answer[2:]
205 205 self.device.save()
206
206
207 207 return self.device.status
208
208
209 209 def read_device(self):
210
210
211 211 answer = api.read(self.device.ip_address,self.device.port_address)
212 212 self.device.status = int(answer[0])
213 213 try:
214 214 data = json.loads(answer[2:])
215 215 parms = data['configurations']['jars']
216 216 except:
217 217 self.device.status = 0
218 218 self.device.save()
219 219 self.message = 'Could not read JARS configuration.'
220 220 return ''
221
221
222 222 #self.dict_to_parms(parms)
223 223 self.message = 'Current JARS configuration was read successfully.'
224 224 self.device.save()
225 225 return parms
226
227
226
227
228 228 def write_device(self):
229
229
230 230 data = self.experiment.parms_to_dict()
231 231 data = json.loads(data)
232 232 data['configurations']['dds'] =''
233 233 data['configurations']['cgs'] =''
234 234 data['configurations']['rc']['pulses']=''
235 235 data['configurations']['rc']['delays']=''
236 236 json_data = json.dumps(data)
237
237
238 238 answer = api.configure(self.device.ip_address,self.device.port_address,json_data)
239 239 #print answer
240 240 self.device.status = int(answer[0])
241 241 self.message = answer[2:]
242
242
243 243 self.device.save()
244
244
245 245 return self.device.status
246
247
246
247
248 248 def start_device(self):
249
249
250 250 self.write_device()
251
252
251
252
253 253 def echo(self):
254
254
255 255 answer = api.echo(self.device.ip_address,self.device.port_address,'(=')
256 256 #print answer
257 257 self.device.status = int(answer[0])
258 258 self.message = answer[2:]
259
259
260 260 self.device.save()
261
261
262 262 return #self.device.status
263
263
264 264 def update_from_file(self, parameters):
265
265
266 266 self.dict_to_parms(parameters)
267 267 self.save()
268
268
269 269 def get_absolute_url_import(self):
270 270 return reverse('url_import_jars_conf', args=[str(self.id)])
271
271
272 272 def get_absolute_url_read(self):
273 return reverse('url_read_jars_conf', args=[str(self.id)]) No newline at end of file
273 return reverse('url_read_jars_conf', args=[str(self.id)])
@@ -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 <script type="text/javascript">
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
54
52
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
62
60
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 $("#id_spectral").val(spectral_comb+"["+$("#num1").val()+", "+$("#num2").val()+"],")
70 $("#id_spectral").val(spectral_comb+"["+$("#num1").val()+", "+$("#num2").val()+"],")
72 71 }
73 updateSpectralNumber()
72 updateSpectralNumber()
74 73 }});
75
76
74
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
91
89
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
103
101
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
117
115
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
130
128
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 updateSpectralNumber()
155 updateSpectralNumber()
157 156 }});
158
159
157
158
160 159 }});
161 160 </script>
162 161 '''
163
164 return mark_safe(html+script) No newline at end of file
162
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 {"fields": {"name": "rc", "description": ""}, "model": "main.devicetype", "pk": 1},
7 {"fields": {"name": "dds", "description": ""}, "model": "main.devicetype", "pk": 2},
8 {"fields": {"name": "cgs", "description": ""}, "model": "main.devicetype", "pk": 3},
9 {"fields": {"name": "jars", "description": ""}, "model": "main.devicetype", "pk": 4}
6 {"fields": {"name": "rc", "description": ""}, "model": "main.devicetype", "pk": 1},
7 {"fields": {"name": "dds", "description": ""}, "model": "main.devicetype", "pk": 2},
8 {"fields": {"name": "cgs", "description": ""}, "model": "main.devicetype", "pk": 3},
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 end = attrs['end_date']
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
74
73
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
108 class DeviceTypeForm(forms.Form):
109 device_type = forms.ChoiceField(choices=add_empty_choice(DeviceType.objects.all().order_by('name').values_list('id', 'name')))
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')))
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
139 if 'length' not in kwargs.keys():
140 length = None
141 else:
142 length = kwargs['length']
143
144 kwargs.pop('length')
145
137
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]
148
140 self.fields['campaign'].choices=add_empty_choice(campaigns.values_list('id', 'name'))
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
179 for field in extra_fields:
171
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 'end_date':kwargs['initial'].get('end_date', '')}
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 %}
14 {% bootstrap_form form layout='horizontal' size='medium' %}
15 <div style="clear: both;"></div>
18 16
19 <form class="form" method="post" action="">
20 {% csrf_token %}
17 {% if campaign %}
21 18
22 {% bootstrap_form form layout='horizontal' size='medium' %}
23 <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
35 {% endif %}
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
75 {% for item in experiments %}
57
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 </table>
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
106 //--------For PLAY Button-------
88
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
112 //--------For STOP Button-------
94
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
118 //--------For REFRESH Button-------
100
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 $("#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);
120 $("#id_campaign").change(function() {
121 document.location = "{% url 'url_operation'%}"+$(this).val();
141 122 });
142 123 });
143 124 {% endif %}
144
145 $("#button-1").click(function() {
146 document.location = "{% url 'url_operation_search' %}";
147 });
148
149
125
126
150 127 </script>
151 {% endblock %} No newline at end of file
128 {% endblock %}
@@ -1,37 +1,37
1
1
2 2 {% if campaign %}
3 3 <div class="panel panel-default">
4 4 <div class="panel-heading">
5 5 <h4>Campaign</h4>
6 6 </div>
7 <div class="list-group">
7 <div class="list-group">
8 8 <a href="{% url 'url_campaign' campaign.id %}" class="list-group-item active" >{{ campaign.name }}</a>
9 9 </div>
10 10 </div>
11 11 {% endif %}
12
12
13 13 {% if experiment %}
14 14 <div class="panel panel-default">
15 15 <div class="panel-heading">
16 16 <h4>Experiments</h4>
17 17 </div>
18 <div class="list-group">
18 <div class="list-group">
19 19 {% for item in side_experiments %}
20 <a href="{% url 'url_experiment' item.id %}" class="list-group-item {%if item.id == experiment.id%}active{%endif%}">{{item.name}}</a>
20 <a href="{% url 'url_experiment' item.id %}" class="list-group-item {%if item.id == experiment.id%}active{%endif%}">{{item.name}}</a>
21 21 {% endfor %}
22 22 </div>
23 23 </div>
24 24 {% endif %}
25
25
26 26 {% if dev_conf %}
27 27 <div class="panel panel-default">
28 28 <div class="panel-heading">
29 29 <h4>Device Configurations</h4>
30 30 </div>
31 <div class="list-group">
31 <div class="list-group">
32 32 {% for item in side_configurations %}
33 33 <a href="{{item.get_absolute_url}}" class="list-group-item {%if item.id == dev_conf.id%}active{%endif%}">{{item}}</a>
34 34 {% endfor %}
35 35 </div>
36 36 </div>
37 37 {% endif %}
@@ -1,59 +1,61
1 1 from django.conf.urls import url
2 2
3 from apps.main import views
4
3 5 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'),
58
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 )
This diff has been collapsed as it changes many lines, (868 lines changed) Show them Hide them
@@ -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
74 kwargs = get_paginator(Location, page, order)
75
79
80 kwargs = get_paginator(Location, page, order)
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 'object': location,
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
170 kwargs = get_paginator(Device, page, order)
171 kwargs['keys'] = ['name', 'ip_address', 'port_address', 'device_type']
175
176 kwargs = get_paginator(Device, page, order)
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 'object': device,
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 kwargs['keys'] = ['name', 'start_date', 'end_date']
275 kwargs['keys'] = ['name', 'start_date', 'end_date']
270 276 kwargs['title'] = 'Campaign'
271 277 kwargs['suptitle'] = 'List'
272 kwargs['form'] = form
278 kwargs['form'] = form
273 279 filters.pop('page', None)
274 kwargs['q'] = urllib.urlencode(filters)
275
280 kwargs['q'] = urlencode(filters)
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 kwargs['experiments'] = Configuration.objects.filter(experiment=request.GET['template'])
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 'template':False})
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 'object': campaign,
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 content = campaign.parms_to_dict()
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
478 form = FilterForm(initial=request.GET, extra_fields=['tags','template'])
479
480 kwargs['keys'] = ['name', 'radar_system', 'start_time', 'end_time']
483
484 form = FilterForm(initial=request.GET, extra_fields=['tags','template'])
485
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)
486
491 kwargs['q'] = urlencode(filters)
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 kwargs['configurations'] = Configuration.objects.filter(experiment=request.GET['template'])
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 form = ExperimentForm(instance=exp,
535 form = ExperimentForm(instance=exp,
530 536 initial={'name': '{} [{:%Y/%m/%d}]'.format(exp.name, datetime.now()),
531 'template': False})
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 configurations = Configuration.objects.filter(experiment=request.GET['template'], type=0)
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 conf.delete()
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 return redirect(experiment.get_absolute_url())
594
598 return redirect(experiment.get_absolute_url())
599
595 600 kwargs = {
596 601 'title': 'Delete',
597 602 'suptitle': 'Experiment',
598 'object': experiment,
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 content = experiment.parms_to_dict()
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
640 return redirect(new_exp.get_absolute_url_edit())
644
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 mix=True,
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
689 if request.method=='GET':
693
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
731
735
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
863 import json
867
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 else:
917 else:
913 918 rc_lines = rc_parms['lines']
914 919 dh = rc_lines[6]['params'][0]['resolution']
915 920 #--Sampling Frequency
916 samp_freq_rc = 0.15/dh
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
930
934
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
945
946
949
950
951
947 952 ###### SIDEBAR ######
948 953 kwargs.update(sidebar(experiment=experiment))
949
950
951
952
953
954
955
956
957
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 html = 'EXP MOD OPE DELAY MASK\r\n'
961
965 html = 'EXP MOD OPE DELAY MASK\r\n'
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 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
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
1004
1008
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 kwargs['keys'] = ['name', 'experiment', 'type', 'programmed_date']
1017 kwargs['keys'] = ['name', 'experiment', 'type', 'programmed_date']
1013 1018 kwargs['title'] = 'Configuration'
1014 1019 kwargs['suptitle'] = 'List'
1015 kwargs['form'] = form
1020 kwargs['form'] = form
1016 1021 filters.pop('page', None)
1017 kwargs['q'] = urllib.urlencode(filters)
1018
1022 kwargs['q'] = urlencode(filters)
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
1034 if id_exp<>0:
1038
1039 if id_exp!=0:
1035 1040 initial['experiment'] = id_exp
1036
1037 if id_dev<>0:
1041
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 initial['name'] = request.GET['name']
1047 form = DevConfForm(initial=initial)
1051 initial['name'] = request.GET['name']
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 kwargs['button'] = 'Create'
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 form = DevConfForm(instance=conf,
1064 form = DevConfForm(instance=conf,
1060 1065 initial={'name': '{} [{:%Y/%m/%d}]'.format(conf.name, datetime.now()),
1061 1066 'template': False,
1062 'experiment':id_exp})
1067 'experiment':id_exp})
1063 1068 elif 'blank' in request.GET:
1064 kwargs['button'] = 'Create'
1069 kwargs['button'] = 'Create'
1065 1070 form = ConfigurationForm(initial=initial)
1066 1071 else:
1067 form = NewForm()
1068
1072 form = NewForm()
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
1084 if conf.device.device_type.name=='jars':
1088
1089 if conf.device.device_type.name=='jars':
1085 1090 conf.add_parms_to_filter()
1086
1087 return redirect('url_dev_conf', id_conf=conf.pk)
1088
1091
1092 return redirect('url_dev_conf', id_conf=conf.pk)
1093
1089 1094 kwargs['id_exp'] = id_exp
1090 1095 kwargs['form'] = form
1091 1096 kwargs['title'] = 'Configuration'
1092 1097 kwargs['suptitle'] = 'New'
1093
1094
1098
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
1106 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1110
1107 1111 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1108
1109 dev_conf = DevConfModel.objects.get(pk=id_conf)
1110
1112
1111 1113 if request.method=='GET':
1112 form = DevConfForm(instance=dev_conf)
1113
1114 form = DevConfForm(instance=conf)
1115
1114 1116 if request.method=='POST':
1115 form = DevConfForm(request.POST, instance=dev_conf)
1116
1117 form = DevConfForm(request.POST, instance=conf)
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
1137 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1138
1139 conf = DevConfModel.objects.get(pk=id_conf)
1140
1138
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
1155 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1156
1157 conf = DevConfModel.objects.get(pk=id_conf)
1158
1152
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
1173 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1174
1175 conf = DevConfModel.objects.get(pk=id_conf)
1176
1166
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
1189 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1190
1191 conf = DevConfModel.objects.get(pk=id_conf)
1192
1178
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
1199 #Creating a historical configuration
1184
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
1214 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1199
1215 1200 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1216
1217 conf = DevConfModel.objects.get(pk=id_conf)
1218
1201
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 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1258 conf = DevConfModel.objects.get(pk=id_conf)
1259
1238 DevConfForm = CONF_FORMS[conf.device.device_type.name]
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
1306 DevConfModel = CONF_MODELS[conf.device.device_type.name]
1307
1308 conf = DevConfModel.objects.get(pk=id_conf)
1309
1285
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 return redirect(conf.get_absolute_url())
1348
1323 return redirect(conf.get_absolute_url())
1324
1349 1325 kwargs = {
1350 1326 'title': 'Delete',
1351 1327 'suptitle': 'Experiment',
1352 'object': conf,
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 tags = filters.pop('tags')
1374 tags = filters.pop('tags')
1399 1375 if 'tags' in model._meta.get_all_field_names():
1400 query = query | Q(tags__icontains=tags)
1376 query = query | Q(tags__icontains=tags)
1401 1377 if 'name' in model._meta.get_all_field_names():
1402 query = query | Q(name__icontains=tags)
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 query = query | Q(device__name__icontains=tags)
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):
1400
1401 kwargs = {}
1402 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1403 end_date__gte=datetime.now()).order_by('-start_date')
1424 1404
1425 if not id_camp:
1426 campaigns = Campaign.objects.all().order_by('-start_date')
1427
1428 if not campaigns:
1429 kwargs = {}
1430 kwargs['title'] = 'No Campaigns'
1431 kwargs['suptitle'] = 'Empty'
1432 return render(request, 'operation.html', kwargs)
1433
1434 id_camp = campaigns[0].id
1435
1436 campaign = get_object_or_404(Campaign, pk = id_camp)
1437 1405
1438 if request.method=='GET':
1439 form = OperationForm(initial={'campaign': campaign.id}, length = 5)
1440
1441 if request.method=='POST':
1442 form = OperationForm(request.POST, initial={'campaign':campaign.id}, length = 5)
1406 if id_camp:
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)
1414
1443 1415
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']
1416
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 kwargs['form'] = form
1466 kwargs['button'] = 'Search'
1467 kwargs['details'] = True
1468 kwargs['search_button'] = True
1469
1427 kwargs['form'] = form
1428
1470 1429 return render(request, 'operation.html', kwargs)
1471 1430
1472 1431
1473 1432 def operation_search(request, id_camp=None):
1474
1475
1433
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
1577
1535
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 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
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 choices=[(0, 'Parallel'), (1, 'Sequence')],
109 choices=[(0, 'Parallel'), (1, 'Sequence')],
110 110 initial=0)
111 111 operation = forms.ChoiceField(widget=forms.RadioSelect(),
112 choices=[(0, 'OR'), (1, 'XOR'), (2, 'AND'), (3, 'NAND')],
112 choices=[(0, 'OR'), (1, 'XOR'), (2, 'AND'), (3, 'NAND')],
113 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
134
133
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 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
156 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
157 157 kwargs['initial']['rc_configuration']),
158 158 initial=model_initial)
159
160
159
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 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
185 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
186 186 self.data['rc_configuration']),
187 187 initial=model_initial)
188
189
188
189
190 190 else:
191 191 if label=='codes' and 'code' in self.data:
192 self.fields[label] = forms.CharField(initial=self.data['codes'])
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
199
198
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
207
206
207
208 208 def clean(self):
209
209
210 210 form_data = self.cleaned_data
211 if 'code' in self.data and self.data['TX_ref']=="0":
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
219
220 def save(self):
218
219
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
243
242
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
270 self.fields[label] = forms.CharField(initial=value)
271
269
270 self.fields[label] = forms.CharField(initial=value)
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
285
284
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 count = -1
303
302 count = -1
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
323 else:
322
323 else:
324 324 self.fields[label] = forms.CharField(initial=value, help_text=help_text)
325
326 if label in ('code', ):
327 self.fields[label].widget = HiddenWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
328
325
326 if label in ('code', ):
327 self.fields[label].widget = HiddenWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
328
329 329 elif 'widget' in params[label]:
330 km2unit = line.rc_configuration.km2unit
331 if params[label]['widget']=='km':
330 km2unit = line.rc_configuration.km2unit
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 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
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
342
341
342
343 343 class Meta:
344 344 model = RCLine
345 345 exclude = ('rc_configuration', 'line_type', 'channel', 'position', 'params', 'pulses')
346
347
346
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 for label, value in extra_fields.items():
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
364
365 class RCLineCodesForm(forms.ModelForm):
366
363
364
365 class RCLineCodesForm(forms.ModelForm):
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
379
378
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 'DELAY_START' : 40, # Write delay status to memory
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 'TX_ONE' : 72, # Output '0' in line TX
46 'TX_ZERO' : 88, # Output '0' in line TX
47 'SW_ONE' : 104, # Output '0' in line SW
43 'TX_ONE' : 72, # Output '0' in line TX
44 'TX_ZERO' : 88, # Output '0' in line TX
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 'CLOCK_DIVIDER' : 8,
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 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(400)], default=1)
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
111 return self
108
109 return self
112 110
113 111 def get_lines(self, **kwargs):
114 112 '''
115 Retrieve configuration lines
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 '''
134 131 '''
135
132 '''
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 line_data = json.loads(line.params)
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 self.clock_in = float(data['clock_in'])
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 positions = {'tx':0, 'tr':0}
183
184 for i, line_data in enumerate(data['lines']):
180 positions = {'tx':0, 'tr':0}
181
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 line_data['code'] = code.pk
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 line = RCLine(rc_configuration=self, line_type=line_type,
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
220
218
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 points.sort()
228
229 if points[0]<>0:
226 points.sort()
227
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
234
232
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 points.sort()
242
240 points.sort()
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 line_points = [[t for x in tups for t in x] for tups in line_points]
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
259 def add_data(self, value):
260
257
258 def add_data(self, value):
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
295 for delay in delays:
296 while delay>252:
293
294 for delay in delays:
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 data.append(self.add_cmd('FLIP_START'))
303
301 data.append(self.add_cmd('FLIP_START'))
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 flip = int(''.join([str(x) for x in flips]), 2)
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 from bokeh.mpl import to_bokeh
352 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, PreviewSaveTool
353
354 lines = self.get_lines()
355
350 from bokeh.mpl import to_bokeh
351 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
352
353 lines = self.get_lines()
354
356 355 N = len(lines)
357 npoints = self.total_units/self.km2unit if km else self.total_units
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 labels = ['IPP']
361
359 labels = ['IPP']
360
362 361 for i, line in enumerate(lines):
363 labels.append(line.get_name(channel=True))
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)]
366 ax.broken_barh(points, (N-i-1, 0.5),
364 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
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
376
374
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 plot = to_bokeh(fig, use_pandas=False)
382 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), PreviewSaveTool()]
383
380 plot = to_bokeh(fig, use_pandas=False)
381 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()]
382 plot.toolbar_location="above"
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
438 def __unicode__(self):
439 return u'%s' % self.name
437
438 def __str__(self):
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
454
453
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
468 def __unicode__(self):
467
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
479 self.save()
478
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 s = ''
487
486 s = ''
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 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
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
509 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
510
508
509 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
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
533 if codes:
532
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 Update pulses field
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 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
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
584 if len(ranges)>0 and ranges[0]<>'0':
583
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
589 if len(tr_ranges)>0 and tr_ranges[0]<>'0':
588
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 params = json.loads(self.params)
599 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
598 params = json.loads(self.params)
599 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
600 600 width = float(params['pulse_width'])*km2unit
601
602 if width>0:
601
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 sync=self.rc_configuration.sync)
611
610 sync=self.rc_configuration.sync)
611
612 612 ranges = params['range'].split(',')
613
614 if len(ranges)>0 and ranges[0]<>'0':
613
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 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])
628 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
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]))
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
657 if 'params' in params and len(params['params'])>0:
656
657 if 'params' in params and len(params['params'])>0:
658 658 for p in params['params']:
659 y_pp = self.points(nntx, nipp,
660 p['end']-p['begin'],
661 before=p['begin'])
662
663 y.extend(y_pp)
664
659 y_pp = self.points(nntx, nipp,
660 p['end']-p['begin'],
661 before=p['begin'])
662
663 y.extend(y_pp)
664
665 665 elif self.line_type.name=='windows':
666 params = json.loads(self.params)
667
666 params = json.loads(self.params)
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 y_win = self.points(ntx, ipp_u,
673 p['resolution']*p['number_of_samples']*km2unit,
672 y_win = self.points(ntx, ipp_u,
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
677 if len(tr_ranges)>0 and tr_ranges[0]<>'0':
676
677 if len(tr_ranges)>0 and tr_ranges[0]!='0':
678 678 y_win = self.mask_ranges(y_win, tr_ranges)
679
680 y.extend(y_win)
681
679
680 y.extend(y_win)
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 mask.reverse()
699
698 mask.reverse()
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 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
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 else:
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
741 if self.rc_configuration.total_units <> total:
740
741 if self.rc_configuration.total_units != total:
742 742 self.rc_configuration.total_units = total
743 743 self.rc_configuration.save()
744
745 self.pulses = unicode(y)
744
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 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
773 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
774 774 else:
775 y[int(index-1)] = Y[int(index-1)]
776
775 y[int(index-1)] = Y[int(index-1)]
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
786 return Y No newline at end of file
785
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