##// END OF EJS Templates
Add support to read abs module status
Juan C. Espinoza -
r326:f70d4e6cdcb2
parent child
Show More
@@ -1,876 +1,879
1 from django.db import models
1 from django.db import models
2 from apps.main.models import Configuration
2 from apps.main.models import Configuration, User
3 from django.core.urlresolvers import reverse
3 from django.core.urlresolvers import reverse
4 # Create your models here.
5 from celery.execute import send_task
4 from celery.execute import send_task
6 from datetime import datetime
5 from datetime import datetime
7 import ast
6 import ast
8 import socket
7 import socket
9 import json
8 import json
10 import requests
9 import requests
11 import struct
10 import struct
12 import os, sys, time
11 import os, sys, time
13
12
14 import multiprocessing
15
16
17 antenna_default = json.dumps({
13 antenna_default = json.dumps({
18 "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],
19 [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],
20 [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],
21 [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],
22 [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],
23 [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],
24 [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],
25 [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]
26 ]
22 ]
27 ,
23 ,
28 "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],
29 [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],
30 [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],
31 [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],
32 [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],
33 [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],
34 [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],
35 [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]],
36 })
32 })
37
33
38
34
39 tx_default = json.dumps({
35 tx_default = json.dumps({
40 "up": [[1,1,1,1,0,0,0,0],
36 "up": [[1,1,1,1,0,0,0,0],
41 [1,1,1,1,0,0,0,0],
37 [1,1,1,1,0,0,0,0],
42 [1,1,1,1,0,0,0,0],
38 [1,1,1,1,0,0,0,0],
43 [1,1,1,1,0,0,0,0],
39 [1,1,1,1,0,0,0,0],
44 [0,0,0,0,1,1,1,1],
40 [0,0,0,0,1,1,1,1],
45 [0,0,0,0,1,1,1,1],
41 [0,0,0,0,1,1,1,1],
46 [0,0,0,0,1,1,1,1],
42 [0,0,0,0,1,1,1,1],
47 [0,0,0,0,1,1,1,1]],
43 [0,0,0,0,1,1,1,1]],
48
44
49 "down": [[1,1,1,1,0,0,0,0],
45 "down": [[1,1,1,1,0,0,0,0],
50 [1,1,1,1,0,0,0,0],
46 [1,1,1,1,0,0,0,0],
51 [1,1,1,1,0,0,0,0],
47 [1,1,1,1,0,0,0,0],
52 [1,1,1,1,0,0,0,0],
48 [1,1,1,1,0,0,0,0],
53 [0,0,0,0,1,1,1,1],
49 [0,0,0,0,1,1,1,1],
54 [0,0,0,0,1,1,1,1],
50 [0,0,0,0,1,1,1,1],
55 [0,0,0,0,1,1,1,1],
51 [0,0,0,0,1,1,1,1],
56 [0,0,0,0,1,1,1,1]],
52 [0,0,0,0,1,1,1,1]],
57 })
53 })
58
54
59 rx_default = json.dumps({
55 rx_default = json.dumps({
60 "up": [[1,1,1,1,0,0,0,0],
56 "up": [[1,1,1,1,0,0,0,0],
61 [1,1,1,1,0,0,0,0],
57 [1,1,1,1,0,0,0,0],
62 [1,1,1,1,0,0,0,0],
58 [1,1,1,1,0,0,0,0],
63 [1,1,1,1,0,0,0,0],
59 [1,1,1,1,0,0,0,0],
64 [0,0,0,0,1,1,1,1],
60 [0,0,0,0,1,1,1,1],
65 [0,0,0,0,1,1,1,1],
61 [0,0,0,0,1,1,1,1],
66 [0,0,0,0,1,1,1,1],
62 [0,0,0,0,1,1,1,1],
67 [0,0,0,0,1,1,1,1]],
63 [0,0,0,0,1,1,1,1]],
68
64
69 "down": [[1,1,1,1,0,0,0,0],
65 "down": [[1,1,1,1,0,0,0,0],
70 [1,1,1,1,0,0,0,0],
66 [1,1,1,1,0,0,0,0],
71 [1,1,1,1,0,0,0,0],
67 [1,1,1,1,0,0,0,0],
72 [1,1,1,1,0,0,0,0],
68 [1,1,1,1,0,0,0,0],
73 [0,0,0,0,1,1,1,1],
69 [0,0,0,0,1,1,1,1],
74 [0,0,0,0,1,1,1,1],
70 [0,0,0,0,1,1,1,1],
75 [0,0,0,0,1,1,1,1],
71 [0,0,0,0,1,1,1,1],
76 [0,0,0,0,1,1,1,1]],
72 [0,0,0,0,1,1,1,1]],
77 })
73 })
78
74
79 status_default = '0000000000000000000000000000000000000000000000000000000000000000'
75 status_default = '0000000000000000000000000000000000000000000000000000000000000000'
80 default_messages = {}
76 default_messages = {}
81
77
82 for i in range(1,65):
78 for i in range(1,65):
83 default_messages[str(i)] = "Module "+str(i)
79 default_messages[str(i)] = "Module "+str(i)
84
80
85
81
86 ues_default = json.dumps({
82 ues_default = json.dumps({
87 "up": [0.533333,0.00000,1.06667,0.00000],
83 "up": [0.533333,0.00000,1.06667,0.00000],
88 "down": [0.533333,0.00000,1.06667,0.00000]
84 "down": [0.533333,0.00000,1.06667,0.00000]
89 })
85 })
90
86
91 onlyrx_default = json.dumps({
87 onlyrx_default = json.dumps({
92 "up": False,
88 "up": False,
93 "down": False
89 "down": False
94 })
90 })
95
91
96 def up_convertion(cadena):
92 def up_convertion(cadena):
97 valores = []
93 valores = []
98 for c in cadena:
94 for c in cadena:
99 if c == 1.0: valores=valores+['000']
95 if c == 1.0: valores=valores+['000']
100 if c == 2.0: valores=valores+['001']
96 if c == 2.0: valores=valores+['001']
101 if c == 3.0: valores=valores+['010']
97 if c == 3.0: valores=valores+['010']
102 if c == 0.0: valores=valores+['011']
98 if c == 0.0: valores=valores+['011']
103 if c == 0.5: valores=valores+['100']
99 if c == 0.5: valores=valores+['100']
104 if c == 1.5: valores=valores+['101']
100 if c == 1.5: valores=valores+['101']
105 if c == 2.5: valores=valores+['110']
101 if c == 2.5: valores=valores+['110']
106 if c == 3.5: valores=valores+['111']
102 if c == 3.5: valores=valores+['111']
107
103
108 return valores
104 return valores
109
105
110 def up_conv_bits(value):
106 def up_conv_bits(value):
111
107
112 if value == 1.0: bits="000"
108 if value == 1.0: bits="000"
113 if value == 2.0: bits="001"
109 if value == 2.0: bits="001"
114 if value == 3.0: bits="010"
110 if value == 3.0: bits="010"
115 if value == 0.0: bits="011"
111 if value == 0.0: bits="011"
116 if value == 0.5: bits="100"
112 if value == 0.5: bits="100"
117 if value == 1.5: bits="101"
113 if value == 1.5: bits="101"
118 if value == 2.5: bits="110"
114 if value == 2.5: bits="110"
119 if value == 3.5: bits="111"
115 if value == 3.5: bits="111"
120
116
121 return bits
117 return bits
122
118
123 def down_convertion(cadena):
119 def down_convertion(cadena):
124 valores = []
120 valores = []
125 for c in cadena:
121 for c in cadena:
126 if c == 1.0: valores=valores+['000']
122 if c == 1.0: valores=valores+['000']
127 if c == 2.0: valores=valores+['001']
123 if c == 2.0: valores=valores+['001']
128 if c == 3.0: valores=valores+['010']
124 if c == 3.0: valores=valores+['010']
129 if c == 0.0: valores=valores+['011']
125 if c == 0.0: valores=valores+['011']
130 if c == 0.5: valores=valores+['100']
126 if c == 0.5: valores=valores+['100']
131 if c == 1.5: valores=valores+['101']
127 if c == 1.5: valores=valores+['101']
132 if c == 2.5: valores=valores+['110']
128 if c == 2.5: valores=valores+['110']
133 if c == 3.5: valores=valores+['111']
129 if c == 3.5: valores=valores+['111']
134
130
135 return valores
131 return valores
136
132
137 def down_conv_bits(value):
133 def down_conv_bits(value):
138
134
139 if value == 1.0: bits="000"
135 if value == 1.0: bits="000"
140 if value == 2.0: bits="001"
136 if value == 2.0: bits="001"
141 if value == 3.0: bits="010"
137 if value == 3.0: bits="010"
142 if value == 0.0: bits="011"
138 if value == 0.0: bits="011"
143 if value == 0.5: bits="100"
139 if value == 0.5: bits="100"
144 if value == 1.5: bits="101"
140 if value == 1.5: bits="101"
145 if value == 2.5: bits="110"
141 if value == 2.5: bits="110"
146 if value == 3.5: bits="111"
142 if value == 3.5: bits="111"
147
143
148 return bits
144 return bits
149
145
150 def up_conv_value(bits):
146 def up_conv_value(bits):
151
147
152 if bits == "000": value=1.0
148 if bits == "000": value=1.0
153 if bits == "001": value=2.0
149 if bits == "001": value=2.0
154 if bits == "010": value=3.0
150 if bits == "010": value=3.0
155 if bits == "011": value=0.0
151 if bits == "011": value=0.0
156 if bits == "100": value=0.5
152 if bits == "100": value=0.5
157 if bits == "101": value=1.5
153 if bits == "101": value=1.5
158 if bits == "110": value=2.5
154 if bits == "110": value=2.5
159 if bits == "111": value=3.5
155 if bits == "111": value=3.5
160
156
161 return value
157 return value
162
158
163 def down_conv_value(bits):
159 def down_conv_value(bits):
164
160
165 if bits == "000": value=1.0
161 if bits == "000": value=1.0
166 if bits == "001": value=2.0
162 if bits == "001": value=2.0
167 if bits == "010": value=3.0
163 if bits == "010": value=3.0
168 if bits == "011": value=0.0
164 if bits == "011": value=0.0
169 if bits == "100": value=0.5
165 if bits == "100": value=0.5
170 if bits == "101": value=1.5
166 if bits == "101": value=1.5
171 if bits == "110": value=2.5
167 if bits == "110": value=2.5
172 if bits == "111": value=3.5
168 if bits == "111": value=3.5
173
169
174 return value
170 return value
175
171
176 def ip2position(module_number):
172 def ip2position(module_number):
177 j=0
173 j=0
178 i=0
174 i=0
179 for x in range(0,module_number-1):
175 for x in range(0,module_number-1):
180 j=j+1
176 j=j+1
181 if j==8:
177 if j==8:
182 i=i+1
178 i=i+1
183 j=0
179 j=0
184
180
185 pos = [i,j]
181 pos = [i,j]
186 return pos
182 return pos
187
183
188
184
189 def fromBinary2Char(binary_string):
185 def fromBinary2Char(binary_string):
190 number = int(binary_string, 2)
186 number = int(binary_string, 2)
191 #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'
192 number = number + 33
188 number = number + 33
193 char = chr(number)
189 char = chr(number)
194 return char
190 return char
195
191
196 def fromChar2Binary(char):
192 def fromChar2Binary(char):
197 number = ord(char) - 33
193 number = ord(char) - 33
198 #Minus 33 to get the real value
194 #Minus 33 to get the real value
199 bits = bin(number)[2:]
195 bits = bin(number)[2:]
200 #To ensure we have a string with 6bits
196 #To ensure we have a string with 6bits
201 if len(bits) < 6:
197 if len(bits) < 6:
202 bits = bits.zfill(6)
198 bits = bits.zfill(6)
203 return bits
199 return bits
204
200
205 OPERATION_MODES = (
201 OPERATION_MODES = (
206 (0, 'Manual'),
202 (0, 'Manual'),
207 (1, 'Automatic'),
203 (1, 'Automatic'),
208 )
204 )
209
205
210
206
211 class ABSConfiguration(Configuration):
207 class ABSConfiguration(Configuration):
212 active_beam = models.PositiveSmallIntegerField(verbose_name='Active Beam', default=0)
208 active_beam = models.PositiveSmallIntegerField(verbose_name='Active Beam', default=0)
213 module_status = models.CharField(verbose_name='Module Status', max_length=10000, default=json.dumps(status_default))
209 module_status = models.CharField(verbose_name='Module Status', max_length=10000, default=status_default)
214 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)
215 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)
216 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))
217
213
218 class Meta:
214 class Meta:
219 db_table = 'abs_configurations'
215 db_table = 'abs_configurations'
220
216
221 def get_absolute_url_plot(self):
217 def get_absolute_url_plot(self):
222 return reverse('url_plot_abs_patterns', args=[str(self.id)])
218 return reverse('url_plot_abs_patterns', args=[str(self.id)])
223
219
224
220
225 def parms_to_dict(self):
221 def parms_to_dict(self):
226
222
227 parameters = {}
223 parameters = {}
228
224
229 parameters['device_id'] = self.device.id
225 parameters['device_id'] = self.device.id
230 parameters['label'] = self.label
226 parameters['label'] = self.label
231 parameters['device_type'] = self.device.device_type.name
227 parameters['device_type'] = self.device.device_type.name
232 parameters['beams'] = {}
228 parameters['beams'] = {}
233
229
234 beams = ABSBeam.objects.filter(abs_conf=self)
230 beams = ABSBeam.objects.filter(abs_conf=self)
235 b=1
231 b=1
236 for beam in beams:
232 for beam in beams:
237 #absbeam = ABSBeam.objects.get(pk=beams[beam])
233 #absbeam = ABSBeam.objects.get(pk=beams[beam])
238 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()
239 b+=1
235 b+=1
240
236
241 return parameters
237 return parameters
242
238
243
239
244 def dict_to_parms(self, parameters):
240 def dict_to_parms(self, parameters):
245
241
246 self.label = parameters['label']
242 self.label = parameters['label']
247
243
248 absbeams = ABSBeam.objects.filter(abs_conf=self)
244 absbeams = ABSBeam.objects.filter(abs_conf=self)
249 beams = parameters['beams']
245 beams = parameters['beams']
250
246
251 if absbeams:
247 if absbeams:
252 beams_number = len(beams)
248 beams_number = len(beams)
253 absbeams_number = len(absbeams)
249 absbeams_number = len(absbeams)
254 if beams_number==absbeams_number:
250 if beams_number==absbeams_number:
255 i = 1
251 i = 1
256 for absbeam in absbeams:
252 for absbeam in absbeams:
257 absbeam.dict_to_parms(beams['beam'+str(i)])
253 absbeam.dict_to_parms(beams['beam'+str(i)])
258 i = i+1
254 i = i+1
259 elif beams_number > absbeams_number:
255 elif beams_number > absbeams_number:
260 i = 1
256 i = 1
261 for absbeam in absbeams:
257 for absbeam in absbeams:
262 absbeam.dict_to_parms(beams['beam'+str(i)])
258 absbeam.dict_to_parms(beams['beam'+str(i)])
263 i=i+1
259 i=i+1
264 for x in range(i,beams_number+1):
260 for x in range(i,beams_number+1):
265 new_beam = ABSBeam(
261 new_beam = ABSBeam(
266 name =beams['beam'+str(i)]['name'],
262 name =beams['beam'+str(i)]['name'],
267 antenna =json.dumps(beams['beam'+str(i)]['antenna']),
263 antenna =json.dumps(beams['beam'+str(i)]['antenna']),
268 abs_conf = self,
264 abs_conf = self,
269 tx =json.dumps(beams['beam'+str(i)]['tx']),
265 tx =json.dumps(beams['beam'+str(i)]['tx']),
270 rx =json.dumps(beams['beam'+str(i)]['rx']),
266 rx =json.dumps(beams['beam'+str(i)]['rx']),
271 ues =json.dumps(beams['beam'+str(i)]['ues']),
267 ues =json.dumps(beams['beam'+str(i)]['ues']),
272 only_rx =json.dumps(beams['beam'+str(i)]['only_rx'])
268 only_rx =json.dumps(beams['beam'+str(i)]['only_rx'])
273 )
269 )
274 new_beam.save()
270 new_beam.save()
275 i=i+1
271 i=i+1
276 else: #beams_number < absbeams_number:
272 else: #beams_number < absbeams_number:
277 i = 1
273 i = 1
278 for absbeam in absbeams:
274 for absbeam in absbeams:
279 if i <= beams_number:
275 if i <= beams_number:
280 absbeam.dict_to_parms(beams['beam'+str(i)])
276 absbeam.dict_to_parms(beams['beam'+str(i)])
281 i=i+1
277 i=i+1
282 else:
278 else:
283 absbeam.delete()
279 absbeam.delete()
284 else:
280 else:
285 for beam in beams:
281 for beam in beams:
286 new_beam = ABSBeam(
282 new_beam = ABSBeam(
287 name =beams[beam]['name'],
283 name =beams[beam]['name'],
288 antenna =json.dumps(beams[beam]['antenna']),
284 antenna =json.dumps(beams[beam]['antenna']),
289 abs_conf = self,
285 abs_conf = self,
290 tx =json.dumps(beams[beam]['tx']),
286 tx =json.dumps(beams[beam]['tx']),
291 rx =json.dumps(beams[beam]['rx']),
287 rx =json.dumps(beams[beam]['rx']),
292 ues =json.dumps(beams[beam]['ues']),
288 ues =json.dumps(beams[beam]['ues']),
293 only_rx =json.dumps(beams[beam]['only_rx'])
289 only_rx =json.dumps(beams[beam]['only_rx'])
294 )
290 )
295 new_beam.save()
291 new_beam.save()
296
292
297
293
298
294
299 def update_from_file(self, parameters):
295 def update_from_file(self, parameters):
300
296
301 self.dict_to_parms(parameters)
297 self.dict_to_parms(parameters)
302 self.save()
298 self.save()
303
299
304
300
305 def get_beams(self, **kwargs):
301 def get_beams(self, **kwargs):
306 '''
302 '''
307 This function returns ABS Configuration beams
303 This function returns ABS Configuration beams
308 '''
304 '''
309 return ABSBeam.objects.filter(abs_conf=self.pk, **kwargs)
305 return ABSBeam.objects.filter(abs_conf=self.pk, **kwargs)
310
306
311 def clone(self, **kwargs):
307 def clone(self, **kwargs):
312
308
313 beams = self.get_beams()
309 beams = self.get_beams()
314 self.pk = None
310 self.pk = None
315 self.id = None
311 self.id = None
316 for attr, value in kwargs.items():
312 for attr, value in kwargs.items():
317 setattr(self, attr, value)
313 setattr(self, attr, value)
318 self.save()
314 self.save()
319
315
320 for beam in beams:
316 for beam in beams:
321 beam.clone(abs_conf=self)
317 beam.clone(abs_conf=self)
322
318
323 #-----For Active Beam-----
319 #-----For Active Beam-----
324 new_beams = ABSBeam.objects.filter(abs_conf=self)
320 new_beams = ABSBeam.objects.filter(abs_conf=self)
325 self.active_beam = new_beams[0].id
321 self.active_beam = new_beams[0].id
326 self.save()
322 self.save()
327 #-----For Active Beam-----
323 #-----For Active Beam-----
328 #-----For Device Status---
324 #-----For Device Status---
329 self.device.status = 3
325 self.device.status = 3
330 self.device.save()
326 self.device.save()
331 #-----For Device Status---
327 #-----For Device Status---
332
328
333 return self
329 return self
334
330
335
331
336 def start_device(self):
332 def start_device(self):
337
333
338 if self.device.status == 3:
334 if self.device.status == 3:
339
335
340 try:
336 try:
341 #self.write_device()
337 #self.write_device()
342 send_task('task_change_beam', [self.id],)
338 send_task('task_change_beam', [self.id],)
343 self.message = 'ABS running'
339 self.message = 'ABS running'
344
340
345 except Exception as e:
341 except Exception as e:
346 self.message = str(e)
342 self.message = str(e)
347 return False
343 return False
348
344
349 return True
345 return True
350
346
351 else:
347 else:
352 self.message = 'Please, select Write ABS Device first.'
348 self.message = 'Please, select Write ABS Device first.'
353 return False
349 return False
354
350
355
351
356 def stop_device(self):
352 def stop_device(self):
357
353
358 self.device.status = 2
354 self.device.status = 2
359 self.device.save()
355 self.device.save()
360 self.message = 'ABS has been stopped.'
356 self.message = 'ABS has been stopped.'
361 self.save()
357 self.save()
362
358
363 return True
359 return True
364
360
365
361
366 def write_device(self):
362 def write_device(self):
367
363
368 """
364 """
369 This function sends the beams list to every abs module.
365 This function sends the beams list to every abs module.
370 It needs 'module_conf' function
366 It needs 'module_conf' function
371 """
367 """
372
368
373 beams = ABSBeam.objects.filter(abs_conf=self)
369 beams = ABSBeam.objects.filter(abs_conf=self)
374 nbeams = len(beams)
370 nbeams = len(beams)
375 if self.connected_modules() == 0 :
371 if self.connected_modules() == 0 :
376 self.message = "No ABS Module detected."
372 self.message = "No ABS Module detected."
377 return False
373 return False
378
374
379 #-------------Write each abs module-----------
375 #-------------Write each abs module-----------
380
376
381 if beams:
377 if beams:
382 block_id = 0
378 block_id = 0
383 message = 'SNDF{:03d}{:02d}{:02d}'.format(nbeams, nbeams, block_id)
379 message = 'SNDF{:03d}{:02d}{:02d}'.format(nbeams, nbeams, block_id)
384 for i, status in enumerate(self.module_status):
380 for i, status in enumerate(self.module_status):
385 message += ''.join([fromBinary2Char(beam.module_6bits(i)) for beam in beams])
381 message += ''.join([fromBinary2Char(beam.module_6bits(i)) for beam in beams])
386 status = ['0'] * 64
382 status = ['0'] * 64
387 n = 0
383 n = 0
388
384
389 sock = self.send_multicast(message)
385 sock = self.send_multicast(message)
390
386
391 for i in range(32):
387 for i in range(32):
392 try:
388 try:
393 data, address = sock.recvfrom(1024)
389 data, address = sock.recvfrom(1024)
394 print address, data
390 print address, data
395 if data == '1':
391 if data == '1':
396 status[int(address[0][10:])-1] = '3'
392 status[int(address[0][10:])-1] = '3'
397 elif data == '0':
393 elif data == '0':
398 status[int(address[0][10:])-1] = '1'
394 status[int(address[0][10:])-1] = '1'
399 except Exception as e:
395 except Exception as e:
400 print 'Error {}'.format(e)
396 print 'Error {}'.format(e)
401 n += 1
397 n += 1
402 sock.close()
398 sock.close()
403 else:
399 else:
404 self.message = "ABS Configuration does not have beams"
400 self.message = "ABS Configuration does not have beams"
405 return False
401 return False
406
402
407 if n == 64:
403 if n == 64:
408 self.message = "Could not write ABS Modules"
404 self.message = "Could not write ABS Modules"
409 self.device.status = 0
405 self.device.status = 0
410 self.module_status = ''.join(status)
406 self.module_status = ''.join(status)
411 self.save()
407 self.save()
412 return False
408 return False
413 else:
409 else:
414 self.message = "ABS Beams List have been sent to ABS Modules"
410 self.message = "ABS Beams List have been sent to ABS Modules"
415 self.active_beam = beams[0].pk
411 self.active_beam = beams[0].pk
416
412
417 self.device.status = 3
413 self.device.status = 3
418 self.module_status = ''.join(status)
414 self.module_status = ''.join(status)
419 self.save()
415 self.save()
416 for u in User.objects.all():
417 u.profile.abs_active = self
418 u.save()
420 return True
419 return True
421
420
422
421
423 def read_module(self, module):
422 def read_module(self, module):
424
423
425 """
424 """
426 Read out-bits (up-down) of 1 abs module NOT for Configuration
425 Read out-bits (up-down) of 1 abs module NOT for Configuration
427 """
426 """
428
427
429 ip_address = self.device.ip_address
428 ip_address = self.device.ip_address
430 ip_address = ip_address.split('.')
429 ip_address = ip_address.split('.')
431 module_seq = (ip_address[0],ip_address[1],ip_address[2])
430 module_seq = (ip_address[0],ip_address[1],ip_address[2])
432 dot = '.'
431 dot = '.'
433 module_ip = dot.join(module_seq)+'.'+str(module)
432 module_ip = dot.join(module_seq)+'.'+str(module)
434 module_port = self.device.port_address
433 module_port = self.device.port_address
435 read_route = 'http://'+module_ip+':'+str(module_port)+'/read'
434 read_route = 'http://'+module_ip+':'+str(module_port)+'/read'
436
435
437 module_status = json.loads(self.module_status)
436 module_status = json.loads(self.module_status)
438 print(read_route)
437 print(read_route)
439
438
440 module_bits = ''
439 module_bits = ''
441
440
442 try:
441 try:
443 r_read = requests.get(read_route, timeout=0.5)
442 r_read = requests.get(read_route, timeout=0.5)
444 answer = r_read.json()
443 answer = r_read.json()
445 module_bits = answer['allbits']
444 module_bits = answer['allbits']
446 except:
445 except:
447 return {}
446 return {}
448
447
449 return module_bits
448 return module_bits
450
449
451 def read_device(self):
450 def read_device(self):
452
451
453 parms = {}
452 parms = {}
454 # Reads active modules.
453 # Reads active modules.
455 module_status = json.loads(self.module_status)
454 module_status = json.loads(self.module_status)
456 total = 0
455 total = 0
457 for status in module_status:
456 for status in module_status:
458 if module_status[status] != 0:
457 if module_status[status] != 0:
459 module_bits = self.read_module(int(status))
458 module_bits = self.read_module(int(status))
460 bits={}
459 bits={}
461 if module_bits:
460 if module_bits:
462 bits = (str(module_bits['um2']) + str(module_bits['um1']) + str(module_bits['um0']) +
461 bits = (str(module_bits['um2']) + str(module_bits['um1']) + str(module_bits['um0']) +
463 str(module_bits['dm2']) + str(module_bits['dm1']) + str(module_bits['dm0']) )
462 str(module_bits['dm2']) + str(module_bits['dm1']) + str(module_bits['dm0']) )
464 parms[str(status)] = bits
463 parms[str(status)] = bits
465
464
466 total +=1
465 total +=1
467
466
468 if total==0:
467 if total==0:
469 self.message = "No ABS Module detected. Please select 'Status'."
468 self.message = "No ABS Module detected. Please select 'Status'."
470 return False
469 return False
471
470
472
471
473
472
474 self.message = "ABS Modules have been read"
473 self.message = "ABS Modules have been read"
475 #monitoreo_tx = JROABSClnt_01CeCnMod000000MNTR10
474 #monitoreo_tx = JROABSClnt_01CeCnMod000000MNTR10
476 return parms
475 return parms
477
476
478
477
479 def connected_modules(self):
478 def connected_modules(self):
480 """
479 """
481 This function returns the number of connected abs-modules without updating.
480 This function returns the number of connected abs-modules without updating.
482 """
481 """
483 num = 0
482 num = 0
484 print(self.module_status)
483 print(self.module_status)
485 for i, status in enumerate(self.module_status):
484 for i, status in enumerate(self.module_status):
486 if status != '0':
485 if status != '0':
487 num += 1
486 num += 1
488 #print('status {}:{}'.format(i+1, status))
487 #print('status {}:{}'.format(i+1, status))
489 return num
488 return num
490
489
491 def send_multicast(self, message):
490 def send_multicast(self, message):
492
491
493 multicast_group = ('224.3.29.71', 10000)
492 multicast_group = ('224.3.29.71', 10000)
494 # Create the datagram socket
493 # Create the datagram socket
495 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
494 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
496 sock.settimeout(1)
495 sock.settimeout(1)
497 # sock.bind((local_ip, 10000))
498 local_ip = os.environ.get('LOCAL_IP', '127.0.0.1')
496 local_ip = os.environ.get('LOCAL_IP', '127.0.0.1')
499 local_ip = '192.168.1.128'
500 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip))
497 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip))
501 sent = sock.sendto(message, multicast_group)
498 sock.sendto(message, multicast_group)
502 print('Sending ' + message)
499 print('Sending ' + message)
503 return sock
500 return sock
504
501
505 def status_device(self):
502 def status_device(self):
506 """
503 """
507 This function returns the status of all abs-modules as one.
504 This function returns the status of all abs-modules as one.
508 If at least one module is connected, its answer is "1"
505 If at least one module is connected, its answer is "1"
509 """
506 """
510
507
511 sock = self.send_multicast('MNTR')
508 sock = self.send_multicast('MNTR')
512
509
513 n = 0
510 n = 0
514 status = ['0'] * 64
511 status = ['0'] * 64
515 for i in range(32):
512 for i in range(32):
516 #if True:
513 #if True:
517 try:
514 try:
518 address = None
515 address = None
519 data, address = sock.recvfrom(1024)
516 data, address = sock.recvfrom(1024)
520 print address, data
517 x = int(address[0][10:])-1
521 if data == '1':
518 if data[0] == '1':
522 status[int(address[0][10:])-1] = '3'
519 remote = fromChar2Binary(data[1])
523 elif data == '0':
520 local = ABSBeam.objects.get(pk=self.active_beam).module_6bits(x)
524 status[int(address[0][10:])-1] = '1'
521 if local == remote:
522 status[x] = '3'
523 print('Module: {} connected...igual'.format(address))
524 else:
525 status[x] = '2'
526 print('Module: {} connected...diferente'.format(address))
527 elif data[0] == '0':
528 status[x] = '1'
525 n += 1
529 n += 1
526 print('Module: {} connected'.format(address))
527 except:
530 except:
528 print('Module: {} error'.format(address))
531 print('Module: {} error'.format(address))
529 pass
532 pass
530 sock.close()
533 sock.close()
531
534
532 if n > 0:
535 if n > 0:
533 self.message = 'ABS modules Status have been updated.'
536 self.message = 'ABS modules Status have been updated.'
534 self.device.status = 1
537 self.device.status = 1
535 else:
538 else:
536 self.device.status = 0
539 self.device.status = 0
537 self.message = 'No ABS module is connected.'
540 self.message = 'No ABS module is connected.'
538 self.module_status = ''.join(status)
541 self.module_status = ''.join(status)
539 self.save()
542 self.save()
540
543
541 return self.device.status
544 return self.device.status
542
545
543
546
544 def send_beam(self, beam_pos):
547 def send_beam(self, beam_pos):
545 """
548 """
546 This function connects to a multicast group and sends the beam number
549 This function connects to a multicast group and sends the beam number
547 to all abs modules.
550 to all abs modules.
548 """
551 """
549
552
550 # Se manda a cero RC para poder realizar cambio de beam
553 # Se manda a cero RC para poder realizar cambio de beam
551 if self.experiment is None:
554 if self.experiment is None:
552 confs = []
555 confs = []
553 else:
556 else:
554 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
557 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
555 confdds = ''
558 confdds = ''
556 confjars = ''
559 confjars = ''
557 confrc = ''
560 confrc = ''
558 #TO STOP DEVICES: DDS-JARS-RC
561 #TO STOP DEVICES: DDS-JARS-RC
559 for i in range(0,len(confs)):
562 for i in range(0,len(confs)):
560 if i==0:
563 if i==0:
561 for conf in confs:
564 for conf in confs:
562 if conf.device.device_type.name == 'dds':
565 if conf.device.device_type.name == 'dds':
563 confdds = conf
566 confdds = conf
564 confdds.stop_device()
567 confdds.stop_device()
565 break
568 break
566 if i==1:
569 if i==1:
567 for conf in confs:
570 for conf in confs:
568 if conf.device.device_type.name == 'jars':
571 if conf.device.device_type.name == 'jars':
569 confjars = conf
572 confjars = conf
570 confjars.stop_device()
573 confjars.stop_device()
571 break
574 break
572 if i==2:
575 if i==2:
573 for conf in confs:
576 for conf in confs:
574 if conf.device.device_type.name == 'rc':
577 if conf.device.device_type.name == 'rc':
575 confrc = conf
578 confrc = conf
576 confrc.stop_device()
579 confrc.stop_device()
577 break
580 break
578 if beam_pos > 0:
581 if beam_pos > 0:
579 beam_pos = beam_pos - 1
582 beam_pos = beam_pos - 1
580 else:
583 else:
581 beam_pos = 0
584 beam_pos = 0
582
585
583 #El indice del apunte debe ser menor que el numero total de apuntes
586 #El indice del apunte debe ser menor que el numero total de apuntes
584 #El servidor tcp en el embebido comienza a contar desde 0
587 #El servidor tcp en el embebido comienza a contar desde 0
585 status = ['0'] * 64
588 status = ['0'] * 64
586 message = 'CHGB{}'.format(beam_pos)
589 message = 'CHGB{}'.format(beam_pos)
587 sock = self.send_multicast(message)
590 sock = self.send_multicast(message)
588 for i in range(32):
591 for i in range(32):
589 try:
592 try:
590 data, address = sock.recvfrom(1024)
593 data, address = sock.recvfrom(1024)
591 print address, data
594 print address, data
592 if data == '1':
595 if data == '1':
593 status[int(address[0][10:])-1] = '3'
596 status[int(address[0][10:])-1] = '3'
594 elif data == '0':
597 elif data == '0':
595 status[int(address[0][10:])-1] = '1'
598 status[int(address[0][10:])-1] = '1'
596 except Exception as e:
599 except Exception as e:
597 print 'Error {}'.format(e)
600 print 'Error {}'.format(e)
598 pass
601 pass
599
602
600 sock.close()
603 sock.close()
601
604
602 #Start DDS-RC-JARS
605 #Start DDS-RC-JARS
603 if confdds:
606 if confdds:
604 confdds.start_device()
607 confdds.start_device()
605 if confrc:
608 if confrc:
606 #print confrc
609 #print confrc
607 confrc.start_device()
610 confrc.start_device()
608 if confjars:
611 if confjars:
609 confjars.start_device()
612 confjars.start_device()
610
613
611 self.message = "ABS Beam has been changed"
614 self.message = "ABS Beam has been changed"
612 self.module_status = ''.join(status)
615 self.module_status = ''.join(status)
613 self.save()
616 self.save()
614 return True
617 return True
615
618
616
619
617 def get_absolute_url_import(self):
620 def get_absolute_url_import(self):
618 return reverse('url_import_abs_conf', args=[str(self.id)])
621 return reverse('url_import_abs_conf', args=[str(self.id)])
619
622
620
623
621 class ABSBeam(models.Model):
624 class ABSBeam(models.Model):
622
625
623 name = models.CharField(max_length=60, default='Beam')
626 name = models.CharField(max_length=60, default='Beam')
624 antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default)
627 antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default)
625 abs_conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration')
628 abs_conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration')
626 tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default)
629 tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default)
627 rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default)
630 rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default)
628 s_time = models.TimeField(verbose_name='Star Time', default='00:00:00')
631 s_time = models.TimeField(verbose_name='Star Time', default='00:00:00')
629 e_time = models.TimeField(verbose_name='End Time', default='23:59:59')
632 e_time = models.TimeField(verbose_name='End Time', default='23:59:59')
630 ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default)
633 ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default)
631 only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default)
634 only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default)
632
635
633 class Meta:
636 class Meta:
634 db_table = 'abs_beams'
637 db_table = 'abs_beams'
635
638
636 def __unicode__(self):
639 def __unicode__(self):
637 return u'%s' % (self.name)
640 return u'%s' % (self.name)
638
641
639 def parms_to_dict(self):
642 def parms_to_dict(self):
640
643
641 parameters = {}
644 parameters = {}
642 parameters['name'] = self.name
645 parameters['name'] = self.name
643 parameters['antenna'] = ast.literal_eval(self.antenna)
646 parameters['antenna'] = ast.literal_eval(self.antenna)
644 parameters['abs_conf'] = self.abs_conf.name
647 parameters['abs_conf'] = self.abs_conf.name
645 parameters['tx'] = ast.literal_eval(self.tx)
648 parameters['tx'] = ast.literal_eval(self.tx)
646 parameters['rx'] = ast.literal_eval(self.rx)
649 parameters['rx'] = ast.literal_eval(self.rx)
647 parameters['s_time'] = self.s_time.strftime("%H:%M:%S")
650 parameters['s_time'] = self.s_time.strftime("%H:%M:%S")
648 parameters['e_time'] = self.e_time.strftime("%H:%M:%S")
651 parameters['e_time'] = self.e_time.strftime("%H:%M:%S")
649 parameters['ues'] = ast.literal_eval(self.ues)
652 parameters['ues'] = ast.literal_eval(self.ues)
650 parameters['only_rx'] = json.loads(self.only_rx)
653 parameters['only_rx'] = json.loads(self.only_rx)
651
654
652 return parameters
655 return parameters
653
656
654 def dict_to_parms(self, parameters):
657 def dict_to_parms(self, parameters):
655
658
656 self.name = parameters['name']
659 self.name = parameters['name']
657 self.antenna = json.dumps(parameters['antenna'])
660 self.antenna = json.dumps(parameters['antenna'])
658 #self.abs_conf = parameters['abs_conf']
661 #self.abs_conf = parameters['abs_conf']
659 self.tx = json.dumps(parameters['tx'])
662 self.tx = json.dumps(parameters['tx'])
660 self.rx = json.dumps(parameters['rx'])
663 self.rx = json.dumps(parameters['rx'])
661 #self.s_time = parameters['s_time']
664 #self.s_time = parameters['s_time']
662 #self.e_time = parameters['e_time']
665 #self.e_time = parameters['e_time']
663 self.ues = json.dumps(parameters['ues'])
666 self.ues = json.dumps(parameters['ues'])
664 self.only_rx = json.dumps(parameters['only_rx'])
667 self.only_rx = json.dumps(parameters['only_rx'])
665 self.save()
668 self.save()
666
669
667
670
668 def clone(self, **kwargs):
671 def clone(self, **kwargs):
669
672
670 self.pk = None
673 self.pk = None
671 self.id = None
674 self.id = None
672 for attr, value in kwargs.items():
675 for attr, value in kwargs.items():
673 setattr(self, attr, value)
676 setattr(self, attr, value)
674
677
675 self.save()
678 self.save()
676
679
677 return self
680 return self
678
681
679
682
680 def module_6bits(self, module):
683 def module_6bits(self, module):
681 """
684 """
682 This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module
685 This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module
683 """
686 """
684 module += 1
687 module += 1
685 if module > 64:
688 if module > 64:
686 beam_bits = ""
689 beam_bits = ""
687 return beam_bits
690 return beam_bits
688
691
689 data = ast.literal_eval(self.antenna)
692 data = ast.literal_eval(self.antenna)
690 up_data = data['antenna_up']
693 up_data = data['antenna_up']
691 down_data = data['antenna_down']
694 down_data = data['antenna_down']
692
695
693 pos = ip2position(module)
696 pos = ip2position(module)
694 up_value = up_data[pos[0]][pos[1]]
697 up_value = up_data[pos[0]][pos[1]]
695 down_value = down_data[pos[0]][pos[1]]
698 down_value = down_data[pos[0]][pos[1]]
696
699
697 up_bits = up_conv_bits(up_value)
700 up_bits = up_conv_bits(up_value)
698 down_bits = down_conv_bits(down_value)
701 down_bits = down_conv_bits(down_value)
699 beam_bits = up_bits+down_bits
702 beam_bits = up_bits+down_bits
700
703
701 return beam_bits
704 return beam_bits
702
705
703
706
704 @property
707 @property
705 def get_upvalues(self):
708 def get_upvalues(self):
706 """
709 """
707 This function reads antenna pattern and show the up-value of one abs module
710 This function reads antenna pattern and show the up-value of one abs module
708 """
711 """
709
712
710 data = ast.literal_eval(self.antenna)
713 data = ast.literal_eval(self.antenna)
711 up_data = data['antenna_up']
714 up_data = data['antenna_up']
712
715
713 up_values = []
716 up_values = []
714 for data in up_data:
717 for data in up_data:
715 for i in range(0,8):
718 for i in range(0,8):
716 up_values.append(data[i])
719 up_values.append(data[i])
717
720
718 return up_values
721 return up_values
719
722
720 @property
723 @property
721 def antenna_upvalues(self):
724 def antenna_upvalues(self):
722 """
725 """
723 This function reads antenna pattern and show the up - values of one abs beam
726 This function reads antenna pattern and show the up - values of one abs beam
724 in a particular order
727 in a particular order
725 """
728 """
726 data = ast.literal_eval(self.antenna)
729 data = ast.literal_eval(self.antenna)
727 up_data = data['antenna_up']
730 up_data = data['antenna_up']
728
731
729 return up_data
732 return up_data
730
733
731 @property
734 @property
732 def antenna_downvalues(self):
735 def antenna_downvalues(self):
733 """
736 """
734 This function reads antenna pattern and show the down - values of one abs beam
737 This function reads antenna pattern and show the down - values of one abs beam
735 in a particular order
738 in a particular order
736 """
739 """
737 data = ast.literal_eval(self.antenna)
740 data = ast.literal_eval(self.antenna)
738 down_data = data['antenna_down']
741 down_data = data['antenna_down']
739
742
740 return down_data
743 return down_data
741
744
742 @property
745 @property
743 def get_downvalues(self):
746 def get_downvalues(self):
744 """
747 """
745 This function reads antenna pattern and show the down-value of one abs module
748 This function reads antenna pattern and show the down-value of one abs module
746 """
749 """
747
750
748 data = ast.literal_eval(self.antenna)
751 data = ast.literal_eval(self.antenna)
749 down_data = data['antenna_down']
752 down_data = data['antenna_down']
750
753
751 down_values = []
754 down_values = []
752 for data in down_data:
755 for data in down_data:
753 for i in range(0,8):
756 for i in range(0,8):
754 down_values.append(data[i])
757 down_values.append(data[i])
755
758
756 return down_values
759 return down_values
757
760
758 @property
761 @property
759 def get_up_ues(self):
762 def get_up_ues(self):
760 """
763 """
761 This function shows the up-ues-value of one beam
764 This function shows the up-ues-value of one beam
762 """
765 """
763 data = ast.literal_eval(self.ues)
766 data = ast.literal_eval(self.ues)
764 up_ues = data['up']
767 up_ues = data['up']
765
768
766 return up_ues
769 return up_ues
767
770
768 @property
771 @property
769 def get_down_ues(self):
772 def get_down_ues(self):
770 """
773 """
771 This function shows the down-ues-value of one beam
774 This function shows the down-ues-value of one beam
772 """
775 """
773 data = ast.literal_eval(self.ues)
776 data = ast.literal_eval(self.ues)
774 down_ues = data['down']
777 down_ues = data['down']
775
778
776 return down_ues
779 return down_ues
777
780
778 @property
781 @property
779 def get_up_onlyrx(self):
782 def get_up_onlyrx(self):
780 """
783 """
781 This function shows the up-onlyrx-value of one beam
784 This function shows the up-onlyrx-value of one beam
782 """
785 """
783 data = json.loads(self.only_rx)
786 data = json.loads(self.only_rx)
784 up_onlyrx = data['up']
787 up_onlyrx = data['up']
785
788
786 return up_onlyrx
789 return up_onlyrx
787
790
788 @property
791 @property
789 def get_down_onlyrx(self):
792 def get_down_onlyrx(self):
790 """
793 """
791 This function shows the down-onlyrx-value of one beam
794 This function shows the down-onlyrx-value of one beam
792 """
795 """
793 data = json.loads(self.only_rx)
796 data = json.loads(self.only_rx)
794 down_onlyrx = data['down']
797 down_onlyrx = data['down']
795
798
796 return down_onlyrx
799 return down_onlyrx
797
800
798 @property
801 @property
799 def get_tx(self):
802 def get_tx(self):
800 """
803 """
801 This function shows the tx-values of one beam
804 This function shows the tx-values of one beam
802 """
805 """
803 data = json.loads(self.tx)
806 data = json.loads(self.tx)
804
807
805 return data
808 return data
806
809
807 @property
810 @property
808 def get_uptx(self):
811 def get_uptx(self):
809 """
812 """
810 This function shows the up-tx-values of one beam
813 This function shows the up-tx-values of one beam
811 """
814 """
812 data = json.loads(self.tx)
815 data = json.loads(self.tx)
813 up_data = data['up']
816 up_data = data['up']
814
817
815 up_values = []
818 up_values = []
816 for data in up_data:
819 for data in up_data:
817 for i in range(0,8):
820 for i in range(0,8):
818 up_values.append(data[i])
821 up_values.append(data[i])
819
822
820 return up_values
823 return up_values
821
824
822 @property
825 @property
823 def get_downtx(self):
826 def get_downtx(self):
824 """
827 """
825 This function shows the down-tx-values of one beam
828 This function shows the down-tx-values of one beam
826 """
829 """
827 data = json.loads(self.tx)
830 data = json.loads(self.tx)
828 down_data = data['down']
831 down_data = data['down']
829
832
830 down_values = []
833 down_values = []
831 for data in down_data:
834 for data in down_data:
832 for i in range(0,8):
835 for i in range(0,8):
833 down_values.append(data[i])
836 down_values.append(data[i])
834
837
835 return down_values
838 return down_values
836
839
837
840
838
841
839 @property
842 @property
840 def get_rx(self):
843 def get_rx(self):
841 """
844 """
842 This function shows the rx-values of one beam
845 This function shows the rx-values of one beam
843 """
846 """
844 data = json.loads(self.rx)
847 data = json.loads(self.rx)
845
848
846 return data
849 return data
847
850
848 @property
851 @property
849 def get_uprx(self):
852 def get_uprx(self):
850 """
853 """
851 This function shows the up-rx-values of one beam
854 This function shows the up-rx-values of one beam
852 """
855 """
853 data = json.loads(self.rx)
856 data = json.loads(self.rx)
854 up_data = data['up']
857 up_data = data['up']
855
858
856 up_values = []
859 up_values = []
857 for data in up_data:
860 for data in up_data:
858 for i in range(0,8):
861 for i in range(0,8):
859 up_values.append(data[i])
862 up_values.append(data[i])
860
863
861 return up_values
864 return up_values
862
865
863 @property
866 @property
864 def get_downrx(self):
867 def get_downrx(self):
865 """
868 """
866 This function shows the down-rx-values of one beam
869 This function shows the down-rx-values of one beam
867 """
870 """
868 data = json.loads(self.rx)
871 data = json.loads(self.rx)
869 down_data = data['down']
872 down_data = data['down']
870
873
871 down_values = []
874 down_values = []
872 for data in down_data:
875 for data in down_data:
873 for i in range(0,8):
876 for i in range(0,8):
874 down_values.append(data[i])
877 down_values.append(data[i])
875
878
876 return down_values
879 return down_values
@@ -1,342 +1,336
1 {% extends "dev_conf.html" %} {% load static %} {% load bootstrap3 %} {% load main_tags %}
1 {% extends "dev_conf.html" %} {% load static %} {% load bootstrap3 %} {% load main_tags %}
2 {% block extra-head %}
2 {% block extra-head %}
3 <style>
3 <style>
4 .abs {
4 .abs {
5 width: auto;
5 width: auto;
6 display: inline-block;
6 display: inline-block;
7 text-align: center;
7 text-align: center;
8 }
8 }
9
9
10 .abs td {
10 .abs td {
11 padding: 4px;
11 padding: 4px;
12 }
12 }
13
13
14 .module td {
14 .module td {
15 padding: 4px 15px 4px 15px;
15 padding: 4px 15px 4px 15px;
16 font-weight: bold;
16 font-weight: bold;
17 border: 1px solid
17 border: 1px solid
18 }
18 }
19
19
20 .legend {
20 .legend {
21 margin-left: 15px;
21 margin-left: 15px;
22 display: inline-block;
22 display: inline-block;
23 border: 2px solid;
23 border: 2px solid;
24 vertical-align: top;
24 vertical-align: top;
25 }
25 }
26
26
27 .legend th {
27 .legend th {
28 border-bottom: 1px dashed;
28 border-bottom: 1px dashed;
29 font-weight: bold;
29 font-weight: bold;
30 vertical-align: center;
30 vertical-align: center;
31 text-align: center;
31 text-align: center;
32 }
32 }
33
33
34 .legend td {
34 .legend td {
35 padding: 2px;
35 padding: 2px;
36 text-align: center;
36 text-align: center;
37 font-weight: bold;
37 }
38 }
38
39
39 </style>
40 </style>
40 {% endblock %}
41 {% endblock %}
41 {% block extra-menu-actions %}
42 {% block extra-menu-actions %}
42 <li>
43 <li>
43 <a href="{{ dev_conf.get_absolute_url_plot }}" target="_blank">
44 <a href="{{ dev_conf.get_absolute_url_plot }}" target="_blank">
44 <span class="glyphicon glyphicon-picture" aria-hidden="true"></span> View Patterns </a>
45 <span class="glyphicon glyphicon-picture" aria-hidden="true"></span> View Patterns </a>
45 </li>
46 </li>
46 {% endblock %}
47 {% endblock %}
47 {% block extra-content %}
48 {% block extra-content %}
48 {% if beams %}
49 {% if beams %}
49 <h4>Beams:</h4>
50 <h4>Beams:</h4>
50 <div class="container">
51 <div class="container">
51 <ul class="nav nav-pills">
52 <ul class="nav nav-pills">
52 {% for beam in beams %}
53 {% for beam in beams %}
53 <li {%if beam.pk == active_beam %} class="active" {% endif %}>
54 <li {%if beam.pk == active_beam %} class="active" {% endif %}>
54 <a data-toggle="pill" href="#menu{{forloop.counter}}">{{forloop.counter}}</a>
55 <a data-toggle="pill" href="#menu{{forloop.counter}}">{{forloop.counter}}</a>
55 </li>
56 </li>
56 {% endfor %}
57 {% endfor %}
57 </ul>
58 </ul>
58
59
59 <div class="tab-content">
60 <div class="tab-content">
60 {% for beam in beams %}
61 {% for beam in beams %}
61 <div id="menu{{forloop.counter}}" class="tab-pane fade {%if beam.pk == active_beam %}active in{% endif %}">
62 <div id="menu{{forloop.counter}}" class="tab-pane fade {%if beam.pk == active_beam %}active in{% endif %}">
62 <h3>{%if beam.pk == active_beam %}Active Beam: {%endif%}{{beam.name}}</h3>
63 <h3>{%if beam.pk == active_beam %}Active Beam: {%endif%}{{beam.name}}</h3>
63 <table id="abs_pattern{{forloop.counter}}" class="abs">
64 <table id="abs_pattern{{forloop.counter}}" class="abs">
64 <tr>
65 <tr>
65 <td>
66 <td>
66 <b>North Quarter</b>
67 <b>North Quarter</b>
67 <table class="module">
68 <table class="module">
68 <tr>
69 <tr>
69 <td title='{{module_messages.1}}'><span {%if beam.pk == active_beam %} {{color_status.1}} {%endif%}>{{beam.get_upvalues.0}}</span></td>
70 <td title='{{module_messages.1}}'><span {%if beam.pk == active_beam %} {{color_status.1}} {%endif%}>{{beam.get_upvalues.0}}</span></td>
70 <td title='{{module_messages.2}}'><span {%if beam.pk == active_beam %} {{color_status.2}} {%endif%}>{{beam.get_upvalues.1}}</span></td>
71 <td title='{{module_messages.2}}'><span {%if beam.pk == active_beam %} {{color_status.2}} {%endif%}>{{beam.get_upvalues.1}}</span></td>
71 <td title='{{module_messages.3}}'><span {%if beam.pk == active_beam %} {{color_status.3}} {%endif%}>{{beam.get_upvalues.2}}</span></td>
72 <td title='{{module_messages.3}}'><span {%if beam.pk == active_beam %} {{color_status.3}} {%endif%}>{{beam.get_upvalues.2}}</span></td>
72 <td title='{{module_messages.4}}'><span {%if beam.pk == active_beam %} {{color_status.4}} {%endif%}>{{beam.get_upvalues.3}}</span></td>
73 <td title='{{module_messages.4}}'><span {%if beam.pk == active_beam %} {{color_status.4}} {%endif%}>{{beam.get_upvalues.3}}</span></td>
73 </tr>
74 </tr>
74 <tr>
75 <tr>
75 <td title='{{module_messages.1}}'><span {%if beam.pk == active_beam %} {{color_status.1}} {%endif%}>{{beam.get_downvalues.0}}</span></td>
76 <td title='{{module_messages.1}}'><span {%if beam.pk == active_beam %} {{color_status.1}} {%endif%}>{{beam.get_downvalues.0}}</span></td>
76 <td title='{{module_messages.2}}'><span {%if beam.pk == active_beam %} {{color_status.2}} {%endif%}>{{beam.get_downvalues.1}}</span></td>
77 <td title='{{module_messages.2}}'><span {%if beam.pk == active_beam %} {{color_status.2}} {%endif%}>{{beam.get_downvalues.1}}</span></td>
77 <td title='{{module_messages.3}}'> <span {%if beam.pk == active_beam %} {{color_status.3}} {%endif%}>{{beam.get_downvalues.2}}</span></td>
78 <td title='{{module_messages.3}}'> <span {%if beam.pk == active_beam %} {{color_status.3}} {%endif%}>{{beam.get_downvalues.2}}</span></td>
78 <td title='{{module_messages.4}}'> <span {%if beam.pk == active_beam %} {{color_status.4}} {%endif%}>{{beam.get_downvalues.3}}</span></td>
79 <td title='{{module_messages.4}}'> <span {%if beam.pk == active_beam %} {{color_status.4}} {%endif%}>{{beam.get_downvalues.3}}</span></td>
79 </tr>
80 </tr>
80 <tr>
81 <tr>
81 <td title='{{module_messages.9}}'> <span {%if beam.pk == active_beam %} {{color_status.9}} {%endif%}>{{beam.get_upvalues.8}}</span></td>
82 <td title='{{module_messages.9}}'> <span {%if beam.pk == active_beam %} {{color_status.9}} {%endif%}>{{beam.get_upvalues.8}}</span></td>
82 <td title='{{module_messages.10}}'><span {%if beam.pk == active_beam %} {{color_status.10}} {%endif%}>{{beam.get_upvalues.9}}</span></td>
83 <td title='{{module_messages.10}}'><span {%if beam.pk == active_beam %} {{color_status.10}} {%endif%}>{{beam.get_upvalues.9}}</span></td>
83 <td title='{{module_messages.11}}'><span {%if beam.pk == active_beam %} {{color_status.11}} {%endif%}>{{beam.get_upvalues.10}}</span></td>
84 <td title='{{module_messages.11}}'><span {%if beam.pk == active_beam %} {{color_status.11}} {%endif%}>{{beam.get_upvalues.10}}</span></td>
84 <td title='{{module_messages.12}}'><span {%if beam.pk == active_beam %} {{color_status.12}} {%endif%}>{{beam.get_upvalues.11}}</span></td>
85 <td title='{{module_messages.12}}'><span {%if beam.pk == active_beam %} {{color_status.12}} {%endif%}>{{beam.get_upvalues.11}}</span></td>
85 </tr>
86 </tr>
86 <tr>
87 <tr>
87 <td title='{{module_messages.9}}'> <span {%if beam.pk == active_beam %} {{color_status.9}} {%endif%}>{{beam.get_downvalues.8}}</span></td>
88 <td title='{{module_messages.9}}'> <span {%if beam.pk == active_beam %} {{color_status.9}} {%endif%}>{{beam.get_downvalues.8}}</span></td>
88 <td title='{{module_messages.10}}'><span {%if beam.pk == active_beam %} {{color_status.10}} {%endif%}>{{beam.get_downvalues.9}}</span></td>
89 <td title='{{module_messages.10}}'><span {%if beam.pk == active_beam %} {{color_status.10}} {%endif%}>{{beam.get_downvalues.9}}</span></td>
89 <td title='{{module_messages.11}}'><span {%if beam.pk == active_beam %} {{color_status.11}} {%endif%}>{{beam.get_downvalues.10}}</span></td>
90 <td title='{{module_messages.11}}'><span {%if beam.pk == active_beam %} {{color_status.11}} {%endif%}>{{beam.get_downvalues.10}}</span></td>
90 <td title='{{module_messages.12}}'><span {%if beam.pk == active_beam %} {{color_status.12}} {%endif%}>{{beam.get_downvalues.11}}</span></td>
91 <td title='{{module_messages.12}}'><span {%if beam.pk == active_beam %} {{color_status.12}} {%endif%}>{{beam.get_downvalues.11}}</span></td>
91 </tr>
92 </tr>
92 <tr>
93 <tr>
93 <td title='{{module_messages.17}}'><span {%if beam.pk == active_beam %} {{color_status.17}} {%endif%}>{{beam.get_upvalues.16}}</span></td>
94 <td title='{{module_messages.17}}'><span {%if beam.pk == active_beam %} {{color_status.17}} {%endif%}>{{beam.get_upvalues.16}}</span></td>
94 <td title='{{module_messages.18}}'><span {%if beam.pk == active_beam %} {{color_status.18}} {%endif%}>{{beam.get_upvalues.17}}</span></td>
95 <td title='{{module_messages.18}}'><span {%if beam.pk == active_beam %} {{color_status.18}} {%endif%}>{{beam.get_upvalues.17}}</span></td>
95 <td title='{{module_messages.19}}'><span {%if beam.pk == active_beam %} {{color_status.19}} {%endif%}>{{beam.get_upvalues.18}}</span></td>
96 <td title='{{module_messages.19}}'><span {%if beam.pk == active_beam %} {{color_status.19}} {%endif%}>{{beam.get_upvalues.18}}</span></td>
96 <td title='{{module_messages.20}}'><span {%if beam.pk == active_beam %} {{color_status.20}} {%endif%}>{{beam.get_upvalues.19}}</span></td>
97 <td title='{{module_messages.20}}'><span {%if beam.pk == active_beam %} {{color_status.20}} {%endif%}>{{beam.get_upvalues.19}}</span></td>
97 </tr>
98 </tr>
98 <tr>
99 <tr>
99 <td title='{{module_messages.17}}'><span {%if beam.pk == active_beam %} {{color_status.17}} {%endif%}>{{beam.get_downvalues.16}}</span></td>
100 <td title='{{module_messages.17}}'><span {%if beam.pk == active_beam %} {{color_status.17}} {%endif%}>{{beam.get_downvalues.16}}</span></td>
100 <td title='{{module_messages.18}}'><span {%if beam.pk == active_beam %} {{color_status.18}} {%endif%}>{{beam.get_downvalues.17}}</span></td>
101 <td title='{{module_messages.18}}'><span {%if beam.pk == active_beam %} {{color_status.18}} {%endif%}>{{beam.get_downvalues.17}}</span></td>
101 <td title='{{module_messages.19}}'><span {%if beam.pk == active_beam %} {{color_status.19}} {%endif%}>{{beam.get_downvalues.18}}</span></td>
102 <td title='{{module_messages.19}}'><span {%if beam.pk == active_beam %} {{color_status.19}} {%endif%}>{{beam.get_downvalues.18}}</span></td>
102 <td title='{{module_messages.20}}'><span {%if beam.pk == active_beam %} {{color_status.20}} {%endif%}>{{beam.get_downvalues.19}}</span></td>
103 <td title='{{module_messages.20}}'><span {%if beam.pk == active_beam %} {{color_status.20}} {%endif%}>{{beam.get_downvalues.19}}</span></td>
103 </tr>
104 </tr>
104 <tr>
105 <tr>
105 <td title='{{module_messages.25}}'><span {%if beam.pk == active_beam %} {{color_status.25}} {%endif%}>{{beam.get_upvalues.24}}</span></td>
106 <td title='{{module_messages.25}}'><span {%if beam.pk == active_beam %} {{color_status.25}} {%endif%}>{{beam.get_upvalues.24}}</span></td>
106 <td title='{{module_messages.26}}'><span {%if beam.pk == active_beam %} {{color_status.26}} {%endif%}>{{beam.get_upvalues.25}}</span></td>
107 <td title='{{module_messages.26}}'><span {%if beam.pk == active_beam %} {{color_status.26}} {%endif%}>{{beam.get_upvalues.25}}</span></td>
107 <td title='{{module_messages.27}}'><span {%if beam.pk == active_beam %} {{color_status.27}} {%endif%}>{{beam.get_upvalues.26}}</span></td>
108 <td title='{{module_messages.27}}'><span {%if beam.pk == active_beam %} {{color_status.27}} {%endif%}>{{beam.get_upvalues.26}}</span></td>
108 <td title='{{module_messages.28}}'><span {%if beam.pk == active_beam %} {{color_status.28}} {%endif%}>{{beam.get_upvalues.27}}</span></td>
109 <td title='{{module_messages.28}}'><span {%if beam.pk == active_beam %} {{color_status.28}} {%endif%}>{{beam.get_upvalues.27}}</span></td>
109 </tr>
110 </tr>
110 <tr>
111 <tr>
111 <td title='{{module_messages.25}}'><span {%if beam.pk == active_beam %} {{color_status.25}} {%endif%}>{{beam.get_downvalues.24}}</span></td>
112 <td title='{{module_messages.25}}'><span {%if beam.pk == active_beam %} {{color_status.25}} {%endif%}>{{beam.get_downvalues.24}}</span></td>
112 <td title='{{module_messages.26}}'><span {%if beam.pk == active_beam %} {{color_status.26}} {%endif%}>{{beam.get_downvalues.25}}</span></td>
113 <td title='{{module_messages.26}}'><span {%if beam.pk == active_beam %} {{color_status.26}} {%endif%}>{{beam.get_downvalues.25}}</span></td>
113 <td title='{{module_messages.27}}'><span {%if beam.pk == active_beam %} {{color_status.27}} {%endif%}>{{beam.get_downvalues.26}}</span></td>
114 <td title='{{module_messages.27}}'><span {%if beam.pk == active_beam %} {{color_status.27}} {%endif%}>{{beam.get_downvalues.26}}</span></td>
114 <td title='{{module_messages.28}}'><span {%if beam.pk == active_beam %} {{color_status.28}} {%endif%}>{{beam.get_downvalues.27}}</span></td>
115 <td title='{{module_messages.28}}'><span {%if beam.pk == active_beam %} {{color_status.28}} {%endif%}>{{beam.get_downvalues.27}}</span></td>
115 </tr>
116 </tr>
116 </table>
117 </table>
117 </td>
118 </td>
118 <td>
119 <td>
119 <b>East Quarter</b>
120 <b>East Quarter</b>
120 <table class="module">
121 <table class="module">
121 <tr>
122 <tr>
122 <td title='{{module_messages.5}}'> <span {%if beam.pk == active_beam %} {{color_status.5}} {%endif%}>{{beam.get_upvalues.4}}</span></td>
123 <td title='{{module_messages.5}}'> <span {%if beam.pk == active_beam %} {{color_status.5}} {%endif%}>{{beam.get_upvalues.4}}</span></td>
123 <td title='{{module_messages.6}}'> <span {%if beam.pk == active_beam %} {{color_status.6}} {%endif%}>{{beam.get_upvalues.5}}</span></td>
124 <td title='{{module_messages.6}}'> <span {%if beam.pk == active_beam %} {{color_status.6}} {%endif%}>{{beam.get_upvalues.5}}</span></td>
124 <td title='{{module_messages.7}}'> <span {%if beam.pk == active_beam %} {{color_status.7}} {%endif%}>{{beam.get_upvalues.6}}</span></td>
125 <td title='{{module_messages.7}}'> <span {%if beam.pk == active_beam %} {{color_status.7}} {%endif%}>{{beam.get_upvalues.6}}</span></td>
125 <td title='{{module_messages.8}}'> <span {%if beam.pk == active_beam %} {{color_status.8}} {%endif%}>{{beam.get_upvalues.7}}</span></td>
126 <td title='{{module_messages.8}}'> <span {%if beam.pk == active_beam %} {{color_status.8}} {%endif%}>{{beam.get_upvalues.7}}</span></td>
126 </tr>
127 </tr>
127 <tr>
128 <tr>
128 <td title='{{module_messages.5}}'> <span {%if beam.pk == active_beam %} {{color_status.5}} {%endif%}>{{beam.get_downvalues.4}}</span></td>
129 <td title='{{module_messages.5}}'> <span {%if beam.pk == active_beam %} {{color_status.5}} {%endif%}>{{beam.get_downvalues.4}}</span></td>
129 <td title='{{module_messages.6}}'> <span {%if beam.pk == active_beam %} {{color_status.6}} {%endif%}>{{beam.get_downvalues.5}}</span></td>
130 <td title='{{module_messages.6}}'> <span {%if beam.pk == active_beam %} {{color_status.6}} {%endif%}>{{beam.get_downvalues.5}}</span></td>
130 <td title='{{module_messages.7}}'> <span {%if beam.pk == active_beam %} {{color_status.7}} {%endif%}>{{beam.get_downvalues.6}}</span></td>
131 <td title='{{module_messages.7}}'> <span {%if beam.pk == active_beam %} {{color_status.7}} {%endif%}>{{beam.get_downvalues.6}}</span></td>
131 <td title='{{module_messages.8}}'> <span {%if beam.pk == active_beam %} {{color_status.8}} {%endif%}>{{beam.get_downvalues.7}}</span></td>
132 <td title='{{module_messages.8}}'> <span {%if beam.pk == active_beam %} {{color_status.8}} {%endif%}>{{beam.get_downvalues.7}}</span></td>
132 </tr>
133 </tr>
133 <tr>
134 <tr>
134 <td title='{{module_messages.13}}'><span {%if beam.pk == active_beam %} {{color_status.13}} {%endif%}>{{beam.get_upvalues.12}}</span></td>
135 <td title='{{module_messages.13}}'><span {%if beam.pk == active_beam %} {{color_status.13}} {%endif%}>{{beam.get_upvalues.12}}</span></td>
135 <td title='{{module_messages.14}}'><span {%if beam.pk == active_beam %} {{color_status.14}} {%endif%}>{{beam.get_upvalues.13}}</span></td>
136 <td title='{{module_messages.14}}'><span {%if beam.pk == active_beam %} {{color_status.14}} {%endif%}>{{beam.get_upvalues.13}}</span></td>
136 <td title='{{module_messages.15}}'><span {%if beam.pk == active_beam %} {{color_status.15}} {%endif%}>{{beam.get_upvalues.14}}</span></td>
137 <td title='{{module_messages.15}}'><span {%if beam.pk == active_beam %} {{color_status.15}} {%endif%}>{{beam.get_upvalues.14}}</span></td>
137 <td title='{{module_messages.16}}'><span {%if beam.pk == active_beam %} {{color_status.16}} {%endif%}>{{beam.get_upvalues.15}}</span></td>
138 <td title='{{module_messages.16}}'><span {%if beam.pk == active_beam %} {{color_status.16}} {%endif%}>{{beam.get_upvalues.15}}</span></td>
138 </tr>
139 </tr>
139 <tr>
140 <tr>
140 <td title='{{module_messages.13}}'><span {%if beam.pk == active_beam %} {{color_status.13}} {%endif%}>{{beam.get_downvalues.12}}</span></td>
141 <td title='{{module_messages.13}}'><span {%if beam.pk == active_beam %} {{color_status.13}} {%endif%}>{{beam.get_downvalues.12}}</span></td>
141 <td title='{{module_messages.14}}'><span {%if beam.pk == active_beam %} {{color_status.14}} {%endif%}>{{beam.get_downvalues.13}}</span></td>
142 <td title='{{module_messages.14}}'><span {%if beam.pk == active_beam %} {{color_status.14}} {%endif%}>{{beam.get_downvalues.13}}</span></td>
142 <td title='{{module_messages.15}}'><span {%if beam.pk == active_beam %} {{color_status.15}} {%endif%}>{{beam.get_downvalues.14}}</span></td>
143 <td title='{{module_messages.15}}'><span {%if beam.pk == active_beam %} {{color_status.15}} {%endif%}>{{beam.get_downvalues.14}}</span></td>
143 <td title='{{module_messages.16}}'><span {%if beam.pk == active_beam %} {{color_status.16}} {%endif%}>{{beam.get_downvalues.15}}</span></td>
144 <td title='{{module_messages.16}}'><span {%if beam.pk == active_beam %} {{color_status.16}} {%endif%}>{{beam.get_downvalues.15}}</span></td>
144 </tr>
145 </tr>
145 <tr>
146 <tr>
146 <td title='{{module_messages.21}}'><span {%if beam.pk == active_beam %} {{color_status.21}} {%endif%}>{{beam.get_upvalues.20}}</span></td>
147 <td title='{{module_messages.21}}'><span {%if beam.pk == active_beam %} {{color_status.21}} {%endif%}>{{beam.get_upvalues.20}}</span></td>
147 <td title='{{module_messages.22}}'><span {%if beam.pk == active_beam %} {{color_status.22}} {%endif%}>{{beam.get_upvalues.21}}</span></td>
148 <td title='{{module_messages.22}}'><span {%if beam.pk == active_beam %} {{color_status.22}} {%endif%}>{{beam.get_upvalues.21}}</span></td>
148 <td title='{{module_messages.23}}'><span {%if beam.pk == active_beam %} {{color_status.23}} {%endif%}>{{beam.get_upvalues.22}}</span></td>
149 <td title='{{module_messages.23}}'><span {%if beam.pk == active_beam %} {{color_status.23}} {%endif%}>{{beam.get_upvalues.22}}</span></td>
149 <td title='{{module_messages.24}}'><span {%if beam.pk == active_beam %} {{color_status.24}} {%endif%}>{{beam.get_upvalues.23}}</span></td>
150 <td title='{{module_messages.24}}'><span {%if beam.pk == active_beam %} {{color_status.24}} {%endif%}>{{beam.get_upvalues.23}}</span></td>
150 </tr>
151 </tr>
151 <tr>
152 <tr>
152 <td title='{{module_messages.21}}'><span {%if beam.pk == active_beam %} {{color_status.21}} {%endif%}>{{beam.get_downvalues.20}}</span></td>
153 <td title='{{module_messages.21}}'><span {%if beam.pk == active_beam %} {{color_status.21}} {%endif%}>{{beam.get_downvalues.20}}</span></td>
153 <td title='{{module_messages.22}}'><span {%if beam.pk == active_beam %} {{color_status.22}} {%endif%}>{{beam.get_downvalues.21}}</span></td>
154 <td title='{{module_messages.22}}'><span {%if beam.pk == active_beam %} {{color_status.22}} {%endif%}>{{beam.get_downvalues.21}}</span></td>
154 <td title='{{module_messages.23}}'><span {%if beam.pk == active_beam %} {{color_status.23}} {%endif%}>{{beam.get_downvalues.22}}</span></td>
155 <td title='{{module_messages.23}}'><span {%if beam.pk == active_beam %} {{color_status.23}} {%endif%}>{{beam.get_downvalues.22}}</span></td>
155 <td title='{{module_messages.24}}'><span {%if beam.pk == active_beam %} {{color_status.24}} {%endif%}>{{beam.get_downvalues.23}}</span></td>
156 <td title='{{module_messages.24}}'><span {%if beam.pk == active_beam %} {{color_status.24}} {%endif%}>{{beam.get_downvalues.23}}</span></td>
156 </tr>
157 </tr>
157 <tr>
158 <tr>
158 <td title='{{module_messages.29}}'><span {%if beam.pk == active_beam %} {{color_status.29}} {%endif%}>{{beam.get_upvalues.28}}</span></td>
159 <td title='{{module_messages.29}}'><span {%if beam.pk == active_beam %} {{color_status.29}} {%endif%}>{{beam.get_upvalues.28}}</span></td>
159 <td title='{{module_messages.30}}'><span {%if beam.pk == active_beam %} {{color_status.30}} {%endif%}>{{beam.get_upvalues.29}}</span></td>
160 <td title='{{module_messages.30}}'><span {%if beam.pk == active_beam %} {{color_status.30}} {%endif%}>{{beam.get_upvalues.29}}</span></td>
160 <td title='{{module_messages.31}}'><span {%if beam.pk == active_beam %} {{color_status.31}} {%endif%}>{{beam.get_upvalues.30}}</span></td>
161 <td title='{{module_messages.31}}'><span {%if beam.pk == active_beam %} {{color_status.31}} {%endif%}>{{beam.get_upvalues.30}}</span></td>
161 <td title='{{module_messages.32}}'><span {%if beam.pk == active_beam %} {{color_status.32}} {%endif%}>{{beam.get_upvalues.31}}</span></td>
162 <td title='{{module_messages.32}}'><span {%if beam.pk == active_beam %} {{color_status.32}} {%endif%}>{{beam.get_upvalues.31}}</span></td>
162 </tr>
163 </tr>
163 <tr>
164 <tr>
164 <td title='{{module_messages.29}}'><span {%if beam.pk == active_beam %} {{color_status.29}} {%endif%}>{{beam.get_downvalues.28}}</span></td>
165 <td title='{{module_messages.29}}'><span {%if beam.pk == active_beam %} {{color_status.29}} {%endif%}>{{beam.get_downvalues.28}}</span></td>
165 <td title='{{module_messages.30}}'><span {%if beam.pk == active_beam %} {{color_status.30}} {%endif%}>{{beam.get_downvalues.29}}</span></td>
166 <td title='{{module_messages.30}}'><span {%if beam.pk == active_beam %} {{color_status.30}} {%endif%}>{{beam.get_downvalues.29}}</span></td>
166 <td title='{{module_messages.31}}'><span {%if beam.pk == active_beam %} {{color_status.31}} {%endif%}>{{beam.get_downvalues.30}}</span></td>
167 <td title='{{module_messages.31}}'><span {%if beam.pk == active_beam %} {{color_status.31}} {%endif%}>{{beam.get_downvalues.30}}</span></td>
167 <td title='{{module_messages.32}}'><span {%if beam.pk == active_beam %} {{color_status.32}} {%endif%}>{{beam.get_downvalues.31}}</span></td>
168 <td title='{{module_messages.32}}'><span {%if beam.pk == active_beam %} {{color_status.32}} {%endif%}>{{beam.get_downvalues.31}}</span></td>
168 </tr>
169 </tr>
169 </table>
170 </table>
170 </td>
171 </td>
171 </tr>
172 </tr>
172 <tr>
173 <tr>
173 <td>
174 <td>
174 <b>West Quarter</b>
175 <b>West Quarter</b>
175 <table class="module">
176 <table class="module">
176 <tr>
177 <tr>
177 <td title='{{module_messages.33}}'><span {%if beam.pk == active_beam %} {{color_status.33}} {%endif%}>{{beam.get_upvalues.32}}</span></td>
178 <td title='{{module_messages.33}}'><span {%if beam.pk == active_beam %} {{color_status.33}} {%endif%}>{{beam.get_upvalues.32}}</span></td>
178 <td title='{{module_messages.34}}'><span {%if beam.pk == active_beam %} {{color_status.34}} {%endif%}>{{beam.get_upvalues.33}}</span></td>
179 <td title='{{module_messages.34}}'><span {%if beam.pk == active_beam %} {{color_status.34}} {%endif%}>{{beam.get_upvalues.33}}</span></td>
179 <td title='{{module_messages.35}}'><span {%if beam.pk == active_beam %} {{color_status.35}} {%endif%}>{{beam.get_upvalues.34}}</span></td>
180 <td title='{{module_messages.35}}'><span {%if beam.pk == active_beam %} {{color_status.35}} {%endif%}>{{beam.get_upvalues.34}}</span></td>
180 <td title='{{module_messages.36}}'><span {%if beam.pk == active_beam %} {{color_status.36}} {%endif%}>{{beam.get_upvalues.35}}</span></td>
181 <td title='{{module_messages.36}}'><span {%if beam.pk == active_beam %} {{color_status.36}} {%endif%}>{{beam.get_upvalues.35}}</span></td>
181 </tr>
182 </tr>
182 <tr>
183 <tr>
183 <td title='{{module_messages.33}}'><span {%if beam.pk == active_beam %} {{color_status.33}} {%endif%}>{{beam.get_downvalues.32}}</span></td>
184 <td title='{{module_messages.33}}'><span {%if beam.pk == active_beam %} {{color_status.33}} {%endif%}>{{beam.get_downvalues.32}}</span></td>
184 <td title='{{module_messages.34}}'><span {%if beam.pk == active_beam %} {{color_status.34}} {%endif%}>{{beam.get_downvalues.33}}</span></td>
185 <td title='{{module_messages.34}}'><span {%if beam.pk == active_beam %} {{color_status.34}} {%endif%}>{{beam.get_downvalues.33}}</span></td>
185 <td title='{{module_messages.35}}'><span {%if beam.pk == active_beam %} {{color_status.35}} {%endif%}>{{beam.get_downvalues.34}}</span></td>
186 <td title='{{module_messages.35}}'><span {%if beam.pk == active_beam %} {{color_status.35}} {%endif%}>{{beam.get_downvalues.34}}</span></td>
186 <td title='{{module_messages.36}}'><span {%if beam.pk == active_beam %} {{color_status.36}} {%endif%}>{{beam.get_downvalues.35}}</span></td>
187 <td title='{{module_messages.36}}'><span {%if beam.pk == active_beam %} {{color_status.36}} {%endif%}>{{beam.get_downvalues.35}}</span></td>
187 </tr>
188 </tr>
188 <tr>
189 <tr>
189 <td title='{{module_messages.41}}'><span {%if beam.pk == active_beam %} {{color_status.41}} {%endif%}>{{beam.get_upvalues.40}}</span></td>
190 <td title='{{module_messages.41}}'><span {%if beam.pk == active_beam %} {{color_status.41}} {%endif%}>{{beam.get_upvalues.40}}</span></td>
190 <td title='{{module_messages.42}}'><span {%if beam.pk == active_beam %} {{color_status.42}} {%endif%}>{{beam.get_upvalues.41}}</span></td>
191 <td title='{{module_messages.42}}'><span {%if beam.pk == active_beam %} {{color_status.42}} {%endif%}>{{beam.get_upvalues.41}}</span></td>
191 <td title='{{module_messages.43}}'><span {%if beam.pk == active_beam %} {{color_status.43}} {%endif%}>{{beam.get_upvalues.42}}</span></td>
192 <td title='{{module_messages.43}}'><span {%if beam.pk == active_beam %} {{color_status.43}} {%endif%}>{{beam.get_upvalues.42}}</span></td>
192 <td title='{{module_messages.44}}'><span {%if beam.pk == active_beam %} {{color_status.44}} {%endif%}>{{beam.get_upvalues.43}}</span></td>
193 <td title='{{module_messages.44}}'><span {%if beam.pk == active_beam %} {{color_status.44}} {%endif%}>{{beam.get_upvalues.43}}</span></td>
193 </tr>
194 </tr>
194 <tr>
195 <tr>
195 <td title='{{module_messages.41}}'><span {%if beam.pk == active_beam %} {{color_status.41}} {%endif%}>{{beam.get_downvalues.40}}</span></td>
196 <td title='{{module_messages.41}}'><span {%if beam.pk == active_beam %} {{color_status.41}} {%endif%}>{{beam.get_downvalues.40}}</span></td>
196 <td title='{{module_messages.42}}'><span {%if beam.pk == active_beam %} {{color_status.42}} {%endif%}>{{beam.get_downvalues.41}}</span></td>
197 <td title='{{module_messages.42}}'><span {%if beam.pk == active_beam %} {{color_status.42}} {%endif%}>{{beam.get_downvalues.41}}</span></td>
197 <td title='{{module_messages.43}}'><span {%if beam.pk == active_beam %} {{color_status.43}} {%endif%}>{{beam.get_downvalues.42}}</span></td>
198 <td title='{{module_messages.43}}'><span {%if beam.pk == active_beam %} {{color_status.43}} {%endif%}>{{beam.get_downvalues.42}}</span></td>
198 <td title='{{module_messages.44}}'><span {%if beam.pk == active_beam %} {{color_status.44}} {%endif%}>{{beam.get_downvalues.43}}</span></td>
199 <td title='{{module_messages.44}}'><span {%if beam.pk == active_beam %} {{color_status.44}} {%endif%}>{{beam.get_downvalues.43}}</span></td>
199 </tr>
200 </tr>
200 <tr>
201 <tr>
201 <td title='{{module_messages.49}}'><span {%if beam.pk == active_beam %} {{color_status.49}} {%endif%}>{{beam.get_upvalues.48}}</span></td>
202 <td title='{{module_messages.49}}'><span {%if beam.pk == active_beam %} {{color_status.49}} {%endif%}>{{beam.get_upvalues.48}}</span></td>
202 <td title='{{module_messages.51}}'><span {%if beam.pk == active_beam %} {{color_status.50}} {%endif%}>{{beam.get_upvalues.49}}</span></td>
203 <td title='{{module_messages.51}}'><span {%if beam.pk == active_beam %} {{color_status.50}} {%endif%}>{{beam.get_upvalues.49}}</span></td>
203 <td title='{{module_messages.52}}'><span {%if beam.pk == active_beam %} {{color_status.51}} {%endif%}>{{beam.get_upvalues.50}}</span></td>
204 <td title='{{module_messages.52}}'><span {%if beam.pk == active_beam %} {{color_status.51}} {%endif%}>{{beam.get_upvalues.50}}</span></td>
204 <td title='{{module_messages.53}}'><span {%if beam.pk == active_beam %} {{color_status.52}} {%endif%}>{{beam.get_upvalues.51}}</span></td>
205 <td title='{{module_messages.53}}'><span {%if beam.pk == active_beam %} {{color_status.52}} {%endif%}>{{beam.get_upvalues.51}}</span></td>
205 </tr>
206 </tr>
206 <tr>
207 <tr>
207 <td title='{{module_messages.49}}'><span {%if beam.pk == active_beam %} {{color_status.49}} {%endif%}>{{beam.get_downvalues.48}}</span></td>
208 <td title='{{module_messages.49}}'><span {%if beam.pk == active_beam %} {{color_status.49}} {%endif%}>{{beam.get_downvalues.48}}</span></td>
208 <td title='{{module_messages.50}}'><span {%if beam.pk == active_beam %} {{color_status.50}} {%endif%}>{{beam.get_downvalues.49}}</span></td>
209 <td title='{{module_messages.50}}'><span {%if beam.pk == active_beam %} {{color_status.50}} {%endif%}>{{beam.get_downvalues.49}}</span></td>
209 <td title='{{module_messages.51}}'><span {%if beam.pk == active_beam %} {{color_status.51}} {%endif%}>{{beam.get_downvalues.50}}</span></td>
210 <td title='{{module_messages.51}}'><span {%if beam.pk == active_beam %} {{color_status.51}} {%endif%}>{{beam.get_downvalues.50}}</span></td>
210 <td title='{{module_messages.52}}'><span {%if beam.pk == active_beam %} {{color_status.52}} {%endif%}>{{beam.get_downvalues.51}}</span></td>
211 <td title='{{module_messages.52}}'><span {%if beam.pk == active_beam %} {{color_status.52}} {%endif%}>{{beam.get_downvalues.51}}</span></td>
211 </tr>
212 </tr>
212 <tr>
213 <tr>
213 <td title='{{module_messages.57}}'><span {%if beam.pk == active_beam %} {{color_status.57}} {%endif%}>{{beam.get_upvalues.56}}</span></td>
214 <td title='{{module_messages.57}}'><span {%if beam.pk == active_beam %} {{color_status.57}} {%endif%}>{{beam.get_upvalues.56}}</span></td>
214 <td title='{{module_messages.58}}'><span {%if beam.pk == active_beam %} {{color_status.58}} {%endif%}>{{beam.get_upvalues.57}}</span></td>
215 <td title='{{module_messages.58}}'><span {%if beam.pk == active_beam %} {{color_status.58}} {%endif%}>{{beam.get_upvalues.57}}</span></td>
215 <td title='{{module_messages.59}}'><span {%if beam.pk == active_beam %} {{color_status.59}} {%endif%}>{{beam.get_upvalues.58}}</span></td>
216 <td title='{{module_messages.59}}'><span {%if beam.pk == active_beam %} {{color_status.59}} {%endif%}>{{beam.get_upvalues.58}}</span></td>
216 <td title='{{module_messages.60}}'><span {%if beam.pk == active_beam %} {{color_status.60}} {%endif%}>{{beam.get_upvalues.59}}</span></td>
217 <td title='{{module_messages.60}}'><span {%if beam.pk == active_beam %} {{color_status.60}} {%endif%}>{{beam.get_upvalues.59}}</span></td>
217 </tr>
218 </tr>
218 <tr>
219 <tr>
219 <td title='{{module_messages.57}}'><span {%if beam.pk == active_beam %} {{color_status.57}} {%endif%}>{{beam.get_downvalues.56}}</span></td>
220 <td title='{{module_messages.57}}'><span {%if beam.pk == active_beam %} {{color_status.57}} {%endif%}>{{beam.get_downvalues.56}}</span></td>
220 <td title='{{module_messages.58}}'><span {%if beam.pk == active_beam %} {{color_status.58}} {%endif%}>{{beam.get_downvalues.57}}</span></td>
221 <td title='{{module_messages.58}}'><span {%if beam.pk == active_beam %} {{color_status.58}} {%endif%}>{{beam.get_downvalues.57}}</span></td>
221 <td title='{{module_messages.59}}'><span {%if beam.pk == active_beam %} {{color_status.59}} {%endif%}>{{beam.get_downvalues.58}}</span></td>
222 <td title='{{module_messages.59}}'><span {%if beam.pk == active_beam %} {{color_status.59}} {%endif%}>{{beam.get_downvalues.58}}</span></td>
222 <td title='{{module_messages.60}}'><span {%if beam.pk == active_beam %} {{color_status.60}} {%endif%}>{{beam.get_downvalues.59}}</span></td>
223 <td title='{{module_messages.60}}'><span {%if beam.pk == active_beam %} {{color_status.60}} {%endif%}>{{beam.get_downvalues.59}}</span></td>
223 </tr>
224 </tr>
224 </table>
225 </table>
225 </td>
226 </td>
226 <td>
227 <td>
227 <b>South Quarter</b>
228 <b>South Quarter</b>
228 <table class="module">
229 <table class="module">
229 <tr>
230 <tr>
230 <td title='{{module_messages.37}}'><span {%if beam.pk == active_beam %} {{color_status.37}} {%endif%}>{{beam.get_upvalues.36}}</span></td>
231 <td title='{{module_messages.37}}'><span {%if beam.pk == active_beam %} {{color_status.37}} {%endif%}>{{beam.get_upvalues.36}}</span></td>
231 <td title='{{module_messages.38}}'><span {%if beam.pk == active_beam %} {{color_status.38}} {%endif%}>{{beam.get_upvalues.37}}</span></td>
232 <td title='{{module_messages.38}}'><span {%if beam.pk == active_beam %} {{color_status.38}} {%endif%}>{{beam.get_upvalues.37}}</span></td>
232 <td title='{{module_messages.39}}'><span {%if beam.pk == active_beam %} {{color_status.39}} {%endif%}>{{beam.get_upvalues.38}}</span></td>
233 <td title='{{module_messages.39}}'><span {%if beam.pk == active_beam %} {{color_status.39}} {%endif%}>{{beam.get_upvalues.38}}</span></td>
233 <td title='{{module_messages.40}}'><span {%if beam.pk == active_beam %} {{color_status.40}} {%endif%}>{{beam.get_upvalues.39}}</span></td>
234 <td title='{{module_messages.40}}'><span {%if beam.pk == active_beam %} {{color_status.40}} {%endif%}>{{beam.get_upvalues.39}}</span></td>
234 </tr>
235 </tr>
235 <tr>
236 <tr>
236 <td title='{{module_messages.37}}'><span {%if beam.pk == active_beam %} {{color_status.37}} {%endif%}>{{beam.get_downvalues.36}}</span></td>
237 <td title='{{module_messages.37}}'><span {%if beam.pk == active_beam %} {{color_status.37}} {%endif%}>{{beam.get_downvalues.36}}</span></td>
237 <td title='{{module_messages.38}}'><span {%if beam.pk == active_beam %} {{color_status.38}} {%endif%}>{{beam.get_downvalues.37}}</span></td>
238 <td title='{{module_messages.38}}'><span {%if beam.pk == active_beam %} {{color_status.38}} {%endif%}>{{beam.get_downvalues.37}}</span></td>
238 <td title='{{module_messages.39}}'><span {%if beam.pk == active_beam %} {{color_status.39}} {%endif%}>{{beam.get_downvalues.38}}</span></td>
239 <td title='{{module_messages.39}}'><span {%if beam.pk == active_beam %} {{color_status.39}} {%endif%}>{{beam.get_downvalues.38}}</span></td>
239 <td title='{{module_messages.40}}'><span {%if beam.pk == active_beam %} {{color_status.40}} {%endif%}>{{beam.get_downvalues.39}}</span></td>
240 <td title='{{module_messages.40}}'><span {%if beam.pk == active_beam %} {{color_status.40}} {%endif%}>{{beam.get_downvalues.39}}</span></td>
240 </tr>
241 </tr>
241 <tr>
242 <tr>
242 <td title='{{module_messages.45}}'><span {%if beam.pk == active_beam %} {{color_status.45}} {%endif%}>{{beam.get_upvalues.44}}</span></td>
243 <td title='{{module_messages.45}}'><span {%if beam.pk == active_beam %} {{color_status.45}} {%endif%}>{{beam.get_upvalues.44}}</span></td>
243 <td title='{{module_messages.46}}'><span {%if beam.pk == active_beam %} {{color_status.46}} {%endif%}>{{beam.get_upvalues.45}}</span></td>
244 <td title='{{module_messages.46}}'><span {%if beam.pk == active_beam %} {{color_status.46}} {%endif%}>{{beam.get_upvalues.45}}</span></td>
244 <td title='{{module_messages.47}}'><span {%if beam.pk == active_beam %} {{color_status.47}} {%endif%}>{{beam.get_upvalues.46}}</span></td>
245 <td title='{{module_messages.47}}'><span {%if beam.pk == active_beam %} {{color_status.47}} {%endif%}>{{beam.get_upvalues.46}}</span></td>
245 <td title='{{module_messages.48}}'><span {%if beam.pk == active_beam %} {{color_status.48}} {%endif%}>{{beam.get_upvalues.47}}</span></td>
246 <td title='{{module_messages.48}}'><span {%if beam.pk == active_beam %} {{color_status.48}} {%endif%}>{{beam.get_upvalues.47}}</span></td>
246 </tr>
247 </tr>
247 <tr>
248 <tr>
248 <td title='{{module_messages.45}}'><span {%if beam.pk == active_beam %} {{color_status.45}} {%endif%}>{{beam.get_downvalues.44}}</span></td>
249 <td title='{{module_messages.45}}'><span {%if beam.pk == active_beam %} {{color_status.45}} {%endif%}>{{beam.get_downvalues.44}}</span></td>
249 <td title='{{module_messages.46}}'><span {%if beam.pk == active_beam %} {{color_status.46}} {%endif%}>{{beam.get_downvalues.45}}</span></td>
250 <td title='{{module_messages.46}}'><span {%if beam.pk == active_beam %} {{color_status.46}} {%endif%}>{{beam.get_downvalues.45}}</span></td>
250 <td title='{{module_messages.47}}'><span {%if beam.pk == active_beam %} {{color_status.47}} {%endif%}>{{beam.get_downvalues.46}}</span></td>
251 <td title='{{module_messages.47}}'><span {%if beam.pk == active_beam %} {{color_status.47}} {%endif%}>{{beam.get_downvalues.46}}</span></td>
251 <td title='{{module_messages.48}}'><span {%if beam.pk == active_beam %} {{color_status.48}} {%endif%}>{{beam.get_downvalues.47}}</span></td>
252 <td title='{{module_messages.48}}'><span {%if beam.pk == active_beam %} {{color_status.48}} {%endif%}>{{beam.get_downvalues.47}}</span></td>
252 </tr>
253 </tr>
253 <tr>
254 <tr>
254 <td title='{{module_messages.53}}'><span {%if beam.pk == active_beam %} {{color_status.53}} {%endif%}>{{beam.get_upvalues.52}}</span></td>
255 <td title='{{module_messages.53}}'><span {%if beam.pk == active_beam %} {{color_status.53}} {%endif%}>{{beam.get_upvalues.52}}</span></td>
255 <td title='{{module_messages.54}}'><span {%if beam.pk == active_beam %} {{color_status.54}} {%endif%}>{{beam.get_upvalues.53}}</span></td>
256 <td title='{{module_messages.54}}'><span {%if beam.pk == active_beam %} {{color_status.54}} {%endif%}>{{beam.get_upvalues.53}}</span></td>
256 <td title='{{module_messages.55}}'><span {%if beam.pk == active_beam %} {{color_status.55}} {%endif%}>{{beam.get_upvalues.54}}</span></td>
257 <td title='{{module_messages.55}}'><span {%if beam.pk == active_beam %} {{color_status.55}} {%endif%}>{{beam.get_upvalues.54}}</span></td>
257 <td title='{{module_messages.56}}'><span {%if beam.pk == active_beam %} {{color_status.56}} {%endif%}>{{beam.get_upvalues.55}}</span></td>
258 <td title='{{module_messages.56}}'><span {%if beam.pk == active_beam %} {{color_status.56}} {%endif%}>{{beam.get_upvalues.55}}</span></td>
258 </tr>
259 </tr>
259 <tr>
260 <tr>
260 <td title='{{module_messages.53}}'><span {%if beam.pk == active_beam %} {{color_status.53}} {%endif%}>{{beam.get_downvalues.52}}</span></td>
261 <td title='{{module_messages.53}}'><span {%if beam.pk == active_beam %} {{color_status.53}} {%endif%}>{{beam.get_downvalues.52}}</span></td>
261 <td title='{{module_messages.54}}'><span {%if beam.pk == active_beam %} {{color_status.54}} {%endif%}>{{beam.get_downvalues.53}}</span></td>
262 <td title='{{module_messages.54}}'><span {%if beam.pk == active_beam %} {{color_status.54}} {%endif%}>{{beam.get_downvalues.53}}</span></td>
262 <td title='{{module_messages.55}}'><span {%if beam.pk == active_beam %} {{color_status.55}} {%endif%}>{{beam.get_downvalues.54}}</span></td>
263 <td title='{{module_messages.55}}'><span {%if beam.pk == active_beam %} {{color_status.55}} {%endif%}>{{beam.get_downvalues.54}}</span></td>
263 <td title='{{module_messages.56}}'><span {%if beam.pk == active_beam %} {{color_status.56}} {%endif%}>{{beam.get_downvalues.55}}</span></td>
264 <td title='{{module_messages.56}}'><span {%if beam.pk == active_beam %} {{color_status.56}} {%endif%}>{{beam.get_downvalues.55}}</span></td>
264 </tr>
265 </tr>
265 <tr>
266 <tr>
266 <td title='{{module_messages.61}}'><span {%if beam.pk == active_beam %} {{color_status.61}} {%endif%}>{{beam.get_upvalues.60}}</span></td>
267 <td title='{{module_messages.61}}'><span {%if beam.pk == active_beam %} {{color_status.61}} {%endif%}>{{beam.get_upvalues.60}}</span></td>
267 <td title='{{module_messages.62}}'><span {%if beam.pk == active_beam %} {{color_status.62}} {%endif%}>{{beam.get_upvalues.61}}</span></td>
268 <td title='{{module_messages.62}}'><span {%if beam.pk == active_beam %} {{color_status.62}} {%endif%}>{{beam.get_upvalues.61}}</span></td>
268 <td title='{{module_messages.63}}'><span {%if beam.pk == active_beam %} {{color_status.63}} {%endif%}>{{beam.get_upvalues.62}}</span></td>
269 <td title='{{module_messages.63}}'><span {%if beam.pk == active_beam %} {{color_status.63}} {%endif%}>{{beam.get_upvalues.62}}</span></td>
269 <td title='{{module_messages.64}}'><span {%if beam.pk == active_beam %} {{color_status.64}} {%endif%}>{{beam.get_upvalues.63}}</span></td>
270 <td title='{{module_messages.64}}'><span {%if beam.pk == active_beam %} {{color_status.64}} {%endif%}>{{beam.get_upvalues.63}}</span></td>
270 </tr>
271 </tr>
271 <tr>
272 <tr>
272 <td title='{{module_messages.61}}'><span {%if beam.pk == active_beam %} {{color_status.61}} {%endif%}>{{beam.get_downvalues.60}}</span></td>
273 <td title='{{module_messages.61}}'><span {%if beam.pk == active_beam %} {{color_status.61}} {%endif%}>{{beam.get_downvalues.60}}</span></td>
273 <td title='{{module_messages.62}}'><span {%if beam.pk == active_beam %} {{color_status.62}} {%endif%}>{{beam.get_downvalues.61}}</span></td>
274 <td title='{{module_messages.62}}'><span {%if beam.pk == active_beam %} {{color_status.62}} {%endif%}>{{beam.get_downvalues.61}}</span></td>
274 <td title='{{module_messages.63}}'><span {%if beam.pk == active_beam %} {{color_status.63}} {%endif%}>{{beam.get_downvalues.62}}</span></td>
275 <td title='{{module_messages.63}}'><span {%if beam.pk == active_beam %} {{color_status.63}} {%endif%}>{{beam.get_downvalues.62}}</span></td>
275 <td title='{{module_messages.64}}'><span {%if beam.pk == active_beam %} {{color_status.64}} {%endif%}>{{beam.get_downvalues.63}}</span></td>
276 <td title='{{module_messages.64}}'><span {%if beam.pk == active_beam %} {{color_status.64}} {%endif%}>{{beam.get_downvalues.63}}</span></td>
276 </tr>
277 </tr>
277 </table>
278 </table>
278 </td>
279 </td>
279 </tr>
280 </tr>
280 </table>
281 </table>
281
282
282 {% if beam.id == active_beam %}
283 {% if beam.id == active_beam %}
283 <table class="legend">
284 <table class="legend">
284 <tr>
285 <tr>
285 <th colspan="2">Legend</th>
286 <th>Legend</th>
286 </tr>
287 </tr>
287 <tr>
288 <tr>
288 <td class="text-danger">
289 <td class="text-warning">Connected</td>
289 <i>RED</i>
290 </td>
291 <td>Disconnected</td>
292 </tr>
290 </tr>
293 <tr>
291 <tr>
294 <td class="text-warning">
292 <td class="text-success">Running</td>
295 <i>ORANGE</i>
296 </td>
297 <td>Connected</td>
298 </tr>
293 </tr>
299 <tr>
294 <tr>
300 <td class="text-success">
295 <td class="text-info">Mismath</td>
301 <i>GREEN</i>
296 </tr>
302 </td>
297 <tr>
303 <td>Running
298 <td class="text-danger">Disconnected</td>
304 </td>
305 </tr>
299 </tr>
306 </table>
300 </table>
307 {% else %}
301 {% else %}
308 <div style="vertical-align: top; display:inline-block;">
302 <div style="vertical-align: top; display:inline-block;">
309 <button id="send_beam{{forloop.counter}}" type="button" class="btn btn-default">
303 <button id="send_beam{{forloop.counter}}" type="button" class="btn btn-default">
310 <span class="glyphicon glyphicon-export" aria-hidden="true"></span>
304 <span class="glyphicon glyphicon-export" aria-hidden="true"></span>
311 Change Beam</button>
305 Change Beam</button>
312 </div>
306 </div>
313 {% endif %}
307 {% endif %}
314 </div>
308 </div>
315 {% endfor %}
309 {% endfor %}
316 </div>
310 </div>
317 </div>
311 </div>
318
312
319
313
320 {% else %}
314 {% else %}
321 <p style="color:#b4bcc2; margin-left: 5%;">
315 <p style="color:#b4bcc2; margin-left: 5%;">
322 <i>No Beams...</i>
316 <i>No Beams...</i>
323 </p>
317 </p>
324 {% endif %} {% endblock extra-content %} {% block extra-js%}
318 {% endif %} {% endblock extra-content %} {% block extra-js%}
325 <script>
319 <script>
326 $(document).ready(function () {
320 $(document).ready(function () {
327
321
328 {% for beam in beams %}
322 {% for beam in beams %}
329
323
330 {% if dev_conf.operation_mode == 1 %}
324 {% if dev_conf.operation_mode == 1 %}
331 $("#send_beam{{forloop.counter}}").prop('disabled', true)
325 $("#send_beam{{forloop.counter}}").prop('disabled', true)
332 {% else %}
326 {% else %}
333 $("#send_beam{{forloop.counter}}").click(function () {
327 $("#send_beam{{forloop.counter}}").click(function () {
334 document.location = "{% url 'url_send_beam' dev_conf.id beam.id %}";
328 document.location = "{% url 'url_send_beam' dev_conf.id beam.id %}";
335 });
329 });
336 {% endif %}
330 {% endif %}
337
331
338 {% endfor %}
332 {% endfor %}
339
333
340
334
341 });
335 });
342 </script> {% endblock %} No newline at end of file
336 </script> {% endblock %}
@@ -1,415 +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
10
10 from datetime import datetime
11 from datetime import datetime
11 from time import sleep
12 from time import sleep
12 import os
13 import os
13 import io
14 import io
14
15
15 from apps.main.models import Device, Configuration, Experiment
16 from apps.main.models import Device, Configuration, Experiment
16 from apps.main.views import sidebar
17 from apps.main.views import sidebar
17
18
18 from .models import ABSConfiguration, ABSBeam
19 from .models import ABSConfiguration, ABSBeam
19 from .forms import ABSConfigurationForm, ABSBeamEditForm, ABSBeamAddForm, ABSImportForm
20 from .forms import ABSConfigurationForm, ABSBeamEditForm, ABSBeamAddForm, ABSImportForm
20
21
21 from .utils.overJroShow import overJroShow
22 from .utils.overJroShow import overJroShow
22 from .utils.OverJRO import OverJRO
23 from .utils.OverJRO import OverJRO
23 # Create your views here.
24 # Create your views here.
24 import json, ast
25 import json, ast
25
26
26
27
27 def get_values_from_form(form_data):
28 def get_values_from_form(form_data):
28
29
29 sublistup = []
30 sublistup = []
30 sublistdown = []
31 sublistdown = []
31 subtxlistup = []
32 subtxlistup = []
32 subtxlistdown = []
33 subtxlistdown = []
33 subrxlistup = []
34 subrxlistup = []
34 subrxlistdown = []
35 subrxlistdown = []
35
36
36 up_values_list = []
37 up_values_list = []
37 down_values_list = []
38 down_values_list = []
38 up_txvalues_list = []
39 up_txvalues_list = []
39 down_txvalues_list = []
40 down_txvalues_list = []
40 up_rxvalues_list = []
41 up_rxvalues_list = []
41 down_rxvalues_list = []
42 down_rxvalues_list = []
42
43
43 values_list = {}
44 values_list = {}
44 cont = 1
45 cont = 1
45
46
46 for i in range(1,65):
47 for i in range(1,65):
47 x = float(form_data['abs_up'+str(i)])
48 x = float(form_data['abs_up'+str(i)])
48 y = float(form_data['abs_down'+str(i)])
49 y = float(form_data['abs_down'+str(i)])
49 sublistup.append(x)
50 sublistup.append(x)
50 sublistdown.append(y)
51 sublistdown.append(y)
51
52
52 if str(i) in form_data.getlist('uptx_checks'):
53 if str(i) in form_data.getlist('uptx_checks'):
53 subtxlistup.append(1)
54 subtxlistup.append(1)
54 else:
55 else:
55 subtxlistup.append(0)
56 subtxlistup.append(0)
56 if str(i) in form_data.getlist('downtx_checks'):
57 if str(i) in form_data.getlist('downtx_checks'):
57 subtxlistdown.append(1)
58 subtxlistdown.append(1)
58 else:
59 else:
59 subtxlistdown.append(0)
60 subtxlistdown.append(0)
60
61
61 if str(i) in form_data.getlist('uprx_checks'):
62 if str(i) in form_data.getlist('uprx_checks'):
62 subrxlistup.append(1)
63 subrxlistup.append(1)
63 else:
64 else:
64 subrxlistup.append(0)
65 subrxlistup.append(0)
65 if str(i) in form_data.getlist('downrx_checks'):
66 if str(i) in form_data.getlist('downrx_checks'):
66 subrxlistdown.append(1)
67 subrxlistdown.append(1)
67 else:
68 else:
68 subrxlistdown.append(0)
69 subrxlistdown.append(0)
69
70
70 cont = cont+1
71 cont = cont+1
71
72
72 if cont == 9:
73 if cont == 9:
73 up_values_list.append(sublistup)
74 up_values_list.append(sublistup)
74 down_values_list.append(sublistdown)
75 down_values_list.append(sublistdown)
75 sublistup = []
76 sublistup = []
76 sublistdown = []
77 sublistdown = []
77
78
78 up_txvalues_list.append(subtxlistup)
79 up_txvalues_list.append(subtxlistup)
79 down_txvalues_list.append(subtxlistdown)
80 down_txvalues_list.append(subtxlistdown)
80 subtxlistup = []
81 subtxlistup = []
81 subtxlistdown = []
82 subtxlistdown = []
82 up_rxvalues_list.append(subrxlistup)
83 up_rxvalues_list.append(subrxlistup)
83 down_rxvalues_list.append(subrxlistdown)
84 down_rxvalues_list.append(subrxlistdown)
84 subrxlistup = []
85 subrxlistup = []
85 subrxlistdown = []
86 subrxlistdown = []
86 cont = 1
87 cont = 1
87
88
88
89
89 list_uesup = []
90 list_uesup = []
90 list_uesdown = []
91 list_uesdown = []
91 for i in range(1,5):
92 for i in range(1,5):
92 if form_data['ues_up'+str(i)] == '':
93 if form_data['ues_up'+str(i)] == '':
93 list_uesup.append(0.0)
94 list_uesup.append(0.0)
94 else:
95 else:
95 list_uesup.append(float(form_data['ues_up'+str(i)]))
96 list_uesup.append(float(form_data['ues_up'+str(i)]))
96
97
97 if form_data['ues_down'+str(i)] == '':
98 if form_data['ues_down'+str(i)] == '':
98 list_uesdown.append(0.0)
99 list_uesdown.append(0.0)
99 else:
100 else:
100 list_uesdown.append(float(form_data['ues_down'+str(i)]))
101 list_uesdown.append(float(form_data['ues_down'+str(i)]))
101
102
102 onlyrx_list = form_data.getlist('onlyrx')
103 onlyrx_list = form_data.getlist('onlyrx')
103 only_rx = {}
104 only_rx = {}
104 if '1' in onlyrx_list:
105 if '1' in onlyrx_list:
105 only_rx['up'] = True
106 only_rx['up'] = True
106 else:
107 else:
107 only_rx['up'] = False
108 only_rx['up'] = False
108 if '2' in onlyrx_list:
109 if '2' in onlyrx_list:
109 only_rx['down'] = True
110 only_rx['down'] = True
110 else:
111 else:
111 only_rx['down'] = False
112 only_rx['down'] = False
112
113
113 antenna = {'antenna_up': up_values_list, 'antenna_down': down_values_list}
114 antenna = {'antenna_up': up_values_list, 'antenna_down': down_values_list}
114 tx = {'up': up_txvalues_list, 'down': down_txvalues_list}
115 tx = {'up': up_txvalues_list, 'down': down_txvalues_list}
115 rx = {'up': up_rxvalues_list, 'down': down_rxvalues_list}
116 rx = {'up': up_rxvalues_list, 'down': down_rxvalues_list}
116 ues = {'up': list_uesup, 'down': list_uesdown}
117 ues = {'up': list_uesup, 'down': list_uesdown}
117 name = str(form_data['beam_name'])
118 name = str(form_data['beam_name'])
118
119
119 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}
120
121
121 return beam_data
122 return beam_data
122
123
123
124
124 def abs_conf(request, id_conf):
125 def abs_conf(request, id_conf):
125
126
126 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
127 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
127 beams = ABSBeam.objects.filter(abs_conf=conf)
128 beams = ABSBeam.objects.filter(abs_conf=conf)
128 #------------Colors for Active Beam:-------------
129 #------------Colors for Active Beam:-------------
129 all_status = {}
130 all_status = {}
130 module_messages = json.loads(conf.module_messages)
131 module_messages = json.loads(conf.module_messages)
131
132
132 color_status = {}
133 color_status = {}
133 for i, status in enumerate(conf.module_status):
134 for i, status in enumerate(conf.module_status):
134 if status == '3': #Running background-color: #00cc00;
135 if status == '3': #Running background-color: #00cc00;
135 all_status['{}'.format(i+1)] = 2
136 all_status['{}'.format(i+1)] = 2
136 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':
139 all_status['{}'.format(i+1)] = 1
140 color_status['{}'.format(i+1)] = 'class=text-info'
137 elif status == '1': #Connected background-color: #ee902c;
141 elif status == '1': #Connected background-color: #ee902c;
138 all_status['{}'.format(i+1)] = 1
142 all_status['{}'.format(i+1)] = 1
139 color_status['{}'.format(i+1)] = 'class=text-warning'#'bgcolor=#ee902c'
143 color_status['{}'.format(i+1)] = 'class=text-warning'#'bgcolor=#ee902c'
140 else: #Disconnected background-color: #ff0000;
144 else: #Disconnected background-color: #ff0000;
141 all_status['{}'.format(i+1)] = 0
145 all_status['{}'.format(i+1)] = 0
142 color_status['{}'.format(i+1)] = 'class=text-danger'#'bgcolor=#FF0000'
146 color_status['{}'.format(i+1)] = 'class=text-danger'#'bgcolor=#FF0000'
143 #------------------------------------------------
147 #------------------------------------------------
144
148
145 kwargs = {}
149 kwargs = {}
146 kwargs['connected_modules'] = str(conf.connected_modules())+'/64'
150 kwargs['connected_modules'] = str(conf.connected_modules())+'/64'
147 kwargs['dev_conf'] = conf
151 kwargs['dev_conf'] = conf
148
152
149 if conf.operation_mode == 0:
153 if conf.operation_mode == 0:
150 kwargs['dev_conf_keys'] = ['label', 'operation_mode']
154 kwargs['dev_conf_keys'] = ['label', 'operation_mode']
151 else:
155 else:
152 kwargs['dev_conf_keys'] = ['label', 'operation_mode', 'operation_value']
156 kwargs['dev_conf_keys'] = ['label', 'operation_mode', 'operation_value']
153
157
154 kwargs['title'] = 'ABS Configuration'
158 kwargs['title'] = 'ABS Configuration'
155 kwargs['suptitle'] = 'Details'
159 kwargs['suptitle'] = 'Details'
156 kwargs['button'] = 'Edit Configuration'
160 kwargs['button'] = 'Edit Configuration'
157
161
158 if conf.active_beam != 0:
162 if conf.active_beam != 0:
159 kwargs['active_beam'] = int(conf.active_beam)
163 kwargs['active_beam'] = int(conf.active_beam)
160
164
161 kwargs['beams'] = beams
165 kwargs['beams'] = beams
162 kwargs['modules_status'] = all_status
166 kwargs['modules_status'] = all_status
163 kwargs['color_status'] = color_status
167 kwargs['color_status'] = color_status
164 kwargs['module_messages'] = module_messages
168 kwargs['module_messages'] = module_messages
165 ###### SIDEBAR ######
169 ###### SIDEBAR ######
166 kwargs.update(sidebar(conf=conf))
170 kwargs.update(sidebar(conf=conf))
167
171
168 return render(request, 'abs_conf.html', kwargs)
172 return render(request, 'abs_conf.html', kwargs)
169
173
170
174
171 def abs_conf_edit(request, id_conf):
175 def abs_conf_edit(request, id_conf):
172
176
173 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
177 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
174
178
175 beams = ABSBeam.objects.filter(abs_conf=conf)
179 beams = ABSBeam.objects.filter(abs_conf=conf)
176
180
177 if request.method=='GET':
181 if request.method=='GET':
178 form = ABSConfigurationForm(instance=conf)
182 form = ABSConfigurationForm(instance=conf)
179
183
180 if request.method=='POST':
184 if request.method=='POST':
181 form = ABSConfigurationForm(request.POST, instance=conf)
185 form = ABSConfigurationForm(request.POST, instance=conf)
182
186
183 if form.is_valid():
187 if form.is_valid():
184 conf = form.save(commit=False)
188 conf = form.save(commit=False)
185 conf.save()
189 conf.save()
186 return redirect('url_abs_conf', id_conf=conf.id)
190 return redirect('url_abs_conf', id_conf=conf.id)
187
191
188 ###### SIDEBAR ######
192 ###### SIDEBAR ######
189 kwargs = {}
193 kwargs = {}
190
194
191 kwargs['dev_conf'] = conf
195 kwargs['dev_conf'] = conf
192 #kwargs['id_dev'] = conf.id
196 #kwargs['id_dev'] = conf.id
193 kwargs['id_conf'] = conf.id
197 kwargs['id_conf'] = conf.id
194 kwargs['form'] = form
198 kwargs['form'] = form
195 kwargs['abs_beams'] = beams
199 kwargs['abs_beams'] = beams
196 kwargs['title'] = 'Device Configuration'
200 kwargs['title'] = 'Device Configuration'
197 kwargs['suptitle'] = 'Edit'
201 kwargs['suptitle'] = 'Edit'
198 kwargs['button'] = 'Save'
202 kwargs['button'] = 'Save'
199
203
200 kwargs['edit'] = True
204 kwargs['edit'] = True
201
205
202 return render(request, 'abs_conf_edit.html', kwargs)
206 return render(request, 'abs_conf_edit.html', kwargs)
203
207
204 @csrf_exempt
208 @csrf_exempt
205 def abs_conf_alert(request):
209 def abs_conf_alert(request):
206
210
207 if request.method == 'POST':
211 if request.method == 'POST':
208 print request.POST
212 print request.POST
209 return HttpResponse(json.dumps({'result':1}), content_type='application/json')
213 return HttpResponse(json.dumps({'result':1}), content_type='application/json')
210 else:
214 else:
211 return redirect('index')
215 return redirect('index')
212
216
213
217
214 def import_file(request, id_conf):
218 def import_file(request, id_conf):
215
219
216 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
220 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
217 if request.method=='POST':
221 if request.method=='POST':
218 form = ABSImportForm(request.POST, request.FILES)
222 form = ABSImportForm(request.POST, request.FILES)
219 if form.is_valid():
223 if form.is_valid():
220 try:
224 try:
221 parms = conf.import_from_file(request.FILES['file_name'])
225 parms = conf.import_from_file(request.FILES['file_name'])
222
226
223 if parms:
227 if parms:
224 conf.update_from_file(parms)
228 conf.update_from_file(parms)
225 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
229 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
226 return redirect(conf.get_absolute_url_edit())
230 return redirect(conf.get_absolute_url_edit())
227
231
228 except Exception as e:
232 except Exception as e:
229 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))
230
234
231 else:
235 else:
232 messages.warning(request, 'Your current configuration will be replaced')
236 messages.warning(request, 'Your current configuration will be replaced')
233 form = ABSImportForm()
237 form = ABSImportForm()
234
238
235 kwargs = {}
239 kwargs = {}
236 kwargs['form'] = form
240 kwargs['form'] = form
237 kwargs['title'] = 'ABS Configuration'
241 kwargs['title'] = 'ABS Configuration'
238 kwargs['suptitle'] = 'Import file'
242 kwargs['suptitle'] = 'Import file'
239 kwargs['button'] = 'Upload'
243 kwargs['button'] = 'Upload'
240 kwargs['previous'] = conf.get_absolute_url()
244 kwargs['previous'] = conf.get_absolute_url()
241
245
242 return render(request, 'abs_import.html', kwargs)
246 return render(request, 'abs_import.html', kwargs)
243
247
244
248
245 def send_beam(request, id_conf, id_beam):
249 def send_beam(request, id_conf, id_beam):
246
250
247 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
251 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
252
253 abs = request.user.profile.abs_active
254 if abs<>conf:
255 url = '#' if abs is None else abs.get_absolute_url()
256 label = 'None' if abs is None else abs.label
257 messages.warning(
258 request,
259 mark_safe('The current configuration has not been written in the modules, the active configuration is <a href="{}">{}</a>'.format(
260 url,
261 label
262 ))
263 )
264 return redirect(conf.get_absolute_url())
265
248 beam = get_object_or_404(ABSBeam, pk=id_beam)
266 beam = get_object_or_404(ABSBeam, pk=id_beam)
249 beams_list = ABSBeam.objects.filter(abs_conf=conf)
267 beams_list = ABSBeam.objects.filter(abs_conf=conf)
250 conf.active_beam = id_beam
268 conf.active_beam = id_beam
251
269
252 i = 0
270 i = 0
253 for b in beams_list:
271 for b in beams_list:
254 if b.id == int(id_beam):
272 if b.id == int(id_beam):
255 break
273 break
256 else:
274 else:
257 i += 1
275 i += 1
258 beam_pos = i + 1 #Estandarizar
276 beam_pos = i + 1 #Estandarizar
259 print '%s Position: %s' % (beam.name, str(beam_pos))
277 print '%s Position: %s' % (beam.name, str(beam_pos))
260 conf.send_beam(beam_pos)
278 conf.send_beam(beam_pos)
261
279
262 return redirect('url_abs_conf', conf.id)
280 return redirect('url_abs_conf', conf.id)
263
281
264
282
265 def add_beam(request, id_conf):
283 def add_beam(request, id_conf):
266
284
267 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
285 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
268 confs = Configuration.objects.all()
286 confs = Configuration.objects.all()
269
287
270 if request.method=='GET':
288 if request.method=='GET':
271 form = ABSBeamAddForm()
289 form = ABSBeamAddForm()
272
290
273 if request.method=='POST':
291 if request.method=='POST':
274 form = ABSBeamAddForm(request.POST)
292 form = ABSBeamAddForm(request.POST)
275
293
276 beam_data = get_values_from_form(request.POST)
294 beam_data = get_values_from_form(request.POST)
277
295
278 new_beam = ABSBeam(
296 new_beam = ABSBeam(
279 name = beam_data['name'],
297 name = beam_data['name'],
280 antenna = json.dumps(beam_data['antenna']),
298 antenna = json.dumps(beam_data['antenna']),
281 abs_conf = conf,
299 abs_conf = conf,
282 tx = json.dumps(beam_data['tx']),
300 tx = json.dumps(beam_data['tx']),
283 rx = json.dumps(beam_data['rx']),
301 rx = json.dumps(beam_data['rx']),
284 ues = json.dumps(beam_data['ues']),
302 ues = json.dumps(beam_data['ues']),
285 only_rx = json.dumps(beam_data['only_rx'])
303 only_rx = json.dumps(beam_data['only_rx'])
286 )
304 )
287 new_beam.save()
305 new_beam.save()
288 messages.success(request, 'Beam: "%s" has been added.' % new_beam.name)
306 messages.success(request, 'Beam: "%s" has been added.' % new_beam.name)
289
307
290 return redirect('url_edit_abs_conf', conf.id)
308 return redirect('url_edit_abs_conf', conf.id)
291
309
292 ###### SIDEBAR ######
310 ###### SIDEBAR ######
293 kwargs = {}
311 kwargs = {}
294
312
295 #kwargs['dev_conf'] = conf.device
313 #kwargs['dev_conf'] = conf.device
296 #kwargs['id_dev'] = conf.device
314 #kwargs['id_dev'] = conf.device
297 kwargs['id_conf'] = conf.id
315 kwargs['id_conf'] = conf.id
298 kwargs['form'] = form
316 kwargs['form'] = form
299 kwargs['title'] = 'ABS Beams'
317 kwargs['title'] = 'ABS Beams'
300 kwargs['suptitle'] = 'Add Beam'
318 kwargs['suptitle'] = 'Add Beam'
301 kwargs['button'] = 'Add'
319 kwargs['button'] = 'Add'
302 kwargs['no_sidebar'] = True
320 kwargs['no_sidebar'] = True
303
321
304 #kwargs['previous'] = conf.get_absolute_url_edit()
322 #kwargs['previous'] = conf.get_absolute_url_edit()
305 kwargs['edit'] = True
323 kwargs['edit'] = True
306
324
307 return render(request, 'abs_add_beam.html', kwargs)
325 return render(request, 'abs_add_beam.html', kwargs)
308
326
309
327
310 def edit_beam(request, id_conf, id_beam):
328 def edit_beam(request, id_conf, id_beam):
311
329
312 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
330 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
313 beam = get_object_or_404(ABSBeam, pk=id_beam)
331 beam = get_object_or_404(ABSBeam, pk=id_beam)
314
332
315 if request.method=='GET':
333 if request.method=='GET':
316 form = ABSBeamEditForm(initial={'beam': beam})
334 form = ABSBeamEditForm(initial={'beam': beam})
317
335
318 if request.method=='POST':
336 if request.method=='POST':
319 form = ABSBeamEditForm(request.POST)
337 form = ABSBeamEditForm(request.POST)
320
338
321 beam_data = get_values_from_form(request.POST)
339 beam_data = get_values_from_form(request.POST)
322
340
323 beam.dict_to_parms(beam_data)
341 beam.dict_to_parms(beam_data)
324 beam.save()
342 beam.save()
325
343
326 messages.success(request, 'Beam: "%s" has been updated.' % beam.name)
344 messages.success(request, 'Beam: "%s" has been updated.' % beam.name)
327
345
328 return redirect('url_edit_abs_conf', conf.id)
346 return redirect('url_edit_abs_conf', conf.id)
329
347
330 ###### SIDEBAR ######
348 ###### SIDEBAR ######
331 kwargs = {}
349 kwargs = {}
332
350
333 kwargs['id_conf'] = conf.id
351 kwargs['id_conf'] = conf.id
334 kwargs['form'] = form
352 kwargs['form'] = form
335 kwargs['title'] = 'ABS Beams'
353 kwargs['title'] = 'ABS Beams'
336 kwargs['suptitle'] = 'Edit Beam'
354 kwargs['suptitle'] = 'Edit Beam'
337 kwargs['button'] = 'Save'
355 kwargs['button'] = 'Save'
338 kwargs['no_sidebar'] = True
356 kwargs['no_sidebar'] = True
339
357
340 #kwargs['previous'] = conf.get_absolute_url_edit()
358 #kwargs['previous'] = conf.get_absolute_url_edit()
341 kwargs['edit'] = True
359 kwargs['edit'] = True
342
360
343 return render(request, 'abs_edit_beam.html', kwargs)
361 return render(request, 'abs_edit_beam.html', kwargs)
344
362
345
363
346
364
347 def remove_beam(request, id_conf, id_beam):
365 def remove_beam(request, id_conf, id_beam):
348
366
349 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
367 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
350 beam = get_object_or_404(ABSBeam, pk=id_beam)
368 beam = get_object_or_404(ABSBeam, pk=id_beam)
351
369
352 if request.method=='POST':
370 if request.method=='POST':
353 if beam:
371 if beam:
354 try:
372 try:
355 beam.delete()
373 beam.delete()
356 messages.success(request, 'Beam: "%s" has been deleted.' % beam)
374 messages.success(request, 'Beam: "%s" has been deleted.' % beam)
357 except:
375 except:
358 messages.error(request, 'Unable to delete beam: "%s".' % beam)
376 messages.error(request, 'Unable to delete beam: "%s".' % beam)
359
377
360 return redirect('url_edit_abs_conf', conf.id)
378 return redirect('url_edit_abs_conf', conf.id)
361
379
362 ###### SIDEBAR ######
380 ###### SIDEBAR ######
363 kwargs = {}
381 kwargs = {}
364
382
365 kwargs['object'] = beam
383 kwargs['object'] = beam
366 kwargs['delete'] = True
384 kwargs['delete'] = True
367 kwargs['title'] = 'Delete'
385 kwargs['title'] = 'Delete'
368 kwargs['suptitle'] = 'Beam'
386 kwargs['suptitle'] = 'Beam'
369 kwargs['previous'] = conf.get_absolute_url_edit()
387 kwargs['previous'] = conf.get_absolute_url_edit()
370 return render(request, 'confirm.html', kwargs)
388 return render(request, 'confirm.html', kwargs)
371
389
372
390
373
391
374 def plot_patterns(request, id_conf, id_beam=None):
392 def plot_patterns(request, id_conf, id_beam=None):
375
393
376 kwargs = {}
394 kwargs = {}
377 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
395 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
378 beams = ABSBeam.objects.filter(abs_conf=conf)
396 beams = ABSBeam.objects.filter(abs_conf=conf)
379
397
380 if id_beam:
398 if id_beam:
381 beam = get_object_or_404(ABSBeam, pk=id_beam)
399 beam = get_object_or_404(ABSBeam, pk=id_beam)
382 kwargs['beam'] = beam
400 kwargs['beam'] = beam
383
401
384 ###### SIDEBAR ######
402 ###### SIDEBAR ######
385
403
386 kwargs['dev_conf'] = conf.device
404 kwargs['dev_conf'] = conf.device
387 kwargs['id_dev'] = conf.device
405 kwargs['id_dev'] = conf.device
388 kwargs['id_conf'] = conf.id
406 kwargs['id_conf'] = conf.id
389 kwargs['abs_beams'] = beams
407 kwargs['abs_beams'] = beams
390 kwargs['title'] = 'ABS Patterns'
408 kwargs['title'] = 'ABS Patterns'
391 kwargs['suptitle'] = conf.name
409 kwargs['suptitle'] = conf.name
392 kwargs['no_sidebar'] = True
410 kwargs['no_sidebar'] = True
393
411
394 return render(request, 'abs_patterns.html', kwargs)
412 return render(request, 'abs_patterns.html', kwargs)
395
413
396
414
397 def plot_pattern(request, id_conf, id_beam, antenna):
415 def plot_pattern(request, id_conf, id_beam, antenna):
398
416
399 if antenna=='down':
417 if antenna=='down':
400 sleep(3)
418 sleep(3)
401
419
402 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
420 conf = get_object_or_404(ABSConfiguration, pk=id_conf)
403 beam = get_object_or_404(ABSBeam, pk=id_beam)
421 beam = get_object_or_404(ABSBeam, pk=id_beam)
404 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
405 phases = json.loads(beam.antenna)['antenna_{}'.format(antenna)]
423 phases = json.loads(beam.antenna)['antenna_{}'.format(antenna)]
406 gain_tx = json.loads(beam.tx)[antenna]
424 gain_tx = json.loads(beam.tx)[antenna]
407 gain_rx = json.loads(beam.rx)[antenna]
425 gain_rx = json.loads(beam.rx)[antenna]
408 ues = json.loads(beam.ues)[antenna]
426 ues = json.loads(beam.ues)[antenna]
409 newOverJro = overJroShow(beam.name)
427 newOverJro = overJroShow(beam.name)
410 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)
411 buf = io.BytesIO()
429 buf = io.BytesIO()
412 fig.savefig(buf, format='png')
430 fig.savefig(buf, format='png')
413 response = HttpResponse(buf.getvalue(), content_type='image/png')
431 response = HttpResponse(buf.getvalue(), content_type='image/png')
414 return response
432 return response
415
433
@@ -1,122 +1,130
1 [
1 [
2 {
2 {
3 "fields": {
3 "fields": {
4 "name": "JRO",
4 "name": "JRO",
5 "description": ""
5 "description": ""
6 },
6 },
7 "model": "main.location",
7 "model": "main.location",
8 "pk": 1
8 "pk": 1
9 },
9 },
10 {
10 {
11 "fields": {
11 "fields": {
12 "name": "JASMET",
12 "name": "JASMET",
13 "description": ""
13 "description": ""
14 },
14 },
15 "model": "main.location",
15 "model": "main.location",
16 "pk": 2
16 "pk": 2
17 },
17 },
18 {
18 {
19 "fields": {
19 "fields": {
20 "name": "SOUSY",
20 "name": "SOUSY",
21 "description": ""
21 "description": ""
22 },
22 },
23 "model": "main.location",
23 "model": "main.location",
24 "pk": 3
24 "pk": 3
25 },
25 },
26 {
26 {
27 "fields": {
27 "fields": {
28 "name": "JULIA",
28 "name": "JULIA",
29 "description": ""
29 "description": ""
30 },
30 },
31 "model": "main.location",
31 "model": "main.location",
32 "pk": 4
32 "pk": 4
33 },
33 },
34 {
34 {
35 "fields": {
35 "fields": {
36 "name": "CLAIRE",
36 "name": "CLAIRE",
37 "description": ""
37 "description": ""
38 },
38 },
39 "model": "main.location",
39 "model": "main.location",
40 "pk": 5
40 "pk": 5
41 },
41 },
42 {
42 {
43 "fields": {
43 "fields": {
44 "name": "IDI",
44 "name": "IDI",
45 "description": ""
45 "description": ""
46 },
46 },
47 "model": "main.location",
47 "model": "main.location",
48 "pk": 6
48 "pk": 6
49 },
49 },
50 {
50 {
51 "fields": {
51 "fields": {
52 "name": "rc",
52 "name": "rc",
53 "description": ""
53 "description": ""
54 },
54 },
55 "model": "main.devicetype",
55 "model": "main.devicetype",
56 "pk": 1
56 "pk": 1
57 },
57 },
58 {
58 {
59 "fields": {
59 "fields": {
60 "name": "dds",
60 "name": "dds",
61 "description": ""
61 "description": ""
62 },
62 },
63 "model": "main.devicetype",
63 "model": "main.devicetype",
64 "pk": 2
64 "pk": 2
65 },
65 },
66 {
66 {
67 "fields": {
67 "fields": {
68 "name": "cgs",
68 "name": "cgs",
69 "description": ""
69 "description": ""
70 },
70 },
71 "model": "main.devicetype",
71 "model": "main.devicetype",
72 "pk": 3
72 "pk": 3
73 },
73 },
74 {
74 {
75 "fields": {
75 "fields": {
76 "name": "jars",
76 "name": "jars",
77 "description": ""
77 "description": ""
78 },
78 },
79 "model": "main.devicetype",
79 "model": "main.devicetype",
80 "pk": 4
80 "pk": 4
81 },
81 },
82 {
82 {
83 "fields": {
83 "fields": {
84 "name": "abs",
84 "name": "abs",
85 "description": ""
85 "description": ""
86 },
86 },
87 "model": "main.devicetype",
87 "model": "main.devicetype",
88 "pk": 5
88 "pk": 5
89 },
89 },
90 {
90 {
91 "fields": {
91 "fields": {
92 "name": "Operator"
92 "name": "Operator"
93 },
93 },
94 "model": "auth.group",
94 "model": "auth.group",
95 "pk": 1
95 "pk": 1
96 },
96 },
97 {
97 {
98 "fields": {
98 "fields": {
99 "name": "Developer"
99 "name": "Developer"
100 },
100 },
101 "model": "auth.group",
101 "model": "auth.group",
102 "pk": 2
102 "pk": 2
103 },
103 },
104 {
104 {
105 "fields": {
105 "fields": {
106 "password": "pbkdf2_sha256$24000$6RRL7xETgdgN$ORRPhrITZKzTTZHCm8T+Er6ght415kYKeU7QP3rry5M=",
106 "password": "pbkdf2_sha256$24000$6RRL7xETgdgN$ORRPhrITZKzTTZHCm8T+Er6ght415kYKeU7QP3rry5M=",
107 "last_login": null,
107 "last_login": null,
108 "is_superuser": true,
108 "is_superuser": true,
109 "username": "admin",
109 "username": "admin",
110 "first_name": "Administrador",
110 "first_name": "Administrador",
111 "last_name": "IDI",
111 "last_name": "IDI",
112 "email": "admin@admin.com",
112 "email": "admin@admin.com",
113 "is_staff": true,
113 "is_staff": true,
114 "is_active": true,
114 "is_active": true,
115 "date_joined": "2017-01-12T16:10:24.383",
115 "date_joined": "2017-01-12T16:10:24.383",
116 "groups": [],
116 "groups": [],
117 "user_permissions": []
117 "user_permissions": []
118 },
118 },
119 "model": "auth.user",
119 "model": "auth.user",
120 "pk": 1
120 "pk": 1
121 },
122 {
123 "fields": {
124 "user": 1,
125 "theme": "spacelab"
126 },
127 "model": "main.profile",
128 "pk": 1
121 }
129 }
122 ] No newline at end of file
130 ]
@@ -1,809 +1,811
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,'Configured'), #BLUE
79 (2,'Running'), #GREEN
79 (2,'Running'), #GREEN
80 (3,'Scheduled'), #YELLOW
80 (3,'Scheduled'), #YELLOW
81 (4,'Not Configured'), #WHITE
81 (4,'Not Configured'), #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='yeti')
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 @receiver(post_save, sender=User)
95 @receiver(post_save, sender=User)
94 def create_user_profile(sender, instance, created, **kwargs):
96 def create_user_profile(sender, instance, created, **kwargs):
95 if created:
97 if created:
96 Profile.objects.create(user=instance)
98 Profile.objects.create(user=instance)
97
99
98 @receiver(post_save, sender=User)
100 @receiver(post_save, sender=User)
99 def save_user_profile(sender, instance, **kwargs):
101 def save_user_profile(sender, instance, **kwargs):
100 instance.profile.save()
102 instance.profile.save()
101
103
102
104
103 class Location(models.Model):
105 class Location(models.Model):
104
106
105 name = models.CharField(max_length = 30)
107 name = models.CharField(max_length = 30)
106 description = models.TextField(blank=True, null=True)
108 description = models.TextField(blank=True, null=True)
107
109
108 class Meta:
110 class Meta:
109 db_table = 'db_location'
111 db_table = 'db_location'
110
112
111 def __str__(self):
113 def __str__(self):
112 return u'%s' % self.name
114 return u'%s' % self.name
113
115
114 def get_absolute_url(self):
116 def get_absolute_url(self):
115 return reverse('url_location', args=[str(self.id)])
117 return reverse('url_location', args=[str(self.id)])
116
118
117
119
118 class DeviceType(models.Model):
120 class DeviceType(models.Model):
119
121
120 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc')
122 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc')
121 sequence = models.PositiveSmallIntegerField(default=1000)
123 sequence = models.PositiveSmallIntegerField(default=1000)
122 description = models.TextField(blank=True, null=True)
124 description = models.TextField(blank=True, null=True)
123
125
124 class Meta:
126 class Meta:
125 db_table = 'db_device_types'
127 db_table = 'db_device_types'
126
128
127 def __str__(self):
129 def __str__(self):
128 return u'%s' % self.get_name_display()
130 return u'%s' % self.get_name_display()
129
131
130 class Device(models.Model):
132 class Device(models.Model):
131
133
132 device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
134 device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
133 location = models.ForeignKey(Location, on_delete=models.CASCADE)
135 location = models.ForeignKey(Location, on_delete=models.CASCADE)
134 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
136 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
135 port_address = models.PositiveSmallIntegerField(default=2000)
137 port_address = models.PositiveSmallIntegerField(default=2000)
136 description = models.TextField(blank=True, null=True)
138 description = models.TextField(blank=True, null=True)
137 status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES)
139 status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES)
138
140
139 class Meta:
141 class Meta:
140 db_table = 'db_devices'
142 db_table = 'db_devices'
141
143
142 def __str__(self):
144 def __str__(self):
143 ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
145 ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
144
146
145 return ret
147 return ret
146
148
147 @property
149 @property
148 def name(self):
150 def name(self):
149 return str(self)
151 return str(self)
150
152
151 def get_status(self):
153 def get_status(self):
152 return self.status
154 return self.status
153
155
154 @property
156 @property
155 def status_color(self):
157 def status_color(self):
156 color = 'muted'
158 color = 'muted'
157 if self.status == 0:
159 if self.status == 0:
158 color = "danger"
160 color = "danger"
159 elif self.status == 1:
161 elif self.status == 1:
160 color = "warning"
162 color = "warning"
161 elif self.status == 2:
163 elif self.status == 2:
162 color = "info"
164 color = "info"
163 elif self.status == 3:
165 elif self.status == 3:
164 color = "success"
166 color = "success"
165
167
166 return color
168 return color
167
169
168 def url(self, path=None):
170 def url(self, path=None):
169
171
170 if path:
172 if path:
171 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
173 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
172 else:
174 else:
173 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
175 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
174
176
175 def get_absolute_url(self):
177 def get_absolute_url(self):
176 return reverse('url_device', args=[str(self.id)])
178 return reverse('url_device', args=[str(self.id)])
177
179
178 def get_absolute_url_edit(self):
180 def get_absolute_url_edit(self):
179 return reverse('url_edit_device', args=[str(self.id)])
181 return reverse('url_edit_device', args=[str(self.id)])
180
182
181 def get_absolute_url_delete(self):
183 def get_absolute_url_delete(self):
182 return reverse('url_delete_device', args=[str(self.id)])
184 return reverse('url_delete_device', args=[str(self.id)])
183
185
184 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
186 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
185
187
186 if self.device_type.name=='dds':
188 if self.device_type.name=='dds':
187 try:
189 try:
188 answer = dds_api.change_ip(ip = self.ip_address,
190 answer = dds_api.change_ip(ip = self.ip_address,
189 port = self.port_address,
191 port = self.port_address,
190 new_ip = ip_address,
192 new_ip = ip_address,
191 mask = mask,
193 mask = mask,
192 gateway = gateway)
194 gateway = gateway)
193 if answer[0]=='1':
195 if answer[0]=='1':
194 self.message = '25|DDS - {}'.format(answer)
196 self.message = '25|DDS - {}'.format(answer)
195 self.ip_address = ip_address
197 self.ip_address = ip_address
196 self.save()
198 self.save()
197 else:
199 else:
198 self.message = '30|DDS - {}'.format(answer)
200 self.message = '30|DDS - {}'.format(answer)
199 return False
201 return False
200 except Exception as e:
202 except Exception as e:
201 self.message = '40|{}'.format(str(e))
203 self.message = '40|{}'.format(str(e))
202 return False
204 return False
203
205
204 elif self.device_type.name=='rc':
206 elif self.device_type.name=='rc':
205 headers = {'content-type': "application/json",
207 headers = {'content-type': "application/json",
206 'cache-control': "no-cache"}
208 'cache-control': "no-cache"}
207
209
208 ip = [int(x) for x in ip_address.split('.')]
210 ip = [int(x) for x in ip_address.split('.')]
209 dns = [int(x) for x in dns.split('.')]
211 dns = [int(x) for x in dns.split('.')]
210 gateway = [int(x) for x in gateway.split('.')]
212 gateway = [int(x) for x in gateway.split('.')]
211 subnet = [int(x) for x in mask.split('.')]
213 subnet = [int(x) for x in mask.split('.')]
212
214
213 payload = {
215 payload = {
214 "ip": ip,
216 "ip": ip,
215 "dns": dns,
217 "dns": dns,
216 "gateway": gateway,
218 "gateway": gateway,
217 "subnet": subnet
219 "subnet": subnet
218 }
220 }
219
221
220 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)
221 try:
223 try:
222 answer = req.json()
224 answer = req.json()
223 if answer['changeip']=='ok':
225 if answer['changeip']=='ok':
224 self.message = '25|IP succesfully changed'
226 self.message = '25|IP succesfully changed'
225 self.ip_address = ip_address
227 self.ip_address = ip_address
226 self.save()
228 self.save()
227 else:
229 else:
228 self.message = '30|An error ocuur when changing IP'
230 self.message = '30|An error ocuur when changing IP'
229 except Exception as e:
231 except Exception as e:
230 self.message = '40|{}'.format(str(e))
232 self.message = '40|{}'.format(str(e))
231 else:
233 else:
232 self.message = 'Not implemented'
234 self.message = 'Not implemented'
233 return False
235 return False
234
236
235 return True
237 return True
236
238
237
239
238 class Campaign(models.Model):
240 class Campaign(models.Model):
239
241
240 template = models.BooleanField(default=False)
242 template = models.BooleanField(default=False)
241 name = models.CharField(max_length=60, unique=True)
243 name = models.CharField(max_length=60, unique=True)
242 start_date = models.DateTimeField(blank=True, null=True)
244 start_date = models.DateTimeField(blank=True, null=True)
243 end_date = models.DateTimeField(blank=True, null=True)
245 end_date = models.DateTimeField(blank=True, null=True)
244 tags = models.CharField(max_length=40, blank=True, null=True)
246 tags = models.CharField(max_length=40, blank=True, null=True)
245 description = models.TextField(blank=True, null=True)
247 description = models.TextField(blank=True, null=True)
246 experiments = models.ManyToManyField('Experiment', blank=True)
248 experiments = models.ManyToManyField('Experiment', blank=True)
247 author = models.ForeignKey(User, null=True, blank=True)
249 author = models.ForeignKey(User, null=True, blank=True)
248
250
249 class Meta:
251 class Meta:
250 db_table = 'db_campaigns'
252 db_table = 'db_campaigns'
251 ordering = ('name',)
253 ordering = ('name',)
252
254
253 def __str__(self):
255 def __str__(self):
254 if self.template:
256 if self.template:
255 return u'{} (template)'.format(self.name)
257 return u'{} (template)'.format(self.name)
256 else:
258 else:
257 return u'{}'.format(self.name)
259 return u'{}'.format(self.name)
258
260
259 def jsonify(self):
261 def jsonify(self):
260
262
261 data = {}
263 data = {}
262
264
263 ignored = ('template')
265 ignored = ('template')
264
266
265 for field in self._meta.fields:
267 for field in self._meta.fields:
266 if field.name in ignored:
268 if field.name in ignored:
267 continue
269 continue
268 data[field.name] = field.value_from_object(self)
270 data[field.name] = field.value_from_object(self)
269
271
270 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
272 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
271 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
273 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
272
274
273 return data
275 return data
274
276
275 def parms_to_dict(self):
277 def parms_to_dict(self):
276
278
277 params = Params({})
279 params = Params({})
278 params.add(self.jsonify(), 'campaigns')
280 params.add(self.jsonify(), 'campaigns')
279
281
280 for exp in Experiment.objects.filter(campaign = self):
282 for exp in Experiment.objects.filter(campaign = self):
281 params.add(exp.jsonify(), 'experiments')
283 params.add(exp.jsonify(), 'experiments')
282 configurations = Configuration.objects.filter(experiment=exp, type=0)
284 configurations = Configuration.objects.filter(experiment=exp, type=0)
283
285
284 for conf in configurations:
286 for conf in configurations:
285 params.add(conf.jsonify(), 'configurations')
287 params.add(conf.jsonify(), 'configurations')
286 if conf.device.device_type.name=='rc':
288 if conf.device.device_type.name=='rc':
287 for line in conf.get_lines():
289 for line in conf.get_lines():
288 params.add(line.jsonify(), 'lines')
290 params.add(line.jsonify(), 'lines')
289
291
290 return params.data
292 return params.data
291
293
292 def dict_to_parms(self, parms, CONF_MODELS):
294 def dict_to_parms(self, parms, CONF_MODELS):
293
295
294 experiments = Experiment.objects.filter(campaign = self)
296 experiments = Experiment.objects.filter(campaign = self)
295
297
296 if experiments:
298 if experiments:
297 for experiment in experiments:
299 for experiment in experiments:
298 experiment.delete()
300 experiment.delete()
299
301
300 for id_exp in parms['experiments']['allIds']:
302 for id_exp in parms['experiments']['allIds']:
301 exp_parms = parms['experiments']['byId'][id_exp]
303 exp_parms = parms['experiments']['byId'][id_exp]
302 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
304 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
303 exp = Experiment(name='{}'.format(dum))
305 exp = Experiment(name='{}'.format(dum))
304 exp.save()
306 exp.save()
305 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
307 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
306 self.experiments.add(exp)
308 self.experiments.add(exp)
307
309
308 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
310 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
309
311
310 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'))
311 self.start_date = camp_parms['start_date']
313 self.start_date = camp_parms['start_date']
312 self.end_date = camp_parms['end_date']
314 self.end_date = camp_parms['end_date']
313 self.tags = camp_parms['tags']
315 self.tags = camp_parms['tags']
314 self.save()
316 self.save()
315
317
316 return self
318 return self
317
319
318 def get_experiments_by_radar(self, radar=None):
320 def get_experiments_by_radar(self, radar=None):
319
321
320 ret = []
322 ret = []
321 if radar:
323 if radar:
322 locations = Location.objects.filter(pk=radar)
324 locations = Location.objects.filter(pk=radar)
323 else:
325 else:
324 locations = set([e.location for e in self.experiments.all()])
326 locations = set([e.location for e in self.experiments.all()])
325
327
326 for loc in locations:
328 for loc in locations:
327 dum = {}
329 dum = {}
328 dum['name'] = loc.name
330 dum['name'] = loc.name
329 dum['id'] = loc.pk
331 dum['id'] = loc.pk
330 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]
331 ret.append(dum)
333 ret.append(dum)
332
334
333 return ret
335 return ret
334
336
335 def get_absolute_url(self):
337 def get_absolute_url(self):
336 return reverse('url_campaign', args=[str(self.id)])
338 return reverse('url_campaign', args=[str(self.id)])
337
339
338 def get_absolute_url_edit(self):
340 def get_absolute_url_edit(self):
339 return reverse('url_edit_campaign', args=[str(self.id)])
341 return reverse('url_edit_campaign', args=[str(self.id)])
340
342
341 def get_absolute_url_delete(self):
343 def get_absolute_url_delete(self):
342 return reverse('url_delete_campaign', args=[str(self.id)])
344 return reverse('url_delete_campaign', args=[str(self.id)])
343
345
344 def get_absolute_url_export(self):
346 def get_absolute_url_export(self):
345 return reverse('url_export_campaign', args=[str(self.id)])
347 return reverse('url_export_campaign', args=[str(self.id)])
346
348
347 def get_absolute_url_import(self):
349 def get_absolute_url_import(self):
348 return reverse('url_import_campaign', args=[str(self.id)])
350 return reverse('url_import_campaign', args=[str(self.id)])
349
351
350
352
351 class RunningExperiment(models.Model):
353 class RunningExperiment(models.Model):
352 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
354 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
353 running_experiment = models.ManyToManyField('Experiment', blank = True)
355 running_experiment = models.ManyToManyField('Experiment', blank = True)
354 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
356 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
355
357
356
358
357 class Experiment(models.Model):
359 class Experiment(models.Model):
358
360
359 template = models.BooleanField(default=False)
361 template = models.BooleanField(default=False)
360 name = models.CharField(max_length=40, default='', unique=True)
362 name = models.CharField(max_length=40, default='', unique=True)
361 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)
362 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)
363 start_time = models.TimeField(default='00:00:00')
365 start_time = models.TimeField(default='00:00:00')
364 end_time = models.TimeField(default='23:59:59')
366 end_time = models.TimeField(default='23:59:59')
365 task = models.CharField(max_length=36, default='', blank=True, null=True)
367 task = models.CharField(max_length=36, default='', blank=True, null=True)
366 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
368 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
367 author = models.ForeignKey(User, null=True, blank=True)
369 author = models.ForeignKey(User, null=True, blank=True)
368 hash = models.CharField(default='', max_length=64, null=True, blank=True)
370 hash = models.CharField(default='', max_length=64, null=True, blank=True)
369
371
370 class Meta:
372 class Meta:
371 db_table = 'db_experiments'
373 db_table = 'db_experiments'
372 ordering = ('template', 'name')
374 ordering = ('template', 'name')
373
375
374 def __str__(self):
376 def __str__(self):
375 if self.template:
377 if self.template:
376 return u'%s (template)' % (self.name)
378 return u'%s (template)' % (self.name)
377 else:
379 else:
378 return u'%s' % (self.name)
380 return u'%s' % (self.name)
379
381
380 def jsonify(self):
382 def jsonify(self):
381
383
382 data = {}
384 data = {}
383
385
384 ignored = ('template')
386 ignored = ('template')
385
387
386 for field in self._meta.fields:
388 for field in self._meta.fields:
387 if field.name in ignored:
389 if field.name in ignored:
388 continue
390 continue
389 data[field.name] = field.value_from_object(self)
391 data[field.name] = field.value_from_object(self)
390
392
391 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
393 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
392 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
394 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
393 data['location'] = self.location.name
395 data['location'] = self.location.name
394 data['configurations'] = ['{}'.format(conf.pk) for
396 data['configurations'] = ['{}'.format(conf.pk) for
395 conf in Configuration.objects.filter(experiment=self, type=0)]
397 conf in Configuration.objects.filter(experiment=self, type=0)]
396
398
397 return data
399 return data
398
400
399 @property
401 @property
400 def radar_system(self):
402 def radar_system(self):
401 return self.location
403 return self.location
402
404
403 def clone(self, **kwargs):
405 def clone(self, **kwargs):
404
406
405 confs = Configuration.objects.filter(experiment=self, type=0)
407 confs = Configuration.objects.filter(experiment=self, type=0)
406 self.pk = None
408 self.pk = None
407 self.name = '{}_{:%y%m%d}'.format(self.name, datetime.now())
409 self.name = '{}_{:%y%m%d}'.format(self.name, datetime.now())
408 for attr, value in kwargs.items():
410 for attr, value in kwargs.items():
409 setattr(self, attr, value)
411 setattr(self, attr, value)
410
412
411 self.save()
413 self.save()
412
414
413 for conf in confs:
415 for conf in confs:
414 conf.clone(experiment=self, template=False)
416 conf.clone(experiment=self, template=False)
415
417
416 return self
418 return self
417
419
418 def start(self):
420 def start(self):
419 '''
421 '''
420 Configure and start experiments's devices
422 Configure and start experiments's devices
421 ABS-CGS-DDS-RC-JARS
423 ABS-CGS-DDS-RC-JARS
422 '''
424 '''
423
425
424 result = 2
426 result = 2
425 confs = []
427 confs = []
426 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
428 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
427 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix]
429 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix]
428 if rc_mix:
430 if rc_mix:
429 for conf in allconfs:
431 for conf in allconfs:
430 if conf.device.device_type.name == 'rc' and not conf.mix:
432 if conf.device.device_type.name == 'rc' and not conf.mix:
431 continue
433 continue
432 confs.append(conf)
434 confs.append(conf)
433 else:
435 else:
434 confs = allconfs
436 confs = allconfs
435 #Only Configured Devices.
437 #Only Configured Devices.
436 for conf in confs:
438 for conf in confs:
437 if conf.device.status in (0, 4):
439 if conf.device.status in (0, 4):
438 result = 0
440 result = 0
439 return result
441 return result
440 for conf in confs:
442 for conf in confs:
441 conf.stop_device()
443 conf.stop_device()
442 conf.write_device()
444 conf.write_device()
443 conf.start_device()
445 conf.start_device()
444 time.sleep(1)
446 time.sleep(1)
445
447
446 return result
448 return result
447
449
448
450
449 def stop(self):
451 def stop(self):
450 '''
452 '''
451 Stop experiments's devices
453 Stop experiments's devices
452 DDS-JARS-RC-CGS-ABS
454 DDS-JARS-RC-CGS-ABS
453 '''
455 '''
454
456
455 result = 1
457 result = 1
456
458
457 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
459 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
458 confs=confs.exclude(device__device_type__name='cgs')
460 confs=confs.exclude(device__device_type__name='cgs')
459 for conf in confs:
461 for conf in confs:
460 if conf.device.status in (0, 4):
462 if conf.device.status in (0, 4):
461 result = 0
463 result = 0
462 continue
464 continue
463 conf.stop_device()
465 conf.stop_device()
464
466
465 return result
467 return result
466
468
467
469
468 def get_status(self):
470 def get_status(self):
469
471
470 if self.status == 3:
472 if self.status == 3:
471 return
473 return
472
474
473 confs = Configuration.objects.filter(experiment=self, type=0)
475 confs = Configuration.objects.filter(experiment=self, type=0)
474
476
475 for conf in confs:
477 for conf in confs:
476 conf.status_device()
478 conf.status_device()
477
479
478 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
480 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
479
481
480 if total==2*confs.count():
482 if total==2*confs.count():
481 status = 1
483 status = 1
482 elif total == 3*confs.count():
484 elif total == 3*confs.count():
483 status = 2
485 status = 2
484 else:
486 else:
485 status = 0
487 status = 0
486
488
487 self.status = status
489 self.status = status
488 self.save()
490 self.save()
489
491
490 def status_color(self):
492 def status_color(self):
491 color = 'muted'
493 color = 'muted'
492 if self.status == 0:
494 if self.status == 0:
493 color = "danger"
495 color = "danger"
494 elif self.status == 1:
496 elif self.status == 1:
495 color = "info"
497 color = "info"
496 elif self.status == 2:
498 elif self.status == 2:
497 color = "success"
499 color = "success"
498 elif self.status == 3:
500 elif self.status == 3:
499 color = "warning"
501 color = "warning"
500
502
501 return color
503 return color
502
504
503 def parms_to_dict(self):
505 def parms_to_dict(self):
504
506
505 params = Params({})
507 params = Params({})
506 params.add(self.jsonify(), 'experiments')
508 params.add(self.jsonify(), 'experiments')
507
509
508 configurations = Configuration.objects.filter(experiment=self, type=0)
510 configurations = Configuration.objects.filter(experiment=self, type=0)
509
511
510 for conf in configurations:
512 for conf in configurations:
511 params.add(conf.jsonify(), 'configurations')
513 params.add(conf.jsonify(), 'configurations')
512 if conf.device.device_type.name=='rc':
514 if conf.device.device_type.name=='rc':
513 for line in conf.get_lines():
515 for line in conf.get_lines():
514 params.add(line.jsonify(), 'lines')
516 params.add(line.jsonify(), 'lines')
515
517
516 return params.data
518 return params.data
517
519
518 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
520 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
519
521
520 configurations = Configuration.objects.filter(experiment=self)
522 configurations = Configuration.objects.filter(experiment=self)
521
523
522 if id_exp is not None:
524 if id_exp is not None:
523 exp_parms = parms['experiments']['byId'][id_exp]
525 exp_parms = parms['experiments']['byId'][id_exp]
524 else:
526 else:
525 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
527 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
526
528
527 if configurations:
529 if configurations:
528 for configuration in configurations:
530 for configuration in configurations:
529 configuration.delete()
531 configuration.delete()
530
532
531 for id_conf in exp_parms['configurations']:
533 for id_conf in exp_parms['configurations']:
532 conf_parms = parms['configurations']['byId'][id_conf]
534 conf_parms = parms['configurations']['byId'][id_conf]
533 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
535 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
534 model = CONF_MODELS[conf_parms['device_type']]
536 model = CONF_MODELS[conf_parms['device_type']]
535 conf = model(
537 conf = model(
536 experiment = self,
538 experiment = self,
537 device = device,
539 device = device,
538 )
540 )
539 conf.dict_to_parms(parms, id=id_conf)
541 conf.dict_to_parms(parms, id=id_conf)
540
542
541
543
542 location, created = Location.objects.get_or_create(name=exp_parms['location'])
544 location, created = Location.objects.get_or_create(name=exp_parms['location'])
543 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
545 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
544 self.location = location
546 self.location = location
545 self.start_time = exp_parms['start_time']
547 self.start_time = exp_parms['start_time']
546 self.end_time = exp_parms['end_time']
548 self.end_time = exp_parms['end_time']
547 self.save()
549 self.save()
548
550
549 return self
551 return self
550
552
551 def get_absolute_url(self):
553 def get_absolute_url(self):
552 return reverse('url_experiment', args=[str(self.id)])
554 return reverse('url_experiment', args=[str(self.id)])
553
555
554 def get_absolute_url_edit(self):
556 def get_absolute_url_edit(self):
555 return reverse('url_edit_experiment', args=[str(self.id)])
557 return reverse('url_edit_experiment', args=[str(self.id)])
556
558
557 def get_absolute_url_delete(self):
559 def get_absolute_url_delete(self):
558 return reverse('url_delete_experiment', args=[str(self.id)])
560 return reverse('url_delete_experiment', args=[str(self.id)])
559
561
560 def get_absolute_url_import(self):
562 def get_absolute_url_import(self):
561 return reverse('url_import_experiment', args=[str(self.id)])
563 return reverse('url_import_experiment', args=[str(self.id)])
562
564
563 def get_absolute_url_export(self):
565 def get_absolute_url_export(self):
564 return reverse('url_export_experiment', args=[str(self.id)])
566 return reverse('url_export_experiment', args=[str(self.id)])
565
567
566 def get_absolute_url_start(self):
568 def get_absolute_url_start(self):
567 return reverse('url_start_experiment', args=[str(self.id)])
569 return reverse('url_start_experiment', args=[str(self.id)])
568
570
569 def get_absolute_url_stop(self):
571 def get_absolute_url_stop(self):
570 return reverse('url_stop_experiment', args=[str(self.id)])
572 return reverse('url_stop_experiment', args=[str(self.id)])
571
573
572
574
573 class Configuration(PolymorphicModel):
575 class Configuration(PolymorphicModel):
574
576
575 template = models.BooleanField(default=False)
577 template = models.BooleanField(default=False)
576 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
578 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
577 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=True, null=True)
579 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=True, null=True)
578 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
580 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
579 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
581 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
580 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
582 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
581 created_date = models.DateTimeField(auto_now_add=True)
583 created_date = models.DateTimeField(auto_now_add=True)
582 programmed_date = models.DateTimeField(auto_now=True)
584 programmed_date = models.DateTimeField(auto_now=True)
583 parameters = models.TextField(default='{}')
585 parameters = models.TextField(default='{}')
584 author = models.ForeignKey(User, null=True, blank=True)
586 author = models.ForeignKey(User, null=True, blank=True)
585 hash = models.CharField(default='', max_length=64, null=True, blank=True)
587 hash = models.CharField(default='', max_length=64, null=True, blank=True)
586 message = ""
588 message = ""
587
589
588 class Meta:
590 class Meta:
589 db_table = 'db_configurations'
591 db_table = 'db_configurations'
590 ordering = ('device__device_type__name',)
592 ordering = ('device__device_type__name',)
591
593
592 def __str__(self):
594 def __str__(self):
593
595
594 ret = u'{} '.format(self.device.device_type.name.upper())
596 ret = u'{} '.format(self.device.device_type.name.upper())
595
597
596 if 'mix' in [f.name for f in self._meta.get_fields()]:
598 if 'mix' in [f.name for f in self._meta.get_fields()]:
597 if self.mix:
599 if self.mix:
598 ret = '{} MIX '.format(self.device.device_type.name.upper())
600 ret = '{} MIX '.format(self.device.device_type.name.upper())
599
601
600 if 'label' in [f.name for f in self._meta.get_fields()]:
602 if 'label' in [f.name for f in self._meta.get_fields()]:
601 ret += '{}'.format(self.label)
603 ret += '{}'.format(self.label)
602
604
603 if self.template:
605 if self.template:
604 ret += ' (template)'
606 ret += ' (template)'
605
607
606 return ret
608 return ret
607
609
608 @property
610 @property
609 def name(self):
611 def name(self):
610
612
611 return str(self)
613 return str(self)
612
614
613 def jsonify(self):
615 def jsonify(self):
614
616
615 data = {}
617 data = {}
616
618
617 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
619 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
618 'created_date', 'programmed_date', 'template', 'device',
620 'created_date', 'programmed_date', 'template', 'device',
619 'experiment')
621 'experiment')
620
622
621 for field in self._meta.fields:
623 for field in self._meta.fields:
622 if field.name in ignored:
624 if field.name in ignored:
623 continue
625 continue
624 data[field.name] = field.value_from_object(self)
626 data[field.name] = field.value_from_object(self)
625
627
626 data['device_type'] = self.device.device_type.name
628 data['device_type'] = self.device.device_type.name
627
629
628 if self.device.device_type.name == 'rc':
630 if self.device.device_type.name == 'rc':
629 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
631 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
630 data['delays'] = self.get_delays()
632 data['delays'] = self.get_delays()
631 data['pulses'] = self.get_pulses()
633 data['pulses'] = self.get_pulses()
632
634
633 elif self.device.device_type.name == 'jars':
635 elif self.device.device_type.name == 'jars':
634 data['decode_type'] = DECODE_TYPE[self.decode_data][1]
636 data['decode_type'] = DECODE_TYPE[self.decode_data][1]
635
637
636 elif self.device.device_type.name == 'dds':
638 elif self.device.device_type.name == 'dds':
637 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
639 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
638 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
640 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
639 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
641 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
640 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
642 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
641
643
642 return data
644 return data
643
645
644 def clone(self, **kwargs):
646 def clone(self, **kwargs):
645
647
646 self.pk = None
648 self.pk = None
647 self.id = None
649 self.id = None
648 for attr, value in kwargs.items():
650 for attr, value in kwargs.items():
649 setattr(self, attr, value)
651 setattr(self, attr, value)
650
652
651 self.save()
653 self.save()
652
654
653 return self
655 return self
654
656
655 def parms_to_dict(self):
657 def parms_to_dict(self):
656
658
657 params = Params({})
659 params = Params({})
658 params.add(self.jsonify(), 'configurations')
660 params.add(self.jsonify(), 'configurations')
659
661
660 if self.device.device_type.name=='rc':
662 if self.device.device_type.name=='rc':
661 for line in self.get_lines():
663 for line in self.get_lines():
662 params.add(line.jsonify(), 'lines')
664 params.add(line.jsonify(), 'lines')
663
665
664 return params.data
666 return params.data
665
667
666 def parms_to_text(self):
668 def parms_to_text(self):
667
669
668 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
670 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
669
671
670
672
671 def parms_to_binary(self):
673 def parms_to_binary(self):
672
674
673 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
675 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
674
676
675
677
676 def dict_to_parms(self, parameters, id=None):
678 def dict_to_parms(self, parameters, id=None):
677
679
678 params = Params(parameters)
680 params = Params(parameters)
679
681
680 if id:
682 if id:
681 data = params.get_conf(id_conf=id)
683 data = params.get_conf(id_conf=id)
682 else:
684 else:
683 data = params.get_conf(dtype=self.device.device_type.name)
685 data = params.get_conf(dtype=self.device.device_type.name)
684
686
685 if data['device_type']=='rc':
687 if data['device_type']=='rc':
686 self.clean_lines()
688 self.clean_lines()
687 lines = data.pop('lines', None)
689 lines = data.pop('lines', None)
688 for line_id in lines:
690 for line_id in lines:
689 pass
691 pass
690
692
691 for key, value in data.items():
693 for key, value in data.items():
692 if key not in ('id', 'device_type'):
694 if key not in ('id', 'device_type'):
693 setattr(self, key, value)
695 setattr(self, key, value)
694
696
695 self.save()
697 self.save()
696
698
697
699
698 def export_to_file(self, format="json"):
700 def export_to_file(self, format="json"):
699
701
700 content_type = ''
702 content_type = ''
701
703
702 if format == 'racp':
704 if format == 'racp':
703 content_type = 'text/plain'
705 content_type = 'text/plain'
704 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
706 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
705 content = self.parms_to_text(file_format = 'racp')
707 content = self.parms_to_text(file_format = 'racp')
706
708
707 if format == 'text':
709 if format == 'text':
708 content_type = 'text/plain'
710 content_type = 'text/plain'
709 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
711 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
710 content = self.parms_to_text()
712 content = self.parms_to_text()
711
713
712 if format == 'binary':
714 if format == 'binary':
713 content_type = 'application/octet-stream'
715 content_type = 'application/octet-stream'
714 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
716 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
715 content = self.parms_to_binary()
717 content = self.parms_to_binary()
716
718
717 if not content_type:
719 if not content_type:
718 content_type = 'application/json'
720 content_type = 'application/json'
719 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
721 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
720 content = json.dumps(self.parms_to_dict(), indent=2)
722 content = json.dumps(self.parms_to_dict(), indent=2)
721
723
722 fields = {'content_type':content_type,
724 fields = {'content_type':content_type,
723 'filename':filename,
725 'filename':filename,
724 'content':content
726 'content':content
725 }
727 }
726
728
727 return fields
729 return fields
728
730
729 def import_from_file(self, fp):
731 def import_from_file(self, fp):
730
732
731 parms = {}
733 parms = {}
732
734
733 path, ext = os.path.splitext(fp.name)
735 path, ext = os.path.splitext(fp.name)
734
736
735 if ext == '.json':
737 if ext == '.json':
736 parms = json.load(fp)
738 parms = json.load(fp)
737
739
738 if ext == '.dds':
740 if ext == '.dds':
739 lines = fp.readlines()
741 lines = fp.readlines()
740 parms = dds_data.text_to_dict(lines)
742 parms = dds_data.text_to_dict(lines)
741
743
742 if ext == '.racp':
744 if ext == '.racp':
743 if self.device.device_type.name == 'jars':
745 if self.device.device_type.name == 'jars':
744 parms = RacpFile(fp).to_dict()
746 parms = RacpFile(fp).to_dict()
745 parms['filter_parms'] = json.loads(self.filter_parms)
747 parms['filter_parms'] = json.loads(self.filter_parms)
746 return parms
748 return parms
747 parms = RCFile(fp).to_dict()
749 parms = RCFile(fp).to_dict()
748
750
749 return parms
751 return parms
750
752
751 def status_device(self):
753 def status_device(self):
752
754
753 self.message = 'Function not implemented'
755 self.message = 'Function not implemented'
754 return False
756 return False
755
757
756
758
757 def stop_device(self):
759 def stop_device(self):
758
760
759 self.message = 'Function not implemented'
761 self.message = 'Function not implemented'
760 return False
762 return False
761
763
762
764
763 def start_device(self):
765 def start_device(self):
764
766
765 self.message = 'Function not implemented'
767 self.message = 'Function not implemented'
766 return False
768 return False
767
769
768
770
769 def write_device(self, parms):
771 def write_device(self, parms):
770
772
771 self.message = 'Function not implemented'
773 self.message = 'Function not implemented'
772 return False
774 return False
773
775
774
776
775 def read_device(self):
777 def read_device(self):
776
778
777 self.message = 'Function not implemented'
779 self.message = 'Function not implemented'
778 return False
780 return False
779
781
780
782
781 def get_absolute_url(self):
783 def get_absolute_url(self):
782 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
784 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
783
785
784 def get_absolute_url_edit(self):
786 def get_absolute_url_edit(self):
785 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
787 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
786
788
787 def get_absolute_url_delete(self):
789 def get_absolute_url_delete(self):
788 return reverse('url_delete_dev_conf', args=[str(self.id)])
790 return reverse('url_delete_dev_conf', args=[str(self.id)])
789
791
790 def get_absolute_url_import(self):
792 def get_absolute_url_import(self):
791 return reverse('url_import_dev_conf', args=[str(self.id)])
793 return reverse('url_import_dev_conf', args=[str(self.id)])
792
794
793 def get_absolute_url_export(self):
795 def get_absolute_url_export(self):
794 return reverse('url_export_dev_conf', args=[str(self.id)])
796 return reverse('url_export_dev_conf', args=[str(self.id)])
795
797
796 def get_absolute_url_write(self):
798 def get_absolute_url_write(self):
797 return reverse('url_write_dev_conf', args=[str(self.id)])
799 return reverse('url_write_dev_conf', args=[str(self.id)])
798
800
799 def get_absolute_url_read(self):
801 def get_absolute_url_read(self):
800 return reverse('url_read_dev_conf', args=[str(self.id)])
802 return reverse('url_read_dev_conf', args=[str(self.id)])
801
803
802 def get_absolute_url_start(self):
804 def get_absolute_url_start(self):
803 return reverse('url_start_dev_conf', args=[str(self.id)])
805 return reverse('url_start_dev_conf', args=[str(self.id)])
804
806
805 def get_absolute_url_stop(self):
807 def get_absolute_url_stop(self):
806 return reverse('url_stop_dev_conf', args=[str(self.id)])
808 return reverse('url_stop_dev_conf', args=[str(self.id)])
807
809
808 def get_absolute_url_status(self):
810 def get_absolute_url_status(self):
809 return reverse('url_status_dev_conf', args=[str(self.id)])
811 return reverse('url_status_dev_conf', args=[str(self.id)])
@@ -1,1850 +1,1865
1 import ast
1 import ast
2 import json
2 import json
3 import hashlib
3 import hashlib
4 from datetime import datetime, timedelta
4 from datetime import datetime, timedelta
5
5
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7 from django.utils.safestring import mark_safe
7 from django.utils.safestring import mark_safe
8 from django.http import HttpResponseRedirect
8 from django.http import HttpResponseRedirect
9 from django.core.urlresolvers import reverse
9 from django.core.urlresolvers import reverse
10 from django.db.models import Q
10 from django.db.models import Q
11 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
11 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
12 from django.contrib import messages
12 from django.contrib import messages
13 from django.http.request import QueryDict
13 from django.http.request import QueryDict
14 from django.contrib.auth.decorators import login_required, user_passes_test
14 from django.contrib.auth.decorators import login_required, user_passes_test
15
15
16 try:
16 try:
17 from urllib.parse import urlencode
17 from urllib.parse import urlencode
18 except ImportError:
18 except ImportError:
19 from urllib import urlencode
19 from urllib import urlencode
20
20
21 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
21 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
22 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
22 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
23
23
24 from .tasks import task_start
24 from .tasks import task_start
25
25
26 from apps.rc.forms import RCConfigurationForm, RCLineCode, RCMixConfigurationForm
26 from apps.rc.forms import RCConfigurationForm, RCLineCode, RCMixConfigurationForm
27 from apps.dds.forms import DDSConfigurationForm
27 from apps.dds.forms import DDSConfigurationForm
28 from apps.jars.forms import JARSConfigurationForm
28 from apps.jars.forms import JARSConfigurationForm
29 from apps.cgs.forms import CGSConfigurationForm
29 from apps.cgs.forms import CGSConfigurationForm
30 from apps.abs.forms import ABSConfigurationForm
30 from apps.abs.forms import ABSConfigurationForm
31 from apps.usrp.forms import USRPConfigurationForm
31 from apps.usrp.forms import USRPConfigurationForm
32 from .utils import Params
32 from .utils import Params
33
33
34 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment, DEV_STATES
34 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment, DEV_STATES
35 from apps.cgs.models import CGSConfiguration
35 from apps.cgs.models import CGSConfiguration
36 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
36 from apps.jars.models import JARSConfiguration, EXPERIMENT_TYPE
37 from apps.usrp.models import USRPConfiguration
37 from apps.usrp.models import USRPConfiguration
38 from apps.abs.models import ABSConfiguration
38 from apps.abs.models import ABSConfiguration
39 from apps.rc.models import RCConfiguration, RCLine, RCLineType
39 from apps.rc.models import RCConfiguration, RCLine, RCLineType
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
1371
1372 return redirect('url_dev_conf', id_conf=conf.pk)
1372 return redirect('url_dev_conf', id_conf=conf.pk)
1373
1373
1374 kwargs['id_exp'] = id_exp
1374 kwargs['id_exp'] = id_exp
1375 kwargs['form'] = form
1375 kwargs['form'] = form
1376 kwargs['title'] = 'Configuration'
1376 kwargs['title'] = 'Configuration'
1377 kwargs['suptitle'] = 'New'
1377 kwargs['suptitle'] = 'New'
1378 kwargs['menu_configurations'] = 'active'
1378 kwargs['menu_configurations'] = 'active'
1379
1379
1380 if id_dev != 0:
1380 if id_dev != 0:
1381 device = Device.objects.get(pk=id_dev)
1381 device = Device.objects.get(pk=id_dev)
1382 kwargs['device'] = device.device_type.name
1382 kwargs['device'] = device.device_type.name
1383
1383
1384 return render(request, 'dev_conf_edit.html', kwargs)
1384 return render(request, 'dev_conf_edit.html', kwargs)
1385
1385
1386
1386
1387 @login_required
1387 @login_required
1388 def dev_conf_edit(request, id_conf):
1388 def dev_conf_edit(request, id_conf):
1389
1389
1390 conf = get_object_or_404(Configuration, pk=id_conf)
1390 conf = get_object_or_404(Configuration, pk=id_conf)
1391
1391
1392 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1392 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1393
1393
1394 if request.method == 'GET':
1394 if request.method == 'GET':
1395 form = DevConfForm(instance=conf)
1395 form = DevConfForm(instance=conf)
1396
1396
1397 if request.method == 'POST':
1397 if request.method == 'POST':
1398 form = DevConfForm(request.POST, instance=conf)
1398 form = DevConfForm(request.POST, instance=conf)
1399
1399
1400 if form.is_valid():
1400 if form.is_valid():
1401 form.save()
1401 form.save()
1402 return redirect('url_dev_conf', id_conf=id_conf)
1402 return redirect('url_dev_conf', id_conf=id_conf)
1403
1403
1404 kwargs = {}
1404 kwargs = {}
1405 kwargs['form'] = form
1405 kwargs['form'] = form
1406 kwargs['title'] = 'Device Configuration'
1406 kwargs['title'] = 'Device Configuration'
1407 kwargs['suptitle'] = 'Edit'
1407 kwargs['suptitle'] = 'Edit'
1408 kwargs['button'] = 'Update'
1408 kwargs['button'] = 'Update'
1409 kwargs['menu_configurations'] = 'active'
1409 kwargs['menu_configurations'] = 'active'
1410
1410
1411 ###### SIDEBAR ######
1411 ###### SIDEBAR ######
1412 kwargs.update(sidebar(conf=conf))
1412 kwargs.update(sidebar(conf=conf))
1413
1413
1414 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1414 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1415
1415
1416
1416
1417 @login_required
1417 @login_required
1418 def dev_conf_start(request, id_conf):
1418 def dev_conf_start(request, id_conf):
1419
1419
1420 conf = get_object_or_404(Configuration, pk=id_conf)
1420 conf = get_object_or_404(Configuration, pk=id_conf)
1421
1421
1422 if conf.start_device():
1422 if conf.start_device():
1423 messages.success(request, conf.message)
1423 messages.success(request, conf.message)
1424 else:
1424 else:
1425 messages.error(request, conf.message)
1425 messages.error(request, conf.message)
1426
1426
1427 #conf.status_device()
1427 #conf.status_device()
1428
1428
1429 return redirect(conf.get_absolute_url())
1429 return redirect(conf.get_absolute_url())
1430
1430
1431
1431
1432 @login_required
1432 @login_required
1433 def dev_conf_stop(request, id_conf):
1433 def dev_conf_stop(request, id_conf):
1434
1434
1435 conf = get_object_or_404(Configuration, pk=id_conf)
1435 conf = get_object_or_404(Configuration, pk=id_conf)
1436
1436
1437 if conf.stop_device():
1437 if conf.stop_device():
1438 messages.success(request, conf.message)
1438 messages.success(request, conf.message)
1439 else:
1439 else:
1440 messages.error(request, conf.message)
1440 messages.error(request, conf.message)
1441
1441
1442 #conf.status_device()
1442 #conf.status_device()
1443
1443
1444 return redirect(conf.get_absolute_url())
1444 return redirect(conf.get_absolute_url())
1445
1445
1446
1446
1447 @login_required
1447 def dev_conf_status(request, id_conf):
1448 def dev_conf_status(request, id_conf):
1448
1449
1449 conf = get_object_or_404(Configuration, pk=id_conf)
1450 conf = get_object_or_404(Configuration, pk=id_conf)
1450
1451
1452 if conf.device.device_type.name == 'abs':
1453 abs = request.user.profile.abs_active
1454 if abs<>conf:
1455 url = '#' if abs is None else abs.get_absolute_url()
1456 label = 'None' if abs is None else abs.label
1457 messages.warning(
1458 request,
1459 mark_safe('The current configuration has not been written in the modules, the active configuration is <a href="{}">{}</a>'.format(
1460 url,
1461 label
1462 ))
1463 )
1464 return redirect(conf.get_absolute_url())
1465
1451 if conf.status_device():
1466 if conf.status_device():
1452 messages.success(request, conf.message)
1467 messages.success(request, conf.message)
1453 else:
1468 else:
1454 messages.error(request, conf.message)
1469 messages.error(request, conf.message)
1455
1470
1456 return redirect(conf.get_absolute_url())
1471 return redirect(conf.get_absolute_url())
1457
1472
1458
1473
1459 @login_required
1474 @login_required
1460 def dev_conf_reset(request, id_conf):
1475 def dev_conf_reset(request, id_conf):
1461
1476
1462 conf = get_object_or_404(Configuration, pk=id_conf)
1477 conf = get_object_or_404(Configuration, pk=id_conf)
1463
1478
1464 if conf.reset_device():
1479 if conf.reset_device():
1465 messages.success(request, conf.message)
1480 messages.success(request, conf.message)
1466 else:
1481 else:
1467 messages.error(request, conf.message)
1482 messages.error(request, conf.message)
1468
1483
1469 return redirect(conf.get_absolute_url())
1484 return redirect(conf.get_absolute_url())
1470
1485
1471
1486
1472 @login_required
1487 @login_required
1473 def dev_conf_write(request, id_conf):
1488 def dev_conf_write(request, id_conf):
1474
1489
1475 conf = get_object_or_404(Configuration, pk=id_conf)
1490 conf = get_object_or_404(Configuration, pk=id_conf)
1476
1491
1477 if conf.write_device():
1492 if conf.write_device():
1478 messages.success(request, conf.message)
1493 messages.success(request, conf.message)
1479 if has_been_modified(conf):
1494 if has_been_modified(conf):
1480 conf.clone(type=1, template=False)
1495 conf.clone(type=1, template=False)
1481 else:
1496 else:
1482 messages.error(request, conf.message)
1497 messages.error(request, conf.message)
1483
1498
1484 return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1499 return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1485
1500
1486
1501
1487 @login_required
1502 @login_required
1488 def dev_conf_read(request, id_conf):
1503 def dev_conf_read(request, id_conf):
1489
1504
1490 conf = get_object_or_404(Configuration, pk=id_conf)
1505 conf = get_object_or_404(Configuration, pk=id_conf)
1491
1506
1492 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1507 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1493
1508
1494 if request.method == 'GET':
1509 if request.method == 'GET':
1495
1510
1496 parms = conf.read_device()
1511 parms = conf.read_device()
1497 #conf.status_device()
1512 #conf.status_device()
1498
1513
1499 if not parms:
1514 if not parms:
1500 messages.error(request, conf.message)
1515 messages.error(request, conf.message)
1501 return redirect(conf.get_absolute_url())
1516 return redirect(conf.get_absolute_url())
1502
1517
1503 form = DevConfForm(initial=parms, instance=conf)
1518 form = DevConfForm(initial=parms, instance=conf)
1504
1519
1505 if request.method == 'POST':
1520 if request.method == 'POST':
1506 form = DevConfForm(request.POST, instance=conf)
1521 form = DevConfForm(request.POST, instance=conf)
1507
1522
1508 if form.is_valid():
1523 if form.is_valid():
1509 form.save()
1524 form.save()
1510 return redirect(conf.get_absolute_url())
1525 return redirect(conf.get_absolute_url())
1511
1526
1512 messages.error(request, "Parameters could not be saved")
1527 messages.error(request, "Parameters could not be saved")
1513
1528
1514 kwargs = {}
1529 kwargs = {}
1515 kwargs['id_dev'] = conf.id
1530 kwargs['id_dev'] = conf.id
1516 kwargs['form'] = form
1531 kwargs['form'] = form
1517 kwargs['title'] = 'Device Configuration'
1532 kwargs['title'] = 'Device Configuration'
1518 kwargs['suptitle'] = 'Parameters read from device'
1533 kwargs['suptitle'] = 'Parameters read from device'
1519 kwargs['button'] = 'Save'
1534 kwargs['button'] = 'Save'
1520
1535
1521 ###### SIDEBAR ######
1536 ###### SIDEBAR ######
1522 kwargs.update(sidebar(conf=conf))
1537 kwargs.update(sidebar(conf=conf))
1523
1538
1524 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1539 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1525
1540
1526
1541
1527 @login_required
1542 @login_required
1528 def dev_conf_import(request, id_conf):
1543 def dev_conf_import(request, id_conf):
1529
1544
1530 conf = get_object_or_404(Configuration, pk=id_conf)
1545 conf = get_object_or_404(Configuration, pk=id_conf)
1531 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1546 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1532
1547
1533 if request.method == 'GET':
1548 if request.method == 'GET':
1534 file_form = UploadFileForm()
1549 file_form = UploadFileForm()
1535
1550
1536 if request.method == 'POST':
1551 if request.method == 'POST':
1537 file_form = UploadFileForm(request.POST, request.FILES)
1552 file_form = UploadFileForm(request.POST, request.FILES)
1538
1553
1539 if file_form.is_valid():
1554 if file_form.is_valid():
1540
1555
1541 data = conf.import_from_file(request.FILES['file'])
1556 data = conf.import_from_file(request.FILES['file'])
1542 parms = Params(data=data).get_conf(
1557 parms = Params(data=data).get_conf(
1543 dtype=conf.device.device_type.name)
1558 dtype=conf.device.device_type.name)
1544
1559
1545 if parms:
1560 if parms:
1546
1561
1547 form = DevConfForm(initial=parms, instance=conf)
1562 form = DevConfForm(initial=parms, instance=conf)
1548
1563
1549 kwargs = {}
1564 kwargs = {}
1550 kwargs['id_dev'] = conf.id
1565 kwargs['id_dev'] = conf.id
1551 kwargs['form'] = form
1566 kwargs['form'] = form
1552 kwargs['title'] = 'Device Configuration'
1567 kwargs['title'] = 'Device Configuration'
1553 kwargs['suptitle'] = 'Parameters imported'
1568 kwargs['suptitle'] = 'Parameters imported'
1554 kwargs['button'] = 'Save'
1569 kwargs['button'] = 'Save'
1555 kwargs['action'] = conf.get_absolute_url_edit()
1570 kwargs['action'] = conf.get_absolute_url_edit()
1556 kwargs['previous'] = conf.get_absolute_url()
1571 kwargs['previous'] = conf.get_absolute_url()
1557
1572
1558 ###### SIDEBAR ######
1573 ###### SIDEBAR ######
1559 kwargs.update(sidebar(conf=conf))
1574 kwargs.update(sidebar(conf=conf))
1560
1575
1561 messages.success(
1576 messages.success(
1562 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
1577 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
1563
1578
1564 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1579 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1565
1580
1566 messages.error(request, "Could not import parameters from file")
1581 messages.error(request, "Could not import parameters from file")
1567
1582
1568 kwargs = {}
1583 kwargs = {}
1569 kwargs['id_dev'] = conf.id
1584 kwargs['id_dev'] = conf.id
1570 kwargs['title'] = 'Device Configuration'
1585 kwargs['title'] = 'Device Configuration'
1571 kwargs['form'] = file_form
1586 kwargs['form'] = file_form
1572 kwargs['suptitle'] = 'Importing file'
1587 kwargs['suptitle'] = 'Importing file'
1573 kwargs['button'] = 'Import'
1588 kwargs['button'] = 'Import'
1574 kwargs['menu_configurations'] = 'active'
1589 kwargs['menu_configurations'] = 'active'
1575
1590
1576 kwargs.update(sidebar(conf=conf))
1591 kwargs.update(sidebar(conf=conf))
1577
1592
1578 return render(request, 'dev_conf_import.html', kwargs)
1593 return render(request, 'dev_conf_import.html', kwargs)
1579
1594
1580
1595
1581 @login_required
1596 @login_required
1582 def dev_conf_export(request, id_conf):
1597 def dev_conf_export(request, id_conf):
1583
1598
1584 conf = get_object_or_404(Configuration, pk=id_conf)
1599 conf = get_object_or_404(Configuration, pk=id_conf)
1585
1600
1586 if request.method == 'GET':
1601 if request.method == 'GET':
1587 file_form = DownloadFileForm(conf.device.device_type.name)
1602 file_form = DownloadFileForm(conf.device.device_type.name)
1588
1603
1589 if request.method == 'POST':
1604 if request.method == 'POST':
1590 file_form = DownloadFileForm(
1605 file_form = DownloadFileForm(
1591 conf.device.device_type.name, request.POST)
1606 conf.device.device_type.name, request.POST)
1592
1607
1593 if file_form.is_valid():
1608 if file_form.is_valid():
1594 fields = conf.export_to_file(
1609 fields = conf.export_to_file(
1595 format=file_form.cleaned_data['format'])
1610 format=file_form.cleaned_data['format'])
1596 if not fields['content']:
1611 if not fields['content']:
1597 messages.error(request, conf.message)
1612 messages.error(request, conf.message)
1598 return redirect(conf.get_absolute_url_export())
1613 return redirect(conf.get_absolute_url_export())
1599 response = HttpResponse(content_type=fields['content_type'])
1614 response = HttpResponse(content_type=fields['content_type'])
1600 response['Content-Disposition'] = 'attachment; filename="%s"' % fields['filename']
1615 response['Content-Disposition'] = 'attachment; filename="%s"' % fields['filename']
1601 response.write(fields['content'])
1616 response.write(fields['content'])
1602
1617
1603 return response
1618 return response
1604
1619
1605 messages.error(request, "Could not export parameters")
1620 messages.error(request, "Could not export parameters")
1606
1621
1607 kwargs = {}
1622 kwargs = {}
1608 kwargs['id_dev'] = conf.id
1623 kwargs['id_dev'] = conf.id
1609 kwargs['title'] = 'Device Configuration'
1624 kwargs['title'] = 'Device Configuration'
1610 kwargs['form'] = file_form
1625 kwargs['form'] = file_form
1611 kwargs['suptitle'] = 'Exporting file'
1626 kwargs['suptitle'] = 'Exporting file'
1612 kwargs['button'] = 'Export'
1627 kwargs['button'] = 'Export'
1613 kwargs['menu_configurations'] = 'active'
1628 kwargs['menu_configurations'] = 'active'
1614
1629
1615 return render(request, 'dev_conf_export.html', kwargs)
1630 return render(request, 'dev_conf_export.html', kwargs)
1616
1631
1617
1632
1618 @login_required
1633 @login_required
1619 def dev_conf_delete(request, id_conf):
1634 def dev_conf_delete(request, id_conf):
1620
1635
1621 conf = get_object_or_404(Configuration, pk=id_conf)
1636 conf = get_object_or_404(Configuration, pk=id_conf)
1622
1637
1623 if request.method == 'POST':
1638 if request.method == 'POST':
1624 if is_developer(request.user):
1639 if is_developer(request.user):
1625 conf.delete()
1640 conf.delete()
1626 return redirect('url_dev_confs')
1641 return redirect('url_dev_confs')
1627
1642
1628 messages.error(request, 'Not enough permission to delete this object')
1643 messages.error(request, 'Not enough permission to delete this object')
1629 return redirect(conf.get_absolute_url())
1644 return redirect(conf.get_absolute_url())
1630
1645
1631 kwargs = {
1646 kwargs = {
1632 'title': 'Delete',
1647 'title': 'Delete',
1633 'suptitle': 'Configuration',
1648 'suptitle': 'Configuration',
1634 'object': conf,
1649 'object': conf,
1635 'delete': True
1650 'delete': True
1636 }
1651 }
1637 kwargs['menu_configurations'] = 'active'
1652 kwargs['menu_configurations'] = 'active'
1638
1653
1639 return render(request, 'confirm.html', kwargs)
1654 return render(request, 'confirm.html', kwargs)
1640
1655
1641
1656
1642 def sidebar(**kwargs):
1657 def sidebar(**kwargs):
1643
1658
1644 side_data = {}
1659 side_data = {}
1645
1660
1646 conf = kwargs.get('conf', None)
1661 conf = kwargs.get('conf', None)
1647 experiment = kwargs.get('experiment', None)
1662 experiment = kwargs.get('experiment', None)
1648
1663
1649 if not experiment:
1664 if not experiment:
1650 experiment = conf.experiment
1665 experiment = conf.experiment
1651
1666
1652 if experiment:
1667 if experiment:
1653 side_data['experiment'] = experiment
1668 side_data['experiment'] = experiment
1654 campaign = experiment.campaign_set.all()
1669 campaign = experiment.campaign_set.all()
1655 if campaign:
1670 if campaign:
1656 side_data['campaign'] = campaign[0]
1671 side_data['campaign'] = campaign[0]
1657 experiments = campaign[0].experiments.all().order_by('name')
1672 experiments = campaign[0].experiments.all().order_by('name')
1658 else:
1673 else:
1659 experiments = [experiment]
1674 experiments = [experiment]
1660 configurations = experiment.configuration_set.filter(type=0)
1675 configurations = experiment.configuration_set.filter(type=0)
1661 side_data['side_experiments'] = experiments
1676 side_data['side_experiments'] = experiments
1662 side_data['side_configurations'] = configurations.order_by(
1677 side_data['side_configurations'] = configurations.order_by(
1663 'device__device_type__name')
1678 'device__device_type__name')
1664
1679
1665 return side_data
1680 return side_data
1666
1681
1667
1682
1668 def get_paginator(model, page, order, filters={}, n=8):
1683 def get_paginator(model, page, order, filters={}, n=8):
1669
1684
1670 kwargs = {}
1685 kwargs = {}
1671 query = Q()
1686 query = Q()
1672 if isinstance(filters, QueryDict):
1687 if isinstance(filters, QueryDict):
1673 filters = filters.dict()
1688 filters = filters.dict()
1674 [filters.pop(key) for key in filters.keys() if filters[key] in ('', ' ')]
1689 [filters.pop(key) for key in filters.keys() if filters[key] in ('', ' ')]
1675 filters.pop('page', None)
1690 filters.pop('page', None)
1676
1691
1677 fields = [f.name for f in model._meta.get_fields()]
1692 fields = [f.name for f in model._meta.get_fields()]
1678
1693
1679 if 'template' in filters:
1694 if 'template' in filters:
1680 filters['template'] = True
1695 filters['template'] = True
1681 if 'historical' in filters:
1696 if 'historical' in filters:
1682 filters.pop('historical')
1697 filters.pop('historical')
1683 filters['type'] = 1
1698 filters['type'] = 1
1684 elif 'type' in fields:
1699 elif 'type' in fields:
1685 filters['type'] = 0
1700 filters['type'] = 0
1686 if 'start_date' in filters:
1701 if 'start_date' in filters:
1687 filters['start_date__gte'] = filters.pop('start_date')
1702 filters['start_date__gte'] = filters.pop('start_date')
1688 if 'end_date' in filters:
1703 if 'end_date' in filters:
1689 filters['start_date__lte'] = filters.pop('end_date')
1704 filters['start_date__lte'] = filters.pop('end_date')
1690 if 'tags' in filters:
1705 if 'tags' in filters:
1691 tags = filters.pop('tags')
1706 tags = filters.pop('tags')
1692 if 'tags' in fields:
1707 if 'tags' in fields:
1693 query = query | Q(tags__icontains=tags)
1708 query = query | Q(tags__icontains=tags)
1694 if 'label' in fields:
1709 if 'label' in fields:
1695 query = query | Q(label__icontains=tags)
1710 query = query | Q(label__icontains=tags)
1696 if 'location' in fields:
1711 if 'location' in fields:
1697 query = query | Q(location__name__icontains=tags)
1712 query = query | Q(location__name__icontains=tags)
1698 if 'device' in fields:
1713 if 'device' in fields:
1699 query = query | Q(device__device_type__name__icontains=tags)
1714 query = query | Q(device__device_type__name__icontains=tags)
1700 query = query | Q(device__location__name__icontains=tags)
1715 query = query | Q(device__location__name__icontains=tags)
1701 if 'device_type' in fields:
1716 if 'device_type' in fields:
1702 query = query | Q(device_type__name__icontains=tags)
1717 query = query | Q(device_type__name__icontains=tags)
1703
1718
1704 if 'mine' in filters:
1719 if 'mine' in filters:
1705 filters['author_id'] = filters['mine']
1720 filters['author_id'] = filters['mine']
1706 filters.pop('mine')
1721 filters.pop('mine')
1707 object_list = model.objects.filter(query, **filters).order_by(*order)
1722 object_list = model.objects.filter(query, **filters).order_by(*order)
1708 paginator = Paginator(object_list, n)
1723 paginator = Paginator(object_list, n)
1709
1724
1710 try:
1725 try:
1711 objects = paginator.page(page)
1726 objects = paginator.page(page)
1712 except PageNotAnInteger:
1727 except PageNotAnInteger:
1713 objects = paginator.page(1)
1728 objects = paginator.page(1)
1714 except EmptyPage:
1729 except EmptyPage:
1715 objects = paginator.page(paginator.num_pages)
1730 objects = paginator.page(paginator.num_pages)
1716
1731
1717 kwargs['objects'] = objects
1732 kwargs['objects'] = objects
1718 kwargs['offset'] = (int(page)-1)*n if page else 0
1733 kwargs['offset'] = (int(page)-1)*n if page else 0
1719
1734
1720 return kwargs
1735 return kwargs
1721
1736
1722
1737
1723 def operation(request, id_camp=None):
1738 def operation(request, id_camp=None):
1724
1739
1725 kwargs = {}
1740 kwargs = {}
1726 kwargs['title'] = 'Radars Operation'
1741 kwargs['title'] = 'Radars Operation'
1727 kwargs['no_sidebar'] = True
1742 kwargs['no_sidebar'] = True
1728 kwargs['menu_operation'] = 'active'
1743 kwargs['menu_operation'] = 'active'
1729 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1744 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1730 end_date__gte=datetime.now()).order_by('-start_date')
1745 end_date__gte=datetime.now()).order_by('-start_date')
1731
1746
1732 if id_camp:
1747 if id_camp:
1733 campaign = get_object_or_404(Campaign, pk=id_camp)
1748 campaign = get_object_or_404(Campaign, pk=id_camp)
1734 form = OperationForm(
1749 form = OperationForm(
1735 initial={'campaign': campaign.id}, campaigns=campaigns)
1750 initial={'campaign': campaign.id}, campaigns=campaigns)
1736 kwargs['campaign'] = campaign
1751 kwargs['campaign'] = campaign
1737 else:
1752 else:
1738 # form = OperationForm(campaigns=campaigns)
1753 # form = OperationForm(campaigns=campaigns)
1739 kwargs['campaigns'] = campaigns
1754 kwargs['campaigns'] = campaigns
1740 return render(request, 'operation.html', kwargs)
1755 return render(request, 'operation.html', kwargs)
1741
1756
1742 #---Experiment
1757 #---Experiment
1743 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1758 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1744 kwargs['experiment_keys'] = keys[1:]
1759 kwargs['experiment_keys'] = keys[1:]
1745 kwargs['experiments'] = experiments
1760 kwargs['experiments'] = experiments
1746 #---Radar
1761 #---Radar
1747 kwargs['locations'] = campaign.get_experiments_by_radar()
1762 kwargs['locations'] = campaign.get_experiments_by_radar()
1748 kwargs['form'] = form
1763 kwargs['form'] = form
1749
1764
1750 return render(request, 'operation.html', kwargs)
1765 return render(request, 'operation.html', kwargs)
1751
1766
1752
1767
1753 @login_required
1768 @login_required
1754 def radar_start(request, id_camp, id_radar):
1769 def radar_start(request, id_camp, id_radar):
1755
1770
1756 campaign = get_object_or_404(Campaign, pk=id_camp)
1771 campaign = get_object_or_404(Campaign, pk=id_camp)
1757 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1772 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1758 now = datetime.now()
1773 now = datetime.now()
1759 for exp in experiments:
1774 for exp in experiments:
1760 start = datetime.combine(datetime.now().date(), exp.start_time)
1775 start = datetime.combine(datetime.now().date(), exp.start_time)
1761 end = datetime.combine(datetime.now().date(), exp.end_time)
1776 end = datetime.combine(datetime.now().date(), exp.end_time)
1762 if end < start:
1777 if end < start:
1763 end += timedelta(1)
1778 end += timedelta(1)
1764
1779
1765 if exp.status == 2:
1780 if exp.status == 2:
1766 messages.warning(
1781 messages.warning(
1767 request, 'Experiment {} already running'.format(exp))
1782 request, 'Experiment {} already running'.format(exp))
1768 continue
1783 continue
1769
1784
1770 if exp.status == 3:
1785 if exp.status == 3:
1771 messages.warning(
1786 messages.warning(
1772 request, 'Experiment {} already programmed'.format(exp))
1787 request, 'Experiment {} already programmed'.format(exp))
1773 continue
1788 continue
1774
1789
1775 if start > campaign.end_date or start < campaign.start_date:
1790 if start > campaign.end_date or start < campaign.start_date:
1776 messages.warning(request, 'Experiment {} out of date'.format(exp))
1791 messages.warning(request, 'Experiment {} out of date'.format(exp))
1777 continue
1792 continue
1778
1793
1779 if now > start and now <= end:
1794 if now > start and now <= end:
1780 exp.status = 3
1795 exp.status = 3
1781 exp.save()
1796 exp.save()
1782 task = task_start.delay(exp.id)
1797 task = task_start.delay(exp.id)
1783 exp.status = task.wait()
1798 exp.status = task.wait()
1784 if exp.status == 0:
1799 if exp.status == 0:
1785 messages.error(request, 'Experiment {} not start'.format(exp))
1800 messages.error(request, 'Experiment {} not start'.format(exp))
1786 if exp.status == 2:
1801 if exp.status == 2:
1787 messages.success(request, 'Experiment {} started'.format(exp))
1802 messages.success(request, 'Experiment {} started'.format(exp))
1788 else:
1803 else:
1789 task = task_start.apply_async(
1804 task = task_start.apply_async(
1790 (exp.pk, ), eta=start+timedelta(hours=5))
1805 (exp.pk, ), eta=start+timedelta(hours=5))
1791 exp.task = task.id
1806 exp.task = task.id
1792 exp.status = 3
1807 exp.status = 3
1793 messages.success(
1808 messages.success(
1794 request, 'Experiment {} programmed to start at {}'.format(exp, start))
1809 request, 'Experiment {} programmed to start at {}'.format(exp, start))
1795
1810
1796 exp.save()
1811 exp.save()
1797
1812
1798 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1813 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1799
1814
1800
1815
1801 @login_required
1816 @login_required
1802 def radar_stop(request, id_camp, id_radar):
1817 def radar_stop(request, id_camp, id_radar):
1803
1818
1804 campaign = get_object_or_404(Campaign, pk=id_camp)
1819 campaign = get_object_or_404(Campaign, pk=id_camp)
1805 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1820 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1806
1821
1807 for exp in experiments:
1822 for exp in experiments:
1808
1823
1809 if exp.task:
1824 if exp.task:
1810 app.control.revoke(exp.task)
1825 app.control.revoke(exp.task)
1811 if exp.status == 2:
1826 if exp.status == 2:
1812 exp.stop()
1827 exp.stop()
1813 messages.warning(request, 'Experiment {} stopped'.format(exp))
1828 messages.warning(request, 'Experiment {} stopped'.format(exp))
1814 exp.status = 1
1829 exp.status = 1
1815 exp.save()
1830 exp.save()
1816
1831
1817 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1832 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1818
1833
1819
1834
1820 @login_required
1835 @login_required
1821 def radar_refresh(request, id_camp, id_radar):
1836 def radar_refresh(request, id_camp, id_radar):
1822
1837
1823 campaign = get_object_or_404(Campaign, pk=id_camp)
1838 campaign = get_object_or_404(Campaign, pk=id_camp)
1824 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1839 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1825
1840
1826 for exp in experiments:
1841 for exp in experiments:
1827 exp.get_status()
1842 exp.get_status()
1828
1843
1829 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1844 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1830
1845
1831
1846
1832 def real_time(request):
1847 def real_time(request):
1833
1848
1834 graphic_path = "/home/fiorella/Pictures/catwbeanie.jpg"
1849 graphic_path = "/home/fiorella/Pictures/catwbeanie.jpg"
1835
1850
1836 kwargs = {}
1851 kwargs = {}
1837 kwargs['title'] = 'CLAIRE'
1852 kwargs['title'] = 'CLAIRE'
1838 kwargs['suptitle'] = 'Real Time'
1853 kwargs['suptitle'] = 'Real Time'
1839 kwargs['no_sidebar'] = True
1854 kwargs['no_sidebar'] = True
1840 kwargs['graphic_path'] = graphic_path
1855 kwargs['graphic_path'] = graphic_path
1841 kwargs['graphic1_path'] = 'http://www.bluemaize.net/im/girls-accessories/shark-beanie-11.jpg'
1856 kwargs['graphic1_path'] = 'http://www.bluemaize.net/im/girls-accessories/shark-beanie-11.jpg'
1842
1857
1843 return render(request, 'real_time.html', kwargs)
1858 return render(request, 'real_time.html', kwargs)
1844
1859
1845 def theme(request, theme):
1860 def theme(request, theme):
1846
1861
1847 user = request.user
1862 user = request.user
1848 user.profile.theme = theme
1863 user.profile.theme = theme
1849 user.save()
1864 user.save()
1850 return redirect('index') No newline at end of file
1865 return redirect('index')
General Comments 0
You need to be logged in to leave comments. Login now