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.
Files changed (214) hide show
  1. quarchpy/.idea/.gitignore +3 -0
  2. quarchpy/.idea/inspectionProfiles/Project_Default.xml +1 -39
  3. quarchpy/.idea/misc.xml +0 -3
  4. quarchpy/.idea/modules.xml +1 -0
  5. quarchpy/.idea/quarchpy.iml +1 -0
  6. quarchpy/.idea/workspace.xml +89 -88
  7. quarchpy/__init__.py +0 -1
  8. quarchpy/__pycache__/__init__.cpython-311.pyc +0 -0
  9. quarchpy/__pycache__/_version.cpython-311.pyc +0 -0
  10. quarchpy/__pycache__/connection.cpython-311.pyc +0 -0
  11. quarchpy/__pycache__/run.cpython-311.pyc +0 -0
  12. quarchpy/_version.py +1 -1
  13. quarchpy/_version.py.bak +1 -0
  14. quarchpy/config_files/__pycache__/__init__.cpython-311.pyc +0 -0
  15. quarchpy/config_files/__pycache__/quarch_config_parser.cpython-311.pyc +0 -0
  16. quarchpy/connection_specific/QPS/win-amd64/app.jar +0 -0
  17. quarchpy/connection_specific/QPS/win-amd64/qis/help.txt +3 -1
  18. quarchpy/connection_specific/QPS/win-amd64/qis/qis.jar +0 -0
  19. quarchpy/connection_specific/QPS/win-amd64/qis/qis_lib/{CInterface-2.0.jar → CInterface-2.2.jar} +0 -0
  20. quarchpy/connection_specific/QPS/win-amd64/qis/qis_lib/QuarchCommon-2.0.jar +0 -0
  21. quarchpy/connection_specific/QPS/win-amd64/qis/qis_lib/usb4java-1.3.1.jar +0 -0
  22. quarchpy/connection_specific/QPS/win-amd64/qps_lib/JFXUtilities-1.0.jar +0 -0
  23. quarchpy/connection_specific/QPS/win-amd64/qps_lib/QuarchCommon-2.0.jar +0 -0
  24. 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
  25. 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
  26. 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
  27. 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
  28. 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
  29. 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
  30. 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
  31. 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
  32. 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
  33. 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
  34. 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
  35. 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
  36. 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
  37. 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
  38. 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
  39. quarchpy/connection_specific/QPS/win-amd64/qps_lib/{qis-1.44.4.jar → qis-1.46.jar} +0 -0
  40. 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
  41. 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
  42. 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
  43. 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
  44. 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
  45. quarchpy/connection_specific/QPS/win-amd64/resources/profiles/3_PHASE_PAM_AC_DEFAULT.rcf +2 -2
  46. quarchpy/connection_specific/QPS/win-amd64/resources/profiles/3_PHASE_PAM_AC_FULL.rcf +5 -56
  47. quarchpy/connection_specific/QPS/win-amd64/resources/profiles/3_PHASE_PAM_AC_FULL.scf +3 -3
  48. quarchpy/connection_specific/QPS/win-amd64/resources/profiles/PAM_EXAMPLE_CONFIG.rcf +1 -1
  49. quarchpy/connection_specific/QPS/win-amd64/scriptCommands.txt +18 -7
  50. quarchpy/connection_specific/QPS/win-amd64/whats-new.txt +16 -18
  51. quarchpy/connection_specific/connection_QIS.py +55 -24
  52. quarchpy/debug/__pycache__/SystemTest.cpython-311.pyc +0 -0
  53. quarchpy/debug/__pycache__/__init__.cpython-311.pyc +0 -0
  54. quarchpy/debug/__pycache__/module_debug.cpython-311.pyc +0 -0
  55. quarchpy/debug/__pycache__/simple_terminal.cpython-311.pyc +0 -0
  56. quarchpy/debug/__pycache__/upgrade_quarchpy.cpython-311.pyc +0 -0
  57. quarchpy/debug/__pycache__/versionCompare.cpython-311.pyc +0 -0
  58. quarchpy/debug/simple_terminal.py +1 -1
  59. quarchpy/device/__pycache__/__init__.cpython-311.pyc +0 -0
  60. quarchpy/device/__pycache__/device.cpython-311.pyc +0 -0
  61. quarchpy/device/__pycache__/quarchArray.cpython-311.pyc +0 -0
  62. quarchpy/device/__pycache__/quarchPPM.cpython-311.pyc +0 -0
  63. quarchpy/device/__pycache__/quarchQPS.cpython-311.pyc +0 -0
  64. quarchpy/device/__pycache__/scanDevices.cpython-311.pyc +0 -0
  65. quarchpy/device/quarchPPM.py +105 -3
  66. quarchpy/device/quarchQPS.py +47 -52
  67. quarchpy/device/quarchQPS.py.bak +398 -0
  68. quarchpy/device/scanDevices.py +18 -10
  69. quarchpy/disk_test/__pycache__/AbsDiskFinder.cpython-311.pyc +0 -0
  70. quarchpy/disk_test/__pycache__/DiskTargetSelection.cpython-311.pyc +0 -0
  71. quarchpy/disk_test/__pycache__/__init__.cpython-311.pyc +0 -0
  72. quarchpy/disk_test/__pycache__/iometerDiskFinder.cpython-311.pyc +0 -0
  73. quarchpy/docs/CHANGES.rst +12 -0
  74. quarchpy/docs/CHANGES.rst.bak +430 -0
  75. quarchpy/docs/_build/doctrees/CHANGES.doctree +0 -0
  76. quarchpy/docs/_build/doctrees/environment.pickle +0 -0
  77. quarchpy/docs/_build/doctrees/index.doctree +0 -0
  78. quarchpy/docs/_build/doctrees/readme.doctree +0 -0
  79. quarchpy/docs/_build/doctrees/source/changelog.doctree +0 -0
  80. quarchpy/docs/_build/doctrees/source/licenses.doctree +0 -0
  81. quarchpy/docs/_build/doctrees/source/modules.doctree +0 -0
  82. quarchpy/docs/_build/doctrees/source/quarchpy.calibration.doctree +0 -0
  83. quarchpy/docs/_build/doctrees/source/quarchpy.config_files.doctree +0 -0
  84. quarchpy/docs/_build/doctrees/source/quarchpy.connection_specific.doctree +0 -0
  85. quarchpy/docs/_build/doctrees/source/quarchpy.debug.doctree +0 -0
  86. quarchpy/docs/_build/doctrees/source/quarchpy.device.doctree +0 -0
  87. quarchpy/docs/_build/doctrees/source/quarchpy.disk_test.doctree +0 -0
  88. quarchpy/docs/_build/doctrees/source/quarchpy.doctree +0 -0
  89. quarchpy/docs/_build/doctrees/source/quarchpy.fio.doctree +0 -0
  90. quarchpy/docs/_build/doctrees/source/quarchpy.iometer.doctree +0 -0
  91. quarchpy/docs/_build/doctrees/source/quarchpy.qis.doctree +0 -0
  92. quarchpy/docs/_build/doctrees/source/quarchpy.qps.doctree +0 -0
  93. quarchpy/docs/_build/doctrees/source/quarchpy.user_interface.doctree +0 -0
  94. quarchpy/docs/_build/doctrees/source/quarchpy.utilities.doctree +0 -0
  95. quarchpy/docs/_build/doctrees/source/readme.doctree +0 -0
  96. quarchpy/docs/_build/html/CHANGES.html +142 -127
  97. quarchpy/docs/_build/html/_sources/CHANGES.rst.txt +12 -0
  98. quarchpy/docs/_build/html/genindex.html +26 -18
  99. quarchpy/docs/_build/html/index.html +66 -64
  100. quarchpy/docs/_build/html/objects.inv +0 -0
  101. quarchpy/docs/_build/html/searchindex.js +1 -1
  102. quarchpy/docs/_build/html/source/changelog.html +208 -191
  103. quarchpy/docs/_build/html/source/quarchpy.device.html +51 -15
  104. quarchpy/docs/_build/html/source/quarchpy.fio.html +0 -10
  105. quarchpy/docs/_build/html/source/quarchpy.html +7 -5
  106. quarchpy/docs/_build/html/source/quarchpy.qps.html +0 -41
  107. quarchpy/fio/FIO_interface.py +0 -7
  108. quarchpy/fio/__pycache__/FIO_interface.cpython-311.pyc +0 -0
  109. quarchpy/fio/__pycache__/__init__.cpython-311.pyc +0 -0
  110. quarchpy/fio/__pycache__/fioDiskFinder.cpython-311.pyc +0 -0
  111. quarchpy/iometer/__pycache__/__init__.cpython-311.pyc +0 -0
  112. quarchpy/iometer/__pycache__/gen_iometer_template.cpython-311.pyc +0 -0
  113. quarchpy/iometer/__pycache__/iometerFuncs.cpython-311.pyc +0 -0
  114. quarchpy/qis/__pycache__/StreamHeaderInfo.cpython-311.pyc +0 -0
  115. quarchpy/qis/__pycache__/__init__.cpython-311.pyc +0 -0
  116. quarchpy/qis/__pycache__/qisFuncs.cpython-311.pyc +0 -0
  117. quarchpy/qps/__init__.py +2 -2
  118. quarchpy/qps/__pycache__/__init__.cpython-311.pyc +0 -0
  119. quarchpy/qps/__pycache__/qpsFuncs.cpython-311.pyc +0 -0
  120. quarchpy/qps/qpsFuncs.py +1 -51
  121. quarchpy/user_interface/__pycache__/__init__.cpython-311.pyc +0 -0
  122. quarchpy/user_interface/__pycache__/user_interface.cpython-311.pyc +0 -0
  123. quarchpy/user_interface/user_interface.py +4 -1
  124. quarchpy/utilities/__pycache__/TestCenter.cpython-311.pyc +0 -0
  125. quarchpy/utilities/__pycache__/TimeValue.cpython-311.pyc +0 -0
  126. quarchpy/utilities/__pycache__/Version.cpython-311.pyc +0 -0
  127. quarchpy/utilities/__pycache__/__init__.cpython-311.pyc +0 -0
  128. {quarchpy-2.2.1.dev6.dist-info → quarchpy-2.2.3.dist-info}/METADATA +13 -1
  129. {quarchpy-2.2.1.dev6.dist-info → quarchpy-2.2.3.dist-info}/RECORD +131 -208
  130. {quarchpy-2.2.1.dev6.dist-info → quarchpy-2.2.3.dist-info}/WHEEL +1 -1
  131. quarchpy/.idea/.name +0 -1
  132. quarchpy/.idea/vcs.xml +0 -6
  133. quarchpy/__pycache__/__init__.cpython-312.pyc +0 -0
  134. quarchpy/__pycache__/_version.cpython-312.pyc +0 -0
  135. quarchpy/__pycache__/connection.cpython-312.pyc +0 -0
  136. quarchpy/__pycache__/run.cpython-312.pyc +0 -0
  137. quarchpy/config_files/__pycache__/__init__.cpython-312.pyc +0 -0
  138. quarchpy/config_files/__pycache__/quarch_config_parser.cpython-312.pyc +0 -0
  139. quarchpy/connection_specific/QPS/win-amd64/InstallType.dat +0 -1
  140. quarchpy/connection_specific/QPS/win-amd64/qps_lib/lin-arm64/javafx-base-21.0.1-linux-aarch64.jar +0 -0
  141. quarchpy/connection_specific/QPS/win-amd64/qps_lib/lin-arm64/javafx-graphics-21.0.1-linux-aarch64.jar +0 -0
  142. quarchpy/connection_specific/QPS/win-amd64/qps_lib/lin-arm64/javafx-swing-21.0.1-linux-aarch64.jar +0 -0
  143. quarchpy/connection_specific/QPS/win-amd64/qps_lib/mac-arm64/javafx-fxml-21.0.1-mac-aarch64.jar +0 -0
  144. quarchpy/connection_specific/QPS/win-amd64/qps_lib/mac-x64/javafx-controls-21.0.1-mac.jar +0 -0
  145. quarchpy/connection_specific/QPS/win-amd64/qps_lib/qis-1.44.2.jar +0 -0
  146. quarchpy/connection_specific/__pycache__/StreamChannels.cpython-311.pyc +0 -0
  147. quarchpy/connection_specific/__pycache__/StreamChannels.cpython-312.pyc +0 -0
  148. quarchpy/connection_specific/__pycache__/__init__.cpython-311.pyc +0 -0
  149. quarchpy/connection_specific/__pycache__/__init__.cpython-312.pyc +0 -0
  150. quarchpy/connection_specific/__pycache__/connection_QIS.cpython-311.pyc +0 -0
  151. quarchpy/connection_specific/__pycache__/connection_QIS.cpython-312.pyc +0 -0
  152. quarchpy/connection_specific/__pycache__/connection_QPS.cpython-311.pyc +0 -0
  153. quarchpy/connection_specific/__pycache__/connection_QPS.cpython-312.pyc +0 -0
  154. quarchpy/connection_specific/__pycache__/connection_ReST.cpython-311.pyc +0 -0
  155. quarchpy/connection_specific/__pycache__/connection_ReST.cpython-312.pyc +0 -0
  156. quarchpy/connection_specific/__pycache__/connection_Serial.cpython-311.pyc +0 -0
  157. quarchpy/connection_specific/__pycache__/connection_Serial.cpython-312.pyc +0 -0
  158. quarchpy/connection_specific/__pycache__/connection_TCP.cpython-311.pyc +0 -0
  159. quarchpy/connection_specific/__pycache__/connection_TCP.cpython-312.pyc +0 -0
  160. quarchpy/connection_specific/__pycache__/connection_USB.cpython-311.pyc +0 -0
  161. quarchpy/connection_specific/__pycache__/connection_USB.cpython-312.pyc +0 -0
  162. quarchpy/connection_specific/__pycache__/mDNS.cpython-311.pyc +0 -0
  163. quarchpy/connection_specific/__pycache__/mDNS.cpython-312.pyc +0 -0
  164. quarchpy/connection_specific/jdk_j21_jres/__pycache__/__init__.cpython-312.pyc +0 -0
  165. quarchpy/connection_specific/jdk_j21_jres/__pycache__/fix_permissions.cpython-312.pyc +0 -0
  166. quarchpy/connection_specific/serial/__pycache__/__init__.cpython-311.pyc +0 -0
  167. quarchpy/connection_specific/serial/__pycache__/__init__.cpython-312.pyc +0 -0
  168. quarchpy/connection_specific/serial/__pycache__/serialutil.cpython-311.pyc +0 -0
  169. quarchpy/connection_specific/serial/__pycache__/serialutil.cpython-312.pyc +0 -0
  170. quarchpy/connection_specific/serial/__pycache__/serialwin32.cpython-311.pyc +0 -0
  171. quarchpy/connection_specific/serial/__pycache__/serialwin32.cpython-312.pyc +0 -0
  172. quarchpy/connection_specific/serial/__pycache__/win32.cpython-311.pyc +0 -0
  173. quarchpy/connection_specific/serial/__pycache__/win32.cpython-312.pyc +0 -0
  174. quarchpy/connection_specific/serial/tools/__pycache__/__init__.cpython-311.pyc +0 -0
  175. quarchpy/connection_specific/serial/tools/__pycache__/__init__.cpython-312.pyc +0 -0
  176. quarchpy/connection_specific/serial/tools/__pycache__/list_ports.cpython-311.pyc +0 -0
  177. quarchpy/connection_specific/serial/tools/__pycache__/list_ports.cpython-312.pyc +0 -0
  178. quarchpy/connection_specific/serial/tools/__pycache__/list_ports_common.cpython-311.pyc +0 -0
  179. quarchpy/connection_specific/serial/tools/__pycache__/list_ports_common.cpython-312.pyc +0 -0
  180. quarchpy/connection_specific/serial/tools/__pycache__/list_ports_windows.cpython-311.pyc +0 -0
  181. quarchpy/connection_specific/serial/tools/__pycache__/list_ports_windows.cpython-312.pyc +0 -0
  182. quarchpy/debug/__pycache__/SystemTest.cpython-312.pyc +0 -0
  183. quarchpy/debug/__pycache__/__init__.cpython-312.pyc +0 -0
  184. quarchpy/debug/__pycache__/module_debug.cpython-312.pyc +0 -0
  185. quarchpy/debug/__pycache__/simple_terminal.cpython-312.pyc +0 -0
  186. quarchpy/debug/__pycache__/upgrade_quarchpy.cpython-312.pyc +0 -0
  187. quarchpy/debug/__pycache__/versionCompare.cpython-312.pyc +0 -0
  188. quarchpy/device/__pycache__/__init__.cpython-312.pyc +0 -0
  189. quarchpy/device/__pycache__/device.cpython-312.pyc +0 -0
  190. quarchpy/device/__pycache__/quarchArray.cpython-312.pyc +0 -0
  191. quarchpy/device/__pycache__/quarchPPM.cpython-312.pyc +0 -0
  192. quarchpy/device/__pycache__/quarchQPS.cpython-312.pyc +0 -0
  193. quarchpy/device/__pycache__/scanDevices.cpython-312.pyc +0 -0
  194. quarchpy/disk_test/__pycache__/AbsDiskFinder.cpython-312.pyc +0 -0
  195. quarchpy/disk_test/__pycache__/DiskTargetSelection.cpython-312.pyc +0 -0
  196. quarchpy/disk_test/__pycache__/__init__.cpython-312.pyc +0 -0
  197. quarchpy/disk_test/__pycache__/iometerDiskFinder.cpython-312.pyc +0 -0
  198. quarchpy/fio/__pycache__/FIO_interface.cpython-312.pyc +0 -0
  199. quarchpy/fio/__pycache__/__init__.cpython-312.pyc +0 -0
  200. quarchpy/iometer/__pycache__/__init__.cpython-312.pyc +0 -0
  201. quarchpy/iometer/__pycache__/gen_iometer_template.cpython-312.pyc +0 -0
  202. quarchpy/iometer/__pycache__/iometerFuncs.cpython-312.pyc +0 -0
  203. quarchpy/qis/__pycache__/StreamHeaderInfo.cpython-312.pyc +0 -0
  204. quarchpy/qis/__pycache__/__init__.cpython-312.pyc +0 -0
  205. quarchpy/qis/__pycache__/qisFuncs.cpython-312.pyc +0 -0
  206. quarchpy/qps/__pycache__/__init__.cpython-312.pyc +0 -0
  207. quarchpy/qps/__pycache__/qpsFuncs.cpython-312.pyc +0 -0
  208. quarchpy/user_interface/__pycache__/__init__.cpython-312.pyc +0 -0
  209. quarchpy/user_interface/__pycache__/user_interface.cpython-312.pyc +0 -0
  210. quarchpy/utilities/__pycache__/TestCenter.cpython-312.pyc +0 -0
  211. quarchpy/utilities/__pycache__/TimeValue.cpython-312.pyc +0 -0
  212. quarchpy/utilities/__pycache__/Version.cpython-312.pyc +0 -0
  213. quarchpy/utilities/__pycache__/__init__.cpython-312.pyc +0 -0
  214. {quarchpy-2.2.1.dev6.dist-info → quarchpy-2.2.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,398 @@
1
+ from quarchpy.device import quarchDevice
2
+ from quarchpy.qps import toQpsTimeStamp
3
+ from quarchpy.utilities.Version import Version
4
+ from quarchpy.user_interface.user_interface import requestDialog
5
+ import os, time, datetime, sys, logging
6
+
7
+ if sys.version_info[0] < 3:
8
+ from StringIO import StringIO
9
+ else:
10
+ from io import StringIO
11
+
12
+ current_milli_time = lambda: int(round(time.time() * 1000))
13
+ current_second_time = lambda: int(round(time.time()))
14
+
15
+
16
+ # Using standard Unix time, milliseconds since the epoch (midnight 1 January 1970 UTC)
17
+ # Should avoid issues with time zones and summer time correction but the local and host
18
+ # clocks should still be synchronised
19
+ def qpsNowStr():
20
+ return current_milli_time() # datetime supports microseconds
21
+
22
+
23
+ class quarchQPS(quarchDevice):
24
+ def __init__(self, quarchDevice):
25
+ self.quarchDevice = quarchDevice
26
+ self.ConType = quarchDevice.ConType
27
+ self.ConString = quarchDevice.ConString
28
+
29
+ self.connectionObj = quarchDevice.connectionObj
30
+ self.IP_address = quarchDevice.connectionObj.qps.host
31
+ self.port_number = quarchDevice.connectionObj.qps.port
32
+
33
+ def startStream(self, directory, unserInput=True):
34
+ """
35
+ directory - str - desired stream dir
36
+ 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
+ """
38
+ #time.sleep(1) # TODO remove this sleep once script->QPS timeing issue resolved. This works fine in the meantime
39
+ return quarchStream(self.quarchDevice, directory, unserInput)
40
+
41
+
42
+ class quarchStream:
43
+ def __init__(self, quarchQPS, directory, unserInput=True):
44
+ self.connectionObj = quarchQPS.connectionObj
45
+ self.IP_address = quarchQPS.connectionObj.qps.host
46
+ self.port_number = quarchQPS.connectionObj.qps.port
47
+ self.ConString = quarchQPS.ConString
48
+ self.ConType = quarchQPS.ConType
49
+ #time.sleep(1)
50
+ response = self.startQPSStream(directory)
51
+ if not "fail:" in response.lower():
52
+ return
53
+ else:
54
+ if unserInput is False:
55
+ raise Exception(response)
56
+ else:
57
+ self.failCheck(response)
58
+
59
+ def startQPSStream(self, newDirectory):
60
+ '''STARTS the stream '''
61
+ response = self.connectionObj.qps.sendCmdVerbose("$start stream \"" + str(newDirectory) + "\"")
62
+ if "Error" in response:
63
+ response = self.connectionObj.qps.sendCmdVerbose("$start stream " + str(newDirectory))
64
+ return response
65
+
66
+ def failCheck(self, response):
67
+ ''' handles failed starting of stream that requires input from user to fix.'''
68
+ while "fail:" in response.lower():
69
+ if "Fail: Directory already exists" in response:
70
+ newDir = requestDialog(message=response+" Please enter a new file name:")
71
+ response = self.startQPSStream(newDir)
72
+ else: # If its a failure we don't know how to handle.
73
+ raise Exception(response)
74
+ return response
75
+
76
+ def get_stats(self, format="df"):
77
+ """
78
+ Returns the QPS annotation statistics grid information as a pandas dataframe object
79
+
80
+ Returns
81
+ -------
82
+ df = : dataframe
83
+ The response text from QPS. If successful "ok. Saving stats to : file_name" otherwise returns the exception thrown
84
+ """
85
+ command_response = self.connectionObj.qps.sendCmdVerbose("$get stats", timeout=60).strip()
86
+ if command_response.startswith("Fail"):
87
+ raise Exception(command_response)
88
+
89
+ if format == "df":
90
+ try:
91
+ import warnings
92
+ import pandas as pd
93
+ warnings.simplefilter(action='ignore', category=FutureWarning)
94
+ except Exception as e:
95
+ logging.error(e)
96
+ logging.warning("pandas not imported correctly. Continuing")
97
+ pd.set_option('display.max_columns', None)
98
+ pd.set_option('display.width', 1024)
99
+ test_data = StringIO(command_response)
100
+
101
+ # pandas.read_csv() replaced error_bad_lines with on_bad_lines from v1.3.0
102
+ if Version.is_v1_ge_v2(pd.__version__, "1.3.0"):
103
+ retVal = pd.read_csv(test_data, sep=",", header=[0, 1], on_bad_lines="skip")
104
+ else:
105
+ retVal = pd.read_csv(test_data, sep=",", header=[0, 1], error_bad_lines=False)
106
+ elif format == "list":
107
+ retVal = []
108
+ for line in command_response.replace("\r\n", "\n").split("\n"):
109
+ row = []
110
+ for element in line.split(","):
111
+ row.append(element)
112
+ retVal.append(row)
113
+
114
+ return retVal
115
+
116
+ def stats_to_CSV(self, file_name=""):
117
+ """
118
+ Saves the statistics grid to a csv file
119
+
120
+ Parameters
121
+ ----------
122
+ file-name= : str, optional
123
+ The absolute path of the file you would like to save the csv to. If left empty then a filename will be give.
124
+ Default location is the path of the executable.
125
+ Returns
126
+ -------
127
+ command_response : str or None
128
+
129
+ The response text from QPS. If successful "ok. Saving stats to : file_name" otherwise returns the exception thrown
130
+ """
131
+ command_response = self.connectionObj.qps.sendCmdVerbose("$stats to csv \"" + file_name + "\"", timeout=60)
132
+ if command_response.startswith("Fail"):
133
+ raise Exception(command_response)
134
+ return command_response
135
+
136
+ def get_custom_stats_range(self, start_time, end_time):
137
+ """
138
+ Returns the QPS statistics information over a specific time ignoring any set annotations.
139
+
140
+ Parameters
141
+ ----------
142
+ start_time = : str
143
+ The time in seconds you would like the stats to start this can be in integer or string format.
144
+ or using the following format to specify daysDhours:minutes:seconds.milliseconds
145
+ xxxDxx:xx:xx.xxxx
146
+ end_time = : str
147
+ The time in seconds you would like the stats to stop this can be in integer or string format
148
+ or using the following format to specify daysDhours:minutes:seconds.milliseconds
149
+ xxxDxx:xx:xx.xxxx
150
+ Returns
151
+ -------
152
+ df = : dataframe
153
+ The response text from QPS. If successful "ok. Saving stats to : file_name" otherwise returns the exception thrown
154
+ """
155
+ try:
156
+ import warnings
157
+ import pandas as pd
158
+ warnings.simplefilter(action='ignore', category=FutureWarning)
159
+ except:
160
+ logging.warning("pandas not imported correctly")
161
+ command_response = self.connectionObj.qps.sendCmdVerbose(
162
+ "$get custom stats range " + str(start_time) + " " + str(end_time), timeout=60)
163
+ if command_response.startswith("Fail"):
164
+ raise Exception(command_response)
165
+ test_data = StringIO(command_response)
166
+ try:
167
+ pd.set_option('display.max_columns', None)
168
+ pd.set_option('display.width', 1024)
169
+ # df = pd.read_csv(test_data, sep=",", header=[0,1])
170
+ # pandas.read_csv() replaced error_bad_lines with on_bad_lines from v1.3.0
171
+ if Version.is_v1_ge_v2(pd.__version__, "1.3.0"):
172
+ df = pd.read_csv(test_data, sep=",", header=[0, 1], on_bad_lines="skip")
173
+ else:
174
+ df = pd.read_csv(test_data, sep=",", header=[0, 1], error_bad_lines=False)
175
+ except Exception as e:
176
+ logging.error("Unable to create pandas data frame from command response :" + str(command_response))
177
+ raise e
178
+ return df
179
+
180
+ def takeSnapshot(self):
181
+ """
182
+ Triggers QPS take snapshot function and saves it in the streams directory.
183
+ """
184
+ command_response = self.connectionObj.qps.sendCmdVerbose("$take snapshot")
185
+ if command_response.startswith("Fail"):
186
+ raise Exception(command_response)
187
+ return (command_response)
188
+
189
+ def getStreamState(self):
190
+ """
191
+ Askes QPS for the stream status.
192
+ QPS stream state != Module stream state.
193
+ This is different from "rec stream?" cmd to the module as it will return "streaming" when the module is nolonger streaming but QPS is still receiveing stream data from the module.
194
+ ei the module has stopped streaming but is emptying the stream buffer.
195
+ """
196
+ command_response = self.connectionObj.qps.sendCmdVerbose("$stream state")
197
+ if command_response.startswith("Fail"):
198
+ raise Exception(command_response)
199
+ return (command_response)
200
+
201
+ def addAnnotation(self, title, annotationTime=0, extraText="", yPos="", titleColor="", annotationColor="",
202
+ annotationType="", annotationGroup=""):
203
+ """
204
+ Adds a custom annotation to stream with given parameters.
205
+
206
+ Parameters
207
+ ----------
208
+ title= : str
209
+ The title appears next to the annotation in the stream
210
+ extraText= : str, optional
211
+ The additional text that can be viewed when selecting the annotation
212
+ yPos : str, optional
213
+ The percetange of how high up the screen the annotation should appear 0 is the bottom and 100 the top
214
+ titleColor : str, optional
215
+ The color of the text next to the annotation in hex format 000000 to FFFFFF
216
+ annotationColor : str, optional
217
+ The color of the annotation marker in hex format 000000 to FFFFFF
218
+ annotationGroup : str, optional
219
+ The group the annotation belongs to
220
+ annotationTime : int, optional
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
+
223
+ Returns
224
+ -------
225
+ command_response : str or None
226
+
227
+ The response text from QPS. "ok" if annotation successfully added
228
+ """
229
+ annotationTime = str(annotationTime)
230
+ annotationType = annotationType.lower()
231
+ if annotationType == "" or annotationType == "annotation":
232
+ annotationType = "annotate"
233
+ elif annotationType == "comment":
234
+ pass # already in the correct format for command
235
+ else:
236
+ retString = "Fail annotationType must be 'annotation' or 'comment'"
237
+ logging.warning(retString)
238
+ return retString
239
+
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
+
276
+ def addComment(self, title, commentTime=0, extraText="", yPos="", titleColor="", commentColor="", annotationType="",
277
+ annotationGroup=""):
278
+ # Comments are just annotations that do not affect the statistics grid.
279
+ # This function was kept to be backwards compatible and is a simple pass through to add annotation.
280
+ if annotationType == "":
281
+ annotationType = "comment"
282
+ return self.addAnnotation(title=title, annotationTime=commentTime, extraText=extraText, yPos=yPos,
283
+ titleColor=titleColor, annotationColor=commentColor, annotationType=annotationType,
284
+ annotationGroup=annotationGroup)
285
+
286
+ def saveCSV(self, filePath, linesPerFile=None, cr=None, delimiter=None, timeout=60):
287
+ """
288
+ Saves the stream to csv file at specified location
289
+
290
+ Parameters
291
+ ----------
292
+ filePath= : str
293
+ The file path that ou would like the CSV file saved to.
294
+ linesPerFile= : str, optional
295
+ The number of lines per CSV file. Can be any int number or "all"
296
+ cr : bool, optional
297
+ Whether the end of line terminator should include a carriage return.
298
+ delimiter : str, optional
299
+ The delimiter to be used by the csv file.
300
+ timeout : str, otptional
301
+ The timeout to wait for a response from QPS
302
+
303
+ Returns
304
+ -------
305
+ command_response : str or None
306
+ The response text from QPS. "ok" if command is successful or the stack trace if exception thrown
307
+ """
308
+ args = ""
309
+
310
+ if linesPerFile != None:
311
+ args += " -l" + str(linesPerFile)
312
+ if cr != None:
313
+ if cr is True:
314
+ args += " -cyes"
315
+ elif cr is False:
316
+ args += " -cno"
317
+ if delimiter != None:
318
+ args += " -s" + delimiter
319
+
320
+ # , filePath, linesPerFile, cr, delimiter
321
+ return self.connectionObj.qps.sendCmdVerbose("$save csv \"" + filePath + "\" " + args, timeout=timeout)
322
+
323
+ def createChannel(self, channelName, channelGroup, baseUnits, usePrefix):
324
+ # Conditions to convert false / true inputs to specification input
325
+ if usePrefix == False:
326
+ usePrefix = "no"
327
+ if usePrefix == True:
328
+ usePrefix = "yes"
329
+
330
+ return self.connectionObj.qps.sendCmdVerbose(
331
+ "$create channel " + channelName + " " + channelGroup + " " + baseUnits + " " + usePrefix)
332
+
333
+ def hideChannel(self, channelSpecifier):
334
+ return self.connectionObj.qps.sendCmdVerbose("$hide channel " + channelSpecifier)
335
+
336
+ def showChannel(self, channelSpecifier):
337
+ return self.connectionObj.qps.sendCmdVerbose("$show channel " + channelSpecifier)
338
+
339
+ def myChannels(self):
340
+ return self.connectionObj.qps.sendCmdVerbose("$channels")
341
+
342
+ def channels(self):
343
+ return self.connectionObj.qps.sendCmdVerbose("$channels").splitlines()
344
+
345
+ def stopStream(self):
346
+ return self.connectionObj.qps.sendCmdVerbose("$stop stream")
347
+
348
+ def stopStreamAndAllowBufferToEmpty(self, checkInterval=0.5):
349
+ self.stopStream()
350
+ streamState = self.getStreamState().lower()
351
+ while "running" in streamState:
352
+ logging.debug("Stream buffer still emptying: " + streamState)
353
+ time.sleep(checkInterval)
354
+ streamState = self.getStreamState().lower()
355
+ logging.debug("QPS no longer Streaming: " + streamState)
356
+
357
+ def hideAllDefaultChannels(self):
358
+
359
+ # TODO query QPS / Device for all channel names and hide all of them
360
+ # All Default Channels
361
+ self.hideChannel("3.3v:voltage")
362
+ self.hideChannel("3v3:voltage")
363
+ self.hideChannel("5v:voltage")
364
+ self.hideChannel("12v:voltage")
365
+ self.hideChannel("3v3:current")
366
+ self.hideChannel("3.3v:current")
367
+ self.hideChannel("5v:current")
368
+ self.hideChannel("12v:current")
369
+ self.hideChannel("3v3:power")
370
+ self.hideChannel("3.3v:power")
371
+ self.hideChannel("5v:power")
372
+ self.hideChannel("12v:power")
373
+ self.hideChannel("tot:power")
374
+ # Default PAM channels
375
+ self.hideChannel("perst#:digital")
376
+ self.hideChannel("wake#:digital")
377
+ self.hideChannel("lkreq#:digital")
378
+ self.hideChannel("smclk:digital")
379
+ self.hideChannel("smdat:digital")
380
+
381
+ # function to add a data point the the stream
382
+ # time value will default to current time if none passed
383
+ def addDataPoint(self, channelName, groupName, dataValue, dataPointTime=0, timeFormat="unix"):
384
+ '''
385
+ channelName - str
386
+ groupName - str
387
+ dataValue - int/float value of the data point
388
+ dataPointTime=0 - time of the data point
389
+ timeFormat="unix" - the format of the given time
390
+ '''
391
+ if dataPointTime == None or dataPointTime == 0:
392
+ dataPointTime = qpsNowStr()
393
+ else:
394
+ dataPointTime = toQpsTimeStamp(dataPointTime)
395
+
396
+ self.connectionObj.qps.sendCmdVerbose(
397
+ "$stream data add " + channelName + " " + groupName + " " + str(dataPointTime) + " " + str(
398
+ dataValue) + " " + timeFormat)
@@ -179,6 +179,7 @@ def list_network(target_conn="all", debugPring=False, lanTimeout=1, ipAddressLoo
179
179
  retVal={}
180
180
  lan_modules = dict()
181
181
  specifiedDevice = None
182
+ moduleFound = None
182
183
  # Broadcast the message.
183
184
  logging.debug("Broadcast LAN discovery message for UDP scan to all network interfaces")
184
185
  ipList = socket.gethostbyname_ex(socket.gethostname())
@@ -199,7 +200,7 @@ def list_network(target_conn="all", debugPring=False, lanTimeout=1, ipAddressLoo
199
200
 
200
201
  if ipAddressLookup is not None:
201
202
  # Attempts to find the device through UDP then REST
202
- specifiedDevice = lookupDevice(str(ipAddressLookup).strip(), mySocket, lan_modules)
203
+ specifiedDevice, moduleFound = lookupDevice(str(ipAddressLookup).strip(), mySocket, lan_modules, moduleFound)
203
204
 
204
205
 
205
206
  mySocket.sendto(b'Discovery: Who is out there?\0\n', ('255.255.255.255', 30303))
@@ -266,7 +267,11 @@ def list_network(target_conn="all", debugPring=False, lanTimeout=1, ipAddressLoo
266
267
  lan_modules["TCP:" + ip_module] = module_name
267
268
  logging.debug("Found TCP module: " + module_name)
268
269
  mySocket.close()
269
-
270
+ if ipAddressLookup is not None:
271
+ if moduleFound is None:
272
+ printText("IP Scan failed, no module found.")
273
+ else:
274
+ printText("IP Scan succeeded, module found: " + moduleFound)
270
275
  logging.debug("Finished UDP scan")
271
276
  retVal.update(lan_modules)
272
277
  return retVal
@@ -304,7 +309,7 @@ def get_user_level_serial_number(network_modules):
304
309
 
305
310
 
306
311
  ''''''
307
- def lookupDevice(ipAddressLookup, mySocket, lan_modules):
312
+ def lookupDevice(ipAddressLookup, mySocket, lan_modules, module_found):
308
313
  try:
309
314
  specifiedDevice =None
310
315
  # For future reference, 0 is the C terminator for a string
@@ -318,8 +323,8 @@ def lookupDevice(ipAddressLookup, mySocket, lan_modules):
318
323
  # Check to see if the response contains the connection protocol
319
324
  return specifiedDevice
320
325
  except Exception as e:
321
- logging.warning("Error during UDP lookup of IP address "+ str(ipAddressLookup) +" Error: " + str(e))
322
- logging.warning("No Quarch module found at this address. Please check the IP address and that you can ping it.\r\n")
326
+ logging.debug("Error during UDP lookup of IP address "+ str(ipAddressLookup) +" Error: " + str(e))
327
+ logging.debug("No Quarch module found at this address. Please check the IP address and that you can ping it.\r\n")
323
328
 
324
329
  #return None # Commented out, attempt a REST connection with IP. This is what other quarch applications do.
325
330
  if specifiedDevice is None: #Only True if TCP not found or errored
@@ -333,10 +338,11 @@ def lookupDevice(ipAddressLookup, mySocket, lan_modules):
333
338
  # Exit as device was found correctly
334
339
  # Add the item to list
335
340
  lan_modules["REST:" + str(ipAddressLookup).replace("\r\n", "")] = restDevice
341
+ module_found = restDevice
336
342
  specifiedDevice=None # Don't return rest connection, to bypass tcp parsing.
337
343
  except Exception as e:
338
- logging.warning("Error During REST scan of IP address " + str(ipAddressLookup) + " Error: " + str(e))
339
- logging.warning("Please check the IP address and that you can ping it.\r\n")
344
+ logging.debug("Error During REST scan of IP address " + str(ipAddressLookup) + " Error: " + str(e))
345
+ logging.debug("Please check the IP address and that you can ping it.\r\n")
340
346
  try:
341
347
  # from threading import Thread
342
348
  # t = Thread(target=connection_TCP.TCPConn, args=(str(ipAddressLookup).replace("\r\n", ""),))
@@ -355,12 +361,14 @@ def lookupDevice(ipAddressLookup, mySocket, lan_modules):
355
361
  # Exit as device was found correctly
356
362
  # Add the item to list
357
363
  lan_modules["TCP:" + str(ipAddressLookup).replace("\r\n", "")] = tcpDevice
364
+ module_found = tcpDevice
358
365
  specifiedDevice=None # Don't return tcp connection, to bypass tcp parsing.
359
366
  except Exception as e:
360
- logging.warning("Error During TCP scan of IP address " + str(ipAddressLookup) + " Error: " + str(e))
361
- logging.warning("Please check the IP address and that you can ping it.\r\n")
367
+ logging.debug("Error During TCP scan of IP address " + str(ipAddressLookup) + " Error: " + str(e))
368
+ logging.debug("Please check the IP address and that you can ping it.\r\n")
369
+
362
370
  # Needs to return None so previous method will not attempt another lookup.
363
- return specifiedDevice
371
+ return specifiedDevice, module_found
364
372
 
365
373
 
366
374
 
quarchpy/docs/CHANGES.rst CHANGED
@@ -13,6 +13,18 @@ Quarchpy
13
13
  Change Log
14
14
  ----------
15
15
 
16
+
17
+ 2.2.2
18
+ -----
19
+ - New QPS 1.44 and QIS 1.46
20
+ - Added support for automatic creation of default synthetic channels when connecting to module via QIS
21
+ - Minor bug fixes
22
+
23
+ 2.2.1
24
+ -----
25
+ - New QPS v1.43 and QIS v1.45 packaged with java 21 with no need for installed java.
26
+ - Minor bug fixes
27
+
16
28
  2.2.0
17
29
  -----
18
30
  - New QPS v1.42 and QIS v1.44 packaged with java 21 with no need for installed java.