##// END OF EJS Templates
Check for active configuration for status update
Juan C. Espinoza -
r329:7d210f98eba4
parent child
Show More
@@ -1,879 +1,877
1 from django.db import models
1 from django.db import models
2 from apps.main.models import Configuration, User
2 from apps.main.models import Configuration, User
3 from django.core.urlresolvers import reverse
3 from django.core.urlresolvers import reverse
4 from celery.execute import send_task
4 from celery.execute import send_task
5 from datetime import datetime
5 from datetime import datetime
6 import ast
6 import ast
7 import socket
7 import socket
8 import json
8 import json
9 import requests
9 import requests
10 import struct
10 import struct
11 import os, sys, time
11 import os, sys, time
12
12
13 antenna_default = json.dumps({
13 antenna_default = json.dumps({
14 "antenna_up": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
14 "antenna_up": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
15 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
15 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
16 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
16 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
17 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
17 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
18 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
18 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
19 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
19 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
20 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
20 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
21 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0]
21 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0]
22 ]
22 ]
23 ,
23 ,
24 "antenna_down": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
24 "antenna_down": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
25 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
25 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
26 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
26 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
27 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
27 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
28 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
28 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
29 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
29 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
30 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
30 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
31 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0]],
31 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0]],
32 })
32 })
33
33
34
34
35 tx_default = json.dumps({
35 tx_default = json.dumps({
36 "up": [[1,1,1,1,0,0,0,0],
36 "up": [[1,1,1,1,0,0,0,0],
37 [1,1,1,1,0,0,0,0],
37 [1,1,1,1,0,0,0,0],
38 [1,1,1,1,0,0,0,0],
38 [1,1,1,1,0,0,0,0],
39 [1,1,1,1,0,0,0,0],
39 [1,1,1,1,0,0,0,0],
40 [0,0,0,0,1,1,1,1],
40 [0,0,0,0,1,1,1,1],
41 [0,0,0,0,1,1,1,1],
41 [0,0,0,0,1,1,1,1],
42 [0,0,0,0,1,1,1,1],
42 [0,0,0,0,1,1,1,1],
43 [0,0,0,0,1,1,1,1]],
43 [0,0,0,0,1,1,1,1]],
44
44
45 "down": [[1,1,1,1,0,0,0,0],
45 "down": [[1,1,1,1,0,0,0,0],
46 [1,1,1,1,0,0,0,0],
46 [1,1,1,1,0,0,0,0],
47 [1,1,1,1,0,0,0,0],
47 [1,1,1,1,0,0,0,0],
48 [1,1,1,1,0,0,0,0],
48 [1,1,1,1,0,0,0,0],
49 [0,0,0,0,1,1,1,1],
49 [0,0,0,0,1,1,1,1],
50 [0,0,0,0,1,1,1,1],
50 [0,0,0,0,1,1,1,1],
51 [0,0,0,0,1,1,1,1],
51 [0,0,0,0,1,1,1,1],
52 [0,0,0,0,1,1,1,1]],
52 [0,0,0,0,1,1,1,1]],
53 })
53 })
54
54
55 rx_default = json.dumps({
55 rx_default = json.dumps({
56 "up": [[1,1,1,1,0,0,0,0],
56 "up": [[1,1,1,1,0,0,0,0],
57 [1,1,1,1,0,0,0,0],
57 [1,1,1,1,0,0,0,0],
58 [1,1,1,1,0,0,0,0],
58 [1,1,1,1,0,0,0,0],
59 [1,1,1,1,0,0,0,0],
59 [1,1,1,1,0,0,0,0],
60 [0,0,0,0,1,1,1,1],
60 [0,0,0,0,1,1,1,1],
61 [0,0,0,0,1,1,1,1],
61 [0,0,0,0,1,1,1,1],
62 [0,0,0,0,1,1,1,1],
62 [0,0,0,0,1,1,1,1],
63 [0,0,0,0,1,1,1,1]],
63 [0,0,0,0,1,1,1,1]],
64
64
65 "down": [[1,1,1,1,0,0,0,0],
65 "down": [[1,1,1,1,0,0,0,0],
66 [1,1,1,1,0,0,0,0],
66 [1,1,1,1,0,0,0,0],
67 [1,1,1,1,0,0,0,0],
67 [1,1,1,1,0,0,0,0],
68 [1,1,1,1,0,0,0,0],
68 [1,1,1,1,0,0,0,0],
69 [0,0,0,0,1,1,1,1],
69 [0,0,0,0,1,1,1,1],
70 [0,0,0,0,1,1,1,1],
70 [0,0,0,0,1,1,1,1],
71 [0,0,0,0,1,1,1,1],
71 [0,0,0,0,1,1,1,1],
72 [0,0,0,0,1,1,1,1]],
72 [0,0,0,0,1,1,1,1]],
73 })
73 })
74
74
75 status_default = '0000000000000000000000000000000000000000000000000000000000000000'
75 status_default = '0000000000000000000000000000000000000000000000000000000000000000'
76 default_messages = {}
76 default_messages = {}
77
77
78 for i in range(1,65):
78 for i in range(1,65):
79 default_messages[str(i)] = "Module "+str(i)
79 default_messages[str(i)] = "Module "+str(i)
80
80
81
81
82 ues_default = json.dumps({
82 ues_default = json.dumps({
83 "up": [0.533333,0.00000,1.06667,0.00000],
83 "up": [0.533333,0.00000,1.06667,0.00000],
84 "down": [0.533333,0.00000,1.06667,0.00000]
84 "down": [0.533333,0.00000,1.06667,0.00000]
85 })
85 })
86
86
87 onlyrx_default = json.dumps({
87 onlyrx_default = json.dumps({
88 "up": False,
88 "up": False,
89 "down": False
89 "down": False
90 })
90 })
91
91
92 def up_convertion(cadena):
92 def up_convertion(cadena):
93 valores = []
93 valores = []
94 for c in cadena:
94 for c in cadena:
95 if c == 1.0: valores=valores+['000']
95 if c == 1.0: valores=valores+['000']
96 if c == 2.0: valores=valores+['001']
96 if c == 2.0: valores=valores+['001']
97 if c == 3.0: valores=valores+['010']
97 if c == 3.0: valores=valores+['010']
98 if c == 0.0: valores=valores+['011']
98 if c == 0.0: valores=valores+['011']
99 if c == 0.5: valores=valores+['100']
99 if c == 0.5: valores=valores+['100']
100 if c == 1.5: valores=valores+['101']
100 if c == 1.5: valores=valores+['101']
101 if c == 2.5: valores=valores+['110']
101 if c == 2.5: valores=valores+['110']
102 if c == 3.5: valores=valores+['111']
102 if c == 3.5: valores=valores+['111']
103
103
104 return valores
104 return valores
105
105
106 def up_conv_bits(value):
106 def up_conv_bits(value):
107
107
108 if value == 1.0: bits="000"
108 if value == 1.0: bits="000"
109 if value == 2.0: bits="001"
109 if value == 2.0: bits="001"
110 if value == 3.0: bits="010"
110 if value == 3.0: bits="010"
111 if value == 0.0: bits="011"
111 if value == 0.0: bits="011"
112 if value == 0.5: bits="100"
112 if value == 0.5: bits="100"
113 if value == 1.5: bits="101"
113 if value == 1.5: bits="101"
114 if value == 2.5: bits="110"
114 if value == 2.5: bits="110"
115 if value == 3.5: bits="111"
115 if value == 3.5: bits="111"
116
116
117 return bits
117 return bits
118
118
119 def down_convertion(cadena):
119 def down_convertion(cadena):
120 valores = []
120 valores = []
121 for c in cadena:
121 for c in cadena:
122 if c == 1.0: valores=valores+['000']
122 if c == 1.0: valores=valores+['000']
123 if c == 2.0: valores=valores+['001']
123 if c == 2.0: valores=valores+['001']
124 if c == 3.0: valores=valores+['010']
124 if c == 3.0: valores=valores+['010']
125 if c == 0.0: valores=valores+['011']
125 if c == 0.0: valores=valores+['011']
126 if c == 0.5: valores=valores+['100']
126 if c == 0.5: valores=valores+['100']
127 if c == 1.5: valores=valores+['101']
127 if c == 1.5: valores=valores+['101']
128 if c == 2.5: valores=valores+['110']
128 if c == 2.5: valores=valores+['110']
129 if c == 3.5: valores=valores+['111']
129 if c == 3.5: valores=valores+['111']
130
130
131 return valores
131 return valores
132
132
133 def down_conv_bits(value):
133 def down_conv_bits(value):
134
134
135 if value == 1.0: bits="000"
135 if value == 1.0: bits="000"
136 if value == 2.0: bits="001"
136 if value == 2.0: bits="001"
137 if value == 3.0: bits="010"
137 if value == 3.0: bits="010"
138 if value == 0.0: bits="011"
138 if value == 0.0: bits="011"
139 if value == 0.5: bits="100"
139 if value == 0.5: bits="100"
140 if value == 1.5: bits="101"
140 if value == 1.5: bits="101"
141 if value == 2.5: bits="110"
141 if value == 2.5: bits="110"
142 if value == 3.5: bits="111"
142 if value == 3.5: bits="111"
143
143
144 return bits
144 return bits
145
145
146 def up_conv_value(bits):
146 def up_conv_value(bits):
147
147
148 if bits == "000": value=1.0
148 if bits == "000": value=1.0
149 if bits == "001": value=2.0
149 if bits == "001": value=2.0
150 if bits == "010": value=3.0
150 if bits == "010": value=3.0
151 if bits == "011": value=0.0
151 if bits == "011": value=0.0
152 if bits == "100": value=0.5
152 if bits == "100": value=0.5
153 if bits == "101": value=1.5
153 if bits == "101": value=1.5
154 if bits == "110": value=2.5
154 if bits == "110": value=2.5
155 if bits == "111": value=3.5
155 if bits == "111": value=3.5
156
156
157 return value
157 return value
158
158
159 def down_conv_value(bits):
159 def down_conv_value(bits):
160
160
161 if bits == "000": value=1.0
161 if bits == "000": value=1.0
162 if bits == "001": value=2.0
162 if bits == "001": value=2.0
163 if bits == "010": value=3.0
163 if bits == "010": value=3.0
164 if bits == "011": value=0.0
164 if bits == "011": value=0.0
165 if bits == "100": value=0.5
165 if bits == "100": value=0.5
166 if bits == "101": value=1.5
166 if bits == "101": value=1.5
167 if bits == "110": value=2.5
167 if bits == "110": value=2.5
168 if bits == "111": value=3.5
168 if bits == "111": value=3.5
169
169
170 return value
170 return value
171
171
172 def ip2position(module_number):
172 def ip2position(module_number):
173 j=0
173 j=0
174 i=0
174 i=0
175 for x in range(0,module_number-1):
175 for x in range(0,module_number-1):
176 j=j+1
176 j=j+1
177 if j==8:
177 if j==8:
178 i=i+1
178 i=i+1
179 j=0
179 j=0
180
180
181 pos = [i,j]
181 pos = [i,j]
182 return pos
182 return pos
183
183
184
184
185 def fromBinary2Char(binary_string):
185 def fromBinary2Char(binary_string):
186 number = int(binary_string, 2)
186 number = int(binary_string, 2)
187 #Plus 33 to avoid more than 1 characters values such as: '\x01'-'\x1f'
187 #Plus 33 to avoid more than 1 characters values such as: '\x01'-'\x1f'
188 number = number + 33
188 number = number + 33
189 char = chr(number)
189 char = chr(number)
190 return char
190 return char
191
191
192 def fromChar2Binary(char):
192 def fromChar2Binary(char):
193 number = ord(char) - 33
193 number = ord(char) - 33
194 #Minus 33 to get the real value
194 #Minus 33 to get the real value
195 bits = bin(number)[2:]
195 bits = bin(number)[2:]
196 #To ensure we have a string with 6bits
196 #To ensure we have a string with 6bits
197 if len(bits) < 6:
197 if len(bits) < 6:
198 bits = bits.zfill(6)
198 bits = bits.zfill(6)
199 return bits
199 return bits
200
200
201 OPERATION_MODES = (
201 OPERATION_MODES = (
202 (0, 'Manual'),
202 (0, 'Manual'),
203 (1, 'Automatic'),
203 (1, 'Automatic'),
204 )
204 )
205
205
206
206
207 class ABSConfiguration(Configuration):
207 class ABSConfiguration(Configuration):
208 active_beam = models.PositiveSmallIntegerField(verbose_name='Active Beam', default=0)
208 active_beam = models.PositiveSmallIntegerField(verbose_name='Active Beam', default=0)
209 module_status = models.CharField(verbose_name='Module Status', max_length=10000, default=status_default)
209 module_status = models.CharField(verbose_name='Module Status', max_length=10000, default=status_default)
210 operation_mode = models.PositiveSmallIntegerField(verbose_name='Operation Mode', choices=OPERATION_MODES, default = 0)
210 operation_mode = models.PositiveSmallIntegerField(verbose_name='Operation Mode', choices=OPERATION_MODES, default = 0)
211 operation_value = models.FloatField(verbose_name='Periodic (seconds)', default="10", null=True, blank=True)
211 operation_value = models.FloatField(verbose_name='Periodic (seconds)', default="10", null=True, blank=True)
212 module_messages = models.CharField(verbose_name='Modules Messages', max_length=10000, default=json.dumps(default_messages))
212 module_messages = models.CharField(verbose_name='Modules Messages', max_length=10000, default=json.dumps(default_messages))
213
213
214 class Meta:
214 class Meta:
215 db_table = 'abs_configurations'
215 db_table = 'abs_configurations'
216
216
217 def get_absolute_url_plot(self):
217 def get_absolute_url_plot(self):
218 return reverse('url_plot_abs_patterns', args=[str(self.id)])
218 return reverse('url_plot_abs_patterns', args=[str(self.id)])
219
219
220
220
221 def parms_to_dict(self):
221 def parms_to_dict(self):
222
222
223 parameters = {}
223 parameters = {}
224
224
225 parameters['device_id'] = self.device.id
225 parameters['device_id'] = self.device.id
226 parameters['label'] = self.label
226 parameters['label'] = self.label
227 parameters['device_type'] = self.device.device_type.name
227 parameters['device_type'] = self.device.device_type.name
228 parameters['beams'] = {}
228 parameters['beams'] = {}
229
229
230 beams = ABSBeam.objects.filter(abs_conf=self)
230 beams = ABSBeam.objects.filter(abs_conf=self)
231 b=1
231 b=1
232 for beam in beams:
232 for beam in beams:
233 #absbeam = ABSBeam.objects.get(pk=beams[beam])
233 #absbeam = ABSBeam.objects.get(pk=beams[beam])
234 parameters['beams']['beam'+str(b)] = beam.parms_to_dict()#absbeam.parms_to_dict()
234 parameters['beams']['beam'+str(b)] = beam.parms_to_dict()#absbeam.parms_to_dict()
235 b+=1
235 b+=1
236
236
237 return parameters
237 return parameters
238
238
239
239
240 def dict_to_parms(self, parameters):
240 def dict_to_parms(self, parameters):
241
241
242 self.label = parameters['label']
242 self.label = parameters['label']
243
243
244 absbeams = ABSBeam.objects.filter(abs_conf=self)
244 absbeams = ABSBeam.objects.filter(abs_conf=self)
245 beams = parameters['beams']
245 beams = parameters['beams']
246
246
247 if absbeams:
247 if absbeams:
248 beams_number = len(beams)
248 beams_number = len(beams)
249 absbeams_number = len(absbeams)
249 absbeams_number = len(absbeams)
250 if beams_number==absbeams_number:
250 if beams_number==absbeams_number:
251 i = 1
251 i = 1
252 for absbeam in absbeams:
252 for absbeam in absbeams:
253 absbeam.dict_to_parms(beams['beam'+str(i)])
253 absbeam.dict_to_parms(beams['beam'+str(i)])
254 i = i+1
254 i = i+1
255 elif beams_number > absbeams_number:
255 elif beams_number > absbeams_number:
256 i = 1
256 i = 1
257 for absbeam in absbeams:
257 for absbeam in absbeams:
258 absbeam.dict_to_parms(beams['beam'+str(i)])
258 absbeam.dict_to_parms(beams['beam'+str(i)])
259 i=i+1
259 i=i+1
260 for x in range(i,beams_number+1):
260 for x in range(i,beams_number+1):
261 new_beam = ABSBeam(
261 new_beam = ABSBeam(
262 name =beams['beam'+str(i)]['name'],
262 name =beams['beam'+str(i)]['name'],
263 antenna =json.dumps(beams['beam'+str(i)]['antenna']),
263 antenna =json.dumps(beams['beam'+str(i)]['antenna']),
264 abs_conf = self,
264 abs_conf = self,
265 tx =json.dumps(beams['beam'+str(i)]['tx']),
265 tx =json.dumps(beams['beam'+str(i)]['tx']),
266 rx =json.dumps(beams['beam'+str(i)]['rx']),
266 rx =json.dumps(beams['beam'+str(i)]['rx']),
267 ues =json.dumps(beams['beam'+str(i)]['ues']),
267 ues =json.dumps(beams['beam'+str(i)]['ues']),
268 only_rx =json.dumps(beams['beam'+str(i)]['only_rx'])
268 only_rx =json.dumps(beams['beam'+str(i)]['only_rx'])
269 )
269 )
270 new_beam.save()
270 new_beam.save()
271 i=i+1
271 i=i+1
272 else: #beams_number < absbeams_number:
272 else: #beams_number < absbeams_number:
273 i = 1
273 i = 1
274 for absbeam in absbeams:
274 for absbeam in absbeams:
275 if i <= beams_number:
275 if i <= beams_number:
276 absbeam.dict_to_parms(beams['beam'+str(i)])
276 absbeam.dict_to_parms(beams['beam'+str(i)])
277 i=i+1
277 i=i+1
278 else:
278 else:
279 absbeam.delete()
279 absbeam.delete()
280 else:
280 else:
281 for beam in beams:
281 for beam in beams:
282 new_beam = ABSBeam(
282 new_beam = ABSBeam(
283 name =beams[beam]['name'],
283 name =beams[beam]['name'],
284 antenna =json.dumps(beams[beam]['antenna']),
284 antenna =json.dumps(beams[beam]['antenna']),
285 abs_conf = self,
285 abs_conf = self,
286 tx =json.dumps(beams[beam]['tx']),
286 tx =json.dumps(beams[beam]['tx']),
287 rx =json.dumps(beams[beam]['rx']),
287 rx =json.dumps(beams[beam]['rx']),
288 ues =json.dumps(beams[beam]['ues']),
288 ues =json.dumps(beams[beam]['ues']),
289 only_rx =json.dumps(beams[beam]['only_rx'])
289 only_rx =json.dumps(beams[beam]['only_rx'])
290 )
290 )
291 new_beam.save()
291 new_beam.save()
292
292
293
293
294
294
295 def update_from_file(self, parameters):
295 def update_from_file(self, parameters):
296
296
297 self.dict_to_parms(parameters)
297 self.dict_to_parms(parameters)
298 self.save()
298 self.save()
299
299
300
300
301 def get_beams(self, **kwargs):
301 def get_beams(self, **kwargs):
302 '''
302 '''
303 This function returns ABS Configuration beams
303 This function returns ABS Configuration beams
304 '''
304 '''
305 return ABSBeam.objects.filter(abs_conf=self.pk, **kwargs)
305 return ABSBeam.objects.filter(abs_conf=self.pk, **kwargs)
306
306
307 def clone(self, **kwargs):
307 def clone(self, **kwargs):
308
308
309 beams = self.get_beams()
309 beams = self.get_beams()
310 self.pk = None
310 self.pk = None
311 self.id = None
311 self.id = None
312 for attr, value in kwargs.items():
312 for attr, value in kwargs.items():
313 setattr(self, attr, value)
313 setattr(self, attr, value)
314 self.save()
314 self.save()
315
315
316 for beam in beams:
316 for beam in beams:
317 beam.clone(abs_conf=self)
317 beam.clone(abs_conf=self)
318
318
319 #-----For Active Beam-----
319 #-----For Active Beam-----
320 new_beams = ABSBeam.objects.filter(abs_conf=self)
320 new_beams = ABSBeam.objects.filter(abs_conf=self)
321 self.active_beam = new_beams[0].id
321 self.active_beam = new_beams[0].id
322 self.save()
322 self.save()
323 #-----For Active Beam-----
323 #-----For Active Beam-----
324 #-----For Device Status---
324 #-----For Device Status---
325 self.device.status = 3
325 self.device.status = 3
326 self.device.save()
326 self.device.save()
327 #-----For Device Status---
327 #-----For Device Status---
328
328
329 return self
329 return self
330
330
331
331
332 def start_device(self):
332 def start_device(self):
333
333
334 if self.device.status == 3:
334 if self.device.status == 3:
335
335
336 try:
336 try:
337 #self.write_device()
337 #self.write_device()
338 send_task('task_change_beam', [self.id],)
338 send_task('task_change_beam', [self.id],)
339 self.message = 'ABS running'
339 self.message = 'ABS running'
340
340
341 except Exception as e:
341 except Exception as e:
342 self.message = str(e)
342 self.message = str(e)
343 return False
343 return False
344
344
345 return True
345 return True
346
346
347 else:
347 else:
348 self.message = 'Please, select Write ABS Device first.'
348 self.message = 'Please, select Write ABS Device first.'
349 return False
349 return False
350
350
351
351
352 def stop_device(self):
352 def stop_device(self):
353
353
354 self.device.status = 2
354 self.device.status = 2
355 self.device.save()
355 self.device.save()
356 self.message = 'ABS has been stopped.'
356 self.message = 'ABS has been stopped.'
357 self.save()
357 self.save()
358
358
359 return True
359 return True
360
360
361
361
362 def write_device(self):
362 def write_device(self):
363
363
364 """
364 """
365 This function sends the beams list to every abs module.
365 This function sends the beams list to every abs module.
366 It needs 'module_conf' function
366 It needs 'module_conf' function
367 """
367 """
368
368
369 beams = ABSBeam.objects.filter(abs_conf=self)
369 beams = ABSBeam.objects.filter(abs_conf=self)
370 nbeams = len(beams)
370 nbeams = len(beams)
371 if self.connected_modules() == 0 :
371 if self.connected_modules() == 0 :
372 self.message = "No ABS Module detected."
372 self.message = "No ABS Module detected."
373 return False
373 return False
374
374
375 #-------------Write each abs module-----------
375 #-------------Write each abs module-----------
376
376
377 if beams:
377 if beams:
378 block_id = 0
378 block_id = 0
379 message = 'SNDF{:03d}{:02d}{:02d}'.format(nbeams, nbeams, block_id)
379 message = 'SNDF{:03d}{:02d}{:02d}'.format(nbeams, nbeams, block_id)
380 for i, status in enumerate(self.module_status):
380 for i, status in enumerate(self.module_status):
381 message += ''.join([fromBinary2Char(beam.module_6bits(i)) for beam in beams])
381 message += ''.join([fromBinary2Char(beam.module_6bits(i)) for beam in beams])
382 status = ['0'] * 64
382 status = ['0'] * 64
383 n = 0
383 n = 0
384
384
385 sock = self.send_multicast(message)
385 sock = self.send_multicast(message)
386
386
387 for i in range(32):
387 for i in range(32):
388 try:
388 try:
389 data, address = sock.recvfrom(1024)
389 data, address = sock.recvfrom(1024)
390 print address, data
390 print address, data
391 if data == '1':
391 if data == '1':
392 status[int(address[0][10:])-1] = '3'
392 status[int(address[0][10:])-1] = '3'
393 elif data == '0':
393 elif data == '0':
394 status[int(address[0][10:])-1] = '1'
394 status[int(address[0][10:])-1] = '1'
395 except Exception as e:
395 except Exception as e:
396 print 'Error {}'.format(e)
396 print 'Error {}'.format(e)
397 n += 1
397 n += 1
398 sock.close()
398 sock.close()
399 else:
399 else:
400 self.message = "ABS Configuration does not have beams"
400 self.message = "ABS Configuration does not have beams"
401 return False
401 return False
402
402
403 if n == 64:
403 if n == 64:
404 self.message = "Could not write ABS Modules"
404 self.message = "Could not write ABS Modules"
405 self.device.status = 0
405 self.device.status = 0
406 self.module_status = ''.join(status)
406 self.module_status = ''.join(status)
407 self.save()
407 self.save()
408 return False
408 return False
409 else:
409 else:
410 self.message = "ABS Beams List have been sent to ABS Modules"
410 self.message = "ABS Beams List have been sent to ABS Modules"
411 self.active_beam = beams[0].pk
411 self.active_beam = beams[0].pk
412
412
413 self.device.status = 3
413 self.device.status = 3
414 self.module_status = ''.join(status)
414 self.module_status = ''.join(status)
415 self.save()
415 self.save()
416 for u in User.objects.all():
416
417 u.profile.abs_active = self
418 u.save()
419 return True
417 return True
420
418
421
419
422 def read_module(self, module):
420 def read_module(self, module):
423
421
424 """
422 """
425 Read out-bits (up-down) of 1 abs module NOT for Configuration
423 Read out-bits (up-down) of 1 abs module NOT for Configuration
426 """
424 """
427
425
428 ip_address = self.device.ip_address
426 ip_address = self.device.ip_address
429 ip_address = ip_address.split('.')
427 ip_address = ip_address.split('.')
430 module_seq = (ip_address[0],ip_address[1],ip_address[2])
428 module_seq = (ip_address[0],ip_address[1],ip_address[2])
431 dot = '.'
429 dot = '.'
432 module_ip = dot.join(module_seq)+'.'+str(module)
430 module_ip = dot.join(module_seq)+'.'+str(module)
433 module_port = self.device.port_address
431 module_port = self.device.port_address
434 read_route = 'http://'+module_ip+':'+str(module_port)+'/read'
432 read_route = 'http://'+module_ip+':'+str(module_port)+'/read'
435
433
436 module_status = json.loads(self.module_status)
434 module_status = json.loads(self.module_status)
437 print(read_route)
435 print(read_route)
438
436
439 module_bits = ''
437 module_bits = ''
440
438
441 try:
439 try:
442 r_read = requests.get(read_route, timeout=0.5)
440 r_read = requests.get(read_route, timeout=0.5)
443 answer = r_read.json()
441 answer = r_read.json()
444 module_bits = answer['allbits']
442 module_bits = answer['allbits']
445 except:
443 except:
446 return {}
444 return {}
447
445
448 return module_bits
446 return module_bits
449
447
450 def read_device(self):
448 def read_device(self):
451
449
452 parms = {}
450 parms = {}
453 # Reads active modules.
451 # Reads active modules.
454 module_status = json.loads(self.module_status)
452 module_status = json.loads(self.module_status)
455 total = 0
453 total = 0
456 for status in module_status:
454 for status in module_status:
457 if module_status[status] != 0:
455 if module_status[status] != 0:
458 module_bits = self.read_module(int(status))
456 module_bits = self.read_module(int(status))
459 bits={}
457 bits={}
460 if module_bits:
458 if module_bits:
461 bits = (str(module_bits['um2']) + str(module_bits['um1']) + str(module_bits['um0']) +
459 bits = (str(module_bits['um2']) + str(module_bits['um1']) + str(module_bits['um0']) +
462 str(module_bits['dm2']) + str(module_bits['dm1']) + str(module_bits['dm0']) )
460 str(module_bits['dm2']) + str(module_bits['dm1']) + str(module_bits['dm0']) )
463 parms[str(status)] = bits
461 parms[str(status)] = bits
464
462
465 total +=1
463 total +=1
466
464
467 if total==0:
465 if total==0:
468 self.message = "No ABS Module detected. Please select 'Status'."
466 self.message = "No ABS Module detected. Please select 'Status'."
469 return False
467 return False
470
468
471
469
472
470
473 self.message = "ABS Modules have been read"
471 self.message = "ABS Modules have been read"
474 #monitoreo_tx = JROABSClnt_01CeCnMod000000MNTR10
472 #monitoreo_tx = JROABSClnt_01CeCnMod000000MNTR10
475 return parms
473 return parms
476
474
477
475
478 def connected_modules(self):
476 def connected_modules(self):
479 """
477 """
480 This function returns the number of connected abs-modules without updating.
478 This function returns the number of connected abs-modules without updating.
481 """
479 """
482 num = 0
480 num = 0
483 print(self.module_status)
481 print(self.module_status)
484 for i, status in enumerate(self.module_status):
482 for i, status in enumerate(self.module_status):
485 if status != '0':
483 if status != '0':
486 num += 1
484 num += 1
487 #print('status {}:{}'.format(i+1, status))
485 #print('status {}:{}'.format(i+1, status))
488 return num
486 return num
489
487
490 def send_multicast(self, message):
488 def send_multicast(self, message):
491
489
492 multicast_group = ('224.3.29.71', 10000)
490 multicast_group = ('224.3.29.71', 10000)
493 # Create the datagram socket
491 # Create the datagram socket
494 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
492 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
495 sock.settimeout(1)
493 sock.settimeout(1)
496 local_ip = os.environ.get('LOCAL_IP', '127.0.0.1')
494 local_ip = os.environ.get('LOCAL_IP', '127.0.0.1')
497 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip))
495 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip))
498 sock.sendto(message, multicast_group)
496 sock.sendto(message, multicast_group)
499 print('Sending ' + message)
497 print('Sending ' + message)
500 return sock
498 return sock
501
499
502 def status_device(self):
500 def status_device(self):
503 """
501 """
504 This function returns the status of all abs-modules as one.
502 This function returns the status of all abs-modules as one.
505 If at least one module is connected, its answer is "1"
503 If at least one module is connected, its answer is "1"
506 """
504 """
507
505
508 sock = self.send_multicast('MNTR')
506 sock = self.send_multicast('MNTR')
509
507
510 n = 0
508 n = 0
511 status = ['0'] * 64
509 status = ['0'] * 64
512 for i in range(32):
510 for i in range(32):
513 #if True:
511 #if True:
514 try:
512 try:
515 address = None
513 address = None
516 data, address = sock.recvfrom(1024)
514 data, address = sock.recvfrom(1024)
517 x = int(address[0][10:])-1
515 x = int(address[0][10:])-1
518 if data[0] == '1':
516 if data[0] == '1':
519 remote = fromChar2Binary(data[1])
517 remote = fromChar2Binary(data[1])
520 local = ABSBeam.objects.get(pk=self.active_beam).module_6bits(x)
518 local = ABSBeam.objects.get(pk=self.active_beam).module_6bits(x)
521 if local == remote:
519 if local == remote:
522 status[x] = '3'
520 status[x] = '3'
523 print('Module: {} connected...igual'.format(address))
521 print('Module: {} connected...igual'.format(address))
524 else:
522 else:
525 status[x] = '2'
523 status[x] = '2'
526 print('Module: {} connected...diferente'.format(address))
524 print('Module: {} connected...diferente'.format(address))
527 elif data[0] == '0':
525 elif data[0] == '0':
528 status[x] = '1'
526 status[x] = '1'
529 n += 1
527 n += 1
530 except:
528 except:
531 print('Module: {} error'.format(address))
529 print('Module: {} error'.format(address))
532 pass
530 pass
533 sock.close()
531 sock.close()
534
532
535 if n > 0:
533 if n > 0:
536 self.message = 'ABS modules Status have been updated.'
534 self.message = 'ABS modules Status have been updated.'
537 self.device.status = 1
535 self.device.status = 1
538 else:
536 else:
539 self.device.status = 0
537 self.device.status = 0
540 self.message = 'No ABS module is connected.'
538 self.message = 'No ABS module is connected.'
541 self.module_status = ''.join(status)
539 self.module_status = ''.join(status)
542 self.save()
540 self.save()
543
541
544 return self.device.status
542 return self.device.status
545
543
546
544
547 def send_beam(self, beam_pos):
545 def send_beam(self, beam_pos):
548 """
546 """
549 This function connects to a multicast group and sends the beam number
547 This function connects to a multicast group and sends the beam number
550 to all abs modules.
548 to all abs modules.
551 """
549 """
552
550
553 # Se manda a cero RC para poder realizar cambio de beam
551 # Se manda a cero RC para poder realizar cambio de beam
554 if self.experiment is None:
552 if self.experiment is None:
555 confs = []
553 confs = []
556 else:
554 else:
557 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
555 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
558 confdds = ''
556 confdds = ''
559 confjars = ''
557 confjars = ''
560 confrc = ''
558 confrc = ''
561 #TO STOP DEVICES: DDS-JARS-RC
559 #TO STOP DEVICES: DDS-JARS-RC
562 for i in range(0,len(confs)):
560 for i in range(0,len(confs)):
563 if i==0:
561 if i==0:
564 for conf in confs:
562 for conf in confs:
565 if conf.device.device_type.name == 'dds':
563 if conf.device.device_type.name == 'dds':
566 confdds = conf
564 confdds = conf
567 confdds.stop_device()
565 confdds.stop_device()
568 break
566 break
569 if i==1:
567 if i==1:
570 for conf in confs:
568 for conf in confs:
571 if conf.device.device_type.name == 'jars':
569 if conf.device.device_type.name == 'jars':
572 confjars = conf
570 confjars = conf
573 confjars.stop_device()
571 confjars.stop_device()
574 break
572 break
575 if i==2:
573 if i==2:
576 for conf in confs:
574 for conf in confs:
577 if conf.device.device_type.name == 'rc':
575 if conf.device.device_type.name == 'rc':
578 confrc = conf
576 confrc = conf
579 confrc.stop_device()
577 confrc.stop_device()
580 break
578 break
581 if beam_pos > 0:
579 if beam_pos > 0:
582 beam_pos = beam_pos - 1
580 beam_pos = beam_pos - 1
583 else:
581 else:
584 beam_pos = 0
582 beam_pos = 0
585
583
586 #El indice del apunte debe ser menor que el numero total de apuntes
584 #El indice del apunte debe ser menor que el numero total de apuntes
587 #El servidor tcp en el embebido comienza a contar desde 0
585 #El servidor tcp en el embebido comienza a contar desde 0
588 status = ['0'] * 64
586 status = ['0'] * 64
589 message = 'CHGB{}'.format(beam_pos)
587 message = 'CHGB{}'.format(beam_pos)
590 sock = self.send_multicast(message)
588 sock = self.send_multicast(message)
591 for i in range(32):
589 for i in range(32):
592 try:
590 try:
593 data, address = sock.recvfrom(1024)
591 data, address = sock.recvfrom(1024)
594 print address, data
592 print address, data
595 if data == '1':
593 if data == '1':
596 status[int(address[0][10:])-1] = '3'
594 status[int(address[0][10:])-1] = '3'
597 elif data == '0':
595 elif data == '0':
598 status[int(address[0][10:])-1] = '1'
596 status[int(address[0][10:])-1] = '1'
599 except Exception as e:
597 except Exception as e:
600 print 'Error {}'.format(e)
598 print 'Error {}'.format(e)
601 pass
599 pass
602
600
603 sock.close()
601 sock.close()
604
602
605 #Start DDS-RC-JARS
603 #Start DDS-RC-JARS
606 if confdds:
604 if confdds:
607 confdds.start_device()
605 confdds.start_device()
608 if confrc:
606 if confrc:
609 #print confrc
607 #print confrc
610 confrc.start_device()
608 confrc.start_device()
611 if confjars:
609 if confjars:
612 confjars.start_device()
610 confjars.start_device()
613
611
614 self.message = "ABS Beam has been changed"
612 self.message = "ABS Beam has been changed"
615 self.module_status = ''.join(status)
613 self.module_status = ''.join(status)
616 self.save()
614 self.save()
617 return True
615 return True
618
616
619
617
620 def get_absolute_url_import(self):
618 def get_absolute_url_import(self):
621 return reverse('url_import_abs_conf', args=[str(self.id)])
619 return reverse('url_import_abs_conf', args=[str(self.id)])
622
620
623
621
624 class ABSBeam(models.Model):
622 class ABSBeam(models.Model):
625
623
626 name = models.CharField(max_length=60, default='Beam')
624 name = models.CharField(max_length=60, default='Beam')
627 antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default)
625 antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default)
628 abs_conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration')
626 abs_conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration')
629 tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default)
627 tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default)
630 rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default)
628 rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default)
631 s_time = models.TimeField(verbose_name='Star Time', default='00:00:00')
629 s_time = models.TimeField(verbose_name='Star Time', default='00:00:00')
632 e_time = models.TimeField(verbose_name='End Time', default='23:59:59')
630 e_time = models.TimeField(verbose_name='End Time', default='23:59:59')
633 ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default)
631 ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default)
634 only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default)
632 only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default)
635
633
636 class Meta:
634 class Meta:
637 db_table = 'abs_beams'
635 db_table = 'abs_beams'
638
636
639 def __unicode__(self):
637 def __unicode__(self):
640 return u'%s' % (self.name)
638 return u'%s' % (self.name)
641
639
642 def parms_to_dict(self):
640 def parms_to_dict(self):
643
641
644 parameters = {}
642 parameters = {}
645 parameters['name'] = self.name
643 parameters['name'] = self.name
646 parameters['antenna'] = ast.literal_eval(self.antenna)
644 parameters['antenna'] = ast.literal_eval(self.antenna)
647 parameters['abs_conf'] = self.abs_conf.name
645 parameters['abs_conf'] = self.abs_conf.name
648 parameters['tx'] = ast.literal_eval(self.tx)
646 parameters['tx'] = ast.literal_eval(self.tx)
649 parameters['rx'] = ast.literal_eval(self.rx)
647 parameters['rx'] = ast.literal_eval(self.rx)
650 parameters['s_time'] = self.s_time.strftime("%H:%M:%S")
648 parameters['s_time'] = self.s_time.strftime("%H:%M:%S")
651 parameters['e_time'] = self.e_time.strftime("%H:%M:%S")
649 parameters['e_time'] = self.e_time.strftime("%H:%M:%S")
652 parameters['ues'] = ast.literal_eval(self.ues)
650 parameters['ues'] = ast.literal_eval(self.ues)
653 parameters['only_rx'] = json.loads(self.only_rx)
651 parameters['only_rx'] = json.loads(self.only_rx)
654
652
655 return parameters
653 return parameters
656
654
657 def dict_to_parms(self, parameters):
655 def dict_to_parms(self, parameters):
658
656
659 self.name = parameters['name']
657 self.name = parameters['name']
660 self.antenna = json.dumps(parameters['antenna'])
658 self.antenna = json.dumps(parameters['antenna'])
661 #self.abs_conf = parameters['abs_conf']
659 #self.abs_conf = parameters['abs_conf']
662 self.tx = json.dumps(parameters['tx'])
660 self.tx = json.dumps(parameters['tx'])
663 self.rx = json.dumps(parameters['rx'])
661 self.rx = json.dumps(parameters['rx'])
664 #self.s_time = parameters['s_time']
662 #self.s_time = parameters['s_time']
665 #self.e_time = parameters['e_time']
663 #self.e_time = parameters['e_time']
666 self.ues = json.dumps(parameters['ues'])
664 self.ues = json.dumps(parameters['ues'])
667 self.only_rx = json.dumps(parameters['only_rx'])
665 self.only_rx = json.dumps(parameters['only_rx'])
668 self.save()
666 self.save()
669
667
670
668
671 def clone(self, **kwargs):
669 def clone(self, **kwargs):
672
670
673 self.pk = None
671 self.pk = None
674 self.id = None
672 self.id = None
675 for attr, value in kwargs.items():
673 for attr, value in kwargs.items():
676 setattr(self, attr, value)
674 setattr(self, attr, value)
677
675
678 self.save()
676 self.save()
679
677
680 return self
678 return self
681
679
682
680
683 def module_6bits(self, module):
681 def module_6bits(self, module):
684 """
682 """
685 This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module
683 This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module
686 """
684 """
687 module += 1
685 module += 1
688 if module > 64:
686 if module > 64:
689 beam_bits = ""
687 beam_bits = ""
690 return beam_bits
688 return beam_bits
691
689
692 data = ast.literal_eval(self.antenna)
690 data = ast.literal_eval(self.antenna)
693 up_data = data['antenna_up']
691 up_data = data['antenna_up']
694 down_data = data['antenna_down']
692 down_data = data['antenna_down']
695
693
696 pos = ip2position(module)
694 pos = ip2position(module)
697 up_value = up_data[pos[0]][pos[1]]
695 up_value = up_data[pos[0]][pos[1]]
698 down_value = down_data[pos[0]][pos[1]]
696 down_value = down_data[pos[0]][pos[1]]
699
697
700 up_bits = up_conv_bits(up_value)
698 up_bits = up_conv_bits(up_value)
701 down_bits = down_conv_bits(down_value)
699 down_bits = down_conv_bits(down_value)
702 beam_bits = up_bits+down_bits
700 beam_bits = up_bits+down_bits
703
701
704 return beam_bits
702 return beam_bits
705
703
706
704
707 @property
705 @property
708 def get_upvalues(self):
706 def get_upvalues(self):
709 """
707 """
710 This function reads antenna pattern and show the up-value of one abs module
708 This function reads antenna pattern and show the up-value of one abs module
711 """
709 """
712
710
713 data = ast.literal_eval(self.antenna)
711 data = ast.literal_eval(self.antenna)
714 up_data = data['antenna_up']
712 up_data = data['antenna_up']
715
713
716 up_values = []
714 up_values = []
717 for data in up_data:
715 for data in up_data:
718 for i in range(0,8):
716 for i in range(0,8):
719 up_values.append(data[i])
717 up_values.append(data[i])
720
718
721 return up_values
719 return up_values
722
720
723 @property
721 @property
724 def antenna_upvalues(self):
722 def antenna_upvalues(self):
725 """
723 """
726 This function reads antenna pattern and show the up - values of one abs beam
724 This function reads antenna pattern and show the up - values of one abs beam
727 in a particular order
725 in a particular order
728 """
726 """
729 data = ast.literal_eval(self.antenna)
727 data = ast.literal_eval(self.antenna)
730 up_data = data['antenna_up']
728 up_data = data['antenna_up']
731
729
732 return up_data
730 return up_data
733
731
734 @property
732 @property
735 def antenna_downvalues(self):
733 def antenna_downvalues(self):
736 """
734 """
737 This function reads antenna pattern and show the down - values of one abs beam
735 This function reads antenna pattern and show the down - values of one abs beam
738 in a particular order
736 in a particular order
739 """
737 """
740 data = ast.literal_eval(self.antenna)
738 data = ast.literal_eval(self.antenna)
741 down_data = data['antenna_down']
739 down_data = data['antenna_down']
742
740
743 return down_data
741 return down_data
744
742
745 @property
743 @property
746 def get_downvalues(self):
744 def get_downvalues(self):
747 """
745 """
748 This function reads antenna pattern and show the down-value of one abs module
746 This function reads antenna pattern and show the down-value of one abs module
749 """
747 """
750
748
751 data = ast.literal_eval(self.antenna)
749 data = ast.literal_eval(self.antenna)
752 down_data = data['antenna_down']
750 down_data = data['antenna_down']
753
751
754 down_values = []
752 down_values = []
755 for data in down_data:
753 for data in down_data:
756 for i in range(0,8):
754 for i in range(0,8):
757 down_values.append(data[i])
755 down_values.append(data[i])
758
756
759 return down_values
757 return down_values
760
758
761 @property
759 @property
762 def get_up_ues(self):
760 def get_up_ues(self):
763 """
761 """
764 This function shows the up-ues-value of one beam
762 This function shows the up-ues-value of one beam
765 """
763 """
766 data = ast.literal_eval(self.ues)
764 data = ast.literal_eval(self.ues)
767 up_ues = data['up']
765 up_ues = data['up']
768
766
769 return up_ues
767 return up_ues
770
768
771 @property
769 @property
772 def get_down_ues(self):
770 def get_down_ues(self):
773 """
771 """
774 This function shows the down-ues-value of one beam
772 This function shows the down-ues-value of one beam
775 """
773 """
776 data = ast.literal_eval(self.ues)
774 data = ast.literal_eval(self.ues)
777 down_ues = data['down']
775 down_ues = data['down']
778
776
779 return down_ues
777 return down_ues
780
778
781 @property
779 @property
782 def get_up_onlyrx(self):
780 def get_up_onlyrx(self):
783 """
781 """
784 This function shows the up-onlyrx-value of one beam
782 This function shows the up-onlyrx-value of one beam
785 """
783 """
786 data = json.loads(self.only_rx)
784 data = json.loads(self.only_rx)
787 up_onlyrx = data['up']
785 up_onlyrx = data['up']
788
786
789 return up_onlyrx
787 return up_onlyrx
790
788
791 @property
789 @property
792 def get_down_onlyrx(self):
790 def get_down_onlyrx(self):
793 """
791 """
794 This function shows the down-onlyrx-value of one beam
792 This function shows the down-onlyrx-value of one beam
795 """
793 """
796 data = json.loads(self.only_rx)
794 data = json.loads(self.only_rx)
797 down_onlyrx = data['down']
795 down_onlyrx = data['down']
798
796
799 return down_onlyrx
797 return down_onlyrx
800
798
801 @property
799 @property
802 def get_tx(self):
800 def get_tx(self):
803 """
801 """
804 This function shows the tx-values of one beam
802 This function shows the tx-values of one beam
805 """
803 """
806 data = json.loads(self.tx)
804 data = json.loads(self.tx)
807
805
808 return data
806 return data
809
807
810 @property
808 @property
811 def get_uptx(self):
809 def get_uptx(self):
812 """
810 """
813 This function shows the up-tx-values of one beam
811 This function shows the up-tx-values of one beam
814 """
812 """
815 data = json.loads(self.tx)
813 data = json.loads(self.tx)
816 up_data = data['up']
814 up_data = data['up']
817
815
818 up_values = []
816 up_values = []
819 for data in up_data:
817 for data in up_data:
820 for i in range(0,8):
818 for i in range(0,8):
821 up_values.append(data[i])
819 up_values.append(data[i])
822
820
823 return up_values
821 return up_values
824
822
825 @property
823 @property
826 def get_downtx(self):
824 def get_downtx(self):
827 """
825 """
828 This function shows the down-tx-values of one beam
826 This function shows the down-tx-values of one beam
829 """
827 """
830 data = json.loads(self.tx)
828 data = json.loads(self.tx)
831 down_data = data['down']
829 down_data = data['down']
832
830
833 down_values = []
831 down_values = []
834 for data in down_data:
832 for data in down_data:
835 for i in range(0,8):
833 for i in range(0,8):
836 down_values.append(data[i])
834 down_values.append(data[i])
837
835
838 return down_values
836 return down_values
839
837
840
838
841
839
842 @property
840 @property
843 def get_rx(self):
841 def get_rx(self):
844 """
842 """
845 This function shows the rx-values of one beam
843 This function shows the rx-values of one beam
846 """
844 """
847 data = json.loads(self.rx)
845 data = json.loads(self.rx)
848
846
849 return data
847 return data
850
848
851 @property
849 @property
852 def get_uprx(self):
850 def get_uprx(self):
853 """
851 """
854 This function shows the up-rx-values of one beam
852 This function shows the up-rx-values of one beam
855 """
853 """
856 data = json.loads(self.rx)
854 data = json.loads(self.rx)
857 up_data = data['up']
855 up_data = data['up']
858
856
859 up_values = []
857 up_values = []
860 for data in up_data:
858 for data in up_data:
861 for i in range(0,8):
859 for i in range(0,8):
862 up_values.append(data[i])
860 up_values.append(data[i])
863
861
864 return up_values
862 return up_values
865
863
866 @property
864 @property
867 def get_downrx(self):
865 def get_downrx(self):
868 """
866 """
869 This function shows the down-rx-values of one beam
867 This function shows the down-rx-values of one beam
870 """
868 """
871 data = json.loads(self.rx)
869 data = json.loads(self.rx)
872 down_data = data['down']
870 down_data = data['down']
873
871
874 down_values = []
872 down_values = []
875 for data in down_data:
873 for data in down_data:
876 for i in range(0,8):
874 for i in range(0,8):
877 down_values.append(data[i])
875 down_values.append(data[i])
878
876
879 return down_values
877 return down_values
@@ -1,433 +1,433
1 from django.shortcuts import render_to_response
1 from django.shortcuts import render_to_response
2 from django.template import RequestContext
2 from django.template import RequestContext
3 from django.shortcuts import redirect, render, get_object_or_404
3 from django.shortcuts import redirect, render, get_object_or_404
4 from django.contrib import messages
4 from django.contrib import messages
5 from django.conf import settings
5 from django.conf import settings
6 from django.http import HttpResponse
6 from django.http import HttpResponse
7 from django.core.urlresolvers import reverse
7 from django.core.urlresolvers import reverse
8 from django.views.decorators.csrf import csrf_exempt
8 from django.views.decorators.csrf import csrf_exempt
9 from django.utils.safestring import mark_safe
9 from django.utils.safestring import mark_safe
10
10
11 from datetime import datetime
11 from datetime import datetime
12 from time import sleep
12 from time import sleep
13 import os
13 import os
14 import io
14 import io
15
15
16 from apps.main.models import Device, Configuration, Experiment
16 from apps.main.models import Device, Configuration, Experiment
17 from apps.main.views import sidebar
17 from apps.main.views import sidebar
18
18
19 from .models import ABSConfiguration, ABSBeam
19 from .models import ABSConfiguration, ABSBeam
20 from .forms import ABSConfigurationForm, ABSBeamEditForm, ABSBeamAddForm, ABSImportForm
20 from .forms import ABSConfigurationForm, ABSBeamEditForm, ABSBeamAddForm, ABSImportForm
21
21
22 from .utils.overJroShow import overJroShow
22 from .utils.overJroShow import overJroShow
23 from .utils.OverJRO import OverJRO
23 from .utils.OverJRO import OverJRO
24 # Create your views here.
24 # Create your views here.
25 import json, ast
25 import json, ast
26
26
27
27
28 def get_values_from_form(form_data):
28 def get_values_from_form(form_data):
29
29
30 sublistup = []
30 sublistup = []
31 sublistdown = []
31 sublistdown = []
32 subtxlistup = []
32 subtxlistup = []
33 subtxlistdown = []
33 subtxlistdown = []
34 subrxlistup = []
34 subrxlistup = []
35 subrxlistdown = []
35 subrxlistdown = []
36
36
37 up_values_list = []
37 up_values_list = []
38 down_values_list = []
38 down_values_list = []
39 up_txvalues_list = []
39 up_txvalues_list = []
40 down_txvalues_list = []
40 down_txvalues_list = []
41 up_rxvalues_list = []
41 up_rxvalues_list = []
42 down_rxvalues_list = []
42 down_rxvalues_list = []
43
43
44 values_list = {}
44 values_list = {}
45 cont = 1
45 cont = 1
46
46
47 for i in range(1,65):
47 for i in range(1,65):
48 x = float(form_data['abs_up'+str(i)])
48 x = float(form_data['abs_up'+str(i)])
49 y = float(form_data['abs_down'+str(i)])
49 y = float(form_data['abs_down'+str(i)])
50 sublistup.append(x)
50 sublistup.append(x)
51 sublistdown.append(y)
51 sublistdown.append(y)
52
52
53 if str(i) in form_data.getlist('uptx_checks'):
53 if str(i) in form_data.getlist('uptx_checks'):
54 subtxlistup.append(1)
54 subtxlistup.append(1)
55 else:
55 else:
56 subtxlistup.append(0)
56 subtxlistup.append(0)
57 if str(i) in form_data.getlist('downtx_checks'):
57 if str(i) in form_data.getlist('downtx_checks'):
58 subtxlistdown.append(1)
58 subtxlistdown.append(1)
59 else:
59 else:
60 subtxlistdown.append(0)
60 subtxlistdown.append(0)
61
61
62 if str(i) in form_data.getlist('uprx_checks'):
62 if str(i) in form_data.getlist('uprx_checks'):
63 subrxlistup.append(1)
63 subrxlistup.append(1)
64 else:
64 else:
65 subrxlistup.append(0)
65 subrxlistup.append(0)
66 if str(i) in form_data.getlist('downrx_checks'):
66 if str(i) in form_data.getlist('downrx_checks'):
67 subrxlistdown.append(1)
67 subrxlistdown.append(1)
68 else:
68 else:
69 subrxlistdown.append(0)
69 subrxlistdown.append(0)
70
70
71 cont = cont+1
71 cont = cont+1
72
72
73 if cont == 9:
73 if cont == 9:
74 up_values_list.append(sublistup)
74 up_values_list.append(sublistup)
75 down_values_list.append(sublistdown)
75 down_values_list.append(sublistdown)
76 sublistup = []
76 sublistup = []
77 sublistdown = []
77 sublistdown = []
78
78
79 up_txvalues_list.append(subtxlistup)
79 up_txvalues_list.append(subtxlistup)
80 down_txvalues_list.append(subtxlistdown)
80 down_txvalues_list.append(subtxlistdown)
81 subtxlistup = []
81 subtxlistup = []
82 subtxlistdown = []
82 subtxlistdown = []
83 up_rxvalues_list.append(subrxlistup)
83 up_rxvalues_list.append(subrxlistup)
84 down_rxvalues_list.append(subrxlistdown)
84 down_rxvalues_list.append(subrxlistdown)
85 subrxlistup = []
85 subrxlistup = []
86 subrxlistdown = []
86 subrxlistdown = []
87 cont = 1
87 cont = 1
88
88
89
89
90 list_uesup = []
90 list_uesup = []
91 list_uesdown = []
91 list_uesdown = []
92 for i in range(1,5):
92 for i in range(1,5):
93 if form_data['ues_up'+str(i)] == '':
93 if form_data['ues_up'+str(i)] == '':
94 list_uesup.append(0.0)
94 list_uesup.append(0.0)
95 else:
95 else:
96 list_uesup.append(float(form_data['ues_up'+str(i)]))
96 list_uesup.append(float(form_data['ues_up'+str(i)]))
97
97
98 if form_data['ues_down'+str(i)] == '':
98 if form_data['ues_down'+str(i)] == '':
99 list_uesdown.append(0.0)
99 list_uesdown.append(0.0)
100 else:
100 else:
101 list_uesdown.append(float(form_data['ues_down'+str(i)]))
101 list_uesdown.append(float(form_data['ues_down'+str(i)]))
102
102
103 onlyrx_list = form_data.getlist('onlyrx')
103 onlyrx_list = form_data.getlist('onlyrx')
104 only_rx = {}
104 only_rx = {}
105 if '1' in onlyrx_list:
105 if '1' in onlyrx_list:
106 only_rx['up'] = True
106 only_rx['up'] = True
107 else:
107 else:
108 only_rx['up'] = False
108 only_rx['up'] = False
109 if '2' in onlyrx_list:
109 if '2' in onlyrx_list:
110 only_rx['down'] = True
110 only_rx['down'] = True
111 else:
111 else:
112 only_rx['down'] = False
112 only_rx['down'] = False
113
113
114 antenna = {'antenna_up': up_values_list, 'antenna_down': down_values_list}
114 antenna = {'antenna_up': up_values_list, 'antenna_down': down_values_list}
115 tx = {'up': up_txvalues_list, 'down': down_txvalues_list}
115 tx = {'up': up_txvalues_list, 'down': down_txvalues_list}
116 rx = {'up': up_rxvalues_list, 'down': down_rxvalues_list}
116 rx = {'up': up_rxvalues_list, 'down': down_rxvalues_list}
117 ues = {'up': list_uesup, 'down': list_uesdown}
117 ues = {'up': list_uesup, 'down': list_uesdown}
118 name = str(form_data['beam_name'])
118 name = str(form_data['beam_name'])
119
119
120 beam_data = {'name': name, 'antenna': antenna, 'tx': tx, 'rx': rx, 'ues': ues, 'only_rx': only_rx}
120 beam_data = {'name': name, 'antenna': antenna, 'tx': tx, 'rx': rx, 'ues': ues, 'only_rx': only_rx}
121
121
122 return beam_data
122 return beam_data
123
123
124
124
125 def abs_conf(request, id_conf):
125 def abs_conf(request, id_conf):
126
126
127 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
127 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
128 beams = ABSBeam.objects.filter(abs_conf=conf)
128 beams = ABSBeam.objects.filter(abs_conf=conf)
129 #------------Colors for Active Beam:-------------
129 #------------Colors for Active Beam:-------------
130 all_status = {}
130 all_status = {}
131 module_messages = json.loads(conf.module_messages)
131 module_messages = json.loads(conf.module_messages)
132
132
133 color_status = {}
133 color_status = {}
134 for i, status in enumerate(conf.module_status):
134 for i, status in enumerate(conf.module_status):
135 if status == '3': #Running background-color: #00cc00;
135 if status == '3': #Running background-color: #00cc00;
136 all_status['{}'.format(i+1)] = 2
136 all_status['{}'.format(i+1)] = 2
137 color_status['{}'.format(i+1)] = 'class=text-success'#'bgcolor=#00cc00'
137 color_status['{}'.format(i+1)] = 'class=text-success'#'bgcolor=#00cc00'
138 elif status == '2':
138 elif status == '2':
139 all_status['{}'.format(i+1)] = 1
139 all_status['{}'.format(i+1)] = 1
140 color_status['{}'.format(i+1)] = 'class=text-info'
140 color_status['{}'.format(i+1)] = 'class=text-info'
141 elif status == '1': #Connected background-color: #ee902c;
141 elif status == '1': #Connected background-color: #ee902c;
142 all_status['{}'.format(i+1)] = 1
142 all_status['{}'.format(i+1)] = 1
143 color_status['{}'.format(i+1)] = 'class=text-warning'#'bgcolor=#ee902c'
143 color_status['{}'.format(i+1)] = 'class=text-warning'#'bgcolor=#ee902c'
144 else: #Disconnected background-color: #ff0000;
144 else: #Disconnected background-color: #ff0000;
145 all_status['{}'.format(i+1)] = 0
145 all_status['{}'.format(i+1)] = 0
146 color_status['{}'.format(i+1)] = 'class=text-danger'#'bgcolor=#FF0000'
146 color_status['{}'.format(i+1)] = 'class=text-danger'#'bgcolor=#FF0000'
147 #------------------------------------------------
147 #------------------------------------------------
148
148
149 kwargs = {}
149 kwargs = {}
150 kwargs['connected_modules'] = str(conf.connected_modules())+'/64'
150 kwargs['connected_modules'] = str(conf.connected_modules())+'/64'
151 kwargs['dev_conf'] = conf
151 kwargs['dev_conf'] = conf
152
152
153 if conf.operation_mode == 0:
153 if conf.operation_mode == 0:
154 kwargs['dev_conf_keys'] = ['label', 'operation_mode']
154 kwargs['dev_conf_keys'] = ['label', 'operation_mode']
155 else:
155 else:
156 kwargs['dev_conf_keys'] = ['label', 'operation_mode', 'operation_value']
156 kwargs['dev_conf_keys'] = ['label', 'operation_mode', 'operation_value']
157
157
158 kwargs['title'] = 'ABS Configuration'
158 kwargs['title'] = 'ABS Configuration'
159 kwargs['suptitle'] = 'Details'
159 kwargs['suptitle'] = 'Details'
160 kwargs['button'] = 'Edit Configuration'
160 kwargs['button'] = 'Edit Configuration'
161
161
162 if conf.active_beam != 0:
162 if conf.active_beam != 0:
163 kwargs['active_beam'] = int(conf.active_beam)
163 kwargs['active_beam'] = int(conf.active_beam)
164
164
165 kwargs['beams'] = beams
165 kwargs['beams'] = beams
166 kwargs['modules_status'] = all_status
166 kwargs['modules_status'] = all_status
167 kwargs['color_status'] = color_status
167 kwargs['color_status'] = color_status
168 kwargs['module_messages'] = module_messages
168 kwargs['module_messages'] = module_messages
169 ###### SIDEBAR ######
169 ###### SIDEBAR ######
170 kwargs.update(sidebar(conf=conf))
170 kwargs.update(sidebar(conf=conf))
171
171
172 return render(request, 'abs_conf.html', kwargs)
172 return render(request, 'abs_conf.html', kwargs)
173
173
174
174
175 def abs_conf_edit(request, id_conf):
175 def abs_conf_edit(request, id_conf):
176
176
177 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
177 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
178
178
179 beams = ABSBeam.objects.filter(abs_conf=conf)
179 beams = ABSBeam.objects.filter(abs_conf=conf)
180
180
181 if request.method=='GET':
181 if request.method=='GET':
182 form = ABSConfigurationForm(instance=conf)
182 form = ABSConfigurationForm(instance=conf)
183
183
184 if request.method=='POST':
184 if request.method=='POST':
185 form = ABSConfigurationForm(request.POST, instance=conf)
185 form = ABSConfigurationForm(request.POST, instance=conf)
186
186
187 if form.is_valid():
187 if form.is_valid():
188 conf = form.save(commit=False)
188 conf = form.save(commit=False)
189 conf.save()
189 conf.save()
190 return redirect('url_abs_conf', id_conf=conf.id)
190 return redirect('url_abs_conf', id_conf=conf.id)
191
191
192 ###### SIDEBAR ######
192 ###### SIDEBAR ######
193 kwargs = {}
193 kwargs = {}
194
194
195 kwargs['dev_conf'] = conf
195 kwargs['dev_conf'] = conf
196 #kwargs['id_dev'] = conf.id
196 #kwargs['id_dev'] = conf.id
197 kwargs['id_conf'] = conf.id
197 kwargs['id_conf'] = conf.id
198 kwargs['form'] = form
198 kwargs['form'] = form
199 kwargs['abs_beams'] = beams
199 kwargs['abs_beams'] = beams
200 kwargs['title'] = 'Device Configuration'
200 kwargs['title'] = 'Device Configuration'
201 kwargs['suptitle'] = 'Edit'
201 kwargs['suptitle'] = 'Edit'
202 kwargs['button'] = 'Save'
202 kwargs['button'] = 'Save'
203
203
204 kwargs['edit'] = True
204 kwargs['edit'] = True
205
205
206 return render(request, 'abs_conf_edit.html', kwargs)
206 return render(request, 'abs_conf_edit.html', kwargs)
207
207
208 @csrf_exempt
208 @csrf_exempt
209 def abs_conf_alert(request):
209 def abs_conf_alert(request):
210
210
211 if request.method == 'POST':
211 if request.method == 'POST':
212 print request.POST
212 print request.POST
213 return HttpResponse(json.dumps({'result':1}), content_type='application/json')
213 return HttpResponse(json.dumps({'result':1}), content_type='application/json')
214 else:
214 else:
215 return redirect('index')
215 return redirect('index')
216
216
217
217
218 def import_file(request, id_conf):
218 def import_file(request, id_conf):
219
219
220 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
220 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
221 if request.method=='POST':
221 if request.method=='POST':
222 form = ABSImportForm(request.POST, request.FILES)
222 form = ABSImportForm(request.POST, request.FILES)
223 if form.is_valid():
223 if form.is_valid():
224 try:
224 try:
225 parms = conf.import_from_file(request.FILES['file_name'])
225 parms = conf.import_from_file(request.FILES['file_name'])
226
226
227 if parms:
227 if parms:
228 conf.update_from_file(parms)
228 conf.update_from_file(parms)
229 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
229 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
230 return redirect(conf.get_absolute_url_edit())
230 return redirect(conf.get_absolute_url_edit())
231
231
232 except Exception as e:
232 except Exception as e:
233 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], e))
233 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], e))
234
234
235 else:
235 else:
236 messages.warning(request, 'Your current configuration will be replaced')
236 messages.warning(request, 'Your current configuration will be replaced')
237 form = ABSImportForm()
237 form = ABSImportForm()
238
238
239 kwargs = {}
239 kwargs = {}
240 kwargs['form'] = form
240 kwargs['form'] = form
241 kwargs['title'] = 'ABS Configuration'
241 kwargs['title'] = 'ABS Configuration'
242 kwargs['suptitle'] = 'Import file'
242 kwargs['suptitle'] = 'Import file'
243 kwargs['button'] = 'Upload'
243 kwargs['button'] = 'Upload'
244 kwargs['previous'] = conf.get_absolute_url()
244 kwargs['previous'] = conf.get_absolute_url()
245
245
246 return render(request, 'abs_import.html', kwargs)
246 return render(request, 'abs_import.html', kwargs)
247
247
248
248
249 def send_beam(request, id_conf, id_beam):
249 def send_beam(request, id_conf, id_beam):
250
250
251 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
251 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
252
252
253 abs = request.user.profile.abs_active
253 abs = Configuration.objects.filter(pk=conf.device.conf_active).first()
254 if abs<>conf:
254 if abs<>conf:
255 url = '#' if abs is None else abs.get_absolute_url()
255 url = '#' if abs is None else abs.get_absolute_url()
256 label = 'None' if abs is None else abs.label
256 label = 'None' if abs is None else abs.label
257 messages.warning(
257 messages.warning(
258 request,
258 request,
259 mark_safe('The current configuration has not been written in the modules, the active configuration is <a href="{}">{}</a>'.format(
259 mark_safe('The current configuration has not been written in the modules, the active configuration is <a href="{}">{}</a>'.format(
260 url,
260 url,
261 label
261 label
262 ))
262 ))
263 )
263 )
264 return redirect(conf.get_absolute_url())
264 return redirect(conf.get_absolute_url())
265
265
266 beam = get_object_or_404(ABSBeam, pk=id_beam)
266 beam = get_object_or_404(ABSBeam, pk=id_beam)
267 beams_list = ABSBeam.objects.filter(abs_conf=conf)
267 beams_list = ABSBeam.objects.filter(abs_conf=conf)
268 conf.active_beam = id_beam
268 conf.active_beam = id_beam
269
269
270 i = 0
270 i = 0
271 for b in beams_list:
271 for b in beams_list:
272 if b.id == int(id_beam):
272 if b.id == int(id_beam):
273 break
273 break
274 else:
274 else:
275 i += 1
275 i += 1
276 beam_pos = i + 1 #Estandarizar
276 beam_pos = i + 1 #Estandarizar
277 print '%s Position: %s' % (beam.name, str(beam_pos))
277 print '%s Position: %s' % (beam.name, str(beam_pos))
278 conf.send_beam(beam_pos)
278 conf.send_beam(beam_pos)
279
279
280 return redirect('url_abs_conf', conf.id)
280 return redirect('url_abs_conf', conf.id)
281
281
282
282
283 def add_beam(request, id_conf):
283 def add_beam(request, id_conf):
284
284
285 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
285 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
286 confs = Configuration.objects.all()
286 confs = Configuration.objects.all()
287
287
288 if request.method=='GET':
288 if request.method=='GET':
289 form = ABSBeamAddForm()
289 form = ABSBeamAddForm()
290
290
291 if request.method=='POST':
291 if request.method=='POST':
292 form = ABSBeamAddForm(request.POST)
292 form = ABSBeamAddForm(request.POST)
293
293
294 beam_data = get_values_from_form(request.POST)
294 beam_data = get_values_from_form(request.POST)
295
295
296 new_beam = ABSBeam(
296 new_beam = ABSBeam(
297 name = beam_data['name'],
297 name = beam_data['name'],
298 antenna = json.dumps(beam_data['antenna']),
298 antenna = json.dumps(beam_data['antenna']),
299 abs_conf = conf,
299 abs_conf = conf,
300 tx = json.dumps(beam_data['tx']),
300 tx = json.dumps(beam_data['tx']),
301 rx = json.dumps(beam_data['rx']),
301 rx = json.dumps(beam_data['rx']),
302 ues = json.dumps(beam_data['ues']),
302 ues = json.dumps(beam_data['ues']),
303 only_rx = json.dumps(beam_data['only_rx'])
303 only_rx = json.dumps(beam_data['only_rx'])
304 )
304 )
305 new_beam.save()
305 new_beam.save()
306 messages.success(request, 'Beam: "%s" has been added.' % new_beam.name)
306 messages.success(request, 'Beam: "%s" has been added.' % new_beam.name)
307
307
308 return redirect('url_edit_abs_conf', conf.id)
308 return redirect('url_edit_abs_conf', conf.id)
309
309
310 ###### SIDEBAR ######
310 ###### SIDEBAR ######
311 kwargs = {}
311 kwargs = {}
312
312
313 #kwargs['dev_conf'] = conf.device
313 #kwargs['dev_conf'] = conf.device
314 #kwargs['id_dev'] = conf.device
314 #kwargs['id_dev'] = conf.device
315 kwargs['id_conf'] = conf.id
315 kwargs['id_conf'] = conf.id
316 kwargs['form'] = form
316 kwargs['form'] = form
317 kwargs['title'] = 'ABS Beams'
317 kwargs['title'] = 'ABS Beams'
318 kwargs['suptitle'] = 'Add Beam'
318 kwargs['suptitle'] = 'Add Beam'
319 kwargs['button'] = 'Add'
319 kwargs['button'] = 'Add'
320 kwargs['no_sidebar'] = True
320 kwargs['no_sidebar'] = True
321
321
322 #kwargs['previous'] = conf.get_absolute_url_edit()
322 #kwargs['previous'] = conf.get_absolute_url_edit()
323 kwargs['edit'] = True
323 kwargs['edit'] = True
324
324
325 return render(request, 'abs_add_beam.html', kwargs)
325 return render(request, 'abs_add_beam.html', kwargs)
326
326
327
327
328 def edit_beam(request, id_conf, id_beam):
328 def edit_beam(request, id_conf, id_beam):
329
329
330 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
330 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
331 beam = get_object_or_404(ABSBeam, pk=id_beam)
331 beam = get_object_or_404(ABSBeam, pk=id_beam)
332
332
333 if request.method=='GET':
333 if request.method=='GET':
334 form = ABSBeamEditForm(initial={'beam': beam})
334 form = ABSBeamEditForm(initial={'beam': beam})
335
335
336 if request.method=='POST':
336 if request.method=='POST':
337 form = ABSBeamEditForm(request.POST)
337 form = ABSBeamEditForm(request.POST)
338
338
339 beam_data = get_values_from_form(request.POST)
339 beam_data = get_values_from_form(request.POST)
340
340
341 beam.dict_to_parms(beam_data)
341 beam.dict_to_parms(beam_data)
342 beam.save()
342 beam.save()
343
343
344 messages.success(request, 'Beam: "%s" has been updated.' % beam.name)
344 messages.success(request, 'Beam: "%s" has been updated.' % beam.name)
345
345
346 return redirect('url_edit_abs_conf', conf.id)
346 return redirect('url_edit_abs_conf', conf.id)
347
347
348 ###### SIDEBAR ######
348 ###### SIDEBAR ######
349 kwargs = {}
349 kwargs = {}
350
350
351 kwargs['id_conf'] = conf.id
351 kwargs['id_conf'] = conf.id
352 kwargs['form'] = form
352 kwargs['form'] = form
353 kwargs['title'] = 'ABS Beams'
353 kwargs['title'] = 'ABS Beams'
354 kwargs['suptitle'] = 'Edit Beam'
354 kwargs['suptitle'] = 'Edit Beam'
355 kwargs['button'] = 'Save'
355 kwargs['button'] = 'Save'
356 kwargs['no_sidebar'] = True
356 kwargs['no_sidebar'] = True
357
357
358 #kwargs['previous'] = conf.get_absolute_url_edit()
358 #kwargs['previous'] = conf.get_absolute_url_edit()
359 kwargs['edit'] = True
359 kwargs['edit'] = True
360
360
361 return render(request, 'abs_edit_beam.html', kwargs)
361 return render(request, 'abs_edit_beam.html', kwargs)
362
362
363
363
364
364
365 def remove_beam(request, id_conf, id_beam):
365 def remove_beam(request, id_conf, id_beam):
366
366
367 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
367 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
368 beam = get_object_or_404(ABSBeam, pk=id_beam)
368 beam = get_object_or_404(ABSBeam, pk=id_beam)
369
369
370 if request.method=='POST':
370 if request.method=='POST':
371 if beam:
371 if beam:
372 try:
372 try:
373 beam.delete()
373 beam.delete()
374 messages.success(request, 'Beam: "%s" has been deleted.' % beam)
374 messages.success(request, 'Beam: "%s" has been deleted.' % beam)
375 except:
375 except:
376 messages.error(request, 'Unable to delete beam: "%s".' % beam)
376 messages.error(request, 'Unable to delete beam: "%s".' % beam)
377
377
378 return redirect('url_edit_abs_conf', conf.id)
378 return redirect('url_edit_abs_conf', conf.id)
379
379
380 ###### SIDEBAR ######
380 ###### SIDEBAR ######
381 kwargs = {}
381 kwargs = {}
382
382
383 kwargs['object'] = beam
383 kwargs['object'] = beam
384 kwargs['delete'] = True
384 kwargs['delete'] = True
385 kwargs['title'] = 'Delete'
385 kwargs['title'] = 'Delete'
386 kwargs['suptitle'] = 'Beam'
386 kwargs['suptitle'] = 'Beam'
387 kwargs['previous'] = conf.get_absolute_url_edit()
387 kwargs['previous'] = conf.get_absolute_url_edit()
388 return render(request, 'confirm.html', kwargs)
388 return render(request, 'confirm.html', kwargs)
389
389
390
390
391
391
392 def plot_patterns(request, id_conf, id_beam=None):
392 def plot_patterns(request, id_conf, id_beam=None):
393
393
394 kwargs = {}
394 kwargs = {}
395 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
395 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
396 beams = ABSBeam.objects.filter(abs_conf=conf)
396 beams = ABSBeam.objects.filter(abs_conf=conf)
397
397
398 if id_beam:
398 if id_beam:
399 beam = get_object_or_404(ABSBeam, pk=id_beam)
399 beam = get_object_or_404(ABSBeam, pk=id_beam)
400 kwargs['beam'] = beam
400 kwargs['beam'] = beam
401
401
402 ###### SIDEBAR ######
402 ###### SIDEBAR ######
403
403
404 kwargs['dev_conf'] = conf.device
404 kwargs['dev_conf'] = conf.device
405 kwargs['id_dev'] = conf.device
405 kwargs['id_dev'] = conf.device
406 kwargs['id_conf'] = conf.id
406 kwargs['id_conf'] = conf.id
407 kwargs['abs_beams'] = beams
407 kwargs['abs_beams'] = beams
408 kwargs['title'] = 'ABS Patterns'
408 kwargs['title'] = 'ABS Patterns'
409 kwargs['suptitle'] = conf.name
409 kwargs['suptitle'] = conf.name
410 kwargs['no_sidebar'] = True
410 kwargs['no_sidebar'] = True
411
411
412 return render(request, 'abs_patterns.html', kwargs)
412 return render(request, 'abs_patterns.html', kwargs)
413
413
414
414
415 def plot_pattern(request, id_conf, id_beam, antenna):
415 def plot_pattern(request, id_conf, id_beam, antenna):
416
416
417 if antenna=='down':
417 if antenna=='down':
418 sleep(3)
418 sleep(3)
419
419
420 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
420 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
421 beam = get_object_or_404(ABSBeam, pk=id_beam)
421 beam = get_object_or_404(ABSBeam, pk=id_beam)
422 just_rx = 1 if json.loads(beam.only_rx)[antenna] else 0
422 just_rx = 1 if json.loads(beam.only_rx)[antenna] else 0
423 phases = json.loads(beam.antenna)['antenna_{}'.format(antenna)]
423 phases = json.loads(beam.antenna)['antenna_{}'.format(antenna)]
424 gain_tx = json.loads(beam.tx)[antenna]
424 gain_tx = json.loads(beam.tx)[antenna]
425 gain_rx = json.loads(beam.rx)[antenna]
425 gain_rx = json.loads(beam.rx)[antenna]
426 ues = json.loads(beam.ues)[antenna]
426 ues = json.loads(beam.ues)[antenna]
427 newOverJro = overJroShow(beam.name)
427 newOverJro = overJroShow(beam.name)
428 fig = newOverJro.plotPattern2(datetime.today(), phases, gain_tx, gain_rx, ues, just_rx)
428 fig = newOverJro.plotPattern2(datetime.today(), phases, gain_tx, gain_rx, ues, just_rx)
429 buf = io.BytesIO()
429 buf = io.BytesIO()
430 fig.savefig(buf, format='png')
430 fig.savefig(buf, format='png')
431 response = HttpResponse(buf.getvalue(), content_type='image/png')
431 response = HttpResponse(buf.getvalue(), content_type='image/png')
432 return response
432 return response
433
433
@@ -1,811 +1,804
1
1
2 import os
2 import os
3 import json
3 import json
4 import requests
4 import requests
5 import time
5 import time
6 from datetime import datetime
6 from datetime import datetime
7
7
8 try:
8 try:
9 from polymorphic.models import PolymorphicModel
9 from polymorphic.models import PolymorphicModel
10 except:
10 except:
11 from polymorphic import PolymorphicModel
11 from polymorphic import PolymorphicModel
12
12
13 from django.template.base import kwarg_re
13 from django.template.base import kwarg_re
14 from django.db import models
14 from django.db import models
15 from django.core.urlresolvers import reverse
15 from django.core.urlresolvers import reverse
16 from django.core.validators import MinValueValidator, MaxValueValidator
16 from django.core.validators import MinValueValidator, MaxValueValidator
17 from django.shortcuts import get_object_or_404
17 from django.shortcuts import get_object_or_404
18 from django.contrib.auth.models import User
18 from django.contrib.auth.models import User
19 from django.db.models.signals import post_save
19 from django.db.models.signals import post_save
20 from django.dispatch import receiver
20 from django.dispatch import receiver
21
21
22 from apps.main.utils import Params
22 from apps.main.utils import Params
23 from apps.rc.utils import RCFile
23 from apps.rc.utils import RCFile
24 from apps.jars.utils import RacpFile
24 from apps.jars.utils import RacpFile
25 from devices.dds import api as dds_api
25 from devices.dds import api as dds_api
26 from devices.dds import data as dds_data
26 from devices.dds import data as dds_data
27
27
28
28
29 DEV_PORTS = {
29 DEV_PORTS = {
30 'rc' : 2000,
30 'rc' : 2000,
31 'dds' : 2000,
31 'dds' : 2000,
32 'jars' : 2000,
32 'jars' : 2000,
33 'usrp' : 2000,
33 'usrp' : 2000,
34 'cgs' : 8080,
34 'cgs' : 8080,
35 'abs' : 8080
35 'abs' : 8080
36 }
36 }
37
37
38 RADAR_STATES = (
38 RADAR_STATES = (
39 (0, 'No connected'),
39 (0, 'No connected'),
40 (1, 'Connected'),
40 (1, 'Connected'),
41 (2, 'Configured'),
41 (2, 'Configured'),
42 (3, 'Running'),
42 (3, 'Running'),
43 (4, 'Scheduled'),
43 (4, 'Scheduled'),
44 )
44 )
45
45
46 EXPERIMENT_TYPE = (
46 EXPERIMENT_TYPE = (
47 (0, 'RAW_DATA'),
47 (0, 'RAW_DATA'),
48 (1, 'PDATA'),
48 (1, 'PDATA'),
49 )
49 )
50
50
51 DECODE_TYPE = (
51 DECODE_TYPE = (
52 (0, 'None'),
52 (0, 'None'),
53 (1, 'TimeDomain'),
53 (1, 'TimeDomain'),
54 (2, 'FreqDomain'),
54 (2, 'FreqDomain'),
55 (3, 'InvFreqDomain'),
55 (3, 'InvFreqDomain'),
56 )
56 )
57
57
58 DEV_STATES = (
58 DEV_STATES = (
59 (0, 'No connected'),
59 (0, 'No connected'),
60 (1, 'Connected'),
60 (1, 'Connected'),
61 (2, 'Configured'),
61 (2, 'Configured'),
62 (3, 'Running'),
62 (3, 'Running'),
63 (4, 'Unknown'),
63 (4, 'Unknown'),
64 )
64 )
65
65
66 DEV_TYPES = (
66 DEV_TYPES = (
67 ('', 'Select a device type'),
67 ('', 'Select a device type'),
68 ('rc', 'Radar Controller'),
68 ('rc', 'Radar Controller'),
69 ('dds', 'Direct Digital Synthesizer'),
69 ('dds', 'Direct Digital Synthesizer'),
70 ('jars', 'Jicamarca Radar Acquisition System'),
70 ('jars', 'Jicamarca Radar Acquisition System'),
71 ('usrp', 'Universal Software Radio Peripheral'),
71 ('usrp', 'Universal Software Radio Peripheral'),
72 ('cgs', 'Clock Generator System'),
72 ('cgs', 'Clock Generator System'),
73 ('abs', 'Automatic Beam Switching'),
73 ('abs', 'Automatic Beam Switching'),
74 )
74 )
75
75
76 EXP_STATES = (
76 EXP_STATES = (
77 (0,'Error'), #RED
77 (0,'Error'), #RED
78 (1,'Configured'), #BLUE
78 (1,'Cancelled'), #YELLOW
79 (2,'Running'), #GREEN
79 (2,'Running'), #GREEN
80 (3,'Scheduled'), #YELLOW
80 (3,'Scheduled'), #BLUE
81 (4,'Not Configured'), #WHITE
81 (4,'Unknown'), #WHITE
82 )
82 )
83
83
84 CONF_TYPES = (
84 CONF_TYPES = (
85 (0, 'Active'),
85 (0, 'Active'),
86 (1, 'Historical'),
86 (1, 'Historical'),
87 )
87 )
88
88
89 class Profile(models.Model):
89 class Profile(models.Model):
90 user = models.OneToOneField(User, on_delete=models.CASCADE)
90 user = models.OneToOneField(User, on_delete=models.CASCADE)
91 theme = models.CharField(max_length=30, default='spacelab')
91 theme = models.CharField(max_length=30, default='spacelab')
92 abs_active = models.ForeignKey('Configuration', null=True, blank=True, verbose_name='Current ABS')
93
92
94
93
95 @receiver(post_save, sender=User)
94 @receiver(post_save, sender=User)
96 def create_user_profile(sender, instance, created, **kwargs):
95 def create_user_profile(sender, instance, created, **kwargs):
97 if created:
96 if created:
98 Profile.objects.create(user=instance)
97 Profile.objects.create(user=instance)
99
98
100 @receiver(post_save, sender=User)
99 @receiver(post_save, sender=User)
101 def save_user_profile(sender, instance, **kwargs):
100 def save_user_profile(sender, instance, **kwargs):
102 instance.profile.save()
101 instance.profile.save()
103
102
104
103
105 class Location(models.Model):
104 class Location(models.Model):
106
105
107 name = models.CharField(max_length = 30)
106 name = models.CharField(max_length = 30)
108 description = models.TextField(blank=True, null=True)
107 description = models.TextField(blank=True, null=True)
109
108
110 class Meta:
109 class Meta:
111 db_table = 'db_location'
110 db_table = 'db_location'
112
111
113 def __str__(self):
112 def __str__(self):
114 return u'%s' % self.name
113 return u'%s' % self.name
115
114
116 def get_absolute_url(self):
115 def get_absolute_url(self):
117 return reverse('url_location', args=[str(self.id)])
116 return reverse('url_location', args=[str(self.id)])
118
117
119
118
120 class DeviceType(models.Model):
119 class DeviceType(models.Model):
121
120
122 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc')
121 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc')
123 sequence = models.PositiveSmallIntegerField(default=1000)
122 sequence = models.PositiveSmallIntegerField(default=1000)
124 description = models.TextField(blank=True, null=True)
123 description = models.TextField(blank=True, null=True)
125
124
126 class Meta:
125 class Meta:
127 db_table = 'db_device_types'
126 db_table = 'db_device_types'
128
127
129 def __str__(self):
128 def __str__(self):
130 return u'%s' % self.get_name_display()
129 return u'%s' % self.get_name_display()
131
130
132 class Device(models.Model):
131 class Device(models.Model):
133
132
134 device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
133 device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
135 location = models.ForeignKey(Location, on_delete=models.CASCADE)
134 location = models.ForeignKey(Location, on_delete=models.CASCADE)
136 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
135 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
137 port_address = models.PositiveSmallIntegerField(default=2000)
136 port_address = models.PositiveSmallIntegerField(default=2000)
138 description = models.TextField(blank=True, null=True)
137 description = models.TextField(blank=True, null=True)
139 status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES)
138 status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES)
139 conf_active = models.PositiveIntegerField(default=0, verbose_name='Current configuration')
140
140
141 class Meta:
141 class Meta:
142 db_table = 'db_devices'
142 db_table = 'db_devices'
143
143
144 def __str__(self):
144 def __str__(self):
145 ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
145 ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
146
146
147 return ret
147 return ret
148
148
149 @property
149 @property
150 def name(self):
150 def name(self):
151 return str(self)
151 return str(self)
152
152
153 def get_status(self):
153 def get_status(self):
154 return self.status
154 return self.status
155
155
156 @property
156 @property
157 def status_color(self):
157 def status_color(self):
158 color = 'muted'
158 color = 'muted'
159 if self.status == 0:
159 if self.status == 0:
160 color = "danger"
160 color = "danger"
161 elif self.status == 1:
161 elif self.status == 1:
162 color = "warning"
162 color = "warning"
163 elif self.status == 2:
163 elif self.status == 2:
164 color = "info"
164 color = "info"
165 elif self.status == 3:
165 elif self.status == 3:
166 color = "success"
166 color = "success"
167
167
168 return color
168 return color
169
169
170 def url(self, path=None):
170 def url(self, path=None):
171
171
172 if path:
172 if path:
173 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
173 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
174 else:
174 else:
175 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
175 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
176
176
177 def get_absolute_url(self):
177 def get_absolute_url(self):
178 return reverse('url_device', args=[str(self.id)])
178 return reverse('url_device', args=[str(self.id)])
179
179
180 def get_absolute_url_edit(self):
180 def get_absolute_url_edit(self):
181 return reverse('url_edit_device', args=[str(self.id)])
181 return reverse('url_edit_device', args=[str(self.id)])
182
182
183 def get_absolute_url_delete(self):
183 def get_absolute_url_delete(self):
184 return reverse('url_delete_device', args=[str(self.id)])
184 return reverse('url_delete_device', args=[str(self.id)])
185
185
186 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
186 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
187
187
188 if self.device_type.name=='dds':
188 if self.device_type.name=='dds':
189 try:
189 try:
190 answer = dds_api.change_ip(ip = self.ip_address,
190 answer = dds_api.change_ip(ip = self.ip_address,
191 port = self.port_address,
191 port = self.port_address,
192 new_ip = ip_address,
192 new_ip = ip_address,
193 mask = mask,
193 mask = mask,
194 gateway = gateway)
194 gateway = gateway)
195 if answer[0]=='1':
195 if answer[0]=='1':
196 self.message = '25|DDS - {}'.format(answer)
196 self.message = '25|DDS - {}'.format(answer)
197 self.ip_address = ip_address
197 self.ip_address = ip_address
198 self.save()
198 self.save()
199 else:
199 else:
200 self.message = '30|DDS - {}'.format(answer)
200 self.message = '30|DDS - {}'.format(answer)
201 return False
201 return False
202 except Exception as e:
202 except Exception as e:
203 self.message = '40|{}'.format(str(e))
203 self.message = '40|{}'.format(str(e))
204 return False
204 return False
205
205
206 elif self.device_type.name=='rc':
206 elif self.device_type.name=='rc':
207 headers = {'content-type': "application/json",
207 headers = {'content-type': "application/json",
208 'cache-control': "no-cache"}
208 'cache-control': "no-cache"}
209
209
210 ip = [int(x) for x in ip_address.split('.')]
210 ip = [int(x) for x in ip_address.split('.')]
211 dns = [int(x) for x in dns.split('.')]
211 dns = [int(x) for x in dns.split('.')]
212 gateway = [int(x) for x in gateway.split('.')]
212 gateway = [int(x) for x in gateway.split('.')]
213 subnet = [int(x) for x in mask.split('.')]
213 subnet = [int(x) for x in mask.split('.')]
214
214
215 payload = {
215 payload = {
216 "ip": ip,
216 "ip": ip,
217 "dns": dns,
217 "dns": dns,
218 "gateway": gateway,
218 "gateway": gateway,
219 "subnet": subnet
219 "subnet": subnet
220 }
220 }
221
221
222 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
222 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
223 try:
223 try:
224 answer = req.json()
224 answer = req.json()
225 if answer['changeip']=='ok':
225 if answer['changeip']=='ok':
226 self.message = '25|IP succesfully changed'
226 self.message = '25|IP succesfully changed'
227 self.ip_address = ip_address
227 self.ip_address = ip_address
228 self.save()
228 self.save()
229 else:
229 else:
230 self.message = '30|An error ocuur when changing IP'
230 self.message = '30|An error ocuur when changing IP'
231 except Exception as e:
231 except Exception as e:
232 self.message = '40|{}'.format(str(e))
232 self.message = '40|{}'.format(str(e))
233 else:
233 else:
234 self.message = 'Not implemented'
234 self.message = 'Not implemented'
235 return False
235 return False
236
236
237 return True
237 return True
238
238
239
239
240 class Campaign(models.Model):
240 class Campaign(models.Model):
241
241
242 template = models.BooleanField(default=False)
242 template = models.BooleanField(default=False)
243 name = models.CharField(max_length=60, unique=True)
243 name = models.CharField(max_length=60, unique=True)
244 start_date = models.DateTimeField(blank=True, null=True)
244 start_date = models.DateTimeField(blank=True, null=True)
245 end_date = models.DateTimeField(blank=True, null=True)
245 end_date = models.DateTimeField(blank=True, null=True)
246 tags = models.CharField(max_length=40, blank=True, null=True)
246 tags = models.CharField(max_length=40, blank=True, null=True)
247 description = models.TextField(blank=True, null=True)
247 description = models.TextField(blank=True, null=True)
248 experiments = models.ManyToManyField('Experiment', blank=True)
248 experiments = models.ManyToManyField('Experiment', blank=True)
249 author = models.ForeignKey(User, null=True, blank=True)
249 author = models.ForeignKey(User, null=True, blank=True)
250
250
251 class Meta:
251 class Meta:
252 db_table = 'db_campaigns'
252 db_table = 'db_campaigns'
253 ordering = ('name',)
253 ordering = ('name',)
254
254
255 def __str__(self):
255 def __str__(self):
256 if self.template:
256 if self.template:
257 return u'{} (template)'.format(self.name)
257 return u'{} (template)'.format(self.name)
258 else:
258 else:
259 return u'{}'.format(self.name)
259 return u'{}'.format(self.name)
260
260
261 def jsonify(self):
261 def jsonify(self):
262
262
263 data = {}
263 data = {}
264
264
265 ignored = ('template')
265 ignored = ('template')
266
266
267 for field in self._meta.fields:
267 for field in self._meta.fields:
268 if field.name in ignored:
268 if field.name in ignored:
269 continue
269 continue
270 data[field.name] = field.value_from_object(self)
270 data[field.name] = field.value_from_object(self)
271
271
272 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
272 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
273 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
273 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
274
274
275 return data
275 return data
276
276
277 def parms_to_dict(self):
277 def parms_to_dict(self):
278
278
279 params = Params({})
279 params = Params({})
280 params.add(self.jsonify(), 'campaigns')
280 params.add(self.jsonify(), 'campaigns')
281
281
282 for exp in Experiment.objects.filter(campaign = self):
282 for exp in Experiment.objects.filter(campaign = self):
283 params.add(exp.jsonify(), 'experiments')
283 params.add(exp.jsonify(), 'experiments')
284 configurations = Configuration.objects.filter(experiment=exp, type=0)
284 configurations = Configuration.objects.filter(experiment=exp, type=0)
285
285
286 for conf in configurations:
286 for conf in configurations:
287 params.add(conf.jsonify(), 'configurations')
287 params.add(conf.jsonify(), 'configurations')
288 if conf.device.device_type.name=='rc':
288 if conf.device.device_type.name=='rc':
289 for line in conf.get_lines():
289 for line in conf.get_lines():
290 params.add(line.jsonify(), 'lines')
290 params.add(line.jsonify(), 'lines')
291
291
292 return params.data
292 return params.data
293
293
294 def dict_to_parms(self, parms, CONF_MODELS):
294 def dict_to_parms(self, parms, CONF_MODELS):
295
295
296 experiments = Experiment.objects.filter(campaign = self)
296 experiments = Experiment.objects.filter(campaign = self)
297
297
298 if experiments:
298 if experiments:
299 for experiment in experiments:
299 for experiment in experiments:
300 experiment.delete()
300 experiment.delete()
301
301
302 for id_exp in parms['experiments']['allIds']:
302 for id_exp in parms['experiments']['allIds']:
303 exp_parms = parms['experiments']['byId'][id_exp]
303 exp_parms = parms['experiments']['byId'][id_exp]
304 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
304 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
305 exp = Experiment(name='{}'.format(dum))
305 exp = Experiment(name='{}'.format(dum))
306 exp.save()
306 exp.save()
307 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
307 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
308 self.experiments.add(exp)
308 self.experiments.add(exp)
309
309
310 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
310 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
311
311
312 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
312 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
313 self.start_date = camp_parms['start_date']
313 self.start_date = camp_parms['start_date']
314 self.end_date = camp_parms['end_date']
314 self.end_date = camp_parms['end_date']
315 self.tags = camp_parms['tags']
315 self.tags = camp_parms['tags']
316 self.save()
316 self.save()
317
317
318 return self
318 return self
319
319
320 def get_experiments_by_radar(self, radar=None):
320 def get_experiments_by_radar(self, radar=None):
321
321
322 ret = []
322 ret = []
323 if radar:
323 if radar:
324 locations = Location.objects.filter(pk=radar)
324 locations = Location.objects.filter(pk=radar)
325 else:
325 else:
326 locations = set([e.location for e in self.experiments.all()])
326 locations = set([e.location for e in self.experiments.all()])
327
327
328 for loc in locations:
328 for loc in locations:
329 dum = {}
329 dum = {}
330 dum['name'] = loc.name
330 dum['name'] = loc.name
331 dum['id'] = loc.pk
331 dum['id'] = loc.pk
332 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
332 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
333 ret.append(dum)
333 ret.append(dum)
334
334
335 return ret
335 return ret
336
336
337 def get_absolute_url(self):
337 def get_absolute_url(self):
338 return reverse('url_campaign', args=[str(self.id)])
338 return reverse('url_campaign', args=[str(self.id)])
339
339
340 def get_absolute_url_edit(self):
340 def get_absolute_url_edit(self):
341 return reverse('url_edit_campaign', args=[str(self.id)])
341 return reverse('url_edit_campaign', args=[str(self.id)])
342
342
343 def get_absolute_url_delete(self):
343 def get_absolute_url_delete(self):
344 return reverse('url_delete_campaign', args=[str(self.id)])
344 return reverse('url_delete_campaign', args=[str(self.id)])
345
345
346 def get_absolute_url_export(self):
346 def get_absolute_url_export(self):
347 return reverse('url_export_campaign', args=[str(self.id)])
347 return reverse('url_export_campaign', args=[str(self.id)])
348
348
349 def get_absolute_url_import(self):
349 def get_absolute_url_import(self):
350 return reverse('url_import_campaign', args=[str(self.id)])
350 return reverse('url_import_campaign', args=[str(self.id)])
351
351
352
352
353 class RunningExperiment(models.Model):
353 class RunningExperiment(models.Model):
354 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
354 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
355 running_experiment = models.ManyToManyField('Experiment', blank = True)
355 running_experiment = models.ManyToManyField('Experiment', blank = True)
356 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
356 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
357
357
358
358
359 class Experiment(models.Model):
359 class Experiment(models.Model):
360
360
361 template = models.BooleanField(default=False)
361 template = models.BooleanField(default=False)
362 name = models.CharField(max_length=40, default='', unique=True)
362 name = models.CharField(max_length=40, default='', unique=True)
363 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
363 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
364 freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
364 freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
365 start_time = models.TimeField(default='00:00:00')
365 start_time = models.TimeField(default='00:00:00')
366 end_time = models.TimeField(default='23:59:59')
366 end_time = models.TimeField(default='23:59:59')
367 task = models.CharField(max_length=36, default='', blank=True, null=True)
367 task = models.CharField(max_length=36, default='', blank=True, null=True)
368 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
368 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
369 author = models.ForeignKey(User, null=True, blank=True)
369 author = models.ForeignKey(User, null=True, blank=True)
370 hash = models.CharField(default='', max_length=64, null=True, blank=True)
370 hash = models.CharField(default='', max_length=64, null=True, blank=True)
371
371
372 class Meta:
372 class Meta:
373 db_table = 'db_experiments'
373 db_table = 'db_experiments'
374 ordering = ('template', 'name')
374 ordering = ('template', 'name')
375
375
376 def __str__(self):
376 def __str__(self):
377 if self.template:
377 if self.template:
378 return u'%s (template)' % (self.name)
378 return u'%s (template)' % (self.name)
379 else:
379 else:
380 return u'%s' % (self.name)
380 return u'%s' % (self.name)
381
381
382 def jsonify(self):
382 def jsonify(self):
383
383
384 data = {}
384 data = {}
385
385
386 ignored = ('template')
386 ignored = ('template')
387
387
388 for field in self._meta.fields:
388 for field in self._meta.fields:
389 if field.name in ignored:
389 if field.name in ignored:
390 continue
390 continue
391 data[field.name] = field.value_from_object(self)
391 data[field.name] = field.value_from_object(self)
392
392
393 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
393 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
394 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
394 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
395 data['location'] = self.location.name
395 data['location'] = self.location.name
396 data['configurations'] = ['{}'.format(conf.pk) for
396 data['configurations'] = ['{}'.format(conf.pk) for
397 conf in Configuration.objects.filter(experiment=self, type=0)]
397 conf in Configuration.objects.filter(experiment=self, type=0)]
398
398
399 return data
399 return data
400
400
401 @property
401 @property
402 def radar_system(self):
402 def radar_system(self):
403 return self.location
403 return self.location
404
404
405 def clone(self, **kwargs):
405 def clone(self, **kwargs):
406
406
407 confs = Configuration.objects.filter(experiment=self, type=0)
407 confs = Configuration.objects.filter(experiment=self, type=0)
408 self.pk = None
408 self.pk = None
409 self.name = '{}_{:%y%m%d}'.format(self.name, datetime.now())
409 self.name = '{}_{:%y%m%d}'.format(self.name, datetime.now())
410 for attr, value in kwargs.items():
410 for attr, value in kwargs.items():
411 setattr(self, attr, value)
411 setattr(self, attr, value)
412
412
413 self.save()
413 self.save()
414
414
415 for conf in confs:
415 for conf in confs:
416 conf.clone(experiment=self, template=False)
416 conf.clone(experiment=self, template=False)
417
417
418 return self
418 return self
419
419
420 def start(self):
420 def start(self):
421 '''
421 '''
422 Configure and start experiments's devices
422 Configure and start experiments's devices
423 ABS-CGS-DDS-RC-JARS
423 ABS-CGS-DDS-RC-JARS
424 '''
424 '''
425
425
426 result = 2
427 confs = []
426 confs = []
428 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
427 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
429 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix]
428 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix]
430 if rc_mix:
429 if rc_mix:
431 for conf in allconfs:
430 for conf in allconfs:
432 if conf.device.device_type.name == 'rc' and not conf.mix:
431 if conf.device.device_type.name == 'rc' and not conf.mix:
433 continue
432 continue
434 confs.append(conf)
433 confs.append(conf)
435 else:
434 else:
436 confs = allconfs
435 confs = allconfs
437 #Only Configured Devices.
436
438 for conf in confs:
437 try:
439 if conf.device.status in (0, 4):
438 for conf in confs:
440 result = 0
439 conf.stop_device()
441 return result
440 conf.write_device()
442 for conf in confs:
441 conf.start_device()
443 conf.stop_device()
442 time.sleep(0.1)
444 conf.write_device()
443 except:
445 conf.start_device()
444 return 0
446 time.sleep(1)
445 return 2
447
448 return result
449
446
450
447
451 def stop(self):
448 def stop(self):
452 '''
449 '''
453 Stop experiments's devices
450 Stop experiments's devices
454 DDS-JARS-RC-CGS-ABS
451 DDS-JARS-RC-CGS-ABS
455 '''
452 '''
456
453
457 result = 1
458
459 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
454 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
460 confs=confs.exclude(device__device_type__name='cgs')
455 confs=confs.exclude(device__device_type__name='cgs')
461 for conf in confs:
456 try:
462 if conf.device.status in (0, 4):
457 for conf in confs:
463 result = 0
458 conf.stop_device()
464 continue
459 except:
465 conf.stop_device()
460 return 0
466
461 return 1
467 return result
468
469
462
470 def get_status(self):
463 def get_status(self):
471
464
472 if self.status == 3:
465 if self.status == 3:
473 return
466 return
474
467
475 confs = Configuration.objects.filter(experiment=self, type=0)
468 confs = Configuration.objects.filter(experiment=self, type=0)
476
469
477 for conf in confs:
470 for conf in confs:
478 conf.status_device()
471 conf.status_device()
479
472
480 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
473 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
481
474
482 if total==2*confs.count():
475 if total==2*confs.count():
483 status = 1
476 status = 1
484 elif total == 3*confs.count():
477 elif total == 3*confs.count():
485 status = 2
478 status = 2
486 else:
479 else:
487 status = 0
480 status = 0
488
481
489 self.status = status
482 self.status = status
490 self.save()
483 self.save()
491
484
492 def status_color(self):
485 def status_color(self):
493 color = 'muted'
486 color = 'muted'
494 if self.status == 0:
487 if self.status == 0:
495 color = "danger"
488 color = "danger"
496 elif self.status == 1:
489 elif self.status == 1:
497 color = "info"
490 color = "warning"
498 elif self.status == 2:
491 elif self.status == 2:
499 color = "success"
492 color = "success"
500 elif self.status == 3:
493 elif self.status == 3:
501 color = "warning"
494 color = "info"
502
495
503 return color
496 return color
504
497
505 def parms_to_dict(self):
498 def parms_to_dict(self):
506
499
507 params = Params({})
500 params = Params({})
508 params.add(self.jsonify(), 'experiments')
501 params.add(self.jsonify(), 'experiments')
509
502
510 configurations = Configuration.objects.filter(experiment=self, type=0)
503 configurations = Configuration.objects.filter(experiment=self, type=0)
511
504
512 for conf in configurations:
505 for conf in configurations:
513 params.add(conf.jsonify(), 'configurations')
506 params.add(conf.jsonify(), 'configurations')
514 if conf.device.device_type.name=='rc':
507 if conf.device.device_type.name=='rc':
515 for line in conf.get_lines():
508 for line in conf.get_lines():
516 params.add(line.jsonify(), 'lines')
509 params.add(line.jsonify(), 'lines')
517
510
518 return params.data
511 return params.data
519
512
520 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
513 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
521
514
522 configurations = Configuration.objects.filter(experiment=self)
515 configurations = Configuration.objects.filter(experiment=self)
523
516
524 if id_exp is not None:
517 if id_exp is not None:
525 exp_parms = parms['experiments']['byId'][id_exp]
518 exp_parms = parms['experiments']['byId'][id_exp]
526 else:
519 else:
527 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
520 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
528
521
529 if configurations:
522 if configurations:
530 for configuration in configurations:
523 for configuration in configurations:
531 configuration.delete()
524 configuration.delete()
532
525
533 for id_conf in exp_parms['configurations']:
526 for id_conf in exp_parms['configurations']:
534 conf_parms = parms['configurations']['byId'][id_conf]
527 conf_parms = parms['configurations']['byId'][id_conf]
535 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
528 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
536 model = CONF_MODELS[conf_parms['device_type']]
529 model = CONF_MODELS[conf_parms['device_type']]
537 conf = model(
530 conf = model(
538 experiment = self,
531 experiment = self,
539 device = device,
532 device = device,
540 )
533 )
541 conf.dict_to_parms(parms, id=id_conf)
534 conf.dict_to_parms(parms, id=id_conf)
542
535
543
536
544 location, created = Location.objects.get_or_create(name=exp_parms['location'])
537 location, created = Location.objects.get_or_create(name=exp_parms['location'])
545 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
538 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
546 self.location = location
539 self.location = location
547 self.start_time = exp_parms['start_time']
540 self.start_time = exp_parms['start_time']
548 self.end_time = exp_parms['end_time']
541 self.end_time = exp_parms['end_time']
549 self.save()
542 self.save()
550
543
551 return self
544 return self
552
545
553 def get_absolute_url(self):
546 def get_absolute_url(self):
554 return reverse('url_experiment', args=[str(self.id)])
547 return reverse('url_experiment', args=[str(self.id)])
555
548
556 def get_absolute_url_edit(self):
549 def get_absolute_url_edit(self):
557 return reverse('url_edit_experiment', args=[str(self.id)])
550 return reverse('url_edit_experiment', args=[str(self.id)])
558
551
559 def get_absolute_url_delete(self):
552 def get_absolute_url_delete(self):
560 return reverse('url_delete_experiment', args=[str(self.id)])
553 return reverse('url_delete_experiment', args=[str(self.id)])
561
554
562 def get_absolute_url_import(self):
555 def get_absolute_url_import(self):
563 return reverse('url_import_experiment', args=[str(self.id)])
556 return reverse('url_import_experiment', args=[str(self.id)])
564
557
565 def get_absolute_url_export(self):
558 def get_absolute_url_export(self):
566 return reverse('url_export_experiment', args=[str(self.id)])
559 return reverse('url_export_experiment', args=[str(self.id)])
567
560
568 def get_absolute_url_start(self):
561 def get_absolute_url_start(self):
569 return reverse('url_start_experiment', args=[str(self.id)])
562 return reverse('url_start_experiment', args=[str(self.id)])
570
563
571 def get_absolute_url_stop(self):
564 def get_absolute_url_stop(self):
572 return reverse('url_stop_experiment', args=[str(self.id)])
565 return reverse('url_stop_experiment', args=[str(self.id)])
573
566
574
567
575 class Configuration(PolymorphicModel):
568 class Configuration(PolymorphicModel):
576
569
577 template = models.BooleanField(default=False)
570 template = models.BooleanField(default=False)
578 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
571 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
579 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=True, null=True)
572 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=True, null=True)
580 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
573 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
581 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
574 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
582 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
575 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
583 created_date = models.DateTimeField(auto_now_add=True)
576 created_date = models.DateTimeField(auto_now_add=True)
584 programmed_date = models.DateTimeField(auto_now=True)
577 programmed_date = models.DateTimeField(auto_now=True)
585 parameters = models.TextField(default='{}')
578 parameters = models.TextField(default='{}')
586 author = models.ForeignKey(User, null=True, blank=True)
579 author = models.ForeignKey(User, null=True, blank=True)
587 hash = models.CharField(default='', max_length=64, null=True, blank=True)
580 hash = models.CharField(default='', max_length=64, null=True, blank=True)
588 message = ""
581 message = ""
589
582
590 class Meta:
583 class Meta:
591 db_table = 'db_configurations'
584 db_table = 'db_configurations'
592 ordering = ('device__device_type__name',)
585 ordering = ('device__device_type__name',)
593
586
594 def __str__(self):
587 def __str__(self):
595
588
596 ret = u'{} '.format(self.device.device_type.name.upper())
589 ret = u'{} '.format(self.device.device_type.name.upper())
597
590
598 if 'mix' in [f.name for f in self._meta.get_fields()]:
591 if 'mix' in [f.name for f in self._meta.get_fields()]:
599 if self.mix:
592 if self.mix:
600 ret = '{} MIX '.format(self.device.device_type.name.upper())
593 ret = '{} MIX '.format(self.device.device_type.name.upper())
601
594
602 if 'label' in [f.name for f in self._meta.get_fields()]:
595 if 'label' in [f.name for f in self._meta.get_fields()]:
603 ret += '{}'.format(self.label)
596 ret += '{}'.format(self.label)
604
597
605 if self.template:
598 if self.template:
606 ret += ' (template)'
599 ret += ' (template)'
607
600
608 return ret
601 return ret
609
602
610 @property
603 @property
611 def name(self):
604 def name(self):
612
605
613 return str(self)
606 return str(self)
614
607
615 def jsonify(self):
608 def jsonify(self):
616
609
617 data = {}
610 data = {}
618
611
619 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
612 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
620 'created_date', 'programmed_date', 'template', 'device',
613 'created_date', 'programmed_date', 'template', 'device',
621 'experiment')
614 'experiment')
622
615
623 for field in self._meta.fields:
616 for field in self._meta.fields:
624 if field.name in ignored:
617 if field.name in ignored:
625 continue
618 continue
626 data[field.name] = field.value_from_object(self)
619 data[field.name] = field.value_from_object(self)
627
620
628 data['device_type'] = self.device.device_type.name
621 data['device_type'] = self.device.device_type.name
629
622
630 if self.device.device_type.name == 'rc':
623 if self.device.device_type.name == 'rc':
631 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
624 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
632 data['delays'] = self.get_delays()
625 data['delays'] = self.get_delays()
633 data['pulses'] = self.get_pulses()
626 data['pulses'] = self.get_pulses()
634
627
635 elif self.device.device_type.name == 'jars':
628 elif self.device.device_type.name == 'jars':
636 data['decode_type'] = DECODE_TYPE[self.decode_data][1]
629 data['decode_type'] = DECODE_TYPE[self.decode_data][1]
637
630
638 elif self.device.device_type.name == 'dds':
631 elif self.device.device_type.name == 'dds':
639 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
632 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
640 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
633 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
641 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
634 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
642 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
635 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
643
636
644 return data
637 return data
645
638
646 def clone(self, **kwargs):
639 def clone(self, **kwargs):
647
640
648 self.pk = None
641 self.pk = None
649 self.id = None
642 self.id = None
650 for attr, value in kwargs.items():
643 for attr, value in kwargs.items():
651 setattr(self, attr, value)
644 setattr(self, attr, value)
652
645
653 self.save()
646 self.save()
654
647
655 return self
648 return self
656
649
657 def parms_to_dict(self):
650 def parms_to_dict(self):
658
651
659 params = Params({})
652 params = Params({})
660 params.add(self.jsonify(), 'configurations')
653 params.add(self.jsonify(), 'configurations')
661
654
662 if self.device.device_type.name=='rc':
655 if self.device.device_type.name=='rc':
663 for line in self.get_lines():
656 for line in self.get_lines():
664 params.add(line.jsonify(), 'lines')
657 params.add(line.jsonify(), 'lines')
665
658
666 return params.data
659 return params.data
667
660
668 def parms_to_text(self):
661 def parms_to_text(self):
669
662
670 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
663 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
671
664
672
665
673 def parms_to_binary(self):
666 def parms_to_binary(self):
674
667
675 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
668 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
676
669
677
670
678 def dict_to_parms(self, parameters, id=None):
671 def dict_to_parms(self, parameters, id=None):
679
672
680 params = Params(parameters)
673 params = Params(parameters)
681
674
682 if id:
675 if id:
683 data = params.get_conf(id_conf=id)
676 data = params.get_conf(id_conf=id)
684 else:
677 else:
685 data = params.get_conf(dtype=self.device.device_type.name)
678 data = params.get_conf(dtype=self.device.device_type.name)
686
679
687 if data['device_type']=='rc':
680 if data['device_type']=='rc':
688 self.clean_lines()
681 self.clean_lines()
689 lines = data.pop('lines', None)
682 lines = data.pop('lines', None)
690 for line_id in lines:
683 for line_id in lines:
691 pass
684 pass
692
685
693 for key, value in data.items():
686 for key, value in data.items():
694 if key not in ('id', 'device_type'):
687 if key not in ('id', 'device_type'):
695 setattr(self, key, value)
688 setattr(self, key, value)
696
689
697 self.save()
690 self.save()
698
691
699
692
700 def export_to_file(self, format="json"):
693 def export_to_file(self, format="json"):
701
694
702 content_type = ''
695 content_type = ''
703
696
704 if format == 'racp':
697 if format == 'racp':
705 content_type = 'text/plain'
698 content_type = 'text/plain'
706 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
699 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
707 content = self.parms_to_text(file_format = 'racp')
700 content = self.parms_to_text(file_format = 'racp')
708
701
709 if format == 'text':
702 if format == 'text':
710 content_type = 'text/plain'
703 content_type = 'text/plain'
711 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
704 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
712 content = self.parms_to_text()
705 content = self.parms_to_text()
713
706
714 if format == 'binary':
707 if format == 'binary':
715 content_type = 'application/octet-stream'
708 content_type = 'application/octet-stream'
716 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
709 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
717 content = self.parms_to_binary()
710 content = self.parms_to_binary()
718
711
719 if not content_type:
712 if not content_type:
720 content_type = 'application/json'
713 content_type = 'application/json'
721 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
714 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
722 content = json.dumps(self.parms_to_dict(), indent=2)
715 content = json.dumps(self.parms_to_dict(), indent=2)
723
716
724 fields = {'content_type':content_type,
717 fields = {'content_type':content_type,
725 'filename':filename,
718 'filename':filename,
726 'content':content
719 'content':content
727 }
720 }
728
721
729 return fields
722 return fields
730
723
731 def import_from_file(self, fp):
724 def import_from_file(self, fp):
732
725
733 parms = {}
726 parms = {}
734
727
735 path, ext = os.path.splitext(fp.name)
728 path, ext = os.path.splitext(fp.name)
736
729
737 if ext == '.json':
730 if ext == '.json':
738 parms = json.load(fp)
731 parms = json.load(fp)
739
732
740 if ext == '.dds':
733 if ext == '.dds':
741 lines = fp.readlines()
734 lines = fp.readlines()
742 parms = dds_data.text_to_dict(lines)
735 parms = dds_data.text_to_dict(lines)
743
736
744 if ext == '.racp':
737 if ext == '.racp':
745 if self.device.device_type.name == 'jars':
738 if self.device.device_type.name == 'jars':
746 parms = RacpFile(fp).to_dict()
739 parms = RacpFile(fp).to_dict()
747 parms['filter_parms'] = json.loads(self.filter_parms)
740 parms['filter_parms'] = json.loads(self.filter_parms)
748 return parms
741 return parms
749 parms = RCFile(fp).to_dict()
742 parms = RCFile(fp).to_dict()
750
743
751 return parms
744 return parms
752
745
753 def status_device(self):
746 def status_device(self):
754
747
755 self.message = 'Function not implemented'
748 self.message = 'Function not implemented'
756 return False
749 return False
757
750
758
751
759 def stop_device(self):
752 def stop_device(self):
760
753
761 self.message = 'Function not implemented'
754 self.message = 'Function not implemented'
762 return False
755 return False
763
756
764
757
765 def start_device(self):
758 def start_device(self):
766
759
767 self.message = 'Function not implemented'
760 self.message = 'Function not implemented'
768 return False
761 return False
769
762
770
763
771 def write_device(self, parms):
764 def write_device(self, parms):
772
765
773 self.message = 'Function not implemented'
766 self.message = 'Function not implemented'
774 return False
767 return False
775
768
776
769
777 def read_device(self):
770 def read_device(self):
778
771
779 self.message = 'Function not implemented'
772 self.message = 'Function not implemented'
780 return False
773 return False
781
774
782
775
783 def get_absolute_url(self):
776 def get_absolute_url(self):
784 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
777 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
785
778
786 def get_absolute_url_edit(self):
779 def get_absolute_url_edit(self):
787 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
780 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
788
781
789 def get_absolute_url_delete(self):
782 def get_absolute_url_delete(self):
790 return reverse('url_delete_dev_conf', args=[str(self.id)])
783 return reverse('url_delete_dev_conf', args=[str(self.id)])
791
784
792 def get_absolute_url_import(self):
785 def get_absolute_url_import(self):
793 return reverse('url_import_dev_conf', args=[str(self.id)])
786 return reverse('url_import_dev_conf', args=[str(self.id)])
794
787
795 def get_absolute_url_export(self):
788 def get_absolute_url_export(self):
796 return reverse('url_export_dev_conf', args=[str(self.id)])
789 return reverse('url_export_dev_conf', args=[str(self.id)])
797
790
798 def get_absolute_url_write(self):
791 def get_absolute_url_write(self):
799 return reverse('url_write_dev_conf', args=[str(self.id)])
792 return reverse('url_write_dev_conf', args=[str(self.id)])
800
793
801 def get_absolute_url_read(self):
794 def get_absolute_url_read(self):
802 return reverse('url_read_dev_conf', args=[str(self.id)])
795 return reverse('url_read_dev_conf', args=[str(self.id)])
803
796
804 def get_absolute_url_start(self):
797 def get_absolute_url_start(self):
805 return reverse('url_start_dev_conf', args=[str(self.id)])
798 return reverse('url_start_dev_conf', args=[str(self.id)])
806
799
807 def get_absolute_url_stop(self):
800 def get_absolute_url_stop(self):
808 return reverse('url_stop_dev_conf', args=[str(self.id)])
801 return reverse('url_stop_dev_conf', args=[str(self.id)])
809
802
810 def get_absolute_url_status(self):
803 def get_absolute_url_status(self):
811 return reverse('url_status_dev_conf', args=[str(self.id)])
804 return reverse('url_status_dev_conf', args=[str(self.id)])
@@ -1,81 +1,85
1 {% extends "base.html" %}
1 {% extends "base.html" %}
2 {% load bootstrap3 %}
2 {% load bootstrap3 %}
3 {% load static %}
3 {% load static %}
4 {% load main_tags %}
4 {% load main_tags %}
5 {% block content-title %}{{title}}{% endblock %}
5 {% block content-title %}{{title}}{% endblock %}
6 {% block content-suptitle %}{{suptitle}}{% endblock %}
6 {% block content-suptitle %}{{suptitle}}{% endblock %}
7
7
8 {% block content %}
8 {% block content %}
9
9
10 {% block menu-actions %}
10 {% block menu-actions %}
11 <span class=" dropdown pull-right">
11 <span class=" dropdown pull-right">
12 <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-menu-hamburger gi-2x" aria-hidden="true"></span></a>
12 <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-menu-hamburger gi-2x" aria-hidden="true"></span></a>
13 <ul class="dropdown-menu" role="menu">
13 <ul class="dropdown-menu" role="menu">
14 <li><a href="{{ dev_conf.get_absolute_url_edit }}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</a></li>
14 <li><a href="{{ dev_conf.get_absolute_url_edit }}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</a></li>
15 <li><a href="{{ dev_conf.get_absolute_url_delete }}"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Delete</a></li>
15 <li><a href="{{ dev_conf.get_absolute_url_delete }}"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Delete</a></li>
16 <li><a href="{{ dev_conf.get_absolute_url_import }}"><span class="glyphicon glyphicon-import" aria-hidden="true"></span> Import </a></li>
16 <li><a href="{{ dev_conf.get_absolute_url_import }}"><span class="glyphicon glyphicon-import" aria-hidden="true"></span> Import </a></li>
17 <li><a href="{{ dev_conf.get_absolute_url_export }}"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Export </a></li>
17 <li><a href="{{ dev_conf.get_absolute_url_export }}"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Export </a></li>
18 {% block extra-menu-actions %}
18 {% block extra-menu-actions %}
19 {% endblock %}
19 {% endblock %}
20 <li><a>----------------</a></li>
20 <li><a>----------------</a></li>
21 <li><a href="{{ dev_conf.get_absolute_url_status }}"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> Status</a></li>
21 <li><a href="{{ dev_conf.get_absolute_url_status }}"><span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> Status</a></li>
22 {% if not no_play %}
22 {% if not no_play %}
23 {% if not only_stop %}
23 {% if not only_stop %}
24 <li><a href="{{ dev_conf.get_absolute_url_start}}"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Start</a></li>
24 <li><a href="{{ dev_conf.get_absolute_url_start}}"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Start</a></li>
25 {% endif %}
25 {% endif %}
26 <li><a href="{{ dev_conf.get_absolute_url_stop }}"><span class="glyphicon glyphicon-stop" aria-hidden="true"></span> Stop</a></li>
26 <li><a href="{{ dev_conf.get_absolute_url_stop }}"><span class="glyphicon glyphicon-stop" aria-hidden="true"></span> Stop</a></li>
27 {% endif %}
27 {% endif %}
28 <li><a href="{{ dev_conf.get_absolute_url_write }}"><span class="glyphicon glyphicon-download" aria-hidden="true"></span> Write</a></li>
28 <li><a href="{{ dev_conf.get_absolute_url_write }}"><span class="glyphicon glyphicon-download" aria-hidden="true"></span> Write</a></li>
29 {% if dev_conf.device.device_type.name != 'abs' %}
29 {% if dev_conf.device.device_type.name != 'abs' %}
30 <li><a href="{{ dev_conf.get_absolute_url_read }}"><span class="glyphicon glyphicon-upload" aria-hidden="true"></span> Read</a></li>
30 <li><a href="{{ dev_conf.get_absolute_url_read }}"><span class="glyphicon glyphicon-upload" aria-hidden="true"></span> Read</a></li>
31 {% endif %}
31 {% endif %}
32 </ul>
32 </ul>
33 </span>
33 </span>
34 {% endblock %}
34 {% endblock %}
35
35
36 {% block content-detail %}
36 {% block content-detail %}
37 <table class="table table-bordered">
37 <table class="table table-bordered">
38 <tr>
38 <tr>
39 <th>Status</th>
39 <th>Status</th>
40 <td class="text-{{dev_conf.device.status_color}}"><strong> {% if dev_conf.device.device_type.name == 'abs' %} {{connected_modules}} {% else %} {{dev_conf.device.get_status_display}}{% endif %}</strong></td>
40 {% if dev_conf.pk == dev_conf.device.conf_active %}
41 </tr>
41 <td class="text-{{dev_conf.device.status_color}}"><strong> {% if dev_conf.device.device_type.name == 'abs' %} {{connected_modules}} {% else %} {{dev_conf.device.get_status_display}}{% endif %}</strong></td>
42 {% else %}
43 <td class="text-info"><strong> Connected </strong></td>
44 {% endif %}
45 </tr>
42
46
43 {% for key in dev_conf_keys %}
47 {% for key in dev_conf_keys %}
44 <tr>
48 <tr>
45 <th>{% get_verbose_field_name dev_conf key %}</th>
49 <th>{% get_verbose_field_name dev_conf key %}</th>
46 <td>{{dev_conf|attr:key}}</td>
50 <td>{{dev_conf|attr:key}}</td>
47 </tr>
51 </tr>
48 {% endfor %}
52 {% endfor %}
49 </table>
53 </table>
50 {% endblock %}
54 {% endblock %}
51
55
52 {% block extra-content %}
56 {% block extra-content %}
53 {% endblock %}
57 {% endblock %}
54
58
55 {% endblock %}
59 {% endblock %}
56
60
57 {% block extra-js%}
61 {% block extra-js%}
58 <script type="text/javascript">
62 <script type="text/javascript">
59
63
60 $("#bt_edit").click(function() {
64 $("#bt_edit").click(function() {
61 document.location = "{{ dev_conf.get_absolute_url_edit }}";
65 document.location = "{{ dev_conf.get_absolute_url_edit }}";
62 });
66 });
63
67
64 $("#bt_read").click(function() {
68 $("#bt_read").click(function() {
65 document.location = "{{ dev_conf.get_absolute_url_read }}";
69 document.location = "{{ dev_conf.get_absolute_url_read }}";
66 });
70 });
67
71
68 $("#bt_write").click(function() {
72 $("#bt_write").click(function() {
69 document.location = "{{ dev_conf.get_absolute_url_write }}";
73 document.location = "{{ dev_conf.get_absolute_url_write }}";
70 });
74 });
71
75
72 $("#bt_import").click(function() {
76 $("#bt_import").click(function() {
73 document.location = "{{ dev_conf.get_absolute_url_import }}";
77 document.location = "{{ dev_conf.get_absolute_url_import }}";
74 });
78 });
75
79
76 $("#bt_export").click(function() {
80 $("#bt_export").click(function() {
77 document.location = "{{ dev_conf.get_absolute_url_export }}";
81 document.location = "{{ dev_conf.get_absolute_url_export }}";
78 });
82 });
79
83
80 </script>
84 </script>
81 {% endblock %}
85 {% endblock %}
@@ -1,105 +1,105
1 {% extends "base.html" %}
1 {% extends "base.html" %}
2 {% load bootstrap3 %}
2 {% load bootstrap3 %}
3 {% load static %}
3 {% load static %}
4 {% load main_tags %}
4 {% load main_tags %}
5 {% block extra-head %}
5 {% block extra-head %}
6 <link href="{% static 'css/bootstrap-datetimepicker.min.css' %}" media="screen" rel="stylesheet">
6 <link href="{% static 'css/bootstrap-datetimepicker.min.css' %}" media="screen" rel="stylesheet">
7 {% endblock %}
7 {% endblock %}
8 {% block content-title %}{{title}}{% endblock %}
8 {% block content-title %}{{title}}{% endblock %}
9 {% block content-suptitle %}{{suptitle}}{% endblock %}
9 {% block content-suptitle %}{{suptitle}}{% endblock %}
10
10
11 {% block content %}
11 {% block content %}
12
12
13 {% block menu-actions %}
13 {% block menu-actions %}
14 <span class=" dropdown pull-right">
14 <span class=" dropdown pull-right">
15 <a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-menu-hamburger gi-2x" 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 <ul class="dropdown-menu" role="menu">
16 <ul class="dropdown-menu" role="menu">
17 <li><a href="{% url 'url_edit_experiment' experiment.id %}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</a></li>
17 <li><a href="{% url 'url_edit_experiment' experiment.id %}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit</a></li>
18 <li><a href="{% url 'url_delete_experiment' experiment.id %}"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Delete</a></li>
18 <li><a href="{% url 'url_delete_experiment' experiment.id %}"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span> Delete</a></li>
19 <li><a href="{{ experiment.get_absolute_url_import }}"><span class="glyphicon glyphicon-import" aria-hidden="true"></span> Import </a></li>
19 <li><a href="{{ experiment.get_absolute_url_import }}"><span class="glyphicon glyphicon-import" aria-hidden="true"></span> Import </a></li>
20 <li><a href="{{ experiment.get_absolute_url_export }}"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Export </a></li>
20 <li><a href="{{ experiment.get_absolute_url_export }}"><span class="glyphicon glyphicon-export" aria-hidden="true"></span> Export </a></li>
21 <li><a>----------------</a></li>
21 <li><a>----------------</a></li>
22 <li><a href="{{ experiment.get_absolute_url_start}}"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Start</a></li>
22 <li><a href="{{ experiment.get_absolute_url_start}}"><span class="glyphicon glyphicon-play" aria-hidden="true"></span> Start</a></li>
23 <li><a href="{{ experiment.get_absolute_url_stop }}"><span class="glyphicon glyphicon-stop" aria-hidden="true"></span> Stop</a></li>
23 <li><a href="{{ experiment.get_absolute_url_stop }}"><span class="glyphicon glyphicon-stop" aria-hidden="true"></span> Stop</a></li>
24 <li><a href="{% url 'url_mix_experiment' experiment.id %}"><span class="glyphicon glyphicon-random" aria-hidden="true"></span> Mix RC Configurations </a></li>
24 <li><a href="{% url 'url_mix_experiment' experiment.id %}"><span class="glyphicon glyphicon-random" aria-hidden="true"></span> Mix RC Configurations </a></li>
25 <li><a href="{% url 'url_add_dev_conf' experiment.id %}"><span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span> Add Configuration</a></li>
25 <li><a href="{% url 'url_add_dev_conf' experiment.id %}"><span class="glyphicon glyphicon-plus-sign" aria-hidden="true"></span> Add Configuration</a></li>
26 <li><a href="{% url 'url_sum_experiment' experiment.id %}"><span class="glyphicon glyphicon-list-alt" aria-hidden="true"></span> Summary</a></li>
26 <li><a href="{% url 'url_sum_experiment' experiment.id %}"><span class="glyphicon glyphicon-list-alt" aria-hidden="true"></span> Summary</a></li>
27
27
28 </ul>
28 </ul>
29 </span>
29 </span>
30 {% endblock %}
30 {% endblock %}
31
31
32 <table class="table table-bordered">
32 <table class="table table-bordered">
33 {% for key in experiment_keys %}
33 {% for key in experiment_keys %}
34 {% if key == 'freq' %}
34 {% if key == 'freq' %}
35 <tr><th>Operating Freq. (MHz)</th><td>{{experiment|attr:key}}</td></tr>
35 <tr><th>Operating Freq. (MHz)</th><td>{{experiment|attr:key}}</td></tr>
36 {% else %}
36 {% else %}
37 <tr><th>{{key|title}}</th><td>{{experiment|attr:key}}</td></tr>
37 <tr><th>{{key|title}}</th><td>{{experiment|attr:key}}</td></tr>
38 {% endif %}
38 {% endif %}
39 {% endfor %}
39 {% endfor %}
40 </table>
40 </table>
41 <br>
41 <br>
42
42
43 <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
43 <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
44
44
45 <div class="panel panel-default bootcards-summary">
45 <div class="panel panel-default bootcards-summary">
46 <div class="panel-heading" role="tab">
46 <div class="panel-heading" role="tab">
47 <h4 class="panel-title">
47 <h4 class="panel-title">
48 Devices
48 Devices
49 </h4>
49 </h4>
50 </div>
50 </div>
51 <div class="panel-body">
51 <div class="panel-body">
52
52
53 {% for item in configurations %}
53 {% for item in configurations %}
54 <div class="col-xs-6 col-sm-4" style="padding-top:5px;padding-bottom:5px">
54 <div class="col-xs-6 col-sm-4" style="padding-top:5px;padding-bottom:5px">
55 <a class="bootcards-summary-item" href="{{item.get_absolute_url}}"><br>
55 <a class="bootcards-summary-item" href="{{item.get_absolute_url}}"><br>
56 {% if item.device.device_type.name == 'cgs' %}
56 {% if item.device.device_type.name == 'cgs' %}
57 <i class="fa fa-2x fa-clock-o"></i>
57 <i class="fa fa-2x fa-clock-o"></i>
58 {% elif item.device.device_type.name == 'rc' %}
58 {% elif item.device.device_type.name == 'rc' %}
59 <i class="fa fa-2x fa-microchip"></i>
59 <i class="fa fa-2x fa-microchip"></i>
60 {% elif item.device.device_type.name == 'abs' %}
60 {% elif item.device.device_type.name == 'abs' %}
61 <i class="fa fa-2x fa-podcast"></i>
61 <i class="fa fa-2x fa-podcast"></i>
62 {% elif item.device.device_type.name == 'jars' %}
62 {% elif item.device.device_type.name == 'jars' %}
63 <i class="fa fa-2x fa-desktop"></i>
63 <i class="fa fa-2x fa-desktop"></i>
64 {% elif item.device.device_type.name == 'dds' %}
64 {% elif item.device.device_type.name == 'dds' %}
65 <i class="fa fa-2x fa-bar-chart"></i>
65 <i class="fa fa-2x fa-bar-chart"></i>
66 {% else %}
66 {% else %}
67 <i class="fa fa-3x fa-puzzle-piece"></i>
67 <i class="fa fa-3x fa-puzzle-piece"></i>
68 {%endif%}
68 {%endif%}
69 <h4>{{item}}<br><small>{{item.device.ip_address}}</small>
69 <h4>{{item}}<br><small>{{item.device.ip_address}}</small>
70 {%if experiment.status == 3 %}
70 {%if item.pk != item.device.conf_active %}
71 <span class="label label-info">Configured</span>
71 <span class="label label-info">Configured</span>
72 {%else%}
72 {%else%}
73 <span class="label label-{{item.device.status_color}}">{{item.device.get_status_display}}</span>
73 <span class="label label-{{item.device.status_color}}">{{item.device.get_status_display}}</span>
74 {%endif%}
74 {%endif%}
75 </h4>
75 </h4>
76 </a>
76 </a>
77 </div>
77 </div>
78 {% endfor %}
78 {% endfor %}
79
79
80 </div>
80 </div>
81 </div>
81 </div>
82 </div>
82 </div>
83 {% endblock %}
83 {% endblock %}
84
84
85 {% block sidebar%}
85 {% block sidebar%}
86 {% include "sidebar_devices.html" %}
86 {% include "sidebar_devices.html" %}
87 {% endblock %}
87 {% endblock %}
88
88
89 {% block extra-js%}
89 {% block extra-js%}
90 <script type="text/javascript">
90 <script type="text/javascript">
91
91
92 $(".clickable-row").click(function() {
92 $(".clickable-row").click(function() {
93 document.location = $(this).data("href");
93 document.location = $(this).data("href");
94 });
94 });
95
95
96 $("#bt_edit").click(function() {
96 $("#bt_edit").click(function() {
97 document.location = "{% url 'url_edit_experiment' experiment.id%}";
97 document.location = "{% url 'url_edit_experiment' experiment.id%}";
98 });
98 });
99
99
100 $("#bt_add_conf").click(function() {
100 $("#bt_add_conf").click(function() {
101 document.location = "{% url 'url_add_dev_conf' experiment.id %}";
101 document.location = "{% url 'url_add_dev_conf' experiment.id %}";
102 });
102 });
103
103
104 </script>
104 </script>
105 {% endblock %}
105 {% endblock %}
@@ -1,1868 +1,1881
1 import ast
1 import ast
2 import json
2 import json
3 import hashlib
3 import hashlib
4 from datetime import datetime, timedelta
4 from datetime import datetime, timedelta
5
5
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7 from django.utils.safestring import mark_safe
7 from django.utils.safestring import mark_safe
8 from django.http import HttpResponseRedirect
8 from django.http import HttpResponseRedirect
9 from django.core.urlresolvers import reverse
9 from django.core.urlresolvers import reverse
10 from django.db.models import Q
10 from django.db.models import Q
11 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
11 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
12 from django.contrib import messages
12 from django.contrib import messages
13 from django.http.request import QueryDict
13 from django.http.request import QueryDict
14 from django.contrib.auth.decorators import login_required, user_passes_test
14 from django.contrib.auth.decorators import login_required, user_passes_test
15
15
16 try:
16 try:
17 from urllib.parse import urlencode
17 from urllib.parse import urlencode
18 except ImportError:
18 except ImportError:
19 from urllib import urlencode
19 from urllib import urlencode
20
20
21 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
21 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
22 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
22 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
23
23
24 from .tasks import task_start
24 from .tasks import task_start
25
25
26 from apps.rc.forms import RCConfigurationForm, RCLineCode, RCMixConfigurationForm
26 from apps.rc.forms import RCConfigurationForm, RCLineCode, RCMixConfigurationForm
27 from apps.dds.forms import DDSConfigurationForm
27 from apps.dds.forms import DDSConfigurationForm
28 from apps.jars.forms import JARSConfigurationForm
28 from apps.jars.forms import JARSConfigurationForm
29 from apps.cgs.forms import CGSConfigurationForm
29 from apps.cgs.forms import CGSConfigurationForm
30 from apps.abs.forms import ABSConfigurationForm
30 from apps.abs.forms import ABSConfigurationForm
31 from apps.usrp.forms import USRPConfigurationForm
31 from apps.usrp.forms import USRPConfigurationForm
32 from .utils import Params
32 from .utils import Params
33
33
34 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment, DEV_STATES
34 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment, DEV_STATES
35 from apps.cgs.models import CGSConfiguration
35 from apps.cgs.models import CGSConfiguration
36 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
36 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
37 from apps.usrp.models import USRPConfiguration
37 from apps.usrp.models import USRPConfiguration
38 from apps.abs.models import ABSConfiguration
38 from apps.abs.models import ABSConfiguration
39 from apps.rc.models import RCConfiguration, RCLine, RCLineType, RCClock
39 from apps.rc.models import RCConfiguration, RCLine, RCLineType, RCClock
40 from apps.dds.models import DDSConfiguration
40 from apps.dds.models import DDSConfiguration
41
41
42 from radarsys.celery import app
42 from radarsys.celery import app
43
43
44
44
45 CONF_FORMS = {
45 CONF_FORMS = {
46 'rc': RCConfigurationForm,
46 'rc': RCConfigurationForm,
47 'dds': DDSConfigurationForm,
47 'dds': DDSConfigurationForm,
48 'jars': JARSConfigurationForm,
48 'jars': JARSConfigurationForm,
49 'cgs': CGSConfigurationForm,
49 'cgs': CGSConfigurationForm,
50 'abs': ABSConfigurationForm,
50 'abs': ABSConfigurationForm,
51 'usrp': USRPConfigurationForm,
51 'usrp': USRPConfigurationForm,
52 }
52 }
53
53
54 CONF_MODELS = {
54 CONF_MODELS = {
55 'rc': RCConfiguration,
55 'rc': RCConfiguration,
56 'dds': DDSConfiguration,
56 'dds': DDSConfiguration,
57 'jars': JARSConfiguration,
57 'jars': JARSConfiguration,
58 'cgs': CGSConfiguration,
58 'cgs': CGSConfiguration,
59 'abs': ABSConfiguration,
59 'abs': ABSConfiguration,
60 'usrp': USRPConfiguration,
60 'usrp': USRPConfiguration,
61 }
61 }
62
62
63 MIX_MODES = {
63 MIX_MODES = {
64 '0': 'P',
64 '0': 'P',
65 '1': 'S',
65 '1': 'S',
66 }
66 }
67
67
68 MIX_OPERATIONS = {
68 MIX_OPERATIONS = {
69 '0': 'OR',
69 '0': 'OR',
70 '1': 'XOR',
70 '1': 'XOR',
71 '2': 'AND',
71 '2': 'AND',
72 '3': 'NAND',
72 '3': 'NAND',
73 }
73 }
74
74
75
75
76 def is_developer(user):
76 def is_developer(user):
77
77
78 groups = [str(g.name) for g in user.groups.all()]
78 groups = [str(g.name) for g in user.groups.all()]
79 return 'Developer' in groups or user.is_staff
79 return 'Developer' in groups or user.is_staff
80
80
81
81
82 def is_operator(user):
82 def is_operator(user):
83
83
84 groups = [str(g.name) for g in user.groups.all()]
84 groups = [str(g.name) for g in user.groups.all()]
85 return 'Operator' in groups or user.is_staff
85 return 'Operator' in groups or user.is_staff
86
86
87
87
88 def has_been_modified(model):
88 def has_been_modified(model):
89
89
90 prev_hash = model.hash
90 prev_hash = model.hash
91 new_hash = hashlib.sha256(str(model.parms_to_dict)).hexdigest()
91 new_hash = hashlib.sha256(str(model.parms_to_dict)).hexdigest()
92 if prev_hash != new_hash:
92 if prev_hash != new_hash:
93 model.hash = new_hash
93 model.hash = new_hash
94 model.save()
94 model.save()
95 return True
95 return True
96 return False
96 return False
97
97
98
98
99 def index(request):
99 def index(request):
100 kwargs = {'no_sidebar': True}
100 kwargs = {'no_sidebar': True}
101
101
102 return render(request, 'index.html', kwargs)
102 return render(request, 'index.html', kwargs)
103
103
104
104
105 def locations(request):
105 def locations(request):
106
106
107 page = request.GET.get('page')
107 page = request.GET.get('page')
108 order = ('name',)
108 order = ('name',)
109
109
110 kwargs = get_paginator(Location, page, order)
110 kwargs = get_paginator(Location, page, order)
111
111
112 kwargs['keys'] = ['name', 'description']
112 kwargs['keys'] = ['name', 'description']
113 kwargs['title'] = 'Radar System'
113 kwargs['title'] = 'Radar System'
114 kwargs['suptitle'] = 'List'
114 kwargs['suptitle'] = 'List'
115 kwargs['no_sidebar'] = True
115 kwargs['no_sidebar'] = True
116
116
117 return render(request, 'base_list.html', kwargs)
117 return render(request, 'base_list.html', kwargs)
118
118
119
119
120 def location(request, id_loc):
120 def location(request, id_loc):
121
121
122 location = get_object_or_404(Location, pk=id_loc)
122 location = get_object_or_404(Location, pk=id_loc)
123
123
124 kwargs = {}
124 kwargs = {}
125 kwargs['location'] = location
125 kwargs['location'] = location
126 kwargs['location_keys'] = ['name', 'description']
126 kwargs['location_keys'] = ['name', 'description']
127
127
128 kwargs['title'] = 'Location'
128 kwargs['title'] = 'Location'
129 kwargs['suptitle'] = 'Details'
129 kwargs['suptitle'] = 'Details'
130
130
131 return render(request, 'location.html', kwargs)
131 return render(request, 'location.html', kwargs)
132
132
133
133
134 @login_required
134 @login_required
135 def location_new(request):
135 def location_new(request):
136
136
137 if request.method == 'GET':
137 if request.method == 'GET':
138 form = LocationForm()
138 form = LocationForm()
139
139
140 if request.method == 'POST':
140 if request.method == 'POST':
141 form = LocationForm(request.POST)
141 form = LocationForm(request.POST)
142
142
143 if form.is_valid():
143 if form.is_valid():
144 form.save()
144 form.save()
145 return redirect('url_locations')
145 return redirect('url_locations')
146
146
147 kwargs = {}
147 kwargs = {}
148 kwargs['form'] = form
148 kwargs['form'] = form
149 kwargs['title'] = 'Radar System'
149 kwargs['title'] = 'Radar System'
150 kwargs['suptitle'] = 'New'
150 kwargs['suptitle'] = 'New'
151 kwargs['button'] = 'Create'
151 kwargs['button'] = 'Create'
152
152
153 return render(request, 'base_edit.html', kwargs)
153 return render(request, 'base_edit.html', kwargs)
154
154
155
155
156 @login_required
156 @login_required
157 def location_edit(request, id_loc):
157 def location_edit(request, id_loc):
158
158
159 location = get_object_or_404(Location, pk=id_loc)
159 location = get_object_or_404(Location, pk=id_loc)
160
160
161 if request.method == 'GET':
161 if request.method == 'GET':
162 form = LocationForm(instance=location)
162 form = LocationForm(instance=location)
163
163
164 if request.method == 'POST':
164 if request.method == 'POST':
165 form = LocationForm(request.POST, instance=location)
165 form = LocationForm(request.POST, instance=location)
166
166
167 if form.is_valid():
167 if form.is_valid():
168 form.save()
168 form.save()
169 return redirect('url_locations')
169 return redirect('url_locations')
170
170
171 kwargs = {}
171 kwargs = {}
172 kwargs['form'] = form
172 kwargs['form'] = form
173 kwargs['title'] = 'Location'
173 kwargs['title'] = 'Location'
174 kwargs['suptitle'] = 'Edit'
174 kwargs['suptitle'] = 'Edit'
175 kwargs['button'] = 'Update'
175 kwargs['button'] = 'Update'
176
176
177 return render(request, 'base_edit.html', kwargs)
177 return render(request, 'base_edit.html', kwargs)
178
178
179
179
180 @login_required
180 @login_required
181 def location_delete(request, id_loc):
181 def location_delete(request, id_loc):
182
182
183 location = get_object_or_404(Location, pk=id_loc)
183 location = get_object_or_404(Location, pk=id_loc)
184
184
185 if request.method == 'POST':
185 if request.method == 'POST':
186
186
187 if is_developer(request.user):
187 if is_developer(request.user):
188 location.delete()
188 location.delete()
189 return redirect('url_locations')
189 return redirect('url_locations')
190
190
191 messages.error(request, 'Not enough permission to delete this object')
191 messages.error(request, 'Not enough permission to delete this object')
192 return redirect(location.get_absolute_url())
192 return redirect(location.get_absolute_url())
193
193
194 kwargs = {
194 kwargs = {
195 'title': 'Delete',
195 'title': 'Delete',
196 'suptitle': 'Location',
196 'suptitle': 'Location',
197 'object': location,
197 'object': location,
198 'delete': True
198 'delete': True
199 }
199 }
200
200
201 return render(request, 'confirm.html', kwargs)
201 return render(request, 'confirm.html', kwargs)
202
202
203
203
204 def devices(request):
204 def devices(request):
205
205
206 page = request.GET.get('page')
206 page = request.GET.get('page')
207 order = ('location', 'device_type')
207 order = ('location', 'device_type')
208
208
209 filters = request.GET.copy()
209 filters = request.GET.copy()
210 kwargs = get_paginator(Device, page, order, filters)
210 kwargs = get_paginator(Device, page, order, filters)
211 form = FilterForm(initial=request.GET, extra_fields=['tags'])
211 form = FilterForm(initial=request.GET, extra_fields=['tags'])
212
212
213 kwargs['keys'] = ['device_type', 'location',
213 kwargs['keys'] = ['device_type', 'location',
214 'ip_address', 'port_address', 'actions']
214 'ip_address', 'port_address', 'actions']
215 kwargs['title'] = 'Device'
215 kwargs['title'] = 'Device'
216 kwargs['suptitle'] = 'List'
216 kwargs['suptitle'] = 'List'
217 kwargs['no_sidebar'] = True
217 kwargs['no_sidebar'] = True
218 kwargs['form'] = form
218 kwargs['form'] = form
219 kwargs['add_url'] = reverse('url_add_device')
219 kwargs['add_url'] = reverse('url_add_device')
220 filters.pop('page', None)
220 filters.pop('page', None)
221 kwargs['q'] = urlencode(filters)
221 kwargs['q'] = urlencode(filters)
222 kwargs['menu_devices'] = 'active'
222 kwargs['menu_devices'] = 'active'
223 return render(request, 'base_list.html', kwargs)
223 return render(request, 'base_list.html', kwargs)
224
224
225
225
226 def device(request, id_dev):
226 def device(request, id_dev):
227
227
228 device = get_object_or_404(Device, pk=id_dev)
228 device = get_object_or_404(Device, pk=id_dev)
229
229
230 kwargs = {}
230 kwargs = {}
231 kwargs['device'] = device
231 kwargs['device'] = device
232 kwargs['device_keys'] = ['device_type',
232 kwargs['device_keys'] = ['device_type',
233 'ip_address', 'port_address', 'description']
233 'ip_address', 'port_address', 'description']
234
234
235 kwargs['title'] = 'Device'
235 kwargs['title'] = 'Device'
236 kwargs['suptitle'] = 'Details'
236 kwargs['suptitle'] = 'Details'
237 kwargs['menu_devices'] = 'active'
237 kwargs['menu_devices'] = 'active'
238
238
239 return render(request, 'device.html', kwargs)
239 return render(request, 'device.html', kwargs)
240
240
241
241
242 @login_required
242 @login_required
243 def device_new(request):
243 def device_new(request):
244
244
245 if request.method == 'GET':
245 if request.method == 'GET':
246 form = DeviceForm()
246 form = DeviceForm()
247
247
248 if request.method == 'POST':
248 if request.method == 'POST':
249 form = DeviceForm(request.POST)
249 form = DeviceForm(request.POST)
250
250
251 if form.is_valid():
251 if form.is_valid():
252 form.save()
252 form.save()
253 return redirect('url_devices')
253 return redirect('url_devices')
254
254
255 kwargs = {}
255 kwargs = {}
256 kwargs['form'] = form
256 kwargs['form'] = form
257 kwargs['title'] = 'Device'
257 kwargs['title'] = 'Device'
258 kwargs['suptitle'] = 'New'
258 kwargs['suptitle'] = 'New'
259 kwargs['button'] = 'Create'
259 kwargs['button'] = 'Create'
260 kwargs['menu_devices'] = 'active'
260 kwargs['menu_devices'] = 'active'
261
261
262 return render(request, 'base_edit.html', kwargs)
262 return render(request, 'base_edit.html', kwargs)
263
263
264
264
265 @login_required
265 @login_required
266 def device_edit(request, id_dev):
266 def device_edit(request, id_dev):
267
267
268 device = get_object_or_404(Device, pk=id_dev)
268 device = get_object_or_404(Device, pk=id_dev)
269
269
270 if request.method == 'GET':
270 if request.method == 'GET':
271 form = DeviceForm(instance=device)
271 form = DeviceForm(instance=device)
272
272
273 if request.method == 'POST':
273 if request.method == 'POST':
274 form = DeviceForm(request.POST, instance=device)
274 form = DeviceForm(request.POST, instance=device)
275
275
276 if form.is_valid():
276 if form.is_valid():
277 form.save()
277 form.save()
278 return redirect(device.get_absolute_url())
278 return redirect(device.get_absolute_url())
279
279
280 kwargs = {}
280 kwargs = {}
281 kwargs['form'] = form
281 kwargs['form'] = form
282 kwargs['title'] = 'Device'
282 kwargs['title'] = 'Device'
283 kwargs['suptitle'] = 'Edit'
283 kwargs['suptitle'] = 'Edit'
284 kwargs['button'] = 'Update'
284 kwargs['button'] = 'Update'
285 kwargs['menu_devices'] = 'active'
285 kwargs['menu_devices'] = 'active'
286
286
287 return render(request, 'base_edit.html', kwargs)
287 return render(request, 'base_edit.html', kwargs)
288
288
289
289
290 @login_required
290 @login_required
291 def device_delete(request, id_dev):
291 def device_delete(request, id_dev):
292
292
293 device = get_object_or_404(Device, pk=id_dev)
293 device = get_object_or_404(Device, pk=id_dev)
294
294
295 if request.method == 'POST':
295 if request.method == 'POST':
296
296
297 if is_developer(request.user):
297 if is_developer(request.user):
298 device.delete()
298 device.delete()
299 return redirect('url_devices')
299 return redirect('url_devices')
300
300
301 messages.error(request, 'Not enough permission to delete this object')
301 messages.error(request, 'Not enough permission to delete this object')
302 return redirect(device.get_absolute_url())
302 return redirect(device.get_absolute_url())
303
303
304 kwargs = {
304 kwargs = {
305 'title': 'Delete',
305 'title': 'Delete',
306 'suptitle': 'Device',
306 'suptitle': 'Device',
307 'object': device,
307 'object': device,
308 'delete': True
308 'delete': True
309 }
309 }
310 kwargs['menu_devices'] = 'active'
310 kwargs['menu_devices'] = 'active'
311
311
312 return render(request, 'confirm.html', kwargs)
312 return render(request, 'confirm.html', kwargs)
313
313
314
314
315 @login_required
315 @login_required
316 def device_change_ip(request, id_dev):
316 def device_change_ip(request, id_dev):
317
317
318 device = get_object_or_404(Device, pk=id_dev)
318 device = get_object_or_404(Device, pk=id_dev)
319
319
320 if request.method == 'POST':
320 if request.method == 'POST':
321
321
322 if is_developer(request.user):
322 if is_developer(request.user):
323 device.change_ip(**request.POST.dict())
323 device.change_ip(**request.POST.dict())
324 level, message = device.message.split('|')
324 level, message = device.message.split('|')
325 messages.add_message(request, level, message)
325 messages.add_message(request, level, message)
326 else:
326 else:
327 messages.error(
327 messages.error(
328 request, 'Not enough permission to delete this object')
328 request, 'Not enough permission to delete this object')
329 return redirect(device.get_absolute_url())
329 return redirect(device.get_absolute_url())
330
330
331 kwargs = {
331 kwargs = {
332 'title': 'Device',
332 'title': 'Device',
333 'suptitle': 'Change IP',
333 'suptitle': 'Change IP',
334 'object': device,
334 'object': device,
335 'previous': device.get_absolute_url(),
335 'previous': device.get_absolute_url(),
336 'form': ChangeIpForm(initial={'ip_address': device.ip_address}),
336 'form': ChangeIpForm(initial={'ip_address': device.ip_address}),
337 'message': ' ',
337 'message': ' ',
338 }
338 }
339 kwargs['menu_devices'] = 'active'
339 kwargs['menu_devices'] = 'active'
340
340
341 return render(request, 'confirm.html', kwargs)
341 return render(request, 'confirm.html', kwargs)
342
342
343
343
344 def campaigns(request):
344 def campaigns(request):
345
345
346 page = request.GET.get('page')
346 page = request.GET.get('page')
347 order = ('-start_date',)
347 order = ('-start_date',)
348 filters = request.GET.copy()
348 filters = request.GET.copy()
349
349
350 kwargs = get_paginator(Campaign, page, order, filters)
350 kwargs = get_paginator(Campaign, page, order, filters)
351
351
352 form = FilterForm(initial=request.GET, extra_fields=[
352 form = FilterForm(initial=request.GET, extra_fields=[
353 'range_date', 'tags', 'template'])
353 'range_date', 'tags', 'template'])
354 kwargs['keys'] = ['name', 'start_date', 'end_date', 'actions']
354 kwargs['keys'] = ['name', 'start_date', 'end_date', 'actions']
355 kwargs['title'] = 'Campaign'
355 kwargs['title'] = 'Campaign'
356 kwargs['suptitle'] = 'List'
356 kwargs['suptitle'] = 'List'
357 kwargs['no_sidebar'] = True
357 kwargs['no_sidebar'] = True
358 kwargs['form'] = form
358 kwargs['form'] = form
359 kwargs['add_url'] = reverse('url_add_campaign')
359 kwargs['add_url'] = reverse('url_add_campaign')
360 filters.pop('page', None)
360 filters.pop('page', None)
361 kwargs['q'] = urlencode(filters)
361 kwargs['q'] = urlencode(filters)
362 kwargs['menu_campaigns'] = 'active'
362 kwargs['menu_campaigns'] = 'active'
363
363
364 return render(request, 'base_list.html', kwargs)
364 return render(request, 'base_list.html', kwargs)
365
365
366
366
367 def campaign(request, id_camp):
367 def campaign(request, id_camp):
368
368
369 campaign = get_object_or_404(Campaign, pk=id_camp)
369 campaign = get_object_or_404(Campaign, pk=id_camp)
370 experiments = Experiment.objects.filter(campaign=campaign)
370 experiments = Experiment.objects.filter(campaign=campaign)
371
371
372 form = CampaignForm(instance=campaign)
372 form = CampaignForm(instance=campaign)
373
373
374 kwargs = {}
374 kwargs = {}
375 kwargs['campaign'] = campaign
375 kwargs['campaign'] = campaign
376 kwargs['campaign_keys'] = ['template', 'name',
376 kwargs['campaign_keys'] = ['template', 'name',
377 'start_date', 'end_date', 'tags', 'description']
377 'start_date', 'end_date', 'tags', 'description']
378
378
379 kwargs['experiments'] = experiments
379 kwargs['experiments'] = experiments
380 kwargs['experiment_keys'] = [
380 kwargs['experiment_keys'] = [
381 'name', 'radar_system', 'start_time', 'end_time']
381 'name', 'radar_system', 'start_time', 'end_time']
382
382
383 kwargs['title'] = 'Campaign'
383 kwargs['title'] = 'Campaign'
384 kwargs['suptitle'] = 'Details'
384 kwargs['suptitle'] = 'Details'
385
385
386 kwargs['form'] = form
386 kwargs['form'] = form
387 kwargs['button'] = 'Add Experiment'
387 kwargs['button'] = 'Add Experiment'
388 kwargs['menu_campaigns'] = 'active'
388 kwargs['menu_campaigns'] = 'active'
389
389
390 return render(request, 'campaign.html', kwargs)
390 return render(request, 'campaign.html', kwargs)
391
391
392
392
393 @login_required
393 @login_required
394 def campaign_new(request):
394 def campaign_new(request):
395
395
396 kwargs = {}
396 kwargs = {}
397
397
398 if request.method == 'GET':
398 if request.method == 'GET':
399
399
400 if 'template' in request.GET:
400 if 'template' in request.GET:
401 if request.GET['template'] == '0':
401 if request.GET['template'] == '0':
402 form = NewForm(initial={'create_from': 2},
402 form = NewForm(initial={'create_from': 2},
403 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
403 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
404 else:
404 else:
405 kwargs['button'] = 'Create'
405 kwargs['button'] = 'Create'
406 kwargs['experiments'] = Configuration.objects.filter(
406 kwargs['experiments'] = Configuration.objects.filter(
407 experiment=request.GET['template'])
407 experiment=request.GET['template'])
408 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
408 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
409 camp = Campaign.objects.get(pk=request.GET['template'])
409 camp = Campaign.objects.get(pk=request.GET['template'])
410 form = CampaignForm(instance=camp,
410 form = CampaignForm(instance=camp,
411 initial={'name': '{}_{:%Y%m%d}'.format(camp.name, datetime.now()),
411 initial={'name': '{}_{:%Y%m%d}'.format(camp.name, datetime.now()),
412 'template': False})
412 'template': False})
413 elif 'blank' in request.GET:
413 elif 'blank' in request.GET:
414 kwargs['button'] = 'Create'
414 kwargs['button'] = 'Create'
415 form = CampaignForm()
415 form = CampaignForm()
416 else:
416 else:
417 form = NewForm()
417 form = NewForm()
418
418
419 if request.method == 'POST':
419 if request.method == 'POST':
420 kwargs['button'] = 'Create'
420 kwargs['button'] = 'Create'
421 post = request.POST.copy()
421 post = request.POST.copy()
422 experiments = []
422 experiments = []
423
423
424 for id_exp in post.getlist('experiments'):
424 for id_exp in post.getlist('experiments'):
425 exp = Experiment.objects.get(pk=id_exp)
425 exp = Experiment.objects.get(pk=id_exp)
426 new_exp = exp.clone(template=False)
426 new_exp = exp.clone(template=False)
427 experiments.append(new_exp)
427 experiments.append(new_exp)
428
428
429 post.setlist('experiments', [])
429 post.setlist('experiments', [])
430
430
431 form = CampaignForm(post)
431 form = CampaignForm(post)
432
432
433 if form.is_valid():
433 if form.is_valid():
434 campaign = form.save(commit=False)
434 campaign = form.save(commit=False)
435 campaign.author = request.user
435 campaign.author = request.user
436 for exp in experiments:
436 for exp in experiments:
437 campaign.experiments.add(exp)
437 campaign.experiments.add(exp)
438 campaign.save()
438 campaign.save()
439 return redirect('url_campaign', id_camp=campaign.id)
439 return redirect('url_campaign', id_camp=campaign.id)
440
440
441 kwargs['form'] = form
441 kwargs['form'] = form
442 kwargs['title'] = 'Campaign'
442 kwargs['title'] = 'Campaign'
443 kwargs['suptitle'] = 'New'
443 kwargs['suptitle'] = 'New'
444 kwargs['menu_campaigns'] = 'active'
444 kwargs['menu_campaigns'] = 'active'
445
445
446 return render(request, 'campaign_edit.html', kwargs)
446 return render(request, 'campaign_edit.html', kwargs)
447
447
448
448
449 @login_required
449 @login_required
450 def campaign_edit(request, id_camp):
450 def campaign_edit(request, id_camp):
451
451
452 campaign = get_object_or_404(Campaign, pk=id_camp)
452 campaign = get_object_or_404(Campaign, pk=id_camp)
453
453
454 if request.method == 'GET':
454 if request.method == 'GET':
455 form = CampaignForm(instance=campaign)
455 form = CampaignForm(instance=campaign)
456
456
457 if request.method == 'POST':
457 if request.method == 'POST':
458 exps = campaign.experiments.all().values_list('pk', flat=True)
458 exps = campaign.experiments.all().values_list('pk', flat=True)
459 post = request.POST.copy()
459 post = request.POST.copy()
460 new_exps = post.getlist('experiments')
460 new_exps = post.getlist('experiments')
461 post.setlist('experiments', [])
461 post.setlist('experiments', [])
462 form = CampaignForm(post, instance=campaign)
462 form = CampaignForm(post, instance=campaign)
463
463
464 if form.is_valid():
464 if form.is_valid():
465 camp = form.save()
465 camp = form.save()
466 for id_exp in new_exps:
466 for id_exp in new_exps:
467 if int(id_exp) in exps:
467 if int(id_exp) in exps:
468 exps.pop(id_exp)
468 exps.pop(id_exp)
469 else:
469 else:
470 exp = Experiment.objects.get(pk=id_exp)
470 exp = Experiment.objects.get(pk=id_exp)
471 if exp.template:
471 if exp.template:
472 camp.experiments.add(exp.clone(template=False))
472 camp.experiments.add(exp.clone(template=False))
473 else:
473 else:
474 camp.experiments.add(exp)
474 camp.experiments.add(exp)
475
475
476 for id_exp in exps:
476 for id_exp in exps:
477 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
477 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
478
478
479 return redirect('url_campaign', id_camp=id_camp)
479 return redirect('url_campaign', id_camp=id_camp)
480
480
481 kwargs = {}
481 kwargs = {}
482 kwargs['form'] = form
482 kwargs['form'] = form
483 kwargs['title'] = 'Campaign'
483 kwargs['title'] = 'Campaign'
484 kwargs['suptitle'] = 'Edit'
484 kwargs['suptitle'] = 'Edit'
485 kwargs['button'] = 'Update'
485 kwargs['button'] = 'Update'
486 kwargs['menu_campaigns'] = 'active'
486 kwargs['menu_campaigns'] = 'active'
487
487
488 return render(request, 'campaign_edit.html', kwargs)
488 return render(request, 'campaign_edit.html', kwargs)
489
489
490
490
491 @login_required
491 @login_required
492 def campaign_delete(request, id_camp):
492 def campaign_delete(request, id_camp):
493
493
494 campaign = get_object_or_404(Campaign, pk=id_camp)
494 campaign = get_object_or_404(Campaign, pk=id_camp)
495
495
496 if request.method == 'POST':
496 if request.method == 'POST':
497 if is_developer(request.user):
497 if is_developer(request.user):
498
498
499 for exp in campaign.experiments.all():
499 for exp in campaign.experiments.all():
500 for conf in Configuration.objects.filter(experiment=exp):
500 for conf in Configuration.objects.filter(experiment=exp):
501 conf.delete()
501 conf.delete()
502 exp.delete()
502 exp.delete()
503 campaign.delete()
503 campaign.delete()
504
504
505 return redirect('url_campaigns')
505 return redirect('url_campaigns')
506
506
507 messages.error(request, 'Not enough permission to delete this object')
507 messages.error(request, 'Not enough permission to delete this object')
508 return redirect(campaign.get_absolute_url())
508 return redirect(campaign.get_absolute_url())
509
509
510 kwargs = {
510 kwargs = {
511 'title': 'Delete',
511 'title': 'Delete',
512 'suptitle': 'Campaign',
512 'suptitle': 'Campaign',
513 'object': campaign,
513 'object': campaign,
514 'delete': True
514 'delete': True
515 }
515 }
516 kwargs['menu_campaigns'] = 'active'
516 kwargs['menu_campaigns'] = 'active'
517
517
518 return render(request, 'confirm.html', kwargs)
518 return render(request, 'confirm.html', kwargs)
519
519
520
520
521 @login_required
521 @login_required
522 def campaign_export(request, id_camp):
522 def campaign_export(request, id_camp):
523
523
524 campaign = get_object_or_404(Campaign, pk=id_camp)
524 campaign = get_object_or_404(Campaign, pk=id_camp)
525 content = campaign.parms_to_dict()
525 content = campaign.parms_to_dict()
526 content_type = 'application/json'
526 content_type = 'application/json'
527 filename = '%s_%s.json' % (campaign.name, campaign.id)
527 filename = '%s_%s.json' % (campaign.name, campaign.id)
528
528
529 response = HttpResponse(content_type=content_type)
529 response = HttpResponse(content_type=content_type)
530 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
530 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
531 response.write(json.dumps(content, indent=2))
531 response.write(json.dumps(content, indent=2))
532
532
533 return response
533 return response
534
534
535
535
536 @login_required
536 @login_required
537 def campaign_import(request, id_camp):
537 def campaign_import(request, id_camp):
538
538
539 campaign = get_object_or_404(Campaign, pk=id_camp)
539 campaign = get_object_or_404(Campaign, pk=id_camp)
540
540
541 if request.method == 'GET':
541 if request.method == 'GET':
542 file_form = UploadFileForm()
542 file_form = UploadFileForm()
543
543
544 if request.method == 'POST':
544 if request.method == 'POST':
545 file_form = UploadFileForm(request.POST, request.FILES)
545 file_form = UploadFileForm(request.POST, request.FILES)
546
546
547 if file_form.is_valid():
547 if file_form.is_valid():
548 new_camp = campaign.dict_to_parms(
548 new_camp = campaign.dict_to_parms(
549 json.load(request.FILES['file']), CONF_MODELS)
549 json.load(request.FILES['file']), CONF_MODELS)
550 messages.success(
550 messages.success(
551 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
551 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
552 return redirect(new_camp.get_absolute_url_edit())
552 return redirect(new_camp.get_absolute_url_edit())
553
553
554 messages.error(request, "Could not import parameters from file")
554 messages.error(request, "Could not import parameters from file")
555
555
556 kwargs = {}
556 kwargs = {}
557 kwargs['title'] = 'Campaign'
557 kwargs['title'] = 'Campaign'
558 kwargs['form'] = file_form
558 kwargs['form'] = file_form
559 kwargs['suptitle'] = 'Importing file'
559 kwargs['suptitle'] = 'Importing file'
560 kwargs['button'] = 'Import'
560 kwargs['button'] = 'Import'
561 kwargs['menu_campaigns'] = 'active'
561 kwargs['menu_campaigns'] = 'active'
562
562
563 return render(request, 'campaign_import.html', kwargs)
563 return render(request, 'campaign_import.html', kwargs)
564
564
565
565
566 def experiments(request):
566 def experiments(request):
567
567
568 page = request.GET.get('page')
568 page = request.GET.get('page')
569 order = ('location',)
569 order = ('location',)
570 filters = request.GET.copy()
570 filters = request.GET.copy()
571
571
572 if 'my experiments' in filters:
572 if 'my experiments' in filters:
573 filters.pop('my experiments', None)
573 filters.pop('my experiments', None)
574 filters['mine'] = request.user.id
574 filters['mine'] = request.user.id
575
575
576 kwargs = get_paginator(Experiment, page, order, filters)
576 kwargs = get_paginator(Experiment, page, order, filters)
577
577
578 fields = ['tags', 'template']
578 fields = ['tags', 'template']
579 if request.user.is_authenticated:
579 if request.user.is_authenticated:
580 fields.append('my experiments')
580 fields.append('my experiments')
581
581
582 form = FilterForm(initial=request.GET, extra_fields=fields)
582 form = FilterForm(initial=request.GET, extra_fields=fields)
583
583
584 kwargs['keys'] = ['name', 'radar_system',
584 kwargs['keys'] = ['name', 'radar_system',
585 'start_time', 'end_time', 'actions']
585 'start_time', 'end_time', 'actions']
586 kwargs['title'] = 'Experiment'
586 kwargs['title'] = 'Experiment'
587 kwargs['suptitle'] = 'List'
587 kwargs['suptitle'] = 'List'
588 kwargs['no_sidebar'] = True
588 kwargs['no_sidebar'] = True
589 kwargs['form'] = form
589 kwargs['form'] = form
590 kwargs['add_url'] = reverse('url_add_experiment')
590 kwargs['add_url'] = reverse('url_add_experiment')
591 filters = request.GET.copy()
591 filters = request.GET.copy()
592 filters.pop('page', None)
592 filters.pop('page', None)
593 kwargs['q'] = urlencode(filters)
593 kwargs['q'] = urlencode(filters)
594 kwargs['menu_experiments'] = 'active'
594 kwargs['menu_experiments'] = 'active'
595
595
596 return render(request, 'base_list.html', kwargs)
596 return render(request, 'base_list.html', kwargs)
597
597
598
598
599 def experiment(request, id_exp):
599 def experiment(request, id_exp):
600
600
601 experiment = get_object_or_404(Experiment, pk=id_exp)
601 experiment = get_object_or_404(Experiment, pk=id_exp)
602
602
603 configurations = Configuration.objects.filter(
603 configurations = Configuration.objects.filter(
604 experiment=experiment, type=0)
604 experiment=experiment, type=0)
605
605
606 kwargs = {}
606 kwargs = {}
607
607
608 kwargs['experiment_keys'] = ['template', 'radar_system',
608 kwargs['experiment_keys'] = ['template', 'radar_system',
609 'name', 'freq', 'start_time', 'end_time']
609 'name', 'freq', 'start_time', 'end_time']
610 kwargs['experiment'] = experiment
610 kwargs['experiment'] = experiment
611 kwargs['configuration_keys'] = ['name', 'device__ip_address',
611 kwargs['configuration_keys'] = ['name', 'device__ip_address',
612 'device__port_address', 'device__status']
612 'device__port_address', 'device__status']
613 kwargs['configurations'] = configurations
613 kwargs['configurations'] = configurations
614 kwargs['title'] = 'Experiment'
614 kwargs['title'] = 'Experiment'
615 kwargs['suptitle'] = 'Details'
615 kwargs['suptitle'] = 'Details'
616 kwargs['button'] = 'Add Configuration'
616 kwargs['button'] = 'Add Configuration'
617 kwargs['menu_experiments'] = 'active'
617 kwargs['menu_experiments'] = 'active'
618
618
619 ###### SIDEBAR ######
619 ###### SIDEBAR ######
620 kwargs.update(sidebar(experiment=experiment))
620 kwargs.update(sidebar(experiment=experiment))
621
621
622 return render(request, 'experiment.html', kwargs)
622 return render(request, 'experiment.html', kwargs)
623
623
624
624
625 @login_required
625 @login_required
626 def experiment_new(request, id_camp=None):
626 def experiment_new(request, id_camp=None):
627
627
628 if not is_developer(request.user):
628 if not is_developer(request.user):
629 messages.error(
629 messages.error(
630 request, 'Developer required, to create new Experiments')
630 request, 'Developer required, to create new Experiments')
631 return redirect('index')
631 return redirect('index')
632 kwargs = {}
632 kwargs = {}
633
633
634 if request.method == 'GET':
634 if request.method == 'GET':
635 if 'template' in request.GET:
635 if 'template' in request.GET:
636 if request.GET['template'] == '0':
636 if request.GET['template'] == '0':
637 form = NewForm(initial={'create_from': 2},
637 form = NewForm(initial={'create_from': 2},
638 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
638 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
639 else:
639 else:
640 kwargs['button'] = 'Create'
640 kwargs['button'] = 'Create'
641 kwargs['configurations'] = Configuration.objects.filter(
641 kwargs['configurations'] = Configuration.objects.filter(
642 experiment=request.GET['template'])
642 experiment=request.GET['template'])
643 kwargs['configuration_keys'] = ['name', 'device__name',
643 kwargs['configuration_keys'] = ['name', 'device__name',
644 'device__ip_address', 'device__port_address']
644 'device__ip_address', 'device__port_address']
645 exp = Experiment.objects.get(pk=request.GET['template'])
645 exp = Experiment.objects.get(pk=request.GET['template'])
646 form = ExperimentForm(instance=exp,
646 form = ExperimentForm(instance=exp,
647 initial={'name': '{}_{:%y%m%d}'.format(exp.name, datetime.now()),
647 initial={'name': '{}_{:%y%m%d}'.format(exp.name, datetime.now()),
648 'template': False})
648 'template': False})
649 elif 'blank' in request.GET:
649 elif 'blank' in request.GET:
650 kwargs['button'] = 'Create'
650 kwargs['button'] = 'Create'
651 form = ExperimentForm()
651 form = ExperimentForm()
652 else:
652 else:
653 form = NewForm()
653 form = NewForm()
654
654
655 if request.method == 'POST':
655 if request.method == 'POST':
656 form = ExperimentForm(request.POST)
656 form = ExperimentForm(request.POST)
657 if form.is_valid():
657 if form.is_valid():
658 experiment = form.save(commit=False)
658 experiment = form.save(commit=False)
659 experiment.author = request.user
659 experiment.author = request.user
660 experiment.save()
660 experiment.save()
661
661
662 if 'template' in request.GET:
662 if 'template' in request.GET:
663 configurations = Configuration.objects.filter(
663 configurations = Configuration.objects.filter(
664 experiment=request.GET['template'], type=0)
664 experiment=request.GET['template'], type=0)
665 for conf in configurations:
665 for conf in configurations:
666 conf.clone(experiment=experiment, template=False)
666 conf.clone(experiment=experiment, template=False)
667
667
668 return redirect('url_experiment', id_exp=experiment.id)
668 return redirect('url_experiment', id_exp=experiment.id)
669
669
670 kwargs['form'] = form
670 kwargs['form'] = form
671 kwargs['title'] = 'Experiment'
671 kwargs['title'] = 'Experiment'
672 kwargs['suptitle'] = 'New'
672 kwargs['suptitle'] = 'New'
673 kwargs['menu_experiments'] = 'active'
673 kwargs['menu_experiments'] = 'active'
674
674
675 return render(request, 'experiment_edit.html', kwargs)
675 return render(request, 'experiment_edit.html', kwargs)
676
676
677
677
678 @login_required
678 @login_required
679 def experiment_edit(request, id_exp):
679 def experiment_edit(request, id_exp):
680
680
681 experiment = get_object_or_404(Experiment, pk=id_exp)
681 experiment = get_object_or_404(Experiment, pk=id_exp)
682
682
683 if request.method == 'GET':
683 if request.method == 'GET':
684 form = ExperimentForm(instance=experiment)
684 form = ExperimentForm(instance=experiment)
685
685
686 if request.method == 'POST':
686 if request.method == 'POST':
687 form = ExperimentForm(request.POST, instance=experiment)
687 form = ExperimentForm(request.POST, instance=experiment)
688
688
689 if form.is_valid():
689 if form.is_valid():
690 experiment = form.save()
690 experiment = form.save()
691 return redirect('url_experiment', id_exp=experiment.id)
691 return redirect('url_experiment', id_exp=experiment.id)
692
692
693 kwargs = {}
693 kwargs = {}
694 kwargs['form'] = form
694 kwargs['form'] = form
695 kwargs['title'] = 'Experiment'
695 kwargs['title'] = 'Experiment'
696 kwargs['suptitle'] = 'Edit'
696 kwargs['suptitle'] = 'Edit'
697 kwargs['button'] = 'Update'
697 kwargs['button'] = 'Update'
698 kwargs['menu_experiments'] = 'active'
698 kwargs['menu_experiments'] = 'active'
699
699
700 return render(request, 'experiment_edit.html', kwargs)
700 return render(request, 'experiment_edit.html', kwargs)
701
701
702
702
703 @login_required
703 @login_required
704 def experiment_delete(request, id_exp):
704 def experiment_delete(request, id_exp):
705
705
706 experiment = get_object_or_404(Experiment, pk=id_exp)
706 experiment = get_object_or_404(Experiment, pk=id_exp)
707
707
708 if request.method == 'POST':
708 if request.method == 'POST':
709 if is_developer(request.user):
709 if is_developer(request.user):
710 for conf in Configuration.objects.filter(experiment=experiment):
710 for conf in Configuration.objects.filter(experiment=experiment):
711 conf.delete()
711 conf.delete()
712 experiment.delete()
712 experiment.delete()
713 return redirect('url_experiments')
713 return redirect('url_experiments')
714
714
715 messages.error(request, 'Not enough permission to delete this object')
715 messages.error(request, 'Not enough permission to delete this object')
716 return redirect(experiment.get_absolute_url())
716 return redirect(experiment.get_absolute_url())
717
717
718 kwargs = {
718 kwargs = {
719 'title': 'Delete',
719 'title': 'Delete',
720 'suptitle': 'Experiment',
720 'suptitle': 'Experiment',
721 'object': experiment,
721 'object': experiment,
722 'delete': True
722 'delete': True
723 }
723 }
724
724
725 return render(request, 'confirm.html', kwargs)
725 return render(request, 'confirm.html', kwargs)
726
726
727
727
728 @login_required
728 @login_required
729 def experiment_export(request, id_exp):
729 def experiment_export(request, id_exp):
730
730
731 experiment = get_object_or_404(Experiment, pk=id_exp)
731 experiment = get_object_or_404(Experiment, pk=id_exp)
732 content = experiment.parms_to_dict()
732 content = experiment.parms_to_dict()
733 content_type = 'application/json'
733 content_type = 'application/json'
734 filename = '%s_%s.json' % (experiment.name, experiment.id)
734 filename = '%s_%s.json' % (experiment.name, experiment.id)
735
735
736 response = HttpResponse(content_type=content_type)
736 response = HttpResponse(content_type=content_type)
737 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
737 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
738 response.write(json.dumps(content, indent=2))
738 response.write(json.dumps(content, indent=2))
739
739
740 return response
740 return response
741
741
742
742
743 @login_required
743 @login_required
744 def experiment_import(request, id_exp):
744 def experiment_import(request, id_exp):
745
745
746 experiment = get_object_or_404(Experiment, pk=id_exp)
746 experiment = get_object_or_404(Experiment, pk=id_exp)
747 configurations = Configuration.objects.filter(experiment=experiment)
747 configurations = Configuration.objects.filter(experiment=experiment)
748
748
749 if request.method == 'GET':
749 if request.method == 'GET':
750 file_form = UploadFileForm()
750 file_form = UploadFileForm()
751
751
752 if request.method == 'POST':
752 if request.method == 'POST':
753 file_form = UploadFileForm(request.POST, request.FILES)
753 file_form = UploadFileForm(request.POST, request.FILES)
754
754
755 if file_form.is_valid():
755 if file_form.is_valid():
756 new_exp = experiment.dict_to_parms(
756 new_exp = experiment.dict_to_parms(
757 json.load(request.FILES['file']), CONF_MODELS)
757 json.load(request.FILES['file']), CONF_MODELS)
758 messages.success(
758 messages.success(
759 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
759 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
760 return redirect(new_exp.get_absolute_url_edit())
760 return redirect(new_exp.get_absolute_url_edit())
761
761
762 messages.error(request, "Could not import parameters from file")
762 messages.error(request, "Could not import parameters from file")
763
763
764 kwargs = {}
764 kwargs = {}
765 kwargs['title'] = 'Experiment'
765 kwargs['title'] = 'Experiment'
766 kwargs['form'] = file_form
766 kwargs['form'] = file_form
767 kwargs['suptitle'] = 'Importing file'
767 kwargs['suptitle'] = 'Importing file'
768 kwargs['button'] = 'Import'
768 kwargs['button'] = 'Import'
769 kwargs['menu_experiments'] = 'active'
769 kwargs['menu_experiments'] = 'active'
770
770
771 kwargs.update(sidebar(experiment=experiment))
771 kwargs.update(sidebar(experiment=experiment))
772
772
773 return render(request, 'experiment_import.html', kwargs)
773 return render(request, 'experiment_import.html', kwargs)
774
774
775
775
776 @login_required
776 @login_required
777 def experiment_start(request, id_exp):
777 def experiment_start(request, id_exp):
778
778
779 exp = get_object_or_404(Experiment, pk=id_exp)
779 exp = get_object_or_404(Experiment, pk=id_exp)
780
780
781 if exp.status == 2:
781 if exp.status == 2:
782 messages.warning(request, 'Experiment {} already runnnig'.format(exp))
782 messages.warning(request, 'Experiment {} already runnnig'.format(exp))
783 else:
783 else:
784 exp.status = exp.start()
784 exp.status = exp.start()
785 if exp.status == 0:
785 if exp.status == 0:
786 messages.error(request, 'Experiment {} not start'.format(exp))
786 messages.error(request, 'Experiment {} not start'.format(exp))
787 if exp.status == 2:
787 if exp.status == 2:
788 messages.success(request, 'Experiment {} started'.format(exp))
788 messages.success(request, 'Experiment {} started'.format(exp))
789
789
790 exp.save()
790 exp.save()
791
791
792 return redirect(exp.get_absolute_url())
792 return redirect(exp.get_absolute_url())
793
793
794
794
795 @login_required
795 @login_required
796 def experiment_stop(request, id_exp):
796 def experiment_stop(request, id_exp):
797
797
798 exp = get_object_or_404(Experiment, pk=id_exp)
798 exp = get_object_or_404(Experiment, pk=id_exp)
799
799
800 if exp.status == 2:
800 if exp.status == 2:
801 exp.status = exp.stop()
801 exp.status = exp.stop()
802 exp.save()
802 exp.save()
803 messages.success(request, 'Experiment {} stopped'.format(exp))
803 messages.success(request, 'Experiment {} stopped'.format(exp))
804 else:
804 else:
805 messages.error(request, 'Experiment {} not running'.format(exp))
805 messages.error(request, 'Experiment {} not running'.format(exp))
806
806
807 return redirect(exp.get_absolute_url())
807 return redirect(exp.get_absolute_url())
808
808
809
809
810 def experiment_status(request, id_exp):
810 def experiment_status(request, id_exp):
811
811
812 exp = get_object_or_404(Experiment, pk=id_exp)
812 exp = get_object_or_404(Experiment, pk=id_exp)
813
813
814 exp.get_status()
814 exp.get_status()
815
815
816 return redirect(exp.get_absolute_url())
816 return redirect(exp.get_absolute_url())
817
817
818
818
819 @login_required
819 @login_required
820 def experiment_mix(request, id_exp):
820 def experiment_mix(request, id_exp):
821
821
822 experiment = get_object_or_404(Experiment, pk=id_exp)
822 experiment = get_object_or_404(Experiment, pk=id_exp)
823 rc_confs = [conf for conf in RCConfiguration.objects.filter(
823 rc_confs = [conf for conf in RCConfiguration.objects.filter(
824 experiment=id_exp,
824 experiment=id_exp,
825 type=0,
825 type=0,
826 mix=False)]
826 mix=False)]
827
827
828 if len(rc_confs) < 2:
828 if len(rc_confs) < 2:
829 messages.warning(
829 messages.warning(
830 request, 'You need at least two RC Configurations to make a mix')
830 request, 'You need at least two RC Configurations to make a mix')
831 return redirect(experiment.get_absolute_url())
831 return redirect(experiment.get_absolute_url())
832
832
833 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True, type=0)
833 mix_confs = RCConfiguration.objects.filter(experiment=id_exp, mix=True, type=0)
834
834
835 if mix_confs:
835 if mix_confs:
836 mix = mix_confs[0]
836 mix = mix_confs[0]
837 else:
837 else:
838 mix = RCConfiguration(experiment=experiment,
838 mix = RCConfiguration(experiment=experiment,
839 device=rc_confs[0].device,
839 device=rc_confs[0].device,
840 ipp=rc_confs[0].ipp,
840 ipp=rc_confs[0].ipp,
841 clock_in=rc_confs[0].clock_in,
841 clock_in=rc_confs[0].clock_in,
842 clock_divider=rc_confs[0].clock_divider,
842 clock_divider=rc_confs[0].clock_divider,
843 mix=True,
843 mix=True,
844 parameters='')
844 parameters='')
845 mix.save()
845 mix.save()
846
846
847 line_type = RCLineType.objects.get(name='mix')
847 line_type = RCLineType.objects.get(name='mix')
848 for i in range(len(rc_confs[0].get_lines())):
848 for i in range(len(rc_confs[0].get_lines())):
849 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
849 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
850 line.save()
850 line.save()
851
851
852 initial = {'name': mix.name,
852 initial = {'name': mix.name,
853 'result': parse_mix_result(mix.parameters),
853 'result': parse_mix_result(mix.parameters),
854 'delay': 0,
854 'delay': 0,
855 'mask': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
855 'mask': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
856 }
856 }
857
857
858 if request.method == 'GET':
858 if request.method == 'GET':
859 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
859 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
860
860
861 if request.method == 'POST':
861 if request.method == 'POST':
862 result = mix.parameters
862 result = mix.parameters
863
863
864 if '{}|'.format(request.POST['experiment']) in result:
864 if '{}|'.format(request.POST['experiment']) in result:
865 messages.error(request, 'Configuration already added')
865 messages.error(request, 'Configuration already added')
866 else:
866 else:
867 if 'operation' in request.POST:
867 if 'operation' in request.POST:
868 operation = MIX_OPERATIONS[request.POST['operation']]
868 operation = MIX_OPERATIONS[request.POST['operation']]
869 else:
869 else:
870 operation = ' '
870 operation = ' '
871
871
872 mode = MIX_MODES[request.POST['mode']]
872 mode = MIX_MODES[request.POST['mode']]
873
873
874 if result:
874 if result:
875 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
875 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
876 request.POST['experiment'],
876 request.POST['experiment'],
877 mode,
877 mode,
878 operation,
878 operation,
879 float(
879 float(
880 request.POST['delay']),
880 request.POST['delay']),
881 parse_mask(
881 parse_mask(
882 request.POST.getlist('mask'))
882 request.POST.getlist('mask'))
883 )
883 )
884 else:
884 else:
885 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
885 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
886 mode,
886 mode,
887 operation,
887 operation,
888 float(request.POST['delay']),
888 float(request.POST['delay']),
889 parse_mask(
889 parse_mask(
890 request.POST.getlist('mask'))
890 request.POST.getlist('mask'))
891 )
891 )
892
892
893 mix.parameters = result
893 mix.parameters = result
894 mix.save()
894 mix.save()
895 mix.update_pulses()
895 mix.update_pulses()
896
896
897 initial['result'] = parse_mix_result(result)
897 initial['result'] = parse_mix_result(result)
898 initial['name'] = mix.name
898 initial['name'] = mix.name
899
899
900 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
900 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
901
901
902 kwargs = {
902 kwargs = {
903 'title': 'Experiment',
903 'title': 'Experiment',
904 'suptitle': 'Mix Configurations',
904 'suptitle': 'Mix Configurations',
905 'form': form,
905 'form': form,
906 'extra_button': 'Delete',
906 'extra_button': 'Delete',
907 'button': 'Add',
907 'button': 'Add',
908 'cancel': 'Back',
908 'cancel': 'Back',
909 'previous': experiment.get_absolute_url(),
909 'previous': experiment.get_absolute_url(),
910 'id_exp': id_exp,
910 'id_exp': id_exp,
911
911
912 }
912 }
913 kwargs['menu_experiments'] = 'active'
913 kwargs['menu_experiments'] = 'active'
914
914
915 return render(request, 'experiment_mix.html', kwargs)
915 return render(request, 'experiment_mix.html', kwargs)
916
916
917
917
918 @login_required
918 @login_required
919 def experiment_mix_delete(request, id_exp):
919 def experiment_mix_delete(request, id_exp):
920
920
921 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True, type=0)
921 conf = RCConfiguration.objects.get(experiment=id_exp, mix=True, type=0)
922 values = conf.parameters.split('-')
922 values = conf.parameters.split('-')
923 conf.parameters = '-'.join(values[:-1])
923 conf.parameters = '-'.join(values[:-1])
924 conf.save()
924 conf.save()
925
925
926 return redirect('url_mix_experiment', id_exp=id_exp)
926 return redirect('url_mix_experiment', id_exp=id_exp)
927
927
928
928
929 def experiment_summary(request, id_exp):
929 def experiment_summary(request, id_exp):
930
930
931 experiment = get_object_or_404(Experiment, pk=id_exp)
931 experiment = get_object_or_404(Experiment, pk=id_exp)
932 configurations = Configuration.objects.filter(
932 configurations = Configuration.objects.filter(
933 experiment=experiment, type=0)
933 experiment=experiment, type=0)
934
934
935 kwargs = {}
935 kwargs = {}
936 kwargs['experiment_keys'] = ['radar_system',
936 kwargs['experiment_keys'] = ['radar_system',
937 'name', 'freq', 'start_time', 'end_time']
937 'name', 'freq', 'start_time', 'end_time']
938 kwargs['experiment'] = experiment
938 kwargs['experiment'] = experiment
939 kwargs['configurations'] = []
939 kwargs['configurations'] = []
940 kwargs['title'] = 'Experiment Summary'
940 kwargs['title'] = 'Experiment Summary'
941 kwargs['suptitle'] = 'Details'
941 kwargs['suptitle'] = 'Details'
942 kwargs['button'] = 'Verify Parameters'
942 kwargs['button'] = 'Verify Parameters'
943
943
944 c_vel = 3.0*(10**8) # m/s
944 c_vel = 3.0*(10**8) # m/s
945 ope_freq = experiment.freq*(10**6) # 1/s
945 ope_freq = experiment.freq*(10**6) # 1/s
946 radar_lambda = c_vel/ope_freq # m
946 radar_lambda = c_vel/ope_freq # m
947 kwargs['radar_lambda'] = radar_lambda
947 kwargs['radar_lambda'] = radar_lambda
948
948
949 ipp = None
949 ipp = None
950 nsa = 1
950 nsa = 1
951 code_id = 0
951 code_id = 0
952 tx_line = {}
952 tx_line = {}
953
953
954 for configuration in configurations.filter(device__device_type__name = 'rc'):
954 for configuration in configurations.filter(device__device_type__name = 'rc'):
955
955
956 if configuration.mix:
956 if configuration.mix:
957 continue
957 continue
958 conf = {'conf': configuration}
958 conf = {'conf': configuration}
959 conf['keys'] = []
959 conf['keys'] = []
960 conf['NTxs'] = configuration.ntx
960 conf['NTxs'] = configuration.ntx
961 conf['keys'].append('NTxs')
961 conf['keys'].append('NTxs')
962 ipp = configuration.ipp
962 ipp = configuration.ipp
963 conf['IPP'] = ipp
963 conf['IPP'] = ipp
964 conf['keys'].append('IPP')
964 conf['keys'].append('IPP')
965 lines = configuration.get_lines(line_type__name='tx')
965 lines = configuration.get_lines(line_type__name='tx')
966
966
967 for tx_line in lines:
967 for tx_line in lines:
968 tx_params = json.loads(tx_line.params)
968 tx_params = json.loads(tx_line.params)
969 conf[tx_line.get_name()] = '{} Km'.format(tx_params['pulse_width'])
969 conf[tx_line.get_name()] = '{} Km'.format(tx_params['pulse_width'])
970 conf['keys'].append(tx_line.get_name())
970 conf['keys'].append(tx_line.get_name())
971 delays = tx_params['delays']
971 delays = tx_params['delays']
972 if delays not in ('', '0'):
972 if delays not in ('', '0'):
973 n = len(delays.split(','))
973 n = len(delays.split(','))
974 taus = '{} Taus: {}'.format(n, delays)
974 taus = '{} Taus: {}'.format(n, delays)
975 else:
975 else:
976 taus = '-'
976 taus = '-'
977 conf['Taus ({})'.format(tx_line.get_name())] = taus
977 conf['Taus ({})'.format(tx_line.get_name())] = taus
978 conf['keys'].append('Taus ({})'.format(tx_line.get_name()))
978 conf['keys'].append('Taus ({})'.format(tx_line.get_name()))
979 for code_line in configuration.get_lines(line_type__name='codes'):
979 for code_line in configuration.get_lines(line_type__name='codes'):
980 code_params = json.loads(code_line.params)
980 code_params = json.loads(code_line.params)
981 code_id = code_params['code']
981 code_id = code_params['code']
982 if tx_line.pk == int(code_params['TX_ref']):
982 if tx_line.pk == int(code_params['TX_ref']):
983 conf['Code ({})'.format(tx_line.get_name())] = '{}:{}'.format(RCLineCode.objects.get(pk=code_params['code']),
983 conf['Code ({})'.format(tx_line.get_name())] = '{}:{}'.format(RCLineCode.objects.get(pk=code_params['code']),
984 '-'.join(code_params['codes']))
984 '-'.join(code_params['codes']))
985 conf['keys'].append('Code ({})'.format(tx_line.get_name()))
985 conf['keys'].append('Code ({})'.format(tx_line.get_name()))
986
986
987 for windows_line in configuration.get_lines(line_type__name='windows'):
987 for windows_line in configuration.get_lines(line_type__name='windows'):
988 win_params = json.loads(windows_line.params)
988 win_params = json.loads(windows_line.params)
989 if tx_line.pk == int(win_params['TX_ref']):
989 if tx_line.pk == int(win_params['TX_ref']):
990 windows = ''
990 windows = ''
991 nsa = win_params['params'][0]['number_of_samples']
991 nsa = win_params['params'][0]['number_of_samples']
992 for i, params in enumerate(win_params['params']):
992 for i, params in enumerate(win_params['params']):
993 windows += 'W{}: Ho={first_height} km DH={resolution} km NSA={number_of_samples}<br>'.format(
993 windows += 'W{}: Ho={first_height} km DH={resolution} km NSA={number_of_samples}<br>'.format(
994 i, **params)
994 i, **params)
995 conf['Window'] = mark_safe(windows)
995 conf['Window'] = mark_safe(windows)
996 conf['keys'].append('Window')
996 conf['keys'].append('Window')
997
997
998 kwargs['configurations'].append(conf)
998 kwargs['configurations'].append(conf)
999
999
1000 for configuration in configurations.filter(device__device_type__name = 'jars'):
1000 for configuration in configurations.filter(device__device_type__name = 'jars'):
1001
1001
1002 conf = {'conf': configuration}
1002 conf = {'conf': configuration}
1003 conf['keys'] = []
1003 conf['keys'] = []
1004 conf['Type of Data'] = EXPERIMENT_TYPE[configuration.exp_type][1]
1004 conf['Type of Data'] = EXPERIMENT_TYPE[configuration.exp_type][1]
1005 conf['keys'].append('Type of Data')
1005 conf['keys'].append('Type of Data')
1006 channels_number = configuration.channels_number
1006 channels_number = configuration.channels_number
1007 exp_type = configuration.exp_type
1007 exp_type = configuration.exp_type
1008 fftpoints = configuration.fftpoints
1008 fftpoints = configuration.fftpoints
1009 filter_parms = json.loads(configuration.filter_parms)
1009 filter_parms = json.loads(configuration.filter_parms)
1010 spectral_number = configuration.spectral_number
1010 spectral_number = configuration.spectral_number
1011 acq_profiles = configuration.acq_profiles
1011 acq_profiles = configuration.acq_profiles
1012 cohe_integr = configuration.cohe_integr
1012 cohe_integr = configuration.cohe_integr
1013 profiles_block = configuration.profiles_block
1013 profiles_block = configuration.profiles_block
1014
1014
1015 conf['Num of Profiles'] = acq_profiles
1015 conf['Num of Profiles'] = acq_profiles
1016 conf['keys'].append('Num of Profiles')
1016 conf['keys'].append('Num of Profiles')
1017
1017
1018 conf['Prof per Block'] = profiles_block
1018 conf['Prof per Block'] = profiles_block
1019 conf['keys'].append('Prof per Block')
1019 conf['keys'].append('Prof per Block')
1020
1020
1021 conf['Blocks per File'] = configuration.raw_data_blocks
1021 conf['Blocks per File'] = configuration.raw_data_blocks
1022 conf['keys'].append('Blocks per File')
1022 conf['keys'].append('Blocks per File')
1023
1023
1024 if exp_type == 0: # Short
1024 if exp_type == 0: # Short
1025 bytes_ = 2
1025 bytes_ = 2
1026 b = nsa*2*bytes_*channels_number
1026 b = nsa*2*bytes_*channels_number
1027 else: # Float
1027 else: # Float
1028 bytes_ = 4
1028 bytes_ = 4
1029 channels = channels_number + spectral_number
1029 channels = channels_number + spectral_number
1030 b = nsa*2*bytes_*fftpoints*channels
1030 b = nsa*2*bytes_*fftpoints*channels
1031
1031
1032 codes_num = 7
1032 codes_num = 7
1033 if code_id == 2:
1033 if code_id == 2:
1034 codes_num = 7
1034 codes_num = 7
1035 elif code_id == 12:
1035 elif code_id == 12:
1036 codes_num = 15
1036 codes_num = 15
1037
1037
1038 #Jars filter values:
1038 #Jars filter values:
1039
1039
1040 clock = float(filter_parms['clock'])
1040 clock = float(filter_parms['clock'])
1041 filter_2 = int(filter_parms['cic_2'])
1041 filter_2 = int(filter_parms['cic_2'])
1042 filter_5 = int(filter_parms['cic_5'])
1042 filter_5 = int(filter_parms['cic_5'])
1043 filter_fir = int(filter_parms['fir'])
1043 filter_fir = int(filter_parms['fir'])
1044 Fs_MHz = clock/(filter_2*filter_5*filter_fir)
1044 Fs_MHz = clock/(filter_2*filter_5*filter_fir)
1045
1045
1046 #Jars values:
1046 #Jars values:
1047 if ipp is not None:
1047 if ipp is not None:
1048 IPP_units = ipp/0.15*Fs_MHz
1048 IPP_units = ipp/0.15*Fs_MHz
1049 IPP_us = IPP_units / Fs_MHz
1049 IPP_us = IPP_units / Fs_MHz
1050 IPP_s = IPP_units / (Fs_MHz * (10**6))
1050 IPP_s = IPP_units / (Fs_MHz * (10**6))
1051 Ts = 1/(Fs_MHz*(10**6))
1051 Ts = 1/(Fs_MHz*(10**6))
1052
1052
1053 Va = radar_lambda/(4*Ts*cohe_integr)
1053 Va = radar_lambda/(4*Ts*cohe_integr)
1054 rate_bh = ((nsa-codes_num)*channels_number*2 *
1054 rate_bh = ((nsa-codes_num)*channels_number*2 *
1055 bytes_/IPP_us)*(36*(10**8)/cohe_integr)
1055 bytes_/IPP_us)*(36*(10**8)/cohe_integr)
1056 rate_gh = rate_bh/(1024*1024*1024)
1056 rate_gh = rate_bh/(1024*1024*1024)
1057
1057
1058 conf['Time per Block'] = IPP_s * profiles_block * cohe_integr
1058 conf['Time per Block'] = IPP_s * profiles_block * cohe_integr
1059 conf['keys'].append('Time per Block')
1059 conf['keys'].append('Time per Block')
1060 conf['Acq time'] = IPP_s * acq_profiles
1060 conf['Acq time'] = IPP_s * acq_profiles
1061 conf['keys'].append('Acq time')
1061 conf['keys'].append('Acq time')
1062 conf['Data rate'] = str(rate_gh)+" (GB/h)"
1062 conf['Data rate'] = str(rate_gh)+" (GB/h)"
1063 conf['keys'].append('Data rate')
1063 conf['keys'].append('Data rate')
1064 conf['Va (m/s)'] = Va
1064 conf['Va (m/s)'] = Va
1065 conf['keys'].append('Va (m/s)')
1065 conf['keys'].append('Va (m/s)')
1066 conf['Vrange (m/s)'] = 3/(2*IPP_s*cohe_integr)
1066 conf['Vrange (m/s)'] = 3/(2*IPP_s*cohe_integr)
1067 conf['keys'].append('Vrange (m/s)')
1067 conf['keys'].append('Vrange (m/s)')
1068
1068
1069 kwargs['configurations'].append(conf)
1069 kwargs['configurations'].append(conf)
1070 kwargs['menu_experiments'] = 'active'
1070 kwargs['menu_experiments'] = 'active'
1071
1071
1072 ###### SIDEBAR ######
1072 ###### SIDEBAR ######
1073 kwargs.update(sidebar(experiment=experiment))
1073 kwargs.update(sidebar(experiment=experiment))
1074
1074
1075 return render(request, 'experiment_summary.html', kwargs)
1075 return render(request, 'experiment_summary.html', kwargs)
1076
1076
1077
1077
1078 @login_required
1078 @login_required
1079 def experiment_verify(request, id_exp):
1079 def experiment_verify(request, id_exp):
1080
1080
1081 experiment = get_object_or_404(Experiment, pk=id_exp)
1081 experiment = get_object_or_404(Experiment, pk=id_exp)
1082 experiment_data = experiment.parms_to_dict()
1082 experiment_data = experiment.parms_to_dict()
1083 configurations = Configuration.objects.filter(
1083 configurations = Configuration.objects.filter(
1084 experiment=experiment, type=0)
1084 experiment=experiment, type=0)
1085
1085
1086 kwargs = {}
1086 kwargs = {}
1087
1087
1088 kwargs['experiment_keys'] = ['template',
1088 kwargs['experiment_keys'] = ['template',
1089 'radar_system', 'name', 'start_time', 'end_time']
1089 'radar_system', 'name', 'start_time', 'end_time']
1090 kwargs['experiment'] = experiment
1090 kwargs['experiment'] = experiment
1091
1091
1092 kwargs['configuration_keys'] = ['name', 'device__ip_address',
1092 kwargs['configuration_keys'] = ['name', 'device__ip_address',
1093 'device__port_address', 'device__status']
1093 'device__port_address', 'device__status']
1094 kwargs['configurations'] = configurations
1094 kwargs['configurations'] = configurations
1095 kwargs['experiment_data'] = experiment_data
1095 kwargs['experiment_data'] = experiment_data
1096
1096
1097 kwargs['title'] = 'Verify Experiment'
1097 kwargs['title'] = 'Verify Experiment'
1098 kwargs['suptitle'] = 'Parameters'
1098 kwargs['suptitle'] = 'Parameters'
1099
1099
1100 kwargs['button'] = 'Update'
1100 kwargs['button'] = 'Update'
1101
1101
1102 jars_conf = False
1102 jars_conf = False
1103 rc_conf = False
1103 rc_conf = False
1104 dds_conf = False
1104 dds_conf = False
1105
1105
1106 for configuration in configurations:
1106 for configuration in configurations:
1107 #-------------------- JARS -----------------------:
1107 #-------------------- JARS -----------------------:
1108 if configuration.device.device_type.name == 'jars':
1108 if configuration.device.device_type.name == 'jars':
1109 jars_conf = True
1109 jars_conf = True
1110 jars = configuration
1110 jars = configuration
1111 kwargs['jars_conf'] = jars_conf
1111 kwargs['jars_conf'] = jars_conf
1112 filter_parms = json.loads(jars.filter_parms)
1112 filter_parms = json.loads(jars.filter_parms)
1113 kwargs['filter_parms'] = filter_parms
1113 kwargs['filter_parms'] = filter_parms
1114 #--Sampling Frequency
1114 #--Sampling Frequency
1115 clock = filter_parms['clock']
1115 clock = filter_parms['clock']
1116 filter_2 = filter_parms['cic_2']
1116 filter_2 = filter_parms['cic_2']
1117 filter_5 = filter_parms['cic_5']
1117 filter_5 = filter_parms['cic_5']
1118 filter_fir = filter_parms['fir']
1118 filter_fir = filter_parms['fir']
1119 samp_freq_jars = clock/filter_2/filter_5/filter_fir
1119 samp_freq_jars = clock/filter_2/filter_5/filter_fir
1120
1120
1121 kwargs['samp_freq_jars'] = samp_freq_jars
1121 kwargs['samp_freq_jars'] = samp_freq_jars
1122 kwargs['jars'] = configuration
1122 kwargs['jars'] = configuration
1123
1123
1124 #--------------------- RC ----------------------:
1124 #--------------------- RC ----------------------:
1125 if configuration.device.device_type.name == 'rc' and not configuration.mix:
1125 if configuration.device.device_type.name == 'rc' and not configuration.mix:
1126 rc_conf = True
1126 rc_conf = True
1127 rc = configuration
1127 rc = configuration
1128
1128
1129 rc_parms = configuration.parms_to_dict()
1129 rc_parms = configuration.parms_to_dict()
1130
1130
1131 win_lines = rc.get_lines(line_type__name='windows')
1131 win_lines = rc.get_lines(line_type__name='windows')
1132 if win_lines:
1132 if win_lines:
1133 dh = json.loads(win_lines[0].params)['params'][0]['resolution']
1133 dh = json.loads(win_lines[0].params)['params'][0]['resolution']
1134 #--Sampling Frequency
1134 #--Sampling Frequency
1135 samp_freq_rc = 0.15/dh
1135 samp_freq_rc = 0.15/dh
1136 kwargs['samp_freq_rc'] = samp_freq_rc
1136 kwargs['samp_freq_rc'] = samp_freq_rc
1137
1137
1138 kwargs['rc_conf'] = rc_conf
1138 kwargs['rc_conf'] = rc_conf
1139 kwargs['rc'] = configuration
1139 kwargs['rc'] = configuration
1140
1140
1141 #-------------------- DDS ----------------------:
1141 #-------------------- DDS ----------------------:
1142 if configuration.device.device_type.name == 'dds':
1142 if configuration.device.device_type.name == 'dds':
1143 dds_conf = True
1143 dds_conf = True
1144 dds = configuration
1144 dds = configuration
1145 dds_parms = configuration.parms_to_dict()
1145 dds_parms = configuration.parms_to_dict()
1146
1146
1147 kwargs['dds_conf'] = dds_conf
1147 kwargs['dds_conf'] = dds_conf
1148 kwargs['dds'] = configuration
1148 kwargs['dds'] = configuration
1149
1149
1150 #------------Validation------------:
1150 #------------Validation------------:
1151 #Clock
1151 #Clock
1152 if dds_conf and rc_conf and jars_conf:
1152 if dds_conf and rc_conf and jars_conf:
1153 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) and float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1153 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) and float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1154 messages.warning(request, "Devices don't have the same clock.")
1154 messages.warning(request, "Devices don't have the same clock.")
1155 elif rc_conf and jars_conf:
1155 elif rc_conf and jars_conf:
1156 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']):
1156 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']):
1157 messages.warning(request, "Devices don't have the same clock.")
1157 messages.warning(request, "Devices don't have the same clock.")
1158 elif rc_conf and dds_conf:
1158 elif rc_conf and dds_conf:
1159 if float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1159 if float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1160 messages.warning(request, "Devices don't have the same clock.")
1160 messages.warning(request, "Devices don't have the same clock.")
1161 if float(samp_freq_rc) != float(dds_parms['configurations']['byId'][str(dds.pk)]['frequencyA']):
1161 if float(samp_freq_rc) != float(dds_parms['configurations']['byId'][str(dds.pk)]['frequencyA']):
1162 messages.warning(
1162 messages.warning(
1163 request, "Devices don't have the same Frequency A.")
1163 request, "Devices don't have the same Frequency A.")
1164
1164
1165 #------------POST METHOD------------:
1165 #------------POST METHOD------------:
1166 if request.method == 'POST':
1166 if request.method == 'POST':
1167 if request.POST['suggest_clock']:
1167 if request.POST['suggest_clock']:
1168 try:
1168 try:
1169 suggest_clock = float(request.POST['suggest_clock'])
1169 suggest_clock = float(request.POST['suggest_clock'])
1170 except:
1170 except:
1171 messages.warning(request, "Invalid value in CLOCK IN.")
1171 messages.warning(request, "Invalid value in CLOCK IN.")
1172 return redirect('url_verify_experiment', id_exp=experiment.id)
1172 return redirect('url_verify_experiment', id_exp=experiment.id)
1173 else:
1173 else:
1174 suggest_clock = ""
1174 suggest_clock = ""
1175 if suggest_clock:
1175 if suggest_clock:
1176 if rc_conf:
1176 if rc_conf:
1177 rc.clock_in = suggest_clock
1177 rc.clock_in = suggest_clock
1178 rc.save()
1178 rc.save()
1179 if jars_conf:
1179 if jars_conf:
1180 filter_parms = jars.filter_parms
1180 filter_parms = jars.filter_parms
1181 filter_parms = ast.literal_eval(filter_parms)
1181 filter_parms = ast.literal_eval(filter_parms)
1182 filter_parms['clock'] = suggest_clock
1182 filter_parms['clock'] = suggest_clock
1183 jars.filter_parms = json.dumps(filter_parms)
1183 jars.filter_parms = json.dumps(filter_parms)
1184 jars.save()
1184 jars.save()
1185 kwargs['filter_parms'] = filter_parms
1185 kwargs['filter_parms'] = filter_parms
1186 if dds_conf:
1186 if dds_conf:
1187 dds.clock = suggest_clock
1187 dds.clock = suggest_clock
1188 dds.save()
1188 dds.save()
1189
1189
1190 if request.POST['suggest_frequencyA']:
1190 if request.POST['suggest_frequencyA']:
1191 try:
1191 try:
1192 suggest_frequencyA = float(request.POST['suggest_frequencyA'])
1192 suggest_frequencyA = float(request.POST['suggest_frequencyA'])
1193 except:
1193 except:
1194 messages.warning(request, "Invalid value in FREQUENCY A.")
1194 messages.warning(request, "Invalid value in FREQUENCY A.")
1195 return redirect('url_verify_experiment', id_exp=experiment.id)
1195 return redirect('url_verify_experiment', id_exp=experiment.id)
1196 else:
1196 else:
1197 suggest_frequencyA = ""
1197 suggest_frequencyA = ""
1198 if suggest_frequencyA:
1198 if suggest_frequencyA:
1199 if jars_conf:
1199 if jars_conf:
1200 filter_parms = jars.filter_parms
1200 filter_parms = jars.filter_parms
1201 filter_parms = ast.literal_eval(filter_parms)
1201 filter_parms = ast.literal_eval(filter_parms)
1202 filter_parms['fch'] = suggest_frequencyA
1202 filter_parms['fch'] = suggest_frequencyA
1203 jars.filter_parms = json.dumps(filter_parms)
1203 jars.filter_parms = json.dumps(filter_parms)
1204 jars.save()
1204 jars.save()
1205 kwargs['filter_parms'] = filter_parms
1205 kwargs['filter_parms'] = filter_parms
1206 if dds_conf:
1206 if dds_conf:
1207 dds.frequencyA_Mhz = request.POST['suggest_frequencyA']
1207 dds.frequencyA_Mhz = request.POST['suggest_frequencyA']
1208 dds.save()
1208 dds.save()
1209
1209
1210 kwargs['menu_experiments'] = 'active'
1210 kwargs['menu_experiments'] = 'active'
1211 kwargs.update(sidebar(experiment=experiment))
1211 kwargs.update(sidebar(experiment=experiment))
1212 return render(request, 'experiment_verify.html', kwargs)
1212 return render(request, 'experiment_verify.html', kwargs)
1213
1213
1214
1214
1215 def parse_mix_result(s):
1215 def parse_mix_result(s):
1216
1216
1217 values = s.split('-')
1217 values = s.split('-')
1218 html = 'EXP MOD OPE DELAY MASK\r\n'
1218 html = 'EXP MOD OPE DELAY MASK\r\n'
1219
1219
1220 if not values or values[0] in ('', ' '):
1220 if not values or values[0] in ('', ' '):
1221 return mark_safe(html)
1221 return mark_safe(html)
1222
1222
1223 for i, value in enumerate(values):
1223 for i, value in enumerate(values):
1224 if not value:
1224 if not value:
1225 continue
1225 continue
1226 pk, mode, operation, delay, mask = value.split('|')
1226 pk, mode, operation, delay, mask = value.split('|')
1227 conf = RCConfiguration.objects.get(pk=pk)
1227 conf = RCConfiguration.objects.get(pk=pk)
1228 if i == 0:
1228 if i == 0:
1229 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1229 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1230 conf.name,
1230 conf.name,
1231 mode,
1231 mode,
1232 ' ',
1232 ' ',
1233 delay,
1233 delay,
1234 mask)
1234 mask)
1235 else:
1235 else:
1236 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1236 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1237 conf.name,
1237 conf.name,
1238 mode,
1238 mode,
1239 operation,
1239 operation,
1240 delay,
1240 delay,
1241 mask)
1241 mask)
1242
1242
1243 return mark_safe(html)
1243 return mark_safe(html)
1244
1244
1245
1245
1246 def parse_mask(l):
1246 def parse_mask(l):
1247
1247
1248 values = []
1248 values = []
1249
1249
1250 for x in range(16):
1250 for x in range(16):
1251 if '{}'.format(x) in l:
1251 if '{}'.format(x) in l:
1252 values.append(1)
1252 values.append(1)
1253 else:
1253 else:
1254 values.append(0)
1254 values.append(0)
1255
1255
1256 values.reverse()
1256 values.reverse()
1257
1257
1258 return int(''.join([str(x) for x in values]), 2)
1258 return int(''.join([str(x) for x in values]), 2)
1259
1259
1260
1260
1261 def dev_confs(request):
1261 def dev_confs(request):
1262
1262
1263 page = request.GET.get('page')
1263 page = request.GET.get('page')
1264 order = ('programmed_date', )
1264 order = ('programmed_date', )
1265 filters = request.GET.copy()
1265 filters = request.GET.copy()
1266 if 'my configurations' in filters:
1266 if 'my configurations' in filters:
1267 filters.pop('my configurations', None)
1267 filters.pop('my configurations', None)
1268 filters['mine'] = request.user.id
1268 filters['mine'] = request.user.id
1269 kwargs = get_paginator(Configuration, page, order, filters)
1269 kwargs = get_paginator(Configuration, page, order, filters)
1270 fields = ['tags', 'template', 'historical']
1270 fields = ['tags', 'template', 'historical']
1271 if request.user.is_authenticated:
1271 if request.user.is_authenticated:
1272 fields.append('my configurations')
1272 fields.append('my configurations')
1273 form = FilterForm(initial=request.GET, extra_fields=fields)
1273 form = FilterForm(initial=request.GET, extra_fields=fields)
1274 kwargs['keys'] = ['name', 'experiment',
1274 kwargs['keys'] = ['name', 'experiment',
1275 'type', 'programmed_date', 'actions']
1275 'type', 'programmed_date', 'actions']
1276 kwargs['title'] = 'Configuration'
1276 kwargs['title'] = 'Configuration'
1277 kwargs['suptitle'] = 'List'
1277 kwargs['suptitle'] = 'List'
1278 kwargs['no_sidebar'] = True
1278 kwargs['no_sidebar'] = True
1279 kwargs['form'] = form
1279 kwargs['form'] = form
1280 kwargs['add_url'] = reverse('url_add_dev_conf', args=[0])
1280 kwargs['add_url'] = reverse('url_add_dev_conf', args=[0])
1281 filters = request.GET.copy()
1281 filters = request.GET.copy()
1282 filters.pop('page', None)
1282 filters.pop('page', None)
1283 kwargs['q'] = urlencode(filters)
1283 kwargs['q'] = urlencode(filters)
1284 kwargs['menu_configurations'] = 'active'
1284 kwargs['menu_configurations'] = 'active'
1285
1285
1286 return render(request, 'base_list.html', kwargs)
1286 return render(request, 'base_list.html', kwargs)
1287
1287
1288
1288
1289 def dev_conf(request, id_conf):
1289 def dev_conf(request, id_conf):
1290
1290
1291 conf = get_object_or_404(Configuration, pk=id_conf)
1291 conf = get_object_or_404(Configuration, pk=id_conf)
1292
1292
1293 return redirect(conf.get_absolute_url())
1293 return redirect(conf.get_absolute_url())
1294
1294
1295
1295
1296 @login_required
1296 @login_required
1297 def dev_conf_new(request, id_exp=0, id_dev=0):
1297 def dev_conf_new(request, id_exp=0, id_dev=0):
1298
1298
1299 if not is_developer(request.user):
1299 if not is_developer(request.user):
1300 messages.error(
1300 messages.error(
1301 request, 'Developer required, to create new configurations')
1301 request, 'Developer required, to create new configurations')
1302 return redirect('index')
1302 return redirect('index')
1303
1303
1304 initial = {}
1304 initial = {}
1305 kwargs = {}
1305 kwargs = {}
1306
1306
1307 if id_exp != 0:
1307 if id_exp != 0:
1308 initial['experiment'] = id_exp
1308 initial['experiment'] = id_exp
1309
1309
1310 if id_dev != 0:
1310 if id_dev != 0:
1311 initial['device'] = id_dev
1311 initial['device'] = id_dev
1312
1312
1313 if request.method == 'GET':
1313 if request.method == 'GET':
1314
1314
1315 if id_dev:
1315 if id_dev:
1316 kwargs['button'] = 'Create'
1316 kwargs['button'] = 'Create'
1317 device = Device.objects.get(pk=id_dev)
1317 device = Device.objects.get(pk=id_dev)
1318 DevConfForm = CONF_FORMS[device.device_type.name]
1318 DevConfForm = CONF_FORMS[device.device_type.name]
1319 initial['name'] = request.GET['name']
1319 initial['name'] = request.GET['name']
1320 form = DevConfForm(initial=initial)
1320 form = DevConfForm(initial=initial)
1321 else:
1321 else:
1322 if 'template' in request.GET:
1322 if 'template' in request.GET:
1323 if request.GET['template'] == '0':
1323 if request.GET['template'] == '0':
1324 choices = [(conf.pk, '{}'.format(conf))
1324 choices = [(conf.pk, '{}'.format(conf))
1325 for conf in Configuration.objects.filter(template=True)]
1325 for conf in Configuration.objects.filter(template=True)]
1326 form = NewForm(initial={'create_from': 2},
1326 form = NewForm(initial={'create_from': 2},
1327 template_choices=choices)
1327 template_choices=choices)
1328 else:
1328 else:
1329 kwargs['button'] = 'Create'
1329 kwargs['button'] = 'Create'
1330 conf = Configuration.objects.get(
1330 conf = Configuration.objects.get(
1331 pk=request.GET['template'])
1331 pk=request.GET['template'])
1332 id_dev = conf.device.pk
1332 id_dev = conf.device.pk
1333 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1333 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1334 form = DevConfForm(instance=conf,
1334 form = DevConfForm(instance=conf,
1335 initial={'name': '{}_{:%y%m%d}'.format(conf.name, datetime.now()),
1335 initial={'name': '{}_{:%y%m%d}'.format(conf.name, datetime.now()),
1336 'template': False,
1336 'template': False,
1337 'experiment': id_exp})
1337 'experiment': id_exp})
1338 elif 'blank' in request.GET:
1338 elif 'blank' in request.GET:
1339 kwargs['button'] = 'Create'
1339 kwargs['button'] = 'Create'
1340 form = ConfigurationForm(initial=initial)
1340 form = ConfigurationForm(initial=initial)
1341 else:
1341 else:
1342 form = NewForm()
1342 form = NewForm()
1343
1343
1344 if request.method == 'POST':
1344 if request.method == 'POST':
1345
1345
1346 device = Device.objects.get(pk=request.POST['device'])
1346 device = Device.objects.get(pk=request.POST['device'])
1347 DevConfForm = CONF_FORMS[device.device_type.name]
1347 DevConfForm = CONF_FORMS[device.device_type.name]
1348
1348
1349 form = DevConfForm(request.POST)
1349 form = DevConfForm(request.POST)
1350 kwargs['button'] = 'Create'
1350 kwargs['button'] = 'Create'
1351 if form.is_valid():
1351 if form.is_valid():
1352 conf = form.save(commit=False)
1352 conf = form.save(commit=False)
1353 conf.author = request.user
1353 conf.author = request.user
1354 conf.save()
1354 conf.save()
1355
1355
1356 if 'template' in request.GET and conf.device.device_type.name == 'rc':
1356 if 'template' in request.GET and conf.device.device_type.name == 'rc':
1357 lines = RCLine.objects.filter(
1357 lines = RCLine.objects.filter(
1358 rc_configuration=request.GET['template'])
1358 rc_configuration=request.GET['template'])
1359 for line in lines:
1359 for line in lines:
1360 line.clone(rc_configuration=conf)
1360 line.clone(rc_configuration=conf)
1361
1361
1362 new_lines = conf.get_lines()
1362 new_lines = conf.get_lines()
1363 for line in new_lines:
1363 for line in new_lines:
1364 line_params = json.loads(line.params)
1364 line_params = json.loads(line.params)
1365 if 'TX_ref' in line_params:
1365 if 'TX_ref' in line_params:
1366 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
1366 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
1367 line_params['TX_ref'] = ['{}'.format(
1367 line_params['TX_ref'] = ['{}'.format(
1368 l.pk) for l in new_lines if l.get_name() == ref_line.get_name()][0]
1368 l.pk) for l in new_lines if l.get_name() == ref_line.get_name()][0]
1369 line.params = json.dumps(line_params)
1369 line.params = json.dumps(line_params)
1370 line.save()
1370 line.save()
1371 elif conf.device.device_type.name == 'rc':
1371 elif conf.device.device_type.name == 'rc':
1372 clk = RCClock(rc_configuration=conf)
1372 clk = RCClock(rc_configuration=conf)
1373 clk.save()
1373 clk.save()
1374
1374
1375 return redirect('url_dev_conf', id_conf=conf.pk)
1375 return redirect('url_dev_conf', id_conf=conf.pk)
1376
1376
1377 kwargs['id_exp'] = id_exp
1377 kwargs['id_exp'] = id_exp
1378 kwargs['form'] = form
1378 kwargs['form'] = form
1379 kwargs['title'] = 'Configuration'
1379 kwargs['title'] = 'Configuration'
1380 kwargs['suptitle'] = 'New'
1380 kwargs['suptitle'] = 'New'
1381 kwargs['menu_configurations'] = 'active'
1381 kwargs['menu_configurations'] = 'active'
1382
1382
1383 if id_dev != 0:
1383 if id_dev != 0:
1384 device = Device.objects.get(pk=id_dev)
1384 device = Device.objects.get(pk=id_dev)
1385 kwargs['device'] = device.device_type.name
1385 kwargs['device'] = device.device_type.name
1386
1386
1387 return render(request, 'dev_conf_edit.html', kwargs)
1387 return render(request, 'dev_conf_edit.html', kwargs)
1388
1388
1389
1389
1390 @login_required
1390 @login_required
1391 def dev_conf_edit(request, id_conf):
1391 def dev_conf_edit(request, id_conf):
1392
1392
1393 conf = get_object_or_404(Configuration, pk=id_conf)
1393 conf = get_object_or_404(Configuration, pk=id_conf)
1394
1394
1395 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1395 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1396
1396
1397 if request.method == 'GET':
1397 if request.method == 'GET':
1398 form = DevConfForm(instance=conf)
1398 form = DevConfForm(instance=conf)
1399
1399
1400 if request.method == 'POST':
1400 if request.method == 'POST':
1401 form = DevConfForm(request.POST, instance=conf)
1401 form = DevConfForm(request.POST, instance=conf)
1402
1402
1403 if form.is_valid():
1403 if form.is_valid():
1404 form.save()
1404 form.save()
1405 return redirect('url_dev_conf', id_conf=id_conf)
1405 return redirect('url_dev_conf', id_conf=id_conf)
1406
1406
1407 kwargs = {}
1407 kwargs = {}
1408 kwargs['form'] = form
1408 kwargs['form'] = form
1409 kwargs['title'] = 'Device Configuration'
1409 kwargs['title'] = 'Device Configuration'
1410 kwargs['suptitle'] = 'Edit'
1410 kwargs['suptitle'] = 'Edit'
1411 kwargs['button'] = 'Update'
1411 kwargs['button'] = 'Update'
1412 kwargs['menu_configurations'] = 'active'
1412 kwargs['menu_configurations'] = 'active'
1413
1413
1414 ###### SIDEBAR ######
1414 ###### SIDEBAR ######
1415 kwargs.update(sidebar(conf=conf))
1415 kwargs.update(sidebar(conf=conf))
1416
1416
1417 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1417 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1418
1418
1419
1419
1420 @login_required
1420 @login_required
1421 def dev_conf_start(request, id_conf):
1421 def dev_conf_start(request, id_conf):
1422
1422
1423 conf = get_object_or_404(Configuration, pk=id_conf)
1423 conf = get_object_or_404(Configuration, pk=id_conf)
1424
1424
1425 if conf.start_device():
1425 if conf.start_device():
1426 messages.success(request, conf.message)
1426 messages.success(request, conf.message)
1427 else:
1427 else:
1428 messages.error(request, conf.message)
1428 messages.error(request, conf.message)
1429
1429
1430 #conf.status_device()
1430 #conf.status_device()
1431
1431
1432 return redirect(conf.get_absolute_url())
1432 return redirect(conf.get_absolute_url())
1433
1433
1434
1434
1435 @login_required
1435 @login_required
1436 def dev_conf_stop(request, id_conf):
1436 def dev_conf_stop(request, id_conf):
1437
1437
1438 conf = get_object_or_404(Configuration, pk=id_conf)
1438 conf = get_object_or_404(Configuration, pk=id_conf)
1439
1439
1440 if conf.stop_device():
1440 if conf.stop_device():
1441 messages.success(request, conf.message)
1441 messages.success(request, conf.message)
1442 else:
1442 else:
1443 messages.error(request, conf.message)
1443 messages.error(request, conf.message)
1444
1444
1445 #conf.status_device()
1445 #conf.status_device()
1446
1446
1447 return redirect(conf.get_absolute_url())
1447 return redirect(conf.get_absolute_url())
1448
1448
1449
1449
1450 @login_required
1450 @login_required
1451 def dev_conf_status(request, id_conf):
1451 def dev_conf_status(request, id_conf):
1452
1452
1453 conf = get_object_or_404(Configuration, pk=id_conf)
1453 conf = get_object_or_404(Configuration, pk=id_conf)
1454
1454
1455 if conf.device.device_type.name == 'abs':
1455 conf_active = Configuration.objects.filter(pk=conf.device.conf_active).first()
1456 abs = request.user.profile.abs_active
1456 if conf_active<>conf:
1457 if abs<>conf:
1457 url = '#' if conf_active is None else conf_active.get_absolute_url()
1458 url = '#' if abs is None else abs.get_absolute_url()
1458 label = 'None' if conf_active is None else conf_active.label
1459 label = 'None' if abs is None else abs.label
1459 messages.warning(
1460 messages.warning(
1460 request,
1461 request,
1461 mark_safe('The current configuration has not been written to device, the active configuration is <a href="{}">{}</a>'.format(
1462 mark_safe('The current configuration has not been written in the modules, the active configuration is <a href="{}">{}</a>'.format(
1462 url,
1463 url,
1463 label
1464 label
1464 ))
1465 ))
1465 )
1466 )
1466
1467 return redirect(conf.get_absolute_url())
1467 return redirect(conf.get_absolute_url())
1468
1468
1469 if conf.status_device():
1469 if conf.status_device():
1470 messages.success(request, conf.message)
1470 messages.success(request, conf.message)
1471 else:
1471 else:
1472 messages.error(request, conf.message)
1472 messages.error(request, conf.message)
1473
1473
1474 return redirect(conf.get_absolute_url())
1474 return redirect(conf.get_absolute_url())
1475
1475
1476
1476
1477 @login_required
1477 @login_required
1478 def dev_conf_reset(request, id_conf):
1478 def dev_conf_reset(request, id_conf):
1479
1479
1480 conf = get_object_or_404(Configuration, pk=id_conf)
1480 conf = get_object_or_404(Configuration, pk=id_conf)
1481
1481
1482 if conf.reset_device():
1482 if conf.reset_device():
1483 messages.success(request, conf.message)
1483 messages.success(request, conf.message)
1484 else:
1484 else:
1485 messages.error(request, conf.message)
1485 messages.error(request, conf.message)
1486
1486
1487 return redirect(conf.get_absolute_url())
1487 return redirect(conf.get_absolute_url())
1488
1488
1489
1489
1490 @login_required
1490 @login_required
1491 def dev_conf_write(request, id_conf):
1491 def dev_conf_write(request, id_conf):
1492
1492
1493 conf = get_object_or_404(Configuration, pk=id_conf)
1493 conf = get_object_or_404(Configuration, pk=id_conf)
1494
1494
1495 if conf.write_device():
1495 if conf.write_device():
1496 conf.device.conf_active = conf.pk
1497 conf.device.save()
1496 messages.success(request, conf.message)
1498 messages.success(request, conf.message)
1497 if has_been_modified(conf):
1499 if has_been_modified(conf):
1498 conf.clone(type=1, template=False)
1500 conf.clone(type=1, template=False)
1499 else:
1501 else:
1500 messages.error(request, conf.message)
1502 messages.error(request, conf.message)
1501
1503
1502 return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1504 return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1503
1505
1504
1506
1505 @login_required
1507 @login_required
1506 def dev_conf_read(request, id_conf):
1508 def dev_conf_read(request, id_conf):
1507
1509
1508 conf = get_object_or_404(Configuration, pk=id_conf)
1510 conf = get_object_or_404(Configuration, pk=id_conf)
1509
1511
1510 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1512 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1511
1513
1512 if request.method == 'GET':
1514 if request.method == 'GET':
1513
1515
1514 parms = conf.read_device()
1516 parms = conf.read_device()
1515 #conf.status_device()
1517 #conf.status_device()
1516
1518
1517 if not parms:
1519 if not parms:
1518 messages.error(request, conf.message)
1520 messages.error(request, conf.message)
1519 return redirect(conf.get_absolute_url())
1521 return redirect(conf.get_absolute_url())
1520
1522
1521 form = DevConfForm(initial=parms, instance=conf)
1523 form = DevConfForm(initial=parms, instance=conf)
1522
1524
1523 if request.method == 'POST':
1525 if request.method == 'POST':
1524 form = DevConfForm(request.POST, instance=conf)
1526 form = DevConfForm(request.POST, instance=conf)
1525
1527
1526 if form.is_valid():
1528 if form.is_valid():
1527 form.save()
1529 form.save()
1528 return redirect(conf.get_absolute_url())
1530 return redirect(conf.get_absolute_url())
1529
1531
1530 messages.error(request, "Parameters could not be saved")
1532 messages.error(request, "Parameters could not be saved")
1531
1533
1532 kwargs = {}
1534 kwargs = {}
1533 kwargs['id_dev'] = conf.id
1535 kwargs['id_dev'] = conf.id
1534 kwargs['form'] = form
1536 kwargs['form'] = form
1535 kwargs['title'] = 'Device Configuration'
1537 kwargs['title'] = 'Device Configuration'
1536 kwargs['suptitle'] = 'Parameters read from device'
1538 kwargs['suptitle'] = 'Parameters read from device'
1537 kwargs['button'] = 'Save'
1539 kwargs['button'] = 'Save'
1538
1540
1539 ###### SIDEBAR ######
1541 ###### SIDEBAR ######
1540 kwargs.update(sidebar(conf=conf))
1542 kwargs.update(sidebar(conf=conf))
1541
1543
1542 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1544 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1543
1545
1544
1546
1545 @login_required
1547 @login_required
1546 def dev_conf_import(request, id_conf):
1548 def dev_conf_import(request, id_conf):
1547
1549
1548 conf = get_object_or_404(Configuration, pk=id_conf)
1550 conf = get_object_or_404(Configuration, pk=id_conf)
1549 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1551 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1550
1552
1551 if request.method == 'GET':
1553 if request.method == 'GET':
1552 file_form = UploadFileForm()
1554 file_form = UploadFileForm()
1553
1555
1554 if request.method == 'POST':
1556 if request.method == 'POST':
1555 file_form = UploadFileForm(request.POST, request.FILES)
1557 file_form = UploadFileForm(request.POST, request.FILES)
1556
1558
1557 if file_form.is_valid():
1559 if file_form.is_valid():
1558
1560
1559 data = conf.import_from_file(request.FILES['file'])
1561 data = conf.import_from_file(request.FILES['file'])
1560 parms = Params(data=data).get_conf(
1562 parms = Params(data=data).get_conf(
1561 dtype=conf.device.device_type.name)
1563 dtype=conf.device.device_type.name)
1562
1564
1563 if parms:
1565 if parms:
1564
1566
1565 form = DevConfForm(initial=parms, instance=conf)
1567 form = DevConfForm(initial=parms, instance=conf)
1566
1568
1567 kwargs = {}
1569 kwargs = {}
1568 kwargs['id_dev'] = conf.id
1570 kwargs['id_dev'] = conf.id
1569 kwargs['form'] = form
1571 kwargs['form'] = form
1570 kwargs['title'] = 'Device Configuration'
1572 kwargs['title'] = 'Device Configuration'
1571 kwargs['suptitle'] = 'Parameters imported'
1573 kwargs['suptitle'] = 'Parameters imported'
1572 kwargs['button'] = 'Save'
1574 kwargs['button'] = 'Save'
1573 kwargs['action'] = conf.get_absolute_url_edit()
1575 kwargs['action'] = conf.get_absolute_url_edit()
1574 kwargs['previous'] = conf.get_absolute_url()
1576 kwargs['previous'] = conf.get_absolute_url()
1575
1577
1576 ###### SIDEBAR ######
1578 ###### SIDEBAR ######
1577 kwargs.update(sidebar(conf=conf))
1579 kwargs.update(sidebar(conf=conf))
1578
1580
1579 messages.success(
1581 messages.success(
1580 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
1582 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
1581
1583
1582 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1584 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1583
1585
1584 messages.error(request, "Could not import parameters from file")
1586 messages.error(request, "Could not import parameters from file")
1585
1587
1586 kwargs = {}
1588 kwargs = {}
1587 kwargs['id_dev'] = conf.id
1589 kwargs['id_dev'] = conf.id
1588 kwargs['title'] = 'Device Configuration'
1590 kwargs['title'] = 'Device Configuration'
1589 kwargs['form'] = file_form
1591 kwargs['form'] = file_form
1590 kwargs['suptitle'] = 'Importing file'
1592 kwargs['suptitle'] = 'Importing file'
1591 kwargs['button'] = 'Import'
1593 kwargs['button'] = 'Import'
1592 kwargs['menu_configurations'] = 'active'
1594 kwargs['menu_configurations'] = 'active'
1593
1595
1594 kwargs.update(sidebar(conf=conf))
1596 kwargs.update(sidebar(conf=conf))
1595
1597
1596 return render(request, 'dev_conf_import.html', kwargs)
1598 return render(request, 'dev_conf_import.html', kwargs)
1597
1599
1598
1600
1599 @login_required
1601 @login_required
1600 def dev_conf_export(request, id_conf):
1602 def dev_conf_export(request, id_conf):
1601
1603
1602 conf = get_object_or_404(Configuration, pk=id_conf)
1604 conf = get_object_or_404(Configuration, pk=id_conf)
1603
1605
1604 if request.method == 'GET':
1606 if request.method == 'GET':
1605 file_form = DownloadFileForm(conf.device.device_type.name)
1607 file_form = DownloadFileForm(conf.device.device_type.name)
1606
1608
1607 if request.method == 'POST':
1609 if request.method == 'POST':
1608 file_form = DownloadFileForm(
1610 file_form = DownloadFileForm(
1609 conf.device.device_type.name, request.POST)
1611 conf.device.device_type.name, request.POST)
1610
1612
1611 if file_form.is_valid():
1613 if file_form.is_valid():
1612 fields = conf.export_to_file(
1614 fields = conf.export_to_file(
1613 format=file_form.cleaned_data['format'])
1615 format=file_form.cleaned_data['format'])
1614 if not fields['content']:
1616 if not fields['content']:
1615 messages.error(request, conf.message)
1617 messages.error(request, conf.message)
1616 return redirect(conf.get_absolute_url_export())
1618 return redirect(conf.get_absolute_url_export())
1617 response = HttpResponse(content_type=fields['content_type'])
1619 response = HttpResponse(content_type=fields['content_type'])
1618 response['Content-Disposition'] = 'attachment; filename="%s"' % fields['filename']
1620 response['Content-Disposition'] = 'attachment; filename="%s"' % fields['filename']
1619 response.write(fields['content'])
1621 response.write(fields['content'])
1620
1622
1621 return response
1623 return response
1622
1624
1623 messages.error(request, "Could not export parameters")
1625 messages.error(request, "Could not export parameters")
1624
1626
1625 kwargs = {}
1627 kwargs = {}
1626 kwargs['id_dev'] = conf.id
1628 kwargs['id_dev'] = conf.id
1627 kwargs['title'] = 'Device Configuration'
1629 kwargs['title'] = 'Device Configuration'
1628 kwargs['form'] = file_form
1630 kwargs['form'] = file_form
1629 kwargs['suptitle'] = 'Exporting file'
1631 kwargs['suptitle'] = 'Exporting file'
1630 kwargs['button'] = 'Export'
1632 kwargs['button'] = 'Export'
1631 kwargs['menu_configurations'] = 'active'
1633 kwargs['menu_configurations'] = 'active'
1632
1634
1633 return render(request, 'dev_conf_export.html', kwargs)
1635 return render(request, 'dev_conf_export.html', kwargs)
1634
1636
1635
1637
1636 @login_required
1638 @login_required
1637 def dev_conf_delete(request, id_conf):
1639 def dev_conf_delete(request, id_conf):
1638
1640
1639 conf = get_object_or_404(Configuration, pk=id_conf)
1641 conf = get_object_or_404(Configuration, pk=id_conf)
1640
1642
1641 if request.method == 'POST':
1643 if request.method == 'POST':
1642 if is_developer(request.user):
1644 if is_developer(request.user):
1643 conf.delete()
1645 conf.delete()
1644 return redirect('url_dev_confs')
1646 return redirect('url_dev_confs')
1645
1647
1646 messages.error(request, 'Not enough permission to delete this object')
1648 messages.error(request, 'Not enough permission to delete this object')
1647 return redirect(conf.get_absolute_url())
1649 return redirect(conf.get_absolute_url())
1648
1650
1649 kwargs = {
1651 kwargs = {
1650 'title': 'Delete',
1652 'title': 'Delete',
1651 'suptitle': 'Configuration',
1653 'suptitle': 'Configuration',
1652 'object': conf,
1654 'object': conf,
1653 'delete': True
1655 'delete': True
1654 }
1656 }
1655 kwargs['menu_configurations'] = 'active'
1657 kwargs['menu_configurations'] = 'active'
1656
1658
1657 return render(request, 'confirm.html', kwargs)
1659 return render(request, 'confirm.html', kwargs)
1658
1660
1659
1661
1660 def sidebar(**kwargs):
1662 def sidebar(**kwargs):
1661
1663
1662 side_data = {}
1664 side_data = {}
1663
1665
1664 conf = kwargs.get('conf', None)
1666 conf = kwargs.get('conf', None)
1665 experiment = kwargs.get('experiment', None)
1667 experiment = kwargs.get('experiment', None)
1666
1668
1667 if not experiment:
1669 if not experiment:
1668 experiment = conf.experiment
1670 experiment = conf.experiment
1669
1671
1670 if experiment:
1672 if experiment:
1671 side_data['experiment'] = experiment
1673 side_data['experiment'] = experiment
1672 campaign = experiment.campaign_set.all()
1674 campaign = experiment.campaign_set.all()
1673 if campaign:
1675 if campaign:
1674 side_data['campaign'] = campaign[0]
1676 side_data['campaign'] = campaign[0]
1675 experiments = campaign[0].experiments.all().order_by('name')
1677 experiments = campaign[0].experiments.all().order_by('name')
1676 else:
1678 else:
1677 experiments = [experiment]
1679 experiments = [experiment]
1678 configurations = experiment.configuration_set.filter(type=0)
1680 configurations = experiment.configuration_set.filter(type=0)
1679 side_data['side_experiments'] = experiments
1681 side_data['side_experiments'] = experiments
1680 side_data['side_configurations'] = configurations.order_by(
1682 side_data['side_configurations'] = configurations.order_by(
1681 'device__device_type__name')
1683 'device__device_type__name')
1682
1684
1683 return side_data
1685 return side_data
1684
1686
1685
1687
1686 def get_paginator(model, page, order, filters={}, n=8):
1688 def get_paginator(model, page, order, filters={}, n=8):
1687
1689
1688 kwargs = {}
1690 kwargs = {}
1689 query = Q()
1691 query = Q()
1690 if isinstance(filters, QueryDict):
1692 if isinstance(filters, QueryDict):
1691 filters = filters.dict()
1693 filters = filters.dict()
1692 [filters.pop(key) for key in filters.keys() if filters[key] in ('', ' ')]
1694 [filters.pop(key) for key in filters.keys() if filters[key] in ('', ' ')]
1693 filters.pop('page', None)
1695 filters.pop('page', None)
1694
1696
1695 fields = [f.name for f in model._meta.get_fields()]
1697 fields = [f.name for f in model._meta.get_fields()]
1696
1698
1697 if 'template' in filters:
1699 if 'template' in filters:
1698 filters['template'] = True
1700 filters['template'] = True
1699 if 'historical' in filters:
1701 if 'historical' in filters:
1700 filters.pop('historical')
1702 filters.pop('historical')
1701 filters['type'] = 1
1703 filters['type'] = 1
1702 elif 'type' in fields:
1704 elif 'type' in fields:
1703 filters['type'] = 0
1705 filters['type'] = 0
1704 if 'start_date' in filters:
1706 if 'start_date' in filters:
1705 filters['start_date__gte'] = filters.pop('start_date')
1707 filters['start_date__gte'] = filters.pop('start_date')
1706 if 'end_date' in filters:
1708 if 'end_date' in filters:
1707 filters['start_date__lte'] = filters.pop('end_date')
1709 filters['start_date__lte'] = filters.pop('end_date')
1708 if 'tags' in filters:
1710 if 'tags' in filters:
1709 tags = filters.pop('tags')
1711 tags = filters.pop('tags')
1710 if 'tags' in fields:
1712 if 'tags' in fields:
1711 query = query | Q(tags__icontains=tags)
1713 query = query | Q(tags__icontains=tags)
1712 if 'label' in fields:
1714 if 'label' in fields:
1713 query = query | Q(label__icontains=tags)
1715 query = query | Q(label__icontains=tags)
1714 if 'location' in fields:
1716 if 'location' in fields:
1715 query = query | Q(location__name__icontains=tags)
1717 query = query | Q(location__name__icontains=tags)
1716 if 'device' in fields:
1718 if 'device' in fields:
1717 query = query | Q(device__device_type__name__icontains=tags)
1719 query = query | Q(device__device_type__name__icontains=tags)
1718 query = query | Q(device__location__name__icontains=tags)
1720 query = query | Q(device__location__name__icontains=tags)
1719 if 'device_type' in fields:
1721 if 'device_type' in fields:
1720 query = query | Q(device_type__name__icontains=tags)
1722 query = query | Q(device_type__name__icontains=tags)
1721
1723
1722 if 'mine' in filters:
1724 if 'mine' in filters:
1723 filters['author_id'] = filters['mine']
1725 filters['author_id'] = filters['mine']
1724 filters.pop('mine')
1726 filters.pop('mine')
1725 object_list = model.objects.filter(query, **filters).order_by(*order)
1727 object_list = model.objects.filter(query, **filters).order_by(*order)
1726 paginator = Paginator(object_list, n)
1728 paginator = Paginator(object_list, n)
1727
1729
1728 try:
1730 try:
1729 objects = paginator.page(page)
1731 objects = paginator.page(page)
1730 except PageNotAnInteger:
1732 except PageNotAnInteger:
1731 objects = paginator.page(1)
1733 objects = paginator.page(1)
1732 except EmptyPage:
1734 except EmptyPage:
1733 objects = paginator.page(paginator.num_pages)
1735 objects = paginator.page(paginator.num_pages)
1734
1736
1735 kwargs['objects'] = objects
1737 kwargs['objects'] = objects
1736 kwargs['offset'] = (int(page)-1)*n if page else 0
1738 kwargs['offset'] = (int(page)-1)*n if page else 0
1737
1739
1738 return kwargs
1740 return kwargs
1739
1741
1740
1742
1741 def operation(request, id_camp=None):
1743 def operation(request, id_camp=None):
1742
1744
1743 kwargs = {}
1745 kwargs = {}
1744 kwargs['title'] = 'Radars Operation'
1746 kwargs['title'] = 'Radars Operation'
1745 kwargs['no_sidebar'] = True
1747 kwargs['no_sidebar'] = True
1746 kwargs['menu_operation'] = 'active'
1748 kwargs['menu_operation'] = 'active'
1747 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1749 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1748 end_date__gte=datetime.now()).order_by('-start_date')
1750 end_date__gte=datetime.now()).order_by('-start_date')
1749
1751
1750 if id_camp:
1752 if id_camp:
1751 campaign = get_object_or_404(Campaign, pk=id_camp)
1753 campaign = get_object_or_404(Campaign, pk=id_camp)
1752 form = OperationForm(
1754 form = OperationForm(
1753 initial={'campaign': campaign.id}, campaigns=campaigns)
1755 initial={'campaign': campaign.id}, campaigns=campaigns)
1754 kwargs['campaign'] = campaign
1756 kwargs['campaign'] = campaign
1755 else:
1757 else:
1756 # form = OperationForm(campaigns=campaigns)
1758 # form = OperationForm(campaigns=campaigns)
1757 kwargs['campaigns'] = campaigns
1759 kwargs['campaigns'] = campaigns
1758 return render(request, 'operation.html', kwargs)
1760 return render(request, 'operation.html', kwargs)
1759
1761
1760 #---Experiment
1762 #---Experiment
1761 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1763 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1762 kwargs['experiment_keys'] = keys[1:]
1764 kwargs['experiment_keys'] = keys[1:]
1763 kwargs['experiments'] = experiments
1765 kwargs['experiments'] = experiments
1764 #---Radar
1766 #---Radar
1765 kwargs['locations'] = campaign.get_experiments_by_radar()
1767 kwargs['locations'] = campaign.get_experiments_by_radar()
1766 kwargs['form'] = form
1768 kwargs['form'] = form
1767
1769
1768 return render(request, 'operation.html', kwargs)
1770 return render(request, 'operation.html', kwargs)
1769
1771
1770
1772
1771 @login_required
1773 @login_required
1772 def radar_start(request, id_camp, id_radar):
1774 def radar_start(request, id_camp, id_radar):
1773
1775
1774 campaign = get_object_or_404(Campaign, pk=id_camp)
1776 campaign = get_object_or_404(Campaign, pk=id_camp)
1775 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1777 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1776 now = datetime.now()
1778 now = datetime.now()
1777 for exp in experiments:
1779 for exp in experiments:
1778 start = datetime.combine(datetime.now().date(), exp.start_time)
1780 start = datetime.combine(datetime.now().date(), exp.start_time)
1779 end = datetime.combine(datetime.now().date(), exp.end_time)
1781 end = datetime.combine(datetime.now().date(), exp.end_time)
1780 if end < start:
1782 if end < start:
1781 end += timedelta(1)
1783 end += timedelta(1)
1782
1784
1783 if exp.status == 2:
1785 if exp.status == 2:
1784 messages.warning(
1786 messages.warning(
1785 request, 'Experiment {} already running'.format(exp))
1787 request, 'Experiment {} already running'.format(exp))
1786 continue
1788 continue
1787
1789
1788 if exp.status == 3:
1790 if exp.status == 3:
1789 messages.warning(
1791 messages.warning(
1790 request, 'Experiment {} already programmed'.format(exp))
1792 request, 'Experiment {} already programmed'.format(exp))
1791 continue
1793 continue
1792
1794
1793 if start > campaign.end_date or start < campaign.start_date:
1795 if start > campaign.end_date or start < campaign.start_date:
1794 messages.warning(request, 'Experiment {} out of date'.format(exp))
1796 messages.warning(request, 'Experiment {} out of date'.format(exp))
1795 continue
1797 continue
1796
1798
1797 if now > start and now <= end:
1799 if now > start and now <= end:
1798 exp.status = 3
1800 exp.status = 3
1799 exp.save()
1801 exp.save()
1800 task = task_start.delay(exp.id)
1802 task = task_start.delay(exp.id)
1801 exp.status = task.wait()
1803 exp.status = task.wait()
1802 if exp.status == 0:
1804 if exp.status == 0:
1803 messages.error(request, 'Experiment {} not start'.format(exp))
1805 messages.error(request, 'Experiment {} not start'.format(exp))
1804 if exp.status == 2:
1806 if exp.status == 2:
1805 messages.success(request, 'Experiment {} started'.format(exp))
1807 messages.success(request, 'Experiment {} started'.format(exp))
1806 else:
1808 else:
1807 task = task_start.apply_async(
1809 task = task_start.apply_async(
1808 (exp.pk, ), eta=start+timedelta(hours=5))
1810 (exp.pk, ), eta=start+timedelta(hours=5))
1809 exp.task = task.id
1811 exp.task = task.id
1810 exp.status = 3
1812 exp.status = 3
1811 messages.success(
1813 messages.success(
1812 request, 'Experiment {} programmed to start at {}'.format(exp, start))
1814 request, 'Experiment {} programmed to start at {}'.format(exp, start))
1813
1815
1814 exp.save()
1816 exp.save()
1815
1817
1816 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1818 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1817
1819
1818
1820
1819 @login_required
1821 @login_required
1820 def radar_stop(request, id_camp, id_radar):
1822 def radar_stop(request, id_camp, id_radar):
1821
1823
1822 campaign = get_object_or_404(Campaign, pk=id_camp)
1824 campaign = get_object_or_404(Campaign, pk=id_camp)
1823 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1825 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1824
1826
1825 for exp in experiments:
1827 for exp in experiments:
1826
1828
1827 if exp.task:
1829 if exp.task:
1828 app.control.revoke(exp.task)
1830 app.control.revoke(exp.task)
1829 if exp.status == 2:
1831 if exp.status == 2:
1830 exp.stop()
1832 exp.stop()
1831 messages.warning(request, 'Experiment {} stopped'.format(exp))
1833 messages.warning(request, 'Experiment {} stopped'.format(exp))
1832 exp.status = 1
1834 exp.status = 1
1833 exp.save()
1835 exp.save()
1834
1836
1835 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1837 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1836
1838
1837
1839
1838 @login_required
1840 @login_required
1839 def radar_refresh(request, id_camp, id_radar):
1841 def radar_refresh(request, id_camp, id_radar):
1840
1842
1841 campaign = get_object_or_404(Campaign, pk=id_camp)
1843 campaign = get_object_or_404(Campaign, pk=id_camp)
1842 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1844 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1843
1845
1844 for exp in experiments:
1846 i = app.control.inspect()
1845 exp.get_status()
1847 scheduled = i.scheduled().values[0]
1848 revoked = i.revoked().values[0]
1846
1849
1850 for exp in experiments:
1851 if exp.task in revoked:
1852 exp.status = 1
1853 elif exp.task in [t['request']['id'] for t in scheduled if 'task_start' in t['request']['name']]:
1854 exp.status = 2
1855 elif exp.task in [t['request']['id'] for t in scheduled if 'task_stop' in t['request']['name']]:
1856 exp.status = 3
1857 else:
1858 exp.status = 4
1859 exp.save()
1847 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1860 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1848
1861
1849
1862
1850 def real_time(request):
1863 def real_time(request):
1851
1864
1852 graphic_path = "/home/fiorella/Pictures/catwbeanie.jpg"
1865 graphic_path = "/home/fiorella/Pictures/catwbeanie.jpg"
1853
1866
1854 kwargs = {}
1867 kwargs = {}
1855 kwargs['title'] = 'CLAIRE'
1868 kwargs['title'] = 'CLAIRE'
1856 kwargs['suptitle'] = 'Real Time'
1869 kwargs['suptitle'] = 'Real Time'
1857 kwargs['no_sidebar'] = True
1870 kwargs['no_sidebar'] = True
1858 kwargs['graphic_path'] = graphic_path
1871 kwargs['graphic_path'] = graphic_path
1859 kwargs['graphic1_path'] = 'http://www.bluemaize.net/im/girls-accessories/shark-beanie-11.jpg'
1872 kwargs['graphic1_path'] = 'http://www.bluemaize.net/im/girls-accessories/shark-beanie-11.jpg'
1860
1873
1861 return render(request, 'real_time.html', kwargs)
1874 return render(request, 'real_time.html', kwargs)
1862
1875
1863 def theme(request, theme):
1876 def theme(request, theme):
1864
1877
1865 user = request.user
1878 user = request.user
1866 user.profile.theme = theme
1879 user.profile.theme = theme
1867 user.save()
1880 user.save()
1868 return redirect('index') No newline at end of file
1881 return redirect('index')
General Comments 0
You need to be logged in to leave comments. Login now