|
@@
-1,1042
+1,1042
|
|
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 [μS]', default=12)
|
|
80
|
time_before = models.PositiveIntegerField(verbose_name='Time before [μS]', default=12)
|
|
81
|
time_after = models.PositiveIntegerField(verbose_name='Time after [μS]', default=1)
|
|
81
|
time_after = models.PositiveIntegerField(verbose_name='Time after [μS]', default=1)
|
|
82
|
sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
|
|
82
|
sync = models.PositiveIntegerField(verbose_name='Synchro delay', default=0)
|
|
83
|
sampling_reference = models.CharField(verbose_name='Sampling Reference', choices=SAMPLING_REFS, default='none', max_length=40)
|
|
83
|
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)
|
|
84
|
control_tx = models.BooleanField(verbose_name='Control Switch TX', default=False)
|
|
85
|
control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
|
|
85
|
control_sw = models.BooleanField(verbose_name='Control Switch SW', default=False)
|
|
86
|
total_units = models.PositiveIntegerField(default=0)
|
|
86
|
total_units = models.PositiveIntegerField(default=0)
|
|
87
|
mix = models.BooleanField(default=False)
|
|
87
|
mix = models.BooleanField(default=False)
|
|
88
|
|
|
88
|
|
|
89
|
class Meta:
|
|
89
|
class Meta:
|
|
90
|
db_table = 'rc_configurations'
|
|
90
|
db_table = 'rc_configurations'
|
|
91
|
|
|
91
|
|
|
92
|
def get_absolute_url_plot(self):
|
|
92
|
def get_absolute_url_plot(self):
|
|
93
|
return reverse('url_plot_rc_pulses', args=[str(self.id)])
|
|
93
|
return reverse('url_plot_rc_pulses', args=[str(self.id)])
|
|
94
|
|
|
94
|
|
|
95
|
@property
|
|
95
|
@property
|
|
96
|
def ipp_unit(self):
|
|
96
|
def ipp_unit(self):
|
|
97
|
|
|
97
|
|
|
98
|
return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
|
|
98
|
return '{} ({})'.format(self.ipp, int(self.ipp*self.km2unit))
|
|
99
|
|
|
99
|
|
|
100
|
@property
|
|
100
|
@property
|
|
101
|
def us2unit(self):
|
|
101
|
def us2unit(self):
|
|
102
|
|
|
102
|
|
|
103
|
return self.clock_in/self.clock_divider
|
|
103
|
return self.clock_in/self.clock_divider
|
|
104
|
|
|
104
|
|
|
105
|
@property
|
|
105
|
@property
|
|
106
|
def km2unit(self):
|
|
106
|
def km2unit(self):
|
|
107
|
|
|
107
|
|
|
108
|
return 20./3*(self.clock_in/self.clock_divider)
|
|
108
|
return 20./3*(self.clock_in/self.clock_divider)
|
|
109
|
|
|
109
|
|
|
110
|
def clone(self, **kwargs):
|
|
110
|
def clone(self, **kwargs):
|
|
111
|
|
|
111
|
|
|
112
|
lines = self.get_lines()
|
|
112
|
lines = self.get_lines()
|
|
113
|
self.pk = None
|
|
113
|
self.pk = None
|
|
114
|
self.id = None
|
|
114
|
self.id = None
|
|
115
|
for attr, value in kwargs.items():
|
|
115
|
for attr, value in kwargs.items():
|
|
116
|
setattr(self, attr, value)
|
|
116
|
setattr(self, attr, value)
|
|
117
|
self.save()
|
|
117
|
self.save()
|
|
118
|
|
|
118
|
|
|
119
|
for line in lines:
|
|
119
|
for line in lines:
|
|
120
|
line.clone(rc_configuration=self)
|
|
120
|
line.clone(rc_configuration=self)
|
|
121
|
|
|
121
|
|
|
122
|
new_lines = self.get_lines()
|
|
122
|
new_lines = self.get_lines()
|
|
123
|
for line in new_lines:
|
|
123
|
for line in new_lines:
|
|
124
|
line_params = json.loads(line.params)
|
|
124
|
line_params = json.loads(line.params)
|
|
125
|
if 'TX_ref' in line_params and (line_params['TX_ref'] != '0'):
|
|
125
|
if 'TX_ref' in line_params and (line_params['TX_ref'] != '0'):
|
|
126
|
ref_line = RCLine.objects.get(pk=line_params['TX_ref'])
|
|
126
|
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]
|
|
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 = json.dumps(line_params)
|
|
128
|
line.params = json.dumps(line_params)
|
|
129
|
line.save()
|
|
129
|
line.save()
|
|
130
|
|
|
130
|
|
|
131
|
return self
|
|
131
|
return self
|
|
132
|
|
|
132
|
|
|
133
|
def get_lines(self, **kwargs):
|
|
133
|
def get_lines(self, **kwargs):
|
|
134
|
'''
|
|
134
|
'''
|
|
135
|
Retrieve configuration lines
|
|
135
|
Retrieve configuration lines
|
|
136
|
'''
|
|
136
|
'''
|
|
137
|
|
|
137
|
|
|
138
|
return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
|
|
138
|
return RCLine.objects.filter(rc_configuration=self.pk, **kwargs)
|
|
139
|
|
|
139
|
|
|
140
|
|
|
140
|
|
|
141
|
def clean_lines(self):
|
|
141
|
def clean_lines(self):
|
|
142
|
'''
|
|
142
|
'''
|
|
143
|
'''
|
|
143
|
'''
|
|
144
|
|
|
144
|
|
|
145
|
empty_line = RCLineType.objects.get(name='none')
|
|
145
|
empty_line = RCLineType.objects.get(name='none')
|
|
146
|
|
|
146
|
|
|
147
|
for line in self.get_lines():
|
|
147
|
for line in self.get_lines():
|
|
148
|
line.line_type = empty_line
|
|
148
|
line.line_type = empty_line
|
|
149
|
line.params = '{}'
|
|
149
|
line.params = '{}'
|
|
150
|
line.save()
|
|
150
|
line.save()
|
|
151
|
|
|
151
|
|
|
152
|
def dict_to_parms(self, params, id=None):
|
|
152
|
def dict_to_parms(self, params, id=None):
|
|
153
|
'''
|
|
153
|
'''
|
|
154
|
'''
|
|
154
|
'''
|
|
155
|
|
|
155
|
|
|
156
|
if id:
|
|
156
|
if id:
|
|
157
|
data = Params(params).get_conf(id_conf=id)
|
|
157
|
data = Params(params).get_conf(id_conf=id)
|
|
158
|
else:
|
|
158
|
else:
|
|
159
|
data = Params(params).get_conf(dtype='rc')
|
|
159
|
data = Params(params).get_conf(dtype='rc')
|
|
160
|
|
|
160
|
|
|
161
|
#print(data)
|
|
161
|
#print(data)
|
|
162
|
# self.name = data['name']
|
|
162
|
# self.name = data['name']
|
|
163
|
self.ipp = data['ipp']
|
|
163
|
self.ipp = data['ipp']
|
|
164
|
self.ntx = data['ntx']
|
|
164
|
self.ntx = data['ntx']
|
|
165
|
self.clock_in = data['clock_in']
|
|
165
|
self.clock_in = data['clock_in']
|
|
166
|
self.clock_divider = data['clock_divider']
|
|
166
|
self.clock_divider = data['clock_divider']
|
|
167
|
self.clock = data['clock']
|
|
167
|
self.clock = data['clock']
|
|
168
|
self.time_before = data['time_before']
|
|
168
|
self.time_before = data['time_before']
|
|
169
|
self.time_after = data['time_after']
|
|
169
|
self.time_after = data['time_after']
|
|
170
|
self.sync = data['sync']
|
|
170
|
self.sync = data['sync']
|
|
171
|
self.sampling_reference = data['sampling_reference']
|
|
171
|
self.sampling_reference = data['sampling_reference']
|
|
172
|
self.total_units = self.ipp*self.ntx*self.km2unit
|
|
172
|
self.total_units = self.ipp*self.ntx*self.km2unit
|
|
173
|
self.save()
|
|
173
|
self.save()
|
|
174
|
self.clean_lines()
|
|
174
|
self.clean_lines()
|
|
175
|
|
|
175
|
|
|
176
|
#print(params)
|
|
176
|
#print(params)
|
|
177
|
|
|
177
|
|
|
178
|
positions = {'tx':0, 'tr':0}
|
|
178
|
positions = {'tx':0, 'tr':0}
|
|
179
|
for i, id in enumerate(data['lines']):
|
|
179
|
for i, id in enumerate(data['lines']):
|
|
180
|
line_data = params['lines']['byId'][id]
|
|
180
|
line_data = params['lines']['byId'][id]
|
|
181
|
line_type = RCLineType.objects.get(name=line_data['line_type'])
|
|
181
|
line_type = RCLineType.objects.get(name=line_data['line_type'])
|
|
182
|
if line_type.name == 'codes':
|
|
182
|
if line_type.name == 'codes':
|
|
183
|
code = RCLineCode.objects.get(name=line_data['params']['code'])
|
|
183
|
code = RCLineCode.objects.get(name=line_data['params']['code'])
|
|
184
|
line_data['params']['code'] = code.pk
|
|
184
|
line_data['params']['code'] = code.pk
|
|
185
|
if line_type.name == 'tx':
|
|
185
|
if line_type.name == 'tx':
|
|
186
|
position = positions['tx']
|
|
186
|
position = positions['tx']
|
|
187
|
positions['tx'] += 1
|
|
187
|
positions['tx'] += 1
|
|
188
|
elif line_type.name == 'tr':
|
|
188
|
elif line_type.name == 'tr':
|
|
189
|
position = positions['tr']
|
|
189
|
position = positions['tr']
|
|
190
|
positions['tr'] += 1
|
|
190
|
positions['tr'] += 1
|
|
191
|
else:
|
|
191
|
else:
|
|
192
|
position = 0
|
|
192
|
position = 0
|
|
193
|
line, dum = RCLine.objects.update_or_create(
|
|
193
|
line, dum = RCLine.objects.update_or_create(
|
|
194
|
rc_configuration=self,
|
|
194
|
rc_configuration=self,
|
|
195
|
channel=i,
|
|
195
|
channel=i,
|
|
196
|
position=position,
|
|
196
|
position=position,
|
|
197
|
defaults={
|
|
197
|
defaults={
|
|
198
|
'line_type': line_type,
|
|
198
|
'line_type': line_type,
|
|
199
|
'params': json.dumps(line_data['params'])
|
|
199
|
'params': json.dumps(line_data['params'])
|
|
200
|
}
|
|
200
|
}
|
|
201
|
)
|
|
201
|
)
|
|
202
|
|
|
202
|
|
|
203
|
for i, line in enumerate(self.get_lines()):
|
|
203
|
for i, line in enumerate(self.get_lines()):
|
|
204
|
line_params = json.loads(line.params)
|
|
204
|
line_params = json.loads(line.params)
|
|
205
|
if 'TX_ref' in line_params:
|
|
205
|
if 'TX_ref' in line_params:
|
|
206
|
if line_params['TX_ref'] in (0, '0'):
|
|
206
|
if line_params['TX_ref'] in (0, '0'):
|
|
207
|
line_params['TX_ref'] = '0'
|
|
207
|
line_params['TX_ref'] = '0'
|
|
208
|
else:
|
|
208
|
else:
|
|
209
|
ref_id = '{}'.format(line_params['TX_ref'])
|
|
209
|
ref_id = '{}'.format(line_params['TX_ref'])
|
|
210
|
ref_line = params['lines']['byId'][ref_id]
|
|
210
|
ref_line = params['lines']['byId'][ref_id]
|
|
211
|
line_params['TX_ref'] = RCLine.objects.get(
|
|
211
|
line_params['TX_ref'] = RCLine.objects.get(
|
|
212
|
rc_configuration=self,
|
|
212
|
rc_configuration=self,
|
|
213
|
params=json.dumps(ref_line['params'])
|
|
213
|
params=json.dumps(ref_line['params'])
|
|
214
|
).pk
|
|
214
|
).pk
|
|
215
|
line.params = json.dumps(line_params)
|
|
215
|
line.params = json.dumps(line_params)
|
|
216
|
print(line.params)
|
|
216
|
print(line.params)
|
|
217
|
line.save()
|
|
217
|
line.save()
|
|
218
|
print("Fin de dict to param")
|
|
218
|
print("Fin de dict to param")
|
|
219
|
|
|
219
|
|
|
220
|
def get_delays(self):
|
|
220
|
def get_delays(self):
|
|
221
|
|
|
221
|
|
|
222
|
pulses = [line.pulses_as_points() for line in self.get_lines()]
|
|
222
|
pulses = [line.pulses_as_points() for line in self.get_lines()]
|
|
223
|
points = [tup for tups in pulses for tup in tups]
|
|
223
|
points = [tup for tups in pulses for tup in tups]
|
|
224
|
points = set([x for tup in points for x in tup])
|
|
224
|
points = set([x for tup in points for x in tup])
|
|
225
|
points = list(points)
|
|
225
|
points = list(points)
|
|
226
|
points.sort()
|
|
226
|
points.sort()
|
|
227
|
|
|
227
|
|
|
228
|
if points[0]!=0:
|
|
228
|
if points[0]!=0:
|
|
229
|
points.insert(0, 0)
|
|
229
|
points.insert(0, 0)
|
|
230
|
|
|
230
|
|
|
231
|
return [points[i+1]-points[i] for i in range(len(points)-1)]
|
|
231
|
return [points[i+1]-points[i] for i in range(len(points)-1)]
|
|
232
|
|
|
232
|
|
|
233
|
|
|
233
|
|
|
234
|
def get_pulses(self, binary=True):
|
|
234
|
def get_pulses(self, binary=True):
|
|
235
|
|
|
235
|
|
|
236
|
pulses = [line.pulses_as_points() for line in self.get_lines()]
|
|
236
|
pulses = [line.pulses_as_points() for line in self.get_lines()]
|
|
237
|
tuples = [tup for tups in pulses for tup in tups]
|
|
237
|
tuples = [tup for tups in pulses for tup in tups]
|
|
238
|
points = set([x for tup in tuples for x in tup])
|
|
238
|
points = set([x for tup in tuples for x in tup])
|
|
239
|
points = list(points)
|
|
239
|
points = list(points)
|
|
240
|
points.sort()
|
|
240
|
points.sort()
|
|
241
|
states = []
|
|
241
|
states = []
|
|
242
|
last = [0 for x in pulses]
|
|
242
|
last = [0 for x in pulses]
|
|
243
|
|
|
243
|
|
|
244
|
for x in points:
|
|
244
|
for x in points:
|
|
245
|
dum = []
|
|
245
|
dum = []
|
|
246
|
for i, tups in enumerate(pulses):
|
|
246
|
for i, tups in enumerate(pulses):
|
|
247
|
ups = [tup[0] for tup in tups if tup!=(0,0)]
|
|
247
|
ups = [tup[0] for tup in tups if tup!=(0,0)]
|
|
248
|
dws = [tup[1] for tup in tups if tup!=(0,0)]
|
|
248
|
dws = [tup[1] for tup in tups if tup!=(0,0)]
|
|
249
|
if x in ups:
|
|
249
|
if x in ups:
|
|
250
|
dum.append(1)
|
|
250
|
dum.append(1)
|
|
251
|
elif x in dws:
|
|
251
|
elif x in dws:
|
|
252
|
dum.append(0)
|
|
252
|
dum.append(0)
|
|
253
|
else:
|
|
253
|
else:
|
|
254
|
dum.append(last[i])
|
|
254
|
dum.append(last[i])
|
|
255
|
states.append(dum)
|
|
255
|
states.append(dum)
|
|
256
|
last = dum
|
|
256
|
last = dum
|
|
257
|
|
|
257
|
|
|
258
|
if binary:
|
|
258
|
if binary:
|
|
259
|
ret = []
|
|
259
|
ret = []
|
|
260
|
for flips in states:
|
|
260
|
for flips in states:
|
|
261
|
flips.reverse()
|
|
261
|
flips.reverse()
|
|
262
|
ret.append(int(''.join([str(x) for x in flips]), 2))
|
|
262
|
ret.append(int(''.join([str(x) for x in flips]), 2))
|
|
263
|
states = ret
|
|
263
|
states = ret
|
|
264
|
|
|
264
|
|
|
265
|
return states[:-1]
|
|
265
|
return states[:-1]
|
|
266
|
|
|
266
|
|
|
267
|
def add_cmd(self, cmd):
|
|
267
|
def add_cmd(self, cmd):
|
|
268
|
|
|
268
|
|
|
269
|
if cmd in DAT_CMDS:
|
|
269
|
if cmd in DAT_CMDS:
|
|
270
|
return (255, DAT_CMDS[cmd])
|
|
270
|
return (255, DAT_CMDS[cmd])
|
|
271
|
|
|
271
|
|
|
272
|
def add_data(self, value):
|
|
272
|
def add_data(self, value):
|
|
273
|
|
|
273
|
|
|
274
|
return (254, value-1)
|
|
274
|
return (254, value-1)
|
|
275
|
|
|
275
|
|
|
276
|
def parms_to_binary(self, dat=True):
|
|
276
|
def parms_to_binary(self, dat=True):
|
|
277
|
'''
|
|
277
|
'''
|
|
278
|
Create "dat" stream to be send to CR
|
|
278
|
Create "dat" stream to be send to CR
|
|
279
|
'''
|
|
279
|
'''
|
|
280
|
|
|
280
|
|
|
281
|
data = bytearray()
|
|
281
|
data = bytearray()
|
|
282
|
# create header
|
|
282
|
# create header
|
|
283
|
data.extend(self.add_cmd('DISABLE'))
|
|
283
|
data.extend(self.add_cmd('DISABLE'))
|
|
284
|
data.extend(self.add_cmd('CONTINUE'))
|
|
284
|
data.extend(self.add_cmd('CONTINUE'))
|
|
285
|
data.extend(self.add_cmd('RESTART'))
|
|
285
|
data.extend(self.add_cmd('RESTART'))
|
|
286
|
|
|
286
|
|
|
287
|
if self.control_sw:
|
|
287
|
if self.control_sw:
|
|
288
|
data.extend(self.add_cmd('SW_ONE'))
|
|
288
|
data.extend(self.add_cmd('SW_ONE'))
|
|
289
|
else:
|
|
289
|
else:
|
|
290
|
data.extend(self.add_cmd('SW_ZERO'))
|
|
290
|
data.extend(self.add_cmd('SW_ZERO'))
|
|
291
|
|
|
291
|
|
|
292
|
if self.control_tx:
|
|
292
|
if self.control_tx:
|
|
293
|
data.extend(self.add_cmd('TX_ONE'))
|
|
293
|
data.extend(self.add_cmd('TX_ONE'))
|
|
294
|
else:
|
|
294
|
else:
|
|
295
|
data.extend(self.add_cmd('TX_ZERO'))
|
|
295
|
data.extend(self.add_cmd('TX_ZERO'))
|
|
296
|
|
|
296
|
|
|
297
|
# write divider
|
|
297
|
# write divider
|
|
298
|
data.extend(self.add_cmd('CLOCK_DIVIDER'))
|
|
298
|
data.extend(self.add_cmd('CLOCK_DIVIDER'))
|
|
299
|
data.extend(self.add_data(self.clock_divider))
|
|
299
|
data.extend(self.add_data(self.clock_divider))
|
|
300
|
|
|
300
|
|
|
301
|
# write delays
|
|
301
|
# write delays
|
|
302
|
data.extend(self.add_cmd('DELAY_START'))
|
|
302
|
data.extend(self.add_cmd('DELAY_START'))
|
|
303
|
# first delay is always zero
|
|
303
|
# first delay is always zero
|
|
304
|
data.extend(self.add_data(1))
|
|
304
|
data.extend(self.add_data(1))
|
|
305
|
|
|
305
|
|
|
306
|
delays = self.get_delays()
|
|
306
|
delays = self.get_delays()
|
|
307
|
|
|
307
|
|
|
308
|
for delay in delays:
|
|
308
|
for delay in delays:
|
|
309
|
while delay>252:
|
|
309
|
while delay>252:
|
|
310
|
data.extend(self.add_data(253))
|
|
310
|
data.extend(self.add_data(253))
|
|
311
|
delay -= 253
|
|
311
|
delay -= 253
|
|
312
|
data.extend(self.add_data(int(delay)))
|
|
312
|
data.extend(self.add_data(int(delay)))
|
|
313
|
|
|
313
|
|
|
314
|
# write flips
|
|
314
|
# write flips
|
|
315
|
data.extend(self.add_cmd('FLIP_START'))
|
|
315
|
data.extend(self.add_cmd('FLIP_START'))
|
|
316
|
|
|
316
|
|
|
317
|
states = self.get_pulses(binary=True)
|
|
317
|
states = self.get_pulses(binary=True)
|
|
318
|
|
|
318
|
|
|
319
|
|
|
319
|
|
|
320
|
last = 0
|
|
320
|
last = 0
|
|
321
|
for flip, delay in zip(states, delays):
|
|
321
|
for flip, delay in zip(states, delays):
|
|
322
|
data.extend(self.add_data((flip^last)+1))
|
|
322
|
data.extend(self.add_data((flip^last)+1))
|
|
323
|
last = flip
|
|
323
|
last = flip
|
|
324
|
while delay>252:
|
|
324
|
while delay>252:
|
|
325
|
data.extend(self.add_data(1))
|
|
325
|
data.extend(self.add_data(1))
|
|
326
|
delay -= 253
|
|
326
|
delay -= 253
|
|
327
|
|
|
327
|
|
|
328
|
# write sampling period
|
|
328
|
# write sampling period
|
|
329
|
data.extend(self.add_cmd('SAMPLING_PERIOD'))
|
|
329
|
data.extend(self.add_cmd('SAMPLING_PERIOD'))
|
|
330
|
wins = self.get_lines(line_type__name='windows')
|
|
330
|
wins = self.get_lines(line_type__name='windows')
|
|
331
|
if wins:
|
|
331
|
if wins:
|
|
332
|
win_params = json.loads(wins[0].params)['params']
|
|
332
|
win_params = json.loads(wins[0].params)['params']
|
|
333
|
if win_params:
|
|
333
|
if win_params:
|
|
334
|
dh = int(win_params[0]['resolution']*self.km2unit)
|
|
334
|
dh = int(win_params[0]['resolution']*self.km2unit)
|
|
335
|
else:
|
|
335
|
else:
|
|
336
|
dh = 1
|
|
336
|
dh = 1
|
|
337
|
else:
|
|
337
|
else:
|
|
338
|
dh = 1
|
|
338
|
dh = 1
|
|
339
|
data.extend(self.add_data(dh))
|
|
339
|
data.extend(self.add_data(dh))
|
|
340
|
|
|
340
|
|
|
341
|
# write enable
|
|
341
|
# write enable
|
|
342
|
data.extend(self.add_cmd('ENABLE'))
|
|
342
|
data.extend(self.add_cmd('ENABLE'))
|
|
343
|
|
|
343
|
|
|
344
|
if not dat:
|
|
344
|
if not dat:
|
|
345
|
return data
|
|
345
|
return data
|
|
346
|
|
|
346
|
|
|
347
|
return '\n'.join(['{}'.format(x) for x in data])
|
|
347
|
return '\n'.join(['{}'.format(x) for x in data])
|
|
348
|
|
|
348
|
|
|
349
|
def update_pulses(self):
|
|
349
|
def update_pulses(self):
|
|
350
|
contador = 0
|
|
350
|
contador = 0
|
|
351
|
for line in self.get_lines():
|
|
351
|
for line in self.get_lines():
|
|
352
|
contador=contador+1
|
|
352
|
contador=contador+1
|
|
353
|
print(contador)
|
|
353
|
print(contador)
|
|
354
|
line.update_pulses()
|
|
354
|
line.update_pulses()
|
|
355
|
|
|
355
|
|
|
356
|
def plot_pulses2(self, km=False):
|
|
356
|
def plot_pulses2(self, km=False):
|
|
357
|
|
|
357
|
|
|
358
|
import matplotlib
|
|
358
|
import matplotlib
|
|
359
|
matplotlib.use('Agg')
|
|
359
|
matplotlib.use('Agg')
|
|
360
|
import matplotlib.pyplot as plt
|
|
360
|
import matplotlib.pyplot as plt
|
|
361
|
from bokeh.resources import CDN
|
|
361
|
from bokeh.resources import CDN
|
|
362
|
from bokeh.embed import components
|
|
362
|
from bokeh.embed import components
|
|
363
|
from bokeh.mpl import to_bokeh
|
|
363
|
from bokeh.mpl import to_bokeh
|
|
364
|
from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
|
|
364
|
from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
|
|
365
|
|
|
365
|
|
|
366
|
lines = self.get_lines()
|
|
366
|
lines = self.get_lines()
|
|
367
|
|
|
367
|
|
|
368
|
N = len(lines)
|
|
368
|
N = len(lines)
|
|
369
|
npoints = self.total_units/self.km2unit if km else self.total_units
|
|
369
|
npoints = self.total_units/self.km2unit if km else self.total_units
|
|
370
|
fig = plt.figure(figsize=(12, 2+N*0.5))
|
|
370
|
fig = plt.figure(figsize=(12, 2+N*0.5))
|
|
371
|
ax = fig.add_subplot(111)
|
|
371
|
ax = fig.add_subplot(111)
|
|
372
|
labels = ['IPP']
|
|
372
|
labels = ['IPP']
|
|
373
|
|
|
373
|
|
|
374
|
for i, line in enumerate(lines):
|
|
374
|
for i, line in enumerate(lines):
|
|
375
|
labels.append(line.get_name(channel=True))
|
|
375
|
labels.append(line.get_name(channel=True))
|
|
376
|
l = ax.plot((0, npoints),(N-i-1, N-i-1))
|
|
376
|
l = ax.plot((0, npoints),(N-i-1, N-i-1))
|
|
377
|
points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
|
|
377
|
points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
|
|
378
|
ax.broken_barh(points, (N-i-1, 0.5),
|
|
378
|
ax.broken_barh(points, (N-i-1, 0.5),
|
|
379
|
edgecolor=l[0].get_color(), facecolor='none')
|
|
379
|
edgecolor=l[0].get_color(), facecolor='none')
|
|
380
|
|
|
380
|
|
|
381
|
n = 0
|
|
381
|
n = 0
|
|
382
|
f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
|
|
382
|
f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
|
|
383
|
for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
|
|
383
|
for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
|
|
384
|
if n%f==0:
|
|
384
|
if n%f==0:
|
|
385
|
ax.text(x, N, '%s' % n, size=10)
|
|
385
|
ax.text(x, N, '%s' % n, size=10)
|
|
386
|
n += 1
|
|
386
|
n += 1
|
|
387
|
|
|
387
|
|
|
388
|
labels.reverse()
|
|
388
|
labels.reverse()
|
|
389
|
ax.set_yticks(range(len(labels)))
|
|
389
|
ax.set_yticks(range(len(labels)))
|
|
390
|
ax.set_yticklabels(labels)
|
|
390
|
ax.set_yticklabels(labels)
|
|
391
|
ax.set_xlabel = 'Units'
|
|
391
|
ax.set_xlabel = 'Units'
|
|
392
|
plot = to_bokeh(fig, use_pandas=False)
|
|
392
|
plot = to_bokeh(fig, use_pandas=False)
|
|
393
|
plot.tools = [PanTool(dimensions="width"), WheelZoomTool(dimensions="width"), ResetTool(), SaveTool()]
|
|
393
|
plot.tools = [PanTool(dimensions="width"), WheelZoomTool(dimensions="width"), ResetTool(), SaveTool()]
|
|
394
|
plot.toolbar_location="above"
|
|
394
|
plot.toolbar_location="above"
|
|
395
|
|
|
395
|
|
|
396
|
return components(plot, CDN)
|
|
396
|
return components(plot, CDN)
|
|
397
|
|
|
397
|
|
|
398
|
def plot_pulses(self, km=False):
|
|
398
|
def plot_pulses(self, km=False):
|
|
399
|
|
|
399
|
|
|
400
|
from bokeh.plotting import figure
|
|
400
|
from bokeh.plotting import figure
|
|
401
|
from bokeh.resources import CDN
|
|
401
|
from bokeh.resources import CDN
|
|
402
|
from bokeh.embed import components
|
|
402
|
from bokeh.embed import components
|
|
403
|
from bokeh.models import FixedTicker, PrintfTickFormatter
|
|
403
|
from bokeh.models import FixedTicker, PrintfTickFormatter
|
|
404
|
from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
|
|
404
|
from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
|
|
405
|
from bokeh.models.sources import ColumnDataSource
|
|
405
|
from bokeh.models.sources import ColumnDataSource
|
|
406
|
|
|
406
|
|
|
407
|
lines = self.get_lines().reverse()
|
|
407
|
lines = self.get_lines().reverse()
|
|
408
|
|
|
408
|
|
|
409
|
N = len(lines)
|
|
409
|
N = len(lines)
|
|
410
|
npoints = self.total_units/self.km2unit if km else self.total_units
|
|
410
|
npoints = self.total_units/self.km2unit if km else self.total_units
|
|
411
|
ipp = self.ipp if km else self.ipp*self.km2unit
|
|
411
|
ipp = self.ipp if km else self.ipp*self.km2unit
|
|
412
|
|
|
412
|
|
|
413
|
hover = HoverTool(tooltips=[("Line", "@name"),
|
|
413
|
hover = HoverTool(tooltips=[("Line", "@name"),
|
|
414
|
("IPP", "@ipp"),
|
|
414
|
("IPP", "@ipp"),
|
|
415
|
("X", "@left")])
|
|
415
|
("X", "@left")])
|
|
416
|
|
|
416
|
|
|
417
|
tools = [PanTool(dimensions="width"),
|
|
417
|
tools = [PanTool(dimensions="width"),
|
|
418
|
WheelZoomTool(dimensions="width"),
|
|
418
|
WheelZoomTool(dimensions="width"),
|
|
419
|
hover, SaveTool()]
|
|
419
|
hover, SaveTool()]
|
|
420
|
|
|
420
|
|
|
421
|
plot = figure(width=1000,
|
|
421
|
plot = figure(width=1000,
|
|
422
|
height=40+N*50,
|
|
422
|
height=40+N*50,
|
|
423
|
y_range = (0, N),
|
|
423
|
y_range = (0, N),
|
|
424
|
tools=tools,
|
|
424
|
tools=tools,
|
|
425
|
toolbar_location='above',
|
|
425
|
toolbar_location='above',
|
|
426
|
toolbar_sticky=False,)
|
|
426
|
toolbar_sticky=False,)
|
|
427
|
|
|
427
|
|
|
428
|
plot.xaxis.axis_label = 'Km' if km else 'Units'
|
|
428
|
plot.xaxis.axis_label = 'Km' if km else 'Units'
|
|
429
|
plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
|
|
429
|
plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
|
|
430
|
plot.yaxis.axis_label = 'Pulses'
|
|
430
|
plot.yaxis.axis_label = 'Pulses'
|
|
431
|
plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
|
|
431
|
plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
|
|
432
|
plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
|
|
432
|
plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
|
|
433
|
|
|
433
|
|
|
434
|
for i, line in enumerate(lines):
|
|
434
|
for i, line in enumerate(lines):
|
|
435
|
|
|
435
|
|
|
436
|
points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
|
|
436
|
points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
|
|
437
|
|
|
437
|
|
|
438
|
source = ColumnDataSource(data = dict(
|
|
438
|
source = ColumnDataSource(data = dict(
|
|
439
|
bottom = [i for tup in points],
|
|
439
|
bottom = [i for tup in points],
|
|
440
|
top = [i+0.5 for tup in points],
|
|
440
|
top = [i+0.5 for tup in points],
|
|
441
|
left = [tup[0] for tup in points],
|
|
441
|
left = [tup[0] for tup in points],
|
|
442
|
right = [tup[1] for tup in points],
|
|
442
|
right = [tup[1] for tup in points],
|
|
443
|
ipp = [int(tup[0]/ipp) for tup in points],
|
|
443
|
ipp = [int(tup[0]/ipp) for tup in points],
|
|
444
|
name = [line.get_name() for tup in points]
|
|
444
|
name = [line.get_name() for tup in points]
|
|
445
|
))
|
|
445
|
))
|
|
446
|
|
|
446
|
|
|
447
|
plot.quad(
|
|
447
|
plot.quad(
|
|
448
|
bottom = 'bottom',
|
|
448
|
bottom = 'bottom',
|
|
449
|
top = 'top',
|
|
449
|
top = 'top',
|
|
450
|
left = 'left',
|
|
450
|
left = 'left',
|
|
451
|
right = 'right',
|
|
451
|
right = 'right',
|
|
452
|
source = source,
|
|
452
|
source = source,
|
|
453
|
fill_alpha = 0,
|
|
453
|
fill_alpha = 0,
|
|
454
|
#line_color = 'blue',
|
|
454
|
#line_color = 'blue',
|
|
455
|
)
|
|
455
|
)
|
|
456
|
|
|
456
|
|
|
457
|
plot.line([0, npoints], [i, i])#, color='blue')
|
|
457
|
plot.line([0, npoints], [i, i])#, color='blue')
|
|
458
|
|
|
458
|
|
|
459
|
return components(plot, CDN)
|
|
459
|
return components(plot, CDN)
|
|
460
|
|
|
460
|
|
|
461
|
def request(self, cmd, method='get', **kwargs):
|
|
461
|
def request(self, cmd, method='get', **kwargs):
|
|
462
|
|
|
462
|
|
|
463
|
req = getattr(requests, method)(self.device.url(cmd), **kwargs)
|
|
463
|
req = getattr(requests, method)(self.device.url(cmd), **kwargs)
|
|
464
|
payload = req.json()
|
|
464
|
payload = req.json()
|
|
465
|
|
|
465
|
|
|
466
|
return payload
|
|
466
|
return payload
|
|
467
|
|
|
467
|
|
|
468
|
def status_device(self):
|
|
468
|
def status_device(self):
|
|
469
|
|
|
469
|
|
|
470
|
try:
|
|
470
|
try:
|
|
471
|
self.device.status = 0
|
|
471
|
self.device.status = 0
|
|
472
|
payload = self.request('status')
|
|
472
|
payload = self.request('status')
|
|
473
|
if payload['status']=='enable':
|
|
473
|
if payload['status']=='enable':
|
|
474
|
self.device.status = 3
|
|
474
|
self.device.status = 3
|
|
475
|
elif payload['status']=='disable':
|
|
475
|
elif payload['status']=='disable':
|
|
476
|
self.device.status = 2
|
|
476
|
self.device.status = 2
|
|
477
|
else:
|
|
477
|
else:
|
|
478
|
self.device.status = 1
|
|
478
|
self.device.status = 1
|
|
479
|
self.device.save()
|
|
479
|
self.device.save()
|
|
480
|
self.message = 'RC status: {}'.format(payload['status'])
|
|
480
|
self.message = 'RC status: {}'.format(payload['status'])
|
|
481
|
return False
|
|
481
|
return False
|
|
482
|
except Exception as e:
|
|
482
|
except Exception as e:
|
|
483
|
if 'No route to host' not in str(e):
|
|
483
|
if 'No route to host' not in str(e):
|
|
484
|
self.device.status = 4
|
|
484
|
self.device.status = 4
|
|
485
|
self.device.save()
|
|
485
|
self.device.save()
|
|
486
|
self.message = 'RC status: {}'.format(str(e))
|
|
486
|
self.message = 'RC status: {}'.format(str(e))
|
|
487
|
return False
|
|
487
|
return False
|
|
488
|
|
|
488
|
|
|
489
|
self.device.save()
|
|
489
|
self.device.save()
|
|
490
|
return True
|
|
490
|
return True
|
|
491
|
|
|
491
|
|
|
492
|
def reset_device(self):
|
|
492
|
def reset_device(self):
|
|
493
|
|
|
493
|
|
|
494
|
try:
|
|
494
|
try:
|
|
495
|
payload = self.request('reset', 'post')
|
|
495
|
payload = self.request('reset', 'post')
|
|
496
|
if payload['reset']=='ok':
|
|
496
|
if payload['reset']=='ok':
|
|
497
|
self.message = 'RC restarted OK'
|
|
497
|
self.message = 'RC restarted OK'
|
|
498
|
self.device.status = 2
|
|
498
|
self.device.status = 2
|
|
499
|
self.device.save()
|
|
499
|
self.device.save()
|
|
500
|
else:
|
|
500
|
else:
|
|
501
|
self.message = 'RC restart fail'
|
|
501
|
self.message = 'RC restart fail'
|
|
502
|
self.device.status = 4
|
|
502
|
self.device.status = 4
|
|
503
|
self.device.save()
|
|
503
|
self.device.save()
|
|
504
|
except Exception as e:
|
|
504
|
except Exception as e:
|
|
505
|
self.message = 'RC reset: {}'.format(str(e))
|
|
505
|
self.message = 'RC reset: {}'.format(str(e))
|
|
506
|
return False
|
|
506
|
return False
|
|
507
|
|
|
507
|
|
|
508
|
return True
|
|
508
|
return True
|
|
509
|
|
|
509
|
|
|
510
|
def stop_device(self):
|
|
510
|
def stop_device(self):
|
|
511
|
|
|
511
|
|
|
512
|
try:
|
|
512
|
try:
|
|
513
|
payload = self.request('stop', 'post')
|
|
513
|
payload = self.request('stop', 'post')
|
|
514
|
self.message = 'RC stop: {}'.format(payload['stop'])
|
|
514
|
self.message = 'RC stop: {}'.format(payload['stop'])
|
|
515
|
if payload['stop']=='ok':
|
|
515
|
if payload['stop']=='ok':
|
|
516
|
self.device.status = 2
|
|
516
|
self.device.status = 2
|
|
517
|
self.device.save()
|
|
517
|
self.device.save()
|
|
518
|
else:
|
|
518
|
else:
|
|
519
|
self.device.status = 4
|
|
519
|
self.device.status = 4
|
|
520
|
self.device.save()
|
|
520
|
self.device.save()
|
|
521
|
return False
|
|
521
|
return False
|
|
522
|
except Exception as e:
|
|
522
|
except Exception as e:
|
|
523
|
if 'No route to host' not in str(e):
|
|
523
|
if 'No route to host' not in str(e):
|
|
524
|
self.device.status = 4
|
|
524
|
self.device.status = 4
|
|
525
|
else:
|
|
525
|
else:
|
|
526
|
self.device.status = 0
|
|
526
|
self.device.status = 0
|
|
527
|
self.message = 'RC stop: {}'.format(str(e))
|
|
527
|
self.message = 'RC stop: {}'.format(str(e))
|
|
528
|
self.device.save()
|
|
528
|
self.device.save()
|
|
529
|
return False
|
|
529
|
return False
|
|
530
|
|
|
530
|
|
|
531
|
return True
|
|
531
|
return True
|
|
532
|
|
|
532
|
|
|
533
|
def start_device(self):
|
|
533
|
def start_device(self):
|
|
534
|
|
|
534
|
|
|
535
|
try:
|
|
535
|
try:
|
|
536
|
payload = self.request('start', 'post')
|
|
536
|
payload = self.request('start', 'post')
|
|
537
|
self.message = 'RC start: {}'.format(payload['start'])
|
|
537
|
self.message = 'RC start: {}'.format(payload['start'])
|
|
538
|
if payload['start']=='ok':
|
|
538
|
if payload['start']=='ok':
|
|
539
|
self.device.status = 3
|
|
539
|
self.device.status = 3
|
|
540
|
self.device.save()
|
|
540
|
self.device.save()
|
|
541
|
else:
|
|
541
|
else:
|
|
542
|
return False
|
|
542
|
return False
|
|
543
|
except Exception as e:
|
|
543
|
except Exception as e:
|
|
544
|
if 'No route to host' not in str(e):
|
|
544
|
if 'No route to host' not in str(e):
|
|
545
|
self.device.status = 4
|
|
545
|
self.device.status = 4
|
|
546
|
else:
|
|
546
|
else:
|
|
547
|
self.device.status = 0
|
|
547
|
self.device.status = 0
|
|
548
|
self.message = 'RC start: {}'.format(str(e))
|
|
548
|
self.message = 'RC start: {}'.format(str(e))
|
|
549
|
self.device.save()
|
|
549
|
self.device.save()
|
|
550
|
return False
|
|
550
|
return False
|
|
551
|
|
|
551
|
|
|
552
|
return True
|
|
552
|
return True
|
|
553
|
|
|
553
|
|
|
554
|
def write_device(self, raw=False):
|
|
554
|
def write_device(self, raw=False):
|
|
555
|
print("write device")
|
|
555
|
print("write device")
|
|
556
|
|
|
556
|
|
|
557
|
if not raw:
|
|
557
|
if not raw:
|
|
558
|
clock = RCClock.objects.get(rc_configuration=self)
|
|
558
|
clock = RCClock.objects.get(rc_configuration=self)
|
|
559
|
if clock.mode:
|
|
559
|
if clock.mode:
|
|
560
|
data = {'default': clock.frequency}
|
|
560
|
data = {'default': clock.frequency}
|
|
561
|
else:
|
|
561
|
else:
|
|
562
|
data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
|
|
562
|
data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
|
|
563
|
payload = self.request('setfreq', 'post', data=json.dumps(data))
|
|
563
|
payload = self.request('setfreq', 'post', data=json.dumps(data))
|
|
564
|
if payload['setfreq'] != 'ok':
|
|
564
|
if payload['command'] != 'ok':
|
|
565
|
self.message = 'RC write: {}'.format(payload['setfreq'])
|
|
565
|
self.message = 'RC write: {}'.format(payload['command'])
|
|
566
|
else:
|
|
566
|
else:
|
|
567
|
self.message = payload['setfreq']
|
|
567
|
self.message = payload['programming']
|
|
568
|
if payload['setfreq'] == 'fail':
|
|
568
|
if payload['programming'] == 'fail':
|
|
569
|
self.message = 'RC write: error programming CGS chip'
|
|
569
|
self.message = 'RC write: error programming CGS chip'
|
|
570
|
|
|
570
|
|
|
571
|
values = []
|
|
571
|
values = []
|
|
572
|
for pulse, delay in zip(self.get_pulses(), self.get_delays()):
|
|
572
|
for pulse, delay in zip(self.get_pulses(), self.get_delays()):
|
|
573
|
while delay > 65536:
|
|
573
|
while delay > 65536:
|
|
574
|
values.append((pulse, 65535))
|
|
574
|
values.append((pulse, 65535))
|
|
575
|
delay -= 65536
|
|
575
|
delay -= 65536
|
|
576
|
values.append((pulse, delay-1))
|
|
576
|
values.append((pulse, delay-1))
|
|
577
|
data = bytearray()
|
|
577
|
data = bytearray()
|
|
578
|
#reset
|
|
578
|
#reset
|
|
579
|
data.extend((128, 0))
|
|
579
|
data.extend((128, 0))
|
|
580
|
#disable
|
|
580
|
#disable
|
|
581
|
data.extend((129, 0))
|
|
581
|
data.extend((129, 0))
|
|
582
|
#SW switch
|
|
582
|
#SW switch
|
|
583
|
if self.control_sw:
|
|
583
|
if self.control_sw:
|
|
584
|
data.extend((130, 2))
|
|
584
|
data.extend((130, 2))
|
|
585
|
else:
|
|
585
|
else:
|
|
586
|
data.extend((130, 0))
|
|
586
|
data.extend((130, 0))
|
|
587
|
#divider
|
|
587
|
#divider
|
|
588
|
data.extend((131, self.clock_divider-1))
|
|
588
|
data.extend((131, self.clock_divider-1))
|
|
589
|
#enable writing
|
|
589
|
#enable writing
|
|
590
|
data.extend((139, 62))
|
|
590
|
data.extend((139, 62))
|
|
591
|
|
|
591
|
|
|
592
|
last = 0
|
|
592
|
last = 0
|
|
593
|
for tup in values:
|
|
593
|
for tup in values:
|
|
594
|
vals = pack('<HH', last^tup[0], tup[1])
|
|
594
|
vals = pack('<HH', last^tup[0], tup[1])
|
|
595
|
last = tup[0]
|
|
595
|
last = tup[0]
|
|
596
|
data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
|
|
596
|
data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
|
|
597
|
|
|
597
|
|
|
598
|
#enable
|
|
598
|
#enable
|
|
599
|
data.extend((129, 1))
|
|
599
|
data.extend((129, 1))
|
|
600
|
|
|
600
|
|
|
601
|
if raw:
|
|
601
|
if raw:
|
|
602
|
return b64encode(data)
|
|
602
|
return b64encode(data)
|
|
603
|
|
|
603
|
|
|
604
|
#try:
|
|
604
|
#try:
|
|
605
|
payload = self.request('stop', 'post')
|
|
605
|
payload = self.request('stop', 'post')
|
|
606
|
payload = self.request('reset', 'post')
|
|
606
|
payload = self.request('reset', 'post')
|
|
607
|
#payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
|
|
607
|
#payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
|
|
608
|
#payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
|
|
608
|
#payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
|
|
609
|
n = len(data)
|
|
609
|
n = len(data)
|
|
610
|
x = 0
|
|
610
|
x = 0
|
|
611
|
#while x < n:
|
|
611
|
#while x < n:
|
|
612
|
payload = self.request('write', 'post', data=b64encode(data))
|
|
612
|
payload = self.request('write', 'post', data=b64encode(data))
|
|
613
|
# x += 1024
|
|
613
|
# x += 1024
|
|
614
|
|
|
614
|
|
|
615
|
if payload['write']=='ok':
|
|
615
|
if payload['write']=='ok':
|
|
616
|
self.device.status = 3
|
|
616
|
self.device.status = 3
|
|
617
|
self.device.save()
|
|
617
|
self.device.save()
|
|
618
|
self.message = 'RC configured and started'
|
|
618
|
self.message = 'RC configured and started'
|
|
619
|
else:
|
|
619
|
else:
|
|
620
|
self.device.status = 1
|
|
620
|
self.device.status = 1
|
|
621
|
self.device.save()
|
|
621
|
self.device.save()
|
|
622
|
self.message = 'RC write: {}'.format(payload['write'])
|
|
622
|
self.message = 'RC write: {}'.format(payload['write'])
|
|
623
|
return False
|
|
623
|
return False
|
|
624
|
|
|
624
|
|
|
625
|
#payload = self.request('start', 'post')
|
|
625
|
#payload = self.request('start', 'post')
|
|
626
|
|
|
626
|
|
|
627
|
#except Exception as e:
|
|
627
|
#except Exception as e:
|
|
628
|
# if 'No route to host' not in str(e):
|
|
628
|
# if 'No route to host' not in str(e):
|
|
629
|
# self.device.status = 4
|
|
629
|
# self.device.status = 4
|
|
630
|
# else:
|
|
630
|
# else:
|
|
631
|
# self.device.status = 0
|
|
631
|
# self.device.status = 0
|
|
632
|
# self.message = 'RC write: {}'.format(str(e))
|
|
632
|
# self.message = 'RC write: {}'.format(str(e))
|
|
633
|
# self.device.save()
|
|
633
|
# self.device.save()
|
|
634
|
# return False
|
|
634
|
# return False
|
|
635
|
|
|
635
|
|
|
636
|
return True
|
|
636
|
return True
|
|
637
|
|
|
637
|
|
|
638
|
|
|
638
|
|
|
639
|
def get_absolute_url_import(self):
|
|
639
|
def get_absolute_url_import(self):
|
|
640
|
return reverse('url_import_rc_conf', args=[str(self.id)])
|
|
640
|
return reverse('url_import_rc_conf', args=[str(self.id)])
|
|
641
|
|
|
641
|
|
|
642
|
|
|
642
|
|
|
643
|
class RCLineCode(models.Model):
|
|
643
|
class RCLineCode(models.Model):
|
|
644
|
|
|
644
|
|
|
645
|
name = models.CharField(max_length=40)
|
|
645
|
name = models.CharField(max_length=40)
|
|
646
|
bits_per_code = models.PositiveIntegerField(default=0)
|
|
646
|
bits_per_code = models.PositiveIntegerField(default=0)
|
|
647
|
number_of_codes = models.PositiveIntegerField(default=0)
|
|
647
|
number_of_codes = models.PositiveIntegerField(default=0)
|
|
648
|
codes = models.TextField(blank=True, null=True)
|
|
648
|
codes = models.TextField(blank=True, null=True)
|
|
649
|
|
|
649
|
|
|
650
|
class Meta:
|
|
650
|
class Meta:
|
|
651
|
db_table = 'rc_line_codes'
|
|
651
|
db_table = 'rc_line_codes'
|
|
652
|
ordering = ('name',)
|
|
652
|
ordering = ('name',)
|
|
653
|
|
|
653
|
|
|
654
|
def __str__(self):
|
|
654
|
def __str__(self):
|
|
655
|
return u'%s' % self.name
|
|
655
|
return u'%s' % self.name
|
|
656
|
|
|
656
|
|
|
657
|
|
|
657
|
|
|
658
|
class RCLineType(models.Model):
|
|
658
|
class RCLineType(models.Model):
|
|
659
|
|
|
659
|
|
|
660
|
name = models.CharField(choices=LINE_TYPES, max_length=40)
|
|
660
|
name = models.CharField(choices=LINE_TYPES, max_length=40)
|
|
661
|
description = models.TextField(blank=True, null=True)
|
|
661
|
description = models.TextField(blank=True, null=True)
|
|
662
|
params = models.TextField(default='[]')
|
|
662
|
params = models.TextField(default='[]')
|
|
663
|
|
|
663
|
|
|
664
|
class Meta:
|
|
664
|
class Meta:
|
|
665
|
db_table = 'rc_line_types'
|
|
665
|
db_table = 'rc_line_types'
|
|
666
|
|
|
666
|
|
|
667
|
def __str__(self):
|
|
667
|
def __str__(self):
|
|
668
|
return u'%s - %s' % (self.name.upper(), self.get_name_display())
|
|
668
|
return u'%s - %s' % (self.name.upper(), self.get_name_display())
|
|
669
|
|
|
669
|
|
|
670
|
|
|
670
|
|
|
671
|
class RCLine(models.Model):
|
|
671
|
class RCLine(models.Model):
|
|
672
|
|
|
672
|
|
|
673
|
rc_configuration = models.ForeignKey('RCConfiguration', on_delete=models.CASCADE)
|
|
673
|
rc_configuration = models.ForeignKey('RCConfiguration', on_delete=models.CASCADE)
|
|
674
|
line_type = models.ForeignKey('RCLineType',on_delete=models.CASCADE)
|
|
674
|
line_type = models.ForeignKey('RCLineType',on_delete=models.CASCADE)
|
|
675
|
channel = models.PositiveIntegerField(default=0)
|
|
675
|
channel = models.PositiveIntegerField(default=0)
|
|
676
|
position = models.PositiveIntegerField(default=0)
|
|
676
|
position = models.PositiveIntegerField(default=0)
|
|
677
|
params = models.TextField(default='{}')
|
|
677
|
params = models.TextField(default='{}')
|
|
678
|
pulses = models.TextField(default='')
|
|
678
|
pulses = models.TextField(default='')
|
|
679
|
|
|
679
|
|
|
680
|
class Meta:
|
|
680
|
class Meta:
|
|
681
|
db_table = 'rc_lines'
|
|
681
|
db_table = 'rc_lines'
|
|
682
|
ordering = ['channel']
|
|
682
|
ordering = ['channel']
|
|
683
|
|
|
683
|
|
|
684
|
def __str__(self):
|
|
684
|
def __str__(self):
|
|
685
|
if self.rc_configuration:
|
|
685
|
if self.rc_configuration:
|
|
686
|
return u'{}|{} - {}'.format(self.pk, self.get_name(), self.rc_configuration.name)
|
|
686
|
return u'{}|{} - {}'.format(self.pk, self.get_name(), self.rc_configuration.name)
|
|
687
|
|
|
687
|
|
|
688
|
def jsonify(self):
|
|
688
|
def jsonify(self):
|
|
689
|
|
|
689
|
|
|
690
|
data = {}
|
|
690
|
data = {}
|
|
691
|
data['params'] = json.loads(self.params)
|
|
691
|
data['params'] = json.loads(self.params)
|
|
692
|
data['id'] = '{}'.format(self.pk)
|
|
692
|
data['id'] = '{}'.format(self.pk)
|
|
693
|
data['line_type'] = self.line_type.name
|
|
693
|
data['line_type'] = self.line_type.name
|
|
694
|
data['name'] = self.get_name()
|
|
694
|
data['name'] = self.get_name()
|
|
695
|
if data['line_type']=='codes':
|
|
695
|
if data['line_type']=='codes':
|
|
696
|
data['params']['code'] = RCLineCode.objects.get(pk=data['params']['code']).name
|
|
696
|
data['params']['code'] = RCLineCode.objects.get(pk=data['params']['code']).name
|
|
697
|
|
|
697
|
|
|
698
|
return data
|
|
698
|
return data
|
|
699
|
|
|
699
|
|
|
700
|
|
|
700
|
|
|
701
|
def clone(self, **kwargs):
|
|
701
|
def clone(self, **kwargs):
|
|
702
|
|
|
702
|
|
|
703
|
self.pk = None
|
|
703
|
self.pk = None
|
|
704
|
self.id = None
|
|
704
|
self.id = None
|
|
705
|
|
|
705
|
|
|
706
|
for attr, value in kwargs.items():
|
|
706
|
for attr, value in kwargs.items():
|
|
707
|
setattr(self, attr, value)
|
|
707
|
setattr(self, attr, value)
|
|
708
|
|
|
708
|
|
|
709
|
self.save()
|
|
709
|
self.save()
|
|
710
|
|
|
710
|
|
|
711
|
return self
|
|
711
|
return self
|
|
712
|
|
|
712
|
|
|
713
|
def get_name(self, channel=False):
|
|
713
|
def get_name(self, channel=False):
|
|
714
|
|
|
714
|
|
|
715
|
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
715
|
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
716
|
s = ''
|
|
716
|
s = ''
|
|
717
|
|
|
717
|
|
|
718
|
if self.line_type.name in ('tx',):
|
|
718
|
if self.line_type.name in ('tx',):
|
|
719
|
s = chars[self.position]
|
|
719
|
s = chars[self.position]
|
|
720
|
elif self.line_type.name in ('codes', 'windows', 'tr'):
|
|
720
|
elif self.line_type.name in ('codes', 'windows', 'tr'):
|
|
721
|
if 'TX_ref' in json.loads(self.params):
|
|
721
|
if 'TX_ref' in json.loads(self.params):
|
|
722
|
pk = json.loads(self.params)['TX_ref']
|
|
722
|
pk = json.loads(self.params)['TX_ref']
|
|
723
|
if pk in (0, '0'):
|
|
723
|
if pk in (0, '0'):
|
|
724
|
s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
|
|
724
|
s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
|
|
725
|
else:
|
|
725
|
else:
|
|
726
|
ref = RCLine.objects.get(pk=pk)
|
|
726
|
ref = RCLine.objects.get(pk=pk)
|
|
727
|
s = chars[ref.position]
|
|
727
|
s = chars[ref.position]
|
|
728
|
s = '({})'.format(s)
|
|
728
|
s = '({})'.format(s)
|
|
729
|
|
|
729
|
|
|
730
|
s = '{}{}'.format(self.line_type.name.upper(), s)
|
|
730
|
s = '{}{}'.format(self.line_type.name.upper(), s)
|
|
731
|
|
|
731
|
|
|
732
|
if channel:
|
|
732
|
if channel:
|
|
733
|
return '{} {}'.format(s, self.channel)
|
|
733
|
return '{} {}'.format(s, self.channel)
|
|
734
|
else:
|
|
734
|
else:
|
|
735
|
return s
|
|
735
|
return s
|
|
736
|
|
|
736
|
|
|
737
|
def get_lines(self, **kwargs):
|
|
737
|
def get_lines(self, **kwargs):
|
|
738
|
|
|
738
|
|
|
739
|
return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
|
|
739
|
return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
|
|
740
|
|
|
740
|
|
|
741
|
def pulses_as_array(self):
|
|
741
|
def pulses_as_array(self):
|
|
742
|
|
|
742
|
|
|
743
|
y = np.zeros(self.rc_configuration.total_units)
|
|
743
|
y = np.zeros(self.rc_configuration.total_units)
|
|
744
|
|
|
744
|
|
|
745
|
for tup in ast.literal_eval(self.pulses):
|
|
745
|
for tup in ast.literal_eval(self.pulses):
|
|
746
|
y[tup[0]:tup[1]] = 1
|
|
746
|
y[tup[0]:tup[1]] = 1
|
|
747
|
|
|
747
|
|
|
748
|
return y.astype(np.int8)
|
|
748
|
return y.astype(np.int8)
|
|
749
|
|
|
749
|
|
|
750
|
def pulses_as_points(self, km=False):
|
|
750
|
def pulses_as_points(self, km=False):
|
|
751
|
|
|
751
|
|
|
752
|
if km:
|
|
752
|
if km:
|
|
753
|
unit2km = 1/self.rc_configuration.km2unit
|
|
753
|
unit2km = 1/self.rc_configuration.km2unit
|
|
754
|
return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
|
|
754
|
return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
|
|
755
|
else:
|
|
755
|
else:
|
|
756
|
return ast.literal_eval(self.pulses)
|
|
756
|
return ast.literal_eval(self.pulses)
|
|
757
|
|
|
757
|
|
|
758
|
def get_win_ref(self, params, tx_id, km2unit):
|
|
758
|
def get_win_ref(self, params, tx_id, km2unit):
|
|
759
|
|
|
759
|
|
|
760
|
ref = self.rc_configuration.sampling_reference
|
|
760
|
ref = self.rc_configuration.sampling_reference
|
|
761
|
codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
|
|
761
|
codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
|
|
762
|
|
|
762
|
|
|
763
|
if codes:
|
|
763
|
if codes:
|
|
764
|
tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
|
|
764
|
tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
|
|
765
|
else:
|
|
765
|
else:
|
|
766
|
tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
|
|
766
|
tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
|
|
767
|
|
|
767
|
|
|
768
|
if ref=='first_baud':
|
|
768
|
if ref=='first_baud':
|
|
769
|
return int(1 + round((tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit))
|
|
769
|
return int(1 + round((tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit))
|
|
770
|
elif ref=='sub_baud':
|
|
770
|
elif ref=='sub_baud':
|
|
771
|
return np.ceil(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
|
|
771
|
return np.ceil(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
|
|
772
|
else:
|
|
772
|
else:
|
|
773
|
return 0
|
|
773
|
return 0
|
|
774
|
|
|
774
|
|
|
775
|
def update_pulses(self):
|
|
775
|
def update_pulses(self):
|
|
776
|
'''
|
|
776
|
'''
|
|
777
|
Update pulses field
|
|
777
|
Update pulses field
|
|
778
|
'''
|
|
778
|
'''
|
|
779
|
|
|
779
|
|
|
780
|
km2unit = self.rc_configuration.km2unit
|
|
780
|
km2unit = self.rc_configuration.km2unit
|
|
781
|
us2unit = self.rc_configuration.us2unit
|
|
781
|
us2unit = self.rc_configuration.us2unit
|
|
782
|
ipp = self.rc_configuration.ipp
|
|
782
|
ipp = self.rc_configuration.ipp
|
|
783
|
ntx = int(self.rc_configuration.ntx)
|
|
783
|
ntx = int(self.rc_configuration.ntx)
|
|
784
|
ipp_u = int(ipp*km2unit)
|
|
784
|
ipp_u = int(ipp*km2unit)
|
|
785
|
total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
|
|
785
|
total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
|
|
786
|
y = []
|
|
786
|
y = []
|
|
787
|
|
|
787
|
|
|
788
|
if self.line_type.name=='tr':
|
|
788
|
if self.line_type.name=='tr':
|
|
789
|
tr_params = json.loads(self.params)
|
|
789
|
tr_params = json.loads(self.params)
|
|
790
|
#print(tr_params)
|
|
790
|
#print(tr_params)
|
|
791
|
#print(tr_params['TX_ref'])
|
|
791
|
#print(tr_params['TX_ref'])
|
|
792
|
if tr_params['TX_ref'] in ('0', 0):
|
|
792
|
if tr_params['TX_ref'] in ('0', 0):
|
|
793
|
txs = self.get_lines(line_type__name='tx')
|
|
793
|
txs = self.get_lines(line_type__name='tx')
|
|
794
|
else:
|
|
794
|
else:
|
|
795
|
txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
|
|
795
|
txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
|
|
796
|
|
|
796
|
|
|
797
|
for tx in txs:
|
|
797
|
for tx in txs:
|
|
798
|
params = json.loads(tx.params)
|
|
798
|
params = json.loads(tx.params)
|
|
799
|
|
|
799
|
|
|
800
|
if float(params['pulse_width'])==0:
|
|
800
|
if float(params['pulse_width'])==0:
|
|
801
|
continue
|
|
801
|
continue
|
|
802
|
delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
|
|
802
|
delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
|
|
803
|
width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
|
|
803
|
width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
|
|
804
|
before = 0
|
|
804
|
before = 0
|
|
805
|
after = int(self.rc_configuration.time_after*us2unit)
|
|
805
|
after = int(self.rc_configuration.time_after*us2unit)
|
|
806
|
|
|
806
|
|
|
807
|
y_tx = self.points(ntx, ipp_u, width,
|
|
807
|
y_tx = self.points(ntx, ipp_u, width,
|
|
808
|
delay=delays,
|
|
808
|
delay=delays,
|
|
809
|
before=before,
|
|
809
|
before=before,
|
|
810
|
after=after,
|
|
810
|
after=after,
|
|
811
|
sync=self.rc_configuration.sync)
|
|
811
|
sync=self.rc_configuration.sync)
|
|
812
|
|
|
812
|
|
|
813
|
ranges = params['range'].split(',')
|
|
813
|
ranges = params['range'].split(',')
|
|
814
|
|
|
814
|
|
|
815
|
if len(ranges)>0 and ranges[0]!='0':
|
|
815
|
if len(ranges)>0 and ranges[0]!='0':
|
|
816
|
y_tx = self.mask_ranges(y_tx, ranges)
|
|
816
|
y_tx = self.mask_ranges(y_tx, ranges)
|
|
817
|
|
|
817
|
|
|
818
|
tr_ranges = tr_params['range'].split(',')
|
|
818
|
tr_ranges = tr_params['range'].split(',')
|
|
819
|
|
|
819
|
|
|
820
|
if len(tr_ranges)>0 and tr_ranges[0]!='0':
|
|
820
|
if len(tr_ranges)>0 and tr_ranges[0]!='0':
|
|
821
|
y_tx = self.mask_ranges(y_tx, tr_ranges)
|
|
821
|
y_tx = self.mask_ranges(y_tx, tr_ranges)
|
|
822
|
|
|
822
|
|
|
823
|
y.extend(y_tx)
|
|
823
|
y.extend(y_tx)
|
|
824
|
|
|
824
|
|
|
825
|
self.pulses = str(y)
|
|
825
|
self.pulses = str(y)
|
|
826
|
y = self.array_to_points(self.pulses_as_array())
|
|
826
|
y = self.array_to_points(self.pulses_as_array())
|
|
827
|
|
|
827
|
|
|
828
|
elif self.line_type.name=='tx':
|
|
828
|
elif self.line_type.name=='tx':
|
|
829
|
params = json.loads(self.params)
|
|
829
|
params = json.loads(self.params)
|
|
830
|
delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
|
|
830
|
delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
|
|
831
|
width = float(params['pulse_width'])*km2unit
|
|
831
|
width = float(params['pulse_width'])*km2unit
|
|
832
|
|
|
832
|
|
|
833
|
if width>0:
|
|
833
|
if width>0:
|
|
834
|
before = int(self.rc_configuration.time_before*us2unit)
|
|
834
|
before = int(self.rc_configuration.time_before*us2unit)
|
|
835
|
after = 0
|
|
835
|
after = 0
|
|
836
|
|
|
836
|
|
|
837
|
y = self.points(ntx, ipp_u, width,
|
|
837
|
y = self.points(ntx, ipp_u, width,
|
|
838
|
delay=delays,
|
|
838
|
delay=delays,
|
|
839
|
before=before,
|
|
839
|
before=before,
|
|
840
|
after=after,
|
|
840
|
after=after,
|
|
841
|
sync=self.rc_configuration.sync)
|
|
841
|
sync=self.rc_configuration.sync)
|
|
842
|
|
|
842
|
|
|
843
|
ranges = params['range'].split(',')
|
|
843
|
ranges = params['range'].split(',')
|
|
844
|
|
|
844
|
|
|
845
|
if len(ranges)>0 and ranges[0]!='0':
|
|
845
|
if len(ranges)>0 and ranges[0]!='0':
|
|
846
|
y = self.mask_ranges(y, ranges)
|
|
846
|
y = self.mask_ranges(y, ranges)
|
|
847
|
|
|
847
|
|
|
848
|
elif self.line_type.name=='flip':
|
|
848
|
elif self.line_type.name=='flip':
|
|
849
|
n = float(json.loads(self.params)['number_of_flips'])
|
|
849
|
n = float(json.loads(self.params)['number_of_flips'])
|
|
850
|
width = n*ipp*km2unit
|
|
850
|
width = n*ipp*km2unit
|
|
851
|
y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
|
|
851
|
y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
|
|
852
|
|
|
852
|
|
|
853
|
elif self.line_type.name=='codes':
|
|
853
|
elif self.line_type.name=='codes':
|
|
854
|
params = json.loads(self.params)
|
|
854
|
params = json.loads(self.params)
|
|
855
|
tx = RCLine.objects.get(pk=params['TX_ref'])
|
|
855
|
tx = RCLine.objects.get(pk=params['TX_ref'])
|
|
856
|
tx_params = json.loads(tx.params)
|
|
856
|
tx_params = json.loads(tx.params)
|
|
857
|
delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
|
|
857
|
delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
|
|
858
|
f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
|
|
858
|
f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
|
|
859
|
codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
|
|
859
|
codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
|
|
860
|
codes = [self.array_to_points(code) for code in codes]
|
|
860
|
codes = [self.array_to_points(code) for code in codes]
|
|
861
|
n = len(codes)
|
|
861
|
n = len(codes)
|
|
862
|
|
|
862
|
|
|
863
|
ranges = tx_params['range'].split(',')
|
|
863
|
ranges = tx_params['range'].split(',')
|
|
864
|
if len(ranges)>0 and ranges[0]!='0':
|
|
864
|
if len(ranges)>0 and ranges[0]!='0':
|
|
865
|
dum = self.mask_ranges(tx.pulses_as_points(), ranges)
|
|
865
|
dum = self.mask_ranges(tx.pulses_as_points(), ranges)
|
|
866
|
else:
|
|
866
|
else:
|
|
867
|
dum = tx.pulses_as_points()
|
|
867
|
dum = tx.pulses_as_points()
|
|
868
|
|
|
868
|
|
|
869
|
for i, tup in enumerate(dum):
|
|
869
|
for i, tup in enumerate(dum):
|
|
870
|
if tup==(0,0): continue
|
|
870
|
if tup==(0,0): continue
|
|
871
|
code = codes[i%n]
|
|
871
|
code = codes[i%n]
|
|
872
|
y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
|
|
872
|
y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
|
|
873
|
|
|
873
|
|
|
874
|
elif self.line_type.name=='sync':
|
|
874
|
elif self.line_type.name=='sync':
|
|
875
|
params = json.loads(self.params)
|
|
875
|
params = json.loads(self.params)
|
|
876
|
n = ipp_u*ntx
|
|
876
|
n = ipp_u*ntx
|
|
877
|
if params['invert'] in ('1', 1):
|
|
877
|
if params['invert'] in ('1', 1):
|
|
878
|
y = [(n-1, n)]
|
|
878
|
y = [(n-1, n)]
|
|
879
|
else:
|
|
879
|
else:
|
|
880
|
y = [(0, 1)]
|
|
880
|
y = [(0, 1)]
|
|
881
|
|
|
881
|
|
|
882
|
elif self.line_type.name=='prog_pulses':
|
|
882
|
elif self.line_type.name=='prog_pulses':
|
|
883
|
params = json.loads(self.params)
|
|
883
|
params = json.loads(self.params)
|
|
884
|
if int(params['periodic'])==0:
|
|
884
|
if int(params['periodic'])==0:
|
|
885
|
nntx = 1
|
|
885
|
nntx = 1
|
|
886
|
nipp = ipp_u*ntx
|
|
886
|
nipp = ipp_u*ntx
|
|
887
|
else:
|
|
887
|
else:
|
|
888
|
nntx = ntx
|
|
888
|
nntx = ntx
|
|
889
|
nipp = ipp_u
|
|
889
|
nipp = ipp_u
|
|
890
|
|
|
890
|
|
|
891
|
if 'params' in params and len(params['params'])>0:
|
|
891
|
if 'params' in params and len(params['params'])>0:
|
|
892
|
for p in params['params']:
|
|
892
|
for p in params['params']:
|
|
893
|
y_pp = self.points(nntx, nipp,
|
|
893
|
y_pp = self.points(nntx, nipp,
|
|
894
|
p['end']-p['begin'],
|
|
894
|
p['end']-p['begin'],
|
|
895
|
before=p['begin'])
|
|
895
|
before=p['begin'])
|
|
896
|
|
|
896
|
|
|
897
|
y.extend(y_pp)
|
|
897
|
y.extend(y_pp)
|
|
898
|
|
|
898
|
|
|
899
|
elif self.line_type.name=='windows':
|
|
899
|
elif self.line_type.name=='windows':
|
|
900
|
params = json.loads(self.params)
|
|
900
|
params = json.loads(self.params)
|
|
901
|
if 'params' in params and len(params['params'])>0:
|
|
901
|
if 'params' in params and len(params['params'])>0:
|
|
902
|
tx = RCLine.objects.get(pk=params['TX_ref'])
|
|
902
|
tx = RCLine.objects.get(pk=params['TX_ref'])
|
|
903
|
tx_params = json.loads(tx.params)
|
|
903
|
tx_params = json.loads(tx.params)
|
|
904
|
ranges = tx_params['range'].split(',')
|
|
904
|
ranges = tx_params['range'].split(',')
|
|
905
|
for p in params['params']:
|
|
905
|
for p in params['params']:
|
|
906
|
y_win = self.points(ntx, ipp_u,
|
|
906
|
y_win = self.points(ntx, ipp_u,
|
|
907
|
p['resolution']*p['number_of_samples']*km2unit,
|
|
907
|
p['resolution']*p['number_of_samples']*km2unit,
|
|
908
|
before=int(self.rc_configuration.time_before*us2unit)+p['first_height']*km2unit,
|
|
908
|
before=int(self.rc_configuration.time_before*us2unit)+p['first_height']*km2unit,
|
|
909
|
sync=self.rc_configuration.sync+self.get_win_ref(p, params['TX_ref'], km2unit))
|
|
909
|
sync=self.rc_configuration.sync+self.get_win_ref(p, params['TX_ref'], km2unit))
|
|
910
|
|
|
910
|
|
|
911
|
|
|
911
|
|
|
912
|
if len(ranges)>0 and ranges[0]!='0':
|
|
912
|
if len(ranges)>0 and ranges[0]!='0':
|
|
913
|
y_win = self.mask_ranges(y_win, ranges)
|
|
913
|
y_win = self.mask_ranges(y_win, ranges)
|
|
914
|
|
|
914
|
|
|
915
|
y.extend(y_win)
|
|
915
|
y.extend(y_win)
|
|
916
|
|
|
916
|
|
|
917
|
elif self.line_type.name=='mix':
|
|
917
|
elif self.line_type.name=='mix':
|
|
918
|
values = self.rc_configuration.parameters.split('-')
|
|
918
|
values = self.rc_configuration.parameters.split('-')
|
|
919
|
confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
|
|
919
|
confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
|
|
920
|
modes = [value.split('|')[1] for value in values]
|
|
920
|
modes = [value.split('|')[1] for value in values]
|
|
921
|
ops = [value.split('|')[2] for value in values]
|
|
921
|
ops = [value.split('|')[2] for value in values]
|
|
922
|
delays = [value.split('|')[3] for value in values]
|
|
922
|
delays = [value.split('|')[3] for value in values]
|
|
923
|
masks = [value.split('|')[4] for value in values]
|
|
923
|
masks = [value.split('|')[4] for value in values]
|
|
924
|
print("masks")
|
|
924
|
print("masks")
|
|
925
|
print(masks)
|
|
925
|
print(masks)
|
|
926
|
print('{:8b}'.format(int(masks[0])))
|
|
926
|
print('{:8b}'.format(int(masks[0])))
|
|
927
|
mask = list('{:8b}'.format(int(masks[0])))
|
|
927
|
mask = list('{:8b}'.format(int(masks[0])))
|
|
928
|
print("mask")
|
|
928
|
print("mask")
|
|
929
|
print(mask)
|
|
929
|
print(mask)
|
|
930
|
mask.reverse()
|
|
930
|
mask.reverse()
|
|
931
|
print("mask reverse")
|
|
931
|
print("mask reverse")
|
|
932
|
print(mask)
|
|
932
|
print(mask)
|
|
933
|
if mask[self.channel] in ('0', '', ' '):
|
|
933
|
if mask[self.channel] in ('0', '', ' '):
|
|
934
|
y = np.zeros(confs[0].total_units, dtype=np.int8)
|
|
934
|
y = np.zeros(confs[0].total_units, dtype=np.int8)
|
|
935
|
else:
|
|
935
|
else:
|
|
936
|
y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
|
|
936
|
y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
|
|
937
|
|
|
937
|
|
|
938
|
for i in range(1, len(values)):
|
|
938
|
for i in range(1, len(values)):
|
|
939
|
mask = list('{:8b}'.format(int(masks[i])))
|
|
939
|
mask = list('{:8b}'.format(int(masks[i])))
|
|
940
|
mask.reverse()
|
|
940
|
mask.reverse()
|
|
941
|
|
|
941
|
|
|
942
|
if mask[self.channel] in ('0', '', ' '):
|
|
942
|
if mask[self.channel] in ('0', '', ' '):
|
|
943
|
continue
|
|
943
|
continue
|
|
944
|
Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
|
|
944
|
Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
|
|
945
|
delay = float(delays[i])*km2unit
|
|
945
|
delay = float(delays[i])*km2unit
|
|
946
|
|
|
946
|
|
|
947
|
if modes[i]=='P':
|
|
947
|
if modes[i]=='P':
|
|
948
|
if delay>0:
|
|
948
|
if delay>0:
|
|
949
|
if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
|
|
949
|
if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
|
|
950
|
y_temp = np.empty_like(Y)
|
|
950
|
y_temp = np.empty_like(Y)
|
|
951
|
y_temp[:delay] = 0
|
|
951
|
y_temp[:delay] = 0
|
|
952
|
y_temp[delay:] = Y[:-delay]
|
|
952
|
y_temp[delay:] = Y[:-delay]
|
|
953
|
elif delay+len(Y)>len(y):
|
|
953
|
elif delay+len(Y)>len(y):
|
|
954
|
y_new = np.zeros(delay+len(Y), dtype=np.int8)
|
|
954
|
y_new = np.zeros(delay+len(Y), dtype=np.int8)
|
|
955
|
y_new[:len(y)] = y
|
|
955
|
y_new[:len(y)] = y
|
|
956
|
y = y_new
|
|
956
|
y = y_new
|
|
957
|
y_temp = np.zeros(delay+len(Y), dtype=np.int8)
|
|
957
|
y_temp = np.zeros(delay+len(Y), dtype=np.int8)
|
|
958
|
y_temp[-len(Y):] = Y
|
|
958
|
y_temp[-len(Y):] = Y
|
|
959
|
elif delay+len(Y)==len(y):
|
|
959
|
elif delay+len(Y)==len(y):
|
|
960
|
y_temp = np.zeros(delay+len(Y))
|
|
960
|
y_temp = np.zeros(delay+len(Y))
|
|
961
|
y_temp[-len(Y):] = Y
|
|
961
|
y_temp[-len(Y):] = Y
|
|
962
|
elif delay+len(Y)<len(y):
|
|
962
|
elif delay+len(Y)<len(y):
|
|
963
|
y_temp = np.zeros(len(y), dtype=np.int8)
|
|
963
|
y_temp = np.zeros(len(y), dtype=np.int8)
|
|
964
|
y_temp[delay:delay+len(Y)] = Y
|
|
964
|
y_temp[delay:delay+len(Y)] = Y
|
|
965
|
else:
|
|
965
|
else:
|
|
966
|
y_temp = Y.copy()
|
|
966
|
y_temp = Y.copy()
|
|
967
|
|
|
967
|
|
|
968
|
if ops[i]=='OR':
|
|
968
|
if ops[i]=='OR':
|
|
969
|
y = y | y_temp
|
|
969
|
y = y | y_temp
|
|
970
|
elif ops[i]=='XOR':
|
|
970
|
elif ops[i]=='XOR':
|
|
971
|
y = y ^ y_temp
|
|
971
|
y = y ^ y_temp
|
|
972
|
elif ops[i]=='AND':
|
|
972
|
elif ops[i]=='AND':
|
|
973
|
y = y & y_temp
|
|
973
|
y = y & y_temp
|
|
974
|
elif ops[i]=='NAND':
|
|
974
|
elif ops[i]=='NAND':
|
|
975
|
y = y & ~y_temp
|
|
975
|
y = y & ~y_temp
|
|
976
|
else:
|
|
976
|
else:
|
|
977
|
y = np.concatenate([y, Y])
|
|
977
|
y = np.concatenate([y, Y])
|
|
978
|
|
|
978
|
|
|
979
|
total = len(y)
|
|
979
|
total = len(y)
|
|
980
|
y = self.array_to_points(y)
|
|
980
|
y = self.array_to_points(y)
|
|
981
|
|
|
981
|
|
|
982
|
else:
|
|
982
|
else:
|
|
983
|
y = []
|
|
983
|
y = []
|
|
984
|
|
|
984
|
|
|
985
|
if self.rc_configuration.total_units != total:
|
|
985
|
if self.rc_configuration.total_units != total:
|
|
986
|
self.rc_configuration.total_units = total
|
|
986
|
self.rc_configuration.total_units = total
|
|
987
|
self.rc_configuration.save()
|
|
987
|
self.rc_configuration.save()
|
|
988
|
|
|
988
|
|
|
989
|
self.pulses = str(y)
|
|
989
|
self.pulses = str(y)
|
|
990
|
self.save()
|
|
990
|
self.save()
|
|
991
|
|
|
991
|
|
|
992
|
@staticmethod
|
|
992
|
@staticmethod
|
|
993
|
def array_to_points(X):
|
|
993
|
def array_to_points(X):
|
|
994
|
|
|
994
|
|
|
995
|
if X.size==0:
|
|
995
|
if X.size==0:
|
|
996
|
return []
|
|
996
|
return []
|
|
997
|
|
|
997
|
|
|
998
|
d = X[1:]-X[:-1]
|
|
998
|
d = X[1:]-X[:-1]
|
|
999
|
|
|
999
|
|
|
1000
|
up = np.where(d==1)[0]
|
|
1000
|
up = np.where(d==1)[0]
|
|
1001
|
if X[0]==1:
|
|
1001
|
if X[0]==1:
|
|
1002
|
up = np.concatenate((np.array([-1]), up))
|
|
1002
|
up = np.concatenate((np.array([-1]), up))
|
|
1003
|
up += 1
|
|
1003
|
up += 1
|
|
1004
|
|
|
1004
|
|
|
1005
|
dw = np.where(d==-1)[0]
|
|
1005
|
dw = np.where(d==-1)[0]
|
|
1006
|
if X[-1]==1:
|
|
1006
|
if X[-1]==1:
|
|
1007
|
dw = np.concatenate((dw, np.array([len(X)-1])))
|
|
1007
|
dw = np.concatenate((dw, np.array([len(X)-1])))
|
|
1008
|
dw += 1
|
|
1008
|
dw += 1
|
|
1009
|
|
|
1009
|
|
|
1010
|
return [(tup[0], tup[1]) for tup in zip(up, dw)]
|
|
1010
|
return [(tup[0], tup[1]) for tup in zip(up, dw)]
|
|
1011
|
|
|
1011
|
|
|
1012
|
@staticmethod
|
|
1012
|
@staticmethod
|
|
1013
|
def mask_ranges(Y, ranges):
|
|
1013
|
def mask_ranges(Y, ranges):
|
|
1014
|
|
|
1014
|
|
|
1015
|
y = [(0, 0) for __ in Y]
|
|
1015
|
y = [(0, 0) for __ in Y]
|
|
1016
|
|
|
1016
|
|
|
1017
|
for index in ranges:
|
|
1017
|
for index in ranges:
|
|
1018
|
if '-' in index:
|
|
1018
|
if '-' in index:
|
|
1019
|
args = [int(a) for a in index.split('-')]
|
|
1019
|
args = [int(a) for a in index.split('-')]
|
|
1020
|
y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
|
|
1020
|
y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
|
|
1021
|
else:
|
|
1021
|
else:
|
|
1022
|
y[int(index)-1] = Y[int(index)-1]
|
|
1022
|
y[int(index)-1] = Y[int(index)-1]
|
|
1023
|
|
|
1023
|
|
|
1024
|
return y
|
|
1024
|
return y
|
|
1025
|
|
|
1025
|
|
|
1026
|
@staticmethod
|
|
1026
|
@staticmethod
|
|
1027
|
def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
|
|
1027
|
def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
|
|
1028
|
|
|
1028
|
|
|
1029
|
delays = len(delay)
|
|
1029
|
delays = len(delay)
|
|
1030
|
|
|
1030
|
|
|
1031
|
Y = [(int(ipp*x+before+delay[x%delays]+sync), int(ipp*x+width+before+delay[x%delays]+after+sync)) for x in range(ntx)]
|
|
1031
|
Y = [(int(ipp*x+before+delay[x%delays]+sync), int(ipp*x+width+before+delay[x%delays]+after+sync)) for x in range(ntx)]
|
|
1032
|
|
|
1032
|
|
|
1033
|
return Y
|
|
1033
|
return Y
|
|
1034
|
|
|
1034
|
|
|
1035
|
class RCClock(models.Model):
|
|
1035
|
class RCClock(models.Model):
|
|
1036
|
|
|
1036
|
|
|
1037
|
rc_configuration = models.ForeignKey('RCConfiguration', on_delete=models.CASCADE)
|
|
1037
|
rc_configuration = models.ForeignKey('RCConfiguration', on_delete=models.CASCADE)
|
|
1038
|
mode = models.BooleanField(default=True, choices=((True, 'Auto'), (False, 'Manual')))
|
|
1038
|
mode = models.BooleanField(default=True, choices=((True, 'Auto'), (False, 'Manual')))
|
|
1039
|
multiplier = models.PositiveIntegerField(default=60)
|
|
1039
|
multiplier = models.PositiveIntegerField(default=60)
|
|
1040
|
divisor = models.PositiveIntegerField(default=10)
|
|
1040
|
divisor = models.PositiveIntegerField(default=10)
|
|
1041
|
reference = models.PositiveSmallIntegerField(default=1, choices=((0, 'Internal (25MHz)'), (1, 'External (10MHz)')))
|
|
1041
|
reference = models.PositiveSmallIntegerField(default=1, choices=((0, 'Internal (25MHz)'), (1, 'External (10MHz)')))
|
|
1042
|
frequency = models.FloatField(default=60.0)
No newline at end of file
|
|
1042
|
frequency = models.FloatField(default=60.0)
|