models.py
245 lines
| 7.7 KiB
| text/x-python
|
PythonLexer
|
r45 | import ast | ||
|
r25 | import json | ||
|
r175 | import requests | ||
r345 | import base64 | |||
r346 | import struct | |||
|
r185 | from struct import pack | ||
r346 | import time | |||
from django.contrib import messages | ||||
|
r0 | from django.db import models | ||
r335 | from django.urls import reverse | |||
|
r23 | from django.core.validators import MinValueValidator, MaxValueValidator | ||
|
r6 | from apps.main.models import Configuration | ||
|
r79 | |||
r365 | MODE_VALUE = ( | |||
r368 | ('position', 'Position'), | |||
('speed', 'Speed'), | ||||
('table', 'Table') | ||||
r345 | ) | |||
|
r6 | |||
r346 | class PedestalConfiguration(Configuration): | |||
|
r172 | |||
r365 | mode = models.CharField( | |||
verbose_name='Mode', | ||||
r360 | max_length=10, | |||
r365 | choices=MODE_VALUE, | |||
r345 | null=False, | |||
blank=False | ||||
) | ||||
r368 | 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( | ||||
r345 | verbose_name='Speed', | |||
r368 | max_length=100, | |||
r345 | blank=False, | |||
r368 | null=False, | |||
default=6 | ||||
r345 | ) | |||
r368 | angle = models.CharField( | |||
verbose_name="Angle(s)", | ||||
r345 | max_length=100, | |||
r368 | 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)], | ||||
r345 | blank=False, | |||
r352 | null=False, | |||
r368 | default=40 | |||
r345 | ) | |||
|
r6 | |||
class Meta: | ||||
r345 | db_table = 'pedestal_configurations' | |||
def __str__(self): | ||||
r368 | 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(',')] | ||||
r390 | speeds = [float(x.strip()) for x in self.speed.split(',')] | |||
table = [float(x.strip()) for x in self.angle.split(',')] | ||||
r368 | return u'Table: Axis {}, Speed {}º/s, Steps {}'.format(axis, speeds, table) | |||
@property | ||||
def label(self): | ||||
return str(self) | ||||
|
r172 | |||
|
r79 | def get_absolute_url_plot(self): | ||
r345 | return reverse('url_plot_pedestal_pulses', args=[str(self.id)]) | |||
|
r172 | |||
|
r264 | def request(self, cmd, method='get', **kwargs): | ||
req = getattr(requests, method)(self.device.url(cmd), **kwargs) | ||||
payload = req.json() | ||||
return payload | ||||
|
r175 | def status_device(self): | ||
|
r172 | |||
|
r222 | try: | ||
r350 | payload = requests.get(self.device.url()) | |||
r368 | ||||
r350 | if payload: | |||
self.device.status = 1 | ||||
|
r264 | elif payload['status']=='disable': | ||
|
r222 | self.device.status = 2 | ||
|
r185 | else: | ||
|
r243 | self.device.status = 1 | ||
|
r222 | self.device.save() | ||
r346 | self.message = 'Pedestal status: {}'.format(payload['status']) | |||
|
r222 | return False | ||
|
r185 | except Exception as e: | ||
|
r222 | if 'No route to host' not in str(e): | ||
self.device.status = 4 | ||||
self.device.save() | ||||
r346 | self.message = 'Pedestal status: {}'.format(str(e)) | |||
|
r185 | return False | ||
|
r243 | |||
self.device.save() | ||||
return True | ||||
|
r175 | |||
def reset_device(self): | ||||
|
r243 | |||
|
r185 | try: | ||
r390 | url = self.device.url() + "position?params=" | |||
r368 | ||||
payload_el = {'axis': 'elevation', 'position': 0} | ||||
r390 | json_data_el = json.dumps(payload_el) | |||
base64_table_el = base64.standard_b64encode(json_data_el.encode('ascii')) | ||||
r368 | ||||
r = requests.get(url + base64_table_el.decode('ascii')) | ||||
payload_az = {'axis': 'azimuth', 'position': 0} | ||||
r390 | json_data_az = json.dumps(payload_az) | |||
base64_table_az = base64.standard_b64encode(json_data_az.encode('ascii')) | ||||
r368 | ||||
r = requests.get(url + base64_table_az.decode('ascii')) | ||||
if r: | ||||
self.device.status = 3 | ||||
|
r264 | self.device.save() | ||
r368 | self.message = 'Pedestal reset' | |||
|
r185 | else: | ||
r368 | return False | |||
|
r185 | except Exception as e: | ||
r346 | self.message = 'Pedestal reset: {}'.format(str(e)) | |||
|
r185 | return False | ||
|
r243 | |||
|
r185 | return True | ||
|
r243 | |||
|
r175 | def stop_device(self): | ||
|
r172 | |||
|
r185 | try: | ||
r346 | command = self.device.url() + "stop" | |||
r = requests.get(command) | ||||
if r: | ||||
self.device.status = 4 | ||||
|
r185 | self.device.save() | ||
r346 | self.message = 'Pedestal stopped' | |||
|
r185 | else: | ||
self.device.status = 4 | ||||
self.device.save() | ||||
return False | ||||
except Exception as e: | ||||
|
r222 | if 'No route to host' not in str(e): | ||
self.device.status = 4 | ||||
else: | ||||
self.device.status = 0 | ||||
r350 | #self.message = 'Pedestal stop: {}'.format(str(e)) | |||
self.message = "Pedestal can't start, please check network/device connection or IP address/port configuration" | ||||
|
r222 | self.device.save() | ||
|
r243 | return False | ||
|
r185 | return True | ||
|
r172 | |||
|
r107 | def start_device(self): | ||
r350 | ||||
r368 | AX = {'az':'azimuth', 'el':'elevation'} | |||
axis = [AX[x.lower().strip()] for x in self.axis.split(',')] | ||||
if len(axis)==1: | ||||
axis = axis[0] | ||||
r346 | ||||
r368 | try: | |||
if self.mode == 'position': | ||||
r390 | url = self.device.url() + "position?params=" | |||
r368 | payload = {'axis': axis, 'position': float(self.angle)} | |||
elif self.mode == 'speed': | ||||
r390 | url = self.device.url() + "speed?params=" | |||
r368 | payload = {'axis': axis, 'speed': float(self.speed)} | |||
elif self.mode == 'table': | ||||
r390 | self.reset_device() | |||
r368 | 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(',')] | ||||
r374 | payload = { | |||
'arraylength': len(speed), | ||||
'axis': axis, | ||||
'speed': speed, | ||||
r390 | 'bottom': self.min_value, | |||
r374 | 'top': self.max_value, | |||
r390 | 'table': coded_table_ascii | |||
r374 | } | |||
r390 | time.sleep(15) | |||
r368 | ||||
json_data = json.dumps(payload) | ||||
print(json_data) | ||||
r357 | base64_table = base64.standard_b64encode(json_data.encode('ascii')) | |||
r368 | url += base64_table.decode('ascii') | |||
print(url) | ||||
r = requests.get(url) | ||||
r346 | ||||
if r: | ||||
|
r185 | self.device.status = 3 | ||
self.device.save() | ||||
r346 | self.message = 'Pedestal configured and started' | |||
|
r185 | else: | ||
return False | ||||
except Exception as e: | ||||
|
r222 | if 'No route to host' not in str(e): | ||
self.device.status = 4 | ||||
else: | ||||
self.device.status = 0 | ||||
r350 | #self.message = 'Pedestal start: {}'.format(str(e)) | |||
self.message = "Pedestal can't start, please check network/device connection or IP address/port configuration" | ||||
|
r222 | self.device.save() | ||
|
r185 | return False | ||
|
r243 | |||
|
r185 | return True | ||
|
r172 | |||
|
r264 | def get_absolute_url_import(self): | ||
r349 | return reverse('url_import_pedestal_conf', args=[str(self.id)]) | |||