##// END OF EJS Templates
New experiment views
amorales -
r360:46316742ce9f
parent child
Show More
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
@@ -0,0 +1,5
1 import time
2
3 while True:
4 print("Adquiriendo")
5 time.sleep(3) No newline at end of file
@@ -0,0 +1,5
1 import time
2
3 while True:
4 print("Transmitiendo")
5 time.sleep(3) No newline at end of file
@@ -1,80 +1,80
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 GeneratorConfiguration
8 from .models import GeneratorConfiguration
9
9
10 def create_choices_from_model(model, conf_id, all_choice=False):
10 def create_choices_from_model(model, conf_id, all_choice=False):
11
11
12 instance = globals()[model]
12 instance = globals()[model]
13 choices = instance.objects.all().values_list('pk', 'name')
13 choices = instance.objects.all().values_list('pk', 'name')
14
14
15 return choices
15 return choices
16
16
17 class GeneratorConfigurationForm(forms.ModelForm):
17 class GeneratorConfigurationForm(forms.ModelForm):
18
18
19 def __init__(self, *args, **kwargs):
19 def __init__(self, *args, **kwargs):
20 super(GeneratorConfigurationForm, self).__init__(*args, **kwargs)
20 super(GeneratorConfigurationForm, self).__init__(*args, **kwargs)
21
21
22 instance = getattr(self, 'instance', None)
22 instance = getattr(self, 'instance', None)
23
23
24 if instance and instance.pk:
24 if instance and instance.pk:
25
25
26 devices = Device.objects.filter(device_type__name='generator')
26 devices = Device.objects.filter(device_type__name='generator')
27 if instance.experiment:
27 #if instance.experiment:
28 self.fields['experiment'].widget.attrs['read_only'] = True
28 #self.fields['experiment'].widget.attrs['read_only'] = True
29 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
29 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
30 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
30 #self.fields['device'].widget.choices = [(device.id, device) for device in devices]
31
31
32 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
32 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
33 self.fields['experiment'].widget.attrs['readonly'] = True
33 self.fields['experiment'].widget.attrs['readonly'] = True
34
34
35 class Meta:
35 class Meta:
36 model = GeneratorConfiguration
36 model = GeneratorConfiguration
37 exclude = ('type', 'parameters', 'status', 'total_units', 'author', 'hash')
37 exclude = ('type', 'parameters', 'status', 'total_units', 'author', 'hash')
38
38
39 def clean(self):
39 def clean(self):
40 form_data = super(GeneratorConfigurationForm, self).clean()
40 form_data = super(GeneratorConfigurationForm, self).clean()
41 return form_data
41 return form_data
42
42
43 def save(self, *args, **kwargs):
43 def save(self, *args, **kwargs):
44 conf = super(GeneratorConfigurationForm, self).save(*args, **kwargs)
44 conf = super(GeneratorConfigurationForm, self).save(*args, **kwargs)
45 conf.save()
45 conf.save()
46 return conf
46 return conf
47
47
48 class ExtFileField(forms.FileField):
48 class ExtFileField(forms.FileField):
49 """
49 """
50 Same as forms.FileField, but you can specify a file extension whitelist.
50 Same as forms.FileField, but you can specify a file extension whitelist.
51
51
52 >>> from django.core.files.uploadedfile import SimpleUploadedFile
52 >>> from django.core.files.uploadedfile import SimpleUploadedFile
53 >>>
53 >>>
54 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
54 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
55 >>>
55 >>>
56 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
56 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
57 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
57 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
58 >>>
58 >>>
59 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
59 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
60 Traceback (most recent call last):
60 Traceback (most recent call last):
61 ...
61 ...
62 ValidationError: [u'Not allowed filetype!']
62 ValidationError: [u'Not allowed filetype!']
63 """
63 """
64 def __init__(self, *args, **kwargs):
64 def __init__(self, *args, **kwargs):
65 extensions = kwargs.pop("extensions")
65 extensions = kwargs.pop("extensions")
66 self.extensions = [i.lower() for i in extensions]
66 self.extensions = [i.lower() for i in extensions]
67
67
68 super(ExtFileField, self).__init__(*args, **kwargs)
68 super(ExtFileField, self).__init__(*args, **kwargs)
69
69
70 def clean(self, *args, **kwargs):
70 def clean(self, *args, **kwargs):
71 data = super(ExtFileField, self).clean(*args, **kwargs)
71 data = super(ExtFileField, self).clean(*args, **kwargs)
72 filename = data.name
72 filename = data.name
73 ext = os.path.splitext(filename)[1]
73 ext = os.path.splitext(filename)[1]
74 ext = ext.lower()
74 ext = ext.lower()
75 if ext not in self.extensions:
75 if ext not in self.extensions:
76 raise forms.ValidationError('Not allowed file type: %s' % ext)
76 raise forms.ValidationError('Not allowed file type: %s' % ext)
77
77
78 class GeneratorImportForm(forms.Form):
78 class GeneratorImportForm(forms.Form):
79
79
80 file_name = ExtFileField(extensions=['.racp', '.json', '.dat']) No newline at end of file
80 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
@@ -1,177 +1,194
1 from django import forms
1 from django import forms
2 from django.utils.safestring import mark_safe
2 from django.utils.safestring import mark_safe
3 from apps.main.models import Device, Experiment, Campaign, Location, Configuration
3 from apps.main.models import Device, Experiment, Campaign, Location, Configuration
4 from django.template.defaultfilters import default
4 from django.template.defaultfilters import default
5
5
6 FILE_FORMAT = (
6 FILE_FORMAT = (
7 ('json', 'json'),
7 ('json', 'json'),
8 )
8 )
9
9
10 def add_empty_choice(choices, pos=0, label='-----'):
10 def add_empty_choice(choices, pos=0, label='-----'):
11 if len(choices)>0:
11 if len(choices)>0:
12 choices = list(choices)
12 choices = list(choices)
13 choices.insert(0, (0, label))
13 choices.insert(0, (0, label))
14 return choices
14 return choices
15 else:
15 else:
16 return [(0, label)]
16 return [(0, label)]
17
17
18 class DatepickerWidget(forms.widgets.TextInput):
18 class DatepickerWidget(forms.widgets.TextInput):
19 def render(self, name, value, attrs=None, renderer=None):
19 def render(self, name, value, attrs=None, renderer=None):
20 input_html = super(DatepickerWidget, self).render(name, value, attrs)
20 input_html = super(DatepickerWidget, self).render(name, value, attrs)
21
21
22 html = '<div class="input-group date">'+input_html+'<span class="input-group-addon"><i class="far fa-calendar-alt"></i></span></div>'
22 html = '<div class="input-group date">'+input_html+'<span class="input-group-addon"><i class="far fa-calendar-alt"></i></span></div>'
23 return mark_safe(html)
23 return mark_safe(html)
24
24
25 class DateRangepickerWidget(forms.widgets.TextInput):
25 class DateRangepickerWidget(forms.widgets.TextInput):
26 def render(self, name, value, attrs=None, renderer=None):
26 def render(self, name, value, attrs=None, renderer=None):
27 start = attrs['start_date']
27 start = attrs['start_date']
28 end = attrs['end_date']
28 end = attrs['end_date']
29 html = '''<div class="col-md-6 input-group date" style="float:inherit">
29 html = '''<div class="col-md-6 input-group date" style="float:inherit">
30 <input class="form-control" id="id_start_date" name="start_date" placeholder="Start" title="" type="text" value="{}">
30 <input class="form-control" id="id_start_date" name="start_date" placeholder="Start" title="" type="text" value="{}">
31 <span class="input-group-addon"><i class="far fa-calendar-alt"></i></span>
31 <span class="input-group-addon"><i class="far fa-calendar-alt"></i></span>
32 </div>
32 </div>
33 <div class="col-md-6 input-group date" style="float:inherit">
33 <div class="col-md-6 input-group date" style="float:inherit">
34 <input class="form-control" id="id_end_date" name="end_date" placeholder="End" title="" type="text" value="{}">
34 <input class="form-control" id="id_end_date" name="end_date" placeholder="End" title="" type="text" value="{}">
35 <span class="input-group-addon"><i class="far fa-calendar-alt"></i></span>
35 <span class="input-group-addon"><i class="far fa-calendar-alt"></i></span>
36 </div>'''.format(start, end)
36 </div>'''.format(start, end)
37 return mark_safe(html)
37 return mark_safe(html)
38
38
39 class TimepickerWidget(forms.widgets.TextInput):
39 class TimepickerWidget(forms.widgets.TextInput):
40 def render(self, name, value, attrs=None, renderer=None):
40 def render(self, name, value, attrs=None, renderer=None):
41 input_html = super(TimepickerWidget, self).render(name, value, attrs)
41 input_html = super(TimepickerWidget, self).render(name, value, attrs)
42
42
43 html = '<div class="input-group time">'+input_html+'<span class="input-group-addon"><i class="far fa-clock"></i></span></div>'
43 html = '<div class="input-group time">'+input_html+'<span class="input-group-addon"><i class="far fa-clock"></i></span></div>'
44 return mark_safe(html)
44 return mark_safe(html)
45
45
46 class CampaignForm(forms.ModelForm):
46 class CampaignForm(forms.ModelForm):
47
47
48 experiments = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(),
48 experiments = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(),
49 queryset=Experiment.objects.filter(template=True),
49 queryset=Experiment.objects.filter(template=True),
50 required=False)
50 required=False)
51
51
52 def __init__(self, *args, **kwargs):
52 def __init__(self, *args, **kwargs):
53 super(CampaignForm, self).__init__(*args, **kwargs)
53 super(CampaignForm, self).__init__(*args, **kwargs)
54 self.fields['start_date'].widget = DatepickerWidget(self.fields['start_date'].widget.attrs)
54 self.fields['start_date'].widget = DatepickerWidget(self.fields['start_date'].widget.attrs)
55 self.fields['end_date'].widget = DatepickerWidget(self.fields['end_date'].widget.attrs)
55 self.fields['end_date'].widget = DatepickerWidget(self.fields['end_date'].widget.attrs)
56 self.fields['description'].widget.attrs = {'rows': 2}
56 self.fields['description'].widget.attrs = {'rows': 2}
57
57
58 if self.instance.pk:
58 if self.instance.pk:
59 self.fields['experiments'].queryset |= self.instance.experiments.all()
59 self.fields['experiments'].queryset |= self.instance.experiments.all()
60
60
61 class Meta:
61 class Meta:
62 model = Campaign
62 model = Campaign
63 exclude = ['author']
63 exclude = ['author']
64
64
65
65
66 class ExperimentForm(forms.ModelForm):
66 class ExperimentForm(forms.ModelForm):
67
67
68 def __init__(self, *args, **kwargs):
68 def __init__(self, *args, **kwargs):
69 super(ExperimentForm, self).__init__(*args, **kwargs)
69 super(ExperimentForm, self).__init__(*args, **kwargs)
70 #self.fields['start_time'].widget = TimepickerWidget(self.fields['start_time'].widget.attrs)
70 #self.fields['start_time'].widget = TimepickerWidget(self.fields['start_time'].widget.attrs)
71 #self.fields['end_time'].widget = TimepickerWidget(self.fields['end_time'].widget.attrs)
71 #self.fields['end_time'].widget = TimepickerWidget(self.fields['end_time'].widget.attrs)
72
72
73 def save(self, *args, **kwargs):
73 def save(self, *args, **kwargs):
74 exp = super(ExperimentForm, self).save(*args, **kwargs)
74 exp = super(ExperimentForm, self).save(*args, **kwargs)
75 exp.name = exp.name.replace(' ', '')
75 exp.name = exp.name.replace(' ', '')
76 exp.save()
76 exp.save()
77 return exp
77 return exp
78
78
79 class Meta:
79 class Meta:
80 model = Experiment
80 model = Experiment
81 exclude = ['task', 'status', 'author', 'hash']
81 exclude = ['task', 'status', 'author', 'hash']
82
82
83 class ExperimentEditionForm(forms.ModelForm):
84
85 def __init__(self, *args, **kwargs):
86 super(ExperimentEditionForm, self).__init__(*args, **kwargs)
87 #self.fields['start_time'].widget = TimepickerWidget(self.fields['start_time'].widget.attrs)
88 #self.fields['end_time'].widget = TimepickerWidget(self.fields['end_time'].widget.attrs)
89
90 def save(self, *args, **kwargs):
91 exp = super(ExperimentEditionForm, self).save(*args, **kwargs)
92 exp.name = exp.name.replace(' ', '')
93 exp.save()
94 return exp
95
96 class Meta:
97 model = Experiment
98 exclude = ['pedestal', 'generator', 'task', 'status', 'author', 'hash']
99
83 class LocationForm(forms.ModelForm):
100 class LocationForm(forms.ModelForm):
84 class Meta:
101 class Meta:
85 model = Location
102 model = Location
86 exclude = ['']
103 exclude = ['']
87
104
88 class DeviceForm(forms.ModelForm):
105 class DeviceForm(forms.ModelForm):
89 class Meta:
106 class Meta:
90 model = Device
107 model = Device
91 exclude = ['status']
108 exclude = ['status']
92
109
93 class ConfigurationForm(forms.ModelForm):
110 class ConfigurationForm(forms.ModelForm):
94
111
95 def __init__(self, *args, **kwargs):
112 def __init__(self, *args, **kwargs):
96 super(ConfigurationForm, self).__init__(*args, **kwargs)
113 super(ConfigurationForm, self).__init__(*args, **kwargs)
97
114
98 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
115 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
99 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
116 self.fields['experiment'].widget.attrs['disabled'] = 'disabled'
100
117
101 class Meta:
118 class Meta:
102 model = Configuration
119 model = Configuration
103 exclude = ['type', 'created_date', 'programmed_date', 'parameters', 'author', 'hash']
120 exclude = ['type', 'created_date', 'programmed_date', 'parameters', 'author', 'hash']
104
121
105 class UploadFileForm(forms.Form):
122 class UploadFileForm(forms.Form):
106
123
107 file = forms.FileField()
124 file = forms.FileField()
108
125
109 class DownloadFileForm(forms.Form):
126 class DownloadFileForm(forms.Form):
110
127
111 format = forms.ChoiceField(choices= ((0, 'json'),) )
128 format = forms.ChoiceField(choices= ((0, 'json'),) )
112
129
113 def __init__(self, device_type, *args, **kwargs):
130 def __init__(self, device_type, *args, **kwargs):
114
131
115 super(DownloadFileForm, self).__init__(*args, **kwargs)
132 super(DownloadFileForm, self).__init__(*args, **kwargs)
116
133
117 self.fields['format'].choices = FILE_FORMAT
134 self.fields['format'].choices = FILE_FORMAT
118
135
119 class OperationForm(forms.Form):
136 class OperationForm(forms.Form):
120
137
121 campaign = forms.ChoiceField(label="Campaign")
138 campaign = forms.ChoiceField(label="Campaign")
122
139
123 def __init__(self, *args, **kwargs):
140 def __init__(self, *args, **kwargs):
124
141
125 campaigns = kwargs.pop('campaigns')
142 campaigns = kwargs.pop('campaigns')
126 super(OperationForm, self).__init__(*args, **kwargs)
143 super(OperationForm, self).__init__(*args, **kwargs)
127 self.fields['campaign'].label = 'Current Campaigns'
144 self.fields['campaign'].label = 'Current Campaigns'
128 self.fields['campaign'].choices = add_empty_choice(campaigns.values_list('id', 'name'))
145 self.fields['campaign'].choices = add_empty_choice(campaigns.values_list('id', 'name'))
129
146
130
147
131 class OperationSearchForm(forms.Form):
148 class OperationSearchForm(forms.Form):
132 # -----ALL Campaigns------
149 # -----ALL Campaigns------
133 campaign = forms.ChoiceField(label="Campaign")
150 campaign = forms.ChoiceField(label="Campaign")
134
151
135 def __init__(self, *args, **kwargs):
152 def __init__(self, *args, **kwargs):
136 super(OperationSearchForm, self).__init__(*args, **kwargs)
153 super(OperationSearchForm, self).__init__(*args, **kwargs)
137 self.fields['campaign'].choices=Campaign.objects.all().order_by('-start_date').values_list('id', 'name')
154 self.fields['campaign'].choices=Campaign.objects.all().order_by('-start_date').values_list('id', 'name')
138
155
139
156
140 class NewForm(forms.Form):
157 class NewForm(forms.Form):
141
158
142 create_from = forms.ChoiceField(choices=((0, '-----'),
159 create_from = forms.ChoiceField(choices=((0, '-----'),
143 (1, 'Empty (blank)'),
160 (1, 'Empty (blank)'),
144 (2, 'Template')))
161 (2, 'Template')))
145 choose_template = forms.ChoiceField()
162 choose_template = forms.ChoiceField()
146
163
147 def __init__(self, *args, **kwargs):
164 def __init__(self, *args, **kwargs):
148
165
149 template_choices = kwargs.pop('template_choices', [])
166 template_choices = kwargs.pop('template_choices', [])
150 super(NewForm, self).__init__(*args, **kwargs)
167 super(NewForm, self).__init__(*args, **kwargs)
151 self.fields['choose_template'].choices = add_empty_choice(template_choices)
168 self.fields['choose_template'].choices = add_empty_choice(template_choices)
152
169
153
170
154 class FilterForm(forms.Form):
171 class FilterForm(forms.Form):
155
172
156 def __init__(self, *args, **kwargs):
173 def __init__(self, *args, **kwargs):
157 extra_fields = kwargs.pop('extra_fields', [])
174 extra_fields = kwargs.pop('extra_fields', [])
158 super(FilterForm, self).__init__(*args, **kwargs)
175 super(FilterForm, self).__init__(*args, **kwargs)
159
176
160 for field in extra_fields:
177 for field in extra_fields:
161 if 'range_date' in field:
178 if 'range_date' in field:
162 self.fields[field] = forms.CharField(required=False)
179 self.fields[field] = forms.CharField(required=False)
163 self.fields[field].widget = DateRangepickerWidget()
180 self.fields[field].widget = DateRangepickerWidget()
164 if 'initial' in kwargs:
181 if 'initial' in kwargs:
165 self.fields[field].widget.attrs = {'start_date':kwargs['initial'].get('start_date', ''),
182 self.fields[field].widget.attrs = {'start_date':kwargs['initial'].get('start_date', ''),
166 'end_date':kwargs['initial'].get('end_date', '')}
183 'end_date':kwargs['initial'].get('end_date', '')}
167 elif field in ('template', 'historical') or 'my ' in field:
184 elif field in ('template', 'historical') or 'my ' in field:
168 self.fields[field] = forms.BooleanField(required=False)
185 self.fields[field] = forms.BooleanField(required=False)
169 else:
186 else:
170 self.fields[field] = forms.CharField(required=False)
187 self.fields[field] = forms.CharField(required=False)
171
188
172 class ChangeIpForm(forms.Form):
189 class ChangeIpForm(forms.Form):
173
190
174 ip_address = forms.GenericIPAddressField()
191 ip_address = forms.GenericIPAddressField()
175 mask = forms.GenericIPAddressField(initial='255.255.255.0')
192 mask = forms.GenericIPAddressField(initial='255.255.255.0')
176 gateway = forms.GenericIPAddressField(initial='0.0.0.0')
193 gateway = forms.GenericIPAddressField(initial='0.0.0.0')
177 dns = forms.GenericIPAddressField(initial='0.0.0.0')
194 dns = forms.GenericIPAddressField(initial='0.0.0.0')
@@ -1,733 +1,756
1
1
2 import os
2 import os
3 import json
3 import json
4 import requests
4 import requests
5 import time
5 import time
6 from datetime import datetime
6 from datetime import datetime
7
7
8 try:
8 try:
9 from polymorphic.models import PolymorphicModel
9 from polymorphic.models import PolymorphicModel
10 except:
10 except:
11 from polymorphic import PolymorphicModel
11 from polymorphic import PolymorphicModel
12
12
13 from django.template.base import kwarg_re
13 from django.template.base import kwarg_re
14 from django.db import models
14 from django.db import models
15 from django.urls import reverse
15 from django.urls import reverse
16 from django.core.validators import MinValueValidator, MaxValueValidator
16 from django.core.validators import MinValueValidator, MaxValueValidator
17 from django.shortcuts import get_object_or_404
17 from django.shortcuts import get_object_or_404
18 from django.contrib.auth.models import User
18 from django.contrib.auth.models import User
19 from django.db.models.signals import post_save
19 from django.db.models.signals import post_save
20 from django.dispatch import receiver
20 from django.dispatch import receiver
21
21
22 from apps.main.utils import Params
22 from apps.main.utils import Params
23
23
24 DEV_PORTS = {
24 DEV_PORTS = {
25 'pedestal' : 80,
25 'pedestal' : 80,
26 'pedestal_dev' : 80,
26 'pedestal_dev' : 80,
27 'generator' : 80,
27 'generator' : 80,
28 'usrp_rx' : 2000,
28 'usrp_rx' : 2000,
29 'usrp_tx' : 2000,
29 'usrp_tx' : 2000,
30 }
30 }
31
31
32 RADAR_STATES = (
32 RADAR_STATES = (
33 (0, 'No connected'),
33 (0, 'No connected'),
34 (1, 'Connected'),
34 (1, 'Connected'),
35 (2, 'Configured'),
35 (2, 'Configured'),
36 (3, 'Running'),
36 (3, 'Running'),
37 (4, 'Scheduled'),
37 (4, 'Scheduled'),
38 )
38 )
39
39
40 EXPERIMENT_TYPE = (
40 EXPERIMENT_TYPE = (
41 (0, 'RAW_DATA'),
41 (0, 'RAW_DATA'),
42 (1, 'PDATA'),
42 (1, 'PDATA'),
43 )
43 )
44
44
45 DECODE_TYPE = (
45 DECODE_TYPE = (
46 (0, 'None'),
46 (0, 'None'),
47 (1, 'TimeDomain'),
47 (1, 'TimeDomain'),
48 (2, 'FreqDomain'),
48 (2, 'FreqDomain'),
49 (3, 'InvFreqDomain'),
49 (3, 'InvFreqDomain'),
50 )
50 )
51
51
52 DEV_STATES = (
52 DEV_STATES = (
53 (0, 'Unknown'),
53 (0, 'Unknown'),
54 (1, 'Connected'),
54 (1, 'Connected'),
55 (2, 'Configured'),
55 (2, 'Configured'),
56 (3, 'Running'),
56 (3, 'Running'),
57 (4, 'Offline'),
57 (4, 'Offline'),
58 )
58 )
59
59
60 DEV_TYPES = (
60 DEV_TYPES = (
61 ('', 'Select a device type'),
61 ('', 'Select a device type'),
62 ('pedestal', 'Pedestal Controller'),
62 ('pedestal', 'Pedestal Controller'),
63 ('pedestal_dev', 'Pedestal Controller Dev Mode'),
63 ('pedestal_dev', 'Pedestal Controller Dev Mode'),
64 ('generator', 'Pulse Generator'),
64 ('generator', 'Pulse Generator'),
65 ('usrp_rx', 'Universal Software Radio Peripheral Rx'),
65 ('usrp_rx', 'Universal Software Radio Peripheral Rx'),
66 ('usrp_tx', 'Universal Software Radio Peripheral Tx'),
66 ('usrp_tx', 'Universal Software Radio Peripheral Tx'),
67 )
67 )
68
68
69 EXP_STATES = (
69 EXP_STATES = (
70 (0,'Error'), #RED
70 (0,'Error'), #RED
71 (1,'Cancelled'), #YELLOW
71 (1,'Cancelled'), #YELLOW
72 (2,'Running'), #GREEN
72 (2,'Running'), #GREEN
73 (3,'Scheduled'), #BLUE
73 (3,'Scheduled'), #BLUE
74 (4,'Unknown'), #WHITE
74 (4,'Unknown'), #WHITE
75 )
75 )
76
76
77 CONF_TYPES = (
77 CONF_TYPES = (
78 (0, 'Active'),
78 (0, 'Active'),
79 (1, 'Historical'),
79 (1, 'Historical'),
80 )
80 )
81
81
82 class Profile(models.Model):
82 class Profile(models.Model):
83 user = models.OneToOneField(User, on_delete=models.CASCADE)
83 user = models.OneToOneField(User, on_delete=models.CASCADE)
84 theme = models.CharField(max_length=30, default='spacelab')
84 theme = models.CharField(max_length=30, default='spacelab')
85
85
86
86
87 @receiver(post_save, sender=User)
87 @receiver(post_save, sender=User)
88 def create_user_profile(sender, instance, created, **kwargs):
88 def create_user_profile(sender, instance, created, **kwargs):
89 if created:
89 if created:
90 Profile.objects.create(user=instance)
90 Profile.objects.create(user=instance)
91
91
92 @receiver(post_save, sender=User)
92 @receiver(post_save, sender=User)
93 def save_user_profile(sender, instance, **kwargs):
93 def save_user_profile(sender, instance, **kwargs):
94 instance.profile.save()
94 instance.profile.save()
95
95
96
96
97 class Location(models.Model):
97 class Location(models.Model):
98
98
99 name = models.CharField(max_length = 30)
99 name = models.CharField(max_length = 30)
100 description = models.TextField(blank=True, null=True)
100 description = models.TextField(blank=True, null=True)
101
101
102 class Meta:
102 class Meta:
103 db_table = 'db_location'
103 db_table = 'db_location'
104
104
105 def __str__(self):
105 def __str__(self):
106 return u'%s' % self.name
106 return u'%s' % self.name
107
107
108 def get_absolute_url(self):
108 def get_absolute_url(self):
109 return reverse('url_location', args=[str(self.id)])
109 return reverse('url_location', args=[str(self.id)])
110
110
111
111
112 class DeviceType(models.Model):
112 class DeviceType(models.Model):
113
113
114 name = models.CharField(max_length = 15, choices = DEV_TYPES, default = 'pedestal')
114 name = models.CharField(max_length = 15, choices = DEV_TYPES, default = 'pedestal')
115 sequence = models.PositiveSmallIntegerField(default=55)
115 sequence = models.PositiveSmallIntegerField(default=55)
116 description = models.TextField(blank=True, null=True)
116 description = models.TextField(blank=True, null=True)
117
117
118 class Meta:
118 class Meta:
119 db_table = 'db_device_types'
119 db_table = 'db_device_types'
120
120
121 def __str__(self):
121 def __str__(self):
122 return u'%s' % self.name.title()
122 return u'%s' % self.name.title()
123
123
124 class Device(models.Model):
124 class Device(models.Model):
125
125
126 device_type = models.ForeignKey('DeviceType', on_delete=models.CASCADE)
126 device_type = models.ForeignKey('DeviceType', on_delete=models.CASCADE)
127 location = models.ForeignKey('Location', on_delete=models.CASCADE)
127 location = models.ForeignKey('Location', on_delete=models.CASCADE)
128 ip_address = models.GenericIPAddressField(verbose_name = 'IP address', protocol='IPv4', default='0.0.0.0')
128 ip_address = models.GenericIPAddressField(verbose_name = 'IP address', protocol='IPv4', default='0.0.0.0')
129 port_address = models.PositiveSmallIntegerField(default=2000)
129 port_address = models.PositiveSmallIntegerField(default=2000)
130 description = models.TextField(blank=True, null=True)
130 description = models.TextField(blank=True, null=True)
131 status = models.PositiveSmallIntegerField(default=4, choices=DEV_STATES)
131 status = models.PositiveSmallIntegerField(default=4, choices=DEV_STATES)
132 conf_active = models.PositiveIntegerField(default=0, verbose_name='Current configuration')
132 conf_active = models.PositiveIntegerField(default=0, verbose_name='Current configuration')
133
133
134 class Meta:
134 class Meta:
135 db_table = 'db_devices'
135 db_table = 'db_devices'
136
136
137 def __str__(self):
137 def __str__(self):
138 ret = self.device_type
138 ret = self.device_type
139 #ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
139 #ret = u'{} [{}]'.format(self.device_type.name.upper(), self.location.name)
140 return str(ret)
140 return str(ret)
141
141
142 @property
142 @property
143 def name(self):
143 def name(self):
144 return str(self)
144 return str(self)
145
145
146 def get_status(self):
146 def get_status(self):
147 return self.status
147 return self.status
148
148
149 @property
149 @property
150 def status_color(self):
150 def status_color(self):
151 color = 'muted'
151 color = 'muted'
152 if self.status == 0:
152 if self.status == 0:
153 color = "danger"
153 color = "danger"
154 elif self.status == 1:
154 elif self.status == 1:
155 color = "warning"
155 color = "primary"
156 elif self.status == 2:
156 elif self.status == 2:
157 color = "info"
157 color = "info"
158 elif self.status == 3:
158 elif self.status == 3:
159 color = "success"
159 color = "success"
160
160
161 return color
161 return color
162
162
163 def url(self, path=None):
163 def url(self, path=None):
164
164
165 if path:
165 if path:
166 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
166 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
167 else:
167 else:
168 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
168 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
169
169
170 def get_absolute_url(self):
170 def get_absolute_url(self):
171 return reverse('url_device', args=[str(self.id)])
171 return reverse('url_device', args=[str(self.id)])
172
172
173 def get_absolute_url_edit(self):
173 def get_absolute_url_edit(self):
174 return reverse('url_edit_device', args=[str(self.id)])
174 return reverse('url_edit_device', args=[str(self.id)])
175
175
176 def get_absolute_url_delete(self):
176 def get_absolute_url_delete(self):
177 return reverse('url_delete_device', args=[str(self.id)])
177 return reverse('url_delete_device', args=[str(self.id)])
178
178
179 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
179 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
180
180
181 if self.device_type.name=='pedestal':
181 if self.device_type.name=='pedestal':
182 headers = {'content-type': "application/json",
182 headers = {'content-type': "application/json",
183 'cache-control': "no-cache"}
183 'cache-control': "no-cache"}
184
184
185 ip = [int(x) for x in ip_address.split('.')]
185 ip = [int(x) for x in ip_address.split('.')]
186 dns = [int(x) for x in dns.split('.')]
186 dns = [int(x) for x in dns.split('.')]
187 gateway = [int(x) for x in gateway.split('.')]
187 gateway = [int(x) for x in gateway.split('.')]
188 subnet = [int(x) for x in mask.split('.')]
188 subnet = [int(x) for x in mask.split('.')]
189
189
190 payload = {
190 payload = {
191 "ip": ip,
191 "ip": ip,
192 "dns": dns,
192 "dns": dns,
193 "gateway": gateway,
193 "gateway": gateway,
194 "subnet": subnet
194 "subnet": subnet
195 }
195 }
196
196
197 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
197 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
198 try:
198 try:
199 answer = req.json()
199 answer = req.json()
200 if answer['changeip']=='ok':
200 if answer['changeip']=='ok':
201 self.message = '25|IP succesfully changed'
201 self.message = '25|IP succesfully changed'
202 self.ip_address = ip_address
202 self.ip_address = ip_address
203 self.save()
203 self.save()
204 else:
204 else:
205 self.message = '30|An error ocuur when changing IP'
205 self.message = '30|An error ocuur when changing IP'
206 except Exception as e:
206 except Exception as e:
207 self.message = '40|{}'.format(str(e))
207 self.message = '40|{}'.format(str(e))
208 else:
208 else:
209 self.message = 'Not implemented'
209 self.message = 'Not implemented'
210 return False
210 return False
211
211
212 return True
212 return True
213
213
214
214
215 class Campaign(models.Model):
215 class Campaign(models.Model):
216
216
217 template = models.BooleanField(default=False)
217 template = models.BooleanField(default=False)
218 name = models.CharField(max_length=60, unique=True)
218 name = models.CharField(max_length=60, unique=True)
219 start_date = models.DateTimeField(blank=True, null=True)
219 start_date = models.DateTimeField(blank=True, null=True)
220 end_date = models.DateTimeField(blank=True, null=True)
220 end_date = models.DateTimeField(blank=True, null=True)
221 tags = models.CharField(max_length=40, blank=True, null=True)
221 tags = models.CharField(max_length=40, blank=True, null=True)
222 description = models.TextField(blank=True, null=True)
222 description = models.TextField(blank=True, null=True)
223 experiments = models.ManyToManyField('Experiment', blank=True)
223 experiments = models.ManyToManyField('Experiment', blank=True)
224 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
224 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
225
225
226 class Meta:
226 class Meta:
227 db_table = 'db_campaigns'
227 db_table = 'db_campaigns'
228 ordering = ('name',)
228 ordering = ('name',)
229
229
230 def __str__(self):
230 def __str__(self):
231 if self.template:
231 if self.template:
232 return u'{} (template)'.format(self.name)
232 return u'{} (template)'.format(self.name)
233 else:
233 else:
234 return u'{}'.format(self.name)
234 return u'{}'.format(self.name)
235
235
236 def jsonify(self):
236 def jsonify(self):
237
237
238 data = {}
238 data = {}
239
239
240 ignored = ('template')
240 ignored = ('template')
241
241
242 for field in self._meta.fields:
242 for field in self._meta.fields:
243 if field.name in ignored:
243 if field.name in ignored:
244 continue
244 continue
245 data[field.name] = field.value_from_object(self)
245 data[field.name] = field.value_from_object(self)
246
246
247 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
247 data['start_date'] = data['start_date'].strftime('%Y-%m-%d')
248 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
248 data['end_date'] = data['end_date'].strftime('%Y-%m-%d')
249
249
250 return data
250 return data
251
251
252 def parms_to_dict(self):
252 def parms_to_dict(self):
253
253
254 params = Params({})
254 params = Params({})
255 params.add(self.jsonify(), 'campaigns')
255 params.add(self.jsonify(), 'campaigns')
256
256
257 for exp in Experiment.objects.filter(campaign = self):
257 for exp in Experiment.objects.filter(campaign = self):
258 params.add(exp.jsonify(), 'experiments')
258 params.add(exp.jsonify(), 'experiments')
259 configurations = Configuration.objects.filter(experiment=exp, type=0)
259 configurations = Configuration.objects.filter(experiment=exp, type=0)
260
260
261 for conf in configurations:
261 for conf in configurations:
262 params.add(conf.jsonify(), 'configurations')
262 params.add(conf.jsonify(), 'configurations')
263
263
264 return params.data
264 return params.data
265
265
266 def dict_to_parms(self, parms, CONF_MODELS):
266 def dict_to_parms(self, parms, CONF_MODELS):
267
267
268 experiments = Experiment.objects.filter(campaign = self)
268 experiments = Experiment.objects.filter(campaign = self)
269
269
270 if experiments:
270 if experiments:
271 for experiment in experiments:
271 for experiment in experiments:
272 experiment.delete()
272 experiment.delete()
273
273
274 for id_exp in parms['experiments']['allIds']:
274 for id_exp in parms['experiments']['allIds']:
275 exp_parms = parms['experiments']['byId'][id_exp]
275 exp_parms = parms['experiments']['byId'][id_exp]
276 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
276 dum = (datetime.now() - datetime(1970, 1, 1)).total_seconds()
277 exp = Experiment(name='{}'.format(dum))
277 exp = Experiment(name='{}'.format(dum))
278 exp.save()
278 exp.save()
279 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
279 exp.dict_to_parms(parms, CONF_MODELS, id_exp=id_exp)
280 self.experiments.add(exp)
280 self.experiments.add(exp)
281
281
282 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
282 camp_parms = parms['campaigns']['byId'][parms['campaigns']['allIds'][0]]
283
283
284 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
284 self.name = '{}-{}'.format(camp_parms['name'], datetime.now().strftime('%y%m%d'))
285 self.start_date = camp_parms['start_date']
285 self.start_date = camp_parms['start_date']
286 self.end_date = camp_parms['end_date']
286 self.end_date = camp_parms['end_date']
287 self.tags = camp_parms['tags']
287 self.tags = camp_parms['tags']
288 self.save()
288 self.save()
289
289
290 return self
290 return self
291
291
292 def get_experiments_by_radar(self, radar=None):
292 def get_experiments_by_radar(self, radar=None):
293
293
294 ret = []
294 ret = []
295 if radar:
295 if radar:
296 locations = Location.objects.filter(pk=radar)
296 locations = Location.objects.filter(pk=radar)
297 else:
297 else:
298 locations = set([e.location for e in self.experiments.all()])
298 locations = set([e.location for e in self.experiments.all()])
299
299
300 for loc in locations:
300 for loc in locations:
301 dum = {}
301 dum = {}
302 dum['name'] = loc.name
302 dum['name'] = loc.name
303 dum['id'] = loc.pk
303 dum['id'] = loc.pk
304 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
304 dum['experiments'] = [e for e in self.experiments.all() if e.location==loc]
305 ret.append(dum)
305 ret.append(dum)
306
306
307 return ret
307 return ret
308
308
309 def get_absolute_url(self):
309 def get_absolute_url(self):
310 return reverse('url_campaign', args=[str(self.id)])
310 return reverse('url_campaign', args=[str(self.id)])
311
311
312 def get_absolute_url_edit(self):
312 def get_absolute_url_edit(self):
313 return reverse('url_edit_campaign', args=[str(self.id)])
313 return reverse('url_edit_campaign', args=[str(self.id)])
314
314
315 def get_absolute_url_delete(self):
315 def get_absolute_url_delete(self):
316 return reverse('url_delete_campaign', args=[str(self.id)])
316 return reverse('url_delete_campaign', args=[str(self.id)])
317
317
318 def get_absolute_url_export(self):
318 def get_absolute_url_export(self):
319 return reverse('url_export_campaign', args=[str(self.id)])
319 return reverse('url_export_campaign', args=[str(self.id)])
320
320
321 def get_absolute_url_import(self):
321 def get_absolute_url_import(self):
322 return reverse('url_import_campaign', args=[str(self.id)])
322 return reverse('url_import_campaign', args=[str(self.id)])
323
323
324
324
325 class RunningExperiment(models.Model):
325 class RunningExperiment(models.Model):
326 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
326 radar = models.OneToOneField('Location', on_delete=models.CASCADE)
327 running_experiment = models.ManyToManyField('Experiment', blank = True)
327 running_experiment = models.ManyToManyField('Experiment', blank = True)
328 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
328 status = models.PositiveSmallIntegerField(default=0, choices=RADAR_STATES)
329
329
330
330
331 class Experiment(models.Model):
331 class Experiment(PolymorphicModel):
332
332
333 template = models.BooleanField(default=False)
333 template = models.BooleanField(default=False)
334 name = models.CharField(max_length=40, default='', unique=True)
334 name = models.CharField(max_length=40, default='', unique=True)
335 location = models.ForeignKey('Location', null=False, blank=False, on_delete=models.CASCADE, default=None)
335 location = models.ForeignKey('Location', null=False, blank=False, on_delete=models.CASCADE, default=None)
336 #freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
336 #freq = models.FloatField(verbose_name='Operating Freq. (MHz)', validators=[MinValueValidator(1), MaxValueValidator(10000)], default=49.9200)
337 #start_time = models.TimeField(default='00:00:00')
337 #start_time = models.TimeField(default='00:00:00')
338 #end_time = models.TimeField(default='23:59:59')
338 #end_time = models.TimeField(default='23:59:59')
339 pedestal = models.ForeignKey('pedestal.PedestalConfiguration', null=False, blank=False, on_delete=models.CASCADE, default=None, related_name = "pedestal_conf")
339 pedestal = models.ForeignKey('pedestal.PedestalConfiguration', null=False, blank=False, on_delete=models.PROTECT, default=None, related_name = "pedestal_conf")
340 generator = models.ForeignKey('Device', null=False, blank=False, on_delete=models.PROTECT, default=None, limit_choices_to={'device_type__name': 'generator'}, related_name = "generator_conf")
341 reception_rx = models.ForeignKey('usrp_rx.USRPRXConfiguration', null=False, blank=False, on_delete=models.PROTECT, default=None, related_name = "usrp_rx_CONF")
342 transmission_tx = models.ForeignKey('usrp_tx.USRPTXConfiguration', null=False, blank=False, on_delete=models.PROTECT, default=None, related_name = "usrp_tx")
340 task = models.CharField(max_length=36, default='', blank=True, null=True)
343 task = models.CharField(max_length=36, default='', blank=True, null=True)
341 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
344 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
342 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
345 author = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE)
343 hash = models.CharField(default='', max_length=64, null=True, blank=True)
346 hash = models.CharField(default='', max_length=64, null=True, blank=True)
344
347
345 class Meta:
348 class Meta:
346 db_table = 'db_experiments'
349 db_table = 'db_experiments'
347 ordering = ('template', 'name')
350 ordering = ('template', 'name')
348
351
349 def __str__(self):
352 def __str__(self):
350 if self.template:
353 if self.template:
351 return u'%s (template)' % (self.name)
354 return u'%s (template)' % (self.name)
352 else:
355 else:
353 return u'%s' % (self.name)
356 return u'%s' % (self.name)
354
357
355 def jsonify(self):
358 def jsonify(self):
356
359
357 data = {}
360 data = {}
358
361
359 ignored = ('template')
362 ignored = ('template')
360
363
361 for field in self._meta.fields:
364 for field in self._meta.fields:
362 if field.name in ignored:
365 if field.name in ignored:
363 continue
366 continue
364 data[field.name] = field.value_from_object(self)
367 data[field.name] = field.value_from_object(self)
365
368
366 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
369 data['start_time'] = data['start_time'].strftime('%H:%M:%S')
367 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
370 data['end_time'] = data['end_time'].strftime('%H:%M:%S')
368 data['location'] = self.location.name
371 data['location'] = self.location.name
369 data['configurations'] = ['{}'.format(conf.pk) for
372 data['configurations'] = ['{}'.format(conf.pk) for
370 conf in Configuration.objects.filter(experiment=self, type=0)]
373 conf in Configuration.objects.filter(experiment=self, type=0)]
371
374
372 return data
375 return data
373
376
374 @property
377 @property
375 def radar_system(self):
378 def radar_system(self):
376 return self.location
379 return self.location
377
380
378 def clone(self, **kwargs):
381 def clone(self, **kwargs):
379
382
380 confs = Configuration.objects.filter(experiment=self, type=0)
383 confs = Configuration.objects.filter(experiment=self, type=0)
381 self.pk = None
384 self.pk = None
382 self.name = '{}_{:%y%m%d}'.format(self.name, datetime.now())
385 self.name = '{}_{:%y%m%d}'.format(self.name, datetime.now())
383 for attr, value in kwargs.items():
386 for attr, value in kwargs.items():
384 setattr(self, attr, value)
387 setattr(self, attr, value)
385
388
386 self.save()
389 self.save()
387
390
388 for conf in confs:
391 for conf in confs:
389 conf.clone(experiment=self, template=False)
392 conf.clone(experiment=self, template=False)
390
393
391 return self
394 return self
392
395
393 def start(self):
396 def start(self):
394 '''
397 '''
395 Configure and start experiments's devices
398 Configure and start experiments's devices
396 '''
399 '''
397
400 #confs = []
398 confs = []
401 #allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
399 allconfs = Configuration.objects.filter(experiment=self, type = 0).order_by('-device__device_type__sequence')
402 #confs = allconfs
400 confs = allconfs
403 experiment = get_object_or_404(Experiment, pk=self.id)
404 id_p = experiment.pedestal_id
405 id_rx = experiment.reception_rx_id
406 id_tx = experiment.transmission_tx_id
407 generator_periode = 1 /experiment.transmission_tx.frequency
408 generator_delay = experiment.transmission_tx.delay_1
409 generator_width = int((experiment.transmission_tx.ipp * 2 / 300000) * 1000000) * experiment.transmission_tx.pulse_1 / 100
410 print(generator_width)
411 generator_selector = 1
401
412
402 try:
413 try:
403 for conf in confs:
414 print("Hola")
404 conf.stop_device()
415 #Configuration.objects.get(id = id_rx).start_device()
405 print("OK")
416 #Configuration.objects.get(id = id_p).start_device()
406 #conf.write_device()
417 #Configuration.objects.get(id = id_tx).start_device()
407 conf.device.conf_active = conf.pk
418 # for conf in confs:
408 conf.device.save()
419 # conf.stop_device()
409 conf.start_device()
420 # print("OK")
410 print("OK")
421 # #conf.write_device()
411 time.sleep(1)
422 # conf.device.conf_active = conf.pk
423 # conf.device.save()
424 # conf.start_device()
425 # print("OK")
426 # time.sleep(1)
412 except:
427 except:
413 return 0
428 return 0
414 return 2
429 return 2
415
430
416
431
417 def stop(self):
432 def stop(self):
418 '''
433 '''
419 Stop experiments's devices
434 Stop experiments's devices
420 PEDESTAL, PULSE GENERATOR & USRP's
435 PEDESTAL, PULSE GENERATOR & USRP's
421 '''
436 '''
422
437
423 confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
438 #confs = Configuration.objects.filter(experiment=self, type = 0).order_by('device__device_type__sequence')
439 experiment = get_object_or_404(Experiment, pk=self.id)
440 id_p = experiment.pedestal_id
441 id_rx = experiment.reception_rx_id
442 id_tx = experiment.transmission_tx_id
443
424 try:
444 try:
425 for conf in confs:
445 Configuration.objects.get(id = id_rx).stop_device()
426 conf.stop_device()
446 Configuration.objects.get(id = id_p).stop_device()
447 Configuration.objects.get(id = id_tx).stop_device()
448 # for conf in confs:
449 # conf.stop_device()
427 except:
450 except:
428 return 0
451 return 0
429 return 1
452 return 1
430
453
431 def get_status(self):
454 def get_status(self):
432
455
433 if self.status == 3:
456 if self.status == 3:
434 return
457 return
435
458
436 confs = Configuration.objects.filter(experiment=self, type=0)
459 confs = Configuration.objects.filter(experiment=self, type=0)
437
460
438 for conf in confs:
461 for conf in confs:
439 conf.status_device()
462 conf.status_device()
440
463
441 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
464 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
442
465
443 if total==2*confs.count():
466 if total==2*confs.count():
444 status = 1
467 status = 1
445 elif total == 3*confs.count():
468 elif total == 3*confs.count():
446 status = 2
469 status = 2
447 else:
470 else:
448 status = 0
471 status = 0
449
472
450 self.status = status
473 self.status = status
451 self.save()
474 self.save()
452
475
453 def status_color(self):
476 def status_color(self):
454 color = 'muted'
477 color = 'muted'
455 if self.status == 0:
478 if self.status == 0:
456 color = "danger"
479 color = "danger"
457 elif self.status == 1:
480 elif self.status == 1:
458 color = "warning"
481 color = "warning"
459 elif self.status == 2:
482 elif self.status == 2:
460 color = "success"
483 color = "success"
461 elif self.status == 3:
484 elif self.status == 3:
462 color = "info"
485 color = "info"
463
486
464 return color
487 return color
465
488
466 def parms_to_dict(self):
489 def parms_to_dict(self):
467
490
468 params = Params({})
491 params = Params({})
469 params.add(self.jsonify(), 'experiments')
492 params.add(self.jsonify(), 'experiments')
470
493
471 configurations = Configuration.objects.filter(experiment=self, type=0)
494 configurations = Configuration.objects.filter(experiment=self, type=0)
472
495
473 for conf in configurations:
496 for conf in configurations:
474 params.add(conf.jsonify(), 'configurations')
497 params.add(conf.jsonify(), 'configurations')
475
498
476 return params.data
499 return params.data
477
500
478 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
501 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
479
502
480 configurations = Configuration.objects.filter(experiment=self)
503 configurations = Configuration.objects.filter(experiment=self)
481
504
482 if id_exp is not None:
505 if id_exp is not None:
483 exp_parms = parms['experiments']['byId'][id_exp]
506 exp_parms = parms['experiments']['byId'][id_exp]
484 else:
507 else:
485 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
508 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
486
509
487 if configurations:
510 if configurations:
488 for configuration in configurations:
511 for configuration in configurations:
489 configuration.delete()
512 configuration.delete()
490
513
491 for id_conf in exp_parms['configurations']:
514 for id_conf in exp_parms['configurations']:
492 conf_parms = parms['configurations']['byId'][id_conf]
515 conf_parms = parms['configurations']['byId'][id_conf]
493 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
516 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
494 model = CONF_MODELS[conf_parms['device_type']]
517 model = CONF_MODELS[conf_parms['device_type']]
495 conf = model(
518 conf = model(
496 experiment = self,
519 experiment = self,
497 device = device,
520 device = device,
498 )
521 )
499 conf.dict_to_parms(parms, id=id_conf)
522 conf.dict_to_parms(parms, id=id_conf)
500
523
501
524
502 location, created = Location.objects.get_or_create(name=exp_parms['location'])
525 location, created = Location.objects.get_or_create(name=exp_parms['location'])
503 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
526 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
504 self.location = location
527 self.location = location
505 self.start_time = exp_parms['start_time']
528 self.start_time = exp_parms['start_time']
506 self.end_time = exp_parms['end_time']
529 self.end_time = exp_parms['end_time']
507 self.save()
530 self.save()
508
531
509 return self
532 return self
510
533
511 def get_absolute_url(self):
534 def get_absolute_url(self):
512 return reverse('url_experiment', args=[str(self.id)])
535 return reverse('url_experiment', args=[str(self.id)])
513
536
514 def get_absolute_url_edit(self):
537 def get_absolute_url_edit(self):
515 return reverse('url_edit_experiment', args=[str(self.id)])
538 return reverse('url_edit_experiment', args=[str(self.id)])
516
539
517 def get_absolute_url_delete(self):
540 def get_absolute_url_delete(self):
518 return reverse('url_delete_experiment', args=[str(self.id)])
541 return reverse('url_delete_experiment', args=[str(self.id)])
519
542
520 def get_absolute_url_import(self):
543 def get_absolute_url_import(self):
521 return reverse('url_import_experiment', args=[str(self.id)])
544 return reverse('url_import_experiment', args=[str(self.id)])
522
545
523 def get_absolute_url_export(self):
546 def get_absolute_url_export(self):
524 return reverse('url_export_experiment', args=[str(self.id)])
547 return reverse('url_export_experiment', args=[str(self.id)])
525
548
526 def get_absolute_url_start(self):
549 def get_absolute_url_start(self):
527 return reverse('url_start_experiment', args=[str(self.id)])
550 return reverse('url_start_experiment', args=[str(self.id)])
528
551
529 def get_absolute_url_stop(self):
552 def get_absolute_url_stop(self):
530 return reverse('url_stop_experiment', args=[str(self.id)])
553 return reverse('url_stop_experiment', args=[str(self.id)])
531
554
532
555
533 class Configuration(PolymorphicModel):
556 class Configuration(PolymorphicModel):
534
557
535 id = models.AutoField(primary_key=True)
558 id = models.AutoField(primary_key=True)
536 template = models.BooleanField(default=False)
559 template = models.BooleanField(default=False)
537 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
560 # name = models.CharField(verbose_name="Configuration Name", max_length=40, default='')
538 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
561 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
539 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=False, null=False)
562 label = models.CharField(verbose_name="Label", max_length=40, default='', blank=False, null=False)
540 experiment = models.ForeignKey('Experiment', verbose_name='Experiment', null=True, blank=True, on_delete=models.CASCADE)
541 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
563 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
542 created_date = models.DateTimeField(auto_now_add=True)
564 created_date = models.DateTimeField(auto_now_add=True)
543 programmed_date = models.DateTimeField(auto_now=True)
565 programmed_date = models.DateTimeField(auto_now=True)
544 parameters = models.TextField(default='{}')
566 parameters = models.TextField(default='{}')
545 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
567 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
546 hash = models.CharField(default='', max_length=64, null=True, blank=True)
568 hash = models.CharField(default='', max_length=64, null=True, blank=True)
547 message = ""
569 message = ""
548
570
549 class Meta:
571 class Meta:
550 db_table = 'db_configurations'
572 db_table = 'db_configurations'
551 ordering = ('device__device_type__name',)
573 ordering = ('device__device_type__name',)
552
574
553 def __str__(self):
575 def __str__(self):
554
576
555 ret = u'{} '.format(self.device.device_type.name.upper())
577 ret = u'{} '.format(self.device.device_type.name.upper())
556
578
557 if 'mix' in [f.name for f in self._meta.get_fields()]:
579 if 'mix' in [f.name for f in self._meta.get_fields()]:
558 if self.mix:
580 if self.mix:
559 ret = '{} MIX '.format(self.device.device_type.name.upper())
581 ret = '{} MIX '.format(self.device.device_type.name.upper())
560
582
561 if 'label' in [f.name for f in self._meta.get_fields()]:
583 if 'label' in [f.name for f in self._meta.get_fields()]:
562 ret += '{}'.format(self.label)
584 ret += '{}'.format(self.label)
563
585
564 if self.template:
586 if self.template:
565 ret += ' (template)'
587 ret += ' (template)'
566
588
567 return ret
589 return ret
568
590
569 @property
591 @property
570 def name(self):
592 def name(self):
571
593
572 return str(self)
594 return str(self)
573
595
574 def jsonify(self):
596 def jsonify(self):
575
597
576 data = {}
598 data = {}
577
599
578 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
600 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
579 'created_date', 'programmed_date', 'template', 'device',
601 'created_date', 'programmed_date', 'template', 'device',
580 'experiment')
602 'experiment', 'author')
581
603
582 for field in self._meta.fields:
604 for field in self._meta.fields:
583 if field.name in ignored:
605 if field.name in ignored:
584 continue
606 continue
585 data[field.name] = field.value_from_object(self)
607 data[field.name] = field.value_from_object(self)
586
608
587 data['device_type'] = self.device.device_type.name
609 data['device_type'] = self.device.device_type.name
588 return data
610 return data
589
611
590 def clone(self, **kwargs):
612 def clone(self, **kwargs):
591
613
592 self.pk = None
614 self.pk = None
593 self.id = None
615 self.id = None
594 for attr, value in kwargs.items():
616 for attr, value in kwargs.items():
595 setattr(self, attr, value)
617 setattr(self, attr, value)
596
618
597 self.save()
619 self.save()
598
620
599 return self
621 return self
600
622
601 def parms_to_dict(self):
623 def parms_to_dict(self):
602
624
603 params = Params({})
625 params = Params({})
604 params.add(self.jsonify(), 'configurations')
626 params.add(self.jsonify(), 'configurations')
605 return params.data
627 return params.data
606
628
607 def parms_to_text(self):
629 def parms_to_text(self):
608
630
609 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
631 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
610
632
611
633
612 def parms_to_binary(self):
634 def parms_to_binary(self):
613
635
614 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
636 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
615
637
616
638
617 def dict_to_parms(self, parameters, id=None):
639 def dict_to_parms(self, parameters, id=None):
618
640
619 params = Params(parameters)
641 params = Params(parameters)
620
642
621 if id:
643 if id:
622 data = params.get_conf(id_conf=id)
644 data = params.get_conf(id_conf=id)
623 else:
645 else:
624 data = params.get_conf(dtype=self.device.device_type.name)
646 data = params.get_conf(dtype=self.device.device_type.name)
625
647
626 for key, value in data.items():
648 for key, value in data.items():
627 if key not in ('id', 'device_type'):
649 if key not in ('id', 'device_type'):
628 setattr(self, key, value)
650 setattr(self, key, value)
629
651
630 self.save()
652 self.save()
631
653
632
654
633 def export_to_file(self, format="json"):
655 def export_to_file(self, format="json"):
634
656
635 content_type = ''
657 content_type = ''
636
658
637 if format == 'racp':
659 if format == 'racp':
638 content_type = 'text/plain'
660 content_type = 'text/plain'
639 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
661 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
640 content = self.parms_to_text(file_format = 'racp')
662 content = self.parms_to_text(file_format = 'racp')
641
663
642 if format == 'text':
664 if format == 'text':
643 content_type = 'text/plain'
665 content_type = 'text/plain'
644 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
666 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
645 content = self.parms_to_text()
667 content = self.parms_to_text()
646
668
647 if format == 'binary':
669 if format == 'binary':
648 content_type = 'application/octet-stream'
670 content_type = 'application/octet-stream'
649 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
671 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
650 content = self.parms_to_binary()
672 content = self.parms_to_binary()
651
673
652 if not content_type:
674 if not content_type:
653 content_type = 'application/json'
675 content_type = 'application/json'
654 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
676 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
655 content = json.dumps(self.parms_to_dict(), indent=2)
677 content = json.dumps(self.parms_to_dict(), indent=2)
678 print(content)
656
679
657 fields = {'content_type':content_type,
680 fields = {'content_type':content_type,
658 'filename':filename,
681 'filename':filename,
659 'content':content
682 'content':content
660 }
683 }
661
684
662 return fields
685 return fields
663
686
664 def import_from_file(self, fp):
687 def import_from_file(self, fp):
665
688
666 parms = {}
689 parms = {}
667
690
668 path, ext = os.path.splitext(fp.name)
691 path, ext = os.path.splitext(fp.name)
669
692
670 if ext == '.json':
693 if ext == '.json':
671 parms = json.load(fp)
694 parms = json.load(fp)
672
695
673 return parms
696 return parms
674
697
675 def status_device(self):
698 def status_device(self):
676
699
677 self.message = 'Function not implemented'
700 self.message = 'Function not supported'
678 return False
701 return False
679
702
680
703
681 def stop_device(self):
704 def stop_device(self):
682
705
683 self.message = 'Function not implemented'
706 self.message = 'Function not supported'
684 return False
707 return False
685
708
686
709
687 def start_device(self):
710 def start_device(self):
688
711
689 self.message = 'Function not implemented'
712 self.message = 'Function not supported'
690 return False
713 return False
691
714
692
715
693 def write_device(self):
716 def write_device(self):
694
717
695 self.message = 'Function not implemented'
718 self.message = 'Function not supported'
696 return False
719 return False
697
720
698
721
699 def read_device(self):
722 def read_device(self):
700
723
701 self.message = 'Function not implemented'
724 self.message = 'Function not supported'
702 return False
725 return False
703
726
704
727
705 def get_absolute_url(self):
728 def get_absolute_url(self):
706 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
729 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
707
730
708 def get_absolute_url_edit(self):
731 def get_absolute_url_edit(self):
709 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
732 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
710
733
711 def get_absolute_url_delete(self):
734 def get_absolute_url_delete(self):
712 return reverse('url_delete_dev_conf', args=[str(self.id)])
735 return reverse('url_delete_dev_conf', args=[str(self.id)])
713
736
714 def get_absolute_url_import(self):
737 def get_absolute_url_import(self):
715 return reverse('url_import_dev_conf', args=[str(self.id)])
738 return reverse('url_import_dev_conf', args=[str(self.id)])
716
739
717 def get_absolute_url_export(self):
740 def get_absolute_url_export(self):
718 return reverse('url_export_dev_conf', args=[str(self.id)])
741 return reverse('url_export_dev_conf', args=[str(self.id)])
719
742
720 def get_absolute_url_write(self):
743 def get_absolute_url_write(self):
721 return reverse('url_write_dev_conf', args=[str(self.id)])
744 return reverse('url_write_dev_conf', args=[str(self.id)])
722
745
723 def get_absolute_url_read(self):
746 def get_absolute_url_read(self):
724 return reverse('url_read_dev_conf', args=[str(self.id)])
747 return reverse('url_read_dev_conf', args=[str(self.id)])
725
748
726 def get_absolute_url_start(self):
749 def get_absolute_url_start(self):
727 return reverse('url_start_dev_conf', args=[str(self.id)])
750 return reverse('url_start_dev_conf', args=[str(self.id)])
728
751
729 def get_absolute_url_stop(self):
752 def get_absolute_url_stop(self):
730 return reverse('url_stop_dev_conf', args=[str(self.id)])
753 return reverse('url_stop_dev_conf', args=[str(self.id)])
731
754
732 def get_absolute_url_status(self):
755 def get_absolute_url_status(self):
733 return reverse('url_status_dev_conf', args=[str(self.id)])
756 return reverse('url_status_dev_conf', args=[str(self.id)])
@@ -1,130 +1,131
1 <!DOCTYPE html>
1 <!DOCTYPE html>
2 {% load static %}
2 {% load static %}
3 {% load bootstrap4 %}
3 {% load bootstrap4 %}
4 <html lang="en">
4 <html lang="en">
5 <head>
5 <head>
6 <meta charset="utf-8">
6 <meta charset="utf-8">
7 <title>{% block title %}Jicamarca Integrated Radar System:::::{% endblock %}</title>
7 <title>{% block title %}Jicamarca Integrated Radar System:::::{% endblock %}</title>
8 <meta name="description" content="">
8 <meta name="description" content="">
9 <meta name="author" content="">
9 <meta name="author" content="">
10 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
10 <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
11 {# bootstrap_css #}
11 {# bootstrap_css #}
12
12
13 <link href="{% static 'css/fontawesome.css' %}" rel="stylesheet">
13 <link href="{% static 'css/fontawesome.css' %}" rel="stylesheet">
14 <link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
14 <link href="{% static 'css/bootstrap.min.css' %}" rel="stylesheet">
15 <link href="{% static 'css/style.css' %}" rel="stylesheet">
15 <link href="{% static 'css/style.css' %}" rel="stylesheet">
16 <link href="{% static 'css/header.css' %}" rel="stylesheet">
16 <link href="{% static 'css/header.css' %}" rel="stylesheet">
17 <link href="{% static 'css/footer.css' %}" rel="stylesheet">
17 <link href="{% static 'css/footer.css' %}" rel="stylesheet">
18 <link rel="shortcut icon" href="{% static 'images/favicon.ico' %}" />
18 <link rel="shortcut icon" href="{% static 'images/favicon.ico' %}" />
19
19
20
20
21 <!--link href="{% static '' %}css/bootstrap-{{theme}}.min.css" media="all" rel="stylesheet"-->
21 <!--link href="{% static '' %}css/bootstrap-{{theme}}.min.css" media="all" rel="stylesheet"-->
22 <!-- <link href="{% static 'css/bootcards-desktop.min.css' %}" media="all" rel="stylesheet"> -->
22 <!-- <link href="{% static 'css/bootcards-desktop.min.css' %}" media="all" rel="stylesheet"> -->
23 <link href="{% static 'css/font-awesome.min.css' %}" media="all" rel="stylesheet"-->
23 <link href="{% static 'css/font-awesome.min.css' %}" media="all" rel="stylesheet"-->
24 <!--link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"-->
24 <!--link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"-->
25
25
26 <!-- Bootcards CSS for iOS: >
26 <!-- Bootcards CSS for iOS: >
27 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootcards/1.0.0/css/bootcards-ios.min.css"-->
27 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootcards/1.0.0/css/bootcards-ios.min.css"-->
28
28
29 <!-- Bootcards CSS for Android: >
29 <!-- Bootcards CSS for Android: >
30 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootcards/1.0.0/css/bootcards-android.min.css"-->
30 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootcards/1.0.0/css/bootcards-android.min.css"-->
31
31
32 <!-- Bootcards CSS for desktop: >
32 <!-- Bootcards CSS for desktop: >
33 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootcards/1.0.0/css/bootcards-desktop.min.css"-->
33 <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootcards/1.0.0/css/bootcards-desktop.min.css"-->
34
34
35 <style type="text/css">
35 <style type="text/css">
36 .logo {padding-top: 5px; height: 50px}
36 .logo {padding-top: 5px; height: 50px}
37 .clickable-row {cursor: pointer;}
37 .clickable-row {cursor: pointer;}
38 .col-no-padding { padding-left:0;}
38 .col-no-padding { padding-left:0;}
39 .gi-2x{font-size: 2em;}
39 .gi-2x{font-size: 2em;}
40 .gi-3x{font-size: 3em;}
40 .gi-3x{font-size: 3em;}
41 .gi-4x{font-size: 4em;}
41 .gi-4x{font-size: 4em;}
42 .gi-5x{font-size: 5em;}
42 .gi-5x{font-size: 5em;}
43 </style>
43 </style>
44 <script src="{% static 'js/jquery.min.js' %}"></script>
44 <script src="{% static 'js/jquery.min.js' %}"></script>
45 {% block extra-head %}{% endblock %}
45 {% block extra-head %}{% endblock %}
46 </head>
46 </head>
47
47
48 <body>
48 <body>
49
49
50 {% include "header_igp.html" %}
50 {% include "header_igp.html" %}
51
51
52 <div style="clear: both;"></div>
52 <div style="clear: both;"></div>
53
53
54 <div class="container">
54 <div class="container">
55 <div id="page" class="row" style="min-height:600px">
55 <div id="page" class="row" style="min-height:600px">
56
56
57 {% if no_sidebar %}
57 {% if no_sidebar %}
58 <div class="col-md-0 hidden-xs hidden-sm" role="complementary"></div>
58 <div class="col-md-0 hidden-xs hidden-sm" role="complementary"></div>
59
59
60 {% else %}
60 {% else %}
61 <div class="col-md-3 hidden-xs hidden-sm" role="complementary">
61 <div class="col-md-3 hidden-xs hidden-sm" role="complementary">
62 <br><br>
62 <br><br>
63 <div id="sidebar">
63 <div id="sidebar">
64 {% block sidebar%}
64 {% block sidebar%}
65 {% include "sidebar_devices.html" %}
65 {% include "sidebar_devices.html" %}
66 {% endblock %}
66 {% endblock %}
67 </div>
67 </div>
68 </div>
68 </div>
69 {% endif %}
69 {% endif %}
70
70
71
71
72 {% if no_sidebar %}
72 {% if no_sidebar %}
73 <div class="col-md-12 col-xs-12" role="main">
73 <div class="col-md-12 col-xs-12" role="main">
74 {% else %}
74 {% else %}
75 <div class="col-md-9 col-xs-12" role="main">
75 <div class="col-md-9 col-xs-12" role="main">
76 {% endif %}
76 {% endif %}
77
77
78 <div class="page-header">
78 <div class="page-header">
79 <h1>{% block content-title %}{% endblock %} <small>{% block content-suptitle %}{% endblock %}</small></h1>
79 <h1>{% block content-title %}{% endblock %} <small>{% block content-suptitle %}{% endblock %}</small></h1>
80 <br>
80 </div>
81 </div>
81 {% block messages %}
82 {% block messages %}
82 {% if messages %}
83 {% if messages %}
83 {% for message in messages %}
84 {% for message in messages %}
84 <div class="alert alert-{% if message.tags %}{% if 'error' in message.tags %}danger{% else %}{{ message.tags }}{% endif %}{% else %}info{% endif %} alert-dismissible" role="alert">
85 <div class="alert alert-{% if message.tags %}{% if 'error' in message.tags %}danger{% else %}{{ message.tags }}{% endif %}{% else %}info{% endif %} alert-dismissible" role="alert">
85 <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
86 <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
86 <strong>{{message.tags|title}}!</strong> {{ message }}
87 <strong>{{message.tags|title}}!</strong> {{ message }}
87 </div>
88 </div>
88 {% endfor %}
89 {% endfor %}
89 {% endif %}
90 {% endif %}
90 {% endblock %}
91 {% endblock %}
91
92
92 {% block content %}
93 {% block content %}
93 {% endblock %}
94 {% endblock %}
94
95
95 </div>
96 </div>
96
97
97
98
98 </div><!--/row-->
99 </div><!--/row-->
99 </div> <!-- container -->
100 </div> <!-- container -->
100
101
101 {% include "footer_igp.html" %}
102 {% include "footer_igp.html" %}
102
103
103
104
104
105
105 <!-- This part put block modal which is used to change parameters of my plot -->
106 <!-- This part put block modal which is used to change parameters of my plot -->
106 {% block modal %}{% endblock modal %}
107 {% block modal %}{% endblock modal %}
107 {% block debug %}<div class="row">{{debug}}</div>{% endblock debug %}
108 {% block debug %}<div class="row">{{debug}}</div>{% endblock debug %}
108 <!-- Optional JavaScript -->
109 <!-- Optional JavaScript -->
109 <!-- jQuery first, then Popper.js, then Bootstrap JS -->
110 <!-- jQuery first, then Popper.js, then Bootstrap JS -->
110 {# % bootstrap_javascript jquery='slim' % #}
111 {# % bootstrap_javascript jquery='slim' % #}
111 <script src="{% static 'js/jquery-3.3.1.slim.min.js' %}"></script>
112 <script src="{% static 'js/jquery-3.3.1.slim.min.js' %}"></script>
112 <script src="{% static 'js/popper.min.js' %}"></script>
113 <script src="{% static 'js/popper.min.js' %}"></script>
113 <script src="{% static 'js/moment.min.js' %}"></script>
114 <script src="{% static 'js/moment.min.js' %}"></script>
114 <script src="{% static 'js/bootstrap.min.js' %}"></script>
115 <script src="{% static 'js/bootstrap.min.js' %}"></script>
115 <script src="{% static 'js/plotly-latest.min.js' %}"></script>
116 <script src="{% static 'js/plotly-latest.min.js' %}"></script>
116
117
117 <!-- Here we put the script from the type of plot that we recibe -->
118 <!-- Here we put the script from the type of plot that we recibe -->
118 <script>
119 <script>
119 $("#menu-toggle").click(function (e) {
120 $("#menu-toggle").click(function (e) {
120 e.preventDefault();
121 e.preventDefault();
121 $("#wrapper").toggleClass("toggled");
122 $("#wrapper").toggleClass("toggled");
122 });
123 });
123 </script>
124 </script>
124 {% block extra-js %}
125 {% block extra-js %}
125 {% endblock%}
126 {% endblock%}
126
127
127
128
128
129
129 </body>
130 </body>
130 </html>
131 </html>
@@ -1,42 +1,56
1 {% extends "base.html" %}
1 {% extends "base.html" %}
2 {% load bootstrap4 %}
2 {% load bootstrap4 %}
3 {% load static %}
3 {% load static %}
4 {% load main_tags %}
4 {% load main_tags %}
5
5
6 {% block content-title %}{{title}}{% endblock %}
6 {% block content-title %}{{title}}{% endblock %}
7 {% block content-suptitle %}{{suptitle}}{% endblock %}
7 {% block content-suptitle %}{{suptitle}}{% endblock %}
8
8
9 {% block content %}
9 {% block content %}
10 {% if form.is_multipart %}
10 {% if form.is_multipart %}
11 <form class="form" enctype="multipart/form-data" method="post" action="{{action}}">
11 <form class="form" enctype="multipart/form-data" method="post" action="{{action}}">
12 {% else %}
12 {% else %}
13 <form class="form" method="post" action="{{action}}">
13 <form class="form" method="post" action="{{action}}">
14 {% endif %}
14 {% endif %}
15 {% csrf_token %}
15 {% csrf_token %}
16
16
17 {% if device_dds == 'dds_rest' %}
17 {% if device_dds == 'dds_rest' %}
18 {% block dds_rest%}
18 {% block dds_rest%}
19 {% endblock %}
19 {% endblock %}
20 {% else %}
20 {% else %}
21 {% bootstrap_form form layout='horizontal' size='medium' %}
21 {% bootstrap_form form layout='horizontal' size='medium' %}
22 {% if form_pedestal %}
23 <br>
24 <h1>Pedestal</h1>
25 <br>
26 {% bootstrap_form form_pedestal layout='horizontal' size='medium' %}
27 <br>
28 <h1>RX</h1>
29 <br>
30 {% bootstrap_form form_rx layout='horizontal' size='medium' %}
31 <br>
32 <h1>TX</h1>
33 <br>
34 {% bootstrap_form form_tx layout='horizontal' size='medium' %}
35 {% endif %}
22 {% endif %}
36 {% endif %}
23
37
24 <div style="clear: both;"></div>
38 <div style="clear: both;"></div>
25 <br>
39 <br>
26 {% if extra_button %}
40 {% if extra_button %}
27 <div class="pull-left">
41 <div class="pull-left">
28 <button type="button" class="btn btn-primary" id="bt_{{extra_button}}">{{extra_button}}</button>
42 <button type="button" class="btn btn-primary" id="bt_{{extra_button}}">{{extra_button}}</button>
29 </div>
43 </div>
30 {% endif %}
44 {% endif %}
31 {% if button %}
45 {% if button %}
32 <div class="pull-right">
46 <div class="pull-right">
33 <button type="button" class="btn btn-primary" onclick="{% if previous %}window.location.replace('{{ previous }}');{% else %}history.go(-1);{% endif %}">{% if cancel %}{{cancel}}{% else %}Cancel{% endif %}</button>
47 <button type="button" class="btn btn-primary" onclick="{% if previous %}window.location.replace('{{ previous }}');{% else %}history.go(-1);{% endif %}">{% if cancel %}{{cancel}}{% else %}Cancel{% endif %}</button>
34 <button type="submit" class="btn btn-primary">{{button}}</button>
48 <button type="submit" class="btn btn-primary">{{button}}</button>
35 </div>
49 </div>
36 {% endif %}
50 {% endif %}
37 </form>
51 </form>
38 {% endblock %}
52 {% endblock %}
39
53
40 {% block sidebar%}
54 {% block sidebar%}
41 {% include "sidebar_devices.html" %}
55 {% include "sidebar_devices.html" %}
42 {% endblock %}
56 {% endblock %}
@@ -1,45 +1,46
1 {% extends "base_edit.html" %}
1 {% extends "base_edit.html" %}
2 {% load bootstrap4 %}
2 {% load bootstrap4 %}
3 {% load static %}
3 {% load static %}
4 {% load main_tags %}
4 {% load main_tags %}
5 {% block extra-head %}
5 {% block extra-head %}
6 <link href="{% static 'css/bootstrap-datetimepicker.min.css' %}" media="screen" rel="stylesheet">
6 <link href="{% static 'css/bootstrap-datetimepicker.min.css' %}" media="screen" rel="stylesheet">
7 {% endblock %}
7 {% endblock %}
8
8
9 {% block extra-js%}
9 {% block extra-js%}
10
10 <script src="{% static 'js/bootstrap-datetimepicker.min.js' %}"></script>
11 <script src="{% static 'js/bootstrap-datetimepicker.min.js' %}"></script>
11 <script type="text/javascript">
12 <script type="text/javascript">
12
13
13 $('.input-group.time').datetimepicker({
14 $('.input-group.time').datetimepicker({
14 format: 'HH:mm:ss',
15 format: 'HH:mm:ss',
15 icons: {
16 icons: {
16 time: 'far fa-clock',
17 time: 'far fa-clock',
17 date: 'far fa-calendar-alt',
18 date: 'far fa-calendar-alt',
18 up: 'fas fa-arrow-up',
19 up: 'fas fa-arrow-up',
19 down: 'fas fa-arrow-down',
20 down: 'fas fa-arrow-down',
20 previous: 'fas fa-chevron-left',
21 previous: 'fas fa-chevron-left',
21 next: 'fas fa-chevron-right',
22 next: 'fas fa-chevron-right',
22 today: 'far fa-calendar-check',
23 today: 'far fa-calendar-check',
23 clear: 'far fa-trash-alt',
24 clear: 'far fa-trash-alt',
24 close: 'fas fa-times'
25 close: 'fas fa-times'
25 }
26 }
26 });
27 });
27
28
28 $('#id_create_from').change(function() {
29 $('#id_create_from').change(function() {
29 var url = "{% url 'url_add_experiment' %}";
30 var url = "{% url 'url_add_experiment' %}";
30 if ($(this).val()=="2"){
31 if ($(this).val()=="2"){
31 document.location = url+"?template=0";
32 document.location = url+"?template=0";
32 }else if ($(this).val()=="1"){
33 }else if ($(this).val()=="1"){
33 document.location = url+"?blank=0";
34 document.location = url+"?blank=0";
34 }else{
35 }else{
35 document.location = url;
36 document.location = url;
36 }
37 }
37 });
38 });
38
39
39 $('#id_choose_template').change(function() {
40 $('#id_choose_template').change(function() {
40 var url = "{% url 'url_add_experiment' %}";
41 var url = "{% url 'url_add_experiment' %}";
41 document.location = url+"?template="+$(this).val();
42 document.location = url+"?template="+$(this).val();
42 });
43 });
43
44
44 </script>
45 </script>
45 {% endblock %}
46 {% endblock %}
@@ -1,1918 +1,1940
1 import ast
1 import ast
2 import json
2 import json
3 import hashlib
3 import hashlib
4 from datetime import datetime, timedelta
4 from datetime import datetime, timedelta
5
5
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
6 from django.shortcuts import render, redirect, get_object_or_404, HttpResponse
7 from django.utils.safestring import mark_safe
7 from django.utils.safestring import mark_safe
8 from django.http import HttpResponseRedirect
8 from django.http import HttpResponseRedirect
9 from django.urls import reverse
9 from django.urls import reverse
10 from django.db.models import Q
10 from django.db.models import Q
11 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
11 from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
12 from django.contrib import messages
12 from django.contrib import messages
13 from django.http.request import QueryDict
13 from django.http.request import QueryDict
14 from django.contrib.auth.decorators import login_required, user_passes_test
14 from django.contrib.auth.decorators import login_required, user_passes_test
15
15
16 from django.utils.timezone import is_aware
16 from django.utils.timezone import is_aware
17
17
18 try:
18 try:
19 from urllib.parse import urlencode
19 from urllib.parse import urlencode
20 except ImportError:
20 except ImportError:
21 from urllib import urlencode
21 from urllib import urlencode
22
22
23 from .forms import CampaignForm, ExperimentForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
23 from .forms import CampaignForm, ExperimentForm, ExperimentEditionForm, DeviceForm, ConfigurationForm, LocationForm, UploadFileForm, DownloadFileForm, OperationForm, NewForm
24 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
24 from .forms import OperationSearchForm, FilterForm, ChangeIpForm
25
25
26 from apps.pedestal.forms import PedestalConfigurationForm
26 from apps.pedestal.forms import PedestalConfigurationForm, PedestalEditionForm
27 from apps.pedestal_dev.forms import PedestalDevConfigurationForm
27 from apps.pedestal_dev.forms import PedestalDevConfigurationForm
28 from apps.generator.forms import GeneratorConfigurationForm
28 from apps.generator.forms import GeneratorConfigurationForm
29 from apps.usrp_rx.forms import USRPRXConfigurationForm
29 from apps.usrp_rx.forms import USRPRXConfigurationForm, USRPRXEditionForm
30 from apps.usrp_tx.forms import USRPTXConfigurationForm
30 from apps.usrp_tx.forms import USRPTXConfigurationForm, USRPTXEditionForm
31 from .utils import Params
31 from .utils import Params
32
32
33 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment, DEV_STATES
33 from .models import Campaign, Experiment, Device, Configuration, Location, RunningExperiment, DEV_STATES
34 from apps.pedestal.models import PedestalConfiguration
34 from apps.pedestal.models import PedestalConfiguration
35 from apps.pedestal_dev.models import PedestalDevConfiguration
35 from apps.pedestal_dev.models import PedestalDevConfiguration
36 from apps.generator.models import GeneratorConfiguration
36 from apps.generator.models import GeneratorConfiguration
37 from apps.usrp_rx.models import USRPRXConfiguration
37 from apps.usrp_rx.models import USRPRXConfiguration
38 from apps.usrp_tx.models import USRPTXConfiguration
38 from apps.usrp_tx.models import USRPTXConfiguration
39
39
40
40
41 #comentario test
41 #comentario test
42 CONF_FORMS = {
42 CONF_FORMS = {
43 'pedestal': PedestalConfigurationForm,
43 'pedestal': PedestalConfigurationForm,
44 'pedestal_dev': PedestalDevConfigurationForm,
44 'pedestal_dev': PedestalDevConfigurationForm,
45 'generator': GeneratorConfigurationForm,
45 'generator': GeneratorConfigurationForm,
46 'usrp_rx': USRPRXConfigurationForm,
46 'usrp_rx': USRPRXConfigurationForm,
47 'usrp_tx': USRPTXConfigurationForm,
47 'usrp_tx': USRPTXConfigurationForm,
48 }
48 }
49
49
50 CONF_MODELS = {
50 CONF_MODELS = {
51 'pedestal': PedestalConfiguration,
51 'pedestal': PedestalConfiguration,
52 'pedestal_dev': PedestalDevConfiguration,
52 'pedestal_dev': PedestalDevConfiguration,
53 'generator': GeneratorConfiguration,
53 'generator': GeneratorConfiguration,
54 'usrp_rx': USRPRXConfiguration,
54 'usrp_rx': USRPRXConfiguration,
55 'usrp_tx': USRPTXConfiguration,
55 'usrp_tx': USRPTXConfiguration,
56 }
56 }
57
57
58 MIX_MODES = {
58 MIX_MODES = {
59 '0': 'P',
59 '0': 'P',
60 '1': 'S',
60 '1': 'S',
61 }
61 }
62
62
63 MIX_OPERATIONS = {
63 MIX_OPERATIONS = {
64 '0': 'OR',
64 '0': 'OR',
65 '1': 'XOR',
65 '1': 'XOR',
66 '2': 'AND',
66 '2': 'AND',
67 '3': 'NAND',
67 '3': 'NAND',
68 }
68 }
69
69
70
70
71 def is_developer(user):
71 def is_developer(user):
72
72
73 groups = [str(g.name) for g in user.groups.all()]
73 groups = [str(g.name) for g in user.groups.all()]
74 return 'Developer' in groups or user.is_staff
74 return 'Developer' in groups or user.is_staff
75
75
76
76
77 def is_operator(user):
77 def is_operator(user):
78
78
79 groups = [str(g.name) for g in user.groups.all()]
79 groups = [str(g.name) for g in user.groups.all()]
80 return 'Operator' in groups or user.is_staff
80 return 'Operator' in groups or user.is_staff
81
81
82
82
83 def has_been_modified(model):
83 def has_been_modified(model):
84
84
85 prev_hash = model.hash
85 prev_hash = model.hash
86 new_hash = hashlib.sha256(str(model.parms_to_dict).encode()).hexdigest()
86 new_hash = hashlib.sha256(str(model.parms_to_dict).encode()).hexdigest()
87 if prev_hash != new_hash:
87 if prev_hash != new_hash:
88 model.hash = new_hash
88 model.hash = new_hash
89 model.save()
89 model.save()
90 return True
90 return True
91 return False
91 return False
92
92
93
93
94 def index(request):
94 def index(request):
95 kwargs = {'no_sidebar': True}
95 kwargs = {'no_sidebar': True}
96
96
97 return render(request, 'index.html', kwargs)
97 return render(request, 'index.html', kwargs)
98
98
99
99
100 def locations(request):
100 def locations(request):
101
101
102 page = request.GET.get('page')
102 page = request.GET.get('page')
103 order = ('name',)
103 order = ('name',)
104
104
105 kwargs = get_paginator(Location, page, order)
105 kwargs = get_paginator(Location, page, order)
106
106
107 kwargs['keys'] = ['name', 'description']
107 kwargs['keys'] = ['name', 'description']
108 kwargs['title'] = 'Radar System'
108 kwargs['title'] = 'Radar System'
109 kwargs['suptitle'] = 'List'
109 kwargs['suptitle'] = 'List'
110 kwargs['no_sidebar'] = True
110 kwargs['no_sidebar'] = True
111
111
112 return render(request, 'base_list.html', kwargs)
112 return render(request, 'base_list.html', kwargs)
113
113
114
114
115 def location(request, id_loc):
115 def location(request, id_loc):
116
116
117 location = get_object_or_404(Location, pk=id_loc)
117 location = get_object_or_404(Location, pk=id_loc)
118
118
119 kwargs = {}
119 kwargs = {}
120 kwargs['location'] = location
120 kwargs['location'] = location
121 kwargs['location_keys'] = ['name', 'description']
121 kwargs['location_keys'] = ['name', 'description']
122
122
123 kwargs['title'] = 'Location'
123 kwargs['title'] = 'Location'
124 kwargs['suptitle'] = 'Details'
124 kwargs['suptitle'] = 'Details'
125
125
126 return render(request, 'location.html', kwargs)
126 return render(request, 'location.html', kwargs)
127
127
128
128
129 @login_required
129 @login_required
130 def location_new(request):
130 def location_new(request):
131
131
132 if request.method == 'GET':
132 if request.method == 'GET':
133 form = LocationForm()
133 form = LocationForm()
134
134
135 if request.method == 'POST':
135 if request.method == 'POST':
136 form = LocationForm(request.POST)
136 form = LocationForm(request.POST)
137
137
138 if form.is_valid():
138 if form.is_valid():
139 form.save()
139 form.save()
140 return redirect('url_locations')
140 return redirect('url_locations')
141
141
142 kwargs = {}
142 kwargs = {}
143 kwargs['form'] = form
143 kwargs['form'] = form
144 kwargs['title'] = 'Radar System'
144 kwargs['title'] = 'Radar System'
145 kwargs['suptitle'] = 'New'
145 kwargs['suptitle'] = 'New'
146 kwargs['button'] = 'Create'
146 kwargs['button'] = 'Create'
147
147
148 return render(request, 'base_edit.html', kwargs)
148 return render(request, 'base_edit.html', kwargs)
149
149
150
150
151 @login_required
151 @login_required
152 def location_edit(request, id_loc):
152 def location_edit(request, id_loc):
153
153
154 location = get_object_or_404(Location, pk=id_loc)
154 location = get_object_or_404(Location, pk=id_loc)
155
155
156 if request.method == 'GET':
156 if request.method == 'GET':
157 form = LocationForm(instance=location)
157 form = LocationForm(instance=location)
158
158
159 if request.method == 'POST':
159 if request.method == 'POST':
160 form = LocationForm(request.POST, instance=location)
160 form = LocationForm(request.POST, instance=location)
161
161
162 if form.is_valid():
162 if form.is_valid():
163 form.save()
163 form.save()
164 return redirect('url_locations')
164 return redirect('url_locations')
165
165
166 kwargs = {}
166 kwargs = {}
167 kwargs['form'] = form
167 kwargs['form'] = form
168 kwargs['title'] = 'Location'
168 kwargs['title'] = 'Location'
169 kwargs['suptitle'] = 'Edit'
169 kwargs['suptitle'] = 'Edit'
170 kwargs['button'] = 'Update'
170 kwargs['button'] = 'Update'
171
171
172 return render(request, 'base_edit.html', kwargs)
172 return render(request, 'base_edit.html', kwargs)
173
173
174
174
175 @login_required
175 @login_required
176 def location_delete(request, id_loc):
176 def location_delete(request, id_loc):
177
177
178 location = get_object_or_404(Location, pk=id_loc)
178 location = get_object_or_404(Location, pk=id_loc)
179
179
180 if request.method == 'POST':
180 if request.method == 'POST':
181
181
182 if is_developer(request.user):
182 if is_developer(request.user):
183 location.delete()
183 location.delete()
184 return redirect('url_locations')
184 return redirect('url_locations')
185
185
186 messages.error(request, 'Not enough permission to delete this object')
186 messages.error(request, 'Not enough permission to delete this object')
187 return redirect(location.get_absolute_url())
187 return redirect(location.get_absolute_url())
188
188
189 kwargs = {
189 kwargs = {
190 'title': 'Delete',
190 'title': 'Delete',
191 'suptitle': 'Location',
191 'suptitle': 'Location',
192 'object': location,
192 'object': location,
193 'delete': True
193 'delete': True
194 }
194 }
195
195
196 return render(request, 'confirm.html', kwargs)
196 return render(request, 'confirm.html', kwargs)
197
197
198
198
199 def devices(request):
199 def devices(request):
200
200
201 page = request.GET.get('page')
201 page = request.GET.get('page')
202 order = ('location', 'device_type')
202 order = ('location', 'device_type')
203
203
204 filters = request.GET.copy()
204 filters = request.GET.copy()
205 kwargs = get_paginator(Device, page, order, filters)
205 kwargs = get_paginator(Device, page, order, filters)
206 form = FilterForm(initial=request.GET, extra_fields=['tags'])
206 form = FilterForm(initial=request.GET, extra_fields=['tags'])
207
207
208 kwargs['keys'] = ['device_type', 'location',
208 kwargs['keys'] = ['device_type', 'location',
209 'ip_address', 'port_address', 'actions']
209 'ip_address', 'port_address', 'actions']
210 kwargs['title'] = 'Device'
210 kwargs['title'] = 'Device'
211 kwargs['suptitle'] = 'List'
211 kwargs['suptitle'] = 'List'
212 kwargs['no_sidebar'] = True
212 kwargs['no_sidebar'] = True
213 kwargs['form'] = form
213 kwargs['form'] = form
214 kwargs['add_url'] = reverse('url_add_device')
214 kwargs['add_url'] = reverse('url_add_device')
215 filters.pop('page', None)
215 filters.pop('page', None)
216 kwargs['q'] = urlencode(filters)
216 kwargs['q'] = urlencode(filters)
217 kwargs['menu_devices'] = 'active'
217 kwargs['menu_devices'] = 'active'
218 return render(request, 'base_list.html', kwargs)
218 return render(request, 'base_list.html', kwargs)
219
219
220
220
221 def device(request, id_dev):
221 def device(request, id_dev):
222
222
223 device = get_object_or_404(Device, pk=id_dev)
223 device = get_object_or_404(Device, pk=id_dev)
224
224
225 kwargs = {}
225 kwargs = {}
226 kwargs['device'] = device
226 kwargs['device'] = device
227 kwargs['device_keys'] = ['device_type',
227 kwargs['device_keys'] = ['device_type',
228 'ip_address', 'port_address', 'description']
228 'ip_address', 'port_address', 'description']
229
229
230 kwargs['title'] = 'Device'
230 kwargs['title'] = 'Device'
231 kwargs['suptitle'] = 'Details'
231 kwargs['suptitle'] = 'Details'
232 kwargs['menu_devices'] = 'active'
232 kwargs['menu_devices'] = 'active'
233
233
234 return render(request, 'device.html', kwargs)
234 return render(request, 'device.html', kwargs)
235
235
236
236
237 @login_required
237 @login_required
238 def device_new(request):
238 def device_new(request):
239
239
240 if request.method == 'GET':
240 if request.method == 'GET':
241 form = DeviceForm()
241 form = DeviceForm()
242
242
243 if request.method == 'POST':
243 if request.method == 'POST':
244 form = DeviceForm(request.POST)
244 form = DeviceForm(request.POST)
245
245
246 if form.is_valid():
246 if form.is_valid():
247 form.save()
247 form.save()
248 return redirect('url_devices')
248 return redirect('url_devices')
249
249
250 kwargs = {}
250 kwargs = {}
251 kwargs['form'] = form
251 kwargs['form'] = form
252 kwargs['title'] = 'Device'
252 kwargs['title'] = 'Device'
253 kwargs['suptitle'] = 'New'
253 kwargs['suptitle'] = 'New'
254 kwargs['button'] = 'Create'
254 kwargs['button'] = 'Create'
255 kwargs['menu_devices'] = 'active'
255 kwargs['menu_devices'] = 'active'
256
256
257 return render(request, 'base_edit.html', kwargs)
257 return render(request, 'base_edit.html', kwargs)
258
258
259
259
260 @login_required
260 @login_required
261 def device_edit(request, id_dev):
261 def device_edit(request, id_dev):
262
262
263 device = get_object_or_404(Device, pk=id_dev)
263 device = get_object_or_404(Device, pk=id_dev)
264
264
265 if request.method == 'GET':
265 if request.method == 'GET':
266 form = DeviceForm(instance=device)
266 form = DeviceForm(instance=device)
267
267
268 if request.method == 'POST':
268 if request.method == 'POST':
269 form = DeviceForm(request.POST, instance=device)
269 form = DeviceForm(request.POST, instance=device)
270
270
271 if form.is_valid():
271 if form.is_valid():
272 form.save()
272 form.save()
273 return redirect(device.get_absolute_url())
273 return redirect(device.get_absolute_url())
274
274
275 kwargs = {}
275 kwargs = {}
276 kwargs['form'] = form
276 kwargs['form'] = form
277 kwargs['title'] = 'Device'
277 kwargs['title'] = 'Device'
278 kwargs['suptitle'] = 'Edit'
278 kwargs['suptitle'] = 'Edit'
279 kwargs['button'] = 'Update'
279 kwargs['button'] = 'Update'
280 kwargs['menu_devices'] = 'active'
280 kwargs['menu_devices'] = 'active'
281
281
282 return render(request, 'base_edit.html', kwargs)
282 return render(request, 'base_edit.html', kwargs)
283
283
284
284
285 @login_required
285 @login_required
286 def device_delete(request, id_dev):
286 def device_delete(request, id_dev):
287
287
288 device = get_object_or_404(Device, pk=id_dev)
288 device = get_object_or_404(Device, pk=id_dev)
289
289
290 if request.method == 'POST':
290 if request.method == 'POST':
291
291
292 if is_developer(request.user):
292 if is_developer(request.user):
293 device.delete()
293 device.delete()
294 return redirect('url_devices')
294 return redirect('url_devices')
295
295
296 messages.error(request, 'Not enough permission to delete this object')
296 messages.error(request, 'Not enough permission to delete this object')
297 return redirect(device.get_absolute_url())
297 return redirect(device.get_absolute_url())
298
298
299 kwargs = {
299 kwargs = {
300 'title': 'Delete',
300 'title': 'Delete',
301 'suptitle': 'Device',
301 'suptitle': 'Device',
302 'object': device,
302 'object': device,
303 'delete': True
303 'delete': True
304 }
304 }
305 kwargs['menu_devices'] = 'active'
305 kwargs['menu_devices'] = 'active'
306
306
307 return render(request, 'confirm.html', kwargs)
307 return render(request, 'confirm.html', kwargs)
308
308
309
309
310 @login_required
310 @login_required
311 def device_change_ip(request, id_dev):
311 def device_change_ip(request, id_dev):
312
312
313 device = get_object_or_404(Device, pk=id_dev)
313 device = get_object_or_404(Device, pk=id_dev)
314
314
315 if request.method == 'POST':
315 if request.method == 'POST':
316
316
317 if is_developer(request.user):
317 if is_developer(request.user):
318 device.change_ip(**request.POST.dict())
318 device.change_ip(**request.POST.dict())
319 level, message = device.message.split('|')
319 level, message = device.message.split('|')
320 messages.add_message(request, level, message)
320 messages.add_message(request, level, message)
321 else:
321 else:
322 messages.error(
322 messages.error(
323 request, 'Not enough permission to delete this object')
323 request, 'Not enough permission to delete this object')
324 return redirect(device.get_absolute_url())
324 return redirect(device.get_absolute_url())
325
325
326 kwargs = {
326 kwargs = {
327 'title': 'Device',
327 'title': 'Device',
328 'suptitle': 'Change IP',
328 'suptitle': 'Change IP',
329 'object': device,
329 'object': device,
330 'previous': device.get_absolute_url(),
330 'previous': device.get_absolute_url(),
331 'form': ChangeIpForm(initial={'ip_address': device.ip_address}),
331 'form': ChangeIpForm(initial={'ip_address': device.ip_address}),
332 'message': ' ',
332 'message': ' ',
333 }
333 }
334 kwargs['menu_devices'] = 'active'
334 kwargs['menu_devices'] = 'active'
335
335
336 return render(request, 'confirm.html', kwargs)
336 return render(request, 'confirm.html', kwargs)
337
337
338
338
339 def campaigns(request):
339 def campaigns(request):
340
340
341 page = request.GET.get('page')
341 page = request.GET.get('page')
342 order = ('-start_date',)
342 order = ('-start_date',)
343 filters = request.GET.copy()
343 filters = request.GET.copy()
344
344
345 kwargs = get_paginator(Campaign, page, order, filters)
345 kwargs = get_paginator(Campaign, page, order, filters)
346
346
347 form = FilterForm(initial=request.GET, extra_fields=[
347 form = FilterForm(initial=request.GET, extra_fields=[
348 'range_date', 'tags', 'template'])
348 'range_date', 'tags', 'template'])
349 kwargs['keys'] = ['name', 'start_date', 'end_date', 'actions']
349 kwargs['keys'] = ['name', 'start_date', 'end_date', 'actions']
350 kwargs['title'] = 'Campaign'
350 kwargs['title'] = 'Campaign'
351 kwargs['suptitle'] = 'List'
351 kwargs['suptitle'] = 'List'
352 kwargs['no_sidebar'] = True
352 kwargs['no_sidebar'] = True
353 kwargs['form'] = form
353 kwargs['form'] = form
354 kwargs['add_url'] = reverse('url_add_campaign')
354 kwargs['add_url'] = reverse('url_add_campaign')
355 filters.pop('page', None)
355 filters.pop('page', None)
356 kwargs['q'] = urlencode(filters)
356 kwargs['q'] = urlencode(filters)
357 kwargs['menu_campaigns'] = 'active'
357 kwargs['menu_campaigns'] = 'active'
358
358
359 return render(request, 'base_list.html', kwargs)
359 return render(request, 'base_list.html', kwargs)
360
360
361
361
362 def campaign(request, id_camp):
362 def campaign(request, id_camp):
363
363
364 campaign = get_object_or_404(Campaign, pk=id_camp)
364 campaign = get_object_or_404(Campaign, pk=id_camp)
365 experiments = Experiment.objects.filter(campaign=campaign)
365 experiments = Experiment.objects.filter(campaign=campaign)
366
366
367 form = CampaignForm(instance=campaign)
367 form = CampaignForm(instance=campaign)
368
368
369 kwargs = {}
369 kwargs = {}
370 kwargs['campaign'] = campaign
370 kwargs['campaign'] = campaign
371 kwargs['campaign_keys'] = ['template', 'name',
371 kwargs['campaign_keys'] = ['template', 'name',
372 'start_date', 'end_date', 'tags', 'description']
372 'start_date', 'end_date', 'tags', 'description']
373
373
374 kwargs['experiments'] = experiments
374 kwargs['experiments'] = experiments
375 kwargs['experiment_keys'] = [
375 kwargs['experiment_keys'] = [
376 'name', 'radar_system', 'start_time', 'end_time']
376 'name', 'radar_system', 'start_time', 'end_time']
377
377
378 kwargs['title'] = 'Campaign'
378 kwargs['title'] = 'Campaign'
379 kwargs['suptitle'] = 'Details'
379 kwargs['suptitle'] = 'Details'
380
380
381 kwargs['form'] = form
381 kwargs['form'] = form
382 kwargs['button'] = 'Add Experiment'
382 kwargs['button'] = 'Add Experiment'
383 kwargs['menu_campaigns'] = 'active'
383 kwargs['menu_campaigns'] = 'active'
384
384
385 return render(request, 'campaign.html', kwargs)
385 return render(request, 'campaign.html', kwargs)
386
386
387
387
388 @login_required
388 @login_required
389 def campaign_new(request):
389 def campaign_new(request):
390
390
391 kwargs = {}
391 kwargs = {}
392
392
393 if request.method == 'GET':
393 if request.method == 'GET':
394
394
395 if 'template' in request.GET:
395 if 'template' in request.GET:
396 if request.GET['template'] == '0':
396 if request.GET['template'] == '0':
397 form = NewForm(initial={'create_from': 2},
397 form = NewForm(initial={'create_from': 2},
398 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
398 template_choices=Campaign.objects.filter(template=True).values_list('id', 'name'))
399 else:
399 else:
400 kwargs['button'] = 'Create'
400 kwargs['button'] = 'Create'
401 kwargs['experiments'] = Configuration.objects.filter(
401 kwargs['experiments'] = Configuration.objects.filter(
402 experiment=request.GET['template'])
402 experiment=request.GET['template'])
403 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
403 kwargs['experiment_keys'] = ['name', 'start_time', 'end_time']
404 camp = Campaign.objects.get(pk=request.GET['template'])
404 camp = Campaign.objects.get(pk=request.GET['template'])
405 form = CampaignForm(instance=camp,
405 form = CampaignForm(instance=camp,
406 initial={'name': '{}_{:%Y%m%d}'.format(camp.name, datetime.now()),
406 initial={'name': '{}_{:%Y%m%d}'.format(camp.name, datetime.now()),
407 'template': False})
407 'template': False})
408 elif 'blank' in request.GET:
408 elif 'blank' in request.GET:
409 kwargs['button'] = 'Create'
409 kwargs['button'] = 'Create'
410 form = CampaignForm()
410 form = CampaignForm()
411 else:
411 else:
412 form = NewForm()
412 form = NewForm()
413
413
414 if request.method == 'POST':
414 if request.method == 'POST':
415 kwargs['button'] = 'Create'
415 kwargs['button'] = 'Create'
416 post = request.POST.copy()
416 post = request.POST.copy()
417 experiments = []
417 experiments = []
418
418
419 for id_exp in post.getlist('experiments'):
419 for id_exp in post.getlist('experiments'):
420 exp = Experiment.objects.get(pk=id_exp)
420 exp = Experiment.objects.get(pk=id_exp)
421 new_exp = exp.clone(template=False)
421 new_exp = exp.clone(template=False)
422 experiments.append(new_exp)
422 experiments.append(new_exp)
423
423
424 post.setlist('experiments', [])
424 post.setlist('experiments', [])
425
425
426 form = CampaignForm(post)
426 form = CampaignForm(post)
427
427
428 if form.is_valid():
428 if form.is_valid():
429 campaign = form.save(commit=False)
429 campaign = form.save(commit=False)
430 campaign.author = request.user
430 campaign.author = request.user
431 for exp in experiments:
431 for exp in experiments:
432 campaign.experiments.add(exp)
432 campaign.experiments.add(exp)
433 campaign.save()
433 campaign.save()
434 return redirect('url_campaign', id_camp=campaign.id)
434 return redirect('url_campaign', id_camp=campaign.id)
435
435
436 kwargs['form'] = form
436 kwargs['form'] = form
437 kwargs['title'] = 'Campaign'
437 kwargs['title'] = 'Campaign'
438 kwargs['suptitle'] = 'New'
438 kwargs['suptitle'] = 'New'
439 kwargs['menu_campaigns'] = 'active'
439 kwargs['menu_campaigns'] = 'active'
440
440
441 return render(request, 'campaign_edit.html', kwargs)
441 return render(request, 'campaign_edit.html', kwargs)
442
442
443
443
444 @login_required
444 @login_required
445 def campaign_edit(request, id_camp):
445 def campaign_edit(request, id_camp):
446
446
447 campaign = get_object_or_404(Campaign, pk=id_camp)
447 campaign = get_object_or_404(Campaign, pk=id_camp)
448
448
449 if request.method == 'GET':
449 if request.method == 'GET':
450 form = CampaignForm(instance=campaign)
450 form = CampaignForm(instance=campaign)
451
451
452 if request.method == 'POST':
452 if request.method == 'POST':
453 exps = campaign.experiments.all().values_list('pk', flat=True)
453 exps = campaign.experiments.all().values_list('pk', flat=True)
454 post = request.POST.copy()
454 post = request.POST.copy()
455 new_exps = post.getlist('experiments')
455 new_exps = post.getlist('experiments')
456 post.setlist('experiments', [])
456 post.setlist('experiments', [])
457 form = CampaignForm(post, instance=campaign)
457 form = CampaignForm(post, instance=campaign)
458
458
459 if form.is_valid():
459 if form.is_valid():
460 camp = form.save()
460 camp = form.save()
461 for id_exp in new_exps:
461 for id_exp in new_exps:
462 if int(id_exp) in exps:
462 if int(id_exp) in exps:
463 exps.pop(id_exp)
463 exps.pop(id_exp)
464 else:
464 else:
465 exp = Experiment.objects.get(pk=id_exp)
465 exp = Experiment.objects.get(pk=id_exp)
466 if exp.template:
466 if exp.template:
467 camp.experiments.add(exp.clone(template=False))
467 camp.experiments.add(exp.clone(template=False))
468 else:
468 else:
469 camp.experiments.add(exp)
469 camp.experiments.add(exp)
470
470
471 for id_exp in exps:
471 for id_exp in exps:
472 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
472 camp.experiments.remove(Experiment.objects.get(pk=id_exp))
473
473
474 return redirect('url_campaign', id_camp=id_camp)
474 return redirect('url_campaign', id_camp=id_camp)
475
475
476 kwargs = {}
476 kwargs = {}
477 kwargs['form'] = form
477 kwargs['form'] = form
478 kwargs['title'] = 'Campaign'
478 kwargs['title'] = 'Campaign'
479 kwargs['suptitle'] = 'Edit'
479 kwargs['suptitle'] = 'Edit'
480 kwargs['button'] = 'Update'
480 kwargs['button'] = 'Update'
481 kwargs['menu_campaigns'] = 'active'
481 kwargs['menu_campaigns'] = 'active'
482
482
483 return render(request, 'campaign_edit.html', kwargs)
483 return render(request, 'campaign_edit.html', kwargs)
484
484
485
485
486 @login_required
486 @login_required
487 def campaign_delete(request, id_camp):
487 def campaign_delete(request, id_camp):
488
488
489 campaign = get_object_or_404(Campaign, pk=id_camp)
489 campaign = get_object_or_404(Campaign, pk=id_camp)
490
490
491 if request.method == 'POST':
491 if request.method == 'POST':
492 if is_developer(request.user):
492 if is_developer(request.user):
493
493
494 for exp in campaign.experiments.all():
494 for exp in campaign.experiments.all():
495 for conf in Configuration.objects.filter(experiment=exp):
495 for conf in Configuration.objects.filter(experiment=exp):
496 conf.delete()
496 conf.delete()
497 exp.delete()
497 exp.delete()
498 campaign.delete()
498 campaign.delete()
499
499
500 return redirect('url_campaigns')
500 return redirect('url_campaigns')
501
501
502 messages.error(request, 'Not enough permission to delete this object')
502 messages.error(request, 'Not enough permission to delete this object')
503 return redirect(campaign.get_absolute_url())
503 return redirect(campaign.get_absolute_url())
504
504
505 kwargs = {
505 kwargs = {
506 'title': 'Delete',
506 'title': 'Delete',
507 'suptitle': 'Campaign',
507 'suptitle': 'Campaign',
508 'object': campaign,
508 'object': campaign,
509 'delete': True
509 'delete': True
510 }
510 }
511 kwargs['menu_campaigns'] = 'active'
511 kwargs['menu_campaigns'] = 'active'
512
512
513 return render(request, 'confirm.html', kwargs)
513 return render(request, 'confirm.html', kwargs)
514
514
515
515
516 @login_required
516 @login_required
517 def campaign_export(request, id_camp):
517 def campaign_export(request, id_camp):
518
518
519 campaign = get_object_or_404(Campaign, pk=id_camp)
519 campaign = get_object_or_404(Campaign, pk=id_camp)
520 content = campaign.parms_to_dict()
520 content = campaign.parms_to_dict()
521 content_type = 'application/json'
521 content_type = 'application/json'
522 filename = '%s_%s.json' % (campaign.name, campaign.id)
522 filename = '%s_%s.json' % (campaign.name, campaign.id)
523
523
524 response = HttpResponse(content_type=content_type)
524 response = HttpResponse(content_type=content_type)
525 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
525 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
526 response.write(json.dumps(content, indent=2))
526 response.write(json.dumps(content, indent=2))
527
527
528 return response
528 return response
529
529
530
530
531 @login_required
531 @login_required
532 def campaign_import(request, id_camp):
532 def campaign_import(request, id_camp):
533
533
534 campaign = get_object_or_404(Campaign, pk=id_camp)
534 campaign = get_object_or_404(Campaign, pk=id_camp)
535
535
536 if request.method == 'GET':
536 if request.method == 'GET':
537 file_form = UploadFileForm()
537 file_form = UploadFileForm()
538
538
539 if request.method == 'POST':
539 if request.method == 'POST':
540 file_form = UploadFileForm(request.POST, request.FILES)
540 file_form = UploadFileForm(request.POST, request.FILES)
541
541
542 if file_form.is_valid():
542 if file_form.is_valid():
543 new_camp = campaign.dict_to_parms(
543 new_camp = campaign.dict_to_parms(
544 json.load(request.FILES['file']), CONF_MODELS)
544 json.load(request.FILES['file']), CONF_MODELS)
545 messages.success(
545 messages.success(
546 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
546 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
547 return redirect(new_camp.get_absolute_url_edit())
547 return redirect(new_camp.get_absolute_url_edit())
548
548
549 messages.error(request, "Could not import parameters from file")
549 messages.error(request, "Could not import parameters from file")
550
550
551 kwargs = {}
551 kwargs = {}
552 kwargs['title'] = 'Campaign'
552 kwargs['title'] = 'Campaign'
553 kwargs['form'] = file_form
553 kwargs['form'] = file_form
554 kwargs['suptitle'] = 'Importing file'
554 kwargs['suptitle'] = 'Importing file'
555 kwargs['button'] = 'Import'
555 kwargs['button'] = 'Import'
556 kwargs['menu_campaigns'] = 'active'
556 kwargs['menu_campaigns'] = 'active'
557
557
558 return render(request, 'campaign_import.html', kwargs)
558 return render(request, 'campaign_import.html', kwargs)
559
559
560
560
561 def experiments(request):
561 def experiments(request):
562
562
563 page = request.GET.get('page')
563 page = request.GET.get('page')
564 order = ('location',)
564 order = ('location',)
565 filters = request.GET.copy()
565 filters = request.GET.copy()
566
566
567 if 'my experiments' in filters:
567 if 'my experiments' in filters:
568 filters.pop('my experiments', None)
568 filters.pop('my experiments', None)
569 filters['mine'] = request.user.id
569 filters['mine'] = request.user.id
570
570
571 kwargs = get_paginator(Experiment, page, order, filters)
571 kwargs = get_paginator(Experiment, page, order, filters)
572
572
573 fields = ['tags', 'template']
573 fields = ['tags', 'template']
574 if request.user.is_authenticated:
574 if request.user.is_authenticated:
575 fields.append('my experiments')
575 fields.append('my experiments')
576
576
577 form = FilterForm(initial=request.GET, extra_fields=fields)
577 form = FilterForm(initial=request.GET, extra_fields=fields)
578
578
579 kwargs['keys'] = ['name', 'radar_system', 'actions']
579 kwargs['keys'] = ['name', 'radar_system', 'pedestal', 'generator', 'reception_rx', 'transmission_tx', 'actions']
580 kwargs['title'] = 'Experiment'
580 kwargs['title'] = 'Experiment'
581 kwargs['suptitle'] = 'List'
581 kwargs['suptitle'] = 'List'
582 kwargs['no_sidebar'] = True
582 kwargs['no_sidebar'] = True
583 kwargs['form'] = form
583 kwargs['form'] = form
584 kwargs['add_url'] = reverse('url_add_experiment')
584 kwargs['add_url'] = reverse('url_add_experiment')
585 filters = request.GET.copy()
585 filters = request.GET.copy()
586 filters.pop('page', None)
586 filters.pop('page', None)
587 kwargs['q'] = urlencode(filters)
587 kwargs['q'] = urlencode(filters)
588 kwargs['menu_experiments'] = 'active'
588 kwargs['menu_experiments'] = 'active'
589
589
590 return render(request, 'base_list.html', kwargs)
590 return render(request, 'base_list.html', kwargs)
591
591
592
592
593 def experiment(request, id_exp):
593 def experiment(request, id_exp):
594
594
595 experiment = get_object_or_404(Experiment, pk=id_exp)
595 experiment = get_object_or_404(Experiment, pk=id_exp)
596
596
597 configurations = Configuration.objects.filter(
597 #experiment = Experiment.objects.select_related('pedestal').get(pk=id_exp)
598 experiment=experiment, type=0)
598 configurations = PedestalConfiguration.objects.filter(id = experiment.pedestal_id)
599
600 kwargs = {}
599 kwargs = {}
601
600
602 kwargs['experiment_keys'] = ['template', 'radar_system', 'name']
601 kwargs['experiment_keys'] = ['template', 'radar_system', 'name', 'pedestal', 'generator', 'reception_rx', 'transmission_tx']
603 kwargs['experiment'] = experiment
602 kwargs['experiment'] = experiment
604 kwargs['configuration_keys'] = ['name', 'device__ip_address',
603 kwargs['configuration_keys'] = ['name', 'device__ip_address',
605 'device__port_address', 'device__status']
604 'device__port_address', 'device__status']
606 kwargs['configurations'] = configurations
605 kwargs['configurations'] = configurations
607 kwargs['title'] = 'Experiment'
606 kwargs['title'] = 'Experiment'
608 kwargs['suptitle'] = 'Details'
607 kwargs['suptitle'] = 'Details'
609 kwargs['button'] = 'Add Configuration'
608 kwargs['button'] = 'Add Configuration'
610 kwargs['menu_experiments'] = 'active'
609 kwargs['menu_experiments'] = 'active'
611
610 #print(kwargs)
612 ###### SIDEBAR ######
611 ###### SIDEBAR ######
613 kwargs.update(sidebar(experiment=experiment))
612 kwargs.update(sidebar(experiment=experiment))
614
613
615 return render(request, 'experiment.html', kwargs)
614 return render(request, 'experiment.html', kwargs)
616
615
617
616
618 @login_required
617 @login_required
619 def experiment_new(request, id_camp=None):
618 def experiment_new(request, id_camp=None):
620
619
621 if not is_developer(request.user):
620 if not is_developer(request.user):
622 messages.error(
621 messages.error(
623 request, 'Developer required, to create new Experiments')
622 request, 'Developer required, to create new Experiments')
624 return redirect('index')
623 return redirect('index')
625 kwargs = {}
624 kwargs = {}
626
625
627 if request.method == 'GET':
626 if request.method == 'GET':
628 if 'template' in request.GET:
627 if 'template' in request.GET:
629 if request.GET['template'] == '0':
628 if request.GET['template'] == '0':
630 form = NewForm(initial={'create_from': 2},
629 form = NewForm(initial={'create_from': 2},
631 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
630 template_choices=Experiment.objects.filter(template=True).values_list('id', 'name'))
632 else:
631 else:
633 kwargs['button'] = 'Create'
632 kwargs['button'] = 'Create'
634 kwargs['configurations'] = Configuration.objects.filter(
633 kwargs['configurations'] = Configuration.objects.filter(
635 experiment=request.GET['template'])
634 experiment=request.GET['template'])
636 kwargs['configuration_keys'] = ['name', 'device__name',
635 kwargs['configuration_keys'] = ['name', 'device__name',
637 'device__ip_address', 'device__port_address']
636 'device__ip_address', 'device__port_address']
638 exp = Experiment.objects.get(pk=request.GET['template'])
637 exp = Experiment.objects.get(pk=request.GET['template'])
639 form = ExperimentForm(instance=exp,
638 form = ExperimentForm(instance=exp,
640 initial={'name': '{}_{:%y%m%d}'.format(exp.name, datetime.now()),
639 initial={'name': '{}_{:%y%m%d}'.format(exp.name, datetime.now()),
641 'template': False})
640 'template': False})
642 elif 'blank' in request.GET:
641 elif 'blank' in request.GET:
643 kwargs['button'] = 'Create'
642 kwargs['button'] = 'Create'
644 form = ExperimentForm()
643 form = ExperimentForm()
645 else:
644 else:
646 form = NewForm()
645 form = NewForm()
647
646
648 if request.method == 'POST':
647 if request.method == 'POST':
649 form = ExperimentForm(request.POST)
648 form = ExperimentForm(request.POST)
650 if form.is_valid():
649 if form.is_valid():
651 experiment = form.save(commit=False)
650 experiment = form.save(commit=False)
652 experiment.author = request.user
651 experiment.author = request.user
653 experiment.save()
652 experiment.save()
654
653
655 if 'template' in request.GET:
654 if 'template' in request.GET:
656 configurations = Configuration.objects.filter(
655 configurations = Configuration.objects.filter(
657 experiment=request.GET['template'], type=0)
656 experiment=request.GET['template'], type=0)
658 for conf in configurations:
657 for conf in configurations:
659 conf.clone(experiment=experiment, template=False)
658 conf.clone(experiment=experiment, template=False)
660
659
661 return redirect('url_experiment', id_exp=experiment.id)
660 return redirect('url_experiment', id_exp=experiment.id)
662
661
663 kwargs['form'] = form
662 kwargs['form'] = form
664 kwargs['title'] = 'Experiment'
663 kwargs['title'] = 'Experiment'
665 kwargs['suptitle'] = 'New'
664 kwargs['suptitle'] = 'New'
666 kwargs['menu_experiments'] = 'active'
665 kwargs['menu_experiments'] = 'active'
667
666
668 return render(request, 'experiment_edit.html', kwargs)
667 return render(request, 'experiment_edit.html', kwargs)
669
668
670
669
671 @login_required
670 @login_required
672 def experiment_edit(request, id_exp):
671 def experiment_edit(request, id_exp):
673
672
674 experiment = get_object_or_404(Experiment, pk=id_exp)
673 experiment = get_object_or_404(Experiment, pk=id_exp)
674 id_p = experiment.pedestal_id
675 id_rx = experiment.reception_rx_id
676 id_tx = experiment.transmission_tx_id
677 #print(id_p)
678 #configurations = get_object_or_404(PedestalConfiguration, id = id_p)
679 conf_pedestal = PedestalConfiguration.objects.get(id = id_p)
680 conf_rx = USRPRXConfiguration.objects.get(id = id_rx)
681 conf_tx = USRPTXConfiguration.objects.get(id = id_tx)
675
682
676 if request.method == 'GET':
683 if request.method == 'GET':
677 form = ExperimentForm(instance=experiment)
684 form = ExperimentEditionForm(instance=experiment)
685 form_pedestal = PedestalEditionForm(instance=conf_pedestal)
686 form_rx = USRPRXEditionForm(instance=conf_rx)
687 form_tx = USRPTXEditionForm(instance=conf_tx)
678
688
679 if request.method == 'POST':
689 if request.method == 'POST':
680 form = ExperimentForm(request.POST, instance=experiment)
690 form = ExperimentEditionForm(request.POST, instance=experiment)
691 form_pedestal = PedestalEditionForm(request.POST, instance=conf_pedestal)
692 form_rx = USRPRXEditionForm(request.POST, instance=conf_rx)
693 form_tx = USRPTXEditionForm(request.POST, instance=conf_tx)
681
694
682 if form.is_valid():
695 if form.is_valid():
683 experiment = form.save()
696 experiment = form.save()
697 form_pedestal.save()
698 form_rx.save()
699 form_tx.save()
684 return redirect('url_experiment', id_exp=experiment.id)
700 return redirect('url_experiment', id_exp=experiment.id)
685
701
686 kwargs = {}
702 kwargs = {}
687 kwargs['form'] = form
703 kwargs['form'] = form
704 kwargs['form_pedestal'] = form_pedestal
705 kwargs['form_rx'] = form_rx
706 kwargs['form_tx'] = form_tx
688 kwargs['title'] = 'Experiment'
707 kwargs['title'] = 'Experiment'
689 kwargs['suptitle'] = 'Edit'
708 kwargs['suptitle'] = 'Edit'
690 kwargs['button'] = 'Update'
709 kwargs['button'] = 'Update'
691 kwargs['menu_experiments'] = 'active'
710 kwargs['menu_experiments'] = 'active'
692
711
693 return render(request, 'experiment_edit.html', kwargs)
712 return render(request, 'experiment_edit.html', kwargs)
694
713
695
714
696 @login_required
715 @login_required
697 def experiment_delete(request, id_exp):
716 def experiment_delete(request, id_exp):
698
717
699 experiment = get_object_or_404(Experiment, pk=id_exp)
718 experiment = get_object_or_404(Experiment, pk=id_exp)
700
719
701 if request.method == 'POST':
720 if request.method == 'POST':
702 if is_developer(request.user):
721 if is_developer(request.user):
703 for conf in Configuration.objects.filter(experiment=experiment):
722 #for conf in Configuration.objects.filter(experiment=experiment):
704 conf.delete()
723 #conf.delete()
705 experiment.delete()
724 experiment.delete()
706 return redirect('url_experiments')
725 return redirect('url_experiments')
707
726
708 messages.error(request, 'Not enough permission to delete this object')
727 messages.error(request, 'Not enough permission to delete this object')
709 return redirect(experiment.get_absolute_url())
728 return redirect(experiment.get_absolute_url())
710
729
711 kwargs = {
730 kwargs = {
712 'title': 'Delete',
731 'title': 'Delete',
713 'suptitle': 'Experiment',
732 'suptitle': 'Experiment',
714 'object': experiment,
733 'object': experiment,
715 'delete': True
734 'delete': True
716 }
735 }
717
736
718 return render(request, 'confirm.html', kwargs)
737 return render(request, 'confirm.html', kwargs)
719
738
720
739
721 @login_required
740 @login_required
722 def experiment_export(request, id_exp):
741 def experiment_export(request, id_exp):
723
742
724 experiment = get_object_or_404(Experiment, pk=id_exp)
743 experiment = get_object_or_404(Experiment, pk=id_exp)
725 content = experiment.parms_to_dict()
744 content = experiment.parms_to_dict()
726 content_type = 'application/json'
745 content_type = 'application/json'
727 filename = '%s_%s.json' % (experiment.name, experiment.id)
746 filename = '%s_%s.json' % (experiment.name, experiment.id)
728
747
729 response = HttpResponse(content_type=content_type)
748 response = HttpResponse(content_type=content_type)
730 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
749 response['Content-Disposition'] = 'attachment; filename="%s"' % filename
731 response.write(json.dumps(content, indent=2))
750 response.write(json.dumps(content, indent=2))
732
751
733 return response
752 return response
734
753
735
754
736 @login_required
755 @login_required
737 def experiment_import(request, id_exp):
756 def experiment_import(request, id_exp):
738
757
739 experiment = get_object_or_404(Experiment, pk=id_exp)
758 experiment = get_object_or_404(Experiment, pk=id_exp)
740 configurations = Configuration.objects.filter(experiment=experiment)
759 configurations = Configuration.objects.filter(experiment=experiment)
741
760
742 if request.method == 'GET':
761 if request.method == 'GET':
743 file_form = UploadFileForm()
762 file_form = UploadFileForm()
744
763
745 if request.method == 'POST':
764 if request.method == 'POST':
746 file_form = UploadFileForm(request.POST, request.FILES)
765 file_form = UploadFileForm(request.POST, request.FILES)
747
766
748 if file_form.is_valid():
767 if file_form.is_valid():
749 new_exp = experiment.dict_to_parms(
768 new_exp = experiment.dict_to_parms(
750 json.load(request.FILES['file']), CONF_MODELS)
769 json.load(request.FILES['file']), CONF_MODELS)
751 messages.success(
770 messages.success(
752 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
771 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
753 return redirect(new_exp.get_absolute_url_edit())
772 return redirect(new_exp.get_absolute_url_edit())
754
773
755 messages.error(request, "Could not import parameters from file")
774 messages.error(request, "Could not import parameters from file")
756
775
757 kwargs = {}
776 kwargs = {}
758 kwargs['title'] = 'Experiment'
777 kwargs['title'] = 'Experiment'
759 kwargs['form'] = file_form
778 kwargs['form'] = file_form
760 kwargs['suptitle'] = 'Importing file'
779 kwargs['suptitle'] = 'Importing file'
761 kwargs['button'] = 'Import'
780 kwargs['button'] = 'Import'
762 kwargs['menu_experiments'] = 'active'
781 kwargs['menu_experiments'] = 'active'
763
782
764 kwargs.update(sidebar(experiment=experiment))
783 kwargs.update(sidebar(experiment=experiment))
765
784
766 return render(request, 'experiment_import.html', kwargs)
785 return render(request, 'experiment_import.html', kwargs)
767
786
768
787
769 @login_required
788 @login_required
770 def experiment_start(request, id_exp):
789 def experiment_start(request, id_exp):
771
790
772 exp = get_object_or_404(Experiment, pk=id_exp)
791 exp = get_object_or_404(Experiment, pk=id_exp)
773
792 exp.status = 0
774 if exp.status == 2:
793 if exp.status == 2:
775 messages.warning(request, 'Experiment {} already runnnig'.format(exp))
794 messages.warning(request, 'Experiment {} already runnnig'.format(exp))
776 else:
795 else:
777 exp.status = exp.start()
796 exp.status = exp.start()
778 if exp.status == 0:
797 if exp.status == 0:
779 messages.error(request, 'Experiment {} not start'.format(exp))
798 messages.error(request, 'Experiment {} not start'.format(exp))
780 if exp.status == 2:
799 if exp.status == 2:
781 messages.success(request, 'Experiment {} started'.format(exp))
800 messages.success(request, 'Experiment {} started'.format(exp))
782
801
783 exp.save()
802 exp.save()
784
803
785 return redirect(exp.get_absolute_url())
804 return redirect(exp.get_absolute_url())
786
805
787
806
788 @login_required
807 @login_required
789 def experiment_stop(request, id_exp):
808 def experiment_stop(request, id_exp):
790
809
791 exp = get_object_or_404(Experiment, pk=id_exp)
810 exp = get_object_or_404(Experiment, pk=id_exp)
792
811
793 if exp.status == 2:
812 if exp.status == 2:
794 exp.status = exp.stop()
813 exp.status = exp.stop()
795 exp.save()
814 exp.save()
796 messages.success(request, 'Experiment {} stopped'.format(exp))
815 messages.success(request, 'Experiment {} stopped'.format(exp))
797 else:
816 else:
798 messages.error(request, 'Experiment {} not running'.format(exp))
817 messages.error(request, 'Experiment {} not running'.format(exp))
799
818
800 return redirect(exp.get_absolute_url())
819 return redirect(exp.get_absolute_url())
801
820
802
821
803 def experiment_status(request, id_exp):
822 def experiment_status(request, id_exp):
804
823
805 exp = get_object_or_404(Experiment, pk=id_exp)
824 exp = get_object_or_404(Experiment, pk=id_exp)
806
825
807 exp.get_status()
826 exp.get_status()
808
827
809 return redirect(exp.get_absolute_url())
828 return redirect(exp.get_absolute_url())
810
829
811
830
812 @login_required
831 @login_required
813 def experiment_mix(request, id_exp):
832 def experiment_mix(request, id_exp):
814
833
815 experiment = get_object_or_404(Experiment, pk=id_exp)
834 experiment = get_object_or_404(Experiment, pk=id_exp)
816 rc_confs = [conf for conf in PedestalConfiguration.objects.filter(
835 rc_confs = [conf for conf in PedestalConfiguration.objects.filter(
817 experiment=id_exp,
836 experiment=id_exp,
818 type=0,
837 type=0,
819 mix=False)]
838 mix=False)]
820
839
821 if len(rc_confs) < 2:
840 if len(rc_confs) < 2:
822 messages.warning(
841 messages.warning(
823 request, 'You need at least two RC Configurations to make a mix')
842 request, 'You need at least two RC Configurations to make a mix')
824 return redirect(experiment.get_absolute_url())
843 return redirect(experiment.get_absolute_url())
825
844
826 mix_confs = PedestalConfiguration.objects.filter(experiment=id_exp, mix=True, type=0)
845 mix_confs = PedestalConfiguration.objects.filter(experiment=id_exp, mix=True, type=0)
827
846
828 if mix_confs:
847 if mix_confs:
829 mix = mix_confs[0]
848 mix = mix_confs[0]
830 else:
849 else:
831 mix = PedestalConfiguration(experiment=experiment,
850 mix = PedestalConfiguration(experiment=experiment,
832 device=rc_confs[0].device,
851 device=rc_confs[0].device,
833 ipp=rc_confs[0].ipp,
852 ipp=rc_confs[0].ipp,
834 clock_in=rc_confs[0].clock_in,
853 clock_in=rc_confs[0].clock_in,
835 clock_divider=rc_confs[0].clock_divider,
854 clock_divider=rc_confs[0].clock_divider,
836 mix=True,
855 mix=True,
837 parameters='')
856 parameters='')
838 mix.save()
857 mix.save()
839
858
840 line_type = RCLineType.objects.get(name='mix')
859 line_type = RCLineType.objects.get(name='mix')
841 print("VIew obteniendo len getlines")
860 print("VIew obteniendo len getlines")
842 print(len(rc_confs[0].get_lines()))
861 print(len(rc_confs[0].get_lines()))
843 for i in range(len(rc_confs[0].get_lines())):
862 for i in range(len(rc_confs[0].get_lines())):
844 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
863 line = RCLine(rc_configuration=mix, line_type=line_type, channel=i)
845 line.save()
864 line.save()
846
865
847 initial = {'name': mix.name,
866 initial = {'name': mix.name,
848 'result': parse_mix_result(mix.parameters),
867 'result': parse_mix_result(mix.parameters),
849 'delay': 0,
868 'delay': 0,
850 'mask': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
869 'mask': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
851 }
870 }
852
871
853 if request.method == 'GET':
872 if request.method == 'GET':
854 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
873 form = RCMixConfigurationForm(confs=rc_confs, initial=initial)
855
874
856 if request.method == 'POST':
875 if request.method == 'POST':
857 result = mix.parameters
876 result = mix.parameters
858
877
859 if '{}|'.format(request.POST['experiment']) in result:
878 if '{}|'.format(request.POST['experiment']) in result:
860 messages.error(request, 'Configuration already added')
879 messages.error(request, 'Configuration already added')
861 else:
880 else:
862 if 'operation' in request.POST:
881 if 'operation' in request.POST:
863 operation = MIX_OPERATIONS[request.POST['operation']]
882 operation = MIX_OPERATIONS[request.POST['operation']]
864 else:
883 else:
865 operation = ' '
884 operation = ' '
866
885
867 mode = MIX_MODES[request.POST['mode']]
886 mode = MIX_MODES[request.POST['mode']]
868
887
869 if result:
888 if result:
870 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
889 result = '{}-{}|{}|{}|{}|{}'.format(mix.parameters,
871 request.POST['experiment'],
890 request.POST['experiment'],
872 mode,
891 mode,
873 operation,
892 operation,
874 float(
893 float(
875 request.POST['delay']),
894 request.POST['delay']),
876 parse_mask(
895 parse_mask(
877 request.POST.getlist('mask'))
896 request.POST.getlist('mask'))
878 )
897 )
879 else:
898 else:
880 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
899 result = '{}|{}|{}|{}|{}'.format(request.POST['experiment'],
881 mode,
900 mode,
882 operation,
901 operation,
883 float(request.POST['delay']),
902 float(request.POST['delay']),
884 parse_mask(
903 parse_mask(
885 request.POST.getlist('mask'))
904 request.POST.getlist('mask'))
886 )
905 )
887
906
888 mix.parameters = result
907 mix.parameters = result
889 mix.save()
908 mix.save()
890 mix.update_pulses()
909 mix.update_pulses()
891
910
892 initial['result'] = parse_mix_result(result)
911 initial['result'] = parse_mix_result(result)
893 initial['name'] = mix.name
912 initial['name'] = mix.name
894
913
895 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
914 form = RCMixConfigurationForm(initial=initial, confs=rc_confs)
896
915
897 kwargs = {
916 kwargs = {
898 'title': 'Experiment',
917 'title': 'Experiment',
899 'suptitle': 'Mix Configurations',
918 'suptitle': 'Mix Configurations',
900 'form': form,
919 'form': form,
901 'extra_button': 'Delete',
920 'extra_button': 'Delete',
902 'button': 'Add',
921 'button': 'Add',
903 'cancel': 'Back',
922 'cancel': 'Back',
904 'previous': experiment.get_absolute_url(),
923 'previous': experiment.get_absolute_url(),
905 'id_exp': id_exp,
924 'id_exp': id_exp,
906
925
907 }
926 }
908 kwargs['menu_experiments'] = 'active'
927 kwargs['menu_experiments'] = 'active'
909
928
910 return render(request, 'experiment_mix.html', kwargs)
929 return render(request, 'experiment_mix.html', kwargs)
911
930
912
931
913 @login_required
932 @login_required
914 def experiment_mix_delete(request, id_exp):
933 def experiment_mix_delete(request, id_exp):
915
934
916 conf = PedestalConfiguration.objects.get(experiment=id_exp, mix=True, type=0)
935 conf = PedestalConfiguration.objects.get(experiment=id_exp, mix=True, type=0)
917 values = conf.parameters.split('-')
936 values = conf.parameters.split('-')
918 conf.parameters = '-'.join(values[:-1])
937 conf.parameters = '-'.join(values[:-1])
919 conf.save()
938 conf.save()
920
939
921 return redirect('url_mix_experiment', id_exp=id_exp)
940 return redirect('url_mix_experiment', id_exp=id_exp)
922
941
923
942
924 def experiment_summary(request, id_exp):
943 def experiment_summary(request, id_exp):
925
944
926 experiment = get_object_or_404(Experiment, pk=id_exp)
945 experiment = get_object_or_404(Experiment, pk=id_exp)
927 configurations = Configuration.objects.filter(
946 configurations = Configuration.objects.filter(
928 experiment=experiment, type=0)
947 experiment=experiment, type=0)
929
948
930 kwargs = {}
949 kwargs = {}
931 kwargs['experiment_keys'] = ['radar_system',
950 kwargs['experiment_keys'] = ['radar_system',
932 'name', 'freq', 'start_time', 'end_time']
951 'name', 'freq', 'start_time', 'end_time']
933 kwargs['experiment'] = experiment
952 kwargs['experiment'] = experiment
934 kwargs['configurations'] = []
953 kwargs['configurations'] = []
935 kwargs['title'] = 'Experiment Summary'
954 kwargs['title'] = 'Experiment Summary'
936 kwargs['suptitle'] = 'Details'
955 kwargs['suptitle'] = 'Details'
937 kwargs['button'] = 'Verify Parameters'
956 kwargs['button'] = 'Verify Parameters'
938
957
939 c_vel = 3.0*(10**8) # m/s
958 c_vel = 3.0*(10**8) # m/s
940 ope_freq = experiment.freq*(10**6) # 1/s
959 ope_freq = experiment.freq*(10**6) # 1/s
941 radar_lambda = c_vel/ope_freq # m
960 radar_lambda = c_vel/ope_freq # m
942 kwargs['radar_lambda'] = radar_lambda
961 kwargs['radar_lambda'] = radar_lambda
943
962
944 ipp = None
963 ipp = None
945 nsa = 1
964 nsa = 1
946 code_id = 0
965 code_id = 0
947 tx_line = {}
966 tx_line = {}
948
967
949 for configuration in configurations.filter(device__device_type__name = 'pedestal'):
968 for configuration in configurations.filter(device__device_type__name = 'pedestal'):
950
969
951 if configuration.mix:
970 if configuration.mix:
952 continue
971 continue
953 conf = {'conf': configuration}
972 conf = {'conf': configuration}
954 conf['keys'] = []
973 conf['keys'] = []
955 conf['NTxs'] = configuration.ntx
974 conf['NTxs'] = configuration.ntx
956 conf['keys'].append('NTxs')
975 conf['keys'].append('NTxs')
957 ipp = configuration.ipp
976 ipp = configuration.ipp
958 conf['IPP'] = ipp
977 conf['IPP'] = ipp
959 conf['keys'].append('IPP')
978 conf['keys'].append('IPP')
960 lines = configuration.get_lines(line_type__name='tx')
979 lines = configuration.get_lines(line_type__name='tx')
961
980
962 for tx_line in lines:
981 for tx_line in lines:
963 tx_params = json.loads(tx_line.params)
982 tx_params = json.loads(tx_line.params)
964 conf[tx_line.get_name()] = '{} Km'.format(tx_params['pulse_width'])
983 conf[tx_line.get_name()] = '{} Km'.format(tx_params['pulse_width'])
965 conf['keys'].append(tx_line.get_name())
984 conf['keys'].append(tx_line.get_name())
966 delays = tx_params['delays']
985 delays = tx_params['delays']
967 if delays not in ('', '0'):
986 if delays not in ('', '0'):
968 n = len(delays.split(','))
987 n = len(delays.split(','))
969 taus = '{} Taus: {}'.format(n, delays)
988 taus = '{} Taus: {}'.format(n, delays)
970 else:
989 else:
971 taus = '-'
990 taus = '-'
972 conf['Taus ({})'.format(tx_line.get_name())] = taus
991 conf['Taus ({})'.format(tx_line.get_name())] = taus
973 conf['keys'].append('Taus ({})'.format(tx_line.get_name()))
992 conf['keys'].append('Taus ({})'.format(tx_line.get_name()))
974 for code_line in configuration.get_lines(line_type__name='codes'):
993 for code_line in configuration.get_lines(line_type__name='codes'):
975 code_params = json.loads(code_line.params)
994 code_params = json.loads(code_line.params)
976 code_id = code_params['code']
995 code_id = code_params['code']
977 if tx_line.pk == int(code_params['TX_ref']):
996 if tx_line.pk == int(code_params['TX_ref']):
978 conf['Code ({})'.format(tx_line.get_name())] = '{}:{}'.format(RCLineCode.objects.get(pk=code_params['code']),
997 conf['Code ({})'.format(tx_line.get_name())] = '{}:{}'.format(RCLineCode.objects.get(pk=code_params['code']),
979 '-'.join(code_params['codes']))
998 '-'.join(code_params['codes']))
980 conf['keys'].append('Code ({})'.format(tx_line.get_name()))
999 conf['keys'].append('Code ({})'.format(tx_line.get_name()))
981
1000
982 for windows_line in configuration.get_lines(line_type__name='windows'):
1001 for windows_line in configuration.get_lines(line_type__name='windows'):
983 win_params = json.loads(windows_line.params)
1002 win_params = json.loads(windows_line.params)
984 if tx_line.pk == int(win_params['TX_ref']):
1003 if tx_line.pk == int(win_params['TX_ref']):
985 windows = ''
1004 windows = ''
986 nsa = win_params['params'][0]['number_of_samples']
1005 nsa = win_params['params'][0]['number_of_samples']
987 for i, params in enumerate(win_params['params']):
1006 for i, params in enumerate(win_params['params']):
988 windows += 'W{}: Ho={first_height} km DH={resolution} km NSA={number_of_samples}<br>'.format(
1007 windows += 'W{}: Ho={first_height} km DH={resolution} km NSA={number_of_samples}<br>'.format(
989 i, **params)
1008 i, **params)
990 conf['Window'] = mark_safe(windows)
1009 conf['Window'] = mark_safe(windows)
991 conf['keys'].append('Window')
1010 conf['keys'].append('Window')
992
1011
993 kwargs['configurations'].append(conf)
1012 kwargs['configurations'].append(conf)
994
1013
995 for configuration in configurations.filter(device__device_type__name = 'jars'):
1014 for configuration in configurations.filter(device__device_type__name = 'jars'):
996
1015
997 conf = {'conf': configuration}
1016 conf = {'conf': configuration}
998 conf['keys'] = []
1017 conf['keys'] = []
999 conf['Type of Data'] = EXPERIMENT_TYPE[configuration.exp_type][1]
1018 conf['Type of Data'] = EXPERIMENT_TYPE[configuration.exp_type][1]
1000 conf['keys'].append('Type of Data')
1019 conf['keys'].append('Type of Data')
1001 channels_number = configuration.channels_number
1020 channels_number = configuration.channels_number
1002 exp_type = configuration.exp_type
1021 exp_type = configuration.exp_type
1003 fftpoints = configuration.fftpoints
1022 fftpoints = configuration.fftpoints
1004 filter_parms = json.loads(configuration.filter_parms)
1023 filter_parms = json.loads(configuration.filter_parms)
1005 spectral_number = configuration.spectral_number
1024 spectral_number = configuration.spectral_number
1006 acq_profiles = configuration.acq_profiles
1025 acq_profiles = configuration.acq_profiles
1007 cohe_integr = configuration.cohe_integr
1026 cohe_integr = configuration.cohe_integr
1008 profiles_block = configuration.profiles_block
1027 profiles_block = configuration.profiles_block
1009
1028
1010 conf['Num of Profiles'] = acq_profiles
1029 conf['Num of Profiles'] = acq_profiles
1011 conf['keys'].append('Num of Profiles')
1030 conf['keys'].append('Num of Profiles')
1012
1031
1013 conf['Prof per Block'] = profiles_block
1032 conf['Prof per Block'] = profiles_block
1014 conf['keys'].append('Prof per Block')
1033 conf['keys'].append('Prof per Block')
1015
1034
1016 conf['Blocks per File'] = configuration.raw_data_blocks
1035 conf['Blocks per File'] = configuration.raw_data_blocks
1017 conf['keys'].append('Blocks per File')
1036 conf['keys'].append('Blocks per File')
1018
1037
1019 if exp_type == 0: # Short
1038 if exp_type == 0: # Short
1020 bytes_ = 2
1039 bytes_ = 2
1021 b = nsa*2*bytes_*channels_number
1040 b = nsa*2*bytes_*channels_number
1022 else: # Float
1041 else: # Float
1023 bytes_ = 4
1042 bytes_ = 4
1024 channels = channels_number + spectral_number
1043 channels = channels_number + spectral_number
1025 b = nsa*2*bytes_*fftpoints*channels
1044 b = nsa*2*bytes_*fftpoints*channels
1026
1045
1027 codes_num = 7
1046 codes_num = 7
1028 if code_id == 2:
1047 if code_id == 2:
1029 codes_num = 7
1048 codes_num = 7
1030 elif code_id == 12:
1049 elif code_id == 12:
1031 codes_num = 15
1050 codes_num = 15
1032
1051
1033 #Jars filter values:
1052 #Jars filter values:
1034
1053
1035 clock = float(filter_parms['clock'])
1054 clock = float(filter_parms['clock'])
1036 filter_2 = int(filter_parms['cic_2'])
1055 filter_2 = int(filter_parms['cic_2'])
1037 filter_5 = int(filter_parms['cic_5'])
1056 filter_5 = int(filter_parms['cic_5'])
1038 filter_fir = int(filter_parms['fir'])
1057 filter_fir = int(filter_parms['fir'])
1039 Fs_MHz = clock/(filter_2*filter_5*filter_fir)
1058 Fs_MHz = clock/(filter_2*filter_5*filter_fir)
1040
1059
1041 #Jars values:
1060 #Jars values:
1042 if ipp is not None:
1061 if ipp is not None:
1043 IPP_units = ipp/0.15*Fs_MHz
1062 IPP_units = ipp/0.15*Fs_MHz
1044 IPP_us = IPP_units / Fs_MHz
1063 IPP_us = IPP_units / Fs_MHz
1045 IPP_s = IPP_units / (Fs_MHz * (10**6))
1064 IPP_s = IPP_units / (Fs_MHz * (10**6))
1046 Ts = 1/(Fs_MHz*(10**6))
1065 Ts = 1/(Fs_MHz*(10**6))
1047
1066
1048 Va = radar_lambda/(4*Ts*cohe_integr)
1067 Va = radar_lambda/(4*Ts*cohe_integr)
1049 rate_bh = ((nsa-codes_num)*channels_number*2 *
1068 rate_bh = ((nsa-codes_num)*channels_number*2 *
1050 bytes_/IPP_us)*(36*(10**8)/cohe_integr)
1069 bytes_/IPP_us)*(36*(10**8)/cohe_integr)
1051 rate_gh = rate_bh/(1024*1024*1024)
1070 rate_gh = rate_bh/(1024*1024*1024)
1052
1071
1053 conf['Time per Block'] = IPP_s * profiles_block * cohe_integr
1072 conf['Time per Block'] = IPP_s * profiles_block * cohe_integr
1054 conf['keys'].append('Time per Block')
1073 conf['keys'].append('Time per Block')
1055 conf['Acq time'] = IPP_s * acq_profiles
1074 conf['Acq time'] = IPP_s * acq_profiles
1056 conf['keys'].append('Acq time')
1075 conf['keys'].append('Acq time')
1057 conf['Data rate'] = str(rate_gh)+" (GB/h)"
1076 conf['Data rate'] = str(rate_gh)+" (GB/h)"
1058 conf['keys'].append('Data rate')
1077 conf['keys'].append('Data rate')
1059 conf['Va (m/s)'] = Va
1078 conf['Va (m/s)'] = Va
1060 conf['keys'].append('Va (m/s)')
1079 conf['keys'].append('Va (m/s)')
1061 conf['Vrange (m/s)'] = 3/(2*IPP_s*cohe_integr)
1080 conf['Vrange (m/s)'] = 3/(2*IPP_s*cohe_integr)
1062 conf['keys'].append('Vrange (m/s)')
1081 conf['keys'].append('Vrange (m/s)')
1063
1082
1064 kwargs['configurations'].append(conf)
1083 kwargs['configurations'].append(conf)
1065 kwargs['menu_experiments'] = 'active'
1084 kwargs['menu_experiments'] = 'active'
1066
1085
1067 ###### SIDEBAR ######
1086 ###### SIDEBAR ######
1068 kwargs.update(sidebar(experiment=experiment))
1087 kwargs.update(sidebar(experiment=experiment))
1069
1088
1070 return render(request, 'experiment_summary.html', kwargs)
1089 return render(request, 'experiment_summary.html', kwargs)
1071
1090
1072
1091
1073 @login_required
1092 @login_required
1074 def experiment_verify(request, id_exp):
1093 def experiment_verify(request, id_exp):
1075
1094
1076 experiment = get_object_or_404(Experiment, pk=id_exp)
1095 experiment = get_object_or_404(Experiment, pk=id_exp)
1077 experiment_data = experiment.parms_to_dict()
1096 experiment_data = experiment.parms_to_dict()
1078 configurations = Configuration.objects.filter(
1097 configurations = Configuration.objects.filter(
1079 experiment=experiment, type=0)
1098 experiment=experiment, type=0)
1080
1099
1081 kwargs = {}
1100 kwargs = {}
1082
1101
1083 kwargs['experiment_keys'] = ['template',
1102 kwargs['experiment_keys'] = ['template',
1084 'radar_system', 'name', 'start_time', 'end_time']
1103 'radar_system', 'name', 'start_time', 'end_time']
1085 kwargs['experiment'] = experiment
1104 kwargs['experiment'] = experiment
1086
1105
1087 kwargs['configuration_keys'] = ['name', 'device__ip_address',
1106 kwargs['configuration_keys'] = ['name', 'device__ip_address',
1088 'device__port_address', 'device__status']
1107 'device__port_address', 'device__status']
1089 kwargs['configurations'] = configurations
1108 kwargs['configurations'] = configurations
1090 kwargs['experiment_data'] = experiment_data
1109 kwargs['experiment_data'] = experiment_data
1091
1110
1092 kwargs['title'] = 'Verify Experiment'
1111 kwargs['title'] = 'Verify Experiment'
1093 kwargs['suptitle'] = 'Parameters'
1112 kwargs['suptitle'] = 'Parameters'
1094
1113
1095 kwargs['button'] = 'Update'
1114 kwargs['button'] = 'Update'
1096
1115
1097 jars_conf = False
1116 jars_conf = False
1098 rc_conf = False
1117 rc_conf = False
1099 dds_conf = False
1118 dds_conf = False
1100
1119
1101 for configuration in configurations:
1120 for configuration in configurations:
1102 #-------------------- JARS -----------------------:
1121 #-------------------- JARS -----------------------:
1103 if configuration.device.device_type.name == 'jars':
1122 if configuration.device.device_type.name == 'jars':
1104 jars_conf = True
1123 jars_conf = True
1105 jars = configuration
1124 jars = configuration
1106 kwargs['jars_conf'] = jars_conf
1125 kwargs['jars_conf'] = jars_conf
1107 filter_parms = json.loads(jars.filter_parms)
1126 filter_parms = json.loads(jars.filter_parms)
1108 kwargs['filter_parms'] = filter_parms
1127 kwargs['filter_parms'] = filter_parms
1109 #--Sampling Frequency
1128 #--Sampling Frequency
1110 clock = filter_parms['clock']
1129 clock = filter_parms['clock']
1111 filter_2 = filter_parms['cic_2']
1130 filter_2 = filter_parms['cic_2']
1112 filter_5 = filter_parms['cic_5']
1131 filter_5 = filter_parms['cic_5']
1113 filter_fir = filter_parms['fir']
1132 filter_fir = filter_parms['fir']
1114 samp_freq_jars = clock/filter_2/filter_5/filter_fir
1133 samp_freq_jars = clock/filter_2/filter_5/filter_fir
1115
1134
1116 kwargs['samp_freq_jars'] = samp_freq_jars
1135 kwargs['samp_freq_jars'] = samp_freq_jars
1117 kwargs['jars'] = configuration
1136 kwargs['jars'] = configuration
1118
1137
1119 #--------------------- RC ----------------------:
1138 #--------------------- RC ----------------------:
1120 if configuration.device.device_type.name == 'pedestal' and not configuration.mix:
1139 if configuration.device.device_type.name == 'pedestal' and not configuration.mix:
1121 rc_conf = True
1140 rc_conf = True
1122 rc = configuration
1141 rc = configuration
1123
1142
1124 rc_parms = configuration.parms_to_dict()
1143 rc_parms = configuration.parms_to_dict()
1125
1144
1126 win_lines = rc.get_lines(line_type__name='windows')
1145 win_lines = rc.get_lines(line_type__name='windows')
1127 if win_lines:
1146 if win_lines:
1128 dh = json.loads(win_lines[0].params)['params'][0]['resolution']
1147 dh = json.loads(win_lines[0].params)['params'][0]['resolution']
1129 #--Sampling Frequency
1148 #--Sampling Frequency
1130 samp_freq_rc = 0.15/dh
1149 samp_freq_rc = 0.15/dh
1131 kwargs['samp_freq_rc'] = samp_freq_rc
1150 kwargs['samp_freq_rc'] = samp_freq_rc
1132
1151
1133 kwargs['rc_conf'] = rc_conf
1152 kwargs['rc_conf'] = rc_conf
1134 kwargs['rc'] = configuration
1153 kwargs['rc'] = configuration
1135
1154
1136 #-------------------- DDS ----------------------:
1155 #-------------------- DDS ----------------------:
1137 if configuration.device.device_type.name == 'dds':
1156 if configuration.device.device_type.name == 'dds':
1138 dds_conf = True
1157 dds_conf = True
1139 dds = configuration
1158 dds = configuration
1140 dds_parms = configuration.parms_to_dict()
1159 dds_parms = configuration.parms_to_dict()
1141
1160
1142 kwargs['dds_conf'] = dds_conf
1161 kwargs['dds_conf'] = dds_conf
1143 kwargs['dds'] = configuration
1162 kwargs['dds'] = configuration
1144
1163
1145 #------------Validation------------:
1164 #------------Validation------------:
1146 #Clock
1165 #Clock
1147 if dds_conf and rc_conf and jars_conf:
1166 if dds_conf and rc_conf and jars_conf:
1148 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) and float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1167 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) and float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1149 messages.warning(request, "Devices don't have the same clock.")
1168 messages.warning(request, "Devices don't have the same clock.")
1150 elif rc_conf and jars_conf:
1169 elif rc_conf and jars_conf:
1151 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']):
1170 if float(filter_parms['clock']) != float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']):
1152 messages.warning(request, "Devices don't have the same clock.")
1171 messages.warning(request, "Devices don't have the same clock.")
1153 elif rc_conf and dds_conf:
1172 elif rc_conf and dds_conf:
1154 if float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1173 if float(rc_parms['configurations']['byId'][str(rc.pk)]['clock_in']) != float(dds_parms['configurations']['byId'][str(dds.pk)]['clock']):
1155 messages.warning(request, "Devices don't have the same clock.")
1174 messages.warning(request, "Devices don't have the same clock.")
1156 if float(samp_freq_rc) != float(dds_parms['configurations']['byId'][str(dds.pk)]['frequencyA']):
1175 if float(samp_freq_rc) != float(dds_parms['configurations']['byId'][str(dds.pk)]['frequencyA']):
1157 messages.warning(
1176 messages.warning(
1158 request, "Devices don't have the same Frequency A.")
1177 request, "Devices don't have the same Frequency A.")
1159
1178
1160 #------------POST METHOD------------:
1179 #------------POST METHOD------------:
1161 if request.method == 'POST':
1180 if request.method == 'POST':
1162 if request.POST['suggest_clock']:
1181 if request.POST['suggest_clock']:
1163 try:
1182 try:
1164 suggest_clock = float(request.POST['suggest_clock'])
1183 suggest_clock = float(request.POST['suggest_clock'])
1165 except:
1184 except:
1166 messages.warning(request, "Invalid value in CLOCK IN.")
1185 messages.warning(request, "Invalid value in CLOCK IN.")
1167 return redirect('url_verify_experiment', id_exp=experiment.id)
1186 return redirect('url_verify_experiment', id_exp=experiment.id)
1168 else:
1187 else:
1169 suggest_clock = ""
1188 suggest_clock = ""
1170 if suggest_clock:
1189 if suggest_clock:
1171 if rc_conf:
1190 if rc_conf:
1172 rc.clock_in = suggest_clock
1191 rc.clock_in = suggest_clock
1173 rc.save()
1192 rc.save()
1174 if jars_conf:
1193 if jars_conf:
1175 filter_parms = jars.filter_parms
1194 filter_parms = jars.filter_parms
1176 filter_parms = ast.literal_eval(filter_parms)
1195 filter_parms = ast.literal_eval(filter_parms)
1177 filter_parms['clock'] = suggest_clock
1196 filter_parms['clock'] = suggest_clock
1178 jars.filter_parms = json.dumps(filter_parms)
1197 jars.filter_parms = json.dumps(filter_parms)
1179 jars.save()
1198 jars.save()
1180 kwargs['filter_parms'] = filter_parms
1199 kwargs['filter_parms'] = filter_parms
1181 if dds_conf:
1200 if dds_conf:
1182 dds.clock = suggest_clock
1201 dds.clock = suggest_clock
1183 dds.save()
1202 dds.save()
1184
1203
1185 if request.POST['suggest_frequencyA']:
1204 if request.POST['suggest_frequencyA']:
1186 try:
1205 try:
1187 suggest_frequencyA = float(request.POST['suggest_frequencyA'])
1206 suggest_frequencyA = float(request.POST['suggest_frequencyA'])
1188 except:
1207 except:
1189 messages.warning(request, "Invalid value in FREQUENCY A.")
1208 messages.warning(request, "Invalid value in FREQUENCY A.")
1190 return redirect('url_verify_experiment', id_exp=experiment.id)
1209 return redirect('url_verify_experiment', id_exp=experiment.id)
1191 else:
1210 else:
1192 suggest_frequencyA = ""
1211 suggest_frequencyA = ""
1193 if suggest_frequencyA:
1212 if suggest_frequencyA:
1194 if jars_conf:
1213 if jars_conf:
1195 filter_parms = jars.filter_parms
1214 filter_parms = jars.filter_parms
1196 filter_parms = ast.literal_eval(filter_parms)
1215 filter_parms = ast.literal_eval(filter_parms)
1197 filter_parms['fch'] = suggest_frequencyA
1216 filter_parms['fch'] = suggest_frequencyA
1198 jars.filter_parms = json.dumps(filter_parms)
1217 jars.filter_parms = json.dumps(filter_parms)
1199 jars.save()
1218 jars.save()
1200 kwargs['filter_parms'] = filter_parms
1219 kwargs['filter_parms'] = filter_parms
1201 if dds_conf:
1220 if dds_conf:
1202 dds.frequencyA_Mhz = request.POST['suggest_frequencyA']
1221 dds.frequencyA_Mhz = request.POST['suggest_frequencyA']
1203 dds.save()
1222 dds.save()
1204
1223
1205 kwargs['menu_experiments'] = 'active'
1224 kwargs['menu_experiments'] = 'active'
1206 kwargs.update(sidebar(experiment=experiment))
1225 kwargs.update(sidebar(experiment=experiment))
1207 return render(request, 'experiment_verify.html', kwargs)
1226 return render(request, 'experiment_verify.html', kwargs)
1208
1227
1209
1228
1210 def parse_mix_result(s):
1229 def parse_mix_result(s):
1211
1230
1212 values = s.split('-')
1231 values = s.split('-')
1213 html = 'EXP MOD OPE DELAY MASK\r\n'
1232 html = 'EXP MOD OPE DELAY MASK\r\n'
1214
1233
1215 if not values or values[0] in ('', ' '):
1234 if not values or values[0] in ('', ' '):
1216 return mark_safe(html)
1235 return mark_safe(html)
1217
1236
1218 for i, value in enumerate(values):
1237 for i, value in enumerate(values):
1219 if not value:
1238 if not value:
1220 continue
1239 continue
1221 pk, mode, operation, delay, mask = value.split('|')
1240 pk, mode, operation, delay, mask = value.split('|')
1222 conf = PedestalConfiguration.objects.get(pk=pk)
1241 conf = PedestalConfiguration.objects.get(pk=pk)
1223 if i == 0:
1242 if i == 0:
1224 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1243 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1225 conf.name,
1244 conf.name,
1226 mode,
1245 mode,
1227 ' ',
1246 ' ',
1228 delay,
1247 delay,
1229 mask)
1248 mask)
1230 else:
1249 else:
1231 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1250 html += '{:20.18}{:3}{:4}{:9}km{:>6}\r\n'.format(
1232 conf.name,
1251 conf.name,
1233 mode,
1252 mode,
1234 operation,
1253 operation,
1235 delay,
1254 delay,
1236 mask)
1255 mask)
1237
1256
1238 return mark_safe(html)
1257 return mark_safe(html)
1239
1258
1240
1259
1241 def parse_mask(l):
1260 def parse_mask(l):
1242
1261
1243 values = []
1262 values = []
1244
1263
1245 for x in range(16):
1264 for x in range(16):
1246 if '{}'.format(x) in l:
1265 if '{}'.format(x) in l:
1247 values.append(1)
1266 values.append(1)
1248 else:
1267 else:
1249 values.append(0)
1268 values.append(0)
1250
1269
1251 values.reverse()
1270 values.reverse()
1252
1271
1253 return int(''.join([str(x) for x in values]), 2)
1272 return int(''.join([str(x) for x in values]), 2)
1254
1273
1255
1274
1256 def dev_confs(request):
1275 def dev_confs(request):
1257
1276
1258 page = request.GET.get('page')
1277 page = request.GET.get('page')
1259 order = ('-programmed_date', )
1278 order = ('-programmed_date', )
1260 filters = request.GET.copy()
1279 filters = request.GET.copy()
1261 if 'my configurations' in filters:
1280 if 'my configurations' in filters:
1262 filters.pop('my configurations', None)
1281 filters.pop('my configurations', None)
1263 filters['mine'] = request.user.id
1282 filters['mine'] = request.user.id
1264 kwargs = get_paginator(Configuration, page, order, filters)
1283 kwargs = get_paginator(Configuration, page, order, filters)
1265 fields = ['tags', 'template', 'historical']
1284 fields = ['tags', 'template', 'historical']
1266 if request.user.is_authenticated:
1285 if request.user.is_authenticated:
1267 fields.append('my configurations')
1286 fields.append('my configurations')
1268 form = FilterForm(initial=request.GET, extra_fields=fields)
1287 form = FilterForm(initial=request.GET, extra_fields=fields)
1269 kwargs['keys'] = ['name', 'device', 'experiment',
1288 kwargs['keys'] = ['name', 'device',
1270 'type', 'programmed_date', 'actions']
1289 'type', 'programmed_date', 'actions']
1271 kwargs['title'] = 'Configuration'
1290 kwargs['title'] = 'Configuration'
1272 kwargs['suptitle'] = 'List'
1291 kwargs['suptitle'] = 'List'
1273 kwargs['no_sidebar'] = True
1292 kwargs['no_sidebar'] = True
1274 kwargs['form'] = form
1293 kwargs['form'] = form
1275 kwargs['add_url'] = reverse('url_add_dev_conf', args=[0])
1294 kwargs['add_url'] = reverse('url_add_dev_conf', args=[0])
1276 filters = request.GET.copy()
1295 filters = request.GET.copy()
1277 filters.pop('page', None)
1296 filters.pop('page', None)
1278 kwargs['q'] = urlencode(filters)
1297 kwargs['q'] = urlencode(filters)
1279 kwargs['menu_configurations'] = 'active'
1298 kwargs['menu_configurations'] = 'active'
1280
1299
1281 return render(request, 'base_list.html', kwargs)
1300 return render(request, 'base_list.html', kwargs)
1282
1301
1283
1302
1284 def dev_conf(request, id_conf):
1303 def dev_conf(request, id_conf):
1285
1304
1286 conf = get_object_or_404(Configuration, pk=id_conf)
1305 conf = get_object_or_404(Configuration, pk=id_conf)
1287
1306
1288 return redirect(conf.get_absolute_url())
1307 return redirect(conf.get_absolute_url())
1289
1308
1290
1309
1291 @login_required
1310 @login_required
1292 def dev_conf_new(request, id_exp=0, id_dev=0):
1311 def dev_conf_new(request, id_exp=0, id_dev=0):
1293
1312
1294 if not is_developer(request.user):
1313 if not is_developer(request.user):
1295 messages.error(
1314 messages.error(
1296 request, 'Developer required, to create new configurations')
1315 request, 'Developer required, to create new configurations')
1297 return redirect('index')
1316 return redirect('index')
1298
1317
1299 initial = {}
1318 initial = {}
1300 kwargs = {}
1319 kwargs = {}
1301
1320
1302 if id_exp != 0:
1321 if id_exp != 0:
1303 initial['experiment'] = id_exp
1322 initial['experiment'] = id_exp
1304
1323
1305 if id_dev != 0:
1324 if id_dev != 0:
1306 initial['device'] = id_dev
1325 initial['device'] = id_dev
1307
1326
1308 if request.method == 'GET':
1327 if request.method == 'GET':
1309
1328
1310 if id_dev:
1329 if id_dev:
1311 kwargs['button'] = 'Create'
1330 kwargs['button'] = 'Create'
1312 device = Device.objects.get(pk=id_dev)
1331 device = Device.objects.get(pk=id_dev)
1313 DevConfForm = CONF_FORMS[device.device_type.name]
1332 DevConfForm = CONF_FORMS[device.device_type.name]
1314 initial['name'] = request.GET['name']
1333 initial['name'] = request.GET['name']
1315 form = DevConfForm(initial=initial)
1334 form = DevConfForm(initial=initial)
1316 else:
1335 else:
1317 if 'template' in request.GET:
1336 if 'template' in request.GET:
1318 if request.GET['template'] == '0':
1337 if request.GET['template'] == '0':
1319 choices = [(conf.pk, '{}'.format(conf))
1338 choices = [(conf.pk, '{}'.format(conf))
1320 for conf in Configuration.objects.filter(template=True)]
1339 for conf in Configuration.objects.filter(template=True)]
1321 form = NewForm(initial={'create_from': 2},
1340 form = NewForm(initial={'create_from': 2},
1322 template_choices=choices)
1341 template_choices=choices)
1323 else:
1342 else:
1324 kwargs['button'] = 'Create'
1343 kwargs['button'] = 'Create'
1325 conf = Configuration.objects.get(
1344 conf = Configuration.objects.get(
1326 pk=request.GET['template'])
1345 pk=request.GET['template'])
1327 id_dev = conf.device.pk
1346 id_dev = conf.device.pk
1328 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1347 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1329 form = DevConfForm(instance=conf,
1348 form = DevConfForm(instance=conf,
1330 initial={'name': '{}_{:%y%m%d}'.format(conf.name, datetime.now()),
1349 initial={'name': '{}_{:%y%m%d}'.format(conf.name, datetime.now()),
1331 'template': False,
1350 'template': False,
1332 'experiment': id_exp})
1351 'experiment': id_exp})
1333 elif 'blank' in request.GET:
1352 elif 'blank' in request.GET:
1334 kwargs['button'] = 'Create'
1353 kwargs['button'] = 'Create'
1335 form = ConfigurationForm(initial=initial)
1354 form = ConfigurationForm(initial=initial)
1336 else:
1355 else:
1337 form = NewForm()
1356 form = NewForm()
1338
1357
1339 if request.method == 'POST':
1358 if request.method == 'POST':
1340
1359
1341 device = Device.objects.get(pk=request.POST['device'])
1360 device = Device.objects.get(pk=request.POST['device'])
1342 DevConfForm = CONF_FORMS[device.device_type.name]
1361 DevConfForm = CONF_FORMS[device.device_type.name]
1343
1362
1344 form = DevConfForm(request.POST)
1363 form = DevConfForm(request.POST)
1345 kwargs['button'] = 'Create'
1364 kwargs['button'] = 'Create'
1346 if form.is_valid():
1365 if form.is_valid():
1347 conf = form.save(commit=False)
1366 conf = form.save(commit=False)
1348 conf.author = request.user
1367 conf.author = request.user
1349 conf.save()
1368 conf.save()
1350 return redirect('url_dev_conf', id_conf=conf.pk)
1369 return redirect('url_dev_conf', id_conf=conf.pk)
1351
1370
1352 kwargs['id_exp'] = id_exp
1371 kwargs['id_exp'] = id_exp
1353 kwargs['form'] = form
1372 kwargs['form'] = form
1354 kwargs['title'] = 'Configuration'
1373 kwargs['title'] = 'Configuration'
1355 kwargs['suptitle'] = 'New'
1374 kwargs['suptitle'] = 'New'
1356 kwargs['menu_configurations'] = 'active'
1375 kwargs['menu_configurations'] = 'active'
1357
1376
1358 if id_dev != 0:
1377 if id_dev != 0:
1359 device = Device.objects.get(pk=id_dev)
1378 device = Device.objects.get(pk=id_dev)
1360 kwargs['device'] = device.device_type.name
1379 kwargs['device'] = device.device_type.name
1361 return render(request, 'dev_conf_edit.html', kwargs)
1380 return render(request, 'dev_conf_edit.html', kwargs)
1362
1381
1363
1382
1364 @login_required
1383 @login_required
1365 def dev_conf_edit(request, id_conf):
1384 def dev_conf_edit(request, id_conf):
1366
1385
1367 conf = get_object_or_404(Configuration, pk=id_conf)
1386 conf = get_object_or_404(Configuration, pk=id_conf)
1368
1387
1369 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1388 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1370
1389
1371 if request.method == 'GET':
1390 if request.method == 'GET':
1372 form = DevConfForm(instance=conf)
1391 form = DevConfForm(instance=conf)
1373
1392
1374 if request.method == 'POST':
1393 if request.method == 'POST':
1375 form = DevConfForm(request.POST, instance=conf)
1394 form = DevConfForm(request.POST, instance=conf)
1376
1395
1377 if form.is_valid():
1396 if form.is_valid():
1378 form.save()
1397 form.save()
1379 return redirect('url_dev_conf', id_conf=id_conf)
1398 return redirect('url_dev_conf', id_conf=id_conf)
1380
1399
1381 kwargs = {}
1400 kwargs = {}
1382 kwargs['form'] = form
1401 kwargs['form'] = form
1383 kwargs['title'] = 'Device Configuration'
1402 kwargs['title'] = 'Device Configuration'
1384 kwargs['suptitle'] = 'Edit'
1403 kwargs['suptitle'] = 'Edit'
1385 kwargs['button'] = 'Update'
1404 kwargs['button'] = 'Update'
1386 kwargs['menu_configurations'] = 'active'
1405 kwargs['menu_configurations'] = 'active'
1387
1406
1388 ###### SIDEBAR ######
1407 ###### SIDEBAR ######
1389 kwargs.update(sidebar(conf=conf))
1408 kwargs.update(sidebar(conf=conf))
1390
1409
1391 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1410 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1392
1411
1393
1412
1394 @login_required
1413 @login_required
1395 def dev_conf_start(request, id_conf):
1414 def dev_conf_start(request, id_conf):
1396
1415
1397 conf = get_object_or_404(Configuration, pk=id_conf)
1416 conf = get_object_or_404(Configuration, pk=id_conf)
1398
1417
1399 if conf.start_device():
1418 if conf.start_device():
1400 messages.success(request, conf.message)
1419 messages.success(request, conf.message)
1401 else:
1420 else:
1402 messages.error(request, conf.message)
1421 messages.error(request, conf.message)
1403
1422
1404 #conf.status_device()
1423 #conf.status_device()
1405
1424
1406 return redirect(conf.get_absolute_url())
1425 return redirect(conf.get_absolute_url())
1407
1426
1408
1427
1409 @login_required
1428 @login_required
1410 def dev_conf_stop(request, id_conf):
1429 def dev_conf_stop(request, id_conf):
1411
1430
1412 conf = get_object_or_404(Configuration, pk=id_conf)
1431 conf = get_object_or_404(Configuration, pk=id_conf)
1413
1432
1414 if conf.stop_device():
1433 if conf.stop_device():
1415 messages.success(request, conf.message)
1434 messages.success(request, conf.message)
1416 else:
1435 else:
1417 messages.error(request, conf.message)
1436 messages.error(request, conf.message)
1418
1437
1419 #conf.status_device()
1438 #conf.status_device()
1420
1439
1421 return redirect(conf.get_absolute_url())
1440 return redirect(conf.get_absolute_url())
1422
1441
1423
1442
1424 @login_required
1443 @login_required
1425 def dev_conf_status(request, id_conf):
1444 def dev_conf_status(request, id_conf):
1426
1445
1427 conf = get_object_or_404(Configuration, pk=id_conf)
1446 conf = get_object_or_404(Configuration, pk=id_conf)
1428
1447
1429 conf_active = Configuration.objects.filter(pk=conf.device.conf_active).first()
1448 conf_active = Configuration.objects.filter(pk=conf.device.conf_active).first()
1430 if conf_active!=conf:
1449 if conf_active!=conf:
1431 url = '#' if conf_active is None else conf_active.get_absolute_url()
1450 url = '#' if conf_active is None else conf_active.get_absolute_url()
1432 label = 'None' if conf_active is None else conf_active.label
1451 label = 'None' if conf_active is None else conf_active.label
1433 messages.warning(
1452 messages.warning(
1434 request,
1453 request,
1435 mark_safe('The current configuration has not been written to device, the active configuration is <a href="{}">{}</a>'.format(
1454 mark_safe('The current configuration has not been written to device, the active configuration is <a href="{}">{}</a>'.format(
1436 url,
1455 url,
1437 label
1456 label
1438 ))
1457 ))
1439 )
1458 )
1440
1459
1441 return redirect(conf.get_absolute_url())
1460 return redirect(conf.get_absolute_url())
1442
1461
1443 if conf.status_device():
1462 if conf.status_device():
1444 messages.success(request, conf.message)
1463 messages.success(request, conf.message)
1445 else:
1464 else:
1446 messages.error(request, conf.message)
1465 messages.error(request, conf.message)
1447
1466
1448 return redirect(conf.get_absolute_url())
1467 return redirect(conf.get_absolute_url())
1449
1468
1450
1469
1451 @login_required
1470 @login_required
1452 def dev_conf_reset(request, id_conf):
1471 def dev_conf_reset(request, id_conf):
1453
1472
1454 conf = get_object_or_404(Configuration, pk=id_conf)
1473 conf = get_object_or_404(Configuration, pk=id_conf)
1455
1474
1456 if conf.reset_device():
1475 if conf.reset_device():
1457 messages.success(request, conf.message)
1476 messages.success(request, conf.message)
1458 else:
1477 else:
1459 messages.error(request, conf.message)
1478 messages.error(request, conf.message)
1460
1479
1461 return redirect(conf.get_absolute_url())
1480 return redirect(conf.get_absolute_url())
1462
1481
1463
1482
1464 @login_required
1483 @login_required
1465 def dev_conf_write(request, id_conf):
1484 def dev_conf_write(request, id_conf):
1466
1485
1467 conf = get_object_or_404(Configuration, pk=id_conf)
1486 conf = get_object_or_404(Configuration, pk=id_conf)
1468
1487
1469 if request.method == 'POST':
1488 if request.method == 'POST':
1470 if conf.write_device():
1489 if conf.write_device():
1471 conf.device.conf_active = conf.pk
1490 conf.device.conf_active = conf.pk
1472 conf.device.save()
1491 conf.device.save()
1473 messages.success(request, conf.message)
1492 messages.success(request, conf.message)
1474 if has_been_modified(conf):
1493 if has_been_modified(conf):
1475 conf.clone(type=1, template=False)
1494 conf.clone(type=1, template=False)
1476 else:
1495 else:
1477 messages.error(request, conf.message)
1496 messages.error(request, conf.message)
1478
1497
1479 return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1498 return redirect(get_object_or_404(Configuration, pk=id_conf).get_absolute_url())
1480
1499
1481 kwargs = {
1500 kwargs = {
1482 'title': 'Write Configuration',
1501 'title': 'Write Configuration',
1483 'suptitle': conf.label,
1502 'suptitle': conf.label,
1484 'message': 'Are you sure yo want to write this {} configuration?'.format(conf.device),
1503 'message': 'Are you sure yo want to write this {} configuration?'.format(conf.device),
1485 'delete': False
1504 'delete': False
1486 }
1505 }
1487 kwargs['menu_configurations'] = 'active'
1506 kwargs['menu_configurations'] = 'active'
1488
1507
1489 return render(request, 'confirm.html', kwargs)
1508 return render(request, 'confirm.html', kwargs)
1490
1509
1491
1510
1492 @login_required
1511 @login_required
1493 def dev_conf_read(request, id_conf):
1512 def dev_conf_read(request, id_conf):
1494
1513
1495 conf = get_object_or_404(Configuration, pk=id_conf)
1514 conf = get_object_or_404(Configuration, pk=id_conf)
1496
1515
1497 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1516 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1498
1517
1499 if request.method == 'GET':
1518 if request.method == 'GET':
1500 parms = conf.read_device()
1519 parms = conf.read_device()
1501 #conf.status_device()
1520 #conf.status_device()
1502
1521
1503 if not parms:
1522 if not parms:
1504 messages.error(request, conf.message)
1523 messages.error(request, conf.message)
1505 return redirect(conf.get_absolute_url())
1524 return redirect(conf.get_absolute_url())
1506
1525
1507 form = DevConfForm(initial=parms, instance=conf)
1526 form = DevConfForm(initial=parms, instance=conf)
1508
1527
1509 if request.method == 'POST':
1528 if request.method == 'POST':
1510 form = DevConfForm(request.POST, instance=conf)
1529 form = DevConfForm(request.POST, instance=conf)
1511
1530
1512 if form.is_valid():
1531 if form.is_valid():
1513 form.save()
1532 form.save()
1514 return redirect(conf.get_absolute_url())
1533 return redirect(conf.get_absolute_url())
1515
1534
1516 messages.error(request, "Parameters could not be saved")
1535 messages.error(request, "Parameters could not be saved")
1517
1536
1518 kwargs = {}
1537 kwargs = {}
1519 kwargs['id_dev'] = conf.id
1538 kwargs['id_dev'] = conf.id
1520 kwargs['form'] = form
1539 kwargs['form'] = form
1521 kwargs['title'] = 'Device Configuration'
1540 kwargs['title'] = 'Device Configuration'
1522 kwargs['suptitle'] = 'Parameters read from device'
1541 kwargs['suptitle'] = 'Parameters read from device'
1523 kwargs['button'] = 'Save'
1542 kwargs['button'] = 'Save'
1524
1543
1525 ###### SIDEBAR ######
1544 ###### SIDEBAR ######
1526 kwargs.update(sidebar(conf=conf))
1545 kwargs.update(sidebar(conf=conf))
1527
1546
1528 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1547 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1529
1548
1530
1549
1531 @login_required
1550 @login_required
1532 def dev_conf_import(request, id_conf):
1551 def dev_conf_import(request, id_conf):
1533
1552
1534 conf = get_object_or_404(Configuration, pk=id_conf)
1553 conf = get_object_or_404(Configuration, pk=id_conf)
1535 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1554 DevConfForm = CONF_FORMS[conf.device.device_type.name]
1536
1555
1537 if request.method == 'GET':
1556 if request.method == 'GET':
1538 file_form = UploadFileForm()
1557 file_form = UploadFileForm()
1539
1558
1540 if request.method == 'POST':
1559 if request.method == 'POST':
1541 file_form = UploadFileForm(request.POST, request.FILES)
1560 file_form = UploadFileForm(request.POST, request.FILES)
1542
1561
1543 if file_form.is_valid():
1562 if file_form.is_valid():
1544
1563
1545 data = conf.import_from_file(request.FILES['file'])
1564 data = conf.import_from_file(request.FILES['file'])
1546 parms = Params(data=data).get_conf(
1565 parms = Params(data=data).get_conf(
1547 dtype=conf.device.device_type.name)
1566 dtype=conf.device.device_type.name)
1548
1567
1549 if parms:
1568 if parms:
1550
1569
1551 form = DevConfForm(initial=parms, instance=conf)
1570 form = DevConfForm(initial=parms, instance=conf)
1552
1571
1553 kwargs = {}
1572 kwargs = {}
1554 kwargs['id_dev'] = conf.id
1573 kwargs['id_dev'] = conf.id
1555 kwargs['form'] = form
1574 kwargs['form'] = form
1556 kwargs['title'] = 'Device Configuration'
1575 kwargs['title'] = 'Device Configuration'
1557 kwargs['suptitle'] = 'Parameters imported'
1576 kwargs['suptitle'] = 'Parameters imported'
1558 kwargs['button'] = 'Save'
1577 kwargs['button'] = 'Save'
1559 kwargs['action'] = conf.get_absolute_url_edit()
1578 kwargs['action'] = conf.get_absolute_url_edit()
1560 kwargs['previous'] = conf.get_absolute_url()
1579 kwargs['previous'] = conf.get_absolute_url()
1561
1580
1562 ###### SIDEBAR ######
1581 ###### SIDEBAR ######
1563 kwargs.update(sidebar(conf=conf))
1582 kwargs.update(sidebar(conf=conf))
1564
1583
1565 messages.success(
1584 messages.success(
1566 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
1585 request, "Parameters imported from: '%s'." % request.FILES['file'].name)
1567
1586
1568 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1587 return render(request, '%s_conf_edit.html' % conf.device.device_type.name, kwargs)
1569
1588
1570 messages.error(request, "Could not import parameters from file")
1589 messages.error(request, "Could not import parameters from file")
1571
1590
1572 kwargs = {}
1591 kwargs = {}
1573 kwargs['id_dev'] = conf.id
1592 kwargs['id_dev'] = conf.id
1574 kwargs['title'] = 'Device Configuration'
1593 kwargs['title'] = 'Device Configuration'
1575 kwargs['form'] = file_form
1594 kwargs['form'] = file_form
1576 kwargs['suptitle'] = 'Importing file'
1595 kwargs['suptitle'] = 'Importing file'
1577 kwargs['button'] = 'Import'
1596 kwargs['button'] = 'Import'
1578 kwargs['menu_configurations'] = 'active'
1597 kwargs['menu_configurations'] = 'active'
1579
1598
1580 kwargs.update(sidebar(conf=conf))
1599 kwargs.update(sidebar(conf=conf))
1581
1600
1582 return render(request, 'dev_conf_import.html', kwargs)
1601 return render(request, 'dev_conf_import.html', kwargs)
1583
1602
1584
1603
1585 @login_required
1604 @login_required
1586 def dev_conf_export(request, id_conf):
1605 def dev_conf_export(request, id_conf):
1587
1606
1588 conf = get_object_or_404(Configuration, pk=id_conf)
1607 conf = get_object_or_404(Configuration, pk=id_conf)
1589
1608
1590 if request.method == 'GET':
1609 if request.method == 'GET':
1591 file_form = DownloadFileForm(conf.device.device_type.name)
1610 file_form = DownloadFileForm(conf.device.device_type.name)
1592
1611
1593 if request.method == 'POST':
1612 if request.method == 'POST':
1594 file_form = DownloadFileForm(
1613 file_form = DownloadFileForm(
1595 conf.device.device_type.name, request.POST)
1614 conf.device.device_type.name, request.POST)
1596
1615
1597 if file_form.is_valid():
1616 if file_form.is_valid():
1598 fields = conf.export_to_file(
1617 fields = conf.export_to_file(
1599 format=file_form.cleaned_data['format'])
1618 format=file_form.cleaned_data['format'])
1619
1600 if not fields['content']:
1620 if not fields['content']:
1601 messages.error(request, conf.message)
1621 messages.error(request, conf.message)
1602 return redirect(conf.get_absolute_url_export())
1622 return redirect(conf.get_absolute_url_export())
1603 response = HttpResponse(content_type=fields['content_type'])
1623 response = HttpResponse(content_type=fields['content_type'])
1604 response['Content-Disposition'] = 'attachment; filename="%s"' % fields['filename']
1624 response['Content-Disposition'] = 'attachment; filename="%s"' % fields['filename']
1605 response.write(fields['content'])
1625 response.write(fields['content'])
1606
1626
1607 return response
1627 return response
1608
1628
1609 messages.error(request, "Could not export parameters")
1629 messages.error(request, "Could not export parameters")
1610
1630
1611 kwargs = {}
1631 kwargs = {}
1612 kwargs['id_dev'] = conf.id
1632 kwargs['id_dev'] = conf.id
1613 kwargs['title'] = 'Device Configuration'
1633 kwargs['title'] = 'Device Configuration'
1614 kwargs['form'] = file_form
1634 kwargs['form'] = file_form
1615 kwargs['suptitle'] = 'Exporting file'
1635 kwargs['suptitle'] = 'Exporting file'
1616 kwargs['button'] = 'Export'
1636 kwargs['button'] = 'Export'
1617 kwargs['menu_configurations'] = 'active'
1637 kwargs['menu_configurations'] = 'active'
1618
1638
1619 return render(request, 'dev_conf_export.html', kwargs)
1639 return render(request, 'dev_conf_export.html', kwargs)
1620
1640
1621
1641
1622 @login_required
1642 @login_required
1623 def dev_conf_delete(request, id_conf):
1643 def dev_conf_delete(request, id_conf):
1624
1644 print("Está aquí")
1625 conf = get_object_or_404(Configuration, pk=id_conf)
1645 conf = get_object_or_404(Configuration, pk=id_conf)
1626
1646
1627 if request.method == 'POST':
1647 if request.method == 'POST':
1628 if is_developer(request.user):
1648 if is_developer(request.user):
1649 try:
1629 conf.delete()
1650 conf.delete()
1651 except Exception as e:
1652 messages.error(request, "The device configuration is protected")
1630 return redirect('url_dev_confs')
1653 return redirect('url_dev_confs')
1631
1654
1632 messages.error(request, 'Not enough permission to delete this object')
1655 messages.error(request, 'Not enough permission to delete this object')
1633 return redirect(conf.get_absolute_url())
1656 return redirect(conf.get_absolute_url())
1634
1657
1635 kwargs = {
1658 kwargs = {
1636 'title': 'Delete',
1659 'title': 'Delete',
1637 'suptitle': 'Configuration',
1660 'suptitle': 'Configuration',
1638 'object': conf,
1661 'object': conf,
1639 'delete': True
1662 'delete': True
1640 }
1663 }
1641 kwargs['menu_configurations'] = 'active'
1664 kwargs['menu_configurations'] = 'active'
1642
1665
1643 return render(request, 'confirm.html', kwargs)
1666 return render(request, 'confirm.html', kwargs)
1644
1667
1645
1668
1646 def sidebar(**kwargs):
1669 def sidebar(**kwargs):
1647
1670
1648 side_data = {}
1671 side_data = {}
1649
1672
1650 conf = kwargs.get('conf', None)
1673 conf = kwargs.get('conf', None)
1651 experiment = kwargs.get('experiment', None)
1674 experiment = kwargs.get('experiment', None)
1652
1675
1653 if not experiment:
1676 #if not experiment:
1654 experiment = conf.experiment
1677 #experiment = conf.experiment
1655
1678
1656 if experiment:
1679 if experiment:
1657 side_data['experiment'] = experiment
1680 side_data['experiment'] = experiment
1658 campaign = experiment.campaign_set.all()
1681 campaign = experiment.campaign_set.all()
1659 if campaign:
1682 if campaign:
1660 side_data['campaign'] = campaign[0]
1683 side_data['campaign'] = campaign[0]
1661 experiments = campaign[0].experiments.all().order_by('name')
1684 experiments = campaign[0].experiments.all().order_by('name')
1662 else:
1685 else:
1663 experiments = [experiment]
1686 experiments = [experiment]
1664 configurations = experiment.configuration_set.filter(type=0)
1687 #configurations = experiment.configuration_set.filter(type=0)
1665 side_data['side_experiments'] = experiments
1688 side_data['side_experiments'] = experiments
1666 side_data['side_configurations'] = configurations.order_by(
1689 #side_data['side_configurations'] = configurations.order_by('device__device_type__name')
1667 'device__device_type__name')
1668
1690
1669 return side_data
1691 return side_data
1670
1692
1671
1693
1672 def get_paginator(model, page, order, filters={}, n=8):
1694 def get_paginator(model, page, order, filters={}, n=8):
1673
1695
1674 kwargs = {}
1696 kwargs = {}
1675 query = Q()
1697 query = Q()
1676 if isinstance(filters, QueryDict):
1698 if isinstance(filters, QueryDict):
1677 filters = filters.dict()
1699 filters = filters.dict()
1678 [filters.pop(key) for key in list(filters) if filters[key] in ('', ' ')]
1700 [filters.pop(key) for key in list(filters) if filters[key] in ('', ' ')]
1679 filters.pop('page', None)
1701 filters.pop('page', None)
1680
1702
1681 fields = [f.name for f in model._meta.get_fields()]
1703 fields = [f.name for f in model._meta.get_fields()]
1682
1704
1683 if 'template' in filters:
1705 if 'template' in filters:
1684 filters['template'] = True
1706 filters['template'] = True
1685 if 'historical' in filters:
1707 if 'historical' in filters:
1686 filters.pop('historical')
1708 filters.pop('historical')
1687 filters['type'] = 1
1709 filters['type'] = 1
1688 elif 'type' in fields:
1710 elif 'type' in fields:
1689 filters['type'] = 0
1711 filters['type'] = 0
1690 if 'start_date' in filters:
1712 if 'start_date' in filters:
1691 filters['start_date__gte'] = filters.pop('start_date')
1713 filters['start_date__gte'] = filters.pop('start_date')
1692 if 'end_date' in filters:
1714 if 'end_date' in filters:
1693 filters['start_date__lte'] = filters.pop('end_date')
1715 filters['start_date__lte'] = filters.pop('end_date')
1694 if 'tags' in filters:
1716 if 'tags' in filters:
1695 tags = filters.pop('tags')
1717 tags = filters.pop('tags')
1696 if 'tags' in fields:
1718 if 'tags' in fields:
1697 query = query | Q(tags__icontains=tags)
1719 query = query | Q(tags__icontains=tags)
1698 if 'label' in fields:
1720 if 'label' in fields:
1699 query = query | Q(label__icontains=tags)
1721 query = query | Q(label__icontains=tags)
1700 if 'location' in fields:
1722 if 'location' in fields:
1701 query = query | Q(location__name__icontains=tags)
1723 query = query | Q(location__name__icontains=tags)
1702 if 'device' in fields:
1724 if 'device' in fields:
1703 query = query | Q(device__device_type__name__icontains=tags)
1725 query = query | Q(device__device_type__name__icontains=tags)
1704 query = query | Q(device__location__name__icontains=tags)
1726 query = query | Q(device__location__name__icontains=tags)
1705 if 'device_type' in fields:
1727 if 'device_type' in fields:
1706 query = query | Q(device_type__name__icontains=tags)
1728 query = query | Q(device_type__name__icontains=tags)
1707
1729
1708 if 'mine' in filters:
1730 if 'mine' in filters:
1709 filters['author_id'] = filters['mine']
1731 filters['author_id'] = filters['mine']
1710 filters.pop('mine')
1732 filters.pop('mine')
1711 object_list = model.objects.filter(query, **filters).order_by(*order)
1733 object_list = model.objects.filter(query, **filters).order_by(*order)
1712 paginator = Paginator(object_list, n)
1734 paginator = Paginator(object_list, n)
1713
1735
1714 try:
1736 try:
1715 objects = paginator.page(page)
1737 objects = paginator.page(page)
1716 except PageNotAnInteger:
1738 except PageNotAnInteger:
1717 objects = paginator.page(1)
1739 objects = paginator.page(1)
1718 except EmptyPage:
1740 except EmptyPage:
1719 objects = paginator.page(paginator.num_pages)
1741 objects = paginator.page(paginator.num_pages)
1720
1742
1721 kwargs['objects'] = objects
1743 kwargs['objects'] = objects
1722 kwargs['offset'] = (int(page)-1)*n if page else 0
1744 kwargs['offset'] = (int(page)-1)*n if page else 0
1723
1745
1724 return kwargs
1746 return kwargs
1725
1747
1726
1748
1727 def operation(request, id_camp=None):
1749 def operation(request, id_camp=None):
1728
1750
1729 kwargs = {}
1751 kwargs = {}
1730 kwargs['title'] = 'Radars Operation'
1752 kwargs['title'] = 'Radars Operation'
1731 kwargs['no_sidebar'] = True
1753 kwargs['no_sidebar'] = True
1732 kwargs['menu_operation'] = 'active'
1754 kwargs['menu_operation'] = 'active'
1733 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1755 campaigns = Campaign.objects.filter(start_date__lte=datetime.now(),
1734 end_date__gte=datetime.now()).order_by('-start_date')
1756 end_date__gte=datetime.now()).order_by('-start_date')
1735
1757
1736 if id_camp:
1758 if id_camp:
1737 campaign = get_object_or_404(Campaign, pk=id_camp)
1759 campaign = get_object_or_404(Campaign, pk=id_camp)
1738 form = OperationForm(
1760 form = OperationForm(
1739 initial={'campaign': campaign.id}, campaigns=campaigns)
1761 initial={'campaign': campaign.id}, campaigns=campaigns)
1740 kwargs['campaign'] = campaign
1762 kwargs['campaign'] = campaign
1741 else:
1763 else:
1742 # form = OperationForm(campaigns=campaigns)
1764 # form = OperationForm(campaigns=campaigns)
1743 kwargs['campaigns'] = campaigns
1765 kwargs['campaigns'] = campaigns
1744 return render(request, 'operation.html', kwargs)
1766 return render(request, 'operation.html', kwargs)
1745
1767
1746 #---Experiment
1768 #---Experiment
1747 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1769 keys = ['id', 'name', 'start_time', 'end_time', 'status']
1748 kwargs['experiment_keys'] = keys[1:]
1770 kwargs['experiment_keys'] = keys[1:]
1749 kwargs['experiments'] = experiments
1771 kwargs['experiments'] = experiments
1750 #---Radar
1772 #---Radar
1751 kwargs['locations'] = campaign.get_experiments_by_radar()
1773 kwargs['locations'] = campaign.get_experiments_by_radar()
1752 kwargs['form'] = form
1774 kwargs['form'] = form
1753
1775
1754 return render(request, 'operation.html', kwargs)
1776 return render(request, 'operation.html', kwargs)
1755
1777
1756
1778
1757 @login_required
1779 @login_required
1758 def radar_start(request, id_camp, id_radar):
1780 def radar_start(request, id_camp, id_radar):
1759
1781
1760 campaign = get_object_or_404(Campaign, pk=id_camp)
1782 campaign = get_object_or_404(Campaign, pk=id_camp)
1761 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1783 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1762 now = datetime.now()
1784 now = datetime.now()
1763
1785
1764 for exp in experiments:
1786 for exp in experiments:
1765 #app.control.revoke(exp.task)
1787 #app.control.revoke(exp.task)
1766 print(exp.status)
1788 print(exp.status)
1767 start = datetime.combine(datetime.now().date(), exp.start_time)
1789 start = datetime.combine(datetime.now().date(), exp.start_time)
1768 end = datetime.combine(datetime.now().date(), exp.end_time)
1790 end = datetime.combine(datetime.now().date(), exp.end_time)
1769 print(exp.start_time)
1791 print(exp.start_time)
1770 print(exp.end_time)
1792 print(exp.end_time)
1771
1793
1772 print(start)
1794 print(start)
1773 print(end)
1795 print(end)
1774 print(is_aware(start))
1796 print(is_aware(start))
1775 print(campaign.start_date)
1797 print(campaign.start_date)
1776 print(campaign.end_date)
1798 print(campaign.end_date)
1777 print(is_aware(campaign.start_date))
1799 print(is_aware(campaign.start_date))
1778 if end < start:
1800 if end < start:
1779 end += timedelta(1)
1801 end += timedelta(1)
1780
1802
1781 if exp.status == 2:
1803 if exp.status == 2:
1782 messages.warning(
1804 messages.warning(
1783 request, 'Experiment {} already running'.format(exp))
1805 request, 'Experiment {} already running'.format(exp))
1784 continue
1806 continue
1785
1807
1786 if exp.status == 3:
1808 if exp.status == 3:
1787 messages.warning(
1809 messages.warning(
1788 request, 'Experiment {} already programmed'.format(exp))
1810 request, 'Experiment {} already programmed'.format(exp))
1789 continue
1811 continue
1790
1812
1791 if start > campaign.end_date or start < campaign.start_date:
1813 if start > campaign.end_date or start < campaign.start_date:
1792 messages.warning(request, 'Experiment {} out of date'.format(exp))
1814 messages.warning(request, 'Experiment {} out of date'.format(exp))
1793 continue
1815 continue
1794
1816
1795 app.control.revoke(exp.task)
1817 app.control.revoke(exp.task)
1796 print("Llego luego del revoke")
1818 print("Llego luego del revoke")
1797 if now > start and now <= end:
1819 if now > start and now <= end:
1798 print("Caso now >start and <end")
1820 print("Caso now >start and <end")
1799 task = task_start.delay(exp.id)
1821 task = task_start.delay(exp.id)
1800 exp.status = task.wait()
1822 exp.status = task.wait()
1801 if exp.status == 0:
1823 if exp.status == 0:
1802 messages.error(request, 'Experiment {} not start'.format(exp))
1824 messages.error(request, 'Experiment {} not start'.format(exp))
1803 if exp.status == 2:
1825 if exp.status == 2:
1804 messages.success(request, 'Experiment {} started'.format(exp))
1826 messages.success(request, 'Experiment {} started'.format(exp))
1805 else:
1827 else:
1806 print("Caso now < start o >end")
1828 print("Caso now < start o >end")
1807 task = task_start.apply_async((exp.pk, ), eta=start)#start+timedelta(hours=5))
1829 task = task_start.apply_async((exp.pk, ), eta=start)#start+timedelta(hours=5))
1808 exp.task = task.id
1830 exp.task = task.id
1809 exp.status = 3
1831 exp.status = 3
1810 messages.success(request, 'Experiment {} programmed to start at {}'.format(exp, start))
1832 messages.success(request, 'Experiment {} programmed to start at {}'.format(exp, start))
1811
1833
1812 exp.save()
1834 exp.save()
1813
1835
1814 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1836 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1815
1837
1816
1838
1817 @login_required
1839 @login_required
1818 def radar_stop(request, id_camp, id_radar):
1840 def radar_stop(request, id_camp, id_radar):
1819
1841
1820 campaign = get_object_or_404(Campaign, pk=id_camp)
1842 campaign = get_object_or_404(Campaign, pk=id_camp)
1821 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1843 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1822 print("Ingreso en stop radar_stop")
1844 print("Ingreso en stop radar_stop")
1823 for exp in experiments:
1845 for exp in experiments:
1824
1846
1825 if exp.task:
1847 if exp.task:
1826 print("Ingreso antes de revoke stop")
1848 print("Ingreso antes de revoke stop")
1827 app.control.revoke(exp.task)
1849 app.control.revoke(exp.task)
1828
1850
1829
1851
1830 if exp.status == 2: #status 2 es started
1852 if exp.status == 2: #status 2 es started
1831 print("llama a exp.stop")
1853 print("llama a exp.stop")
1832 exp.stop()
1854 exp.stop()
1833 messages.warning(request, 'Experiment {} stopped'.format(exp))
1855 messages.warning(request, 'Experiment {} stopped'.format(exp))
1834 exp.status = 1
1856 exp.status = 1
1835 exp.save()
1857 exp.save()
1836
1858
1837 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1859 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1838
1860
1839
1861
1840 @login_required
1862 @login_required
1841 def radar_refresh(request, id_camp, id_radar):
1863 def radar_refresh(request, id_camp, id_radar):
1842
1864
1843 campaign = get_object_or_404(Campaign, pk=id_camp)
1865 campaign = get_object_or_404(Campaign, pk=id_camp)
1844 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1866 experiments = campaign.get_experiments_by_radar(id_radar)[0]['experiments']
1845
1867
1846 i = app.control.inspect()
1868 i = app.control.inspect()
1847 print(i)
1869 print(i)
1848 print(i.scheduled())
1870 print(i.scheduled())
1849 print(i.scheduled().values())
1871 print(i.scheduled().values())
1850 scheduled = list(i.scheduled().values())[0]
1872 scheduled = list(i.scheduled().values())[0]
1851 revoked = list(i.revoked().values())[0]
1873 revoked = list(i.revoked().values())[0]
1852
1874
1853 for exp in experiments:
1875 for exp in experiments:
1854 if exp.task in revoked:
1876 if exp.task in revoked:
1855 exp.status = 1
1877 exp.status = 1
1856 elif exp.task in [t['request']['id'] for t in scheduled if 'task_stop' in t['request']['name']]:
1878 elif exp.task in [t['request']['id'] for t in scheduled if 'task_stop' in t['request']['name']]:
1857 exp.status = 2
1879 exp.status = 2
1858 elif exp.task in [t['request']['id'] for t in scheduled if 'task_start' in t['request']['name']]:
1880 elif exp.task in [t['request']['id'] for t in scheduled if 'task_start' in t['request']['name']]:
1859 exp.status = 3
1881 exp.status = 3
1860 else:
1882 else:
1861 exp.status = 4
1883 exp.status = 4
1862 exp.save()
1884 exp.save()
1863 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1885 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1864
1886
1865 @login_required
1887 @login_required
1866 def revoke_tasks(request, id_camp):
1888 def revoke_tasks(request, id_camp):
1867
1889
1868 i = app.control.inspect()
1890 i = app.control.inspect()
1869 scheduled = list(i.scheduled().values())[0]
1891 scheduled = list(i.scheduled().values())[0]
1870 revoked = list(i.revoked().values())[0]
1892 revoked = list(i.revoked().values())[0]
1871
1893
1872 for t in scheduled:
1894 for t in scheduled:
1873 if t['request']['id'] in revoked:
1895 if t['request']['id'] in revoked:
1874 continue
1896 continue
1875 app.control.revoke(t['request']['id'])
1897 app.control.revoke(t['request']['id'])
1876 exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
1898 exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
1877 eta = t['eta']
1899 eta = t['eta']
1878 task = t['request']['name'].split('.')[-1]
1900 task = t['request']['name'].split('.')[-1]
1879 messages.warning(request, 'Scheduled {} at {} for experiment {} revoked'.format(task, eta, exp.name))
1901 messages.warning(request, 'Scheduled {} at {} for experiment {} revoked'.format(task, eta, exp.name))
1880
1902
1881 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1903 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1882
1904
1883 @login_required
1905 @login_required
1884 def show_tasks(request, id_camp):
1906 def show_tasks(request, id_camp):
1885
1907
1886 i = app.control.inspect()
1908 i = app.control.inspect()
1887 scheduled = list(i.scheduled().values())[0]
1909 scheduled = list(i.scheduled().values())[0]
1888 revoked = list(i.revoked().values())[0]
1910 revoked = list(i.revoked().values())[0]
1889
1911
1890 for t in scheduled:
1912 for t in scheduled:
1891 if t['request']['id'] in revoked:
1913 if t['request']['id'] in revoked:
1892 continue
1914 continue
1893 exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
1915 exp = Experiment.objects.get(pk=eval(str(t['request']['args']))[0])
1894 eta = t['eta']
1916 eta = t['eta']
1895 task = t['request']['name'].split('.')[-1]
1917 task = t['request']['name'].split('.')[-1]
1896 messages.success(request, 'Task {} scheduled at {} for experiment {}'.format(task, eta, exp.name))
1918 messages.success(request, 'Task {} scheduled at {} for experiment {}'.format(task, eta, exp.name))
1897
1919
1898 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1920 return HttpResponseRedirect(reverse('url_operation', args=[id_camp]))
1899
1921
1900 def real_time(request):
1922 def real_time(request):
1901
1923
1902 graphic_path = "/home/fiorella/Pictures/catwbeanie.jpg"
1924 graphic_path = "/home/fiorella/Pictures/catwbeanie.jpg"
1903
1925
1904 kwargs = {}
1926 kwargs = {}
1905 kwargs['title'] = 'CLAIRE'
1927 kwargs['title'] = 'CLAIRE'
1906 kwargs['suptitle'] = 'Real Time'
1928 kwargs['suptitle'] = 'Real Time'
1907 kwargs['no_sidebar'] = True
1929 kwargs['no_sidebar'] = True
1908 kwargs['graphic_path'] = graphic_path
1930 kwargs['graphic_path'] = graphic_path
1909 kwargs['graphic1_path'] = 'http://www.bluemaize.net/im/girls-accessories/shark-beanie-11.jpg'
1931 kwargs['graphic1_path'] = 'http://www.bluemaize.net/im/girls-accessories/shark-beanie-11.jpg'
1910
1932
1911 return render(request, 'real_time.html', kwargs)
1933 return render(request, 'real_time.html', kwargs)
1912
1934
1913 def theme(request, theme):
1935 def theme(request, theme):
1914
1936
1915 user = request.user
1937 user = request.user
1916 user.profile.theme = theme
1938 user.profile.theme = theme
1917 user.save()
1939 user.save()
1918 return redirect('index')
1940 return redirect('index')
@@ -1,80 +1,111
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 PedestalConfiguration
8 from .models import PedestalConfiguration
9
9
10 def create_choices_from_model(model, conf_id, all_choice=False):
10 def create_choices_from_model(model, conf_id, all_choice=False):
11
11
12 instance = globals()[model]
12 instance = globals()[model]
13 choices = instance.objects.all().values_list('pk', 'name')
13 choices = instance.objects.all().values_list('pk', 'name')
14
14
15 return choices
15 return choices
16
16
17 class PedestalConfigurationForm(forms.ModelForm):
17 class PedestalConfigurationForm(forms.ModelForm):
18
18
19 def __init__(self, *args, **kwargs):
19 def __init__(self, *args, **kwargs):
20 super(PedestalConfigurationForm, self).__init__(*args, **kwargs)
20 super(PedestalConfigurationForm, self).__init__(*args, **kwargs)
21
21
22 instance = getattr(self, 'instance', None)
22 instance = getattr(self, 'instance', None)
23
23
24 if instance and instance.pk:
24 if instance and instance.pk:
25
25
26 devices = Device.objects.filter(device_type__name='pedestal')
26 devices = Device.objects.filter(device_type__name='pedestal')
27 if instance.experiment:
27 #if instance.experiment:
28 self.fields['experiment'].widget.attrs['read_only'] = True
28 #self.fields['experiment'].widget.attrs['read_only'] = True
29 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
29 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
30 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
30 #self.fields['device'].widget.choices = [(device.id, device) for device in devices]
31
31
32 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
32 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
33 self.fields['experiment'].widget.attrs['readonly'] = True
33 self.fields['experiment'].widget.attrs['readonly'] = True
34
34
35 class Meta:
35 class Meta:
36 model = PedestalConfiguration
36 model = PedestalConfiguration
37 exclude = ('type', 'parameters', 'status', 'total_units', 'author', 'hash')
37 exclude = ('template', 'type', 'parameters', 'status', 'total_units', 'author', 'hash')
38
38
39 def clean(self):
39 def clean(self):
40 form_data = super(PedestalConfigurationForm, self).clean()
40 form_data = super(PedestalConfigurationForm, self).clean()
41 return form_data
41 return form_data
42
42
43 def save(self, *args, **kwargs):
43 def save(self, *args, **kwargs):
44 conf = super(PedestalConfigurationForm, self).save(*args, **kwargs)
44 conf = super(PedestalConfigurationForm, self).save(*args, **kwargs)
45 conf.save()
45 conf.save()
46 return conf
46 return conf
47
47
48 class PedestalEditionForm(forms.ModelForm):
49
50 def __init__(self, *args, **kwargs):
51 super(PedestalEditionForm, self).__init__(*args, **kwargs)
52
53 instance = getattr(self, 'instance', None)
54
55 if instance and instance.pk:
56
57 devices = Device.objects.filter(device_type__name='pedestal')
58 #if instance.experiment:
59 #self.fields['experiment'].widget.attrs['read_only'] = True
60 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
61 #self.fields['device'].widget.choices = [(device.id, device) for device in devices]
62
63 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
64 self.fields['experiment'].widget.attrs['readonly'] = True
65
66 class Meta:
67 model = PedestalConfiguration
68 exclude = ('device', 'label', 'template', 'type', 'parameters', 'status', 'total_units', 'author', 'hash')
69
70 def clean(self):
71 form_data = super(PedestalEditionForm, self).clean()
72 return form_data
73
74 def save(self, *args, **kwargs):
75 conf = super(PedestalEditionForm, self).save(*args, **kwargs)
76 conf.save()
77 return conf
78
48 class ExtFileField(forms.FileField):
79 class ExtFileField(forms.FileField):
49 """
80 """
50 Same as forms.FileField, but you can specify a file extension whitelist.
81 Same as forms.FileField, but you can specify a file extension whitelist.
51
82
52 >>> from django.core.files.uploadedfile import SimpleUploadedFile
83 >>> from django.core.files.uploadedfile import SimpleUploadedFile
53 >>>
84 >>>
54 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
85 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
55 >>>
86 >>>
56 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
87 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
57 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
88 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
58 >>>
89 >>>
59 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
90 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
60 Traceback (most recent call last):
91 Traceback (most recent call last):
61 ...
92 ...
62 ValidationError: [u'Not allowed filetype!']
93 ValidationError: [u'Not allowed filetype!']
63 """
94 """
64 def __init__(self, *args, **kwargs):
95 def __init__(self, *args, **kwargs):
65 extensions = kwargs.pop("extensions")
96 extensions = kwargs.pop("extensions")
66 self.extensions = [i.lower() for i in extensions]
97 self.extensions = [i.lower() for i in extensions]
67
98
68 super(ExtFileField, self).__init__(*args, **kwargs)
99 super(ExtFileField, self).__init__(*args, **kwargs)
69
100
70 def clean(self, *args, **kwargs):
101 def clean(self, *args, **kwargs):
71 data = super(ExtFileField, self).clean(*args, **kwargs)
102 data = super(ExtFileField, self).clean(*args, **kwargs)
72 filename = data.name
103 filename = data.name
73 ext = os.path.splitext(filename)[1]
104 ext = os.path.splitext(filename)[1]
74 ext = ext.lower()
105 ext = ext.lower()
75 if ext not in self.extensions:
106 if ext not in self.extensions:
76 raise forms.ValidationError('Not allowed file type: %s' % ext)
107 raise forms.ValidationError('Not allowed file type: %s' % ext)
77
108
78 class PedestalImportForm(forms.Form):
109 class PedestalImportForm(forms.Form):
79
110
80 file_name = ExtFileField(extensions=['.racp', '.json', '.dat']) No newline at end of file
111 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
@@ -1,296 +1,296
1 import ast
1 import ast
2 import json
2 import json
3 import requests
3 import requests
4 import base64
4 import base64
5 import struct
5 import struct
6 from struct import pack
6 from struct import pack
7 import time
7 import time
8 from django.contrib import messages
8 from django.contrib import messages
9 from django.db import models
9 from django.db import models
10 from django.urls import reverse
10 from django.urls import reverse
11 from django.core.validators import MinValueValidator, MaxValueValidator
11 from django.core.validators import MinValueValidator, MaxValueValidator
12
12
13 from apps.main.models import Configuration
13 from apps.main.models import Configuration
14
14
15 AXIS_VALUE = (
15 AXIS_VALUE = (
16 ('AZI', 'azimuth'),
16 ('azimuth', 'PPI'),
17 ('ELE', 'elevation')
17 ('elevation', 'RHI')
18 )
18 )
19
19
20 class PedestalConfiguration(Configuration):
20 class PedestalConfiguration(Configuration):
21
21
22 axis = models.CharField(
22 axis = models.CharField(
23 verbose_name='Axis',
23 verbose_name='Axis',
24 max_length=3,
24 max_length=10,
25 choices=AXIS_VALUE,
25 choices=AXIS_VALUE,
26 null=False,
26 null=False,
27 blank=False
27 blank=False
28 )
28 )
29
29
30 speed = models.FloatField(
30 speed = models.FloatField(
31 verbose_name='Speed',
31 verbose_name='Speed',
32 validators=[MinValueValidator(-20), MaxValueValidator(20)],
32 validators=[MinValueValidator(-20), MaxValueValidator(20)],
33 blank=False,
33 blank=False,
34 null=False
34 null=False
35 )
35 )
36
36
37 table = models.CharField(
37 table = models.CharField(
38 verbose_name="Table",
38 verbose_name="Table",
39 max_length=100,
39 max_length=100,
40 default='',
40 default='',
41 blank=False,
41 blank=False,
42 null=False,
42 null=False,
43 help_text="Please separate the values with commas"
43 help_text="Please separate the values with commas"
44 )
44 )
45
45
46 class Meta:
46 class Meta:
47 db_table = 'pedestal_configurations'
47 db_table = 'pedestal_configurations'
48
48
49 def __str__(self):
49 def __str__(self):
50 return str(self.label)
50 return str(self.label)
51
51
52 def get_absolute_url_plot(self):
52 def get_absolute_url_plot(self):
53 return reverse('url_plot_pedestal_pulses', args=[str(self.id)])
53 return reverse('url_plot_pedestal_pulses', args=[str(self.id)])
54
54
55 def request(self, cmd, method='get', **kwargs):
55 def request(self, cmd, method='get', **kwargs):
56
56
57 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
57 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
58 payload = req.json()
58 payload = req.json()
59
59
60 return payload
60 return payload
61
61
62 def status_device(self):
62 def status_device(self):
63
63
64 try:
64 try:
65 #self.device.status = 0
65 #self.device.status = 0
66 #payload = self.request('status')
66 #payload = self.request('status')
67 payload = requests.get(self.device.url())
67 payload = requests.get(self.device.url())
68 print(payload)
68 print(payload)
69 if payload:
69 if payload:
70 self.device.status = 1
70 self.device.status = 1
71 elif payload['status']=='disable':
71 elif payload['status']=='disable':
72 self.device.status = 2
72 self.device.status = 2
73 else:
73 else:
74 self.device.status = 1
74 self.device.status = 1
75 self.device.save()
75 self.device.save()
76 self.message = 'Pedestal status: {}'.format(payload['status'])
76 self.message = 'Pedestal status: {}'.format(payload['status'])
77 return False
77 return False
78 except Exception as e:
78 except Exception as e:
79 if 'No route to host' not in str(e):
79 if 'No route to host' not in str(e):
80 self.device.status = 4
80 self.device.status = 4
81 self.device.save()
81 self.device.save()
82 self.message = 'Pedestal status: {}'.format(str(e))
82 self.message = 'Pedestal status: {}'.format(str(e))
83 return False
83 return False
84
84
85 self.device.save()
85 self.device.save()
86 return True
86 return True
87
87
88 def reset_device(self):
88 def reset_device(self):
89
89
90 try:
90 try:
91 payload = self.request('reset', 'post')
91 payload = self.request('reset', 'post')
92 if payload['reset']=='ok':
92 if payload['reset']=='ok':
93 self.message = 'Pedestal restarted OK'
93 self.message = 'Pedestal restarted OK'
94 self.device.status = 2
94 self.device.status = 2
95 self.device.save()
95 self.device.save()
96 else:
96 else:
97 self.message = 'Pedestal restart fail'
97 self.message = 'Pedestal restart fail'
98 self.device.status = 4
98 self.device.status = 4
99 self.device.save()
99 self.device.save()
100 except Exception as e:
100 except Exception as e:
101 self.message = 'Pedestal reset: {}'.format(str(e))
101 self.message = 'Pedestal reset: {}'.format(str(e))
102 return False
102 return False
103
103
104 return True
104 return True
105
105
106 def stop_device(self):
106 def stop_device(self):
107
107
108 try:
108 try:
109 command = self.device.url() + "stop"
109 command = self.device.url() + "stop"
110 r = requests.get(command)
110 r = requests.get(command)
111 if r:
111 if r:
112 self.device.status = 4
112 self.device.status = 4
113 self.device.save()
113 self.device.save()
114 self.message = 'Pedestal stopped'
114 self.message = 'Pedestal stopped'
115 else:
115 else:
116 self.device.status = 4
116 self.device.status = 4
117 self.device.save()
117 self.device.save()
118 return False
118 return False
119 except Exception as e:
119 except Exception as e:
120 if 'No route to host' not in str(e):
120 if 'No route to host' not in str(e):
121 self.device.status = 4
121 self.device.status = 4
122 else:
122 else:
123 self.device.status = 0
123 self.device.status = 0
124 #self.message = 'Pedestal stop: {}'.format(str(e))
124 #self.message = 'Pedestal stop: {}'.format(str(e))
125 self.message = "Pedestal can't start, please check network/device connection or IP address/port configuration"
125 self.message = "Pedestal can't start, please check network/device connection or IP address/port configuration"
126 self.device.save()
126 self.device.save()
127 return False
127 return False
128
128
129 return True
129 return True
130
130
131 def start_device(self):
131 def start_device(self):
132
132
133 try:
133 try:
134 pedestal = PedestalConfiguration.objects.get(pk=self)
134 pedestal = PedestalConfiguration.objects.get(pk=self)
135 print(pedestal)
135 print(pedestal)
136 pedestal_axis = pedestal.get_axis_display()
136 #pedestal_axis = pedestal.get_axis_display()
137 print(pedestal)
137 print(pedestal)
138 print(pedestal_axis)
138 #print(pedestal_axis)
139 table = pedestal.table
139 table = pedestal.table
140 print(table)
140 print(table)
141 li = list(table.split(","))
141 li = list(table.split(","))
142 print(li)
142 print(li)
143 list_of_floats = []
143 list_of_floats = []
144 for item in li:
144 for item in li:
145 list_of_floats.append(float(item))
145 list_of_floats.append(float(item))
146 print(list_of_floats)
146 print(list_of_floats)
147 byte_table = []
147 byte_table = []
148 for x in list_of_floats:
148 for x in list_of_floats:
149 temp = bytearray(struct.pack("f", x))
149 temp = bytearray(struct.pack("f", x))
150 byte_table.append(temp[3])
150 byte_table.append(temp[3])
151 byte_table.append(temp[2])
151 byte_table.append(temp[2])
152 byte_table.append(temp[1])
152 byte_table.append(temp[1])
153 byte_table.append(temp[0])
153 byte_table.append(temp[0])
154 print(byte_table)
154 print(byte_table)
155 coded_table = base64.standard_b64encode(bytes(byte_table))
155 coded_table = base64.standard_b64encode(bytes(byte_table))
156 coded_table_ascii = coded_table.decode('ascii')
156 coded_table_ascii = coded_table.decode('ascii')
157 print(coded_table_ascii)
157 print(coded_table_ascii)
158 data = {'axis': pedestal_axis, 'speed': pedestal.speed, 'table': coded_table_ascii}
158 data = {'axis': pedestal.axis, 'speed': pedestal.speed, 'table': coded_table_ascii}
159 print(data)
159 print(data)
160 json_data = json.dumps(data)
160 json_data = json.dumps(data)
161 print(json_data)
161 print(json_data)
162 first_position = table[0]
162 first_position = table[0]
163
163
164 if pedestal.axis=='azimuth':
164 if pedestal.axis=='PPI':
165 json_az = json.dumps({"axis": 'azimuth', "position": 0.0})
165 json_az = json.dumps({"axis": 'azimuth', "position": 0.0})
166 json_el = json.dumps({"axis": 'elevation', "position": first_position})
166 json_el = json.dumps({"axis": 'elevation', "position": first_position})
167 else:
167 else:
168 json_az = json.dumps({"axis": 'azimuth', "position": first_position})
168 json_az = json.dumps({"axis": 'azimuth', "position": first_position})
169 json_el = json.dumps({"axis": 'elevation', "position": 0.0})
169 json_el = json.dumps({"axis": 'elevation', "position": 0.0})
170
170
171 base64_table = base64.standard_b64encode(json_data.encode('ascii'))
171 base64_table = base64.standard_b64encode(json_data.encode('ascii'))
172 base64_az = base64.standard_b64encode(json_az.encode('ascii'))
172 base64_az = base64.standard_b64encode(json_az.encode('ascii'))
173 base64_el = base64.standard_b64encode(json_el.encode('ascii'))
173 base64_el = base64.standard_b64encode(json_el.encode('ascii'))
174
174
175 table_url = self.device.url() + "table?params="
175 table_url = self.device.url() + "table?params="
176 az_url = self.device.url() + "position?params="
176 az_url = self.device.url() + "position?params="
177 el_url = self.device.url() + "position?params="
177 el_url = self.device.url() + "position?params="
178
178
179
179
180 complete_url = table_url + base64_table.decode('ascii')
180 complete_url = table_url + base64_table.decode('ascii')
181
181
182 az_url = az_url + base64_az.decode('ascii')
182 az_url = az_url + base64_az.decode('ascii')
183 el_url = el_url + base64_el.decode('ascii')
183 el_url = el_url + base64_el.decode('ascii')
184 print(complete_url)
184 print(complete_url)
185 print(az_url)
185 print(az_url)
186 print(el_url)
186 print(el_url)
187 r = requests.get(az_url)
187 r = requests.get(az_url)
188 r = requests.get(el_url)
188 r = requests.get(el_url)
189 #time.sleep(10)
189 #time.sleep(10)
190 r = requests.get(complete_url)
190 r = requests.get(complete_url)
191 if r:
191 if r:
192 self.device.status = 3
192 self.device.status = 3
193 self.device.save()
193 self.device.save()
194 self.message = 'Pedestal configured and started'
194 self.message = 'Pedestal configured and started'
195 else:
195 else:
196 return False
196 return False
197 except Exception as e:
197 except Exception as e:
198 if 'No route to host' not in str(e):
198 if 'No route to host' not in str(e):
199 self.device.status = 4
199 self.device.status = 4
200 else:
200 else:
201 self.device.status = 0
201 self.device.status = 0
202 #self.message = 'Pedestal start: {}'.format(str(e))
202 #self.message = 'Pedestal start: {}'.format(str(e))
203 self.message = "Pedestal can't start, please check network/device connection or IP address/port configuration"
203 self.message = "Pedestal can't start, please check network/device connection or IP address/port configuration"
204 self.device.save()
204 self.device.save()
205 return False
205 return False
206
206
207 return True
207 return True
208
208
209 #def write_device(self, raw=False):
209 #def write_device(self, raw=False):
210
210
211 if not raw:
211 if not raw:
212 clock = RCClock.objects.get(rc_configuration=self)
212 clock = RCClock.objects.get(rc_configuration=self)
213 print(clock)
213 print(clock)
214 if clock.mode:
214 if clock.mode:
215 data = {'default': clock.frequency}
215 data = {'default': clock.frequency}
216 else:
216 else:
217 data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
217 data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
218 payload = self.request('setfreq', 'post', data=json.dumps(data))
218 payload = self.request('setfreq', 'post', data=json.dumps(data))
219 print(payload)
219 print(payload)
220 if payload['command'] != 'ok':
220 if payload['command'] != 'ok':
221 self.message = 'Pedestal write: {}'.format(payload['command'])
221 self.message = 'Pedestal write: {}'.format(payload['command'])
222 else:
222 else:
223 self.message = payload['programming']
223 self.message = payload['programming']
224 if payload['programming'] == 'fail':
224 if payload['programming'] == 'fail':
225 self.message = 'Pedestal write: error programming CGS chip'
225 self.message = 'Pedestal write: error programming CGS chip'
226
226
227 values = []
227 values = []
228 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
228 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
229 while delay>65536:
229 while delay>65536:
230 values.append((pulse, 65535))
230 values.append((pulse, 65535))
231 delay -= 65536
231 delay -= 65536
232 values.append((pulse, delay-1))
232 values.append((pulse, delay-1))
233 data = bytearray()
233 data = bytearray()
234 #reset
234 #reset
235 data.extend((128, 0))
235 data.extend((128, 0))
236 #disable
236 #disable
237 data.extend((129, 0))
237 data.extend((129, 0))
238 #SW switch
238 #SW switch
239 if self.control_sw:
239 if self.control_sw:
240 data.extend((130, 2))
240 data.extend((130, 2))
241 else:
241 else:
242 data.extend((130, 0))
242 data.extend((130, 0))
243 #divider
243 #divider
244 data.extend((131, self.clock_divider-1))
244 data.extend((131, self.clock_divider-1))
245 #enable writing
245 #enable writing
246 data.extend((139, 62))
246 data.extend((139, 62))
247
247
248 last = 0
248 last = 0
249 for tup in values:
249 for tup in values:
250 vals = pack('<HH', last^tup[0], tup[1])
250 vals = pack('<HH', last^tup[0], tup[1])
251 last = tup[0]
251 last = tup[0]
252 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
252 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
253
253
254 #enable
254 #enable
255 data.extend((129, 1))
255 data.extend((129, 1))
256
256
257 if raw:
257 if raw:
258 return b64encode(data)
258 return b64encode(data)
259
259
260 try:
260 try:
261 payload = self.request('stop', 'post')
261 payload = self.request('stop', 'post')
262 payload = self.request('reset', 'post')
262 payload = self.request('reset', 'post')
263 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
263 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
264 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
264 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
265 n = len(data)
265 n = len(data)
266 x = 0
266 x = 0
267 #while x < n:
267 #while x < n:
268 payload = self.request('write', 'post', data=b64encode(data))
268 payload = self.request('write', 'post', data=b64encode(data))
269 # x += 1024
269 # x += 1024
270
270
271 if payload['write']=='ok':
271 if payload['write']=='ok':
272 self.device.status = 3
272 self.device.status = 3
273 self.device.save()
273 self.device.save()
274 self.message = 'Pedestal configured and started'
274 self.message = 'Pedestal configured and started'
275 else:
275 else:
276 self.device.status = 1
276 self.device.status = 1
277 self.device.save()
277 self.device.save()
278 self.message = 'Pedestal write: {}'.format(payload['write'])
278 self.message = 'Pedestal write: {}'.format(payload['write'])
279 return False
279 return False
280
280
281 #payload = self.request('start', 'post')
281 #payload = self.request('start', 'post')
282
282
283 except Exception as e:
283 except Exception as e:
284 if 'No route to host' not in str(e):
284 if 'No route to host' not in str(e):
285 self.device.status = 4
285 self.device.status = 4
286 else:
286 else:
287 self.device.status = 0
287 self.device.status = 0
288 self.message = 'Pedestal write: {}'.format(str(e))
288 self.message = 'Pedestal write: {}'.format(str(e))
289 self.device.save()
289 self.device.save()
290 return False
290 return False
291
291
292 return True
292 return True
293
293
294
294
295 def get_absolute_url_import(self):
295 def get_absolute_url_import(self):
296 return reverse('url_import_pedestal_conf', args=[str(self.id)])
296 return reverse('url_import_pedestal_conf', args=[str(self.id)])
@@ -1,27 +1,26
1 {% extends "dev_conf_edit.html" %}
1 {% extends "dev_conf_edit.html" %}
2 {% load bootstrap4 %}
2 {% load bootstrap4 %}
3 {% load static %}
3 {% load static %}
4
4
5 {% block extra-head %}
5 {% block extra-head %}
6 <style type="text/css">
6 <style type="text/css">
7 /* show the move cursor as the user moves the mouse over the panel header.*/
7 /* show the move cursor as the user moves the mouse over the panel header.*/
8 .panel-default { cursor: move; }
8 .panel-default { cursor: move; }
9 </style>
9 </style>
10 <script src="{% static 'js/jquery-ui.min.js' %}"></script>
10 <script src="{% static 'js/jquery-ui.min.js' %}"></script>
11
11
12 {% endblock %}
12 {% endblock %}
13
13
14 {% block content %}
14 {% block content %}
15 <form class="form" method="post">
15 <form class="form" method="post">
16 {% csrf_token %}
16 {% csrf_token %}
17 <h2>Pedestal</h2>
18 {% bootstrap_form form layout='horizontal' size='medium' %}
17 {% bootstrap_form form layout='horizontal' size='medium' %}
19 <div style="clear: both;"></div>
18 <div style="clear: both;"></div>
20 <br>
19 <br>
21 <div class="pull-right">
20 <div class="pull-right">
22 <button type="button" class="btn btn-primary" onclick="{% if previous %}window.location.replace('{{ previous }}');{% else %}history.go(-1);{% endif %}">Cancel</button>
21 <button type="button" class="btn btn-primary" onclick="{% if previous %}window.location.replace('{{ previous }}');{% else %}history.go(-1);{% endif %}">Cancel</button>
23 <button type="submit" class="btn btn-primary">{{button}}</button>
22 <button type="submit" class="btn btn-primary">{{button}}</button>
24 </div>
23 </div>
25 </form>
24 </form>
26 {% endblock %}
25 {% endblock %}
27 No newline at end of file
26
1 NO CONTENT: modified file
NO CONTENT: modified file
@@ -1,80 +1,111
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 USRPRXConfiguration
8 from .models import USRPRXConfiguration
9
9
10 def create_choices_from_model(model, conf_id, all_choice=False):
10 def create_choices_from_model(model, conf_id, all_choice=False):
11
11
12 instance = globals()[model]
12 instance = globals()[model]
13 choices = instance.objects.all().values_list('pk', 'name')
13 choices = instance.objects.all().values_list('pk', 'name')
14
14
15 return choices
15 return choices
16
16
17 class USRPRXConfigurationForm(forms.ModelForm):
17 class USRPRXConfigurationForm(forms.ModelForm):
18
18
19 def __init__(self, *args, **kwargs):
19 def __init__(self, *args, **kwargs):
20 super(USRPRXConfigurationForm, self).__init__(*args, **kwargs)
20 super(USRPRXConfigurationForm, self).__init__(*args, **kwargs)
21
21
22 instance = getattr(self, 'instance', None)
22 instance = getattr(self, 'instance', None)
23
23
24 if instance and instance.pk:
24 if instance and instance.pk:
25
25
26 devices = Device.objects.filter(device_type__name='usrp_rx')
26 devices = Device.objects.filter(device_type__name='usrp_rx')
27 if instance.experiment:
27 #if instance.experiment:
28 self.fields['experiment'].widget.attrs['read_only'] = True
28 #self.fields['experiment'].widget.attrs['read_only'] = True
29 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
29 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
30 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
30 #self.fields['device'].widget.choices = [(device.id, device) for device in devices]
31
31
32 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
32 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
33 self.fields['experiment'].widget.attrs['readonly'] = True
33 self.fields['experiment'].widget.attrs['readonly'] = True
34
34
35 class Meta:
35 class Meta:
36 model = USRPRXConfiguration
36 model = USRPRXConfiguration
37 exclude = ('type', 'parameters', 'status', 'total_units', 'author', 'hash')
37 exclude = ('type', 'parameters', 'status', 'total_units', 'author', 'hash')
38
38
39 def clean(self):
39 def clean(self):
40 form_data = super(USRPRXConfigurationForm, self).clean()
40 form_data = super(USRPRXConfigurationForm, self).clean()
41 return form_data
41 return form_data
42
42
43 def save(self, *args, **kwargs):
43 def save(self, *args, **kwargs):
44 conf = super(USRPRXConfigurationForm, self).save(*args, **kwargs)
44 conf = super(USRPRXConfigurationForm, self).save(*args, **kwargs)
45 conf.save()
45 conf.save()
46 return conf
46 return conf
47
47
48 class USRPRXEditionForm(forms.ModelForm):
49
50 def __init__(self, *args, **kwargs):
51 super(USRPRXEditionForm, self).__init__(*args, **kwargs)
52
53 instance = getattr(self, 'instance', None)
54
55 if instance and instance.pk:
56
57 devices = Device.objects.filter(device_type__name='usrp_rx')
58 #if instance.experiment:
59 #self.fields['experiment'].widget.attrs['read_only'] = True
60 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
61 #self.fields['device'].widget.choices = [(device.id, device) for device in devices]
62
63 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
64 self.fields['experiment'].widget.attrs['readonly'] = True
65
66 class Meta:
67 model = USRPRXConfiguration
68 exclude = ('template', 'device', 'label', 'ip_address', 'daughterboard', 'antenna', 'type', 'parameters', 'status', 'total_units', 'author', 'hash')
69
70 def clean(self):
71 form_data = super(USRPRXEditionForm, self).clean()
72 return form_data
73
74 def save(self, *args, **kwargs):
75 conf = super(USRPRXEditionForm, self).save(*args, **kwargs)
76 conf.save()
77 return conf
78
48 class ExtFileField(forms.FileField):
79 class ExtFileField(forms.FileField):
49 """
80 """
50 Same as forms.FileField, but you can specify a file extension whitelist.
81 Same as forms.FileField, but you can specify a file extension whitelist.
51
82
52 >>> from django.core.files.uploadedfile import SimpleUploadedFile
83 >>> from django.core.files.uploadedfile import SimpleUploadedFile
53 >>>
84 >>>
54 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
85 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
55 >>>
86 >>>
56 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
87 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
57 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
88 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
58 >>>
89 >>>
59 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
90 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
60 Traceback (most recent call last):
91 Traceback (most recent call last):
61 ...
92 ...
62 ValidationError: [u'Not allowed filetype!']
93 ValidationError: [u'Not allowed filetype!']
63 """
94 """
64 def __init__(self, *args, **kwargs):
95 def __init__(self, *args, **kwargs):
65 extensions = kwargs.pop("extensions")
96 extensions = kwargs.pop("extensions")
66 self.extensions = [i.lower() for i in extensions]
97 self.extensions = [i.lower() for i in extensions]
67
98
68 super(ExtFileField, self).__init__(*args, **kwargs)
99 super(ExtFileField, self).__init__(*args, **kwargs)
69
100
70 def clean(self, *args, **kwargs):
101 def clean(self, *args, **kwargs):
71 data = super(ExtFileField, self).clean(*args, **kwargs)
102 data = super(ExtFileField, self).clean(*args, **kwargs)
72 filename = data.name
103 filename = data.name
73 ext = os.path.splitext(filename)[1]
104 ext = os.path.splitext(filename)[1]
74 ext = ext.lower()
105 ext = ext.lower()
75 if ext not in self.extensions:
106 if ext not in self.extensions:
76 raise forms.ValidationError('Not allowed file type: %s' % ext)
107 raise forms.ValidationError('Not allowed file type: %s' % ext)
77
108
78 class USRPRXImportForm(forms.Form):
109 class USRPRXImportForm(forms.Form):
79
110
80 file_name = ExtFileField(extensions=['.racp', '.json', '.dat']) No newline at end of file
111 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
@@ -1,310 +1,310
1 import ast
1 import ast
2 import json
2 import json
3 import requests
3 import requests
4 import base64
4 import base64
5 from struct import pack
5 from struct import pack
6
6
7 from django.db import models
7 from django.db import models
8 from django.urls import reverse
8 from django.urls import reverse
9 from django.core.validators import MinValueValidator, MaxValueValidator
9 from django.core.validators import MinValueValidator, MaxValueValidator
10
10
11 from apps.main.models import Configuration
11 from apps.main.models import Configuration
12
12
13 BOARD_VALUE = (
13 BOARD_VALUE = (
14 ('1', 'A:AB'),
14 ('1', 'A:AB'),
15 ('2', 'AB'),
15 ('2', 'AB'),
16 ('3', 'A:A A:B'),
16 ('3', 'A:A A:B'),
17 )
17 )
18
18
19 ANT_VALUE = (
19 ANT_VALUE = (
20 ('1', 'RX'),
20 ('1', 'RX'),
21 ('2', 'TX')
21 ('2', 'TX')
22 )
22 )
23
23
24 CLK_VALUE = (
24 CLK_VALUE = (
25 ('1', 'internal'),
25 ('1', 'internal'),
26 ('2', 'external')
26 ('2', 'external')
27 )
27 )
28
28
29 TIME_VALUE = (
29 TIME_VALUE = (
30 ('1', 'internal'),
30 ('1', 'internal'),
31 ('2', 'external')
31 ('2', 'external')
32 )
32 )
33
33
34 class USRPRXConfiguration(Configuration):
34 class USRPRXConfiguration(Configuration):
35
35
36 ip_address = models.GenericIPAddressField(
36 ip_address = models.GenericIPAddressField(
37 verbose_name = 'IP address',
37 verbose_name = 'IP address',
38 protocol='IPv4',
38 protocol='IPv4',
39 default='0.0.0.0')
39 default='0.0.0.0')
40
40
41 daughterboard = models.CharField(
41 daughterboard = models.CharField(
42 verbose_name='Daughterboard',
42 verbose_name='Daughterboard',
43 max_length=3,
43 max_length=3,
44 choices=BOARD_VALUE,
44 choices=BOARD_VALUE,
45 null=False,
45 null=False,
46 blank=False
46 blank=False
47 )
47 )
48
48
49 antenna = models.CharField(
49 antenna = models.CharField(
50 verbose_name='Antenna',
50 verbose_name='Antenna',
51 max_length=3,
51 max_length=3,
52 choices=ANT_VALUE,
52 choices=ANT_VALUE,
53 null=False,
53 null=False,
54 blank=False
54 blank=False
55 )
55 )
56
56
57 samplerate = models.FloatField(
57 samplerate = models.FloatField(
58 verbose_name='Sample Rate',
58 verbose_name='Sample Rate',
59 blank=False,
59 blank=False,
60 null=False,
60 null=False,
61 help_text='Introduce the value in MHz (10^6)'
61 help_text='Introduce the value in MHz (10^6)'
62 )
62 )
63
63
64 frequency = models.FloatField(
64 frequency = models.FloatField(
65 verbose_name='Frequency',
65 verbose_name='Frequency',
66 blank=False,
66 blank=False,
67 null=False,
67 null=False,
68 help_text='Introduce the value in MHz (10^6)'
68 help_text='Introduce the value in MHz (10^6)'
69 )
69 )
70
70
71 datadir = models.CharField(
71 datadir = models.CharField(
72 verbose_name="Data Directory",
72 verbose_name="Data Directory",
73 max_length=100,
73 max_length=100,
74 default='',
74 default='',
75 blank=False,
75 blank=False,
76 null=False,
76 null=False,
77 help_text='Fill with a directory. Example: /media/soporte/DATA'
77 help_text='Fill with a directory. Example: /media/soporte/DATA'
78 )
78 )
79
79
80 clocksource = models.CharField(
80 clocksource = models.CharField(
81 verbose_name='Clock Source',
81 verbose_name='Clock Source',
82 max_length=3,
82 max_length=3,
83 choices=CLK_VALUE,
83 choices=CLK_VALUE,
84 null=False,
84 null=False,
85 blank=False
85 blank=False
86 )
86 )
87
87
88 timesource = models.CharField(
88 timesource = models.CharField(
89 verbose_name='Time Source',
89 verbose_name='Time Source',
90 max_length=3,
90 max_length=3,
91 choices=TIME_VALUE,
91 choices=TIME_VALUE,
92 null=False,
92 null=False,
93 blank=False
93 blank=False
94 )
94 )
95
95
96 clockrate = models.FloatField(
96 clockrate = models.FloatField(
97 verbose_name='Clock Rate',
97 verbose_name='Clock Rate',
98 blank=False,
98 blank=False,
99 null=False,
99 null=False,
100 help_text='Introduce the value in MHz (10^6)'
100 help_text='Introduce the value in MHz (10^6)'
101 )
101 )
102
102
103 class Meta:
103 class Meta:
104 db_table = 'usrp_rx_configurations'
104 db_table = 'usrp_rx_configurations'
105
105
106 def __str__(self):
106 def __str__(self):
107 return str(self.label)
107 return str(self.label)
108
108
109 def get_absolute_url_plot(self):
109 def get_absolute_url_plot(self):
110 return reverse('url_plot_usrp_rx_pulses', args=[str(self.id)])
110 return reverse('url_plot_usrp_rx_pulses', args=[str(self.id)])
111
111
112 def request(self, cmd, method='get', **kwargs):
112 def request(self, cmd, method='get', **kwargs):
113
113
114 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
114 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
115 payload = req.json()
115 payload = req.json()
116 return payload
116 return payload
117
117
118 def status_device(self):
118 def status_device(self):
119
119
120 try:
120 try:
121 #self.device.status = 0
121 #self.device.status = 0
122 #payload = self.request('status')
122 #payload = self.request('status')
123 payload = requests.get(self.device.url())
123 payload = requests.get(self.device.url())
124 print(payload)
124 print(payload)
125 if payload:
125 if payload:
126 self.device.status = 1
126 self.device.status = 1
127 elif payload['status']=='disable':
127 elif payload['status']=='disable':
128 self.device.status = 2
128 self.device.status = 2
129 else:
129 else:
130 self.device.status = 1
130 self.device.status = 1
131 self.device.save()
131 self.device.save()
132 self.message = 'USRP Rx Dev status: {}'.format(payload['status'])
132 self.message = 'USRP Rx Dev status: {}'.format(payload['status'])
133 return False
133 return False
134 except Exception as e:
134 except Exception as e:
135 if 'No route to host' not in str(e):
135 if 'No route to host' not in str(e):
136 self.device.status = 4
136 self.device.status = 4
137 self.device.save()
137 self.device.save()
138 self.message = 'USRP Rx status: {}'.format(str(e))
138 self.message = 'USRP Rx status: {}'.format(str(e))
139 return False
139 return False
140
140
141 self.device.save()
141 self.device.save()
142 return True
142 return True
143
143
144 def reset_device(self):
144 def reset_device(self):
145
145
146 try:
146 try:
147 payload = self.request('reset', 'post')
147 payload = self.request('reset', 'post')
148 if payload['reset']=='ok':
148 if payload['reset']=='ok':
149 self.message = 'USRP Rx restarted OK'
149 self.message = 'USRP Rx restarted OK'
150 self.device.status = 2
150 self.device.status = 2
151 self.device.save()
151 self.device.save()
152 else:
152 else:
153 self.message = 'USRP Rx restart fail'
153 self.message = 'USRP Rx restart fail'
154 self.device.status = 4
154 self.device.status = 4
155 self.device.save()
155 self.device.save()
156 except Exception as e:
156 except Exception as e:
157 self.message = 'USRP Rx reset: {}'.format(str(e))
157 self.message = 'USRP Rx reset: {}'.format(str(e))
158 return False
158 return False
159
159
160 return True
160 return True
161
161
162 def stop_device(self):
162 def stop_device(self):
163
163
164 try:
164 try:
165 command = self.device.url() + "stop"
165 command = self.device.url() + "stoprx"
166 r = requests.get(command)
166 r = requests.get(command)
167 if r:
167 if r:
168 self.device.status = 4
168 self.device.status = 4
169 self.device.save()
169 self.device.save()
170 self.message = 'USRP stopped'
170 self.message = 'USRP stopped'
171 else:
171 else:
172 self.device.status = 4
172 self.device.status = 4
173 self.device.save()
173 self.device.save()
174 return False
174 return False
175 except Exception as e:
175 except Exception as e:
176 if 'No route to host' not in str(e):
176 if 'No route to host' not in str(e):
177 self.device.status = 4
177 self.device.status = 4
178 else:
178 else:
179 self.device.status = 0
179 self.device.status = 0
180 #self.message = 'USRP Rx stop: {}'.format(str(e))
180 #self.message = 'USRP Rx stop: {}'.format(str(e))
181 self.message = "USRP Rx can't start, please check network/device connection or IP address/port configuration"
181 self.message = "USRP Rx can't start, please check network/device connection or IP address/port configuration"
182 self.device.save()
182 self.device.save()
183 return False
183 return False
184
184
185 return True
185 return True
186
186
187 def start_device(self):
187 def start_device(self):
188
188
189 try:
189 try:
190 usrp = USRPRXConfiguration.objects.get(pk=self)
190 usrp = USRPRXConfiguration.objects.get(pk=self)
191 usrp_daughterboard = usrp.get_daughterboard_display()
191 usrp_daughterboard = usrp.get_daughterboard_display()
192 usrp_antenna = usrp.get_antenna_display()
192 usrp_antenna = usrp.get_antenna_display()
193 usrp_clocksource = usrp.get_clocksource_display()
193 usrp_clocksource = usrp.get_clocksource_display()
194 usrp_timesource = usrp.get_timesource_display()
194 usrp_timesource = usrp.get_timesource_display()
195 print(usrp)
195 print(usrp)
196 payload = {'ip_address': usrp.ip_address, 'daughterboard': usrp_daughterboard, 'antenna': usrp_antenna, 'sample_rate': usrp.samplerate, 'frequency': usrp.frequency,
196 payload = {'ip_address': usrp.ip_address, 'daughterboard': usrp_daughterboard, 'antenna': usrp_antenna, 'sample_rate': usrp.samplerate, 'frequency': usrp.frequency,
197 'datadir': usrp.datadir, 'clock_source': usrp_clocksource, 'time_source': usrp_timesource, 'clock_rate':usrp.clockrate}
197 'datadir': usrp.datadir, 'clock_source': usrp_clocksource, 'time_source': usrp_timesource, 'clock_rate':usrp.clockrate}
198 print(payload)
198 print(payload)
199 r = requests.post(self.device.url("usrprx"), json=payload)
199 r = requests.post(self.device.url("usrprx"), json=payload)
200 print(r.text)
200 print(r.text)
201 #payload = self.request('usrp', 'post', data=json.dumps(data))
201 #payload = self.request('usrp', 'post', data=json.dumps(data))
202 #print(payload)
202 #print(payload)
203 if r:
203 if r:
204 self.device.status = 3
204 self.device.status = 3
205 self.device.save()
205 self.device.save()
206 self.message = 'USRP Rx configured and started'
206 self.message = 'USRP Rx configured and started'
207 else:
207 else:
208 return False
208 return False
209 except Exception as e:
209 except Exception as e:
210 if 'No route to host' not in str(e):
210 if 'No route to host' not in str(e):
211 self.device.status = 4
211 self.device.status = 4
212 else:
212 else:
213 self.device.status = 0
213 self.device.status = 0
214 #self.message = 'USRP Rx start: {}'.format(str(e))
214 #self.message = 'USRP Rx start: {}'.format(str(e))
215 self.message = "USRP Rx can't start, please check network/device connection or IP address/port configuration"
215 self.message = "USRP Rx can't start, please check network/device connection or IP address/port configuration"
216 self.device.save()
216 self.device.save()
217 return False
217 return False
218
218
219 return True
219 return True
220
220
221 #def write_device(self, raw=False):
221 #def write_device(self, raw=False):
222
222
223 if not raw:
223 if not raw:
224 clock = RCClock.objects.get(rc_configuration=self)
224 clock = RCClock.objects.get(rc_configuration=self)
225 print(clock)
225 print(clock)
226 if clock.mode:
226 if clock.mode:
227 data = {'default': clock.frequency}
227 data = {'default': clock.frequency}
228 else:
228 else:
229 data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
229 data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
230 payload = self.request('setfreq', 'post', data=json.dumps(data))
230 payload = self.request('setfreq', 'post', data=json.dumps(data))
231 print(payload)
231 print(payload)
232 if payload['command'] != 'ok':
232 if payload['command'] != 'ok':
233 self.message = 'USRP Rx write: {}'.format(payload['command'])
233 self.message = 'USRP Rx write: {}'.format(payload['command'])
234 else:
234 else:
235 self.message = payload['programming']
235 self.message = payload['programming']
236 if payload['programming'] == 'fail':
236 if payload['programming'] == 'fail':
237 self.message = 'USRP Rx write: error programming CGS chip'
237 self.message = 'USRP Rx write: error programming CGS chip'
238
238
239 values = []
239 values = []
240 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
240 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
241 while delay>65536:
241 while delay>65536:
242 values.append((pulse, 65535))
242 values.append((pulse, 65535))
243 delay -= 65536
243 delay -= 65536
244 values.append((pulse, delay-1))
244 values.append((pulse, delay-1))
245 data = bytearray()
245 data = bytearray()
246 #reset
246 #reset
247 data.extend((128, 0))
247 data.extend((128, 0))
248 #disable
248 #disable
249 data.extend((129, 0))
249 data.extend((129, 0))
250 #SW switch
250 #SW switch
251 if self.control_sw:
251 if self.control_sw:
252 data.extend((130, 2))
252 data.extend((130, 2))
253 else:
253 else:
254 data.extend((130, 0))
254 data.extend((130, 0))
255 #divider
255 #divider
256 data.extend((131, self.clock_divider-1))
256 data.extend((131, self.clock_divider-1))
257 #enable writing
257 #enable writing
258 data.extend((139, 62))
258 data.extend((139, 62))
259
259
260 last = 0
260 last = 0
261 for tup in values:
261 for tup in values:
262 vals = pack('<HH', last^tup[0], tup[1])
262 vals = pack('<HH', last^tup[0], tup[1])
263 last = tup[0]
263 last = tup[0]
264 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
264 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
265
265
266 #enable
266 #enable
267 data.extend((129, 1))
267 data.extend((129, 1))
268
268
269 if raw:
269 if raw:
270 return b64encode(data)
270 return b64encode(data)
271
271
272 try:
272 try:
273 payload = self.request('stop', 'post')
273 payload = self.request('stop', 'post')
274 payload = self.request('reset', 'post')
274 payload = self.request('reset', 'post')
275 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
275 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
276 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
276 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
277 n = len(data)
277 n = len(data)
278 x = 0
278 x = 0
279 #while x < n:
279 #while x < n:
280 payload = self.request('write', 'post', data=b64encode(data))
280 payload = self.request('write', 'post', data=b64encode(data))
281 # x += 1024
281 # x += 1024
282
282
283 if payload['write']=='ok':
283 if payload['write']=='ok':
284 self.device.status = 3
284 self.device.status = 3
285 self.device.save()
285 self.device.save()
286 self.message = 'USRP Rx configured and started'
286 self.message = 'USRP Rx configured and started'
287 else:
287 else:
288 self.device.status = 1
288 self.device.status = 1
289 self.device.save()
289 self.device.save()
290 self.message = 'USRP Rx write: {}'.format(payload['write'])
290 self.message = 'USRP Rx write: {}'.format(payload['write'])
291 return False
291 return False
292
292
293 #payload = self.request('start', 'post')
293 #payload = self.request('start', 'post')
294
294
295 except Exception as e:
295 except Exception as e:
296 if 'No route to host' not in str(e):
296 if 'No route to host' not in str(e):
297 self.device.status = 4
297 self.device.status = 4
298 else:
298 else:
299 self.device.status = 0
299 self.device.status = 0
300 self.message = 'USRP Rx write: {}'.format(str(e))
300 self.message = 'USRP Rx write: {}'.format(str(e))
301 self.device.save()
301 self.device.save()
302 return False
302 return False
303
303
304 return True
304 return True
305
305
306 def get_absolute_url_import(self):
306 def get_absolute_url_import(self):
307 return reverse('url_import_usrp_rx_conf', args=[str(self.id)])
307 return reverse('url_import_usrp_rx_conf', args=[str(self.id)])
308
308
309
309
310
310
@@ -1,80 +1,111
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 USRPTXConfiguration
8 from .models import USRPTXConfiguration
9
9
10 def create_choices_from_model(model, conf_id, all_choice=False):
10 def create_choices_from_model(model, conf_id, all_choice=False):
11
11
12 instance = globals()[model]
12 instance = globals()[model]
13 choices = instance.objects.all().values_list('pk', 'name')
13 choices = instance.objects.all().values_list('pk', 'name')
14
14
15 return choices
15 return choices
16
16
17 class USRPTXConfigurationForm(forms.ModelForm):
17 class USRPTXConfigurationForm(forms.ModelForm):
18
18
19 def __init__(self, *args, **kwargs):
19 def __init__(self, *args, **kwargs):
20 super(USRPTXConfigurationForm, self).__init__(*args, **kwargs)
20 super(USRPTXConfigurationForm, self).__init__(*args, **kwargs)
21
21
22 instance = getattr(self, 'instance', None)
22 instance = getattr(self, 'instance', None)
23
23
24 if instance and instance.pk:
24 if instance and instance.pk:
25
25
26 devices = Device.objects.filter(device_type__name='usrp_tx')
26 devices = Device.objects.filter(device_type__name='usrp_tx')
27 if instance.experiment:
27 #if instance.experiment:
28 self.fields['experiment'].widget.attrs['read_only'] = True
28 #self.fields['experiment'].widget.attrs['read_only'] = True
29 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
29 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
30 self.fields['device'].widget.choices = [(device.id, device) for device in devices]
30 #self.fields['device'].widget.choices = [(device.id, device) for device in devices]
31
31
32 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
32 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
33 self.fields['experiment'].widget.attrs['readonly'] = True
33 self.fields['experiment'].widget.attrs['readonly'] = True
34
34
35 class Meta:
35 class Meta:
36 model = USRPTXConfiguration
36 model = USRPTXConfiguration
37 exclude = ('type', 'parameters', 'status', 'total_units', 'author', 'hash')
37 exclude = ('type', 'parameters', 'status', 'total_units', 'author', 'hash')
38
38
39 def clean(self):
39 def clean(self):
40 form_data = super(USRPTXConfigurationForm, self).clean()
40 form_data = super(USRPTXConfigurationForm, self).clean()
41 return form_data
41 return form_data
42
42
43 def save(self, *args, **kwargs):
43 def save(self, *args, **kwargs):
44 conf = super(USRPTXConfigurationForm, self).save(*args, **kwargs)
44 conf = super(USRPTXConfigurationForm, self).save(*args, **kwargs)
45 conf.save()
45 conf.save()
46 return conf
46 return conf
47
47
48 class USRPTXEditionForm(forms.ModelForm):
49
50 def __init__(self, *args, **kwargs):
51 super(USRPTXEditionForm, self).__init__(*args, **kwargs)
52
53 instance = getattr(self, 'instance', None)
54
55 if instance and instance.pk:
56
57 devices = Device.objects.filter(device_type__name='usrp_tx')
58 #if instance.experiment:
59 #self.fields['experiment'].widget.attrs['read_only'] = True
60 #self.fields['experiment'].widget.choices = [(instance.experiment.id, instance.experiment)]
61 #self.fields['device'].widget.choices = [(device.id, device) for device in devices]
62
63 if 'initial' in kwargs and 'experiment' in kwargs['initial'] and kwargs['initial']['experiment'] not in (0, '0'):
64 self.fields['experiment'].widget.attrs['readonly'] = True
65
66 class Meta:
67 model = USRPTXConfiguration
68 exclude = ('template', 'device', 'label', 'ip_address', 'daughterboard', 'antenna', 'type', 'parameters', 'status', 'total_units', 'author', 'hash')
69
70 def clean(self):
71 form_data = super(USRPTXEditionForm, self).clean()
72 return form_data
73
74 def save(self, *args, **kwargs):
75 conf = super(USRPTXEditionForm, self).save(*args, **kwargs)
76 conf.save()
77 return conf
78
48 class ExtFileField(forms.FileField):
79 class ExtFileField(forms.FileField):
49 """
80 """
50 Same as forms.FileField, but you can specify a file extension whitelist.
81 Same as forms.FileField, but you can specify a file extension whitelist.
51
82
52 >>> from django.core.files.uploadedfile import SimpleUploadedFile
83 >>> from django.core.files.uploadedfile import SimpleUploadedFile
53 >>>
84 >>>
54 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
85 >>> t = ExtFileField(ext_whitelist=(".pdf", ".txt"))
55 >>>
86 >>>
56 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
87 >>> t.clean(SimpleUploadedFile('filename.pdf', 'Some File Content'))
57 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
88 >>> t.clean(SimpleUploadedFile('filename.txt', 'Some File Content'))
58 >>>
89 >>>
59 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
90 >>> t.clean(SimpleUploadedFile('filename.exe', 'Some File Content'))
60 Traceback (most recent call last):
91 Traceback (most recent call last):
61 ...
92 ...
62 ValidationError: [u'Not allowed filetype!']
93 ValidationError: [u'Not allowed filetype!']
63 """
94 """
64 def __init__(self, *args, **kwargs):
95 def __init__(self, *args, **kwargs):
65 extensions = kwargs.pop("extensions")
96 extensions = kwargs.pop("extensions")
66 self.extensions = [i.lower() for i in extensions]
97 self.extensions = [i.lower() for i in extensions]
67
98
68 super(ExtFileField, self).__init__(*args, **kwargs)
99 super(ExtFileField, self).__init__(*args, **kwargs)
69
100
70 def clean(self, *args, **kwargs):
101 def clean(self, *args, **kwargs):
71 data = super(ExtFileField, self).clean(*args, **kwargs)
102 data = super(ExtFileField, self).clean(*args, **kwargs)
72 filename = data.name
103 filename = data.name
73 ext = os.path.splitext(filename)[1]
104 ext = os.path.splitext(filename)[1]
74 ext = ext.lower()
105 ext = ext.lower()
75 if ext not in self.extensions:
106 if ext not in self.extensions:
76 raise forms.ValidationError('Not allowed file type: %s' % ext)
107 raise forms.ValidationError('Not allowed file type: %s' % ext)
77
108
78 class USRPTXImportForm(forms.Form):
109 class USRPTXImportForm(forms.Form):
79
110
80 file_name = ExtFileField(extensions=['.racp', '.json', '.dat']) No newline at end of file
111 file_name = ExtFileField(extensions=['.racp', '.json', '.dat'])
@@ -1,378 +1,379
1 import ast
1 import ast
2 import json
2 import json
3 import requests
3 import requests
4 import base64
4 import base64
5 from struct import pack
5 from struct import pack
6
6
7 from django.db import models
7 from django.db import models
8 from django.urls import reverse
8 from django.urls import reverse
9 from django.core.validators import MinValueValidator, MaxValueValidator
9 from django.core.validators import MinValueValidator, MaxValueValidator
10
10
11 from apps.main.models import Configuration
11 from apps.main.models import Configuration
12
12
13 BOARD_VALUE = (
13 BOARD_VALUE = (
14 ('1', 'A:AB'),
14 ('1', 'A:AB'),
15 ('2', 'AB')
15 ('2', 'AB')
16 )
16 )
17
17
18 ANT_VALUE = (
18 ANT_VALUE = (
19 ('1', 'RX'),
19 ('1', 'RX'),
20 ('2', 'TX'),
20 ('2', 'TX'),
21 ('3', 'TX/RX')
21 ('3', 'TX/RX')
22 )
22 )
23
23
24 TYPE_VALUE = (
24 TYPE_VALUE = (
25 ('0', 'None'),
25 ('0', 'None'),
26 ('1', 'User define'),
26 ('1', 'User define'),
27 ('2', 'Barker 2'),
27 ('2', 'Barker 2'),
28 ('3', 'Barker 3'),
28 ('3', 'Barker 3'),
29 ('4', 'Barker 4'),
29 ('4', 'Barker 4'),
30 ('5', 'Barker 5'),
30 ('5', 'Barker 5'),
31 ('7', 'Barker 7'),
31 ('7', 'Barker 7'),
32 ('11', 'Barker 11'),
32 ('11', 'Barker 11'),
33 ('13', 'Barker 13')
33 ('13', 'Barker 13')
34 )
34 )
35
35
36 class USRPTXConfiguration(Configuration):
36 class USRPTXConfiguration(Configuration):
37
37
38 ip_address = models.GenericIPAddressField(
38 ip_address = models.GenericIPAddressField(
39 verbose_name = 'IP address',
39 verbose_name = 'IP address',
40 protocol='IPv4',
40 protocol='IPv4',
41 default='0.0.0.0')
41 default='0.0.0.0')
42
42
43 daughterboard = models.CharField(
43 daughterboard = models.CharField(
44 verbose_name='Daughterboard',
44 verbose_name='Daughterboard',
45 max_length=3,
45 max_length=3,
46 choices=BOARD_VALUE,
46 choices=BOARD_VALUE,
47 null=False,
47 null=False,
48 blank=False
48 blank=False
49 )
49 )
50
50
51 antenna = models.CharField(
51 antenna = models.CharField(
52 verbose_name='Antenna',
52 verbose_name='Antenna',
53 max_length=3,
53 max_length=3,
54 choices=ANT_VALUE,
54 choices=ANT_VALUE,
55 null=False,
55 null=False,
56 blank=False
56 blank=False
57 )
57 )
58
58
59 frequency = models.FloatField(
59 frequency = models.FloatField(
60 verbose_name='Frequency',
60 verbose_name='Frequency',
61 blank=False,
61 blank=False,
62 null=False,
62 null=False,
63 help_text='Introduce the value in MHz (10^6)'
63 help_text='Introduce the value in MHz (10^6)'
64 )
64 )
65
65
66 samplerate = models.FloatField(
66 samplerate = models.FloatField(
67 verbose_name='Sample rate',
67 verbose_name='Sample rate',
68 blank=False,
68 blank=False,
69 null=False,
69 null=False,
70 help_text='Introduce the value in MHz (10^6)'
70 help_text='Introduce the value in MHz (10^6)'
71 )
71 )
72
72
73 ipp = models.FloatField(
73 ipp = models.FloatField(
74 verbose_name='IPP',
74 verbose_name='IPP',
75 blank=False,
75 blank=False,
76 null=False,
76 null=False,
77 help_text='Introduce the value in km'
77 help_text='Introduce the value in km'
78 )
78 )
79
79
80 enable_1 = models.BooleanField(
80 enable_1 = models.BooleanField(
81 verbose_name='Pulse 1',
81 verbose_name='Pulse 1',
82 default=True,
82 default=True,
83 blank=False,
83 blank=False,
84 null=False
84 null=False
85 )
85 )
86
86
87 pulse_1 = models.FloatField(
87 pulse_1 = models.FloatField(
88 verbose_name='Width (Pulse 1)',
88 verbose_name='Width (Pulse 1)',
89 blank=False,
89 blank=False,
90 null=False,
90 null=False,
91 help_text='Introduce the value in %'
91 help_text='Introduce the value in %'
92 )
92 )
93
93
94 delay_1 = models.IntegerField(
94 delay_1 = models.IntegerField(
95 verbose_name='Delay (Pulse 1)',
95 verbose_name='Delay (Pulse 1)',
96 default=0,
96 default=0,
97 blank=True,
97 blank=True,
98 null=False,
98 null=False,
99 help_text='Introduce the value in µs'
99 help_text='Introduce the value in µs'
100 )
100 )
101
101
102 type_1 = models.CharField(
102 type_1 = models.CharField(
103 verbose_name='Type (Pulse 1)',
103 verbose_name='Type (Pulse 1)',
104 default = 0,
104 default = 0,
105 max_length=3,
105 max_length=3,
106 choices=TYPE_VALUE,
106 choices=TYPE_VALUE,
107 blank=False,
107 blank=False,
108 null=False
108 null=False
109 )
109 )
110
110
111 code_1 = models.IntegerField(
111 code_1 = models.IntegerField(
112 verbose_name="Code (Pulse 1)",
112 verbose_name="Code (Pulse 1)",
113 blank=True,
113 blank=True,
114 null=True,
114 null=True,
115 help_text="Introduce the binary code"
115 help_text="Introduce the binary code"
116 )
116 )
117
117
118 repetitions_1 = models.IntegerField(
118 repetitions_1 = models.IntegerField(
119 verbose_name='N° of repetitions (Pulse 1)',
119 verbose_name='N° of repetitions (Pulse 1)',
120 default=1,
120 default=1,
121 blank=True,
121 blank=True,
122 null=True
122 null=True
123 )
123 )
124
124
125 enable_2 = models.BooleanField(
125 enable_2 = models.BooleanField(
126 verbose_name='Pulse 2',
126 verbose_name='Pulse 2',
127 blank=False,
127 blank=False,
128 null=False
128 null=False
129 )
129 )
130
130
131 pulse_2 = models.FloatField(
131 pulse_2 = models.FloatField(
132 verbose_name='Width (Pulse 2)',
132 verbose_name='Width (Pulse 2)',
133 default=1,
133 blank=True,
134 blank=True,
134 null=True,
135 null=True,
135 help_text='Introduce the value in %'
136 help_text='Introduce the value in %'
136 )
137 )
137
138
138 delay_2 = models.IntegerField(
139 delay_2 = models.IntegerField(
139 verbose_name='Delay (Pulse 2)',
140 verbose_name='Delay (Pulse 2)',
140 default=0,
141 default=0,
141 blank=True,
142 blank=True,
142 null=True,
143 null=True,
143 help_text='Introduce the value in µs'
144 help_text='Introduce the value in µs'
144 )
145 )
145
146
146 type_2 = models.CharField(
147 type_2 = models.CharField(
147 verbose_name='Type (Pulse 2)',
148 verbose_name='Type (Pulse 2)',
148 default = 0,
149 default = 0,
149 max_length=3,
150 max_length=3,
150 choices=TYPE_VALUE,
151 choices=TYPE_VALUE,
151 blank=True,
152 blank=True,
152 null=False
153 null=False
153 )
154 )
154
155
155 code_2 = models.IntegerField(
156 code_2 = models.IntegerField(
156 verbose_name="Code (Pulse 2)",
157 verbose_name="Code (Pulse 2)",
157 blank=True,
158 blank=True,
158 null=True,
159 null=True,
159 help_text="Introduce the binary code"
160 help_text="Introduce the binary code"
160 )
161 )
161
162
162 repetitions_2 = models.IntegerField(
163 repetitions_2 = models.IntegerField(
163 verbose_name='N° of repetitions (Pulse 2)',
164 verbose_name='N° of repetitions (Pulse 2)',
164 default=1,
165 default=1,
165 blank=True,
166 blank=True,
166 null=True
167 null=True
167 )
168 )
168
169
169 class Meta:
170 class Meta:
170 db_table = 'usrp_tx_configurations'
171 db_table = 'usrp_tx_configurations'
171
172
172 def __str__(self):
173 def __str__(self):
173 return str(self.label)
174 return str(self.label)
174
175
175 def get_absolute_url_plot(self):
176 def get_absolute_url_plot(self):
176 return reverse('url_plot_usrp_tx_pulses', args=[str(self.id)])
177 return reverse('url_plot_usrp_tx_pulses', args=[str(self.id)])
177
178
178 def request(self, cmd, method='get', **kwargs):
179 def request(self, cmd, method='get', **kwargs):
179
180
180 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
181 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
181 payload = req.json()
182 payload = req.json()
182 return payload
183 return payload
183
184
184 def status_device(self):
185 def status_device(self):
185
186
186 try:
187 try:
187 #self.device.status = 0
188 #self.device.status = 0
188 #payload = self.request('status')
189 #payload = self.request('status')
189 payload = requests.get(self.device.url())
190 payload = requests.get(self.device.url())
190 print(payload)
191 print(payload)
191 if payload:
192 if payload:
192 self.device.status = 1
193 self.device.status = 1
193 elif payload['status']=='disable':
194 elif payload['status']=='disable':
194 self.device.status = 2
195 self.device.status = 2
195 else:
196 else:
196 self.device.status = 1
197 self.device.status = 1
197 self.device.save()
198 self.device.save()
198 self.message = 'USRP Tx status: {}'.format(payload['status'])
199 self.message = 'USRP Tx status: {}'.format(payload['status'])
199 return False
200 return False
200 except Exception as e:
201 except Exception as e:
201 if 'No route to host' not in str(e):
202 if 'No route to host' not in str(e):
202 self.device.status = 4
203 self.device.status = 4
203 self.device.save()
204 self.device.save()
204 self.message = 'USRP Tx status: {}'.format(str(e))
205 self.message = 'USRP Tx status: {}'.format(str(e))
205 return False
206 return False
206
207
207 self.device.save()
208 self.device.save()
208 return True
209 return True
209
210
210 def reset_device(self):
211 def reset_device(self):
211
212
212 try:
213 try:
213 payload = self.request('reset', 'post')
214 payload = self.request('reset', 'post')
214 if payload['reset']=='ok':
215 if payload['reset']=='ok':
215 self.message = 'USRP Tx restarted OK'
216 self.message = 'USRP Tx restarted OK'
216 self.device.status = 2
217 self.device.status = 2
217 self.device.save()
218 self.device.save()
218 else:
219 else:
219 self.message = 'USRP Tx restart fail'
220 self.message = 'USRP Tx restart fail'
220 self.device.status = 4
221 self.device.status = 4
221 self.device.save()
222 self.device.save()
222 except Exception as e:
223 except Exception as e:
223 self.message = 'USRP Tx reset: {}'.format(str(e))
224 self.message = 'USRP Tx reset: {}'.format(str(e))
224 return False
225 return False
225
226
226 return True
227 return True
227
228
228 def stop_device(self):
229 def stop_device(self):
229
230
230 try:
231 try:
231 command = self.device.url() + "stop"
232 command = self.device.url() + "stoptx"
232 r = requests.get(command)
233 r = requests.get(command)
233 if r:
234 if r:
234 self.device.status = 4
235 self.device.status = 4
235 self.device.save()
236 self.device.save()
236 self.message = 'USRP stopped'
237 self.message = 'USRP stopped'
237 else:
238 else:
238 self.device.status = 4
239 self.device.status = 4
239 self.device.save()
240 self.device.save()
240 return False
241 return False
241 except Exception as e:
242 except Exception as e:
242 if 'No route to host' not in str(e):
243 if 'No route to host' not in str(e):
243 self.device.status = 4
244 self.device.status = 4
244 else:
245 else:
245 self.device.status = 0
246 self.device.status = 0
246 #self.message = 'USRP Tx stop: {}'.format(str(e))
247 #self.message = 'USRP Tx stop: {}'.format(str(e))
247 self.message = "USRP Tx can't start, please check network/device connection or IP address/port configuration"
248 self.message = "USRP Tx can't start, please check network/device connection or IP address/port configuration"
248 self.device.save()
249 self.device.save()
249 return False
250 return False
250
251
251 return True
252 return True
252
253
253 def start_device(self):
254 def start_device(self):
254 print("Entró al start")
255 print("Entró al start")
255 try:
256 try:
256 usrp = USRPTXConfiguration.objects.get(pk=self)
257 usrp = USRPTXConfiguration.objects.get(pk=self)
257 usrp_daughterboard = usrp.get_daughterboard_display()
258 usrp_daughterboard = usrp.get_daughterboard_display()
258 usrp_antenna = usrp.get_antenna_display()
259 usrp_antenna = usrp.get_antenna_display()
259 print(usrp)
260 print(usrp)
260
261
261 payload = {'ip_address': usrp.ip_address, 'daughterboard': usrp_daughterboard, 'antenna': usrp_antenna,
262 payload = {'ip_address': usrp.ip_address, 'daughterboard': usrp_daughterboard, 'antenna': usrp_antenna,
262 'frequency': usrp.frequency, 'sample_rate': usrp.samplerate, 'ipp': usrp.ipp, 'enable_1': usrp.enable_1,
263 'frequency': usrp.frequency, 'sample_rate': usrp.samplerate, 'ipp': usrp.ipp, 'enable_1': usrp.enable_1,
263 'pulse_1': usrp.pulse_1, 'delay_1': usrp.delay_1, 'type_1': usrp.type_1, 'code_1': usrp.code_1,
264 'pulse_1': usrp.pulse_1, 'delay_1': usrp.delay_1, 'type_1': usrp.type_1, 'code_1': usrp.code_1,
264 'repetitions_1': usrp.repetitions_1, 'enable_2': usrp.enable_2, 'pulse_2': usrp.pulse_2, 'delay_2': usrp.delay_2,
265 'repetitions_1': usrp.repetitions_1, 'enable_2': usrp.enable_2, 'pulse_2': usrp.pulse_2, 'delay_2': usrp.delay_2,
265 'type_2': usrp.type_2, 'code_2': usrp.code_2, 'repetitions_2': usrp.repetitions_2}
266 'type_2': usrp.type_2, 'code_2': usrp.code_2, 'repetitions_2': usrp.repetitions_2}
266 print(payload)
267 print(payload)
267 r = requests.post(self.device.url("usrptx"), json=payload)
268 r = requests.post(self.device.url("usrptx"), json=payload)
268 print(r.text)
269 print(r.text)
269 #payload = self.request('usrp', 'post', data=json.dumps(data))
270 #payload = self.request('usrp', 'post', data=json.dumps(data))
270 #print(payload)
271 #print(payload)
271 if r:
272 if r:
272 self.device.status = 3
273 self.device.status = 3
273 self.device.save()
274 self.device.save()
274 self.message = 'USRP Tx configured and started'
275 self.message = 'USRP Tx configured and started'
275 else:
276 else:
276 return False
277 return False
277 except Exception as e:
278 except Exception as e:
278 if 'No route to host' not in str(e):
279 if 'No route to host' not in str(e):
279 self.device.status = 4
280 self.device.status = 4
280 else:
281 else:
281 self.device.status = 0
282 self.device.status = 0
282 #self.message = 'USRP Tx start: {}'.format(str(e))
283 #self.message = 'USRP Tx start: {}'.format(str(e))
283 self.message = "USRP Tx can't start, please check network/device connection or IP address/port configuration"
284 self.message = "USRP Tx can't start, please check network/device connection or IP address/port configuration"
284 self.device.save()
285 self.device.save()
285 return False
286 return False
286
287
287 return True
288 return True
288
289
289 #def write_device(self, raw=False):
290 #def write_device(self, raw=False):
290
291
291 if not raw:
292 if not raw:
292 clock = RCClock.objects.get(rc_configuration=self)
293 clock = RCClock.objects.get(rc_configuration=self)
293 print(clock)
294 print(clock)
294 if clock.mode:
295 if clock.mode:
295 data = {'default': clock.frequency}
296 data = {'default': clock.frequency}
296 else:
297 else:
297 data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
298 data = {'manual': [clock.multiplier, clock.divisor, clock.reference]}
298 payload = self.request('setfreq', 'post', data=json.dumps(data))
299 payload = self.request('setfreq', 'post', data=json.dumps(data))
299 print(payload)
300 print(payload)
300 if payload['command'] != 'ok':
301 if payload['command'] != 'ok':
301 self.message = 'USRP Tx write: {}'.format(payload['command'])
302 self.message = 'USRP Tx write: {}'.format(payload['command'])
302 else:
303 else:
303 self.message = payload['programming']
304 self.message = payload['programming']
304 if payload['programming'] == 'fail':
305 if payload['programming'] == 'fail':
305 self.message = 'USRP Tx write: error programming CGS chip'
306 self.message = 'USRP Tx write: error programming CGS chip'
306
307
307 values = []
308 values = []
308 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
309 for pulse, delay in zip(self.get_pulses(), self.get_delays()):
309 while delay>65536:
310 while delay>65536:
310 values.append((pulse, 65535))
311 values.append((pulse, 65535))
311 delay -= 65536
312 delay -= 65536
312 values.append((pulse, delay-1))
313 values.append((pulse, delay-1))
313 data = bytearray()
314 data = bytearray()
314 #reset
315 #reset
315 data.extend((128, 0))
316 data.extend((128, 0))
316 #disable
317 #disable
317 data.extend((129, 0))
318 data.extend((129, 0))
318 #SW switch
319 #SW switch
319 if self.control_sw:
320 if self.control_sw:
320 data.extend((130, 2))
321 data.extend((130, 2))
321 else:
322 else:
322 data.extend((130, 0))
323 data.extend((130, 0))
323 #divider
324 #divider
324 data.extend((131, self.clock_divider-1))
325 data.extend((131, self.clock_divider-1))
325 #enable writing
326 #enable writing
326 data.extend((139, 62))
327 data.extend((139, 62))
327
328
328 last = 0
329 last = 0
329 for tup in values:
330 for tup in values:
330 vals = pack('<HH', last^tup[0], tup[1])
331 vals = pack('<HH', last^tup[0], tup[1])
331 last = tup[0]
332 last = tup[0]
332 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
333 data.extend((133, vals[1], 132, vals[0], 133, vals[3], 132, vals[2]))
333
334
334 #enable
335 #enable
335 data.extend((129, 1))
336 data.extend((129, 1))
336
337
337 if raw:
338 if raw:
338 return b64encode(data)
339 return b64encode(data)
339
340
340 try:
341 try:
341 payload = self.request('stop', 'post')
342 payload = self.request('stop', 'post')
342 payload = self.request('reset', 'post')
343 payload = self.request('reset', 'post')
343 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
344 #payload = self.request('divider', 'post', data={'divider': self.clock_divider-1})
344 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
345 #payload = self.request('write', 'post', data=b64encode(bytearray((139, 62))), timeout=20)
345 n = len(data)
346 n = len(data)
346 x = 0
347 x = 0
347 #while x < n:
348 #while x < n:
348 payload = self.request('write', 'post', data=b64encode(data))
349 payload = self.request('write', 'post', data=b64encode(data))
349 # x += 1024
350 # x += 1024
350
351
351 if payload['write']=='ok':
352 if payload['write']=='ok':
352 self.device.status = 3
353 self.device.status = 3
353 self.device.save()
354 self.device.save()
354 self.message = 'USRP Tx configured and started'
355 self.message = 'USRP Tx configured and started'
355 else:
356 else:
356 self.device.status = 1
357 self.device.status = 1
357 self.device.save()
358 self.device.save()
358 self.message = 'USRP Tx write: {}'.format(payload['write'])
359 self.message = 'USRP Tx write: {}'.format(payload['write'])
359 return False
360 return False
360
361
361 #payload = self.request('start', 'post')
362 #payload = self.request('start', 'post')
362
363
363 except Exception as e:
364 except Exception as e:
364 if 'No route to host' not in str(e):
365 if 'No route to host' not in str(e):
365 self.device.status = 4
366 self.device.status = 4
366 else:
367 else:
367 self.device.status = 0
368 self.device.status = 0
368 self.message = 'USRP Tx write: {}'.format(str(e))
369 self.message = 'USRP Tx write: {}'.format(str(e))
369 self.device.save()
370 self.device.save()
370 return False
371 return False
371
372
372 return True
373 return True
373
374
374 def get_absolute_url_import(self):
375 def get_absolute_url_import(self):
375 return reverse('url_import_usrp_tx_conf', args=[str(self.id)])
376 return reverse('url_import_usrp_tx_conf', args=[str(self.id)])
376
377
377
378
378
379
@@ -1,142 +1,142
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 USRPTXConfiguration
12 from .models import USRPTXConfiguration
13 from .forms import USRPTXConfigurationForm, USRPTXImportForm
13 from .forms import USRPTXConfigurationForm, USRPTXImportForm
14
14
15
15
16 def conf(request, conf_id):
16 def conf(request, conf_id):
17
17
18 conf = get_object_or_404(USRPTXConfiguration, pk=conf_id)
18 conf = get_object_or_404(USRPTXConfiguration, pk=conf_id)
19
19
20 kwargs = {}
20 kwargs = {}
21 kwargs['dev_conf'] = conf
21 kwargs['dev_conf'] = conf
22 kwargs['dev_conf_keys'] = ['ip_address', 'daughterboard', 'antenna', 'frequency', 'samplerate', 'ipp', 'enable_1', 'pulse_1',
22 kwargs['dev_conf_keys'] = ['ip_address', 'daughterboard', 'antenna', 'frequency', 'samplerate', 'ipp', 'enable_1', 'pulse_1',
23 'delay_1', 'type_1', 'code_1', 'repetitions_1', 'enable_2', 'pulse_2', 'delay_2', 'type_2', 'code_2',
23 'delay_1', 'type_1', 'code_1', 'repetitions_1', 'enable_2', 'pulse_2', 'delay_2', 'type_2', 'code_2',
24 'repetitions_2']
24 'repetitions_2']
25
25
26 kwargs['title'] = 'Configuration'
26 kwargs['title'] = 'Configuration'
27 kwargs['suptitle'] = 'Detail'
27 kwargs['suptitle'] = 'Detail'
28
28
29 kwargs['button'] = 'Edit Configuration'
29 kwargs['button'] = 'Edit Configuration'
30
30
31 conf.status_device()
31 conf.status_device()
32
32
33 ###### SIDEBAR ######
33 ###### SIDEBAR ######
34 kwargs.update(sidebar(conf=conf))
34 kwargs.update(sidebar(conf=conf))
35
35
36 return render(request, 'usrp_tx_conf.html', kwargs)
36 return render(request, 'usrp_tx_conf.html', kwargs)
37
37
38 @login_required
38 @login_required
39 def conf_edit(request, conf_id):
39 def conf_edit(request, conf_id):
40 print(conf_id)
40 print(conf_id)
41 conf = get_object_or_404(USRPTXConfiguration, pk=conf_id)
41 conf = get_object_or_404(USRPTXConfiguration, pk=conf_id)
42 print(conf)
42 print(conf)
43 #print("fin de carga de params")
43 #print("fin de carga de params")
44 if request.method=='GET':
44 if request.method=='GET':
45 print("GET case")
45 print("GET case")
46 form = USRPTXConfigurationForm(instance=conf)
46 form = USRPTXConfigurationForm(instance=conf)
47 print(form)
47 print(form)
48
48
49 elif request.method=='POST':
49 elif request.method=='POST':
50 print("ingreso a post conf edit")
50 print("ingreso a post conf edit")
51 line_data = {}
51 line_data = {}
52 conf_data = {}
52 conf_data = {}
53 clock_data = {}
53 clock_data = {}
54 extras = []
54 extras = []
55 print("Inicio impresion POST#####")
55 print("Inicio impresion POST#####")
56 print(request.POST.items)
56 print(request.POST.items)
57 print("Fin impresion de POST items#####")
57 print("Fin impresion de POST items#####")
58 #classified post fields
58 #classified post fields
59 for label,value in request.POST.items():
59 for label,value in request.POST.items():
60 if label=='csrfmiddlewaretoken':
60 if label=='csrfmiddlewaretoken':
61 continue
61 continue
62
62
63 if label.count('|')==0:
63 if label.count('|')==0:
64 if label in ('mode', 'multiplier', 'divisor', 'reference'):
64 if label in ('mode', 'multiplier', 'divisor', 'reference'):
65 clock_data[label] = value
65 clock_data[label] = value
66 else:
66 else:
67 conf_data[label] = value
67 conf_data[label] = value
68 continue
68 continue
69
69
70 elif label.split('|')[0]!='-1':
70 elif label.split('|')[0]!='-1':
71 extras.append(label)
71 extras.append(label)
72 continue
72 continue
73
73
74 #print(label)
74 #print(label)
75 x, pk, name = label.split('|')
75 x, pk, name = label.split('|')
76
76
77 if name=='codes':
77 if name=='codes':
78 value = [s for s in value.split('\r\n') if s]
78 value = [s for s in value.split('\r\n') if s]
79
79
80 if pk in line_data:
80 if pk in line_data:
81 line_data[pk][name] = value
81 line_data[pk][name] = value
82 else:
82 else:
83 line_data[pk] = {name:value}
83 line_data[pk] = {name:value}
84 #print(line_data[pk])
84 #print(line_data[pk])
85 #update conf
85 #update conf
86
86
87 form = USRPTXConfigurationForm(conf_data, instance=conf)
87 form = USRPTXConfigurationForm(conf_data, instance=conf)
88
88
89 #print(request.POST.items())
89 #print(request.POST.items())
90
90
91 if form.is_valid():
91 if form.is_valid():
92 form.save()
92 form.save()
93
93
94 messages.success(request, 'USRP Tx configuration successfully updated')
94 messages.success(request, 'USRP Tx configuration successfully updated')
95
95
96 return redirect(conf.get_absolute_url())
96 return redirect(conf.get_absolute_url())
97
97
98 kwargs = {}
98 kwargs = {}
99 kwargs['dev_conf'] = conf
99 kwargs['dev_conf'] = conf
100 kwargs['form'] = form
100 kwargs['form'] = form
101 kwargs['edit'] = True
101 kwargs['edit'] = True
102
102
103 kwargs['title'] = 'USRP Tx Configuration'
103 kwargs['title'] = 'USRP Tx Configuration'
104 kwargs['suptitle'] = 'Edit'
104 kwargs['suptitle'] = 'Edit'
105 kwargs['button'] = 'Update'
105 kwargs['button'] = 'Update'
106
106
107 print(kwargs)
107 print(kwargs)
108 print(form)
108 print(form)
109 return render(request, 'usrp_tx_conf_edit.html', kwargs)
109 return render(request, 'usrp_tx_conf_edit.html', kwargs)
110
110
111 def import_file(request, conf_id):
111 def import_file(request, conf_id):
112
112
113 conf = get_object_or_404(USRPTXConfiguration, pk=conf_id)
113 conf = get_object_or_404(USRPTXConfiguration, pk=conf_id)
114 if request.method=='POST':
114 if request.method=='POST':
115 form = USRPTXImportForm(request.POST, request.FILES)
115 form = USRPTXImportForm(request.POST, request.FILES)
116 if form.is_valid():
116 if form.is_valid():
117 try:
117 try:
118 data = conf.import_from_file(request.FILES['file_name'])
118 data = conf.import_from_file(request.FILES['file_name'])
119 conf.dict_to_parms(data)
119 conf.dict_to_parms(data)
120 conf.update_pulses()
120 #conf.update_pulses()
121 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
121 messages.success(request, 'Configuration "%s" loaded succesfully' % request.FILES['file_name'])
122 return redirect(conf.get_absolute_url_edit())
122 return redirect(conf.get_absolute_url_edit())
123
123
124 except Exception as e:
124 except Exception as e:
125 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
125 messages.error(request, 'Error parsing file: "%s" - %s' % (request.FILES['file_name'], repr(e)))
126 else:
126 else:
127 messages.warning(request, 'Your current configuration will be replaced')
127 messages.warning(request, 'Your current configuration will be replaced')
128 form = USRPTXImportForm()
128 form = USRPTXImportForm()
129
129
130 kwargs = {}
130 kwargs = {}
131 kwargs['form'] = form
131 kwargs['form'] = form
132 kwargs['title'] = 'USRP Tx Configuration'
132 kwargs['title'] = 'USRP Tx Configuration'
133 kwargs['suptitle'] = 'Import file'
133 kwargs['suptitle'] = 'Import file'
134 kwargs['button'] = 'Upload'
134 kwargs['button'] = 'Upload'
135 kwargs['previous'] = conf.get_absolute_url()
135 kwargs['previous'] = conf.get_absolute_url()
136
136
137 return render(request, 'usrp_tx_import.html', kwargs)
137 return render(request, 'usrp_tx_import.html', kwargs)
138
138
139 def conf_raw(request, conf_id):
139 def conf_raw(request, conf_id):
140 conf = get_object_or_404(USRPTXConfiguration, pk=conf_id)
140 conf = get_object_or_404(USRPTXConfiguration, pk=conf_id)
141 raw = conf.write_device(raw=True)
141 raw = conf.write_device(raw=True)
142 return HttpResponse(raw, content_type='application/json') No newline at end of file
142 return HttpResponse(raw, content_type='application/json')
@@ -1,187 +1,195
1 from __future__ import (absolute_import, division, print_function,
1 from __future__ import (absolute_import, division, print_function,
2 unicode_literals)
2 unicode_literals)
3
3
4 import numpy as np
4 import numpy as np
5 import os
5 import os
6 import subprocess
6 import subprocess
7 from flask import Flask, request
7 from flask import Flask, request
8
8
9 BARKER_DICT = {
9 BARKER_DICT = {
10 "BARKER_2_SEQUENCE" : np.array([1, 1]),
10 "BARKER_2_SEQUENCE" : np.array([1, 1]),
11 "BARKER_3_SEQUENCE" : np.array([1, 1, 0]),
11 "BARKER_3_SEQUENCE" : np.array([1, 1, 0]),
12 "BARKER_4_SEQUENCE" : np.array([1, 1, 0, 1]),
12 "BARKER_4_SEQUENCE" : np.array([1, 1, 0, 1]),
13 "BARKER_5_SEQUENCE" : np.array([1, 1, 1, 0, 1]),
13 "BARKER_5_SEQUENCE" : np.array([1, 1, 1, 0, 1]),
14 "BARKER_7_SEQUENCE" : np.array([1, 1, 1, 0, 0, 0, 1, 0]),
14 "BARKER_7_SEQUENCE" : np.array([1, 1, 1, 0, 0, 0, 1, 0]),
15 "BARKER_11_SEQUENCE" : np.array([1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0]),
15 "BARKER_11_SEQUENCE" : np.array([1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0]),
16 "BARKER_13_SEQUENCE" : np.array([1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1]),
16 "BARKER_13_SEQUENCE" : np.array([1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1]),
17 }
17 }
18
18
19 app = Flask(__name__)
19 app = Flask(__name__)
20
20
21 @app.route('/')
21 @app.route('/')
22 def archivo():
22 def archivo():
23 stream = os.popen('echo Returned output')
23 stream = os.popen('echo Returned output')
24 output = stream.read()
24 output = stream.read()
25 print(output)
25 print(output)
26 return 'Se ejecuto el comando'
26 return 'Se ejecuto el comando'
27
27
28 @app.route('/usrprx/', methods=['POST'])
28 @app.route('/usrprx/', methods=['POST'])
29 def usrprx_start():
29 def usrprx_start():
30 request_data = request.get_json()
30 request_data = request.get_json()
31 print(request_data)
31 print(request_data)
32 ip_address = request_data['ip_address']
32 ip_address = request_data['ip_address']
33 daughterboard = request_data['daughterboard']
33 daughterboard = request_data['daughterboard']
34 antenna = request_data['antenna']
34 antenna = request_data['antenna']
35 sample_rate = request_data['sample_rate']
35 sample_rate = request_data['sample_rate']
36 frequency = request_data['frequency']
36 frequency = request_data['frequency']
37 datadir = request_data['datadir']
37 datadir = request_data['datadir']
38 clock_source = request_data['clock_source']
38 clock_source = request_data['clock_source']
39 time_source = request_data['time_source']
39 time_source = request_data['time_source']
40 clock_rate = request_data['clock_rate']
40 clock_rate = request_data['clock_rate']
41
41
42 command_usrp_rx = subprocess.Popen(["python2.7", "/home/developer/HaystackOP/thor.py", "-m", ip_address, "-d", daughterboard,
42 #command_usrp_rx = subprocess.Popen(["python2.7", "/home/developer/HaystackOP/thor.py", "-m", ip_address, "-d", daughterboard,
43 "-c ch0,ch1", "-y", antenna, "-r", str(sample_rate) + "e6", "-f", str(frequency) + "e6",
43 # "-c ch0,ch1", "-y", antenna, "-r", str(sample_rate) + "e6", "-f", str(frequency) + "e6",
44 "-datadir", datadir, "--clock_source", clock_source, "--time_source", time_source,
44 # "-datadir", datadir, "--clock_source", clock_source, "--time_source", time_source,
45 "--clock_rate", str(clock_rate) + "e6"], stdout=subprocess.PIPE)
45 # "--clock_rate", str(clock_rate) + "e6"], stdout=subprocess.PIPE)
46 command_usrp_rx_out = command_usrp_rx.communicate()[0]
46 command_usrp_rx = subprocess.Popen(["python", "thor.py"], stdout=subprocess.PIPE)
47 print(command_usrp_rx_out)
47 #command_usrp_rx_out = command_usrp_rx.communicate()[0]
48 #print(command_usrp_rx_out)
48
49
49 return "USRP Rx configured"
50 return "USRP Rx configured"
50
51
52 @app.route('/stoprx/', methods=['GET'])
53 def usrprx_stop():
54 #stop_usrp_rx = subprocess.Popen(["pkill", "-f", "thor.py"], stdout=subprocess.PIPE)
55 return 'USRP stopped'
56
51 @app.route('/usrptx/', methods=['POST'])
57 @app.route('/usrptx/', methods=['POST'])
52 def usrptx_start():
58 def usrptx_start():
53 request_data = request.get_json()
59 request_data = request.get_json()
54 print(request_data)
60 print(request_data)
55 ip_address = request_data['ip_address']
61 ip_address = request_data['ip_address']
56 daughterboard = request_data['daughterboard']
62 daughterboard = request_data['daughterboard']
57 antenna = request_data['antenna']
63 antenna = request_data['antenna']
58 frequency = request_data['frequency']
64 frequency = request_data['frequency']
59 sample_rate = request_data['sample_rate']
65 sample_rate = request_data['sample_rate']
60 ipp = request_data['ipp']
66 ipp = request_data['ipp']
61 enable_1 = request_data['enable_1']
67 enable_1 = request_data['enable_1']
62 pulse_1 = request_data['pulse_1']
68 pulse_1 = request_data['pulse_1']
63 delay_1 = request_data['delay_1']
69 delay_1 = request_data['delay_1']
64 type_1 = int(request_data['type_1'])
70 type_1 = int(request_data['type_1'])
65 code_1 = request_data['code_1']
71 code_1 = request_data['code_1']
66 repetitions_1 = request_data['repetitions_1']
72 repetitions_1 = request_data['repetitions_1']
67 enable_2 = request_data['enable_2']
73 enable_2 = request_data['enable_2']
68 pulse_2 = request_data['pulse_2']
74 pulse_2 = request_data['pulse_2']
69 delay_2 = request_data['delay_2']
75 delay_2 = request_data['delay_2']
70 type_2 = int(request_data['type_2'])
76 type_2 = int(request_data['type_2'])
71 code_2 = request_data['code_2']
77 code_2 = request_data['code_2']
72 repetitions_2 = request_data['repetitions_2']
78 repetitions_2 = request_data['repetitions_2']
73
79
74 if enable_1 == True and enable_2 == False:
80 if enable_1 == True and enable_2 == False:
75 clen = int((ipp * 2 / 300000) * 1000000)
81 clen = int((ipp * 2 / 300000) * 1000000)
76 if type_1 == 0:
82 if type_1 == 0:
77 z = np.zeros(clen)
83 z = np.zeros(clen)
78 o = 1*np.ones(clen)
84 o = 1*np.ones(clen)
79 cod = np.zeros([clen])
85 cod = np.zeros([clen])
80 N = z.shape[0]
86 N = z.shape[0]
81 for ri in np.arange(N):
87 for ri in np.arange(N):
82 if ri < (pulse_1/100.0)*clen:
88 if ri < (pulse_1/100.0)*clen:
83 cod[ri]=o[ri]
89 cod[ri]=o[ri]
84 else:
90 else:
85 cod[ri]=0
91 cod[ri]=0
86 cod = np.roll(cod, delay_1)
92 cod = np.roll(cod, delay_1)
87 cod = np.tile(cod, repetitions_1)
93 cod = np.tile(cod, repetitions_1)
88
94
89 if type_1 == 1:
95 if type_1 == 1:
90 code_1 = np.array([int(x) for x in str(code_1)])
96 code_1 = np.array([int(x) for x in str(code_1)])
91 units_1 = ((pulse_1/100.0)*clen)/len(code_1)
97 units_1 = ((pulse_1/100.0)*clen)/len(code_1)
92 seq_1 = np.repeat(code_1, units_1)
98 seq_1 = np.repeat(code_1, units_1)
93 cod = np.concatenate([seq_1, np.zeros(clen-len(seq_1))])
99 cod = np.concatenate([seq_1, np.zeros(clen-len(seq_1))])
94 cod = np.roll(cod, delay_1)
100 cod = np.roll(cod, delay_1)
95 cod = np.tile(cod, repetitions_1)
101 cod = np.tile(cod, repetitions_1)
96
102
97 if type_1 > 1:
103 if type_1 > 1:
98 units_1 = ((pulse_1/100.0)*clen)/type_1
104 units_1 = ((pulse_1/100.0)*clen)/type_1
99 seq_1 = np.repeat(BARKER_DICT["BARKER_" + str(type_1) + "_SEQUENCE"], units_1)
105 seq_1 = np.repeat(BARKER_DICT["BARKER_" + str(type_1) + "_SEQUENCE"], units_1)
100 cod = np.concatenate([seq_1, np.zeros(clen-len(seq_1))])
106 cod = np.concatenate([seq_1, np.zeros(clen-len(seq_1))])
101 cod = np.roll(cod, delay_1)
107 cod = np.roll(cod, delay_1)
102 cod = np.tile(cod, repetitions_1)
108 cod = np.tile(cod, repetitions_1)
103
109
104 if enable_1 == True and enable_2 == True:
110 if enable_1 == True and enable_2 == True:
105 clen = int((ipp * 2 / 300000) * 1000000)
111 clen = int((ipp * 2 / 300000) * 1000000)
106 if type_1 == 0:
112 if type_1 == 0:
107 z = np.zeros(clen)
113 z = np.zeros(clen)
108 o = 1*np.ones(clen)
114 o = 1*np.ones(clen)
109 cod_1 = np.zeros([clen])
115 cod_1 = np.zeros([clen])
110 N = z.shape[0]
116 N = z.shape[0]
111 for ri in np.arange(N):
117 for ri in np.arange(N):
112 if ri < (pulse_1/100.0)*clen:
118 if ri < (pulse_1/100.0)*clen:
113 cod_1[ri]=o[ri]
119 cod_1[ri]=o[ri]
114 else:
120 else:
115 cod_1[ri]=0
121 cod_1[ri]=0
116 cod_1 = np.roll(cod_1, delay_1)
122 cod_1 = np.roll(cod_1, delay_1)
117 cod_1 = np.tile(cod_1, repetitions_1)
123 cod_1 = np.tile(cod_1, repetitions_1)
118
124
119 if type_1 == 1:
125 if type_1 == 1:
120 code_1 = np.array([int(x) for x in str(code_1)])
126 code_1 = np.array([int(x) for x in str(code_1)])
121 units_1 = ((pulse_1/100.0)*clen)/len(code_1)
127 units_1 = ((pulse_1/100.0)*clen)/len(code_1)
122 seq_1 = np.repeat(code_1, units_1)
128 seq_1 = np.repeat(code_1, units_1)
123 cod_1 = np.concatenate([seq_1, np.zeros(clen-len(seq_1))])
129 cod_1 = np.concatenate([seq_1, np.zeros(clen-len(seq_1))])
124 cod_1 = np.roll(cod_1, delay_1)
130 cod_1 = np.roll(cod_1, delay_1)
125 cod_1 = np.tile(cod_1, repetitions_1)
131 cod_1 = np.tile(cod_1, repetitions_1)
126
132
127 if type_1 > 1:
133 if type_1 > 1:
128 units_1 = ((pulse_1/100.0)*clen)/type_1
134 units_1 = ((pulse_1/100.0)*clen)/type_1
129 seq_1 = np.repeat(BARKER_DICT["BARKER_" + str(type_1) + "_SEQUENCE"], units_1)
135 seq_1 = np.repeat(BARKER_DICT["BARKER_" + str(type_1) + "_SEQUENCE"], units_1)
130 cod_1 = np.concatenate([seq_1, np.zeros(clen-len(seq_1))])
136 cod_1 = np.concatenate([seq_1, np.zeros(clen-len(seq_1))])
131 cod_1 = np.roll(cod_1, delay_1)
137 cod_1 = np.roll(cod_1, delay_1)
132 cod_1 = np.tile(cod_1, repetitions_1)
138 cod_1 = np.tile(cod_1, repetitions_1)
133
139
134 if type_2 == 0:
140 if type_2 == 0:
135 z = np.zeros(clen)
141 z = np.zeros(clen)
136 o = 1*np.ones(clen)
142 o = 1*np.ones(clen)
137 cod_2 = np.zeros([clen])
143 cod_2 = np.zeros([clen])
138 N = z.shape[0]
144 N = z.shape[0]
139 for ri in np.arange(N):
145 for ri in np.arange(N):
140 if ri < (pulse_2/100.0)*clen:
146 if ri < (pulse_2/100.0)*clen:
141 cod_2[ri]=o[ri]
147 cod_2[ri]=o[ri]
142 else:
148 else:
143 cod_2[ri]=0
149 cod_2[ri]=0
144 cod_2 = np.roll(cod_2, delay_2)
150 cod_2 = np.roll(cod_2, delay_2)
145 cod_2 = np.tile(cod_2, repetitions_2)
151 cod_2 = np.tile(cod_2, repetitions_2)
146
152
147 if type_2 == 1:
153 if type_2 == 1:
148 code_2 = np.array([int(x) for x in str(code_2)])
154 code_2 = np.array([int(x) for x in str(code_2)])
149 print(code_2)
155 print(code_2)
150 units_2 = ((pulse_2/100.0)*clen)/len(code_2)
156 units_2 = ((pulse_2/100.0)*clen)/len(code_2)
151 seq_2 = np.repeat(code_2, units_2)
157 seq_2 = np.repeat(code_2, units_2)
152 cod_2 = np.concatenate([seq_2, np.zeros(clen-len(seq_2))])
158 cod_2 = np.concatenate([seq_2, np.zeros(clen-len(seq_2))])
153 cod_2 = np.roll(cod_2, delay_2)
159 cod_2 = np.roll(cod_2, delay_2)
154 cod_2 = np.tile(cod_2, repetitions_2)
160 cod_2 = np.tile(cod_2, repetitions_2)
155
161
156 if type_2 > 1:
162 if type_2 > 1:
157 units_2 = ((pulse_2/100.0)*clen)/type_2
163 units_2 = ((pulse_2/100.0)*clen)/type_2
158 seq_2 = np.repeat(BARKER_DICT["BARKER_" + str(type_2) + "_SEQUENCE"], units_2)
164 seq_2 = np.repeat(BARKER_DICT["BARKER_" + str(type_2) + "_SEQUENCE"], units_2)
159 cod_2 = np.concatenate([seq_2, np.zeros(clen-len(seq_2))])
165 cod_2 = np.concatenate([seq_2, np.zeros(clen-len(seq_2))])
160 cod_2 = np.roll(cod_2, delay_2)
166 cod_2 = np.roll(cod_2, delay_2)
161 cod_2 = np.tile(cod_2, repetitions_2)
167 cod_2 = np.tile(cod_2, repetitions_2)
162
168
163 print(cod_1)
169 print(cod_1)
164 print(len(cod_1))
170 print(len(cod_1))
165 print(cod_2)
171 print(cod_2)
166 print(len(cod_2))
172 print(len(cod_2))
167
173
168 cod = np.concatenate([cod_1, cod_2])
174 cod = np.concatenate([cod_1, cod_2])
169
175
170 print(cod)
176 print(cod)
171 name = 'code.bin'
177 name = 'code.bin'
172 print(name)
178 print(name)
173 cod.tofile(name)
179 cod.tofile(name)
174
180
175 command_usrp_tx = subprocess.Popen(["python", "tx.py", "-m", ip_address, "-d", daughterboard, "-y", antenna, "-f", str(frequency) + "e6",
181 #command_usrp_tx = subprocess.Popen(["python", "tx.py", "-m", ip_address, "-d", daughterboard, "-y", antenna, "-f", str(frequency) + "e6",
176 "-r", str(sample_rate) + "e6", "code.bin"], stdout=subprocess.PIPE)
182 # "-r", str(sample_rate) + "e6", "code.bin"], stdout=subprocess.PIPE)
177 command_usrp_tx_out = command_usrp_tx.communicate()[0]
183 command_usrp_tx = subprocess.Popen(["python", "tx.py"], stdout=subprocess.PIPE)
178 print(command_usrp_tx_out)
184 #command_usrp_tx_out = command_usrp_tx.communicate()[1]
185 #print(command_usrp_tx_out)
179
186
180 return "USRP Tx configured"
187 return "USRP Tx configured"
181
188
182 @app.route('/stop/', methods=['GET'])
189 @app.route('/stoptx/', methods=['GET'])
183 def usrp_stop():
190 def usrptx_stop():
191 #stop_usrp_tx = subprocess.Popen(["pkill", "-f", "tx.py"], stdout=subprocess.PIPE)
184 return 'USRP stopped'
192 return 'USRP stopped'
185
193
186 if __name__ =='__main__':
194 if __name__ =='__main__':
187 app.run(debug=True, port=4000) No newline at end of file
195 app.run(debug=True, port=4000)
General Comments 0
You need to be logged in to leave comments. Login now