##// END OF EJS Templates
Update several views and models in main app...
Juan C. Espinoza -
r85:d4fe0e132735
parent child
Show More
@@ -1,19 +1,14
1 1 ## DJANGO
2 2
3 3 WSGIScriptAlias / /usr/local/radarsys/radarsys/wsgi.py
4 4 WSGIPythonPath /usr/local/radarsys/:/usr/local/virtuals/radarsys/lib/python2.7/site-packages
5 5
6 Alias /static/ /usr/local/radarsys/apps/main/static/
7 <Directory /usr/local/radarsys/apps/main/static>
8 Require all granted
9 </Directory>
6 Alias /static/ /var/www/html/static/
10 7
11 8 <Directory /usr/local/radarsys/>
12 9 <Files wsgi.py>
13 10 #Order deny,allow
14 11 Require all granted
15 12 #Allow from all
16 13 </Files>
17 </Directory>
18
19
14 </Directory> No newline at end of file
@@ -1,34 +1,34
1 1 from django import forms
2 2 from apps.main.models import Device
3 3 from .models import CGSConfiguration
4 4
5 5 class CGSConfigurationForm(forms.ModelForm):
6 #freq0.widget = te
6
7 7 def __init__(self, *args, **kwargs):
8 8 #request = kwargs.pop('request')
9 9 super(CGSConfigurationForm, self).__init__(*args, **kwargs)
10 10
11 11 instance = getattr(self, 'instance', None)
12 12
13 13 if instance and instance.pk:
14 14
15 15 devices = Device.objects.filter(device_type__name='cgs')
16 items = devices.values('id', 'name', 'device_type__name', 'ip_address')
17 16
18 self.fields['experiment'].widget.attrs['readonly'] = True
19 self.fields['device'].widget.choices = [(item['id'], '[%s]: %s | %s' % (item['device_type__name'], item['name'], item['ip_address'])) for item in items]
17 if instance.experiment:
18 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
19
20 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
20 21
21 22 def clean(self):
22 23 return
23 24 #
24 25
25 26 class Meta:
26 27 model = CGSConfiguration
27 #exclude = ('freqs', 'clk_in', 'mult','div',)
28 # exclude = ('freqs',)
29 fields = ('experiment', 'device', 'freq0', 'freq1', 'freq2', 'freq3')
28 exclude = ('type', 'parameters', 'status')
29 #fields = ('experiment', 'device', 'freq0', 'freq1', 'freq2', 'freq3')
30 30
31 31
32 32 class UploadFileForm(forms.Form):
33 33 title = forms.CharField(label='Extension Type', widget=forms.TextInput(attrs={'readonly':'readonly'}))
34 34 file = forms.FileField() No newline at end of file
@@ -1,176 +1,174
1 1 from django.db import models
2 2 from apps.main.models import Configuration
3 3 #from json_field import JSONField
4 4 from django.core.validators import MinValueValidator, MaxValueValidator
5 5
6 6
7 7 from apps.main.models import Device, Experiment
8 8
9 9 from files import read_json_file
10 10 # Create your models here. validators=[MinValueValidator(62.5e6), MaxValueValidator(450e6)]
11 11
12 12 class CGSConfiguration(Configuration):
13 13
14 14 freq0 = models.IntegerField(verbose_name='Frequency 0',validators=[MinValueValidator(0), MaxValueValidator(450e6)], blank=True, null=True)
15 15 freq1 = models.IntegerField(verbose_name='Frequency 1',validators=[MinValueValidator(0), MaxValueValidator(450e6)], blank=True, null=True)
16 16 freq2 = models.IntegerField(verbose_name='Frequency 2',validators=[MinValueValidator(0), MaxValueValidator(450e6)], blank=True, null=True)
17 17 freq3 = models.IntegerField(verbose_name='Frequency 3',validators=[MinValueValidator(0), MaxValueValidator(450e6)], blank=True, null=True)
18 #jfreqs = JSONField(default={"frequencies":[{"f0":freq0,"f1":freq1,"f2":freq2,"f3":freq3}]}, blank=True)
19
20 18
21 19 def verify_frequencies(self):
22 20
23 21 return True
24 22
25 23
26 24 def update_from_file(self, fp):
27 25
28 26 kwargs = read_json_file(fp)
29 27
30 28 if not kwargs:
31 29 return False
32 30
33 31 self.freq0 = kwargs['freq0']
34 32 self.freq1 = kwargs['freq1']
35 33 self.freq2 = kwargs['freq2']
36 34 self.freq3 = kwargs['freq3']
37 35
38 36 return True
39 37
40 38 def parms_to_dict(self):
41 39
42 40 parameters = {}
43 41
44 42 if self.freq0 == None or self.freq0 == '':
45 43 parameters['freq0'] = 0
46 44 else:
47 45 parameters['freq0'] = self.freq0
48 46
49 47 if self.freq1 == None or self.freq1 == '':
50 48 parameters['freq1'] = 0
51 49 else:
52 50 parameters['freq1'] = self.freq1
53 51
54 52 if self.freq2 == None or self.freq2 == '':
55 53 parameters['freq2'] = 0
56 54 else:
57 55 parameters['freq2'] = self.freq2
58 56
59 57 if self.freq3 == None or self.freq3 == '':
60 58 parameters['freq3'] = 0
61 59 else:
62 60 parameters['freq3'] = self.freq3
63 61
64 62
65 63 return parameters
66 64
67 65
68 66 def status_device(self):
69 67
70 68 import requests
71 69
72 70 ip=self.device.ip_address
73 71 port=self.device.port_address
74 72
75 73 route = "http://" + str(ip) + ":" + str(port) + "/status/ad9548"
76 74 try:
77 75 r = requests.get(route)
78 76 except:
79 77 self.device.status = 0
80 78 self.device.save()
81 79 return self.device.status
82 80
83 81 response = str(r.text)
84 82 response = response.split(";")
85 83 icon = response[0]
86 84 status = response[-1]
87 85
88 86 print icon, status
89 87 #"icon" could be: "alert" or "okay"
90 88 if "alert" in icon:
91 89 if "Starting Up" in status: #No Esta conectado
92 90 self.device.status = 0
93 91 else:
94 92 self.device.status = 1
95 93 elif "okay" in icon:
96 94 self.device.status = 3
97 95 else:
98 96 self.device.status = 1
99 97
100 98 self.message = status
101 99 self.device.save()
102 100
103 101
104 102 return self.device.status
105 103
106 104
107 105 def read_device(self):
108 106
109 107 import requests
110 108
111 109 ip=self.device.ip_address
112 110 port=self.device.port_address
113 111
114 112 route = "http://" + str(ip) + ":" + str(port) + "/frequencies/"
115 113 try:
116 114 frequencies = requests.get(route)
117 115
118 116 except:
119 117 self.message = "Could not read CGS parameters from this device"
120 118 return None
121 119
122 120 frequencies = frequencies.json()
123 121 frequencies = frequencies.get("Frecuencias")
124 122 f0 = frequencies.get("f0")
125 123 f1 = frequencies.get("f1")
126 124 f2 = frequencies.get("f2")
127 125 f3 = frequencies.get("f3")
128 126
129 127 parms = {'freq0': f0,
130 128 'freq1': f1,
131 129 'freq2': f2,
132 130 'freq3': f3}
133 131
134 132 self.message = ""
135 133 return parms
136 134
137 135
138 136 def write_device(self):
139 137
140 138 import requests
141 139
142 140 ip=self.device.ip_address
143 141 port=self.device.port_address
144 142
145 143 #---Frequencies from form
146 144 f0 = self.freq0
147 145 f1 = self.freq1
148 146 f2 = self.freq2
149 147 f3 = self.freq3
150 148 post_data = {"f0":f0, "f1":f1, "f2":f2, "f3":f3}
151 149 route = "http://" + str(ip) + ":" + str(port) + "/frequencies/"
152 150
153 151 try:
154 152 r = requests.post(route, post_data)
155 153 except:
156 154 self.message = "Could not write CGS parameters"
157 155 return None
158 156
159 157 text = r.text
160 158 text = text.split(',')
161 159
162 160 if len(text)>1:
163 161 title = text[0]
164 162 status = text[1]
165 163 if title == "okay":
166 164 self.message = status
167 165 return 3
168 166 else:
169 167 self.message = title + ", " + status
170 168 return 1
171 169
172 170 return 1
173 171
174 172
175 173 class Meta:
176 174 db_table = 'cgs_configurations'
@@ -1,326 +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 5 from apps.main.models import Experiment, Configuration
6 6 from .models import CGSConfiguration
7 7
8 8 from .forms import CGSConfigurationForm, UploadFileForm
9 9 from apps.main.views import sidebar
10 10
11 11 import requests
12 12 import json
13 13 #from __builtin__ import None
14 14 # Create your views here.
15 15
16 16 def cgs_conf(request, id_conf):
17 17
18 18 conf = get_object_or_404(CGSConfiguration, pk=id_conf)
19 19
20 20 ip=conf.device.ip_address
21 21 port=conf.device.port_address
22 22
23 23 kwargs = {}
24 24
25 25 kwargs['status'] = conf.device.get_status_display()
26 26
27 27 #if request.method=='GET':
28 28 #r: response = icon, status
29 29 # try:
30 30 # route = "http://" + str(ip) + ":" + str(port) + "/status/ad9548"
31 31 # r = requests.get(route)
32 32 # response = str(r.text)
33 33 # response = response.split(";")
34 34 # icon = response[0]
35 35 # status = response[-1]
36 36 #print r.text
37 37 #"icon" could be: "alert" or "okay"
38 38 # Si hay alerta pero esta conectado
39 39 # if "alert" in icon:
40 40 # if "Starting Up" in status: #No Esta conectado
41 41 # kwargs['connected'] = False
42 42 # else:
43 43 # kwargs['connected'] = True
44 44 # elif "okay" in icon:
45 45 # kwargs['connected'] = True
46 46 # else:
47 47 # kwargs['connected'] = False
48 48
49 49 # except:
50 50 # kwargs['connected'] = False
51 51 # status = "The Device is not connected."
52 52
53 53 #if not kwargs['connected']:
54 54 # messages.error(request, message=status)
55 55
56 56 kwargs['dev_conf'] = conf
57 57 kwargs['dev_conf_keys'] = ['experiment', 'device',
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 kwargs.update(sidebar(conf))
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
105 ###### SIDEBAR ######
106 kwargs.update(sidebar(conf))
107
108 104 return render(request, 'cgs_conf_edit.html', kwargs)
109 105 #
110 106 # def cgs_conf_write(request, id_conf):
111 107 #
112 108 # conf = get_object_or_404(CGSConfiguration, pk=id_conf)
113 109 # ip=conf.device.ip_address
114 110 # port=conf.device.port_address
115 111 #
116 112 # #Frequencies from form
117 113 # f0 = conf.freq0
118 114 # f1 = conf.freq1
119 115 # f2 = conf.freq2
120 116 # f3 = conf.freq3
121 117 #
122 118 # try:
123 119 # post_data = {"f0":f0, "f1":f1, "f2":f2, "f3":f3}
124 120 # route = "http://" + str(ip) + ":" + str(port) + "/frequencies/"
125 121 # r = requests.post(route, post_data)
126 122 # text = r.text
127 123 # text = text.split(',')
128 124 #
129 125 # try:
130 126 # if len(text)>1:
131 127 # title = text[0]
132 128 # status = text[1]
133 129 # status_ok = r.status_code
134 130 # if title == "okay":
135 131 # messages.success(request, status)
136 132 # else:
137 133 # messages.error(request, status)
138 134 #
139 135 # else:
140 136 # title = text[0]
141 137 # messages.error(request, title)
142 138 #
143 139 # except:
144 140 # messages.error(request, "An hardware error was found.")
145 141 #
146 142 # except:
147 143 # messages.error(request, "Could not write parameters.")
148 144 #
149 145 #
150 146 #
151 147 #
152 148 # return redirect('url_cgs_conf', id_conf=conf.id)
153 149 #
154 150 # def cgs_conf_read(request, id_conf):
155 151 #
156 152 # conf = get_object_or_404(CGSConfiguration, pk=id_conf)
157 153 #
158 154 # ip=conf.device.ip_address
159 155 # port=conf.device.port_address
160 156 #
161 157 # if request.method=='POST':
162 158 # form = CGSConfigurationForm(request.POST, instance=conf)
163 159 #
164 160 # if form.is_valid():
165 161 # cgs_model = form.save(commit=False)
166 162 #
167 163 # if cgs_model.verify_frequencies():
168 164 #
169 165 # cgs_model.save()
170 166 # return redirect('url_cgs_conf', id_conf=conf.id)
171 167 #
172 168 # messages.error(request, "Parameters could not be saved. Invalid parameters")
173 169 #
174 170 # data = {}
175 171 #
176 172 #
177 173 # if request.method=='GET':
178 174 # #r: response = icon, status
179 175 # route = "http://" + str(ip) + ":" + str(port) + "/status/ad9548"
180 176 # try:
181 177 # r = requests.get(route)
182 178 # response = str(r.text)
183 179 # response = response.split(";")
184 180 # icon = response[0]
185 181 # status = response[-1]
186 182 # print r.text
187 183 # #"icon" could be: "alert" or "okay"
188 184 # if "okay" in icon:
189 185 # messages.success(request, status)
190 186 # else:
191 187 # messages.error(request, status)
192 188 # #Get Frequencies
193 189 # route = "http://" + str(ip) + ":" + str(port) + "/frequencies/"
194 190 # #frequencies = requests.get('http://10.10.10.175:8080/frequencies/')
195 191 # frequencies = requests.get(route)
196 192 # frequencies = frequencies.json()
197 193 # frequencies = frequencies.get("Frecuencias")
198 194 # f0 = frequencies.get("f0")
199 195 # f1 = frequencies.get("f1")
200 196 # f2 = frequencies.get("f2")
201 197 # f3 = frequencies.get("f3")
202 198 # print f0,f1,f2,f3
203 199 #
204 200 #
205 201 # if not response:
206 202 # messages.error(request, "Could not read parameters from Device")
207 203 # return redirect('url_cgs_conf', id_conf=conf.id)
208 204 #
209 205 # data = {'experiment' : conf.experiment.id,
210 206 # 'device' : conf.device.id,
211 207 # 'freq0' : f0,
212 208 # 'freq1' : f1,
213 209 # 'freq2' : f2,
214 210 # 'freq3' : f3,
215 211 # }
216 212 # except:
217 213 # messages.error(request, "Could not read parameters from Device")
218 214 # data = {'experiment' : conf.experiment.id,
219 215 # 'device' : conf.device.id,
220 216 # 'freq0' : None,
221 217 # 'freq1' : None,
222 218 # 'freq2' : None,
223 219 # 'freq3' : None,
224 220 # }
225 221 # return redirect('url_cgs_conf', id_conf=conf.id)
226 222 #
227 223 # form = CGSConfigurationForm(initial = data)
228 224 #
229 225 # kwargs = {}
230 226 # kwargs['id_dev'] = conf.id
231 227 # kwargs['form'] = form
232 228 # kwargs['title'] = 'Device Configuration'
233 229 # kwargs['suptitle'] = 'Parameters read from device'
234 230 # kwargs['button'] = 'Save'
235 231 #
236 232 # ###### SIDEBAR ######
237 233 # kwargs.update(sidebar(conf))
238 234 #
239 235 # return render(request, 'cgs_conf_edit.html', kwargs)
240 236 #
241 237 # def cgs_conf_import(request, id_conf):
242 238 #
243 239 # conf = get_object_or_404(CGSConfiguration, pk=id_conf)
244 240 #
245 241 # if request.method == 'POST':
246 242 # file_form = UploadFileForm(request.POST, request.FILES)
247 243 #
248 244 # if file_form.is_valid():
249 245 #
250 246 # try:
251 247 # if conf.update_from_file(request.FILES['file']):
252 248 #
253 249 # try:
254 250 # conf.full_clean()
255 251 # except ValidationError as e:
256 252 # messages.error(request, e)
257 253 # else:
258 254 # conf.save()
259 255 #
260 256 # messages.success(request, "Parameters imported from file: '%s'." %request.FILES['file'].name)
261 257 # #messages.warning(request,"")
262 258 # return redirect('url_cgs_conf', id_conf=conf.id)
263 259 # except:
264 260 # messages.error(request, "No JSON object could be decoded.")
265 261 #
266 262 # messages.error(request, "Could not import parameters from file")
267 263 #
268 264 # else:
269 265 # file_form = UploadFileForm(initial={'title': '.json'})
270 266 #
271 267 #
272 268 # kwargs = {}
273 269 # kwargs['id_dev'] = conf.id
274 270 # kwargs['title'] = 'Device Configuration'
275 271 # kwargs['form'] = file_form
276 272 # kwargs['suptitle'] = 'Importing file'
277 273 # kwargs['button'] = 'Import'
278 274 #
279 275 # kwargs.update(sidebar(conf))
280 276 #
281 277 # return render(request, 'cgs_conf_import.html', kwargs)
282 278 #
283 279 # def handle_uploaded_file(f):
284 280 #
285 281 # data = {'freq0' : 62500000,
286 282 # 'freq1' : 62500000,
287 283 # 'freq2' : 62500000,
288 284 # 'freq3' : 62500000,
289 285 # }
290 286 #
291 287 # return data
292 288 #
293 289 # def cgs_conf_export(request, id_conf):
294 290 #
295 291 # conf = get_object_or_404(CGSConfiguration, pk=id_conf)
296 292 # ip=conf.device.ip_address
297 293 # port=conf.device.port_address
298 294 #
299 295 # #if request.method=='GET':
300 296 # # data = {"Frequencies": [
301 297 # # ["freq0", conf.freq0],
302 298 # # ["freq1", conf.freq1],
303 299 # # ["freq2", conf.freq2],
304 300 # # ["freq3", conf.freq3]
305 301 # # ]}
306 302 # # json_data = json.dumps(data)
307 303 # # conf.parameters = json_data
308 304 # # response = HttpResponse(conf.parameters, content_type="application/json")
309 305 # # response['Content-Disposition'] = 'attachment; filename="data.json"'
310 306 #
311 307 # # return response
312 308 #
313 309 # kwargs = {}
314 310 # kwargs['dev_conf'] = conf
315 311 # kwargs['dev_conf_keys'] = ['experiment', 'device',
316 312 # 'freq0', 'freq1',
317 313 # 'freq2', 'freq3']
318 314 #
319 315 # kwargs['title'] = 'CGS Configuration'
320 316 # kwargs['suptitle'] = 'Details'
321 317 #
322 318 # kwargs['button'] = 'Edit Configuration'
323 319 #
324 320 # ###### SIDEBAR ######
325 321 # kwargs.update(sidebar(conf))
326 322 # return render(request, 'cgs_conf.html', kwargs) No newline at end of file
@@ -1,29 +1,27
1 1 from django import forms
2 2 from apps.main.models import Device
3 3 from .models import DDSConfiguration
4 4
5 5 # from django.core.validators import MinValueValidator, MaxValueValidator
6 6
7 7 class DDSConfigurationForm(forms.ModelForm):
8 8
9 9 def __init__(self, *args, **kwargs):
10 10 #request = kwargs.pop('request')
11 11 super(DDSConfigurationForm, self).__init__(*args, **kwargs)
12 12
13 13 instance = getattr(self, 'instance', None)
14 14
15 15 if instance and instance.pk:
16 16
17 17 devices = Device.objects.filter(device_type__name='dds')
18 18
19 self.fields['experiment'].widget.attrs['readonly'] = True
20
21 if instance.experiment is not None:
22 self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
19 if instance.experiment:
20 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
23 21
24 22 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
25 23
26 24
27 25 class Meta:
28 26 model = DDSConfiguration
29 27 exclude = ('type', 'parameters', 'status') No newline at end of file
@@ -1,234 +1,231
1 1 # Create your views here.
2 2 from django.shortcuts import redirect, render, get_object_or_404
3 3
4 4 # from apps.main.models import Experiment, Configuration
5 5 from apps.main.views import sidebar
6 6
7 7 from .models import DDSConfiguration
8 8 from .forms import DDSConfigurationForm
9 9 # Create your views here.
10 10
11 11 def dds_conf(request, id_conf):
12 12
13 13 conf = get_object_or_404(DDSConfiguration, pk=id_conf)
14 14
15 15 kwargs = {}
16 16
17 17 kwargs['status'] = conf.device.get_status_display()
18 18
19 19 # if not kwargs['connected']:
20 20 # messages.error(request, message=answer)
21 21
22 22 kwargs['dev_conf'] = conf
23 23 kwargs['dev_conf_keys'] = ['name',
24 24 'experiment',
25 25 'device',
26 26 'clock',
27 27 'multiplier',
28 28 'frequencyA_Mhz',
29 29 'frequencyA',
30 30 'frequencyB_Mhz',
31 31 'frequencyB',
32 32 'phaseA_degrees',
33 33 'phaseB_degrees',
34 34 'modulation',
35 35 'amplitude_enabled',
36 36 'amplitudeI',
37 37 'amplitudeQ']
38 38
39 39 kwargs['title'] = 'DDS Configuration'
40 40 kwargs['suptitle'] = 'Details'
41 41
42 42 kwargs['button'] = 'Edit Configuration'
43 43
44 44 ###### SIDEBAR ######
45 kwargs.update(sidebar(conf))
45 kwargs.update(sidebar(conf=conf))
46 46
47 47 return render(request, 'dds_conf.html', kwargs)
48 48
49 49 def dds_conf_edit(request, id_conf):
50 50
51 51 conf = get_object_or_404(DDSConfiguration, pk=id_conf)
52 52
53 53 if request.method=='GET':
54 54 form = DDSConfigurationForm(instance=conf)
55 55
56 56 if request.method=='POST':
57 57 form = DDSConfigurationForm(request.POST, instance=conf)
58 58
59 59 if form.is_valid():
60 60 conf = form.save(commit=False)
61 61
62 62 if conf.verify_frequencies():
63 63
64 64 conf.save()
65 65 return redirect('url_dds_conf', id_conf=conf.id)
66 66
67 67 ##ERRORS
68 68
69 69 kwargs = {}
70 70 kwargs['id_dev'] = conf.id
71 71 kwargs['form'] = form
72 72 kwargs['title'] = 'Device Configuration'
73 73 kwargs['suptitle'] = 'Edit'
74 74 kwargs['button'] = 'Save'
75 75
76 ###### SIDEBAR ######
77 kwargs.update(sidebar(conf))
78
79 76 return render(request, 'dds_conf_edit.html', kwargs)
80 77
81 78 # def dds_conf_import(request, id_conf):
82 79 #
83 80 # conf = get_object_or_404(DDSConfiguration, pk=id_conf)
84 81 #
85 82 # if request.method == 'GET':
86 83 # file_form = UploadFileForm()
87 84 #
88 85 # if request.method == 'POST':
89 86 # file_form = UploadFileForm(request.POST, request.FILES)
90 87 #
91 88 # if file_form.is_valid():
92 89 #
93 90 # parms = files.read_dds_file(request.FILES['file'])
94 91 #
95 92 # if parms:
96 93 #
97 94 # if not parms['clock']:
98 95 # messages.warning(request, "Clock Input could not be imported from '%s'. Please fill it out." %request.FILES['file'].name)
99 96 # else:
100 97 # messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
101 98 #
102 99 # form = DDSConfigurationForm(initial=parms, instance=conf)
103 100 #
104 101 # kwargs = {}
105 102 # kwargs['id_dev'] = conf.id
106 103 # kwargs['form'] = form
107 104 # kwargs['title'] = 'Device Configuration'
108 105 # kwargs['suptitle'] = 'Parameters imported'
109 106 # kwargs['button'] = 'Save'
110 107 # kwargs['action'] = conf.get_absolute_url_edit()
111 108 # kwargs['previous'] = conf.get_absolute_url()
112 109 #
113 110 # ###### SIDEBAR ######
114 111 # kwargs.update(sidebar(conf))
115 112 #
116 113 # return render(request, 'dds_conf_edit.html', kwargs)
117 114 #
118 115 # messages.error(request, "Could not import parameters from file")
119 116 #
120 117 # kwargs = {}
121 118 # kwargs['id_dev'] = conf.id
122 119 # kwargs['title'] = 'Device Configuration'
123 120 # kwargs['form'] = file_form
124 121 # kwargs['suptitle'] = 'Importing file'
125 122 # kwargs['button'] = 'Import'
126 123 #
127 124 # kwargs.update(sidebar(conf))
128 125 #
129 126 # return render(request, 'dds_conf_import.html', kwargs)
130 127 #
131 128 # def dds_conf_export(request, id_conf):
132 129 #
133 130 # conf = get_object_or_404(DDSConfiguration, pk=id_conf)
134 131 #
135 132 # response = HttpResponse(content_type='text/plain')
136 133 # response['Content-Disposition'] = 'attachment; filename="%s.dds"' %conf.name
137 134 # response.write(conf.export_parms_to_dict())
138 135 #
139 136 # return response
140 137 #
141 138 # def dds_conf_start(request, id_conf):
142 139 #
143 140 # conf = get_object_or_404(DDSConfiguration, pk=id_conf)
144 141 #
145 142 # if conf.start_device():
146 143 # messages.success(request, conf.message)
147 144 # else:
148 145 # messages.error(request, conf.message)
149 146 #
150 147 # return redirect('url_dds_conf', id_conf=conf.id)
151 148 #
152 149 # def dds_conf_stop(request, id_conf):
153 150 #
154 151 # conf = get_object_or_404(DDSConfiguration, pk=id_conf)
155 152 #
156 153 # if conf.stop_device():
157 154 # messages.success(request, conf.message)
158 155 # else:
159 156 # messages.error(request, conf.message)
160 157 #
161 158 # return redirect('url_dds_conf', id_conf=conf.id)
162 159 #
163 160 # def dds_conf_status(request, id_conf):
164 161 #
165 162 # conf = get_object_or_404(DDSConfiguration, pk=id_conf)
166 163 #
167 164 # if conf.status_device():
168 165 # messages.success(request, conf.message)
169 166 # else:
170 167 # messages.error(request, conf.message)
171 168 #
172 169 # return redirect('url_dds_conf', id_conf=conf.id)
173 170 #
174 171 #
175 172 # def dds_conf_write(request, id_conf):
176 173 #
177 174 # conf = get_object_or_404(DDSConfiguration, pk=id_conf)
178 175 #
179 176 # answer = conf.write_device()
180 177 #
181 178 # if answer:
182 179 # messages.success(request, conf.message)
183 180 #
184 181 # conf.pk = None
185 182 # conf.id = None
186 183 # conf.type = 1
187 184 # conf.template = 0
188 185 # conf.save()
189 186 #
190 187 # else:
191 188 # messages.error(request, conf.message)
192 189 #
193 190 # return redirect('url_dds_conf', id_conf=id_conf)
194 191 #
195 192 # def dds_conf_read(request, id_conf):
196 193 #
197 194 # conf = get_object_or_404(DDSConfiguration, pk=id_conf)
198 195 #
199 196 # if request.method=='GET':
200 197 #
201 198 # parms = conf.read_device()
202 199 #
203 200 # if not parms:
204 201 # messages.error(request, conf.message)
205 202 # return redirect('url_dds_conf', id_conf=conf.id)
206 203 #
207 204 # messages.warning(request, "Clock Input cannot be read from device. Please fill it out.")
208 205 #
209 206 # form = DDSConfigurationForm(initial=parms, instance=conf)
210 207 #
211 208 # if request.method=='POST':
212 209 # form = DDSConfigurationForm(request.POST, instance=conf)
213 210 #
214 211 # if form.is_valid():
215 212 # dds_model = form.save(commit=False)
216 213 #
217 214 # if dds_model.verify_frequencies():
218 215 #
219 216 # dds_model.save()
220 217 # return redirect('url_dds_conf', id_conf=conf.id)
221 218 #
222 219 # messages.error(request, "DDS parameters could not be saved")
223 220 #
224 221 # kwargs = {}
225 222 # kwargs['id_dev'] = conf.id
226 223 # kwargs['form'] = form
227 224 # kwargs['title'] = 'Device Configuration'
228 225 # kwargs['suptitle'] = 'Parameters read from device'
229 226 # kwargs['button'] = 'Save'
230 227 #
231 228 # ###### SIDEBAR ######
232 229 # kwargs.update(sidebar(conf))
233 230 #
234 231 # return render(request, 'dds_conf_edit.html', kwargs) No newline at end of file
@@ -1,9 +1,10
1 1 [
2 {"fields": {"name": "JRO", "description": ""}, "model": "main.location", "pk": 1},
3 {"fields": {"name": "JASMET", "description": ""}, "model": "main.location", "pk": 2},
4 {"fields": {"name": "SOUSY", "description": ""}, "model": "main.location", "pk": 3},
2 {"fields": {"name": "MAIN RADAR", "description": ""}, "model": "main.location", "pk": 1},
3 {"fields": {"name": "JASMET", "description": ""}, "model": "main.location", "pk": 2},
4 {"fields": {"name": "SOUSY", "description": ""}, "model": "main.location", "pk": 3},
5 {"fields": {"name": "JULIA", "description": ""}, "model": "main.location", "pk": 4},
5 6 {"fields": {"name": "rc", "description": ""}, "model": "main.devicetype", "pk": 1},
6 7 {"fields": {"name": "dds", "description": ""}, "model": "main.devicetype", "pk": 2},
7 8 {"fields": {"name": "cgs", "description": ""}, "model": "main.devicetype", "pk": 3},
8 9 {"fields": {"name": "jars", "description": ""}, "model": "main.devicetype", "pk": 4}
9 10 ]
@@ -1,127 +1,151
1 1 from django import forms
2 2 from django.utils.safestring import mark_safe
3 3
4 4 from .models import DeviceType, Device, Experiment, Campaign, Configuration, Location
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 TimepickerWidget(forms.widgets.TextInput):
36 36 def render(self, name, value, attrs=None):
37 37 input_html = super(TimepickerWidget, self).render(name, value, attrs)
38 38 html = '<div class="input-group time">'+input_html+'<span class="input-group-addon"><i class="glyphicon glyphicon-time"></i></span></div>'
39 39 return mark_safe(html)
40 40
41 41 class CampaignForm(forms.ModelForm):
42
43 experiments = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(),
44 queryset=Experiment.objects.filter(template=True),
45 required=False)
46
42 47 def __init__(self, *args, **kwargs):
43 48 super(CampaignForm, self).__init__(*args, **kwargs)
44 49 self.fields['start_date'].widget = DatepickerWidget(self.fields['start_date'].widget.attrs)
45 50 self.fields['end_date'].widget = DatepickerWidget(self.fields['end_date'].widget.attrs)
51 self.fields['description'].widget.attrs = {'rows': 2}
46 52
47 53 class Meta:
48 54 model = Campaign
49 55 exclude = ['']
50 56
51 57 class ExperimentForm(forms.ModelForm):
52 58
53 59 def __init__(self, *args, **kwargs):
54 60 super(ExperimentForm, self).__init__(*args, **kwargs)
55 61 self.fields['start_time'].widget = TimepickerWidget(self.fields['start_time'].widget.attrs)
56 62 self.fields['end_time'].widget = TimepickerWidget(self.fields['end_time'].widget.attrs)
57
58 self.fields['campaign'].widget.attrs['readonly'] = True
59 63
60 64 class Meta:
61 65 model = Experiment
62 66 exclude = ['']
63 67
64 68 class LocationForm(forms.ModelForm):
65 69 class Meta:
66 70 model = Location
67 71 exclude = ['']
68 72
69 73 class DeviceForm(forms.ModelForm):
70 74 class Meta:
71 75 model = Device
72 76 exclude = ['status']
73 77
74 78 class ConfigurationForm(forms.ModelForm):
79
80 def __init__(self, *args, **kwargs):
81 super(ConfigurationForm, self).__init__(*args, **kwargs)
82
83 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
84 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
85
75 86 class Meta:
76 87 model = Configuration
77 88 exclude = ['type', 'created_date', 'programmed_date', 'parameters']
78 89
79 90 class DeviceTypeForm(forms.Form):
80 91 device_type = forms.ChoiceField(choices=add_empty_choice(DeviceType.objects.all().order_by('name').values_list('id', 'name')))
81 92
82 93
83 94 class UploadFileForm(forms.Form):
84 95
85 96 file = forms.FileField()
86 97
87 98 class DownloadFileForm(forms.Form):
88 99
89 100 format = forms.ChoiceField(choices= ((0, 'json'),) )
90 101
91 102 def __init__(self, device_type, *args, **kwargs):
92 103
93 104 super(DownloadFileForm, self).__init__(*args, **kwargs)
94 105
95 106 self.fields['format'].choices = FILE_FORMAT
96 107
97 108 if device_type == 'dds':
98 109 self.fields['format'].choices = DDS_FILE_FORMAT
99 110
100 111 if device_type == 'rc':
101 112 self.fields['format'].choices = RC_FILE_FORMAT
102 113
103 114 class OperationForm(forms.Form):
104 115 # today = datetime.today()
105 116 # -----Campaigns from this month------[:5]
106 117 campaign = forms.ChoiceField(label="Campaign")
107 118
108 119 def __init__(self, *args, **kwargs):
109 120
110 121 if 'length' not in kwargs.keys():
111 122 length = None
112 123 else:
113 124 length = kwargs['length']
114 125
115 126 kwargs.pop('length')
116 127
117 128 super(OperationForm, self).__init__(*args, **kwargs)
118 129 self.fields['campaign'].choices=Campaign.objects.all().order_by('-start_date').values_list('id', 'name')[:length]
119 130
120 131 class OperationSearchForm(forms.Form):
121 132 # -----ALL Campaigns------
122 133 campaign = forms.ChoiceField(label="Campaign")
123 134
124 135 def __init__(self, *args, **kwargs):
125 136 super(OperationSearchForm, self).__init__(*args, **kwargs)
126 137 self.fields['campaign'].choices=Campaign.objects.all().order_by('-start_date').values_list('id', 'name')
138
139 class NewForm(forms.Form):
140
141 create_from = forms.ChoiceField(choices=((0, '-----'),
142 (1, 'Empty (blank)'),
143 (2, 'Template')))
144 choose_template = forms.ChoiceField()
145
146 def __init__(self, *args, **kwargs):
147
148 template_choices = kwargs.pop('template_choices', [])
149 super(NewForm, self).__init__(*args, **kwargs)
150 self.fields['choose_template'].choices = add_empty_choice(template_choices)
127 151 No newline at end of file
@@ -1,358 +1,371
1
2 from datetime import datetime
3
1 4 from django.db import models
2 5 from polymorphic import PolymorphicModel
3 6
4 7 from django.core.urlresolvers import reverse
5 8
6 9 CONF_STATES = (
7 10 (0, 'Disconnected'),
8 11 (1, 'Connected'),
9 12 (2, 'Running'),
10 13 )
11 14
12 15 EXP_STATES = (
13 16 (0,'Error'), #RED
14 17 (1,'Configurated'), #BLUE
15 18 (2,'Running'), #GREEN
16 19 (3,'Waiting'), #YELLOW
17 20 (4,'Not Configured'), #WHITE
18 21 )
19 22
20 23 CONF_TYPES = (
21 24 (0, 'Active'),
22 25 (1, 'Historical'),
23 26 )
24 27
25 28 DEV_STATES = (
26 29 (0, 'No connected'),
27 30 (1, 'Connected'),
28 31 (2, 'Configured'),
29 32 (3, 'Running'),
30 33 )
31 34
32 35 DEV_TYPES = (
33 36 ('', 'Select a device type'),
34 37 ('rc', 'Radar Controller'),
35 38 ('dds', 'Direct Digital Synthesizer'),
36 39 ('jars', 'Jicamarca Radar Acquisition System'),
37 40 ('usrp', 'Universal Software Radio Peripheral'),
38 41 ('cgs', 'Clock Generator System'),
39 42 ('abs', 'Automatic Beam Switching'),
40 43 )
41 44
42 45 DEV_PORTS = {
43 46 'rc' : 2000,
44 47 'dds' : 2000,
45 48 'jars' : 2000,
46 49 'usrp' : 2000,
47 50 'cgs' : 8080,
48 51 'abs' : 8080
49 52 }
50 53
51 54 RADAR_STATES = (
52 55 (0, 'No connected'),
53 56 (1, 'Connected'),
54 57 (2, 'Configured'),
55 58 (3, 'Running'),
56 59 (4, 'Scheduled'),
57 60 )
58 61 # Create your models here.
59 62
60 63 class Location(models.Model):
61 64
62 65 name = models.CharField(max_length = 30)
63 66 description = models.TextField(blank=True, null=True)
64 67
65 68 class Meta:
66 69 db_table = 'db_location'
67 70
68 71 def __unicode__(self):
69 72 return u'%s' % self.name
70 73
71 74 class DeviceType(models.Model):
72 75
73 76 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc')
74 77 description = models.TextField(blank=True, null=True)
75 78
76 79 class Meta:
77 80 db_table = 'db_device_types'
78 81
79 82 def __unicode__(self):
80 83 return u'%s' % self.get_name_display()
81 84
82 85 class Device(models.Model):
83 86
84 87 device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
85 88 location = models.ForeignKey(Location, on_delete=models.CASCADE)
86 89
87 90 name = models.CharField(max_length=40, default='')
88 91 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
89 92 port_address = models.PositiveSmallIntegerField(default=2000)
90 93 description = models.TextField(blank=True, null=True)
91 94 status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES)
92 95
93 96 class Meta:
94 97 db_table = 'db_devices'
95 98
96 99 def __unicode__(self):
97 100 return u'%s | %s' % (self.name, self.ip_address)
98 101
99 102 def get_status(self):
100 103
101 104 return self.status
102 105
103 106
104 107 class Campaign(models.Model):
105 108
106 template = models.BooleanField(default=False)
107
108 name = models.CharField(max_length=40, unique=True)
109 experiment = models.ManyToManyField('Experiment')
110
109 template = models.BooleanField(default=False)
110 name = models.CharField(max_length=60, unique=True)
111 111 start_date = models.DateTimeField(blank=True, null=True)
112 112 end_date = models.DateTimeField(blank=True, null=True)
113 113 tags = models.CharField(max_length=40)
114 114 description = models.TextField(blank=True, null=True)
115 experiments = models.ManyToManyField('Experiment', blank=True)
115 116
116 117 class Meta:
117 118 db_table = 'db_campaigns'
119 ordering = ('name',)
118 120
119 121 def __unicode__(self):
120 122 return u'%s' % (self.name)
121
122 # class Radar(models.Model):
123 #
124 # # name = models.CharField(max_length = 30)
125 # experiment = models.ForeignKey('Experiment', on_delete=models.CASCADE)
126 # location = models.OneToOneField('Location', on_delete=models.CASCADE)
127 # status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
128 #
129 # class Meta:
130 # db_table = 'db_radar'
131 #
132 # def __unicode__(self):
133 # return u'%s' % self.location
134 123
124
135 125 class RunningExperiment(models.Model):
136 126 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
137 127 running_experiment = models.ManyToManyField('Experiment')
138 128 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
139 129
140 130
141 131 class Experiment(models.Model):
142 132
143 template = models.BooleanField(default=False)
144
145 #campaign = models.ForeignKey('Campaign', null=True, blank=True, on_delete=models.CASCADE)
133 template = models.BooleanField(default=False)
134 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
135 name = models.CharField(max_length=40, default='', unique=True)
146 136 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
147
148 name = models.CharField(max_length=40, default='')
149 137 start_time = models.TimeField(default='00:00:00')
150 138 end_time = models.TimeField(default='23:59:59')
151 139 status = models.PositiveSmallIntegerField(default=0, choices=EXP_STATES)
152 140
153 141 class Meta:
154 142 db_table = 'db_experiments'
143 ordering = ('name',)
155 144
156 145 def __unicode__(self):
157 146 return u'%s' % (self.name)
158 147
148 def clone(self, **kwargs):
149
150 confs = Configuration.objects.filter(experiment=self, type=0)
151 self.pk = None
152 self.name = '{} [{:%Y/%m/%d}]'.format(self.name, datetime.now())
153 for attr, value in kwargs.items():
154 setattr(self, attr, value)
155
156 self.save()
157
158 for conf in confs:
159 conf.clone(experiment=self, template=False)
160
161 return self
159 162
160 163 def get_status(self):
161 164 configurations = Configuration.objects.filter(experiment=self)
162 165 exp_status=[]
163 166 for conf in configurations:
164 167 print conf.status_device()
165 168 exp_status.append(conf.status_device())
166 169
167 170 if not exp_status: #No Configuration
168 171 self.status = 4
169 172 self.save()
170 173 return
171 174
172 175 total = 1
173 176 for e_s in exp_status:
174 177 total = total*e_s
175 178
176 179 if total == 0: #Error
177 180 status = 0
178 181 elif total == (3**len(exp_status)): #Running
179 182 status = 2
180 183 else:
181 184 status = 1 #Configurated
182 185
183 186 self.status = status
184 187 self.save()
185 188
186 189 def status_color(self):
187 190 color = 'danger'
188 191 if self.status == 0:
189 192 color = "danger"
190 193 elif self.status == 1:
191 194 color = "info"
192 195 elif self.status == 2:
193 196 color = "succes"
194 197 elif self.status == 3:
195 198 color = "warning"
196 199 else:
197 200 color = "muted"
198 201
199 202 return color
200 203
204
201 205 class Configuration(PolymorphicModel):
202 206
203 207 template = models.BooleanField(default=False)
204 208
205 209 name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
206 210
207 211 experiment = models.ForeignKey('Experiment', null=True, blank=True, on_delete=models.CASCADE)
208 212 device = models.ForeignKey(Device, on_delete=models.CASCADE)
209 213
210 214 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
211 215
212 216 created_date = models.DateTimeField(auto_now_add=True)
213 217 programmed_date = models.DateTimeField(auto_now=True)
214 218
215 219 parameters = models.TextField(default='{}')
216 220
217 221 message = ""
218 222
219 223 class Meta:
220 224 db_table = 'db_configurations'
221 225
222 226 def __unicode__(self):
223 227
224 228 if self.experiment:
225 229 return u'[%s, %s]: %s' % (self.experiment.name,
226 230 self.device.name,
227 231 self.name)
228 232 else:
229 233 return u'%s' % self.device.name
230 234
235 def clone(self, **kwargs):
231 236
237 self.pk = None
238 self.id = None
239 for attr, value in kwargs.items():
240 setattr(self, attr, value)
241
242 self.save()
243
244 return self
232 245
233 246 def parms_to_dict(self):
234 247
235 248 parameters = {}
236 249
237 250 for key in self.__dict__.keys():
238 251 parameters[key] = getattr(self, key)
239 252
240 253 return parameters
241 254
242 255 def parms_to_text(self):
243 256
244 257 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
245 258
246 259 return ''
247 260
248 261 def parms_to_binary(self):
249 262
250 263 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
251 264
252 265 return ''
253 266
254 267 def dict_to_parms(self, parameters):
255 268
256 269 if type(parameters) != type({}):
257 270 return
258 271
259 272 for key in parameters.keys():
260 273 setattr(self, key, parameters[key])
261 274
262 275 def export_to_file(self, format="json"):
263 276
264 277 import json
265 278
266 279 content_type = ''
267 280
268 281 if format == 'text':
269 282 content_type = 'text/plain'
270 283 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
271 284 content = self.parms_to_text()
272 285
273 286 if format == 'binary':
274 287 content_type = 'application/octet-stream'
275 288 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
276 289 content = self.parms_to_binary()
277 290
278 291 if not content_type:
279 292 content_type = 'application/json'
280 293 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
281 294 content = json.dumps(self.parms_to_dict(), indent=2)
282 295
283 296 fields = {'content_type':content_type,
284 297 'filename':filename,
285 298 'content':content
286 299 }
287 300
288 301 return fields
289 302
290 303 def import_from_file(self, fp):
291 304
292 305 import os, json
293 306
294 307 parms = {}
295 308
296 309 path, ext = os.path.splitext(fp.name)
297 310
298 311 if ext == '.json':
299 312 parms = json.load(fp)
300 313
301 314 return parms
302 315
303 316 def status_device(self):
304 317
305 318 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
306 319
307 320 return None
308 321
309 322 def stop_device(self):
310 323
311 324 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
312 325
313 326 return None
314 327
315 328 def start_device(self):
316 329
317 330 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
318 331
319 332 return None
320 333
321 334 def write_device(self, parms):
322 335
323 336 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
324 337
325 338 return None
326 339
327 340 def read_device(self):
328 341
329 342 raise NotImplementedError, "This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper()
330 343
331 344 return None
332 345
333 346 def get_absolute_url(self):
334 347 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
335 348
336 349 def get_absolute_url_edit(self):
337 350 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
338 351
339 352 def get_absolute_url_import(self):
340 353 return reverse('url_import_dev_conf', args=[str(self.id)])
341 354
342 355 def get_absolute_url_export(self):
343 356 return reverse('url_export_dev_conf', args=[str(self.id)])
344 357
345 358 def get_absolute_url_write(self):
346 359 return reverse('url_write_dev_conf', args=[str(self.id)])
347 360
348 361 def get_absolute_url_read(self):
349 362 return reverse('url_read_dev_conf', args=[str(self.id)])
350 363
351 364 def get_absolute_url_start(self):
352 365 return reverse('url_start_dev_conf', args=[str(self.id)])
353 366
354 367 def get_absolute_url_stop(self):
355 368 return reverse('url_stop_dev_conf', args=[str(self.id)])
356 369
357 370 def get_absolute_url_status(self):
358 371 return reverse('url_status_dev_conf', args=[str(self.id)]) No newline at end of file
@@ -1,144 +1,141
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 .col-no-padding { padding-left:0; }
16 .col-no-padding { padding-left:0;}
17 .gi-2x{font-size: 2em;}
18 .gi-3x{font-size: 3em;}
19 .gi-4x{font-size: 4em;}
20 .gi-5x{font-size: 5em;}
17 21 </style>
18 22 <!--[if lt IE 9]>
19 23 <script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
20 24 <![endif]-->
21 25 <script src="{% static 'js/jquery.min.js' %}"></script>
22 26 {% block extra-head %}
23 27 {% endblock %}
24 28 </head>
25 29
26 30 <body>
27 31
28 32 {% block main_menu %}
29 33 <nav class="navbar navbar-default navbar-fixed-top" role="banner">
30 34 <div class="container-fluid">
31 35 <div class="navbar-header">
32 36 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navigationbar">
33 37 <span class="sr-only">Toggle navigation</span>
34 38 <span class="icon-bar"></span>
35 39 <span class="icon-bar"></span>
36 40 <span class="icon-bar"></span>
37 41 </button>
38 42 <a class="navbar-brand" href="{% url 'index' %}" style="padding-top:1px"><img class="logo" alt="JRO" src="{% static "images/logo-jro-white-trans.png" %}"></a>
39 43 </div>
40 44 <div class="collapse navbar-collapse" id="navigationbar">
41 45 <ul class="nav navbar-nav">
42 46 <li class=" dropdown {% block operation-active %}{% endblock %}"><a href="{% url 'url_operation'%}">Operation</a>
43 47 </li>
44 <li class=" dropdown {% block conf-active %}{% endblock %}">
48 <li class=" dropdown {% block new-active %}{% endblock %}">
45 49 <a href="#" class="dropdown-toggle" data-toggle="dropdown">New<span class="caret"></span></a>
46 50 <ul class="dropdown-menu" role="menu">
47 51 <li><a href="{% url 'url_add_campaign' %}">Campaign</a></li>
48 <li><a href="{% url 'url_add_experiment' 0%}">Experiment</a></li>
52 <li><a href="{% url 'url_add_experiment' %}">Experiment</a></li>
49 53 <li><a href="{% url 'url_add_dev_conf' 0%}">Device Configuration</a></li>
50 <li><a href="{% url 'url_add_device'%}">Radar/Device</a></li>
51
54 <li><a href="{% url 'url_add_device'%}">Device</a></li>
52 55 </ul>
53 56 </li>
54 <li class=" dropdown {% block test-active %}{% endblock %}">
55 <a href="#" class="dropdown-toggle" data-toggle="dropdown">Test<span class="caret"></span></a>
56 <ul class="dropdown-menu" role="menu">
57 <li><a href="{% url 'url_experiments' %}">Experiments</a></li>
58 <li><a href="{% url 'url_devices' %}">Devices</a></li>
59 </ul>
60 </li>
61 57 <li class=" dropdown {% block search-active %}{% endblock %}">
62 58 <a href="#" class="dropdown-toggle" data-toggle="dropdown">Search<span class="caret"></span></a>
63 59 <ul class="dropdown-menu" role="menu">
64 60 <li><a href="{% url 'url_campaigns' %}">Campaigns</a></li>
65 61 <li><a href="{% url 'url_experiments' %}">Experiments</a></li>
66 62 <li><a href="{% url 'url_dev_confs' %}">Configurations</a></li>
63 <li><a href="{% url 'url_devices' %}">Devices</a></li>
67 64 </ul>
68 65 </li>
69 66 </ul>
70 67 <ul class="nav navbar-nav navbar-right">
71 68 <li class="nav-divider"></li>
72 69 {% if user.is_authenticated %}
73 70 <li class="dropdown">
74 71 <a href="#" class="dropdown-toggle" data-toggle="dropdown">Hi {{ user.username }}<span class="caret"></span></a>
75 72 <ul class="dropdown-menu" role="menu">
76 73 <li><a href="#">Control Panel</a></li>
77 74 <li><a href="{% url 'django.contrib.auth.views.logout' %}">Logout</a></li>
78 75 </ul>
79 76 </li>
80 77 {% else %}
81 78 <li><a href="{% url 'django.contrib.auth.views.login' %}?next={{request.get_full_path}}">Login</a></li>
82 79 {% endif %}
83 80 </ul>
84 81 </div>
85 82 </div>
86 83 </nav>
87 84 <div style="clear: both;"></div>
88 85 {% endblock %}
89 86
90 87 <div class="container">
91 88 <div id="page" class="row" style="min-height:600px">
92 89
93 90 <div class="col-md-3 hidden-xs hidden-sm" role="complementary">
94 91 <br><br>
95 92 <div id="sidebar">
96 93 {% block sidebar%}
97 94 {% endblock %}
98 95 </div>
99 96 </div>
100 97
101 98 <div class="col-md-9 col-xs-12" role="main">
102 99 <div class="page-header">
103 100 <h1>{% block content-title %}{% endblock %} <small>{% block content-suptitle %}{% endblock %}</small></h1>
104 101 </div>
105 102 {% block messages %}
106 103 {% if messages %}
107 104 {% for message in messages %}
108 105 <div class="alert alert-{% if message.tags %}{% if 'error' in message.tags %}danger{% else %}{{ message.tags }}{% endif %}{% else %}info{% endif %} alert-dismissible" role="alert">
109 106 <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
110 107 <strong>{{message.tags|title}}!</strong> {{ message }}
111 108 </div>
112 109 {% endfor %}
113 110 {% endif %}
114 111 {% endblock %}
115 112
116 113 {% block content %}
117 114 {% endblock %}
118 115
119 116 </div>
120 117
121 118 </div><!--/row-->
122 119 </div> <!-- container -->
123 120
124 121 <div id="debug">{{debug}}</div>
125 122
126 123 {% block footer %}
127 124 <footer class="footer">
128 125 <div class="container">
129 126 <p><hr></p>
130 127 <p>
131 128 &copy; <a href="http://jro.igp.gob.pe">Jicamarca Radio Observatory</a> - {% now "Y" %}
132 129 </p>
133 130 </div>
134 131 </footer>
135 132 {% endblock %}
136 133
137 134 {# bootstrap_javascript jquery=True #}
138 135
139 136 <script src="{% static 'js/bootstrap.min.js' %}"></script>
140 137 {% block extra-js %}
141 138 {% endblock%}
142 139 </body>
143 140 </html>
144 141
@@ -1,83 +1,78
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 9 {% block camp-active %}active{% endblock %}
10 10
11 11 {% block content-title %}{{title}}{% endblock %}
12 12 {% block content-suptitle %}{{suptitle}}{% endblock %}
13 13
14 14 {% block content %}
15 15 <table class="table table-bordered">
16 16 {% for key in campaign_keys %}
17 17 <tr><th>{{key|title}}</th><td>{{campaign|attr:key}}</td></tr>
18 18 {% endfor %}
19 19 </table>
20 20
21 21 <button class="btn btn-primary pull-right" style="margin-left: 10px" id="bt_export">Export</button>
22 22 <button class="btn btn-primary pull-right" style="margin-left: 10px" id="bt_edit">Edit</button>
23 23
24 24 <br></br>
25 25 <br></br>
26 26
27 27 <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
28 28
29 29 <div class="panel panel-default">
30 30 <div class="panel-heading" role="tab" id="headingTwo">
31 31 <h4 class="panel-title">
32 32 <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
33 33 Experiment List
34 34 </a>
35 35 </h4>
36 36 </div>
37 37
38 38 <div id="collapseTwo" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingTwo">
39 39 <div class="panel-body">
40 40 <table class="table table-hover">
41 41 <tr>
42 42 <th>#</th>
43 43 {% for header in experiment_keys %}
44 44 <th>{{ header|title }}</th>
45 45 {% endfor%}
46 46 </tr>
47 47 {% for item in experiments %}
48 48 <tr class="clickable-row" data-href="{% url 'url_experiment' item.id %}">
49 49 <td>{{ forloop.counter }}</td>
50 50 {% for key in experiment_keys %}
51 51 <td>{{ item|attr:key }}</td>
52 52 {% endfor %}
53 53 </tr>
54 54 {% endfor %}
55 </table>
56 <button class="btn btn-primary pull-right" id="bt_add">{{button}}</button>
55 </table>
57 56 </div>
58 57 </div>
59 58 </div>
60 59 </div>
61 60 {% endblock %}
62 61
63 62 {% block sidebar%}
64 63 {% include "sidebar_devices.html" %}
65 64 {% endblock %}
66 65
67 66 {% block extra-js%}
68 67 <script type="text/javascript">
69 68
70 69 $(".clickable-row").click(function() {
71 70 document.location = $(this).data("href");
72 71 });
73 72
74 73 $("#bt_edit").click(function() {
75 document.location = "{% url 'url_edit_campaign' campaign.id%}";
74 document.location = "{% url 'url_edit_campaign' campaign.id %}";
76 75 });
77 76
78 $("#bt_add").click(function() {
79 document.location = "{% url 'url_add_experiment' campaign.id%}";
80 });
81
82 77 </script>
83 78 {% endblock %} No newline at end of file
@@ -1,36 +1,54
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 9 {% block camp-active %}active{% endblock %}
10 10
11 11 {% block content-title %}{{title}}{% endblock %}
12 12 {% block content-suptitle %}{{suptitle}}{% endblock %}
13 13
14 14 {% block content %}
15 15 <form class="form" method="post" action="">
16 16 {% csrf_token %}
17 17 {% bootstrap_form form layout='horizontal' size='medium' %}
18 18 <div style="clear: both;"></div>
19 <br>
20 <button type="submit" class="btn btn-primary pull-right">{{button}}</button>
19 {% if button %}
20 <br>
21 <button type="submit" class="btn btn-primary pull-right">{{button}}</button>
22 {% endif %}
21 23 </form>
22 24 {% endblock %}
23 25
24 26 {% block sidebar%}
25 27 {% include "sidebar_devices.html" %}
26 28 {% endblock %}
27 29
28 30 {% block extra-js%}
29 31 <script src="{% static 'js/moment.min.js' %}"></script>
30 32 <script src="{% static 'js/bootstrap-datetimepicker.min.js' %}"></script>
31 33 <script type="text/javascript">
32 34
33 35 $('.input-group.date').datetimepicker({"format": "YYYY-MM-DD HH:mm"});
34 36
37 $('#id_create_from').change(function() {
38 var url = "{% url 'url_add_campaign' %}";
39 if ($(this).val()=="2"){
40 document.location = url+"?template=0";
41 }else if ($(this).val()=="1"){
42 document.location = url+"?blank=0";
43 }else{
44 document.location = url;
45 }
46 });
47
48 $('#id_choose_template').change(function() {
49 var url = "{% url 'url_add_campaign' %}";
50 document.location = url+"?template="+$(this).val();
51 });
52
35 53 </script>
36 54 {% endblock %} No newline at end of file
@@ -1,50 +1,46
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 9 {% block camp-active %}active{% endblock %}
10 10
11 11 {% block content-title %}{{title}}{% endblock %}
12 12 {% block content-suptitle %}{{suptitle}}{% endblock %}
13 13
14 14 {% block content %}
15 15 <table class="table table-hover">
16 16 <tr>
17 17 <th>#</th>
18 18 {% for key in campaign_keys %}
19 19 <th>{{ key|title }}</th>
20 20 {% endfor%}
21 21 </tr>
22 22 {% for campaign in campaigns %}
23 23 <tr class="clickable-row" data-href="{% url 'url_campaign' campaign.id %}">
24 24 <td>{{ forloop.counter }}</td>
25 25 {% for key in campaign_keys %}
26 26 <td>{{ campaign|attr:key }}</td>
27 27 {% endfor %}
28 28 </tr>
29 29 {% endfor %}
30 30 </table>
31 <button class="btn btn-primary pull-right" id="bt_add">{{button}}</button>
31
32 32 {% endblock %}
33 33
34 34 {% block sidebar%}
35 35 {% include "sidebar_devices.html" %}
36 36 {% endblock %}
37 37
38 38 {% block extra-js%}
39 39 <script type="text/javascript">
40
41 $("#bt_add").click(function() {
42 document.location = "{% url 'url_add_campaign' %}";
43 });
44 40
45 41 $(".clickable-row").click(function() {
46 42 document.location = $(this).data("href");
47 });
43 });
48 44
49 45 </script>
50 46 {% endblock %} No newline at end of file
@@ -1,81 +1,81
1 1 {% extends "base.html" %}
2 2 {% load bootstrap3 %}
3 3 {% load static %}
4 4 {% load main_tags %}
5 5
6 {% block conf-active %}active{% endblock %}
6 {% block search-active %}active{% endblock %}
7 7
8 8 {% block content-title %}{{title}}{% endblock %}
9 9 {% block content-suptitle %}{{suptitle}}{% endblock %}
10 10
11 11 {% block content %}
12 12
13 13 {% block menu-actions %}
14 14 <span class=" dropdown pull-right">
15 <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-menu-hamburger" aria-hidden="true"></span></a>
15 <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-menu-hamburger gi-2x" aria-hidden="true"></span></a>
16 16 <ul class="dropdown-menu" role="menu">
17 17 <li><a href="{{ dev_conf.get_absolute_url_edit }}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</a></li>
18 18 <li><a href="{{ dev_conf.get_absolute_url_import }}"><span class="glyphicon glyphicon-import" aria-hidden="true"></span> Import </a></li>
19 19 <li><a href="{{ dev_conf.get_absolute_url_export }}"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Export </a></li>
20 20 {% block extra-menu-actions %}
21 21 {% endblock %}
22 22 <li><a>----------------</a></li>
23 23 <li><a href="{{ dev_conf.get_absolute_url_status }}"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> Status</a></li>
24 24 {% if not no_play %}
25 25 <li><a href="{{ dev_conf.get_absolute_url_start}}"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Start</a></li>
26 26 <li><a href="{{ dev_conf.get_absolute_url_stop }}"><span class="glyphicon glyphicon-stop" aria-hidden="true"></span> Stop</a></li>
27 27 {% endif %}
28 28 <li><a href="{{ dev_conf.get_absolute_url_write }}"><span class="glyphicon glyphicon-download" aria-hidden="true"></span> Write</a></li>
29 29 <li><a href="{{ dev_conf.get_absolute_url_read }}"><span class="glyphicon glyphicon-upload" aria-hidden="true"></span> Read</a></li>
30 30 </ul>
31 31 </span>
32 32 {% endblock %}
33 33
34 34 <table class="table table-bordered">
35 35 <tr>
36 36 <th>Status</th>
37 37 <td>{%if status != "No connected" %} <span class="glyphicon glyphicon-ok-circle text-success" aria-hidden="true"></span> {{status}} {% else %} <span class="glyphicon glyphicon-remove-circle text-danger" aria-hidden="true"></span> {{status}} {% endif %}</td>
38 38 </tr>
39 39
40 40 {% for key in dev_conf_keys %}
41 41 <tr>
42 42 <th>{% get_verbose_field_name dev_conf key %}</th>
43 43 <td>{{dev_conf|attr:key}}</td>
44 44 </tr>
45 45 {% endfor %}
46 46 </table>
47 47
48 48 {% block extra-content %}
49 49 {% endblock %}
50 50
51 51 {% endblock %}
52 52
53 53 {% block sidebar%}
54 54 {% include "sidebar_devices.html" %}
55 55 {% endblock %}
56 56
57 57 {% block extra-js%}
58 58 <script type="text/javascript">
59 59
60 60 $("#bt_edit").click(function() {
61 61 document.location = "{{ dev_conf.get_absolute_url_edit }}";
62 62 });
63 63
64 64 $("#bt_read").click(function() {
65 65 document.location = "{{ dev_conf.get_absolute_url_read }}";
66 66 });
67 67
68 68 $("#bt_write").click(function() {
69 69 document.location = "{{ dev_conf.get_absolute_url_write }}";
70 70 });
71 71
72 72 $("#bt_import").click(function() {
73 73 document.location = "{{ dev_conf.get_absolute_url_import }}";
74 74 });
75 75
76 76 $("#bt_export").click(function() {
77 77 document.location = "{{ dev_conf.get_absolute_url_export }}";
78 78 });
79 79
80 80 </script>
81 81 {% endblock %} No newline at end of file
@@ -1,46 +1,48
1 1 {% extends "base.html" %}
2 2 {% load bootstrap3 %}
3 3 {% load static %}
4 4 {% load main_tags %}
5 5
6 6 {% block conf-active %}active{% endblock %}
7 7
8 8 {% block content-title %}{{title}}{% endblock %}
9 9 {% block content-suptitle %}{{suptitle}}{% endblock %}
10 10
11 11 {% block content %}
12 12
13 13 {% if form.is_multipart %}
14 14 <form class="form" enctype="multipart/form-data" method="post" action="{{action}}">
15 15 {% else %}
16 16 <form class="form" method="post" action="{{action}}">
17 17 {% endif %}
18 18
19 19 {% csrf_token %}
20 20 {% bootstrap_form form layout='horizontal' size='medium' %}
21 21 <div style="clear: both;"></div>
22 22 <br>
23 23 {% if extra_button %}
24 24 <div class="pull-left">
25 25 <button type="button" class="btn btn-primary" id="bt_{{extra_button}}">{{extra_button}}</button>
26 26 </div>
27 27 {% endif %}
28 28 <div class="pull-right">
29 29 <button type="button" class="btn btn-primary" onclick="{% if previous %}window.location.replace('{{ previous }}');{% else %}history.go(-1);{% endif %}">Cancel</button>
30 30 <button type="submit" class="btn btn-primary">{{button}}</button>
31 31 </div>
32 32 </form>
33 33 {% endblock %}
34 34
35 35 {% block sidebar%}
36 36 {% include "sidebar_devices.html" %}
37 37 {% endblock %}
38 38
39 39 {% block extra-js%}
40 {% if id_exp %}
40 41 <script type="text/javascript">
41 42 $("#id_device").change(function() {
42 43 var url = "{% url 'url_add_dev_conf' id_exp %}";
43 44 document.location = url+ $(this).val() + "/";
44 45 });
45 </script>
46 </script>
47 {% endif %}
46 48 {% endblock %} No newline at end of file
@@ -1,50 +1,45
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 9 {% block conf-active %}active{% endblock %}
10 10
11 11 {% block content-title %}{{title}}{% endblock %}
12 12 {% block content-suptitle %}{{suptitle}}{% endblock %}
13 13
14 14 {% block content %}
15 15 <table class="table table-hover">
16 16 <tr>
17 17 <th>#</th>
18 18 {% for key in configuration_keys %}
19 19 <th>{{ key|title }}</th>
20 20 {% endfor%}
21 21 </tr>
22 22 {% for item in configurations %}
23 23 <tr class="clickable-row" data-href="{{item.get_absolute_url}}">
24 24 <td>{{ forloop.counter }}</td>
25 25 {% for key in configuration_keys %}
26 26 <td>{{ item|attr:key }}</td>
27 27 {% endfor %}
28 28 </tr>
29 29 {% endfor %}
30 30 </table>
31 <button class="btn btn-primary pull-right" id="bt_add">{{button}}</button>
32 31 {% endblock %}
33 32
34 33 {% block sidebar%}
35 34 {% include "sidebar_devices.html" %}
36 35 {% endblock %}
37 36
38 37 {% block extra-js%}
39 38 <script type="text/javascript">
40
41 $("#bt_add").click(function() {
42 document.location = "{% url 'url_add_dev_conf' 0%}";
43 });
44 39
45 40 $(".clickable-row").click(function() {
46 41 document.location = $(this).data("href");
47 });
42 });
48 43
49 44 </script>
50 45 {% endblock %} No newline at end of file
@@ -1,47 +1,43
1 1 {% extends "base.html" %}
2 2 {% load bootstrap3 %}
3 3 {% load static %}
4 4 {% load main_tags %}
5 5
6 6 {% block dev-active %}active{% endblock %}
7 7
8 8 {% block content-title %}{{title}}{% endblock %}
9 9 {% block content-suptitle %}{{suptitle}}{% endblock %}
10 10
11 11 {% block content %}
12 12 <table class="table table-hover">
13 13 <tr>
14 14 <th>#</th>
15 15 {% for key in device_keys %}
16 16 <th>{{ key|title }}</th>
17 17 {% endfor%}
18 18 </tr>
19 19 {% for device in devices %}
20 20 <tr class="clickable-row" data-href="{% url 'url_device' device.id %}">
21 21 <td>{{ forloop.counter }}</td>
22 22 {% for key in device_keys %}
23 23 <td>{{ device|attr:key }}</td>
24 24 {% endfor %}
25 25 </tr>
26 26 {% endfor %}
27 27 </table>
28 <button class="btn btn-primary pull-right" id="bt_add">{{button}}</button>
28
29 29 {% endblock %}
30 30
31 31 {% block sidebar%}
32 32 {% include "sidebar_devices.html" %}
33 33 {% endblock %}
34 34
35 35 {% block extra-js%}
36 36 <script type="text/javascript">
37
38 $("#bt_add").click(function() {
39 document.location = "{% url 'url_add_device' %}";
40 });
41 37
42 38 $(".clickable-row").click(function() {
43 39 document.location = $(this).data("href");
44 });
40 });
45 41
46 42 </script>
47 43 {% endblock %} No newline at end of file
@@ -1,80 +1,80
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 9 {% block exp-active %}active{% endblock %}
10 10
11 11 {% block content-title %}{{title}}{% endblock %}
12 12 {% block content-suptitle %}{{suptitle}}{% endblock %}
13 13
14 14 {% block content %}
15 15 <table class="table table-bordered">
16 16 {% for key in experiment_keys %}
17 17 <tr><th>{{key|title}}</th><td>{{experiment|attr:key}}</td></tr>
18 18 {% endfor %}
19 19 </table>
20 20 <button class="btn btn-primary pull-right" style="margin-left: 10px" id="bt_export">Export</button>
21 21 <button class="btn btn-primary pull-right" style="margin-left: 10px" id="bt_edit">Edit</button>
22 22 <br></br>
23 23 <br></br>
24 24
25 25 <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
26 26
27 27 <div class="panel panel-default">
28 28 <div class="panel-heading" role="tab" id="headingTwo">
29 29 <h4 class="panel-title">
30 30 <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseThree">
31 31 Device Configurations
32 32 </a>
33 33 </h4>
34 34 </div>
35 35 <div id="collapseTwo" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingTwo">
36 36 <div class="panel-body">
37 37 <table class="table table-hover">
38 38 <tr>
39 39 <th>#</th>
40 40 {% for key in configuration_labels %}
41 41 <th>{{ key|title }}</th>
42 42 {% endfor%}
43 43 </tr>
44 44 {% for item in configurations %}
45 45 <tr class="clickable-row" data-href="{{item.get_absolute_url}}">
46 46 <td>{{ forloop.counter }}</td>
47 47 {% for key in configuration_keys %}
48 48 <td>{{ item|value:key }}</td>
49 49 {% endfor %}
50 50 </tr>
51 51 {% endfor %}
52 52 </table>
53 53 <button class="btn btn-primary pull-right" id="bt_add_conf">{{button}}</button>
54 54 </div>
55 55 </div>
56 56 </div>
57 57 </div>
58 58 {% endblock %}
59 59
60 60 {% block sidebar%}
61 61 {% include "sidebar_devices.html" %}
62 62 {% endblock %}
63 63
64 64 {% block extra-js%}
65 65 <script type="text/javascript">
66 66
67 67 $(".clickable-row").click(function() {
68 68 document.location = $(this).data("href");
69 69 });
70 70
71 71 $("#bt_edit").click(function() {
72 72 document.location = "{% url 'url_edit_experiment' experiment.id%}";
73 73 });
74 74
75 75 $("#bt_add_conf").click(function() {
76 document.location = "{% url 'url_add_dev_conf' experiment.id%}";
76 document.location = "{% url 'url_add_dev_conf' experiment.id %}";
77 77 });
78 78
79 79 </script>
80 80 {% endblock %} No newline at end of file
@@ -1,38 +1,93
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 9 {% block exp-active %}active{% endblock %}
10 10
11 11 {% block content-title %}{{title}}{% endblock %}
12 12 {% block content-suptitle %}{{suptitle}}{% endblock %}
13 13
14 14 {% block content %}
15 15 <form class="form" method="post" action="">
16 16 {% csrf_token %}
17 17 {% bootstrap_form form layout='horizontal' size='medium' %}
18 18 <div style="clear: both;"></div>
19 19 <br>
20 <button type="submit" class="btn btn-primary pull-right">{{button}}</button>
20 {% if configurations %}
21 <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
22 <div class="panel panel-default">
23 <div class="panel-heading" role="tab" id="headingTwo">
24 <h4 class="panel-title">
25 <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseThree">
26 Device Configurations
27 </a>
28 </h4>
29 </div>
30 <div id="collapseTwo" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingTwo">
31 <div class="panel-body">
32 <table class="table table-hover">
33 <tr>
34 <th>#</th>
35 {% for key in configuration_keys %}
36 <th>{{ key|title }}</th>
37 {% endfor%}
38 </tr>
39 {% for item in configurations %}
40 <tr class="clickable-row" data-href="{{item.get_absolute_url}}">
41 <td>{{ forloop.counter }}</td>
42 {% for key in configuration_keys %}
43 <td>{{ item|value:key }}</td>
44 {% endfor %}
45 </tr>
46 {% endfor %}
47 </table>
48 </div>
49 </div>
50 </div>
51 </div>
52 {% endif %}
53
54 {% if button %}
55 <br>
56 <button type="submit" class="btn btn-primary pull-right">{{button}}</button>
57 {% endif %}
21 58 </form>
22 59 {% endblock %}
23 60
24 61 {% block sidebar%}
25 62 {% include "sidebar_devices.html" %}
26 63 {% endblock %}
27 64
28 65 {% block extra-js%}
29 66 <script src="{% static 'js/moment.min.js' %}"></script>
30 67 <script src="{% static 'js/bootstrap-datetimepicker.min.js' %}"></script>
31 68 <script type="text/javascript">
69
32 70 $('.input-group.time').datetimepicker({
33 71 format: 'HH:mm:ss',
34 72 pickDate: false,
35 73 pickSeconds: true
36 74 });
75
76 $('#id_create_from').change(function() {
77 var url = "{% url 'url_add_experiment' %}";
78 if ($(this).val()=="2"){
79 document.location = url+"?template=0";
80 }else if ($(this).val()=="1"){
81 document.location = url+"?blank=0";
82 }else{
83 document.location = url;
84 }
85 });
86
87 $('#id_choose_template').change(function() {
88 var url = "{% url 'url_add_experiment' %}";
89 document.location = url+"?template="+$(this).val();
90 });
91
37 92 </script>
38 93 {% endblock %} No newline at end of file
@@ -1,50 +1,45
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 9 {% block exp-active %}active{% endblock %}
10 10
11 11 {% block content-title %}{{title}}{% endblock %}
12 12 {% block content-suptitle %}{{suptitle}}{% endblock %}
13 13
14 14 {% block content %}
15 15 <table class="table table-hover">
16 16 <tr>
17 17 <th>#</th>
18 18 {% for key in experiment_keys %}
19 19 <th>{{ key|title }}</th>
20 20 {% endfor%}
21 21 </tr>
22 22 {% for experiment in experiments %}
23 23 <tr class="clickable-row" data-href="{% url 'url_experiment' experiment.id %}">
24 24 <td>{{ forloop.counter }}</td>
25 25 {% for key in experiment_keys %}
26 26 <td>{{ experiment|attr:key }}</td>
27 27 {% endfor %}
28 28 </tr>
29 29 {% endfor %}
30 30 </table>
31 <button class="btn btn-primary pull-right" id="bt_add">{{button}}</button>
32 31 {% endblock %}
33 32
34 33 {% block sidebar%}
35 34 {% include "sidebar_devices.html" %}
36 35 {% endblock %}
37 36
38 37 {% block extra-js%}
39 38 <script type="text/javascript">
40 39
41 40 $(".clickable-row").click(function() {
42 41 document.location = $(this).data("href");
43 42 });
44 43
45 $("#bt_add").click(function() {
46 document.location = "{% url 'url_add_experiment' 0 %}";
47 });
48
49 44 </script>
50 45 {% endblock %} No newline at end of file
@@ -1,103 +1,37
1 {% if campaign %}
2 <div class="panel panel-default">
3 <div class="panel-heading">
4 <h4>Campaign</h4>
5 </div>
6 <div class="list-group">
7 <a href="{% url 'url_campaign' campaign.id %}" class="list-group-item active" >{{ campaign.name }}</a>
8 </div>
9 </div>
10
11 {% if experiments %}
12 <div class="panel panel-default">
13 <div class="panel-heading">
14 <h4>Experiments</h4>
15 </div>
16 <div class="list-group">
17 {% for item in experiments %}
18 <a href="{% url 'url_experiment' item.id %}" class="list-group-item {{item.active}}">{{item.name}}</a>
19 {% endfor %}
20 </div>
21 </div>
22 {% endif %}
23 {% endif %}
24
25 {% if experiment %}
26 <div class="panel panel-default">
27 <div class="panel-heading">
28 <h4>Campaign</h4>
29 </div>
30 <div class="list-group">
31 <a href="{% url 'url_campaign' experiment.campaign.id %}" class="list-group-item active" >{{ experiment.campaign.name }}</a>
32 </div>
33 </div>
34
35 {% if experiments %}
36 <div class="panel panel-default">
37 <div class="panel-heading">
38 <h4>Experiments</h4>
39 </div>
40 <div class="list-group">
41 {% for item in experiments %}
42 <a href="{% url 'url_experiment' item.id %}" class="list-group-item {%if item.id == experiment.id%}active{%endif%}">{{item.name}}</a>
43 {% endfor %}
44 </div>
45 </div>
46 {% endif %}
47
48 {% if configurations %}
49 <div class="panel panel-default">
50 <div class="panel-heading">
51 <h4>Device Configurations</h4>
52 </div>
53 <div class="list-group">
54 {% for item in configurations %}
55 <a href="{{item.get_absolute_url}}" class="list-group-item {{item.active}}">{{item.device.name}}</a>
56 {% endfor %}
57 </div>
58 </div>
59 {% endif %}
60
61 {% endif %}
62
63 {% if dev_conf %}
64 1
65 2 {% if campaign %}
66 3 <div class="panel panel-default">
67 4 <div class="panel-heading">
68 5 <h4>Campaign</h4>
69 6 </div>
70 7 <div class="list-group">
71 <a href="{% url 'url_campaign' dev_conf.experiment.campaign.id %}" class="list-group-item active" >{{ dev_conf.experiment.campaign.name }}</a>
8 <a href="{% url 'url_campaign' campaign.id %}" class="list-group-item active" >{{ campaign.name }}</a>
72 9 </div>
73 10 </div>
74 11 {% endif %}
75 12
76 {% if experiments %}
13 {% if experiment %}
77 14 <div class="panel panel-default">
78 15 <div class="panel-heading">
79 16 <h4>Experiments</h4>
80 17 </div>
81 18 <div class="list-group">
82 {% for item in experiments %}
83 <a href="{% url 'url_experiment' item.id %}" class="list-group-item {%if item.id == dev_conf.experiment.id%}active{%endif%}">{{item.name}}</a>
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>
84 21 {% endfor %}
85 22 </div>
86 23 </div>
87 24 {% endif %}
88 25
89 {% if configurations %}
26 {% if dev_conf %}
90 27 <div class="panel panel-default">
91 28 <div class="panel-heading">
92 29 <h4>Device Configurations</h4>
93 30 </div>
94 31 <div class="list-group">
95 {% for item in configurations %}
32 {% for item in side_configurations %}
96 33 <a href="{{item.get_absolute_url}}" class="list-group-item {%if item.id == dev_conf.id%}active{%endif%}">{{item.device.name}}</a>
97 34 {% endfor %}
98 35 </div>
99 36 </div>
100 37 {% endif %}
101
102
103 {% endif %}
@@ -1,37 +1,36
1 1 from django.template.defaulttags import register
2 2 from django.utils.safestring import mark_safe
3 3
4 4 @register.filter
5 5 def attr(instance, key):
6 6
7 7 display_key = "get_" + key + "_display"
8 8
9 9 if hasattr(instance, display_key):
10 10 return getattr(instance, display_key)()
11 11
12 12 if hasattr(instance, key):
13 13 return getattr(instance, key)
14 14
15 15 return instance.get(key)
16 16
17 17 @register.filter
18 18 def title(s):
19 19 return s.replace('_', ' ').title()
20 20
21 21 @register.filter
22 22 def value(instance, key):
23 23
24 24 item = instance
25 25 for my_key in key.split("__"):
26 26 item = attr(item, my_key)
27 27
28 print item
29 28 return item
30 29
31 30 @register.simple_tag
32 31 def get_verbose_field_name(instance, field_name):
33 32 """
34 33 Returns verbose_name for a field.
35 34 """
36 35
37 36 return mark_safe(instance._meta.get_field(field_name).verbose_name) No newline at end of file
@@ -1,50 +1,50
1 1 from django.conf.urls import url
2 2
3 3 urlpatterns = (
4 4 url(r'^location/new/$', 'apps.main.views.location_new', name='url_add_location'),
5 5 url(r'^location/$', 'apps.main.views.locations', name='url_locations'),
6 6 url(r'^location/(?P<id_loc>-?\d+)/$', 'apps.main.views.location', name='url_location'),
7 7 url(r'^location/(?P<id_loc>-?\d+)/edit/$', 'apps.main.views.location_edit', name='url_edit_location'),
8 8 url(r'^location/(?P<id_loc>-?\d+)/delete/$', 'apps.main.views.location_delete', name='url_delete_location'),
9 9
10 10 url(r'^device/new/$', 'apps.main.views.device_new', name='url_add_device'),
11 11 url(r'^device/$', 'apps.main.views.devices', name='url_devices'),
12 12 url(r'^device/(?P<id_dev>-?\d+)/$', 'apps.main.views.device', name='url_device'),
13 13 url(r'^device/(?P<id_dev>-?\d+)/edit/$', 'apps.main.views.device_edit', name='url_edit_device'),
14 14 url(r'^device/(?P<id_dev>-?\d+)/delete/$', 'apps.main.views.device_delete', name='url_delete_device'),
15 15
16 16 url(r'^campaign/new/$', 'apps.main.views.campaign_new', name='url_add_campaign'),
17 17 url(r'^campaign/$', 'apps.main.views.campaigns', name='url_campaigns'),
18 18 url(r'^campaign/(?P<id_camp>-?\d+)/$', 'apps.main.views.campaign', name='url_campaign'),
19 19 url(r'^campaign/(?P<id_camp>-?\d+)/edit/$', 'apps.main.views.campaign_edit', name='url_edit_campaign'),
20 20 url(r'^campaign/(?P<id_camp>-?\d+)/delete/$', 'apps.main.views.campaign_delete', name='url_delete_campaign'),
21 21
22 url(r'^campaign/(?P<id_camp>-?\d+)/new_experiment/$', 'apps.main.views.experiment_new', name='url_add_experiment'),
22 url(r'^experiment/new/$', 'apps.main.views.experiment_new', name='url_add_experiment'),
23 23 url(r'^experiment/$', 'apps.main.views.experiments', name='url_experiments'),
24 24 url(r'^experiment/(?P<id_exp>-?\d+)/$', 'apps.main.views.experiment', name='url_experiment'),
25 25 url(r'^experiment/(?P<id_exp>-?\d+)/edit/$', 'apps.main.views.experiment_edit', name='url_edit_experiment'),
26 26 url(r'^experiment/(?P<id_exp>-?\d+)/delete/$', 'apps.main.views.experiment_delete', name='url_delete_experiment'),
27 27
28 28 url(r'^experiment/(?P<id_exp>-?\d+)/new_dev_conf/$', 'apps.main.views.dev_conf_new', name='url_add_dev_conf'),
29 29 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'),
30 30 url(r'^dev_conf/$', 'apps.main.views.dev_confs', name='url_dev_confs'),
31 31 url(r'^dev_conf/(?P<id_conf>-?\d+)/$', 'apps.main.views.dev_conf', name='url_dev_conf'),
32 32 url(r'^dev_conf/(?P<id_conf>-?\d+)/edit/$', 'apps.main.views.dev_conf_edit', name='url_edit_dev_conf'),
33 33 url(r'^dev_conf/(?P<id_conf>-?\d+)/delete/$', 'apps.main.views.dev_conf_delete', name='url_delete_dev_conf'),
34 34
35 35 url(r'^dev_conf/(?P<id_conf>-?\d+)/write/$', 'apps.main.views.dev_conf_write', name='url_write_dev_conf'),
36 36 url(r'^dev_conf/(?P<id_conf>-?\d+)/read/$', 'apps.main.views.dev_conf_read', name='url_read_dev_conf'),
37 37 url(r'^dev_conf/(?P<id_conf>-?\d+)/import/$', 'apps.main.views.dev_conf_import', name='url_import_dev_conf'),
38 38 url(r'^dev_conf/(?P<id_conf>-?\d+)/export/$', 'apps.main.views.dev_conf_export', name='url_export_dev_conf'),
39 39 url(r'^dev_conf/(?P<id_conf>-?\d+)/start/$', 'apps.main.views.dev_conf_start', name='url_start_dev_conf'),
40 40 url(r'^dev_conf/(?P<id_conf>-?\d+)/stop/$', 'apps.main.views.dev_conf_stop', name='url_stop_dev_conf'),
41 41 url(r'^dev_conf/(?P<id_conf>-?\d+)/status/$', 'apps.main.views.dev_conf_status', name='url_status_dev_conf'),
42 42
43 43 url(r'^operation/$', 'apps.main.views.operation', name='url_operation'),
44 44 url(r'^operation/(?P<id_camp>-?\d+)/$', 'apps.main.views.operation', name='url_operation'),
45 45 url(r'^operation/search/$', 'apps.main.views.operation_search', name='url_operation_search'),
46 46 url(r'^operation/search/(?P<id_camp>-?\d+)/$', 'apps.main.views.operation_search', name='url_operation_search'),
47 47 url(r'^operation/(?P<id_camp>-?\d+)/radar/(?P<id_radar>-?\d+)/play/$', 'apps.main.views.radar_play', name='url_radar_play'),
48 48 url(r'^operation/(?P<id_camp>-?\d+)/radar/(?P<id_radar>-?\d+)/stop/$', 'apps.main.views.radar_stop', name='url_radar_stop'),
49 49
50 50 )
@@ -1,906 +1,961
1 1 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
2 2 from django.http import HttpResponseRedirect
3 3 from django.core.urlresolvers import reverse
4 4 from django.contrib import messages
5 5
6 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm
6 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
7 7 from .forms import OperationSearchForm
8 8 from apps.cgs.forms import CGSConfigurationForm
9 9 from apps.jars.forms import JARSConfigurationForm
10 10 from apps.usrp.forms import USRPConfigurationForm
11 11 from apps.abs.forms import ABSConfigurationForm
12 12 from apps.rc.forms import RCConfigurationForm
13 13 from apps.dds.forms import DDSConfigurationForm
14 14
15 15 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment
16 16 from apps.cgs.models import CGSConfiguration
17 17 from apps.jars.models import JARSConfiguration
18 18 from apps.usrp.models import USRPConfiguration
19 19 from apps.abs.models import ABSConfiguration
20 20 from apps.rc.models import RCConfiguration
21 21 from apps.dds.models import DDSConfiguration
22 22
23 23 # Create your views here.
24 24
25 25 CONF_FORMS = {
26 26 'rc': RCConfigurationForm,
27 27 'dds': DDSConfigurationForm,
28 28 'jars': JARSConfigurationForm,
29 29 'cgs': CGSConfigurationForm,
30 30 'abs': ABSConfigurationForm,
31 31 'usrp': USRPConfigurationForm,
32 32 }
33 33
34 34 CONF_MODELS = {
35 35 'rc': RCConfiguration,
36 36 'dds': DDSConfiguration,
37 37 'jars': JARSConfiguration,
38 38 'cgs': CGSConfiguration,
39 39 'abs': ABSConfiguration,
40 40 'usrp': USRPConfiguration,
41 41 }
42 42
43 43 def index(request):
44 44 kwargs = {}
45 45
46 46 return render(request, 'index.html', kwargs)
47 47
48 48 def locations(request):
49 49
50 50 locations = Location.objects.all().order_by('name')
51 51
52 52 keys = ['id', 'name', 'description']
53 53
54 54 kwargs = {}
55 55 kwargs['location_keys'] = keys[1:]
56 56 kwargs['locations'] = locations
57 57 kwargs['title'] = 'Location'
58 58 kwargs['suptitle'] = 'List'
59 59 kwargs['button'] = 'New Location'
60 60
61 61 return render(request, 'locations.html', kwargs)
62 62
63 63 def location(request, id_loc):
64 64
65 65 location = get_object_or_404(Location, pk=id_loc)
66 66
67 67 kwargs = {}
68 68 kwargs['location'] = location
69 69 kwargs['location_keys'] = ['name', 'description']
70 70
71 71 kwargs['title'] = 'Location'
72 72 kwargs['suptitle'] = 'Details'
73 73
74 74 return render(request, 'location.html', kwargs)
75 75
76 76 #def location_play(request, id_camp, id_loc):
77 77
78 78 # campaign = get_object_or_404(Campaign, pk=id_camp)
79 79 # print campaign
80 80 # location = get_object_or_404(Location, pk=id_loc)
81 81 # experiments = Experiment.objects.filter(location__pk=location.id).filter(campaign__pk=campaign.id)
82 82 # locations = Location.objects.filter(pk=id_loc)
83 83
84 84 # if request.method=='GET':
85 85 # form = OperationForm(initial={'campaign': campaign.id})
86 86
87 87 # kwargs = {}
88 88 #---Campaign
89 89 # kwargs['campaign'] = campaign
90 90 # kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
91 91 #---Experiment
92 92 # keys = ['id', 'name', 'start_time', 'end_time']
93 93 # kwargs['experiment_keys'] = keys[1:]
94 94 # kwargs['experiments'] = experiments
95 95 #---Radar
96 96 # kwargs['location'] = location
97 97 #---Else
98 98 # kwargs['title'] = 'Campaign'
99 99 # kwargs['suptitle'] = campaign.name
100 100 # kwargs['form'] = form
101 101 # kwargs['button'] = 'Search'
102 102
103 103 # return render(request, 'operation_play.html', kwargs)
104 104
105 105 def location_new(request):
106 106
107 107 if request.method == 'GET':
108 108 form = LocationForm()
109 109
110 110 if request.method == 'POST':
111 111 form = LocationForm(request.POST)
112 112
113 113 if form.is_valid():
114 114 form.save()
115 115 return redirect('url_locations')
116 116
117 117 kwargs = {}
118 118 kwargs['form'] = form
119 119 kwargs['title'] = 'Location'
120 120 kwargs['suptitle'] = 'New'
121 121 kwargs['button'] = 'Create'
122 122
123 123 return render(request, 'location_edit.html', kwargs)
124 124
125 125 def location_edit(request, id_loc):
126 126
127 127 location = get_object_or_404(Location, pk=id_loc)
128 128
129 129 if request.method=='GET':
130 130 form = LocationForm(instance=location)
131 131
132 132 if request.method=='POST':
133 133 form = LocationForm(request.POST, instance=location)
134 134
135 135 if form.is_valid():
136 136 form.save()
137 137 return redirect('url_locations')
138 138
139 139 kwargs = {}
140 140 kwargs['form'] = form
141 141 kwargs['title'] = 'Location'
142 142 kwargs['suptitle'] = 'Edit'
143 143 kwargs['button'] = 'Update'
144 144
145 145 return render(request, 'location_edit.html', kwargs)
146 146
147 147 def location_delete(request, id_loc):
148 148
149 149 location = get_object_or_404(Location, pk=id_loc)
150 150
151 151 if request.method=='POST':
152 152
153 153 if request.user.is_staff:
154 154 location.delete()
155 155 return redirect('url_locations')
156 156
157 157 return HttpResponse("Not enough permission to delete this object")
158 158
159 159 kwargs = {'object':location, 'loc_active':'active',
160 160 'url_cancel':'url_location', 'id_item':id_loc}
161 161
162 162 return render(request, 'item_delete.html', kwargs)
163 163
164 164 def devices(request):
165 165
166 166 devices = Device.objects.all().order_by('device_type__name')
167 167
168 168 # keys = ['id', 'device_type__name', 'name', 'ip_address']
169 169 keys = ['id', 'name', 'ip_address', 'port_address', 'device_type']
170 170
171 171 kwargs = {}
172 172 kwargs['device_keys'] = keys[1:]
173 173 kwargs['devices'] = devices#.values(*keys)
174 174 kwargs['title'] = 'Device'
175 175 kwargs['suptitle'] = 'List'
176 176 kwargs['button'] = 'New Device'
177 177
178 178 return render(request, 'devices.html', kwargs)
179 179
180 180 def device(request, id_dev):
181 181
182 182 device = get_object_or_404(Device, pk=id_dev)
183 183
184 184 kwargs = {}
185 185 kwargs['device'] = device
186 186 kwargs['device_keys'] = ['device_type', 'name', 'ip_address', 'port_address', 'description']
187 187
188 188 kwargs['title'] = 'Device'
189 189 kwargs['suptitle'] = 'Details'
190 190
191 191 return render(request, 'device.html', kwargs)
192 192
193 193 def device_new(request):
194 194
195 195 if request.method == 'GET':
196 196 form = DeviceForm()
197 197
198 198 if request.method == 'POST':
199 199 form = DeviceForm(request.POST)
200 200
201 201 if form.is_valid():
202 202 form.save()
203 203 return redirect('url_devices')
204 204
205 205 kwargs = {}
206 206 kwargs['form'] = form
207 207 kwargs['title'] = 'Device'
208 208 kwargs['suptitle'] = 'New'
209 209 kwargs['button'] = 'Create'
210 210
211 211 return render(request, 'device_edit.html', kwargs)
212 212
213 213 def device_edit(request, id_dev):
214 214
215 215 device = get_object_or_404(Device, pk=id_dev)
216 216
217 217 if request.method=='GET':
218 218 form = DeviceForm(instance=device)
219 219
220 220 if request.method=='POST':
221 221 form = DeviceForm(request.POST, instance=device)
222 222
223 223 if form.is_valid():
224 224 form.save()
225 225 return redirect('url_devices')
226 226
227 227 kwargs = {}
228 228 kwargs['form'] = form
229 229 kwargs['title'] = 'Device'
230 230 kwargs['suptitle'] = 'Edit'
231 231 kwargs['button'] = 'Update'
232 232
233 233 return render(request, 'device_edit.html', kwargs)
234 234
235 235 def device_delete(request, id_dev):
236 236
237 237 device = get_object_or_404(Device, pk=id_dev)
238 238
239 239 if request.method=='POST':
240 240
241 241 if request.user.is_staff:
242 242 device.delete()
243 243 return redirect('url_devices')
244 244
245 245 return HttpResponse("Not enough permission to delete this object")
246 246
247 247 kwargs = {'object':device, 'dev_active':'active',
248 248 'url_cancel':'url_device', 'id_item':id_dev}
249 249
250 250 return render(request, 'item_delete.html', kwargs)
251 251
252 252 def campaigns(request):
253 253
254 254 campaigns = Campaign.objects.all().order_by('start_date')
255 255
256 256 keys = ['id', 'name', 'start_date', 'end_date']
257 257
258 258 kwargs = {}
259 259 kwargs['campaign_keys'] = keys[1:]
260 260 kwargs['campaigns'] = campaigns#.values(*keys)
261 261 kwargs['title'] = 'Campaign'
262 262 kwargs['suptitle'] = 'List'
263 263 kwargs['button'] = 'New Campaign'
264 264
265 265 return render(request, 'campaigns.html', kwargs)
266 266
267 267 def campaign(request, id_camp):
268 268
269 269 campaign = get_object_or_404(Campaign, pk=id_camp)
270 270 experiments = Experiment.objects.filter(campaign=campaign)
271 271
272 272 form = CampaignForm(instance=campaign)
273 273
274 274 kwargs = {}
275 275 kwargs['campaign'] = campaign
276 276 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
277 277
278 278 keys = ['id', 'name', 'start_time', 'end_time']
279 279
280 280 kwargs['experiment_keys'] = keys[1:]
281 281 kwargs['experiments'] = experiments.values(*keys)
282 282
283 283 kwargs['title'] = 'Campaign'
284 284 kwargs['suptitle'] = 'Details'
285 285
286 286 kwargs['form'] = form
287 287 kwargs['button'] = 'Add Experiment'
288 288
289 289 return render(request, 'campaign.html', kwargs)
290 290
291 291 def campaign_new(request):
292 292
293 kwargs = {}
294
293 295 if request.method == 'GET':
294 form = CampaignForm()
296
297 if 'template' in request.GET:
298 if request.GET['template']=='0':
299 form = NewForm(initial={'create_from':2},
300 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
301 else:
302 kwargs['button'] = 'Create'
303 kwargs['experiments'] = Configuration.objects.filter(experiment=request.GET['template'])
304 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
305 form = CampaignForm(instance=Campaign.objects.get(pk=request.GET['template']),
306 initial={'template':False})
307 elif 'blank' in request.GET:
308 kwargs['button'] = 'Create'
309 form = CampaignForm()
310 else:
311 form = NewForm()
295 312
296 313 if request.method == 'POST':
297 form = CampaignForm(request.POST)
314 kwargs['button'] = 'Create'
315 post = request.POST.copy()
316 experiments = []
317
318 for id_exp in post.getlist('experiments'):
319 exp = Experiment.objects.get(pk=id_exp)
320 new_exp = exp.clone(template=False)
321 experiments.append(new_exp)
322
323 post.setlist('experiments', [])
324
325 form = CampaignForm(post)
298 326
299 327 if form.is_valid():
300 328 campaign = form.save()
329 for exp in experiments:
330 campaign.experiments.add(exp)
331 campaign.save()
301 332 return redirect('url_campaign', id_camp=campaign.id)
302 333
303 kwargs = {}
304 334 kwargs['form'] = form
305 335 kwargs['title'] = 'Campaign'
306 336 kwargs['suptitle'] = 'New'
307 kwargs['button'] = 'Create'
308 337
309 338 return render(request, 'campaign_edit.html', kwargs)
310 339
311 340 def campaign_edit(request, id_camp):
312 341
313 342 campaign = get_object_or_404(Campaign, pk=id_camp)
314 343
315 344 if request.method=='GET':
316 345 form = CampaignForm(instance=campaign)
317 346
318 347 if request.method=='POST':
319 348 form = CampaignForm(request.POST, instance=campaign)
320 349
321 350 if form.is_valid():
322 351 form.save()
323 352 return redirect('url_campaign', id_camp=id_camp)
324 353
325 354 kwargs = {}
326 355 kwargs['form'] = form
327 356 kwargs['title'] = 'Campaign'
328 357 kwargs['suptitle'] = 'Edit'
329 358 kwargs['button'] = 'Update'
330 359
331 360 return render(request, 'campaign_edit.html', kwargs)
332 361
333 362 def campaign_delete(request, id_camp):
334 363
335 364 campaign = get_object_or_404(Campaign, pk=id_camp)
336 365
337 366 if request.method=='POST':
338 367 if request.user.is_staff:
368
369 for exp in campaign.experiments.all():
370 for conf in Configuration.objects.filter(experiment=exp):
371 conf.delete()
372 exp.delete()
339 373 campaign.delete()
374
340 375 return redirect('url_campaigns')
341 376
342 377 return HttpResponse("Not enough permission to delete this object")
343 378
344 379 kwargs = {'object':campaign, 'camp_active':'active',
345 380 'url_cancel':'url_campaign', 'id_item':id_camp}
346 381
347 382 return render(request, 'item_delete.html', kwargs)
348 383
349 384 def experiments(request):
350 385
351 experiment_list = Experiment.objects.all().order_by('campaign')
386 experiment_list = Experiment.objects.all()
352 387
353 keys = ['id', 'name', 'start_time', 'end_time', 'campaign']
388 keys = ['id', 'name', 'start_time', 'end_time']
354 389
355 390 kwargs = {}
356 391
357 392 kwargs['experiment_keys'] = keys[1:]
358 kwargs['experiments'] = experiment_list#.values(*keys)
393 kwargs['experiments'] = experiment_list
359 394
360 395 kwargs['title'] = 'Experiment'
361 396 kwargs['suptitle'] = 'List'
362 397 kwargs['button'] = 'New Experiment'
363 398
364 399 return render(request, 'experiments.html', kwargs)
365 400
366 401 def experiment(request, id_exp):
367 402
368 403 experiment = get_object_or_404(Experiment, pk=id_exp)
369 404
370 experiments = Experiment.objects.filter(campaign=experiment.campaign)
371 405 configurations = Configuration.objects.filter(experiment=experiment, type=0)
372 406
373 407 kwargs = {}
374 408
375 exp_keys = ['id', 'campaign', 'location', 'name', 'start_time', 'end_time']
409 exp_keys = ['id', 'location', 'name', 'start_time', 'end_time']
376 410 conf_keys = ['id', 'device__name', 'device__device_type', 'device__ip_address', 'device__port_address']
377 411
378 412 conf_labels = ['id', 'device__name', 'device_type', 'ip_address', 'port_address']
379 413
380 414 kwargs['experiment_keys'] = exp_keys[1:]
381 415 kwargs['experiment'] = experiment
382 416
383 kwargs['experiments'] = experiments.values(*exp_keys)
384
385 417 kwargs['configuration_labels'] = conf_labels[1:]
386 418 kwargs['configuration_keys'] = conf_keys[1:]
387 419 kwargs['configurations'] = configurations #.values(*conf_keys)
388 420
389 421 kwargs['title'] = 'Experiment'
390 422 kwargs['suptitle'] = 'Details'
391 423
392 424 kwargs['button'] = 'Add Configuration'
393 425
426 ###### SIDEBAR ######
427 kwargs.update(sidebar(experiment=experiment))
428
394 429 return render(request, 'experiment.html', kwargs)
395 430
431
396 432 def experiment_new(request, id_camp=None):
397 433
434 kwargs = {}
435
398 436 if request.method == 'GET':
399 form = ExperimentForm(initial={'campaign':id_camp})
437 if 'template' in request.GET:
438 if request.GET['template']=='0':
439 form = NewForm(initial={'create_from':2},
440 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
441 else:
442 kwargs['button'] = 'Create'
443 kwargs['configurations'] = Configuration.objects.filter(experiment=request.GET['template'])
444 kwargs['configuration_keys'] = ['name', 'device__name', 'device__ip_address', 'device__port_address']
445 form = ExperimentForm(instance=Experiment.objects.get(pk=request.GET['template']),
446 initial={'template':False})
447 elif 'blank' in request.GET:
448 kwargs['button'] = 'Create'
449 form = ExperimentForm()
450 else:
451 form = NewForm()
400 452
401 453 if request.method == 'POST':
402 form = ExperimentForm(request.POST, initial={'campaign':id_camp})
403
454 form = ExperimentForm(request.POST)
404 455 if form.is_valid():
405 456 experiment = form.save()
457
458 if 'template' in request.GET:
459 configurations = Configuration.objects.filter(experiment=request.GET['template'], type=0)
460 for conf in configurations:
461 conf.clone(experiment=experiment, template=False)
462
406 463 return redirect('url_experiment', id_exp=experiment.id)
407
408 kwargs = {}
464
409 465 kwargs['form'] = form
410 466 kwargs['title'] = 'Experiment'
411 467 kwargs['suptitle'] = 'New'
412 kwargs['button'] = 'Create'
413 468
414 469 return render(request, 'experiment_edit.html', kwargs)
415 470
416 471 def experiment_edit(request, id_exp):
417 472
418 473 experiment = get_object_or_404(Experiment, pk=id_exp)
419 474
420 475 if request.method == 'GET':
421 476 form = ExperimentForm(instance=experiment)
422 477
423 478 if request.method=='POST':
424 479 form = ExperimentForm(request.POST, instance=experiment)
425 480
426 481 if form.is_valid():
427 482 experiment = form.save()
428 483 return redirect('url_experiment', id_exp=experiment.id)
429 484
430 485 kwargs = {}
431 486 kwargs['form'] = form
432 487 kwargs['title'] = 'Experiment'
433 488 kwargs['suptitle'] = 'Edit'
434 489 kwargs['button'] = 'Update'
435 490
436 491 return render(request, 'experiment_edit.html', kwargs)
437 492
438 493 def experiment_delete(request, id_exp):
439 494
440 495 experiment = get_object_or_404(Experiment, pk=id_exp)
441 496
442 497 if request.method=='POST':
443 498 if request.user.is_staff:
444 id_camp = experiment.campaign.id
445 499 experiment.delete()
446 return redirect('url_campaign', id_camp=id_camp)
500 return redirect('url_experiments')
447 501
448 502 return HttpResponse("Not enough permission to delete this object")
449 503
450 504 kwargs = {'object':experiment, 'exp_active':'active',
451 505 'url_cancel':'url_experiment', 'id_item':id_exp}
452 506
453 507 return render(request, 'item_delete.html', kwargs)
454 508
455 509 def dev_confs(request):
456 510
457 511 configurations = Configuration.objects.all().order_by('type', 'device__device_type', 'experiment')
458 512
459 513 # keys = ['id', 'device__device_type__name', 'device__name', 'experiment__campaign__name', 'experiment__name']
460 514
461 515 keys = ['id', 'device', 'experiment', 'type', 'programmed_date']
462 516
463 517 kwargs = {}
464 518
465 519 kwargs['configuration_keys'] = keys[1:]
466 520 kwargs['configurations'] = configurations#.values(*keys)
467 521
468 522 kwargs['title'] = 'Configuration'
469 523 kwargs['suptitle'] = 'List'
470 524 kwargs['button'] = 'New Configuration'
471 525
472 526 return render(request, 'dev_confs.html', kwargs)
473 527
474 528 def dev_conf(request, id_conf):
475 529
476 530 conf = get_object_or_404(Configuration, pk=id_conf)
477 531
478 532 return redirect(conf.get_absolute_url())
479 533
480 534
481 535 def dev_conf_new(request, id_exp=0, id_dev=0):
482 536
483 537 initial = {}
484 538
485 if id_exp==0:
539 if id_exp<>0:
486 540 initial['experiment'] = id_exp
487 541
488 542 if id_dev<>0:
489 543 initial['device'] = id_dev
490 544
491 545 if request.method == 'GET':
492 546 if id_dev==0:
493 547 form = ConfigurationForm(initial=initial)
494 548 else:
495 549 device = Device.objects.get(pk=id_dev)
496 550 DevConfForm = CONF_FORMS[device.device_type.name]
497 551
498 552 form = DevConfForm(initial=initial)
499 553
500 554 if request.method == 'POST':
501 555
502 556 device = Device.objects.get(pk=request.POST['device'])
503 557 DevConfForm = CONF_FORMS[device.device_type.name]
504 558
505 559 form = DevConfForm(request.POST)
506 560
507 561 if form.is_valid():
508 562 dev_conf = form.save()
509 563
510 564 return redirect('url_dev_confs')
511 565
512 566 kwargs = {}
513 567 kwargs['id_exp'] = id_exp
514 568 kwargs['form'] = form
515 569 kwargs['title'] = 'Configuration'
516 570 kwargs['suptitle'] = 'New'
517 571 kwargs['button'] = 'Create'
518 572
519 573 return render(request, 'dev_conf_edit.html', kwargs)
520 574
521 575 def dev_conf_edit(request, id_conf):
522 576
523 577 conf = get_object_or_404(Configuration, pk=id_conf)
524 578
525 579 DevConfModel = CONF_MODELS[conf.device.device_type.name]
526 580 DevConfForm = CONF_FORMS[conf.device.device_type.name]
527 581
528 582 dev_conf = DevConfModel.objects.get(pk=id_conf)
529 583
530 584 if request.method=='GET':
531 585 form = DevConfForm(instance=dev_conf)
532 586
533 587 if request.method=='POST':
534 588 form = DevConfForm(request.POST, instance=dev_conf)
535 589
536 590 if form.is_valid():
537 591 form.save()
538 592 return redirect('url_dev_conf', id_conf=id_conf)
539 593
540 594 kwargs = {}
541 595 kwargs['form'] = form
542 596 kwargs['title'] = 'Device Configuration'
543 597 kwargs['suptitle'] = 'Edit'
544 598 kwargs['button'] = 'Update'
545 599
546 600 ###### SIDEBAR ######
547 kwargs.update(sidebar(conf))
601 kwargs.update(sidebar(conf=conf))
548 602
549 603 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
550 604
551 605 def dev_conf_start(request, id_conf):
552 606
553 607 conf = get_object_or_404(Configuration, pk=id_conf)
554 608
555 609 DevConfModel = CONF_MODELS[conf.device.device_type.name]
556 610
557 611 conf = DevConfModel.objects.get(pk=id_conf)
558 612
559 613 if conf.start_device():
560 614 messages.success(request, conf.message)
561 615 else:
562 616 messages.error(request, conf.message)
563 617
564 618 conf.status_device()
565 619
566 620 return redirect(conf.get_absolute_url())
567 621
568 622 def dev_conf_stop(request, id_conf):
569 623
570 624 conf = get_object_or_404(Configuration, pk=id_conf)
571 625
572 626 DevConfModel = CONF_MODELS[conf.device.device_type.name]
573 627
574 628 conf = DevConfModel.objects.get(pk=id_conf)
575 629
576 630 if conf.stop_device():
577 631 messages.success(request, conf.message)
578 632 else:
579 633 messages.error(request, conf.message)
580 634
581 635 conf.status_device()
582 636
583 637 return redirect(conf.get_absolute_url())
584 638
585 639 def dev_conf_status(request, id_conf):
586 640
587 641 conf = get_object_or_404(Configuration, pk=id_conf)
588 642
589 643 DevConfModel = CONF_MODELS[conf.device.device_type.name]
590 644
591 645 conf = DevConfModel.objects.get(pk=id_conf)
592 646
593 647 if conf.status_device():
594 648 messages.success(request, conf.message)
595 649 else:
596 650 messages.error(request, conf.message)
597 651
598 652 return redirect(conf.get_absolute_url())
599 653
600 654
601 655 def dev_conf_write(request, id_conf):
602 656
603 657 conf = get_object_or_404(Configuration, pk=id_conf)
604 658
605 659 DevConfModel = CONF_MODELS[conf.device.device_type.name]
606 660
607 661 conf = DevConfModel.objects.get(pk=id_conf)
608 662
609 663 answer = conf.write_device()
610 664 conf.status_device()
611 665
612 666 if answer:
613 667 messages.success(request, conf.message)
614 668
615 #Creating a historical configuration
616 conf.pk = None
617 conf.id = None
618 conf.type = 1
619 conf.template = 0
620 conf.save()
669 #Creating a historical configuration
670 conf.clone(type=0, template=False)
621 671
622 672 #Original configuration
623 673 conf = DevConfModel.objects.get(pk=id_conf)
624 674 else:
625 675 messages.error(request, conf.message)
626 676
627 677 return redirect(conf.get_absolute_url())
628 678
629 679 def dev_conf_read(request, id_conf):
630 680
631 681 conf = get_object_or_404(Configuration, pk=id_conf)
632 682
633 683 DevConfModel = CONF_MODELS[conf.device.device_type.name]
634 684 DevConfForm = CONF_FORMS[conf.device.device_type.name]
635 685
636 686 conf = DevConfModel.objects.get(pk=id_conf)
637 687
638 688 if request.method=='GET':
639 689
640 690 parms = conf.read_device()
641 691 conf.status_device()
642 692
643 693 if not parms:
644 694 messages.error(request, conf.message)
645 695 return redirect(conf.get_absolute_url())
646 696
647 697 form = DevConfForm(initial=parms, instance=conf)
648 698
649 699 if request.method=='POST':
650 700 form = DevConfForm(request.POST, instance=conf)
651 701
652 702 if form.is_valid():
653 703 form.save()
654 704 return redirect(conf.get_absolute_url())
655 705
656 706 messages.error(request, "Parameters could not be saved")
657 707
658 708 kwargs = {}
659 709 kwargs['id_dev'] = conf.id
660 710 kwargs['form'] = form
661 711 kwargs['title'] = 'Device Configuration'
662 712 kwargs['suptitle'] = 'Parameters read from device'
663 713 kwargs['button'] = 'Save'
664 714
665 715 ###### SIDEBAR ######
666 kwargs.update(sidebar(conf))
716 kwargs.update(sidebar(conf=conf))
667 717
668 718 return render(request, '%s_conf_edit.html' %conf.device.device_type.name, kwargs)
669 719
670 720 def dev_conf_import(request, id_conf):
671 721
672 722 conf = get_object_or_404(Configuration, pk=id_conf)
673 723
674 724 DevConfModel = CONF_MODELS[conf.device.device_type.name]
675 DevConfForm = CONF_FORMS[conf.device.device_type.name]
676
725 DevConfForm = CONF_FORMS[conf.device.device_type.name]
677 726 conf = DevConfModel.objects.get(pk=id_conf)
678 727
679 728 if request.method == 'GET':
680 729 file_form = UploadFileForm()
681 730
682 731 if request.method == 'POST':
683 732 file_form = UploadFileForm(request.POST, request.FILES)
684 733
685 734 if file_form.is_valid():
686 735
687 736 parms = conf.import_from_file(request.FILES['file'])
688 737
689 738 if parms:
690 739 messages.success(request, "Parameters imported from: '%s'." %request.FILES['file'].name)
691 print parms
692 740 form = DevConfForm(initial=parms, instance=conf)
693 741
694 742 kwargs = {}
695 743 kwargs['id_dev'] = conf.id
696 744 kwargs['form'] = form
697 745 kwargs['title'] = 'Device Configuration'
698 746 kwargs['suptitle'] = 'Parameters imported'
699 747 kwargs['button'] = 'Save'
700 748 kwargs['action'] = conf.get_absolute_url_edit()
701 749 kwargs['previous'] = conf.get_absolute_url()
702 750
703 751 ###### SIDEBAR ######
704 kwargs.update(sidebar(conf))
752 kwargs.update(sidebar(conf=conf))
705 753
706 754 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
707 755
708 756 messages.error(request, "Could not import parameters from file")
709 757
710 758 kwargs = {}
711 759 kwargs['id_dev'] = conf.id
712 760 kwargs['title'] = 'Device Configuration'
713 761 kwargs['form'] = file_form
714 762 kwargs['suptitle'] = 'Importing file'
715 763 kwargs['button'] = 'Import'
716 764
717 kwargs.update(sidebar(conf))
765 kwargs.update(sidebar(conf=conf))
718 766
719 767 return render(request, 'dev_conf_import.html', kwargs)
720 768
721 769 def dev_conf_export(request, id_conf):
722 770
723 771 conf = get_object_or_404(Configuration, pk=id_conf)
724 772
725 773 DevConfModel = CONF_MODELS[conf.device.device_type.name]
726 774
727 775 conf = DevConfModel.objects.get(pk=id_conf)
728 776
729 777 if request.method == 'GET':
730 778 file_form = DownloadFileForm(conf.device.device_type.name)
731 779
732 780 if request.method == 'POST':
733 781 file_form = DownloadFileForm(conf.device.device_type.name, request.POST)
734 782
735 783 if file_form.is_valid():
736 784 fields = conf.export_to_file(format = file_form.cleaned_data['format'])
737 785
738 786 response = HttpResponse(content_type=fields['content_type'])
739 787 response['Content-Disposition'] = 'attachment; filename="%s"' %fields['filename']
740 788 response.write(fields['content'])
741 789
742 790 return response
743 791
744 792 messages.error(request, "Could not export parameters")
745 793
746 794 kwargs = {}
747 795 kwargs['id_dev'] = conf.id
748 796 kwargs['title'] = 'Device Configuration'
749 797 kwargs['form'] = file_form
750 798 kwargs['suptitle'] = 'Exporting file'
751 799 kwargs['button'] = 'Export'
752 800
753 801 return render(request, 'dev_conf_export.html', kwargs)
754 802
755 803 def dev_conf_delete(request, id_conf):
756 804
757 805 conf = get_object_or_404(Configuration, pk=id_conf)
758 806
759 807 if request.method=='POST':
760 808 if request.user.is_staff:
761 809 id_exp = conf.experiment.id
762 810 conf.delete()
763 811 return redirect('url_experiment', id_exp=id_exp)
764 812
765 813 return HttpResponse("Not enough permission to delete this object")
766 814
767 815 kwargs = {'object':conf, 'conf_active':'active',
768 816 'url_cancel':'url_dev_conf', 'id_item':id_conf}
769 817
770 ###### SIDEBAR ######
771 kwargs.update(sidebar(conf))
772
773 818 return render(request, 'item_delete.html', kwargs)
774 819
775 def sidebar(conf):
820
821 def sidebar(**kwargs):
776 822
777 kwargs = {}
823 side_data = {}
824
825 conf = kwargs.get('conf', None)
826 experiment = kwargs.get('experiment', None)
778 827
779 if conf.experiment:
780 experiments = Experiment.objects.filter(campaign=conf.experiment.campaign)
781 configurations = Configuration.objects.filter(experiment=conf.experiment, type=0)
782 exp_keys = ['id', 'campaign', 'name', 'start_time', 'end_time']
783 kwargs['experiment_keys'] = exp_keys[1:]
784 kwargs['experiments'] = experiments.values(*exp_keys)
785 conf_keys = ['id', 'device']
786 kwargs['configuration_keys'] = conf_keys[1:]
787 kwargs['configurations'] = configurations #.values(*conf_keys)
828 if not experiment:
829 experiment = conf.experiment
830
831 if experiment:
832 side_data['experiment'] = experiment
833 campaign = experiment.campaign_set.all()
834 if campaign:
835 side_data['campaign'] = campaign[0]
836 experiments = campaign[0].experiments.all()
837 else:
838 experiments = [experiment]
839 configurations = experiment.configuration_set.filter(type=0)
840 side_data['side_experiments'] = experiments
841 side_data['side_configurations'] = configurations
788 842
789 return kwargs
843 return side_data
790 844
791 845
792 846 def operation(request, id_camp=None):
793 847
794 848 if not id_camp:
795 849 campaigns = Campaign.objects.all().order_by('-start_date')
796 850
797 851 if not campaigns:
798 852 kwargs = {}
799 853 kwargs['title'] = 'No Campaigns'
800 854 kwargs['suptitle'] = 'Empty'
801 855 return render(request, 'operation.html', kwargs)
802 856
803 857 id_camp = campaigns[0].id
804 858
805 859 campaign = get_object_or_404(Campaign, pk = id_camp)
806 860
807 861 if request.method=='GET':
808 862 form = OperationForm(initial={'campaign': campaign.id}, length = 5)
809 863
810 864 if request.method=='POST':
811 865 form = OperationForm(request.POST, initial={'campaign':campaign.id}, length = 5)
812 866
813 867 if form.is_valid():
814 868 return redirect('url_operation', id_camp=campaign.id)
815 869 #locations = Location.objects.filter(experiment__campaign__pk = campaign.id).distinct()
816 870 experiments = Experiment.objects.filter(campaign__pk=campaign.id)
817 871 for exs in experiments:
818 872 exs.get_status()
819 873 locations= Location.objects.filter(experiment=experiments).distinct()
820 874 #experiments = [Experiment.objects.filter(location__pk=location.id).filter(campaign__pk=campaign.id) for location in locations]
821 875 kwargs = {}
822 876 #---Campaign
823 877 kwargs['campaign'] = campaign
824 878 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
825 879 #---Experiment
826 880 keys = ['id', 'name', 'start_time', 'end_time', 'status']
827 881 kwargs['experiment_keys'] = keys[1:]
828 882 kwargs['experiments'] = experiments
829 883 #---Radar
830 884 kwargs['locations'] = locations
831 885 #---Else
832 886 kwargs['title'] = 'Campaign'
833 887 kwargs['suptitle'] = campaign.name
834 888 kwargs['form'] = form
835 889 kwargs['button'] = 'Search'
836 890 kwargs['details'] = True
837 891 kwargs['search_button'] = True
838 892
839 893 return render(request, 'operation.html', kwargs)
840 894
841 895 def operation_search(request, id_camp=None):
842 896
843 897
844 898 if not id_camp:
845 899 campaigns = Campaign.objects.all().order_by('-start_date')
846 900
847 901 if not campaigns:
848 902 return render(request, 'operation.html', {})
849 903
850 904 id_camp = campaigns[0].id
851 905 campaign = get_object_or_404(Campaign, pk = id_camp)
852 906
853 907 if request.method=='GET':
854 908 form = OperationSearchForm(initial={'campaign': campaign.id})
855 909
856 910 if request.method=='POST':
857 911 form = OperationSearchForm(request.POST, initial={'campaign':campaign.id})
858 912
859 913 if form.is_valid():
860 914 return redirect('url_operation', id_camp=campaign.id)
861 915
862 916 #locations = Location.objects.filter(experiment__campaign__pk = campaign.id).distinct()
863 917 experiments = Experiment.objects.filter(campaign__pk=campaign.id)
864 918 for exs in experiments:
865 919 exs.get_status()
866 920 locations= Location.objects.filter(experiment=experiments).distinct()
867 921 form = OperationSearchForm(initial={'campaign': campaign.id})
868 922
869 923 kwargs = {}
870 924 #---Campaign
871 925 kwargs['campaign'] = campaign
872 926 kwargs['campaign_keys'] = ['name', 'start_date', 'end_date', 'tags', 'description']
873 927 #---Experiment
874 928 keys = ['id', 'name', 'start_time', 'end_time', 'status']
875 929 kwargs['experiment_keys'] = keys[1:]
876 930 kwargs['experiments'] = experiments
877 931 #---Radar
878 932 kwargs['locations'] = locations
879 933 #---Else
880 934 kwargs['title'] = 'Campaign'
881 935 kwargs['suptitle'] = campaign.name
882 936 kwargs['form'] = form
883 937 kwargs['button'] = 'Select'
884 938 kwargs['details'] = True
885 939 kwargs['search_button'] = False
886 940
887 941 return render(request, 'operation.html', kwargs)
888 942
889 943
890 944 def radar_play(request, id_camp, id_radar):
891 945
892 946 route = request.META['HTTP_REFERER']
893 947 route = str(route)
894 948 if 'search' in route:
895 949 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
896 950 else:
897 951 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
898 952
899 953 def radar_stop(request, id_camp, id_radar):
900
954
901 955 route = request.META['HTTP_REFERER']
902 956 route = str(route)
903 957 if 'search' in route:
904 958 return HttpResponseRedirect(reverse('url_operation_search', args=[id_camp]))
905 959 else:
906 return HttpResponseRedirect(reverse('url_operation', args=[id_camp])) No newline at end of file
960 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
961
@@ -1,336 +1,338
1 1 import os
2 2 import ast
3 3 import json
4 4
5 5 from django import forms
6 6 from django.utils.safestring import mark_safe
7 7 from apps.main.models import Device
8 8 from apps.main.forms import add_empty_choice
9 9 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
10 10 from .widgets import KmUnitWidget, KmUnitHzWidget, KmUnitDcWidget, UnitKmWidget, DefaultWidget, CodesWidget, HiddenWidget
11 11
12 12 def create_choices_from_model(model, conf_id, all=False):
13 13
14 14 if model=='RCLine':
15 15 instance = RCConfiguration.objects.get(pk=conf_id)
16 16 choices = [(line.pk, line.get_name()) for line in instance.get_lines(type='tx')]
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 self.fields['experiment'].widget.attrs['readonly'] = True
68 self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
67 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
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 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
77 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
76 78
77 79 class Meta:
78 80 model = RCConfiguration
79 81 exclude = ('type', 'parameters', 'status')
80 82
81 83 def clean(self):
82 84 form_data = super(RCConfigurationForm, self).clean()
83 85
84 86 if 'clock_divider' in form_data:
85 87 if form_data['clock_divider']<1:
86 88 self.add_error('clock_divider', 'Invalid Value')
87 89 else:
88 90 if form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))%10<>0:
89 91 self.add_error('ipp', 'Invalid IPP units={}'.format(form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))))
90 92
91 93 return form_data
92 94
93 95 class RCLineForm(forms.ModelForm):
94 96
95 97 def __init__(self, *args, **kwargs):
96 98 self.extra_fields = kwargs.pop('extra_fields', [])
97 99 super(RCLineForm, self).__init__(*args, **kwargs)
98 100
99 101 if 'initial' in kwargs and 'line_type' in kwargs['initial']:
100 102 line_type = RCLineType.objects.get(pk=kwargs['initial']['line_type'])
101 103
102 104 if 'code_id' in kwargs['initial']:
103 105 model_initial = kwargs['initial']['code_id']
104 106 else:
105 107 model_initial = 0
106 108
107 109 params = json.loads(line_type.params)
108 110
109 111 for label, value in self.extra_fields.items():
110 112 if label=='params':
111 113 continue
112 114
113 115 if 'model' in params[label]:
114 116 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
115 117 kwargs['initial']['rc_configuration']),
116 118 initial=model_initial)
117 119
118 120
119 121 else:
120 122 if label=='codes' and 'code_id' in kwargs['initial']:
121 123 self.fields[label] = forms.CharField(initial=RCLineCode.objects.get(pk=kwargs['initial']['code_id']).codes)
122 124 else:
123 125 self.fields[label] = forms.CharField(initial=value['value'])
124 126
125 127 if label=='codes':
126 128 self.fields[label].widget = CodesWidget()
127 129
128 130 if self.data:
129 131 line_type = RCLineType.objects.get(pk=self.data['line_type'])
130 132
131 133 if 'code_id' in self.data:
132 134 model_initial = self.data['code_id']
133 135 else:
134 136 model_initial = 0
135 137
136 138 params = json.loads(line_type.params)
137 139
138 140 for label, value in self.extra_fields.items():
139 141 if label=='params':
140 142 continue
141 143
142 144 if 'model' in params[label]:
143 145 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
144 146 self.data['rc_configuration']),
145 147 initial=model_initial)
146 148
147 149
148 150 else:
149 151 if label=='codes' and 'code' in self.data:
150 152 self.fields[label] = forms.CharField(initial=self.data['codes'])
151 153 else:
152 154 self.fields[label] = forms.CharField(initial=self.data[label])
153 155
154 156 if label=='codes':
155 157 self.fields[label].widget = CodesWidget()
156 158
157 159
158 160 class Meta:
159 161 model = RCLine
160 162 fields = ('rc_configuration', 'line_type', 'channel')
161 163 widgets = {
162 164 'channel': forms.HiddenInput(),
163 165 }
164 166
165 167
166 168 def clean(self):
167 169
168 170 form_data = self.cleaned_data
169 171 if 'code' in self.data and self.data['TX_ref']=="0":
170 172 self.add_error('TX_ref', 'Choose a valid TX reference')
171 173
172 174 return form_data
173 175
174 176
175 177 def save(self):
176 178 line = super(RCLineForm, self).save()
177 179
178 180 #auto add channel
179 181 line.channel = RCLine.objects.filter(rc_configuration=line.rc_configuration).count()-1
180 182
181 183 #auto add position for TX, TR & CODE
182 184 if line.line_type.name in ('tx', ):
183 185 line.position = RCLine.objects.filter(rc_configuration=line.rc_configuration, line_type=line.line_type).count()-1
184 186
185 187 #save extra fields in params
186 188 params = {}
187 189 for label, value in self.extra_fields.items():
188 190 if label=='params':
189 191 params['params'] = []
190 192 elif label=='codes':
191 193 params[label] = [s for s in self.data[label].split('\r\n') if s]
192 194 else:
193 195 params[label] = self.data[label]
194 196 line.params = json.dumps(params)
195 197 line.save()
196 198 return
197 199
198 200
199 201 class RCLineViewForm(forms.Form):
200 202
201 203 def __init__(self, *args, **kwargs):
202 204
203 205 extra_fields = kwargs.pop('extra_fields')
204 206 line = kwargs.pop('line')
205 207 subform = kwargs.pop('subform', False)
206 208 super(RCLineViewForm, self).__init__(*args, **kwargs)
207 209
208 210 if subform:
209 211 params = json.loads(line.line_type.params)['params']
210 212 else:
211 213 params = json.loads(line.line_type.params)
212 214
213 215 for label, value in extra_fields.items():
214 216
215 217 if label=='params':
216 218 continue
217 219 if 'ref' in label:
218 220 if value in (0, '0'):
219 221 value = 'All'
220 222 else:
221 223 value = RCLine.objects.get(pk=value).get_name()
222 224 elif label=='code':
223 225 value = RCLineCode.objects.get(pk=value).name
224 226
225 227 self.fields[label] = forms.CharField(initial=value)
226 228
227 229 if 'widget' in params[label]:
228 230 km2unit = line.rc_configuration.km2unit
229 231 if params[label]['widget']=='km':
230 232 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
231 233 elif params[label]['widget']=='unit':
232 234 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
233 235 elif params[label]['widget']=='dc':
234 236 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
235 237 elif params[label]['widget']=='codes':
236 238 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
237 239 else:
238 240 self.fields[label].widget = DefaultWidget(attrs={'disabled':True})
239 241
240 242
241 243 class RCLineEditForm(forms.ModelForm):
242 244
243 245 def __init__(self, *args, **kwargs):
244 246
245 247 extra_fields = kwargs.pop('extra_fields', [])
246 248 conf = kwargs.pop('conf', False)
247 249 line = kwargs.pop('line')
248 250 subform = kwargs.pop('subform', False)
249 251
250 252 super(RCLineEditForm, self).__init__(*args, **kwargs)
251 253
252 254 if subform is not False:
253 255 params = json.loads(line.line_type.params)['params']
254 256 count = subform
255 257 else:
256 258 params = json.loads(line.line_type.params)
257 259 count = -1
258 260
259 261 for label, value in extra_fields.items():
260 262
261 263 if label in ('params',):
262 264 continue
263 265 if 'help' in params[label]:
264 266 help_text = params[label]['help']
265 267 else:
266 268 help_text = ''
267 269
268 270 if 'model' in params[label]:
269 271 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'], conf.id),
270 272 initial=value,
271 273 widget=forms.Select(attrs={'name':'%s|%s|%s' % (count, line.id, label)}),
272 274 help_text=help_text)
273 275
274 276 else:
275 277
276 278 self.fields[label] = forms.CharField(initial=value, help_text=help_text)
277 279
278 280 if label in ('code', ):
279 281 self.fields[label].widget = HiddenWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
280 282
281 283 elif 'widget' in params[label]:
282 284 km2unit = line.rc_configuration.km2unit
283 285 if params[label]['widget']=='km':
284 286 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
285 287 elif params[label]['widget']=='unit':
286 288 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
287 289 elif params[label]['widget']=='dc':
288 290 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
289 291 elif params[label]['widget']=='codes':
290 292 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
291 293 else:
292 294 self.fields[label].widget = DefaultWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
293 295
294 296
295 297 class Meta:
296 298 model = RCLine
297 299 exclude = ('rc_configuration', 'line_type', 'channel', 'position', 'params', 'pulses')
298 300
299 301
300 302 class RCSubLineEditForm(forms.Form):
301 303
302 304 def __init__(self, *args, **kwargs):
303 305 extra_fields = kwargs.pop('extra_fields')
304 306 count = kwargs.pop('count')
305 307 line = kwargs.pop('line')
306 308 super(RCSubLineEditForm, self).__init__(*args, **kwargs)
307 309 for label, value in extra_fields.items():
308 310 self.fields[label] = forms.CharField(initial=value,
309 311 widget=forms.TextInput(attrs={'name':'%s|%s|%s' % (count, line, label)}))
310 312
311 313
312 314 class RCImportForm(forms.Form):
313 315
314 316 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
315 317
316 318
317 319 class RCLineCodesForm(forms.ModelForm):
318 320
319 321 def __init__(self, *args, **kwargs):
320 322 super(RCLineCodesForm, self).__init__(*args, **kwargs)
321 323
322 324 if 'initial' in kwargs:
323 325 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
324 326 initial=kwargs['initial']['code'])
325 327 if 'instance' in kwargs:
326 328 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
327 329 initial=kwargs['instance'].pk)
328 330
329 331 self.fields['codes'].widget = CodesWidget()
330 332
331 333
332 334 class Meta:
333 335 model = RCLineCode
334 336 exclude = ('name',)
335 337
336 338 No newline at end of file
@@ -1,530 +1,559
1 1
2 2 import ast
3 3 import json
4 4 import numpy as np
5 5
6 6 from polymorphic import PolymorphicModel
7 7
8 8 from django.db import models
9 9 from django.core.urlresolvers import reverse
10 10 from django.core.validators import MinValueValidator, MaxValueValidator
11 11
12 12 from apps.main.models import Configuration
13 13 from .utils import RCFile, pulses, pulses_from_code, create_mask, pulses_to_points
14 14
15 15 # Create your models here.
16 16
17 17 LINE_TYPES = (
18 18 ('none', 'Not used'),
19 19 ('tr', 'Transmission/reception selector signal'),
20 20 ('tx', 'A modulating signal (Transmission pulse)'),
21 21 ('codes', 'BPSK modulating signal'),
22 22 ('windows', 'Sample window signal'),
23 23 ('sync', 'Synchronizing signal'),
24 24 ('flip', 'IPP related periodic signal'),
25 25 ('prog_pulses', 'Programmable pulse'),
26 26 )
27 27
28 28
29 29 SAMPLING_REFS = (
30 30 ('none', 'No Reference'),
31 31 ('first_baud', 'Middle of the first baud'),
32 32 ('sub_baud', 'Middle of the sub-baud')
33 33 )
34 34
35 35 DAT_CMDS = {
36 36 # Pulse Design commands
37 37 'DISABLE' : 0, # Disables pulse generation
38 38 'ENABLE' : 24, # Enables pulse generation
39 39 'DELAY_START' : 40, # Write delay status to memory
40 40 'FLIP_START' : 48, # Write flip status to memory
41 41 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
42 42 'TX_ONE' : 72, # Output '0' in line TX
43 43 'TX_ZERO' : 88, # Output '0' in line TX
44 44 'SW_ONE' : 104, # Output '0' in line SW
45 45 'SW_ZERO' : 112, # Output '1' in line SW
46 46 'RESTART': 120, # Restarts CR8 Firmware
47 47 'CONTINUE' : 253, # Function Unknown
48 48 # Commands available to new controllers
49 49 # 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.
50 50 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
51 51 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
52 52 'CLOCK_DIVIDER' : 8,
53 53 }
54 54
55 55
56 56 class RCConfiguration(Configuration):
57 57
58 58 ipp = models.FloatField(verbose_name='Inter pulse period (Km)', validators=[MinValueValidator(1), MaxValueValidator(1000)], default=10)
59 59 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
60 60 clock_in = models.FloatField(verbose_name='Clock in (MHz)', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
61 61 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
62 62 clock = models.FloatField(verbose_name='Clock Master (MHz)', blank=True, default=1)
63 63 time_before = models.PositiveIntegerField(verbose_name='Time before (&mu;S)', default=0)
64 64 time_after = models.PositiveIntegerField(verbose_name='Time after (&mu;S)', default=0)
65 65 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
66 66 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
67 67 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
68 68 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
69 69
70 70
71 71 class Meta:
72 72 db_table = 'rc_configurations'
73 73
74 74
75 75 def get_absolute_url_plot(self):
76 76 return reverse('url_plot_rc_pulses', args=[str(self.id)])
77 77
78 78 def get_absolute_url_import(self):
79 79 return reverse('url_import_rc_conf', args=[str(self.id)])
80 80
81 81 @property
82 82 def us2unit(self):
83 83
84 84 return self.clock_in/self.clock_divider
85 85
86 86
87 87 @property
88 88 def km2unit(self):
89 89
90 90 return 20./3*(self.clock_in/self.clock_divider)
91 91
92 92
93 def clone(self, **kwargs):
94
95 lines = self.get_lines()
96 self.pk = None
97 self.id = None
98 for attr, value in kwargs.items():
99 setattr(self, attr, value)
100 self.save()
101
102 for line in lines:
103 line.clone(rc_configuration=self)
104
105 return self
106
93 107 def get_lines(self, type=None):
94 108 '''
95 109 Retrieve configuration lines
96 110 '''
97 111
98 112 if type is not None:
99 113 return RCLine.objects.filter(rc_configuration=self.pk, line_type__name=type)
100 114 else:
101 115 return RCLine.objects.filter(rc_configuration=self.pk)
102 116
103 117 def clean_lines(self):
104 118 '''
105 119 '''
106 120
107 121 empty_line = RCLineType.objects.get(pk=8)
108 122
109 123 for line in self.get_lines():
110 124 line.line_type = empty_line
111 125 line.params = '{}'
112 126 line.save()
113 127
114 128 def parms_to_dict(self):
115 129 '''
116 130 '''
117 131
118 132 data = {}
119 133 for field in self._meta.fields:
120 134
121 135 data[field.name] = '{}'.format(field.value_from_object(self))
122 136
123 137 data.pop('parameters')
124 138 data['lines'] = []
125 139
126 140 for line in self.get_lines():
127 141 line_data = json.loads(line.params)
128 142 if 'TX_ref' in line_data and line_data['TX_ref'] not in (0, '0'):
129 143 line_data['TX_ref'] = RCLine.objects.get(pk=line_data['TX_ref']).get_name()
130 144 if 'code' in line_data:
131 145 line_data['code'] = RCLineCode.objects.get(pk=line_data['code']).name
132 146 line_data['type'] = line.line_type.name
133 147 data['lines'].append(line_data)
134 148
135 149
136 150 return data
137 151
138 152 def get_delays(self):
139 153
140 154 pulses = [line.get_pulses() for line in self.get_lines()]
141 155 points = [tup for tups in pulses for tup in tups]
142 156 points = set([x for tup in points for x in tup])
143 157 points = list(points)
144 158 points.sort()
145 159
146 160 if points[0]<>0:
147 161 points.insert(0, 0)
148 162
149 163 return [points[i+1]-points[i] for i in range(len(points)-1)]
150 164
151 165
152 166 def get_flips(self):
153 167
154 168 line_points = [pulses_to_points(line.pulses_as_array()) for line in self.get_lines()]
155 169 line_points = [[(x, x+y) for x,y in tups] for tups in line_points]
156 170 line_points = [[t for x in tups for t in x] for tups in line_points]
157 171 states = [[1 if x in tups else 0 for tups in line_points] for x in points]
158 172
159 173 return states
160 174
161 175 def add_cmd(self, cmd):
162 176
163 177 if cmd in DAT_CMDS:
164 178 return (255, DAT_CMDS[cmd])
165 179
166 180 def add_data(self, value):
167 181
168 182 return (254, value-1)
169 183
170 184 def parms_to_binary(self):
171 185 '''
172 186 Create "dat" stream to be send to CR
173 187 '''
174 188
175 189 data = []
176 190 # create header
177 191 data.append(self.add_cmd('DISABLE'))
178 192 data.append(self.add_cmd('CONTINUE'))
179 193 data.append(self.add_cmd('RESTART'))
180 194
181 195 if self.control_sw:
182 196 data.append(self.add_cmd('SW_ONE'))
183 197 else:
184 198 data.append(self.add_cmd('SW_ZERO'))
185 199
186 200 if self.control_tx:
187 201 data.append(self.add_cmd('TX_ONE'))
188 202 else:
189 203 data.append(self.add_cmd('TX_ZERO'))
190 204
191 205 # write divider
192 206 data.append(self.add_cmd('CLOCK_DIVIDER'))
193 207 data.append(self.add_data(self.clock_divider))
194 208
195 209 # write delays
196 210 data.append(self.add_cmd('DELAY_START'))
197 211 # first delay is always zero
198 212 data.append(self.add_data(1))
199 213 line_points = [pulses_to_points(line.pulses_as_array()) for line in self.get_lines()]
200 214 points = [tup for tups in line_points for tup in tups]
201 215 points = [(x, x+y) for x,y in points]
202 216 points = set([x for tup in points for x in tup])
203 217 points = list(points)
204 218 points.sort()
205 219
206 220 if points[0]<>0:
207 221 points.insert(0, 0)
208 222
209 223 delays = [points[i+1]-points[i] for i in range(len(points)-1)]
210 224
211 225 for delay in delays:
212 226 while delay>252:
213 227 data.append(self.add_data(253))
214 228 delay -= 253
215 229 data.append(self.add_data(delay))
216 230
217 231 # write flips
218 232 data.append(self.add_cmd('FLIP_START'))
219 233 line_points = [[(x, x+y) for x,y in tups] for tups in line_points]
220 234 line_points = [[t for x in tups for t in x] for tups in line_points]
221 235 states = [[1 if x in tups else 0 for tups in line_points] for x in points]
222 236 for flips, delay in zip(states[:-1], delays):
223 237 flips.reverse()
224 238 flip = int(''.join([str(x) for x in flips]), 2)
225 239 data.append(self.add_data(flip+1))
226 240 while delay>252:
227 241 data.append(self.add_data(1))
228 242 delay -= 253
229 243
230 244 # write sampling period
231 245 data.append(self.add_cmd('SAMPLING_PERIOD'))
232 246 wins = self.get_lines(type='windows')
233 247 if wins:
234 248 win_params = json.loads(wins[0].params)['params']
235 249 if win_params:
236 250 dh = int(win_params[0]['resolution']*self.km2unit)
237 251 else:
238 252 dh = 1
239 253 else:
240 254 dh = 1
241 255 data.append(self.add_data(dh))
242 256
243 257 # write enable
244 258 data.append(self.add_cmd('ENABLE'))
245 259
246 260 return '\n'.join(['{}'.format(x) for tup in data for x in tup])
247 261
248 262 def update_from_file(self, filename):
249 263 '''
250 264 Update instance from file
251 265 '''
252 266
253 267 f = RCFile(filename)
254 268 data = f.data
255 269 self.name = data['name']
256 270 self.ipp = data['ipp']
257 271 self.ntx = data['ntx']
258 272 self.clock_in = data['clock_in']
259 273 self.clock_divider = data['clock_divider']
260 274 self.clock = data['clock']
261 275 self.time_before = data['time_before']
262 276 self.time_after = data['time_after']
263 277 self.sync = data['sync']
264 278 self.sampling_reference = data['sampling_reference']
265 279 self.clean_lines()
266 280
267 281 lines = []
268 282 positions = {'tx':0, 'tr':0}
269 283
270 284 for i, line_data in enumerate(data['lines']):
271 285 line_type = RCLineType.objects.get(name=line_data.pop('type'))
272 286 if line_type.name=='codes':
273 287 code = RCLineCode.objects.get(name=line_data['code'])
274 288 line_data['code'] = code.pk
275 289 line = RCLine.objects.filter(rc_configuration=self, channel=i)
276 290 if line:
277 291 line = line[0]
278 292 line.line_type = line_type
279 293 line.params = json.dumps(line_data)
280 294 else:
281 295 line = RCLine(rc_configuration=self, line_type=line_type,
282 296 params=json.dumps(line_data),
283 297 channel=i)
284 298
285 299 if line_type.name=='tx':
286 300 line.position = positions['tx']
287 301 positions['tx'] += 1
288 302
289 303 if line_type.name=='tr':
290 304 line.position = positions['tr']
291 305 positions['tr'] += 1
292 306
293 307 line.save()
294 308 lines.append(line)
295 309
296 310 for line, line_data in zip(lines, data['lines']):
297 311 if 'TX_ref' in line_data:
298 312 params = json.loads(line.params)
299 313 if line_data['TX_ref'] in (0, '0'):
300 314 params['TX_ref'] = '0'
301 315 else:
302 316 params['TX_ref'] = [l.pk for l in lines if l.line_type.name=='tx' and l.get_name()==line_data['TX_ref']][0]
303 317 line.params = json.dumps(params)
304 318 line.save()
305 319
306 320
321 def status_device(self):
322
323 return 0
324
307 325 class RCLineCode(models.Model):
308 326
309 327 name = models.CharField(max_length=40)
310 328 bits_per_code = models.PositiveIntegerField(default=0)
311 329 number_of_codes = models.PositiveIntegerField(default=0)
312 330 codes = models.TextField(blank=True, null=True)
313 331
314 332 class Meta:
315 333 db_table = 'rc_line_codes'
316 334 ordering = ('name',)
317 335
318 336 def __unicode__(self):
319 337 return u'%s' % self.name
320 338
321 339 class RCLineType(models.Model):
322 340
323 341 name = models.CharField(choices=LINE_TYPES, max_length=40)
324 342 description = models.TextField(blank=True, null=True)
325 343 params = models.TextField(default='[]')
326 344
327 345 class Meta:
328 346 db_table = 'rc_line_types'
329 347
330 348 def __unicode__(self):
331 349 return u'%s - %s' % (self.name.upper(), self.get_name_display())
332 350
333 351
334 352 class RCLine(models.Model):
335 353
336 rc_configuration = models.ForeignKey(RCConfiguration)
354 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
337 355 line_type = models.ForeignKey(RCLineType)
338 356 channel = models.PositiveIntegerField(default=0)
339 357 position = models.PositiveIntegerField(default=0)
340 358 params = models.TextField(default='{}')
341 359 pulses = models.TextField(default='')
342 360
343 361 class Meta:
344 362 db_table = 'rc_lines'
345 363 ordering = ['channel']
346 364
347 365 def __unicode__(self):
348 366 if self.rc_configuration:
349 367 return u'%s - %s' % (self.rc_configuration, self.get_name())
350 368
369 def clone(self, **kwargs):
370
371 self.pk = None
372
373 for attr, value in kwargs.items():
374 setattr(self, attr, value)
375
376 self.save()
377
378 return self
379
351 380 def get_name(self):
352 381
353 382 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
354 383
355 384 if self.line_type.name in ('tx',):
356 385 return '%s%s' % (self.line_type.name.upper(), chars[self.position])
357 386 elif self.line_type.name in ('codes', 'windows', 'tr'):
358 387 if 'TX_ref' not in json.loads(self.params):
359 388 return self.line_type.name.upper()
360 389 pk = json.loads(self.params)['TX_ref']
361 390 if pk in (0, '0'):
362 391 refs = ','.join(chars[l.position] for l in self.rc_configuration.get_lines('tx'))
363 392 return '%s (%s)' % (self.line_type.name.upper(), refs)
364 393 else:
365 394 ref = RCLine.objects.get(pk=pk)
366 395 return '%s (%s)' % (self.line_type.name.upper(), chars[ref.position])
367 396 elif self.line_type.name in ('flip', 'prog_pulses', 'sync', 'none'):
368 397 return '%s %s' % (self.line_type.name.upper(), self.channel)
369 398 else:
370 399 return self.line_type.name.upper()
371 400
372 401 def get_lines(self, type=None):
373 402
374 403 if type is not None:
375 404 return RCLine.objects.filter(rc_configuration=self.rc_configuration, line_type__name=type)
376 405 else:
377 406 return RCLine.objects.filter(rc_configuration=self.rc_configuration)
378 407
379 408
380 409 def pulses_as_array(self):
381 410
382 411 return (np.fromstring(self.pulses, dtype=np.uint8)-48).astype(np.int8)
383 412
384 413
385 414 def get_pulses(self):
386 415
387 416 X = self.pulses_as_array()
388 417
389 418 d = X[1:]-X[:-1]
390 419
391 420 up = np.where(d==1)[0]
392 421 if X[0]==1:
393 422 up = np.concatenate((np.array([-1]), up))
394 423 up += 1
395 424
396 425 dw = np.where(d==-1)[0]
397 426 if X[-1]==1:
398 427 dw = np.concatenate((dw, np.array([len(X)-1])))
399 428 dw += 1
400 429
401 430 return [(tup[0], tup[1]) for tup in zip(up, dw)]
402 431
403 432 def get_win_ref(self, params, tx_id, km2unit):
404 433
405 434 ref = self.rc_configuration.sampling_reference
406 435
407 436 codes = [line for line in self.get_lines(type='code') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
408 437
409 438 if codes:
410 439 code_line = RCLineCode.objects.get(pk=json.loads(codes[0].params)['code'])
411 440 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/code_line.bits_per_code
412 441 else:
413 442 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
414 443
415 444 if ref=='first_baud':
416 445 return int(1 + (tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit)
417 446 elif ref=='sub_baud':
418 447 return int(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
419 448 else:
420 449 return 0
421 450
422 451 def update_pulses(self, save=True, tr=False):
423 452 '''
424 453 Update pulses field
425 454 '''
426 455
427 456 km2unit = self.rc_configuration.km2unit
428 457 us2unit = self.rc_configuration.us2unit
429 458 ipp = self.rc_configuration.ipp
430 459 ntx = self.rc_configuration.ntx
431 460 ipp_u = int(ipp*km2unit)
432 461
433 462 x = np.arange(0, ipp_u*ntx)
434 463
435 464 if self.line_type.name=='tr':
436 465 params = json.loads(self.params)
437 466 if params['TX_ref'] in ('0', 0):
438 467 txs = [tx.update_pulses(save=False, tr=True) for tx in self.get_lines('tx')]
439 468 else:
440 469 txs = [tx.update_pulses(save=False, tr=True) for tx in RCLine.objects.filter(pk=params['TX_ref'])]
441 470 if len(txs)==0 or 0 in [len(tx) for tx in txs]:
442 471 return
443 472
444 473 y = np.any(txs, axis=0, out=np.ones(ipp_u*ntx))
445 474
446 475 ranges = params['range'].split(',')
447 476 if len(ranges)>0 and ranges[0]<>'0':
448 477 mask = create_mask(ranges, ipp_u, ntx, self.rc_configuration.sync)
449 478 y = y.astype(np.int8) & mask
450 479
451 480 elif self.line_type.name=='tx':
452 481 params = json.loads(self.params)
453 482 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
454 483 y = pulses(x, ipp_u, float(params['pulse_width'])*km2unit,
455 484 delay=delays,
456 485 before=int(self.rc_configuration.time_before*us2unit),
457 486 after=int(self.rc_configuration.time_after*us2unit) if tr else 0,
458 487 sync=self.rc_configuration.sync)
459 488
460 489 ranges = params['range'].split(',')
461 490
462 491 if len(ranges)>0 and ranges[0]<>'0':
463 492 mask = create_mask(ranges, ipp_u, ntx, self.rc_configuration.sync)
464 493 y = y & mask
465 494
466 495 elif self.line_type.name=='flip':
467 496 width = float(json.loads(self.params)['number_of_flips'])*ipp*km2unit
468 497 y = pulses(x, 2*width, width)
469 498
470 499 elif self.line_type.name=='codes':
471 500 params = json.loads(self.params)
472 501 #codes = ast.literal_eval(RCLineCode.objects.get(pk=json.loads(self.params)['code']).codes)
473 502 tx = RCLine.objects.get(pk=params['TX_ref'])
474 503 tx_params = json.loads(tx.params)
475 504
476 505 y = pulses_from_code(ipp_u, ntx, params['codes'],
477 506 int(float(tx_params['pulse_width'])*km2unit),
478 507 before=int(self.rc_configuration.time_before*us2unit)+self.rc_configuration.sync)
479 508
480 509 ranges = tx_params['range'].split(',')
481 510 if len(ranges)>0 and ranges[0]<>'0':
482 511 mask = create_mask(ranges, ipp_u, ntx, self.rc_configuration.sync)
483 512 y = y.astype(np.int8) & mask
484 513
485 514 elif self.line_type.name=='sync':
486 515 params = json.loads(self.params)
487 516 y = np.zeros(ipp_u*ntx)
488 517 if params['invert'] in ('1', 1):
489 518 y[-1] = 1
490 519 else:
491 520 y[0] = 1
492 521
493 522 elif self.line_type.name=='prog_pulses':
494 523 params = json.loads(self.params)
495 524 if int(params['periodic'])==0:
496 525 nntx = ntx
497 526 else:
498 527 nntx = 1
499 528
500 529 if 'params' in params and len(params['params'])>0:
501 530 y = sum([pulses(x, ipp_u*nntx, (pp['end']-pp['begin']), shift=pp['begin']) for pp in params['params']])
502 531 else:
503 532 y = np.zeros(ipp_u*ntx)
504 533
505 534 elif self.line_type.name=='windows':
506 535 params = json.loads(self.params)
507 536 if 'params' in params and len(params['params'])>0:
508 537 print 'REFS'
509 538 print [self.get_win_ref(pp, params['TX_ref'],km2unit) for pp in params['params']]
510 539 y = sum([pulses(x, ipp_u, pp['resolution']*pp['number_of_samples']*km2unit,
511 540 shift=0,
512 541 before=int(self.rc_configuration.time_before*us2unit)+self.get_win_ref(pp, params['TX_ref'],km2unit),
513 542 sync=self.rc_configuration.sync) for pp in params['params']])
514 543 tr = self.get_lines('tr')[0]
515 544 ranges = json.loads(tr.params)['range'].split(',')
516 545 if len(ranges)>0 and ranges[0]<>'0':
517 546 mask = create_mask(ranges, ipp_u, ntx, self.rc_configuration.sync)
518 547 y = y & mask
519 548 else:
520 549 y = np.zeros(ipp_u*ntx)
521 550 else:
522 551 y = np.zeros(ipp_u*ntx)
523 552
524 553 if save:
525 554 self.pulses = (y+48).astype(np.uint8).tostring()
526 555 self.save()
527 556 else:
528 557 return y
529 558
530 559 No newline at end of file
@@ -1,395 +1,391
1 1
2 2 import json
3 3
4 4 from django.contrib import messages
5 5 from django.utils.safestring import mark_safe
6 6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7 7
8 8 from apps.main.models import Configuration, Experiment, Device
9 9 from apps.main.views import sidebar
10 10
11 11 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode
12 12 from .forms import RCConfigurationForm, RCLineForm, RCLineViewForm, RCLineEditForm, RCImportForm, RCLineCodesForm
13 13 from .utils import plot_pulses
14 14
15 15
16 16 def conf(request, conf_id):
17 17
18 18 conf = get_object_or_404(RCConfiguration, pk=conf_id)
19 19
20 20 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
21 21
22 22 for line in lines:
23 23 params = json.loads(line.params)
24 24 line.form = RCLineViewForm(extra_fields=params, line=line)
25 25 if 'params' in params:
26 26 line.subforms = [RCLineViewForm(extra_fields=fields, line=line, subform=True) for fields in params['params']]
27 27
28 28 kwargs = {}
29 29 kwargs['dev_conf'] = conf
30 30 kwargs['rc_lines'] = lines
31 31 kwargs['dev_conf_keys'] = ['name', 'ipp', 'ntx', 'clock_in', 'clock_divider', 'clock',
32 32 'time_before', 'time_after', 'sync', 'sampling_reference', 'control_tx', 'control_sw']
33 33
34 34 kwargs['title'] = 'RC Configuration'
35 35 kwargs['suptitle'] = 'Details'
36 36
37 37 kwargs['button'] = 'Edit Configuration'
38 38 ###### SIDEBAR ######
39 kwargs.update(sidebar(conf))
39 kwargs.update(sidebar(conf=conf))
40 40
41 41 return render(request, 'rc_conf.html', kwargs)
42 42
43 43
44 44 def conf_edit(request, conf_id):
45 45
46 46 conf = get_object_or_404(RCConfiguration, pk=conf_id)
47 47
48 48 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
49 49
50 50 for line in lines:
51 51 params = json.loads(line.params)
52 52 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
53 53 line.subform = False
54 54
55 55 if 'params' in params:
56 56 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
57 57 line.subform = True
58 58
59 59 if request.method=='GET':
60 60
61 61 form = RCConfigurationForm(instance=conf)
62 62
63 63 elif request.method=='POST':
64 64
65 65 line_data = {}
66 66 conf_data = {}
67 67 extras = []
68 68
69 69 #classified post fields
70 70 for label,value in request.POST.items():
71 71 if label=='csrfmiddlewaretoken':
72 72 continue
73 73
74 74 if label.count('|')==0:
75 75 conf_data[label] = value
76 76 continue
77 77
78 78 elif label.split('|')[0]<>'-1':
79 79 extras.append(label)
80 80 continue
81 81
82 82 x, pk, name = label.split('|')
83 83
84 84 if name=='codes':
85 85 value = [s for s in value.split('\r\n') if s]
86 86
87 87 if pk in line_data:
88 88 line_data[pk][name] = value
89 89 else:
90 90 line_data[pk] = {name:value}
91 91
92 92 #update conf
93 93 form = RCConfigurationForm(conf_data, instance=conf)
94 94
95 95 if form.is_valid():
96 96
97 97 form.save()
98 98
99 99 #update lines fields
100 100 extras.sort()
101 101 for label in extras:
102 102 x, pk, name = label.split('|')
103 103 if pk not in line_data:
104 104 line_data[pk] = {}
105 105 if 'params' not in line_data[pk]:
106 106 line_data[pk]['params'] = []
107 107 if len(line_data[pk]['params'])<int(x)+1:
108 108 line_data[pk]['params'].append({})
109 109 line_data[pk]['params'][int(x)][name] = float(request.POST[label])
110 110
111 111 for pk, params in line_data.items():
112 112 line = RCLine.objects.get(pk=pk)
113 113 if line.line_type.name in ('windows', 'prog_pulses'):
114 114 if 'params' not in params:
115 115 params['params'] = []
116 116 line.params = json.dumps(params)
117 117 line.save()
118 118
119 119 #update pulses field
120 120 for line in conf.get_lines():
121 121 if line.line_type.name=='tr':
122 122 continue
123 123 line.update_pulses()
124 124
125 125 for tr in conf.get_lines('tr'):
126 126 tr.update_pulses()
127 127
128 128 messages.success(request, 'RC Configuration successfully updated')
129 129
130 130 return redirect(conf.get_absolute_url())
131 131
132 132 kwargs = {}
133 133 kwargs['dev_conf'] = conf
134 134 kwargs['form'] = form
135 135 kwargs['rc_lines'] = lines
136 136 kwargs['edit'] = True
137 137
138 138 kwargs['title'] = 'RC Configuration'
139 139 kwargs['suptitle'] = 'Edit'
140 140 kwargs['button'] = 'Update'
141 141 kwargs['previous'] = conf.get_absolute_url()
142
143 kwargs.update(sidebar(conf))
144 142
145 143 return render(request, 'rc_conf_edit.html', kwargs)
146 144
147 145
148 146 def add_line(request, conf_id, line_type_id=None, code_id=None):
149 147
150 148 conf = get_object_or_404(RCConfiguration, pk=conf_id)
151 149
152 150 if request.method=='GET':
153 151 if line_type_id:
154 152 line_type = get_object_or_404(RCLineType, pk=line_type_id)
155 153
156 154 if code_id:
157 155 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id, 'code_id': code_id},
158 156 extra_fields=json.loads(line_type.params))
159 157 else:
160 158 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id},
161 159 extra_fields=json.loads(line_type.params))
162 160 else:
163 161 line_type = {'id':0}
164 162 form = RCLineForm(initial={'rc_configuration':conf_id})
165 163
166 164 if request.method=='POST':
167 165
168 166 line_type = get_object_or_404(RCLineType, pk=line_type_id)
169 167 form = RCLineForm(request.POST,
170 168 extra_fields=json.loads(line_type.params))
171 169
172 170 if form.is_valid():
173 171 form.save()
174 172 form.instance.update_pulses()
175 173 return redirect('url_edit_rc_conf', conf.id)
176 174
177 175 kwargs = {}
178 176 kwargs['form'] = form
179 177 kwargs['title'] = 'RC Configuration'
180 178 kwargs['suptitle'] = 'Add Line'
181 179 kwargs['button'] = 'Add'
182 180 kwargs['previous'] = conf.get_absolute_url_edit()
183 181 kwargs['dev_conf'] = conf
184 182 kwargs['line_type'] = line_type
185 183
186 kwargs.update(sidebar(conf))
187
188 184 return render(request, 'rc_add_line.html', kwargs)
189 185
190 186 def edit_codes(request, conf_id, line_id, code_id=None):
191 187
192 188 conf = get_object_or_404(RCConfiguration, pk=conf_id)
193 189 line = get_object_or_404(RCLine, pk=line_id)
194 190 params = json.loads(line.params)
195 191
196 192 if request.method=='GET':
197 193 if code_id:
198 194 code = get_object_or_404(RCLineCode, pk=code_id)
199 195 form = RCLineCodesForm(instance=code)
200 196 else:
201 197 initial = {'code': params['code'],
202 198 'codes': params['codes'] if 'codes' in params else [],
203 199 'number_of_codes': len(params['codes']) if 'codes' in params else 0,
204 200 'bits_per_code': len(params['codes'][0]) if 'codes' in params else 0,
205 201 }
206 202 form = RCLineCodesForm(initial=initial)
207 203
208 204 if request.method=='POST':
209 205 form = RCLineCodesForm(request.POST)
210 206 if form.is_valid():
211 207 params['code'] = request.POST['code']
212 208 params['codes'] = [s for s in request.POST['codes'].split('\r\n') if s]
213 209 line.params = json.dumps(params)
214 210 line.save()
215 211 messages.success(request, 'Line: "%s" has been updated.' % line)
216 212 return redirect('url_edit_rc_conf', conf.id)
217 213
218 214 kwargs = {}
219 215 kwargs['form'] = form
220 216 kwargs['title'] = line
221 217 kwargs['suptitle'] = 'Edit'
222 218 kwargs['button'] = 'Update'
223 219 kwargs['dev_conf'] = conf
224 220 kwargs['previous'] = conf.get_absolute_url_edit()
225 221 kwargs['line'] = line
226 222
227 223 return render(request, 'rc_edit_codes.html', kwargs)
228 224
229 225 def add_subline(request, conf_id, line_id):
230 226
231 227 conf = get_object_or_404(RCConfiguration, pk=conf_id)
232 228 line = get_object_or_404(RCLine, pk=line_id)
233 229
234 230 if request.method == 'POST':
235 231 if line:
236 232 params = json.loads(line.params)
237 233 subparams = json.loads(line.line_type.params)
238 234 if 'params' in subparams:
239 235 dum = {}
240 236 for key, value in subparams['params'].items():
241 237 dum[key] = value['value']
242 238 params['params'].append(dum)
243 239 line.params = json.dumps(params)
244 240 line.save()
245 241 return redirect('url_edit_rc_conf', conf.id)
246 242
247 243 kwargs = {}
248 244
249 245 kwargs['title'] = 'Add new'
250 246 kwargs['suptitle'] = '%s to %s' % (line.line_type.name, line)
251 247
252 248 return render(request, 'confirm.html', kwargs)
253 249
254 250 def remove_line(request, conf_id, line_id):
255 251
256 252 conf = get_object_or_404(RCConfiguration, pk=conf_id)
257 253 line = get_object_or_404(RCLine, pk=line_id)
258 254
259 255 if request.method == 'POST':
260 256 if line:
261 257 try:
262 258 channel = line.channel
263 259 line.delete()
264 260 for ch in range(channel+1, RCLine.objects.filter(rc_configuration=conf).count()+1):
265 261 l = RCLine.objects.get(rc_configuration=conf, channel=ch)
266 262 l.channel = l.channel-1
267 263 l.save()
268 264 messages.success(request, 'Line: "%s" has been deleted.' % line)
269 265 except:
270 266 messages.error(request, 'Unable to delete line: "%s".' % line)
271 267
272 268 return redirect('url_edit_rc_conf', conf.id)
273 269
274 270 kwargs = {}
275 271
276 272 kwargs['object'] = line
277 273 kwargs['delete_view'] = True
278 274 kwargs['title'] = 'Confirm delete'
279 275 kwargs['previous'] = conf.get_absolute_url_edit()
280 276 return render(request, 'confirm.html', kwargs)
281 277
282 278
283 279 def remove_subline(request, conf_id, line_id, subline_id):
284 280
285 281 conf = get_object_or_404(RCConfiguration, pk=conf_id)
286 282 line = get_object_or_404(RCLine, pk=line_id)
287 283
288 284 if request.method == 'POST':
289 285 if line:
290 286 params = json.loads(line.params)
291 287 params['params'].remove(params['params'][int(subline_id)-1])
292 288 line.params = json.dumps(params)
293 289 line.save()
294 290
295 291 return redirect('url_edit_rc_conf', conf.id)
296 292
297 293 kwargs = {}
298 294
299 295 kwargs['object'] = line
300 296 kwargs['object_name'] = line.line_type.name
301 297 kwargs['delete_view'] = True
302 298 kwargs['title'] = 'Confirm delete'
303 299
304 300 return render(request, 'confirm.html', kwargs)
305 301
306 302
307 303 def update_lines_position(request, conf_id):
308 304
309 305 conf = get_object_or_404(RCConfiguration, pk=conf_id)
310 306
311 307 if request.method=='POST':
312 308 ch = 0
313 309 for item in request.POST['items'].split('&'):
314 310 line = RCLine.objects.get(pk=item.split('=')[-1])
315 311 line.channel = ch
316 312 line.save()
317 313 ch += 1
318 314
319 315 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
320 316
321 317 for line in lines:
322 318 params = json.loads(line.params)
323 319 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
324 320
325 321 if 'params' in params:
326 322 line.subform = True
327 323 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
328 324
329 325 html = render(request, 'rc_lines.html', {'dev_conf':conf, 'rc_lines':lines, 'edit':True})
330 326 data = {'html': html.content}
331 327
332 328 return HttpResponse(json.dumps(data), content_type="application/json")
333 329 return redirect('url_edit_rc_conf', conf.id)
334 330
335 331
336 332 def import_file(request, conf_id):
337 333
338 334 conf = get_object_or_404(RCConfiguration, pk=conf_id)
339 335 if request.method=='POST':
340 336 form = RCImportForm(request.POST, request.FILES)
341 337 if form.is_valid():
342 338 #try:
343 339 if True:
344 340
345 341 conf.update_from_file(request.FILES['file_name'])
346 342 conf.save()
347 343
348 344 for line in conf.get_lines():
349 345 if line.line_type.name=='tr':
350 346 continue
351 347 line.update_pulses()
352 348
353 349 for tr in conf.get_lines('tr'):
354 350 tr.update_pulses()
355 351
356 352 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
357 353 return redirect(conf.get_absolute_url())
358 354
359 355 #except Exception as e:
360 356 # messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], e))
361 357
362 358 else:
363 359 messages.warning(request, 'Your current configuration will be replaced')
364 360 form = RCImportForm()
365 361
366 362 kwargs = {}
367 363 kwargs['form'] = form
368 364 kwargs['title'] = 'RC Configuration'
369 365 kwargs['suptitle'] = 'Import file'
370 366 kwargs['button'] = 'Upload'
371 367 kwargs['previous'] = conf.get_absolute_url()
372 368
373 369 return render(request, 'rc_import.html', kwargs)
374 370
375 371
376 372 def view_pulses(request, conf_id):
377 373
378 374 conf = get_object_or_404(RCConfiguration, pk=conf_id)
379 375 lines = RCLine.objects.filter(rc_configuration=conf)
380 376
381 377 unit = (conf.clock/conf.clock_divider)*3./20
382 378
383 379 N = int(conf.ipp*(conf.clock/conf.clock_divider)*20./3)*conf.ntx
384 380
385 381 script, div = plot_pulses(unit, N, lines)
386 382
387 383 kwargs = {}
388 384
389 385 kwargs['title'] = 'RC Pulses'
390 386 kwargs['suptitle'] = conf.name
391 387 kwargs['div'] = mark_safe(div)
392 388 kwargs['script'] = mark_safe(script)
393 389
394 390 return render(request, 'rc_pulses.html', kwargs)
395 391
General Comments 0
You need to be logged in to leave comments. Login now