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