##// END OF EJS Templates
Added monitor channel to the RC configuration.
krodriguez -
r414:08d5cd67904a
parent child
Show More
@@ -1,1079 +1,1095
1
1
2
2
3 import ast
3 import ast
4 import json
4 import json
5 import requests
5 import requests
6 import numpy as np
6 import numpy as np
7 from base64 import b64encode
7 from base64 import b64encode
8 from struct import pack
8 from struct import pack
9
9
10 from django.db import models
10 from django.db import models
11 from django.urls import reverse
11 from django.urls import reverse
12 from django.core.validators import MinValueValidator, MaxValueValidator
12 from django.core.validators import MinValueValidator, MaxValueValidator
13
13
14 from apps.main.models import Configuration
14 from apps.main.models import Configuration
15 from apps.main.utils import Params
15 from apps.main.utils import Params
16 from devices.rc import api
16 from devices.rc import api
17 from apps.rc.utils import RCFile
17 from apps.rc.utils import RCFile
18
18
19
19
20 LINE_TYPES = (
20 LINE_TYPES = (
21 ('none', 'Not used'),
21 ('none', 'Not used'),
22 ('tr', 'Transmission/reception selector signal'),
22 ('tr', 'Transmission/reception selector signal'),
23 ('tx', 'A modulating signal (Transmission pulse)'),
23 ('tx', 'A modulating signal (Transmission pulse)'),
24 ('codes', 'BPSK modulating signal'),
24 ('codes', 'BPSK modulating signal'),
25 ('windows', 'Sample window signal'),
25 ('windows', 'Sample window signal'),
26 ('sync', 'Synchronizing signal'),
26 ('sync', 'Synchronizing signal'),
27 ('flip', 'IPP related periodic signal'),
27 ('flip', 'IPP related periodic signal'),
28 ('prog_pulses', 'Programmable pulse'),
28 ('prog_pulses', 'Programmable pulse'),
29 ('mix', 'Mixed line'),
29 ('mix', 'Mixed line'),
30 )
30 )
31
31
32
32
33 SAMPLING_REFS = (
33 SAMPLING_REFS = (
34 ('none', 'No Reference'),
34 ('none', 'No Reference'),
35 ('begin_baud', 'Begin of the first baud'),
35 ('begin_baud', 'Begin of the first baud'),
36 ('first_baud', 'Middle of the first baud'),
36 ('first_baud', 'Middle of the first baud'),
37 ('sub_baud', 'Middle of the sub-baud')
37 ('sub_baud', 'Middle of the sub-baud')
38 )
38 )
39
39
40 DAT_CMDS = {
40 DAT_CMDS = {
41 # Pulse Design commands
41 # Pulse Design commands
42 'DISABLE' : 0, # Disables pulse generation
42 'DISABLE' : 0, # Disables pulse generation
43 'ENABLE' : 24, # Enables pulse generation
43 'ENABLE' : 24, # Enables pulse generation
44 'DELAY_START' : 40, # Write delay status to memory
44 'DELAY_START' : 40, # Write delay status to memory
45 'FLIP_START' : 48, # Write flip status to memory
45 'FLIP_START' : 48, # Write flip status to memory
46 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
46 'SAMPLING_PERIOD' : 64, # Establish Sampling Period
47 'TX_ONE' : 72, # Output '0' in line TX
47 'TX_ONE' : 72, # Output '0' in line TX
48 'TX_ZERO' : 88, # Output '0' in line TX
48 'TX_ZERO' : 88, # Output '0' in line TX
49 'SW_ONE' : 104, # Output '0' in line SW
49 'SW_ONE' : 104, # Output '0' in line SW
50 'SW_ZERO' : 112, # Output '1' in line SW
50 'SW_ZERO' : 112, # Output '1' in line SW
51 'RESTART': 120, # Restarts CR8 Firmware
51 'RESTART': 120, # Restarts CR8 Firmware
52 'CONTINUE' : 253, # Function Unknown
52 'CONTINUE' : 253, # Function Unknown
53 # Commands available to new controllers
53 # Commands available to new controllers
54 # In Pulse Design Executable, the clock divisor code is written as 12 at the start, but it should be written as code 22(below) just before the final enable.
54 # In Pulse Design Executable, the clock divisor code is written as 12 at the start, but it should be written as code 22(below) just before the final enable.
55 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
55 'CLOCK_DIVISOR_INIT' : 12, # Specifies Clock Divisor. Legacy command, ignored in the actual .dat conversion
56 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
56 'CLOCK_DIVISOR_LAST' : 22, # Specifies Clock Divisor (default 60 if not included) syntax: 255,22 254,N-1.
57 'CLOCK_DIVIDER' : 8,
57 'CLOCK_DIVIDER' : 8,
58 }
58 }
59
59
60 MAX_BITS = 8
60 MAX_BITS = 8
61
61
62 # Rotate left: 0b1001 --> 0b0011
62 # Rotate left: 0b1001 --> 0b0011
63 rol = lambda val, r_bits: \
63 rol = lambda val, r_bits: \
64 (val << r_bits%MAX_BITS) & (2**MAX_BITS-1) | \
64 (val << r_bits%MAX_BITS) & (2**MAX_BITS-1) | \
65 ((val & (2**MAX_BITS-1)) >> (MAX_BITS-(r_bits%MAX_BITS)))
65 ((val & (2**MAX_BITS-1)) >> (MAX_BITS-(r_bits%MAX_BITS)))
66
66
67 # Rotate right: 0b1001 --> 0b1100
67 # Rotate right: 0b1001 --> 0b1100
68 ror = lambda val, r_bits: \
68 ror = lambda val, r_bits: \
69 ((val & (2**MAX_BITS-1)) >> r_bits%MAX_BITS) | \
69 ((val & (2**MAX_BITS-1)) >> r_bits%MAX_BITS) | \
70 (val << (MAX_BITS-(r_bits%MAX_BITS)) & (2**MAX_BITS-1))
70 (val << (MAX_BITS-(r_bits%MAX_BITS)) & (2**MAX_BITS-1))
71
71
72
72
73 class RCConfiguration(Configuration):
73 class RCConfiguration(Configuration):
74
74
75 ipp = models.FloatField(verbose_name='IPP [Km]', validators=[MinValueValidator(1)], default=300)
75 ipp = models.FloatField(verbose_name='IPP [Km]', validators=[MinValueValidator(1)], default=300)
76 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1)], default=1)
76 ntx = models.PositiveIntegerField(verbose_name='Number of TX', validators=[MinValueValidator(1)], default=1)
77 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
77 clock_in = models.FloatField(verbose_name='Clock in [MHz]', validators=[MinValueValidator(1), MaxValueValidator(80)], default=1)
78 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
78 clock_divider = models.PositiveIntegerField(verbose_name='Clock divider', validators=[MinValueValidator(1), MaxValueValidator(256)], default=1)
79 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
79 clock = models.FloatField(verbose_name='Clock Master [MHz]', blank=True, default=1)
80 time_before = models.PositiveIntegerField(verbose_name='Time before [&mu;S]', default=12)
80 time_before = models.PositiveIntegerField(verbose_name='Time before [&mu;S]', default=12)
81 time_after = models.PositiveIntegerField(verbose_name='Time after [&mu;S]', default=1)
81 time_after = models.PositiveIntegerField(verbose_name='Time after [&mu;S]', default=1)
82 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
82 sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
83 ch_monitor = models.PositiveIntegerField(verbose_name='Channel Monitor', validators=[MinValueValidator(0), MaxValueValidator(15)], default=6)
83 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
84 sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
84 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
85 control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
85 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
86 control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
86 total_units = models.PositiveIntegerField(default=0)
87 total_units = models.PositiveIntegerField(default=0)
87 mix = models.BooleanField(default=False)
88 mix = models.BooleanField(default=False)
88
89
89 class Meta:
90 class Meta:
90 db_table = 'rc_configurations'
91 db_table = 'rc_configurations'
91
92
92 def get_absolute_url_plot(self):
93 def get_absolute_url_plot(self):
93 return reverse('url_plot_rc_pulses', args=[str(self.id)])
94 return reverse('url_plot_rc_pulses', args=[str(self.id)])
94
95
95 @property
96 @property
96 def ipp_unit(self):
97 def ipp_unit(self):
97
98
98 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
99 return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
99
100
100 @property
101 @property
101 def us2unit(self):
102 def us2unit(self):
102
103
103 return self.clock_in/self.clock_divider
104 return self.clock_in/self.clock_divider
104
105
105 @property
106 @property
106 def km2unit(self):
107 def km2unit(self):
107
108
108 return 20./3*(self.clock_in/self.clock_divider)
109 return 20./3*(self.clock_in/self.clock_divider)
109
110
110 def clone(self, **kwargs):
111 def clone(self, **kwargs):
111
112
112 lines = self.get_lines()
113 lines = self.get_lines()
113 self.pk = None
114 self.pk = None
114 self.id = None
115 self.id = None
115 for attr, value in kwargs.items():
116 for attr, value in kwargs.items():
116 setattr(self, attr, value)
117 setattr(self, attr, value)
117 self.save()
118 self.save()
118
119
119 for line in lines:
120 for line in lines:
120 line.clone(rc_configuration=self)
121 line.clone(rc_configuration=self)
121
122
122 new_lines = self.get_lines()
123 new_lines = self.get_lines()
123 for line in new_lines:
124 for line in new_lines:
124 line_params = json.loads(line.params)
125 line_params = json.loads(line.params)
125 if 'TX_ref' in line_params and (line_params['TX_ref'] != '0'):
126 if 'TX_ref' in line_params and (line_params['TX_ref'] != '0'):
126 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
127 ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
127 line_params['TX_ref'] = ['{}'.format(l.pk) for l in new_lines if l.get_name()==ref_line.get_name()][0]
128 line_params['TX_ref'] = ['{}'.format(l.pk) for l in new_lines if l.get_name()==ref_line.get_name()][0]
128 line.params = json.dumps(line_params)
129 line.params = json.dumps(line_params)
129 line.save()
130 line.save()
130
131
131 return self
132 return self
132
133
133 def get_lines(self, **kwargs):
134 def get_lines(self, **kwargs):
134 '''
135 '''
135 Retrieve configuration lines
136 Retrieve configuration lines
136 '''
137 '''
137
138
138 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
139 return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
139
140
140
141
141 def clean_lines(self):
142 def clean_lines(self):
142 '''
143 '''
143 '''
144 '''
144
145
145 empty_line = RCLineType.objects.get(name='none')
146 empty_line = RCLineType.objects.get(name='none')
146
147
147 for line in self.get_lines():
148 for line in self.get_lines():
148 line.line_type = empty_line
149 line.line_type = empty_line
149 line.params = '{}'
150 line.params = '{}'
150 line.save()
151 line.save()
151
152
152 def dict_to_parms(self, params, id=None):
153 def dict_to_parms(self, params, id=None):
153 '''
154 '''
154 '''
155 '''
155
156
156 if id:
157 if id:
157 data = Params(params).get_conf(id_conf=id)
158 data = Params(params).get_conf(id_conf=id)
158 else:
159 else:
159 data = Params(params).get_conf(dtype='rc')
160 data = Params(params).get_conf(dtype='rc')
160
161
161 #print(data)
162 #print(data)
162 # self.name = data['name']
163 # self.name = data['name']
163 self.ipp = data['ipp']
164 self.ipp = data['ipp']
164 self.ntx = data['ntx']
165 self.ntx = data['ntx']
165 self.clock_in = data['clock_in']
166 self.clock_in = data['clock_in']
166 self.clock_divider = data['clock_divider']
167 self.clock_divider = data['clock_divider']
167 self.clock = data['clock']
168 self.clock = data['clock']
168 self.time_before = data['time_before']
169 self.time_before = data['time_before']
169 self.time_after = data['time_after']
170 self.time_after = data['time_after']
170 self.sync = data['sync']
171 self.sync = data['sync']
171 self.sampling_reference = data['sampling_reference']
172 self.sampling_reference = data['sampling_reference']
172 self.total_units = self.ipp*self.ntx*self.km2unit
173 self.total_units = self.ipp*self.ntx*self.km2unit
173 self.save()
174 self.save()
174 self.clean_lines()
175 self.clean_lines()
175
176
176 #print(params)
177 #print(params)
177
178
178 positions = {'tx':0, 'tr':0}
179 positions = {'tx':0, 'tr':0}
179 for i, id in enumerate(data['lines']):
180 for i, id in enumerate(data['lines']):
180 line_data = params['lines']['byId'][id]
181 line_data = params['lines']['byId'][id]
181 line_type = RCLineType.objects.get(name=line_data['line_type'])
182 line_type = RCLineType.objects.get(name=line_data['line_type'])
182 if line_type.name == 'codes':
183 if line_type.name == 'codes':
183 code = RCLineCode.objects.get(name=line_data['params']['code'])
184 code = RCLineCode.objects.get(name=line_data['params']['code'])
184 line_data['params']['code'] = code.pk
185 line_data['params']['code'] = code.pk
185 if line_type.name == 'tx':
186 if line_type.name == 'tx':
186 position = positions['tx']
187 position = positions['tx']
187 positions['tx'] += 1
188 positions['tx'] += 1
188 elif line_type.name == 'tr':
189 elif line_type.name == 'tr':
189 position = positions['tr']
190 position = positions['tr']
190 positions['tr'] += 1
191 positions['tr'] += 1
191 else:
192 else:
192 position = 0
193 position = 0
193 line, dum = RCLine.objects.update_or_create(
194 line, dum = RCLine.objects.update_or_create(
194 rc_configuration=self,
195 rc_configuration=self,
195 channel=i,
196 channel=i,
196 position=position,
197 position=position,
197 defaults={
198 defaults={
198 'line_type': line_type,
199 'line_type': line_type,
199 'params': json.dumps(line_data['params'])
200 'params': json.dumps(line_data['params'])
200 }
201 }
201 )
202 )
202
203
203 for i, line in enumerate(self.get_lines()):
204 for i, line in enumerate(self.get_lines()):
204 line_params = json.loads(line.params)
205 line_params = json.loads(line.params)
205 if 'TX_ref' in line_params:
206 if 'TX_ref' in line_params:
206 if line_params['TX_ref'] in (0, '0'):
207 if line_params['TX_ref'] in (0, '0'):
207 line_params['TX_ref'] = '0'
208 line_params['TX_ref'] = '0'
208 else:
209 else:
209 ref_id = '{}'.format(line_params['TX_ref'])
210 ref_id = '{}'.format(line_params['TX_ref'])
210 ref_line = params['lines']['byId'][ref_id]
211 ref_line = params['lines']['byId'][ref_id]
211 line_params['TX_ref'] = RCLine.objects.get(
212 line_params['TX_ref'] = RCLine.objects.get(
212 rc_configuration=self,
213 rc_configuration=self,
213 params=json.dumps(ref_line['params'])
214 params=json.dumps(ref_line['params'])
214 ).pk
215 ).pk
215 line.params = json.dumps(line_params)
216 line.params = json.dumps(line_params)
216 print(line.params)
217 print(line.params)
217 line.save()
218 line.save()
218 print("Fin de dict to param")
219 print("Fin de dict to param")
219
220
220 def get_delays(self):
221 def get_delays(self):
221
222
222 pulses = [line.pulses_as_points() for line in self.get_lines()]
223 pulses = [line.pulses_as_points() for line in self.get_lines()]
223 points = [tup for tups in pulses for tup in tups]
224 points = [tup for tups in pulses for tup in tups]
224 points = set([x for tup in points for x in tup])
225 points = set([x for tup in points for x in tup])
225 points = list(points)
226 points = list(points)
226 points.sort()
227 points.sort()
227
228
228 if points[0]!=0:
229 if points[0]!=0:
229 points.insert(0, 0)
230 points.insert(0, 0)
230
231
231 return [points[i+1]-points[i] for i in range(len(points)-1)]
232 return [points[i+1]-points[i] for i in range(len(points)-1)]
232
233
233 def get_pulses(self, binary=True):
234 def get_pulses(self, binary=True):
234
235
235 pulses = [line.pulses_as_points() for line in self.get_lines()]
236 pulses = [line.pulses_as_points() for line in self.get_lines()]
236 tuples = [tup for tups in pulses for tup in tups]
237 tuples = [tup for tups in pulses for tup in tups]
237 points = set([x for tup in tuples for x in tup])
238 points = set([x for tup in tuples for x in tup])
238 points = list(points)
239 points = list(points)
239 points.sort()
240 points.sort()
240 states = []
241 states = []
241 last = [0 for x in pulses]
242 last = [0 for x in pulses]
242 n_pulses = len(pulses)
243 n_pulses = len(pulses)
243 print('len_pulses', n_pulses)
244 print('len_pulses', n_pulses)
244 print('len_points', len(points))
245 print('len_points', len(points))
245 ups_arr = [[] for _ in range(n_pulses)]
246 ups_arr = [[] for _ in range(n_pulses)]
246 dws_arr = [[] for _ in range(n_pulses)]
247 dws_arr = [[] for _ in range(n_pulses)]
247
248
248 for i, tups in enumerate(pulses):
249 for i, tups in enumerate(pulses):
249 ups_arr[i] = [tup[0] for tup in tups if tup!=(0,0)]
250 ups_arr[i] = [tup[0] for tup in tups if tup!=(0,0)]
250 dws_arr[i] = [tup[1] for tup in tups if tup!=(0,0)]
251 dws_arr[i] = [tup[1] for tup in tups if tup!=(0,0)]
251 print('len_points*n_pulses',len(points)*n_pulses)
252 print('len_points*n_pulses',len(points)*n_pulses)
252 #print('ups_arr', ups_arr)
253 #print('ups_arr', ups_arr)
253 #print('dws_arr', dws_arr)
254 #print('dws_arr', dws_arr)
254
255
255 for x in points:
256 for x in points:
256 dum = []
257 dum = []
257 print('loading', x*100/max(points))
258 print('loading', x*100/max(points))
258
259
259 for i in range(n_pulses):
260 for i in range(n_pulses):
260 if x in ups_arr[i]:
261 if x in ups_arr[i]:
261 dum.append(1)
262 dum.append(1)
262 elif x in dws_arr[i]:
263 elif x in dws_arr[i]:
263 dum.append(0)
264 dum.append(0)
264 else:
265 else:
265 dum.append(last[i])
266 dum.append(last[i])
266 #print(dum)
267 #print(dum)
267 states.append(dum)
268 states.append(dum)
268 last = dum
269 last = dum
269
270
270 if binary:
271 if binary:
271 ret = []
272 ret = []
272 for flips in states:
273 for flips in states:
273 flips.reverse()
274 flips.reverse()
274 ret.append(int(''.join([str(x) for x in flips]), 2))
275 ret.append(int(''.join([str(x) for x in flips]), 2))
275 states = ret
276 states = ret
276 #print(states[:-1])
277 #print(states[:-1])
277 #print('len_states',len(states[:-1]))
278 #print('len_states',len(states[:-1]))
278
279
279 return states[:-1]
280 return states[:-1]
280
281
281 def add_cmd(self, cmd):
282 def add_cmd(self, cmd):
282
283
283 if cmd in DAT_CMDS:
284 if cmd in DAT_CMDS:
284 return (255, DAT_CMDS[cmd])
285 return (255, DAT_CMDS[cmd])
285
286
286 def add_data(self, value):
287 def add_data(self, value):
287
288
288 return (254, value-1)
289 return (254, value-1)
289
290
290 def parms_to_binary(self, dat=True):
291 def parms_to_binary(self, dat=True):
291 '''
292 '''
292 Create "dat" stream to be send to CR
293 Create "dat" stream to be send to CR
293 '''
294 '''
294
295
295 data = bytearray()
296 data = bytearray()
296 # create header
297 # create header
297 data.extend(self.add_cmd('DISABLE'))
298 data.extend(self.add_cmd('DISABLE'))
298 data.extend(self.add_cmd('CONTINUE'))
299 data.extend(self.add_cmd('CONTINUE'))
299 data.extend(self.add_cmd('RESTART'))
300 data.extend(self.add_cmd('RESTART'))
300
301
301 if self.control_sw:
302 if self.control_sw:
302 data.extend(self.add_cmd('SW_ONE'))
303 data.extend(self.add_cmd('SW_ONE'))
303 else:
304 else:
304 data.extend(self.add_cmd('SW_ZERO'))
305 data.extend(self.add_cmd('SW_ZERO'))
305
306
306 if self.control_tx:
307 if self.control_tx:
307 data.extend(self.add_cmd('TX_ONE'))
308 data.extend(self.add_cmd('TX_ONE'))
308 else:
309 else:
309 data.extend(self.add_cmd('TX_ZERO'))
310 data.extend(self.add_cmd('TX_ZERO'))
310
311
311 # write divider
312 # write divider
312 data.extend(self.add_cmd('CLOCK_DIVIDER'))
313 data.extend(self.add_cmd('CLOCK_DIVIDER'))
313 data.extend(self.add_data(self.clock_divider))
314 data.extend(self.add_data(self.clock_divider))
314
315
315 # write delays
316 # write delays
316 data.extend(self.add_cmd('DELAY_START'))
317 data.extend(self.add_cmd('DELAY_START'))
317 # first delay is always zero
318 # first delay is always zero
318 data.extend(self.add_data(1))
319 data.extend(self.add_data(1))
319
320
320 delays = self.get_delays()
321 delays = self.get_delays()
321
322
322 for delay in delays:
323 for delay in delays:
323 while delay>252:
324 while delay>252:
324 data.extend(self.add_data(253))
325 data.extend(self.add_data(253))
325 delay -= 253
326 delay -= 253
326 data.extend(self.add_data(int(delay)))
327 data.extend(self.add_data(int(delay)))
327
328
328 # write flips
329 # write flips
329 data.extend(self.add_cmd('FLIP_START'))
330 data.extend(self.add_cmd('FLIP_START'))
330
331
331 states = self.get_pulses(binary=True)
332 states = self.get_pulses(binary=True)
332
333
333
334
334 last = 0
335 last = 0
335 for flip, delay in zip(states, delays):
336 for flip, delay in zip(states, delays):
336 data.extend(self.add_data((flip^last)+1))
337 data.extend(self.add_data((flip^last)+1))
337 last = flip
338 last = flip
338 while delay>252:
339 while delay>252:
339 data.extend(self.add_data(1))
340 data.extend(self.add_data(1))
340 delay -= 253
341 delay -= 253
341
342
342 # write sampling period
343 # write sampling period
343 data.extend(self.add_cmd('SAMPLING_PERIOD'))
344 data.extend(self.add_cmd('SAMPLING_PERIOD'))
344 wins = self.get_lines(line_type__name='windows')
345 wins = self.get_lines(line_type__name='windows')
345 if wins:
346 if wins:
346 win_params = json.loads(wins[0].params)['params']
347 win_params = json.loads(wins[0].params)['params']
347 if win_params:
348 if win_params:
348 dh = int(win_params[0]['resolution']*self.km2unit)
349 dh = int(win_params[0]['resolution']*self.km2unit)
349 else:
350 else:
350 dh = 1
351 dh = 1
351 else:
352 else:
352 dh = 1
353 dh = 1
353 data.extend(self.add_data(dh))
354 data.extend(self.add_data(dh))
354
355
355 # write enable
356 # write enable
356 data.extend(self.add_cmd('ENABLE'))
357 data.extend(self.add_cmd('ENABLE'))
357
358
358 if not dat:
359 if not dat:
359 return data
360 return data
360
361
361 return '\n'.join(['{}'.format(x) for x in data])
362 return '\n'.join(['{}'.format(x) for x in data])
362
363
363 def update_pulses(self):
364 def update_pulses(self):
364 contador = 0
365 contador = 0
365 for line in self.get_lines():
366 for line in self.get_lines():
366 contador=contador+1
367 contador=contador+1
367 print(contador)
368 print(contador)
368 line.update_pulses()
369 line.update_pulses()
369
370
370 def plot_pulses2(self, km=False):
371 def plot_pulses2(self, km=False):
371
372
372 import matplotlib
373 import matplotlib
373 matplotlib.use('Agg')
374 matplotlib.use('Agg')
374 import matplotlib.pyplot as plt
375 import matplotlib.pyplot as plt
375 from bokeh.resources import CDN
376 from bokeh.resources import CDN
376 from bokeh.embed import components
377 from bokeh.embed import components
377 from bokeh.mpl import to_bokeh
378 from bokeh.mpl import to_bokeh
378 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
379 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
379
380
380 lines = self.get_lines()
381 lines = self.get_lines()
381
382
382 N = len(lines)
383 N = len(lines)
383 npoints = self.total_units/self.km2unit if km else self.total_units
384 npoints = self.total_units/self.km2unit if km else self.total_units
384 fig = plt.figure(figsize=(12, 2+N*0.5))
385 fig = plt.figure(figsize=(12, 2+N*0.5))
385 ax = fig.add_subplot(111)
386 ax = fig.add_subplot(111)
386 labels = ['IPP']
387 labels = ['IPP']
387
388
388 for i, line in enumerate(lines):
389 for i, line in enumerate(lines):
389 labels.append(line.get_name(channel=True))
390 labels.append(line.get_name(channel=True))
390 l = ax.plot((0, npoints),(N-i-1, N-i-1))
391 l = ax.plot((0, npoints),(N-i-1, N-i-1))
391 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
392 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
392 ax.broken_barh(points, (N-i-1, 0.5),
393 ax.broken_barh(points, (N-i-1, 0.5),
393 edgecolor=l[0].get_color(), facecolor='none')
394 edgecolor=l[0].get_color(), facecolor='none')
394
395
395 n = 0
396 n = 0
396 f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
397 f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
397 for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
398 for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
398 if n%f==0:
399 if n%f==0:
399 ax.text(x, N, '%s' % n, size=10)
400 ax.text(x, N, '%s' % n, size=10)
400 n += 1
401 n += 1
401
402
402 labels.reverse()
403 labels.reverse()
403 ax.set_yticks(range(len(labels)))
404 ax.set_yticks(range(len(labels)))
404 ax.set_yticklabels(labels)
405 ax.set_yticklabels(labels)
405 ax.set_xlabel = 'Units'
406 ax.set_xlabel = 'Units'
406 plot = to_bokeh(fig, use_pandas=False)
407 plot = to_bokeh(fig, use_pandas=False)
407 plot.tools = [PanTool(dimensions="width"), WheelZoomTool(dimensions="width"), ResetTool(), SaveTool()]
408 plot.tools = [PanTool(dimensions="width"), WheelZoomTool(dimensions="width"), ResetTool(), SaveTool()]
408 plot.toolbar_location="above"
409 plot.toolbar_location="above"
409
410
410 return components(plot, CDN)
411 return components(plot, CDN)
411
412
412 def plot_pulses(self, km=False):
413 def plot_pulses(self, km=False):
413
414
414 from bokeh.plotting import figure
415 from bokeh.plotting import figure
415 from bokeh.resources import CDN
416 from bokeh.resources import CDN
416 from bokeh.embed import components
417 from bokeh.embed import components
417 from bokeh.models import FixedTicker, PrintfTickFormatter, Label
418 from bokeh.models import FixedTicker, PrintfTickFormatter, Label
418 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
419 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
419 from bokeh.models.sources import ColumnDataSource
420 from bokeh.models.sources import ColumnDataSource
420
421
421 lines = self.get_lines().reverse()
422 lines = self.get_lines().reverse()
422
423
423 N = len(lines)
424 N = len(lines)
424 npoints = self.total_units/self.km2unit if km else self.total_units
425 npoints = self.total_units/self.km2unit if km else self.total_units
425 ipp = self.ipp if km else self.ipp*self.km2unit
426 ipp = self.ipp if km else self.ipp*self.km2unit
426
427
427 hover = HoverTool(tooltips=[("Line", "@name"),
428 hover = HoverTool(tooltips=[("Line", "@name"),
428 ("IPP", "@ipp"),
429 ("IPP", "@ipp"),
429 ("X", "@left")])
430 ("X", "@left")])
430
431
431 tools = [PanTool(dimensions="width"),
432 tools = [PanTool(dimensions="width"),
432 WheelZoomTool(dimensions="width"),
433 WheelZoomTool(dimensions="width"),
433 hover, SaveTool()]
434 hover, SaveTool()]
434
435
435 plot = figure(width=1000,
436 plot = figure(width=1000,
436 height=40+N*50,
437 height=40+N*50,
437 y_range = (0, N),
438 y_range = (0, N),
438 tools=tools,
439 tools=tools,
439 toolbar_location='above',
440 toolbar_location='above',
440 toolbar_sticky=False,)
441 toolbar_sticky=False,)
441
442
442 pulses = [line.pulses_as_points() for line in self.get_lines()]
443 pulses = [line.pulses_as_points() for line in self.get_lines()]
443 tuples = [tup for tups in pulses for tup in tups]
444 tuples = [tup for tups in pulses for tup in tups]
444 points = set([x for tup in tuples for x in tup])
445 points = set([x for tup in tuples for x in tup])
445 capacity_bytes = round((8*(len(points)-1)+12)/2) # se divide entre 2 porque la mitad era solo para direcciones
446 capacity_bytes = round((8*(len(points)-1)+12)/2) # se divide entre 2 porque la mitad era solo para direcciones
446 capacity_percent = (capacity_bytes/2097152)*100
447 capacity_percent = (capacity_bytes/2097152)*100
447 # Add the used memory message
448 # Add the used memory message
448 x_label_memory = Label(x=900, y=-1.5, text='Used memory of '+str(capacity_bytes)+'/2097152 bytes ('+'%.3f'%capacity_percent+'%)', text_align="right", x_units='screen', text_font_size='14pt')
449 x_label_memory = Label(x=900, y=-1.5, text='Used memory of '+str(capacity_bytes)+'/2097152 bytes ('+'%.3f'%capacity_percent+'%)', text_align="right", x_units='screen', text_font_size='14pt')
449 plot.add_layout(x_label_memory, 'below')
450 plot.add_layout(x_label_memory, 'below')
450
451
451 plot.xaxis.axis_label = 'Km' if km else 'Units'
452 plot.xaxis.axis_label = 'Km' if km else 'Units'
452 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
453 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
453 plot.yaxis.axis_label = 'Pulses'
454 plot.yaxis.axis_label = 'Pulses'
454 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
455 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
455 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
456 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
456
457
457 for i, line in enumerate(lines):
458 for i, line in enumerate(lines):
458
459
459 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
460 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
460
461
461 source = ColumnDataSource(data = dict(
462 source = ColumnDataSource(data = dict(
462 bottom = [i for tup in points],
463 bottom = [i for tup in points],
463 top = [i+0.5 for tup in points],
464 top = [i+0.5 for tup in points],
464 left = [tup[0] for tup in points],
465 left = [tup[0] for tup in points],
465 right = [tup[1] for tup in points],
466 right = [tup[1] for tup in points],
466 ipp = [int(tup[0]/ipp) for tup in points],
467 ipp = [int(tup[0]/ipp) for tup in points],
467 name = [line.get_name() for tup in points]
468 name = [line.get_name() for tup in points]
468 ))
469 ))
469
470
470 plot.quad(
471 plot.quad(
471 bottom = 'bottom',
472 bottom = 'bottom',
472 top = 'top',
473 top = 'top',
473 left = 'left',
474 left = 'left',
474 right = 'right',
475 right = 'right',
475 source = source,
476 source = source,
476 fill_alpha = 0,
477 fill_alpha = 0,
477 #line_color = 'blue',
478 #line_color = 'blue',
478 )
479 )
479
480
480 plot.line([0, npoints], [i, i])#, color='blue')
481 plot.line([0, npoints], [i, i])#, color='blue')
481
482
482 return components(plot, CDN)
483 return components(plot, CDN)
483
484
484 def request(self, cmd, method='get', **kwargs):
485 def request(self, cmd, method='get', **kwargs):
485
486
486 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
487 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
487 payload = req.json()
488 payload = req.json()
488
489
489 return payload
490 return payload
490
491
491 def status_device(self):
492 def status_device(self):
492
493
493 try:
494 try:
494 self.device.status = 0
495 self.device.status = 0
495 payload = self.request('status')
496 payload = self.request('status')
496 if payload['status']=='enable':
497 if payload['status']=='enable':
497 self.device.status = 3
498 self.device.status = 3
498 elif payload['status']=='disable':
499 elif payload['status']=='disable':
499 self.device.status = 2
500 self.device.status = 2
500 else:
501 else:
501 self.device.status = 1
502 self.device.status = 1
502 self.device.save()
503 self.device.save()
503 self.message = 'RC status: {}'.format(payload['status'])
504 self.message = 'RC status: {}'.format(payload['status'])
504 return False
505 return False
505 except Exception as e:
506 except Exception as e:
506 if 'No route to host' not in str(e):
507 if 'No route to host' not in str(e):
507 self.device.status = 4
508 self.device.status = 4
508 self.device.save()
509 self.device.save()
509 self.message = 'RC status: {}'.format(str(e))
510 self.message = 'RC status: {}'.format(str(e))
510 return False
511 return False
511
512
512 self.device.save()
513 self.device.save()
513 return True
514 return True
514
515
515 def reset_device(self):
516 def reset_device(self):
516
517
517 try:
518 try:
518 payload = self.request('reset', 'post')
519 payload = self.request('reset', 'post')
519 if payload['reset']=='ok':
520 if payload['reset']=='ok':
520 self.message = 'RC restarted OK'
521 self.message = 'RC restarted OK'
521 self.device.status = 2
522 self.device.status = 2
522 self.device.save()
523 self.device.save()
523 else:
524 else:
524 self.message = 'RC restart fail'
525 self.message = 'RC restart fail'
525 self.device.status = 4
526 self.device.status = 4
526 self.device.save()
527 self.device.save()
527 except Exception as e:
528 except Exception as e:
528 self.message = 'RC reset: {}'.format(str(e))
529 self.message = 'RC reset: {}'.format(str(e))
529 return False
530 return False
530
531
531 return True
532 return True
532
533
533 def stop_device(self):
534 def stop_device(self):
534
535
535 try:
536 try:
536 payload = self.request('stop', 'post')
537 payload = self.request('stop', 'post')
537 self.message = 'RC stop: {}'.format(payload['stop'])
538 self.message = 'RC stop: {}'.format(payload['stop'])
538 if payload['stop']=='ok':
539 if payload['stop']=='ok':
539 self.device.status = 2
540 self.device.status = 2
540 self.device.save()
541 self.device.save()
541 else:
542 else:
542 self.device.status = 4
543 self.device.status = 4
543 self.device.save()
544 self.device.save()
544 return False
545 return False
545 except Exception as e:
546 except Exception as e:
546 if 'No route to host' not in str(e):
547 if 'No route to host' not in str(e):
547 self.device.status = 4
548 self.device.status = 4
548 else:
549 else:
549 self.device.status = 0
550 self.device.status = 0
550 self.message = 'RC stop: {}'.format(str(e))
551 self.message = 'RC stop: {}'.format(str(e))
551 self.device.save()
552 self.device.save()
552 return False
553 return False
553
554
554 return True
555 return True
555
556
556 def start_device(self):
557 def start_device(self):
557
558
558 try:
559 try:
559 payload = self.request('start', 'post')
560 payload = self.request('start', 'post')
560 self.message = 'RC start: {}'.format(payload['start'])
561 self.message = 'RC start: {}'.format(payload['start'])
561 if payload['start']=='ok':
562 if payload['start']=='ok':
562 self.device.status = 3
563 self.device.status = 3
563 self.device.save()
564 self.device.save()
564 else:
565 else:
565 return False
566 return False
566 except Exception as e:
567 except Exception as e:
567 if 'No route to host' not in str(e):
568 if 'No route to host' not in str(e):
568 self.device.status = 4
569 self.device.status = 4
569 else:
570 else:
570 self.device.status = 0
571 self.device.status = 0
571 self.message = 'RC start: {}'.format(str(e))
572 self.message = 'RC start: {}'.format(str(e))
572 self.device.save()
573 self.device.save()
573 return False
574 return False
574
575
575 return True
576 return True
576
577
577 def write_device(self, raw=False):
578 def write_device(self, raw=False):
578 print("write device")
579 print("write device")
579
580
580 if not raw:
581 if not raw:
582
583
584
581 clock = RCClock.objects.get(rc_configuration=self)
585 clock = RCClock.objects.get(rc_configuration=self)
582 if clock.mode:
586 if clock.mode:
583 data = {'default': clock.frequency}
587 data = {'default': clock.frequency}
584 else:
588 else:
585 data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
589 data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
586 payload = self.request('setfreq', 'post', data=json.dumps(data))
590 payload = self.request('setfreq', 'post', data=json.dumps(data))
587 #if payload['setfreq'] != 'ok':
591 #if payload['setfreq'] != 'ok':
588 if payload['command'] != 'ok':
592 if payload['command'] != 'ok':
589 #self.message = 'RC write: {}'.format(payload['setfreq'])
593 #self.message = 'RC write: {}'.format(payload['setfreq'])
590 self.message = 'RC write: {}'.format(payload['command'])
594 self.message = 'RC write: {}'.format(payload['command'])
591 else:
595 else:
592 #self.message = payload['setfreq']
596 #self.message = payload['setfreq']
593 self.message = payload['programming']
597 self.message = payload['programming']
594 #if payload['setfreq'] == 'fail':
598 #if payload['setfreq'] == 'fail':
595 if payload['programming'] == 'fail':
599 if payload['programming'] == 'fail':
596 self.message = 'RC write: error programming CGS chip'
600 self.message = 'RC write: error programming CGS chip'
601
602 ##############################################################
603 data = {'setwindow': self.ch_monitor}
604 print(data)
605 payload = self.request('setwin', 'post', data=json.dumps(data))
606
607 if payload['setwindow'] == 'ok':
608 self.message = 'RC write: {}'.format(payload['setwindow'])
609 else:
610 if payload['command'] != 'wrong format or key':
611 self.message = 'Error RC monitor channel: {}'.format(payload['command'])
612 ##############################################################
597
613
598 values = []
614 values = []
599 print('wait delay values...')
615 print('wait delay values...')
600 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
616 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
601 #print('wait zip...')
617 #print('wait zip...')
602 while delay > 65536:
618 while delay > 65536:
603 values.append((pulse, 65535))
619 values.append((pulse, 65535))
604 delay -= 65536
620 delay -= 65536
605 values.append((pulse, delay-1))
621 values.append((pulse, delay-1))
606 data = bytearray()
622 data = bytearray()
607 #reset
623 #reset
608 data.extend((128, 0))
624 data.extend((128, 0))
609 #disable
625 #disable
610 data.extend((129, 0))
626 data.extend((129, 0))
611 #SW switch
627 #SW switch
612 if self.control_sw:
628 if self.control_sw:
613 data.extend((130, 2))
629 data.extend((130, 2))
614 else:
630 else:
615 data.extend((130, 0))
631 data.extend((130, 0))
616 #divider
632 #divider
617 data.extend((131, self.clock_divider-1))
633 data.extend((131, self.clock_divider-1))
618 #enable writing
634 #enable writing
619 data.extend((139, 62))
635 data.extend((139, 62))
620
636
621 last = 0
637 last = 0
622 print('wait data...')
638 print('wait data...')
623 for tup in values:
639 for tup in values:
624 vals = pack('<HH', last^tup[0], tup[1])
640 vals = pack('<HH', last^tup[0], tup[1])
625 last = tup[0]
641 last = tup[0]
626 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
642 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
627
643
628 #enable
644 #enable
629 data.extend((129, 1))
645 data.extend((129, 1))
630 print('len',len(data))
646 print('len',len(data))
631
647
632 if raw:
648 if raw:
633 return b64encode(data)
649 return b64encode(data)
634
650
635 #try:
651 #try:
636 print('requests')
652 print('requests')
637 payload = self.request('stop', 'post')
653 payload = self.request('stop', 'post')
638 payload = self.request('reset', 'post')
654 payload = self.request('reset', 'post')
639 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
655 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
640 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
656 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
641 n = len(data)
657 n = len(data)
642 print('len: ',n)
658 print('len: ',n)
643 x = 0
659 x = 0
644 cnt = 0
660 cnt = 0
645 while x < n:
661 while x < n:
646 print('writing...', cnt)
662 print('writing...', cnt)
647 payload = self.request('write', 'post', data=b64encode(data[x:x+3072]))#(data))#
663 payload = self.request('write', 'post', data=b64encode(data[x:x+3072]))#(data))#
648 x += 3072
664 x += 3072
649 cnt += 1#time.sleep(1)
665 cnt += 1#time.sleep(1)
650 print('writing...', x*100/n)
666 print('writing...', x*100/n)
651
667
652 if payload['write']=='ok':
668 if payload['write']=='ok':
653 self.device.status = 3
669 self.device.status = 3
654 self.device.save()
670 self.device.save()
655 self.message = 'RC configured and started'
671 self.message = 'RC configured and started'
656 else:
672 else:
657 self.device.status = 1
673 self.device.status = 1
658 self.device.save()
674 self.device.save()
659 self.message = 'RC write: {}'.format(payload['write'])
675 self.message = 'RC write: {}'.format(payload['write'])
660 return False
676 return False
661
677
662 #payload = self.request('start', 'post')
678 #payload = self.request('start', 'post')
663
679
664 #except Exception as e:
680 #except Exception as e:
665 # if 'No route to host' not in str(e):
681 # if 'No route to host' not in str(e):
666 # self.device.status = 4
682 # self.device.status = 4
667 # else:
683 # else:
668 # self.device.status = 0
684 # self.device.status = 0
669 # self.message = 'RC write: {}'.format(str(e))
685 # self.message = 'RC write: {}'.format(str(e))
670 # self.device.save()
686 # self.device.save()
671 # return False
687 # return False
672
688
673 return True
689 return True
674
690
675
691
676 def get_absolute_url_import(self):
692 def get_absolute_url_import(self):
677 return reverse('url_import_rc_conf', args=[str(self.id)])
693 return reverse('url_import_rc_conf', args=[str(self.id)])
678
694
679
695
680 class RCLineCode(models.Model):
696 class RCLineCode(models.Model):
681
697
682 name = models.CharField(max_length=40)
698 name = models.CharField(max_length=40)
683 bits_per_code = models.PositiveIntegerField(default=0)
699 bits_per_code = models.PositiveIntegerField(default=0)
684 number_of_codes = models.PositiveIntegerField(default=0)
700 number_of_codes = models.PositiveIntegerField(default=0)
685 codes = models.TextField(blank=True, null=True)
701 codes = models.TextField(blank=True, null=True)
686
702
687 class Meta:
703 class Meta:
688 db_table = 'rc_line_codes'
704 db_table = 'rc_line_codes'
689 ordering = ('name',)
705 ordering = ('name',)
690
706
691 def __str__(self):
707 def __str__(self):
692 return u'%s' % self.name
708 return u'%s' % self.name
693
709
694
710
695 class RCLineType(models.Model):
711 class RCLineType(models.Model):
696
712
697 name = models.CharField(choices=LINE_TYPES, max_length=40)
713 name = models.CharField(choices=LINE_TYPES, max_length=40)
698 description = models.TextField(blank=True, null=True)
714 description = models.TextField(blank=True, null=True)
699 params = models.TextField(default='[]')
715 params = models.TextField(default='[]')
700
716
701 class Meta:
717 class Meta:
702 db_table = 'rc_line_types'
718 db_table = 'rc_line_types'
703
719
704 def __str__(self):
720 def __str__(self):
705 return u'%s - %s' % (self.name.upper(), self.get_name_display())
721 return u'%s - %s' % (self.name.upper(), self.get_name_display())
706
722
707
723
708 class RCLine(models.Model):
724 class RCLine(models.Model):
709
725
710 rc_configuration = models.ForeignKey('RCConfiguration', on_delete=models.CASCADE)
726 rc_configuration = models.ForeignKey('RCConfiguration', on_delete=models.CASCADE)
711 line_type = models.ForeignKey('RCLineType',on_delete=models.CASCADE)
727 line_type = models.ForeignKey('RCLineType',on_delete=models.CASCADE)
712 channel = models.PositiveIntegerField(default=0)
728 channel = models.PositiveIntegerField(default=0)
713 position = models.PositiveIntegerField(default=0)
729 position = models.PositiveIntegerField(default=0)
714 params = models.TextField(default='{}')
730 params = models.TextField(default='{}')
715 pulses = models.TextField(default='')
731 pulses = models.TextField(default='')
716
732
717 class Meta:
733 class Meta:
718 db_table = 'rc_lines'
734 db_table = 'rc_lines'
719 ordering = ['channel']
735 ordering = ['channel']
720
736
721 def __str__(self):
737 def __str__(self):
722 if self.rc_configuration:
738 if self.rc_configuration:
723 return u'{}|{} - {}'.format(self.pk, self.get_name(), self.rc_configuration.name)
739 return u'{}|{} - {}'.format(self.pk, self.get_name(), self.rc_configuration.name)
724
740
725 def jsonify(self):
741 def jsonify(self):
726
742
727 data = {}
743 data = {}
728 data['params'] = json.loads(self.params)
744 data['params'] = json.loads(self.params)
729 data['id'] = '{}'.format(self.pk)
745 data['id'] = '{}'.format(self.pk)
730 data['line_type'] = self.line_type.name
746 data['line_type'] = self.line_type.name
731 data['name'] = self.get_name()
747 data['name'] = self.get_name()
732 if data['line_type']=='codes':
748 if data['line_type']=='codes':
733 data['params']['code'] = RCLineCode.objects.get(pk=data['params']['code']).name
749 data['params']['code'] = RCLineCode.objects.get(pk=data['params']['code']).name
734
750
735 return data
751 return data
736
752
737
753
738 def clone(self, **kwargs):
754 def clone(self, **kwargs):
739
755
740 self.pk = None
756 self.pk = None
741 self.id = None
757 self.id = None
742
758
743 for attr, value in kwargs.items():
759 for attr, value in kwargs.items():
744 setattr(self, attr, value)
760 setattr(self, attr, value)
745
761
746 self.save()
762 self.save()
747
763
748 return self
764 return self
749
765
750 def get_name(self, channel=False):
766 def get_name(self, channel=False):
751
767
752 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
768 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
753 s = ''
769 s = ''
754
770
755 if self.line_type.name in ('tx',):
771 if self.line_type.name in ('tx',):
756 s = chars[self.position]
772 s = chars[self.position]
757 elif self.line_type.name in ('codes', 'windows', 'tr'):
773 elif self.line_type.name in ('codes', 'windows', 'tr'):
758 if 'TX_ref' in json.loads(self.params):
774 if 'TX_ref' in json.loads(self.params):
759 pk = json.loads(self.params)['TX_ref']
775 pk = json.loads(self.params)['TX_ref']
760 if pk in (0, '0'):
776 if pk in (0, '0'):
761 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
777 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
762 else:
778 else:
763 ref = RCLine.objects.get(pk=pk)
779 ref = RCLine.objects.get(pk=pk)
764 s = chars[ref.position]
780 s = chars[ref.position]
765 s = '({})'.format(s)
781 s = '({})'.format(s)
766
782
767 s = '{}{}'.format(self.line_type.name.upper(), s)
783 s = '{}{}'.format(self.line_type.name.upper(), s)
768
784
769 if channel:
785 if channel:
770 return '{} {}'.format(s, self.channel)
786 return '{} {}'.format(s, self.channel)
771 else:
787 else:
772 return s
788 return s
773
789
774 def get_lines(self, **kwargs):
790 def get_lines(self, **kwargs):
775
791
776 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
792 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
777
793
778 def pulses_as_array(self):
794 def pulses_as_array(self):
779
795
780 y = np.zeros(self.rc_configuration.total_units)
796 y = np.zeros(self.rc_configuration.total_units)
781
797
782 for tup in ast.literal_eval(self.pulses):
798 for tup in ast.literal_eval(self.pulses):
783 y[tup[0]:tup[1]] = 1
799 y[tup[0]:tup[1]] = 1
784
800
785 return y.astype(np.int8)
801 return y.astype(np.int8)
786
802
787 def pulses_as_points(self, km=False):
803 def pulses_as_points(self, km=False):
788
804
789 if km:
805 if km:
790 unit2km = 1/self.rc_configuration.km2unit
806 unit2km = 1/self.rc_configuration.km2unit
791 return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
807 return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
792 else:
808 else:
793 return ast.literal_eval(self.pulses)
809 return ast.literal_eval(self.pulses)
794
810
795 def get_win_ref(self, params, tx_id, km2unit):
811 def get_win_ref(self, params, tx_id, km2unit):
796
812
797 ref = self.rc_configuration.sampling_reference
813 ref = self.rc_configuration.sampling_reference
798 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
814 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
799
815
800 if codes:
816 if codes:
801 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
817 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
802 else:
818 else:
803 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
819 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
804
820
805 if ref=='first_baud':
821 if ref=='first_baud':
806 return int(1 + round((tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit))
822 return int(1 + round((tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit))
807 elif ref=='sub_baud':
823 elif ref=='sub_baud':
808 return np.ceil(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
824 return np.ceil(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
809 else:
825 else:
810 return 0
826 return 0
811
827
812 def update_pulses(self):
828 def update_pulses(self):
813 '''
829 '''
814 Update pulses field
830 Update pulses field
815 '''
831 '''
816
832
817 km2unit = self.rc_configuration.km2unit
833 km2unit = self.rc_configuration.km2unit
818 us2unit = self.rc_configuration.us2unit
834 us2unit = self.rc_configuration.us2unit
819 ipp = self.rc_configuration.ipp
835 ipp = self.rc_configuration.ipp
820 ntx = int(self.rc_configuration.ntx)
836 ntx = int(self.rc_configuration.ntx)
821 ipp_u = int(ipp*km2unit)
837 ipp_u = int(ipp*km2unit)
822 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
838 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
823 y = []
839 y = []
824
840
825 if self.line_type.name=='tr':
841 if self.line_type.name=='tr':
826 tr_params = json.loads(self.params)
842 tr_params = json.loads(self.params)
827 #print(tr_params)
843 #print(tr_params)
828 #print(tr_params['TX_ref'])
844 #print(tr_params['TX_ref'])
829 if tr_params['TX_ref'] in ('0', 0):
845 if tr_params['TX_ref'] in ('0', 0):
830 txs = self.get_lines(line_type__name='tx')
846 txs = self.get_lines(line_type__name='tx')
831 else:
847 else:
832 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
848 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
833
849
834 for tx in txs:
850 for tx in txs:
835 params = json.loads(tx.params)
851 params = json.loads(tx.params)
836
852
837 if float(params['pulse_width'])==0:
853 if float(params['pulse_width'])==0:
838 continue
854 continue
839 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
855 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
840 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
856 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
841 before = 0
857 before = 0
842 after = int(self.rc_configuration.time_after*us2unit)
858 after = int(self.rc_configuration.time_after*us2unit)
843
859
844 y_tx = self.points(ntx, ipp_u, width,
860 y_tx = self.points(ntx, ipp_u, width,
845 delay=delays,
861 delay=delays,
846 before=before,
862 before=before,
847 after=after,
863 after=after,
848 sync=self.rc_configuration.sync)
864 sync=self.rc_configuration.sync)
849
865
850 ranges = params['range'].split(',')
866 ranges = params['range'].split(',')
851
867
852 if len(ranges)>0 and ranges[0]!='0':
868 if len(ranges)>0 and ranges[0]!='0':
853 y_tx = self.mask_ranges(y_tx, ranges)
869 y_tx = self.mask_ranges(y_tx, ranges)
854
870
855 tr_ranges = tr_params['range'].split(',')
871 tr_ranges = tr_params['range'].split(',')
856
872
857 if len(tr_ranges)>0 and tr_ranges[0]!='0':
873 if len(tr_ranges)>0 and tr_ranges[0]!='0':
858 y_tx = self.mask_ranges(y_tx, tr_ranges)
874 y_tx = self.mask_ranges(y_tx, tr_ranges)
859
875
860 y.extend(y_tx)
876 y.extend(y_tx)
861
877
862 self.pulses = str(y)
878 self.pulses = str(y)
863 y = self.array_to_points(self.pulses_as_array())
879 y = self.array_to_points(self.pulses_as_array())
864
880
865 elif self.line_type.name=='tx':
881 elif self.line_type.name=='tx':
866 params = json.loads(self.params)
882 params = json.loads(self.params)
867 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
883 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
868 width = float(params['pulse_width'])*km2unit
884 width = float(params['pulse_width'])*km2unit
869
885
870 if width>0:
886 if width>0:
871 before = int(self.rc_configuration.time_before*us2unit)
887 before = int(self.rc_configuration.time_before*us2unit)
872 after = 0
888 after = 0
873
889
874 y = self.points(ntx, ipp_u, width,
890 y = self.points(ntx, ipp_u, width,
875 delay=delays,
891 delay=delays,
876 before=before,
892 before=before,
877 after=after,
893 after=after,
878 sync=self.rc_configuration.sync)
894 sync=self.rc_configuration.sync)
879
895
880 ranges = params['range'].split(',')
896 ranges = params['range'].split(',')
881
897
882 if len(ranges)>0 and ranges[0]!='0':
898 if len(ranges)>0 and ranges[0]!='0':
883 y = self.mask_ranges(y, ranges)
899 y = self.mask_ranges(y, ranges)
884
900
885 elif self.line_type.name=='flip':
901 elif self.line_type.name=='flip':
886 n = float(json.loads(self.params)['number_of_flips'])
902 n = float(json.loads(self.params)['number_of_flips'])
887 width = n*ipp*km2unit
903 width = n*ipp*km2unit
888 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
904 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
889
905
890 elif self.line_type.name=='codes':
906 elif self.line_type.name=='codes':
891 params = json.loads(self.params)
907 params = json.loads(self.params)
892 tx = RCLine.objects.get(pk=params['TX_ref'])
908 tx = RCLine.objects.get(pk=params['TX_ref'])
893 tx_params = json.loads(tx.params)
909 tx_params = json.loads(tx.params)
894 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
910 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
895 f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
911 f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
896 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
912 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
897 codes = [self.array_to_points(code) for code in codes]
913 codes = [self.array_to_points(code) for code in codes]
898 n = len(codes)
914 n = len(codes)
899
915
900 ranges = tx_params['range'].split(',')
916 ranges = tx_params['range'].split(',')
901 if len(ranges)>0 and ranges[0]!='0':
917 if len(ranges)>0 and ranges[0]!='0':
902 dum = self.mask_ranges(tx.pulses_as_points(), ranges)
918 dum = self.mask_ranges(tx.pulses_as_points(), ranges)
903 else:
919 else:
904 dum = tx.pulses_as_points()
920 dum = tx.pulses_as_points()
905
921
906 for i, tup in enumerate(dum):
922 for i, tup in enumerate(dum):
907 if tup==(0,0): continue
923 if tup==(0,0): continue
908 code = codes[i%n]
924 code = codes[i%n]
909 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
925 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
910
926
911 elif self.line_type.name=='sync':
927 elif self.line_type.name=='sync':
912 params = json.loads(self.params)
928 params = json.loads(self.params)
913 n = ipp_u*ntx
929 n = ipp_u*ntx
914 if params['invert'] in ('1', 1):
930 if params['invert'] in ('1', 1):
915 y = [(n-1, n)]
931 y = [(n-1, n)]
916 else:
932 else:
917 y = [(0, 1)]
933 y = [(0, 1)]
918
934
919 elif self.line_type.name=='prog_pulses':
935 elif self.line_type.name=='prog_pulses':
920 params = json.loads(self.params)
936 params = json.loads(self.params)
921 if int(params['periodic'])==0:
937 if int(params['periodic'])==0:
922 nntx = 1
938 nntx = 1
923 nipp = ipp_u*ntx
939 nipp = ipp_u*ntx
924 else:
940 else:
925 nntx = ntx
941 nntx = ntx
926 nipp = ipp_u
942 nipp = ipp_u
927
943
928 if 'params' in params and len(params['params'])>0:
944 if 'params' in params and len(params['params'])>0:
929 for p in params['params']:
945 for p in params['params']:
930 y_pp = self.points(nntx, nipp,
946 y_pp = self.points(nntx, nipp,
931 p['end']-p['begin'],
947 p['end']-p['begin'],
932 before=p['begin'])
948 before=p['begin'])
933
949
934 y.extend(y_pp)
950 y.extend(y_pp)
935
951
936 elif self.line_type.name=='windows':
952 elif self.line_type.name=='windows':
937 params = json.loads(self.params)
953 params = json.loads(self.params)
938 if 'params' in params and len(params['params'])>0:
954 if 'params' in params and len(params['params'])>0:
939 tx = RCLine.objects.get(pk=params['TX_ref'])
955 tx = RCLine.objects.get(pk=params['TX_ref'])
940 tx_params = json.loads(tx.params)
956 tx_params = json.loads(tx.params)
941 ranges = tx_params['range'].split(',')
957 ranges = tx_params['range'].split(',')
942 for p in params['params']:
958 for p in params['params']:
943 y_win = self.points(ntx, ipp_u,
959 y_win = self.points(ntx, ipp_u,
944 p['resolution']*p['number_of_samples']*km2unit,
960 p['resolution']*p['number_of_samples']*km2unit,
945 before=int(self.rc_configuration.time_before*us2unit)+p['first_height']*km2unit,
961 before=int(self.rc_configuration.time_before*us2unit)+p['first_height']*km2unit,
946 sync=self.rc_configuration.sync+self.get_win_ref(p, params['TX_ref'], km2unit))
962 sync=self.rc_configuration.sync+self.get_win_ref(p, params['TX_ref'], km2unit))
947
963
948
964
949 if len(ranges)>0 and ranges[0]!='0':
965 if len(ranges)>0 and ranges[0]!='0':
950 y_win = self.mask_ranges(y_win, ranges)
966 y_win = self.mask_ranges(y_win, ranges)
951
967
952 y.extend(y_win)
968 y.extend(y_win)
953
969
954 elif self.line_type.name=='mix':
970 elif self.line_type.name=='mix':
955 values = self.rc_configuration.parameters.split('-')
971 values = self.rc_configuration.parameters.split('-')
956 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
972 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
957 modes = [value.split('|')[1] for value in values]
973 modes = [value.split('|')[1] for value in values]
958 ops = [value.split('|')[2] for value in values]
974 ops = [value.split('|')[2] for value in values]
959 delays = [value.split('|')[3] for value in values]
975 delays = [value.split('|')[3] for value in values]
960 masks = [value.split('|')[4] for value in values]
976 masks = [value.split('|')[4] for value in values]
961 print("masks")
977 print("masks")
962 print(masks)
978 print(masks)
963 print('{:8b}'.format(int(masks[0])))
979 print('{:8b}'.format(int(masks[0])))
964 mask = list('{:8b}'.format(int(masks[0])))
980 mask = list('{:8b}'.format(int(masks[0])))
965 print("mask")
981 print("mask")
966 print(mask)
982 print(mask)
967 mask.reverse()
983 mask.reverse()
968 print("mask reverse")
984 print("mask reverse")
969 print(mask)
985 print(mask)
970 if mask[self.channel] in ('0', '', ' '):
986 if mask[self.channel] in ('0', '', ' '):
971 y = np.zeros(confs[0].total_units, dtype=np.int8)
987 y = np.zeros(confs[0].total_units, dtype=np.int8)
972 else:
988 else:
973 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
989 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
974
990
975 for i in range(1, len(values)):
991 for i in range(1, len(values)):
976 mask = list('{:8b}'.format(int(masks[i])))
992 mask = list('{:8b}'.format(int(masks[i])))
977 mask.reverse()
993 mask.reverse()
978
994
979 if mask[self.channel] in ('0', '', ' '):
995 if mask[self.channel] in ('0', '', ' '):
980 continue
996 continue
981 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
997 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
982 delay = float(delays[i])*km2unit
998 delay = float(delays[i])*km2unit
983
999
984 if modes[i]=='P':
1000 if modes[i]=='P':
985 if delay>0:
1001 if delay>0:
986 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
1002 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
987 y_temp = np.empty_like(Y)
1003 y_temp = np.empty_like(Y)
988 y_temp[:delay] = 0
1004 y_temp[:delay] = 0
989 y_temp[delay:] = Y[:-delay]
1005 y_temp[delay:] = Y[:-delay]
990 elif delay+len(Y)>len(y):
1006 elif delay+len(Y)>len(y):
991 y_new = np.zeros(delay+len(Y), dtype=np.int8)
1007 y_new = np.zeros(delay+len(Y), dtype=np.int8)
992 y_new[:len(y)] = y
1008 y_new[:len(y)] = y
993 y = y_new
1009 y = y_new
994 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
1010 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
995 y_temp[-len(Y):] = Y
1011 y_temp[-len(Y):] = Y
996 elif delay+len(Y)==len(y):
1012 elif delay+len(Y)==len(y):
997 y_temp = np.zeros(delay+len(Y))
1013 y_temp = np.zeros(delay+len(Y))
998 y_temp[-len(Y):] = Y
1014 y_temp[-len(Y):] = Y
999 elif delay+len(Y)<len(y):
1015 elif delay+len(Y)<len(y):
1000 y_temp = np.zeros(len(y), dtype=np.int8)
1016 y_temp = np.zeros(len(y), dtype=np.int8)
1001 y_temp[delay:delay+len(Y)] = Y
1017 y_temp[delay:delay+len(Y)] = Y
1002 else:
1018 else:
1003 y_temp = Y.copy()
1019 y_temp = Y.copy()
1004
1020
1005 if ops[i]=='OR':
1021 if ops[i]=='OR':
1006 y = y | y_temp
1022 y = y | y_temp
1007 elif ops[i]=='XOR':
1023 elif ops[i]=='XOR':
1008 y = y ^ y_temp
1024 y = y ^ y_temp
1009 elif ops[i]=='AND':
1025 elif ops[i]=='AND':
1010 y = y & y_temp
1026 y = y & y_temp
1011 elif ops[i]=='NAND':
1027 elif ops[i]=='NAND':
1012 y = y & ~y_temp
1028 y = y & ~y_temp
1013 else:
1029 else:
1014 y = np.concatenate([y, Y])
1030 y = np.concatenate([y, Y])
1015
1031
1016 total = len(y)
1032 total = len(y)
1017 y = self.array_to_points(y)
1033 y = self.array_to_points(y)
1018
1034
1019 else:
1035 else:
1020 y = []
1036 y = []
1021
1037
1022 if self.rc_configuration.total_units != total:
1038 if self.rc_configuration.total_units != total:
1023 self.rc_configuration.total_units = total
1039 self.rc_configuration.total_units = total
1024 self.rc_configuration.save()
1040 self.rc_configuration.save()
1025
1041
1026 self.pulses = str(y)
1042 self.pulses = str(y)
1027 self.save()
1043 self.save()
1028
1044
1029 @staticmethod
1045 @staticmethod
1030 def array_to_points(X):
1046 def array_to_points(X):
1031
1047
1032 if X.size==0:
1048 if X.size==0:
1033 return []
1049 return []
1034
1050
1035 d = X[1:]-X[:-1]
1051 d = X[1:]-X[:-1]
1036
1052
1037 up = np.where(d==1)[0]
1053 up = np.where(d==1)[0]
1038 if X[0]==1:
1054 if X[0]==1:
1039 up = np.concatenate((np.array([-1]), up))
1055 up = np.concatenate((np.array([-1]), up))
1040 up += 1
1056 up += 1
1041
1057
1042 dw = np.where(d==-1)[0]
1058 dw = np.where(d==-1)[0]
1043 if X[-1]==1:
1059 if X[-1]==1:
1044 dw = np.concatenate((dw, np.array([len(X)-1])))
1060 dw = np.concatenate((dw, np.array([len(X)-1])))
1045 dw += 1
1061 dw += 1
1046
1062
1047 return [(tup[0], tup[1]) for tup in zip(up, dw)]
1063 return [(tup[0], tup[1]) for tup in zip(up, dw)]
1048
1064
1049 @staticmethod
1065 @staticmethod
1050 def mask_ranges(Y, ranges):
1066 def mask_ranges(Y, ranges):
1051
1067
1052 y = [(0, 0) for __ in Y]
1068 y = [(0, 0) for __ in Y]
1053
1069
1054 for index in ranges:
1070 for index in ranges:
1055 if '-' in index:
1071 if '-' in index:
1056 args = [int(a) for a in index.split('-')]
1072 args = [int(a) for a in index.split('-')]
1057 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
1073 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
1058 else:
1074 else:
1059 y[int(index)-1] = Y[int(index)-1]
1075 y[int(index)-1] = Y[int(index)-1]
1060
1076
1061 return y
1077 return y
1062
1078
1063 @staticmethod
1079 @staticmethod
1064 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
1080 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
1065
1081
1066 delays = len(delay)
1082 delays = len(delay)
1067
1083
1068 Y = [(int(ipp*x+before+delay[x%delays]+sync), int(ipp*x+width+before+delay[x%delays]+after+sync)) for x in range(ntx)]
1084 Y = [(int(ipp*x+before+delay[x%delays]+sync), int(ipp*x+width+before+delay[x%delays]+after+sync)) for x in range(ntx)]
1069
1085
1070 return Y
1086 return Y
1071
1087
1072 class RCClock(models.Model):
1088 class RCClock(models.Model):
1073
1089
1074 rc_configuration = models.ForeignKey('RCConfiguration', on_delete=models.CASCADE)
1090 rc_configuration = models.ForeignKey('RCConfiguration', on_delete=models.CASCADE)
1075 mode = models.BooleanField(default=True, choices=((True, 'Auto'), (False, 'Manual')))
1091 mode = models.BooleanField(default=True, choices=((True, 'Auto'), (False, 'Manual')))
1076 multiplier = models.PositiveIntegerField(default=60)
1092 multiplier = models.PositiveIntegerField(default=60)
1077 divisor = models.PositiveIntegerField(default=10)
1093 divisor = models.PositiveIntegerField(default=10)
1078 reference = models.PositiveSmallIntegerField(default=1, choices=((0, 'Internal (25MHz)'), (1, 'External (10MHz)')))
1094 reference = models.PositiveSmallIntegerField(default=1, choices=((0, 'Internal (25MHz)'), (1, 'External (10MHz)')))
1079 frequency = models.FloatField(default=60.0)
1095 frequency = models.FloatField(default=60.0)
@@ -1,435 +1,435
1 import json
1 import json
2
2
3 from django.contrib import messages
3 from django.contrib import messages
4 from django.utils.safestring import mark_safe
4 from django.utils.safestring import mark_safe
5 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
5 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
6 from django.contrib.auth.decorators import login_required
6 from django.contrib.auth.decorators import login_required
7
7
8 from apps.main.models import Experiment, Device
8 from apps.main.models import Experiment, Device
9 from apps.main.views import sidebar
9 from apps.main.views import sidebar
10
10
11 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode, RCClock
11 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode, RCClock
12 from .forms import RCConfigurationForm, RCLineForm, RCLineViewForm, RCLineEditForm, RCImportForm, RCLineCodesForm, RCClockForm
12 from .forms import RCConfigurationForm, RCLineForm, RCLineViewForm, RCLineEditForm, RCImportForm, RCLineCodesForm, RCClockForm
13
13
14
14
15 def conf(request, conf_id):
15 def conf(request, conf_id):
16
16
17 conf = get_object_or_404(RCConfiguration, pk=conf_id)
17 conf = get_object_or_404(RCConfiguration, pk=conf_id)
18
18
19 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
19 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
20 clk = RCClock.objects.filter(rc_configuration=conf).first()
20 clk = RCClock.objects.filter(rc_configuration=conf).first()
21 if clk is None:
21 if clk is None:
22 clk = RCClock(rc_configuration=conf)
22 clk = RCClock(rc_configuration=conf)
23 clk.save()
23 clk.save()
24
24
25 for line in lines:
25 for line in lines:
26 params = json.loads(line.params)
26 params = json.loads(line.params)
27 line.form = RCLineViewForm(extra_fields=params, line=line)
27 line.form = RCLineViewForm(extra_fields=params, line=line)
28 if 'params' in params:
28 if 'params' in params:
29 line.subforms = [RCLineViewForm(extra_fields=fields, line=line, subform=True) for fields in params['params']]
29 line.subforms = [RCLineViewForm(extra_fields=fields, line=line, subform=True) for fields in params['params']]
30
30
31 kwargs = {}
31 kwargs = {}
32 kwargs['clock'] = clk
32 kwargs['clock'] = clk
33 kwargs['dev_conf'] = conf
33 kwargs['dev_conf'] = conf
34 kwargs['rc_lines'] = lines
34 kwargs['rc_lines'] = lines
35 kwargs['dev_conf_keys'] = ['ipp_unit', 'ntx', 'clock_divider', 'clock',
35 kwargs['dev_conf_keys'] = ['ipp_unit', 'ntx', 'clock_divider', 'clock',
36 'time_before', 'time_after', 'sync', 'sampling_reference',
36 'time_before', 'time_after', 'sync', 'ch_monitor', 'sampling_reference',
37 'control_tx', 'control_sw']
37 'control_tx', 'control_sw']
38
38
39 kwargs['title'] = 'Configuration'
39 kwargs['title'] = 'Configuration'
40 kwargs['suptitle'] = 'Detail'
40 kwargs['suptitle'] = 'Detail'
41
41
42 kwargs['button'] = 'Edit Configuration'
42 kwargs['button'] = 'Edit Configuration'
43 ###### SIDEBAR ######
43 ###### SIDEBAR ######
44 kwargs.update(sidebar(conf=conf))
44 kwargs.update(sidebar(conf=conf))
45
45
46 return render(request, 'rc_conf.html', kwargs)
46 return render(request, 'rc_conf.html', kwargs)
47
47
48 @login_required
48 @login_required
49 def conf_edit(request, conf_id):
49 def conf_edit(request, conf_id):
50
50
51 conf = get_object_or_404(RCConfiguration, pk=conf_id)
51 conf = get_object_or_404(RCConfiguration, pk=conf_id)
52 clock = RCClock.objects.get(rc_configuration=conf)
52 clock = RCClock.objects.get(rc_configuration=conf)
53 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
53 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
54
54
55 for line in lines:
55 for line in lines:
56 params = json.loads(line.params)
56 params = json.loads(line.params)
57 #print(params)
57 #print(params)
58 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
58 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
59 line.subform = False
59 line.subform = False
60
60
61 if 'params' in params:
61 if 'params' in params:
62 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
62 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
63 line.subform = True
63 line.subform = True
64 print(params)
64 print(params)
65 print("fin de sub carga de params")
65 print("fin de sub carga de params")
66 #print("fin de carga de params")
66 #print("fin de carga de params")
67 if request.method=='GET':
67 if request.method=='GET':
68 print("GET case")
68 print("GET case")
69 form = RCConfigurationForm(instance=conf)
69 form = RCConfigurationForm(instance=conf)
70 form_clock = RCClockForm(instance=clock)
70 form_clock = RCClockForm(instance=clock)
71
71
72 elif request.method=='POST':
72 elif request.method=='POST':
73 #print("ingreso a post conf edit")
73 #print("ingreso a post conf edit")
74 line_data = {}
74 line_data = {}
75 conf_data = {}
75 conf_data = {}
76 clock_data = {}
76 clock_data = {}
77 extras = []
77 extras = []
78 print("Inicio impresion POST#####")
78 print("Inicio impresion POST#####")
79 print(request.POST.items)
79 print(request.POST.items)
80 print("Fin impresion de POST items#####")
80 print("Fin impresion de POST items#####")
81 #classified post fields
81 #classified post fields
82 for label,value in request.POST.items():
82 for label,value in request.POST.items():
83 if label=='csrfmiddlewaretoken':
83 if label=='csrfmiddlewaretoken':
84 continue
84 continue
85
85
86 if label.count('|')==0:
86 if label.count('|')==0:
87 if label in ('mode', 'multiplier', 'divisor', 'reference', 'frequency'):
87 if label in ('mode', 'multiplier', 'divisor', 'reference', 'frequency'):
88 clock_data[label] = value
88 clock_data[label] = value
89 else:
89 else:
90 conf_data[label] = value
90 conf_data[label] = value
91 continue
91 continue
92
92
93 elif label.split('|')[0]!='-1':
93 elif label.split('|')[0]!='-1':
94 extras.append(label)
94 extras.append(label)
95 continue
95 continue
96
96
97 #print(label)
97 #print(label)
98 x, pk, name = label.split('|')
98 x, pk, name = label.split('|')
99
99
100 if name=='codes':
100 if name=='codes':
101 value = [s for s in value.split('\r\n') if s]
101 value = [s for s in value.split('\r\n') if s]
102
102
103 if pk in line_data:
103 if pk in line_data:
104 line_data[pk][name] = value
104 line_data[pk][name] = value
105 else:
105 else:
106 line_data[pk] = {name:value}
106 line_data[pk] = {name:value}
107 #print(line_data[pk])
107 #print(line_data[pk])
108 #update conf
108 #update conf
109
109
110 form_clock = RCClockForm(clock_data, instance=clock)
110 form_clock = RCClockForm(clock_data, instance=clock)
111 form = RCConfigurationForm(conf_data, instance=conf)
111 form = RCConfigurationForm(conf_data, instance=conf)
112
112
113 #print(request.POST.items())
113 #print(request.POST.items())
114
114
115 if form_clock.is_valid() and form.is_valid():
115 if form_clock.is_valid() and form.is_valid():
116 form_clock.save()
116 form_clock.save()
117 form.save()
117 form.save()
118
118
119 #update lines fields
119 #update lines fields
120 extras.sort(key=lambda x: int(x.split('|')[0]))
120 extras.sort(key=lambda x: int(x.split('|')[0]))
121 #print("Inicio extras")
121 #print("Inicio extras")
122 #print(extras)
122 #print(extras)
123 #print("Fin extras")
123 #print("Fin extras")
124 for label in extras:
124 for label in extras:
125 x, pk, name = label.split('|')
125 x, pk, name = label.split('|')
126 if pk not in line_data:
126 if pk not in line_data:
127 line_data[pk] = {}
127 line_data[pk] = {}
128 if 'params' not in line_data[pk]:
128 if 'params' not in line_data[pk]:
129 line_data[pk]['params'] = []
129 line_data[pk]['params'] = []
130 if len(line_data[pk]['params'])<int(x)+1:
130 if len(line_data[pk]['params'])<int(x)+1:
131 line_data[pk]['params'].append({})
131 line_data[pk]['params'].append({})
132 line_data[pk]['params'][int(x)][name] = float(request.POST[label])
132 line_data[pk]['params'][int(x)][name] = float(request.POST[label])
133
133
134 for pk, params in line_data.items():
134 for pk, params in line_data.items():
135 line = RCLine.objects.get(pk=pk)
135 line = RCLine.objects.get(pk=pk)
136 if line.line_type.name in ('windows', 'prog_pulses'):
136 if line.line_type.name in ('windows', 'prog_pulses'):
137 if 'params' not in params:
137 if 'params' not in params:
138 params['params'] = []
138 params['params'] = []
139 line.params = json.dumps(params)
139 line.params = json.dumps(params)
140 #print(line.params)
140 #print(line.params)
141 line.save()
141 line.save()
142
142
143
143
144 #update pulses field
144 #update pulses field
145 conf.update_pulses()
145 conf.update_pulses()
146
146
147 messages.success(request, 'RC Configuration successfully updated')
147 messages.success(request, 'RC Configuration successfully updated')
148
148
149 return redirect(conf.get_absolute_url())
149 return redirect(conf.get_absolute_url())
150
150
151 kwargs = {}
151 kwargs = {}
152 kwargs['dev_conf'] = conf
152 kwargs['dev_conf'] = conf
153 kwargs['form'] = form
153 kwargs['form'] = form
154 kwargs['form_clock'] = form_clock
154 kwargs['form_clock'] = form_clock
155 kwargs['rc_lines'] = lines
155 kwargs['rc_lines'] = lines
156 kwargs['edit'] = True
156 kwargs['edit'] = True
157
157
158 kwargs['title'] = 'RC Configuration'
158 kwargs['title'] = 'RC Configuration'
159 kwargs['suptitle'] = 'Edit'
159 kwargs['suptitle'] = 'Edit'
160 kwargs['button'] = 'Update'
160 kwargs['button'] = 'Update'
161
161
162 return render(request, 'rc_conf_edit.html', kwargs)
162 return render(request, 'rc_conf_edit.html', kwargs)
163
163
164
164
165 def add_line(request, conf_id, line_type_id=None, code_id=None):
165 def add_line(request, conf_id, line_type_id=None, code_id=None):
166
166
167 conf = get_object_or_404(RCConfiguration, pk=conf_id)
167 conf = get_object_or_404(RCConfiguration, pk=conf_id)
168
168
169 if request.method=='GET':
169 if request.method=='GET':
170 if line_type_id:
170 if line_type_id:
171 line_type = get_object_or_404(RCLineType, pk=line_type_id)
171 line_type = get_object_or_404(RCLineType, pk=line_type_id)
172
172
173 if code_id:
173 if code_id:
174 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id, 'code_id': code_id},
174 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id, 'code_id': code_id},
175 extra_fields=json.loads(line_type.params))
175 extra_fields=json.loads(line_type.params))
176 else:
176 else:
177 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id},
177 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id},
178 extra_fields=json.loads(line_type.params))
178 extra_fields=json.loads(line_type.params))
179 else:
179 else:
180 line_type = {'id':0}
180 line_type = {'id':0}
181 form = RCLineForm(initial={'rc_configuration':conf_id})
181 form = RCLineForm(initial={'rc_configuration':conf_id})
182
182
183 if request.method=='POST':
183 if request.method=='POST':
184
184
185 line_type = get_object_or_404(RCLineType, pk=line_type_id)
185 line_type = get_object_or_404(RCLineType, pk=line_type_id)
186 form = RCLineForm(request.POST,
186 form = RCLineForm(request.POST,
187 extra_fields=json.loads(line_type.params))
187 extra_fields=json.loads(line_type.params))
188
188
189 if form.is_valid():
189 if form.is_valid():
190 form.save()
190 form.save()
191 form.instance.update_pulses()
191 form.instance.update_pulses()
192 return redirect('url_edit_rc_conf', conf.id)
192 return redirect('url_edit_rc_conf', conf.id)
193
193
194 kwargs = {}
194 kwargs = {}
195 kwargs['form'] = form
195 kwargs['form'] = form
196 kwargs['title'] = 'RC Configuration'
196 kwargs['title'] = 'RC Configuration'
197 kwargs['suptitle'] = 'Add Line'
197 kwargs['suptitle'] = 'Add Line'
198 kwargs['button'] = 'Add'
198 kwargs['button'] = 'Add'
199 kwargs['previous'] = conf.get_absolute_url_edit()
199 kwargs['previous'] = conf.get_absolute_url_edit()
200 kwargs['dev_conf'] = conf
200 kwargs['dev_conf'] = conf
201 kwargs['line_type'] = line_type
201 kwargs['line_type'] = line_type
202
202
203 return render(request, 'rc_add_line.html', kwargs)
203 return render(request, 'rc_add_line.html', kwargs)
204
204
205 def edit_codes(request, conf_id, line_id, code_id=None):
205 def edit_codes(request, conf_id, line_id, code_id=None):
206
206
207 conf = get_object_or_404(RCConfiguration, pk=conf_id)
207 conf = get_object_or_404(RCConfiguration, pk=conf_id)
208 line = get_object_or_404(RCLine, pk=line_id)
208 line = get_object_or_404(RCLine, pk=line_id)
209 params = json.loads(line.params)
209 params = json.loads(line.params)
210
210
211 if request.method=='GET':
211 if request.method=='GET':
212 if code_id:
212 if code_id:
213 code = get_object_or_404(RCLineCode, pk=code_id)
213 code = get_object_or_404(RCLineCode, pk=code_id)
214 form = RCLineCodesForm(instance=code)
214 form = RCLineCodesForm(instance=code)
215 else:
215 else:
216 initial = {'code': params['code'],
216 initial = {'code': params['code'],
217 'codes': params['codes'] if 'codes' in params else [],
217 'codes': params['codes'] if 'codes' in params else [],
218 'number_of_codes': len(params['codes']) if 'codes' in params else 0,
218 'number_of_codes': len(params['codes']) if 'codes' in params else 0,
219 'bits_per_code': len(params['codes'][0]) if 'codes' in params else 0,
219 'bits_per_code': len(params['codes'][0]) if 'codes' in params else 0,
220 }
220 }
221 form = RCLineCodesForm(initial=initial)
221 form = RCLineCodesForm(initial=initial)
222
222
223 if request.method=='POST':
223 if request.method=='POST':
224 form = RCLineCodesForm(request.POST)
224 form = RCLineCodesForm(request.POST)
225 if form.is_valid():
225 if form.is_valid():
226 params['code'] = request.POST['code']
226 params['code'] = request.POST['code']
227 params['codes'] = [s for s in request.POST['codes'].split('\r\n') if s]
227 params['codes'] = [s for s in request.POST['codes'].split('\r\n') if s]
228 line.params = json.dumps(params)
228 line.params = json.dumps(params)
229 line.save()
229 line.save()
230 messages.success(request, 'Line: "%s" has been updated.' % line)
230 messages.success(request, 'Line: "%s" has been updated.' % line)
231 return redirect('url_edit_rc_conf', conf.id)
231 return redirect('url_edit_rc_conf', conf.id)
232
232
233 kwargs = {}
233 kwargs = {}
234 kwargs['form'] = form
234 kwargs['form'] = form
235 kwargs['title'] = line
235 kwargs['title'] = line
236 kwargs['suptitle'] = 'Edit'
236 kwargs['suptitle'] = 'Edit'
237 kwargs['button'] = 'Update'
237 kwargs['button'] = 'Update'
238 kwargs['dev_conf'] = conf
238 kwargs['dev_conf'] = conf
239 kwargs['previous'] = conf.get_absolute_url_edit()
239 kwargs['previous'] = conf.get_absolute_url_edit()
240 kwargs['line'] = line
240 kwargs['line'] = line
241
241
242 return render(request, 'rc_edit_codes.html', kwargs)
242 return render(request, 'rc_edit_codes.html', kwargs)
243
243
244 def add_subline(request, conf_id, line_id):
244 def add_subline(request, conf_id, line_id):
245
245
246 conf = get_object_or_404(RCConfiguration, pk=conf_id)
246 conf = get_object_or_404(RCConfiguration, pk=conf_id)
247 line = get_object_or_404(RCLine, pk=line_id)
247 line = get_object_or_404(RCLine, pk=line_id)
248
248
249 if request.method == 'POST':
249 if request.method == 'POST':
250 if line:
250 if line:
251 params = json.loads(line.params)
251 params = json.loads(line.params)
252 subparams = json.loads(line.line_type.params)
252 subparams = json.loads(line.line_type.params)
253 if 'params' in subparams:
253 if 'params' in subparams:
254 dum = {}
254 dum = {}
255 for key, value in subparams['params'].items():
255 for key, value in subparams['params'].items():
256 dum[key] = value['value']
256 dum[key] = value['value']
257 params['params'].append(dum)
257 params['params'].append(dum)
258 line.params = json.dumps(params)
258 line.params = json.dumps(params)
259 line.save()
259 line.save()
260 return redirect('url_edit_rc_conf', conf.id)
260 return redirect('url_edit_rc_conf', conf.id)
261
261
262 kwargs = {}
262 kwargs = {}
263
263
264 kwargs['title'] = 'Add new'
264 kwargs['title'] = 'Add new'
265 kwargs['suptitle'] = '%s to %s' % (line.line_type.name, line)
265 kwargs['suptitle'] = '%s to %s' % (line.line_type.name, line)
266
266
267 return render(request, 'confirm.html', kwargs)
267 return render(request, 'confirm.html', kwargs)
268
268
269 def remove_line(request, conf_id, line_id):
269 def remove_line(request, conf_id, line_id):
270
270
271 conf = get_object_or_404(RCConfiguration, pk=conf_id)
271 conf = get_object_or_404(RCConfiguration, pk=conf_id)
272 line = get_object_or_404(RCLine, pk=line_id)
272 line = get_object_or_404(RCLine, pk=line_id)
273
273
274 if request.method == 'POST':
274 if request.method == 'POST':
275 if line:
275 if line:
276 try:
276 try:
277 channel = line.channel
277 channel = line.channel
278 line.delete()
278 line.delete()
279 for ch in range(channel+1, RCLine.objects.filter(rc_configuration=conf).count()+1):
279 for ch in range(channel+1, RCLine.objects.filter(rc_configuration=conf).count()+1):
280 l = RCLine.objects.get(rc_configuration=conf, channel=ch)
280 l = RCLine.objects.get(rc_configuration=conf, channel=ch)
281 l.channel = l.channel-1
281 l.channel = l.channel-1
282 l.save()
282 l.save()
283 messages.success(request, 'Line: "%s" has been deleted.' % line)
283 messages.success(request, 'Line: "%s" has been deleted.' % line)
284 except:
284 except:
285 messages.error(request, 'Unable to delete line: "%s".' % line)
285 messages.error(request, 'Unable to delete line: "%s".' % line)
286
286
287 return redirect('url_edit_rc_conf', conf.id)
287 return redirect('url_edit_rc_conf', conf.id)
288
288
289 kwargs = {}
289 kwargs = {}
290
290
291 kwargs['object'] = line
291 kwargs['object'] = line
292 kwargs['delete'] = True
292 kwargs['delete'] = True
293 kwargs['title'] = 'Delete'
293 kwargs['title'] = 'Delete'
294 kwargs['suptitle'] = 'Line'
294 kwargs['suptitle'] = 'Line'
295 kwargs['previous'] = conf.get_absolute_url_edit()
295 kwargs['previous'] = conf.get_absolute_url_edit()
296 return render(request, 'confirm.html', kwargs)
296 return render(request, 'confirm.html', kwargs)
297
297
298
298
299 def remove_subline(request, conf_id, line_id, subline_id):
299 def remove_subline(request, conf_id, line_id, subline_id):
300
300
301 conf = get_object_or_404(RCConfiguration, pk=conf_id)
301 conf = get_object_or_404(RCConfiguration, pk=conf_id)
302 line = get_object_or_404(RCLine, pk=line_id)
302 line = get_object_or_404(RCLine, pk=line_id)
303
303
304 if request.method == 'POST':
304 if request.method == 'POST':
305 if line:
305 if line:
306 params = json.loads(line.params)
306 params = json.loads(line.params)
307 params['params'].remove(params['params'][int(subline_id)-1])
307 params['params'].remove(params['params'][int(subline_id)-1])
308 line.params = json.dumps(params)
308 line.params = json.dumps(params)
309 line.save()
309 line.save()
310
310
311 return redirect('url_edit_rc_conf', conf.id)
311 return redirect('url_edit_rc_conf', conf.id)
312
312
313 kwargs = {}
313 kwargs = {}
314
314
315 kwargs['object'] = line
315 kwargs['object'] = line
316 kwargs['object_name'] = line.line_type.name
316 kwargs['object_name'] = line.line_type.name
317 kwargs['delete_view'] = True
317 kwargs['delete_view'] = True
318 kwargs['title'] = 'Confirm delete'
318 kwargs['title'] = 'Confirm delete'
319
319
320 return render(request, 'confirm.html', kwargs)
320 return render(request, 'confirm.html', kwargs)
321
321
322
322
323 def update_lines_position(request, conf_id):
323 def update_lines_position(request, conf_id):
324
324
325 conf = get_object_or_404(RCConfiguration, pk=conf_id)
325 conf = get_object_or_404(RCConfiguration, pk=conf_id)
326 print("ingreso a update_lines_position")
326 print("ingreso a update_lines_position")
327 if request.method=='POST':
327 if request.method=='POST':
328 ch = 0
328 ch = 0
329 for item in request.POST['items'].split('&'):
329 for item in request.POST['items'].split('&'):
330 line = RCLine.objects.get(pk=item.split('=')[-1])
330 line = RCLine.objects.get(pk=item.split('=')[-1])
331 line.channel = ch
331 line.channel = ch
332 line.save()
332 line.save()
333 ch += 1
333 ch += 1
334
334
335 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
335 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
336
336
337 for line in lines:
337 for line in lines:
338
338
339 params = json.loads(line.params)
339 params = json.loads(line.params)
340 print(params)
340 print(params)
341 print("Fin de impresion_lines_position")
341 print("Fin de impresion_lines_position")
342 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
342 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
343
343
344 if 'params' in params:
344 if 'params' in params:
345 line.subform = True
345 line.subform = True
346 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
346 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
347
347
348 html = render(request, 'rc_lines.html', {'dev_conf':conf, 'rc_lines':lines, 'edit':True})
348 html = render(request, 'rc_lines.html', {'dev_conf':conf, 'rc_lines':lines, 'edit':True})
349 data = {'html': html.content.decode('utf8')}
349 data = {'html': html.content.decode('utf8')}
350
350
351 return HttpResponse(json.dumps(data), content_type="application/json")
351 return HttpResponse(json.dumps(data), content_type="application/json")
352 return redirect('url_edit_rc_conf', conf.id)
352 return redirect('url_edit_rc_conf', conf.id)
353
353
354
354
355 def import_file(request, conf_id):
355 def import_file(request, conf_id):
356
356
357 conf = get_object_or_404(RCConfiguration, pk=conf_id)
357 conf = get_object_or_404(RCConfiguration, pk=conf_id)
358 if request.method=='POST':
358 if request.method=='POST':
359 form = RCImportForm(request.POST, request.FILES)
359 form = RCImportForm(request.POST, request.FILES)
360 if form.is_valid():
360 if form.is_valid():
361 try:
361 try:
362 data = conf.import_from_file(request.FILES['file_name'])
362 data = conf.import_from_file(request.FILES['file_name'])
363 conf.dict_to_parms(data)
363 conf.dict_to_parms(data)
364 conf.update_pulses()
364 conf.update_pulses()
365 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
365 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
366 return redirect(conf.get_absolute_url_edit())
366 return redirect(conf.get_absolute_url_edit())
367
367
368 except Exception as e:
368 except Exception as e:
369 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
369 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
370 else:
370 else:
371 messages.warning(request, 'Your current configuration will be replaced')
371 messages.warning(request, 'Your current configuration will be replaced')
372 form = RCImportForm()
372 form = RCImportForm()
373
373
374 kwargs = {}
374 kwargs = {}
375 kwargs['form'] = form
375 kwargs['form'] = form
376 kwargs['title'] = 'RC Configuration'
376 kwargs['title'] = 'RC Configuration'
377 kwargs['suptitle'] = 'Import file'
377 kwargs['suptitle'] = 'Import file'
378 kwargs['button'] = 'Upload'
378 kwargs['button'] = 'Upload'
379 kwargs['previous'] = conf.get_absolute_url()
379 kwargs['previous'] = conf.get_absolute_url()
380
380
381 return render(request, 'rc_import.html', kwargs)
381 return render(request, 'rc_import.html', kwargs)
382
382
383
383
384 def plot_pulses(request, conf_id):
384 def plot_pulses(request, conf_id):
385
385
386 conf = get_object_or_404(RCConfiguration, pk=conf_id)
386 conf = get_object_or_404(RCConfiguration, pk=conf_id)
387 km = True if 'km' in request.GET else False
387 km = True if 'km' in request.GET else False
388
388
389 script, div = conf.plot_pulses(km=km)
389 script, div = conf.plot_pulses(km=km)
390
390
391 kwargs = {}
391 kwargs = {}
392 kwargs['no_sidebar'] = True
392 kwargs['no_sidebar'] = True
393 kwargs['title'] = 'RC Pulses'
393 kwargs['title'] = 'RC Pulses'
394 kwargs['suptitle'] = conf.name
394 kwargs['suptitle'] = conf.name
395 kwargs['div'] = mark_safe(div)
395 kwargs['div'] = mark_safe(div)
396 kwargs['script'] = mark_safe(script)
396 kwargs['script'] = mark_safe(script)
397 kwargs['units'] = conf.km2unit
397 kwargs['units'] = conf.km2unit
398 kwargs['kms'] = 1/conf.km2unit
398 kwargs['kms'] = 1/conf.km2unit
399
399
400 if km:
400 if km:
401 kwargs['km_selected'] = True
401 kwargs['km_selected'] = True
402
402
403 if 'json' in request.GET:
403 if 'json' in request.GET:
404 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
404 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
405 else:
405 else:
406 return render(request, 'rc_pulses.html', kwargs)
406 return render(request, 'rc_pulses.html', kwargs)
407
407
408 def plot_pulses2(request, conf_id):
408 def plot_pulses2(request, conf_id):
409
409
410 conf = get_object_or_404(RCConfiguration, pk=conf_id)
410 conf = get_object_or_404(RCConfiguration, pk=conf_id)
411 km = True if 'km' in request.GET else False
411 km = True if 'km' in request.GET else False
412
412
413 script, div = conf.plot_pulses2(km=km)
413 script, div = conf.plot_pulses2(km=km)
414
414
415 kwargs = {}
415 kwargs = {}
416 kwargs['no_sidebar'] = True
416 kwargs['no_sidebar'] = True
417 kwargs['title'] = 'RC Pulses'
417 kwargs['title'] = 'RC Pulses'
418 kwargs['suptitle'] = conf.name
418 kwargs['suptitle'] = conf.name
419 kwargs['div'] = mark_safe(div)
419 kwargs['div'] = mark_safe(div)
420 kwargs['script'] = mark_safe(script)
420 kwargs['script'] = mark_safe(script)
421 kwargs['units'] = conf.km2unit
421 kwargs['units'] = conf.km2unit
422 kwargs['kms'] = 1/conf.km2unit
422 kwargs['kms'] = 1/conf.km2unit
423
423
424 if km:
424 if km:
425 kwargs['km_selected'] = True
425 kwargs['km_selected'] = True
426
426
427 if 'json' in request.GET:
427 if 'json' in request.GET:
428 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
428 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
429 else:
429 else:
430 return render(request, 'rc_pulses.html', kwargs)
430 return render(request, 'rc_pulses.html', kwargs)
431
431
432 def conf_raw(request, conf_id):
432 def conf_raw(request, conf_id):
433 conf = get_object_or_404(RCConfiguration, pk=conf_id)
433 conf = get_object_or_404(RCConfiguration, pk=conf_id)
434 raw = conf.write_device(raw=True)
434 raw = conf.write_device(raw=True)
435 return HttpResponse(raw, content_type='application/json')
435 return HttpResponse(raw, content_type='application/json')
General Comments 0
You need to be logged in to leave comments. Login now