##// END OF EJS Templates
Update models.py (generator, pedestal, usrp tx, ursp rx, experiments
eynilupu -
r398:e746ceb18854
parent child
Show More
@@ -1,215 +1,211
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 SELECTOR_VALUE = (
16 16 (0, 'disable'),
17 17 (1, 'enable')
18 18 )
19 19
20 20 class GeneratorConfiguration(Configuration):
21 21
22 22 delay = models.IntegerField(
23 23 verbose_name='Delay',
24 24 blank=False,
25 25 null=False,
26 26 help_text='Introduce the value in us'
27 27 )
28 28
29 29 periode_1 = models.IntegerField(
30 30 verbose_name='Periode 1',
31 31 blank=False,
32 32 null=False,
33 33 help_text='Introduce the value in us'
34 34 )
35 35
36 36 width_1 = models.IntegerField(
37 37 verbose_name='Pulse Width 1',
38 38 blank=False,
39 39 null=False,
40 40 help_text='Introduce the value in us'
41 41 )
42 42
43 43 ntx_1 = models.IntegerField(
44 44 verbose_name='NTX 1',
45 45 blank=False,
46 46 null=False
47 47 )
48 48
49 49 enable_2 = models.BooleanField(
50 50 verbose_name='Pulse 2',
51 51 default=True,
52 52 blank=False,
53 53 null=False,
54 54 )
55 55
56 56 periode_2 = models.IntegerField(
57 57 verbose_name='Periode 2',
58 58 blank=False,
59 59 null=False,
60 60 help_text='Introduce the value in us'
61 61 )
62 62
63 63 width_2 = models.IntegerField(
64 64 verbose_name='Pulse Width 2',
65 65 blank=False,
66 66 null=False,
67 67 help_text='Introduce the value in us'
68 68 )
69 69
70 70 ntx_2 = models.IntegerField(
71 71 verbose_name='NTX 2',
72 72 blank=False,
73 73 null=False
74 74 )
75 75
76 76 selector = models.IntegerField(
77 77 verbose_name='Selector',
78 78 choices=SELECTOR_VALUE,
79 79 blank=False,
80 80 null=False
81 81 )
82 82
83 83 class Meta:
84 84 db_table = 'generator_configurations'
85 85
86 86 def __str__(self):
87 87 if not self.enable_2:
88 88 return u'TR: Period: {} us, PW: {} us, {} NTX'.format(self.periode_1, self.width_1, self.ntx_1)
89 89 else:
90 90 return u'TR1: Period: {} us, PW: {} us, {} NTX - TR2: Period: {} us, PW: {} us, {} NTX'.format(self.periode_1, self.width_1, self.ntx_1, self.periode_2, self.width_2, self.ntx_2)
91 91
92 92 def get_absolute_url_plot(self):
93 93 return reverse('url_plot_generator_pulses', args=[str(self.id)])
94 94
95 95 def request(self, cmd, method='get', **kwargs):
96 96
97 97 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
98 98 payload = req.json()
99 99
100 100 return payload
101 101
102 102 def status_device(self):
103 103
104 104 try:
105 #self.device.status = 0
106 #payload = self.request('status')
107 105 payload = requests.get(self.device.url())
108 106
109 107 if payload:
110 108 self.device.status = 1
111 109 elif payload['status']=='disable':
112 110 self.device.status = 2
113 111 else:
114 112 self.device.status = 1
115 113 self.device.save()
116 114 self.message = 'Generator status: {}'.format(payload['status'])
117 115 return False
118 116 except Exception as e:
119 117 if 'No route to host' not in str(e):
120 118 self.device.status = 4
121 119 self.device.save()
122 120 self.message = 'Generator status: {}'.format(str(e))
123 121 return False
124 122
125 123 self.device.save()
126 124 return True
127 125
128 126 def reset_device(self):
129 127
130 128 try:
131 129 payload = self.request('reset', 'post')
132 130 if payload['reset']=='ok':
133 131 self.message = 'Generator restarted OK'
134 132 self.device.status = 2
135 133 self.device.save()
136 134 else:
137 135 self.message = 'Generator restart fail'
138 136 self.device.status = 4
139 137 self.device.save()
140 138 except Exception as e:
141 139 self.message = 'Generator reset: {}'.format(str(e))
142 140 return False
143 141
144 142 return True
145 143
146 144 def stop_device(self):
147 145
148 146 try:
149 self.selector = 0
150 self.save()
151 payload = {"enable": self.selector}
147 payload = {"enable": 0}
152 148
153 149 json_trmode_selector = json.dumps(payload)
154 150 base64_trmode_selector = base64.standard_b64encode(json_trmode_selector.encode('ascii'))
155 151
156 152 trmode_url = self.device.url() + "trmode?params="
157 153 url_trmode_selector = trmode_url + base64_trmode_selector.decode('ascii')
158 154 r = requests.get(url_trmode_selector)
159 155
160 156 if r:
161 157 self.device.status = 4
162 158 self.device.save()
163 159 self.message = 'Generator stopped'
164 160 else:
165 161 self.device.status = 4
166 162 self.device.save()
167 163 return False
168 164 except Exception as e:
169 165 if 'No route to host' not in str(e):
170 166 self.device.status = 4
171 167 else:
172 168 self.device.status = 0
173 169 #self.message = 'Generator stop: {}'.format(str(e))
174 170 self.message = "Generator can't start, please check network/device connection or IP address/port configuration"
175 171 self.device.save()
176 172 return False
177 173
178 174 return True
179 175
180 176 def start_device(self):
181 177
182 178 try:
183 179 if self.enable_2:
184 180 payload = {"Delay": self.delay, "periode1": self.periode_1, "width1": self.width_1, "repeatability1": self.ntx_1, "periode2": self.periode_2, "width2": self.width_2, "repeatability2": self.ntx_2, "enable": self.selector}
185 181 else:
186 182 payload = {"Delay": self.delay, "periode1": self.periode_1, "width1": self.width_1, "repeatability1": 1, "periode2": self.periode_1, "width2": self.width_1, "repeatability2": 1, "enable": self.selector}
187 183
188 184 json_trmode = json.dumps(payload)
189 185
190 186 base64_trmode = base64.standard_b64encode(json_trmode.encode('ascii'))
191 187
192 188 trmode_url = self.device.url() + "trmode?params="
193 189 complete_url_trmode = trmode_url + base64_trmode.decode('ascii')
194 190
195 191 r = requests.get(complete_url_trmode)
196 192
197 193 if r:
198 194 self.device.status = 3
199 195 self.device.save()
200 196 self.message = 'Generator configured and started'
201 197 else:
202 198 return False
203 199 except Exception as e:
204 200 if 'No route to host' not in str(e):
205 201 self.device.status = 4
206 202 else:
207 203 self.device.status = 0
208 204 self.message = "Generator can't start, please check network/device connection or IP address/port configuration"
209 205 self.device.save()
210 206 return False
211 207
212 208 return True
213 209
214 210 def get_absolute_url_import(self):
215 211 return reverse('url_import_generator_conf', args=[str(self.id)])
@@ -1,618 +1,615
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 import base64
8 8
9 9 try:
10 10 from polymorphic.models import PolymorphicModel
11 11 except:
12 12 from polymorphic import PolymorphicModel
13 13
14 14 from django.template.base import kwarg_re
15 15 from django.db import models
16 16 from django.urls import reverse
17 17 from django.core.validators import MinValueValidator, MaxValueValidator
18 18 from django.shortcuts import get_object_or_404
19 19 from django.contrib.auth.models import User
20 20 from django.db.models.signals import post_save
21 21 from django.dispatch import receiver
22 22
23 23 from apps.main.utils import Params
24 24
25 25 DEV_PORTS = {
26 26 'pedestal' : 80,
27 27 'pedestal_dev' : 80,
28 28 'generator' : 80,
29 29 'usrp_rx' : 2000,
30 30 'usrp_tx' : 2000,
31 31 }
32 32
33 33 RADAR_STATES = (
34 34 (0, 'No connected'),
35 35 (1, 'Connected'),
36 36 (2, 'Configured'),
37 37 (3, 'Running'),
38 38 (4, 'Scheduled'),
39 39 )
40 40
41 41 EXPERIMENT_TYPE = (
42 42 (0, 'RAW_DATA'),
43 43 (1, 'PDATA'),
44 44 )
45 45
46 46 DECODE_TYPE = (
47 47 (0, 'None'),
48 48 (1, 'TimeDomain'),
49 49 (2, 'FreqDomain'),
50 50 (3, 'InvFreqDomain'),
51 51 )
52 52
53 53 DEV_STATES = (
54 54 (0, 'Unknown'),
55 55 (1, 'Connected'),
56 56 (2, 'Configured'),
57 57 (3, 'Running'),
58 58 (4, 'Offline'),
59 59 )
60 60
61 61 DEV_TYPES = (
62 62 ('', 'Select a device type'),
63 63 ('pedestal', 'Pedestal Controller'),
64 64 ('pedestal_dev', 'Pedestal Controller Dev Mode'),
65 65 ('generator', 'Pulse Generator'),
66 66 ('usrp_rx', 'Universal Software Radio Peripheral Rx'),
67 67 ('usrp_tx', 'Universal Software Radio Peripheral Tx'),
68 68 )
69 69
70 70 EXP_STATES = (
71 71 (0,'Error'), #RED
72 72 (1,'Cancelled'), #YELLOW
73 73 (2,'Running'), #GREEN
74 74 (3,'Scheduled'), #BLUE
75 75 (4,'Unknown'), #WHITE
76 76 )
77 77
78 78 CONF_TYPES = (
79 79 (0, 'Active'),
80 80 (1, 'Historical'),
81 81 )
82 82
83 83 class Profile(models.Model):
84 84 user = models.OneToOneField(User, on_delete=models.CASCADE)
85 85 theme = models.CharField(max_length=30, default='spacelab')
86 86
87 87
88 88 @receiver(post_save, sender=User)
89 89 def create_user_profile(sender, instance, created, **kwargs):
90 90 if created:
91 91 Profile.objects.create(user=instance)
92 92
93 93 @receiver(post_save, sender=User)
94 94 def save_user_profile(sender, instance, **kwargs):
95 95 instance.profile.save()
96 96
97 97
98 98 class DeviceType(models.Model):
99 99
100 100 name = models.CharField(max_length = 15, choices = DEV_TYPES, default = 'pedestal')
101 101 sequence = models.PositiveSmallIntegerField(default=55)
102 102 description = models.TextField(blank=True, null=True)
103 103
104 104 class Meta:
105 105 db_table = 'db_device_types'
106 106
107 107 def __str__(self):
108 108 return u'%s' % self.name.title()
109 109
110 110 class Device(models.Model):
111 111
112 112 device_type = models.ForeignKey('DeviceType', on_delete=models.CASCADE)
113 113 ip_address = models.GenericIPAddressField(verbose_name = 'IP address', protocol='IPv4', default='0.0.0.0')
114 114 port_address = models.PositiveSmallIntegerField(default=2000)
115 115 description = models.TextField(blank=True, null=True)
116 116 status = models.PositiveSmallIntegerField(default=4, choices=DEV_STATES)
117 117 conf_active = models.PositiveIntegerField(default=0, verbose_name='Current configuration')
118 118
119 119 class Meta:
120 120 db_table = 'db_devices'
121 121
122 122 def __str__(self):
123 123 ret = self.device_type
124 124 return str(ret)
125 125
126 126 @property
127 127 def name(self):
128 128 return str(self)
129 129
130 130 def get_status(self):
131 131 return self.status
132 132
133 133 @property
134 134 def status_color(self):
135 135 color = 'muted'
136 136 if self.status == 0:
137 137 color = "danger"
138 138 elif self.status == 1:
139 139 color = "primary"
140 140 elif self.status == 2:
141 141 color = "info"
142 142 elif self.status == 3:
143 143 color = "success"
144 144
145 145 return color
146 146
147 147 def url(self, path=None):
148 148
149 149 if path:
150 150 return 'http://{}:{}/{}/'.format(self.ip_address, self.port_address, path)
151 151 else:
152 152 return 'http://{}:{}/'.format(self.ip_address, self.port_address)
153 153
154 154 def get_absolute_url(self):
155 155 return reverse('url_device', args=[str(self.id)])
156 156
157 157 def get_absolute_url_edit(self):
158 158 return reverse('url_edit_device', args=[str(self.id)])
159 159
160 160 def get_absolute_url_delete(self):
161 161 return reverse('url_delete_device', args=[str(self.id)])
162 162
163 163 def change_ip(self, ip_address, mask, gateway, dns, **kwargs):
164 164
165 165 if self.device_type.name=='pedestal':
166 166 headers = {'content-type': "application/json",
167 167 'cache-control': "no-cache"}
168 168
169 169 ip = [int(x) for x in ip_address.split('.')]
170 170 dns = [int(x) for x in dns.split('.')]
171 171 gateway = [int(x) for x in gateway.split('.')]
172 172 subnet = [int(x) for x in mask.split('.')]
173 173
174 174 payload = {
175 175 "ip": ip,
176 176 "dns": dns,
177 177 "gateway": gateway,
178 178 "subnet": subnet
179 179 }
180 180
181 181 req = requests.post(self.url('changeip'), data=json.dumps(payload), headers=headers)
182 182 try:
183 183 answer = req.json()
184 184 if answer['changeip']=='ok':
185 185 self.message = '25|IP succesfully changed'
186 186 self.ip_address = ip_address
187 187 self.save()
188 188 else:
189 189 self.message = '30|An error ocuur when changing IP'
190 190 except Exception as e:
191 191 self.message = '40|{}'.format(str(e))
192 192 else:
193 193 self.message = 'Not implemented'
194 194 return False
195 195
196 196 return True
197 197
198 198
199 199 class Experiment(PolymorphicModel):
200 200
201 201 name = models.CharField(max_length=40, default='', unique=True)
202 202 pedestal = models.ForeignKey('pedestal.PedestalConfiguration', null=False, blank=False, on_delete=models.PROTECT, default=None, related_name = "pedestal_conf")
203 203 generator = models.ForeignKey('generator.GeneratorConfiguration', null=False, blank=False, on_delete=models.PROTECT, default=None, related_name = "generator_conf")
204 204 reception_rx = models.ForeignKey('usrp_rx.USRPRXConfiguration', null=False, blank=False, on_delete=models.PROTECT, default=None, related_name = "usrp_rx_CONF")
205 205 transmission_tx = models.ForeignKey('usrp_tx.USRPTXConfiguration', null=False, blank=False, on_delete=models.PROTECT, default=None, related_name = "usrp_tx")
206 206 task = models.CharField(max_length=36, default='', blank=True, null=True)
207 207 status = models.PositiveSmallIntegerField(default=4, choices=EXP_STATES)
208 208 author = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE)
209 209 hash = models.CharField(default='', max_length=64, null=True, blank=True)
210 210 latitude = models.FloatField(null=True, blank=True)
211 211 longitude = models.FloatField(null=True, blank=True)
212 212 heading = models.FloatField(null=True, blank=True)
213 213
214 214 class Meta:
215 215 db_table = 'db_experiments'
216 216 ordering = ('name',)
217 217
218 218 def __str__(self):
219 219 return u'%s' % (self.name)
220 220
221 221 def jsonify(self):
222 222
223 223 data = {}
224 224
225 225 ignored = []
226 226
227 227 for field in self._meta.fields:
228 228 if field.name in ignored:
229 229 continue
230 230 data[field.name] = field.value_from_object(self)
231 231
232 232 data['configurations'] = ['{}'.format(conf.pk) for
233 233 conf in Configuration.objects.filter(experiment=self, type=0)]
234 234
235 235 return data
236 236
237 237 def clone(self, **kwargs):
238 238
239 239 confs = Configuration.objects.filter(experiment=self, type=0)
240 240 self.pk = None
241 241 self.name = '{}_{:%y%m%d}'.format(self.name, datetime.now())
242 242 for attr, value in kwargs.items():
243 243 setattr(self, attr, value)
244 244
245 245 self.save()
246 246
247 247 for conf in confs:
248 248 conf.clone(experiment=self)
249 249
250 250 return self
251 251
252 252
253 253 def generator_start(self):
254 254 try:
255 255 period = self.transmission_tx.ipp*2/0.3
256 256 if self.transmission_tx.enable_2:
257 257 payload = {"Delay": 0, "periode1": period, "width1": self.transmission_tx.pulse_1, "repeatability1": self.transmission_tx.repetitions_1, "periode2": period, "width2": self.transmission_tx.pulse_2, "repeatability2": self.transmission_tx.repetitions_2, "enable": 1}
258 258 else:
259 259 payload = {"Delay": 0, "periode1": period, "width1": self.transmission_tx.pulse_1, "repeatability1": 1, "periode2": self.transmission_tx.periode_1, "width2": self.transmission_tx.pulse_1, "repeatability2": 1, "enable": 1}
260 260
261 261 json_trmode = json.dumps(payload)
262 262
263 263 base64_trmode = base64.standard_b64encode(json_trmode.encode('ascii'))
264 264
265 265 trmode_url = self.generator.device.url() + "trmode?params="
266 266 complete_url_trmode = trmode_url + base64_trmode.decode('ascii')
267 267
268 268 r = requests.get(complete_url_trmode)
269 269 except:
270 270 return False
271 271 return True
272 272
273 273 def start(self):
274 274 '''
275 275 Configure and start experiments's devices
276 276 '''
277 277
278 278 data = {
279 279 'name': '%s_%d' % (self.name, int(time.time())),
280 280 'latitude': self.latitude,
281 281 'longitude': self.longitude,
282 282 'heading': self.heading
283 283 }
284 284
285 285 self.reception_rx.datadir = os.path.join(os.environ['EXPOSE_NAS'], data['name'], 'rawdata')
286 286 self.reception_rx.save()
287 287
288 288 try:
289 289 proc_url = 'http://'+os.environ['PROC_SITE']+'/start'
290 data['pedestal'] = self.pedestal.jsonify()
291 data['usrp_rx'] = self.reception_rx.jsonify()
292 data['usrp_tx'] = self.transmission_tx.jsonify()
293 r = requests.post(proc_url, json=data)
294 self.reception_rx.start_device()
295 self.pedestal.start_device()
290 data['usrp_rx'] = self.reception_rx.start_device()
291 data['pedestal'] = self.pedestal.start_device()
296 292 self.generator_start()
297 self.transmission_tx.start_device()
293 data['usrp_tx'] = self.transmission_tx.start_device()
294 requests.post(proc_url, json=data)
298 295
299 296 except:
300 297 return 0
301 298 return 2
302 299
303 300
304 301 def stop(self):
305 302 '''
306 303 Stop experiments's devices
307 304 PEDESTAL, GENERATOR & USRP's
308 305 '''
309 306
310 307 try:
311 308 proc_url = 'http://'+os.environ['PROC_SITE']+'/stop'
312 r = requests.get(proc_url)
309 requests.get(proc_url)
313 310 self.reception_rx.stop_device()
314 311 self.pedestal.stop_device()
315 312 self.generator.stop_device()
316 313 self.transmission_tx.stop_device()
317 314 except:
318 315 return 0
319 return 1
316 return 2
320 317
321 318 def get_status(self):
322 319
323 320 if self.status == 3:
324 321 return
325 322
326 323 confs = Configuration.objects.filter(experiment=self, type=0)
327 324
328 325 for conf in confs:
329 326 conf.status_device()
330 327
331 328 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
332 329
333 330 if total==2*confs.count():
334 331 status = 1
335 332 elif total == 3*confs.count():
336 333 status = 2
337 334 else:
338 335 status = 0
339 336
340 337 self.status = status
341 338 self.save()
342 339
343 340 def status_color(self):
344 341 color = 'muted'
345 342 if self.status == 0:
346 343 color = "danger"
347 344 elif self.status == 1:
348 345 color = "warning"
349 346 elif self.status == 2:
350 347 color = "success"
351 348 elif self.status == 3:
352 349 color = "info"
353 350
354 351 return color
355 352
356 353 def parms_to_dict(self):
357 354
358 355 params = Params({})
359 356 params.add(self.jsonify(), 'experiments')
360 357
361 358 configurations = Configuration.objects.filter(experiment=self, type=0)
362 359
363 360 for conf in configurations:
364 361 params.add(conf.jsonify(), 'configurations')
365 362
366 363 return params.data
367 364
368 365 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
369 366
370 367 configurations = Configuration.objects.filter(experiment=self)
371 368
372 369 if id_exp is not None:
373 370 exp_parms = parms['experiments']['byId'][id_exp]
374 371 else:
375 372 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
376 373
377 374 if configurations:
378 375 for configuration in configurations:
379 376 configuration.delete()
380 377
381 378 for id_conf in exp_parms['configurations']:
382 379 conf_parms = parms['configurations']['byId'][id_conf]
383 380 device = Device.objects.filter(device_type__name=conf_parms['device_type'])[0]
384 381 model = CONF_MODELS[conf_parms['device_type']]
385 382 conf = model(
386 383 experiment = self,
387 384 device = device,
388 385 )
389 386 conf.dict_to_parms(parms, id=id_conf)
390 387
391 388
392 389 self.name = '{}-{}'.format(exp_parms['name'], datetime.now().strftime('%y%m%d'))
393 390 self.save()
394 391
395 392 return self
396 393
397 394 def get_absolute_url(self):
398 395 return reverse('url_experiment', args=[str(self.id)])
399 396
400 397 def get_absolute_url_edit(self):
401 398 return reverse('url_edit_experiment', args=[str(self.id)])
402 399
403 400 def get_absolute_url_delete(self):
404 401 return reverse('url_delete_experiment', args=[str(self.id)])
405 402
406 403 def get_absolute_url_import(self):
407 404 return reverse('url_import_experiment', args=[str(self.id)])
408 405
409 406 def get_absolute_url_export(self):
410 407 return reverse('url_export_experiment', args=[str(self.id)])
411 408
412 409 def get_absolute_url_start(self):
413 410 return reverse('url_start_experiment', args=[str(self.id)])
414 411
415 412 def get_absolute_url_stop(self):
416 413 return reverse('url_stop_experiment', args=[str(self.id)])
417 414
418 415
419 416 class Configuration(PolymorphicModel):
420 417
421 418 id = models.AutoField(primary_key=True)
422 419 device = models.ForeignKey('Device', verbose_name='Device', null=True, on_delete=models.CASCADE)
423 420 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
424 421 created_date = models.DateTimeField(auto_now_add=True)
425 422 programmed_date = models.DateTimeField(auto_now=True)
426 423 parameters = models.TextField(default='{}')
427 424 author = models.ForeignKey(User, null=True, blank=True,on_delete=models.CASCADE)
428 425 hash = models.CharField(default='', max_length=64, null=True, blank=True)
429 426 message = ""
430 427
431 428 class Meta:
432 429 db_table = 'db_configurations'
433 430 ordering = ('device__device_type__name',)
434 431
435 432 def __str__(self):
436 433
437 434 ret = u'{} '.format(self.device.device_type.name.upper())
438 435
439 436 if 'mix' in [f.name for f in self._meta.get_fields()]:
440 437 if self.mix:
441 438 ret = '{} MIX '.format(self.device.device_type.name.upper())
442 439
443 440 if 'label' in [f.name for f in self._meta.get_fields()]:
444 441 ret += '{}'.format(self.label)
445 442
446 443 return ret
447 444
448 445 @property
449 446 def name(self):
450 447
451 448 return str(self)
452 449
453 450 @property
454 451 def label(self):
455 452
456 453 return str(self)
457 454
458 455 def jsonify(self):
459 456
460 457 data = {}
461 458
462 459 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
463 460 'created_date', 'programmed_date', 'device',
464 461 'experiment', 'author')
465 462
466 463 for field in self._meta.fields:
467 464 if field.name in ignored:
468 465 continue
469 466 data[field.name] = field.value_from_object(self)
470 467
471 468 data['device_type'] = self.device.device_type.name
472 469 return data
473 470
474 471 def clone(self, **kwargs):
475 472
476 473 self.pk = None
477 474 self.id = None
478 475 for attr, value in kwargs.items():
479 476 setattr(self, attr, value)
480 477
481 478 self.save()
482 479
483 480 return self
484 481
485 482 def parms_to_dict(self):
486 483
487 484 params = Params({})
488 485 params.add(self.jsonify(), 'configurations')
489 486 return params.data
490 487
491 488 def parms_to_text(self):
492 489
493 490 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
494 491
495 492
496 493 def parms_to_binary(self):
497 494
498 495 raise NotImplementedError("This method should be implemented in %s Configuration model" %str(self.device.device_type.name).upper())
499 496
500 497
501 498 def dict_to_parms(self, parameters, id=None):
502 499
503 500 params = Params(parameters)
504 501
505 502 if id:
506 503 data = params.get_conf(id_conf=id)
507 504 else:
508 505 data = params.get_conf(dtype=self.device.device_type.name)
509 506
510 507 for key, value in data.items():
511 508 if key not in ('id', 'device_type'):
512 509 setattr(self, key, value)
513 510
514 511 self.save()
515 512
516 513
517 514 def export_to_file(self, format="json"):
518 515
519 516 content_type = ''
520 517
521 518 if format == 'racp':
522 519 content_type = 'text/plain'
523 520 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, 'racp')
524 521 content = self.parms_to_text(file_format = 'racp')
525 522
526 523 if format == 'text':
527 524 content_type = 'text/plain'
528 525 filename = '%s_%s.%s' %(self.device.device_type.name, self.name, self.device.device_type.name)
529 526 content = self.parms_to_text()
530 527
531 528 if format == 'binary':
532 529 content_type = 'application/octet-stream'
533 530 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
534 531 content = self.parms_to_binary()
535 532
536 533 if not content_type:
537 534 content_type = 'application/json'
538 535 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
539 536 content = json.dumps(self.parms_to_dict(), indent=2)
540 537
541 538
542 539 fields = {'content_type':content_type,
543 540 'filename':filename,
544 541 'content':content
545 542 }
546 543
547 544 return fields
548 545
549 546 def import_from_file(self, fp):
550 547
551 548 parms = {}
552 549
553 550 path, ext = os.path.splitext(fp.name)
554 551
555 552 if ext == '.json':
556 553 parms = json.load(fp)
557 554
558 555 return parms
559 556
560 557 def status_device(self):
561 558
562 559 self.message = 'Function not supported'
563 560 return False
564 561
565 562
566 563 def stop_device(self):
567 564
568 565 self.message = 'Function not supported'
569 566 return False
570 567
571 568
572 569 def start_device(self):
573 570
574 571 self.message = 'Function not supported'
575 572 return False
576 573
577 574
578 575 def write_device(self):
579 576
580 577 self.message = 'Function not supported'
581 578 return False
582 579
583 580
584 581 def read_device(self):
585 582
586 583 self.message = 'Function not supported'
587 584 return False
588 585
589 586
590 587 def get_absolute_url(self):
591 588 return reverse('url_%s_conf' % self.device.device_type.name, args=[str(self.id)])
592 589
593 590 def get_absolute_url_edit(self):
594 591 return reverse('url_edit_%s_conf' % self.device.device_type.name, args=[str(self.id)])
595 592
596 593 def get_absolute_url_delete(self):
597 594 return reverse('url_delete_dev_conf', args=[str(self.id)])
598 595
599 596 def get_absolute_url_import(self):
600 597 return reverse('url_import_dev_conf', args=[str(self.id)])
601 598
602 599 def get_absolute_url_export(self):
603 600 return reverse('url_export_dev_conf', args=[str(self.id)])
604 601
605 602 def get_absolute_url_write(self):
606 603 return reverse('url_write_dev_conf', args=[str(self.id)])
607 604
608 605 def get_absolute_url_read(self):
609 606 return reverse('url_read_dev_conf', args=[str(self.id)])
610 607
611 608 def get_absolute_url_start(self):
612 609 return reverse('url_start_dev_conf', args=[str(self.id)])
613 610
614 611 def get_absolute_url_stop(self):
615 612 return reverse('url_stop_dev_conf', args=[str(self.id)])
616 613
617 614 def get_absolute_url_status(self):
618 615 return reverse('url_status_dev_conf', args=[str(self.id)])
@@ -1,255 +1,263
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 MODE_VALUE = (
16 16 ('position', 'Position'),
17 17 ('speed', 'Speed'),
18 18 ('table', 'Table')
19 19 )
20 20
21 21 class PedestalConfiguration(Configuration):
22 22
23 23 mode = models.CharField(
24 24 verbose_name='Mode',
25 25 max_length=10,
26 26 choices=MODE_VALUE,
27 27 null=False,
28 28 blank=False
29 29 )
30 30
31 31 axis = models.CharField(
32 32 verbose_name="Axis",
33 33 max_length=100,
34 34 default='az',
35 35 blank=False,
36 36 null=False,
37 37 help_text="Please separate the values with commas when using table mode"
38 38 )
39 39
40 40 speed = models.CharField(
41 41 verbose_name='Speed',
42 42 max_length=100,
43 43 blank=False,
44 44 null=False,
45 45 default=6
46 46 )
47 47
48 48 angle = models.CharField(
49 49 verbose_name="Angle(s)",
50 50 max_length=100,
51 51 default='0',
52 52 blank=False,
53 53 null=False,
54 54 help_text="Please separate the values with commas when using table mode"
55 55 )
56 56
57 57 min_value = models.FloatField(
58 58 verbose_name='Min angle',
59 59 validators=[MinValueValidator(-5), MaxValueValidator(185)],
60 60 blank=False,
61 61 null=False,
62 62 default=0
63 63 )
64 64
65 65 max_value = models.FloatField(
66 66 verbose_name='Max angle',
67 67 validators=[MinValueValidator(-5), MaxValueValidator(185)],
68 68 blank=False,
69 69 null=False,
70 70 default=40
71 71 )
72 72
73 73 class Meta:
74 74 db_table = 'pedestal_configurations'
75 75
76 76 def __str__(self):
77 77 if self.mode=='position':
78 78 return u'Position: {}ΒΊ {}'.format(self.angle, self.axis.upper())
79 79 if self.mode=='speed':
80 80 return u'Speed: {}ΒΊ/s {}'.format(self.speed, self.axis.upper())
81 81 if self.mode=='table':
82 82 axis = [x.strip().upper() for x in self.axis.split(',')]
83 83 speeds = [float(x.strip()) for x in self.speed.split(',')]
84 84 table = [float(x.strip()) for x in self.angle.split(',')]
85 85 return u'Table: Axis {}, Speed {}ΒΊ/s, Steps {}'.format(axis, speeds, table)
86 86
87 87 @property
88 88 def label(self):
89 89 return str(self)
90 90
91 91 def get_absolute_url_plot(self):
92 92 return reverse('url_plot_pedestal_pulses', args=[str(self.id)])
93 93
94 94 def request(self, cmd, method='get', **kwargs):
95 95
96 96 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
97 97 payload = req.json()
98 98
99 99 return payload
100 100
101 101 def status_device(self):
102 102
103 103 try:
104 104 payload = requests.get(self.device.url())
105 105
106 106 if payload:
107 107 self.device.status = 1
108 108 elif payload['status']=='disable':
109 109 self.device.status = 2
110 110 else:
111 111 self.device.status = 1
112 112 self.device.save()
113 113 self.message = 'Pedestal status: {}'.format(payload['status'])
114 114 return False
115 115 except Exception as e:
116 116 if 'No route to host' not in str(e):
117 117 self.device.status = 4
118 118 self.device.save()
119 119 self.message = 'Pedestal status: {}'.format(str(e))
120 120 return False
121 121
122 122 self.device.save()
123 123 return True
124 124
125 125 def reset_device(self, axi, angle):
126 126
127 127 try:
128 128 url = self.device.url() + "position?params="
129 129
130 130 payload_el = {'axis': 'elevation'}
131 131 payload_az = {'axis': 'azimuth'}
132 132
133 133 if axi == 'elevation':
134 134 payload_az['position'] = angle
135 135 payload_el['position'] = 0
136 136 elif axi == 'azimuth':
137 137 payload_el['position'] = angle
138 138 payload_az['position'] = 0
139 139 else:
140 140 payload_el['position'] = 0
141 141 payload_az['position'] = 0
142 142
143 143 json_data_el = json.dumps(payload_el)
144 144 json_data_az = json.dumps(payload_az)
145 145
146 146 base64_table_el = base64.standard_b64encode(json_data_el.encode('ascii'))
147 147 base64_table_az = base64.standard_b64encode(json_data_az.encode('ascii'))
148 148
149 149 r = requests.get(url + base64_table_el.decode('ascii'))
150 150 r = requests.get(url + base64_table_az.decode('ascii'))
151 151
152 152 if r:
153 153 self.device.status = 3
154 154 self.device.save()
155 155 self.message = 'Pedestal reset'
156 156 else:
157 157 return False
158 158
159 159 except Exception as e:
160 160 self.message = 'Pedestal reset: {}'.format(str(e))
161 161 return False
162 162
163 163 return True
164 164
165 165 def stop_device(self):
166 166
167 167 try:
168 168 command = self.device.url() + "stop"
169 169 r = requests.get(command)
170
171 if self.mode == 'table':
172 AX = {'az':'azimuth', 'el':'elevation'}
173 axis = [AX[x.lower().strip()] for x in self.axis.split(',')]
174 list_of_floats = [float(x.strip()) for x in self.angle.split(",")]
175 self.reset_device(axis[0], list_of_floats[0])
176
170 177 if r:
171 178 self.device.status = 4
172 179 self.device.save()
173 180 self.message = 'Pedestal stopped'
174 181 else:
175 182 self.device.status = 4
176 183 self.device.save()
177 184 return False
178 185 except Exception as e:
179 186 if 'No route to host' not in str(e):
180 187 self.device.status = 4
181 188 else:
182 189 self.device.status = 0
183 190 #self.message = 'Pedestal stop: {}'.format(str(e))
184 191 self.message = "Pedestal can't start, please check network/device connection or IP address/port configuration"
185 192 self.device.save()
186 193 return False
187 194
188 195 return True
189 196
190 197 def start_device(self):
191 198
192 199 AX = {'az':'azimuth', 'el':'elevation'}
193 200 axis = [AX[x.lower().strip()] for x in self.axis.split(',')]
194 201 if len(axis)==1:
195 202 axis = axis[0]
196 203
197 204 try:
198 205 if self.mode == 'position':
199 206 url = self.device.url() + "position?params="
200 207 payload = {'axis': axis, 'position': float(self.angle)}
201 208 elif self.mode == 'speed':
202 209 url = self.device.url() + "speed?params="
203 210 payload = {'axis': axis, 'speed': float(self.speed)}
204 211 elif self.mode == 'table':
205 212 url = self.device.url() + "combinedtable?params="
206 213 list_of_floats = [float(x.strip()) for x in self.angle.split(",")]
207 214 byte_table = []
208 215 for x in list_of_floats:
209 216 temp = bytearray(struct.pack("f", x))
210 217 byte_table.append(temp[3])
211 218 byte_table.append(temp[2])
212 219 byte_table.append(temp[1])
213 220 byte_table.append(temp[0])
214 221
215 222 coded_table = base64.standard_b64encode(bytes(byte_table))
216 223 coded_table_ascii = coded_table.decode('ascii')
217 224 speed = [float(x.strip()) for x in self.speed.split(',')]
218 225 payload = {
219 226 'arraylength': len(speed),
220 227 'axis': axis,
221 228 'speed': speed,
222 229 'bottom': self.min_value,
223 230 'top': self.max_value,
224 231 'table': coded_table_ascii
225 232 }
226 self.reset_device(axis[0], list_of_floats[0])
227 time.sleep(15)
228 233
229 234 json_data = json.dumps(payload)
230 235 print(json_data)
231 236 base64_table = base64.standard_b64encode(json_data.encode('ascii'))
232 237 url += base64_table.decode('ascii')
233 238 print(url)
234 239 r = requests.get(url)
240
241 if self.mode == 'table':
242 payload['table'] = list_of_floats
235 243
236 244 if r:
237 245 self.device.status = 3
238 246 self.device.save()
239 247 self.message = 'Pedestal configured and started'
240 248 else:
241 249 return False
242 250 except Exception as e:
243 251 if 'No route to host' not in str(e):
244 252 self.device.status = 4
245 253 else:
246 254 self.device.status = 0
247 255 #self.message = 'Pedestal start: {}'.format(str(e))
248 256 self.message = "Pedestal can't start, please check network/device connection or IP address/port configuration"
249 257 self.device.save()
250 258 return False
251 259
252 return True
260 return payload
253 261
254 262 def get_absolute_url_import(self):
255 263 return reverse('url_import_pedestal_conf', args=[str(self.id)])
@@ -1,223 +1,220
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 u'RX at {} MHz @ {} MHz'.format(self.frequency, self.samplerate)
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
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 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
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
199 199 r = requests.post(self.device.url("usrprx"), json=payload)
200 200
201 201 if r:
202 202 self.device.status = 3
203 203 self.device.save()
204 204 self.message = 'USRP Rx configured and started'
205 205 else:
206 206 return False
207 207 except Exception as e:
208 208 if 'No route to host' not in str(e):
209 209 self.device.status = 4
210 210 else:
211 211 self.device.status = 0
212 212 #self.message = 'USRP Rx start: {}'.format(str(e))
213 213 self.message = "USRP Rx can't start, please check network/device connection or IP address/port configuration"
214 214 self.device.save()
215 215 return False
216 216
217 return True
217 return payload
218 218
219 219 def get_absolute_url_import(self):
220 return reverse('url_import_usrp_rx_conf', args=[str(self.id)])
221
222
223
220 return reverse('url_import_usrp_rx_conf', args=[str(self.id)]) No newline at end of file
@@ -1,287 +1,287
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
25 25 class TXCode(models.Model):
26 26
27 27 name = models.CharField(max_length=40)
28 28 bits_per_code = models.PositiveIntegerField(default=0)
29 29 number_of_codes = models.PositiveIntegerField(default=0)
30 30 codes = models.TextField(blank=True, null=True)
31 31
32 32 class Meta:
33 33 db_table = 'tx_codes'
34 34 ordering = ('name',)
35 35
36 36 def __str__(self):
37 37 return u'%s' % self.name
38 38
39 39
40 40 class USRPTXConfiguration(Configuration):
41 41
42 42 ip_address = models.GenericIPAddressField(
43 43 verbose_name = 'IP address',
44 44 protocol='IPv4',
45 45 default='0.0.0.0')
46 46
47 47 daughterboard = models.CharField(
48 48 verbose_name='Daughterboard',
49 49 max_length=3,
50 50 choices=BOARD_VALUE,
51 51 null=False,
52 52 blank=False
53 53 )
54 54
55 55 antenna = models.CharField(
56 56 verbose_name='Antenna',
57 57 max_length=3,
58 58 choices=ANT_VALUE,
59 59 null=False,
60 60 blank=False
61 61 )
62 62
63 63 frequency = models.FloatField(
64 64 verbose_name='Frequency [MHz]',
65 65 validators=[MinValueValidator(0.1)],
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 samplerate = models.FloatField(
72 72 verbose_name='Sample rate [MHz]',
73 73 validators=[MinValueValidator(0.1)],
74 74 blank=False,
75 75 null=False,
76 76 help_text='Introduce the value in MHz (10^6)'
77 77 )
78 78
79 79 ipp = models.FloatField(
80 80 verbose_name='IPP [km]',
81 81 validators=[MinValueValidator(0.1)],
82 82 blank=False,
83 83 null=False,
84 84 help_text='Introduce the value in km'
85 85 )
86 86
87 87 delay = models.FloatField(
88 88 verbose_name='Delay [us]',
89 89 validators=[MinValueValidator(0.0)],
90 90 null=False,
91 91 help_text='Introduce the value in Β΅s'
92 92 )
93 93
94 94 pulse_1 = models.FloatField(
95 95 verbose_name='Pulse Width 1 [us]',
96 96 validators=[MinValueValidator(0.1)],
97 97 blank=False,
98 98 null=False,
99 99 help_text='Introduce the value in us'
100 100 )
101 101
102 102 code_type_1 = models.ForeignKey(
103 103 TXCode,
104 104 on_delete=models.CASCADE,
105 105 related_name='%(class)s_code_1',
106 106 verbose_name="Code Type 1"
107 107 )
108 108
109 109 code_1 = models.TextField(
110 110 verbose_name="Code 1",
111 111 blank=True,
112 112 null=True,
113 113 help_text="binary code"
114 114 )
115 115
116 116 repetitions_1 = models.IntegerField(
117 117 verbose_name='NTX 1',
118 118 default=1,
119 119 blank=True,
120 120 null=True
121 121 )
122 122
123 123 enable_2 = models.BooleanField(
124 124 verbose_name='Pulse 2',
125 125 blank=False,
126 126 null=False
127 127 )
128 128
129 129 pulse_2 = models.FloatField(
130 130 verbose_name='Pulse Width 2 [us]',
131 131 default=1,
132 132 blank=True,
133 133 null=True,
134 134 help_text='Introduce the value in Β΅s'
135 135 )
136 136
137 137 code_type_2 = models.ForeignKey(
138 138 TXCode,
139 139 on_delete=models.CASCADE,
140 140 related_name='%(class)s_code_2',
141 141 verbose_name="Code Type 2",
142 142 blank=True,
143 143 null=True,
144 144 )
145 145
146 146 code_2 = models.TextField(
147 147 verbose_name="Code 2",
148 148 blank=True,
149 149 null=True,
150 150 help_text="Introduce the binary code"
151 151 )
152 152
153 153 repetitions_2 = models.IntegerField(
154 154 verbose_name='NTX 2',
155 155 default=0,
156 156 blank=True,
157 157 null=True
158 158 )
159 159
160 160 class Meta:
161 161 db_table = 'usrp_tx_configurations'
162 162
163 163 def __str__(self):
164 164
165 165 if not self.enable_2:
166 166 return 'TX with IPP={}km, Pulse 1: PW={} us, CODE={}'.format(self.ipp, self.pulse_1, self.code_type_1)
167 167 else:
168 168 return 'TX with IPP={}km, Pulse 1: PW={} us, CODE={} Pulse 2: PW={} us, CODE={}'.format(self.ipp, self.pulse_1, self.code_type_1, self.pulse_2, self.code_type_2)
169 169
170 170 def get_absolute_url_plot(self):
171 171 return reverse('url_plot_usrp_tx_pulses', args=[str(self.id)])
172 172
173 173 def request(self, cmd, method='get', **kwargs):
174 174
175 175 req = getattr(requests, method)(self.device.url(cmd), **kwargs)
176 176 payload = req.json()
177 177 return payload
178 178
179 179 def status_device(self):
180 180
181 181 try:
182 182
183 183 payload = requests.get(self.device.url())
184 184
185 185 if payload:
186 186 self.device.status = 1
187 187 elif payload['status']=='disable':
188 188 self.device.status = 2
189 189 else:
190 190 self.device.status = 1
191 191 self.device.save()
192 192 self.message = 'USRP Tx status: {}'.format(payload['status'])
193 193 return False
194 194 except Exception as e:
195 195 if 'No route to host' not in str(e):
196 196 self.device.status = 4
197 197 self.device.save()
198 198 self.message = 'USRP Tx status: {}'.format(str(e))
199 199 return False
200 200
201 201 self.device.save()
202 202 return True
203 203
204 204 def reset_device(self):
205 205
206 206 try:
207 207 payload = self.request('reset', 'post')
208 208 if payload['reset']=='ok':
209 209 self.message = 'USRP Tx restarted OK'
210 210 self.device.status = 2
211 211 self.device.save()
212 212 else:
213 213 self.message = 'USRP Tx restart fail'
214 214 self.device.status = 4
215 215 self.device.save()
216 216 except Exception as e:
217 217 self.message = 'USRP Tx reset: {}'.format(str(e))
218 218 return False
219 219
220 220 return True
221 221
222 222 def stop_device(self):
223 223
224 224 try:
225 225 command = self.device.url() + "stoptx"
226 226 r = requests.get(command)
227 227 if r:
228 228 self.device.status = 4
229 229 self.device.save()
230 230 self.message = 'USRP stopped'
231 231 else:
232 232 self.device.status = 4
233 233 self.device.save()
234 234 return False
235 235 except Exception as e:
236 236 if 'No route to host' not in str(e):
237 237 self.device.status = 4
238 238 else:
239 239 self.device.status = 0
240 240 #self.message = 'USRP Tx stop: {}'.format(str(e))
241 241 self.message = "USRP Tx can't start, please check network/device connection or IP address/port configuration"
242 242 self.device.save()
243 243 return False
244 244
245 245 return True
246 246
247 247 def start_device(self):
248 248
249 249 try:
250 250 usrp = USRPTXConfiguration.objects.get(pk=self)
251 251 usrp_daughterboard = usrp.get_daughterboard_display()
252 252 usrp_antenna = usrp.get_antenna_display()
253 253
254 254 if usrp.enable_2 is True:
255 255 payload = {'ip_address': usrp.ip_address, 'daughterboard': usrp_daughterboard, 'antenna': usrp_antenna,
256 256 'frequency': usrp.frequency, 'sample_rate': usrp.samplerate, 'ipp': usrp.ipp, 'delay': usrp.delay,
257 257 'pulse_1': usrp.pulse_1, 'code_type_1': usrp.code_type_1.name, 'code_1': usrp.code_1,
258 258 'repetitions_1': usrp.repetitions_1, 'enable_2': usrp.enable_2, 'pulse_2': usrp.pulse_2, 'code_type_2': usrp.code_type_2.name,
259 259 'code_2': usrp.code_2, 'repetitions_2': usrp.repetitions_2}
260 260 else:
261 261 payload = {'ip_address': usrp.ip_address, 'daughterboard': usrp_daughterboard, 'antenna': usrp_antenna,
262 262 'frequency': usrp.frequency, 'sample_rate': usrp.samplerate, 'ipp': usrp.ipp, 'delay': usrp.delay,
263 263 'pulse_1': usrp.pulse_1, 'code_type_1': usrp.code_type_1.name, 'code_1': usrp.code_1,
264 264 'repetitions_1': usrp.repetitions_1, 'enable_2': usrp.enable_2}
265 265
266 266 r = requests.post(self.device.url("usrptx"), json=payload)
267 267
268 268 if r:
269 269 self.device.status = 3
270 270 self.device.save()
271 271 self.message = 'USRP Tx configured and started'
272 272 else:
273 273 return False
274 274 except Exception as e:
275 275 if 'No route to host' not in str(e):
276 276 self.device.status = 4
277 277 else:
278 278 self.device.status = 0
279 279 #self.message = 'USRP Tx start: {}'.format(str(e))
280 280 self.message = "USRP Tx can't start, please check network/device connection or IP address/port configuration"
281 281 self.device.save()
282 282 return False
283 283
284 return True
284 return payload
285 285
286 286 def get_absolute_url_import(self):
287 287 return reverse('url_import_usrp_tx_conf', args=[str(self.id)]) No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now