syndesi 0.3.2__py3-none-any.whl → 0.4.1__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.
@@ -69,8 +69,9 @@ class IPDescriptor(Descriptor):
69
69
 
70
70
  DETECTION_PATTERN = r"(\d+.\d+.\d+.\d+|[\w\.]+):\d+:(UDP|TCP)"
71
71
  address: str
72
+ transport: Transport
72
73
  port: int | None = None
73
- transport: Transport | None = None
74
+ #transport: Transport | None = None
74
75
 
75
76
  @staticmethod
76
77
  def from_string(string: str) -> "IPDescriptor":
@@ -78,7 +79,7 @@ class IPDescriptor(Descriptor):
78
79
  address = parts[0]
79
80
  port = int(parts[1])
80
81
  transport = IPDescriptor.Transport(parts[2])
81
- return IPDescriptor(address, port, transport)
82
+ return IPDescriptor(address, transport, port)
82
83
 
83
84
  def __str__(self) -> str:
84
85
  return f"{self.address}:{self.port}:{self.Transport(self.transport).value}"
@@ -140,6 +140,7 @@ class IPBackend(AdapterBackend):
140
140
 
141
141
  if fragment.data == b"":
142
142
  # Socket disconnected
143
+ self._logger.debug('## Socket disconnected')
143
144
  self.close()
144
145
 
145
146
  return fragment
@@ -6,7 +6,7 @@
6
6
 
7
7
  import time
8
8
 
9
- import serial # type: ignore
9
+ import serial
10
10
  from serial.serialutil import PortNotOpenError
11
11
 
12
12
  from syndesi.tools.backend_api import AdapterBackendStatus, Fragment
@@ -83,10 +83,10 @@ class SerialPortBackend(AdapterBackend):
83
83
  baudrate=self.descriptor.baudrate,
84
84
  rtscts=self._rts_cts,
85
85
  )
86
- elif not self._port.isOpen():
86
+ elif not self._port.isOpen(): # type: ignore
87
87
  self._port.open()
88
88
 
89
- if self._port.isOpen():
89
+ if self._port.isOpen(): # type: ignore
90
90
  self._logger.info(f"Adapter {self.descriptor} opened")
91
91
  self._status = AdapterBackendStatus.CONNECTED
92
92
  return True
@@ -100,7 +100,7 @@ class SerialPortBackend(AdapterBackend):
100
100
  if hasattr(self, "_port") and self._port is not None:
101
101
  # Close and the read thread will die by itself
102
102
  self._port.close()
103
- self._logger.info("Adapter closed !")
103
+ self._logger.info("Adapter closed")
104
104
  return True
105
105
  else:
106
106
  return False
@@ -112,17 +112,17 @@ class SerialPortBackend(AdapterBackend):
112
112
  return False
113
113
  else:
114
114
  if self._rts_cts: # Experimental
115
- self._port.setRTS(True) # type : ignore
115
+ self._port.setRTS(True) # type: ignore
116
116
  # TODO : Implement auto open
117
117
  # if self._status == AdapterBackendStatus.DISCONNECTED:
118
118
  # self.open()
119
- write_start = time.time()
119
+ #write_start = time.time()
120
120
  try:
121
121
  self._port.write(data)
122
122
  except (OSError, PortNotOpenError):
123
123
  return False
124
- write_duration = time.time() - write_start
125
- self._logger.debug(f"Write [{write_duration * 1e3:.3f}ms]: {repr(data)}")
124
+ # write_duration = time.time() - write_start
125
+ #self._logger.debug(f"Write [{write_duration * 1e3:.3f}ms]: {repr(data)}")
126
126
 
127
127
  return True
128
128
 
@@ -130,17 +130,23 @@ class SerialPortBackend(AdapterBackend):
130
130
  t = time.time()
131
131
 
132
132
  if self._port is None:
133
+ self._logger.debug('Port is None -> b""')
133
134
  return Fragment(b"", t)
134
135
  else:
135
136
  try:
136
137
  data = self._port.read_all()
137
138
  except (OSError, PortNotOpenError):
138
- return Fragment(b'', t)
139
+ self._logger.debug('Port error -> b""')
140
+ return Fragment(b"", t)
139
141
  else:
140
- if data is None:
141
- return Fragment(b"", t)
142
- else:
142
+ # This is a test, it seems b"" happens sometimes and disconnects the adapter
143
+ if data is not None and data != b"":
143
144
  return Fragment(data, t)
145
+ else:
146
+ return Fragment(b"", t)
147
+ #self._logger.debug('Data is none -> b""')
148
+ # else:
149
+ # self._logger.debug(f'{data=}')
144
150
 
145
151
  # def _start_thread(self):
146
152
  # """
@@ -224,7 +230,7 @@ class SerialPortBackend(AdapterBackend):
224
230
 
225
231
  def is_opened(self) -> bool:
226
232
  if self._port is not None:
227
- if self._port.isOpen(): # type : ignore
233
+ if self._port.isOpen(): # type: ignore
228
234
  return True
229
235
 
230
236
  return False
@@ -10,25 +10,9 @@ import time
10
10
  from abc import abstractmethod
11
11
  from enum import Enum
12
12
 
13
- from syndesi.adapters.stop_condition import StopCondition, Termination, Length, TimeoutStopCondition
13
+ from syndesi.adapters.stop_condition import StopCondition, Termination, Length, Continuation, Total, StopConditionType
14
14
 
15
15
  from ...tools.backend_api import Fragment
16
-
17
-
18
- # class StopConditionType(Enum):
19
- # TERMINATION = "termination"
20
- # LENGTH = "length"
21
- # LAMBDA = "lambda"
22
- # TIMEOUT = "timeout"
23
-
24
-
25
- # class StopConditionDescriptorKey(Enum):
26
- # TYPE = "type"
27
- # TERMINATION_SEQUENCE = "sequence"
28
- # LENGTH_N = "N"
29
- # TIMEOUT_CONTINUATION = "tc"
30
- # TIMEOUT_TOTAL = "tt"
31
-
32
16
  def termination_in_data(termination: bytes, data: bytes) -> tuple[int | None, int]:
33
17
  """
34
18
  Return the position (if it exists) and length of the termination (or part of it) inside data
@@ -51,61 +35,43 @@ def termination_in_data(termination: bytes, data: bytes) -> tuple[int | None, in
51
35
 
52
36
  return p, L
53
37
 
54
- class StopConditionBackend:
55
- def __init__(self, stop_condition : StopCondition) -> None:
56
- self.stop_condition = stop_condition
57
-
58
- # Termination
59
- self._sequence_found_length = 0
60
-
61
- # Length
62
- self._counter = 0
63
38
 
64
- # Timeout
65
- self._start_time: float | None = None
66
- self._last_fragment: float | None = None
39
+ class StopConditionBackend:
40
+ def __init__(self) -> None:
41
+ pass
67
42
 
68
43
  def initiate_read(self) -> None:
69
- # Termination
70
- self._sequence_found_length = 0
71
- # Length
72
- self._counter = 0
73
- # Timeout
74
- self._start_time = time.time()
75
- self._last_fragment = self._start_time
76
-
44
+ raise NotImplementedError()
77
45
 
78
46
  def evaluate(
79
47
  self, raw_fragment: Fragment) -> tuple[bool, Fragment, Fragment, float | None]:
48
+ raise NotImplementedError()
80
49
 
81
- if isinstance(self.stop_condition, Termination):
82
- return self._evaluate_termination(raw_fragment)
83
- elif isinstance(self.stop_condition, Length):
84
- return self._evaluate_length(raw_fragment)
85
- elif isinstance(self.stop_condition, TimeoutStopCondition):
86
- return self._evaluate_timeout(raw_fragment)
87
- else:
88
- raise RuntimeError(f"Invalid stop condition : {self.stop_condition}")
50
+ def type(self) -> StopConditionType:
51
+ raise NotImplementedError()
52
+
53
+ def flush_read(self) -> None:
54
+ raise NotImplementedError()
89
55
 
90
- def flush_read(self):
56
+ class TerminationBackend(StopConditionBackend):
57
+ def __init__(self, sequence : bytes) -> None:
58
+ super().__init__()
59
+ self._sequence = sequence
91
60
  self._sequence_found_length = 0
92
- self._counter = 0
93
- self._start_time = None
94
- self._last_fragment = None
95
61
 
96
- def __repr__(self) -> str:
97
- return self.__str__()
62
+ def initiate_read(self) -> None:
63
+ # Termination
64
+ self._sequence_found_length = 0
98
65
 
99
- def __str__(self) -> str:
100
- return self.stop_condition.__str__()
66
+ def flush_read(self) -> None:
67
+ self._sequence_found_length = 0
101
68
 
102
- def _evaluate_termination(self, raw_fragment: Fragment) -> tuple[bool, Fragment, Fragment, float | None]:
103
- self.stop_condition : Termination
69
+ def evaluate(self, raw_fragment: Fragment) -> tuple[bool, Fragment, Fragment, float | None]:
104
70
  if raw_fragment.data is None:
105
71
  raise RuntimeError("Trying to evaluate an invalid fragment")
106
72
 
107
73
  position, length = termination_in_data(
108
- self.stop_condition.sequence[self._sequence_found_length :], raw_fragment.data
74
+ self._sequence[self._sequence_found_length :], raw_fragment.data
109
75
  )
110
76
  stop = False
111
77
  deferred = Fragment(b"", None)
@@ -116,7 +82,7 @@ class StopConditionBackend:
116
82
  else:
117
83
  self._sequence_found_length += length
118
84
 
119
- if self._sequence_found_length == len(self.stop_condition.sequence):
85
+ if self._sequence_found_length == len(self._sequence):
120
86
  # The sequence was found entirely
121
87
  deferred = raw_fragment[position + length :]
122
88
  self._sequence_found_length = 0
@@ -129,214 +95,104 @@ class StopConditionBackend:
129
95
  kept = raw_fragment[:position]
130
96
 
131
97
  return stop, kept, deferred, None
98
+
99
+ def type(self) -> StopConditionType:
100
+ return StopConditionType.TERMINATION
101
+
102
+ class LengthBackend(StopConditionBackend):
103
+ def __init__(self, N : int) -> None:
104
+ super().__init__()
105
+ self._N = N
106
+ self._counter = 0
107
+
108
+ def initiate_read(self) -> None:
109
+ # Length
110
+ self._counter = 0
111
+
112
+ def flush_read(self) -> None:
113
+ self._counter = 0
132
114
 
133
- def _evaluate_length(self, raw_fragment: Fragment) -> tuple[bool, Fragment, Fragment, float | None]:
134
- self.stop_condition : Length
135
- remaining_bytes = self.stop_condition.N - self._counter
115
+ def evaluate(self, raw_fragment: Fragment) -> tuple[bool, Fragment, Fragment, float | None]:
116
+ remaining_bytes = self._N - self._counter
136
117
  kept_fragment = raw_fragment[:remaining_bytes]
137
118
  deferred_fragment = raw_fragment[remaining_bytes:]
138
119
  self._counter += len(kept_fragment.data)
139
- remaining_bytes = self.stop_condition.N - self._counter
120
+ remaining_bytes = self._N - self._counter
140
121
  # TODO : remaining_bytes <= 0 ? Alongside above TODO maybe
141
122
  return remaining_bytes == 0, kept_fragment, deferred_fragment, None
123
+
124
+ def type(self) -> StopConditionType:
125
+ return StopConditionType.LENGTH
142
126
 
143
- def _evaluate_timeout(self, raw_fragment: Fragment) -> tuple[bool, Fragment, Fragment, float | None]:
144
- self.stop_condition : TimeoutStopCondition
127
+ class ContinuationBackend(StopConditionBackend):
128
+ def __init__(self, time : float) -> None:
129
+ super().__init__()
130
+ self._continuation = time
131
+ self._last_fragment: float | None = None
132
+
133
+ def initiate_read(self) -> None:
134
+ self._last_fragment = time.time()
145
135
 
146
- stop = False
147
- kept = raw_fragment
136
+ def flush_read(self) -> None:
137
+ self._last_fragment = None
138
+
139
+ def evaluate(self, raw_fragment: Fragment) -> tuple[bool, Fragment, Fragment, float | None]:
148
140
  deferred = Fragment(b"", None)
149
- next_event_timeout = None
141
+ kept = raw_fragment
150
142
 
151
143
  if raw_fragment.timestamp is None:
152
144
  raise RuntimeError("Cannot evaluate fragment with no timestamp")
153
145
  # last_fragment can be none if no data was ever received
154
- if self.stop_condition.continuation is not None and self._last_fragment is not None:
155
- continuation_timestamp = self._last_fragment + self.stop_condition.continuation
156
- stop |= continuation_timestamp <= raw_fragment.timestamp
146
+ if self._last_fragment is not None:
147
+ continuation_timestamp = self._last_fragment + self._continuation
148
+ stop = continuation_timestamp <= raw_fragment.timestamp
157
149
  next_event_timeout = continuation_timestamp
158
-
159
- if self.stop_condition.total is not None:
160
- if self._start_time is None:
161
- raise RuntimeError("Invalid start time")
162
- total_timestamp = self._start_time + self.stop_condition.total
163
- stop |= total_timestamp <= raw_fragment.timestamp
164
- if next_event_timeout is None:
165
- next_event_timeout = total_timestamp
166
- else:
167
- next_event_timeout = min(next_event_timeout, total_timestamp)
150
+ else:
151
+ stop = False
152
+ next_event_timeout = None
168
153
 
169
154
  return stop, kept, deferred, next_event_timeout
170
-
171
-
172
-
173
-
174
- # @property
175
- # @abstractmethod
176
- # def _TYPE(self) -> StopConditionType:
177
- # raise NotImplementedError
178
-
179
- # def __init__(self) -> None:
180
- # """
181
- # A condition to stop reading from a device
182
-
183
- # Cannot be used on its own
184
- # """
185
- # self._and = None
186
- # self._or = None
187
-
188
- # self._eval_time = None
189
-
190
- # @abstractmethod
191
- # def initiate_read(self) -> float | None:
192
- # """
193
- # Initiate a read sequence.
194
-
195
- # The maximum time that should be spent in the next byte read
196
- # is returned
197
-
198
- # Returns
199
- # -------
200
- # timeout : float or None
201
- # None is there's no timeout
202
- # """
203
- # pass
204
-
205
- # @abstractmethod
206
- # def evaluate(
207
- # self, raw_fragment: Fragment, timestamp: float
208
- # ) -> tuple[bool, Fragment, Fragment, float | None]:
209
- # """
210
- # Evaluate the next received byte
211
-
212
- # Returns
213
- # -------
214
- # stop : bool
215
- # False if read should continue
216
- # True if read should stop
217
- # kept_fragment : bytes
218
- # Part of the fragment kept for future use
219
- # deferred_fragment : bytes
220
- # Part of the fragment that was deferred because of a stop condition
221
- # """
222
- # pass
223
-
224
- # @abstractmethod
225
- # def flush_read(self) -> None:
226
- # """
227
- # Flush input buffer and reset stop-condition
228
- # """
229
- # pass
230
-
231
-
232
-
233
-
234
- # class TerminationBackend(StopConditionBackend):
235
- # # _TYPE = StopConditionType.TERMINATION
236
- # def flush_read(self) -> None:
237
- # self._sequence_found_length = 0
238
-
239
- # def __repr__(self) -> str:
240
- # return self.__str__()
241
-
242
- # def __str__(self) -> str:
243
- # return f"TerminationBackend({repr(self._sequence)})"
244
-
245
-
246
- # # TODO : Add a "allow_longer" parameter ? If more than N data is received, keep it instead of raising an error ?
247
- # class LengthBackend(StopConditionBackend):
248
- # # _TYPE = StopConditionType.LENGTH
249
-
250
155
 
156
+ def type(self) -> StopConditionType:
157
+ return StopConditionType.TIMEOUT
251
158
 
252
- # def __repr__(self) -> str:
253
- # return self.__str__()
254
-
255
- # def __str__(self) -> str:
256
- # return f"LengthBackend({self._N})"
257
-
258
- # def flush_read(self) -> None:
259
- # self._counter = 0
159
+ class TotalBackend(StopConditionBackend):
160
+ def __init__(self, time : float) -> None:
161
+ super().__init__()
162
+ self._total = time
163
+ self._start_time : float | None = None
260
164
 
165
+ def initiate_read(self) -> None:
166
+ self._start_time = time.time()
261
167
 
262
- # class TimeoutStopConditionBackend(StopConditionBackend):
263
- # # _TYPE = StopConditionType.TIMEOUT
168
+ def flush_read(self) -> None:
169
+ self._start_time = None
264
170
 
265
- # def __init__(self, continuation: float | None, total: float | None) -> None:
266
- # """
267
- # Timeout stop condition, can stop on continuation (device not responding after x seconds),
268
- # or total (total communication time exceeds a given value)
171
+ def evaluate(self, raw_fragment: Fragment) -> tuple[bool, Fragment, Fragment, float | None]:
172
+ kept = raw_fragment
173
+ deferred = Fragment(b"", None)
269
174
 
270
- # Parameters
271
- # ----------
272
- # continuation : float
273
- # total : float
274
- # """
275
- # super().__init__()
276
- # self._start_time: float | None = None
277
- # self._last_fragment: float | None = None
278
- # self._continuation = continuation
279
- # self._total = total
175
+ if raw_fragment.timestamp is None:
176
+ raise RuntimeError("Cannot evaluate fragment with no timestamp")
280
177
 
281
- # def initiate_read(self) -> None:
282
- # self._start_time = time.time()
283
- # self._last_fragment = self._start_time
178
+ if self._start_time is None:
179
+ raise RuntimeError("Invalid start time")
180
+ total_timestamp = self._start_time + self._total
181
+ stop = total_timestamp <= raw_fragment.timestamp
284
182
 
183
+ return stop, kept, deferred, total_timestamp
285
184
 
286
-
287
- # def flush_read(self) -> None:
288
- # self._counter = 0
289
- # self._start_time = None
290
- # self._last_fragment = None
291
-
292
-
293
- # class Lambda(StopCondition): # TODO : maybe work on this a bit more
294
- # class LambdaReturn:
295
- # ERROR = 'error' # Discard everything and raise an error
296
- # VALID = 'valid' # Return everything
297
- # KEEP_N = 'keep_n' # Keep the first N bytes
298
- # CONTINUE = 'continue' # Keep reading
299
-
300
- # def __init__(self, _lambda : Callable) -> None:
301
- # super().__init__()
302
- # self._lambda = _lambda
303
-
304
- # def initiate_read(self) -> Union[float, None]:
305
- # return None
306
-
307
- # def evaluate(self, fragment: bytes) -> Tuple[bool, Union[float, None]]:
308
- # lambda_return, N = self._lambda(fragment)
309
- # match lambda_return:
310
- # case self.LambdaReturn.ERROR:
311
- # raise RuntimeError(f"Couldn't apply Lambda condition on fragment : {fragment}")
312
- # case self.LambdaReturn.VALID:
313
- # return True, fragment, b''
314
- # case self.LambdaReturn.KEEP_N:
315
- # return True, fragment[:N], fragment[N:]
316
- # case self.LambdaReturn.CONTINUE:
317
- # return False, fragment, b'' # TODO : Check this
318
-
319
- # def __repr__(self) -> str:
320
- # return self.__str__()
321
-
322
- # def __str__(self) -> str:
323
- # return f'Lambda(...)'
324
-
325
- # def stop_conditions_to_backends(stop_conditions: list[StopCondition]) -> list["StopConditionBackend"]:
326
- # output = []
327
- # for stop_condition in stop_conditions:
328
- # if isinstance(stop_condition, Termination):
329
- # output.append(TerminationBackend(
330
- # sequence=stop_condition.sequence
331
- # ))
332
- # elif isinstance(stop_condition, Length):
333
- # output.append(LengthBackend(
334
- # N=stop_condition.N
335
- # ))
336
- # elif isinstance(stop_condition, TimeoutStopCondition):
337
- # output.append(TimeoutStopConditionBackend(
338
- # continuation=stop_condition.continuation,
339
- # total=stop_condition.total,
340
- # ))
341
-
342
- # return output
185
+ def type(self) -> StopConditionType:
186
+ return StopConditionType.TIMEOUT
187
+
188
+ def stop_condition_to_backend(stop_condition : StopCondition) -> StopConditionBackend:
189
+ if isinstance(stop_condition, Termination):
190
+ return TerminationBackend(stop_condition.sequence)
191
+ elif isinstance(stop_condition, Length):
192
+ return LengthBackend(stop_condition.N)
193
+ elif isinstance(stop_condition, Continuation):
194
+ return ContinuationBackend(stop_condition.continuation)
195
+ elif isinstance(stop_condition, Total):
196
+ return TotalBackend(stop_condition.total)
197
+ else:
198
+ raise RuntimeError(f'Invalid stop condition : {stop_condition}')
@@ -24,14 +24,14 @@ from .descriptors import VisaDescriptor
24
24
 
25
25
  # --- Typing-only imports so mypy knows pyvisa symbols without requiring it at runtime
26
26
  if TYPE_CHECKING:
27
- import pyvisa
28
- from pyvisa.resources import Resource
27
+ import pyvisa # type: ignore
28
+ from pyvisa.resources import Resource # type: ignore
29
29
 
30
30
  # --- Runtime optional import
31
31
  try:
32
32
  import pyvisa as _pyvisa_runtime
33
33
  except Exception:
34
- _pyvisa_runtime = None # type:ignore
34
+ _pyvisa_runtime = None
35
35
 
36
36
  pyvisa: ModuleType | None = _pyvisa_runtime # type: ignore
37
37
 
@@ -105,8 +105,8 @@ class VisaBackend(AdapterBackend):
105
105
 
106
106
  if self._status == AdapterBackendStatus.DISCONNECTED:
107
107
  # These attributes exist on pyvisa resources
108
- self._inst.write_termination = "" # type: ignore[attr-defined]
109
- self._inst.read_termination = None # type: ignore[attr-defined]
108
+ self._inst.write_termination = ""
109
+ self._inst.read_termination = None
110
110
 
111
111
  self._inst_lock = threading.Lock()
112
112
  self._status = AdapterBackendStatus.CONNECTED
@@ -136,7 +136,7 @@ class VisaBackend(AdapterBackend):
136
136
  super().write(data)
137
137
  with self._inst_lock:
138
138
  if self._inst is not None:
139
- self._inst.write_raw(data) # type: ignore[attr-defined]
139
+ self._inst.write_raw(data)
140
140
  return True
141
141
 
142
142
  def _socket_read(self) -> Fragment:
@@ -169,7 +169,7 @@ class VisaBackend(AdapterBackend):
169
169
  try:
170
170
  while True:
171
171
  # Read up to an error
172
- payload += inst.read_bytes(1) # type: ignore[attr-defined]
172
+ payload += inst.read_bytes(1)
173
173
  inst.timeout = 0
174
174
  except pyvisa.VisaIOError:
175
175
  # Timeout
syndesi/adapters/ip.py CHANGED
@@ -28,9 +28,9 @@ class IP(Adapter):
28
28
  self,
29
29
  address: str,
30
30
  port: int | None = None,
31
- transport: str = IPDescriptor.Transport.TCP.value,
31
+ transport: str = DEFAULT_PROTOCOL.value,
32
32
  timeout: Timeout | NumberLike | None | EllipsisType = ...,
33
- stop_conditions: StopCondition | None | EllipsisType | list = ...,
33
+ stop_conditions: StopCondition | EllipsisType | list[StopCondition] = ...,
34
34
  alias: str = "",
35
35
  encoding: str = "utf-8",
36
36
  event_callback: Callable[[AdapterSignal], None] | None = None,
@@ -63,11 +63,7 @@ class IP(Adapter):
63
63
  descriptor=IPDescriptor(
64
64
  address=address,
65
65
  port=port,
66
- transport=(
67
- IPDescriptor.Transport(transport.upper())
68
- if transport is not None
69
- else self.DEFAULT_PROTOCOL
70
- ),
66
+ transport=IPDescriptor.Transport(transport.upper())
71
67
  ),
72
68
  alias=alias,
73
69
  timeout=timeout,
@@ -80,8 +76,8 @@ class IP(Adapter):
80
76
  )
81
77
  self.descriptor: IPDescriptor
82
78
 
83
- if self.descriptor.transport is None:
84
- self._logger.info(f"Setting up {self.descriptor.transport.value} IP adapter")
79
+ #if self.descriptor.transport is not None:
80
+ self._logger.info(f"Setting up {self.descriptor.transport.value} IP adapter")
85
81
 
86
82
  self.set_default_timeout(self._default_timeout())
87
83
 
@@ -102,7 +98,7 @@ class IP(Adapter):
102
98
  if self.descriptor.port is None:
103
99
  self.descriptor.port = port
104
100
 
105
- def set_default_transport(self, transport : str | IPDescriptor.Transport):
101
+ def set_default_transport(self, transport : str | IPDescriptor.Transport) -> None:
106
102
  """
107
103
  Sets the default IP transport protocol
108
104
 
@@ -20,7 +20,7 @@ class SerialPort(Adapter):
20
20
  port: str,
21
21
  baudrate: int | None = None,
22
22
  timeout: Timeout | NumberLike | None | EllipsisType = ...,
23
- stop_condition: StopCondition | None | EllipsisType = ...,
23
+ stop_conditions: StopCondition | list[StopCondition] | EllipsisType = ...,
24
24
  alias: str = "",
25
25
  rts_cts: bool = False, # rts_cts experimental
26
26
  event_callback: Callable[[AdapterSignal], None] | None = None,
@@ -39,7 +39,7 @@ class SerialPort(Adapter):
39
39
  super().__init__(
40
40
  descriptor=descriptor,
41
41
  timeout=timeout,
42
- stop_conditions=stop_condition,
42
+ stop_conditions=stop_conditions,
43
43
  alias=alias,
44
44
  event_callback=event_callback,
45
45
  backend_address=backend_address,
@@ -48,9 +48,8 @@ class SerialPort(Adapter):
48
48
  self.descriptor: SerialPortDescriptor
49
49
 
50
50
  self._logger.info(
51
- f"Setting up SerialPort adapter {self.descriptor}, timeout={timeout} and stop_condition={stop_condition}"
51
+ f"Setting up SerialPort adapter {self.descriptor}, timeout={timeout} and stop_conditions={self._stop_conditions}"
52
52
  )
53
- # self._port = None
54
53
 
55
54
  self.open()
56
55
 
@@ -78,4 +77,4 @@ class SerialPort(Adapter):
78
77
 
79
78
  def close(self, force: bool = False) -> None:
80
79
  super().close(force)
81
- self._logger.info("Adapter closed !")
80
+ self._logger.info("Adapter closed")