syndesi 0.4.2__py3-none-any.whl → 0.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- syndesi/__init__.py +22 -2
- syndesi/adapters/adapter.py +332 -489
- syndesi/adapters/adapter_worker.py +820 -0
- syndesi/adapters/auto.py +58 -25
- syndesi/adapters/descriptors.py +38 -0
- syndesi/adapters/ip.py +203 -71
- syndesi/adapters/serialport.py +154 -25
- syndesi/adapters/stop_conditions.py +354 -0
- syndesi/adapters/timeout.py +58 -21
- syndesi/adapters/visa.py +236 -11
- syndesi/cli/console.py +51 -16
- syndesi/cli/shell.py +95 -47
- syndesi/cli/terminal_tools.py +8 -8
- syndesi/component.py +315 -0
- syndesi/protocols/delimited.py +92 -107
- syndesi/protocols/modbus.py +2368 -868
- syndesi/protocols/protocol.py +186 -33
- syndesi/protocols/raw.py +45 -62
- syndesi/protocols/scpi.py +65 -102
- syndesi/remote/remote.py +188 -0
- syndesi/scripts/syndesi.py +12 -2
- syndesi/tools/errors.py +49 -31
- syndesi/tools/log_settings.py +21 -8
- syndesi/tools/{log.py → logmanager.py} +24 -13
- syndesi/tools/types.py +9 -7
- syndesi/version.py +5 -1
- {syndesi-0.4.2.dist-info → syndesi-0.5.0.dist-info}/METADATA +1 -1
- syndesi-0.5.0.dist-info/RECORD +41 -0
- syndesi/adapters/backend/__init__.py +0 -0
- syndesi/adapters/backend/adapter_backend.py +0 -438
- syndesi/adapters/backend/adapter_manager.py +0 -48
- syndesi/adapters/backend/adapter_session.py +0 -346
- syndesi/adapters/backend/backend.py +0 -438
- syndesi/adapters/backend/backend_status.py +0 -0
- syndesi/adapters/backend/backend_tools.py +0 -66
- syndesi/adapters/backend/descriptors.py +0 -153
- syndesi/adapters/backend/ip_backend.py +0 -149
- syndesi/adapters/backend/serialport_backend.py +0 -241
- syndesi/adapters/backend/stop_condition_backend.py +0 -219
- syndesi/adapters/backend/timed_queue.py +0 -39
- syndesi/adapters/backend/timeout.py +0 -252
- syndesi/adapters/backend/visa_backend.py +0 -197
- syndesi/adapters/ip_server.py +0 -102
- syndesi/adapters/stop_condition.py +0 -90
- syndesi/cli/backend_console.py +0 -96
- syndesi/cli/backend_status.py +0 -274
- syndesi/cli/backend_wrapper.py +0 -61
- syndesi/scripts/syndesi_backend.py +0 -37
- syndesi/tools/backend_api.py +0 -175
- syndesi/tools/backend_logger.py +0 -64
- syndesi/tools/exceptions.py +0 -16
- syndesi/tools/internal.py +0 -0
- syndesi-0.4.2.dist-info/RECORD +0 -60
- {syndesi-0.4.2.dist-info → syndesi-0.5.0.dist-info}/WHEEL +0 -0
- {syndesi-0.4.2.dist-info → syndesi-0.5.0.dist-info}/entry_points.txt +0 -0
- {syndesi-0.4.2.dist-info → syndesi-0.5.0.dist-info}/licenses/LICENSE +0 -0
- {syndesi-0.4.2.dist-info → syndesi-0.5.0.dist-info}/top_level.txt +0 -0
syndesi/remote/remote.py
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
DEFAULT_REMOTE_PORT = 59677
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# Backend protocol format
|
|
5
|
+
# (action, arguments)
|
|
6
|
+
# If the command succeeds, it is returned as :
|
|
7
|
+
# (action, other arguments)
|
|
8
|
+
# If the command fails, it is returned as :
|
|
9
|
+
# (error, error_description)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# The backend links the client with an adapter when SELECT_ADAPTER is
|
|
13
|
+
# sent along with an adapter descriptor
|
|
14
|
+
|
|
15
|
+
EXTRA_BUFFER_RESPONSE_TIME = 1
|
|
16
|
+
|
|
17
|
+
# Delay to let the adapter connect
|
|
18
|
+
DEFAULT_ADAPTER_OPEN_TIMEOUT = 0.5
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# def add_backend_address_port_arguments(
|
|
22
|
+
# parser: argparse.ArgumentParser, client_side: bool
|
|
23
|
+
# ) -> None:
|
|
24
|
+
# """
|
|
25
|
+
# Add -a/--address and -p/--port to a given ArgumentParser. The description of -a/--address
|
|
26
|
+
# is different based on the value of client_side
|
|
27
|
+
# """
|
|
28
|
+
# if client_side:
|
|
29
|
+
# address_help = "Address of the backend"
|
|
30
|
+
# else:
|
|
31
|
+
# address_help = (
|
|
32
|
+
# "Backend listening address, set it to the host address used by clients"
|
|
33
|
+
# )
|
|
34
|
+
|
|
35
|
+
# parser.add_argument(
|
|
36
|
+
# "-a", "--address", type=str, default=LOCALHOST, help=address_help
|
|
37
|
+
# )
|
|
38
|
+
# parser.add_argument("-p", "--port", type=int, default=BACKEND_PORT)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# class Action(Enum):
|
|
42
|
+
# """
|
|
43
|
+
# Backend actions enum
|
|
44
|
+
# """
|
|
45
|
+
|
|
46
|
+
# # All adapters
|
|
47
|
+
# SELECT_ADAPTER = "select"
|
|
48
|
+
# OPEN = "open" # (descriptor,stop_condition) -> ()
|
|
49
|
+
# CLOSE = "close" # (descriptor,force) -> ()
|
|
50
|
+
# # FORCE_CLOSE = "force_close" # (descriptor,) -> ()
|
|
51
|
+
# WRITE = "write" # (descriptor,data) -> ()
|
|
52
|
+
# READ = "read" # (descriptor,full_output,temp_timeout,temp_stop_condition) -> (data,metrics)
|
|
53
|
+
# SET_STOP_CONDITIONS = "set_stop_condition" # (descriptor,stop_condition)
|
|
54
|
+
# FLUSHREAD = "flushread"
|
|
55
|
+
# START_READ = "start_read" # Start a read (descriptor,response_time)
|
|
56
|
+
# RESPONSE_TIMEOUT = "response_timeout"
|
|
57
|
+
|
|
58
|
+
# # Signal
|
|
59
|
+
# ADAPTER_SIGNAL = "adapter_signal"
|
|
60
|
+
|
|
61
|
+
# # Other
|
|
62
|
+
# SET_ROLE_ADAPTER = (
|
|
63
|
+
# "set_role_adapter" # Define the client as an adapter (exchange of data)
|
|
64
|
+
# )
|
|
65
|
+
# SET_ROLE_MONITORING = "set_role_monitoring" # The client queries for backend info
|
|
66
|
+
# SET_ROLE_LOGGER = "set_role_logger" # The client receives logs
|
|
67
|
+
# SET_LOG_LEVEL = "set_log_level"
|
|
68
|
+
# PING = "ping"
|
|
69
|
+
# STOP = "stop"
|
|
70
|
+
|
|
71
|
+
# # Backend debugger
|
|
72
|
+
# ENUMERATE_ADAPTER_CONNECTIONS = "enumerate_adapter_connections"
|
|
73
|
+
# ENUMERATE_MONITORING_CONNECTIONS = "enumerate_monitoring_connections"
|
|
74
|
+
# BACKEND_STATS = "backend_stats"
|
|
75
|
+
|
|
76
|
+
# # Errors
|
|
77
|
+
# ERROR_GENERIC = "error_generic"
|
|
78
|
+
# ERROR_UNKNOWN_ACTION = "error_unknown_action"
|
|
79
|
+
# ERROR_INVALID_REQUEST = "error_invalid_request"
|
|
80
|
+
# ERROR_ADAPTER_NOT_OPENED = "error_adapter_not_opened"
|
|
81
|
+
# ERROR_INVALID_ROLE = "error_invalid_role"
|
|
82
|
+
# ERROR_ADAPTER_DISCONNECTED = "error_adapter_disconnected"
|
|
83
|
+
# ERROR_BACKEND_DISCONNECTED = "error_backend_disconnected"
|
|
84
|
+
# ERROR_FAILED_TO_OPEN = "error_failed_to_open"
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# def is_action_error(action: Action) -> bool:
|
|
88
|
+
# """
|
|
89
|
+
# Return True if the action describes an error
|
|
90
|
+
# """
|
|
91
|
+
# return action.value.startswith("error_")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# class BackendException(Exception):
|
|
95
|
+
# """
|
|
96
|
+
# Generic backend error
|
|
97
|
+
# """
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
# def frontend_send(conn: Connection, action: Action, *args: Any) -> bool:
|
|
101
|
+
# """
|
|
102
|
+
# Send an action to the frontend
|
|
103
|
+
# """
|
|
104
|
+
# try:
|
|
105
|
+
# conn.send((action.value, *args))
|
|
106
|
+
# except (BrokenPipeError, OSError):
|
|
107
|
+
# return False
|
|
108
|
+
# return True
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
# def backend_request(
|
|
112
|
+
# conn: Connection,
|
|
113
|
+
# action: Action,
|
|
114
|
+
# *args: Any,
|
|
115
|
+
# timeout: float = EXTRA_BUFFER_RESPONSE_TIME,
|
|
116
|
+
# ) -> BackendResponse:
|
|
117
|
+
# """
|
|
118
|
+
# Send a request to the backend an expect a response with the time specified by timeout
|
|
119
|
+
# """
|
|
120
|
+
# try:
|
|
121
|
+
# conn.send((action.value, *args))
|
|
122
|
+
# except (BrokenPipeError, OSError) as err:
|
|
123
|
+
# raise BackendCommunicationError("Failed to communicate with backend") from err
|
|
124
|
+
|
|
125
|
+
# ready = wait([conn], timeout=timeout)
|
|
126
|
+
# if conn not in ready:
|
|
127
|
+
# raise BackendCommunicationError("Failed to receive backend response in time")
|
|
128
|
+
|
|
129
|
+
# try:
|
|
130
|
+
# raw_response: object = conn.recv()
|
|
131
|
+
# except (EOFError, ConnectionResetError) as err:
|
|
132
|
+
# raise BackendCommunicationError(
|
|
133
|
+
# f"Failed to receive backend response to {action.value}"
|
|
134
|
+
# ) from err
|
|
135
|
+
|
|
136
|
+
# # Check if the response is correctly formatted
|
|
137
|
+
# if not (isinstance(raw_response, tuple) and isinstance(raw_response[0], str)):
|
|
138
|
+
# raise BackendCommunicationError(
|
|
139
|
+
# f"Invalid response received from backend : {raw_response}"
|
|
140
|
+
# )
|
|
141
|
+
|
|
142
|
+
# response_action: Action = Action(raw_response[0])
|
|
143
|
+
# arguments: tuple[Any, ...] = raw_response[1:]
|
|
144
|
+
|
|
145
|
+
# if is_action_error(response_action):
|
|
146
|
+
# if len(arguments) > 0:
|
|
147
|
+
# if isinstance(arguments[0], str):
|
|
148
|
+
# error_message: str = arguments[0]
|
|
149
|
+
# else:
|
|
150
|
+
# error_message = "failed to read error message"
|
|
151
|
+
# else:
|
|
152
|
+
# error_message = "Missing error message"
|
|
153
|
+
# raise BackendError(f"{response_action} : {error_message}")
|
|
154
|
+
# return arguments
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
# backend_send = frontend_send
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
# def raise_if_error(response: BackendResponse) -> None:
|
|
161
|
+
# """
|
|
162
|
+
# Raise error if the action is an error, ignore otherwise
|
|
163
|
+
# """
|
|
164
|
+
# action = Action(response[0])
|
|
165
|
+
# if is_action_error(action):
|
|
166
|
+
# if len(response) > 1:
|
|
167
|
+
# description = response[1]
|
|
168
|
+
# else:
|
|
169
|
+
# description = f"{action}"
|
|
170
|
+
# raise BackendException(f"{action.name}/{description}")
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
# class AdapterBackendStatus(Enum):
|
|
174
|
+
# """
|
|
175
|
+
# Adapter backend status enum
|
|
176
|
+
# """
|
|
177
|
+
|
|
178
|
+
# DISCONNECTED = 0
|
|
179
|
+
# CONNECTED = 1
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
# class ClientStatus(Enum):
|
|
183
|
+
# """
|
|
184
|
+
# Client status enum
|
|
185
|
+
# """
|
|
186
|
+
|
|
187
|
+
# DISCONNECTED = 0
|
|
188
|
+
# CONNECTED = 1
|
syndesi/scripts/syndesi.py
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
# File : syndesi.py
|
|
2
2
|
# Author : Sébastien Deriaz
|
|
3
3
|
# License : GPL
|
|
4
|
+
"""
|
|
5
|
+
Main syndesi CLI script
|
|
6
|
+
"""
|
|
4
7
|
|
|
5
8
|
import argparse
|
|
6
9
|
from enum import Enum
|
|
7
10
|
|
|
8
11
|
from ..cli.shell import AdapterShell, AdapterType
|
|
9
|
-
from ..tools.
|
|
12
|
+
from ..tools.logmanager import log
|
|
10
13
|
from ..version import __version__
|
|
11
14
|
|
|
12
15
|
|
|
13
16
|
class SyndesiCommands(Enum):
|
|
17
|
+
"""
|
|
18
|
+
Syndesi script commands enum
|
|
19
|
+
"""
|
|
20
|
+
|
|
14
21
|
SERIAL = "serial"
|
|
15
22
|
IP = "ip"
|
|
16
23
|
MODBUS = "modbus"
|
|
@@ -18,6 +25,9 @@ class SyndesiCommands(Enum):
|
|
|
18
25
|
|
|
19
26
|
|
|
20
27
|
def main() -> None:
|
|
28
|
+
"""
|
|
29
|
+
Main syndesi entry point
|
|
30
|
+
"""
|
|
21
31
|
parser = argparse.ArgumentParser(
|
|
22
32
|
prog="syndesi", description="Syndesi command line tool", epilog=""
|
|
23
33
|
)
|
|
@@ -43,7 +53,7 @@ def main() -> None:
|
|
|
43
53
|
elif command == SyndesiCommands.VISA:
|
|
44
54
|
AdapterShell(AdapterType.VISA, remaining_args).run()
|
|
45
55
|
else:
|
|
46
|
-
raise
|
|
56
|
+
raise NotImplementedError(f"Command '{command.value}' is not supported yet")
|
|
47
57
|
|
|
48
58
|
|
|
49
59
|
if __name__ == "__main__":
|
syndesi/tools/errors.py
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
# File : errors.py
|
|
2
2
|
# Author : Sébastien Deriaz
|
|
3
3
|
# License : GPL
|
|
4
|
+
"""
|
|
5
|
+
Syndesi errors
|
|
6
|
+
"""
|
|
4
7
|
|
|
5
8
|
from pathlib import Path
|
|
6
9
|
|
|
10
|
+
from syndesi.tools.types import NumberLike
|
|
11
|
+
|
|
7
12
|
PACKAGE_PATH = Path(__file__).resolve().parent.parent
|
|
8
13
|
|
|
9
14
|
|
|
@@ -11,40 +16,53 @@ class SyndesiError(Exception):
|
|
|
11
16
|
"""Base class for all Syndesi errors"""
|
|
12
17
|
|
|
13
18
|
|
|
14
|
-
class
|
|
15
|
-
"""
|
|
19
|
+
class AdapterError(SyndesiError):
|
|
20
|
+
"""Adapter error"""
|
|
16
21
|
|
|
17
22
|
|
|
18
|
-
class
|
|
19
|
-
"""
|
|
23
|
+
class AdapterConfigurationError(AdapterError):
|
|
24
|
+
"""Adapter configuration error"""
|
|
20
25
|
|
|
21
26
|
|
|
22
|
-
class
|
|
23
|
-
"""
|
|
27
|
+
class AdapterOpenError(AdapterError):
|
|
28
|
+
"""Adapter failed to open"""
|
|
24
29
|
|
|
25
30
|
|
|
26
|
-
class AdapterError
|
|
27
|
-
"""
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
31
|
+
class AdapterWriteError(AdapterError):
|
|
32
|
+
"""Adapter failed to write"""
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class AdapterDisconnected(AdapterError):
|
|
36
|
+
"""Adapter disconnected"""
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class WorkerThreadError(AdapterError):
|
|
40
|
+
"""Adapters worker thread error"""
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class AdapterReadError(AdapterError):
|
|
44
|
+
"""Error while performing read operation"""
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class ProtocolError(SyndesiError):
|
|
48
|
+
"""Protocol error"""
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class ProtocolWriteError(SyndesiError):
|
|
52
|
+
"""Protocol error when writing"""
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class ProtocolReadError(SyndesiError):
|
|
56
|
+
"""Protocol error when reading"""
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class AdapterTimeoutError(AdapterError):
|
|
60
|
+
"""
|
|
61
|
+
Adapter timeout error
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
def __init__(self, timeout: NumberLike) -> None:
|
|
65
|
+
self.timeout = timeout
|
|
66
|
+
super().__init__(
|
|
67
|
+
f"No response received from target within {self.timeout} seconds"
|
|
68
|
+
)
|
syndesi/tools/log_settings.py
CHANGED
|
@@ -1,17 +1,30 @@
|
|
|
1
|
-
# File :
|
|
1
|
+
# File : log_settings.py
|
|
2
2
|
# Author : Sébastien Deriaz
|
|
3
3
|
# License : GPL
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
"""
|
|
5
|
+
Log utilities
|
|
6
|
+
Set log level, destination, etc...
|
|
7
|
+
"""
|
|
8
|
+
import logging
|
|
8
9
|
from enum import Enum
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class LoggerAlias(Enum):
|
|
13
|
+
"""
|
|
14
|
+
Name of the Syndesi loggers inside the logging module
|
|
15
|
+
"""
|
|
16
|
+
|
|
12
17
|
ADAPTER = "syndesi.adapter"
|
|
13
18
|
PROTOCOL = "syndesi.protocol"
|
|
14
19
|
CLI = "syndesi.cli"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
20
|
+
REMOTE = "syndesi.remote"
|
|
21
|
+
ADAPTER_WORKER = "syndesi.adapterworker"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
LOGGING_COLORS = {
|
|
25
|
+
logging.DEBUG: "grey66",
|
|
26
|
+
logging.INFO: "green",
|
|
27
|
+
logging.WARNING: "yellow",
|
|
28
|
+
logging.ERROR: "red",
|
|
29
|
+
logging.CRITICAL: "bold purple",
|
|
30
|
+
}
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
# File : logmanager.py
|
|
2
2
|
# Author : Sébastien Deriaz
|
|
3
3
|
# License : GPL
|
|
4
|
-
|
|
4
|
+
"""
|
|
5
|
+
Log manager implementation
|
|
6
|
+
"""
|
|
5
7
|
import logging
|
|
6
8
|
import threading
|
|
7
9
|
from typing import TextIO
|
|
8
10
|
|
|
9
|
-
from .backend_logger import BackendLogger
|
|
10
11
|
from .log_settings import LoggerAlias
|
|
11
12
|
|
|
13
|
+
|
|
12
14
|
class LogManager:
|
|
15
|
+
"""
|
|
16
|
+
Log manager, responsible for logging configuration, backend logging and
|
|
17
|
+
printing to console and/or to a file
|
|
18
|
+
"""
|
|
19
|
+
|
|
13
20
|
_lock = threading.Lock()
|
|
14
21
|
|
|
15
22
|
DEFAULT_FORMATTER = logging.Formatter(
|
|
@@ -23,13 +30,11 @@ class LogManager:
|
|
|
23
30
|
self._loggers: list[str] = []
|
|
24
31
|
self._level = self.DEFAULT_LOG_LEVEL
|
|
25
32
|
self._stream_handler: logging.StreamHandler[TextIO] | None = None
|
|
26
|
-
self._backend_logger: BackendLogger | None = None
|
|
27
|
-
|
|
28
|
-
def enable_backend_logging(self) -> None:
|
|
29
|
-
self._backend_logger = BackendLogger()
|
|
30
|
-
self._backend_logger.start()
|
|
31
33
|
|
|
32
34
|
def set_log_level(self, level: str | int) -> None:
|
|
35
|
+
"""
|
|
36
|
+
Set log level
|
|
37
|
+
"""
|
|
33
38
|
if isinstance(level, str):
|
|
34
39
|
if not hasattr(logging, level.upper()):
|
|
35
40
|
raise ValueError(f"Invalid log level: {level}")
|
|
@@ -43,6 +48,9 @@ class LogManager:
|
|
|
43
48
|
self.update_loggers()
|
|
44
49
|
|
|
45
50
|
def set_console_log(self, enabled: bool) -> None:
|
|
51
|
+
"""
|
|
52
|
+
Enable or disable console logging
|
|
53
|
+
"""
|
|
46
54
|
if enabled:
|
|
47
55
|
self._stream_handler = logging.StreamHandler()
|
|
48
56
|
self._stream_handler.setFormatter(self.DEFAULT_FORMATTER)
|
|
@@ -50,6 +58,9 @@ class LogManager:
|
|
|
50
58
|
self._stream_handler = None
|
|
51
59
|
|
|
52
60
|
def set_log_file(self, file: str | None) -> None:
|
|
61
|
+
"""
|
|
62
|
+
Define a file for loggers output
|
|
63
|
+
"""
|
|
53
64
|
if file is not None:
|
|
54
65
|
self._file_handler = logging.FileHandler(file)
|
|
55
66
|
self._file_handler.setFormatter(self.DEFAULT_FORMATTER)
|
|
@@ -59,6 +70,9 @@ class LogManager:
|
|
|
59
70
|
self._file_handler = None
|
|
60
71
|
|
|
61
72
|
def set_logger_filter(self, loggers: list[str] | str) -> None:
|
|
73
|
+
"""
|
|
74
|
+
Select loggers
|
|
75
|
+
"""
|
|
62
76
|
self._all_loggers = False
|
|
63
77
|
self._loggers = []
|
|
64
78
|
if isinstance(loggers, list):
|
|
@@ -72,6 +86,9 @@ class LogManager:
|
|
|
72
86
|
raise ValueError("Invalid argument loggers")
|
|
73
87
|
|
|
74
88
|
def update_loggers(self) -> None:
|
|
89
|
+
"""
|
|
90
|
+
Update configuration of each logger
|
|
91
|
+
"""
|
|
75
92
|
# 1) Remove everything
|
|
76
93
|
for alias in LoggerAlias:
|
|
77
94
|
logger = logging.getLogger(alias.value)
|
|
@@ -86,12 +103,6 @@ class LogManager:
|
|
|
86
103
|
logger.addHandler(self._stream_handler)
|
|
87
104
|
logger.setLevel(self._level)
|
|
88
105
|
|
|
89
|
-
def backend_logger_conn_description(self) -> str:
|
|
90
|
-
if self._backend_logger is None:
|
|
91
|
-
return ""
|
|
92
|
-
else:
|
|
93
|
-
return self._backend_logger.conn_description
|
|
94
|
-
|
|
95
106
|
|
|
96
107
|
log_manager = LogManager()
|
|
97
108
|
|
syndesi/tools/types.py
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# File : types.py
|
|
2
2
|
# Author : Sébastien Deriaz
|
|
3
3
|
# License : GPL
|
|
4
|
+
"""
|
|
5
|
+
Type tools
|
|
6
|
+
"""
|
|
4
7
|
|
|
5
8
|
from typing import TYPE_CHECKING, Any, TypeGuard
|
|
6
9
|
|
|
@@ -16,7 +19,8 @@ if TYPE_CHECKING:
|
|
|
16
19
|
else:
|
|
17
20
|
NumberLike = int | float | np.number # runtime will resolve string
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
|
|
23
|
+
def is_number(x: Any) -> TypeGuard[NumberLike]:
|
|
20
24
|
"""
|
|
21
25
|
Check if the given X is an instance of int or float
|
|
22
26
|
|
|
@@ -29,9 +33,8 @@ def is_number(X: Any) -> TypeGuard[NumberLike]:
|
|
|
29
33
|
result : bool
|
|
30
34
|
"""
|
|
31
35
|
if np is None:
|
|
32
|
-
return isinstance(
|
|
33
|
-
|
|
34
|
-
return isinstance(X, int | float | np.number)
|
|
36
|
+
return isinstance(x, int | float)
|
|
37
|
+
return isinstance(x, int | float | np.number)
|
|
35
38
|
|
|
36
39
|
|
|
37
40
|
def assert_number(*args: Any) -> None:
|
|
@@ -57,7 +60,6 @@ def to_bytes(data: str | bytes) -> bytes:
|
|
|
57
60
|
"""
|
|
58
61
|
if isinstance(data, bytes):
|
|
59
62
|
return data
|
|
60
|
-
|
|
63
|
+
if isinstance(data, str):
|
|
61
64
|
return data.encode("utf-8")
|
|
62
|
-
|
|
63
|
-
raise ValueError(f"Invalid data type : {type(data)}")
|
|
65
|
+
raise ValueError(f"Invalid data type : {type(data)}")
|
syndesi/version.py
CHANGED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
syndesi/__init__.py,sha256=Lapn-qSSzcSGPgGVX_TLBM-FJyBzr0JKd3EmgwaYBn8,624
|
|
2
|
+
syndesi/__main__.py,sha256=S9G9k0SHGJJ9qMdF_txtYryiPdEPTI10bgQ-M-rVITs,75
|
|
3
|
+
syndesi/component.py,sha256=zdky9tOtN-Z0qEcGWfJ1d-xRmbqQaOyXfvV7HgS-M2A,8402
|
|
4
|
+
syndesi/version.py,sha256=NdA_xw1pibpr0hHkrQoBM6UBvPRxxSywMz2CF2kMq7I,98
|
|
5
|
+
syndesi/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
syndesi/adapters/adapter.py,sha256=w1zZhg9PPxRUnC2mjh7iWKv9bAYGi7yhmG2BZs3tV1g,15282
|
|
7
|
+
syndesi/adapters/adapter_worker.py,sha256=vll3TWvZ1G4eTs4aJqQwxsFfD1LtIhXX2MRnMAYl4K0,28467
|
|
8
|
+
syndesi/adapters/auto.py,sha256=_hXCGM6TCe_cgLyQ_6CUDo8_lqXNB7nTsxkn25kCC5U,2355
|
|
9
|
+
syndesi/adapters/descriptors.py,sha256=GehtGriResi4IBE1fo2xPA8CK-q64p8acghORKY1I18,1021
|
|
10
|
+
syndesi/adapters/ip.py,sha256=Kd_q0-sONL8vFRbEz3Zvj17IhffEJ6QfLBe1-86SIV4,7849
|
|
11
|
+
syndesi/adapters/serialport.py,sha256=RHLqy11L2t-k6XvPRjRjh6KArcZqPIdukywiYwQTRNk,6105
|
|
12
|
+
syndesi/adapters/stop_conditions.py,sha256=5d1F3YQxGj69oDD9iKKbt2uYOZlSchQdiuLSCy5uME8,10150
|
|
13
|
+
syndesi/adapters/timeout.py,sha256=TZdPWBqAyW7Wes2tarbM1fiJL3Gw5xd5J2YRAtVITZw,3184
|
|
14
|
+
syndesi/adapters/visa.py,sha256=xeKRu4P4c_hhcBF327Raq59SvrD11aiFNI_Q1aFrgBk,8455
|
|
15
|
+
syndesi/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
+
syndesi/cli/console.py,sha256=pwEOukoRDq-AnJSMfmd8jyKjm_2DT8CoWU2OENWSnMI,8864
|
|
17
|
+
syndesi/cli/shell.py,sha256=0jNE7LT22RRru3BCHEobUSmLDNNeDhk-OGL5eUGkFNs,7969
|
|
18
|
+
syndesi/cli/shell_tools.py,sha256=wqa0d5yELV1my_NhcLw00OXmYP8vKlrlkPqjLF2dCNs,3335
|
|
19
|
+
syndesi/cli/terminal.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
|
+
syndesi/cli/terminal_apps.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
|
+
syndesi/cli/terminal_tools.py,sha256=HuhJebeF_SWywwMhw3G91poSphTDF_aaaiw_m8Z5HIM,301
|
|
22
|
+
syndesi/protocols/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
|
+
syndesi/protocols/delimited.py,sha256=6MJDV1Schll9bFk9OHvID6GVg4Fj2s_NzmmfMnR-qqk,5549
|
|
24
|
+
syndesi/protocols/modbus.py,sha256=8VmjPVeEjgcwXHghdSw5n1MYxd3cVyXu_Wb_9eJR-9I,94938
|
|
25
|
+
syndesi/protocols/protocol.py,sha256=Pv92qL__weswyu60ZTMcjy17Rp-ToHChFJHfPmPcOhw,6490
|
|
26
|
+
syndesi/protocols/raw.py,sha256=_UrfDkXT3LpI2vQut8AhN6zorFD-fcnzctR8nYQEtT0,2022
|
|
27
|
+
syndesi/protocols/scpi.py,sha256=hZRA4sDd--xfQHHNA-3M4yTGe6GJtirmOgW8YoHraCc,2985
|
|
28
|
+
syndesi/remote/remote.py,sha256=7ykrmNjCGxTnwwIC2qzeXSne3C2fgpVRYXFB7AOXlt0,5759
|
|
29
|
+
syndesi/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
|
+
syndesi/scripts/syndesi.py,sha256=bEueSyCsWr_HVvPxfXffogVXLm-LetDmLQvESaZZS30,1512
|
|
31
|
+
syndesi/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
32
|
+
syndesi/tools/errors.py,sha256=_BZXlETGGkHS_IgPM7Z7-KJkIAQVtJ8MTdpGpWM6B-Q,1331
|
|
33
|
+
syndesi/tools/log_settings.py,sha256=0iy6mQPnAnuGvwsoZPBhCdA5fCMfgSpMhMbJe1sT9bY,604
|
|
34
|
+
syndesi/tools/logmanager.py,sha256=d-CUgPRK8kNED3vwUKF6wJdLSbeGAf3PJh9XBVqTdOs,4455
|
|
35
|
+
syndesi/tools/types.py,sha256=jSLpR-ymLnhCT2BqRNU_g_qhOGWUn5mZ4FobAhFx05k,1393
|
|
36
|
+
syndesi-0.5.0.dist-info/licenses/LICENSE,sha256=7oldAMqsditrYeX4dzMFHpFZ-6AkyGi3bha2zeaJB0A,34492
|
|
37
|
+
syndesi-0.5.0.dist-info/METADATA,sha256=W4Q_6ClHfYhZvPQ0anw66yfYLqmeCfJ7ZoexqOujXD8,2827
|
|
38
|
+
syndesi-0.5.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
39
|
+
syndesi-0.5.0.dist-info/entry_points.txt,sha256=1JbZYMX6PrakEg-6b_M_f58QJ1mGFJKJd7puoPQPyKM,112
|
|
40
|
+
syndesi-0.5.0.dist-info/top_level.txt,sha256=HrY36JU6hFYp_6qv-GuVBBtHYYemn8qhCrqpvXBd1Lg,8
|
|
41
|
+
syndesi-0.5.0.dist-info/RECORD,,
|
|
File without changes
|