quarchpy 2.2.1.dev6__py2.py3-none-any.whl → 2.2.3__py2.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.
- quarchpy/.idea/.gitignore +3 -0
- quarchpy/.idea/inspectionProfiles/Project_Default.xml +1 -39
- quarchpy/.idea/misc.xml +0 -3
- quarchpy/.idea/modules.xml +1 -0
- quarchpy/.idea/quarchpy.iml +1 -0
- quarchpy/.idea/workspace.xml +89 -88
- quarchpy/__init__.py +0 -1
- quarchpy/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/__pycache__/_version.cpython-311.pyc +0 -0
- quarchpy/__pycache__/connection.cpython-311.pyc +0 -0
- quarchpy/__pycache__/run.cpython-311.pyc +0 -0
- quarchpy/_version.py +1 -1
- quarchpy/_version.py.bak +1 -0
- quarchpy/config_files/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/config_files/__pycache__/quarch_config_parser.cpython-311.pyc +0 -0
- quarchpy/connection_specific/QPS/win-amd64/app.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qis/help.txt +3 -1
- quarchpy/connection_specific/QPS/win-amd64/qis/qis.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qis/qis_lib/{CInterface-2.0.jar → CInterface-2.2.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qis/qis_lib/QuarchCommon-2.0.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qis/qis_lib/usb4java-1.3.1.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/JFXUtilities-1.0.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/QuarchCommon-2.0.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/lin-x64/{javafx-base-21.0.1-linux.jar → javafx-base-21.0.4-linux.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/lin-x64/{javafx-controls-21.0.1-linux.jar → javafx-controls-21.0.4-linux.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/{lin-arm64/javafx-fxml-21.0.1-linux-aarch64.jar → lin-x64/javafx-fxml-21.0.4-linux.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/lin-x64/{javafx-graphics-21.0.1-linux.jar → javafx-graphics-21.0.4-linux.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/lin-x64/{javafx-swing-21.0.1-linux.jar → javafx-swing-21.0.4-linux.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/mac-arm64/{javafx-base-21.0.1-mac-aarch64.jar → javafx-base-21.0.4-mac-aarch64.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/mac-arm64/{javafx-controls-21.0.1-mac-aarch64.jar → javafx-controls-21.0.4-mac-aarch64.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/{lin-x64/javafx-fxml-21.0.1-linux.jar → mac-arm64/javafx-fxml-21.0.4-mac-aarch64.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/mac-arm64/{javafx-graphics-21.0.1-mac-aarch64.jar → javafx-graphics-21.0.4-mac-aarch64.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/mac-arm64/{javafx-swing-21.0.1-mac-aarch64.jar → javafx-swing-21.0.4-mac-aarch64.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/mac-x64/{javafx-base-21.0.1-mac.jar → javafx-base-21.0.4-mac.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/{lin-arm64/javafx-controls-21.0.1-linux-aarch64.jar → mac-x64/javafx-controls-21.0.4-mac.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/{win-x64/javafx-fxml-21.0.1-win.jar → mac-x64/javafx-fxml-21.0.4-mac.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/mac-x64/{javafx-graphics-21.0.1-mac.jar → javafx-graphics-21.0.4-mac.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/mac-x64/{javafx-swing-21.0.1-mac.jar → javafx-swing-21.0.4-mac.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/{qis-1.44.4.jar → qis-1.46.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/win-x64/{javafx-base-21.0.1-win.jar → javafx-base-21.0.4-win.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/win-x64/{javafx-controls-21.0.1-win.jar → javafx-controls-21.0.4-win.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/{mac-x64/javafx-fxml-21.0.1-mac.jar → win-x64/javafx-fxml-21.0.4-win.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/win-x64/{javafx-graphics-21.0.1-win.jar → javafx-graphics-21.0.4-win.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/win-x64/{javafx-swing-21.0.1-win.jar → javafx-swing-21.0.4-win.jar} +0 -0
- quarchpy/connection_specific/QPS/win-amd64/resources/profiles/3_PHASE_PAM_AC_DEFAULT.rcf +2 -2
- quarchpy/connection_specific/QPS/win-amd64/resources/profiles/3_PHASE_PAM_AC_FULL.rcf +5 -56
- quarchpy/connection_specific/QPS/win-amd64/resources/profiles/3_PHASE_PAM_AC_FULL.scf +3 -3
- quarchpy/connection_specific/QPS/win-amd64/resources/profiles/PAM_EXAMPLE_CONFIG.rcf +1 -1
- quarchpy/connection_specific/QPS/win-amd64/scriptCommands.txt +18 -7
- quarchpy/connection_specific/QPS/win-amd64/whats-new.txt +16 -18
- quarchpy/connection_specific/connection_QIS.py +55 -24
- quarchpy/debug/__pycache__/SystemTest.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/module_debug.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/simple_terminal.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/upgrade_quarchpy.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/versionCompare.cpython-311.pyc +0 -0
- quarchpy/debug/simple_terminal.py +1 -1
- quarchpy/device/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/device.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/quarchArray.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/quarchPPM.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/quarchQPS.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/scanDevices.cpython-311.pyc +0 -0
- quarchpy/device/quarchPPM.py +105 -3
- quarchpy/device/quarchQPS.py +47 -52
- quarchpy/device/quarchQPS.py.bak +398 -0
- quarchpy/device/scanDevices.py +18 -10
- quarchpy/disk_test/__pycache__/AbsDiskFinder.cpython-311.pyc +0 -0
- quarchpy/disk_test/__pycache__/DiskTargetSelection.cpython-311.pyc +0 -0
- quarchpy/disk_test/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/disk_test/__pycache__/iometerDiskFinder.cpython-311.pyc +0 -0
- quarchpy/docs/CHANGES.rst +12 -0
- quarchpy/docs/CHANGES.rst.bak +430 -0
- quarchpy/docs/_build/doctrees/CHANGES.doctree +0 -0
- quarchpy/docs/_build/doctrees/environment.pickle +0 -0
- quarchpy/docs/_build/doctrees/index.doctree +0 -0
- quarchpy/docs/_build/doctrees/readme.doctree +0 -0
- quarchpy/docs/_build/doctrees/source/changelog.doctree +0 -0
- quarchpy/docs/_build/doctrees/source/licenses.doctree +0 -0
- quarchpy/docs/_build/doctrees/source/modules.doctree +0 -0
- quarchpy/docs/_build/doctrees/source/quarchpy.calibration.doctree +0 -0
- quarchpy/docs/_build/doctrees/source/quarchpy.config_files.doctree +0 -0
- quarchpy/docs/_build/doctrees/source/quarchpy.connection_specific.doctree +0 -0
- quarchpy/docs/_build/doctrees/source/quarchpy.debug.doctree +0 -0
- quarchpy/docs/_build/doctrees/source/quarchpy.device.doctree +0 -0
- quarchpy/docs/_build/doctrees/source/quarchpy.disk_test.doctree +0 -0
- quarchpy/docs/_build/doctrees/source/quarchpy.doctree +0 -0
- quarchpy/docs/_build/doctrees/source/quarchpy.fio.doctree +0 -0
- quarchpy/docs/_build/doctrees/source/quarchpy.iometer.doctree +0 -0
- quarchpy/docs/_build/doctrees/source/quarchpy.qis.doctree +0 -0
- quarchpy/docs/_build/doctrees/source/quarchpy.qps.doctree +0 -0
- quarchpy/docs/_build/doctrees/source/quarchpy.user_interface.doctree +0 -0
- quarchpy/docs/_build/doctrees/source/quarchpy.utilities.doctree +0 -0
- quarchpy/docs/_build/doctrees/source/readme.doctree +0 -0
- quarchpy/docs/_build/html/CHANGES.html +142 -127
- quarchpy/docs/_build/html/_sources/CHANGES.rst.txt +12 -0
- quarchpy/docs/_build/html/genindex.html +26 -18
- quarchpy/docs/_build/html/index.html +66 -64
- quarchpy/docs/_build/html/objects.inv +0 -0
- quarchpy/docs/_build/html/searchindex.js +1 -1
- quarchpy/docs/_build/html/source/changelog.html +208 -191
- quarchpy/docs/_build/html/source/quarchpy.device.html +51 -15
- quarchpy/docs/_build/html/source/quarchpy.fio.html +0 -10
- quarchpy/docs/_build/html/source/quarchpy.html +7 -5
- quarchpy/docs/_build/html/source/quarchpy.qps.html +0 -41
- quarchpy/fio/FIO_interface.py +0 -7
- quarchpy/fio/__pycache__/FIO_interface.cpython-311.pyc +0 -0
- quarchpy/fio/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/fio/__pycache__/fioDiskFinder.cpython-311.pyc +0 -0
- quarchpy/iometer/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/iometer/__pycache__/gen_iometer_template.cpython-311.pyc +0 -0
- quarchpy/iometer/__pycache__/iometerFuncs.cpython-311.pyc +0 -0
- quarchpy/qis/__pycache__/StreamHeaderInfo.cpython-311.pyc +0 -0
- quarchpy/qis/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/qis/__pycache__/qisFuncs.cpython-311.pyc +0 -0
- quarchpy/qps/__init__.py +2 -2
- quarchpy/qps/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/qps/__pycache__/qpsFuncs.cpython-311.pyc +0 -0
- quarchpy/qps/qpsFuncs.py +1 -51
- quarchpy/user_interface/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/user_interface/__pycache__/user_interface.cpython-311.pyc +0 -0
- quarchpy/user_interface/user_interface.py +4 -1
- quarchpy/utilities/__pycache__/TestCenter.cpython-311.pyc +0 -0
- quarchpy/utilities/__pycache__/TimeValue.cpython-311.pyc +0 -0
- quarchpy/utilities/__pycache__/Version.cpython-311.pyc +0 -0
- quarchpy/utilities/__pycache__/__init__.cpython-311.pyc +0 -0
- {quarchpy-2.2.1.dev6.dist-info → quarchpy-2.2.3.dist-info}/METADATA +13 -1
- {quarchpy-2.2.1.dev6.dist-info → quarchpy-2.2.3.dist-info}/RECORD +131 -208
- {quarchpy-2.2.1.dev6.dist-info → quarchpy-2.2.3.dist-info}/WHEEL +1 -1
- quarchpy/.idea/.name +0 -1
- quarchpy/.idea/vcs.xml +0 -6
- quarchpy/__pycache__/__init__.cpython-312.pyc +0 -0
- quarchpy/__pycache__/_version.cpython-312.pyc +0 -0
- quarchpy/__pycache__/connection.cpython-312.pyc +0 -0
- quarchpy/__pycache__/run.cpython-312.pyc +0 -0
- quarchpy/config_files/__pycache__/__init__.cpython-312.pyc +0 -0
- quarchpy/config_files/__pycache__/quarch_config_parser.cpython-312.pyc +0 -0
- quarchpy/connection_specific/QPS/win-amd64/InstallType.dat +0 -1
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/lin-arm64/javafx-base-21.0.1-linux-aarch64.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/lin-arm64/javafx-graphics-21.0.1-linux-aarch64.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/lin-arm64/javafx-swing-21.0.1-linux-aarch64.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/mac-arm64/javafx-fxml-21.0.1-mac-aarch64.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/mac-x64/javafx-controls-21.0.1-mac.jar +0 -0
- quarchpy/connection_specific/QPS/win-amd64/qps_lib/qis-1.44.2.jar +0 -0
- quarchpy/connection_specific/__pycache__/StreamChannels.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/StreamChannels.cpython-312.pyc +0 -0
- quarchpy/connection_specific/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/__init__.cpython-312.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_QIS.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_QIS.cpython-312.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_QPS.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_QPS.cpython-312.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_ReST.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_ReST.cpython-312.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_Serial.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_Serial.cpython-312.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_TCP.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_TCP.cpython-312.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_USB.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_USB.cpython-312.pyc +0 -0
- quarchpy/connection_specific/__pycache__/mDNS.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/mDNS.cpython-312.pyc +0 -0
- quarchpy/connection_specific/jdk_j21_jres/__pycache__/__init__.cpython-312.pyc +0 -0
- quarchpy/connection_specific/jdk_j21_jres/__pycache__/fix_permissions.cpython-312.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/__init__.cpython-312.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/serialutil.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/serialutil.cpython-312.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/serialwin32.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/serialwin32.cpython-312.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/win32.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/win32.cpython-312.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/__init__.cpython-312.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports.cpython-312.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports_common.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports_common.cpython-312.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports_windows.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports_windows.cpython-312.pyc +0 -0
- quarchpy/debug/__pycache__/SystemTest.cpython-312.pyc +0 -0
- quarchpy/debug/__pycache__/__init__.cpython-312.pyc +0 -0
- quarchpy/debug/__pycache__/module_debug.cpython-312.pyc +0 -0
- quarchpy/debug/__pycache__/simple_terminal.cpython-312.pyc +0 -0
- quarchpy/debug/__pycache__/upgrade_quarchpy.cpython-312.pyc +0 -0
- quarchpy/debug/__pycache__/versionCompare.cpython-312.pyc +0 -0
- quarchpy/device/__pycache__/__init__.cpython-312.pyc +0 -0
- quarchpy/device/__pycache__/device.cpython-312.pyc +0 -0
- quarchpy/device/__pycache__/quarchArray.cpython-312.pyc +0 -0
- quarchpy/device/__pycache__/quarchPPM.cpython-312.pyc +0 -0
- quarchpy/device/__pycache__/quarchQPS.cpython-312.pyc +0 -0
- quarchpy/device/__pycache__/scanDevices.cpython-312.pyc +0 -0
- quarchpy/disk_test/__pycache__/AbsDiskFinder.cpython-312.pyc +0 -0
- quarchpy/disk_test/__pycache__/DiskTargetSelection.cpython-312.pyc +0 -0
- quarchpy/disk_test/__pycache__/__init__.cpython-312.pyc +0 -0
- quarchpy/disk_test/__pycache__/iometerDiskFinder.cpython-312.pyc +0 -0
- quarchpy/fio/__pycache__/FIO_interface.cpython-312.pyc +0 -0
- quarchpy/fio/__pycache__/__init__.cpython-312.pyc +0 -0
- quarchpy/iometer/__pycache__/__init__.cpython-312.pyc +0 -0
- quarchpy/iometer/__pycache__/gen_iometer_template.cpython-312.pyc +0 -0
- quarchpy/iometer/__pycache__/iometerFuncs.cpython-312.pyc +0 -0
- quarchpy/qis/__pycache__/StreamHeaderInfo.cpython-312.pyc +0 -0
- quarchpy/qis/__pycache__/__init__.cpython-312.pyc +0 -0
- quarchpy/qis/__pycache__/qisFuncs.cpython-312.pyc +0 -0
- quarchpy/qps/__pycache__/__init__.cpython-312.pyc +0 -0
- quarchpy/qps/__pycache__/qpsFuncs.cpython-312.pyc +0 -0
- quarchpy/user_interface/__pycache__/__init__.cpython-312.pyc +0 -0
- quarchpy/user_interface/__pycache__/user_interface.cpython-312.pyc +0 -0
- quarchpy/utilities/__pycache__/TestCenter.cpython-312.pyc +0 -0
- quarchpy/utilities/__pycache__/TimeValue.cpython-312.pyc +0 -0
- quarchpy/utilities/__pycache__/Version.cpython-312.pyc +0 -0
- quarchpy/utilities/__pycache__/__init__.cpython-312.pyc +0 -0
- {quarchpy-2.2.1.dev6.dist-info → quarchpy-2.2.3.dist-info}/top_level.txt +0 -0
@@ -1,41 +1,39 @@
|
|
1
1
|
*** What's New In Quarch Power Studio ***
|
2
2
|
|
3
|
-
|
3
|
+
11th November 2024
|
4
4
|
|
5
|
-
QPS version 1.
|
6
|
-
QIS version 1.
|
5
|
+
QPS version 1.44
|
6
|
+
QIS version 1.46
|
7
7
|
|
8
8
|
|
9
9
|
|
10
10
|
*** New Features ***
|
11
11
|
|
12
|
-
|
12
|
+
Synthetic channels can now be disabled without deleting them (as with instrument channels)
|
13
13
|
|
14
|
-
|
14
|
+
Added channel options to the CSV export dialog
|
15
15
|
|
16
|
-
|
16
|
+
Improved cursor controls and display
|
17
17
|
|
18
|
-
|
18
|
+
Instrument profiles now display their name and description information when loaded
|
19
19
|
|
20
|
-
|
20
|
+
Synthetic channel for subtraction added
|
21
21
|
|
22
|
-
|
22
|
+
Channels can now have visibility disabled by default for a less cluttered view
|
23
23
|
|
24
|
-
|
24
|
+
Added a simple user debug command to capture all logs
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
Summary data can now be collapsed to make it more readable
|
26
|
+
Improved debug logging when loading traces
|
29
27
|
|
30
28
|
|
31
29
|
*** Major Fixes ***
|
32
30
|
|
33
|
-
Fixed
|
31
|
+
Fixed loading of synthetic channel files for AC PAM
|
34
32
|
|
35
|
-
Fixed
|
33
|
+
Fixed failure to calculate statistics for very short regions
|
36
34
|
|
37
|
-
Fixed issue where
|
35
|
+
Fixed issue where stream start could take a second or so to begin showing data
|
38
36
|
|
39
|
-
|
37
|
+
Fixed bug where QIS debug logging did not work to console
|
40
38
|
|
41
|
-
|
39
|
+
Fixed bug where sparse user channels did not always export correctly to CSV
|
@@ -1100,24 +1100,25 @@ class QisInterface:
|
|
1100
1100
|
try:
|
1101
1101
|
if sock == None:
|
1102
1102
|
sock = self.sock
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1103
|
+
count = 0
|
1104
|
+
while(True):
|
1105
|
+
if count > 5:
|
1106
|
+
break
|
1107
|
+
count += 1
|
1108
|
+
# Get the raw data
|
1109
|
+
headerData = self.sendAndReceiveText(sock, sentText='stream text header', device=device)
|
1106
1110
|
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
logging.error(device + ' Header not in XML form.' + self.host + ':' + str(self.port))
|
1119
|
-
return None;
|
1120
|
-
|
1111
|
+
# Check for no header (no stream started)
|
1112
|
+
if('Header Not Available' in headerData):
|
1113
|
+
logging.error(device + ' Stream header not available.' + self.host + ':' + str(self.port))
|
1114
|
+
continue
|
1115
|
+
|
1116
|
+
# Check for XML format
|
1117
|
+
if('?xml version=' not in headerData):
|
1118
|
+
logging.error(device + ' Header not in XML form.' + self.host + ':' + str(self.port))
|
1119
|
+
continue
|
1120
|
+
|
1121
|
+
break
|
1121
1122
|
# Parse XML into structured format
|
1122
1123
|
xml_root = ET.fromstring(headerData)
|
1123
1124
|
|
@@ -1567,9 +1568,12 @@ class QisInterface:
|
|
1567
1568
|
res = self.sendAndReceiveText(sock, cmd, device, readUntilCursor)
|
1568
1569
|
if (betweenCommandDelay > 0):
|
1569
1570
|
time.sleep(betweenCommandDelay)
|
1571
|
+
|
1570
1572
|
# If ends with cursor get rid of it
|
1571
|
-
if res[-
|
1572
|
-
res = res[:-3] # remove last three chars -
|
1573
|
+
if res[-3:] == '\r\n>':
|
1574
|
+
res = res[:-3] # remove last three chars - '\r\n>'
|
1575
|
+
elif res[-2:] == '\n>':
|
1576
|
+
res = res[:-2] # remove last 2 chars - '\n>'
|
1573
1577
|
return res
|
1574
1578
|
|
1575
1579
|
else :
|
@@ -1638,15 +1642,42 @@ class QisInterface:
|
|
1638
1642
|
logging.warning(res[0])
|
1639
1643
|
# If reading until a cursor comes back then keep reading until a cursor appears or max tries exceeded
|
1640
1644
|
if readUntilCursor:
|
1645
|
+
import xml.etree.ElementTree as ET
|
1646
|
+
|
1641
1647
|
maxReads = 1000
|
1642
1648
|
count = 1
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1646
|
-
|
1649
|
+
is_xml = False
|
1650
|
+
|
1651
|
+
while True:
|
1652
|
+
|
1653
|
+
# Determine if the response is XML based on its start
|
1654
|
+
if count == 1: # Only check this on the first read
|
1655
|
+
if res.startswith("<?xml"): # Likely XML if it starts with '<'
|
1656
|
+
is_xml = True
|
1657
|
+
elif res.startswith("<XmlResponse"):
|
1658
|
+
is_xml = True
|
1659
|
+
|
1660
|
+
|
1661
|
+
if is_xml:
|
1662
|
+
# Try to parse the XML to check if it's complete
|
1663
|
+
try:
|
1664
|
+
ET.fromstring(res[:-1]) # If it parses, the response is complete
|
1665
|
+
return res[:-1] # Exit the loop, valid XML received
|
1666
|
+
except ET.ParseError:
|
1667
|
+
pass # Keep reading until XML is complete
|
1668
|
+
else:
|
1669
|
+
# Handle normal strings
|
1670
|
+
if res[-1:] == self.cursor: # If the last character is '>', stop reading
|
1671
|
+
break
|
1672
|
+
|
1673
|
+
# Receive more data
|
1674
|
+
res += self.receiveText(sock)
|
1675
|
+
|
1676
|
+
# Increment count and check for max reads
|
1647
1677
|
count += 1
|
1648
1678
|
if count >= maxReads:
|
1649
|
-
raise Exception('
|
1679
|
+
raise Exception('Count = Error: max reads exceeded before response was complete')
|
1680
|
+
|
1650
1681
|
return res
|
1651
1682
|
|
1652
1683
|
except Exception as e:
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -4,7 +4,7 @@ Feel free to expand and add your own features to this.
|
|
4
4
|
|
5
5
|
########### VERSION HISTORY ###########
|
6
6
|
|
7
|
-
26/11/2020 - Stuart Boon
|
7
|
+
26/11/2020 - Stuart Boon - First Version
|
8
8
|
|
9
9
|
########### INSTRUCTIONS ###########
|
10
10
|
Select the module you would like to talk to.
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
quarchpy/device/quarchPPM.py
CHANGED
@@ -1,16 +1,22 @@
|
|
1
1
|
from .device import quarchDevice
|
2
2
|
import logging
|
3
|
+
import xml.etree.ElementTree as ET
|
3
4
|
from quarchpy.user_interface.user_interface import printText
|
4
5
|
|
6
|
+
|
5
7
|
class quarchPPM(quarchDevice):
|
6
|
-
def __init__(self, originObj):
|
8
|
+
def __init__(self, originObj, skipDefaultSyntheticChannels=False):
|
7
9
|
|
8
10
|
self.connectionObj = originObj.connectionObj
|
9
11
|
self.ConString = originObj.ConString
|
10
12
|
self.ConType = originObj.ConType
|
13
|
+
self.fixture_definition = self.sendCommand("fix:chan:xml?")
|
14
|
+
self.default_channels = None
|
11
15
|
numb_colons = self.ConString.count(":")
|
12
16
|
if numb_colons == 1:
|
13
17
|
self.ConString = self.ConString.replace(':', '::')
|
18
|
+
if not skipDefaultSyntheticChannels and self.ConType[:3].upper() == "QIS":
|
19
|
+
self.create_default_synthetic_channels()
|
14
20
|
|
15
21
|
def startStream(self, fileName='streamData.txt', fileMaxMB=200000, streamName ='Stream With No Name', streamDuration = None, streamAverage = None, releaseOnData = False, separator=",", inMemoryData = None):
|
16
22
|
return self.connectionObj.qis.startStream(self.ConString, fileName, fileMaxMB, streamName, streamAverage, releaseOnData, separator, streamDuration, inMemoryData)
|
@@ -27,9 +33,12 @@ class quarchPPM(quarchDevice):
|
|
27
33
|
def waitStop(self):
|
28
34
|
return self.connectionObj.qis.waitStop()
|
29
35
|
|
30
|
-
def streamResampleMode(self, streamCom):
|
36
|
+
def streamResampleMode(self, streamCom, group=None):
|
31
37
|
if streamCom.lower() == "off" or streamCom[0:-2].isdigit():
|
32
|
-
|
38
|
+
cmd = "stream mode resample " + streamCom.lower()
|
39
|
+
if group is not None:
|
40
|
+
cmd = "stream mode resample group " + str(group) + " " + streamCom.lower()
|
41
|
+
retVal = self.connectionObj.qis.sendAndReceiveCmd(cmd=cmd,
|
33
42
|
device=self.ConString)
|
34
43
|
if "fail" in retVal.lower():
|
35
44
|
logging.error(retVal)
|
@@ -65,3 +74,96 @@ class quarchPPM(quarchDevice):
|
|
65
74
|
if "OFF" in powerState or "PULLED" in powerState: # PULLED comes from PAM
|
66
75
|
# Power Up
|
67
76
|
printText("\n Turning the outputs on:"), myModule.sendCommand("run:power up"), "!"
|
77
|
+
|
78
|
+
'''
|
79
|
+
Parses the fixture XML and extracts the synthetic channels specified by the instrument defaults.
|
80
|
+
This function reads the fixture XML structure and looks for channels under the SyntheticChannels node,
|
81
|
+
extracting the relevant information (number, function, enable status, etc.).
|
82
|
+
'''
|
83
|
+
|
84
|
+
def parse_synthetic_channels_from_instrument(self):
|
85
|
+
# Parse the XML data from the fixture_definition (which is an XML string) to get the root element
|
86
|
+
root = ET.fromstring(self.fixture_definition)
|
87
|
+
|
88
|
+
# Initialize an empty list to hold all parsed synthetic channels
|
89
|
+
synthetic_channels = []
|
90
|
+
|
91
|
+
# Loop over each 'Channel' element found within 'SyntheticChannels' in the XML tree
|
92
|
+
for channel in root.findall(".//SyntheticChannels/Channel"):
|
93
|
+
# Extract values of interest from each channel, using XPath queries to find the relevant parameters
|
94
|
+
number = channel.find(".//Param[Name='Number']/Value")
|
95
|
+
function = channel.find(".//Param[Name='Function']/Value")
|
96
|
+
enable = channel.find(".//Param[Name='Enable']/Value")
|
97
|
+
enabled_by_default = channel.find(".//Param[Name='EnabledByDefault']/Value")
|
98
|
+
visible_by_default = channel.find(".//Param[Name='VisibleByDefault']/Value")
|
99
|
+
|
100
|
+
# Convert values from XML to appropriate data types (number is an integer, others are strings or booleans)
|
101
|
+
number = int(number.text) if number is not None else 0
|
102
|
+
function = function.text if function is not None else ""
|
103
|
+
enable = enable.text.lower() == 'true' if enable is not None else False
|
104
|
+
enabled_by_default = enabled_by_default.text.lower() == 'true' if enabled_by_default is not None else False
|
105
|
+
visible_by_default = visible_by_default.text.lower() == 'true' if visible_by_default is not None else False
|
106
|
+
|
107
|
+
# Create an instance of the SyntheticChannel class with the extracted information
|
108
|
+
synthetic_channel = SyntheticChannel(number, function, enable, enabled_by_default, visible_by_default)
|
109
|
+
|
110
|
+
# Append the newly created SyntheticChannel object to the list of channels
|
111
|
+
synthetic_channels.append(synthetic_channel)
|
112
|
+
|
113
|
+
# Return the list of synthetic channels extracted from the XML
|
114
|
+
return synthetic_channels
|
115
|
+
|
116
|
+
'''
|
117
|
+
Sends the set of synthetic channels to the device.
|
118
|
+
This method iterates through the list of synthetic channels and sends the appropriate
|
119
|
+
commands to a QIS/QPS-based device to create the channels.
|
120
|
+
'''
|
121
|
+
|
122
|
+
def send_synthetic_channels(self, channels):
|
123
|
+
# Loop through each channel in the provided list of channels
|
124
|
+
for channel in channels:
|
125
|
+
# Send a command to the device to create a stream with the channel's function
|
126
|
+
result = self.sendCommand("stream create channel " + channel.function)
|
127
|
+
|
128
|
+
# If the command result is not "OK", raise an exception with an error message
|
129
|
+
if result != "OK":
|
130
|
+
raise Exception(f"Command failed for channel {channel.number}: {channel.function} = {result}")
|
131
|
+
|
132
|
+
'''
|
133
|
+
Creates the default synthetic channels based on the fixture XML.
|
134
|
+
This method first parses the synthetic channels from the instrument and sends them to the device.
|
135
|
+
'''
|
136
|
+
|
137
|
+
def create_default_synthetic_channels(self):
|
138
|
+
# The fixture XML and synthetic channels are only parsed once per connection.
|
139
|
+
# If the fixture is replaced or changed, this info should be refreshed via an API call.
|
140
|
+
# This stores the default channels in the class for later use to avoid re-parsing multiple times.
|
141
|
+
self.default_channels = self.parse_synthetic_channels_from_instrument()
|
142
|
+
|
143
|
+
# Sends the parsed default synthetic channels to the device.
|
144
|
+
# This could be part of the device initialization process, with an option to skip it using a flag.
|
145
|
+
self.send_synthetic_channels(self.default_channels)
|
146
|
+
|
147
|
+
# The following commented-out example shows how to manually send a command for a specific synthetic channel.
|
148
|
+
# Example: This command calculates the RMS current for the neutral line.
|
149
|
+
# self.sendCommand("stream create channel chan(Neutral_RMS,A) rms(100ms,chan(Neutral,A))")
|
150
|
+
|
151
|
+
'''
|
152
|
+
Class representing a SyntheticChannel.
|
153
|
+
Each synthetic channel is characterized by a number, function, enable status,
|
154
|
+
whether it's enabled by default, and whether it's visible by default.
|
155
|
+
'''
|
156
|
+
|
157
|
+
class SyntheticChannel:
|
158
|
+
def __init__(self, number, function, enable, enabled_by_default, visible_by_default):
|
159
|
+
self.number = number # The unique number identifier for the synthetic channel
|
160
|
+
self.function = function # The function or behavior of the channel (e.g., RMS calculation)
|
161
|
+
self.enable = enable # Whether the channel is currently enabled
|
162
|
+
self.enabled_by_default = enabled_by_default # Whether the channel is enabled by default
|
163
|
+
self.visible_by_default = visible_by_default # Whether the channel is visible by default
|
164
|
+
|
165
|
+
def __repr__(self):
|
166
|
+
# Provide a readable string representation of the synthetic channel, useful for debugging or logging
|
167
|
+
return (f"SyntheticChannel(Number={self.number}, Function='{self.function}', "
|
168
|
+
f"Enable={self.enable}, EnabledByDefault={self.enabled_by_default}, "
|
169
|
+
f"VisibleByDefault={self.visible_by_default})")
|
quarchpy/device/quarchQPS.py
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
from quarchpy.device import quarchDevice
|
2
|
-
from quarchpy.qps import toQpsTimeStamp
|
3
2
|
from quarchpy.utilities.Version import Version
|
4
3
|
from quarchpy.user_interface.user_interface import requestDialog
|
5
4
|
import os, time, datetime, sys, logging
|
@@ -35,7 +34,7 @@ class quarchQPS(quarchDevice):
|
|
35
34
|
directory - str - desired stream dir
|
36
35
|
unserInput=True - if a failure occurs userInput=True allows user to rectify problem with user input. set to False if user interaction is not available (automating).
|
37
36
|
"""
|
38
|
-
time.sleep(1) # TODO remove this sleep once script->QPS timeing issue resolved. This works fine in the meantime
|
37
|
+
#time.sleep(1) # TODO remove this sleep once script->QPS timeing issue resolved. This works fine in the meantime
|
39
38
|
return quarchStream(self.quarchDevice, directory, unserInput)
|
40
39
|
|
41
40
|
|
@@ -198,8 +197,9 @@ class quarchStream:
|
|
198
197
|
raise Exception(command_response)
|
199
198
|
return (command_response)
|
200
199
|
|
200
|
+
|
201
201
|
def addAnnotation(self, title, annotationTime=0, extraText="", yPos="", titleColor="", annotationColor="",
|
202
|
-
annotationType="",
|
202
|
+
annotationType="", timeFormat="unix"):
|
203
203
|
"""
|
204
204
|
Adds a custom annotation to stream with given parameters.
|
205
205
|
|
@@ -215,9 +215,9 @@ class quarchStream:
|
|
215
215
|
The color of the text next to the annotation in hex format 000000 to FFFFFF
|
216
216
|
annotationColor : str, optional
|
217
217
|
The color of the annotation marker in hex format 000000 to FFFFFF
|
218
|
-
|
219
|
-
The group the annotation belongs to
|
220
|
-
|
218
|
+
annotationType : str, optional
|
219
|
+
The group the annotation belongs to, annotation comment or any custom group the user has made.
|
220
|
+
timeFormat : str, optional
|
221
221
|
The time in milliseconds after the start of the stream at which the annotation should be placed. 0 will plot the annotation live at the most recent sample
|
222
222
|
|
223
223
|
Returns
|
@@ -226,62 +226,56 @@ class quarchStream:
|
|
226
226
|
|
227
227
|
The response text from QPS. "ok" if annotation successfully added
|
228
228
|
"""
|
229
|
-
|
229
|
+
|
230
230
|
annotationType = annotationType.lower()
|
231
|
+
annotationTime = str(annotationTime)
|
232
|
+
|
233
|
+
if (annotationTime[0].isalpha() or annotationTime[-1].isalpha()):
|
234
|
+
timeFormat="elapsed"
|
235
|
+
if annotationTime.startswith("e"): #Old format allowed e to be used to pass elapsed time in seconds "e2" -> 2s + elapsed
|
236
|
+
annotationTime=annotationTime[1:]+"s"
|
237
|
+
|
238
|
+
elif annotationTime=="0":
|
239
|
+
annotationTime=current_milli_time()
|
240
|
+
timeFormat="unix"
|
241
|
+
|
231
242
|
if annotationType == "" or annotationType == "annotation":
|
232
243
|
annotationType = "annotate"
|
233
244
|
elif annotationType == "comment":
|
234
245
|
pass # already in the correct format for command
|
235
|
-
else:
|
236
|
-
|
237
|
-
|
238
|
-
|
246
|
+
# else: # QPS now supports custom types passed as annotationType rather than annotation group.
|
247
|
+
# retString = "Fail annotationType must be 'annotation' or 'comment'"
|
248
|
+
# logging.warning(retString)
|
249
|
+
# return retString
|
250
|
+
|
251
|
+
title = title.replace("\n", "\\n")
|
252
|
+
cmd="$stream annotation add "+" time="+str(annotationTime)+ " text=\""+title+"\""
|
253
|
+
if extraText!="":
|
254
|
+
extraText = extraText.replace("\n", "\\n")
|
255
|
+
cmd+=" extraText=\"" +str(extraText)+"\""
|
256
|
+
if yPos!= "":
|
257
|
+
cmd+=" yPos="+str(yPos)
|
258
|
+
if type!="":
|
259
|
+
cmd+=" type="+ str(annotationType)
|
260
|
+
if annotationColor!="":
|
261
|
+
cmd+=" colour="+str(annotationColor)
|
262
|
+
if titleColor!="":
|
263
|
+
cmd+=" textColour="+str(titleColor)
|
264
|
+
if timeFormat!="":
|
265
|
+
cmd+=" timeFormat="+str(timeFormat)
|
266
|
+
|
267
|
+
return self.connectionObj.qps.sendCmdVerbose(cmd)
|
239
268
|
|
240
|
-
# If the function has already been passed the XML string to give to QPS
|
241
|
-
if ("<<" in title.replace(" ", "")):
|
242
|
-
annotationString = str(title)
|
243
|
-
else:
|
244
|
-
annotationString = "<"
|
245
|
-
|
246
|
-
if annotationTime == "0":
|
247
|
-
# Use current time
|
248
|
-
annotationTime = qpsNowStr()
|
249
|
-
elif (annotationTime.startswith("e")):
|
250
|
-
pass
|
251
|
-
else:
|
252
|
-
# Convert timestamp to QPS format
|
253
|
-
# annotationTime = toQpsTimeStamp(annotationTime)
|
254
|
-
annotationTime = str(annotationTime)
|
255
|
-
|
256
|
-
if title != "":
|
257
|
-
annotationString += "<text>" + str(title) + "</text>"
|
258
|
-
if extraText != "":
|
259
|
-
annotationString += "<extraText>" + str(extraText) + "</extraText>"
|
260
|
-
if yPos != "":
|
261
|
-
annotationString += "<yPos>" + str(yPos) + "</yPos>"
|
262
|
-
if titleColor != "":
|
263
|
-
annotationString += "<textColor>" + str(titleColor) + "</textColor>"
|
264
|
-
if annotationColor != "":
|
265
|
-
annotationString += "<color>" + str(annotationColor) + "</color>"
|
266
|
-
if annotationGroup != "":
|
267
|
-
annotationString += "<userType>" + str(annotationGroup) + "</userType>"
|
268
|
-
annotationString += ">"
|
269
|
-
|
270
|
-
# command is sent on newline so \n needs to be chnaged to \\n which is changed back just before printing in qps.
|
271
|
-
annotationString = annotationString.replace("\n", "\\n")
|
272
|
-
logging.debug("Time sending to QPS:" + str(annotationTime))
|
273
|
-
return self.connectionObj.qps.sendCmdVerbose(
|
274
|
-
"$" + annotationType + " " + str(annotationTime) + " " + annotationString)
|
275
269
|
|
276
270
|
def addComment(self, title, commentTime=0, extraText="", yPos="", titleColor="", commentColor="", annotationType="",
|
277
|
-
annotationGroup=""):
|
271
|
+
annotationGroup="", timeFormat="unix"):
|
278
272
|
# Comments are just annotations that do not affect the statistics grid.
|
279
273
|
# This function was kept to be backwards compatible and is a simple pass through to add annotation.
|
280
274
|
if annotationType == "":
|
281
275
|
annotationType = "comment"
|
282
276
|
return self.addAnnotation(title=title, annotationTime=commentTime, extraText=extraText, yPos=yPos,
|
283
277
|
titleColor=titleColor, annotationColor=commentColor, annotationType=annotationType,
|
284
|
-
annotationGroup=annotationGroup)
|
278
|
+
annotationGroup=annotationGroup, timeFormat=timeFormat)
|
285
279
|
|
286
280
|
def saveCSV(self, filePath, linesPerFile=None, cr=None, delimiter=None, timeout=60):
|
287
281
|
"""
|
@@ -378,7 +372,7 @@ class quarchStream:
|
|
378
372
|
self.hideChannel("smclk:digital")
|
379
373
|
self.hideChannel("smdat:digital")
|
380
374
|
|
381
|
-
# function to add a data point
|
375
|
+
# function to add a data point to the stream
|
382
376
|
# time value will default to current time if none passed
|
383
377
|
def addDataPoint(self, channelName, groupName, dataValue, dataPointTime=0, timeFormat="unix"):
|
384
378
|
'''
|
@@ -386,13 +380,14 @@ class quarchStream:
|
|
386
380
|
groupName - str
|
387
381
|
dataValue - int/float value of the data point
|
388
382
|
dataPointTime=0 - time of the data point
|
389
|
-
timeFormat="unix" - the format of the given time
|
383
|
+
timeFormat="unix" - the format of the given time ["elapsed"|"unix"]
|
390
384
|
'''
|
391
385
|
if dataPointTime == None or dataPointTime == 0:
|
392
386
|
dataPointTime = qpsNowStr()
|
393
387
|
else:
|
394
|
-
dataPointTime =
|
395
|
-
|
388
|
+
dataPointTime = int(dataPointTime)
|
389
|
+
logging.warning("$stream data add " + channelName + " " + groupName + " " + str(dataPointTime) + " " + str(
|
390
|
+
dataValue) + " " + timeFormat)
|
396
391
|
self.connectionObj.qps.sendCmdVerbose(
|
397
392
|
"$stream data add " + channelName + " " + groupName + " " + str(dataPointTime) + " " + str(
|
398
393
|
dataValue) + " " + timeFormat)
|