socket_client_telescope_gemini.py
7.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
#!/usr/bin/env python3
"""Socket Client GEMINI Telescope implementation
To be used as a concrete class to system control a GEMINI telescope
"""
# Standard library imports
#import socket
#import logging
#import sys
# Third party imports
# None
# Local application imports
#sys.path.append('../..')
from src.client.socket_client_telescope_abstract import Position, UnknownCommandException, SocketClientTelescopeAbstract
TERMINATOR = '\x00'
class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract):
'''
http://82.64.28.71:8083/L5V1serial.html
ACK = 0x06
=> 06 00 (le 00 à la fin signifie que la commande s’est bien passée)
Réponse:
- B#
- b#
- G#
Ce qui marche:
- REQUEST TO SERVER [ex: ':GD#' (Get Dec), ':GR#' (Get RA)']: 01000000:GD#
Received (all data): 01000000+90:00:00#
- REQUEST TO SERVER [ex: ':GD#' (Get Dec), ':GR#' (Get RA)']: 01000000:GR#
Received (all data): 0100000015:01:48#
- REQUEST TO SERVER [ex: ':GD#' (Get Dec), ':GR#' (Get RA)']: 01000000:GR#
Received (all data): 0100000016:04:17#
- Get Software Level l(one digit) and Version vv(two digits)
REQUEST TO SERVER [ex: ':GD#' (Get Dec), ':GR#' (Get RA)']: 01000000:GV#
Received (all data): 01000000510#
- REQUEST TO SERVER [ex: ':GD#' (Get Dec), ':GR#' (Get RA)']: 01000000:GG#
Received (all data): 01000000+00#
- Get Maximum Velocity of both axes (N = No mvmt)
REQUEST TO SERVER [ex: ':GD#' (Get Dec), ':GR#' (Get RA)']: 01000000:Gv#
Received (all data): 01000000N
'''
# STAMP :
# 00 00 00 00 00 00 00' (8 bytes from '00' to 'FF', 1st one is LOW BYTE)
# ex: 01 + STAMP = 01 00 00 00 00 00 00 00' (8 bytes from '00' to 'FF', 1st one is LOW BYTE)
#STAMP_FILLER = '00000000000000'
#MY_FULL_STAMP = MYSTAMP + STAMP_FILLER
# Initialize request number (will be increased at each request)
request_num = 0
# Request number stands on 4 digits (from 0001 to 9999)
request_num_nb_digits = 4
# For 4 digits, we should get the format '{:04d}':
request_num_format = '{:0'+str(request_num_nb_digits)+'d}'
# Stamp filler with 0
STAMP_FILLER = '0' * (8 - request_num_nb_digits)
#data = " ".join(sys.argv[1:])
#data_to_send = bytes(data + "\n", "utf-8")
# @override
# GEMINI is using UDP
def __init__(self, server_host:str="localhost", server_port:int=11110, DEBUG=False):
super().__init__(server_host, server_port, "UDP", 1024, DEBUG)
'''
Encapsulate useful data to be ready for sending
If data is "complete" (with stamp, and well formatted), send it as is
Otherwise, add stamp and format it
Examples:
'01000000:GD#' => complete, so send it as is
':GD#' => add stamp in order to send '01000000:GD#'
'GD' => add stamp + format in order to send '01000000:GD#'
'''
# @override
def _encapsulate_data_to_send(self, data:str):
####return bytes(self.MYSTAMP + self.STAMP_FILLER + data + "\n", "utf-8")
'''
sep_pos = data.find(':')
# no ":"
if sep_pos == -1:
stamp = ''
command = data
else:
# has ":"
stamp,command = data.split(':',1)
if stamp == '': stamp = self.MY_FULL_STAMP
#if command.find('#')>-1: command,_ = command.split('#',1)
#command = ':' + command + '#'
#command = command + '#'
'''
command = data
self.request_num += 1
# Format to request_num_nb_digits (4) digits
request_num_str = self.request_num_format.format(self.request_num)
self.last_stamp = request_num_str + self.STAMP_FILLER
return self.last_stamp + command
#return bytes(data + "\n", "utf-8")
####return bytes(self.MYSTAMP + self.STAMP_FILLER + data + "\n", "utf-8")
# Extract useful data from received raw data
# @override
def _uncap_data(self, data_received:str):
# Remove STAMP (and \n at the end):
#useful_data = data_received.split(self.MY_FULL_STAMP)[1][:-1]
useful_data = data_received.split(self.last_stamp)[1][:-1]
# Remove '#' at the end, if exists
if useful_data[-1] == '#': useful_data = useful_data[:-1]
return useful_data
'''
TELESCOPE COMMANDS implementation
'''
'''
The 3 main generic commands : get(), set(), do()
'''
''' 1) GET methods '''
# @override
def get(self, what:str):
cmd = None
if what == "ALT": cmd = ('GA',)
if what == "AZ": cmd = ('GZ',)
if what == "ALT-AZ": cmd = ('GA','GZ')
if what == "DEC": cmd = ('GD',)
if what == "RA": cmd = ('GR',)
if what == "RA-DEC": cmd = ('GR','GD')
if what == "LONG": cmd = ('Gg',)
if what == "LAT": cmd = ('Gt',)
if what == "LONG-LAT": cmd = ('Gg','Gt')
if what == "hour-angle": cmd = ('GH',)
if what == "max-vel": cmd = ('Gv',)
if not cmd: raise UnknownCommandException()
res = []
for c in cmd:
res.append(self.put_read(':'+c+'#'))
if len(res) == 1: return res[0]
return res
''' 2) SET methods '''
# @override
def set(self):
pass
''' 3) DO methods '''
# @override
def do(self):
pass
''' SPECIFIC methods
# @override
def get_coord_sys(self):
pass
# @override
def get_position(self)->Position:
pass
# @override
def set_coord_sys(self):
pass
# @override
def start(self):
pass
# @override
def park(self):
pass
# @override
def goto(self, position:Position):
pass
# Move to Home Position. The Home Position defaults to the celestial pole visible at the given hemisphere (north or south)
# :hP#
# Move to the Startup Position. This position is the position required for a Cold or Warm Start, pointing to the celestial pole of the given hemisphere (north or south), with the counterweight pointing downwards (CWD position)
# :hC#
# @override
def move(self, position:Position):
pass
'''
if __name__ == "__main__":
# Classic usage:
#tsock = SocketClient_GEMINI(HOST, PORT)
# More elegant usage, using "with":
with SocketClientTelescopeGEMINI("localhost", 11110, DEBUG=False) as tsock:
# 0) CONNECT to server (only for TCP, does nothing for UDP)
tsock._connect_to_server()
# Send some commands to the Telescope
pos = tsock.get_position()
# Do EXPERT mode execution
while True:
# 1) SEND REQUEST data to server
# saisie de la requête au clavier et suppression des espaces des 2 côtés
data = input("(EXPERT MODE) REQUEST TO SERVER [ex: ':GD#' (Get Dec), ':GR#' (Get RA)']: ").strip()
# test d'arrêt
if data == "": break
#data_to_send = bytes(data + "\n", "utf-8")
tsock.send_data(data)
#mysock.sendto("%s" % data, (HOST, PORT))
#print("Sent: {}".format(data))
# 2) RECEIVE REPLY data from server
data_received = tsock.receive_data()
#reponse, adr = mysock.recvfrom(buf)
#print("Received: {}".format(data_received))
#print("Useful data received: {}".format(data_useful))
print('\n')
#tsock.close()