##// END OF EJS Templates
Update models.py files (pedestal and main/generator)
eynilupu -
r402:40436666afd2
parent child
Show More
@@ -1,615 +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": 1, "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": 1, "periode1": period, "width1": self.transmission_tx.pulse_1, "repeatability1": 1, "periode2": period, "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 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['usrp_rx'] = self.reception_rx.start_device()
290 data['usrp_rx'] = self.reception_rx.start_device()
291 data['pedestal'] = self.pedestal.start_device()
291 data['pedestal'] = self.pedestal.start_device()
292 self.generator_start()
292 self.generator_start()
293 data['usrp_tx'] = self.transmission_tx.start_device()
293 data['usrp_tx'] = self.transmission_tx.start_device()
294 requests.post(proc_url, json=data)
294 requests.post(proc_url, json=data)
295
295
296 except:
296 except:
297 return 0
297 return 0
298 return 2
298 return 2
299
299
300
300
301 def stop(self):
301 def stop(self):
302 '''
302 '''
303 Stop experiments's devices
303 Stop experiments's devices
304 PEDESTAL, GENERATOR & USRP's
304 PEDESTAL, GENERATOR & USRP's
305 '''
305 '''
306
306
307 try:
307 try:
308 proc_url = 'http://'+os.environ['PROC_SITE']+'/stop'
308 proc_url = 'http://'+os.environ['PROC_SITE']+'/stop'
309 requests.get(proc_url)
309 requests.get(proc_url)
310 self.reception_rx.stop_device()
310 self.reception_rx.stop_device()
311 self.pedestal.stop_device()
311 self.pedestal.stop_device()
312 self.generator.stop_device()
312 self.generator.stop_device()
313 self.transmission_tx.stop_device()
313 self.transmission_tx.stop_device()
314 except:
314 except:
315 return 0
315 return 0
316 return 2
316 return 2
317
317
318 def get_status(self):
318 def get_status(self):
319
319
320 if self.status == 3:
320 if self.status == 3:
321 return
321 return
322
322
323 confs = Configuration.objects.filter(experiment=self, type=0)
323 confs = Configuration.objects.filter(experiment=self, type=0)
324
324
325 for conf in confs:
325 for conf in confs:
326 conf.status_device()
326 conf.status_device()
327
327
328 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
328 total = confs.aggregate(models.Sum('device__status'))['device__status__sum']
329
329
330 if total==2*confs.count():
330 if total==2*confs.count():
331 status = 1
331 status = 1
332 elif total == 3*confs.count():
332 elif total == 3*confs.count():
333 status = 2
333 status = 2
334 else:
334 else:
335 status = 0
335 status = 0
336
336
337 self.status = status
337 self.status = status
338 self.save()
338 self.save()
339
339
340 def status_color(self):
340 def status_color(self):
341 color = 'muted'
341 color = 'muted'
342 if self.status == 0:
342 if self.status == 0:
343 color = "danger"
343 color = "danger"
344 elif self.status == 1:
344 elif self.status == 1:
345 color = "warning"
345 color = "warning"
346 elif self.status == 2:
346 elif self.status == 2:
347 color = "success"
347 color = "success"
348 elif self.status == 3:
348 elif self.status == 3:
349 color = "info"
349 color = "info"
350
350
351 return color
351 return color
352
352
353 def parms_to_dict(self):
353 def parms_to_dict(self):
354
354
355 params = Params({})
355 params = Params({})
356 params.add(self.jsonify(), 'experiments')
356 params.add(self.jsonify(), 'experiments')
357
357
358 configurations = Configuration.objects.filter(experiment=self, type=0)
358 configurations = Configuration.objects.filter(experiment=self, type=0)
359
359
360 for conf in configurations:
360 for conf in configurations:
361 params.add(conf.jsonify(), 'configurations')
361 params.add(conf.jsonify(), 'configurations')
362
362
363 return params.data
363 return params.data
364
364
365 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
365 def dict_to_parms(self, parms, CONF_MODELS, id_exp=None):
366
366
367 configurations = Configuration.objects.filter(experiment=self)
367 configurations = Configuration.objects.filter(experiment=self)
368
368
369 if id_exp is not None:
369 if id_exp is not None:
370 exp_parms = parms['experiments']['byId'][id_exp]
370 exp_parms = parms['experiments']['byId'][id_exp]
371 else:
371 else:
372 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
372 exp_parms = parms['experiments']['byId'][parms['experiments']['allIds'][0]]
373
373
374 if configurations:
374 if configurations:
375 for configuration in configurations:
375 for configuration in configurations:
376 configuration.delete()
376 configuration.delete()
377
377
378 for id_conf in exp_parms['configurations']:
378 for id_conf in exp_parms['configurations']:
379 conf_parms = parms['configurations']['byId'][id_conf]
379 conf_parms = parms['configurations']['byId'][id_conf]
380 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]
381 model = CONF_MODELS[conf_parms['device_type']]
381 model = CONF_MODELS[conf_parms['device_type']]
382 conf = model(
382 conf = model(
383 experiment = self,
383 experiment = self,
384 device = device,
384 device = device,
385 )
385 )
386 conf.dict_to_parms(parms, id=id_conf)
386 conf.dict_to_parms(parms, id=id_conf)
387
387
388
388
389 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'))
390 self.save()
390 self.save()
391
391
392 return self
392 return self
393
393
394 def get_absolute_url(self):
394 def get_absolute_url(self):
395 return reverse('url_experiment', args=[str(self.id)])
395 return reverse('url_experiment', args=[str(self.id)])
396
396
397 def get_absolute_url_edit(self):
397 def get_absolute_url_edit(self):
398 return reverse('url_edit_experiment', args=[str(self.id)])
398 return reverse('url_edit_experiment', args=[str(self.id)])
399
399
400 def get_absolute_url_delete(self):
400 def get_absolute_url_delete(self):
401 return reverse('url_delete_experiment', args=[str(self.id)])
401 return reverse('url_delete_experiment', args=[str(self.id)])
402
402
403 def get_absolute_url_import(self):
403 def get_absolute_url_import(self):
404 return reverse('url_import_experiment', args=[str(self.id)])
404 return reverse('url_import_experiment', args=[str(self.id)])
405
405
406 def get_absolute_url_export(self):
406 def get_absolute_url_export(self):
407 return reverse('url_export_experiment', args=[str(self.id)])
407 return reverse('url_export_experiment', args=[str(self.id)])
408
408
409 def get_absolute_url_start(self):
409 def get_absolute_url_start(self):
410 return reverse('url_start_experiment', args=[str(self.id)])
410 return reverse('url_start_experiment', args=[str(self.id)])
411
411
412 def get_absolute_url_stop(self):
412 def get_absolute_url_stop(self):
413 return reverse('url_stop_experiment', args=[str(self.id)])
413 return reverse('url_stop_experiment', args=[str(self.id)])
414
414
415
415
416 class Configuration(PolymorphicModel):
416 class Configuration(PolymorphicModel):
417
417
418 id = models.AutoField(primary_key=True)
418 id = models.AutoField(primary_key=True)
419 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)
420 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
420 type = models.PositiveSmallIntegerField(default=0, choices=CONF_TYPES)
421 created_date = models.DateTimeField(auto_now_add=True)
421 created_date = models.DateTimeField(auto_now_add=True)
422 programmed_date = models.DateTimeField(auto_now=True)
422 programmed_date = models.DateTimeField(auto_now=True)
423 parameters = models.TextField(default='{}')
423 parameters = models.TextField(default='{}')
424 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)
425 hash = models.CharField(default='', max_length=64, null=True, blank=True)
425 hash = models.CharField(default='', max_length=64, null=True, blank=True)
426 message = ""
426 message = ""
427
427
428 class Meta:
428 class Meta:
429 db_table = 'db_configurations'
429 db_table = 'db_configurations'
430 ordering = ('device__device_type__name',)
430 ordering = ('device__device_type__name',)
431
431
432 def __str__(self):
432 def __str__(self):
433
433
434 ret = u'{} '.format(self.device.device_type.name.upper())
434 ret = u'{} '.format(self.device.device_type.name.upper())
435
435
436 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()]:
437 if self.mix:
437 if self.mix:
438 ret = '{} MIX '.format(self.device.device_type.name.upper())
438 ret = '{} MIX '.format(self.device.device_type.name.upper())
439
439
440 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()]:
441 ret += '{}'.format(self.label)
441 ret += '{}'.format(self.label)
442
442
443 return ret
443 return ret
444
444
445 @property
445 @property
446 def name(self):
446 def name(self):
447
447
448 return str(self)
448 return str(self)
449
449
450 @property
450 @property
451 def label(self):
451 def label(self):
452
452
453 return str(self)
453 return str(self)
454
454
455 def jsonify(self):
455 def jsonify(self):
456
456
457 data = {}
457 data = {}
458
458
459 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
459 ignored = ('type', 'polymorphic_ctype', 'configuration_ptr',
460 'created_date', 'programmed_date', 'device',
460 'created_date', 'programmed_date', 'device',
461 'experiment', 'author')
461 'experiment', 'author')
462
462
463 for field in self._meta.fields:
463 for field in self._meta.fields:
464 if field.name in ignored:
464 if field.name in ignored:
465 continue
465 continue
466 data[field.name] = field.value_from_object(self)
466 data[field.name] = field.value_from_object(self)
467
467
468 data['device_type'] = self.device.device_type.name
468 data['device_type'] = self.device.device_type.name
469 return data
469 return data
470
470
471 def clone(self, **kwargs):
471 def clone(self, **kwargs):
472
472
473 self.pk = None
473 self.pk = None
474 self.id = None
474 self.id = None
475 for attr, value in kwargs.items():
475 for attr, value in kwargs.items():
476 setattr(self, attr, value)
476 setattr(self, attr, value)
477
477
478 self.save()
478 self.save()
479
479
480 return self
480 return self
481
481
482 def parms_to_dict(self):
482 def parms_to_dict(self):
483
483
484 params = Params({})
484 params = Params({})
485 params.add(self.jsonify(), 'configurations')
485 params.add(self.jsonify(), 'configurations')
486 return params.data
486 return params.data
487
487
488 def parms_to_text(self):
488 def parms_to_text(self):
489
489
490 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())
491
491
492
492
493 def parms_to_binary(self):
493 def parms_to_binary(self):
494
494
495 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())
496
496
497
497
498 def dict_to_parms(self, parameters, id=None):
498 def dict_to_parms(self, parameters, id=None):
499
499
500 params = Params(parameters)
500 params = Params(parameters)
501
501
502 if id:
502 if id:
503 data = params.get_conf(id_conf=id)
503 data = params.get_conf(id_conf=id)
504 else:
504 else:
505 data = params.get_conf(dtype=self.device.device_type.name)
505 data = params.get_conf(dtype=self.device.device_type.name)
506
506
507 for key, value in data.items():
507 for key, value in data.items():
508 if key not in ('id', 'device_type'):
508 if key not in ('id', 'device_type'):
509 setattr(self, key, value)
509 setattr(self, key, value)
510
510
511 self.save()
511 self.save()
512
512
513
513
514 def export_to_file(self, format="json"):
514 def export_to_file(self, format="json"):
515
515
516 content_type = ''
516 content_type = ''
517
517
518 if format == 'racp':
518 if format == 'racp':
519 content_type = 'text/plain'
519 content_type = 'text/plain'
520 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')
521 content = self.parms_to_text(file_format = 'racp')
521 content = self.parms_to_text(file_format = 'racp')
522
522
523 if format == 'text':
523 if format == 'text':
524 content_type = 'text/plain'
524 content_type = 'text/plain'
525 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)
526 content = self.parms_to_text()
526 content = self.parms_to_text()
527
527
528 if format == 'binary':
528 if format == 'binary':
529 content_type = 'application/octet-stream'
529 content_type = 'application/octet-stream'
530 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
530 filename = '%s_%s.bin' %(self.device.device_type.name, self.name)
531 content = self.parms_to_binary()
531 content = self.parms_to_binary()
532
532
533 if not content_type:
533 if not content_type:
534 content_type = 'application/json'
534 content_type = 'application/json'
535 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
535 filename = '%s_%s.json' %(self.device.device_type.name, self.name)
536 content = json.dumps(self.parms_to_dict(), indent=2)
536 content = json.dumps(self.parms_to_dict(), indent=2)
537
537
538
538
539 fields = {'content_type':content_type,
539 fields = {'content_type':content_type,
540 'filename':filename,
540 'filename':filename,
541 'content':content
541 'content':content
542 }
542 }
543
543
544 return fields
544 return fields
545
545
546 def import_from_file(self, fp):
546 def import_from_file(self, fp):
547
547
548 parms = {}
548 parms = {}
549
549
550 path, ext = os.path.splitext(fp.name)
550 path, ext = os.path.splitext(fp.name)
551
551
552 if ext == '.json':
552 if ext == '.json':
553 parms = json.load(fp)
553 parms = json.load(fp)
554
554
555 return parms
555 return parms
556
556
557 def status_device(self):
557 def status_device(self):
558
558
559 self.message = 'Function not supported'
559 self.message = 'Function not supported'
560 return False
560 return False
561
561
562
562
563 def stop_device(self):
563 def stop_device(self):
564
564
565 self.message = 'Function not supported'
565 self.message = 'Function not supported'
566 return False
566 return False
567
567
568
568
569 def start_device(self):
569 def start_device(self):
570
570
571 self.message = 'Function not supported'
571 self.message = 'Function not supported'
572 return False
572 return False
573
573
574
574
575 def write_device(self):
575 def write_device(self):
576
576
577 self.message = 'Function not supported'
577 self.message = 'Function not supported'
578 return False
578 return False
579
579
580
580
581 def read_device(self):
581 def read_device(self):
582
582
583 self.message = 'Function not supported'
583 self.message = 'Function not supported'
584 return False
584 return False
585
585
586
586
587 def get_absolute_url(self):
587 def get_absolute_url(self):
588 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)])
589
589
590 def get_absolute_url_edit(self):
590 def get_absolute_url_edit(self):
591 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)])
592
592
593 def get_absolute_url_delete(self):
593 def get_absolute_url_delete(self):
594 return reverse('url_delete_dev_conf', args=[str(self.id)])
594 return reverse('url_delete_dev_conf', args=[str(self.id)])
595
595
596 def get_absolute_url_import(self):
596 def get_absolute_url_import(self):
597 return reverse('url_import_dev_conf', args=[str(self.id)])
597 return reverse('url_import_dev_conf', args=[str(self.id)])
598
598
599 def get_absolute_url_export(self):
599 def get_absolute_url_export(self):
600 return reverse('url_export_dev_conf', args=[str(self.id)])
600 return reverse('url_export_dev_conf', args=[str(self.id)])
601
601
602 def get_absolute_url_write(self):
602 def get_absolute_url_write(self):
603 return reverse('url_write_dev_conf', args=[str(self.id)])
603 return reverse('url_write_dev_conf', args=[str(self.id)])
604
604
605 def get_absolute_url_read(self):
605 def get_absolute_url_read(self):
606 return reverse('url_read_dev_conf', args=[str(self.id)])
606 return reverse('url_read_dev_conf', args=[str(self.id)])
607
607
608 def get_absolute_url_start(self):
608 def get_absolute_url_start(self):
609 return reverse('url_start_dev_conf', args=[str(self.id)])
609 return reverse('url_start_dev_conf', args=[str(self.id)])
610
610
611 def get_absolute_url_stop(self):
611 def get_absolute_url_stop(self):
612 return reverse('url_stop_dev_conf', args=[str(self.id)])
612 return reverse('url_stop_dev_conf', args=[str(self.id)])
613
613
614 def get_absolute_url_status(self):
614 def get_absolute_url_status(self):
615 return reverse('url_status_dev_conf', args=[str(self.id)])
615 return reverse('url_status_dev_conf', args=[str(self.id)])
@@ -1,263 +1,265
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 time.sleep(0.1)
149 r = requests.get(url + base64_table_el.decode('ascii'))
150 r = requests.get(url + base64_table_el.decode('ascii'))
151 time.sleep(0.1)
150 r = requests.get(url + base64_table_az.decode('ascii'))
152 r = requests.get(url + base64_table_az.decode('ascii'))
151
153
152 if r:
154 if r:
153 self.device.status = 3
155 self.device.status = 3
154 self.device.save()
156 self.device.save()
155 self.message = 'Pedestal reset'
157 self.message = 'Pedestal reset'
156 else:
158 else:
157 return False
159 return False
158
160
159 except Exception as e:
161 except Exception as e:
160 self.message = 'Pedestal reset: {}'.format(str(e))
162 self.message = 'Pedestal reset: {}'.format(str(e))
161 return False
163 return False
162
164
163 return True
165 return True
164
166
165 def stop_device(self):
167 def stop_device(self):
166
168
167 try:
169 try:
168 command = self.device.url() + "stop"
170 command = self.device.url() + "stop"
169 r = requests.get(command)
171 r = requests.get(command)
170
172
171 if self.mode == 'table':
173 if self.mode == 'table':
172 AX = {'az':'azimuth', 'el':'elevation'}
174 AX = {'az':'azimuth', 'el':'elevation'}
173 axis = [AX[x.lower().strip()] for x in self.axis.split(',')]
175 axis = [AX[x.lower().strip()] for x in self.axis.split(',')]
174 list_of_floats = [float(x.strip()) for x in self.angle.split(",")]
176 list_of_floats = [float(x.strip()) for x in self.angle.split(",")]
175 self.reset_device(axis[0], list_of_floats[0])
177 self.reset_device(axis[0], list_of_floats[0])
176
178
177 if r:
179 if r:
178 self.device.status = 4
180 self.device.status = 4
179 self.device.save()
181 self.device.save()
180 self.message = 'Pedestal stopped'
182 self.message = 'Pedestal stopped'
181 else:
183 else:
182 self.device.status = 4
184 self.device.status = 4
183 self.device.save()
185 self.device.save()
184 return False
186 return False
185 except Exception as e:
187 except Exception as e:
186 if 'No route to host' not in str(e):
188 if 'No route to host' not in str(e):
187 self.device.status = 4
189 self.device.status = 4
188 else:
190 else:
189 self.device.status = 0
191 self.device.status = 0
190 #self.message = 'Pedestal stop: {}'.format(str(e))
192 #self.message = 'Pedestal stop: {}'.format(str(e))
191 self.message = "Pedestal can't start, please check network/device connection or IP address/port configuration"
193 self.message = "Pedestal can't start, please check network/device connection or IP address/port configuration"
192 self.device.save()
194 self.device.save()
193 return False
195 return False
194
196
195 return True
197 return True
196
198
197 def start_device(self):
199 def start_device(self):
198
200
199 AX = {'az':'azimuth', 'el':'elevation'}
201 AX = {'az':'azimuth', 'el':'elevation'}
200 axis = [AX[x.lower().strip()] for x in self.axis.split(',')]
202 axis = [AX[x.lower().strip()] for x in self.axis.split(',')]
201 if len(axis)==1:
203 if len(axis)==1:
202 axis = axis[0]
204 axis = axis[0]
203
205
204 try:
206 try:
205 if self.mode == 'position':
207 if self.mode == 'position':
206 url = self.device.url() + "position?params="
208 url = self.device.url() + "position?params="
207 payload = {'axis': axis, 'position': float(self.angle)}
209 payload = {'axis': axis, 'position': float(self.angle)}
208 elif self.mode == 'speed':
210 elif self.mode == 'speed':
209 url = self.device.url() + "speed?params="
211 url = self.device.url() + "speed?params="
210 payload = {'axis': axis, 'speed': float(self.speed)}
212 payload = {'axis': axis, 'speed': float(self.speed)}
211 elif self.mode == 'table':
213 elif self.mode == 'table':
212 url = self.device.url() + "combinedtable?params="
214 url = self.device.url() + "combinedtable?params="
213 list_of_floats = [float(x.strip()) for x in self.angle.split(",")]
215 list_of_floats = [float(x.strip()) for x in self.angle.split(",")]
214 byte_table = []
216 byte_table = []
215 for x in list_of_floats:
217 for x in list_of_floats:
216 temp = bytearray(struct.pack("f", x))
218 temp = bytearray(struct.pack("f", x))
217 byte_table.append(temp[3])
219 byte_table.append(temp[3])
218 byte_table.append(temp[2])
220 byte_table.append(temp[2])
219 byte_table.append(temp[1])
221 byte_table.append(temp[1])
220 byte_table.append(temp[0])
222 byte_table.append(temp[0])
221
223
222 coded_table = base64.standard_b64encode(bytes(byte_table))
224 coded_table = base64.standard_b64encode(bytes(byte_table))
223 coded_table_ascii = coded_table.decode('ascii')
225 coded_table_ascii = coded_table.decode('ascii')
224 speed = [float(x.strip()) for x in self.speed.split(',')]
226 speed = [float(x.strip()) for x in self.speed.split(',')]
225 payload = {
227 payload = {
226 'arraylength': len(speed),
228 'arraylength': len(speed),
227 'axis': axis,
229 'axis': axis,
228 'speed': speed,
230 'speed': speed,
229 'bottom': self.min_value,
231 'bottom': self.min_value,
230 'top': self.max_value,
232 'top': self.max_value,
231 'table': coded_table_ascii
233 'table': coded_table_ascii
232 }
234 }
233
235
234 json_data = json.dumps(payload)
236 json_data = json.dumps(payload)
235 print(json_data)
237 print(json_data)
236 base64_table = base64.standard_b64encode(json_data.encode('ascii'))
238 base64_table = base64.standard_b64encode(json_data.encode('ascii'))
237 url += base64_table.decode('ascii')
239 url += base64_table.decode('ascii')
238 print(url)
240 print(url)
239 r = requests.get(url)
241 r = requests.get(url)
240
242
241 if self.mode == 'table':
243 if self.mode == 'table':
242 payload['table'] = list_of_floats
244 payload['table'] = list_of_floats
243
245
244 if r:
246 if r:
245 self.device.status = 3
247 self.device.status = 3
246 self.device.save()
248 self.device.save()
247 self.message = 'Pedestal configured and started'
249 self.message = 'Pedestal configured and started'
248 else:
250 else:
249 return False
251 return False
250 except Exception as e:
252 except Exception as e:
251 if 'No route to host' not in str(e):
253 if 'No route to host' not in str(e):
252 self.device.status = 4
254 self.device.status = 4
253 else:
255 else:
254 self.device.status = 0
256 self.device.status = 0
255 #self.message = 'Pedestal start: {}'.format(str(e))
257 #self.message = 'Pedestal start: {}'.format(str(e))
256 self.message = "Pedestal can't start, please check network/device connection or IP address/port configuration"
258 self.message = "Pedestal can't start, please check network/device connection or IP address/port configuration"
257 self.device.save()
259 self.device.save()
258 return False
260 return False
259
261
260 return payload
262 return payload
261
263
262 def get_absolute_url_import(self):
264 def get_absolute_url_import(self):
263 return reverse('url_import_pedestal_conf', args=[str(self.id)])
265 return reverse('url_import_pedestal_conf', args=[str(self.id)])
General Comments 0
You need to be logged in to leave comments. Login now