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