@@ -1,245 +1,255 | |||||
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): |
|
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 | json_data_el = json.dumps(payload_el) |
|
131 | payload_az = {'axis': 'azimuth'} | |
132 | base64_table_el = base64.standard_b64encode(json_data_el.encode('ascii')) |
|
|||
133 |
|
132 | |||
134 | r = requests.get(url + base64_table_el.decode('ascii')) |
|
133 | if axi == 'elevation': | |
|
134 | payload_az['position'] = angle | |||
|
135 | payload_el['position'] = 0 | |||
|
136 | elif axi == 'azimuth': | |||
|
137 | payload_el['position'] = angle | |||
|
138 | payload_az['position'] = 0 | |||
|
139 | else: | |||
|
140 | payload_el['position'] = 0 | |||
|
141 | payload_az['position'] = 0 | |||
135 |
|
142 | |||
136 | payload_az = {'axis': 'azimuth', 'position': 0} |
|
143 | json_data_el = json.dumps(payload_el) | |
137 | json_data_az = json.dumps(payload_az) |
|
144 | json_data_az = json.dumps(payload_az) | |
|
145 | ||||
|
146 | base64_table_el = base64.standard_b64encode(json_data_el.encode('ascii')) | |||
138 | base64_table_az = base64.standard_b64encode(json_data_az.encode('ascii')) |
|
147 | base64_table_az = base64.standard_b64encode(json_data_az.encode('ascii')) | |
139 |
|
148 | |||
|
149 | r = requests.get(url + base64_table_el.decode('ascii')) | |||
140 | r = requests.get(url + base64_table_az.decode('ascii')) |
|
150 | r = requests.get(url + base64_table_az.decode('ascii')) | |
141 |
|
151 | |||
142 | if r: |
|
152 | if r: | |
143 | self.device.status = 3 |
|
153 | self.device.status = 3 | |
144 | self.device.save() |
|
154 | self.device.save() | |
145 | self.message = 'Pedestal reset' |
|
155 | self.message = 'Pedestal reset' | |
146 | else: |
|
156 | else: | |
147 | return False |
|
157 | return False | |
148 |
|
158 | |||
149 | except Exception as e: |
|
159 | except Exception as e: | |
150 | self.message = 'Pedestal reset: {}'.format(str(e)) |
|
160 | self.message = 'Pedestal reset: {}'.format(str(e)) | |
151 | return False |
|
161 | return False | |
152 |
|
162 | |||
153 | return True |
|
163 | return True | |
154 |
|
164 | |||
155 | def stop_device(self): |
|
165 | def stop_device(self): | |
156 |
|
166 | |||
157 | try: |
|
167 | try: | |
158 | command = self.device.url() + "stop" |
|
168 | command = self.device.url() + "stop" | |
159 | r = requests.get(command) |
|
169 | r = requests.get(command) | |
160 | if r: |
|
170 | if r: | |
161 | self.device.status = 4 |
|
171 | self.device.status = 4 | |
162 | self.device.save() |
|
172 | self.device.save() | |
163 | self.message = 'Pedestal stopped' |
|
173 | self.message = 'Pedestal stopped' | |
164 | else: |
|
174 | else: | |
165 | self.device.status = 4 |
|
175 | self.device.status = 4 | |
166 | self.device.save() |
|
176 | self.device.save() | |
167 | return False |
|
177 | return False | |
168 | except Exception as e: |
|
178 | except Exception as e: | |
169 | if 'No route to host' not in str(e): |
|
179 | if 'No route to host' not in str(e): | |
170 | self.device.status = 4 |
|
180 | self.device.status = 4 | |
171 | else: |
|
181 | else: | |
172 | self.device.status = 0 |
|
182 | self.device.status = 0 | |
173 | #self.message = 'Pedestal stop: {}'.format(str(e)) |
|
183 | #self.message = 'Pedestal stop: {}'.format(str(e)) | |
174 | self.message = "Pedestal can't start, please check network/device connection or IP address/port configuration" |
|
184 | self.message = "Pedestal can't start, please check network/device connection or IP address/port configuration" | |
175 | self.device.save() |
|
185 | self.device.save() | |
176 | return False |
|
186 | return False | |
177 |
|
187 | |||
178 | return True |
|
188 | return True | |
179 |
|
189 | |||
180 | def start_device(self): |
|
190 | def start_device(self): | |
181 |
|
191 | |||
182 | AX = {'az':'azimuth', 'el':'elevation'} |
|
192 | AX = {'az':'azimuth', 'el':'elevation'} | |
183 | axis = [AX[x.lower().strip()] for x in self.axis.split(',')] |
|
193 | axis = [AX[x.lower().strip()] for x in self.axis.split(',')] | |
184 | if len(axis)==1: |
|
194 | if len(axis)==1: | |
185 | axis = axis[0] |
|
195 | axis = axis[0] | |
186 |
|
196 | |||
187 | try: |
|
197 | try: | |
188 | if self.mode == 'position': |
|
198 | if self.mode == 'position': | |
189 | url = self.device.url() + "position?params=" |
|
199 | url = self.device.url() + "position?params=" | |
190 | payload = {'axis': axis, 'position': float(self.angle)} |
|
200 | payload = {'axis': axis, 'position': float(self.angle)} | |
191 | elif self.mode == 'speed': |
|
201 | elif self.mode == 'speed': | |
192 | url = self.device.url() + "speed?params=" |
|
202 | url = self.device.url() + "speed?params=" | |
193 | payload = {'axis': axis, 'speed': float(self.speed)} |
|
203 | payload = {'axis': axis, 'speed': float(self.speed)} | |
194 | elif self.mode == 'table': |
|
204 | elif self.mode == 'table': | |
195 | self.reset_device() |
|
|||
196 | url = self.device.url() + "combinedtable?params=" |
|
205 | url = self.device.url() + "combinedtable?params=" | |
197 | list_of_floats = [float(x.strip()) for x in self.angle.split(",")] |
|
206 | list_of_floats = [float(x.strip()) for x in self.angle.split(",")] | |
198 | byte_table = [] |
|
207 | byte_table = [] | |
199 | for x in list_of_floats: |
|
208 | for x in list_of_floats: | |
200 | temp = bytearray(struct.pack("f", x)) |
|
209 | temp = bytearray(struct.pack("f", x)) | |
201 | byte_table.append(temp[3]) |
|
210 | byte_table.append(temp[3]) | |
202 | byte_table.append(temp[2]) |
|
211 | byte_table.append(temp[2]) | |
203 | byte_table.append(temp[1]) |
|
212 | byte_table.append(temp[1]) | |
204 | byte_table.append(temp[0]) |
|
213 | byte_table.append(temp[0]) | |
205 |
|
214 | |||
206 | coded_table = base64.standard_b64encode(bytes(byte_table)) |
|
215 | coded_table = base64.standard_b64encode(bytes(byte_table)) | |
207 | coded_table_ascii = coded_table.decode('ascii') |
|
216 | coded_table_ascii = coded_table.decode('ascii') | |
208 | speed = [float(x.strip()) for x in self.speed.split(',')] |
|
217 | speed = [float(x.strip()) for x in self.speed.split(',')] | |
209 | payload = { |
|
218 | payload = { | |
210 | 'arraylength': len(speed), |
|
219 | 'arraylength': len(speed), | |
211 | 'axis': axis, |
|
220 | 'axis': axis, | |
212 | 'speed': speed, |
|
221 | 'speed': speed, | |
213 | 'bottom': self.min_value, |
|
222 | 'bottom': self.min_value, | |
214 | 'top': self.max_value, |
|
223 | 'top': self.max_value, | |
215 | 'table': coded_table_ascii |
|
224 | 'table': coded_table_ascii | |
216 | } |
|
225 | } | |
|
226 | self.reset_device(axis[0], list_of_floats[0]) | |||
217 | time.sleep(15) |
|
227 | time.sleep(15) | |
218 |
|
228 | |||
219 | json_data = json.dumps(payload) |
|
229 | json_data = json.dumps(payload) | |
220 | print(json_data) |
|
230 | print(json_data) | |
221 | base64_table = base64.standard_b64encode(json_data.encode('ascii')) |
|
231 | base64_table = base64.standard_b64encode(json_data.encode('ascii')) | |
222 | url += base64_table.decode('ascii') |
|
232 | url += base64_table.decode('ascii') | |
223 | print(url) |
|
233 | print(url) | |
224 | r = requests.get(url) |
|
234 | r = requests.get(url) | |
225 |
|
235 | |||
226 | if r: |
|
236 | if r: | |
227 | self.device.status = 3 |
|
237 | self.device.status = 3 | |
228 | self.device.save() |
|
238 | self.device.save() | |
229 | self.message = 'Pedestal configured and started' |
|
239 | self.message = 'Pedestal configured and started' | |
230 | else: |
|
240 | else: | |
231 | return False |
|
241 | return False | |
232 | except Exception as e: |
|
242 | except Exception as e: | |
233 | if 'No route to host' not in str(e): |
|
243 | if 'No route to host' not in str(e): | |
234 | self.device.status = 4 |
|
244 | self.device.status = 4 | |
235 | else: |
|
245 | else: | |
236 | self.device.status = 0 |
|
246 | self.device.status = 0 | |
237 | #self.message = 'Pedestal start: {}'.format(str(e)) |
|
247 | #self.message = 'Pedestal start: {}'.format(str(e)) | |
238 | self.message = "Pedestal can't start, please check network/device connection or IP address/port configuration" |
|
248 | self.message = "Pedestal can't start, please check network/device connection or IP address/port configuration" | |
239 | self.device.save() |
|
249 | self.device.save() | |
240 | return False |
|
250 | return False | |
241 |
|
251 | |||
242 | return True |
|
252 | return True | |
243 |
|
253 | |||
244 | def get_absolute_url_import(self): |
|
254 | def get_absolute_url_import(self): | |
245 | return reverse('url_import_pedestal_conf', args=[str(self.id)]) |
|
255 | return reverse('url_import_pedestal_conf', args=[str(self.id)]) |
General Comments 0
You need to be logged in to leave comments.
Login now