1414from __future__ import annotations
1515
1616from types import TracebackType
17- from typing import Iterable
1817
19- from serial import Serial , SerialException , SerialTimeoutException
18+ from serial import (
19+ Serial ,
20+ SerialException ,
21+ SerialTimeoutException ,
22+ PARITY_NONE
23+ )
2024
2125
2226class Connection :
@@ -27,16 +31,6 @@ class Connection:
2731
2832 """
2933
30- def __init__ (self , name : str = "" ):
31- """
32- Parameters
33- ----------
34- name : str, optional
35- Descriptive name, by default ""
36-
37- """
38- self .name : str = name
39-
4034 def is_open (self ) -> bool :
4135 """
4236 Checks if the communication channel is currently open.
@@ -88,32 +82,9 @@ def receive(self) -> str:
8882 """
8983 raise NotImplementedError ("interface does not implement 'receive'" )
9084
91- def exchange (self , cmds : Iterable [ str ] ) -> list [ str ] :
85+ def exchange (self , cmd : str ) -> str :
9286 """
93- Sends an arbitrary number of messages through the connection,
94- and receives the corresponding responses.
95-
96- Parameters
97- ----------
98- cmds : Iterable[str]
99- Collection of messages to send.
100-
101- Returns
102- -------
103- list
104- Responses to the sent messages.
105-
106- Raises
107- ------
108- NotImplementedError
109- If the method is not implemented on the child class.
110-
111- """
112- raise NotImplementedError ("interface does not implement 'exchange'" )
113-
114- def exchange1 (self , cmd : str ) -> str :
115- """
116- Sends a single message through the connection, and receives the
87+ Sends a message through the connection, and receives the
11788 corresponding response.
11889
11990 Parameters
@@ -135,6 +106,64 @@ def exchange1(self, cmd: str) -> str:
135106 raise NotImplementedError ("interface does not implement 'exchange1'" )
136107
137108
109+ def open_serial (
110+ port : str ,
111+ * ,
112+ speed : int = 9600 ,
113+ databits : int = 8 ,
114+ stopbits : int = 1 ,
115+ parity : str = PARITY_NONE ,
116+ timeout : int = 15 ,
117+ eom : str = "\r \n " ,
118+ eoa : str = "\r \n "
119+ ) -> SerialConnection :
120+ """
121+ Constructs a SerialConnection with the given communication
122+ parameters.
123+
124+ Parameters
125+ ----------
126+ port : str
127+ Name of the port to use (e.g. ``COM1`` or ``/dev/ttyUSB0``).
128+ speed : int, optional
129+ Communication speed (baud), by default 9600
130+ databits : int, optional
131+ Number of data bits, by default 8
132+ stopbits : int, optional
133+ Number of stop bits, by default 1
134+ parity : str, optional
135+ Parity bit behavior, by default PARITY_NONE
136+ timeout : int, optional
137+ Communication timeout threshold, by default 15
138+ eom : str, optional
139+ EndOfMessage sequence, by default ``"\\ r\\ n"``
140+ eoa : str, optional
141+ EndOfAnswer sequence, by default ``"\\ r\\ n"``
142+
143+ Returns
144+ -------
145+ SerialConnection
146+
147+ Examples
148+ --------
149+
150+ Opening a serial connection similar to a file:
151+
152+ >>> conn = open_serial("COM1", speed=19200, timeout=5)
153+ >>> # do operations
154+ >>> conn.close()
155+
156+ Using as a context manager:
157+
158+ >>> with open_serial("COM1", timeout=20) as conn:
159+ ... conn.send("test")
160+
161+ """
162+ serialport = Serial (port , speed , databits , parity , stopbits , timeout )
163+ wrapper = SerialConnection (serialport , eom = eom , eoa = eoa )
164+ return wrapper
165+
166+
138167class SerialConnection (Connection ):
139168 """
140169 Connection wrapping an open serial port.
@@ -194,7 +223,6 @@ def __init__(
194223 be opened.
195224
196225 """
197- super ().__init__ ("" )
198226
199227 self ._port : Serial = port
200228 self .eom : str = eom # end of message
@@ -293,40 +321,9 @@ def receive(self) -> str:
293321
294322 return answer .decode ("ascii" ).removesuffix (self .eoa )
295323
296- def exchange (self , cmds : Iterable [str ]) -> list [str ]:
297- """
298- Writes an arbitrary number of messages to the serial line,
299- and receives the corresponding responses, one pair at a time.
300-
301- Parameters
302- ----------
303- cmds : Iterable[str]
304- Collection of messages to send.
305-
306- Returns
307- -------
308- list
309- Responses to the sent messages.
310-
311- Raises
312- ------
313- ~serial.SerialException
314- If the serial port is not open.
315- ~serial.SerialTimeoutException
316- If the connection timed out before receiving the
317- EndOfAnswer sequence for one of the responses.
318-
319- """
320- answers : list [str ] = []
321- for item in cmds :
322- self .send (item )
323- answers .append (self .receive ())
324-
325- return answers
326-
327- def exchange1 (self , cmd : str ) -> str :
324+ def exchange (self , cmd : str ) -> str :
328325 """
329- Writes a single message to the serial line, and receives the
326+ Writes a message to the serial line, and receives the
330327 corresponding response.
331328
332329 Parameters
0 commit comments