SerialDevice¶
-
class
dvg_devices.BaseDevice.
SerialDevice
(name='Dev_1', long_name='Serial Device')[source]¶ This class provides higher-level general I/O methods for a serial device, by wrapping the excellent pySerial library.
The following functionality is offered:
- TODO: mention write(), query(), query_ascii_values(), query_bytes(), readline() and close().
- Scanning over all serial ports to autoconnect to the desired serial device, based on the device’s reply to a validation query.
- Autoconnecting to the device, based on the last known successful port that gets written to a configuration textfile.
Instances of this class will tie in nicely with
dvg_qdeviceio.QDeviceIO
.Parameters: Attributes:
-
long_name
¶ Long display name of the device in a general sense. E.g, “Keysight N8700 PSU” or “Arduino M0 Pro”.
Type: str
-
serial_settings
¶ Dictionary of keyword arguments to be passed directly to
serial.Serial
at initialization of the serial port when trying to connect. Do not specify port in this dictionary as it will be supplied by this class’s machinery.Default: {“baudrate”: 9600, “timeout”: 2, “write_timeout”: 2}
Type: dict
-
ser
¶ Will be set to a
serial.Serial
device instance when a connection has been established. Otherwise:None
.Type: serial.Serial
|None
Methods¶
-
SerialDevice.
set_ID_validation_query
(ID_validation_query: Callable[[], tuple], valid_ID_broad: object, valid_ID_specific: object = None)[source]¶ When this method is not called, then the following default scheme applies:
Duringconnect_at_port()
,scan_ports()
orauto_connect()
a succesful connection to any serial device will be accepted and be stored in class memberser
.When this method is called, then the following scheme applies:
Duringconnect_at_port()
,scan_ports()
orauto_connect()
a connection to a desired device will be attempted by performing a query for a device ID over the serial connection. The serial connection will be accepted and be stored in class memberser
whenever the following scheme returns succesful:Parameters: ID_validation_query (
Callable
[[],tuple
]) – Reference to a function to perform an ID validation query on the device when connecting. The function should take zero arguments and return a tuple consisting of two objects, as will be explained further down. Only when the outcome of the validation is successful, will the connection be accepted and remain open. Otherwise, the connection will be automatically closed again.The device’s reply on the validation query will be tested against the two other arguments:
valid_ID_broad
(required) andvalid_ID_specific
(optional).The broad reply can be used to allow connections to a device of a certain manufacturer and model. E.g., in a response to an
*idn?
validation query, one can test a part of the full reply – say, “THURLBY THANDAR, QL355TP, 279730, 1.00 – 1.00” – against “THURLBY THANDAR, QL” to allow connections to any Thurlby Thandar QL-series power supply.The specific reply can be used to narrow down to a specific device, once it has passed the broad validation test. In the example above, one could test against the series number “279730”, for instance. When argument
valid_ID_specific
is not supplied, any broad match will be accepted as connection.The function to be passed, being defined as a class method inside of a derived
SerialDevice
class, should have a general form like:def my_ID_validation_query(self) -> tuple[str, str]: # Expected: reply = "THURLBY THANDAR, QL355TP, 279730, 1.00 – 1.00" _success, reply = self.query("*idn?") reply_broad = ans[:19] # "THURLBY THANDAR, QL" reply_specific = ans.split(",")[2] # "279730", i.e. serial number return reply_broad, reply_specific
When
ID_validation_query
is set toNone
, no validation will take place and any successful connection will be accepted and remain open.valid_ID_broad (
object
) – Reply to be broadly matched when a function reference is being passed ontoID_validation_query
.valid_ID_specific (
object
, optional) – Reply to be specifically matched when a function reference is being passed ontoID_validation_query
. Note: When set toNone
, any connection that is broadly matched will be accepted and remain open.Default:
None
-
SerialDevice.
set_read_termination
(termination: str | bytes | None, query_wait_time: float = 0.1)[source]¶ Set the termination character(s) for serial read.
Parameters: termination (
str
|bytes
|None
) – Termination character(s). When set toNone
or empty the I/O operationquery()
will waitquery_wait_time
seconds before reading out the complete serial-input buffer, which by then should contain the device’s reply to the query.query_wait_time (
float
, optional) – See above.Default:
0.1
-
SerialDevice.
set_write_termination
(termination: str | bytes | None)[source]¶ Set the termination character(s) for serial write.
Parameters: termination ( str
|bytes
|None
) – Termination character(s).
-
SerialDevice.
readline
(raises_on_timeout: bool = False, returns_ascii: bool = True) tuple[bool, str | bytes | None] [source]¶ Listen to the Arduino for incoming data. This method is blocking and returns when a full line has been received or when the serial read timeout has expired.
Parameters: Returns: Return type:
-
SerialDevice.
write
(msg: str | bytes, raises_on_timeout: bool = False) bool [source]¶ Send a message to the serial device.
Parameters: Returns: True if successful, False otherwise.
-
SerialDevice.
query
(msg: str | bytes, raises_on_timeout: bool = False, returns_ascii: bool = True) tuple[bool, str | bytes | None] [source]¶ Send a message to the serial device and subsequently read the reply.
Parameters: msg (
str
|bytes
) – ASCII string or bytes to be sent to the serial device.raises_on_timeout (
bool
, optional) – Should an exception be raised when a write or read timeout occurs?Default:
False
returns_ascii (
bool
, optional) – When set toTrue
the device’s reply will be returned as an ASCII string. Otherwise, it will return as bytes.TODO & NOTE: ASCII is a misnomer. The returned reply will be UTF-8 encoded, not ASCII. Need to fix the argument name somehow, without breaking code elsewhere.
Default:
True
Returns: Return type:
-
SerialDevice.
query_bytes
(msg: bytes, N_bytes_to_read: int, raises_on_timeout: bool = False) tuple[bool, bytes | None] [source]¶ Send a message as bytes to the serial device and subsequently read the reply. Will block until reaching
N_bytes_to_read
or a read timeout occurs.Parameters: Returns: - success (
bool
): True when
N_bytes_to_read
bytes are indeed read within the timeout, False otherwise.- reply (
bytes
|None
): Reply received from the device as bytes.
If
success
is False and 0 bytes got returned from the device, thenreply
will beNone
. Ifsuccess
is False because the read timed out and too few bytes got returned,reply
will contain the bytes read so far.
Return type: - success (
-
SerialDevice.
query_ascii_values
(msg: str, delimiter='\t', raises_on_timeout: bool = False) tuple[bool, list] [source]¶ Send a message to the serial device and subsequently read the reply. Expects a reply in the form of an ASCII string containing a list of numeric values, separated by a delimiter. These values will be parsed into a list and returned.
Parameters: Returns: Return type:
-
SerialDevice.
connect_at_port
(port: str, verbose: bool = True) bool [source]¶ Open the serial port at address
port
and try to establish a connection.If the connection is successful and
set_ID_validation_query()
was not set, then this function will returnTrue
.If
set_ID_validation_query()
was set, then this function will returnTrue
orFalse
depending on the validation scheme as explained inset_ID_validation_query()
.Parameters: Returns: True if successful, False otherwise.
-
SerialDevice.
scan_ports
(verbose: bool = True) bool [source]¶ Scan over all serial ports and try to establish a connection. See further the description at
connect_at_port()
.Parameters: verbose (
bool
, optional) – Print a “Scanning ports for: “-message to the terminal?Default:
True
Returns: True if successful, False otherwise.
-
SerialDevice.
auto_connect
(filepath_last_known_port: str = 'config/port.txt') bool [source]¶ Try to connect to the device using the last-known successful port as got written to the textfile
filepath_last_known_port
by the previous call toauto_connect()
.When the file does not exist, can not be read or if the desired device can not be found at that specific port, then a scan over all ports will be performed by automatically invoking
scan_ports()
.Parameters: filepath_last_known_port ( str
) – Default: “config/port.txt”Returns: True if successful, False otherwise.