##// END OF EJS Templates
Fix RC plots bug
Juan C. Espinoza -
r332:9bb45c0e1ac7
parent child
Show More
@@ -1,877 +1,877
1 from django.db import models
1 from django.db import models
2 from apps.main.models import Configuration, User
2 from apps.main.models import Configuration, User
3 from django.core.urlresolvers import reverse
3 from django.core.urlresolvers import reverse
4 from celery.execute import send_task
4 from celery.execute import send_task
5 from datetime import datetime
5 from datetime import datetime
6 import ast
6 import ast
7 import socket
7 import socket
8 import json
8 import json
9 import requests
9 import requests
10 import struct
10 import struct
11 import os, sys, time
11 import os, sys, time
12
12
13 antenna_default = json.dumps({
13 antenna_default = json.dumps({
14 "antenna_up": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
14 "antenna_up": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
15 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
15 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
16 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
16 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
17 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
17 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
18 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
18 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
19 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
19 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
20 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
20 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0],
21 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0]
21 [0.5,0.5,0.5,0.5,1.0,1.0,1.0,1.0]
22 ]
22 ]
23 ,
23 ,
24 "antenna_down": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
24 "antenna_down": [[0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
25 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
25 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
26 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
26 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
27 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
27 [0.0,0.0,0.0,0.0,0.5,0.5,0.5,0.5],
28 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
28 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
29 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
29 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
30 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
30 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0],
31 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0]],
31 [0.5,0.5,0.5,0.5,3.0,3.0,3.0,3.0]],
32 })
32 })
33
33
34
34
35 tx_default = json.dumps({
35 tx_default = json.dumps({
36 "up": [[1,1,1,1,0,0,0,0],
36 "up": [[1,1,1,1,0,0,0,0],
37 [1,1,1,1,0,0,0,0],
37 [1,1,1,1,0,0,0,0],
38 [1,1,1,1,0,0,0,0],
38 [1,1,1,1,0,0,0,0],
39 [1,1,1,1,0,0,0,0],
39 [1,1,1,1,0,0,0,0],
40 [0,0,0,0,1,1,1,1],
40 [0,0,0,0,1,1,1,1],
41 [0,0,0,0,1,1,1,1],
41 [0,0,0,0,1,1,1,1],
42 [0,0,0,0,1,1,1,1],
42 [0,0,0,0,1,1,1,1],
43 [0,0,0,0,1,1,1,1]],
43 [0,0,0,0,1,1,1,1]],
44
44
45 "down": [[1,1,1,1,0,0,0,0],
45 "down": [[1,1,1,1,0,0,0,0],
46 [1,1,1,1,0,0,0,0],
46 [1,1,1,1,0,0,0,0],
47 [1,1,1,1,0,0,0,0],
47 [1,1,1,1,0,0,0,0],
48 [1,1,1,1,0,0,0,0],
48 [1,1,1,1,0,0,0,0],
49 [0,0,0,0,1,1,1,1],
49 [0,0,0,0,1,1,1,1],
50 [0,0,0,0,1,1,1,1],
50 [0,0,0,0,1,1,1,1],
51 [0,0,0,0,1,1,1,1],
51 [0,0,0,0,1,1,1,1],
52 [0,0,0,0,1,1,1,1]],
52 [0,0,0,0,1,1,1,1]],
53 })
53 })
54
54
55 rx_default = json.dumps({
55 rx_default = json.dumps({
56 "up": [[1,1,1,1,0,0,0,0],
56 "up": [[1,1,1,1,0,0,0,0],
57 [1,1,1,1,0,0,0,0],
57 [1,1,1,1,0,0,0,0],
58 [1,1,1,1,0,0,0,0],
58 [1,1,1,1,0,0,0,0],
59 [1,1,1,1,0,0,0,0],
59 [1,1,1,1,0,0,0,0],
60 [0,0,0,0,1,1,1,1],
60 [0,0,0,0,1,1,1,1],
61 [0,0,0,0,1,1,1,1],
61 [0,0,0,0,1,1,1,1],
62 [0,0,0,0,1,1,1,1],
62 [0,0,0,0,1,1,1,1],
63 [0,0,0,0,1,1,1,1]],
63 [0,0,0,0,1,1,1,1]],
64
64
65 "down": [[1,1,1,1,0,0,0,0],
65 "down": [[1,1,1,1,0,0,0,0],
66 [1,1,1,1,0,0,0,0],
66 [1,1,1,1,0,0,0,0],
67 [1,1,1,1,0,0,0,0],
67 [1,1,1,1,0,0,0,0],
68 [1,1,1,1,0,0,0,0],
68 [1,1,1,1,0,0,0,0],
69 [0,0,0,0,1,1,1,1],
69 [0,0,0,0,1,1,1,1],
70 [0,0,0,0,1,1,1,1],
70 [0,0,0,0,1,1,1,1],
71 [0,0,0,0,1,1,1,1],
71 [0,0,0,0,1,1,1,1],
72 [0,0,0,0,1,1,1,1]],
72 [0,0,0,0,1,1,1,1]],
73 })
73 })
74
74
75 status_default = '0000000000000000000000000000000000000000000000000000000000000000'
75 status_default = '0000000000000000000000000000000000000000000000000000000000000000'
76 default_messages = {}
76 default_messages = {}
77
77
78 for i in range(1,65):
78 for i in range(1,65):
79 default_messages[str(i)] = "Module "+str(i)
79 default_messages[str(i)] = "Module "+str(i)
80
80
81
81
82 ues_default = json.dumps({
82 ues_default = json.dumps({
83 "up": [0.533333,0.00000,1.06667,0.00000],
83 "up": [0.533333,0.00000,1.06667,0.00000],
84 "down": [0.533333,0.00000,1.06667,0.00000]
84 "down": [0.533333,0.00000,1.06667,0.00000]
85 })
85 })
86
86
87 onlyrx_default = json.dumps({
87 onlyrx_default = json.dumps({
88 "up": False,
88 "up": False,
89 "down": False
89 "down": False
90 })
90 })
91
91
92 def up_convertion(cadena):
92 def up_convertion(cadena):
93 valores = []
93 valores = []
94 for c in cadena:
94 for c in cadena:
95 if c == 1.0: valores=valores+['000']
95 if c == 1.0: valores=valores+['000']
96 if c == 2.0: valores=valores+['001']
96 if c == 2.0: valores=valores+['001']
97 if c == 3.0: valores=valores+['010']
97 if c == 3.0: valores=valores+['010']
98 if c == 0.0: valores=valores+['011']
98 if c == 0.0: valores=valores+['011']
99 if c == 0.5: valores=valores+['100']
99 if c == 0.5: valores=valores+['100']
100 if c == 1.5: valores=valores+['101']
100 if c == 1.5: valores=valores+['101']
101 if c == 2.5: valores=valores+['110']
101 if c == 2.5: valores=valores+['110']
102 if c == 3.5: valores=valores+['111']
102 if c == 3.5: valores=valores+['111']
103
103
104 return valores
104 return valores
105
105
106 def up_conv_bits(value):
106 def up_conv_bits(value):
107
107
108 if value == 1.0: bits="000"
108 if value == 1.0: bits="000"
109 if value == 2.0: bits="001"
109 if value == 2.0: bits="001"
110 if value == 3.0: bits="010"
110 if value == 3.0: bits="010"
111 if value == 0.0: bits="011"
111 if value == 0.0: bits="011"
112 if value == 0.5: bits="100"
112 if value == 0.5: bits="100"
113 if value == 1.5: bits="101"
113 if value == 1.5: bits="101"
114 if value == 2.5: bits="110"
114 if value == 2.5: bits="110"
115 if value == 3.5: bits="111"
115 if value == 3.5: bits="111"
116
116
117 return bits
117 return bits
118
118
119 def down_convertion(cadena):
119 def down_convertion(cadena):
120 valores = []
120 valores = []
121 for c in cadena:
121 for c in cadena:
122 if c == 1.0: valores=valores+['000']
122 if c == 1.0: valores=valores+['000']
123 if c == 2.0: valores=valores+['001']
123 if c == 2.0: valores=valores+['001']
124 if c == 3.0: valores=valores+['010']
124 if c == 3.0: valores=valores+['010']
125 if c == 0.0: valores=valores+['011']
125 if c == 0.0: valores=valores+['011']
126 if c == 0.5: valores=valores+['100']
126 if c == 0.5: valores=valores+['100']
127 if c == 1.5: valores=valores+['101']
127 if c == 1.5: valores=valores+['101']
128 if c == 2.5: valores=valores+['110']
128 if c == 2.5: valores=valores+['110']
129 if c == 3.5: valores=valores+['111']
129 if c == 3.5: valores=valores+['111']
130
130
131 return valores
131 return valores
132
132
133 def down_conv_bits(value):
133 def down_conv_bits(value):
134
134
135 if value == 1.0: bits="000"
135 if value == 1.0: bits="000"
136 if value == 2.0: bits="001"
136 if value == 2.0: bits="001"
137 if value == 3.0: bits="010"
137 if value == 3.0: bits="010"
138 if value == 0.0: bits="011"
138 if value == 0.0: bits="011"
139 if value == 0.5: bits="100"
139 if value == 0.5: bits="100"
140 if value == 1.5: bits="101"
140 if value == 1.5: bits="101"
141 if value == 2.5: bits="110"
141 if value == 2.5: bits="110"
142 if value == 3.5: bits="111"
142 if value == 3.5: bits="111"
143
143
144 return bits
144 return bits
145
145
146 def up_conv_value(bits):
146 def up_conv_value(bits):
147
147
148 if bits == "000": value=1.0
148 if bits == "000": value=1.0
149 if bits == "001": value=2.0
149 if bits == "001": value=2.0
150 if bits == "010": value=3.0
150 if bits == "010": value=3.0
151 if bits == "011": value=0.0
151 if bits == "011": value=0.0
152 if bits == "100": value=0.5
152 if bits == "100": value=0.5
153 if bits == "101": value=1.5
153 if bits == "101": value=1.5
154 if bits == "110": value=2.5
154 if bits == "110": value=2.5
155 if bits == "111": value=3.5
155 if bits == "111": value=3.5
156
156
157 return value
157 return value
158
158
159 def down_conv_value(bits):
159 def down_conv_value(bits):
160
160
161 if bits == "000": value=1.0
161 if bits == "000": value=1.0
162 if bits == "001": value=2.0
162 if bits == "001": value=2.0
163 if bits == "010": value=3.0
163 if bits == "010": value=3.0
164 if bits == "011": value=0.0
164 if bits == "011": value=0.0
165 if bits == "100": value=0.5
165 if bits == "100": value=0.5
166 if bits == "101": value=1.5
166 if bits == "101": value=1.5
167 if bits == "110": value=2.5
167 if bits == "110": value=2.5
168 if bits == "111": value=3.5
168 if bits == "111": value=3.5
169
169
170 return value
170 return value
171
171
172 def ip2position(module_number):
172 def ip2position(module_number):
173 j=0
173 j=0
174 i=0
174 i=0
175 for x in range(0,module_number-1):
175 for x in range(0,module_number-1):
176 j=j+1
176 j=j+1
177 if j==8:
177 if j==8:
178 i=i+1
178 i=i+1
179 j=0
179 j=0
180
180
181 pos = [i,j]
181 pos = [i,j]
182 return pos
182 return pos
183
183
184
184
185 def fromBinary2Char(binary_string):
185 def fromBinary2Char(binary_string):
186 number = int(binary_string, 2)
186 number = int(binary_string, 2)
187 #Plus 33 to avoid more than 1 characters values such as: '\x01'-'\x1f'
187 #Plus 33 to avoid more than 1 characters values such as: '\x01'-'\x1f'
188 number = number + 33
188 number = number + 33
189 char = chr(number)
189 char = chr(number)
190 return char
190 return char
191
191
192 def fromChar2Binary(char):
192 def fromChar2Binary(char):
193 number = ord(char) - 33
193 number = ord(char) - 33
194 #Minus 33 to get the real value
194 #Minus 33 to get the real value
195 bits = bin(number)[2:]
195 bits = bin(number)[2:]
196 #To ensure we have a string with 6bits
196 #To ensure we have a string with 6bits
197 if len(bits) < 6:
197 if len(bits) < 6:
198 bits = bits.zfill(6)
198 bits = bits.zfill(6)
199 return bits
199 return bits
200
200
201 OPERATION_MODES = (
201 OPERATION_MODES = (
202 (0, 'Manual'),
202 (0, 'Manual'),
203 (1, 'Automatic'),
203 (1, 'Automatic'),
204 )
204 )
205
205
206
206
207 class ABSConfiguration(Configuration):
207 class ABSConfiguration(Configuration):
208 active_beam = models.PositiveSmallIntegerField(verbose_name='Active Beam', default=0)
208 active_beam = models.PositiveSmallIntegerField(verbose_name='Active Beam', default=0)
209 module_status = models.CharField(verbose_name='Module Status', max_length=10000, default=status_default)
209 module_status = models.CharField(verbose_name='Module Status', max_length=10000, default=status_default)
210 operation_mode = models.PositiveSmallIntegerField(verbose_name='Operation Mode', choices=OPERATION_MODES, default = 0)
210 operation_mode = models.PositiveSmallIntegerField(verbose_name='Operation Mode', choices=OPERATION_MODES, default = 0)
211 operation_value = models.FloatField(verbose_name='Periodic (seconds)', default="10", null=True, blank=True)
211 operation_value = models.FloatField(verbose_name='Periodic (seconds)', default="10", null=True, blank=True)
212 module_messages = models.CharField(verbose_name='Modules Messages', max_length=10000, default=json.dumps(default_messages))
212 module_messages = models.CharField(verbose_name='Modules Messages', max_length=10000, default=json.dumps(default_messages))
213
213
214 class Meta:
214 class Meta:
215 db_table = 'abs_configurations'
215 db_table = 'abs_configurations'
216
216
217 def get_absolute_url_plot(self):
217 def get_absolute_url_plot(self):
218 return reverse('url_plot_abs_patterns', args=[str(self.id)])
218 return reverse('url_plot_abs_patterns', args=[str(self.id)])
219
219
220
220
221 def parms_to_dict(self):
221 def parms_to_dict(self):
222
222
223 parameters = {}
223 parameters = {}
224
224
225 parameters['device_id'] = self.device.id
225 parameters['device_id'] = self.device.id
226 parameters['label'] = self.label
226 parameters['label'] = self.label
227 parameters['device_type'] = self.device.device_type.name
227 parameters['device_type'] = self.device.device_type.name
228 parameters['beams'] = {}
228 parameters['beams'] = {}
229
229
230 beams = ABSBeam.objects.filter(abs_conf=self)
230 beams = ABSBeam.objects.filter(abs_conf=self)
231 b=1
231 b=1
232 for beam in beams:
232 for beam in beams:
233 #absbeam = ABSBeam.objects.get(pk=beams[beam])
233 #absbeam = ABSBeam.objects.get(pk=beams[beam])
234 parameters['beams']['beam'+str(b)] = beam.parms_to_dict()#absbeam.parms_to_dict()
234 parameters['beams']['beam'+str(b)] = beam.parms_to_dict()#absbeam.parms_to_dict()
235 b+=1
235 b+=1
236
236
237 return parameters
237 return parameters
238
238
239
239
240 def dict_to_parms(self, parameters):
240 def dict_to_parms(self, parameters):
241
241
242 self.label = parameters['label']
242 self.label = parameters['label']
243
243
244 absbeams = ABSBeam.objects.filter(abs_conf=self)
244 absbeams = ABSBeam.objects.filter(abs_conf=self)
245 beams = parameters['beams']
245 beams = parameters['beams']
246
246
247 if absbeams:
247 if absbeams:
248 beams_number = len(beams)
248 beams_number = len(beams)
249 absbeams_number = len(absbeams)
249 absbeams_number = len(absbeams)
250 if beams_number==absbeams_number:
250 if beams_number==absbeams_number:
251 i = 1
251 i = 1
252 for absbeam in absbeams:
252 for absbeam in absbeams:
253 absbeam.dict_to_parms(beams['beam'+str(i)])
253 absbeam.dict_to_parms(beams['beam'+str(i)])
254 i = i+1
254 i = i+1
255 elif beams_number > absbeams_number:
255 elif beams_number > absbeams_number:
256 i = 1
256 i = 1
257 for absbeam in absbeams:
257 for absbeam in absbeams:
258 absbeam.dict_to_parms(beams['beam'+str(i)])
258 absbeam.dict_to_parms(beams['beam'+str(i)])
259 i=i+1
259 i=i+1
260 for x in range(i,beams_number+1):
260 for x in range(i,beams_number+1):
261 new_beam = ABSBeam(
261 new_beam = ABSBeam(
262 name =beams['beam'+str(i)]['name'],
262 name =beams['beam'+str(i)]['name'],
263 antenna =json.dumps(beams['beam'+str(i)]['antenna']),
263 antenna =json.dumps(beams['beam'+str(i)]['antenna']),
264 abs_conf = self,
264 abs_conf = self,
265 tx =json.dumps(beams['beam'+str(i)]['tx']),
265 tx =json.dumps(beams['beam'+str(i)]['tx']),
266 rx =json.dumps(beams['beam'+str(i)]['rx']),
266 rx =json.dumps(beams['beam'+str(i)]['rx']),
267 ues =json.dumps(beams['beam'+str(i)]['ues']),
267 ues =json.dumps(beams['beam'+str(i)]['ues']),
268 only_rx =json.dumps(beams['beam'+str(i)]['only_rx'])
268 only_rx =json.dumps(beams['beam'+str(i)]['only_rx'])
269 )
269 )
270 new_beam.save()
270 new_beam.save()
271 i=i+1
271 i=i+1
272 else: #beams_number < absbeams_number:
272 else: #beams_number < absbeams_number:
273 i = 1
273 i = 1
274 for absbeam in absbeams:
274 for absbeam in absbeams:
275 if i <= beams_number:
275 if i <= beams_number:
276 absbeam.dict_to_parms(beams['beam'+str(i)])
276 absbeam.dict_to_parms(beams['beam'+str(i)])
277 i=i+1
277 i=i+1
278 else:
278 else:
279 absbeam.delete()
279 absbeam.delete()
280 else:
280 else:
281 for beam in beams:
281 for beam in beams:
282 new_beam = ABSBeam(
282 new_beam = ABSBeam(
283 name =beams[beam]['name'],
283 name =beams[beam]['name'],
284 antenna =json.dumps(beams[beam]['antenna']),
284 antenna =json.dumps(beams[beam]['antenna']),
285 abs_conf = self,
285 abs_conf = self,
286 tx =json.dumps(beams[beam]['tx']),
286 tx =json.dumps(beams[beam]['tx']),
287 rx =json.dumps(beams[beam]['rx']),
287 rx =json.dumps(beams[beam]['rx']),
288 ues =json.dumps(beams[beam]['ues']),
288 ues =json.dumps(beams[beam]['ues']),
289 only_rx =json.dumps(beams[beam]['only_rx'])
289 only_rx =json.dumps(beams[beam]['only_rx'])
290 )
290 )
291 new_beam.save()
291 new_beam.save()
292
292
293
293
294
294
295 def update_from_file(self, parameters):
295 def update_from_file(self, parameters):
296
296
297 self.dict_to_parms(parameters)
297 self.dict_to_parms(parameters)
298 self.save()
298 self.save()
299
299
300
300
301 def get_beams(self, **kwargs):
301 def get_beams(self, **kwargs):
302 '''
302 '''
303 This function returns ABS Configuration beams
303 This function returns ABS Configuration beams
304 '''
304 '''
305 return ABSBeam.objects.filter(abs_conf=self.pk, **kwargs)
305 return ABSBeam.objects.filter(abs_conf=self.pk, **kwargs)
306
306
307 def clone(self, **kwargs):
307 def clone(self, **kwargs):
308
308
309 beams = self.get_beams()
309 beams = self.get_beams()
310 self.pk = None
310 self.pk = None
311 self.id = None
311 self.id = None
312 for attr, value in kwargs.items():
312 for attr, value in kwargs.items():
313 setattr(self, attr, value)
313 setattr(self, attr, value)
314 self.save()
314 self.save()
315
315
316 for beam in beams:
316 for beam in beams:
317 beam.clone(abs_conf=self)
317 beam.clone(abs_conf=self)
318
318
319 #-----For Active Beam-----
319 #-----For Active Beam-----
320 new_beams = ABSBeam.objects.filter(abs_conf=self)
320 new_beams = ABSBeam.objects.filter(abs_conf=self)
321 self.active_beam = new_beams[0].id
321 self.active_beam = new_beams[0].id
322 self.save()
322 self.save()
323 #-----For Active Beam-----
323 #-----For Active Beam-----
324 #-----For Device Status---
324 #-----For Device Status---
325 self.device.status = 3
325 self.device.status = 3
326 self.device.save()
326 self.device.save()
327 #-----For Device Status---
327 #-----For Device Status---
328
328
329 return self
329 return self
330
330
331
331
332 def start_device(self):
332 def start_device(self):
333
333
334 if self.device.status == 3:
334 if self.device.status == 3:
335
335
336 try:
336 try:
337 #self.write_device()
337 #self.write_device()
338 send_task('task_change_beam', [self.id],)
338 send_task('task_change_beam', [self.id],)
339 self.message = 'ABS running'
339 self.message = 'ABS running'
340
340
341 except Exception as e:
341 except Exception as e:
342 self.message = str(e)
342 self.message = str(e)
343 return False
343 return False
344
344
345 return True
345 return True
346
346
347 else:
347 else:
348 self.message = 'Please, select Write ABS Device first.'
348 self.message = 'Please, select Write ABS Device first.'
349 return False
349 return False
350
350
351
351
352 def stop_device(self):
352 def stop_device(self):
353
353
354 self.device.status = 2
354 self.device.status = 2
355 self.device.save()
355 self.device.save()
356 self.message = 'ABS has been stopped.'
356 self.message = 'ABS has been stopped.'
357 self.save()
357 self.save()
358
358
359 return True
359 return True
360
360
361
361
362 def write_device(self):
362 def write_device(self):
363
363
364 """
364 """
365 This function sends the beams list to every abs module.
365 This function sends the beams list to every abs module.
366 It needs 'module_conf' function
366 It needs 'module_conf' function
367 """
367 """
368
368
369 beams = ABSBeam.objects.filter(abs_conf=self)
369 beams = ABSBeam.objects.filter(abs_conf=self)
370 nbeams = len(beams)
370 nbeams = len(beams)
371 if self.connected_modules() == 0 :
371 if self.connected_modules() == 0 :
372 self.message = "No ABS Module detected."
372 self.message = "No ABS Module detected."
373 return False
373 return False
374
374
375 #-------------Write each abs module-----------
375 #-------------Write each abs module-----------
376
376
377 if beams:
377 if beams:
378 block_id = 0
378 block_id = 0
379 message = 'SNDF{:03d}{:02d}{:02d}'.format(nbeams, nbeams, block_id)
379 message = 'SNDF{:03d}{:02d}{:02d}'.format(nbeams, nbeams, block_id)
380 for i, status in enumerate(self.module_status):
380 for i, status in enumerate(self.module_status):
381 message += ''.join([fromBinary2Char(beam.module_6bits(i)) for beam in beams])
381 message += ''.join([fromBinary2Char(beam.module_6bits(i)) for beam in beams])
382 status = ['0'] * 64
382 status = ['0'] * 64
383 n = 0
383 n = 0
384
384
385 sock = self.send_multicast(message)
385 sock = self.send_multicast(message)
386
386
387 for i in range(32):
387 for i in range(32):
388 try:
388 try:
389 data, address = sock.recvfrom(1024)
389 data, address = sock.recvfrom(1024)
390 print address, data
390 print address, data
391 if data == '1':
391 if data == '1':
392 status[int(address[0][10:])-1] = '3'
392 status[int(address[0][10:])-1] = '3'
393 elif data == '0':
393 elif data == '0':
394 status[int(address[0][10:])-1] = '1'
394 status[int(address[0][10:])-1] = '1'
395 except Exception as e:
395 except Exception as e:
396 print 'Error {}'.format(e)
396 print 'Error {}'.format(e)
397 n += 1
397 n += 1
398 sock.close()
398 sock.close()
399 else:
399 else:
400 self.message = "ABS Configuration does not have beams"
400 self.message = "ABS Configuration does not have beams"
401 return False
401 return False
402
402
403 if n == 64:
403 if n == 64:
404 self.message = "Could not write ABS Modules"
404 self.message = "Could not write ABS Modules"
405 self.device.status = 0
405 self.device.status = 0
406 self.module_status = ''.join(status)
406 self.module_status = ''.join(status)
407 self.save()
407 self.save()
408 return False
408 return False
409 else:
409 else:
410 self.message = "ABS Beams List have been sent to ABS Modules"
410 self.message = "ABS Beams List have been sent to ABS Modules"
411 self.active_beam = beams[0].pk
411 self.active_beam = beams[0].pk
412
412
413 self.device.status = 3
413 self.device.status = 3
414 self.module_status = ''.join(status)
414 self.module_status = ''.join(status)
415 self.save()
415 self.save()
416
416
417 return True
417 return True
418
418
419
419
420 def read_module(self, module):
420 def read_module(self, module):
421
421
422 """
422 """
423 Read out-bits (up-down) of 1 abs module NOT for Configuration
423 Read out-bits (up-down) of 1 abs module NOT for Configuration
424 """
424 """
425
425
426 ip_address = self.device.ip_address
426 ip_address = self.device.ip_address
427 ip_address = ip_address.split('.')
427 ip_address = ip_address.split('.')
428 module_seq = (ip_address[0],ip_address[1],ip_address[2])
428 module_seq = (ip_address[0],ip_address[1],ip_address[2])
429 dot = '.'
429 dot = '.'
430 module_ip = dot.join(module_seq)+'.'+str(module)
430 module_ip = dot.join(module_seq)+'.'+str(module)
431 module_port = self.device.port_address
431 module_port = self.device.port_address
432 read_route = 'http://'+module_ip+':'+str(module_port)+'/read'
432 read_route = 'http://'+module_ip+':'+str(module_port)+'/read'
433
433
434 module_status = json.loads(self.module_status)
434 module_status = json.loads(self.module_status)
435 print(read_route)
435 print(read_route)
436
436
437 module_bits = ''
437 module_bits = ''
438
438
439 try:
439 try:
440 r_read = requests.get(read_route, timeout=0.5)
440 r_read = requests.get(read_route, timeout=0.5)
441 answer = r_read.json()
441 answer = r_read.json()
442 module_bits = answer['allbits']
442 module_bits = answer['allbits']
443 except:
443 except:
444 return {}
444 return {}
445
445
446 return module_bits
446 return module_bits
447
447
448 def read_device(self):
448 def read_device(self):
449
449
450 parms = {}
450 parms = {}
451 # Reads active modules.
451 # Reads active modules.
452 module_status = json.loads(self.module_status)
452 module_status = json.loads(self.module_status)
453 total = 0
453 total = 0
454 for status in module_status:
454 for status in module_status:
455 if module_status[status] != 0:
455 if module_status[status] != 0:
456 module_bits = self.read_module(int(status))
456 module_bits = self.read_module(int(status))
457 bits={}
457 bits={}
458 if module_bits:
458 if module_bits:
459 bits = (str(module_bits['um2']) + str(module_bits['um1']) + str(module_bits['um0']) +
459 bits = (str(module_bits['um2']) + str(module_bits['um1']) + str(module_bits['um0']) +
460 str(module_bits['dm2']) + str(module_bits['dm1']) + str(module_bits['dm0']) )
460 str(module_bits['dm2']) + str(module_bits['dm1']) + str(module_bits['dm0']) )
461 parms[str(status)] = bits
461 parms[str(status)] = bits
462
462
463 total +=1
463 total +=1
464
464
465 if total==0:
465 if total==0:
466 self.message = "No ABS Module detected. Please select 'Status'."
466 self.message = "No ABS Module detected. Please select 'Status'."
467 return False
467 return False
468
468
469
469
470
470
471 self.message = "ABS Modules have been read"
471 self.message = "ABS Modules have been read"
472 #monitoreo_tx = JROABSClnt_01CeCnMod000000MNTR10
472 #monitoreo_tx = JROABSClnt_01CeCnMod000000MNTR10
473 return parms
473 return parms
474
474
475
475
476 def connected_modules(self):
476 def connected_modules(self):
477 """
477 """
478 This function returns the number of connected abs-modules without updating.
478 This function returns the number of connected abs-modules without updating.
479 """
479 """
480 num = 0
480 num = 0
481 print(self.module_status)
481 print(self.module_status)
482 for i, status in enumerate(self.module_status):
482 for i, status in enumerate(self.module_status):
483 if status != '0':
483 if status != '0':
484 num += 1
484 num += 1
485 #print('status {}:{}'.format(i+1, status))
485 #print('status {}:{}'.format(i+1, status))
486 return num
486 return num
487
487
488 def send_multicast(self, message):
488 def send_multicast(self, message):
489
489
490 multicast_group = ('224.3.29.71', 10000)
490 multicast_group = ('224.3.29.71', 10000)
491 # Create the datagram socket
491 # Create the datagram socket
492 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
492 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
493 sock.settimeout(1)
493 sock.settimeout(1)
494 local_ip = os.environ.get('LOCAL_IP', '127.0.0.1')
494 local_ip = os.environ.get('LOCAL_IP', '192.168.1.128')
495 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip))
495 sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(local_ip))
496 sock.sendto(message, multicast_group)
496 sock.sendto(message, multicast_group)
497 print('Sending ' + message)
497 print('Sending ' + message)
498 return sock
498 return sock
499
499
500 def status_device(self):
500 def status_device(self):
501 """
501 """
502 This function returns the status of all abs-modules as one.
502 This function returns the status of all abs-modules as one.
503 If at least one module is connected, its answer is "1"
503 If at least one module is connected, its answer is "1"
504 """
504 """
505
505
506 sock = self.send_multicast('MNTR')
506 sock = self.send_multicast('MNTR')
507
507
508 n = 0
508 n = 0
509 status = ['0'] * 64
509 status = ['0'] * 64
510 for i in range(32):
510 for i in range(32):
511 #if True:
511 #if True:
512 try:
512 try:
513 address = None
513 address = None
514 data, address = sock.recvfrom(1024)
514 data, address = sock.recvfrom(1024)
515 x = int(address[0][10:])-1
515 x = int(address[0][10:])-1
516 if data[0] == '1':
516 if data[0] == '1':
517 remote = fromChar2Binary(data[1])
517 remote = fromChar2Binary(data[1])
518 local = ABSBeam.objects.get(pk=self.active_beam).module_6bits(x)
518 local = ABSBeam.objects.get(pk=self.active_beam).module_6bits(x)
519 if local == remote:
519 if local == remote:
520 status[x] = '3'
520 status[x] = '3'
521 print('Module: {} connected...igual'.format(address))
521 print('Module: {} connected...igual'.format(address))
522 else:
522 else:
523 status[x] = '2'
523 status[x] = '2'
524 print('Module: {} connected...diferente'.format(address))
524 print('Module: {} connected...diferente'.format(address))
525 elif data[0] == '0':
525 elif data[0] == '0':
526 status[x] = '1'
526 status[x] = '1'
527 n += 1
527 n += 1
528 except:
528 except:
529 print('Module: {} error'.format(address))
529 print('Module: {} error'.format(address))
530 pass
530 pass
531 sock.close()
531 sock.close()
532
532
533 if n > 0:
533 if n > 0:
534 self.message = 'ABS modules Status have been updated.'
534 self.message = 'ABS modules Status have been updated.'
535 self.device.status = 1
535 self.device.status = 1
536 else:
536 else:
537 self.device.status = 0
537 self.device.status = 0
538 self.message = 'No ABS module is connected.'
538 self.message = 'No ABS module is connected.'
539 self.module_status = ''.join(status)
539 self.module_status = ''.join(status)
540 self.save()
540 self.save()
541
541
542 return self.device.status
542 return self.device.status
543
543
544
544
545 def send_beam(self, beam_pos):
545 def send_beam(self, beam_pos):
546 """
546 """
547 This function connects to a multicast group and sends the beam number
547 This function connects to a multicast group and sends the beam number
548 to all abs modules.
548 to all abs modules.
549 """
549 """
550
550
551 # Se manda a cero RC para poder realizar cambio de beam
551 # Se manda a cero RC para poder realizar cambio de beam
552 if self.experiment is None:
552 if self.experiment is None:
553 confs = []
553 confs = []
554 else:
554 else:
555 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
555 confs = Configuration.objects.filter(experiment = self.experiment).filter(type=0)
556 confdds = ''
556 confdds = ''
557 confjars = ''
557 confjars = ''
558 confrc = ''
558 confrc = ''
559 #TO STOP DEVICES: DDS-JARS-RC
559 #TO STOP DEVICES: DDS-JARS-RC
560 for i in range(0,len(confs)):
560 for i in range(0,len(confs)):
561 if i==0:
561 if i==0:
562 for conf in confs:
562 for conf in confs:
563 if conf.device.device_type.name == 'dds':
563 if conf.device.device_type.name == 'dds':
564 confdds = conf
564 confdds = conf
565 confdds.stop_device()
565 confdds.stop_device()
566 break
566 break
567 if i==1:
567 if i==1:
568 for conf in confs:
568 for conf in confs:
569 if conf.device.device_type.name == 'jars':
569 if conf.device.device_type.name == 'jars':
570 confjars = conf
570 confjars = conf
571 confjars.stop_device()
571 confjars.stop_device()
572 break
572 break
573 if i==2:
573 if i==2:
574 for conf in confs:
574 for conf in confs:
575 if conf.device.device_type.name == 'rc':
575 if conf.device.device_type.name == 'rc':
576 confrc = conf
576 confrc = conf
577 confrc.stop_device()
577 confrc.stop_device()
578 break
578 break
579 if beam_pos > 0:
579 if beam_pos > 0:
580 beam_pos = beam_pos - 1
580 beam_pos = beam_pos - 1
581 else:
581 else:
582 beam_pos = 0
582 beam_pos = 0
583
583
584 #El indice del apunte debe ser menor que el numero total de apuntes
584 #El indice del apunte debe ser menor que el numero total de apuntes
585 #El servidor tcp en el embebido comienza a contar desde 0
585 #El servidor tcp en el embebido comienza a contar desde 0
586 status = ['0'] * 64
586 status = ['0'] * 64
587 message = 'CHGB{}'.format(beam_pos)
587 message = 'CHGB{}'.format(beam_pos)
588 sock = self.send_multicast(message)
588 sock = self.send_multicast(message)
589 for i in range(32):
589 for i in range(32):
590 try:
590 try:
591 data, address = sock.recvfrom(1024)
591 data, address = sock.recvfrom(1024)
592 print address, data
592 print address, data
593 if data == '1':
593 if data == '1':
594 status[int(address[0][10:])-1] = '3'
594 status[int(address[0][10:])-1] = '3'
595 elif data == '0':
595 elif data == '0':
596 status[int(address[0][10:])-1] = '1'
596 status[int(address[0][10:])-1] = '1'
597 except Exception as e:
597 except Exception as e:
598 print 'Error {}'.format(e)
598 print 'Error {}'.format(e)
599 pass
599 pass
600
600
601 sock.close()
601 sock.close()
602
602
603 #Start DDS-RC-JARS
603 #Start DDS-RC-JARS
604 if confdds:
604 if confdds:
605 confdds.start_device()
605 confdds.start_device()
606 if confrc:
606 if confrc:
607 #print confrc
607 #print confrc
608 confrc.start_device()
608 confrc.start_device()
609 if confjars:
609 if confjars:
610 confjars.start_device()
610 confjars.start_device()
611
611
612 self.message = "ABS Beam has been changed"
612 self.message = "ABS Beam has been changed"
613 self.module_status = ''.join(status)
613 self.module_status = ''.join(status)
614 self.save()
614 self.save()
615 return True
615 return True
616
616
617
617
618 def get_absolute_url_import(self):
618 def get_absolute_url_import(self):
619 return reverse('url_import_abs_conf', args=[str(self.id)])
619 return reverse('url_import_abs_conf', args=[str(self.id)])
620
620
621
621
622 class ABSBeam(models.Model):
622 class ABSBeam(models.Model):
623
623
624 name = models.CharField(max_length=60, default='Beam')
624 name = models.CharField(max_length=60, default='Beam')
625 antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default)
625 antenna = models.CharField(verbose_name='Antenna', max_length=1000, default=antenna_default)
626 abs_conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration')
626 abs_conf = models.ForeignKey(ABSConfiguration, null=True, verbose_name='ABS Configuration')
627 tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default)
627 tx = models.CharField(verbose_name='Tx', max_length=1000, default=tx_default)
628 rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default)
628 rx = models.CharField(verbose_name='Rx', max_length=1000, default=rx_default)
629 s_time = models.TimeField(verbose_name='Star Time', default='00:00:00')
629 s_time = models.TimeField(verbose_name='Star Time', default='00:00:00')
630 e_time = models.TimeField(verbose_name='End Time', default='23:59:59')
630 e_time = models.TimeField(verbose_name='End Time', default='23:59:59')
631 ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default)
631 ues = models.CharField(verbose_name='Ues', max_length=100, default=ues_default)
632 only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default)
632 only_rx = models.CharField(verbose_name='Only RX', max_length=40, default=onlyrx_default)
633
633
634 class Meta:
634 class Meta:
635 db_table = 'abs_beams'
635 db_table = 'abs_beams'
636
636
637 def __unicode__(self):
637 def __unicode__(self):
638 return u'%s' % (self.name)
638 return u'%s' % (self.name)
639
639
640 def parms_to_dict(self):
640 def parms_to_dict(self):
641
641
642 parameters = {}
642 parameters = {}
643 parameters['name'] = self.name
643 parameters['name'] = self.name
644 parameters['antenna'] = ast.literal_eval(self.antenna)
644 parameters['antenna'] = ast.literal_eval(self.antenna)
645 parameters['abs_conf'] = self.abs_conf.name
645 parameters['abs_conf'] = self.abs_conf.name
646 parameters['tx'] = ast.literal_eval(self.tx)
646 parameters['tx'] = ast.literal_eval(self.tx)
647 parameters['rx'] = ast.literal_eval(self.rx)
647 parameters['rx'] = ast.literal_eval(self.rx)
648 parameters['s_time'] = self.s_time.strftime("%H:%M:%S")
648 parameters['s_time'] = self.s_time.strftime("%H:%M:%S")
649 parameters['e_time'] = self.e_time.strftime("%H:%M:%S")
649 parameters['e_time'] = self.e_time.strftime("%H:%M:%S")
650 parameters['ues'] = ast.literal_eval(self.ues)
650 parameters['ues'] = ast.literal_eval(self.ues)
651 parameters['only_rx'] = json.loads(self.only_rx)
651 parameters['only_rx'] = json.loads(self.only_rx)
652
652
653 return parameters
653 return parameters
654
654
655 def dict_to_parms(self, parameters):
655 def dict_to_parms(self, parameters):
656
656
657 self.name = parameters['name']
657 self.name = parameters['name']
658 self.antenna = json.dumps(parameters['antenna'])
658 self.antenna = json.dumps(parameters['antenna'])
659 #self.abs_conf = parameters['abs_conf']
659 #self.abs_conf = parameters['abs_conf']
660 self.tx = json.dumps(parameters['tx'])
660 self.tx = json.dumps(parameters['tx'])
661 self.rx = json.dumps(parameters['rx'])
661 self.rx = json.dumps(parameters['rx'])
662 #self.s_time = parameters['s_time']
662 #self.s_time = parameters['s_time']
663 #self.e_time = parameters['e_time']
663 #self.e_time = parameters['e_time']
664 self.ues = json.dumps(parameters['ues'])
664 self.ues = json.dumps(parameters['ues'])
665 self.only_rx = json.dumps(parameters['only_rx'])
665 self.only_rx = json.dumps(parameters['only_rx'])
666 self.save()
666 self.save()
667
667
668
668
669 def clone(self, **kwargs):
669 def clone(self, **kwargs):
670
670
671 self.pk = None
671 self.pk = None
672 self.id = None
672 self.id = None
673 for attr, value in kwargs.items():
673 for attr, value in kwargs.items():
674 setattr(self, attr, value)
674 setattr(self, attr, value)
675
675
676 self.save()
676 self.save()
677
677
678 return self
678 return self
679
679
680
680
681 def module_6bits(self, module):
681 def module_6bits(self, module):
682 """
682 """
683 This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module
683 This function reads antenna pattern and choose 6bits (upbits-downbits) for one abs module
684 """
684 """
685 module += 1
685 module += 1
686 if module > 64:
686 if module > 64:
687 beam_bits = ""
687 beam_bits = ""
688 return beam_bits
688 return beam_bits
689
689
690 data = ast.literal_eval(self.antenna)
690 data = ast.literal_eval(self.antenna)
691 up_data = data['antenna_up']
691 up_data = data['antenna_up']
692 down_data = data['antenna_down']
692 down_data = data['antenna_down']
693
693
694 pos = ip2position(module)
694 pos = ip2position(module)
695 up_value = up_data[pos[0]][pos[1]]
695 up_value = up_data[pos[0]][pos[1]]
696 down_value = down_data[pos[0]][pos[1]]
696 down_value = down_data[pos[0]][pos[1]]
697
697
698 up_bits = up_conv_bits(up_value)
698 up_bits = up_conv_bits(up_value)
699 down_bits = down_conv_bits(down_value)
699 down_bits = down_conv_bits(down_value)
700 beam_bits = up_bits+down_bits
700 beam_bits = up_bits+down_bits
701
701
702 return beam_bits
702 return beam_bits
703
703
704
704
705 @property
705 @property
706 def get_upvalues(self):
706 def get_upvalues(self):
707 """
707 """
708 This function reads antenna pattern and show the up-value of one abs module
708 This function reads antenna pattern and show the up-value of one abs module
709 """
709 """
710
710
711 data = ast.literal_eval(self.antenna)
711 data = ast.literal_eval(self.antenna)
712 up_data = data['antenna_up']
712 up_data = data['antenna_up']
713
713
714 up_values = []
714 up_values = []
715 for data in up_data:
715 for data in up_data:
716 for i in range(0,8):
716 for i in range(0,8):
717 up_values.append(data[i])
717 up_values.append(data[i])
718
718
719 return up_values
719 return up_values
720
720
721 @property
721 @property
722 def antenna_upvalues(self):
722 def antenna_upvalues(self):
723 """
723 """
724 This function reads antenna pattern and show the up - values of one abs beam
724 This function reads antenna pattern and show the up - values of one abs beam
725 in a particular order
725 in a particular order
726 """
726 """
727 data = ast.literal_eval(self.antenna)
727 data = ast.literal_eval(self.antenna)
728 up_data = data['antenna_up']
728 up_data = data['antenna_up']
729
729
730 return up_data
730 return up_data
731
731
732 @property
732 @property
733 def antenna_downvalues(self):
733 def antenna_downvalues(self):
734 """
734 """
735 This function reads antenna pattern and show the down - values of one abs beam
735 This function reads antenna pattern and show the down - values of one abs beam
736 in a particular order
736 in a particular order
737 """
737 """
738 data = ast.literal_eval(self.antenna)
738 data = ast.literal_eval(self.antenna)
739 down_data = data['antenna_down']
739 down_data = data['antenna_down']
740
740
741 return down_data
741 return down_data
742
742
743 @property
743 @property
744 def get_downvalues(self):
744 def get_downvalues(self):
745 """
745 """
746 This function reads antenna pattern and show the down-value of one abs module
746 This function reads antenna pattern and show the down-value of one abs module
747 """
747 """
748
748
749 data = ast.literal_eval(self.antenna)
749 data = ast.literal_eval(self.antenna)
750 down_data = data['antenna_down']
750 down_data = data['antenna_down']
751
751
752 down_values = []
752 down_values = []
753 for data in down_data:
753 for data in down_data:
754 for i in range(0,8):
754 for i in range(0,8):
755 down_values.append(data[i])
755 down_values.append(data[i])
756
756
757 return down_values
757 return down_values
758
758
759 @property
759 @property
760 def get_up_ues(self):
760 def get_up_ues(self):
761 """
761 """
762 This function shows the up-ues-value of one beam
762 This function shows the up-ues-value of one beam
763 """
763 """
764 data = ast.literal_eval(self.ues)
764 data = ast.literal_eval(self.ues)
765 up_ues = data['up']
765 up_ues = data['up']
766
766
767 return up_ues
767 return up_ues
768
768
769 @property
769 @property
770 def get_down_ues(self):
770 def get_down_ues(self):
771 """
771 """
772 This function shows the down-ues-value of one beam
772 This function shows the down-ues-value of one beam
773 """
773 """
774 data = ast.literal_eval(self.ues)
774 data = ast.literal_eval(self.ues)
775 down_ues = data['down']
775 down_ues = data['down']
776
776
777 return down_ues
777 return down_ues
778
778
779 @property
779 @property
780 def get_up_onlyrx(self):
780 def get_up_onlyrx(self):
781 """
781 """
782 This function shows the up-onlyrx-value of one beam
782 This function shows the up-onlyrx-value of one beam
783 """
783 """
784 data = json.loads(self.only_rx)
784 data = json.loads(self.only_rx)
785 up_onlyrx = data['up']
785 up_onlyrx = data['up']
786
786
787 return up_onlyrx
787 return up_onlyrx
788
788
789 @property
789 @property
790 def get_down_onlyrx(self):
790 def get_down_onlyrx(self):
791 """
791 """
792 This function shows the down-onlyrx-value of one beam
792 This function shows the down-onlyrx-value of one beam
793 """
793 """
794 data = json.loads(self.only_rx)
794 data = json.loads(self.only_rx)
795 down_onlyrx = data['down']
795 down_onlyrx = data['down']
796
796
797 return down_onlyrx
797 return down_onlyrx
798
798
799 @property
799 @property
800 def get_tx(self):
800 def get_tx(self):
801 """
801 """
802 This function shows the tx-values of one beam
802 This function shows the tx-values of one beam
803 """
803 """
804 data = json.loads(self.tx)
804 data = json.loads(self.tx)
805
805
806 return data
806 return data
807
807
808 @property
808 @property
809 def get_uptx(self):
809 def get_uptx(self):
810 """
810 """
811 This function shows the up-tx-values of one beam
811 This function shows the up-tx-values of one beam
812 """
812 """
813 data = json.loads(self.tx)
813 data = json.loads(self.tx)
814 up_data = data['up']
814 up_data = data['up']
815
815
816 up_values = []
816 up_values = []
817 for data in up_data:
817 for data in up_data:
818 for i in range(0,8):
818 for i in range(0,8):
819 up_values.append(data[i])
819 up_values.append(data[i])
820
820
821 return up_values
821 return up_values
822
822
823 @property
823 @property
824 def get_downtx(self):
824 def get_downtx(self):
825 """
825 """
826 This function shows the down-tx-values of one beam
826 This function shows the down-tx-values of one beam
827 """
827 """
828 data = json.loads(self.tx)
828 data = json.loads(self.tx)
829 down_data = data['down']
829 down_data = data['down']
830
830
831 down_values = []
831 down_values = []
832 for data in down_data:
832 for data in down_data:
833 for i in range(0,8):
833 for i in range(0,8):
834 down_values.append(data[i])
834 down_values.append(data[i])
835
835
836 return down_values
836 return down_values
837
837
838
838
839
839
840 @property
840 @property
841 def get_rx(self):
841 def get_rx(self):
842 """
842 """
843 This function shows the rx-values of one beam
843 This function shows the rx-values of one beam
844 """
844 """
845 data = json.loads(self.rx)
845 data = json.loads(self.rx)
846
846
847 return data
847 return data
848
848
849 @property
849 @property
850 def get_uprx(self):
850 def get_uprx(self):
851 """
851 """
852 This function shows the up-rx-values of one beam
852 This function shows the up-rx-values of one beam
853 """
853 """
854 data = json.loads(self.rx)
854 data = json.loads(self.rx)
855 up_data = data['up']
855 up_data = data['up']
856
856
857 up_values = []
857 up_values = []
858 for data in up_data:
858 for data in up_data:
859 for i in range(0,8):
859 for i in range(0,8):
860 up_values.append(data[i])
860 up_values.append(data[i])
861
861
862 return up_values
862 return up_values
863
863
864 @property
864 @property
865 def get_downrx(self):
865 def get_downrx(self):
866 """
866 """
867 This function shows the down-rx-values of one beam
867 This function shows the down-rx-values of one beam
868 """
868 """
869 data = json.loads(self.rx)
869 data = json.loads(self.rx)
870 down_data = data['down']
870 down_data = data['down']
871
871
872 down_values = []
872 down_values = []
873 for data in down_data:
873 for data in down_data:
874 for i in range(0,8):
874 for i in range(0,8):
875 down_values.append(data[i])
875 down_values.append(data[i])
876
876
877 return down_values
877 return down_values
@@ -1,806 +1,806
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,'Cancelled'), #YELLOW
78 (1,'Cancelled'), #YELLOW
79 (2,'Running'), #GREEN
79 (2,'Running'), #GREEN
80 (3,'Scheduled'), #BLUE
80 (3,'Scheduled'), #BLUE
81 (4,'Unknown'), #WHITE
81 (4,'Unknown'), #WHITE
82 )
82 )
83
83
84 CONF_TYPES = (
84 CONF_TYPES = (
85 (0, 'Active'),
85 (0, 'Active'),
86 (1, 'Historical'),
86 (1, 'Historical'),
87 )
87 )
88
88
89 class Profile(models.Model):
89 class Profile(models.Model):
90 user = models.OneToOneField(User, on_delete=models.CASCADE)
90 user = models.OneToOneField(User, on_delete=models.CASCADE)
91 theme = models.CharField(max_length=30, default='spacelab')
91 theme = models.CharField(max_length=30, default='spacelab')
92
92
93
93
94 @receiver(post_save, sender=User)
94 @receiver(post_save, sender=User)
95 def create_user_profile(sender, instance, created, **kwargs):
95 def create_user_profile(sender, instance, created, **kwargs):
96 if created:
96 if created:
97 Profile.objects.create(user=instance)
97 Profile.objects.create(user=instance)
98
98
99 @receiver(post_save, sender=User)
99 @receiver(post_save, sender=User)
100 def save_user_profile(sender, instance, **kwargs):
100 def save_user_profile(sender, instance, **kwargs):
101 instance.profile.save()
101 instance.profile.save()
102
102
103
103
104 class Location(models.Model):
104 class Location(models.Model):
105
105
106 name = models.CharField(max_length = 30)
106 name = models.CharField(max_length = 30)
107 description = models.TextField(blank=True, null=True)
107 description = models.TextField(blank=True, null=True)
108
108
109 class Meta:
109 class Meta:
110 db_table = 'db_location'
110 db_table = 'db_location'
111
111
112 def __str__(self):
112 def __str__(self):
113 return u'%s' % self.name
113 return u'%s' % self.name
114
114
115 def get_absolute_url(self):
115 def get_absolute_url(self):
116 return reverse('url_location', args=[str(self.id)])
116 return reverse('url_location', args=[str(self.id)])
117
117
118
118
119 class DeviceType(models.Model):
119 class DeviceType(models.Model):
120
120
121 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc')
121 name = models.CharField(max_length = 10, choices = DEV_TYPES, default = 'rc')
122 sequence = models.PositiveSmallIntegerField(default=1000)
122 sequence = models.PositiveSmallIntegerField(default=1000)
123 description = models.TextField(blank=True, null=True)
123 description = models.TextField(blank=True, null=True)
124
124
125 class Meta:
125 class Meta:
126 db_table = 'db_device_types'
126 db_table = 'db_device_types'
127
127
128 def __str__(self):
128 def __str__(self):
129 return u'%s' % self.get_name_display()
129 return u'%s' % self.get_name_display()
130
130
131 class Device(models.Model):
131 class Device(models.Model):
132
132
133 device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
133 device_type = models.ForeignKey(DeviceType, on_delete=models.CASCADE)
134 location = models.ForeignKey(Location, on_delete=models.CASCADE)
134 location = models.ForeignKey(Location, on_delete=models.CASCADE)
135 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
135 ip_address = models.GenericIPAddressField(protocol='IPv4', default='0.0.0.0')
136 port_address = models.PositiveSmallIntegerField(default=2000)
136 port_address = models.PositiveSmallIntegerField(default=2000)
137 description = models.TextField(blank=True, null=True)
137 description = models.TextField(blank=True, null=True)
138 status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES)
138 status = models.PositiveSmallIntegerField(default=0, choices=DEV_STATES)
139 conf_active = models.PositiveIntegerField(default=0, verbose_name='Current configuration')
139 conf_active = models.PositiveIntegerField(default=0, verbose_name='Current configuration')
140
140
141 class Meta:
141 class Meta:
142 db_table = 'db_devices'
142 db_table = 'db_devices'
143
143
144 def __str__(self):
144 def __str__(self):
145 ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
145 ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
146
146
147 return ret
147 return ret
148
148
149 @property
149 @property
150 def name(self):
150 def name(self):
151 return str(self)
151 return str(self)
152
152
153 def get_status(self):
153 def get_status(self):
154 return self.status
154 return self.status
155
155
156 @property
156 @property
157 def status_color(self):
157 def status_color(self):
158 color = 'muted'
158 color = 'muted'
159 if self.status == 0:
159 if self.status == 0:
160 color = "danger"
160 color = "danger"
161 elif self.status == 1:
161 elif self.status == 1:
162 color = "warning"
162 color = "warning"
163 elif self.status == 2:
163 elif self.status == 2:
164 color = "info"
164 color = "info"
165 elif self.status == 3:
165 elif self.status == 3:
166 color = "success"
166 color = "success"
167
167
168 return color
168 return color
169
169
170 def url(self, path=None):
170 def url(self, path=None):
171
171
172 if path:
172 if path:
173 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
173 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
174 else:
174 else:
175 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
175 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
176
176
177 def get_absolute_url(self):
177 def get_absolute_url(self):
178 return reverse('url_device', args=[str(self.id)])
178 return reverse('url_device', args=[str(self.id)])
179
179
180 def get_absolute_url_edit(self):
180 def get_absolute_url_edit(self):
181 return reverse('url_edit_device', args=[str(self.id)])
181 return reverse('url_edit_device', args=[str(self.id)])
182
182
183 def get_absolute_url_delete(self):
183 def get_absolute_url_delete(self):
184 return reverse('url_delete_device', args=[str(self.id)])
184 return reverse('url_delete_device', args=[str(self.id)])
185
185
186 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
186 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
187
187
188 if self.device_type.name=='dds':
188 if self.device_type.name=='dds':
189 try:
189 try:
190 answer = dds_api.change_ip(ip = self.ip_address,
190 answer = dds_api.change_ip(ip = self.ip_address,
191 port = self.port_address,
191 port = self.port_address,
192 new_ip = ip_address,
192 new_ip = ip_address,
193 mask = mask,
193 mask = mask,
194 gateway = gateway)
194 gateway = gateway)
195 if answer[0]=='1':
195 if answer[0]=='1':
196 self.message = '25|DDS - {}'.format(answer)
196 self.message = '25|DDS - {}'.format(answer)
197 self.ip_address = ip_address
197 self.ip_address = ip_address
198 self.save()
198 self.save()
199 else:
199 else:
200 self.message = '30|DDS - {}'.format(answer)
200 self.message = '30|DDS - {}'.format(answer)
201 return False
201 return False
202 except Exception as e:
202 except Exception as e:
203 self.message = '40|{}'.format(str(e))
203 self.message = '40|{}'.format(str(e))
204 return False
204 return False
205
205
206 elif self.device_type.name=='rc':
206 elif self.device_type.name=='rc':
207 headers = {'content-type': "application/json",
207 headers = {'content-type': "application/json",
208 'cache-control': "no-cache"}
208 'cache-control': "no-cache"}
209
209
210 ip = [int(x) for x in ip_address.split('.')]
210 ip = [int(x) for x in ip_address.split('.')]
211 dns = [int(x) for x in dns.split('.')]
211 dns = [int(x) for x in dns.split('.')]
212 gateway = [int(x) for x in gateway.split('.')]
212 gateway = [int(x) for x in gateway.split('.')]
213 subnet = [int(x) for x in mask.split('.')]
213 subnet = [int(x) for x in mask.split('.')]
214
214
215 payload = {
215 payload = {
216 "ip": ip,
216 "ip": ip,
217 "dns": dns,
217 "dns": dns,
218 "gateway": gateway,
218 "gateway": gateway,
219 "subnet": subnet
219 "subnet": subnet
220 }
220 }
221
221
222 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
222 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
223 try:
223 try:
224 answer = req.json()
224 answer = req.json()
225 if answer['changeip']=='ok':
225 if answer['changeip']=='ok':
226 self.message = '25|IP succesfully changed'
226 self.message = '25|IP succesfully changed'
227 self.ip_address = ip_address
227 self.ip_address = ip_address
228 self.save()
228 self.save()
229 else:
229 else:
230 self.message = '30|An error ocuur when changing IP'
230 self.message = '30|An error ocuur when changing IP'
231 except Exception as e:
231 except Exception as e:
232 self.message = '40|{}'.format(str(e))
232 self.message = '40|{}'.format(str(e))
233 else:
233 else:
234 self.message = 'Not implemented'
234 self.message = 'Not implemented'
235 return False
235 return False
236
236
237 return True
237 return True
238
238
239
239
240 class Campaign(models.Model):
240 class Campaign(models.Model):
241
241
242 template = models.BooleanField(default=False)
242 template = models.BooleanField(default=False)
243 name = models.CharField(max_length=60, unique=True)
243 name = models.CharField(max_length=60, unique=True)
244 start_date = models.DateTimeField(blank=True, null=True)
244 start_date = models.DateTimeField(blank=True, null=True)
245 end_date = models.DateTimeField(blank=True, null=True)
245 end_date = models.DateTimeField(blank=True, null=True)
246 tags = models.CharField(max_length=40, blank=True, null=True)
246 tags = models.CharField(max_length=40, blank=True, null=True)
247 description = models.TextField(blank=True, null=True)
247 description = models.TextField(blank=True, null=True)
248 experiments = models.ManyToManyField('Experiment', blank=True)
248 experiments = models.ManyToManyField('Experiment', blank=True)
249 author = models.ForeignKey(User, null=True, blank=True)
249 author = models.ForeignKey(User, null=True, blank=True)
250
250
251 class Meta:
251 class Meta:
252 db_table = 'db_campaigns'
252 db_table = 'db_campaigns'
253 ordering = ('name',)
253 ordering = ('name',)
254
254
255 def __str__(self):
255 def __str__(self):
256 if self.template:
256 if self.template:
257 return u'{} (template)'.format(self.name)
257 return u'{} (template)'.format(self.name)
258 else:
258 else:
259 return u'{}'.format(self.name)
259 return u'{}'.format(self.name)
260
260
261 def jsonify(self):
261 def jsonify(self):
262
262
263 data = {}
263 data = {}
264
264
265 ignored = ('template')
265 ignored = ('template')
266
266
267 for field in self._meta.fields:
267 for field in self._meta.fields:
268 if field.name in ignored:
268 if field.name in ignored:
269 continue
269 continue
270 data[field.name] = field.value_from_object(self)
270 data[field.name] = field.value_from_object(self)
271
271
272 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
272 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
273 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
273 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
274
274
275 return data
275 return data
276
276
277 def parms_to_dict(self):
277 def parms_to_dict(self):
278
278
279 params = Params({})
279 params = Params({})
280 params.add(self.jsonify(), 'campaigns')
280 params.add(self.jsonify(), 'campaigns')
281
281
282 for exp in Experiment.objects.filter(campaign = self):
282 for exp in Experiment.objects.filter(campaign = self):
283 params.add(exp.jsonify(), 'experiments')
283 params.add(exp.jsonify(), 'experiments')
284 configurations = Configuration.objects.filter(experiment=exp, type=0)
284 configurations = Configuration.objects.filter(experiment=exp, type=0)
285
285
286 for conf in configurations:
286 for conf in configurations:
287 params.add(conf.jsonify(), 'configurations')
287 params.add(conf.jsonify(), 'configurations')
288 if conf.device.device_type.name=='rc':
288 if conf.device.device_type.name=='rc':
289 for line in conf.get_lines():
289 for line in conf.get_lines():
290 params.add(line.jsonify(), 'lines')
290 params.add(line.jsonify(), 'lines')
291
291
292 return params.data
292 return params.data
293
293
294 def dict_to_parms(self, parms, CONF_MODELS):
294 def dict_to_parms(self, parms, CONF_MODELS):
295
295
296 experiments = Experiment.objects.filter(campaign = self)
296 experiments = Experiment.objects.filter(campaign = self)
297
297
298 if experiments:
298 if experiments:
299 for experiment in experiments:
299 for experiment in experiments:
300 experiment.delete()
300 experiment.delete()
301
301
302 for id_exp in parms['experiments']['allIds']:
302 for id_exp in parms['experiments']['allIds']:
303 exp_parms = parms['experiments']['byId'][id_exp]
303 exp_parms = parms['experiments']['byId'][id_exp]
304 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
304 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
305 exp = Experiment(name='{}'.format(dum))
305 exp = Experiment(name='{}'.format(dum))
306 exp.save()
306 exp.save()
307 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
307 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
308 self.experiments.add(exp)
308 self.experiments.add(exp)
309
309
310 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
310 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
311
311
312 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
312 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
313 self.start_date = camp_parms['start_date']
313 self.start_date = camp_parms['start_date']
314 self.end_date = camp_parms['end_date']
314 self.end_date = camp_parms['end_date']
315 self.tags = camp_parms['tags']
315 self.tags = camp_parms['tags']
316 self.save()
316 self.save()
317
317
318 return self
318 return self
319
319
320 def get_experiments_by_radar(self, radar=None):
320 def get_experiments_by_radar(self, radar=None):
321
321
322 ret = []
322 ret = []
323 if radar:
323 if radar:
324 locations = Location.objects.filter(pk=radar)
324 locations = Location.objects.filter(pk=radar)
325 else:
325 else:
326 locations = set([e.location for e in self.experiments.all()])
326 locations = set([e.location for e in self.experiments.all()])
327
327
328 for loc in locations:
328 for loc in locations:
329 dum = {}
329 dum = {}
330 dum['name'] = loc.name
330 dum['name'] = loc.name
331 dum['id'] = loc.pk
331 dum['id'] = loc.pk
332 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
332 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
333 ret.append(dum)
333 ret.append(dum)
334
334
335 return ret
335 return ret
336
336
337 def get_absolute_url(self):
337 def get_absolute_url(self):
338 return reverse('url_campaign', args=[str(self.id)])
338 return reverse('url_campaign', args=[str(self.id)])
339
339
340 def get_absolute_url_edit(self):
340 def get_absolute_url_edit(self):
341 return reverse('url_edit_campaign', args=[str(self.id)])
341 return reverse('url_edit_campaign', args=[str(self.id)])
342
342
343 def get_absolute_url_delete(self):
343 def get_absolute_url_delete(self):
344 return reverse('url_delete_campaign', args=[str(self.id)])
344 return reverse('url_delete_campaign', args=[str(self.id)])
345
345
346 def get_absolute_url_export(self):
346 def get_absolute_url_export(self):
347 return reverse('url_export_campaign', args=[str(self.id)])
347 return reverse('url_export_campaign', args=[str(self.id)])
348
348
349 def get_absolute_url_import(self):
349 def get_absolute_url_import(self):
350 return reverse('url_import_campaign', args=[str(self.id)])
350 return reverse('url_import_campaign', args=[str(self.id)])
351
351
352
352
353 class RunningExperiment(models.Model):
353 class RunningExperiment(models.Model):
354 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
354 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
355 running_experiment = models.ManyToManyField('Experiment', blank = True)
355 running_experiment = models.ManyToManyField('Experiment', blank = True)
356 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
356 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
357
357
358
358
359 class Experiment(models.Model):
359 class Experiment(models.Model):
360
360
361 template = models.BooleanField(default=False)
361 template = models.BooleanField(default=False)
362 name = models.CharField(max_length=40, default='', unique=True)
362 name = models.CharField(max_length=40, default='', unique=True)
363 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
363 location = models.ForeignKey('Location', null=True, blank=True, on_delete=models.CASCADE)
364 freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
364 freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
365 start_time = models.TimeField(default='00:00:00')
365 start_time = models.TimeField(default='00:00:00')
366 end_time = models.TimeField(default='23:59:59')
366 end_time = models.TimeField(default='23:59:59')
367 task = models.CharField(max_length=36, default='', blank=True, null=True)
367 task = models.CharField(max_length=36, default='', blank=True, null=True)
368 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
368 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
369 author = models.ForeignKey(User, null=True, blank=True)
369 author = models.ForeignKey(User, null=True, blank=True)
370 hash = models.CharField(default='', max_length=64, null=True, blank=True)
370 hash = models.CharField(default='', max_length=64, null=True, blank=True)
371
371
372 class Meta:
372 class Meta:
373 db_table = 'db_experiments'
373 db_table = 'db_experiments'
374 ordering = ('template', 'name')
374 ordering = ('template', 'name')
375
375
376 def __str__(self):
376 def __str__(self):
377 if self.template:
377 if self.template:
378 return u'%s (template)' % (self.name)
378 return u'%s (template)' % (self.name)
379 else:
379 else:
380 return u'%s' % (self.name)
380 return u'%s' % (self.name)
381
381
382 def jsonify(self):
382 def jsonify(self):
383
383
384 data = {}
384 data = {}
385
385
386 ignored = ('template')
386 ignored = ('template')
387
387
388 for field in self._meta.fields:
388 for field in self._meta.fields:
389 if field.name in ignored:
389 if field.name in ignored:
390 continue
390 continue
391 data[field.name] = field.value_from_object(self)
391 data[field.name] = field.value_from_object(self)
392
392
393 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
393 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
394 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
394 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
395 data['location'] = self.location.name
395 data['location'] = self.location.name
396 data['configurations'] = ['{}'.format(conf.pk) for
396 data['configurations'] = ['{}'.format(conf.pk) for
397 conf in Configuration.objects.filter(experiment=self, type=0)]
397 conf in Configuration.objects.filter(experiment=self, type=0)]
398
398
399 return data
399 return data
400
400
401 @property
401 @property
402 def radar_system(self):
402 def radar_system(self):
403 return self.location
403 return self.location
404
404
405 def clone(self, **kwargs):
405 def clone(self, **kwargs):
406
406
407 confs = Configuration.objects.filter(experiment=self, type=0)
407 confs = Configuration.objects.filter(experiment=self, type=0)
408 self.pk = None
408 self.pk = None
409 self.name = '{}_{:%y%m%d}'.format(self.name, datetime.now())
409 self.name = '{}_{:%y%m%d}'.format(self.name, datetime.now())
410 for attr, value in kwargs.items():
410 for attr, value in kwargs.items():
411 setattr(self, attr, value)
411 setattr(self, attr, value)
412
412
413 self.save()
413 self.save()
414
414
415 for conf in confs:
415 for conf in confs:
416 conf.clone(experiment=self, template=False)
416 conf.clone(experiment=self, template=False)
417
417
418 return self
418 return self
419
419
420 def start(self):
420 def start(self):
421 '''
421 '''
422 Configure and start experiments's devices
422 Configure and start experiments's devices
423 ABS-CGS-DDS-RC-JARS
423 ABS-CGS-DDS-RC-JARS
424 '''
424 '''
425
425
426 confs = []
426 confs = []
427 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
427 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
428 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix]
428 rc_mix = [conf for conf in allconfs if conf.device.device_type.name=='rc' and conf.mix]
429 if rc_mix:
429 if rc_mix:
430 for conf in allconfs:
430 for conf in allconfs:
431 if conf.device.device_type.name == 'rc' and not conf.mix:
431 if conf.device.device_type.name == 'rc' and not conf.mix:
432 continue
432 continue
433 confs.append(conf)
433 confs.append(conf)
434 else:
434 else:
435 confs = allconfs
435 confs = allconfs
436
436
437 try:
437 try:
438 for conf in confs:
438 for conf in confs:
439 conf.stop_device()
439 conf.stop_device()
440 conf.write_device()
440 conf.write_device()
441 conf.device.conf_active = conf.pk
441 conf.device.conf_active = conf.pk
442 conf.device.save()
442 conf.device.save()
443 conf.start_device()
443 conf.start_device()
444 time.sleep(1)
444 time.sleep(1)
445 except:
445 except:
446 return 0
446 return 0
447 return 2
447 return 2
448
448
449
449
450 def stop(self):
450 def stop(self):
451 '''
451 '''
452 Stop experiments's devices
452 Stop experiments's devices
453 DDS-JARS-RC-CGS-ABS
453 DDS-JARS-RC-CGS-ABS
454 '''
454 '''
455
455
456 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
456 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
457 confs=confs.exclude(device__device_type__name='cgs')
457 confs=confs.exclude(device__device_type__name='cgs')
458 try:
458 try:
459 for conf in confs:
459 for conf in confs:
460 conf.stop_device()
460 conf.stop_device()
461 except:
461 except:
462 return 0
462 return 0
463 return 1
463 return 1
464
464
465 def get_status(self):
465 def get_status(self):
466
466
467 if self.status == 3:
467 if self.status == 3:
468 return
468 return
469
469
470 confs = Configuration.objects.filter(experiment=self, type=0)
470 confs = Configuration.objects.filter(experiment=self, type=0)
471
471
472 for conf in confs:
472 for conf in confs:
473 conf.status_device()
473 conf.status_device()
474
474
475 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
475 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
476
476
477 if total==2*confs.count():
477 if total==2*confs.count():
478 status = 1
478 status = 1
479 elif total == 3*confs.count():
479 elif total == 3*confs.count():
480 status = 2
480 status = 2
481 else:
481 else:
482 status = 0
482 status = 0
483
483
484 self.status = status
484 self.status = status
485 self.save()
485 self.save()
486
486
487 def status_color(self):
487 def status_color(self):
488 color = 'muted'
488 color = 'muted'
489 if self.status == 0:
489 if self.status == 0:
490 color = "danger"
490 color = "danger"
491 elif self.status == 1:
491 elif self.status == 1:
492 color = "warning"
492 color = "warning"
493 elif self.status == 2:
493 elif self.status == 2:
494 color = "success"
494 color = "success"
495 elif self.status == 3:
495 elif self.status == 3:
496 color = "info"
496 color = "info"
497
497
498 return color
498 return color
499
499
500 def parms_to_dict(self):
500 def parms_to_dict(self):
501
501
502 params = Params({})
502 params = Params({})
503 params.add(self.jsonify(), 'experiments')
503 params.add(self.jsonify(), 'experiments')
504
504
505 configurations = Configuration.objects.filter(experiment=self, type=0)
505 configurations = Configuration.objects.filter(experiment=self, type=0)
506
506
507 for conf in configurations:
507 for conf in configurations:
508 params.add(conf.jsonify(), 'configurations')
508 params.add(conf.jsonify(), 'configurations')
509 if conf.device.device_type.name=='rc':
509 if conf.device.device_type.name=='rc':
510 for line in conf.get_lines():
510 for line in conf.get_lines():
511 params.add(line.jsonify(), 'lines')
511 params.add(line.jsonify(), 'lines')
512
512
513 return params.data
513 return params.data
514
514
515 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
515 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
516
516
517 configurations = Configuration.objects.filter(experiment=self)
517 configurations = Configuration.objects.filter(experiment=self)
518
518
519 if id_exp is not None:
519 if id_exp is not None:
520 exp_parms = parms['experiments']['byId'][id_exp]
520 exp_parms = parms['experiments']['byId'][id_exp]
521 else:
521 else:
522 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
522 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
523
523
524 if configurations:
524 if configurations:
525 for configuration in configurations:
525 for configuration in configurations:
526 configuration.delete()
526 configuration.delete()
527
527
528 for id_conf in exp_parms['configurations']:
528 for id_conf in exp_parms['configurations']:
529 conf_parms = parms['configurations']['byId'][id_conf]
529 conf_parms = parms['configurations']['byId'][id_conf]
530 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
530 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
531 model = CONF_MODELS[conf_parms['device_type']]
531 model = CONF_MODELS[conf_parms['device_type']]
532 conf = model(
532 conf = model(
533 experiment = self,
533 experiment = self,
534 device = device,
534 device = device,
535 )
535 )
536 conf.dict_to_parms(parms, id=id_conf)
536 conf.dict_to_parms(parms, id=id_conf)
537
537
538
538
539 location, created = Location.objects.get_or_create(name=exp_parms['location'])
539 location, created = Location.objects.get_or_create(name=exp_parms['location'])
540 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
540 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
541 self.location = location
541 self.location = location
542 self.start_time = exp_parms['start_time']
542 self.start_time = exp_parms['start_time']
543 self.end_time = exp_parms['end_time']
543 self.end_time = exp_parms['end_time']
544 self.save()
544 self.save()
545
545
546 return self
546 return self
547
547
548 def get_absolute_url(self):
548 def get_absolute_url(self):
549 return reverse('url_experiment', args=[str(self.id)])
549 return reverse('url_experiment', args=[str(self.id)])
550
550
551 def get_absolute_url_edit(self):
551 def get_absolute_url_edit(self):
552 return reverse('url_edit_experiment', args=[str(self.id)])
552 return reverse('url_edit_experiment', args=[str(self.id)])
553
553
554 def get_absolute_url_delete(self):
554 def get_absolute_url_delete(self):
555 return reverse('url_delete_experiment', args=[str(self.id)])
555 return reverse('url_delete_experiment', args=[str(self.id)])
556
556
557 def get_absolute_url_import(self):
557 def get_absolute_url_import(self):
558 return reverse('url_import_experiment', args=[str(self.id)])
558 return reverse('url_import_experiment', args=[str(self.id)])
559
559
560 def get_absolute_url_export(self):
560 def get_absolute_url_export(self):
561 return reverse('url_export_experiment', args=[str(self.id)])
561 return reverse('url_export_experiment', args=[str(self.id)])
562
562
563 def get_absolute_url_start(self):
563 def get_absolute_url_start(self):
564 return reverse('url_start_experiment', args=[str(self.id)])
564 return reverse('url_start_experiment', args=[str(self.id)])
565
565
566 def get_absolute_url_stop(self):
566 def get_absolute_url_stop(self):
567 return reverse('url_stop_experiment', args=[str(self.id)])
567 return reverse('url_stop_experiment', args=[str(self.id)])
568
568
569
569
570 class Configuration(PolymorphicModel):
570 class Configuration(PolymorphicModel):
571
571
572 template = models.BooleanField(default=False)
572 template = models.BooleanField(default=False)
573 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
573 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
574 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
574 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=True, null=True)
575 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=True, null=True)
575 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
576 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
576 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
577 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
577 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
578 created_date = models.DateTimeField(auto_now_add=True)
578 created_date = models.DateTimeField(auto_now_add=True)
579 programmed_date = models.DateTimeField(auto_now=True)
579 programmed_date = models.DateTimeField(auto_now=True)
580 parameters = models.TextField(default='{}')
580 parameters = models.TextField(default='{}')
581 author = models.ForeignKey(User, null=True, blank=True)
581 author = models.ForeignKey(User, null=True, blank=True)
582 hash = models.CharField(default='', max_length=64, null=True, blank=True)
582 hash = models.CharField(default='', max_length=64, null=True, blank=True)
583 message = ""
583 message = ""
584
584
585 class Meta:
585 class Meta:
586 db_table = 'db_configurations'
586 db_table = 'db_configurations'
587 ordering = ('device__device_type__name',)
587 ordering = ('device__device_type__name',)
588
588
589 def __str__(self):
589 def __str__(self):
590
590
591 ret = u'{} '.format(self.device.device_type.name.upper())
591 ret = u'{} '.format(self.device.device_type.name.upper())
592
592
593 if 'mix' in [f.name for f in self._meta.get_fields()]:
593 if 'mix' in [f.name for f in self._meta.get_fields()]:
594 if self.mix:
594 if self.mix:
595 ret = '{} MIX '.format(self.device.device_type.name.upper())
595 ret = '{} MIX '.format(self.device.device_type.name.upper())
596
596
597 if 'label' in [f.name for f in self._meta.get_fields()]:
597 if 'label' in [f.name for f in self._meta.get_fields()]:
598 ret += '{}'.format(self.label)
598 ret += '{}'.format(self.label)
599
599
600 if self.template:
600 if self.template:
601 ret += ' (template)'
601 ret += ' (template)'
602
602
603 return ret
603 return ret
604
604
605 @property
605 @property
606 def name(self):
606 def name(self):
607
607
608 return str(self)
608 return str(self)
609
609
610 def jsonify(self):
610 def jsonify(self):
611
611
612 data = {}
612 data = {}
613
613
614 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
614 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
615 'created_date', 'programmed_date', 'template', 'device',
615 'created_date', 'programmed_date', 'template', 'device',
616 'experiment')
616 'experiment')
617
617
618 for field in self._meta.fields:
618 for field in self._meta.fields:
619 if field.name in ignored:
619 if field.name in ignored:
620 continue
620 continue
621 data[field.name] = field.value_from_object(self)
621 data[field.name] = field.value_from_object(self)
622
622
623 data['device_type'] = self.device.device_type.name
623 data['device_type'] = self.device.device_type.name
624
624
625 if self.device.device_type.name == 'rc':
625 if self.device.device_type.name == 'rc':
626 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
626 data['lines'] = ['{}'.format(line.pk) for line in self.get_lines()]
627 data['delays'] = self.get_delays()
627 data['delays'] = self.get_delays()
628 data['pulses'] = self.get_pulses()
628 data['pulses'] = self.get_pulses()
629
629
630 elif self.device.device_type.name == 'jars':
630 elif self.device.device_type.name == 'jars':
631 data['decode_type'] = DECODE_TYPE[self.decode_data][1]
631 data['decode_type'] = DECODE_TYPE[self.decode_data][1]
632
632
633 elif self.device.device_type.name == 'dds':
633 elif self.device.device_type.name == 'dds':
634 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
634 data['frequencyA_Mhz'] = float(data['frequencyA_Mhz'])
635 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
635 data['frequencyB_Mhz'] = float(data['frequencyB_Mhz'])
636 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
636 data['phaseA'] = dds_data.phase_to_binary(data['phaseA_degrees'])
637 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
637 data['phaseB'] = dds_data.phase_to_binary(data['phaseB_degrees'])
638
638
639 return data
639 return data
640
640
641 def clone(self, **kwargs):
641 def clone(self, **kwargs):
642
642
643 self.pk = None
643 self.pk = None
644 self.id = None
644 self.id = None
645 for attr, value in kwargs.items():
645 for attr, value in kwargs.items():
646 setattr(self, attr, value)
646 setattr(self, attr, value)
647
647
648 self.save()
648 self.save()
649
649
650 return self
650 return self
651
651
652 def parms_to_dict(self):
652 def parms_to_dict(self):
653
653
654 params = Params({})
654 params = Params({})
655 params.add(self.jsonify(), 'configurations')
655 params.add(self.jsonify(), 'configurations')
656
656
657 if self.device.device_type.name=='rc':
657 if self.device.device_type.name=='rc':
658 for line in self.get_lines():
658 for line in self.get_lines():
659 params.add(line.jsonify(), 'lines')
659 params.add(line.jsonify(), 'lines')
660
660
661 return params.data
661 return params.data
662
662
663 def parms_to_text(self):
663 def parms_to_text(self):
664
664
665 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
665 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
666
666
667
667
668 def parms_to_binary(self):
668 def parms_to_binary(self):
669
669
670 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())
671
671
672
672
673 def dict_to_parms(self, parameters, id=None):
673 def dict_to_parms(self, parameters, id=None):
674
674
675 params = Params(parameters)
675 params = Params(parameters)
676
676
677 if id:
677 if id:
678 data = params.get_conf(id_conf=id)
678 data = params.get_conf(id_conf=id)
679 else:
679 else:
680 data = params.get_conf(dtype=self.device.device_type.name)
680 data = params.get_conf(dtype=self.device.device_type.name)
681
681
682 if data['device_type']=='rc':
682 if data['device_type']=='rc':
683 self.clean_lines()
683 self.clean_lines()
684 lines = data.pop('lines', None)
684 lines = data.pop('lines', None)
685 for line_id in lines:
685 for line_id in lines:
686 pass
686 pass
687
687
688 for key, value in data.items():
688 for key, value in data.items():
689 if key not in ('id', 'device_type'):
689 if key not in ('id', 'device_type'):
690 setattr(self, key, value)
690 setattr(self, key, value)
691
691
692 self.save()
692 self.save()
693
693
694
694
695 def export_to_file(self, format="json"):
695 def export_to_file(self, format="json"):
696
696
697 content_type = ''
697 content_type = ''
698
698
699 if format == 'racp':
699 if format == 'racp':
700 content_type = 'text/plain'
700 content_type = 'text/plain'
701 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
701 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
702 content = self.parms_to_text(file_format = 'racp')
702 content = self.parms_to_text(file_format = 'racp')
703
703
704 if format == 'text':
704 if format == 'text':
705 content_type = 'text/plain'
705 content_type = 'text/plain'
706 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
706 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
707 content = self.parms_to_text()
707 content = self.parms_to_text()
708
708
709 if format == 'binary':
709 if format == 'binary':
710 content_type = 'application/octet-stream'
710 content_type = 'application/octet-stream'
711 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
711 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
712 content = self.parms_to_binary()
712 content = self.parms_to_binary()
713
713
714 if not content_type:
714 if not content_type:
715 content_type = 'application/json'
715 content_type = 'application/json'
716 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
716 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
717 content = json.dumps(self.parms_to_dict(), indent=2)
717 content = json.dumps(self.parms_to_dict(), indent=2)
718
718
719 fields = {'content_type':content_type,
719 fields = {'content_type':content_type,
720 'filename':filename,
720 'filename':filename,
721 'content':content
721 'content':content
722 }
722 }
723
723
724 return fields
724 return fields
725
725
726 def import_from_file(self, fp):
726 def import_from_file(self, fp):
727
727
728 parms = {}
728 parms = {}
729
729
730 path, ext = os.path.splitext(fp.name)
730 path, ext = os.path.splitext(fp.name)
731
731
732 if ext == '.json':
732 if ext == '.json':
733 parms = json.load(fp)
733 parms = json.load(fp)
734
734
735 if ext == '.dds':
735 if ext == '.dds':
736 lines = fp.readlines()
736 lines = fp.readlines()
737 parms = dds_data.text_to_dict(lines)
737 parms = dds_data.text_to_dict(lines)
738
738
739 if ext == '.racp':
739 if ext == '.racp':
740 if self.device.device_type.name == 'jars':
740 if self.device.device_type.name == 'jars':
741 parms = RacpFile(fp).to_dict()
741 parms = RacpFile(fp).to_dict()
742 parms['filter_parms'] = json.loads(self.filter_parms)
742 parms['filter_parms'] = json.loads(self.filter_parms)
743 return parms
743 return parms
744 parms = RCFile(fp).to_dict()
744 parms = RCFile(fp).to_dict()
745
745
746 return parms
746 return parms
747
747
748 def status_device(self):
748 def status_device(self):
749
749
750 self.message = 'Function not implemented'
750 self.message = 'Function not implemented'
751 return False
751 return False
752
752
753
753
754 def stop_device(self):
754 def stop_device(self):
755
755
756 self.message = 'Function not implemented'
756 self.message = 'Function not implemented'
757 return False
757 return False
758
758
759
759
760 def start_device(self):
760 def start_device(self):
761
761
762 self.message = 'Function not implemented'
762 self.message = 'Function not implemented'
763 return False
763 return False
764
764
765
765
766 def write_device(self, parms):
766 def write_device(self, parms):
767
767
768 self.message = 'Function not implemented'
768 self.message = 'Function not implemented'
769 return False
769 return False
770
770
771
771
772 def read_device(self):
772 def read_device(self):
773
773
774 self.message = 'Function not implemented'
774 self.message = 'Function not implemented'
775 return False
775 return False
776
776
777
777
778 def get_absolute_url(self):
778 def get_absolute_url(self):
779 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
779 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
780
780
781 def get_absolute_url_edit(self):
781 def get_absolute_url_edit(self):
782 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
782 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
783
783
784 def get_absolute_url_delete(self):
784 def get_absolute_url_delete(self):
785 return reverse('url_delete_dev_conf', args=[str(self.id)])
785 return reverse('url_delete_dev_conf', args=[str(self.id)])
786
786
787 def get_absolute_url_import(self):
787 def get_absolute_url_import(self):
788 return reverse('url_import_dev_conf', args=[str(self.id)])
788 return reverse('url_import_dev_conf', args=[str(self.id)])
789
789
790 def get_absolute_url_export(self):
790 def get_absolute_url_export(self):
791 return reverse('url_export_dev_conf', args=[str(self.id)])
791 return reverse('url_export_dev_conf', args=[str(self.id)])
792
792
793 def get_absolute_url_write(self):
793 def get_absolute_url_write(self):
794 return reverse('url_write_dev_conf', args=[str(self.id)])
794 return reverse('url_write_dev_conf', args=[str(self.id)])
795
795
796 def get_absolute_url_read(self):
796 def get_absolute_url_read(self):
797 return reverse('url_read_dev_conf', args=[str(self.id)])
797 return reverse('url_read_dev_conf', args=[str(self.id)])
798
798
799 def get_absolute_url_start(self):
799 def get_absolute_url_start(self):
800 return reverse('url_start_dev_conf', args=[str(self.id)])
800 return reverse('url_start_dev_conf', args=[str(self.id)])
801
801
802 def get_absolute_url_stop(self):
802 def get_absolute_url_stop(self):
803 return reverse('url_stop_dev_conf', args=[str(self.id)])
803 return reverse('url_stop_dev_conf', args=[str(self.id)])
804
804
805 def get_absolute_url_status(self):
805 def get_absolute_url_status(self):
806 return reverse('url_status_dev_conf', args=[str(self.id)])
806 return reverse('url_status_dev_conf', args=[str(self.id)])
@@ -1,415 +1,418
1 import os
1 import os
2 import json
2 import json
3
3
4 from django import forms
4 from django import forms
5 from django.utils.safestring import mark_safe
5 from django.utils.safestring import mark_safe
6 from apps.main.models import Device
6 from apps.main.models import Device
7 from apps.main.forms import add_empty_choice
7 from apps.main.forms import add_empty_choice
8 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode, RCClock
8 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode, RCClock
9 from .widgets import KmUnitWidget, KmUnitHzWidget, KmUnitDcWidget, UnitKmWidget, DefaultWidget, CodesWidget, HiddenWidget, HCheckboxSelectMultiple
9 from .widgets import KmUnitWidget, KmUnitHzWidget, KmUnitDcWidget, UnitKmWidget, DefaultWidget, CodesWidget, HiddenWidget, HCheckboxSelectMultiple
10
10
11 def create_choices_from_model(model, conf_id, all_choice=False):
11 def create_choices_from_model(model, conf_id, all_choice=False):
12
12
13 if model=='RCLine':
13 if model=='RCLine':
14 instance = RCConfiguration.objects.get(pk=conf_id)
14 instance = RCConfiguration.objects.get(pk=conf_id)
15 choices = [(line.pk, line.get_name()) for line in instance.get_lines(line_type__name='tx')]
15 choices = [(line.pk, line.get_name()) for line in instance.get_lines(line_type__name='tx')]
16 if all_choice:
16 if all_choice:
17 choices = add_empty_choice(choices, label='All')
17 choices = add_empty_choice(choices, label='All')
18 else:
18 else:
19 instance = globals()[model]
19 instance = globals()[model]
20 choices = instance.objects.all().values_list('pk', 'name')
20 choices = instance.objects.all().values_list('pk', 'name')
21
21
22 return choices
22 return choices
23
23
24
24
25 class ExtFileField(forms.FileField):
25 class ExtFileField(forms.FileField):
26 """
26 """
27 Same as forms.FileField, but you can specify a file extension whitelist.
27 Same as forms.FileField, but you can specify a file extension whitelist.
28
28
29 >>> from django.core.files.uploadedfile import SimpleUploadedFile
29 >>> from django.core.files.uploadedfile import SimpleUploadedFile
30 >>>
30 >>>
31 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
31 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
32 >>>
32 >>>
33 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
33 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
34 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
34 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
35 >>>
35 >>>
36 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
36 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
37 Traceback (most recent call last):
37 Traceback (most recent call last):
38 ...
38 ...
39 ValidationError: [u'Not allowed filetype!']
39 ValidationError: [u'Not allowed filetype!']
40 """
40 """
41 def __init__(self, *args, **kwargs):
41 def __init__(self, *args, **kwargs):
42 extensions = kwargs.pop("extensions")
42 extensions = kwargs.pop("extensions")
43 self.extensions = [i.lower() for i in extensions]
43 self.extensions = [i.lower() for i in extensions]
44
44
45 super(ExtFileField, self).__init__(*args, **kwargs)
45 super(ExtFileField, self).__init__(*args, **kwargs)
46
46
47 def clean(self, *args, **kwargs):
47 def clean(self, *args, **kwargs):
48 data = super(ExtFileField, self).clean(*args, **kwargs)
48 data = super(ExtFileField, self).clean(*args, **kwargs)
49 filename = data.name
49 filename = data.name
50 ext = os.path.splitext(filename)[1]
50 ext = os.path.splitext(filename)[1]
51 ext = ext.lower()
51 ext = ext.lower()
52 if ext not in self.extensions:
52 if ext not in self.extensions:
53 raise forms.ValidationError('Not allowed file type: %s' % ext)
53 raise forms.ValidationError('Not allowed file type: %s' % ext)
54
54
55
55
56 class RCConfigurationForm(forms.ModelForm):
56 class RCConfigurationForm(forms.ModelForm):
57
57
58 def __init__(self, *args, **kwargs):
58 def __init__(self, *args, **kwargs):
59 super(RCConfigurationForm, self).__init__(*args, **kwargs)
59 super(RCConfigurationForm, self).__init__(*args, **kwargs)
60
60
61 instance = getattr(self, 'instance', None)
61 instance = getattr(self, 'instance', None)
62
62
63 if instance and instance.pk:
63 if instance and instance.pk:
64
64
65 devices = Device.objects.filter(device_type__name='rc')
65 devices = Device.objects.filter(device_type__name='rc')
66 if instance.experiment:
66 if instance.experiment:
67 self.fields['experiment'].widget.attrs['read_only'] = True
67 self.fields['experiment'].widget.attrs['read_only'] = True
68 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
68 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
69 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
69 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
70 self.fields['ipp'].widget = KmUnitHzWidget(attrs={'km2unit':instance.km2unit})
70 self.fields['ipp'].widget = KmUnitHzWidget(attrs={'km2unit':instance.km2unit})
71 self.fields['clock'].widget.attrs['readonly'] = True
71 self.fields['clock'].widget.attrs['readonly'] = True
72
72
73 self.fields['time_before'].label = mark_safe(self.fields['time_before'].label)
73 self.fields['time_before'].label = mark_safe(self.fields['time_before'].label)
74 self.fields['time_after'].label = mark_safe(self.fields['time_after'].label)
74 self.fields['time_after'].label = mark_safe(self.fields['time_after'].label)
75
75
76 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
76 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
77 self.fields['experiment'].widget.attrs['readonly'] = True
77 self.fields['experiment'].widget.attrs['readonly'] = True
78
78
79 class Meta:
79 class Meta:
80 model = RCConfiguration
80 model = RCConfiguration
81 exclude = ('type', 'parameters', 'status', 'total_units', 'mix', 'author', 'hash', 'clock_in')
81 exclude = ('type', 'parameters', 'status', 'total_units', 'mix', 'author', 'hash', 'clock_in')
82
82
83 def clean(self):
83 def clean(self):
84 form_data = super(RCConfigurationForm, self).clean()
84 form_data = super(RCConfigurationForm, self).clean()
85
85
86 if 'clock_divider' in form_data:
86 if 'clock_divider' in form_data:
87 if form_data['clock_divider']<1:
87 if form_data['clock_divider']<1:
88 self.add_error('clock_divider', 'Invalid Value')
88 self.add_error('clock_divider', 'Invalid Value')
89 #else:
89 #else:
90 # if form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))%10!=0:
90 # if form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))%10!=0:
91 # self.add_error('ipp', 'Invalid IPP units={}'.format(form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))))
91 # self.add_error('ipp', 'Invalid IPP units={}'.format(form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))))
92
92
93 return form_data
93 return form_data
94
94
95 def save(self, *args, **kwargs):
95 def save(self, *args, **kwargs):
96 conf = super(RCConfigurationForm, self).save(*args, **kwargs)
96 conf = super(RCConfigurationForm, self).save(*args, **kwargs)
97 clk = RCClock.objects.filter(rc_configuration=conf).first()
98 if clk:
99 conf.clock_in = clk.frequency
97 conf.total_units = conf.ipp*conf.ntx*conf.km2unit
100 conf.total_units = conf.ipp*conf.ntx*conf.km2unit
98 conf.save()
101 conf.save()
99 return conf
102 return conf
100
103
101
104
102 class RCMixConfigurationForm(forms.Form):
105 class RCMixConfigurationForm(forms.Form):
103
106
104 clock_in = forms.CharField(widget=forms.HiddenInput())
107 clock_in = forms.CharField(widget=forms.HiddenInput())
105 clock_divider = forms.CharField(widget=forms.HiddenInput())
108 clock_divider = forms.CharField(widget=forms.HiddenInput())
106 name = forms.CharField()
109 name = forms.CharField()
107 experiment = forms.ChoiceField()
110 experiment = forms.ChoiceField()
108 mode = forms.ChoiceField(widget=forms.RadioSelect(),
111 mode = forms.ChoiceField(widget=forms.RadioSelect(),
109 choices=[(0, 'Parallel'), (1, 'Sequence')],
112 choices=[(0, 'Parallel'), (1, 'Sequence')],
110 initial=0)
113 initial=0)
111 operation = forms.ChoiceField(widget=forms.RadioSelect(),
114 operation = forms.ChoiceField(widget=forms.RadioSelect(),
112 choices=[(0, 'OR'), (1, 'XOR'), (2, 'AND'), (3, 'NAND')],
115 choices=[(0, 'OR'), (1, 'XOR'), (2, 'AND'), (3, 'NAND')],
113 initial=1)
116 initial=1)
114 delay = forms.CharField()
117 delay = forms.CharField()
115 mask = forms.MultipleChoiceField(
118 mask = forms.MultipleChoiceField(
116 choices=[(0, 'L1'),(1, 'L2'),(2, 'L3'),(3, 'L4'),(4, 'L5'),(5, 'L6'),(6, 'L7'),(7, 'L8'),
119 choices=[(0, 'L1'),(1, 'L2'),(2, 'L3'),(3, 'L4'),(4, 'L5'),(5, 'L6'),(6, 'L7'),(7, 'L8'),
117 (8, 'L9'),(9, 'L10'),(10, 'L11'),(11, 'L12'),(12, 'L13'),(13, 'L14'),(14, 'L15'),(15, 'L16')],
120 (8, 'L9'),(9, 'L10'),(10, 'L11'),(11, 'L12'),(12, 'L13'),(13, 'L14'),(14, 'L15'),(15, 'L16')],
118 widget=HCheckboxSelectMultiple())
121 widget=HCheckboxSelectMultiple())
119 result = forms.CharField(required=False,
122 result = forms.CharField(required=False,
120 widget=forms.Textarea(attrs={'readonly':True, 'rows':5, 'class':'tabuled'}))
123 widget=forms.Textarea(attrs={'readonly':True, 'rows':5, 'class':'tabuled'}))
121
124
122 def __init__(self, *args, **kwargs):
125 def __init__(self, *args, **kwargs):
123 confs = kwargs.pop('confs', [])
126 confs = kwargs.pop('confs', [])
124 if confs:
127 if confs:
125 km2unit = confs[0].km2unit
128 km2unit = confs[0].km2unit
126 clock_in = confs[0].clock_in
129 clock_in = confs[0].clock_in
127 clock_divider = confs[0].clock_divider
130 clock_divider = confs[0].clock_divider
128 else:
131 else:
129 km2unit = clock_in = clock_divider = 0
132 km2unit = clock_in = clock_divider = 0
130 super(RCMixConfigurationForm, self).__init__(*args, **kwargs)
133 super(RCMixConfigurationForm, self).__init__(*args, **kwargs)
131 self.fields['experiment'].choices = [(conf.pk, '{} | {}'.format(conf.pk, conf.name)) for conf in confs]
134 self.fields['experiment'].choices = [(conf.pk, '{} | {}'.format(conf.pk, conf.name)) for conf in confs]
132 self.fields['delay'].widget = KmUnitWidget(attrs = {'km2unit':km2unit})
135 self.fields['delay'].widget = KmUnitWidget(attrs = {'km2unit':km2unit})
133 self.fields['clock_in'].initial = clock_in
136 self.fields['clock_in'].initial = clock_in
134 self.fields['clock_divider'].initial = clock_divider
137 self.fields['clock_divider'].initial = clock_divider
135
138
136
139
137 class RCLineForm(forms.ModelForm):
140 class RCLineForm(forms.ModelForm):
138
141
139 def __init__(self, *args, **kwargs):
142 def __init__(self, *args, **kwargs):
140 self.extra_fields = kwargs.pop('extra_fields', [])
143 self.extra_fields = kwargs.pop('extra_fields', [])
141 super(RCLineForm, self).__init__(*args, **kwargs)
144 super(RCLineForm, self).__init__(*args, **kwargs)
142
145
143 if 'initial' in kwargs and 'line_type' in kwargs['initial']:
146 if 'initial' in kwargs and 'line_type' in kwargs['initial']:
144 line_type = RCLineType.objects.get(pk=kwargs['initial']['line_type'])
147 line_type = RCLineType.objects.get(pk=kwargs['initial']['line_type'])
145
148
146 if 'code_id' in kwargs['initial']:
149 if 'code_id' in kwargs['initial']:
147 model_initial = kwargs['initial']['code_id']
150 model_initial = kwargs['initial']['code_id']
148 else:
151 else:
149 model_initial = 0
152 model_initial = 0
150
153
151 params = json.loads(line_type.params)
154 params = json.loads(line_type.params)
152
155
153 for label, value in self.extra_fields.items():
156 for label, value in self.extra_fields.items():
154 if label=='params':
157 if label=='params':
155 continue
158 continue
156
159
157 if 'model' in params[label]:
160 if 'model' in params[label]:
158 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
161 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
159 kwargs['initial']['rc_configuration']),
162 kwargs['initial']['rc_configuration']),
160 initial=model_initial)
163 initial=model_initial)
161
164
162
165
163 else:
166 else:
164 if label=='codes' and 'code_id' in kwargs['initial']:
167 if label=='codes' and 'code_id' in kwargs['initial']:
165 self.fields[label] = forms.CharField(initial=RCLineCode.objects.get(pk=kwargs['initial']['code_id']).codes)
168 self.fields[label] = forms.CharField(initial=RCLineCode.objects.get(pk=kwargs['initial']['code_id']).codes)
166 else:
169 else:
167 self.fields[label] = forms.CharField(initial=value['value'])
170 self.fields[label] = forms.CharField(initial=value['value'])
168
171
169 if label=='codes':
172 if label=='codes':
170 self.fields[label].widget = CodesWidget()
173 self.fields[label].widget = CodesWidget()
171
174
172 if self.data:
175 if self.data:
173 line_type = RCLineType.objects.get(pk=self.data['line_type'])
176 line_type = RCLineType.objects.get(pk=self.data['line_type'])
174
177
175 if 'code_id' in self.data:
178 if 'code_id' in self.data:
176 model_initial = self.data['code_id']
179 model_initial = self.data['code_id']
177 else:
180 else:
178 model_initial = 0
181 model_initial = 0
179
182
180 params = json.loads(line_type.params)
183 params = json.loads(line_type.params)
181
184
182 for label, value in self.extra_fields.items():
185 for label, value in self.extra_fields.items():
183 if label=='params':
186 if label=='params':
184 continue
187 continue
185
188
186 if 'model' in params[label]:
189 if 'model' in params[label]:
187 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
190 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
188 self.data['rc_configuration']),
191 self.data['rc_configuration']),
189 initial=model_initial)
192 initial=model_initial)
190
193
191
194
192 else:
195 else:
193 if label=='codes' and 'code' in self.data:
196 if label=='codes' and 'code' in self.data:
194 self.fields[label] = forms.CharField(initial=self.data['codes'])
197 self.fields[label] = forms.CharField(initial=self.data['codes'])
195 else:
198 else:
196 self.fields[label] = forms.CharField(initial=self.data[label])
199 self.fields[label] = forms.CharField(initial=self.data[label])
197
200
198 if label=='codes':
201 if label=='codes':
199 self.fields[label].widget = CodesWidget()
202 self.fields[label].widget = CodesWidget()
200
203
201
204
202 class Meta:
205 class Meta:
203 model = RCLine
206 model = RCLine
204 fields = ('rc_configuration', 'line_type', 'channel')
207 fields = ('rc_configuration', 'line_type', 'channel')
205 widgets = {
208 widgets = {
206 'channel': forms.HiddenInput(),
209 'channel': forms.HiddenInput(),
207 }
210 }
208
211
209
212
210 def clean(self):
213 def clean(self):
211
214
212 form_data = self.cleaned_data
215 form_data = self.cleaned_data
213 if 'code' in self.data and self.data['TX_ref']=="0":
216 if 'code' in self.data and self.data['TX_ref']=="0":
214 self.add_error('TX_ref', 'Choose a valid TX reference')
217 self.add_error('TX_ref', 'Choose a valid TX reference')
215
218
216 if RCLineType.objects.get(pk=self.data['line_type']).name=='mix':
219 if RCLineType.objects.get(pk=self.data['line_type']).name=='mix':
217 self.add_error('line_type', 'Invalid Line type')
220 self.add_error('line_type', 'Invalid Line type')
218
221
219 return form_data
222 return form_data
220
223
221
224
222 def save(self):
225 def save(self):
223 line = super(RCLineForm, self).save()
226 line = super(RCLineForm, self).save()
224
227
225 #auto add channel
228 #auto add channel
226 line.channel = RCLine.objects.filter(rc_configuration=line.rc_configuration).count()-1
229 line.channel = RCLine.objects.filter(rc_configuration=line.rc_configuration).count()-1
227
230
228 #auto add position for TX, TR & CODE
231 #auto add position for TX, TR & CODE
229 if line.line_type.name in ('tx', ):
232 if line.line_type.name in ('tx', ):
230 line.position = RCLine.objects.filter(rc_configuration=line.rc_configuration, line_type=line.line_type).count()-1
233 line.position = RCLine.objects.filter(rc_configuration=line.rc_configuration, line_type=line.line_type).count()-1
231
234
232 #save extra fields in params
235 #save extra fields in params
233 params = {}
236 params = {}
234 for label, value in self.extra_fields.items():
237 for label, value in self.extra_fields.items():
235 if label=='params':
238 if label=='params':
236 params['params'] = []
239 params['params'] = []
237 elif label=='codes':
240 elif label=='codes':
238 params[label] = [s for s in self.data[label].split('\r\n') if s]
241 params[label] = [s for s in self.data[label].split('\r\n') if s]
239 else:
242 else:
240 params[label] = self.data[label]
243 params[label] = self.data[label]
241 line.params = json.dumps(params)
244 line.params = json.dumps(params)
242 line.save()
245 line.save()
243 return
246 return
244
247
245
248
246 class RCLineViewForm(forms.Form):
249 class RCLineViewForm(forms.Form):
247
250
248 def __init__(self, *args, **kwargs):
251 def __init__(self, *args, **kwargs):
249
252
250 extra_fields = kwargs.pop('extra_fields')
253 extra_fields = kwargs.pop('extra_fields')
251 line = kwargs.pop('line')
254 line = kwargs.pop('line')
252 subform = kwargs.pop('subform', False)
255 subform = kwargs.pop('subform', False)
253 super(RCLineViewForm, self).__init__(*args, **kwargs)
256 super(RCLineViewForm, self).__init__(*args, **kwargs)
254
257
255 if subform:
258 if subform:
256 params = json.loads(line.line_type.params)['params']
259 params = json.loads(line.line_type.params)['params']
257 else:
260 else:
258 params = json.loads(line.line_type.params)
261 params = json.loads(line.line_type.params)
259
262
260 for label, value in extra_fields.items():
263 for label, value in extra_fields.items():
261
264
262 if label=='params':
265 if label=='params':
263 continue
266 continue
264 if 'ref' in label:
267 if 'ref' in label:
265 if value in (0, '0'):
268 if value in (0, '0'):
266 value = 'All'
269 value = 'All'
267 else:
270 else:
268 value = RCLine.objects.get(pk=value).get_name()
271 value = RCLine.objects.get(pk=value).get_name()
269 elif label=='code':
272 elif label=='code':
270 value = RCLineCode.objects.get(pk=value).name
273 value = RCLineCode.objects.get(pk=value).name
271
274
272 self.fields[label] = forms.CharField(initial=value)
275 self.fields[label] = forms.CharField(initial=value)
273
276
274 if 'widget' in params[label]:
277 if 'widget' in params[label]:
275 km2unit = line.rc_configuration.km2unit
278 km2unit = line.rc_configuration.km2unit
276 if params[label]['widget']=='km':
279 if params[label]['widget']=='km':
277 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
280 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
278 elif params[label]['widget']=='unit':
281 elif params[label]['widget']=='unit':
279 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
282 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
280 elif params[label]['widget']=='dc':
283 elif params[label]['widget']=='dc':
281 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
284 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
282 elif params[label]['widget']=='codes':
285 elif params[label]['widget']=='codes':
283 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
286 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
284 else:
287 else:
285 self.fields[label].widget = DefaultWidget(attrs={'disabled':True})
288 self.fields[label].widget = DefaultWidget(attrs={'disabled':True})
286
289
287
290
288 class RCLineEditForm(forms.ModelForm):
291 class RCLineEditForm(forms.ModelForm):
289
292
290 def __init__(self, *args, **kwargs):
293 def __init__(self, *args, **kwargs):
291
294
292 extra_fields = kwargs.pop('extra_fields', [])
295 extra_fields = kwargs.pop('extra_fields', [])
293 conf = kwargs.pop('conf', False)
296 conf = kwargs.pop('conf', False)
294 line = kwargs.pop('line')
297 line = kwargs.pop('line')
295 subform = kwargs.pop('subform', False)
298 subform = kwargs.pop('subform', False)
296
299
297 super(RCLineEditForm, self).__init__(*args, **kwargs)
300 super(RCLineEditForm, self).__init__(*args, **kwargs)
298
301
299 if subform is not False:
302 if subform is not False:
300 params = json.loads(line.line_type.params)['params']
303 params = json.loads(line.line_type.params)['params']
301 count = subform
304 count = subform
302 else:
305 else:
303 params = json.loads(line.line_type.params)
306 params = json.loads(line.line_type.params)
304 count = -1
307 count = -1
305
308
306 for label, value in extra_fields.items():
309 for label, value in extra_fields.items():
307
310
308 if label in ('params',):
311 if label in ('params',):
309 continue
312 continue
310 if 'help' in params[label]:
313 if 'help' in params[label]:
311 help_text = params[label]['help']
314 help_text = params[label]['help']
312 else:
315 else:
313 help_text = ''
316 help_text = ''
314
317
315 if 'model' in params[label]:
318 if 'model' in params[label]:
316 if line.line_type.name=='tr':
319 if line.line_type.name=='tr':
317 all_choice = True
320 all_choice = True
318 else:
321 else:
319 all_choice = False
322 all_choice = False
320 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'], conf.id, all_choice=all_choice),
323 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'], conf.id, all_choice=all_choice),
321 initial=value,
324 initial=value,
322 widget=forms.Select(attrs={'name':'%s|%s|%s' % (count, line.id, label)}),
325 widget=forms.Select(attrs={'name':'%s|%s|%s' % (count, line.id, label)}),
323 help_text=help_text)
326 help_text=help_text)
324
327
325 else:
328 else:
326 self.fields[label] = forms.CharField(initial=value, help_text=help_text)
329 self.fields[label] = forms.CharField(initial=value, help_text=help_text)
327
330
328 if label in ('code', ):
331 if label in ('code', ):
329 self.fields[label].widget = HiddenWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
332 self.fields[label].widget = HiddenWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
330
333
331 elif 'widget' in params[label]:
334 elif 'widget' in params[label]:
332 km2unit = line.rc_configuration.km2unit
335 km2unit = line.rc_configuration.km2unit
333 if params[label]['widget']=='km':
336 if params[label]['widget']=='km':
334 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
337 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
335 elif params[label]['widget']=='unit':
338 elif params[label]['widget']=='unit':
336 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
339 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
337 elif params[label]['widget']=='dc':
340 elif params[label]['widget']=='dc':
338 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
341 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
339 elif params[label]['widget']=='codes':
342 elif params[label]['widget']=='codes':
340 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
343 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
341 else:
344 else:
342 self.fields[label].widget = DefaultWidget(attrs={'line':line, 'name':'%s|%s|%s' % (count, line.id, label)})
345 self.fields[label].widget = DefaultWidget(attrs={'line':line, 'name':'%s|%s|%s' % (count, line.id, label)})
343
346
344
347
345 class Meta:
348 class Meta:
346 model = RCLine
349 model = RCLine
347 exclude = ('rc_configuration', 'line_type', 'channel', 'position', 'params', 'pulses')
350 exclude = ('rc_configuration', 'line_type', 'channel', 'position', 'params', 'pulses')
348
351
349
352
350 class RCSubLineEditForm(forms.Form):
353 class RCSubLineEditForm(forms.Form):
351
354
352 def __init__(self, *args, **kwargs):
355 def __init__(self, *args, **kwargs):
353 extra_fields = kwargs.pop('extra_fields')
356 extra_fields = kwargs.pop('extra_fields')
354 count = kwargs.pop('count')
357 count = kwargs.pop('count')
355 line = kwargs.pop('line')
358 line = kwargs.pop('line')
356 super(RCSubLineEditForm, self).__init__(*args, **kwargs)
359 super(RCSubLineEditForm, self).__init__(*args, **kwargs)
357 for label, value in extra_fields.items():
360 for label, value in extra_fields.items():
358 self.fields[label] = forms.CharField(initial=value,
361 self.fields[label] = forms.CharField(initial=value,
359 widget=forms.TextInput(attrs={'name':'%s|%s|%s' % (count, line, label)}))
362 widget=forms.TextInput(attrs={'name':'%s|%s|%s' % (count, line, label)}))
360
363
361
364
362 class RCImportForm(forms.Form):
365 class RCImportForm(forms.Form):
363
366
364 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
367 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
365
368
366
369
367 class RCLineCodesForm(forms.ModelForm):
370 class RCLineCodesForm(forms.ModelForm):
368
371
369 def __init__(self, *args, **kwargs):
372 def __init__(self, *args, **kwargs):
370 super(RCLineCodesForm, self).__init__(*args, **kwargs)
373 super(RCLineCodesForm, self).__init__(*args, **kwargs)
371
374
372 if 'initial' in kwargs:
375 if 'initial' in kwargs:
373 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
376 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
374 initial=kwargs['initial']['code'])
377 initial=kwargs['initial']['code'])
375 if 'instance' in kwargs:
378 if 'instance' in kwargs:
376 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
379 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
377 initial=kwargs['instance'].pk)
380 initial=kwargs['instance'].pk)
378
381
379 self.fields['codes'].widget = CodesWidget()
382 self.fields['codes'].widget = CodesWidget()
380
383
381
384
382 class Meta:
385 class Meta:
383 model = RCLineCode
386 model = RCLineCode
384 exclude = ('name',)
387 exclude = ('name',)
385
388
386 class RCClockForm(forms.ModelForm):
389 class RCClockForm(forms.ModelForm):
387
390
388 def __init__(self, *args, **kwargs):
391 def __init__(self, *args, **kwargs):
389 super(RCClockForm, self).__init__(*args, **kwargs)
392 super(RCClockForm, self).__init__(*args, **kwargs)
390
393
391 instance = getattr(self, 'instance', None)
394 instance = getattr(self, 'instance', None)
392
395
393 if instance is not None and instance.mode:
396 if instance is not None and instance.mode:
394 self.fields['multiplier'].widget.attrs['readonly'] = True
397 self.fields['multiplier'].widget.attrs['readonly'] = True
395 self.fields['divisor'].widget.attrs['readonly'] = True
398 self.fields['divisor'].widget.attrs['readonly'] = True
396 self.fields['reference'].widget.attrs['readonly'] = True
399 self.fields['reference'].widget.attrs['readonly'] = True
397
400
398
401
399 class Meta:
402 class Meta:
400 model = RCClock
403 model = RCClock
401 exclude = ('rc_configuration',)
404 exclude = ('rc_configuration',)
402
405
403 def clean(self):
406 def clean(self):
404
407
405 form_data = self.cleaned_data
408 form_data = self.cleaned_data
406
409
407 if form_data['mode'] is True and float(form_data['frequency']) not in (60., 55.):
410 if form_data['mode'] is True and float(form_data['frequency']) not in (60., 55.):
408 self.add_error('frequency', 'Only 60 and 55 are valid values in auto mode')
411 self.add_error('frequency', 'Only 60 and 55 are valid values in auto mode')
409 elif form_data['mode'] is False:
412 elif form_data['mode'] is False:
410 if form_data['reference']==0 and not 24<=form_data['multiplier']<=36:
413 if form_data['reference']==0 and not 24<=form_data['multiplier']<=36:
411 self.add_error('multiplier', 'For 25MHz, valid values are between 24 and 36')
414 self.add_error('multiplier', 'For 25MHz, valid values are between 24 and 36')
412 elif form_data['reference']==1 and not 60<=form_data['multiplier']<=90:
415 elif form_data['reference']==1 and not 60<=form_data['multiplier']<=90:
413 self.add_error('multiplier', 'For 10MHz, valid values are between 60 and 90')
416 self.add_error('multiplier', 'For 10MHz, valid values are between 60 and 90')
414
417
415 return form_data No newline at end of file
418 return form_data
General Comments 0
You need to be logged in to leave comments. Login now