Blame view

src/device_controller/channels/client_channel.py 4.24 KB
ac0e5c70   Etienne Pallier   nouveau devices_c...
1
2
3
4
5
6
7
8
9
#!/usr/bin/env python3

"""Socket Client (abstract)

To be used as a base class (interface) for any concrete socket client class
"""


# Standard library imports
1cf4a67f   Etienne Pallier   Affichage console...
10
import os
ac0e5c70   Etienne Pallier   nouveau devices_c...
11
12
13
14
15

# Third party imports
# None

# Local application imports
ce74dbbb   Etienne Pallier   LOGGER unique : p...
16
from src.logpyros import LogPyros
db68c03d   Etienne Pallier   Supprimé les 3 an...
17
##from device_controller.logs import *
ac0e5c70   Etienne Pallier   nouveau devices_c...
18
19


ce74dbbb   Etienne Pallier   LOGGER unique : p...
20
'''
1cf4a67f   Etienne Pallier   Affichage console...
21
22
def printd(*args, **kwargs):
    if os.environ.get('PYROS_DEBUG', '0')=='1': print(*args, **kwargs)
ce74dbbb   Etienne Pallier   LOGGER unique : p...
23
'''
1cf4a67f   Etienne Pallier   Affichage console...
24

0538ed53   Etienne Pallier   cleanup
25
26
class ChannelCommunicationException(Exception):
    pass
ac0e5c70   Etienne Pallier   nouveau devices_c...
27
28
29

##class SocketClientAbstract():
class ClientChannel():
ce74dbbb   Etienne Pallier   LOGGER unique : p...
30

ac0e5c70   Etienne Pallier   nouveau devices_c...
31
32
    my_channel = None
    buf = 1024
ce74dbbb   Etienne Pallier   LOGGER unique : p...
33
34
35

    #def __init__(self, server_host:str="localhost", server_port:int=11110, PROTOCOL:str="SOCKET-TCP", buffer_size=1024, DEBUG=False):
    def __init__(self, server_host:str="localhost", server_port:int=11110, PROTOCOL:str="SOCKET-TCP", buffer_size=1024):
ac0e5c70   Etienne Pallier   nouveau devices_c...
36
37
38
39
40
        '''
        :param server_host: server IP or hostname
        :param server_port: server port
        :param PROTOCOL: "SOCKET-TCP" or "SOCKET-UDP" or "SERIAL" or "USB" (to be continued...)
        '''
ce74dbbb   Etienne Pallier   LOGGER unique : p...
41
        self.DEBUG_MODE = os.environ.get('PYROS_DEBUG', '0') == '1'
ac0e5c70   Etienne Pallier   nouveau devices_c...
42
43
44
45
        self.HOST = server_host
        self.PORT = server_port
        self.PROTOCOL = PROTOCOL
        self.buf = buffer_size
ce74dbbb   Etienne Pallier   LOGGER unique : p...
46

3edb50a6   Etienne Pallier   bugfix simulateur...
47
        self.log = LogPyros(self.__class__.__name__)
ce74dbbb   Etienne Pallier   LOGGER unique : p...
48

ac0e5c70   Etienne Pallier   nouveau devices_c...
49
50
51
        # Logger configuration
        #self.set_logger()
        ##set_logger(DEBUG)
ce74dbbb   Etienne Pallier   LOGGER unique : p...
52
        self.printd("\n**************************")
1cf4a67f   Etienne Pallier   Affichage console...
53
        ##log_d("Client CHANNEL instanciated")
ce74dbbb   Etienne Pallier   LOGGER unique : p...
54
55
56
        self.printd("Client CHANNEL instanciated")


ac0e5c70   Etienne Pallier   nouveau devices_c...
57
58
59
60
61
    # So that we can use this with the "with" statement (context manager)
    def __enter__(self):
        return self
    def __exit__(self, type, value, traceback):
        self.close()
1cf4a67f   Etienne Pallier   Affichage console...
62
        #printd("Client channel killed")
ac0e5c70   Etienne Pallier   nouveau devices_c...
63
64
        print("Client channel killed")

ce74dbbb   Etienne Pallier   LOGGER unique : p...
65
    # LOG methods
3edb50a6   Etienne Pallier   bugfix simulateur...
66
67
    def print(self, *args, **kwargs): self.log.print(*args, **kwargs)
    def printd(self, *args, **kwargs): self.log.printd(*args, **kwargs)
ce74dbbb   Etienne Pallier   LOGGER unique : p...
68

ac0e5c70   Etienne Pallier   nouveau devices_c...
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

    def send_data(self, data:str):
        ##data_encapsulated = self.encapsulate_data_to_send(data)
        self._send_data(data)
        '''
        #data_to_send = bytes(data_to_send + "\n", "utf-8")
        #data_to_send = bytes(data_to_send + "\x00", "utf-8")
        ##data_to_send = bytes(data_to_send, "utf-8")
        data_to_send_bytes = data_to_send.encode("utf-8")
        #data_to_send_bytes = data_to_send.encode()
        if self.PROTOCOL=="SOCKET-TCP": 
            # Unlike send(), this method sendall() continues to send data from bytes until either all data has been sent or an error occurs. 
            # None is returned on success. 
            # On error, an exception is raised, and there is no way to determine how much data, if any, was successfully sent
            nb_bytes_sent = self.mysock.sendall(data_to_send_bytes)
        else: 
            # SOCKET-UDP
            nb_bytes_sent = self.mysock.sendto(data_to_send_bytes, (self.HOST, self.PORT))
        log_i(f'Sent: {data_to_send_bytes}')
        log_i(f"Sent {nb_bytes_sent} bytes")
        '''
    #@abstract
    def _send_data(self, data_to_send:str):
        pass

    def receive_data(self)->str:
        data_received = self._receive_data()
        ##data_received_bytes = self.mysock.recv(self.buf)
1cf4a67f   Etienne Pallier   Affichage console...
97
98
        #printd("Received (all data): {}".format(data_received))
        #printd("data in bytes: "+str(bytes(data_received, "utf-8")))
ac0e5c70   Etienne Pallier   nouveau devices_c...
99
100
101
102
103
104
105
106
        ##data_received_uncaped = self.uncap_received_data(data_received)
        #log_i("RECEIVED (useful data): {}".format(data_received))
        return data_received
    #@abstract
    def _receive_data(self)->bytes:
        pass
        '''
        data_received = self.mysock.recv(self.buf)
1cf4a67f   Etienne Pallier   Affichage console...
107
        #printd("data type is "+str(type(data_received)))
ac0e5c70   Etienne Pallier   nouveau devices_c...
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
        log_i(f"RECEIVED (ALL BYTES): {data_received}") 
        #return str(data_received, "utf-8")
        return data_received
        '''

    #@abstract
    def _connect_to_server(self):
        pass
    
    # Close socket
    def close(self):
        self.mysock.close()
        

    '''
    put(), read(), put_read() commands
    '''
    def put(self, data:str):
        self.send_data(data)
    def read(self)->str:
        return self.receive_data()
    def put_read(self, data:str)->str:
        # send command
        self.put(data)
        # receive answer (or ack)
        return self.read()