##// END OF EJS Templates
last changes
jespinoza -
r334:ff9b4f433b43
parent child
Show More
@@ -1,12 +1,12
1 REDIS_HOST=radarsys-redis
1 REDIS_HOST=radarsys-redis
2 REDIS_PORT=6379
2 REDIS_PORT=6379
3 POSTGRES_PORT_5432_TCP_ADDR=radarsys-postgres
3 POSTGRES_PORT_5432_TCP_ADDR=radarsys-postgres
4 POSTGRES_PORT_5432_TCP_PORT=5432
4 POSTGRES_PORT_5432_TCP_PORT=5432
5 DB_NAME=radarsys
5 DB_NAME=radarsys
6 DB_USER=docker
6 DB_USER=docker
7 DB_PASSWORD=docker
7 DB_PASSWORD=docker
8 PGDATA=/var/lib/postgresql/data
8 PGDATA=/var/lib/postgresql/data
9 LC_ALL=C.UTF-8
9 LC_ALL=C.UTF-8
10 TZ=America/Lima
10 TZ=America/Lima
11 DOCKER_DATA=/Volumes/dockers/radarsys/
11 DOCKER_DATA=/data/dockers/radarsys/
12 LOCAL_IP=192.168.1.128
12 LOCAL_IP=192.168.1.128
@@ -1,194 +1,193
1 from django.shortcuts import render_to_response
1 from django.shortcuts import render_to_response
2 from django.template import RequestContext
2 from django.template import RequestContext
3 from django.shortcuts import redirect, render, get_object_or_404
3 from django.shortcuts import redirect, render, get_object_or_404
4 from django.contrib import messages
4 from django.contrib import messages
5 from django.http import HttpResponse
5 from django.http import HttpResponse
6
6
7 from apps.main.models import Device
7 from apps.main.models import Device
8 from apps.main.views import sidebar
8 from apps.main.views import sidebar
9
9
10 from .models import JARSConfiguration, JARSFilter
10 from .models import JARSConfiguration, JARSFilter
11 from .forms import JARSConfigurationForm, JARSFilterForm, JARSImportForm
11 from .forms import JARSConfigurationForm, JARSFilterForm, JARSImportForm
12
12
13 import json
13 import json
14 # Create your views here.
14 # Create your views here.
15
15
16 def jars_conf(request, id_conf):
16 def jars_conf(request, id_conf):
17
17
18 conf = get_object_or_404(JARSConfiguration, pk=id_conf)
18 conf = get_object_or_404(JARSConfiguration, pk=id_conf)
19
19
20 filter_parms = json.loads(conf.filter_parms)
20 filter_parms = json.loads(conf.filter_parms)
21
21
22 kwargs = {}
22 kwargs = {}
23 kwargs['filter'] = filter_parms
23 kwargs['filter'] = filter_parms
24 kwargs['filter_obj'] = JARSFilter.objects.get(pk=1)
24 kwargs['filter_obj'] = JARSFilter.objects.get(pk=1)
25 kwargs['filter_keys'] = ['clock', 'multiplier', 'frequency', 'f_decimal',
25 kwargs['filter_keys'] = ['clock', 'multiplier', 'frequency', 'f_decimal',
26 'cic_2', 'scale_cic_2', 'cic_5', 'scale_cic_5', 'fir',
26 'cic_2', 'scale_cic_2', 'cic_5', 'scale_cic_5', 'fir',
27 'scale_fir', 'number_taps', 'taps']
27 'scale_fir', 'number_taps', 'taps']
28
28
29 filter_resolution = conf.filter_resolution()
29 filter_resolution = conf.filter_resolution()
30 kwargs['resolution'] = '{} (MHz)'.format(filter_resolution)
30 kwargs['resolution'] = '{} (MHz)'.format(filter_resolution)
31 if filter_resolution < 1:
31 if filter_resolution < 1:
32 kwargs['resolution'] = '{} (kHz)'.format(filter_resolution*1000)
32 kwargs['resolution'] = '{} (kHz)'.format(filter_resolution*1000)
33
33
34 kwargs['status'] = conf.device.get_status_display()
34 kwargs['status'] = conf.device.get_status_display()
35 kwargs['dev_conf'] = conf
35 kwargs['dev_conf'] = conf
36 kwargs['dev_conf_keys'] = ['cards_number', 'channels_number', 'channels',
36 kwargs['dev_conf_keys'] = ['cards_number', 'channels_number', 'channels',
37 'ftp_interval', 'data_type','acq_profiles',
37 'ftp_interval', 'data_type','acq_profiles',
38 'profiles_block', 'raw_data_blocks', 'ftp_interval',
38 'profiles_block', 'raw_data_blocks', 'ftp_interval',
39 'cohe_integr_str', 'cohe_integr', 'decode_data', 'post_coh_int',
39 'cohe_integr_str', 'cohe_integr', 'decode_data', 'post_coh_int',
40 'incohe_integr', 'fftpoints', 'spectral_number',
40 'incohe_integr', 'fftpoints', 'spectral_number',
41 'spectral', 'create_directory', 'include_expname',
41 'spectral', 'create_directory', 'include_expname',
42 'save_ch_dc', 'save_data']
42 'save_ch_dc', 'save_data']
43
43
44 if conf.exp_type == 0:
44 if conf.exp_type == 0:
45 for field in ['incohe_integr','fftpoints','spectral_number', 'spectral', 'save_ch_dc']:
45 for field in ['incohe_integr','fftpoints','spectral_number', 'spectral', 'save_ch_dc']:
46 kwargs['dev_conf_keys'].remove(field)
46 kwargs['dev_conf_keys'].remove(field)
47
47
48 if conf.decode_data == 0:
48 if conf.decode_data == 0:
49 kwargs['dev_conf_keys'].remove('decode_data')
49 kwargs['dev_conf_keys'].remove('decode_data')
50 kwargs['dev_conf_keys'].remove('post_coh_int')
50 kwargs['dev_conf_keys'].remove('post_coh_int')
51
51
52 kwargs['title'] = 'JARS Configuration'
52 kwargs['title'] = 'JARS Configuration'
53 kwargs['suptitle'] = 'Details'
53 kwargs['suptitle'] = 'Details'
54
54
55 ###### SIDEBAR ######
55 ###### SIDEBAR ######
56 kwargs.update(sidebar(conf=conf))
56 kwargs.update(sidebar(conf=conf))
57
57
58 return render(request, 'jars_conf.html', kwargs)
58 return render(request, 'jars_conf.html', kwargs)
59
59
60 def jars_conf_edit(request, id_conf):
60 def jars_conf_edit(request, id_conf):
61
61
62 conf = get_object_or_404(JARSConfiguration, pk=id_conf)
62 conf = get_object_or_404(JARSConfiguration, pk=id_conf)
63
63
64 filter_parms = json.loads(conf.filter_parms)
64 filter_parms = json.loads(conf.filter_parms)
65
65
66 if request.method=='GET':
66 if request.method=='GET':
67 form = JARSConfigurationForm(instance=conf)
67 form = JARSConfigurationForm(instance=conf)
68 filter_form = JARSFilterForm(initial=filter_parms)
68 filter_form = JARSFilterForm(initial=filter_parms)
69
69
70 if request.method=='POST':
70 if request.method=='POST':
71 form = JARSConfigurationForm(request.POST, instance=conf)
71 form = JARSConfigurationForm(request.POST, instance=conf)
72 filter_form = JARSFilterForm(request.POST)
72 filter_form = JARSFilterForm(request.POST)
73
73
74 if filter_form.is_valid():
74 if filter_form.is_valid():
75 jars_filter = filter_form.cleaned_data
75 jars_filter = filter_form.cleaned_data
76 jars_filter['id'] = request.POST['filter_template']
76 jars_filter['id'] = request.POST['filter_template']
77 if form.is_valid():
78 conf = form.save(commit=False)
79 conf.filter_parms = json.dumps(jars_filter)
80 conf.save()
81 return redirect('url_jars_conf', id_conf=conf.id)
77 else:
82 else:
78 messages.error(request, filter_form.errors)
83 messages.error(request, filter_form.errors)
79
84
80 if form.is_valid():
81 conf = form.save(commit=False)
82 conf.filter_parms = json.dumps(jars_filter)
83 conf.save()
84 return redirect('url_jars_conf', id_conf=conf.id)
85
86 kwargs = {}
85 kwargs = {}
87
86
88 kwargs['id_dev'] = conf.id
87 kwargs['id_dev'] = conf.id
89 kwargs['form'] = form
88 kwargs['form'] = form
90 kwargs['filter_form'] = filter_form
89 kwargs['filter_form'] = filter_form
91 kwargs['filter_name'] = JARSFilter.objects.get(pk=filter_parms['id']).name
90 kwargs['filter_name'] = JARSFilter.objects.get(pk=filter_parms['id']).name
92 kwargs['title'] = 'Device Configuration'
91 kwargs['title'] = 'Device Configuration'
93 kwargs['suptitle'] = 'Edit'
92 kwargs['suptitle'] = 'Edit'
94 kwargs['button'] = 'Save'
93 kwargs['button'] = 'Save'
95
94
96 return render(request, 'jars_conf_edit.html', kwargs)
95 return render(request, 'jars_conf_edit.html', kwargs)
97
96
98 def import_file(request, conf_id):
97 def import_file(request, conf_id):
99
98
100 conf = get_object_or_404(JARSConfiguration, pk=conf_id)
99 conf = get_object_or_404(JARSConfiguration, pk=conf_id)
101 if request.method=='POST':
100 if request.method=='POST':
102 form = JARSImportForm(request.POST, request.FILES)
101 form = JARSImportForm(request.POST, request.FILES)
103 if form.is_valid():
102 if form.is_valid():
104 try:
103 try:
105 data = conf.import_from_file(request.FILES['file_name'])
104 data = conf.import_from_file(request.FILES['file_name'])
106 conf.dict_to_parms(data)
105 conf.dict_to_parms(data)
107 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
106 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
108 return redirect(conf.get_absolute_url_edit())
107 return redirect(conf.get_absolute_url_edit())
109
108
110 except Exception as e:
109 except Exception as e:
111 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
110 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
112 else:
111 else:
113 messages.warning(request, 'Your current configuration will be replaced')
112 messages.warning(request, 'Your current configuration will be replaced')
114 form = JARSImportForm()
113 form = JARSImportForm()
115
114
116 kwargs = {}
115 kwargs = {}
117 kwargs['form'] = form
116 kwargs['form'] = form
118 kwargs['title'] = 'JARS Configuration'
117 kwargs['title'] = 'JARS Configuration'
119 kwargs['suptitle'] = 'Import file'
118 kwargs['suptitle'] = 'Import file'
120 kwargs['button'] = 'Upload'
119 kwargs['button'] = 'Upload'
121 kwargs['previous'] = conf.get_absolute_url()
120 kwargs['previous'] = conf.get_absolute_url()
122
121
123 return render(request, 'jars_import.html', kwargs)
122 return render(request, 'jars_import.html', kwargs)
124
123
125 def read_conf(request, conf_id):
124 def read_conf(request, conf_id):
126
125
127 conf = get_object_or_404(JARSConfiguration, pk=conf_id)
126 conf = get_object_or_404(JARSConfiguration, pk=conf_id)
128 #filter = get_object_or_404(JARSfilter, pk=filter_id)
127 #filter = get_object_or_404(JARSfilter, pk=filter_id)
129
128
130 if request.method=='GET':
129 if request.method=='GET':
131
130
132 parms = conf.read_device()
131 parms = conf.read_device()
133 conf.status_device()
132 conf.status_device()
134
133
135 if not parms:
134 if not parms:
136 messages.error(request, conf.message)
135 messages.error(request, conf.message)
137 return redirect(conf.get_absolute_url())
136 return redirect(conf.get_absolute_url())
138
137
139 form = JARSConfigurationForm(initial=parms, instance=conf)
138 form = JARSConfigurationForm(initial=parms, instance=conf)
140
139
141 if request.method=='POST':
140 if request.method=='POST':
142 form = JARSConfigurationForm(request.POST, instance=conf)
141 form = JARSConfigurationForm(request.POST, instance=conf)
143
142
144 if form.is_valid():
143 if form.is_valid():
145 form.save()
144 form.save()
146 return redirect(conf.get_absolute_url())
145 return redirect(conf.get_absolute_url())
147
146
148 messages.error(request, "Parameters could not be saved")
147 messages.error(request, "Parameters could not be saved")
149
148
150 kwargs = {}
149 kwargs = {}
151 kwargs['id_dev'] = conf.id
150 kwargs['id_dev'] = conf.id
152 kwargs['filter_id'] = conf.filter.id
151 kwargs['filter_id'] = conf.filter.id
153 kwargs['form'] = form
152 kwargs['form'] = form
154 kwargs['title'] = 'Device Configuration'
153 kwargs['title'] = 'Device Configuration'
155 kwargs['suptitle'] = 'Parameters read from device'
154 kwargs['suptitle'] = 'Parameters read from device'
156 kwargs['button'] = 'Save'
155 kwargs['button'] = 'Save'
157
156
158 ###### SIDEBAR ######
157 ###### SIDEBAR ######
159 kwargs.update(sidebar(conf=conf))
158 kwargs.update(sidebar(conf=conf))
160
159
161 return render(request, 'jars_conf_edit.html', kwargs)
160 return render(request, 'jars_conf_edit.html', kwargs)
162
161
163 def change_filter(request, conf_id, filter_id):
162 def change_filter(request, conf_id, filter_id):
164
163
165 conf = get_object_or_404(JARSConfiguration, pk=conf_id)
164 conf = get_object_or_404(JARSConfiguration, pk=conf_id)
166 filter = get_object_or_404(JARSFilter, pk=filter_id)
165 filter = get_object_or_404(JARSFilter, pk=filter_id)
167 conf.filter_parms = json.dumps(filter.jsonify())
166 conf.filter_parms = json.dumps(filter.jsonify())
168 conf.save()
167 conf.save()
169
168
170 return redirect('url_edit_jars_conf', id_conf=conf.id)
169 return redirect('url_edit_jars_conf', id_conf=conf.id)
171
170
172 def get_log(request, conf_id):
171 def get_log(request, conf_id):
173
172
174 conf = get_object_or_404(JARSConfiguration, pk=conf_id)
173 conf = get_object_or_404(JARSConfiguration, pk=conf_id)
175 response = conf.get_log()
174 response = conf.get_log()
176
175
177 if not response:
176 if not response:
178 message = conf.message
177 message = conf.message
179 messages.error(request, message)
178 messages.error(request, message)
180 return redirect('url_jars_conf', id_conf=conf.id)
179 return redirect('url_jars_conf', id_conf=conf.id)
181
180
182 try:
181 try:
183 message = response.json()['message']
182 message = response.json()['message']
184 messages.error(request, message)
183 messages.error(request, message)
185 return redirect('url_jars_conf', id_conf=conf.id)
184 return redirect('url_jars_conf', id_conf=conf.id)
186 except Exception as e:
185 except Exception as e:
187 message = 'Restarting Report.txt has been downloaded successfully.'
186 message = 'Restarting Report.txt has been downloaded successfully.'
188
187
189 content = response
188 content = response
190 filename = 'Log_%s_%s.txt' %(conf.experiment.name, conf.experiment.id)
189 filename = 'Log_%s_%s.txt' %(conf.experiment.name, conf.experiment.id)
191 response = HttpResponse(content,content_type='text/plain')
190 response = HttpResponse(content,content_type='text/plain')
192 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
191 response['Content-Disposition'] = 'attachment; filename="%s"' %filename
193
192
194 return response
193 return response
@@ -1,418 +1,420
1 import os
1 import os
2 import json
2 import json
3
3
4 from django import forms
4 from django import forms
5 from django.utils.safestring import mark_safe
5 from django.utils.safestring import mark_safe
6 from apps.main.models import Device
6 from apps.main.models import Device
7 from apps.main.forms import add_empty_choice
7 from apps.main.forms import add_empty_choice
8 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode, RCClock
8 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode, RCClock
9 from .widgets import KmUnitWidget, KmUnitHzWidget, KmUnitDcWidget, UnitKmWidget, DefaultWidget, CodesWidget, HiddenWidget, HCheckboxSelectMultiple
9 from .widgets import KmUnitWidget, KmUnitHzWidget, KmUnitDcWidget, UnitKmWidget, DefaultWidget, CodesWidget, HiddenWidget, HCheckboxSelectMultiple
10
10
11 def create_choices_from_model(model, conf_id, all_choice=False):
11 def create_choices_from_model(model, conf_id, all_choice=False):
12
12
13 if model=='RCLine':
13 if model=='RCLine':
14 instance = RCConfiguration.objects.get(pk=conf_id)
14 instance = RCConfiguration.objects.get(pk=conf_id)
15 choices = [(line.pk, line.get_name()) for line in instance.get_lines(line_type__name='tx')]
15 choices = [(line.pk, line.get_name()) for line in instance.get_lines(line_type__name='tx')]
16 if all_choice:
16 if all_choice:
17 choices = add_empty_choice(choices, label='All')
17 choices = add_empty_choice(choices, label='All')
18 else:
18 else:
19 instance = globals()[model]
19 instance = globals()[model]
20 choices = instance.objects.all().values_list('pk', 'name')
20 choices = instance.objects.all().values_list('pk', 'name')
21
21
22 return choices
22 return choices
23
23
24
24
25 class ExtFileField(forms.FileField):
25 class ExtFileField(forms.FileField):
26 """
26 """
27 Same as forms.FileField, but you can specify a file extension whitelist.
27 Same as forms.FileField, but you can specify a file extension whitelist.
28
28
29 >>> from django.core.files.uploadedfile import SimpleUploadedFile
29 >>> from django.core.files.uploadedfile import SimpleUploadedFile
30 >>>
30 >>>
31 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
31 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
32 >>>
32 >>>
33 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
33 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
34 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
34 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
35 >>>
35 >>>
36 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
36 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
37 Traceback (most recent call last):
37 Traceback (most recent call last):
38 ...
38 ...
39 ValidationError: [u'Not allowed filetype!']
39 ValidationError: [u'Not allowed filetype!']
40 """
40 """
41 def __init__(self, *args, **kwargs):
41 def __init__(self, *args, **kwargs):
42 extensions = kwargs.pop("extensions")
42 extensions = kwargs.pop("extensions")
43 self.extensions = [i.lower() for i in extensions]
43 self.extensions = [i.lower() for i in extensions]
44
44
45 super(ExtFileField, self).__init__(*args, **kwargs)
45 super(ExtFileField, self).__init__(*args, **kwargs)
46
46
47 def clean(self, *args, **kwargs):
47 def clean(self, *args, **kwargs):
48 data = super(ExtFileField, self).clean(*args, **kwargs)
48 data = super(ExtFileField, self).clean(*args, **kwargs)
49 filename = data.name
49 filename = data.name
50 ext = os.path.splitext(filename)[1]
50 ext = os.path.splitext(filename)[1]
51 ext = ext.lower()
51 ext = ext.lower()
52 if ext not in self.extensions:
52 if ext not in self.extensions:
53 raise forms.ValidationError('Not allowed file type: %s' % ext)
53 raise forms.ValidationError('Not allowed file type: %s' % ext)
54
54
55
55
56 class RCConfigurationForm(forms.ModelForm):
56 class RCConfigurationForm(forms.ModelForm):
57
57
58 def __init__(self, *args, **kwargs):
58 def __init__(self, *args, **kwargs):
59 super(RCConfigurationForm, self).__init__(*args, **kwargs)
59 super(RCConfigurationForm, self).__init__(*args, **kwargs)
60
60
61 instance = getattr(self, 'instance', None)
61 instance = getattr(self, 'instance', None)
62
62
63 if instance and instance.pk:
63 if instance and instance.pk:
64
64
65 devices = Device.objects.filter(device_type__name='rc')
65 devices = Device.objects.filter(device_type__name='rc')
66 if instance.experiment:
66 if instance.experiment:
67 self.fields['experiment'].widget.attrs['read_only'] = True
67 self.fields['experiment'].widget.attrs['read_only'] = True
68 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
68 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
69 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
69 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
70 self.fields['ipp'].widget = KmUnitHzWidget(attrs={'km2unit':instance.km2unit})
70 self.fields['ipp'].widget = KmUnitHzWidget(attrs={'km2unit':instance.km2unit})
71 self.fields['clock'].widget.attrs['readonly'] = True
71 self.fields['clock'].widget.attrs['readonly'] = True
72
72
73 self.fields['time_before'].label = mark_safe(self.fields['time_before'].label)
73 self.fields['time_before'].label = mark_safe(self.fields['time_before'].label)
74 self.fields['time_after'].label = mark_safe(self.fields['time_after'].label)
74 self.fields['time_after'].label = mark_safe(self.fields['time_after'].label)
75
75
76 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
76 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
77 self.fields['experiment'].widget.attrs['readonly'] = True
77 self.fields['experiment'].widget.attrs['readonly'] = True
78
78
79 class Meta:
79 class Meta:
80 model = RCConfiguration
80 model = RCConfiguration
81 exclude = ('type', 'parameters', 'status', 'total_units', 'mix', 'author', 'hash', 'clock_in')
81 exclude = ('type', 'parameters', 'status', 'total_units', 'mix', 'author', 'hash', 'clock_in')
82
82
83 def clean(self):
83 def clean(self):
84 form_data = super(RCConfigurationForm, self).clean()
84 form_data = super(RCConfigurationForm, self).clean()
85
85
86 if 'clock_divider' in form_data:
86 if 'clock_divider' in form_data:
87 if form_data['clock_divider']<1:
87 if form_data['clock_divider']<1:
88 self.add_error('clock_divider', 'Invalid Value')
88 self.add_error('clock_divider', 'Invalid Value')
89 #else:
89 #else:
90 # if form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))%10!=0:
90 # if form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))%10!=0:
91 # self.add_error('ipp', 'Invalid IPP units={}'.format(form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))))
91 # self.add_error('ipp', 'Invalid IPP units={}'.format(form_data['ipp']*(20./3*(form_data['clock_in']/form_data['clock_divider']))))
92
92
93 return form_data
93 return form_data
94
94
95 def save(self, *args, **kwargs):
95 def save(self, *args, **kwargs):
96 conf = super(RCConfigurationForm, self).save(*args, **kwargs)
96 conf = super(RCConfigurationForm, self).save(*args, **kwargs)
97 clk = RCClock.objects.filter(rc_configuration=conf).first()
97 clk = RCClock.objects.filter(rc_configuration=conf).first()
98 if clk:
98 if clk:
99 conf.clock_in = clk.frequency
99 conf.clock_in = clk.frequency
100 conf.total_units = conf.ipp*conf.ntx*conf.km2unit
100 conf.total_units = conf.ipp*conf.ntx*conf.km2unit
101 conf.save()
101 conf.save()
102 return conf
102 return conf
103
103
104
104
105 class RCMixConfigurationForm(forms.Form):
105 class RCMixConfigurationForm(forms.Form):
106
106
107 clock_in = forms.CharField(widget=forms.HiddenInput())
107 clock_in = forms.CharField(widget=forms.HiddenInput())
108 frequency = forms.CharField(widget=forms.HiddenInput())
108 clock_divider = forms.CharField(widget=forms.HiddenInput())
109 clock_divider = forms.CharField(widget=forms.HiddenInput())
109 name = forms.CharField()
110 name = forms.CharField()
110 experiment = forms.ChoiceField()
111 experiment = forms.ChoiceField()
111 mode = forms.ChoiceField(widget=forms.RadioSelect(),
112 mode = forms.ChoiceField(widget=forms.RadioSelect(),
112 choices=[(0, 'Parallel'), (1, 'Sequence')],
113 choices=[(0, 'Parallel'), (1, 'Sequence')],
113 initial=0)
114 initial=0)
114 operation = forms.ChoiceField(widget=forms.RadioSelect(),
115 operation = forms.ChoiceField(widget=forms.RadioSelect(),
115 choices=[(0, 'OR'), (1, 'XOR'), (2, 'AND'), (3, 'NAND')],
116 choices=[(0, 'OR'), (1, 'XOR'), (2, 'AND'), (3, 'NAND')],
116 initial=1)
117 initial=1)
117 delay = forms.CharField()
118 delay = forms.CharField()
118 mask = forms.MultipleChoiceField(
119 mask = forms.MultipleChoiceField(
119 choices=[(0, 'L1'),(1, 'L2'),(2, 'L3'),(3, 'L4'),(4, 'L5'),(5, 'L6'),(6, 'L7'),(7, 'L8'),
120 choices=[(0, 'L1'),(1, 'L2'),(2, 'L3'),(3, 'L4'),(4, 'L5'),(5, 'L6'),(6, 'L7'),(7, 'L8'),
120 (8, 'L9'),(9, 'L10'),(10, 'L11'),(11, 'L12'),(12, 'L13'),(13, 'L14'),(14, 'L15'),(15, 'L16')],
121 (8, 'L9'),(9, 'L10'),(10, 'L11'),(11, 'L12'),(12, 'L13'),(13, 'L14'),(14, 'L15'),(15, 'L16')],
121 widget=HCheckboxSelectMultiple())
122 widget=HCheckboxSelectMultiple())
122 result = forms.CharField(required=False,
123 result = forms.CharField(required=False,
123 widget=forms.Textarea(attrs={'readonly':True, 'rows':5, 'class':'tabuled'}))
124 widget=forms.Textarea(attrs={'readonly':True, 'rows':5, 'class':'tabuled'}))
124
125
125 def __init__(self, *args, **kwargs):
126 def __init__(self, *args, **kwargs):
126 confs = kwargs.pop('confs', [])
127 confs = kwargs.pop('confs', [])
127 if confs:
128 if confs:
128 km2unit = confs[0].km2unit
129 km2unit = confs[0].km2unit
129 clock_in = confs[0].clock_in
130 clock_in = confs[0].clock_in
130 clock_divider = confs[0].clock_divider
131 clock_divider = confs[0].clock_divider
131 else:
132 else:
132 km2unit = clock_in = clock_divider = 0
133 km2unit = clock_in = clock_divider = 0
133 super(RCMixConfigurationForm, self).__init__(*args, **kwargs)
134 super(RCMixConfigurationForm, self).__init__(*args, **kwargs)
134 self.fields['experiment'].choices = [(conf.pk, '{} | {}'.format(conf.pk, conf.name)) for conf in confs]
135 self.fields['experiment'].choices = [(conf.pk, '{} | {}'.format(conf.pk, conf.name)) for conf in confs]
135 self.fields['delay'].widget = KmUnitWidget(attrs = {'km2unit':km2unit})
136 self.fields['delay'].widget = KmUnitWidget(attrs = {'km2unit':km2unit})
136 self.fields['clock_in'].initial = clock_in
137 self.fields['clock_in'].initial = clock_in
138 self.fields['frequency'].initial = clock_in
137 self.fields['clock_divider'].initial = clock_divider
139 self.fields['clock_divider'].initial = clock_divider
138
140
139
141
140 class RCLineForm(forms.ModelForm):
142 class RCLineForm(forms.ModelForm):
141
143
142 def __init__(self, *args, **kwargs):
144 def __init__(self, *args, **kwargs):
143 self.extra_fields = kwargs.pop('extra_fields', [])
145 self.extra_fields = kwargs.pop('extra_fields', [])
144 super(RCLineForm, self).__init__(*args, **kwargs)
146 super(RCLineForm, self).__init__(*args, **kwargs)
145
147
146 if 'initial' in kwargs and 'line_type' in kwargs['initial']:
148 if 'initial' in kwargs and 'line_type' in kwargs['initial']:
147 line_type = RCLineType.objects.get(pk=kwargs['initial']['line_type'])
149 line_type = RCLineType.objects.get(pk=kwargs['initial']['line_type'])
148
150
149 if 'code_id' in kwargs['initial']:
151 if 'code_id' in kwargs['initial']:
150 model_initial = kwargs['initial']['code_id']
152 model_initial = kwargs['initial']['code_id']
151 else:
153 else:
152 model_initial = 0
154 model_initial = 0
153
155
154 params = json.loads(line_type.params)
156 params = json.loads(line_type.params)
155
157
156 for label, value in self.extra_fields.items():
158 for label, value in self.extra_fields.items():
157 if label=='params':
159 if label=='params':
158 continue
160 continue
159
161
160 if 'model' in params[label]:
162 if 'model' in params[label]:
161 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
163 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
162 kwargs['initial']['rc_configuration']),
164 kwargs['initial']['rc_configuration']),
163 initial=model_initial)
165 initial=model_initial)
164
166
165
167
166 else:
168 else:
167 if label=='codes' and 'code_id' in kwargs['initial']:
169 if label=='codes' and 'code_id' in kwargs['initial']:
168 self.fields[label] = forms.CharField(initial=RCLineCode.objects.get(pk=kwargs['initial']['code_id']).codes)
170 self.fields[label] = forms.CharField(initial=RCLineCode.objects.get(pk=kwargs['initial']['code_id']).codes)
169 else:
171 else:
170 self.fields[label] = forms.CharField(initial=value['value'])
172 self.fields[label] = forms.CharField(initial=value['value'])
171
173
172 if label=='codes':
174 if label=='codes':
173 self.fields[label].widget = CodesWidget()
175 self.fields[label].widget = CodesWidget()
174
176
175 if self.data:
177 if self.data:
176 line_type = RCLineType.objects.get(pk=self.data['line_type'])
178 line_type = RCLineType.objects.get(pk=self.data['line_type'])
177
179
178 if 'code_id' in self.data:
180 if 'code_id' in self.data:
179 model_initial = self.data['code_id']
181 model_initial = self.data['code_id']
180 else:
182 else:
181 model_initial = 0
183 model_initial = 0
182
184
183 params = json.loads(line_type.params)
185 params = json.loads(line_type.params)
184
186
185 for label, value in self.extra_fields.items():
187 for label, value in self.extra_fields.items():
186 if label=='params':
188 if label=='params':
187 continue
189 continue
188
190
189 if 'model' in params[label]:
191 if 'model' in params[label]:
190 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
192 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'],
191 self.data['rc_configuration']),
193 self.data['rc_configuration']),
192 initial=model_initial)
194 initial=model_initial)
193
195
194
196
195 else:
197 else:
196 if label=='codes' and 'code' in self.data:
198 if label=='codes' and 'code' in self.data:
197 self.fields[label] = forms.CharField(initial=self.data['codes'])
199 self.fields[label] = forms.CharField(initial=self.data['codes'])
198 else:
200 else:
199 self.fields[label] = forms.CharField(initial=self.data[label])
201 self.fields[label] = forms.CharField(initial=self.data[label])
200
202
201 if label=='codes':
203 if label=='codes':
202 self.fields[label].widget = CodesWidget()
204 self.fields[label].widget = CodesWidget()
203
205
204
206
205 class Meta:
207 class Meta:
206 model = RCLine
208 model = RCLine
207 fields = ('rc_configuration', 'line_type', 'channel')
209 fields = ('rc_configuration', 'line_type', 'channel')
208 widgets = {
210 widgets = {
209 'channel': forms.HiddenInput(),
211 'channel': forms.HiddenInput(),
210 }
212 }
211
213
212
214
213 def clean(self):
215 def clean(self):
214
216
215 form_data = self.cleaned_data
217 form_data = self.cleaned_data
216 if 'code' in self.data and self.data['TX_ref']=="0":
218 if 'code' in self.data and self.data['TX_ref']=="0":
217 self.add_error('TX_ref', 'Choose a valid TX reference')
219 self.add_error('TX_ref', 'Choose a valid TX reference')
218
220
219 if RCLineType.objects.get(pk=self.data['line_type']).name=='mix':
221 if RCLineType.objects.get(pk=self.data['line_type']).name=='mix':
220 self.add_error('line_type', 'Invalid Line type')
222 self.add_error('line_type', 'Invalid Line type')
221
223
222 return form_data
224 return form_data
223
225
224
226
225 def save(self):
227 def save(self):
226 line = super(RCLineForm, self).save()
228 line = super(RCLineForm, self).save()
227
229
228 #auto add channel
230 #auto add channel
229 line.channel = RCLine.objects.filter(rc_configuration=line.rc_configuration).count()-1
231 line.channel = RCLine.objects.filter(rc_configuration=line.rc_configuration).count()-1
230
232
231 #auto add position for TX, TR & CODE
233 #auto add position for TX, TR & CODE
232 if line.line_type.name in ('tx', ):
234 if line.line_type.name in ('tx', ):
233 line.position = RCLine.objects.filter(rc_configuration=line.rc_configuration, line_type=line.line_type).count()-1
235 line.position = RCLine.objects.filter(rc_configuration=line.rc_configuration, line_type=line.line_type).count()-1
234
236
235 #save extra fields in params
237 #save extra fields in params
236 params = {}
238 params = {}
237 for label, value in self.extra_fields.items():
239 for label, value in self.extra_fields.items():
238 if label=='params':
240 if label=='params':
239 params['params'] = []
241 params['params'] = []
240 elif label=='codes':
242 elif label=='codes':
241 params[label] = [s for s in self.data[label].split('\r\n') if s]
243 params[label] = [s for s in self.data[label].split('\r\n') if s]
242 else:
244 else:
243 params[label] = self.data[label]
245 params[label] = self.data[label]
244 line.params = json.dumps(params)
246 line.params = json.dumps(params)
245 line.save()
247 line.save()
246 return
248 return
247
249
248
250
249 class RCLineViewForm(forms.Form):
251 class RCLineViewForm(forms.Form):
250
252
251 def __init__(self, *args, **kwargs):
253 def __init__(self, *args, **kwargs):
252
254
253 extra_fields = kwargs.pop('extra_fields')
255 extra_fields = kwargs.pop('extra_fields')
254 line = kwargs.pop('line')
256 line = kwargs.pop('line')
255 subform = kwargs.pop('subform', False)
257 subform = kwargs.pop('subform', False)
256 super(RCLineViewForm, self).__init__(*args, **kwargs)
258 super(RCLineViewForm, self).__init__(*args, **kwargs)
257
259
258 if subform:
260 if subform:
259 params = json.loads(line.line_type.params)['params']
261 params = json.loads(line.line_type.params)['params']
260 else:
262 else:
261 params = json.loads(line.line_type.params)
263 params = json.loads(line.line_type.params)
262
264
263 for label, value in extra_fields.items():
265 for label, value in extra_fields.items():
264
266
265 if label=='params':
267 if label=='params':
266 continue
268 continue
267 if 'ref' in label:
269 if 'ref' in label:
268 if value in (0, '0'):
270 if value in (0, '0'):
269 value = 'All'
271 value = 'All'
270 else:
272 else:
271 value = RCLine.objects.get(pk=value).get_name()
273 value = RCLine.objects.get(pk=value).get_name()
272 elif label=='code':
274 elif label=='code':
273 value = RCLineCode.objects.get(pk=value).name
275 value = RCLineCode.objects.get(pk=value).name
274
276
275 self.fields[label] = forms.CharField(initial=value)
277 self.fields[label] = forms.CharField(initial=value)
276
278
277 if 'widget' in params[label]:
279 if 'widget' in params[label]:
278 km2unit = line.rc_configuration.km2unit
280 km2unit = line.rc_configuration.km2unit
279 if params[label]['widget']=='km':
281 if params[label]['widget']=='km':
280 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
282 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
281 elif params[label]['widget']=='unit':
283 elif params[label]['widget']=='unit':
282 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
284 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
283 elif params[label]['widget']=='dc':
285 elif params[label]['widget']=='dc':
284 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
286 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
285 elif params[label]['widget']=='codes':
287 elif params[label]['widget']=='codes':
286 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
288 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'disabled':True})
287 else:
289 else:
288 self.fields[label].widget = DefaultWidget(attrs={'disabled':True})
290 self.fields[label].widget = DefaultWidget(attrs={'disabled':True})
289
291
290
292
291 class RCLineEditForm(forms.ModelForm):
293 class RCLineEditForm(forms.ModelForm):
292
294
293 def __init__(self, *args, **kwargs):
295 def __init__(self, *args, **kwargs):
294
296
295 extra_fields = kwargs.pop('extra_fields', [])
297 extra_fields = kwargs.pop('extra_fields', [])
296 conf = kwargs.pop('conf', False)
298 conf = kwargs.pop('conf', False)
297 line = kwargs.pop('line')
299 line = kwargs.pop('line')
298 subform = kwargs.pop('subform', False)
300 subform = kwargs.pop('subform', False)
299
301
300 super(RCLineEditForm, self).__init__(*args, **kwargs)
302 super(RCLineEditForm, self).__init__(*args, **kwargs)
301
303
302 if subform is not False:
304 if subform is not False:
303 params = json.loads(line.line_type.params)['params']
305 params = json.loads(line.line_type.params)['params']
304 count = subform
306 count = subform
305 else:
307 else:
306 params = json.loads(line.line_type.params)
308 params = json.loads(line.line_type.params)
307 count = -1
309 count = -1
308
310
309 for label, value in extra_fields.items():
311 for label, value in extra_fields.items():
310
312
311 if label in ('params',):
313 if label in ('params',):
312 continue
314 continue
313 if 'help' in params[label]:
315 if 'help' in params[label]:
314 help_text = params[label]['help']
316 help_text = params[label]['help']
315 else:
317 else:
316 help_text = ''
318 help_text = ''
317
319
318 if 'model' in params[label]:
320 if 'model' in params[label]:
319 if line.line_type.name=='tr':
321 if line.line_type.name=='tr':
320 all_choice = True
322 all_choice = True
321 else:
323 else:
322 all_choice = False
324 all_choice = False
323 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'], conf.id, all_choice=all_choice),
325 self.fields[label] = forms.ChoiceField(choices=create_choices_from_model(params[label]['model'], conf.id, all_choice=all_choice),
324 initial=value,
326 initial=value,
325 widget=forms.Select(attrs={'name':'%s|%s|%s' % (count, line.id, label)}),
327 widget=forms.Select(attrs={'name':'%s|%s|%s' % (count, line.id, label)}),
326 help_text=help_text)
328 help_text=help_text)
327
329
328 else:
330 else:
329 self.fields[label] = forms.CharField(initial=value, help_text=help_text)
331 self.fields[label] = forms.CharField(initial=value, help_text=help_text)
330
332
331 if label in ('code', ):
333 if label in ('code', ):
332 self.fields[label].widget = HiddenWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
334 self.fields[label].widget = HiddenWidget(attrs={'name':'%s|%s|%s' % (count, line.id, label)})
333
335
334 elif 'widget' in params[label]:
336 elif 'widget' in params[label]:
335 km2unit = line.rc_configuration.km2unit
337 km2unit = line.rc_configuration.km2unit
336 if params[label]['widget']=='km':
338 if params[label]['widget']=='km':
337 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
339 self.fields[label].widget = KmUnitWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
338 elif params[label]['widget']=='unit':
340 elif params[label]['widget']=='unit':
339 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
341 self.fields[label].widget = UnitKmWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
340 elif params[label]['widget']=='dc':
342 elif params[label]['widget']=='dc':
341 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
343 self.fields[label].widget = KmUnitDcWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
342 elif params[label]['widget']=='codes':
344 elif params[label]['widget']=='codes':
343 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
345 self.fields[label].widget = CodesWidget(attrs={'line':line, 'km2unit':km2unit, 'name':'%s|%s|%s' % (count, line.id, label)})
344 else:
346 else:
345 self.fields[label].widget = DefaultWidget(attrs={'line':line, 'name':'%s|%s|%s' % (count, line.id, label)})
347 self.fields[label].widget = DefaultWidget(attrs={'line':line, 'name':'%s|%s|%s' % (count, line.id, label)})
346
348
347
349
348 class Meta:
350 class Meta:
349 model = RCLine
351 model = RCLine
350 exclude = ('rc_configuration', 'line_type', 'channel', 'position', 'params', 'pulses')
352 exclude = ('rc_configuration', 'line_type', 'channel', 'position', 'params', 'pulses')
351
353
352
354
353 class RCSubLineEditForm(forms.Form):
355 class RCSubLineEditForm(forms.Form):
354
356
355 def __init__(self, *args, **kwargs):
357 def __init__(self, *args, **kwargs):
356 extra_fields = kwargs.pop('extra_fields')
358 extra_fields = kwargs.pop('extra_fields')
357 count = kwargs.pop('count')
359 count = kwargs.pop('count')
358 line = kwargs.pop('line')
360 line = kwargs.pop('line')
359 super(RCSubLineEditForm, self).__init__(*args, **kwargs)
361 super(RCSubLineEditForm, self).__init__(*args, **kwargs)
360 for label, value in extra_fields.items():
362 for label, value in extra_fields.items():
361 self.fields[label] = forms.CharField(initial=value,
363 self.fields[label] = forms.CharField(initial=value,
362 widget=forms.TextInput(attrs={'name':'%s|%s|%s' % (count, line, label)}))
364 widget=forms.TextInput(attrs={'name':'%s|%s|%s' % (count, line, label)}))
363
365
364
366
365 class RCImportForm(forms.Form):
367 class RCImportForm(forms.Form):
366
368
367 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
369 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
368
370
369
371
370 class RCLineCodesForm(forms.ModelForm):
372 class RCLineCodesForm(forms.ModelForm):
371
373
372 def __init__(self, *args, **kwargs):
374 def __init__(self, *args, **kwargs):
373 super(RCLineCodesForm, self).__init__(*args, **kwargs)
375 super(RCLineCodesForm, self).__init__(*args, **kwargs)
374
376
375 if 'initial' in kwargs:
377 if 'initial' in kwargs:
376 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
378 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
377 initial=kwargs['initial']['code'])
379 initial=kwargs['initial']['code'])
378 if 'instance' in kwargs:
380 if 'instance' in kwargs:
379 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
381 self.fields['code'] = forms.ChoiceField(choices=RCLineCode.objects.all().values_list('pk', 'name'),
380 initial=kwargs['instance'].pk)
382 initial=kwargs['instance'].pk)
381
383
382 self.fields['codes'].widget = CodesWidget()
384 self.fields['codes'].widget = CodesWidget()
383
385
384
386
385 class Meta:
387 class Meta:
386 model = RCLineCode
388 model = RCLineCode
387 exclude = ('name',)
389 exclude = ('name',)
388
390
389 class RCClockForm(forms.ModelForm):
391 class RCClockForm(forms.ModelForm):
390
392
391 def __init__(self, *args, **kwargs):
393 def __init__(self, *args, **kwargs):
392 super(RCClockForm, self).__init__(*args, **kwargs)
394 super(RCClockForm, self).__init__(*args, **kwargs)
393
395
394 instance = getattr(self, 'instance', None)
396 instance = getattr(self, 'instance', None)
395
397
396 if instance is not None and instance.mode:
398 if instance is not None and instance.mode:
397 self.fields['multiplier'].widget.attrs['readonly'] = True
399 self.fields['multiplier'].widget.attrs['readonly'] = True
398 self.fields['divisor'].widget.attrs['readonly'] = True
400 self.fields['divisor'].widget.attrs['readonly'] = True
399 self.fields['reference'].widget.attrs['readonly'] = True
401 self.fields['reference'].widget.attrs['readonly'] = True
400
402
401
403
402 class Meta:
404 class Meta:
403 model = RCClock
405 model = RCClock
404 exclude = ('rc_configuration',)
406 exclude = ('rc_configuration',)
405
407
406 def clean(self):
408 def clean(self):
407
409
408 form_data = self.cleaned_data
410 form_data = self.cleaned_data
409
411
410 if form_data['mode'] is True and float(form_data['frequency']) not in (60., 55.):
412 if form_data['mode'] is True and float(form_data['frequency']) not in (60., 55.):
411 self.add_error('frequency', 'Only 60 and 55 are valid values in auto mode')
413 self.add_error('frequency', 'Only 60 and 55 are valid values in auto mode')
412 elif form_data['mode'] is False:
414 elif form_data['mode'] is False:
413 if form_data['reference']==0 and not 24<=form_data['multiplier']<=36:
415 if form_data['reference']==0 and not 24<=form_data['multiplier']<=36:
414 self.add_error('multiplier', 'For 25MHz, valid values are between 24 and 36')
416 self.add_error('multiplier', 'For 25MHz, valid values are between 24 and 36')
415 elif form_data['reference']==1 and not 60<=form_data['multiplier']<=90:
417 elif form_data['reference']==1 and not 60<=form_data['multiplier']<=90:
416 self.add_error('multiplier', 'For 10MHz, valid values are between 60 and 90')
418 self.add_error('multiplier', 'For 10MHz, valid values are between 60 and 90')
417
419
418 return form_data No newline at end of file
420 return form_data
@@ -1,1027 +1,1030
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.core.urlresolvers import reverse
11 from django.core.urlresolvers 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 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 # self.name = data['name']
161 # self.name = data['name']
162 self.ipp = data['ipp']
162 self.ipp = data['ipp']
163 self.ntx = data['ntx']
163 self.ntx = data['ntx']
164 self.clock_in = data['clock_in']
164 self.clock_in = data['clock_in']
165 self.clock_divider = data['clock_divider']
165 self.clock_divider = data['clock_divider']
166 self.clock = data['clock']
166 self.clock = data['clock']
167 self.time_before = data['time_before']
167 self.time_before = data['time_before']
168 self.time_after = data['time_after']
168 self.time_after = data['time_after']
169 self.sync = data['sync']
169 self.sync = data['sync']
170 self.sampling_reference = data['sampling_reference']
170 self.sampling_reference = data['sampling_reference']
171 self.total_units = self.ipp*self.ntx*self.km2unit
171 self.total_units = self.ipp*self.ntx*self.km2unit
172 self.save()
172 self.save()
173 self.clean_lines()
173 self.clean_lines()
174
174
175 positions = {'tx':0, 'tr':0}
175 positions = {'tx':0, 'tr':0}
176 for i, id in enumerate(data['lines']):
176 for i, id in enumerate(data['lines']):
177 line_data = params['lines']['byId'][id]
177 line_data = params['lines']['byId'][id]
178 line_type = RCLineType.objects.get(name=line_data['line_type'])
178 line_type = RCLineType.objects.get(name=line_data['line_type'])
179 if line_type.name == 'codes':
179 if line_type.name == 'codes':
180 code = RCLineCode.objects.get(name=line_data['params']['code'])
180 code = RCLineCode.objects.get(name=line_data['params']['code'])
181 line_data['params']['code'] = code.pk
181 line_data['params']['code'] = code.pk
182 if line_type.name == 'tx':
182 if line_type.name == 'tx':
183 position = positions['tx']
183 position = positions['tx']
184 positions['tx'] += 1
184 positions['tx'] += 1
185 elif line_type.name == 'tr':
185 elif line_type.name == 'tr':
186 position = positions['tr']
186 position = positions['tr']
187 positions['tr'] += 1
187 positions['tr'] += 1
188 else:
188 else:
189 position = 0
189 position = 0
190 line, dum = RCLine.objects.update_or_create(
190 line, dum = RCLine.objects.update_or_create(
191 rc_configuration=self,
191 rc_configuration=self,
192 channel=i,
192 channel=i,
193 position=position,
193 position=position,
194 defaults={
194 defaults={
195 'line_type': line_type,
195 'line_type': line_type,
196 'params': json.dumps(line_data['params'])
196 'params': json.dumps(line_data['params'])
197 }
197 }
198 )
198 )
199
199
200 for i, line in enumerate(self.get_lines()):
200 for i, line in enumerate(self.get_lines()):
201 line_params = json.loads(line.params)
201 line_params = json.loads(line.params)
202 if 'TX_ref' in line_params:
202 if 'TX_ref' in line_params:
203 if line_params['TX_ref'] in (0, '0'):
203 if line_params['TX_ref'] in (0, '0'):
204 line_params['TX_ref'] = '0'
204 line_params['TX_ref'] = '0'
205 else:
205 else:
206 ref_id = '{}'.format(line_params['TX_ref'])
206 ref_id = '{}'.format(line_params['TX_ref'])
207 ref_line = params['lines']['byId'][ref_id]
207 ref_line = params['lines']['byId'][ref_id]
208 line_params['TX_ref'] = RCLine.objects.get(
208 line_params['TX_ref'] = RCLine.objects.get(
209 rc_configuration=self,
209 rc_configuration=self,
210 params=json.dumps(ref_line['params'])
210 params=json.dumps(ref_line['params'])
211 ).pk
211 ).pk
212 line.params = json.dumps(line_params)
212 line.params = json.dumps(line_params)
213 line.save()
213 line.save()
214
214
215
215
216 def get_delays(self):
216 def get_delays(self):
217
217
218 pulses = [line.pulses_as_points() for line in self.get_lines()]
218 pulses = [line.pulses_as_points() for line in self.get_lines()]
219 points = [tup for tups in pulses for tup in tups]
219 points = [tup for tups in pulses for tup in tups]
220 points = set([x for tup in points for x in tup])
220 points = set([x for tup in points for x in tup])
221 points = list(points)
221 points = list(points)
222 points.sort()
222 points.sort()
223
223
224 if points[0]!=0:
224 if points[0]!=0:
225 points.insert(0, 0)
225 points.insert(0, 0)
226
226
227 return [points[i+1]-points[i] for i in range(len(points)-1)]
227 return [points[i+1]-points[i] for i in range(len(points)-1)]
228
228
229
229
230 def get_pulses(self, binary=True):
230 def get_pulses(self, binary=True):
231
231
232 pulses = [line.pulses_as_points() for line in self.get_lines()]
232 pulses = [line.pulses_as_points() for line in self.get_lines()]
233 tuples = [tup for tups in pulses for tup in tups]
233 tuples = [tup for tups in pulses for tup in tups]
234 points = set([x for tup in tuples for x in tup])
234 points = set([x for tup in tuples for x in tup])
235 points = list(points)
235 points = list(points)
236 points.sort()
236 points.sort()
237 states = []
237 states = []
238 last = [0 for x in pulses]
238 last = [0 for x in pulses]
239
239
240 for x in points:
240 for x in points:
241 dum = []
241 dum = []
242 for i, tups in enumerate(pulses):
242 for i, tups in enumerate(pulses):
243 ups = [tup[0] for tup in tups if tup!=(0,0)]
243 ups = [tup[0] for tup in tups if tup!=(0,0)]
244 dws = [tup[1] for tup in tups if tup!=(0,0)]
244 dws = [tup[1] for tup in tups if tup!=(0,0)]
245 if x in ups:
245 if x in ups:
246 dum.append(1)
246 dum.append(1)
247 elif x in dws:
247 elif x in dws:
248 dum.append(0)
248 dum.append(0)
249 else:
249 else:
250 dum.append(last[i])
250 dum.append(last[i])
251 states.append(dum)
251 states.append(dum)
252 last = dum
252 last = dum
253
253
254 if binary:
254 if binary:
255 ret = []
255 ret = []
256 for flips in states:
256 for flips in states:
257 flips.reverse()
257 flips.reverse()
258 ret.append(int(''.join([str(x) for x in flips]), 2))
258 ret.append(int(''.join([str(x) for x in flips]), 2))
259 states = ret
259 states = ret
260
260
261 return states[:-1]
261 return states[:-1]
262
262
263 def add_cmd(self, cmd):
263 def add_cmd(self, cmd):
264
264
265 if cmd in DAT_CMDS:
265 if cmd in DAT_CMDS:
266 return (255, DAT_CMDS[cmd])
266 return (255, DAT_CMDS[cmd])
267
267
268 def add_data(self, value):
268 def add_data(self, value):
269
269
270 return (254, value-1)
270 return (254, value-1)
271
271
272 def parms_to_binary(self, dat=True):
272 def parms_to_binary(self, dat=True):
273 '''
273 '''
274 Create "dat" stream to be send to CR
274 Create "dat" stream to be send to CR
275 '''
275 '''
276
276
277 data = bytearray()
277 data = bytearray()
278 # create header
278 # create header
279 data.extend(self.add_cmd('DISABLE'))
279 data.extend(self.add_cmd('DISABLE'))
280 data.extend(self.add_cmd('CONTINUE'))
280 data.extend(self.add_cmd('CONTINUE'))
281 data.extend(self.add_cmd('RESTART'))
281 data.extend(self.add_cmd('RESTART'))
282
282
283 if self.control_sw:
283 if self.control_sw:
284 data.extend(self.add_cmd('SW_ONE'))
284 data.extend(self.add_cmd('SW_ONE'))
285 else:
285 else:
286 data.extend(self.add_cmd('SW_ZERO'))
286 data.extend(self.add_cmd('SW_ZERO'))
287
287
288 if self.control_tx:
288 if self.control_tx:
289 data.extend(self.add_cmd('TX_ONE'))
289 data.extend(self.add_cmd('TX_ONE'))
290 else:
290 else:
291 data.extend(self.add_cmd('TX_ZERO'))
291 data.extend(self.add_cmd('TX_ZERO'))
292
292
293 # write divider
293 # write divider
294 data.extend(self.add_cmd('CLOCK_DIVIDER'))
294 data.extend(self.add_cmd('CLOCK_DIVIDER'))
295 data.extend(self.add_data(self.clock_divider))
295 data.extend(self.add_data(self.clock_divider))
296
296
297 # write delays
297 # write delays
298 data.extend(self.add_cmd('DELAY_START'))
298 data.extend(self.add_cmd('DELAY_START'))
299 # first delay is always zero
299 # first delay is always zero
300 data.extend(self.add_data(1))
300 data.extend(self.add_data(1))
301
301
302 delays = self.get_delays()
302 delays = self.get_delays()
303
303
304 for delay in delays:
304 for delay in delays:
305 while delay>252:
305 while delay>252:
306 data.extend(self.add_data(253))
306 data.extend(self.add_data(253))
307 delay -= 253
307 delay -= 253
308 data.extend(self.add_data(int(delay)))
308 data.extend(self.add_data(int(delay)))
309
309
310 # write flips
310 # write flips
311 data.extend(self.add_cmd('FLIP_START'))
311 data.extend(self.add_cmd('FLIP_START'))
312
312
313 states = self.get_pulses(binary=True)
313 states = self.get_pulses(binary=True)
314
314
315
315
316 last = 0
316 last = 0
317 for flip, delay in zip(states, delays):
317 for flip, delay in zip(states, delays):
318 data.extend(self.add_data((flip^last)+1))
318 data.extend(self.add_data((flip^last)+1))
319 last = flip
319 last = flip
320 while delay>252:
320 while delay>252:
321 data.extend(self.add_data(1))
321 data.extend(self.add_data(1))
322 delay -= 253
322 delay -= 253
323
323
324 # write sampling period
324 # write sampling period
325 data.extend(self.add_cmd('SAMPLING_PERIOD'))
325 data.extend(self.add_cmd('SAMPLING_PERIOD'))
326 wins = self.get_lines(line_type__name='windows')
326 wins = self.get_lines(line_type__name='windows')
327 if wins:
327 if wins:
328 win_params = json.loads(wins[0].params)['params']
328 win_params = json.loads(wins[0].params)['params']
329 if win_params:
329 if win_params:
330 dh = int(win_params[0]['resolution']*self.km2unit)
330 dh = int(win_params[0]['resolution']*self.km2unit)
331 else:
331 else:
332 dh = 1
332 dh = 1
333 else:
333 else:
334 dh = 1
334 dh = 1
335 data.extend(self.add_data(dh))
335 data.extend(self.add_data(dh))
336
336
337 # write enable
337 # write enable
338 data.extend(self.add_cmd('ENABLE'))
338 data.extend(self.add_cmd('ENABLE'))
339
339
340 if not dat:
340 if not dat:
341 return data
341 return data
342
342
343 return '\n'.join(['{}'.format(x) for x in data])
343 return '\n'.join(['{}'.format(x) for x in data])
344
344
345 def update_pulses(self):
345 def update_pulses(self):
346
346
347 for line in self.get_lines():
347 for line in self.get_lines():
348 line.update_pulses()
348 line.update_pulses()
349
349
350 def plot_pulses2(self, km=False):
350 def plot_pulses2(self, km=False):
351
351
352 import matplotlib
352 import matplotlib
353 matplotlib.use('Agg')
353 matplotlib.use('Agg')
354 import matplotlib.pyplot as plt
354 import matplotlib.pyplot as plt
355 from bokeh.resources import CDN
355 from bokeh.resources import CDN
356 from bokeh.embed import components
356 from bokeh.embed import components
357 from bokeh.mpl import to_bokeh
357 from bokeh.mpl import to_bokeh
358 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
358 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
359
359
360 lines = self.get_lines()
360 lines = self.get_lines()
361
361
362 N = len(lines)
362 N = len(lines)
363 npoints = self.total_units/self.km2unit if km else self.total_units
363 npoints = self.total_units/self.km2unit if km else self.total_units
364 fig = plt.figure(figsize=(12, 2+N*0.5))
364 fig = plt.figure(figsize=(12, 2+N*0.5))
365 ax = fig.add_subplot(111)
365 ax = fig.add_subplot(111)
366 labels = ['IPP']
366 labels = ['IPP']
367
367
368 for i, line in enumerate(lines):
368 for i, line in enumerate(lines):
369 labels.append(line.get_name(channel=True))
369 labels.append(line.get_name(channel=True))
370 l = ax.plot((0, npoints),(N-i-1, N-i-1))
370 l = ax.plot((0, npoints),(N-i-1, N-i-1))
371 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
371 points = [(tup[0], tup[1]-tup[0]) for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
372 ax.broken_barh(points, (N-i-1, 0.5),
372 ax.broken_barh(points, (N-i-1, 0.5),
373 edgecolor=l[0].get_color(), facecolor='none')
373 edgecolor=l[0].get_color(), facecolor='none')
374
374
375 n = 0
375 n = 0
376 f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
376 f = ((self.ntx+50)/100)*5 if ((self.ntx+50)/100)*10>0 else 2
377 for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
377 for x in np.arange(0, npoints, self.ipp if km else self.ipp*self.km2unit):
378 if n%f==0:
378 if n%f==0:
379 ax.text(x, N, '%s' % n, size=10)
379 ax.text(x, N, '%s' % n, size=10)
380 n += 1
380 n += 1
381
381
382 labels.reverse()
382 labels.reverse()
383 ax.set_yticks(range(len(labels)))
383 ax.set_yticks(range(len(labels)))
384 ax.set_yticklabels(labels)
384 ax.set_yticklabels(labels)
385 ax.set_xlabel = 'Units'
385 ax.set_xlabel = 'Units'
386 plot = to_bokeh(fig, use_pandas=False)
386 plot = to_bokeh(fig, use_pandas=False)
387 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()]
387 plot.tools = [PanTool(dimensions=['width']), WheelZoomTool(dimensions=['width']), ResetTool(), SaveTool()]
388 plot.toolbar_location="above"
388 plot.toolbar_location="above"
389
389
390 return components(plot, CDN)
390 return components(plot, CDN)
391
391
392 def plot_pulses(self, km=False):
392 def plot_pulses(self, km=False):
393
393
394 from bokeh.plotting import figure
394 from bokeh.plotting import figure
395 from bokeh.resources import CDN
395 from bokeh.resources import CDN
396 from bokeh.embed import components
396 from bokeh.embed import components
397 from bokeh.models import FixedTicker, PrintfTickFormatter
397 from bokeh.models import FixedTicker, PrintfTickFormatter
398 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
398 from bokeh.models.tools import WheelZoomTool, ResetTool, PanTool, HoverTool, SaveTool
399 from bokeh.models.sources import ColumnDataSource
399 from bokeh.models.sources import ColumnDataSource
400
400
401 lines = self.get_lines().reverse()
401 lines = self.get_lines().reverse()
402
402
403 N = len(lines)
403 N = len(lines)
404 npoints = self.total_units/self.km2unit if km else self.total_units
404 npoints = self.total_units/self.km2unit if km else self.total_units
405 ipp = self.ipp if km else self.ipp*self.km2unit
405 ipp = self.ipp if km else self.ipp*self.km2unit
406
406
407 hover = HoverTool(tooltips=[("Line", "@name"),
407 hover = HoverTool(tooltips=[("Line", "@name"),
408 ("IPP", "@ipp"),
408 ("IPP", "@ipp"),
409 ("X", "@left")])
409 ("X", "@left")])
410
410
411 tools = [PanTool(dimensions=['width']),
411 tools = [PanTool(dimensions=['width']),
412 WheelZoomTool(dimensions=['width']),
412 WheelZoomTool(dimensions=['width']),
413 hover, SaveTool()]
413 hover, SaveTool()]
414
414
415 plot = figure(width=1000,
415 plot = figure(width=1000,
416 height=40+N*50,
416 height=40+N*50,
417 y_range = (0, N),
417 y_range = (0, N),
418 tools=tools,
418 tools=tools,
419 toolbar_location='above',
419 toolbar_location='above',
420 toolbar_sticky=False,)
420 toolbar_sticky=False,)
421
421
422 plot.xaxis.axis_label = 'Km' if km else 'Units'
422 plot.xaxis.axis_label = 'Km' if km else 'Units'
423 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
423 plot.xaxis[0].formatter = PrintfTickFormatter(format='%d')
424 plot.yaxis.axis_label = 'Pulses'
424 plot.yaxis.axis_label = 'Pulses'
425 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
425 plot.yaxis[0].ticker=FixedTicker(ticks=list(range(N)))
426 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
426 plot.yaxis[0].formatter = PrintfTickFormatter(format='Line %d')
427
427
428 for i, line in enumerate(lines):
428 for i, line in enumerate(lines):
429
429
430 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
430 points = [tup for tup in line.pulses_as_points(km=km) if tup!=(0,0)]
431
431
432 source = ColumnDataSource(data = dict(
432 source = ColumnDataSource(data = dict(
433 bottom = [i for tup in points],
433 bottom = [i for tup in points],
434 top = [i+0.5 for tup in points],
434 top = [i+0.5 for tup in points],
435 left = [tup[0] for tup in points],
435 left = [tup[0] for tup in points],
436 right = [tup[1] for tup in points],
436 right = [tup[1] for tup in points],
437 ipp = [int(tup[0]/ipp) for tup in points],
437 ipp = [int(tup[0]/ipp) for tup in points],
438 name = [line.get_name() for tup in points]
438 name = [line.get_name() for tup in points]
439 ))
439 ))
440
440
441 plot.quad(
441 plot.quad(
442 bottom = 'bottom',
442 bottom = 'bottom',
443 top = 'top',
443 top = 'top',
444 left = 'left',
444 left = 'left',
445 right = 'right',
445 right = 'right',
446 source = source,
446 source = source,
447 fill_alpha = 0,
447 fill_alpha = 0,
448 #line_color = 'blue',
448 #line_color = 'blue',
449 )
449 )
450
450
451 plot.line([0, npoints], [i, i])#, color='blue')
451 plot.line([0, npoints], [i, i])#, color='blue')
452
452
453 return components(plot, CDN)
453 return components(plot, CDN)
454
454
455 def request(self, cmd, method='get', **kwargs):
455 def request(self, cmd, method='get', **kwargs):
456
456
457 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
457 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
458 payload = req.json()
458 payload = req.json()
459
459
460 return payload
460 return payload
461
461
462 def status_device(self):
462 def status_device(self):
463
463
464 try:
464 try:
465 self.device.status = 0
465 self.device.status = 0
466 payload = self.request('status')
466 payload = self.request('status')
467 if payload['status']=='enable':
467 if payload['status']=='enable':
468 self.device.status = 3
468 self.device.status = 3
469 elif payload['status']=='disable':
469 elif payload['status']=='disable':
470 self.device.status = 2
470 self.device.status = 2
471 else:
471 else:
472 self.device.status = 1
472 self.device.status = 1
473 self.device.save()
473 self.device.save()
474 self.message = 'RC status: {}'.format(payload['status'])
474 self.message = 'RC status: {}'.format(payload['status'])
475 return False
475 return False
476 except Exception as e:
476 except Exception as e:
477 if 'No route to host' not in str(e):
477 if 'No route to host' not in str(e):
478 self.device.status = 4
478 self.device.status = 4
479 self.device.save()
479 self.device.save()
480 self.message = 'RC status: {}'.format(str(e))
480 self.message = 'RC status: {}'.format(str(e))
481 return False
481 return False
482
482
483 self.device.save()
483 self.device.save()
484 return True
484 return True
485
485
486 def reset_device(self):
486 def reset_device(self):
487
487
488 try:
488 try:
489 payload = self.request('reset', 'post')
489 payload = self.request('reset', 'post')
490 if payload['reset']=='ok':
490 if payload['reset']=='ok':
491 self.message = 'RC restarted OK'
491 self.message = 'RC restarted OK'
492 self.device.status = 2
492 self.device.status = 2
493 self.device.save()
493 self.device.save()
494 else:
494 else:
495 self.message = 'RC restart fail'
495 self.message = 'RC restart fail'
496 self.device.status = 4
496 self.device.status = 4
497 self.device.save()
497 self.device.save()
498 except Exception as e:
498 except Exception as e:
499 self.message = 'RC reset: {}'.format(str(e))
499 self.message = 'RC reset: {}'.format(str(e))
500 return False
500 return False
501
501
502 return True
502 return True
503
503
504 def stop_device(self):
504 def stop_device(self):
505
505
506 try:
506 try:
507 payload = self.request('stop', 'post')
507 payload = self.request('stop', 'post')
508 self.message = 'RC stop: {}'.format(payload['stop'])
508 self.message = 'RC stop: {}'.format(payload['stop'])
509 if payload['stop']=='ok':
509 if payload['stop']=='ok':
510 self.device.status = 2
510 self.device.status = 2
511 self.device.save()
511 self.device.save()
512 else:
512 else:
513 self.device.status = 4
513 self.device.status = 4
514 self.device.save()
514 self.device.save()
515 return False
515 return False
516 except Exception as e:
516 except Exception as e:
517 if 'No route to host' not in str(e):
517 if 'No route to host' not in str(e):
518 self.device.status = 4
518 self.device.status = 4
519 else:
519 else:
520 self.device.status = 0
520 self.device.status = 0
521 self.message = 'RC stop: {}'.format(str(e))
521 self.message = 'RC stop: {}'.format(str(e))
522 self.device.save()
522 self.device.save()
523 return False
523 return False
524
524
525 return True
525 return True
526
526
527 def start_device(self):
527 def start_device(self):
528
528
529 try:
529 try:
530 payload = self.request('start', 'post')
530 payload = self.request('start', 'post')
531 self.message = 'RC start: {}'.format(payload['start'])
531 self.message = 'RC start: {}'.format(payload['start'])
532 if payload['start']=='ok':
532 if payload['start']=='ok':
533 self.device.status = 3
533 self.device.status = 3
534 self.device.save()
534 self.device.save()
535 else:
535 else:
536 return False
536 return False
537 except Exception as e:
537 except Exception as e:
538 if 'No route to host' not in str(e):
538 if 'No route to host' not in str(e):
539 self.device.status = 4
539 self.device.status = 4
540 else:
540 else:
541 self.device.status = 0
541 self.device.status = 0
542 self.message = 'RC start: {}'.format(str(e))
542 self.message = 'RC start: {}'.format(str(e))
543 self.device.save()
543 self.device.save()
544 return False
544 return False
545
545
546 return True
546 return True
547
547
548 def write_device(self, raw=False):
548 def write_device(self, raw=False):
549
549
550 if not raw:
550 if not raw:
551 clock = RCClock.objects.get(rc_configuration=self)
551 clock = RCClock.objects.get(rc_configuration=self)
552 if clock.mode:
552 if clock.mode:
553 data = {'default': clock.frequency}
553 data = {'default': clock.frequency}
554 else:
554 else:
555 data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
555 data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
556 payload = self.request('setfreq', 'post', data=json.dumps(data))
556 try:
557 if payload['command'] <> 'ok':
557 payload = self.request('setfreq', 'post', data=json.dumps(data))
558 self.message = 'RC write: {}'.format(payload['command'])
558 if payload['command'] <> 'ok':
559 else:
559 self.message = 'RC write: {}'.format(payload['command'])
560 self.message = payload['programming']
560 else:
561 if payload['programming'] == 'fail':
561 self.message = payload['programming']
562 self.message = 'RC write: error programming CGS chip'
562 if payload['programming'] == 'fail':
563
563 self.message = 'RC write: error programming CGS chip'
564 except Exception as e:
565 self.message = 'RC Write: No CGS found {}'.format(e)
566 # return False
564 values = []
567 values = []
565 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
568 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
566 while delay>65536:
569 while delay>65536:
567 values.append((pulse, 65535))
570 values.append((pulse, 65535))
568 delay -= 65536
571 delay -= 65536
569 values.append((pulse, delay-1))
572 values.append((pulse, delay-1))
570 data = bytearray()
573 data = bytearray()
571 #reset
574 #reset
572 data.extend((128, 0))
575 data.extend((128, 0))
573 #disable
576 #disable
574 data.extend((129, 0))
577 data.extend((129, 0))
575 #SW switch
578 #SW switch
576 if self.control_sw:
579 if self.control_sw:
577 data.extend((130, 2))
580 data.extend((130, 2))
578 else:
581 else:
579 data.extend((130, 0))
582 data.extend((130, 0))
580 #divider
583 #divider
581 data.extend((131, self.clock_divider-1))
584 data.extend((131, self.clock_divider-1))
582 #enable writing
585 #enable writing
583 data.extend((139, 62))
586 data.extend((139, 62))
584
587
585 last = 0
588 last = 0
586 for tup in values:
589 for tup in values:
587 vals = pack('<HH', last^tup[0], tup[1])
590 vals = pack('<HH', last^tup[0], tup[1])
588 last = tup[0]
591 last = tup[0]
589 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
592 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
590
593
591 #enable
594 #enable
592 data.extend((129, 1))
595 data.extend((129, 1))
593
596
594 if raw:
597 if raw:
595 return b64encode(data)
598 return b64encode(data)
596
599
597 try:
600 try:
598 payload = self.request('stop', 'post')
601 payload = self.request('stop', 'post')
599 payload = self.request('reset', 'post')
602 payload = self.request('reset', 'post')
600 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
603 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
601 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
604 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
602 n = len(data)
605 n = len(data)
603 x = 0
606 x = 0
604 #while x < n:
607 #while x < n:
605 payload = self.request('write', 'post', data=b64encode(data))
608 payload = self.request('write', 'post', data=b64encode(data))
606 # x += 1024
609 # x += 1024
607
610
608 if payload['write']=='ok':
611 if payload['write']=='ok':
609 self.device.status = 3
612 self.device.status = 3
610 self.device.save()
613 self.device.save()
611 self.message = 'RC configured and started'
614 self.message = 'RC configured and started'
612 else:
615 else:
613 self.device.status = 1
616 self.device.status = 1
614 self.device.save()
617 self.device.save()
615 self.message = 'RC write: {}'.format(payload['write'])
618 self.message = 'RC write: {}'.format(payload['write'])
616 return False
619 return False
617
620
618 #payload = self.request('start', 'post')
621 #payload = self.request('start', 'post')
619
622
620 except Exception as e:
623 except Exception as e:
621 if 'No route to host' not in str(e):
624 if 'No route to host' not in str(e):
622 self.device.status = 4
625 self.device.status = 4
623 else:
626 else:
624 self.device.status = 0
627 self.device.status = 0
625 self.message = 'RC write: {}'.format(str(e))
628 self.message = 'RC write: {}'.format(str(e))
626 self.device.save()
629 self.device.save()
627 return False
630 return False
628
631
629 return True
632 return True
630
633
631
634
632 def get_absolute_url_import(self):
635 def get_absolute_url_import(self):
633 return reverse('url_import_rc_conf', args=[str(self.id)])
636 return reverse('url_import_rc_conf', args=[str(self.id)])
634
637
635
638
636 class RCLineCode(models.Model):
639 class RCLineCode(models.Model):
637
640
638 name = models.CharField(max_length=40)
641 name = models.CharField(max_length=40)
639 bits_per_code = models.PositiveIntegerField(default=0)
642 bits_per_code = models.PositiveIntegerField(default=0)
640 number_of_codes = models.PositiveIntegerField(default=0)
643 number_of_codes = models.PositiveIntegerField(default=0)
641 codes = models.TextField(blank=True, null=True)
644 codes = models.TextField(blank=True, null=True)
642
645
643 class Meta:
646 class Meta:
644 db_table = 'rc_line_codes'
647 db_table = 'rc_line_codes'
645 ordering = ('name',)
648 ordering = ('name',)
646
649
647 def __str__(self):
650 def __str__(self):
648 return u'%s' % self.name
651 return u'%s' % self.name
649
652
650
653
651 class RCLineType(models.Model):
654 class RCLineType(models.Model):
652
655
653 name = models.CharField(choices=LINE_TYPES, max_length=40)
656 name = models.CharField(choices=LINE_TYPES, max_length=40)
654 description = models.TextField(blank=True, null=True)
657 description = models.TextField(blank=True, null=True)
655 params = models.TextField(default='[]')
658 params = models.TextField(default='[]')
656
659
657 class Meta:
660 class Meta:
658 db_table = 'rc_line_types'
661 db_table = 'rc_line_types'
659
662
660 def __str__(self):
663 def __str__(self):
661 return u'%s - %s' % (self.name.upper(), self.get_name_display())
664 return u'%s - %s' % (self.name.upper(), self.get_name_display())
662
665
663
666
664 class RCLine(models.Model):
667 class RCLine(models.Model):
665
668
666 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
669 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
667 line_type = models.ForeignKey(RCLineType)
670 line_type = models.ForeignKey(RCLineType)
668 channel = models.PositiveIntegerField(default=0)
671 channel = models.PositiveIntegerField(default=0)
669 position = models.PositiveIntegerField(default=0)
672 position = models.PositiveIntegerField(default=0)
670 params = models.TextField(default='{}')
673 params = models.TextField(default='{}')
671 pulses = models.TextField(default='')
674 pulses = models.TextField(default='')
672
675
673 class Meta:
676 class Meta:
674 db_table = 'rc_lines'
677 db_table = 'rc_lines'
675 ordering = ['channel']
678 ordering = ['channel']
676
679
677 def __str__(self):
680 def __str__(self):
678 if self.rc_configuration:
681 if self.rc_configuration:
679 return u'{}|{} - {}'.format(self.pk, self.get_name(), self.rc_configuration.name)
682 return u'{}|{} - {}'.format(self.pk, self.get_name(), self.rc_configuration.name)
680
683
681 def jsonify(self):
684 def jsonify(self):
682
685
683 data = {}
686 data = {}
684 data['params'] = json.loads(self.params)
687 data['params'] = json.loads(self.params)
685 data['id'] = '{}'.format(self.pk)
688 data['id'] = '{}'.format(self.pk)
686 data['line_type'] = self.line_type.name
689 data['line_type'] = self.line_type.name
687 data['name'] = self.get_name()
690 data['name'] = self.get_name()
688 if data['line_type']=='codes':
691 if data['line_type']=='codes':
689 data['params']['code'] = RCLineCode.objects.get(pk=data['params']['code']).name
692 data['params']['code'] = RCLineCode.objects.get(pk=data['params']['code']).name
690
693
691 return data
694 return data
692
695
693
696
694 def clone(self, **kwargs):
697 def clone(self, **kwargs):
695
698
696 self.pk = None
699 self.pk = None
697 self.id = None
700 self.id = None
698
701
699 for attr, value in kwargs.items():
702 for attr, value in kwargs.items():
700 setattr(self, attr, value)
703 setattr(self, attr, value)
701
704
702 self.save()
705 self.save()
703
706
704 return self
707 return self
705
708
706 def get_name(self, channel=False):
709 def get_name(self, channel=False):
707
710
708 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
711 chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
709 s = ''
712 s = ''
710
713
711 if self.line_type.name in ('tx',):
714 if self.line_type.name in ('tx',):
712 s = chars[self.position]
715 s = chars[self.position]
713 elif self.line_type.name in ('codes', 'windows', 'tr'):
716 elif self.line_type.name in ('codes', 'windows', 'tr'):
714 if 'TX_ref' in json.loads(self.params):
717 if 'TX_ref' in json.loads(self.params):
715 pk = json.loads(self.params)['TX_ref']
718 pk = json.loads(self.params)['TX_ref']
716 if pk in (0, '0'):
719 if pk in (0, '0'):
717 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
720 s = ','.join(chars[l.position] for l in self.rc_configuration.get_lines(line_type__name='tx'))
718 else:
721 else:
719 ref = RCLine.objects.get(pk=pk)
722 ref = RCLine.objects.get(pk=pk)
720 s = chars[ref.position]
723 s = chars[ref.position]
721 s = '({})'.format(s)
724 s = '({})'.format(s)
722
725
723 s = '{}{}'.format(self.line_type.name.upper(), s)
726 s = '{}{}'.format(self.line_type.name.upper(), s)
724
727
725 if channel:
728 if channel:
726 return '{} {}'.format(s, self.channel)
729 return '{} {}'.format(s, self.channel)
727 else:
730 else:
728 return s
731 return s
729
732
730 def get_lines(self, **kwargs):
733 def get_lines(self, **kwargs):
731
734
732 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
735 return RCLine.objects.filter(rc_configuration=self.rc_configuration, **kwargs)
733
736
734 def pulses_as_array(self):
737 def pulses_as_array(self):
735
738
736 y = np.zeros(self.rc_configuration.total_units)
739 y = np.zeros(self.rc_configuration.total_units)
737
740
738 for tup in ast.literal_eval(self.pulses):
741 for tup in ast.literal_eval(self.pulses):
739 y[tup[0]:tup[1]] = 1
742 y[tup[0]:tup[1]] = 1
740
743
741 return y.astype(np.int8)
744 return y.astype(np.int8)
742
745
743 def pulses_as_points(self, km=False):
746 def pulses_as_points(self, km=False):
744
747
745 if km:
748 if km:
746 unit2km = 1/self.rc_configuration.km2unit
749 unit2km = 1/self.rc_configuration.km2unit
747 return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
750 return [(tup[0]*unit2km, tup[1]*unit2km) for tup in ast.literal_eval(self.pulses)]
748 else:
751 else:
749 return ast.literal_eval(self.pulses)
752 return ast.literal_eval(self.pulses)
750
753
751 def get_win_ref(self, params, tx_id, km2unit):
754 def get_win_ref(self, params, tx_id, km2unit):
752
755
753 ref = self.rc_configuration.sampling_reference
756 ref = self.rc_configuration.sampling_reference
754 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
757 codes = [line for line in self.get_lines(line_type__name='codes') if int(json.loads(line.params)['TX_ref'])==int(tx_id)]
755
758
756 if codes:
759 if codes:
757 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
760 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit/len(json.loads(codes[0].params)['codes'][0])
758 else:
761 else:
759 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
762 tx_width = float(json.loads(RCLine.objects.get(pk=tx_id).params)['pulse_width'])*km2unit
760
763
761 if ref=='first_baud':
764 if ref=='first_baud':
762 return int(1 + round((tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit))
765 return int(1 + round((tx_width + 1)/2 + params['first_height']*km2unit - params['resolution']*km2unit))
763 elif ref=='sub_baud':
766 elif ref=='sub_baud':
764 return np.ceil(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
767 return np.ceil(1 + params['first_height']*km2unit - params['resolution']*km2unit/2)
765 else:
768 else:
766 return 0
769 return 0
767
770
768 def update_pulses(self):
771 def update_pulses(self):
769 '''
772 '''
770 Update pulses field
773 Update pulses field
771 '''
774 '''
772
775
773 km2unit = self.rc_configuration.km2unit
776 km2unit = self.rc_configuration.km2unit
774 us2unit = self.rc_configuration.us2unit
777 us2unit = self.rc_configuration.us2unit
775 ipp = self.rc_configuration.ipp
778 ipp = self.rc_configuration.ipp
776 ntx = int(self.rc_configuration.ntx)
779 ntx = int(self.rc_configuration.ntx)
777 ipp_u = int(ipp*km2unit)
780 ipp_u = int(ipp*km2unit)
778 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
781 total = ipp_u*ntx if self.rc_configuration.total_units==0 else self.rc_configuration.total_units
779 y = []
782 y = []
780
783
781 if self.line_type.name=='tr':
784 if self.line_type.name=='tr':
782 tr_params = json.loads(self.params)
785 tr_params = json.loads(self.params)
783
786
784 if tr_params['TX_ref'] in ('0', 0):
787 if tr_params['TX_ref'] in ('0', 0):
785 txs = self.get_lines(line_type__name='tx')
788 txs = self.get_lines(line_type__name='tx')
786 else:
789 else:
787 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
790 txs = RCLine.objects.filter(pk=tr_params['TX_ref'])
788
791
789 for tx in txs:
792 for tx in txs:
790 params = json.loads(tx.params)
793 params = json.loads(tx.params)
791
794
792 if float(params['pulse_width'])==0:
795 if float(params['pulse_width'])==0:
793 continue
796 continue
794 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
797 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
795 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
798 width = float(params['pulse_width'])*km2unit+int(self.rc_configuration.time_before*us2unit)
796 before = 0
799 before = 0
797 after = int(self.rc_configuration.time_after*us2unit)
800 after = int(self.rc_configuration.time_after*us2unit)
798
801
799 y_tx = self.points(ntx, ipp_u, width,
802 y_tx = self.points(ntx, ipp_u, width,
800 delay=delays,
803 delay=delays,
801 before=before,
804 before=before,
802 after=after,
805 after=after,
803 sync=self.rc_configuration.sync)
806 sync=self.rc_configuration.sync)
804
807
805 ranges = params['range'].split(',')
808 ranges = params['range'].split(',')
806
809
807 if len(ranges)>0 and ranges[0]!='0':
810 if len(ranges)>0 and ranges[0]!='0':
808 y_tx = self.mask_ranges(y_tx, ranges)
811 y_tx = self.mask_ranges(y_tx, ranges)
809
812
810 tr_ranges = tr_params['range'].split(',')
813 tr_ranges = tr_params['range'].split(',')
811
814
812 if len(tr_ranges)>0 and tr_ranges[0]!='0':
815 if len(tr_ranges)>0 and tr_ranges[0]!='0':
813 y_tx = self.mask_ranges(y_tx, tr_ranges)
816 y_tx = self.mask_ranges(y_tx, tr_ranges)
814
817
815 y.extend(y_tx)
818 y.extend(y_tx)
816
819
817 self.pulses = str(y)
820 self.pulses = str(y)
818 y = self.array_to_points(self.pulses_as_array())
821 y = self.array_to_points(self.pulses_as_array())
819
822
820 elif self.line_type.name=='tx':
823 elif self.line_type.name=='tx':
821 params = json.loads(self.params)
824 params = json.loads(self.params)
822 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
825 delays = [float(d)*km2unit for d in params['delays'].split(',') if d]
823 width = float(params['pulse_width'])*km2unit
826 width = float(params['pulse_width'])*km2unit
824
827
825 if width>0:
828 if width>0:
826 before = int(self.rc_configuration.time_before*us2unit)
829 before = int(self.rc_configuration.time_before*us2unit)
827 after = 0
830 after = 0
828
831
829 y = self.points(ntx, ipp_u, width,
832 y = self.points(ntx, ipp_u, width,
830 delay=delays,
833 delay=delays,
831 before=before,
834 before=before,
832 after=after,
835 after=after,
833 sync=self.rc_configuration.sync)
836 sync=self.rc_configuration.sync)
834
837
835 ranges = params['range'].split(',')
838 ranges = params['range'].split(',')
836
839
837 if len(ranges)>0 and ranges[0]!='0':
840 if len(ranges)>0 and ranges[0]!='0':
838 y = self.mask_ranges(y, ranges)
841 y = self.mask_ranges(y, ranges)
839
842
840 elif self.line_type.name=='flip':
843 elif self.line_type.name=='flip':
841 n = float(json.loads(self.params)['number_of_flips'])
844 n = float(json.loads(self.params)['number_of_flips'])
842 width = n*ipp*km2unit
845 width = n*ipp*km2unit
843 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
846 y = self.points(int((ntx+1)/(2*n)), ipp_u*n*2, width)
844
847
845 elif self.line_type.name=='codes':
848 elif self.line_type.name=='codes':
846 params = json.loads(self.params)
849 params = json.loads(self.params)
847 tx = RCLine.objects.get(pk=params['TX_ref'])
850 tx = RCLine.objects.get(pk=params['TX_ref'])
848 tx_params = json.loads(tx.params)
851 tx_params = json.loads(tx.params)
849 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
852 delays = [float(d)*km2unit for d in tx_params['delays'].split(',') if d]
850 f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
853 f = int(float(tx_params['pulse_width'])*km2unit/len(params['codes'][0]))
851 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
854 codes = [(np.fromstring(''.join([s*f for s in code]), dtype=np.uint8)-48).astype(np.int8) for code in params['codes']]
852 codes = [self.array_to_points(code) for code in codes]
855 codes = [self.array_to_points(code) for code in codes]
853 n = len(codes)
856 n = len(codes)
854
857
855 ranges = tx_params['range'].split(',')
858 ranges = tx_params['range'].split(',')
856 if len(ranges)>0 and ranges[0]!='0':
859 if len(ranges)>0 and ranges[0]!='0':
857 dum = self.mask_ranges(tx.pulses_as_points(), ranges)
860 dum = self.mask_ranges(tx.pulses_as_points(), ranges)
858 else:
861 else:
859 dum = tx.pulses_as_points()
862 dum = tx.pulses_as_points()
860
863
861 for i, tup in enumerate(dum):
864 for i, tup in enumerate(dum):
862 if tup==(0,0): continue
865 if tup==(0,0): continue
863 code = codes[i%n]
866 code = codes[i%n]
864 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
867 y.extend([(c[0]+tup[0], c[1]+tup[0]) for c in code])
865
868
866 elif self.line_type.name=='sync':
869 elif self.line_type.name=='sync':
867 params = json.loads(self.params)
870 params = json.loads(self.params)
868 n = ipp_u*ntx
871 n = ipp_u*ntx
869 if params['invert'] in ('1', 1):
872 if params['invert'] in ('1', 1):
870 y = [(n-1, n)]
873 y = [(n-2, n)]
871 else:
874 else:
872 y = [(0, 1)]
875 y = [(0, 1)]
873
876
874 elif self.line_type.name=='prog_pulses':
877 elif self.line_type.name=='prog_pulses':
875 params = json.loads(self.params)
878 params = json.loads(self.params)
876 if int(params['periodic'])==0:
879 if int(params['periodic'])==0:
877 nntx = 1
880 nntx = 1
878 nipp = ipp_u*ntx
881 nipp = ipp_u*ntx
879 else:
882 else:
880 nntx = ntx
883 nntx = ntx
881 nipp = ipp_u
884 nipp = ipp_u
882
885
883 if 'params' in params and len(params['params'])>0:
886 if 'params' in params and len(params['params'])>0:
884 for p in params['params']:
887 for p in params['params']:
885 y_pp = self.points(nntx, nipp,
888 y_pp = self.points(nntx, nipp,
886 p['end']-p['begin'],
889 p['end']-p['begin'],
887 before=p['begin'])
890 before=p['begin'])
888
891
889 y.extend(y_pp)
892 y.extend(y_pp)
890
893
891 elif self.line_type.name=='windows':
894 elif self.line_type.name=='windows':
892 params = json.loads(self.params)
895 params = json.loads(self.params)
893 if 'params' in params and len(params['params'])>0:
896 if 'params' in params and len(params['params'])>0:
894 tx = RCLine.objects.get(pk=params['TX_ref'])
897 tx = RCLine.objects.get(pk=params['TX_ref'])
895 tx_params = json.loads(tx.params)
898 tx_params = json.loads(tx.params)
896 ranges = tx_params['range'].split(',')
899 ranges = tx_params['range'].split(',')
897 for p in params['params']:
900 for p in params['params']:
898 y_win = self.points(ntx, ipp_u,
901 y_win = self.points(ntx, ipp_u,
899 p['resolution']*p['number_of_samples']*km2unit,
902 p['resolution']*p['number_of_samples']*km2unit,
900 before=int(self.rc_configuration.time_before*us2unit)+p['first_height']*km2unit,
903 before=int(self.rc_configuration.time_before*us2unit)+p['first_height']*km2unit,
901 sync=self.rc_configuration.sync+self.get_win_ref(p, params['TX_ref'], km2unit))
904 sync=self.rc_configuration.sync+self.get_win_ref(p, params['TX_ref'], km2unit))
902
905
903
906
904 if len(ranges)>0 and ranges[0]!='0':
907 if len(ranges)>0 and ranges[0]!='0':
905 y_win = self.mask_ranges(y_win, ranges)
908 y_win = self.mask_ranges(y_win, ranges)
906
909
907 y.extend(y_win)
910 y.extend(y_win)
908
911
909 elif self.line_type.name=='mix':
912 elif self.line_type.name=='mix':
910 values = self.rc_configuration.parameters.split('-')
913 values = self.rc_configuration.parameters.split('-')
911 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
914 confs = [RCConfiguration.objects.get(pk=value.split('|')[0]) for value in values]
912 modes = [value.split('|')[1] for value in values]
915 modes = [value.split('|')[1] for value in values]
913 ops = [value.split('|')[2] for value in values]
916 ops = [value.split('|')[2] for value in values]
914 delays = [value.split('|')[3] for value in values]
917 delays = [value.split('|')[3] for value in values]
915 masks = [value.split('|')[4] for value in values]
918 masks = [value.split('|')[4] for value in values]
916 mask = list('{:8b}'.format(int(masks[0])))
919 mask = list('{:8b}'.format(int(masks[0])))
917 mask.reverse()
920 mask.reverse()
918 if mask[self.channel] in ('0', '', ' '):
921 if mask[self.channel] in ('0', '', ' '):
919 y = np.zeros(confs[0].total_units, dtype=np.int8)
922 y = np.zeros(confs[0].total_units, dtype=np.int8)
920 else:
923 else:
921 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
924 y = confs[0].get_lines(channel=self.channel)[0].pulses_as_array()
922
925
923 for i in range(1, len(values)):
926 for i in range(1, len(values)):
924 mask = list('{:8b}'.format(int(masks[i])))
927 mask = list('{:8b}'.format(int(masks[i])))
925 mask.reverse()
928 mask.reverse()
926
929
927 if mask[self.channel] in ('0', '', ' '):
930 if mask[self.channel] in ('0', '', ' '):
928 continue
931 continue
929 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
932 Y = confs[i].get_lines(channel=self.channel)[0].pulses_as_array()
930 delay = float(delays[i])*km2unit
933 delay = int(float(delays[i])*km2unit)
931
934
932 if modes[i]=='P':
935 if modes[i]=='P':
933 if delay>0:
936 if delay>0:
934 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
937 if delay<self.rc_configuration.ipp*km2unit and len(Y)==len(y):
935 y_temp = np.empty_like(Y)
938 y_temp = np.empty_like(Y)
936 y_temp[:delay] = 0
939 y_temp[:delay] = 0
937 y_temp[delay:] = Y[:-delay]
940 y_temp[delay:] = Y[:-delay]
938 elif delay+len(Y)>len(y):
941 elif delay+len(Y)>len(y):
939 y_new = np.zeros(delay+len(Y), dtype=np.int8)
942 y_new = np.zeros(delay+len(Y), dtype=np.int8)
940 y_new[:len(y)] = y
943 y_new[:len(y)] = y
941 y = y_new
944 y = y_new
942 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
945 y_temp = np.zeros(delay+len(Y), dtype=np.int8)
943 y_temp[-len(Y):] = Y
946 y_temp[-len(Y):] = Y
944 elif delay+len(Y)==len(y):
947 elif delay+len(Y)==len(y):
945 y_temp = np.zeros(delay+len(Y))
948 y_temp = np.zeros(delay+len(Y))
946 y_temp[-len(Y):] = Y
949 y_temp[-len(Y):] = Y
947 elif delay+len(Y)<len(y):
950 elif delay+len(Y)<len(y):
948 y_temp = np.zeros(len(y), dtype=np.int8)
951 y_temp = np.zeros(len(y), dtype=np.int8)
949 y_temp[delay:delay+len(Y)] = Y
952 y_temp[delay:delay+len(Y)] = Y
950 else:
953 else:
951 y_temp = Y.copy()
954 y_temp = Y.copy()
952
955
953 if ops[i]=='OR':
956 if ops[i]=='OR':
954 y = y | y_temp
957 y = y | y_temp
955 elif ops[i]=='XOR':
958 elif ops[i]=='XOR':
956 y = y ^ y_temp
959 y = y ^ y_temp
957 elif ops[i]=='AND':
960 elif ops[i]=='AND':
958 y = y & y_temp
961 y = y & y_temp
959 elif ops[i]=='NAND':
962 elif ops[i]=='NAND':
960 y = y & ~y_temp
963 y = y & ~y_temp
961 else:
964 else:
962 y = np.concatenate([y, Y])
965 y = np.concatenate([y, Y])
963
966
964 total = len(y)
967 total = len(y)
965 y = self.array_to_points(y)
968 y = self.array_to_points(y)
966
969
967 else:
970 else:
968 y = []
971 y = []
969
972
970 if self.rc_configuration.total_units != total:
973 if self.rc_configuration.total_units != total:
971 self.rc_configuration.total_units = total
974 self.rc_configuration.total_units = total
972 self.rc_configuration.save()
975 self.rc_configuration.save()
973
976
974 self.pulses = str(y)
977 self.pulses = str(y)
975 self.save()
978 self.save()
976
979
977 @staticmethod
980 @staticmethod
978 def array_to_points(X):
981 def array_to_points(X):
979
982
980 if X.size==0:
983 if X.size==0:
981 return []
984 return []
982
985
983 d = X[1:]-X[:-1]
986 d = X[1:]-X[:-1]
984
987
985 up = np.where(d==1)[0]
988 up = np.where(d==1)[0]
986 if X[0]==1:
989 if X[0]==1:
987 up = np.concatenate((np.array([-1]), up))
990 up = np.concatenate((np.array([-1]), up))
988 up += 1
991 up += 1
989
992
990 dw = np.where(d==-1)[0]
993 dw = np.where(d==-1)[0]
991 if X[-1]==1:
994 if X[-1]==1:
992 dw = np.concatenate((dw, np.array([len(X)-1])))
995 dw = np.concatenate((dw, np.array([len(X)-1])))
993 dw += 1
996 dw += 1
994
997
995 return [(tup[0], tup[1]) for tup in zip(up, dw)]
998 return [(tup[0], tup[1]) for tup in zip(up, dw)]
996
999
997 @staticmethod
1000 @staticmethod
998 def mask_ranges(Y, ranges):
1001 def mask_ranges(Y, ranges):
999
1002
1000 y = [(0, 0) for __ in Y]
1003 y = [(0, 0) for __ in Y]
1001
1004
1002 for index in ranges:
1005 for index in ranges:
1003 if '-' in index:
1006 if '-' in index:
1004 args = [int(a) for a in index.split('-')]
1007 args = [int(a) for a in index.split('-')]
1005 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
1008 y[args[0]-1:args[1]] = Y[args[0]-1:args[1]]
1006 else:
1009 else:
1007 y[int(index)-1] = Y[int(index)-1]
1010 y[int(index)-1] = Y[int(index)-1]
1008
1011
1009 return y
1012 return y
1010
1013
1011 @staticmethod
1014 @staticmethod
1012 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
1015 def points(ntx, ipp, width, delay=[0], before=0, after=0, sync=0):
1013
1016
1014 delays = len(delay)
1017 delays = len(delay)
1015
1018
1016 Y = [(int(ipp*x+before+delay[x%delays]+sync), int(ipp*x+width+before+delay[x%delays]+after+sync)) for x in range(ntx)]
1019 Y = [(int(ipp*x+before+delay[x%delays]+sync), int(ipp*x+width+before+delay[x%delays]+after+sync)) for x in range(ntx)]
1017
1020
1018 return Y
1021 return Y
1019
1022
1020 class RCClock(models.Model):
1023 class RCClock(models.Model):
1021
1024
1022 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
1025 rc_configuration = models.ForeignKey(RCConfiguration, on_delete=models.CASCADE)
1023 mode = models.BooleanField(default=True, choices=((True, 'Auto'), (False, 'Manual')))
1026 mode = models.BooleanField(default=True, choices=((True, 'Auto'), (False, 'Manual')))
1024 multiplier = models.PositiveIntegerField(default=60)
1027 multiplier = models.PositiveIntegerField(default=60)
1025 divisor = models.PositiveIntegerField(default=10)
1028 divisor = models.PositiveIntegerField(default=10)
1026 reference = models.PositiveSmallIntegerField(default=1, choices=((0, 'Internal (25MHz)'), (1, 'External (10MHz)')))
1029 reference = models.PositiveSmallIntegerField(default=1, choices=((0, 'Internal (25MHz)'), (1, 'External (10MHz)')))
1027 frequency = models.FloatField(default=60.0) No newline at end of file
1030 frequency = models.FloatField(default=60.0)
@@ -1,420 +1,425
1
1
2 import json
2 import json
3
3
4 from django.contrib import messages
4 from django.contrib import messages
5 from django.utils.safestring import mark_safe
5 from django.utils.safestring import mark_safe
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7 from django.contrib.auth.decorators import login_required
7 from django.contrib.auth.decorators import login_required
8
8
9 from apps.main.models import Experiment, Device
9 from apps.main.models import Experiment, Device
10 from apps.main.views import sidebar
10 from apps.main.views import sidebar
11
11
12 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode, RCClock
12 from .models import RCConfiguration, RCLine, RCLineType, RCLineCode, RCClock
13 from .forms import RCConfigurationForm, RCLineForm, RCLineViewForm, RCLineEditForm, RCImportForm, RCLineCodesForm, RCClockForm
13 from .forms import RCConfigurationForm, RCLineForm, RCLineViewForm, RCLineEditForm, RCImportForm, RCLineCodesForm, RCClockForm
14
14
15
15
16 def conf(request, conf_id):
16 def conf(request, conf_id):
17
17
18 conf = get_object_or_404(RCConfiguration, pk=conf_id)
18 conf = get_object_or_404(RCConfiguration, pk=conf_id)
19
19
20 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
20 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
21 clk = RCClock.objects.filter(rc_configuration=conf).first()
21 clk = RCClock.objects.filter(rc_configuration=conf).first()
22 if clk is None:
22 if clk is None:
23 clk = RCClock(rc_configuration=conf)
23 clk = RCClock(rc_configuration=conf)
24 clk.save()
24 clk.save()
25
25
26 for line in lines:
26 for line in lines:
27 params = json.loads(line.params)
27 params = json.loads(line.params)
28 line.form = RCLineViewForm(extra_fields=params, line=line)
28 line.form = RCLineViewForm(extra_fields=params, line=line)
29 if 'params' in params:
29 if 'params' in params:
30 line.subforms = [RCLineViewForm(extra_fields=fields, line=line, subform=True) for fields in params['params']]
30 line.subforms = [RCLineViewForm(extra_fields=fields, line=line, subform=True) for fields in params['params']]
31
31
32 kwargs = {}
32 kwargs = {}
33 kwargs['clock'] = clk
33 kwargs['clock'] = clk
34 kwargs['dev_conf'] = conf
34 kwargs['dev_conf'] = conf
35 kwargs['rc_lines'] = lines
35 kwargs['rc_lines'] = lines
36 kwargs['dev_conf_keys'] = ['ipp_unit', 'ntx', 'clock_divider', 'clock',
36 kwargs['dev_conf_keys'] = ['ipp_unit', 'ntx', 'clock_divider', 'clock',
37 'time_before', 'time_after', 'sync', 'sampling_reference',
37 'time_before', 'time_after', 'sync', 'sampling_reference',
38 'control_tx', 'control_sw']
38 'control_tx', 'control_sw']
39
39
40 kwargs['title'] = 'Configuration'
40 kwargs['title'] = 'Configuration'
41 kwargs['suptitle'] = 'Detail'
41 kwargs['suptitle'] = 'Detail'
42
42
43 kwargs['button'] = 'Edit Configuration'
43 kwargs['button'] = 'Edit Configuration'
44 ###### SIDEBAR ######
44 ###### SIDEBAR ######
45 kwargs.update(sidebar(conf=conf))
45 kwargs.update(sidebar(conf=conf))
46
46
47 return render(request, 'rc_conf.html', kwargs)
47 return render(request, 'rc_conf.html', kwargs)
48
48
49 @login_required
49 @login_required
50 def conf_edit(request, conf_id):
50 def conf_edit(request, conf_id):
51
51
52 conf = get_object_or_404(RCConfiguration, pk=conf_id)
52 conf = get_object_or_404(RCConfiguration, pk=conf_id)
53 clock = RCClock.objects.get(rc_configuration=conf)
53 clock = RCClock.objects.get(rc_configuration=conf)
54 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
54 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
55
55
56 for line in lines:
56 for line in lines:
57 params = json.loads(line.params)
57 params = json.loads(line.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
64
65 if request.method=='GET':
65 if request.method=='GET':
66
66
67 form = RCConfigurationForm(instance=conf)
67 form = RCConfigurationForm(instance=conf)
68 form_clock = RCClockForm(instance=clock)
68 form_clock = RCClockForm(instance=clock)
69
69
70 elif request.method=='POST':
70 elif request.method=='POST':
71
71
72 line_data = {}
72 line_data = {}
73 conf_data = {}
73 conf_data = {}
74 clock_data = {}
74 clock_data = {}
75 extras = []
75 extras = []
76
76
77 #classified post fields
77 #classified post fields
78 for label,value in request.POST.items():
78 for label,value in request.POST.items():
79 if label=='csrfmiddlewaretoken':
79 if label=='csrfmiddlewaretoken':
80 continue
80 continue
81
81
82 if label.count('|')==0:
82 if label.count('|')==0:
83 if label in ('mode', 'multiplier', 'divisor', 'reference', 'frequency'):
83 if label in ('mode', 'multiplier', 'divisor', 'reference', 'frequency'):
84 clock_data[label] = value
84 clock_data[label] = value
85 else:
85 else:
86 conf_data[label] = value
86 conf_data[label] = value
87 continue
87 continue
88
88
89 elif label.split('|')[0]!='-1':
89 elif label.split('|')[0]!='-1':
90 extras.append(label)
90 extras.append(label)
91 continue
91 continue
92
92
93 x, pk, name = label.split('|')
93 x, pk, name = label.split('|')
94
94
95 if name=='codes':
95 if name=='codes':
96 value = [s for s in value.split('\r\n') if s]
96 value = [s for s in value.split('\r\n') if s]
97
97
98 if pk in line_data:
98 if pk in line_data:
99 line_data[pk][name] = value
99 line_data[pk][name] = value
100 else:
100 else:
101 line_data[pk] = {name:value}
101 line_data[pk] = {name:value}
102
102
103 #update conf
103 #update conf
104
104
105 form_clock = RCClockForm(clock_data, instance=clock)
105 form_clock = RCClockForm(clock_data, instance=clock)
106 form = RCConfigurationForm(conf_data, instance=conf)
106 form = RCConfigurationForm(conf_data, instance=conf)
107
107
108 if form_clock.is_valid() and form.is_valid():
108 if form_clock.is_valid() and form.is_valid():
109 form_clock.save()
109 form_clock.save()
110 form.save()
110 form.save()
111
111
112 #update lines fields
112 #update lines fields
113 extras.sort()
113 extras.sort()
114 xxs = {}
114 for label in extras:
115 for label in extras:
115 x, pk, name = label.split('|')
116 x, pk, name = label.split('|')
116 if pk not in line_data:
117 if pk not in line_data:
117 line_data[pk] = {}
118 line_data[pk] = {}
118 if 'params' not in line_data[pk]:
119 if 'params' not in line_data[pk]:
119 line_data[pk]['params'] = []
120 line_data[pk]['params'] = []
120 if len(line_data[pk]['params'])<int(x)+1:
121 xxs[pk] = []
122 if x not in xxs[pk]:
121 line_data[pk]['params'].append({})
123 line_data[pk]['params'].append({})
124 xxs[pk].append(x)
125 for label in extras:
126 x, pk, name = label.split('|')
122 line_data[pk]['params'][int(x)][name] = float(request.POST[label])
127 line_data[pk]['params'][int(x)][name] = float(request.POST[label])
123
128
124 for pk, params in line_data.items():
129 for pk, params in line_data.items():
125 line = RCLine.objects.get(pk=pk)
130 line = RCLine.objects.get(pk=pk)
126 if line.line_type.name in ('windows', 'prog_pulses'):
131 if line.line_type.name in ('windows', 'prog_pulses'):
127 if 'params' not in params:
132 if 'params' not in params:
128 params['params'] = []
133 params['params'] = []
129 line.params = json.dumps(params)
134 line.params = json.dumps(params)
130 line.save()
135 line.save()
131
136
132 #update pulses field
137 #update pulses field
133 conf.update_pulses()
138 conf.update_pulses()
134
139
135 messages.success(request, 'RC Configuration successfully updated')
140 messages.success(request, 'RC Configuration successfully updated')
136
141
137 return redirect(conf.get_absolute_url())
142 return redirect(conf.get_absolute_url())
138
143
139 kwargs = {}
144 kwargs = {}
140 kwargs['dev_conf'] = conf
145 kwargs['dev_conf'] = conf
141 kwargs['form'] = form
146 kwargs['form'] = form
142 kwargs['form_clock'] = form_clock
147 kwargs['form_clock'] = form_clock
143 kwargs['rc_lines'] = lines
148 kwargs['rc_lines'] = lines
144 kwargs['edit'] = True
149 kwargs['edit'] = True
145
150
146 kwargs['title'] = 'RC Configuration'
151 kwargs['title'] = 'RC Configuration'
147 kwargs['suptitle'] = 'Edit'
152 kwargs['suptitle'] = 'Edit'
148 kwargs['button'] = 'Update'
153 kwargs['button'] = 'Update'
149
154
150 return render(request, 'rc_conf_edit.html', kwargs)
155 return render(request, 'rc_conf_edit.html', kwargs)
151
156
152
157
153 def add_line(request, conf_id, line_type_id=None, code_id=None):
158 def add_line(request, conf_id, line_type_id=None, code_id=None):
154
159
155 conf = get_object_or_404(RCConfiguration, pk=conf_id)
160 conf = get_object_or_404(RCConfiguration, pk=conf_id)
156
161
157 if request.method=='GET':
162 if request.method=='GET':
158 if line_type_id:
163 if line_type_id:
159 line_type = get_object_or_404(RCLineType, pk=line_type_id)
164 line_type = get_object_or_404(RCLineType, pk=line_type_id)
160
165
161 if code_id:
166 if code_id:
162 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id, 'code_id': code_id},
167 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id, 'code_id': code_id},
163 extra_fields=json.loads(line_type.params))
168 extra_fields=json.loads(line_type.params))
164 else:
169 else:
165 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id},
170 form = RCLineForm(initial={'rc_configuration':conf_id, 'line_type': line_type_id},
166 extra_fields=json.loads(line_type.params))
171 extra_fields=json.loads(line_type.params))
167 else:
172 else:
168 line_type = {'id':0}
173 line_type = {'id':0}
169 form = RCLineForm(initial={'rc_configuration':conf_id})
174 form = RCLineForm(initial={'rc_configuration':conf_id})
170
175
171 if request.method=='POST':
176 if request.method=='POST':
172
177
173 line_type = get_object_or_404(RCLineType, pk=line_type_id)
178 line_type = get_object_or_404(RCLineType, pk=line_type_id)
174 form = RCLineForm(request.POST,
179 form = RCLineForm(request.POST,
175 extra_fields=json.loads(line_type.params))
180 extra_fields=json.loads(line_type.params))
176
181
177 if form.is_valid():
182 if form.is_valid():
178 form.save()
183 form.save()
179 form.instance.update_pulses()
184 form.instance.update_pulses()
180 return redirect('url_edit_rc_conf', conf.id)
185 return redirect('url_edit_rc_conf', conf.id)
181
186
182 kwargs = {}
187 kwargs = {}
183 kwargs['form'] = form
188 kwargs['form'] = form
184 kwargs['title'] = 'RC Configuration'
189 kwargs['title'] = 'RC Configuration'
185 kwargs['suptitle'] = 'Add Line'
190 kwargs['suptitle'] = 'Add Line'
186 kwargs['button'] = 'Add'
191 kwargs['button'] = 'Add'
187 kwargs['previous'] = conf.get_absolute_url_edit()
192 kwargs['previous'] = conf.get_absolute_url_edit()
188 kwargs['dev_conf'] = conf
193 kwargs['dev_conf'] = conf
189 kwargs['line_type'] = line_type
194 kwargs['line_type'] = line_type
190
195
191 return render(request, 'rc_add_line.html', kwargs)
196 return render(request, 'rc_add_line.html', kwargs)
192
197
193 def edit_codes(request, conf_id, line_id, code_id=None):
198 def edit_codes(request, conf_id, line_id, code_id=None):
194
199
195 conf = get_object_or_404(RCConfiguration, pk=conf_id)
200 conf = get_object_or_404(RCConfiguration, pk=conf_id)
196 line = get_object_or_404(RCLine, pk=line_id)
201 line = get_object_or_404(RCLine, pk=line_id)
197 params = json.loads(line.params)
202 params = json.loads(line.params)
198
203
199 if request.method=='GET':
204 if request.method=='GET':
200 if code_id:
205 if code_id:
201 code = get_object_or_404(RCLineCode, pk=code_id)
206 code = get_object_or_404(RCLineCode, pk=code_id)
202 form = RCLineCodesForm(instance=code)
207 form = RCLineCodesForm(instance=code)
203 else:
208 else:
204 initial = {'code': params['code'],
209 initial = {'code': params['code'],
205 'codes': params['codes'] if 'codes' in params else [],
210 'codes': params['codes'] if 'codes' in params else [],
206 'number_of_codes': len(params['codes']) if 'codes' in params else 0,
211 'number_of_codes': len(params['codes']) if 'codes' in params else 0,
207 'bits_per_code': len(params['codes'][0]) if 'codes' in params else 0,
212 'bits_per_code': len(params['codes'][0]) if 'codes' in params else 0,
208 }
213 }
209 form = RCLineCodesForm(initial=initial)
214 form = RCLineCodesForm(initial=initial)
210
215
211 if request.method=='POST':
216 if request.method=='POST':
212 form = RCLineCodesForm(request.POST)
217 form = RCLineCodesForm(request.POST)
213 if form.is_valid():
218 if form.is_valid():
214 params['code'] = request.POST['code']
219 params['code'] = request.POST['code']
215 params['codes'] = [s for s in request.POST['codes'].split('\r\n') if s]
220 params['codes'] = [s for s in request.POST['codes'].split('\r\n') if s]
216 line.params = json.dumps(params)
221 line.params = json.dumps(params)
217 line.save()
222 line.save()
218 messages.success(request, 'Line: "%s" has been updated.' % line)
223 messages.success(request, 'Line: "%s" has been updated.' % line)
219 return redirect('url_edit_rc_conf', conf.id)
224 return redirect('url_edit_rc_conf', conf.id)
220
225
221 kwargs = {}
226 kwargs = {}
222 kwargs['form'] = form
227 kwargs['form'] = form
223 kwargs['title'] = line
228 kwargs['title'] = line
224 kwargs['suptitle'] = 'Edit'
229 kwargs['suptitle'] = 'Edit'
225 kwargs['button'] = 'Update'
230 kwargs['button'] = 'Update'
226 kwargs['dev_conf'] = conf
231 kwargs['dev_conf'] = conf
227 kwargs['previous'] = conf.get_absolute_url_edit()
232 kwargs['previous'] = conf.get_absolute_url_edit()
228 kwargs['line'] = line
233 kwargs['line'] = line
229
234
230 return render(request, 'rc_edit_codes.html', kwargs)
235 return render(request, 'rc_edit_codes.html', kwargs)
231
236
232 def add_subline(request, conf_id, line_id):
237 def add_subline(request, conf_id, line_id):
233
238
234 conf = get_object_or_404(RCConfiguration, pk=conf_id)
239 conf = get_object_or_404(RCConfiguration, pk=conf_id)
235 line = get_object_or_404(RCLine, pk=line_id)
240 line = get_object_or_404(RCLine, pk=line_id)
236
241
237 if request.method == 'POST':
242 if request.method == 'POST':
238 if line:
243 if line:
239 params = json.loads(line.params)
244 params = json.loads(line.params)
240 subparams = json.loads(line.line_type.params)
245 subparams = json.loads(line.line_type.params)
241 if 'params' in subparams:
246 if 'params' in subparams:
242 dum = {}
247 dum = {}
243 for key, value in subparams['params'].items():
248 for key, value in subparams['params'].items():
244 dum[key] = value['value']
249 dum[key] = value['value']
245 params['params'].append(dum)
250 params['params'].append(dum)
246 line.params = json.dumps(params)
251 line.params = json.dumps(params)
247 line.save()
252 line.save()
248 return redirect('url_edit_rc_conf', conf.id)
253 return redirect('url_edit_rc_conf', conf.id)
249
254
250 kwargs = {}
255 kwargs = {}
251
256
252 kwargs['title'] = 'Add new'
257 kwargs['title'] = 'Add new'
253 kwargs['suptitle'] = '%s to %s' % (line.line_type.name, line)
258 kwargs['suptitle'] = '%s to %s' % (line.line_type.name, line)
254
259
255 return render(request, 'confirm.html', kwargs)
260 return render(request, 'confirm.html', kwargs)
256
261
257 def remove_line(request, conf_id, line_id):
262 def remove_line(request, conf_id, line_id):
258
263
259 conf = get_object_or_404(RCConfiguration, pk=conf_id)
264 conf = get_object_or_404(RCConfiguration, pk=conf_id)
260 line = get_object_or_404(RCLine, pk=line_id)
265 line = get_object_or_404(RCLine, pk=line_id)
261
266
262 if request.method == 'POST':
267 if request.method == 'POST':
263 if line:
268 if line:
264 try:
269 try:
265 channel = line.channel
270 channel = line.channel
266 line.delete()
271 line.delete()
267 for ch in range(channel+1, RCLine.objects.filter(rc_configuration=conf).count()+1):
272 for ch in range(channel+1, RCLine.objects.filter(rc_configuration=conf).count()+1):
268 l = RCLine.objects.get(rc_configuration=conf, channel=ch)
273 l = RCLine.objects.get(rc_configuration=conf, channel=ch)
269 l.channel = l.channel-1
274 l.channel = l.channel-1
270 l.save()
275 l.save()
271 messages.success(request, 'Line: "%s" has been deleted.' % line)
276 messages.success(request, 'Line: "%s" has been deleted.' % line)
272 except:
277 except:
273 messages.error(request, 'Unable to delete line: "%s".' % line)
278 messages.error(request, 'Unable to delete line: "%s".' % line)
274
279
275 return redirect('url_edit_rc_conf', conf.id)
280 return redirect('url_edit_rc_conf', conf.id)
276
281
277 kwargs = {}
282 kwargs = {}
278
283
279 kwargs['object'] = line
284 kwargs['object'] = line
280 kwargs['delete'] = True
285 kwargs['delete'] = True
281 kwargs['title'] = 'Delete'
286 kwargs['title'] = 'Delete'
282 kwargs['suptitle'] = 'Line'
287 kwargs['suptitle'] = 'Line'
283 kwargs['previous'] = conf.get_absolute_url_edit()
288 kwargs['previous'] = conf.get_absolute_url_edit()
284 return render(request, 'confirm.html', kwargs)
289 return render(request, 'confirm.html', kwargs)
285
290
286
291
287 def remove_subline(request, conf_id, line_id, subline_id):
292 def remove_subline(request, conf_id, line_id, subline_id):
288
293
289 conf = get_object_or_404(RCConfiguration, pk=conf_id)
294 conf = get_object_or_404(RCConfiguration, pk=conf_id)
290 line = get_object_or_404(RCLine, pk=line_id)
295 line = get_object_or_404(RCLine, pk=line_id)
291
296
292 if request.method == 'POST':
297 if request.method == 'POST':
293 if line:
298 if line:
294 params = json.loads(line.params)
299 params = json.loads(line.params)
295 params['params'].remove(params['params'][int(subline_id)-1])
300 params['params'].remove(params['params'][int(subline_id)-1])
296 line.params = json.dumps(params)
301 line.params = json.dumps(params)
297 line.save()
302 line.save()
298
303
299 return redirect('url_edit_rc_conf', conf.id)
304 return redirect('url_edit_rc_conf', conf.id)
300
305
301 kwargs = {}
306 kwargs = {}
302
307
303 kwargs['object'] = line
308 kwargs['object'] = line
304 kwargs['object_name'] = line.line_type.name
309 kwargs['object_name'] = line.line_type.name
305 kwargs['delete_view'] = True
310 kwargs['delete_view'] = True
306 kwargs['title'] = 'Confirm delete'
311 kwargs['title'] = 'Confirm delete'
307
312
308 return render(request, 'confirm.html', kwargs)
313 return render(request, 'confirm.html', kwargs)
309
314
310
315
311 def update_lines_position(request, conf_id):
316 def update_lines_position(request, conf_id):
312
317
313 conf = get_object_or_404(RCConfiguration, pk=conf_id)
318 conf = get_object_or_404(RCConfiguration, pk=conf_id)
314
319
315 if request.method=='POST':
320 if request.method=='POST':
316 ch = 0
321 ch = 0
317 for item in request.POST['items'].split('&'):
322 for item in request.POST['items'].split('&'):
318 line = RCLine.objects.get(pk=item.split('=')[-1])
323 line = RCLine.objects.get(pk=item.split('=')[-1])
319 line.channel = ch
324 line.channel = ch
320 line.save()
325 line.save()
321 ch += 1
326 ch += 1
322
327
323 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
328 lines = RCLine.objects.filter(rc_configuration=conf).order_by('channel')
324
329
325 for line in lines:
330 for line in lines:
326 params = json.loads(line.params)
331 params = json.loads(line.params)
327 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
332 line.form = RCLineEditForm(conf=conf, line=line, extra_fields=params)
328
333
329 if 'params' in params:
334 if 'params' in params:
330 line.subform = True
335 line.subform = True
331 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
336 line.subforms = [RCLineEditForm(extra_fields=fields, line=line, subform=i) for i, fields in enumerate(params['params'])]
332
337
333 html = render(request, 'rc_lines.html', {'dev_conf':conf, 'rc_lines':lines, 'edit':True})
338 html = render(request, 'rc_lines.html', {'dev_conf':conf, 'rc_lines':lines, 'edit':True})
334 data = {'html': html.content.decode('utf8')}
339 data = {'html': html.content.decode('utf8')}
335
340
336 return HttpResponse(json.dumps(data), content_type="application/json")
341 return HttpResponse(json.dumps(data), content_type="application/json")
337 return redirect('url_edit_rc_conf', conf.id)
342 return redirect('url_edit_rc_conf', conf.id)
338
343
339
344
340 def import_file(request, conf_id):
345 def import_file(request, conf_id):
341
346
342 conf = get_object_or_404(RCConfiguration, pk=conf_id)
347 conf = get_object_or_404(RCConfiguration, pk=conf_id)
343 if request.method=='POST':
348 if request.method=='POST':
344 form = RCImportForm(request.POST, request.FILES)
349 form = RCImportForm(request.POST, request.FILES)
345 if form.is_valid():
350 if form.is_valid():
346 try:
351 try:
347 data = conf.import_from_file(request.FILES['file_name'])
352 data = conf.import_from_file(request.FILES['file_name'])
348 conf.dict_to_parms(data)
353 conf.dict_to_parms(data)
349 conf.update_pulses()
354 conf.update_pulses()
350 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
355 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
351 return redirect(conf.get_absolute_url_edit())
356 return redirect(conf.get_absolute_url_edit())
352
357
353 except Exception as e:
358 except Exception as e:
354 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
359 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
355 else:
360 else:
356 messages.warning(request, 'Your current configuration will be replaced')
361 messages.warning(request, 'Your current configuration will be replaced')
357 form = RCImportForm()
362 form = RCImportForm()
358
363
359 kwargs = {}
364 kwargs = {}
360 kwargs['form'] = form
365 kwargs['form'] = form
361 kwargs['title'] = 'RC Configuration'
366 kwargs['title'] = 'RC Configuration'
362 kwargs['suptitle'] = 'Import file'
367 kwargs['suptitle'] = 'Import file'
363 kwargs['button'] = 'Upload'
368 kwargs['button'] = 'Upload'
364 kwargs['previous'] = conf.get_absolute_url()
369 kwargs['previous'] = conf.get_absolute_url()
365
370
366 return render(request, 'rc_import.html', kwargs)
371 return render(request, 'rc_import.html', kwargs)
367
372
368
373
369 def plot_pulses(request, conf_id):
374 def plot_pulses(request, conf_id):
370
375
371 conf = get_object_or_404(RCConfiguration, pk=conf_id)
376 conf = get_object_or_404(RCConfiguration, pk=conf_id)
372 km = True if 'km' in request.GET else False
377 km = True if 'km' in request.GET else False
373
378
374 script, div = conf.plot_pulses(km=km)
379 script, div = conf.plot_pulses(km=km)
375
380
376 kwargs = {}
381 kwargs = {}
377 kwargs['no_sidebar'] = True
382 kwargs['no_sidebar'] = True
378 kwargs['title'] = 'RC Pulses'
383 kwargs['title'] = 'RC Pulses'
379 kwargs['suptitle'] = conf.name
384 kwargs['suptitle'] = conf.name
380 kwargs['div'] = mark_safe(div)
385 kwargs['div'] = mark_safe(div)
381 kwargs['script'] = mark_safe(script)
386 kwargs['script'] = mark_safe(script)
382 kwargs['units'] = conf.km2unit
387 kwargs['units'] = conf.km2unit
383 kwargs['kms'] = 1/conf.km2unit
388 kwargs['kms'] = 1/conf.km2unit
384
389
385 if km:
390 if km:
386 kwargs['km_selected'] = True
391 kwargs['km_selected'] = True
387
392
388 if 'json' in request.GET:
393 if 'json' in request.GET:
389 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
394 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
390 else:
395 else:
391 return render(request, 'rc_pulses.html', kwargs)
396 return render(request, 'rc_pulses.html', kwargs)
392
397
393 def plot_pulses2(request, conf_id):
398 def plot_pulses2(request, conf_id):
394
399
395 conf = get_object_or_404(RCConfiguration, pk=conf_id)
400 conf = get_object_or_404(RCConfiguration, pk=conf_id)
396 km = True if 'km' in request.GET else False
401 km = True if 'km' in request.GET else False
397
402
398 script, div = conf.plot_pulses2(km=km)
403 script, div = conf.plot_pulses2(km=km)
399
404
400 kwargs = {}
405 kwargs = {}
401 kwargs['no_sidebar'] = True
406 kwargs['no_sidebar'] = True
402 kwargs['title'] = 'RC Pulses'
407 kwargs['title'] = 'RC Pulses'
403 kwargs['suptitle'] = conf.name
408 kwargs['suptitle'] = conf.name
404 kwargs['div'] = mark_safe(div)
409 kwargs['div'] = mark_safe(div)
405 kwargs['script'] = mark_safe(script)
410 kwargs['script'] = mark_safe(script)
406 kwargs['units'] = conf.km2unit
411 kwargs['units'] = conf.km2unit
407 kwargs['kms'] = 1/conf.km2unit
412 kwargs['kms'] = 1/conf.km2unit
408
413
409 if km:
414 if km:
410 kwargs['km_selected'] = True
415 kwargs['km_selected'] = True
411
416
412 if 'json' in request.GET:
417 if 'json' in request.GET:
413 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
418 return HttpResponse(json.dumps({'div':mark_safe(div), 'script':mark_safe(script)}), content_type="application/json")
414 else:
419 else:
415 return render(request, 'rc_pulses.html', kwargs)
420 return render(request, 'rc_pulses.html', kwargs)
416
421
417 def conf_raw(request, conf_id):
422 def conf_raw(request, conf_id):
418 conf = get_object_or_404(RCConfiguration, pk=conf_id)
423 conf = get_object_or_404(RCConfiguration, pk=conf_id)
419 raw = conf.write_device(raw=True)
424 raw = conf.write_device(raw=True)
420 return HttpResponse(raw, content_type='application/json') No newline at end of file
425 return HttpResponse(raw, content_type='application/json')
@@ -1,68 +1,70
1 version: '2'
1 version: '2'
2 services:
2 services:
3 # Django app
3 # Django app
4 web:
4 # web:
5 container_name: 'radarsys'
5 # container_name: 'radarsys'
6 build: .
6 # build: .
7 restart: always
7 # restart: always
8 image: radarsys
8 # image: radarsys
9 command: gunicorn radarsys.wsgi:application -w 2 -b :8000
9 # command: gunicorn radarsys.wsgi:application -w 2 -b :8000
10 # command: python manage.py runserver 0.0.0.0:8030
10 # # command: python manage.py runserver 0.0.0.0:8030
11 # ports:
11 # # ports:
12 # - 8030:8030
12 # # - 8030:8030
13 env_file: .env
13 # env_file: .env
14
14
15 links:
15 # links:
16 - redis
16 # - redis
17 - postgres
17 # - postgres
18 volumes:
18 # volumes:
19 - './:/radarsys'
19 # - './:/radarsys'
20 - '${DOCKER_DATA}/static:/radarsys/static'
20 # - '${DOCKER_DATA}/static:/radarsys/static'
21 depends_on:
21 # depends_on:
22 - redis
22 # - redis
23 - postgres
23 # - postgres
24
24
25 redis:
25 redis:
26 container_name: 'radarsys-redis'
26 container_name: 'radarsys-redis'
27 image: 'redis:3.2-alpine'
27 image: 'redis:3.2-alpine'
28 volumes:
28 volumes:
29 - '${DOCKER_DATA}/redis:/data'
29 - '${DOCKER_DATA}/redis:/data'
30 ports:
31 - 6300:6379
30
32
31 celery_worker:
33 celery_worker:
32 container_name: 'radarsys-celery'
34 container_name: 'radarsys-celery'
33 image: radarsys
35 image: radarsys
34 env_file: .env
36 env_file: .env
35 command: celery -A radarsys worker -l info
37 command: celery -A radarsys worker -l info
36 volumes_from:
38 # volumes_from:
37 - web
39 # - web
38 depends_on:
40 # depends_on:
39 - web
41 # - web
40
42
41 # PostgreSQL
43 # PostgreSQL
42 postgres:
44 postgres:
43 container_name: 'radarsys-postgres'
45 container_name: 'radarsys-postgres'
44 build: ./postgres/
46 build: ./postgres/
45 volumes:
47 volumes:
46 - ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
48 - ./postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
47 - pgdata:/var/lib/postgresql/data
49 - pgdata:/var/lib/postgresql/data
48 # ports:
50 ports:
49 # - 5432:5432
51 - 5400:5432
50 env_file: .env
52 env_file: .env
51
53
52 # Web Server
54 # Web Server
53 nginx:
55 # nginx:
54 container_name: 'radarsys-nginx'
56 # container_name: 'radarsys-nginx'
55 restart: always
57 # restart: always
56 build: ./nginx/
58 # build: ./nginx/
57 ports:
59 # ports:
58 - '8030:8030'
60 # - '8030:8030'
59 volumes_from:
61 # volumes_from:
60 - web
62 # - web
61 links:
63 # links:
62 - web:web
64 # - web:web
63 depends_on:
65 # depends_on:
64 - web
66 # - web
65
67
66 volumes:
68 volumes:
67 pgdata:
69 pgdata:
68 driver: local
70 driver: local
General Comments 0
You need to be logged in to leave comments. Login now