quarchpy 2.1.20.dev3__py2.py3-none-any.whl → 2.1.22__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 (184) hide show
  1. quarchpy/.idea/.name +1 -1
  2. quarchpy/.idea/modules.xml +1 -0
  3. quarchpy/.idea/quarchpy.iml +4 -1
  4. quarchpy/.idea/workspace.xml +231 -21
  5. quarchpy/__pycache__/__init__.cpython-311.pyc +0 -0
  6. quarchpy/__pycache__/_version.cpython-311.pyc +0 -0
  7. quarchpy/__pycache__/connection.cpython-311.pyc +0 -0
  8. quarchpy/__pycache__/run.cpython-311.pyc +0 -0
  9. quarchpy/_version.py +1 -1
  10. quarchpy/config_files/__pycache__/__init__.cpython-311.pyc +0 -0
  11. quarchpy/config_files/__pycache__/quarch_config_parser.cpython-311.pyc +0 -0
  12. quarchpy/connection_specific/QPS/qis/qis.jar +0 -0
  13. quarchpy/connection_specific/QPS/qis/qis_lib/{CInterface-1.7.8.jar → CInterface-1.8.0.jar} +0 -0
  14. quarchpy/connection_specific/QPS/{qps_lib/QuarchCommon-0.2.9.jar → qis/qis_lib/QuarchCommon-0.2.12.jar} +0 -0
  15. quarchpy/connection_specific/QPS/qis/qis_lib/jmdns-3.5.9.jar +0 -0
  16. quarchpy/connection_specific/QPS/qis/resources/filters/iec_filters.xml +0 -9
  17. quarchpy/connection_specific/QPS/qps.jar +0 -0
  18. quarchpy/connection_specific/QPS/{qis/qis_lib/QuarchCommon-0.2.9.jar → qps_lib/QuarchCommon-0.2.12.jar} +0 -0
  19. quarchpy/connection_specific/QPS/qps_lib/{qis-1.40.jar → qis-1.41.jar} +0 -0
  20. quarchpy/connection_specific/QPS/resources/profiles/3_PHASE_PAM_AC_DEFAULT.scf +90 -0
  21. quarchpy/connection_specific/QPS/resources/profiles/3_PHASE_PAM_AC_FULL.scf +144 -0
  22. quarchpy/connection_specific/QPS/scriptCommands.txt +2 -2
  23. quarchpy/connection_specific/__pycache__/StreamChannels.cpython-311.pyc +0 -0
  24. quarchpy/connection_specific/__pycache__/__init__.cpython-311.pyc +0 -0
  25. quarchpy/connection_specific/__pycache__/connection_QIS.cpython-311.pyc +0 -0
  26. quarchpy/connection_specific/__pycache__/connection_QPS.cpython-311.pyc +0 -0
  27. quarchpy/connection_specific/__pycache__/connection_ReST.cpython-311.pyc +0 -0
  28. quarchpy/connection_specific/__pycache__/connection_Serial.cpython-311.pyc +0 -0
  29. quarchpy/connection_specific/__pycache__/connection_TCP.cpython-311.pyc +0 -0
  30. quarchpy/connection_specific/__pycache__/connection_Telnet.cpython-311.pyc +0 -0
  31. quarchpy/connection_specific/__pycache__/connection_USB.cpython-311.pyc +0 -0
  32. quarchpy/connection_specific/__pycache__/connection_mDNS.cpython-311.pyc +0 -0
  33. quarchpy/connection_specific/connection_QIS.py +8 -3
  34. quarchpy/connection_specific/serial/__pycache__/__init__.cpython-311.pyc +0 -0
  35. quarchpy/connection_specific/serial/__pycache__/rfc2217.cpython-311.pyc +0 -0
  36. quarchpy/connection_specific/serial/__pycache__/rs485.cpython-311.pyc +0 -0
  37. quarchpy/connection_specific/serial/__pycache__/serialcli.cpython-311.pyc +0 -0
  38. quarchpy/connection_specific/serial/__pycache__/serialjava.cpython-311.pyc +0 -0
  39. quarchpy/connection_specific/serial/__pycache__/serialposix.cpython-311.pyc +0 -0
  40. quarchpy/connection_specific/serial/__pycache__/serialutil.cpython-311.pyc +0 -0
  41. quarchpy/connection_specific/serial/__pycache__/serialwin32.cpython-311.pyc +0 -0
  42. quarchpy/connection_specific/serial/__pycache__/win32.cpython-311.pyc +0 -0
  43. quarchpy/connection_specific/serial/threaded/__pycache__/__init__.cpython-311.pyc +0 -0
  44. quarchpy/connection_specific/serial/tools/__pycache__/__init__.cpython-311.pyc +0 -0
  45. quarchpy/connection_specific/serial/tools/__pycache__/hexlify_codec.cpython-311.pyc +0 -0
  46. quarchpy/connection_specific/serial/tools/__pycache__/list_ports.cpython-311.pyc +0 -0
  47. quarchpy/connection_specific/serial/tools/__pycache__/list_ports_common.cpython-311.pyc +0 -0
  48. quarchpy/connection_specific/serial/tools/__pycache__/list_ports_linux.cpython-311.pyc +0 -0
  49. quarchpy/connection_specific/serial/tools/__pycache__/list_ports_osx.cpython-311.pyc +0 -0
  50. quarchpy/connection_specific/serial/tools/__pycache__/list_ports_posix.cpython-311.pyc +0 -0
  51. quarchpy/connection_specific/serial/tools/__pycache__/list_ports_windows.cpython-311.pyc +0 -0
  52. quarchpy/connection_specific/serial/tools/__pycache__/miniterm.cpython-311.pyc +0 -0
  53. quarchpy/connection_specific/serial/urlhandler/__pycache__/__init__.cpython-311.pyc +0 -0
  54. quarchpy/connection_specific/serial/urlhandler/__pycache__/protocol_alt.cpython-311.pyc +0 -0
  55. quarchpy/connection_specific/serial/urlhandler/__pycache__/protocol_hwgrep.cpython-311.pyc +0 -0
  56. quarchpy/connection_specific/serial/urlhandler/__pycache__/protocol_loop.cpython-311.pyc +0 -0
  57. quarchpy/connection_specific/serial/urlhandler/__pycache__/protocol_rfc2217.cpython-311.pyc +0 -0
  58. quarchpy/connection_specific/serial/urlhandler/__pycache__/protocol_socket.cpython-311.pyc +0 -0
  59. quarchpy/connection_specific/serial/urlhandler/__pycache__/protocol_spy.cpython-311.pyc +0 -0
  60. quarchpy/connection_specific/usb_libs/MS32/__pycache__/__init__.cpython-311.pyc +0 -0
  61. quarchpy/connection_specific/usb_libs/MS64/__pycache__/__init__.cpython-311.pyc +0 -0
  62. quarchpy/connection_specific/usb_libs/__pycache__/__init__.cpython-311.pyc +0 -0
  63. quarchpy/connection_specific/usb_libs/__pycache__/libusb1.cpython-311.pyc +0 -0
  64. quarchpy/connection_specific/usb_libs/__pycache__/usb1.cpython-311.pyc +0 -0
  65. quarchpy/debug/__pycache__/SystemTest.cpython-311.pyc +0 -0
  66. quarchpy/debug/__pycache__/__init__.cpython-311.pyc +0 -0
  67. quarchpy/debug/__pycache__/__main__.cpython-311.pyc +0 -0
  68. quarchpy/debug/__pycache__/module_debug.cpython-311.pyc +0 -0
  69. quarchpy/debug/__pycache__/simple_terminal.cpython-311.pyc +0 -0
  70. quarchpy/debug/__pycache__/upgrade_quarchpy.cpython-311.pyc +0 -0
  71. quarchpy/debug/__pycache__/versionCompare.cpython-311.pyc +0 -0
  72. quarchpy/device/__pycache__/__init__.cpython-311.pyc +0 -0
  73. quarchpy/device/__pycache__/device.cpython-311.pyc +0 -0
  74. quarchpy/device/__pycache__/quarchArray.cpython-311.pyc +0 -0
  75. quarchpy/device/__pycache__/quarchPPM.cpython-311.pyc +0 -0
  76. quarchpy/device/__pycache__/quarchQPS.cpython-311.pyc +0 -0
  77. quarchpy/device/__pycache__/scanDevices.cpython-311.pyc +0 -0
  78. quarchpy/device/scanDevices.py +1 -1
  79. quarchpy/disk_test/__pycache__/AbsDiskFinder.cpython-311.pyc +0 -0
  80. quarchpy/disk_test/__pycache__/DiskTargetSelection.cpython-311.pyc +0 -0
  81. quarchpy/disk_test/__pycache__/__init__.cpython-311.pyc +0 -0
  82. quarchpy/disk_test/__pycache__/iometerDiskFinder.cpython-311.pyc +0 -0
  83. quarchpy/docs/CHANGES.rst +10 -0
  84. quarchpy/docs/__pycache__/__init__.cpython-311.pyc +0 -0
  85. quarchpy/docs/__pycache__/conf.cpython-311.pyc +0 -0
  86. quarchpy/docs/_build/doctrees/CHANGES.doctree +0 -0
  87. quarchpy/docs/_build/doctrees/environment.pickle +0 -0
  88. quarchpy/docs/_build/doctrees/index.doctree +0 -0
  89. quarchpy/docs/_build/doctrees/readme.doctree +0 -0
  90. quarchpy/docs/_build/doctrees/source/changelog.doctree +0 -0
  91. quarchpy/docs/_build/doctrees/source/licenses.doctree +0 -0
  92. quarchpy/docs/_build/doctrees/source/modules.doctree +0 -0
  93. quarchpy/docs/_build/doctrees/source/quarchpy.calibration.doctree +0 -0
  94. quarchpy/docs/_build/doctrees/source/quarchpy.config_files.doctree +0 -0
  95. quarchpy/docs/_build/doctrees/source/quarchpy.connection_specific.doctree +0 -0
  96. quarchpy/docs/_build/doctrees/source/quarchpy.debug.doctree +0 -0
  97. quarchpy/docs/_build/doctrees/source/quarchpy.device.doctree +0 -0
  98. quarchpy/docs/_build/doctrees/source/quarchpy.disk_test.doctree +0 -0
  99. quarchpy/docs/_build/doctrees/source/quarchpy.doctree +0 -0
  100. quarchpy/docs/_build/doctrees/source/quarchpy.fio.doctree +0 -0
  101. quarchpy/docs/_build/doctrees/source/quarchpy.iometer.doctree +0 -0
  102. quarchpy/docs/_build/doctrees/source/quarchpy.qis.doctree +0 -0
  103. quarchpy/docs/_build/doctrees/source/quarchpy.qps.doctree +0 -0
  104. quarchpy/docs/_build/doctrees/source/quarchpy.user_interface.doctree +0 -0
  105. quarchpy/docs/_build/doctrees/source/quarchpy.utilities.doctree +0 -0
  106. quarchpy/docs/_build/doctrees/source/readme.doctree +0 -0
  107. quarchpy/docs/_build/html/CHANGES.html +142 -116
  108. quarchpy/docs/_build/html/_sources/CHANGES.rst.txt +20 -1
  109. quarchpy/docs/_build/html/_static/alabaster.css +9 -14
  110. quarchpy/docs/_build/html/_static/basic.css +1 -1
  111. quarchpy/docs/_build/html/_static/pygments.css +1 -1
  112. quarchpy/docs/_build/html/genindex.html +33 -11
  113. quarchpy/docs/_build/html/index.html +65 -62
  114. quarchpy/docs/_build/html/objects.inv +0 -0
  115. quarchpy/docs/_build/html/py-modindex.html +11 -7
  116. quarchpy/docs/_build/html/readme.html +6 -7
  117. quarchpy/docs/_build/html/search.html +6 -7
  118. quarchpy/docs/_build/html/searchindex.js +1 -1
  119. quarchpy/docs/_build/html/source/changelog.html +201 -171
  120. quarchpy/docs/_build/html/source/licenses.html +6 -7
  121. quarchpy/docs/_build/html/source/modules.html +7 -8
  122. quarchpy/docs/_build/html/source/quarchpy.calibration.html +6 -7
  123. quarchpy/docs/_build/html/source/quarchpy.config_files.html +6 -7
  124. quarchpy/docs/_build/html/source/quarchpy.connection_specific.html +9 -8
  125. quarchpy/docs/_build/html/source/quarchpy.debug.html +6 -7
  126. quarchpy/docs/_build/html/source/quarchpy.device.html +81 -12
  127. quarchpy/docs/_build/html/source/quarchpy.disk_test.html +6 -7
  128. quarchpy/docs/_build/html/source/quarchpy.fio.html +34 -9
  129. quarchpy/docs/_build/html/source/quarchpy.html +18 -8
  130. quarchpy/docs/_build/html/source/quarchpy.iometer.html +6 -7
  131. quarchpy/docs/_build/html/source/quarchpy.qis.html +23 -28
  132. quarchpy/docs/_build/html/source/quarchpy.qps.html +8 -9
  133. quarchpy/docs/_build/html/source/quarchpy.user_interface.html +15 -8
  134. quarchpy/docs/_build/html/source/quarchpy.utilities.html +6 -7
  135. quarchpy/docs/_build/html/source/readme.html +6 -7
  136. quarchpy/fio/__pycache__/FIO_interface.cpython-311.pyc +0 -0
  137. quarchpy/fio/__pycache__/__init__.cpython-311.pyc +0 -0
  138. quarchpy/fio/__pycache__/fioDiskFinder.cpython-311.pyc +0 -0
  139. quarchpy/fio/__pycache__/performanceClass.cpython-311.pyc +0 -0
  140. quarchpy/fio/__pycache__/test_performance_class.cpython-311.pyc +0 -0
  141. quarchpy/iometer/__pycache__/__init__.cpython-311.pyc +0 -0
  142. quarchpy/iometer/__pycache__/gen_iometer_template.cpython-311.pyc +0 -0
  143. quarchpy/iometer/__pycache__/iometerFuncs.cpython-311.pyc +0 -0
  144. quarchpy/qis/__pycache__/StreamHeaderInfo.cpython-311.pyc +0 -0
  145. quarchpy/qis/__pycache__/__init__.cpython-311.pyc +0 -0
  146. quarchpy/qis/__pycache__/qisFuncs.cpython-311.pyc +0 -0
  147. quarchpy/qis/qisFuncs.py +4 -3
  148. quarchpy/qps/__pycache__/__init__.cpython-311.pyc +0 -0
  149. quarchpy/qps/__pycache__/qpsFuncs.cpython-311.pyc +0 -0
  150. quarchpy/qps/qpsFuncs.py +3 -1
  151. quarchpy/user_interface/__pycache__/__init__.cpython-311.pyc +0 -0
  152. quarchpy/user_interface/__pycache__/user_interface.cpython-311.pyc +0 -0
  153. quarchpy/user_interface/user_interface.py +17 -1
  154. quarchpy/utilities/__pycache__/BitManipulation.cpython-311.pyc +0 -0
  155. quarchpy/utilities/__pycache__/TestCenter.cpython-311.pyc +0 -0
  156. quarchpy/utilities/__pycache__/TimeValue.cpython-311.pyc +0 -0
  157. quarchpy/utilities/__pycache__/Version.cpython-311.pyc +0 -0
  158. quarchpy/utilities/__pycache__/__init__.cpython-311.pyc +0 -0
  159. {quarchpy-2.1.20.dev3.dist-info → quarchpy-2.1.22.dist-info}/METADATA +11 -1
  160. {quarchpy-2.1.20.dev3.dist-info → quarchpy-2.1.22.dist-info}/RECORD +162 -155
  161. quarchpy/.idea/inspectionProfiles/Project_Default.xml +0 -26
  162. quarchpy/connection_specific/QPS/qis/qis_lib/CInterface-1.7.04.jar +0 -0
  163. quarchpy/connection_specific/QPS/qis/qis_lib/QuarchCommon-0.2.6.jar +0 -0
  164. quarchpy/connection_specific/QPS/qis/qis_lib/commons-csv-1.8.jar +0 -0
  165. quarchpy/connection_specific/QPS/qis/qis_lib/commons-lang3-3.2.1.jar +0 -0
  166. quarchpy/connection_specific/QPS/qis/resources/filters/filters.csv +0 -1004
  167. quarchpy/connection_specific/QPS/qis/resources/filters/iec_filters.xml.bak +0 -26
  168. quarchpy/connection_specific/QPS/qps_lib/QuarchCommon-0.2.6.jar +0 -0
  169. quarchpy/connection_specific/QPS/qps_lib/commons-lang3-3.12.0.jar +0 -0
  170. quarchpy/connection_specific/QPS/qps_lib/jfxtras-labs-8.0-r6.jar +0 -0
  171. quarchpy/connection_specific/QPS/qps_lib/opencsv-5.9.jar +0 -0
  172. quarchpy/connection_specific/QPS/qps_lib/qis-1.39.jar +0 -0
  173. quarchpy/connection_specific/connection_QIS.py.bak +0 -1738
  174. quarchpy/debug/TextScanIP.py +0 -11
  175. quarchpy/device/device.py.bak +0 -504
  176. quarchpy/device/quarchPPM.py.bak +0 -67
  177. quarchpy/device/quarchQPS.py.bak +0 -396
  178. quarchpy/device/scanDevices.py.bak +0 -661
  179. quarchpy/docs/CHANGES.rst.bak +0 -364
  180. quarchpy/qps/qpsFuncs.py.bak +0 -231
  181. quarchpy/user_interface/user_interface.py.bak +0 -749
  182. quarchpy/utilities/TestCenter.py.bak +0 -150
  183. {quarchpy-2.1.20.dev3.dist-info → quarchpy-2.1.22.dist-info}/WHEEL +0 -0
  184. {quarchpy-2.1.20.dev3.dist-info → quarchpy-2.1.22.dist-info}/top_level.txt +0 -0
@@ -1,661 +0,0 @@
1
- import time
2
- import socket
3
- import sys
4
- import operator
5
- import logging
6
- import os
7
-
8
- from sys import platform
9
-
10
- from quarchpy.config_files.quarch_config_parser import return_module_type_list
11
- from quarchpy.user_interface import*
12
- from quarchpy.user_interface import User_interface
13
- try:
14
- from quarchpy.connection_specific.connection_USB import importUSB # , USBConn
15
- except:
16
- printText("System Compatibility issue - Is your Python architecture consistent with the Operating System?")
17
- pass
18
- from quarchpy.device import quarchDevice, quarchArray
19
- from quarchpy.connection_specific.connection_Serial import serialList, serial
20
- from quarchpy.device.quarchArray import isThisAnArrayController
21
- from quarchpy.connection_specific.connection_USB import TQuarchUSB_IF
22
- from quarchpy.connection_specific import connection_ReST
23
-
24
- # TODO: bodge bodge bodge
25
- from quarchpy.utilities import TestCenter
26
-
27
-
28
- '''
29
- Merge two dictionaries and return the result
30
- '''
31
- def mergeDict(x, y):
32
- if (y is None):
33
- return x
34
- else:
35
- merged = x.copy()
36
- merged.update(y)
37
- return merged
38
-
39
-
40
- '''
41
- Scan for Quarch modules across all available COM ports
42
- '''
43
- def list_serial(debuPrint=False):
44
- serial_ports = serialList.comports()
45
- serial_modules = dict()
46
-
47
- for i in serial_ports:
48
- logging.debug("Scanning for Quarch devices on: " + str(i))
49
- try:
50
- ser = serial.Serial(i[0], 19200, timeout=0.5)
51
- ser.write(b'*serial?\r\n')
52
- s = ser.read(size=64)
53
- serial_module = s.splitlines()[1]
54
-
55
- serial_module = str(serial_module).replace("'", "").replace("b", "")
56
-
57
- if "QTL" not in serial_module:
58
- serial_module = "QTL" + serial_module
59
-
60
- module = str(i[0]), str(serial_module)
61
-
62
- if serial_module[7] == "-" and serial_module[10] == "-":
63
- serial_modules["SERIAL:" + str(i[0])] = serial_module
64
- logging.debug("Located quarch module: " + serial_module)
65
-
66
- ser.close()
67
- logging.debug("Finished scanning for Quarch devices on: " + str(i))
68
- except Exception as err:
69
- logging.debug("Exception during serial scan: " + str(err))
70
- pass
71
- return serial_modules
72
-
73
-
74
- '''
75
- Scan for all Quarch devices available over USB
76
- '''
77
- def list_USB(debuPrint=False):
78
- QUARCH_VENDOR_ID = 0x16d0
79
- QUARCH_PRODUCT_ID1 = 0x0449
80
-
81
- usb1 = importUSB()
82
-
83
- context = usb1.USBContext()
84
- usb_list = context.getDeviceList()
85
-
86
- if (debuPrint): printText(usb_list)
87
-
88
- usb_modules = dict()
89
- hdList = []
90
-
91
- usb_permission_error = False
92
-
93
- for i in usb_list:
94
- if hex(i.device_descriptor.idVendor) == hex(QUARCH_VENDOR_ID) and hex(i.device_descriptor.idProduct) == hex(
95
- QUARCH_PRODUCT_ID1):
96
- try:
97
- logging.debug("Opening USB handle to quarch module: " + str(i))
98
- i_handle = i.open()
99
- except Exception as err:
100
- logging.debug("USB port open exception: " + str(err))
101
- if "LIBUSB_ERROR_ACCESS [-3]" in str(err):
102
- logging.debug("Unable to communicate with Quarch module over USB, device may be in use already.")
103
- if not platform == "win32":
104
- if not os.path.isfile("/etc/udev/rules.d/20-quarchmodules.rules"):
105
- usb_permission_error = True
106
- usb_modules["USB:???"] = "LOCKED MODULE"
107
-
108
-
109
- try:
110
- module_sn = i_handle.getASCIIStringDescriptor(3)
111
- if "1944" in module_sn or "2098" in module_sn : #use enclosure number instead of serial number
112
- hdList.append(i)
113
- except Exception as err:
114
- logging.debug("USB exception on reading serial number: " + str(err))
115
- usb_modules["USB:???"] = "LOCKED MODULE"
116
- continue
117
-
118
- try:
119
- if (debuPrint): printText(i_handle.getASCIIStringDescriptor(3) + " " + i_handle.getASCIIStringDescriptor(
120
- 2) + " " + i_handle.getASCIIStringDescriptor(1))
121
- except Exception as err:
122
- logging.error("USB exception on reading descriptor strings: " + str(err))
123
- usb_modules["USB:???"] = "LOCKED MODULE"
124
- continue
125
-
126
- if "QTL" not in module_sn:
127
- module_sn = "QTL" + module_sn.strip()
128
- else:
129
- module_sn = module_sn.strip()
130
-
131
- if (debuPrint): printText(module_sn)
132
-
133
- usb_modules["USB:" + module_sn] = module_sn
134
- logging.debug("Located USB module: " + module_sn)
135
-
136
- try:
137
- logging.debug("Closing USB handle to quarch module: " + str(i))
138
- i_handle.close()
139
- except Exception as err:
140
- logging.error("Exception on closing USB port: " + str(err))
141
- continue
142
-
143
- # before returning the list of usb modules scan through the list for a 1944 create a quarch device and use sendCommand("*enclosure?")
144
-
145
- for module in hdList:
146
-
147
- QquarchDevice = None
148
- quarchDevice = None
149
- quarchDevice = module
150
- QquarchDevice = TQuarchUSB_IF(context)
151
- QquarchDevice.connection = quarchDevice
152
- QquarchDevice.OpenPort()
153
- time.sleep(0.02) # sleep sometimes needed before sending comand directly after opening device
154
- QquarchDevice.SetTimeout(2000)
155
- serialNo = (QquarchDevice.RunCommand("*serial?")).replace("\r\n", "")
156
- enclNo = (QquarchDevice.RunCommand("*enclosure?")).replace("\r\n", "")
157
-
158
- keyToFind = "USB:QTL" + serialNo
159
-
160
- if keyToFind in usb_modules:
161
- del usb_modules[keyToFind]
162
- usb_modules["USB:QTL" + enclNo] = "QTL" + enclNo
163
- logging.debug("Located USB module: QTL" + enclNo)
164
-
165
- QquarchDevice.ClosePort()
166
- QquarchDevice.deviceHandle = None
167
-
168
-
169
- if usb_permission_error:
170
- logging.warning("Potential permission error accessing Quarch module(s) via USB.")
171
- logging.warning("If unknown, run the command 'sudo python3 -m quarchpy.run debug --fixusb' to add a new usb rule.")
172
-
173
- return usb_modules
174
-
175
-
176
- '''
177
- List all Quarch devices found over LAN, using a UDP broadcast scan
178
- '''
179
-
180
- def get_interface_ips():
181
- interfaces = socket.if_nameindex()
182
- interface_ips = {}
183
- for idx, interface in interfaces:
184
- try:
185
- addresses = socket.getaddrinfo(interface, None)
186
- ip_addresses = [addr[4][0] for addr in addresses]
187
- interface_ips[interface] = ip_addresses
188
- except socket.gaierror:
189
- logging.warning(f"Unable to get IP address for interface {interface}")
190
- return interface_ips
191
- def list_network(target_conn="all", debugPring=False, lanTimeout=1, ipAddressLookup=None):
192
-
193
- retVal={}
194
- # Create and configure the socket for broadcast.
195
- mySocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
196
- mySocket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
197
- mySocket.settimeout(lanTimeout)
198
-
199
- lan_modules = dict()
200
-
201
- specifiedDevice = None
202
-
203
- if ipAddressLookup is not None:
204
- # Attempts to find the device through UDP then REST
205
- specifiedDevice = lookupDevice(str(ipAddressLookup).strip(), mySocket, lan_modules )
206
- mySocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
207
- mySocket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
208
- mySocket.settimeout(lanTimeout)
209
-
210
-
211
-
212
- # Broadcast the message.
213
- logging.debug("Broadcast LAN discovery message for UDP scan to all network interfaces")
214
- logging.debug("Available network interfaces before binding:")
215
- interfaces = socket.if_nameindex()
216
- for idx, interface in interfaces:
217
- logging.debug(f"Interface {idx}: {interface}")
218
- try:
219
- # Bind to all network interfaces using '', same as '0.0.0.0'
220
- mySocket.bind(('',56732))
221
- except Exception as err:
222
- logging.debug("Error while trying to bind to network interfaces: "+" Error: "+str(err))
223
- mySocket.sendto(b'Discovery: Who is out there?\0\n', ('255.255.255.255', 30303))
224
- #mySocket.sendto(b'Discovery: Who is out there?\0\n', ('255.255.255.255', 30303)) #56732
225
-
226
- counter = 0
227
-
228
- # Receive messages until timeout.
229
- while True:
230
- network_modules = {}
231
- counter += 1
232
- # Receive raw message until timeout, then break.
233
- try:
234
- msg_received = mySocket.recvfrom(256)
235
- except:
236
- # check if any a device was targeted directly and allow parse
237
- if specifiedDevice is not None:
238
- msg_received = specifiedDevice
239
- specifiedDevice = None
240
- else:
241
- break
242
- cont = 0
243
-
244
- # print(msg_received)
245
- # Used split \r\n since values of 13 or 10 were looked at as /r and /n when using splitlines
246
- # This fixes for all cases except if 13 is followed by 10.
247
- splits = msg_received[0].split(b"\r\n")
248
- del splits[-1]
249
- for lines in splits:
250
- if cont <= 1:
251
- index = cont
252
- data = repr(lines).replace("'", "").replace("b", "")
253
- cont += 1
254
- else:
255
- index = repr(lines[0]).replace("'", "")
256
- data = repr(lines[1:]).replace("'", "").replace("b", "")
257
-
258
- network_modules[index] = data
259
-
260
- module_name = get_user_level_serial_number(network_modules)
261
- logging.debug("Found UDP response: " + module_name)
262
-
263
- ip_module = msg_received[1][0].strip()
264
-
265
- try:
266
- # Add a QTL before modules without it.
267
- if "QTL" not in module_name.decode("utf-8"):
268
- module_name = "QTL" + module_name.decode("utf-8")
269
- except:
270
- # Add a QTL before modules without it.
271
- if "QTL" not in module_name:
272
- module_name = "QTL" + module_name
273
-
274
- # Checks if there's a value in the TELNET key.
275
- if (target_conn.lower() == "all" or target_conn.lower() == "telnet"):
276
- if network_modules.get("\\x8a") or network_modules.get("138"):
277
- # Append the information to the list.
278
- lan_modules["TELNET:" + ip_module] = module_name
279
- logging.debug("Found Telnet module: " + module_name)
280
-
281
- # Checks if there's a value in the REST key.
282
- if (target_conn.lower() == "all" or target_conn.lower() == "rest"):
283
- if network_modules.get("\\x84") or network_modules.get("132"):
284
- # Append the information to the list.
285
- lan_modules["REST:" + ip_module] = module_name
286
- logging.debug("Found REST module: " + module_name)
287
-
288
- # Checks if there's a value in the TCP key.
289
- if (target_conn.lower() == "all" or target_conn.lower() == "tcp"):
290
- if network_modules.get("\\x85") or network_modules.get("133"):
291
- # Append the information to the list.
292
- lan_modules["TCP:" + ip_module] = module_name
293
- logging.debug("Found TCP module: " + module_name)
294
-
295
- mySocket.close()
296
- logging.debug("Finished UDP scan")
297
- retVal.update(lan_modules)
298
- return retVal
299
-
300
-
301
- ''''''
302
- def get_user_level_serial_number(network_modules):
303
- list_of_multi_module_units = ["1995"] # List of modules that require enclosure number + Port to be displayed.
304
-
305
- # Filter the raw message to get the module and ip address.
306
- if "134" in network_modules.keys():
307
- module_name = network_modules.get("134").strip() # enclosure number only
308
- for module in list_of_multi_module_units:
309
- if module in module_name:
310
- module_name += "-" + network_modules.get("135").strip() # enclosure number with port
311
- break
312
- elif "\\x86" in network_modules.keys():
313
- module_name = network_modules.get("\\x86").strip() # enclosure number only
314
- for module in list_of_multi_module_units:
315
- if module in module_name:
316
- module_name += "-" + network_modules.get("\\x87").strip() # enclosure number with port
317
- break
318
- else:
319
- if "131" in network_modules.keys():
320
- module_name = module_name = network_modules.get("131").strip() # serial number
321
- elif "\\x83" in network_modules.keys():
322
- module_name = module_name = network_modules.get("\\x83").strip() # serial number
323
-
324
- return module_name
325
-
326
-
327
- ''''''
328
- def lookupDevice(ipAddressLookup, mySocket, lan_modules):
329
- try:
330
- printText("Ipaddress lookup " + ipAddressLookup)
331
- # For future reference, 0 is the C terminator for a string
332
- mySocket.sendto(b'Discovery: Who is out there?\0\n', (str(ipAddressLookup).strip(), 30303))
333
- specifiedDevice = mySocket.recvfrom(256)
334
- # Check to see if the response contains the connection protocol
335
- if ("\\x8a") or ("138") or ("\\x84") or ("132") or ("\\x85") or ("133") not in specifiedDevice:
336
- # If not allow it to fall-back to REST
337
- specifiedDevice = None
338
- else:
339
- # Exit as device was found correctly
340
- return specifiedDevice
341
- except Exception as e:
342
- printText("Error during UDP lookup " + str(e))
343
- printText("Is the IP address correct?\r\n")
344
- # Return if there's an error
345
- return None
346
-
347
- if specifiedDevice is None:
348
- try:
349
- restCon = connection_ReST.ReSTConn(str(ipAddressLookup).replace("\r\n", ""))
350
- restDevice = restCon.sendCommand("*serial?")
351
- if not str(restDevice).startswith("QTL"):
352
- restDevice = "QTL" + restDevice
353
- # Add the item to list
354
- lan_modules["REST:" + str(ipAddressLookup).replace("\r\n", "")] = restDevice
355
-
356
- except Exception as e:
357
- printText("Error During REST scan " + str(e))
358
-
359
- # Needs to return None so previous method will not attempt another lookup.
360
- return None
361
-
362
-
363
- """
364
- Takes in the connection target and returns the serial number of a module found on the standard scan.
365
-
366
- Parameters
367
- ----------
368
- connectionTarget= : str
369
- The connection target of the module you would like to know the serial number of.
370
-
371
- Returns
372
- -------
373
- ret_val : str
374
- The Serial number of the supplied device.
375
-
376
- """
377
- def getSerialNumberFromConnectionTarget(connectionTarget):
378
- myDict = scanDevices(favouriteOnly=False)
379
- for k,v in myDict.items():
380
- if k == connectionTarget:
381
- return v
382
- return None
383
-
384
-
385
- """
386
- Takes in the connection type and serial number of a module and returns the connection target.
387
-
388
- Parameters
389
- ----------
390
- module_string= : str
391
- The connection type and serial number combination eg. TCP:QTL1999-05-005.
392
-
393
- scan_dictionary= :dict, optional
394
- A scan dictionary can be passed so that a scan does not need to take place on every call.
395
- This would be advised if calling this for every item in a list of serial numbers.
396
-
397
- connection_preference= : list str, optional
398
- The preference of which connection type to prioratise if none it given.
399
- Defaults to "USB", "TCP", "SERIAL", "REST", "TELNET" in that order.
400
-
401
- include_conn_type = : boolean, optional
402
- Decided whether the connection type will appear in the return value eg. TCP:192.168.1.1 vs 192.168.1.1
403
-
404
- Returns
405
- -------
406
- ret_val : str
407
- The Connection target of the supplied device.
408
-
409
- """
410
- def get_connection_target(module_string ,scan_dictionary=None, connection_preference= None, include_conn_type = True):
411
- logging.debug("Getting connection target for : "+ str(module_string))
412
- if connection_preference == None:
413
- connection_preference = ["USB", "TCP", "SERIAL", "REST", "TELNET"]
414
- module_string.replace("::", ":") #QIS/QPS format to QuarchPy format
415
- delimeter_pos = module_string.find(":")
416
- if delimeter_pos == -1:
417
- con_type = None
418
- serial_number = module_string.lower()
419
- else:
420
- con_type = module_string[:delimeter_pos]
421
- serial_number = module_string[delimeter_pos + 1:].lower()
422
- if serial_number.find("qtl") !=-1:
423
- serial_number=serial_number.replace("qtl","")
424
- if scan_dictionary is None:
425
- logging.debug("Scanning for devices...")
426
- scan_dictionary = scanDevices(favouriteOnly=False,filterStr=[serial_number])
427
-
428
- ret_val="Fail Module Not Found"
429
-
430
- if con_type is None:
431
- connection_found = False
432
- for con_type in connection_preference:
433
- if connection_found is False:
434
- for k, v in scan_dictionary.items():
435
- if k.__contains__(con_type):
436
- ret_val = k
437
- connection_found = True
438
- else:
439
- for k, v in scan_dictionary.items():
440
- if k.lower().__contains__(con_type.lower()):
441
- ret_val=k
442
-
443
- if not include_conn_type and not ret_val.__contains__("Fail"):
444
- delimeter_pos = ret_val.find(":")
445
- ret_val = ret_val[delimeter_pos + 1:]
446
-
447
- return ret_val
448
-
449
-
450
- '''
451
- Scans for Quarch modules across the given interface(s). Returns a dictionary of module addresses and serial numbers
452
- '''
453
- def filter_module_type(module_type_filter, found_devices):
454
- """
455
- Used in scandevices to filter modules by their type.
456
- Uses config files.
457
-
458
- :param module_type_filter: Acceptable values are 'Cable', 'Card', 'Drive', 'Power', 'Switch'
459
- :param found_devices: List of found devices passed from scan_devices
460
- :return: Returns all devices in found devices that are of 'module filter type'
461
- """
462
- accepted_qtl_numbers = return_module_type_list(module_type_filter)
463
- accepted_qtl_numbers = [x.lower() for x in accepted_qtl_numbers]
464
- filtered_devices = {}
465
- if not accepted_qtl_numbers:
466
- return {}
467
- for key, value in found_devices.items():
468
- if "qtl" in str(value).lower():
469
- qtl_num = str(value[str(value.lower()).index("qtl"):str(value).index("-")]).lower()
470
- if any(qtl_num in x for x in accepted_qtl_numbers):
471
- filtered_devices.update({key: value})
472
- return filtered_devices
473
-
474
-
475
- '''
476
- Scans for Quarch modules across the given interface(s). Returns a dictionary of module addresses and serial numbers
477
- '''
478
- def scanDevices(target_conn="all", lanTimeout=1, scanInArray=True, favouriteOnly=True,filterStr=None,
479
- module_type_filter=None, ipAddressLookup=None):
480
- foundDevices = dict()
481
- scannedArrays = list()
482
-
483
- if target_conn.lower() == "all":
484
- foundDevices = list_USB()
485
- foundDevices = mergeDict(foundDevices, list_serial())
486
- try:
487
- #This will fail if the test machine is not connected to a network
488
- foundDevices = mergeDict(foundDevices, list_network("all", ipAddressLookup=ipAddressLookup, lanTimeout=lanTimeout))
489
- except Exception as e:
490
- logging.error(e)
491
- logging.warning("Network scan failed, check network connection")
492
- # print(foundDevices)
493
-
494
- if target_conn.lower() == "serial":
495
- foundDevices = list_serial()
496
-
497
- if target_conn.lower() == "usb":
498
- foundDevices = list_USB()
499
-
500
- if target_conn.lower() == "tcp" or target_conn.lower() == "rest" or target_conn.lower() == "telnet":
501
- foundDevices = list_network(target_conn, ipAddressLookup=ipAddressLookup, lanTimeout=lanTimeout)
502
-
503
- if (scanInArray):
504
- for k, v in foundDevices.items(): # k=Connection target, v=serial number
505
- if (k not in scannedArrays):
506
- scannedArrays.append(k)
507
- if (isThisAnArrayController(v)):
508
- try:
509
- myQuarchDevice = quarchDevice(k)
510
- myArrayControler = quarchArray(myQuarchDevice)
511
- scanDevices = myArrayControler.scanSubModules()
512
- foundDevices = mergeDict(foundDevices, scanDevices)
513
- myArrayControler.closeConnection()
514
- except Exception as e:
515
- logging.error(e, exc_info=True)
516
- logging.warning("Cannot get serial number. Quarch device may be in use by another program.")
517
- foundDevices[k] = "DEVICE IN USE"
518
-
519
- if (favouriteOnly):
520
-
521
- # Sort list in order of connection type preference. Can be changed by changing position in conPref list. This must be done so that it is in the correct format for picking the favourite connections.
522
- index = 0
523
- sortedFoundDevices = {}
524
- conPref = ["USB", "TCP", "SERIAL", "REST", "TELNET"]
525
- while len(sortedFoundDevices) != len(foundDevices):
526
- for k, v in foundDevices.items():
527
- if conPref[index] in k:
528
- sortedFoundDevices[k] = v
529
- index += 1
530
- foundDevices = sortedFoundDevices
531
-
532
- # new dictionary only containing one favourite connection to each device.
533
- favConFoundDevices = {}
534
- index = 0
535
- for k, v in sortedFoundDevices.items():
536
- if (favConFoundDevices == {} or not v in favConFoundDevices.values()):
537
- favConFoundDevices[k] = v
538
- foundDevices = favConFoundDevices
539
-
540
- # Sort by alphabetic order of key
541
- sortedFoundDevices = {}
542
- sortedFoundDevices = sorted(foundDevices.items(), key=operator.itemgetter(1))
543
- foundDevices = dict(sortedFoundDevices)
544
- if filterStr != None:
545
- filteredDevices = {}
546
- for k, v in foundDevices.items():
547
- for j in filterStr:
548
- if (j in v or "LOCKED MODULE" in v): #show locked modules too incase the module you are looking for is on the system but is locked
549
- filteredDevices[k] = v
550
- foundDevices = filteredDevices
551
-
552
- # used to filter module via type ( Power / Drive / ...)
553
- if module_type_filter:
554
- foundDevices = filter_module_type(module_type_filter, foundDevices)
555
-
556
- return foundDevices
557
-
558
-
559
- '''
560
- Prints out a list of Quarch devices nicely onto the terminal, numbering each unit
561
- '''
562
- def listDevices(scanDictionary):
563
- if not scanDictionary:
564
- printText("No quarch devices found to display")
565
- else:
566
- x = 1
567
- for k, v in scanDictionary.items():
568
- printText('{0:>3}'.format(str(x)) + " - " + '{0:<18}'.format(
569
- v) + "\t" + k) # add padding to keep responses in line
570
- x += 1
571
-
572
-
573
- '''
574
- Requests the user to select one of the devices in the given list
575
- '''
576
- def userSelectDevice(scanDictionary=None, scanFilterStr=None,favouriteOnly=True, message=None, title=None, nice=False, additionalOptions = None, target_conn="all"):
577
- if User_interface.instance != None and User_interface.instance.selectedInterface == "testcenter":
578
- nice = False
579
- if message is None: message = "Please select a quarch device"
580
- if title is None: title = "Select a Device"
581
- ip_address = None
582
- while (True):
583
- # Scan first, if no list is supplied
584
- if (scanDictionary is None):
585
- printText("Scanning for devices...")
586
- if ip_address == None:
587
- scanDictionary = scanDevices(filterStr=scanFilterStr, favouriteOnly=favouriteOnly, target_conn=target_conn)
588
- else:
589
- scanDictionary = scanDevices(filterStr=scanFilterStr, favouriteOnly=favouriteOnly, target_conn=target_conn, ipAddressLookup=ip_address)
590
-
591
- if len(scanDictionary)<1:
592
- scanDictionary["***No Devices Found***"]="***No Devices Found***"
593
-
594
-
595
- if nice: #Prepair the data for niceListSelection using displayTable().
596
- if additionalOptions is None: additionalOptions = ["IP Scan","Rescan","Quit"]
597
- tempList = []
598
- tempEl = []
599
- for k, v in scanDictionary.items():
600
- tempEl = []
601
- tempEl.append(v)
602
- charPos = k.find(":")
603
- tempEl.append(k)
604
- tempList.append(tempEl)
605
- adOp =[]
606
- for option in additionalOptions:
607
- adOp.append([option]*2) # Put option in all columns
608
- #adOp.append([option,"-"])
609
- userStr = listSelection(title, message, tempList, additionalOptions=adOp, indexReq=True, nice=nice, tableHeaders=["Selection", "Description"])
610
- userStr = userStr[2] #With the data formatted in this way the ConnTarget will always be in userStr[2]
611
-
612
- else: # Prepare data for old style selection or testCenter
613
- devicesString = []
614
- for k, v in scanDictionary.items():
615
- charPos = k.find(":")
616
- devicesString.append(k + '=' + v + ": " + k[:charPos])
617
- devicesString = ','.join(devicesString)
618
- if additionalOptions is None :
619
- additionalOptions = "IP Scan=IP Scan,Rescan=Rescan,Quit=Quit"
620
- userStr = listSelection(title=title,message=message,selectionList=devicesString, additionalOptions=additionalOptions)
621
-
622
- # Process the user response
623
- if (userStr.lower() in 'quit'):
624
- return "quit"
625
- elif (userStr.lower() in 'rescan'):
626
- ip_address = None
627
- scanDictionary = None
628
- favouriteOnly = True
629
- elif (userStr.lower() in 'all conn types'):
630
- ip_address = None
631
- scanDictionary = None
632
- favouriteOnly = False
633
- elif(userStr.lower() in 'ip scan'):
634
- ip_address = requestDialog("Please input IP Address of the module you would like to connect to: ")
635
- scanDictionary = None
636
- favouriteOnly = False
637
- else:
638
- # Return the address string of the selected module
639
- return userStr
640
-
641
-
642
- #Not used but could come in usefull in near future.
643
- # def userSelectAndReturnDevice(scanDictionary=None, scanFilterStr=None,favouriteOnly=True, message=None, title=None, nice=True, additionalOptions =["rescan","all conn types", "quit"], target_conn="all"):
644
- # scanDictionary = scanDevices()
645
- # connectionTarget = userSelectDevice(scanDictionary, scanFilterStr, favouriteOnly, message, title, nice,
646
- # additionalOptions, target_conn)
647
- # serialNumber = getSerialNumberFromConnectionTarget(connectionTarget)
648
- #
649
- # if connectionTarget.__contains__("<") and connectionTarget.__contains__(">"):
650
- # connectionTarget, portNumber = connectionTarget.split("<")
651
- # portNumber = portNumber[:-1]
652
- # myDevice = quarchDevice(connectionTarget)
653
- # myArrayController = quarchArray(myDevice)
654
- # mySubDevice = myArrayController.getSubDevice(portNumber)
655
- # myDevice = mySubDevice
656
- # elif(serialNumber.lower().__contains__("qtl1999") or serialNumber.lower().__contains__("qtl1995") or serialNumber.lower().__contains__("qtl2312")):
657
- # myDevice = quarchPPM(quarchDevice(connectionTarget))
658
- #
659
- # else:
660
- # myDevice = quarchDevice(connectionTarget)
661
- # return myDevice