sqidevice 2.0.0__tar.gz
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.
- sqidevice-2.0.0/.gitignore +1 -0
- sqidevice-2.0.0/.gitlab-ci.yml +12 -0
- sqidevice-2.0.0/.pre-commit-config.yaml +23 -0
- sqidevice-2.0.0/LICENSE.txt +7 -0
- sqidevice-2.0.0/PKG-INFO +104 -0
- sqidevice-2.0.0/README.md +84 -0
- sqidevice-2.0.0/pyproject.toml +48 -0
- sqidevice-2.0.0/sqidevice/__init__.py +18 -0
- sqidevice-2.0.0/sqidevice/sqidevice.py +801 -0
- sqidevice-2.0.0/tests/dummy_device.py +102 -0
- sqidevice-2.0.0/tests/test_conversion.py +105 -0
- sqidevice-2.0.0/tests/test_device.py +281 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__pycache__/
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v2.3.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: check-yaml
|
|
6
|
+
- id: end-of-file-fixer
|
|
7
|
+
- id: trailing-whitespace
|
|
8
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
9
|
+
# Ruff version.
|
|
10
|
+
rev: v0.12.0
|
|
11
|
+
hooks:
|
|
12
|
+
# Run the linter.
|
|
13
|
+
- id: ruff-check
|
|
14
|
+
# Run the formatter.
|
|
15
|
+
- id: ruff-format
|
|
16
|
+
- repo: local
|
|
17
|
+
hooks:
|
|
18
|
+
- id: pytest-check
|
|
19
|
+
name: pytest-check
|
|
20
|
+
entry: pytest
|
|
21
|
+
language: system
|
|
22
|
+
pass_filenames: false
|
|
23
|
+
always_run: true
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright (c) 2017 - present, Santec Australia Pty Ltd.
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
|
sqidevice-2.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: sqidevice
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: Python interface for communicating with Santec Quantum Instrument devices
|
|
5
|
+
Author: Santec Australia
|
|
6
|
+
License: MIT
|
|
7
|
+
License-File: LICENSE.txt
|
|
8
|
+
Keywords: ethernet,instrument,quantum,santec,usb
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Instrument Drivers
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
17
|
+
Requires-Python: >=3.8
|
|
18
|
+
Requires-Dist: pyserial>=3.0
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# SQIDevice: Simple interface to Santec Quantum Instruments
|
|
22
|
+
|
|
23
|
+
The `SQIDevice` class provides a simple interface for interacting with Santec Quantum Instruments over
|
|
24
|
+
a USB or ETH connection.
|
|
25
|
+
|
|
26
|
+
It handles end-of-message termination, concatenating multi-component responses, and converts error messages into exceptions to simplify error handling in the application.
|
|
27
|
+
|
|
28
|
+
Helper functions are provided for common operations, such as `ask_val()` for querying a numerical value and converting SI units, and `ask_list()` to transform comma-separated values into a `list`.
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
## Overview
|
|
32
|
+
|
|
33
|
+
The `SQIDevice` class is instantiated with a string defining the connection instance, for example:
|
|
34
|
+
```
|
|
35
|
+
# TCP connection by specifying IP address and optionally server port
|
|
36
|
+
SQIDevice("10.1.1.122")
|
|
37
|
+
SQIDevice("10.1.1.122:7802")
|
|
38
|
+
SQIDevice("10.1.1.122", port=7802)
|
|
39
|
+
|
|
40
|
+
# USB connection via virtual COM port
|
|
41
|
+
SQIDevice("COM3")
|
|
42
|
+
SQIDevice("USB", port=3)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The primary functions for communicating with the device are:
|
|
46
|
+
* `ask(query)`: Send the provided `query` string and return the response as a string.
|
|
47
|
+
Intended as the main mechanism for _reading_ values from the device.
|
|
48
|
+
If `query` is bytes, the return value is also bytes.
|
|
49
|
+
* `ask_val(query)`: Calls `ask(query)` and performs type conversion on the response string; to `float` by default.
|
|
50
|
+
Also performs simple SI-units conversion of the response, when units are provided.
|
|
51
|
+
Recommended for querying measured values from the device, instead of type-casting the response string directly.
|
|
52
|
+
* `ask_dict(query)`: Calls `ask(query)` and parses the response string into a python dictionary.
|
|
53
|
+
Intended for parsing compound responses such as `VER` and `REPORT`.
|
|
54
|
+
Does not perform type conversion of the values.
|
|
55
|
+
* `ask_list(query)`: Calls `ask(query)` and parses the response as a comma-separated list of values.
|
|
56
|
+
Optionally performs unit conversion and type conversion.
|
|
57
|
+
* `cmd(command)`: Send the provided command string to the device and wait for a response.
|
|
58
|
+
Commands are different from queries in that they induce an action and hence are expected to respond with an `OK` string.
|
|
59
|
+
Intended to be used when _writing_ values to the device.
|
|
60
|
+
Failing to respond in this way raises a `DeviceError`.
|
|
61
|
+
* `reconnect()`: Close the connection (if applicable) and reconnect with the same parameters.
|
|
62
|
+
Recommended for handling disconnection or reboot events.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
The queries and commands are product-specific, and can be found in the appropriate Appendix of the relevant product manual.
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
## Properties
|
|
70
|
+
The `INFO` query is common across compatible devices to help identify the product at a glance.
|
|
71
|
+
The `SQIDevice` parses this query at connection and stores the results as a `dict` which can be accessed directly by indexing the device instance via `__getitem__()`.
|
|
72
|
+
|
|
73
|
+
The dictionary contains at least the following keys:
|
|
74
|
+
- `type`: Product name string (e.g. "DDLC" or "FZW").
|
|
75
|
+
- `rev`: Mainboard PCB revision, to help identify firmware compatibility.
|
|
76
|
+
- `ver`: Primary version numbers for the UC (and FPGA if applicable). See also the `VER` query for additional information.
|
|
77
|
+
- `serial`: Serial number of the unit.
|
|
78
|
+
- `name`: User-defined name for the unit, as set with the `DEVNAME` command, or the serial number when a custom name is not set.
|
|
79
|
+
- `iap`: Identifies that the devices is in firmware-update (IAP) mode.
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
## Error handling
|
|
83
|
+
The command and query functions of the `SQIDevice` class raise exceptions to handle error scenarios, that should be caught at the application level.
|
|
84
|
+
|
|
85
|
+
### DeviceError
|
|
86
|
+
A response was successfully received from the device, but that response is an error message.
|
|
87
|
+
This raises an instance of `DeviceError` containing both the request that failed and the response error message.
|
|
88
|
+
|
|
89
|
+
### USBError
|
|
90
|
+
Particularly on the Windows(tm) operating system, the error messages raised by `pyserial` are often unintuitive and it is unclear how to resolve them.
|
|
91
|
+
|
|
92
|
+
The `USBError` class is a subclass of `OSError` that translates the most common error messages into a clearer form.
|
|
93
|
+
|
|
94
|
+
### TimeoutError
|
|
95
|
+
Raised if no response was received, or an incomplete response was received before the timeout period elapsed.
|
|
96
|
+
|
|
97
|
+
### OSError
|
|
98
|
+
Typically any error at the transport level will result in a subclass of `OSError` being raised by the underlying `socket` or `serial` class instances.
|
|
99
|
+
Usually this indicates that the device has been disconnected, rebooted, or powered off, and needs to be reconnected.
|
|
100
|
+
|
|
101
|
+
Examples include `TimeoutError` and `USBError`.
|
|
102
|
+
|
|
103
|
+
### AssertionError
|
|
104
|
+
If an attempt is made to communicate with the device after closing the connection, it will cause `AssertionError` to be raised.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# SQIDevice: Simple interface to Santec Quantum Instruments
|
|
2
|
+
|
|
3
|
+
The `SQIDevice` class provides a simple interface for interacting with Santec Quantum Instruments over
|
|
4
|
+
a USB or ETH connection.
|
|
5
|
+
|
|
6
|
+
It handles end-of-message termination, concatenating multi-component responses, and converts error messages into exceptions to simplify error handling in the application.
|
|
7
|
+
|
|
8
|
+
Helper functions are provided for common operations, such as `ask_val()` for querying a numerical value and converting SI units, and `ask_list()` to transform comma-separated values into a `list`.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
The `SQIDevice` class is instantiated with a string defining the connection instance, for example:
|
|
14
|
+
```
|
|
15
|
+
# TCP connection by specifying IP address and optionally server port
|
|
16
|
+
SQIDevice("10.1.1.122")
|
|
17
|
+
SQIDevice("10.1.1.122:7802")
|
|
18
|
+
SQIDevice("10.1.1.122", port=7802)
|
|
19
|
+
|
|
20
|
+
# USB connection via virtual COM port
|
|
21
|
+
SQIDevice("COM3")
|
|
22
|
+
SQIDevice("USB", port=3)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The primary functions for communicating with the device are:
|
|
26
|
+
* `ask(query)`: Send the provided `query` string and return the response as a string.
|
|
27
|
+
Intended as the main mechanism for _reading_ values from the device.
|
|
28
|
+
If `query` is bytes, the return value is also bytes.
|
|
29
|
+
* `ask_val(query)`: Calls `ask(query)` and performs type conversion on the response string; to `float` by default.
|
|
30
|
+
Also performs simple SI-units conversion of the response, when units are provided.
|
|
31
|
+
Recommended for querying measured values from the device, instead of type-casting the response string directly.
|
|
32
|
+
* `ask_dict(query)`: Calls `ask(query)` and parses the response string into a python dictionary.
|
|
33
|
+
Intended for parsing compound responses such as `VER` and `REPORT`.
|
|
34
|
+
Does not perform type conversion of the values.
|
|
35
|
+
* `ask_list(query)`: Calls `ask(query)` and parses the response as a comma-separated list of values.
|
|
36
|
+
Optionally performs unit conversion and type conversion.
|
|
37
|
+
* `cmd(command)`: Send the provided command string to the device and wait for a response.
|
|
38
|
+
Commands are different from queries in that they induce an action and hence are expected to respond with an `OK` string.
|
|
39
|
+
Intended to be used when _writing_ values to the device.
|
|
40
|
+
Failing to respond in this way raises a `DeviceError`.
|
|
41
|
+
* `reconnect()`: Close the connection (if applicable) and reconnect with the same parameters.
|
|
42
|
+
Recommended for handling disconnection or reboot events.
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
The queries and commands are product-specific, and can be found in the appropriate Appendix of the relevant product manual.
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
## Properties
|
|
50
|
+
The `INFO` query is common across compatible devices to help identify the product at a glance.
|
|
51
|
+
The `SQIDevice` parses this query at connection and stores the results as a `dict` which can be accessed directly by indexing the device instance via `__getitem__()`.
|
|
52
|
+
|
|
53
|
+
The dictionary contains at least the following keys:
|
|
54
|
+
- `type`: Product name string (e.g. "DDLC" or "FZW").
|
|
55
|
+
- `rev`: Mainboard PCB revision, to help identify firmware compatibility.
|
|
56
|
+
- `ver`: Primary version numbers for the UC (and FPGA if applicable). See also the `VER` query for additional information.
|
|
57
|
+
- `serial`: Serial number of the unit.
|
|
58
|
+
- `name`: User-defined name for the unit, as set with the `DEVNAME` command, or the serial number when a custom name is not set.
|
|
59
|
+
- `iap`: Identifies that the devices is in firmware-update (IAP) mode.
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
## Error handling
|
|
63
|
+
The command and query functions of the `SQIDevice` class raise exceptions to handle error scenarios, that should be caught at the application level.
|
|
64
|
+
|
|
65
|
+
### DeviceError
|
|
66
|
+
A response was successfully received from the device, but that response is an error message.
|
|
67
|
+
This raises an instance of `DeviceError` containing both the request that failed and the response error message.
|
|
68
|
+
|
|
69
|
+
### USBError
|
|
70
|
+
Particularly on the Windows(tm) operating system, the error messages raised by `pyserial` are often unintuitive and it is unclear how to resolve them.
|
|
71
|
+
|
|
72
|
+
The `USBError` class is a subclass of `OSError` that translates the most common error messages into a clearer form.
|
|
73
|
+
|
|
74
|
+
### TimeoutError
|
|
75
|
+
Raised if no response was received, or an incomplete response was received before the timeout period elapsed.
|
|
76
|
+
|
|
77
|
+
### OSError
|
|
78
|
+
Typically any error at the transport level will result in a subclass of `OSError` being raised by the underlying `socket` or `serial` class instances.
|
|
79
|
+
Usually this indicates that the device has been disconnected, rebooted, or powered off, and needs to be reconnected.
|
|
80
|
+
|
|
81
|
+
Examples include `TimeoutError` and `USBError`.
|
|
82
|
+
|
|
83
|
+
### AssertionError
|
|
84
|
+
If an attempt is made to communicate with the device after closing the connection, it will cause `AssertionError` to be raised.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "sqidevice"
|
|
3
|
+
version = "2.0.0"
|
|
4
|
+
description = "Python interface for communicating with Santec Quantum Instrument devices"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.8"
|
|
7
|
+
license = { text = "MIT" }
|
|
8
|
+
authors = [{ name = "Santec Australia" }]
|
|
9
|
+
keywords = ["santec", "quantum", "instrument", "usb", "ethernet"]
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 5 - Production/Stable",
|
|
12
|
+
"Intended Audience :: Developers",
|
|
13
|
+
"Intended Audience :: Science/Research",
|
|
14
|
+
"License :: OSI Approved :: MIT License",
|
|
15
|
+
"Operating System :: OS Independent",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Topic :: Software Development :: Libraries",
|
|
18
|
+
"Topic :: Scientific/Engineering :: Instrument Drivers",
|
|
19
|
+
]
|
|
20
|
+
dependencies = [
|
|
21
|
+
"pyserial>=3.0",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[build-system]
|
|
25
|
+
requires = ["hatchling>=1.18"]
|
|
26
|
+
build-backend = "hatchling.build"
|
|
27
|
+
|
|
28
|
+
[tool.hatch.build.targets.wheel]
|
|
29
|
+
packages = ["sqidevice"]
|
|
30
|
+
|
|
31
|
+
[tool.uv]
|
|
32
|
+
package = true
|
|
33
|
+
|
|
34
|
+
[tool.ruff]
|
|
35
|
+
line-length = 120
|
|
36
|
+
indent-width = 4
|
|
37
|
+
|
|
38
|
+
target-version = "py38"
|
|
39
|
+
|
|
40
|
+
[tool.ruff.lint]
|
|
41
|
+
select = ["E", "F", "B", "SIM", "PL"]
|
|
42
|
+
|
|
43
|
+
[tool.ruff.format]
|
|
44
|
+
quote-style = "double"
|
|
45
|
+
indent-style = "space"
|
|
46
|
+
skip-magic-trailing-comma = false
|
|
47
|
+
line-ending = "auto"
|
|
48
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Public device class
|
|
2
|
+
from .sqidevice import SQIDevice, CRLF
|
|
3
|
+
|
|
4
|
+
# Error handling classes
|
|
5
|
+
from .sqidevice import DeviceError, USBError
|
|
6
|
+
|
|
7
|
+
# Helper functions
|
|
8
|
+
from .sqidevice import convert_measurement, load_script
|
|
9
|
+
|
|
10
|
+
# Define * imports
|
|
11
|
+
__all__ = [
|
|
12
|
+
"SQIDevice",
|
|
13
|
+
"CRLF",
|
|
14
|
+
"DeviceError",
|
|
15
|
+
"USBError",
|
|
16
|
+
"convert_measurement",
|
|
17
|
+
"load_script",
|
|
18
|
+
]
|