Commit 23b4fbc5098e1347cd471218c626a5b9706456f5

Authored by Etienne Pallier
1 parent a494f372
Exists in dev

move do_init() to abstract class AND generic return code for each

command
sockets_tele/README.txt
@@ -63,6 +63,9 @@ Pour lancer le client sur le "simulateur" de telescope (localhost, port 11110): @@ -63,6 +63,9 @@ Pour lancer le client sur le "simulateur" de telescope (localhost, port 11110):
63 ******************************************************************************************** 63 ********************************************************************************************
64 4) DONE 64 4) DONE
65 65
  66 + - move do_init() to abstract class
  67 + - generic return code for each command
  68 +
66 - clean code 69 - clean code
67 - move do_goto() and move_dir() to abstract class 70 - move do_goto() and move_dir() to abstract class
68 71
@@ -101,10 +104,8 @@ Pour lancer le client sur le "simulateur" de telescope (localhost, port 11110): @@ -101,10 +104,8 @@ Pour lancer le client sur le "simulateur" de telescope (localhost, port 11110):
101 ******************************************************************************************** 104 ********************************************************************************************
102 5) WORK CURRENTLY IN PROGRESS... 105 5) WORK CURRENTLY IN PROGRESS...
103 106
104 - - generic return code for each command  
105 -  
106 - - move do_init() to abstract class  
107 - 107 + - interpreteur de cde generique : set ra "20:00:00"
  108 +
108 - improve server answers 109 - improve server answers
109 110
110 - main updated 111 - main updated
sockets_tele/client_gemini_run.py
@@ -8,7 +8,55 @@ import sys @@ -8,7 +8,55 @@ import sys
8 DEBUG = True 8 DEBUG = True
9 9
10 10
  11 +class essai:
  12 + a = 'a'
  13 + c = 'c'
  14 + def __init__(self):
  15 + self.b = 'bB'
  16 + def __get__(self, instance, owner):
  17 + return self.b
  18 + '''
  19 + def __set__(self, instance, value):
  20 + self.b = value
  21 + def __str__(self):
  22 + return self.b
  23 + '''
  24 +class user:
  25 + e = essai()
  26 +
  27 +class GenericResult:
  28 + ''' Usage:
  29 + res = execute(command)
  30 + print("result is", res)
  31 + if res.ko: raise UnexpectedReturnCode()
  32 + if res.ok:
  33 + ...
  34 + '''
  35 + # By default, bad result
  36 + ok = False
  37 + ko = True
  38 +
  39 + def __init__(self, native_result:str, ok=False):
  40 + self.txt = native_result
  41 + self.ok = ok
  42 + self.ko = not ok
  43 + '''
  44 + def __str__(self):
  45 + return self.native_result
  46 + def __repr__(self):
  47 + return self.native_result
  48 + def __get__(self, instance, owner):
  49 + return self.b
  50 + def __set__(self, instance, value):
  51 + self.b = value
  52 + '''
  53 +
  54 +
  55 +
  56 +
  57 +
11 def main(): 58 def main():
  59 +
12 # No argument => connexion to REAL TELESCOPE (DISTANT) 60 # No argument => connexion to REAL TELESCOPE (DISTANT)
13 if len(sys.argv) == 1: 61 if len(sys.argv) == 1:
14 # Port local AK 8085 = redirigรฉ sur lโ€™IP du tele 192.168.0.12 sur port 11110 62 # Port local AK 8085 = redirigรฉ sur lโ€™IP du tele 192.168.0.12 sur port 11110
@@ -24,17 +72,23 @@ def main(): @@ -24,17 +72,23 @@ def main():
24 # (optional) Only useful for TCP (does nothing for UDP) 72 # (optional) Only useful for TCP (does nothing for UDP)
25 tele_client._connect_to_server() 73 tele_client._connect_to_server()
26 74
27 - print("RA is", tele_client.get_RA())  
28 - print("ack is", tele_client.get_ACK()) 75 + print("RA is", tele_client.get_ra())
  76 +
  77 + ack = tele_client.get_ack()
  78 + print("ack is", ack)
  79 + print("ack.txt is", ack)
  80 + if ack.ok: print("ack is ok")
  81 + if ack.ko: print("ack is ko")
29 82
30 # Initialize telescope config (ack, date, time) 83 # Initialize telescope config (ack, date, time)
31 tele_client.do_init() 84 tele_client.do_init()
32 85
33 - _mes_tests_temporaires_avirer(tele_client) 86 + #_mes_tests_temporaires_avirer(tele_client)
34 87
35 #radec = tele_client.get("RA-DEC") 88 #radec = tele_client.get("RA-DEC")
36 - radec = tele_client.get_RADEC()  
37 - print("RA-DEC is", radec) 89 + ra,dec = tele_client.get_radec()
  90 + print("RA-DEC is", ra,dec)
  91 + print("ra is", ra.txt)
38 92
39 #tele_client.do_GOTO(ra='22:00:00',dec='+30:00:00') 93 #tele_client.do_GOTO(ra='22:00:00',dec='+30:00:00')
40 #tele_client.do_GOTO(ra='21:00:00',dec='+20:00:00') 94 #tele_client.do_GOTO(ra='21:00:00',dec='+20:00:00')
@@ -49,7 +103,9 @@ def main(): @@ -49,7 +103,9 @@ def main():
49 req = input("REQUEST TO SERVER (ENTER to quit): >>> ").strip() 103 req = input("REQUEST TO SERVER (ENTER to quit): >>> ").strip()
50 if not req: break 104 if not req: break
51 105
52 - result = tele_client.execute(req) 106 + res = tele_client.execute(req)
  107 + print("result is", res)
  108 + #print("result.txt is", res.txt)
53 109
54 # END: park telescope 110 # END: park telescope
55 ###tele_client.do_PARK() 111 ###tele_client.do_PARK()
@@ -58,11 +114,20 @@ def main(): @@ -58,11 +114,20 @@ def main():
58 114
59 115
60 116
61 - 117 +# @private
62 def _mes_tests_temporaires_avirer(tele_client): 118 def _mes_tests_temporaires_avirer(tele_client):
63 119
64 print("\n...Execution de mes tests temporaires...\n") 120 print("\n...Execution de mes tests temporaires...\n")
65 121
  122 + u = user()
  123 + print(u.e)
  124 +
  125 + res = GenericResult('G',False)
  126 + print("res is", res)
  127 + if res.ok: print("res is ok")
  128 + if not res.ko: print("res is not ko")
  129 + if res.txt == 'G': print("res is G")
  130 +
66 tele_client.do_move_dir('EAST','4', 'slew') 131 tele_client.do_move_dir('EAST','4', 'slew')
67 tele_client.do_goto(ra='21:00:00',dec='+20:00:00') 132 tele_client.do_goto(ra='21:00:00',dec='+20:00:00')
68 ''' 133 '''
sockets_tele/src_socket/client/socket_client_telescope_abstract.py
@@ -35,6 +35,11 @@ GET_ONLY=False @@ -35,6 +35,11 @@ GET_ONLY=False
35 # Execute only "get" commands 35 # Execute only "get" commands
36 #GET_ONLY=True 36 #GET_ONLY=True
37 37
  38 +# Default timeouts
  39 +TIMEOUT_SEND = 10
  40 +TIMEOUT_RECEIVE = 10
  41 +
  42 +
38 ''' 43 '''
39 class c(Enum): 44 class c(Enum):
40 45
@@ -50,6 +55,33 @@ class c(Enum): @@ -50,6 +55,33 @@ class c(Enum):
50 55
51 56
52 57
  58 +class GenericResult:
  59 + ''' Usage:
  60 + res = execute(command)
  61 + print("result is", res)
  62 + if res.ko: raise UnexpectedReturnCode()
  63 + if res.ok:
  64 + ...
  65 + '''
  66 + # By default, bad result
  67 + ok = True
  68 + ko = False
  69 +
  70 + def __init__(self, native_result:str, ok=True):
  71 + self.txt = native_result
  72 + self.ok = ok
  73 + self.ko = not ok
  74 + def __str__(self):
  75 + return self.txt
  76 + '''
  77 + def __repr__(self):
  78 + return self.txt
  79 + def __get__(self, instance, owner):
  80 + return self.b
  81 + def __set__(self, instance, value):
  82 + self.b = value
  83 + '''
  84 +
53 85
54 class Position(): 86 class Position():
55 x = 0 87 x = 0
@@ -82,11 +114,11 @@ class SocketClientTelescopeAbstract(SocketClientAbstract): @@ -82,11 +114,11 @@ class SocketClientTelescopeAbstract(SocketClientAbstract):
82 'CMD-NAME': ['cmd-get', 'cmd-set', 'comment'], 114 'CMD-NAME': ['cmd-get', 'cmd-set', 'comment'],
83 ''' 115 '''
84 _cmd_getset = { 116 _cmd_getset = {
85 - 'ACK': [],  
86 - 'RA': [],  
87 - 'DEC': [],  
88 - 'RADEC': [],  
89 - 'TIMEZONE': [], 117 + 'ack': [],
  118 + 'ra': [],
  119 + 'dec': [],
  120 + #'RADEC': [],
  121 + 'timezone': [],
90 #'TIMEZONE_IS_UTC': [], 122 #'TIMEZONE_IS_UTC': [],
91 'DATE': [], 123 'DATE': [],
92 'TIME': [], 124 'TIME': [],
@@ -128,7 +160,11 @@ class SocketClientTelescopeAbstract(SocketClientAbstract): @@ -128,7 +160,11 @@ class SocketClientTelescopeAbstract(SocketClientAbstract):
128 if request.startswith('get_') or request.startswith('set_') or request.startswith('do_'): 160 if request.startswith('get_') or request.startswith('set_') or request.startswith('do_'):
129 print("GENERIC COMMAND") 161 print("GENERIC COMMAND")
130 if request.startswith('get_'): 162 if request.startswith('get_'):
131 - generic_cmd,_ = request[4:].split('(') 163 + #generic_cmd,_ = request[4:].split('(')
  164 + generic_cmd = request[4:]
  165 + if (generic_cmd not in self._cmd_getset.keys()) and (generic_cmd not in self._cmd_do.keys()):
  166 + #eval(request)
  167 + return self.get_radec()
132 print("cmd is", generic_cmd) 168 print("cmd is", generic_cmd)
133 return self._get(generic_cmd) 169 return self._get(generic_cmd)
134 return 170 return
@@ -136,16 +172,23 @@ class SocketClientTelescopeAbstract(SocketClientAbstract): @@ -136,16 +172,23 @@ class SocketClientTelescopeAbstract(SocketClientAbstract):
136 print("NATIVE COMMAND") 172 print("NATIVE COMMAND")
137 return self.execute_native_cmd(request) 173 return self.execute_native_cmd(request)
138 174
139 - def execute_native_cmd(self, request:str)->str: 175 + def execute_native_cmd(self, request:str, awaited_res_if_ok=None)->GenericResult:
140 self.send_request(request) 176 self.send_request(request)
141 - return self.receive_data() 177 + native_res = self.receive_data()
  178 + ok = True if not awaited_res_if_ok else (native_res == awaited_res_if_ok)
  179 + return GenericResult(native_res, ok)
  180 +
  181 + def execute_native_cmd_OLD(self, request:str)->str:
  182 + self.send_request(request)
  183 + native_res = self.receive_data()
  184 + return native_res
142 def execute_unformated_native_cmd(self, request:str)->str: 185 def execute_unformated_native_cmd(self, request:str)->str:
143 request = self.formated_cmd(request) 186 request = self.formated_cmd(request)
144 - self.send_request(request)  
145 - return self.receive_data() 187 + return self.execute_native_cmd_OLD(request)
146 188
147 def send_request(self, request:str)->str: 189 def send_request(self, request:str)->str:
148 return self.send_data(request) 190 return self.send_data(request)
  191 +
149 192
150 def print_available_commands(self): 193 def print_available_commands(self):
151 print("\nAvailable commands are:") 194 print("\nAvailable commands are:")
@@ -176,14 +219,40 @@ class SocketClientTelescopeAbstract(SocketClientAbstract): @@ -176,14 +219,40 @@ class SocketClientTelescopeAbstract(SocketClientAbstract):
176 return self._get_set_do(self._cmd_getset, 0, generic_param) 219 return self._get_set_do(self._cmd_getset, 0, generic_param)
177 def _set(self, generic_param:str, value:str)->str: 220 def _set(self, generic_param:str, value:str)->str:
178 if GET_ONLY: return 'NOT_DONE' 221 if GET_ONLY: return 'NOT_DONE'
179 - return self._get_set_do(self._cmd_getset, 1, generic_param, value) 222 + return self._get_set_do(self._cmd_getset, 2, generic_param, value)
180 def _do(self, generic_param:str)->str: 223 def _do(self, generic_param:str)->str:
181 if GET_ONLY: return 'NOT_DONE' 224 if GET_ONLY: return 'NOT_DONE'
182 return self._get_set_do(self._cmd_do, 0, generic_param) 225 return self._get_set_do(self._cmd_do, 0, generic_param)
183 226
  227 +
  228 + def _get_set_do(self, dic:dict, indice:int, generic_param:str, value:str=None)->str:
  229 +
  230 + generic_cmd = 'do_'
  231 + if dic == self._cmd_getset:
  232 + generic_cmd = 'get_' if indice==0 else 'set_'
  233 + generic_cmd += generic_param
  234 + log_d("\nGENERIC command: "+generic_cmd)
  235 +
  236 + # Check if generic_param exists
  237 + if not generic_param: raise UnknownCommandException()
  238 + if generic_param not in dic.keys(): raise UnknownCommandException()
  239 + # if this command is not overriden by this class, raise NotImplementedError
  240 + if not dic[generic_param]: raise NotImplementedError
  241 + if len(dic[generic_param]) < indice+1: raise NotImplementedError
  242 +
  243 + # Get corresponding native command:
  244 + native_cmd = dic[generic_param][indice]
  245 + # if this command is not overriden by this class, raise NotImplementedError
  246 + if native_cmd == '': raise NotImplementedError
  247 +
  248 + awaited_res_ok = None
  249 + if len(dic[generic_param]) > 1: awaited_res_ok = dic[generic_param][indice+1]
  250 + return self.execute_native_cmd(self.formated_cmd(native_cmd,value), awaited_res_ok)
  251 +
  252 + '''
184 def _get_set_do(self, dic:dict, indice:int, generic_param:str, value:str=None)->str: 253 def _get_set_do(self, dic:dict, indice:int, generic_param:str, value:str=None)->str:
185 #if generic_param in c: return generic_param.name 254 #if generic_param in c: return generic_param.name
186 - #if generic_param == c.RA_DEC: return self.get_RADEC() 255 + #if generic_param == c.RA_DEC: return self.get_radec()
187 #return NotImplementedError 256 #return NotImplementedError
188 native_cmds = [] 257 native_cmds = []
189 258
@@ -213,87 +282,22 @@ class SocketClientTelescopeAbstract(SocketClientAbstract): @@ -213,87 +282,22 @@ class SocketClientTelescopeAbstract(SocketClientAbstract):
213 for cmd in native_cmds: 282 for cmd in native_cmds:
214 #print("command is", repr(cmd)) 283 #print("command is", repr(cmd))
215 #res.append(self.put_read(self.formated_cmd(cmd))) 284 #res.append(self.put_read(self.formated_cmd(cmd)))
216 - res.append(self.execute_native_cmd(self.formated_cmd(cmd,value))) 285 + res.append(self.execute_native_cmd_OLD(self.formated_cmd(cmd,value)))
217 if len(res) == 1: return res[0] 286 if len(res) == 1: return res[0]
218 return res 287 return res
219 -  
220 -  
221 - def set_SPEED(self, speed_rate):  
222 - print("from super")  
223 - pass  
224 -  
225 -  
226 - ''' GOTO (p105)  
227 - - GOTO(position, blocking=Y/N):  
228 - (MS = move start)  
229 - = Goto RA=18h23m45s Dec=+34d00m00s J2000  
230 - - radec.goto()  
231 ''' 288 '''
232 - def do_goto(self, ra, dec, speed_rate=None):  
233 -  
234 - # 1) set speed  
235 - if speed_rate: self.set_SPEED(speed_rate)  
236 -  
237 - radec = self.get_RADEC()  
238 - print("Current position is", radec)  
239 289
240 - # 2) set RA-DEC  
241 - '''  
242 - :Sr18:23:45#:Sd+34:00:00#:MS#  
243 - '''  
244 - res = self.set_RA(ra)  
245 - if res != '1': raise UnexpectedCommandReturnCode(res)  
246 - res = self.set_DEC(dec)  
247 - if res != '1': raise UnexpectedCommandReturnCode(res)  
248 -  
249 - # 3) MOVE (non blocking by default for GEMINI)  
250 - self.do_MOVE()  
251 -  
252 - # 4) Test velocity until it is "Tracking"  
253 - '''  
254 - After MOVE, test velocity with ':Gv#' (p103) : we should have 'S', then 'C', then 'T'  
255 - - N (for "no tracking")  
256 - - T (for Tracking)  
257 - - G (for Guiding)  
258 - - C (for Centering)  
259 - - S (for Slewing)  
260 - '''  
261 - v = None  
262 - while v != 'T':  
263 - v = self.get_VELOCITY()  
264 - print("Velocity is", v)  
265 - time.sleep(2)  
266 -  
267 - time.sleep(2)  
268 - radec = self.get_RADEC()  
269 - print("Current position is", radec)  
270 -  
271 - def do_MOVE_NORTH(self): pass  
272 - def do_MOVE_SOUTH(self): pass  
273 - def do_MOVE_WEST(self): pass  
274 - def do_MOVE_EAST(self): pass  
275 -  
276 - def do_move_dir(self, dir, nbsec, speed_rate=None):  
277 - if speed_rate: self.set_SPEED(speed_rate)  
278 - if dir=="NORTH": self.do_MOVE_NORTH()  
279 - if dir=="SOUTH": self.do_MOVE_SOUTH()  
280 - if dir=="WEST": self.do_MOVE_WEST()  
281 - if dir=="EAST": self.do_MOVE_EAST()  
282 - time.sleep(int(nbsec))  
283 - self.do_STOP()  
284 290
285 291
286 ''' 292 '''
287 - def do(self, generic_cmd:str):  
288 - return NotImplementedError  
289 - def set(self, generic_param:str):  
290 - return NotImplementedError 293 + ****************************
  294 + GENERIC GET & SET commands
  295 + ****************************
291 ''' 296 '''
292 297
293 - ''' GET & SET commands '''  
294 -  
295 # @abstract 298 # @abstract
296 - def get_ACK(self): return self._get("ACK") 299 + def get_ack(self):
  300 + return self._get("ack")
297 301
298 # RA/DEC 302 # RA/DEC
299 # @abstract 303 # @abstract
@@ -307,8 +311,8 @@ class SocketClientTelescopeAbstract(SocketClientAbstract): @@ -307,8 +311,8 @@ class SocketClientTelescopeAbstract(SocketClientAbstract):
307 0 if invalid 311 0 if invalid
308 1 if valid 312 1 if valid
309 ''' 313 '''
310 - def get_RA(self): return self._get("RA")  
311 - def set_RA(self, ra): return self._set("RA", ra) 314 + def get_ra(self): return self._get("ra")
  315 + def set_ra(self, ra): return self._set("ra", ra)
312 316
313 ''' 317 '''
314 Sets the object's declination. 318 Sets the object's declination.
@@ -321,16 +325,18 @@ class SocketClientTelescopeAbstract(SocketClientAbstract): @@ -321,16 +325,18 @@ class SocketClientTelescopeAbstract(SocketClientAbstract):
321 0 if invalid 325 0 if invalid
322 1 if valid 326 1 if valid
323 ''' 327 '''
324 - def get_DEC(self): return self._get("DEC")  
325 - def set_DEC(self, dec): return self._set("DEC", dec) 328 + def get_dec(self): return self._get("dec")
  329 + def set_dec(self, dec): return self._set("dec", dec)
326 # @abstract 330 # @abstract
327 # @abstract 331 # @abstract
328 - def get_RADEC(self): return self._get("RADEC") 332 + #def get_radec(self): return self._get("RADEC")
  333 + def get_radec(self)->tuple: return (self.get_ra(),self.get_dec())
  334 +
329 def set_RADEC(self, radec): return self._set("RADEC", radec) 335 def set_RADEC(self, radec): return self._set("RADEC", radec)
330 336
331 #def set_TIMEZONE_IS_UTC(self): return self._set('TIMEZONE_IS_UTC') 337 #def set_TIMEZONE_IS_UTC(self): return self._set('TIMEZONE_IS_UTC')
332 - def get_TIMEZONE(self): return self._get('TIMEZONE')  
333 - def set_TIMEZONE(self, hh): return self._set('TIMEZONE', hh) 338 + def get_timezone(self): return self._get('timezone')
  339 + def set_timezone(self, hh): return self._set('timezone', hh)
334 def get_DATE(self): return self._get('DATE') 340 def get_DATE(self): return self._get('DATE')
335 def set_DATE(self, mmddyy): return self._set('DATE', mmddyy) 341 def set_DATE(self, mmddyy): return self._set('DATE', mmddyy)
336 def get_TIME(self): return self._get('TIME') 342 def get_TIME(self): return self._get('TIME')
@@ -342,9 +348,15 @@ class SocketClientTelescopeAbstract(SocketClientAbstract): @@ -342,9 +348,15 @@ class SocketClientTelescopeAbstract(SocketClientAbstract):
342 def set_LATITUDE(self, latitude): return self._set('LATITUDE', latitude) 348 def set_LATITUDE(self, latitude): return self._set('LATITUDE', latitude)
343 349
344 def get_VELOCITY(self): return self._get('VELOCITY') 350 def get_VELOCITY(self): return self._get('VELOCITY')
345 -  
346 -  
347 - ''' DO commands ''' 351 +
  352 +
  353 +
  354 +
  355 + '''
  356 + ****************************
  357 + GENERIC DO commands
  358 + ****************************
  359 + '''
348 360
349 # @abstract 361 # @abstract
350 #def do_INIT(self): return self._do("INIT") 362 #def do_INIT(self): return self._do("INIT")
@@ -365,8 +377,254 @@ class SocketClientTelescopeAbstract(SocketClientAbstract): @@ -365,8 +377,254 @@ class SocketClientTelescopeAbstract(SocketClientAbstract):
365 377
366 # @abstract 378 # @abstract
367 #def do_GOTO(self, pos:Position): return self._do("GOTO") 379 #def do_GOTO(self, pos:Position): return self._do("GOTO")
368 - def do_WARM_START(self): return self._do("WARM_START")  
369 - def do_PREC_REFR(self): return self._do("PREC_REFR") 380 + #def do_WARM_START(self): return self._do("WARM_START")
  381 + def do_warm_start(self): pass
  382 + def do_PREC_REFR(self): return self._do("PREC_REFR")
  383 +
  384 +
  385 +
  386 + # @abstract
  387 + def do_init(self):
  388 +
  389 + '''
  390 + 1) Send cde ACK ('06') and check answer to see if telescope is ready (see doc page 100)
  391 + (utile pour savoir si tout est ok ; par ex, si une raquette est branchรฉe sur le tele, รงa peut bloquer le protocole)
  392 + Usable for testing the serial link and determining the type of mount (German equatorial).
  393 + Return code can be:
  394 + - B# while the initial startup message is being displayed (new in L4),
  395 + - b# while waiting for the selection of the Startup Mode,
  396 + - S# during a Cold Start (new in L4),
  397 + - G# after completed startup ==> MEANS ALL IS OK
  398 + '''
  399 + #ACK = self.get("ACK")
  400 + ACK = self.get_ack()
  401 +
  402 + '''
  403 + 2) IF telescope is not ready (still starting up), ask it to do a Warm Start ('bW#')
  404 + During Startup, with a "b#" being returned, the PC can select the startup mode by sending a
  405 + โ€ข bC# for selecting the Cold Start,
  406 + โ€ข bW# for selecting the Warm Start,
  407 + โ€ข bR# for selecting the Warm Restart
  408 + If not ok (still starting up, no 'G#' in return), send 'bW#' (see above) for selecting the Warm Start
  409 + '''
  410 + #if ACK != 'G':
  411 + if not ACK.ok:
  412 + self.do_warm_start()
  413 + ACK = self.get_ack()
  414 + elapsed_time = 0
  415 + while not ACK.ok:
  416 + time.sleep(1)
  417 + elapsed_time += 1
  418 + if elapsed_time == TIMEOUT_RECEIVE: raise TimeoutException()
  419 + ACK = self.get_ack()
  420 +
  421 +
  422 + '''
  423 + 3) Set timezone, date, and time (p109)
  424 + '''
  425 +
  426 + '''
  427 + a) set TIMEZONE
  428 + Set the number of hours by which your local time differs from UTC.
  429 + If your local time is earlier than UTC set a positive value,
  430 + if later than UTC set a negative value. The time difference has to be set before setting the calendar date (SC) and local time (SL), since the Real Time Clock is running at UTC
  431 + => :SG{+-}hh#
  432 + '''
  433 + res = self.get_timezone()
  434 + print("Current timezone is", res)
  435 + res = self.set_timezone('+00')
  436 + #if res != '1': raise UnexpectedCommandReturnCode(res)
  437 + if not res.ok: raise UnexpectedCommandReturnCode(res)
  438 + res = self.get_timezone()
  439 + if res.txt != '+00': raise UnexpectedCommandReturnCode(res)
  440 + print("NEW timezone set is", res)
  441 +
  442 +
  443 + return
  444 + '''
  445 + b) set DATE
  446 + Set Calendar Date:
  447 + months mm, days dd, year yy of the civil time according to the timezone set.
  448 + The internal calendar/clock uses GMT
  449 + :SC<mm>/<dd>/<yy>#
  450 + 0 if invalid
  451 + or
  452 + TODO:
  453 + 1Updating planetary data#<24 blanks>#
  454 + '''
  455 + res = self.get_DATE()
  456 + print("Current date is", res)
  457 + # format is 2018-09-26T17:50:21
  458 + d = self.get_utc_date()
  459 + # format to mm/dd/yy
  460 + now_utc_mm_dd_yy = d[5:7] + '/' + d[8:10] + '/' + d[2:4]
  461 + #print("date is", now_utc_mm_dd_yy)
  462 + res = self.set_DATE(now_utc_mm_dd_yy)
  463 + #res = self.set_DATE(self.get_utc_date())
  464 + #if res[0] != '1': raise UnexpectedCommandReturnCode(res)
  465 + #if not res.startswith('1Updating planetary data'): raise UnexpectedCommandReturnCode(res)
  466 + if not res: raise UnexpectedCommandReturnCode(res)
  467 + res = self.get_DATE()
  468 + if res != now_utc_mm_dd_yy: raise UnexpectedCommandReturnCode(res)
  469 + print("NEW DATE set is", res)
  470 +
  471 + '''
  472 + c) set TIME
  473 + Set RTC Time from the civil time hours hh, minutes mm and seconds ss.
  474 + The timezone must be set before using this command
  475 + :SL<hh>:<mm>:<ss>#
  476 + '''
  477 + res = self.get_TIME()
  478 + print("Current time is", res)
  479 + _,now_utc_hh_mm_ss = d.split('T')
  480 + #print("time is", now_utc_hh_mm_ss[:5])
  481 + res = self.set_TIME(now_utc_hh_mm_ss)
  482 + #if res != '1': raise UnexpectedCommandReturnCode(res)
  483 + if not res: raise UnexpectedCommandReturnCode(res)
  484 + res = self.get_TIME()
  485 + if res[:5] != now_utc_hh_mm_ss[:5]: raise UnexpectedCommandReturnCode(res)
  486 +
  487 +
  488 + '''
  489 + 4) Set LOCATION (lat,long) (p103,110)
  490 + Pour l'observatoire de Guitalens:
  491 + Sg = 2.0375 E
  492 + St = 43.6443 N
  493 + (attention, 2.0375 E = - 2.0375)
  494 + '''
  495 +
  496 + '''
  497 + a) set Longitude
  498 + Sets the longitude of the observing site to ddd degrees and mm minutes.
  499 + The longitude has to be specified positively for western latitudes
  500 + (west of Greenwich, the plus sign may be omitted) and negatively for eastern longitudes.
  501 + Alternatively, 360 degrees may be added to eastern longitudes.
  502 + => :Sg{+-}<ddd>*<mm>#
  503 + '''
  504 + # TELE format is -002ยฐ02 (I convert it to -002:02)
  505 + res = self.get_LONGITUDE()
  506 + print("Current longitude is", res)
  507 +
  508 + # CELME format is -002:02:15
  509 + res = self.get_celme_longitude("-2.0375")
  510 + res_ddd_mm = res[:-3]
  511 + #res_ddd_mm = '-002:03'
  512 +
  513 + #print("celme longitude is", res)
  514 + ddd,mm,ss = res.split(':')
  515 + dddmm = ddd+'*'+mm
  516 + #dddmm = '-002*03'
  517 + res = self.set_LONGITUDE(dddmm)
  518 + #if res != '1': raise UnexpectedCommandReturnCode(res)
  519 + if not res: raise UnexpectedCommandReturnCode(res)
  520 + res = self.get_LONGITUDE()
  521 + if res != res_ddd_mm: raise UnexpectedCommandReturnCode(res)
  522 +
  523 + '''
  524 + b) set Latitude
  525 + Sets the latitude of the observing site to dd degrees, mm minutes.
  526 + The minus sign indicates southern latitudes, the positive sign may be omitted.
  527 + => :St{+-}<dd>*<mm>#
  528 + '''
  529 + # TELE format is +43ยฐ38 (I convert it to +43:38)
  530 + res = self.get_LATITUDE()
  531 + print("Current latitude is", res)
  532 +
  533 + # CELME format is +43:38:15
  534 + res = self.get_celme_latitude("+43.6443")
  535 + res_dd_mm = res[:-3]
  536 + print("res is", res)
  537 + #res_dd_mm = '+43:50'
  538 +
  539 + #print("celme longitude is", res)
  540 + dd,mm,ss = res.split(':')
  541 + ddmm = dd+'*'+mm
  542 + #ddmm = '+43*50'
  543 + res = self.set_LATITUDE(ddmm)
  544 + #if res != '1': raise UnexpectedCommandReturnCode(res)
  545 + if not res: raise UnexpectedCommandReturnCode(res)
  546 + res = self.get_LATITUDE()
  547 + if res != res_dd_mm: raise UnexpectedCommandReturnCode(res)
  548 +
  549 +
  550 + '''
  551 + 5) Send cde ':p3#' : Precession & Refraction (see page 107)
  552 + Ask Gemini to do Precession calculation
  553 + Coordinates transferred to the Gemini refer to the standard epoch J2000.0.
  554 + Refraction is calculated (From L4, V1.0 up)
  555 + '''
  556 + self.do_PREC_REFR()
  557 +
  558 +
  559 + # @abstract
  560 + def set_SPEED(self, speed_rate):
  561 + pass
  562 +
  563 +
  564 + ''' GOTO (p105)
  565 + - GOTO(position, blocking=Y/N):
  566 + (MS = move start)
  567 + = Goto RA=18h23m45s Dec=+34d00m00s J2000
  568 + - radec.goto()
  569 + '''
  570 + # @abstract
  571 + def do_goto(self, ra, dec, speed_rate=None):
  572 +
  573 + # 1) set speed
  574 + if speed_rate: self.set_SPEED(speed_rate)
  575 +
  576 + radec = self.get_radec()
  577 + print("Current position is", radec)
  578 +
  579 + # 2) set RA-DEC
  580 + '''
  581 + :Sr18:23:45#:Sd+34:00:00#:MS#
  582 + '''
  583 + res = self.set_ra(ra)
  584 + if res != '1': raise UnexpectedCommandReturnCode(res)
  585 + res = self.set_dec(dec)
  586 + if res != '1': raise UnexpectedCommandReturnCode(res)
  587 +
  588 + # 3) MOVE (non blocking by default for GEMINI)
  589 + self.do_MOVE()
  590 +
  591 + # 4) Test velocity until it is "Tracking"
  592 + '''
  593 + After MOVE, test velocity with ':Gv#' (p103) : we should have 'S', then 'C', then 'T'
  594 + - N (for "no tracking")
  595 + - T (for Tracking)
  596 + - G (for Guiding)
  597 + - C (for Centering)
  598 + - S (for Slewing)
  599 + '''
  600 + v = None
  601 + while v != 'T':
  602 + v = self.get_VELOCITY()
  603 + print("Velocity is", v)
  604 + time.sleep(2)
  605 +
  606 + time.sleep(2)
  607 + radec = self.get_radec()
  608 + print("Current position is", radec)
  609 +
  610 +
  611 + def do_MOVE_NORTH(self): pass
  612 + def do_MOVE_SOUTH(self): pass
  613 + def do_MOVE_WEST(self): pass
  614 + def do_MOVE_EAST(self): pass
  615 +
  616 + # @abstract
  617 + def do_move_dir(self, dir, nbsec, speed_rate=None):
  618 + if speed_rate: self.set_SPEED(speed_rate)
  619 + if dir=="NORTH": self.do_MOVE_NORTH()
  620 + if dir=="SOUTH": self.do_MOVE_SOUTH()
  621 + if dir=="WEST": self.do_MOVE_WEST()
  622 + if dir=="EAST": self.do_MOVE_EAST()
  623 + time.sleep(int(nbsec))
  624 + self.do_STOP()
  625 +
  626 +
  627 +
370 628
371 629
372 #TODO: delete if not necessary 630 #TODO: delete if not necessary
sockets_tele/src_socket/client/socket_client_telescope_gemini.py
@@ -21,8 +21,9 @@ sys.path.append(&#39;../..&#39;) @@ -21,8 +21,9 @@ sys.path.append(&#39;../..&#39;)
21 from src_socket.client.socket_client_telescope_abstract import * 21 from src_socket.client.socket_client_telescope_abstract import *
22 22
23 23
24 -# Default timeout set to 10s  
25 -TIMEOUT = 10 24 +# Default timeouts
  25 +TIMEOUT_SEND = 10
  26 +TIMEOUT_RECEIVE = 10
26 27
27 # COMMON CONSTANTS WITH SERVER 28 # COMMON CONSTANTS WITH SERVER
28 TERMINATOR = '\x00' 29 TERMINATOR = '\x00'
@@ -56,39 +57,39 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract): @@ -56,39 +57,39 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract):
56 57
57 58
58 ''' Commands dictionary 59 ''' Commands dictionary
59 - 'CMD-NAME': ['cmd-get', 'cmd-set', 'comment'], 60 + 'CMD-NAME': ['cmd-get', 'awaited_res_ok_for_get', 'cmd-set', 'awaited_res_ok_for_set', 'comment'],
60 ''' 61 '''
61 # @override 62 # @override
62 _cmd_getset = { 63 _cmd_getset = {
63 64
64 - 'ACK': [COMMAND6], 65 + 'ack': [COMMAND6, 'G'],
65 66
66 # RA-DEC (p109-110) 67 # RA-DEC (p109-110)
67 #:Sr<hh>:<mm>.<m># or :Sr<hh>:<mm>:<ss># 68 #:Sr<hh>:<mm>.<m># or :Sr<hh>:<mm>:<ss>#
68 #Sets the object's Right Ascension and the object status to "Not Selected". The :Sd# command has to follow to complete the selection. The subsequent use of the :ON...# command is recommended 69 #Sets the object's Right Ascension and the object status to "Not Selected". The :Sd# command has to follow to complete the selection. The subsequent use of the :ON...# command is recommended
69 #:Sd{+-}<dd>{*ยฐ}<mm># or :Sd{+- }<dd>{*ยฐ:}<mm>:<ss> 70 #:Sd{+-}<dd>{*ยฐ}<mm># or :Sd{+- }<dd>{*ยฐ:}<mm>:<ss>
70 #Sets the object's declination. It is important that the :Sr# command has been send prior. Internal calculations are done that may take up to 0.5 seconds. If the coordinate selection is valid the object status is set to "Selected" 71 #Sets the object's declination. It is important that the :Sr# command has been send prior. Internal calculations are done that may take up to 0.5 seconds. If the coordinate selection is valid the object status is set to "Selected"
71 - 'RA': ['GR', 'Sr', 'commentaire'],  
72 - 'DEC': ['GD', 'Sd'],  
73 - 'RADEC': [('GR','GD'), ''], 72 + 'ra': ['GR', None, 'Sr', None, 'commentaire'],
  73 + 'dec': ['GD', None, 'Sd'],
  74 + #'RADEC': [('GR','GD'), ''],
74 75
75 # ALT-AZ (p?) 76 # ALT-AZ (p?)
76 - "ALT": ['GA', ''],  
77 - "AZ": ['GZ', ''],  
78 - "ALT-AZ": [('GA','GZ'), ''], 77 + "ALT": ['GA'],
  78 + "AZ": ['GZ'],
  79 + #"ALT-AZ": [('GA','GZ'), ''],
79 80
80 # LONG-LAT 81 # LONG-LAT
81 - "LONGITUDE": ['Gg', 'Sg'],  
82 - "LATITUDE": ['Gt', 'St'],  
83 - "LONGLAT": [('Gg','Gt'), ''], 82 + "LONGITUDE": ['Gg', None, 'Sg'],
  83 + "LATITUDE": ['Gt', None, 'St'],
  84 + #"LONGLAT": [('Gg','Gt'), ''],
84 85
85 - "hour-angle": ['GH', ''], 86 + "hour-angle": ['GH'],
86 87
87 - "max-vel": ['Gv', ''], 88 + "max-vel": ['Gv'],
88 89
89 - 'TIMEZONE': ['GG', 'SG'],  
90 - 'DATE': ['GC', 'SC'],  
91 - 'TIME': ['GL', 'SL'], 90 + 'timezone': ['GG', None, 'SG', '1'],
  91 + 'DATE': ['GC', None, 'SC'],
  92 + 'TIME': ['GL', None, 'SL'],
92 93
93 'VELOCITY': ['Gv'], 94 'VELOCITY': ['Gv'],
94 95
@@ -210,6 +211,14 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract): @@ -210,6 +211,14 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract):
210 return useful_data 211 return useful_data
211 212
212 213
  214 +
  215 + # @overwrite
  216 + #def get_ack(self): return self.execute_native_cmd(COMMAND6, 'G')
  217 + #def do_warm_start(self): return self.execute_native_cmd('bW')
  218 +
  219 +
  220 +
  221 + """ moved to abstract parent
213 # @override 222 # @override
214 def do_init(self): 223 def do_init(self):
215 224
@@ -224,7 +233,7 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract): @@ -224,7 +233,7 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract):
224 - G# after completed startup ==> MEANS ALL IS OK 233 - G# after completed startup ==> MEANS ALL IS OK
225 ''' 234 '''
226 #ACK = self.get("ACK") 235 #ACK = self.get("ACK")
227 - ACK = self.get_ACK() 236 + ACK = self.get_ack()
228 237
229 ''' 238 '''
230 2) IF telescope is not ready (still starting up), ask it to do a Warm Start ('bW#') 239 2) IF telescope is not ready (still starting up), ask it to do a Warm Start ('bW#')
@@ -236,13 +245,13 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract): @@ -236,13 +245,13 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract):
236 ''' 245 '''
237 if ACK != 'G': 246 if ACK != 'G':
238 self.do_WARM_START() 247 self.do_WARM_START()
239 - ACK = self.get_ACK() 248 + ACK = self.get_ack()
240 elapsed_time = 0 249 elapsed_time = 0
241 while ACK != 'G': 250 while ACK != 'G':
242 time.sleep(1) 251 time.sleep(1)
243 elapsed_time += 1 252 elapsed_time += 1
244 if elapsed_time == TIMEOUT: raise TimeoutException() 253 if elapsed_time == TIMEOUT: raise TimeoutException()
245 - ACK = self.get_ACK() 254 + ACK = self.get_ack()
246 255
247 256
248 ''' 257 '''
@@ -374,6 +383,7 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract): @@ -374,6 +383,7 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract):
374 Refraction is calculated (From L4, V1.0 up) 383 Refraction is calculated (From L4, V1.0 up)
375 ''' 384 '''
376 self.do_PREC_REFR() 385 self.do_PREC_REFR()
  386 + """
377 387
378 388
379 def set_SPEED(self, speed_rate): 389 def set_SPEED(self, speed_rate):
@@ -390,10 +400,10 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract): @@ -390,10 +400,10 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract):
390 if not native_cmd: raise UnknownCommandException(speed_rate) 400 if not native_cmd: raise UnknownCommandException(speed_rate)
391 return self.execute_unformated_native_cmd(native_cmd) 401 return self.execute_unformated_native_cmd(native_cmd)
392 402
393 - def do_MOVE_NORTH(self): return self.execute_native_cmd(':Mn#')  
394 - def do_MOVE_SOUTH(self): return self.execute_native_cmd(':Ms#')  
395 - def do_MOVE_WEST(self): return self.execute_native_cmd(':Mw#')  
396 - def do_MOVE_EAST(self): return self.execute_native_cmd(':Me#') 403 + def do_MOVE_NORTH(self): return self.execute_native_cmd_OLD(':Mn#')
  404 + def do_MOVE_SOUTH(self): return self.execute_native_cmd_OLD(':Ms#')
  405 + def do_MOVE_WEST(self): return self.execute_native_cmd_OLD(':Mw#')
  406 + def do_MOVE_EAST(self): return self.execute_native_cmd_OLD(':Me#')
397 407
398 408
399 409