Commit f6e5fcb2a6c30e248bacb81c37c4ce5d004eea8a

Authored by Etienne Pallier
1 parent 430e6c92
Exists in dev

abstract commands dictionary is now the default one and is ovewritable

with native dictionary

	- native telescope class is now less than 300 lines (majority of code
is in the abstract class so that it is easy to make a new concrete
telescope class):
	=> ne contient quasiment QUE le dictionnaire des commandes natives
	- cleanup
sockets_tele/README.txt
@@ -63,6 +63,12 @@ Pour lancer le client sur le "simulateur" de telescope (localhost, port 11110): @@ -63,6 +63,12 @@ Pour lancer le client sur le "simulateur" de telescope (localhost, port 11110):
63 ******************************************************************************************** 63 ********************************************************************************************
64 4) DONE 64 4) DONE
65 65
  66 + 2/10/18:
  67 + - abstract commands dictionary is now the default one and is ovewritable with native dictionary
  68 + - native telescope class is now less than 300 lines (majority of code is in the abstract class so that it is easy to make a new concrete telescope class):
  69 + => ne contient quasiment QUE le dictionnaire des commandes natives
  70 + - cleanup
  71 +
66 1/10/18: 72 1/10/18:
67 - interpreteur de cde generique et native : set ra 20:00:00 ou :GR# 73 - interpreteur de cde generique et native : set ra 20:00:00 ou :GR#
68 - execute_cmd(): 74 - execute_cmd():
sockets_tele/client_gemini_run.py
@@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
2 2
3 from src_socket.client.socket_client_telescope_gemini import SocketClientTelescopeGEMINI 3 from src_socket.client.socket_client_telescope_gemini import SocketClientTelescopeGEMINI
4 4
  5 +import pprint
5 import sys 6 import sys
6 7
7 #DEBUG = False 8 #DEBUG = False
@@ -57,7 +58,6 @@ class GenericResult: @@ -57,7 +58,6 @@ class GenericResult:
57 58
58 def main(): 59 def main():
59 60
60 -  
61 # No argument => connexion to REAL TELESCOPE (DISTANT) 61 # No argument => connexion to REAL TELESCOPE (DISTANT)
62 if len(sys.argv) == 1: 62 if len(sys.argv) == 1:
63 # Port local AK 8085 = redirigé sur l’IP du tele 192.168.0.12 sur port 11110 63 # Port local AK 8085 = redirigé sur l’IP du tele 192.168.0.12 sur port 11110
@@ -70,8 +70,6 @@ def main(): @@ -70,8 +70,6 @@ def main():
70 #tele_client = SocketClient_UDP_TCP(HOST, PORT) 70 #tele_client = SocketClient_UDP_TCP(HOST, PORT)
71 with SocketClientTelescopeGEMINI(HOST, PORT, DEBUG) as tele_client: 71 with SocketClientTelescopeGEMINI(HOST, PORT, DEBUG) as tele_client:
72 72
73 - print("res is", tele_client.run_func('formated_cmd','GD'))  
74 -  
75 # (optional) Only useful for TCP (does nothing for UDP) 73 # (optional) Only useful for TCP (does nothing for UDP)
76 tele_client._connect_to_server() 74 tele_client._connect_to_server()
77 75
@@ -121,6 +119,10 @@ def main(): @@ -121,6 +119,10 @@ def main():
121 def _mes_tests_temporaires_avirer(tele_client): 119 def _mes_tests_temporaires_avirer(tele_client):
122 120
123 print("\n...Execution de mes tests temporaires...\n") 121 print("\n...Execution de mes tests temporaires...\n")
  122 +
  123 + print("res is", tele_client.run_func('formated_cmd','GD'))
  124 + print("dict is")
  125 + pprint.pprint(tele_client._cmd)
124 126
125 u = user() 127 u = user()
126 print(u.e) 128 print(u.e)
sockets_tele/src_socket/client/socket_client_telescope_abstract.py
@@ -110,29 +110,45 @@ class UnknownCommandException(Exception): @@ -110,29 +110,45 @@ class UnknownCommandException(Exception):
110 class SocketClientTelescopeAbstract(SocketClientAbstract): 110 class SocketClientTelescopeAbstract(SocketClientAbstract):
111 111
112 # @abstract (to be overriden) 112 # @abstract (to be overriden)
113 - _cmd = {}  
114 - """  
115 - _cmd_getset = {  
116 - 'ack': [],  
117 - 'ra': [],  
118 - 'dec': [],  
119 - #'RADEC': [],  
120 - 'timezone': [],  
121 - #'TIMEZONE_IS_UTC': [],  
122 - 'DATE': [],  
123 - 'TIME': [],  
124 - 'LONGITUDE': [],  
125 - 'LATITUDE': [],  
126 - 'VELOCITY': [],  
127 - }  
128 - _cmd_do = {  
129 - #'INIT': [],  
130 - 'PARK': [],  
131 - 'MOVE': [],  
132 - 'WARM_START': [],  
133 - 'PREC_REFR': [], 113 + _cmd_native = {}
  114 + _cmd = {
  115 + # GET-SET commands:
  116 + 'get_ack': [],
  117 +
  118 + 'get_ra': [],
  119 + 'set_ra': [],
  120 + 'get_dec': [],
  121 + 'set_dec': [],
  122 + 'get_radec': ['get_radec'],
  123 + 'set_radec': ['set_radec'],
  124 +
  125 + 'get_timezone': [],
  126 + 'set_timezone': [],
  127 +
  128 + 'get_date': [],
  129 + 'set_date': [],
  130 +
  131 + 'get_time': [],
  132 + 'set_time': [],
  133 +
  134 + 'get_longitude': [],
  135 + 'set_longitude': [],
  136 + 'get_latitude': [],
  137 + 'set_latitude': [],
  138 +
  139 + 'get_velocity': [],
  140 + 'set_velocity': [],
  141 +
  142 + # DO commands:
  143 + 'do_init': ['do_init'],
  144 + 'do_park': [],
  145 + 'do_goto': [],
  146 + 'do_move_dir': [],
  147 + 'do_warm_start': [],
  148 + 'do_prec_refr': [],
134 } 149 }
135 - """ 150 +
  151 +
136 152
137 def __init__(self, server_host:str="localhost", server_port:int=11110, PROTOCOL:str="TCP", buffer_size=1024, DEBUG=False): 153 def __init__(self, server_host:str="localhost", server_port:int=11110, PROTOCOL:str="TCP", buffer_size=1024, DEBUG=False):
138 ''' 154 '''
@@ -141,6 +157,8 @@ class SocketClientTelescopeAbstract(SocketClientAbstract): @@ -141,6 +157,8 @@ class SocketClientTelescopeAbstract(SocketClientAbstract):
141 :param PROTOCOL: "UDP" or "TCP" 157 :param PROTOCOL: "UDP" or "TCP"
142 ''' 158 '''
143 super().__init__(server_host, server_port, PROTOCOL, buffer_size, DEBUG) 159 super().__init__(server_host, server_port, PROTOCOL, buffer_size, DEBUG)
  160 + # overwrite abstract _cmd dictionary with subclass native _cmd_native dictionary:
  161 + self._cmd = {**self._cmd, **self._cmd_native}
144 162
145 163
146 164
@@ -187,11 +205,9 @@ class SocketClientTelescopeAbstract(SocketClientAbstract): @@ -187,11 +205,9 @@ class SocketClientTelescopeAbstract(SocketClientAbstract):
187 # ex: "set_radec" 205 # ex: "set_radec"
188 generic_cmd = cmd_splitted[0] + '_' + cmd_splitted[1] 206 generic_cmd = cmd_splitted[0] + '_' + cmd_splitted[1]
189 # Check this generic command exists 207 # Check this generic command exists
190 - if (generic_cmd not in self._cmd.keys()) and ():  
191 - return False,False 208 + if (generic_cmd not in self._cmd.keys()): return False,False
192 # Is there value(s) passed ? 209 # Is there value(s) passed ?
193 - if len(cmd_splitted) > 2:  
194 - values_to_set = cmd_splitted[2:] 210 + if len(cmd_splitted) > 2: values_to_set = cmd_splitted[2:]
195 # ex: return "set_radec", ["20:00:00", "90:00:00"] 211 # ex: return "set_radec", ["20:00:00", "90:00:00"]
196 return generic_cmd, values_to_set 212 return generic_cmd, values_to_set
197 213
@@ -244,11 +260,11 @@ class SocketClientTelescopeAbstract(SocketClientAbstract): @@ -244,11 +260,11 @@ class SocketClientTelescopeAbstract(SocketClientAbstract):
244 def print_available_commands(self): 260 def print_available_commands(self):
245 print("\nAvailable commands are:") 261 print("\nAvailable commands are:")
246 print("- GET commands:") 262 print("- GET commands:")
247 - print (list(cmd for cmd in self._cmd.keys() if cmd.startswith('get_'))) 263 + print (list(cmd.replace('_',' ') for cmd in self._cmd.keys() if cmd.startswith('get_')))
248 print("- SET commands:") 264 print("- SET commands:")
249 - print (list(cmd for cmd in self._cmd.keys() if cmd.startswith('set_'))) 265 + print (list(cmd.replace('_',' ') for cmd in self._cmd.keys() if cmd.startswith('set_')))
250 print("- DO commands:") 266 print("- DO commands:")
251 - print (list(cmd for cmd in self._cmd.keys() if cmd.startswith('do_'))) 267 + print (list(cmd.replace('_',' ') for cmd in self._cmd.keys() if cmd.startswith('do_')))
252 268
253 def available_commands(self): 269 def available_commands(self):
254 return list(self._cmd.keys()) 270 return list(self._cmd.keys())
@@ -418,8 +434,7 @@ class SocketClientTelescopeAbstract(SocketClientAbstract): @@ -418,8 +434,7 @@ class SocketClientTelescopeAbstract(SocketClientAbstract):
418 # @abstract 434 # @abstract
419 #def get_radec(self): return self._get("RADEC") 435 #def get_radec(self): return self._get("RADEC")
420 def get_radec(self)->tuple: return (self.get_ra(), self.get_dec()) 436 def get_radec(self)->tuple: return (self.get_ra(), self.get_dec())
421 -  
422 - def set_RADEC(self, radec): return self._set("RADEC", radec) 437 + def set_radec(self, ra, dec)->tuple: return (self.set_ra(ra), self.set_dec(dec))
423 438
424 #def set_TIMEZONE_IS_UTC(self): return self._set('TIMEZONE_IS_UTC') 439 #def set_TIMEZONE_IS_UTC(self): return self._set('TIMEZONE_IS_UTC')
425 def get_timezone(self): return self.execute_generic_cmd('get_timezone') 440 def get_timezone(self): return self.execute_generic_cmd('get_timezone')
sockets_tele/src_socket/client/socket_client_telescope_gemini.py
1 #!/usr/bin/env python3 1 #!/usr/bin/env python3
2 2
3 """Socket Client GEMINI Telescope implementation 3 """Socket Client GEMINI Telescope implementation
4 -  
5 To be used as a concrete class to system control a GEMINI telescope 4 To be used as a concrete class to system control a GEMINI telescope
6 """ 5 """
7 6
8 -  
9 # Standard library imports 7 # Standard library imports
10 #import socket 8 #import socket
11 #import logging 9 #import logging
@@ -20,7 +18,6 @@ sys.path.append('../..') @@ -20,7 +18,6 @@ sys.path.append('../..')
20 #from src.client.socket_client_telescope_abstract import Position, UnknownCommandException, TimeoutException, SocketClientTelescopeAbstract 18 #from src.client.socket_client_telescope_abstract import Position, UnknownCommandException, TimeoutException, SocketClientTelescopeAbstract
21 from src_socket.client.socket_client_telescope_abstract import * 19 from src_socket.client.socket_client_telescope_abstract import *
22 20
23 -  
24 # Default timeouts 21 # Default timeouts
25 TIMEOUT_SEND = 10 22 TIMEOUT_SEND = 10
26 TIMEOUT_RECEIVE = 10 23 TIMEOUT_RECEIVE = 10
@@ -55,95 +52,78 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract): @@ -55,95 +52,78 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract):
55 #data = " ".join(sys.argv[1:]) 52 #data = " ".join(sys.argv[1:])
56 #data_to_send = bytes(data + "\n", "utf-8") 53 #data_to_send = bytes(data + "\n", "utf-8")
57 54
58 -  
59 ''' Commands dictionary 55 ''' Commands dictionary
  56 + NEW foramt is:
  57 + 'generic-command-name': ['native-command-name', 'awaited_result_if_ok', 'other-awaited-results if not ok...],
  58 +
  59 + Old format was:
60 'CMD-NAME': ['cmd-get', 'awaited_res_ok_for_get', 'cmd-set', 'awaited_res_ok_for_set', 'comment'], 60 'CMD-NAME': ['cmd-get', 'awaited_res_ok_for_get', 'cmd-set', 'awaited_res_ok_for_set', 'comment'],
61 ''' 61 '''
62 -  
63 - # @override  
64 - _cmd = { 62 + # @overwrite
  63 + _cmd_native = {
65 # GET @ SET commands 64 # GET @ SET commands
66 'get_ack': [COMMAND6, 'G', 'B','b','S'], # B# while the initial startup message is being displayed (new in L4), b# while waiting for the selection of the Startup Mode, S# during a Cold Start (new in L4), G# after completed startup. 65 'get_ack': [COMMAND6, 'G', 'B','b','S'], # B# while the initial startup message is being displayed (new in L4), b# while waiting for the selection of the Startup Mode, S# during a Cold Start (new in L4), G# after completed startup.
67 66
68 - 'get_ra': ['GR'],  
69 - 'set_ra': ['Sr'],  
70 -  
71 - 'get_dec': ['GD'],  
72 -  
73 - 'get_timezone': ['GG'],  
74 - 'set_timezone': ['SG', '1'],  
75 -  
76 -  
77 - # DO commands  
78 - 'do_move': [':MS#', '0', '1Object below horizon.#', '2No object selected.#', '3Manual Control.#', '4Position unreachable.#', '5Not aligned.#', '6Outside Limits.#' ],  
79 - 'do_stop': [':Q#'],  
80 - 'do_init': ['do_init'],  
81 - }  
82 -  
83 - """  
84 - # @override  
85 - _cmd_getset = {  
86 -  
87 - 'ack': [COMMAND6, 'G'],  
88 -  
89 # RA-DEC (p109-110) 67 # RA-DEC (p109-110)
90 #:Sr<hh>:<mm>.<m># or :Sr<hh>:<mm>:<ss># 68 #:Sr<hh>:<mm>.<m># or :Sr<hh>:<mm>:<ss>#
91 #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
92 #:Sd{+-}<dd>{*°}<mm># or :Sd{+- }<dd>{*°:}<mm>:<ss> 70 #:Sd{+-}<dd>{*°}<mm># or :Sd{+- }<dd>{*°:}<mm>:<ss>
93 #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"
94 - 'ra': ['GR', None, 'Sr', None, 'commentaire'],  
95 - 'dec': ['GD', None, 'Sd'],  
96 #'RADEC': [('GR','GD'), ''], 72 #'RADEC': [('GR','GD'), ''],
  73 + #'ra': ['GR', None, 'Sr', None, 'commentaire'],
  74 + 'get_ra': ['GR'],
  75 + 'set_ra': ['Sr'],
  76 + 'get_dec': ['GD'],
  77 + 'set_dec': ['Sd'],
  78 + # get_radec and set_radec are already defined in abstract class
  79 +
  80 + 'get_timezone': ['GG'],
  81 + 'set_timezone': ['SG', '1'],
97 82
98 # ALT-AZ (p?) 83 # ALT-AZ (p?)
99 - "ALT": ['GA'],  
100 - "AZ": ['GZ'], 84 + "get_alt": ['GA'],
  85 + "get_az": ['GZ'],
101 #"ALT-AZ": [('GA','GZ'), ''], 86 #"ALT-AZ": [('GA','GZ'), ''],
102 87
103 # LONG-LAT 88 # LONG-LAT
104 - "LONGITUDE": ['Gg', None, 'Sg'],  
105 - "LATITUDE": ['Gt', None, 'St'], 89 + "get_long": ['Gg'],
  90 + "set_long": ['Sg'],
  91 + "get_lat": ['Gt'],
  92 + "set_lat": ['St'],
106 #"LONGLAT": [('Gg','Gt'), ''], 93 #"LONGLAT": [('Gg','Gt'), ''],
107 94
108 - "hour-angle": ['GH'], 95 + "get_hangle": ['GH'],
109 96
110 - "max-vel": ['Gv'], 97 + 'get_vel': ['Gv'],
  98 + #"get_maxvel": ['Gv'],
111 99
112 - 'timezone': ['GG', None, 'SG', '1'],  
113 - 'DATE': ['GC', None, 'SC'],  
114 - 'TIME': ['GL', None, 'SL'],  
115 -  
116 - 'VELOCITY': ['Gv'],  
117 -  
118 - 100 + 'get_date': ['GC'],
  101 + 'set_date': ['SC'],
  102 + 'get_time': ['GL'],
  103 + 'set_time': ['SL'],
119 104
  105 + # DO commands
  106 + # defined in abstract class:
  107 + #'do_init': ['do_init'],
  108 + 'do_park': ['hP'],
  109 + 'do_warm_start': ['bW'],
  110 + 'do_prec_refr': ['p3'],
  111 + 'do_move': ['MS', '0', '1Object below horizon.', '2No object selected.', '3Manual Control.', '4Position unreachable.', '5Not aligned.', '6Outside Limits.' ],
  112 + 'do_movenorth': ['Mn'],
  113 + 'do_movesouth': ['Ms'],
  114 + 'do_movewest': ['Mw'],
  115 + 'do_moveeast': ['Me'],
  116 + 'do_stop': ['Q'],
120 } 117 }
121 - ''' Commands dictionary  
122 - 'CMD-NAME': ['cmd-do', 'comment'],  
123 - '''  
124 - # @override  
125 - _cmd_do = {  
126 - #'INIT': [],  
127 - 'PARK': ['hP'],  
128 - 'WARM_START': ['bW'],  
129 - 'PREC_REFR': ['p3'],  
130 - 'MOVE': ['MS'],  
131 - 'MOVE_NORTH': ['Mn'],  
132 - 'MOVE_SOUTH': ['Ms'],  
133 - 'MOVE_WEST': ['Mw'],  
134 - 'MOVE_EAST': ['Me'],  
135 - 'STOP': ['Q'],  
136 - }  
137 - """  
138 118
139 119
140 - # @override 120 + # @overwrite
141 # GEMINI is using UDP 121 # GEMINI is using UDP
142 def __init__(self, server_host:str="localhost", server_port:int=11110, DEBUG=False): 122 def __init__(self, server_host:str="localhost", server_port:int=11110, DEBUG=False):
143 super().__init__(server_host, server_port, "UDP", 1024, DEBUG) 123 super().__init__(server_host, server_port, "UDP", 1024, DEBUG)
144 124
145 125
146 - # @override 126 + # @overwrite
147 def formated_cmd(self, cmd:str, values_to_set:str=None)->str: 127 def formated_cmd(self, cmd:str, values_to_set:str=None)->str:
148 if values_to_set != None: 128 if values_to_set != None:
149 for value_to_set in values_to_set: 129 for value_to_set in values_to_set:
@@ -158,7 +138,7 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract): @@ -158,7 +138,7 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract):
158 return getattr(self, func)(arg) 138 return getattr(self, func)(arg)
159 139
160 140
161 - # @override 141 + # @overwrite
162 def _encapsulate_data_to_send(self, command:str): 142 def _encapsulate_data_to_send(self, command:str):
163 r''' Encapsulate useful data to be ready for sending 143 r''' Encapsulate useful data to be ready for sending
164 144
@@ -207,7 +187,7 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract): @@ -207,7 +187,7 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract):
207 #return bytes(data + "\n", "utf-8") 187 #return bytes(data + "\n", "utf-8")
208 ####return bytes(self.MYSTAMP + self.STAMP_FILLER + data + "\n", "utf-8") 188 ####return bytes(self.MYSTAMP + self.STAMP_FILLER + data + "\n", "utf-8")
209 189
210 - # @override 190 + # @overwrite
211 def _uncap_received_data(self, data_received_bytes:bytes)->str: 191 def _uncap_received_data(self, data_received_bytes:bytes)->str:
212 r""" 192 r"""
213 Extract useful data from received raw data 193 Extract useful data from received raw data
@@ -256,25 +236,6 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract): @@ -256,25 +236,6 @@ class SocketClientTelescopeGEMINI(SocketClientTelescopeAbstract):
256 if not native_cmd: raise UnknownCommandException(speed_rate) 236 if not native_cmd: raise UnknownCommandException(speed_rate)
257 return self.execute_unformated_native_cmd(native_cmd) 237 return self.execute_unformated_native_cmd(native_cmd)
258 238
259 - '''  
260 - def do_MOVE_NORTH(self): return self.execute_native_cmd_OLD(':Mn#')  
261 - def do_MOVE_SOUTH(self): return self.execute_native_cmd_OLD(':Ms#')  
262 - def do_MOVE_WEST(self): return self.execute_native_cmd_OLD(':Mw#')  
263 - def do_MOVE_EAST(self): return self.execute_native_cmd_OLD(':Me#')  
264 - '''  
265 -  
266 - '''  
267 - TELESCOPE COMMANDS implementation  
268 - '''  
269 -  
270 - '''  
271 - The 3 main generic commands : get(), set(), do()  
272 - '''  
273 - ''' 1) GET methods '''  
274 - ''' 2) SET methods '''  
275 - ''' 3) DO methods '''  
276 - ''' SPECIFIC methods '''  
277 -  
278 239
279 if __name__ == "__main__": 240 if __name__ == "__main__":
280 241
@@ -315,4 +276,4 @@ if __name__ == &quot;__main__&quot;: @@ -315,4 +276,4 @@ if __name__ == &quot;__main__&quot;:
315 #print("Useful data received: {}".format(data_useful)) 276 #print("Useful data received: {}".format(data_useful))
316 print('\n') 277 print('\n')
317 278
318 - #tele_client.close() 279 - #tele_client.close()
  280 + #tele_client.close()
319 \ No newline at end of file 281 \ No newline at end of file