Blame view

src/device_controller/concrete_component/gemini/gemini_controller.py 19.4 KB
ac0e5c70   Etienne Pallier   nouveau devices_c...
1
2
#!/usr/bin/env python3

9ee212a8   Etienne Pallier   Renommage des fic...
3
4
"""Socket Client Gemini Telescope implementation
To be used as a concrete class to system control a Gemini telescope
ac0e5c70   Etienne Pallier   nouveau devices_c...
5
6
7
8
9
"""

# Standard library imports
#import socket
#import logging
51c0662b   Etienne Pallier   Lecture du mode D...
10
import os
ac0e5c70   Etienne Pallier   nouveau devices_c...
11
12
13
14
15
16
17
import sys
import time

# Third party imports
# None

# Local application imports
b23417b8   Etienne Pallier   Restructuration d...
18
sys.path.append('../../..')
57621753   Etienne Pallier   NOUVELLE ARCHI un...
19
20

# My parent class and exceptions
1b4dae11   Etienne Pallier   Nouvelle classe (...
21
22
23
from device_controller.abstract_component.device_controller import (
    printd,
    DeviceController,
be14030d   Etienne Pallier   dataclass en comm...
24
25
    Gen2NatCmds, 
    #Cmd,
1b4dae11   Etienne Pallier   Nouvelle classe (...
26
27
    UnknownNativeCmdException, UnknownGenericCmdArgException
)
bcf29d0f   Etienne Pallier   update controller...
28

57621753   Etienne Pallier   NOUVELLE ARCHI un...
29
#from src.client.socket_client_telescope_abstract import Position, UnknownNativeCmdException, TimeoutException, SocketClientTelescopeAbstract
ac0e5c70   Etienne Pallier   nouveau devices_c...
30
##from src_socket.client.socket_client_telescope_abstract import *
7a7e30cc   Etienne Pallier   Chaque DeviceCont...
31

57621753   Etienne Pallier   NOUVELLE ARCHI un...
32
33
34
35
# My device controller component(s)
#from device_controller.abstract_component.mount import *
from device_controller.abstract_component.mount import DC_Mount

bcf29d0f   Etienne Pallier   update controller...
36
# My simulator
57621753   Etienne Pallier   NOUVELLE ARCHI un...
37
from device_controller.concrete_component.gemini.gemini_simulator import DS_Gemini
ac0e5c70   Etienne Pallier   nouveau devices_c...
38

bcf29d0f   Etienne Pallier   update controller...
39
'''
ac0e5c70   Etienne Pallier   nouveau devices_c...
40
41
42
# Default timeouts
TIMEOUT_SEND = 10
TIMEOUT_RECEIVE = 10
bcf29d0f   Etienne Pallier   update controller...
43
44
45
'''

MY_DEVICE_CHANNEL_BUFFER_SIZE = 1024
ac0e5c70   Etienne Pallier   nouveau devices_c...
46

57621753   Etienne Pallier   NOUVELLE ARCHI un...
47
''' Moved inside the Protocol class
ac0e5c70   Etienne Pallier   nouveau devices_c...
48
49
50
51
52
53
# COMMON CONSTANTS WITH SERVER
TERMINATOR = '\x00'
COMMAND5 = '050000'
#COMMAND6_SIMPLE = '\x00\x06'
COMMAND6 = '\x00\x06\x00'
COMMAND6_SIMPLE = '6'
57621753   Etienne Pallier   NOUVELLE ARCHI un...
54
'''
ac0e5c70   Etienne Pallier   nouveau devices_c...
55
56


51c0662b   Etienne Pallier   Lecture du mode D...
57
58
59
60
'''
def printd(*args, **kwargs):
    if os.environ.get('PYROS_DEBUG')=='1': print(*args, **kwargs)
'''
ac0e5c70   Etienne Pallier   nouveau devices_c...
61

68758b47   Etienne Pallier   On attaque Gemini...
62
63
64
65
class DC_MountBis(DC_Mount):
    pass


57621753   Etienne Pallier   NOUVELLE ARCHI un...
66
67
#class DeviceControllerTelescopeGemini(DC_Mount):
#class DC_Gemini(DC_Mount):
e0853b2e   Etienne Pallier   Bugfixes assert t...
68
class DC_Gemini(DeviceController):
ac0e5c70   Etienne Pallier   nouveau devices_c...
69

7a7e30cc   Etienne Pallier   Chaque DeviceCont...
70

57621753   Etienne Pallier   NOUVELLE ARCHI un...
71
72
73
74
    # Gemini communication protocol
    # @override
    class Protocol:

bcf29d0f   Etienne Pallier   update controller...
75
76
77
78
        # Default timeouts
        TIMEOUT_SEND = 10
        TIMEOUT_RECEIVE = 10

57621753   Etienne Pallier   NOUVELLE ARCHI un...
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
        # COMMON CONSTANTS WITH SERVER
        TERMINATOR = '\x00'
        COMMAND5 = '050000'
        #COMMAND6_SIMPLE = '\x00\x06'
        COMMAND6 = '\x00\x06\x00'
        COMMAND6_SIMPLE = '6'

        # 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
bcf29d0f   Etienne Pallier   update controller...
98
99
        STAMP_LENGTH = 8
        STAMP_FILLER = '0' * (STAMP_LENGTH - request_num_nb_digits)
57621753   Etienne Pallier   NOUVELLE ARCHI un...
100
101
102
103
104
105
106
107

        # @override
        @classmethod
        def formated_cmd(cls, cmd:str, values_to_set:str=None)->str:
            if values_to_set != None: 
                for value_to_set in values_to_set:
                    cmd += value_to_set
            if cmd not in (cls.COMMAND6, cls.COMMAND5):
245d927b   Etienne Pallier   Commandes de type...
108
                cmd += '#'
57621753   Etienne Pallier   NOUVELLE ARCHI un...
109
110
111
112
113
114
115
116
117
118
                if cmd not in ('bC#','bW#','bR#'): 
                    cmd=':'+cmd
            return cmd

        # @override
        #def encapsulate_data_to_send(self, command:str):
        #def encap_data_to_send(self, command:str):
        @classmethod
        def encap(cls, command:str):
            r''' Encapsulate useful data to be ready for sending
6e7269c4   Etienne Pallier   bugfix gemini test
119

57621753   Etienne Pallier   NOUVELLE ARCHI un...
120
121
            If data is "complete" (with stamp, and well formatted), send it as is
            Otherwise, add stamp and format it
6e7269c4   Etienne Pallier   bugfix gemini test
122

57621753   Etienne Pallier   NOUVELLE ARCHI un...
123
124
125
126
            3 types of commands:
            - TYPE1: '06' or '050000'
            - TYPE2: ':cde#' (mainly ':??#' - i.e : ':GD#', ':GR#', ...)
            - TYPE3: 'b?#' (bC# = Cold Start, bW# = selecting Warm Start, bR# = selecting Warm Restart)
6e7269c4   Etienne Pallier   bugfix gemini test
127

57621753   Etienne Pallier   NOUVELLE ARCHI un...
128
            :Examples:
6e7269c4   Etienne Pallier   bugfix gemini test
129
            >>> tele = DC_Gemini("localhost", 11110)
57621753   Etienne Pallier   NOUVELLE ARCHI un...
130
131
            Starting device simulator on (host:port):  localhost:11110
            >>> tele.encap(':GD#')
6e7269c4   Etienne Pallier   bugfix gemini test
132
            ('00010000', '00010000:GD#\x00')
57621753   Etienne Pallier   NOUVELLE ARCHI un...
133
            >>> tele.encap(':GR#')
6e7269c4   Etienne Pallier   bugfix gemini test
134
            ('00020000', '00020000:GR#\x00')
57621753   Etienne Pallier   NOUVELLE ARCHI un...
135
            >>> tele.close()
6e7269c4   Etienne Pallier   bugfix gemini test
136

57621753   Etienne Pallier   NOUVELLE ARCHI un...
137
138
            # ne marche pas => '00010000:GD#\x00'
            '''
6e7269c4   Etienne Pallier   bugfix gemini test
139

57621753   Etienne Pallier   NOUVELLE ARCHI un...
140
141
142
            ####return bytes(self.MYSTAMP + self.STAMP_FILLER + data + "\n", "utf-8")
            
            # TYPE1
51c0662b   Etienne Pallier   Lecture du mode D...
143
            #printd("command to encapsulate is", repr(command))
57621753   Etienne Pallier   NOUVELLE ARCHI un...
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
            
            if command == cls.COMMAND6_SIMPLE: command = cls.COMMAND6
            
            if command not in (cls.COMMAND6, cls.COMMAND5):
                # TYPE2 or 3
                #has_starting_car = data.find(':') > -1
                if len(command) < 3: raise UnknownNativeCmdException(command)
                if not (command[-1]=='#'): raise UnknownNativeCmdException(command)
                if not (command[0]==':') and command not in ('bC#','bW#','bR#'): raise UnknownNativeCmdException(command)
                #stamp,command = data.split(':',1)
            
            #if command.find('#')>-1: command,_ = command.split('#',1)
            cls.request_num += 1
            # Format to request_num_nb_digits (4) digits
            request_num_str = cls.request_num_format.format(cls.request_num)
            cls.last_stamp = request_num_str + cls.STAMP_FILLER
            
            #if command == COMMAND6_SIMPLE: command = COMMAND6_REAL
            data_encapsulated = cls.last_stamp + command + cls.TERMINATOR
            #return super().encap(data_encapsulated)
            #return self._my_channel.encap(data_encapsulated)
bcf29d0f   Etienne Pallier   update controller...
165
166
            #return data_encapsulated
            return cls.last_stamp, data_encapsulated
57621753   Etienne Pallier   NOUVELLE ARCHI un...
167
168
169
    
            #return bytes(data + "\n", "utf-8")
            ####return bytes(self.MYSTAMP + self.STAMP_FILLER + data + "\n", "utf-8")
ac0e5c70   Etienne Pallier   nouveau devices_c...
170
    
57621753   Etienne Pallier   NOUVELLE ARCHI un...
171
172
        # @override
        #def uncap_received_data(self, data_received:str)->str:
bcf29d0f   Etienne Pallier   update controller...
173
        #def uncap(cls, data_received:str)->str:
57621753   Etienne Pallier   NOUVELLE ARCHI un...
174
        @classmethod
bcf29d0f   Etienne Pallier   update controller...
175
        def uncap(cls, dcc_name:str, stamp:str, data_received:str)->str:
57621753   Etienne Pallier   NOUVELLE ARCHI un...
176
177
178
179
180
181
182
183
            #data_received = super().uncap(data_received_bytes)
            ##data_received = self._my_channel.uncap(data_received_bytes)
    
            #>>> tele.uncap(b'001700001\x00')
    
            r"""
                Extract useful data from received raw data 
    
6e7269c4   Etienne Pallier   bugfix gemini test
184
            >>> tele = DC_Gemini("localhost", 11110)
57621753   Etienne Pallier   NOUVELLE ARCHI un...
185
186
            Starting device simulator on (host:port):  localhost:11110
            >>> tele.last_stamp = '00170000'
6e7269c4   Etienne Pallier   bugfix gemini test
187
            >>> tele.uncap('00170000', '001700001#')
57621753   Etienne Pallier   NOUVELLE ARCHI un...
188
189
190
            '1'
            >>> tele.close()
            """
bcf29d0f   Etienne Pallier   update controller...
191

51c0662b   Etienne Pallier   Lecture du mode D...
192
193
194
            printd("\n*********** DEBUG IS ON ***********\n")
            printd(f"(gemini protoc used from {dcc_name}) data_received_bytes type is", type(data_received))
            printd(f"(gemini protoc used from {dcc_name}) data received is", data_received)
57621753   Etienne Pallier   NOUVELLE ARCHI un...
195
            ##data_received = data_received_bytes.decode()
51c0662b   Etienne Pallier   Lecture du mode D...
196
            #printd("data_received is", data_received)
57621753   Etienne Pallier   NOUVELLE ARCHI un...
197
198
            # Remove STAMP (and \n at the end):
            #useful_data = data_received.split(self.MY_FULL_STAMP)[1][:-1]
bcf29d0f   Etienne Pallier   update controller...
199
            #useful_data = data_received.split(cls.last_stamp)[1][:-1]
51c0662b   Etienne Pallier   Lecture du mode D...
200
            printd(f"*** (gemini protoc used from {dcc_name}) Last stamp is ***", cls.last_stamp, ", data received is", data_received)
bcf29d0f   Etienne Pallier   update controller...
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
            '''
            # Normal case: LAST stamp found
            if cls.last_stamp in data_received:
                useful_data = data_received.split(cls.last_stamp)[1][:-1]
            # Bad case: LAST stamp NOT found => try PREVIOUS stamp
            else:
                request_num_str = cls.request_num_format.format(cls.request_num-1)
                temp_last_stamp = request_num_str + cls.STAMP_FILLER
                if temp_last_stamp in data_received:
                    useful_data = data_received.split(temp_last_stamp)[1][:-1]
                else:
                    raise Exception("BAD STAMP")
            '''
            if stamp not in data_received:
                    raise Exception("BAD STAMP, this is not the answer to my request, but another request's")
            else:
                useful_data = data_received.split(stamp)[1][:-1]
57621753   Etienne Pallier   NOUVELLE ARCHI un...
218
219
220
221
222
223
224
225
226
            # Remove '#' at the end, if exists
            if useful_data[-1] == '#': useful_data = useful_data[:-1]
            return useful_data

        # end of class Protocol




ac0e5c70   Etienne Pallier   nouveau devices_c...
227
228
229
230
    #data = " ".join(sys.argv[1:])
    #data_to_send = bytes(data + "\n", "utf-8")

    ''' Commands dictionary
ac0e5c70   Etienne Pallier   nouveau devices_c...
231
    '''
d20a7876   Etienne Pallier   Nouveau format de...
232

1b4dae11   Etienne Pallier   Nouvelle classe (...
233
    #
d20a7876   Etienne Pallier   Nouveau format de...
234
    # VERSION 1 : 1 gros dictionnaire par commande
1b4dae11   Etienne Pallier   Nouvelle classe (...
235
236
237
    # CON : long et error prone
    #

d20a7876   Etienne Pallier   Nouveau format de...
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
    get_ack = {
        'generic_name': 'get_ack',
        'native_name': Protocol.COMMAND6,
        'params': {},
        # ready
        'final_device_responses': {
            'G' : 'after completed startup',
            '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)',
        },
        'final_simul_response': 'G',
        'immediate_response': {
            'ready' : 'gg',
            'wait' : 10,
            'error' : '',
        },
        # native error codes
        'errors': {
            '0' : 'pb 0 ...',
            '1' : 'pb 1 ...',
        }
    }
aea9578a   Etienne Pallier   merge de install....
261
    get_ra = {
d20a7876   Etienne Pallier   Nouveau format de...
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
        'generic_name': 'set_ra',
        'native_name': 'GR',
        'params': {'ra':'', },
        # ready
        'final_device_responses': [],
        'final_simul_response': '15:01:49',
        'immediate_response': {
            'ready' : 'gg',
            'wait' : 10,
            'error' : '',
        },
        # native error codes
        'errors': {
            '0' : 'pb 0 ...',
            '1' : 'pb 1 ...',
        }
    }

1b4dae11   Etienne Pallier   Nouvelle classe (...
280
    #
d20a7876   Etienne Pallier   Nouveau format de...
281
    # VERSION 2 : on utilise la methode build_cmd() en précisant key=val à chaque paramètre (sauf les paramètres vides, par défaut)
1b4dae11   Etienne Pallier   Nouvelle classe (...
282
283
284
    # PRO: court, pas d'erreur possible
    # CON: appel de fonction

d20a7876   Etienne Pallier   Nouveau format de...
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
    mes_commandes = Gen2NatCmds({})
    get_ack = mes_commandes.build_cmd(
        generic_name = 'get_ack', 
        native_name = Protocol.COMMAND6,
        #params = {},
        final_device_responses={
            'G': 'after completed startup',
            '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)',
        },
        final_simul_response='G',
        immediate_responses={
            'ready': 'gg',
            'wait': 10,
            'error': '',
        },
        errors = {
            '0': 'pb 0 ...',
            '1': 'pb 1 ...',
        }
    )
    mes_commandes.add_cmd(get_ack)

1b4dae11   Etienne Pallier   Nouvelle classe (...
309
    #
d20a7876   Etienne Pallier   Nouveau format de...
310
    # VERSION 3 (+court): on utilise la methode build_cmd() SANS préciser le nom des param => il faut alors les rentrer TOUS
1b4dae11   Etienne Pallier   Nouvelle classe (...
311
312
    #

d20a7876   Etienne Pallier   Nouveau format de...
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
    get_ack = mes_commandes.build_cmd(
        'get_ack', 
        Protocol.COMMAND6,
        {},
        {
            'G' : 'after completed startup',
            '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', 
        {
            'ready' : 'gg',
            'wait' : 10,
            'error' : '',
        },
        {
            '0' : 'pb 0 ...',
            '1' : 'pb 1 ...',
        }
    )
1b4dae11   Etienne Pallier   Nouvelle classe (...
334

d20a7876   Etienne Pallier   Nouveau format de...
335
336
337
    # Commande vide
    cmd2 = mes_commandes.build_cmd('cmd2_generic', 'cmd2_native')

1b4dae11   Etienne Pallier   Nouvelle classe (...
338
339
340
341
    #
    # OPTIMISATION possible pour les commandes get et set : 
    # on construit les 2 en même temps, et ca génère 2 commandes différentes (un get et un set)
    #
d20a7876   Etienne Pallier   Nouveau format de...
342
343
344
345
    get_dec, set_dec = mes_commandes.build_cmd_get_set(generic_name='dec', native_get_name='GD', native_set_name='Sd')
    do_init = mes_commandes.build_cmd_do('do_init', 'titi')


1b4dae11   Etienne Pallier   Nouvelle classe (...
346
347
348
    #
    # VERSION 4 : Command class (Cmd)
    #
be14030d   Etienne Pallier   dataclass en comm...
349
    '''
1b4dae11   Etienne Pallier   Nouvelle classe (...
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
    get_ack2 = Cmd(
        #generic_name = 
        'get_ack2', 
        #native_name = 
        Protocol.COMMAND6,
        {},
        {
            'G' : 'after completed startup',
            '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', 
        {
            'ready' : 'gg',
            'wait' : 10,
            'error' : '',
        },
        {
            '0' : 'pb 0 ...',
            '1' : 'pb 1 ...',
        }
    )
be14030d   Etienne Pallier   dataclass en comm...
373
    '''
1b4dae11   Etienne Pallier   Nouvelle classe (...
374

d20a7876   Etienne Pallier   Nouveau format de...
375

1b4dae11   Etienne Pallier   Nouvelle classe (...
376
    # Utilisation, affichage
d20a7876   Etienne Pallier   Nouveau format de...
377
    mes_commandes.add_cmd(get_ack)
be14030d   Etienne Pallier   dataclass en comm...
378
    #mes_commandes.add_cmd2(get_ack2)
d20a7876   Etienne Pallier   Nouveau format de...
379
380
381
382
383
384
385
386
    mes_commandes.add_cmd(cmd2)
    mes_commandes.add_cmd(set_ra)

    print("******************************")
    print("Mes commandes")
    mes_commandes.print_mes_commandes()
    print("******************************")

ed7f9eb6   Etienne Pallier   update sbig_contr...
387
    GEN2NAT_CMDS_GENERAL = {
bcf29d0f   Etienne Pallier   update controller...
388
389
390
391

        # Possible answers:
        # - B# while the initial startup message is being displayed (new in L4),
        # - b# while waiting for the selection of the Startup Mode,
f098fd90   Etienne Pallier   bugfix client et ...
392
393
        # - S# during a Cold Start (new in L4),
        # - G# after completed startup
06d39216   Etienne Pallier   Simulateur donne ...
394
        'get_ack': [Protocol.COMMAND6, 'G', ['G', 'B','b','S']],
bcf29d0f   Etienne Pallier   update controller...
395
396

        # General commands for the Gemini controller
06d39216   Etienne Pallier   Simulateur donne ...
397
        'get_date': ['GC', '10/10/19'],
bcf29d0f   Etienne Pallier   update controller...
398
        'set_date': ['SC'],
06d39216   Etienne Pallier   Simulateur donne ...
399
        'get_time': ['GL', '10:20:36'],
bcf29d0f   Etienne Pallier   update controller...
400
        'set_time': ['SL'],
f098fd90   Etienne Pallier   bugfix client et ...
401
    }
ed7f9eb6   Etienne Pallier   update sbig_contr...
402
    GEN2NAT_CMDS_MOUNT = {
ac0e5c70   Etienne Pallier   nouveau devices_c...
403

57621753   Etienne Pallier   NOUVELLE ARCHI un...
404
        # GET & SET commands
57621753   Etienne Pallier   NOUVELLE ARCHI un...
405
406

        # RA-DEC (p109-110)
ac0e5c70   Etienne Pallier   nouveau devices_c...
407
408
409
410
411
412
        #:Sr<hh>:<mm>.<m># or :Sr<hh>:<mm>:<ss>#
        #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
        #:Sd{+-}<dd>{*°}<mm># or :Sd{+- }<dd>{*°:}<mm>:<ss>
        #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"
        #'RADEC': [('GR','GD'), ''],
        #'ra': ['GR', None, 'Sr', None, 'commentaire'],
aea9578a   Etienne Pallier   merge de install....
413
        ##get_ra.,
06d39216   Etienne Pallier   Simulateur donne ...
414
        'get_ra': ['GR', '15:01:49'],
ac0e5c70   Etienne Pallier   nouveau devices_c...
415
        'set_ra': ['Sr'],
06d39216   Etienne Pallier   Simulateur donne ...
416
        'get_dec': ['GD', '+12:29'],
ac0e5c70   Etienne Pallier   nouveau devices_c...
417
418
        'set_dec': ['Sd'],
        # get_radec and set_radec are already defined in abstract class
57621753   Etienne Pallier   NOUVELLE ARCHI un...
419

06d39216   Etienne Pallier   Simulateur donne ...
420
        'get_timezone': ['GG', "+00"],
ac0e5c70   Etienne Pallier   nouveau devices_c...
421
422
423
424
425
426
427
428
        'set_timezone': ['SG', '1'],

        # ALT-AZ (p?)
        "get_alt": ['GA'],
        "get_az": ['GZ'],
        #"ALT-AZ": [('GA','GZ'), ''],

        # LONG-LAT
06d39216   Etienne Pallier   Simulateur donne ...
429
        "get_long": ['Gg', '+10'],
ac0e5c70   Etienne Pallier   nouveau devices_c...
430
        "set_long": ['Sg'],
06d39216   Etienne Pallier   Simulateur donne ...
431
        "get_lat": ['Gt', '+45:00:00'],
ac0e5c70   Etienne Pallier   nouveau devices_c...
432
433
        "set_lat": ['St'],
        #"LONGLAT": [('Gg','Gt'), ''],
57621753   Etienne Pallier   NOUVELLE ARCHI un...
434

ac0e5c70   Etienne Pallier   nouveau devices_c...
435
436
        "get_hangle": ['GH'],

06d39216   Etienne Pallier   Simulateur donne ...
437
        'get_vel': ['Gv', 'T'],
ac0e5c70   Etienne Pallier   nouveau devices_c...
438
        #"get_maxvel": ['Gv'],
57621753   Etienne Pallier   NOUVELLE ARCHI un...
439

06d39216   Etienne Pallier   Simulateur donne ...
440
        
ac0e5c70   Etienne Pallier   nouveau devices_c...
441
442
443
444
445
446
        # DO commands
        # defined in abstract class:
        #'do_init': ['do_init'],
        'do_park': ['hP'],
        'do_warm_start': ['bW'],
        'do_prec_refr': ['p3'],
57621753   Etienne Pallier   NOUVELLE ARCHI un...
447
448

        # for test only
f098fd90   Etienne Pallier   bugfix client et ...
449
        'gem_only': [],
57621753   Etienne Pallier   NOUVELLE ARCHI un...
450

ac0e5c70   Etienne Pallier   nouveau devices_c...
451
452
453
454
455
456
457
        'do_move': ['MS', '0', '1Object below horizon.', '2No object selected.', '3Manual Control.', '4Position unreachable.', '5Not aligned.', '6Outside Limits.' ],    
        'do_movenorth': ['Mn'],
        'do_movesouth': ['Ms'],
        'do_movewest': ['Mw'],
        'do_moveeast': ['Me'],
        'do_stop': ['Q'],
    }
ed7f9eb6   Etienne Pallier   update sbig_contr...
458
    GEN2NAT_CMDS = {
bcf29d0f   Etienne Pallier   update controller...
459
        # My GENERAL commands
ed7f9eb6   Etienne Pallier   update sbig_contr...
460
        **GEN2NAT_CMDS_GENERAL,
ac0e5c70   Etienne Pallier   nouveau devices_c...
461

bcf29d0f   Etienne Pallier   update controller...
462
        # SPECIFIC commands for my DCCs
ed7f9eb6   Etienne Pallier   update sbig_contr...
463
        'DC_Mount' : GEN2NAT_CMDS_MOUNT
57621753   Etienne Pallier   NOUVELLE ARCHI un...
464
    }
ac0e5c70   Etienne Pallier   nouveau devices_c...
465

ac0e5c70   Etienne Pallier   nouveau devices_c...
466

57621753   Etienne Pallier   NOUVELLE ARCHI un...
467
468
    # Gemini is using UDP
    #def __init__(self, device_host:str="localhost", device_port:int=11110, channel=socket, DEBUG=False):
e36f962e   Etienne Pallier   option "-d" (DEBU...
469
    #def __init__(self, device_host:str="localhost", device_port:int=11110, DEBUG=False):
ce74dbbb   Etienne Pallier   LOGGER unique : p...
470
471
    #def __init__(self, device_host:str="localhost", device_port:int=11110, dcc_list=[], DEBUG=False):
    def __init__(self, device_host:str="localhost", device_port:int=11110, dcc_list=[]):
57621753   Etienne Pallier   NOUVELLE ARCHI un...
472
        ##super().__init__(device_host, device_port, "SOCKET-UDP", 1024, DEBUG)
ce74dbbb   Etienne Pallier   LOGGER unique : p...
473
474
        #super().__init__(device_host, device_port, "SOCKET-UDP", MY_DEVICE_CHANNEL_BUFFER_SIZE, protoc=self.Protocol, gen2nat_cmds=self.GEN2NAT_CMDS, device_sim=DS_Gemini, DEBUG=DEBUG)
        super().__init__(device_host, device_port, "SOCKET-UDP", MY_DEVICE_CHANNEL_BUFFER_SIZE, protoc=self.Protocol, gen2nat_cmds=self.GEN2NAT_CMDS, device_sim=DS_Gemini)
bcf29d0f   Etienne Pallier   update controller...
475
476
477
478
479
480

        '''
        Initialize my dcc(s), passing them the SAME parameters as I use :
            - device_host, device_port,
            - self._my_channel (passed by superclass), MY_DEVICE_CHANNEL_BUFFER_SIZE, 
            - self.Protocol,
ed7f9eb6   Etienne Pallier   update sbig_contr...
481
            - self.GEN2NAT_CMDS (subset of my commands related to the dcc), 
bcf29d0f   Etienne Pallier   update controller...
482
483
484
            - NO SIMULATOR (because my dccs will use the same as me and I have already launched it),
            - DEBUG
        '''
e36f962e   Etienne Pallier   option "-d" (DEBU...
485
486
487
        # TODO: utiliser dcc_list
        # Default list of DCCs (if not given)
        if not dcc_list: dcc_list = [DC_Mount, DC_MountBis]
57621753   Etienne Pallier   NOUVELLE ARCHI un...
488
        # @override superclass empty list of dc components
57621753   Etienne Pallier   NOUVELLE ARCHI un...
489
490
        self.set_dc_components( 
            [
ed7f9eb6   Etienne Pallier   update sbig_contr...
491
                #DC_Mount(device_host, device_port, self._my_channel, 1024, protoc= self.Protocol, gen2nat_cmds= self.GEN2NAT_CMDS['DC_Mount'], device_sim=None, DEBUG=DEBUG),
ce74dbbb   Etienne Pallier   LOGGER unique : p...
492
493
                DC_Mount(device_host, device_port, self._my_channel, MY_DEVICE_CHANNEL_BUFFER_SIZE, protoc=self.Protocol, gen2nat_cmds=self.GEN2NAT_CMDS_MOUNT, device_sim=None),
                DC_MountBis(device_host, device_port, self._my_channel, MY_DEVICE_CHANNEL_BUFFER_SIZE, protoc=self.Protocol, gen2nat_cmds=self.GEN2NAT_CMDS_MOUNT, device_sim=None),
57621753   Etienne Pallier   NOUVELLE ARCHI un...
494
495
            ]
        )
ac0e5c70   Etienne Pallier   nouveau devices_c...
496

ac0e5c70   Etienne Pallier   nouveau devices_c...
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514


    # @overwrite
    #def get_ack(self): return self.execute_native_cmd(COMMAND6, 'G')
    #def do_warm_start(self): return self.execute_native_cmd('bW')

    #TODO: déplacer dans parent avec nouvelles commandes set_speed_slew, set_speed_average, ...
    # @override
    def set_speed(self, speed_rate):
        native_cmd = None
        # quick
        if speed_rate == "slew": native_cmd = 'RS'
        # average
        if speed_rate == "average": native_cmd = 'RM'
        # slow
        if speed_rate == "center": native_cmd = 'RC'
        # very slow
        if speed_rate == "guide": native_cmd = 'RG'
57621753   Etienne Pallier   NOUVELLE ARCHI un...
515
        if not native_cmd: raise UnknownGenericCmdArgException(__name__, speed_rate)
ac0e5c70   Etienne Pallier   nouveau devices_c...
516
517
518
519
520
521
522
523
524
525
        return self.execute_unformated_native_cmd(native_cmd)


if __name__ == "__main__":
    
    import doctest
    doctest.testmod()
    exit()
    """
    # Classic usage:
9ee212a8   Etienne Pallier   Renommage des fic...
526
    #tele_ctrl = SocketClient_Gemini(HOST, PORT)
ac0e5c70   Etienne Pallier   nouveau devices_c...
527
    # More elegant usage, using "with":
9ee212a8   Etienne Pallier   Renommage des fic...
528
529
    ##with SocketClientTelescopeGemini("localhost", 11110, DEBUG=False) as tele_ctrl:
    with TelescopeControllerGemini("localhost", 11110, DEBUG=False) as tele_ctrl:
ac0e5c70   Etienne Pallier   nouveau devices_c...
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
        
        # 0) CONNECT to server (only for TCP, does nothing for UDP)
        tele_ctrl._connect_to_server()
        
        #tele_ctrl.config()
        
        # Send some commands to the Telescope
        #pos = tele_ctrl.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")
            tele_ctrl.send_data(data)
            #mysock.sendto("%s" % data, (HOST, PORT))
51c0662b   Etienne Pallier   Lecture du mode D...
550
            #printd("Sent: {}".format(data))
ac0e5c70   Etienne Pallier   nouveau devices_c...
551
552
553
554
    
            # 2) RECEIVE REPLY data from server
            data_received = tele_ctrl.receive_data()
            #reponse, adr = mysock.recvfrom(buf)
51c0662b   Etienne Pallier   Lecture du mode D...
555
556
557
            #printd("Received: {}".format(data_received))
            #printd("Useful data received: {}".format(data_useful))
            printd('\n')
ac0e5c70   Etienne Pallier   nouveau devices_c...
558
559
560

        #tele_ctrl.close()
    """