|
|
import ast
|
|
|
import json
|
|
|
import requests
|
|
|
import base64
|
|
|
import struct
|
|
|
from struct import pack
|
|
|
import time
|
|
|
from django.contrib import messages
|
|
|
from django.db import models
|
|
|
from django.urls import reverse
|
|
|
from django.core.validators import MinValueValidator, MaxValueValidator
|
|
|
|
|
|
from apps.main.models import Configuration
|
|
|
|
|
|
MODE_VALUE = (
|
|
|
('position', 'Position'),
|
|
|
('speed', 'Speed'),
|
|
|
('table', 'Table')
|
|
|
)
|
|
|
|
|
|
class PedestalConfiguration(Configuration):
|
|
|
|
|
|
mode = models.CharField(
|
|
|
verbose_name='Mode',
|
|
|
max_length=10,
|
|
|
choices=MODE_VALUE,
|
|
|
null=False,
|
|
|
blank=False
|
|
|
)
|
|
|
|
|
|
axis = models.CharField(
|
|
|
verbose_name="Axis",
|
|
|
max_length=100,
|
|
|
default='az',
|
|
|
blank=False,
|
|
|
null=False,
|
|
|
help_text="Please separate the values with commas when using table mode"
|
|
|
)
|
|
|
|
|
|
speed = models.CharField(
|
|
|
verbose_name='Speed',
|
|
|
max_length=100,
|
|
|
blank=False,
|
|
|
null=False,
|
|
|
default=6
|
|
|
)
|
|
|
|
|
|
angle = models.CharField(
|
|
|
verbose_name="Angle(s)",
|
|
|
max_length=100,
|
|
|
default='0',
|
|
|
blank=False,
|
|
|
null=False,
|
|
|
help_text="Please separate the values with commas when using table mode"
|
|
|
)
|
|
|
|
|
|
min_value = models.FloatField(
|
|
|
verbose_name='Min angle',
|
|
|
validators=[MinValueValidator(-5), MaxValueValidator(185)],
|
|
|
blank=False,
|
|
|
null=False,
|
|
|
default=0
|
|
|
)
|
|
|
|
|
|
max_value = models.FloatField(
|
|
|
verbose_name='Max angle',
|
|
|
validators=[MinValueValidator(-5), MaxValueValidator(185)],
|
|
|
blank=False,
|
|
|
null=False,
|
|
|
default=40
|
|
|
)
|
|
|
|
|
|
class Meta:
|
|
|
db_table = 'pedestal_configurations'
|
|
|
|
|
|
def __str__(self):
|
|
|
if self.mode=='position':
|
|
|
return u'Position: {}º {}'.format(self.angle, self.axis.upper())
|
|
|
if self.mode=='speed':
|
|
|
return u'Speed: {}º/s {}'.format(self.speed, self.axis.upper())
|
|
|
if self.mode=='table':
|
|
|
axis = [x.strip().upper() for x in self.axis.split(',')]
|
|
|
speeds = [float(x.strip()) for x in self.speed.split(',')]
|
|
|
table = [float(x.strip()) for x in self.angle.split(',')]
|
|
|
return u'Table: Axis {}, Speed {}º/s, Steps {}'.format(axis, speeds, table)
|
|
|
|
|
|
@property
|
|
|
def label(self):
|
|
|
return str(self)
|
|
|
|
|
|
def get_absolute_url_plot(self):
|
|
|
return reverse('url_plot_pedestal_pulses', args=[str(self.id)])
|
|
|
|
|
|
def request(self, cmd, method='get', **kwargs):
|
|
|
|
|
|
req = getattr(requests, method)(self.device.url(cmd), **kwargs)
|
|
|
payload = req.json()
|
|
|
|
|
|
return payload
|
|
|
|
|
|
def status_device(self):
|
|
|
|
|
|
try:
|
|
|
payload = requests.get(self.device.url())
|
|
|
|
|
|
if payload:
|
|
|
self.device.status = 1
|
|
|
elif payload['status']=='disable':
|
|
|
self.device.status = 2
|
|
|
else:
|
|
|
self.device.status = 1
|
|
|
self.device.save()
|
|
|
self.message = 'Pedestal status: {}'.format(payload['status'])
|
|
|
return False
|
|
|
except Exception as e:
|
|
|
if 'No route to host' not in str(e):
|
|
|
self.device.status = 4
|
|
|
self.device.save()
|
|
|
self.message = 'Pedestal status: {}'.format(str(e))
|
|
|
return False
|
|
|
|
|
|
self.device.save()
|
|
|
return True
|
|
|
|
|
|
def reset_device(self):
|
|
|
|
|
|
try:
|
|
|
url = self.device.url() + "position?params="
|
|
|
|
|
|
payload_el = {'axis': 'elevation', 'position': 0}
|
|
|
json_data_el = json.dumps(payload_el)
|
|
|
base64_table_el = base64.standard_b64encode(json_data_el.encode('ascii'))
|
|
|
|
|
|
r = requests.get(url + base64_table_el.decode('ascii'))
|
|
|
|
|
|
payload_az = {'axis': 'azimuth', 'position': 0}
|
|
|
json_data_az = json.dumps(payload_az)
|
|
|
base64_table_az = base64.standard_b64encode(json_data_az.encode('ascii'))
|
|
|
|
|
|
r = requests.get(url + base64_table_az.decode('ascii'))
|
|
|
|
|
|
if r:
|
|
|
self.device.status = 3
|
|
|
self.device.save()
|
|
|
self.message = 'Pedestal reset'
|
|
|
else:
|
|
|
return False
|
|
|
|
|
|
except Exception as e:
|
|
|
self.message = 'Pedestal reset: {}'.format(str(e))
|
|
|
return False
|
|
|
|
|
|
return True
|
|
|
|
|
|
def stop_device(self):
|
|
|
|
|
|
try:
|
|
|
command = self.device.url() + "stop"
|
|
|
r = requests.get(command)
|
|
|
if r:
|
|
|
self.device.status = 4
|
|
|
self.device.save()
|
|
|
self.message = 'Pedestal stopped'
|
|
|
else:
|
|
|
self.device.status = 4
|
|
|
self.device.save()
|
|
|
return False
|
|
|
except Exception as e:
|
|
|
if 'No route to host' not in str(e):
|
|
|
self.device.status = 4
|
|
|
else:
|
|
|
self.device.status = 0
|
|
|
#self.message = 'Pedestal stop: {}'.format(str(e))
|
|
|
self.message = "Pedestal can't start, please check network/device connection or IP address/port configuration"
|
|
|
self.device.save()
|
|
|
return False
|
|
|
|
|
|
return True
|
|
|
|
|
|
def start_device(self):
|
|
|
|
|
|
AX = {'az':'azimuth', 'el':'elevation'}
|
|
|
axis = [AX[x.lower().strip()] for x in self.axis.split(',')]
|
|
|
if len(axis)==1:
|
|
|
axis = axis[0]
|
|
|
|
|
|
try:
|
|
|
if self.mode == 'position':
|
|
|
url = self.device.url() + "position?params="
|
|
|
payload = {'axis': axis, 'position': float(self.angle)}
|
|
|
elif self.mode == 'speed':
|
|
|
url = self.device.url() + "speed?params="
|
|
|
payload = {'axis': axis, 'speed': float(self.speed)}
|
|
|
elif self.mode == 'table':
|
|
|
self.reset_device()
|
|
|
url = self.device.url() + "combinedtable?params="
|
|
|
list_of_floats = [float(x.strip()) for x in self.angle.split(",")]
|
|
|
byte_table = []
|
|
|
for x in list_of_floats:
|
|
|
temp = bytearray(struct.pack("f", x))
|
|
|
byte_table.append(temp[3])
|
|
|
byte_table.append(temp[2])
|
|
|
byte_table.append(temp[1])
|
|
|
byte_table.append(temp[0])
|
|
|
|
|
|
coded_table = base64.standard_b64encode(bytes(byte_table))
|
|
|
coded_table_ascii = coded_table.decode('ascii')
|
|
|
speed = [float(x.strip()) for x in self.speed.split(',')]
|
|
|
payload = {
|
|
|
'arraylength': len(speed),
|
|
|
'axis': axis,
|
|
|
'speed': speed,
|
|
|
'bottom': self.min_value,
|
|
|
'top': self.max_value,
|
|
|
'table': coded_table_ascii
|
|
|
}
|
|
|
time.sleep(15)
|
|
|
|
|
|
json_data = json.dumps(payload)
|
|
|
print(json_data)
|
|
|
base64_table = base64.standard_b64encode(json_data.encode('ascii'))
|
|
|
url += base64_table.decode('ascii')
|
|
|
print(url)
|
|
|
r = requests.get(url)
|
|
|
|
|
|
if r:
|
|
|
self.device.status = 3
|
|
|
self.device.save()
|
|
|
self.message = 'Pedestal configured and started'
|
|
|
else:
|
|
|
return False
|
|
|
except Exception as e:
|
|
|
if 'No route to host' not in str(e):
|
|
|
self.device.status = 4
|
|
|
else:
|
|
|
self.device.status = 0
|
|
|
#self.message = 'Pedestal start: {}'.format(str(e))
|
|
|
self.message = "Pedestal can't start, please check network/device connection or IP address/port configuration"
|
|
|
self.device.save()
|
|
|
return False
|
|
|
|
|
|
return True
|
|
|
|
|
|
def get_absolute_url_import(self):
|
|
|
return reverse('url_import_pedestal_conf', args=[str(self.id)])
|
|
|
|