quarchpy 2.2.17.dev2__py3-none-any.whl → 2.2.17.dev3__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/qps/qpsFuncs.py CHANGED
@@ -1,6 +1,9 @@
1
+ import socket
2
+ from subprocess import CompletedProcess, Popen
1
3
  from threading import Thread, Lock, Event
2
4
  from queue import Queue, Empty
3
5
  import platform
6
+ from typing import Optional, List, Any, Tuple, Union
4
7
 
5
8
  import quarchpy_binaries
6
9
 
@@ -8,9 +11,11 @@ from quarchpy.install_qps import find_qps
8
11
  from quarchpy.qis import isQisRunning, startLocalQis
9
12
  from quarchpy.connection_specific.connection_QPS import QpsInterface
10
13
  from quarchpy.connection_specific.jdk_jres.fix_permissions import main as fix_permissions, find_java_permissions
14
+ from quarchpy.qis.qisFuncs import isQisRunningAndResponding
11
15
  from quarchpy.user_interface import *
12
16
  import subprocess
13
17
  import logging
18
+
14
19
  logger = logging.getLogger(__name__)
15
20
 
16
21
 
@@ -18,7 +23,7 @@ def isQpsRunning(host='127.0.0.1', port=9822, timeout=0):
18
23
  '''
19
24
  This func will return true if QPS is running with a working QIS connection.
20
25
  '''
21
- myQps=None
26
+ myQps = None
22
27
  logger.debug("Checking if QPS is running")
23
28
  start = time.time()
24
29
  while True:
@@ -34,12 +39,13 @@ def isQpsRunning(host='127.0.0.1', port=9822, timeout=0):
34
39
  logger.debug("QPS is not running")
35
40
  return False
36
41
 
37
- logger.debug("Checking if QPS reports a QIS connection") # "$qis status" returns connected if it has ever had a QIS connection.
38
- answer=0
39
- counter=0
42
+ logger.debug(
43
+ "Checking if QPS reports a QIS connection") # "$qis status" returns connected if it has ever had a QIS connection.
44
+ answer = 0
45
+ counter = 0
40
46
  while True:
41
47
  answer = myQps.sendCmdVerbose(cmd="$qis status")
42
- if answer.lower()=="connected":
48
+ if answer.lower() == "connected":
43
49
  logger.debug("QPS Running With QIS Connected")
44
50
  break
45
51
  else:
@@ -47,7 +53,7 @@ def isQpsRunning(host='127.0.0.1', port=9822, timeout=0):
47
53
  time.sleep(0.5)
48
54
  counter += 1
49
55
  if counter > 5:
50
- logger.debug("QPS Running QIS NOT found after "+str(counter)+" attempts.")
56
+ logger.debug("QPS Running QIS NOT found after " + str(counter) + " attempts.")
51
57
  return False
52
58
 
53
59
  logger.debug("Checking if QPS/QIS comms are running")
@@ -71,122 +77,88 @@ def isQpsRunning(host='127.0.0.1', port=9822, timeout=0):
71
77
  return False
72
78
 
73
79
 
74
- def startLocalQps(keepQisRunning=False, args=[], timeout=30, startQPSMinimised=True):
75
-
80
+ def startLocalQps(
81
+ keepQisRunning: bool = False,
82
+ args: Optional[List[str]] = [],
83
+ timeout: int = 30,
84
+ startQPSMinimised: bool = True,
85
+ host: str = '127.0.0.1',
86
+ port: int = 9822,
87
+ qis_port: int = 9722,
88
+ qis_rest_port: int = 9780
89
+ ) -> Optional['QpsInterface']:
90
+ """
91
+ Main entry point to start a local QPS instance.
92
+ """
93
+ # 1. Prepare Arguments
94
+ # We copy the list to avoid modifying the input in place
95
+ launch_args = args.copy()
96
+ if not launch_args:
97
+ launch_args = ""
98
+
99
+ # Sync 'port' arg to CLI flags if non-default
100
+ if port != 9822:
101
+ # Only add if not already manually present in args
102
+ if not any("-port=" in arg for arg in launch_args):
103
+ launch_args.append(f"-port={port}")
104
+
105
+ # Sync 'qisport' arg to CLI flags if non-default
106
+ if qis_port != 9722:
107
+ if not any("-qisport=" in arg for arg in launch_args):
108
+ launch_args.append(f"-qisport={qis_port}")
109
+
110
+ # Sync 'qisrestport' arg to CLI flags if non-default
111
+ if qis_rest_port != 9780:
112
+ if not any("-qisrestport=" in arg for arg in launch_args):
113
+ launch_args.append(f"-qisrestport={qis_port}")
114
+
115
+ # 2. Check if already running on the specific target port
116
+ if _check_port_open(host, port):
117
+ logger.debug(f"QPS instance on port {port} is already running. Connecting...")
118
+ return QpsInterface(host=host, port=port)
119
+
120
+ # 3. Check for QPS installation
76
121
  if not find_qps():
77
122
  logger.error("Unable to find or install QPS... Aborting...")
78
- return
123
+ return None
79
124
 
125
+ # 4. Handle QIS Backend (if required)
80
126
  if keepQisRunning:
81
- if not isQisRunning():
82
- startLocalQis()
127
+ if not _ensure_qis_running(host, qis_port, qis_rest_port, timeout):
128
+ return None
83
129
 
84
- if args.__len__() !=0:
85
- args = " ".join(args)
86
- else:
87
- args=" "
88
- if startQPSMinimised == True:
89
- if "-ccs" not in args.lower():
90
- args +=" -ccs=MIN"
130
+ # 5. Prepare Command and Environment
131
+ command, qps_dir = _prepare_qps_launch_env(launch_args, startQPSMinimised)
132
+ if not command:
133
+ return None
91
134
 
92
- # Record current working directory
135
+ # 6. Launch QPS Process
93
136
  current_dir = os.getcwd()
94
137
 
95
- # JRE path
96
- java_path = quarchpy_binaries.get_jre_home()
97
- java_path = "\"" + java_path
98
- # Start to build the path towards qps.jar
99
- qps_path = os.path.dirname(os.path.abspath(__file__))
100
- qps_path, junk = os.path.split(qps_path)
101
-
102
- # Check the current OS
103
- current_os = platform.system()
104
- current_arch = platform.machine()
105
- current_arch = current_arch.lower() # ensure comparing same case
106
-
107
- # Currently officially unsupported
108
- if (current_os in "Linux" and current_arch == "aarch64") or (current_os in "Darwin" and current_arch == "arm64"):
109
- logger.warning("The system [" + current_os + ", " + current_arch + "] is not officially supported.")
110
- logger.warning("Please contact Quarch support for running QuarchPy on this system.")
111
- return
112
-
113
- # ensure the jres folder has the required permissions
114
- permissions, message = find_java_permissions()
115
- if permissions is False:
116
- logger.warning(message)
117
- logger.warning("Not having correct permissions will prevent Quarch Java Programs from launching.")
118
- logger.warning("Run \"python -m quarchpy.run permission_fix\" to fix this.")
119
- user_input = input("Would you like to use auto run this now? (Y/N)")
120
- if user_input.lower() == "y":
121
- fix_permissions()
122
- permissions, message = find_java_permissions()
123
- time.sleep(0.5)
124
- if permissions is False:
125
- logger.warning("Attempt to fix permissions was unsuccessful. Please fix manually.")
126
- else:
127
- logger.warning("Attempt to fix permissions was successful. Now continuing.")
128
-
129
-
130
- qps_path = os.path.join(qps_path, "connection_specific", "QPS", "qps.jar")
131
-
132
-
133
- # Change the working directory to the directory containing qps.jar
134
- os.chdir(os.path.dirname(qps_path))
135
-
136
-
137
- # OS dependency
138
- if current_os in "Windows":
139
- command = java_path + "\\bin\\java\" -jar qps.jar " + str(args)
140
- elif current_os in "Linux" and current_arch == "x86_64":
141
- command = java_path + "/bin/java\" -jar qps.jar " + str(args)
142
- elif current_os in "Linux" and current_arch == "aarch64":
143
- command = java_path + "/bin/java\" -jar qps.jar " + str(args)
144
- elif current_os in "Darwin" and current_arch == "x86_64":
145
- command = java_path + "/bin/java\" -jar qps.jar " + str(args)
146
- elif current_os in "Darwin" and current_arch == "arm64":
147
- command = java_path + "/bin/java\" -jar qps.jar " + str(args)
148
- else: # default to windows
149
- command = java_path + "\\bin\\java\" -jar qps.jar " + str(args)
150
-
151
138
  if isQpsRunning():
152
139
  logger.debug("QPS is already running. Not starting another instance.")
153
140
  os.chdir(current_dir)
154
- return
155
- if "-logging=ON" in str(args): #If logging to a terminal window is on then os.system should be used to keep a window open to view logging.
156
- if current_os in "Windows":
157
- process = subprocess.Popen(command,shell=True)
158
- else:
159
- # Add a hold command to keep the terminal open (useful for bash)
160
- command_with_pause = command + "; exec bash"
161
- process = subprocess.run(command_with_pause, shell=True)
162
- else:
163
- if sys.version_info[0] < 3:
164
- process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
165
- else:
166
- process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, shell=True)
141
+ return None
167
142
 
168
- startTime = time.time()
169
- while not isQpsRunning():
170
- time.sleep(0.2)
171
- _get_std_msg_and_err_from_QPS_process(process)
172
- if time.time() - startTime > timeout:
173
- os.chdir(current_dir)
174
- raise TimeoutError("QPS failed to launch within timelimit of " + str(timeout) + " sec.")
175
- logger.debug("QPS detected after " + str(time.time() - startTime) + "s")
143
+ try:
144
+ os.chdir(qps_dir) # Switch to QPS dir for launch dependencies
145
+ process = _launch_process(command, args)
146
+ finally:
147
+ os.chdir(current_dir) # Always return to original dir
176
148
 
177
- while not isQisRunning():
178
- if time.time() - startTime > timeout:
179
- raise TimeoutError(
180
- "QPS did launch but QIS did not respond during the timeout time of " + str(timeout) + " sec.")
181
- time.sleep(0.2)
182
- logger.debug("QIS detected after " + str(time.time() - startTime) + "s")
149
+ # 7. Wait for QPS to be ready
150
+ if not _wait_for_service(host, port, timeout, process, args):
151
+ return None
183
152
 
184
- # return current working directory
185
- os.chdir(current_dir)
186
- return
153
+ # 8. Return Connected Interface
154
+ try:
155
+ return QpsInterface(host=host, port=port)
156
+ except Exception as e:
157
+ logger.error(f"QPS started, but failed to create interface object: {e}")
158
+ return None
187
159
 
188
160
 
189
- def reader(stream, q, source, lock,stop_flag):
161
+ def reader(stream, q, source, lock, stop_flag):
190
162
  '''
191
163
  Used to read output and place it in a queue for multithreaded reading
192
164
  :param stream:
@@ -222,7 +194,7 @@ def _get_std_msg_and_err_from_QPS_process(process):
222
194
  t2.start()
223
195
  counter = 0
224
196
  # check for stderr or stdmsg from the queue
225
- while counter <= 3: # If 3 empty reads from the queue then move on to see if QPS is running.
197
+ while counter <= 3: # If 3 empty reads from the queue then move on to see if QPS is running.
226
198
  try:
227
199
  source, line = q.get(timeout=1) # Wait for 1 second for new lines
228
200
  counter = 0
@@ -232,73 +204,197 @@ def _get_std_msg_and_err_from_QPS_process(process):
232
204
  printText(f"{source}: {line}")
233
205
  except Empty:
234
206
  counter += 1
235
- stop_flag.set() #Close the threads and return to the main loop where QPS is check to see if its started yet
207
+ stop_flag.set() #Close the threads and return to the main loop where QPS is check to see if its started yet
236
208
 
237
209
 
238
210
  def closeQps(host='127.0.0.1', port=9822):
239
211
  myQps = QpsInterface(host, port)
240
212
  myQps.sendCmdVerbose("$shutdown")
241
213
  del myQps
242
- time.sleep(1) #needed as calling "isQpsRunning()" will throw an error if it ties to connect while shutdown is in progress.
214
+ time.sleep(
215
+ 1) #needed as calling "isQpsRunning()" will throw an error if it ties to connect while shutdown is in progress.
216
+
217
+
218
+ def GetQpsModuleSelection(QpsConnection: 'QpsInterface', favouriteOnly=True,
219
+ additionalOptions=['rescan', 'all con types', 'ip scan'], scan=True):
220
+ """
221
+ Deprecated: use QpsInterface.get_module_selection instead.
222
+ This function will return a module selection list from QPS.
223
+
224
+ """
225
+ return (
226
+ QpsConnection.get_qps_module_selection(preferred_connection_only=favouriteOnly,
227
+ additional_options=additionalOptions, scan=scan)
228
+ )
229
+
230
+
231
+ # ==========================================
232
+ # HELPER FUNCTIONS
233
+ # ==========================================
234
+
235
+ def _parse_ports(args: List[str]) -> Tuple[int, int, int]:
236
+ """Extracts QPS and QIS ports from the argument list."""
237
+ qps_port = 9822
238
+ qis_port = 9722
239
+ qis_rest_port = 9780
240
+
241
+ for arg in args:
242
+ arg_lower = arg.lower()
243
+ if "-port=" in arg_lower:
244
+ try:
245
+ qps_port = int(arg.split('=')[1])
246
+ except (IndexError, ValueError):
247
+ pass
248
+ elif "-qisport=" in arg_lower:
249
+ try:
250
+ qis_port = int(arg.split('=')[1])
251
+ except (IndexError, ValueError):
252
+ pass
253
+ elif "-qisrestport=" in arg_lower:
254
+ try:
255
+ qis_rest_port = int(arg.split('=')[1])
256
+ except (IndexError, ValueError):
257
+ pass
258
+
259
+ return qps_port, qis_port, qis_rest_port
260
+
261
+
262
+ def _ensure_qis_running(host: str, qis_port: int, qis_rest_port: int, timeout: int) -> bool:
263
+ """Checks if QIS is running on the target port, starts it if not."""
264
+ if _check_port_open(host, qis_port):
265
+ return True
243
266
 
244
- def GetQpsModuleSelection(QpsConnection, favouriteOnly=True, additionalOptions=['rescan', 'all con types', 'ip scan'], scan=True):
245
- favourite = favouriteOnly
246
- ip_address = None
247
- while True:
248
- printText("QPS scanning for devices")
249
- tableHeaders = ["Module"]
250
- # Request a list of all USB and LAN accessible power modules
251
- if ip_address == None:
252
- devList = QpsConnection.getDeviceList(scan=scan)
253
- else:
254
- devList = QpsConnection.getDeviceList(scan=scan, ipAddress=ip_address)
255
- if "no device" in devList[0].lower() or "no module" in devList[0].lower():
256
- favourite = False # If no device found conPref wont match and will bugout
257
-
258
- # Removes rest devices
259
- devList = [x for x in devList if "rest" not in x]
260
- message = "Select a quarch module"
261
-
262
- if (favourite):
263
- index = 0
264
- sortedDevList = []
265
- conPref = ["USB", "TCP", "SERIAL", "REST", "TELNET"]
266
- while len(sortedDevList) < len(devList):
267
- for device in devList:
268
- if conPref[index] in device.upper():
269
- sortedDevList.append(device)
270
- index += 1
271
- devList = sortedDevList
272
-
273
- # new dictionary only containing one favourite connection to each device.
274
- favConDevList = []
275
- index = 0
276
- for device in sortedDevList:
277
- if (favConDevList == [] or not device.split("::")[1] in str(favConDevList)):
278
- favConDevList.append(device)
279
- devList = favConDevList
280
-
281
- if User_interface.instance != None and User_interface.instance.selectedInterface == "testcenter":
282
- tempString = ""
283
- for module in devList:
284
- tempString+=module+"="+module+","
285
- devList = tempString[0:-1]
286
-
287
-
288
- myDeviceID = listSelection(title=message, message=message, selectionList=devList,
289
- additionalOptions=additionalOptions, nice=True, tableHeaders=tableHeaders, indexReq=True)
290
-
291
- if myDeviceID in 'rescan':
292
- ip_address = None
293
- favourite = True
294
- continue
295
- elif myDeviceID in 'all con types':
296
- printText('Displaying all conection types...')
297
- favourite = False
298
- continue
299
- elif myDeviceID in 'ip scan':
300
- ip_address = requestDialog("Please input IP Address of the module you would like to connect to: ")
301
- favourite = False
302
- continue
267
+ logger.debug(f"Starting QIS on ports {qis_port}/{qis_rest_port}...")
268
+ qis_args = [f'-port={qis_port}', f'-restport={qis_rest_port}']
269
+ startLocalQis(args=qis_args)
270
+
271
+ # Wait for QIS
272
+ start_time = time.time()
273
+ while not _check_port_open(host, qis_port):
274
+ if time.time() - start_time > timeout:
275
+ logger.error(f"QIS failed to start on port {qis_port} within timeout.")
276
+ return False
277
+ time.sleep(0.5)
278
+
279
+ while isQisRunningAndResponding():
280
+ time.sleep(0.5)
281
+
282
+ return True
283
+
284
+
285
+ def _prepare_qps_launch_env(args: List[str], startQPSMinimised: bool) -> Tuple[Optional[str], Optional[str]]:
286
+ """Resolves paths using quarchpy_binaries, checks permissions, and builds command."""
287
+
288
+ # 1. Check OS Support
289
+ current_os = platform.system()
290
+ current_arch = platform.machine().lower()
291
+
292
+ # 2. Handle Permissions
293
+ _handle_java_permissions()
294
+
295
+ # 3. Resolve Paths using quarchpy_binaries
296
+ if 'quarchpy_binaries' not in globals() and 'quarchpy_binaries' not in locals():
297
+ # Fallback if module isn't imported or available
298
+ logger.error("quarchpy_binaries module not found. Cannot locate JRE.")
299
+ return None, None
300
+
301
+ try:
302
+ java_home = quarchpy_binaries.get_jre_home()
303
+ except Exception as e:
304
+ logger.error(f"Failed to get JRE home: {e}")
305
+ return None, None
306
+
307
+ # Resolve QPS Jar Path
308
+ qps_root = os.path.dirname(os.path.abspath(__file__))
309
+ qps_root, _ = os.path.split(qps_root) # Up one level
310
+ qps_jar_path = os.path.join(qps_root, "connection_specific", "QPS", "qps.jar")
311
+ qps_dir = os.path.dirname(qps_jar_path)
312
+
313
+ # 4. Construct Command
314
+ # Determine separator based on OS (Windows uses \, Linux/Mac use /)
315
+
316
+ java_bin = "bin/java"
317
+ if current_os == "Windows":
318
+ java_bin = r"bin\java"
319
+
320
+ # Full path to java executable
321
+ java_exe = os.path.join(java_home, java_bin)
322
+
323
+ # Wrap java path in quotes for safety
324
+ java_exe_quoted = f'"{java_exe}"'
325
+
326
+ # Prepare Args String
327
+ args_str = " ".join(args) if args else " "
328
+ if startQPSMinimised and "-ccs" not in args_str.lower():
329
+ args_str += " -ccs=MIN"
330
+
331
+ # Build Final Command
332
+ command = f'{java_exe_quoted} -jar qps.jar {args_str}'
333
+
334
+ return command, qps_dir
335
+
336
+
337
+ def _handle_java_permissions() -> None:
338
+ """Checks and attempts to fix Java execution permissions."""
339
+ permissions, message = find_java_permissions()
340
+ if not permissions:
341
+ logger.warning(message)
342
+ printText("Not having correct permissions will prevent Quarch Java Programs from launching.")
343
+ printText('Run "python -m quarchpy.run permission_fix" to fix this.')
344
+ printText("Would you like quarchpy to attempt to fix the permissions now? (Y/N)")
345
+ try:
346
+ user_input = requestDialog(">>> ")
347
+ except EOFError:
348
+ user_input = "N"
349
+ if user_input.strip().lower() in ['y', 'yes']:
350
+ fix_permissions()
351
+
352
+
353
+ def _launch_process(command: str, args: List[str]) -> Union[Popen, CompletedProcess]:
354
+ """Launches the subprocess, handling logging flags."""
355
+ args_str = " ".join(args) if args else ""
356
+
357
+ if "-logconsole=ON" in args_str:
358
+ if platform.system() == "Windows":
359
+ return subprocess.Popen(command, shell=True)
303
360
  else:
304
- return myDeviceID
361
+ return subprocess.run(command + "; exec bash", shell=True)
362
+ else:
363
+ # Use text=True for Python 3.7+
364
+ text_mode = True if sys.version_info >= (3, 7) else False
365
+ # Fallback for 3.6 if needed (universal_newlines=True)
366
+ return subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=text_mode, shell=True)
367
+
368
+
369
+ def _wait_for_service(host: str, port: int, timeout: int, process: Optional[subprocess.Popen], args: List[str]) -> bool:
370
+ """Polls the port until open, checking process output for errors."""
371
+ start_time = time.time()
372
+ args_str = " ".join(args) if args else ""
373
+ logging_on = "-logconsole=ON" in args_str
374
+
375
+ while True:
376
+ if _check_port_open(host, port):
377
+ logger.debug(f"QPS detected on port {port} after {time.time() - start_time:.2f}s")
378
+ return True
379
+
380
+ # If hidden, drain pipes to prevent deadlock and check for crashes
381
+ if not logging_on and process:
382
+ _get_std_msg_and_err_from_QPS_process(process)
383
+
384
+ if time.time() - start_time > timeout:
385
+ logger.error(f"QPS failed to launch on port {port} within timelimit of {timeout} sec.")
386
+ return False
387
+
388
+ time.sleep(0.2)
389
+
390
+
391
+ def _check_port_open(host: str, port: int) -> bool:
392
+ """Simple TCP connect check."""
393
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
394
+ s.settimeout(1)
395
+ try:
396
+ s.connect((host, int(port)))
397
+ s.close()
398
+ return True
399
+ except (socket.timeout, ConnectionRefusedError, OSError):
400
+ return False
quarchpy/run.py CHANGED
@@ -240,7 +240,7 @@ def _run_qps_function(args=[]):
240
240
  printText("QPS is not running")
241
241
 
242
242
  if not shutdown:
243
- startLocalQps(args=args)
243
+ startLocalQps(args=args, startQPSMinimised=False)
244
244
 
245
245
 
246
246
  def _run_calibration_function(args=[]):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quarchpy
3
- Version: 2.2.17.dev2
3
+ Version: 2.2.17.dev3
4
4
  Summary: This packpage offers Python support for Quarch Technology modules.
5
5
  Author: Quarch Technology ltd
6
6
  Author-email: support@quarch.com
@@ -18,6 +18,7 @@ Classifier: Topic :: System
18
18
  Classifier: Topic :: System :: Power (UPS)
19
19
  Requires-Python: >=3.7
20
20
  Description-Content-Type: text/x-rst
21
+ License-File: LICENSE.txt
21
22
  Requires-Dist: zeroconf>=0.23.0
22
23
  Requires-Dist: numpy
23
24
  Requires-Dist: pandas
@@ -25,6 +26,8 @@ Requires-Dist: requests
25
26
  Requires-Dist: packaging
26
27
  Requires-Dist: quarchpy-binaries
27
28
  Requires-Dist: typing-extensions
29
+ Requires-Dist: libusb-package
30
+ Requires-Dist: telnetlib-313-and-up; python_version >= "3.13"
28
31
  Dynamic: author
29
32
  Dynamic: author-email
30
33
  Dynamic: classifier
@@ -32,6 +35,7 @@ Dynamic: description
32
35
  Dynamic: description-content-type
33
36
  Dynamic: keywords
34
37
  Dynamic: license
38
+ Dynamic: license-file
35
39
  Dynamic: requires-dist
36
40
  Dynamic: requires-python
37
41
  Dynamic: summary
@@ -1,11 +1,11 @@
1
1
  quarchpy/LICENSE.rst,sha256=SmYK6o5Xs2xRaUwYT-HqNDRu9eygu6y9QwweXNttiRc,3690
2
2
  quarchpy/QuarchPy Function Listing.xlsx,sha256=NE68cZPn7b9P3wcnCsnQr3H6yBkt6D5S6dH6457X520,31245
3
3
  quarchpy/README.txt,sha256=-LbrJ5rCPGSxoBmvr9CxJVokQUDwZSjoHa43eN8bWck,980
4
- quarchpy/__init__.py,sha256=Tcy5E_CYPeI9gZIXo8HGFU8EEFAHy_iLLLGGvJY0LII,4827
5
- quarchpy/_version.py,sha256=C7lcL4wEmssyY-yDgX28o5czgs4xOCFShHls1_F6jIs,28
4
+ quarchpy/__init__.py,sha256=Qox6pyz_dPX-N5mMraLgur7v9-u8NAUyigvbGCjefco,5003
5
+ quarchpy/_version.py,sha256=_FVcSU9SQj97J4Jk9e2K-JYMHsTCEl3ptgFdZH3NtjI,28
6
6
  quarchpy/connection.py,sha256=9lPIUP4LCWkFAedc8CWorDY-3ujdAA-cyeNkSBdIv9E,2226
7
7
  quarchpy/install_qps.py,sha256=SA5apEma3MOAZUibgwZD7tzQZw8VExTIfBKIFpdhPK0,14276
8
- quarchpy/run.py,sha256=CXclGxRDuXzFKw7jNM0f_ooF-s7TaPxbubnYOYg2BRk,10550
8
+ quarchpy/run.py,sha256=CnvsKWamSSCpSlLA4yhWBeRx7wTHGqn22CrQwft2jxs,10575
9
9
  quarchpy/config_files/__init__.py,sha256=bP9FM5hjP0r7s8qmWqcsVjAfHM0B4XY7cz5sTpe2HDA,290
10
10
  quarchpy/config_files/quarch_config_parser.py,sha256=U3zLFrBcOzUjGXnLy68x5OTzXjdcri2T-oebUFBSku0,28909
11
11
  quarchpy/config_files/Cable_Modules/QTL1253-01 - Mini SAS Module Config v3.5 c1.3.qfg,sha256=ouKaSi7fSp2fjgDKZYXDWXck1WUENPjtz4Ur-GPZlTI,4727
@@ -220,12 +220,12 @@ quarchpy/config_files/Switch_Modules/QTL1564-xx - 12 Port Mini SAS HD MUX Module
220
220
  quarchpy/config_files/Switch_Modules/QTL1584-xx - 1-4 ExpressCard MUX Module Config v4.000.qfg,sha256=EKF_xwQ8EltFothcCRYphSK_Q19Ow1Dg2hmkg6--jfQ,1439
221
221
  quarchpy/connection_specific/StreamChannels.py,sha256=_xBEgDpTCeQue-bsv3fwO3aN1JPWvbuvK3ZwTgvXB4c,601
222
222
  quarchpy/connection_specific/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
223
- quarchpy/connection_specific/connection_QIS.py,sha256=FY8Vm0qQosZujgn5s6Px8CzoZAEcICpANBCYfjdeKdg,66408
224
- quarchpy/connection_specific/connection_QPS.py,sha256=U-XnbnhkUFwJyV07YQr-btTsE4E9tJLaW2lGrZEGew8,9847
223
+ quarchpy/connection_specific/connection_QIS.py,sha256=W_Oqwvq14hzLI5XqbvTsKIzEYy3O8kZ11vC91u2pgZI,66216
224
+ quarchpy/connection_specific/connection_QPS.py,sha256=K9ei0DhIVvF3krQw-Bheh0AUd6NTprE0O-jkmAcwOoQ,14228
225
225
  quarchpy/connection_specific/connection_ReST.py,sha256=rYcC-wv2kO2365_ltyAyN99afTPi1JWb9B5JFRPg5F0,1727
226
226
  quarchpy/connection_specific/connection_Serial.py,sha256=j0KTxOX7c5rmu09s68sqOzHpVV2TyB0WnPc-Cv5YstI,1834
227
227
  quarchpy/connection_specific/connection_TCP.py,sha256=hkKJC9QkopBaaWnWB9xz9LRlvcvGAwvz9w3RxRDXfgc,2427
228
- quarchpy/connection_specific/connection_Telnet.py,sha256=yY6TbkEIEHy-HhXuJbbEjgpX0oPvzlX1EdHa9BNlyLI,1000
228
+ quarchpy/connection_specific/connection_Telnet.py,sha256=n-UJxxaz-Jmehn3uO7fXGvdbjAZ3_swuVaBOTGFtA30,1631
229
229
  quarchpy/connection_specific/connection_USB.py,sha256=PRpYCt_dPIOWneOUPIx_-8NL3BPQ6ps1ZOoZT_M0VWk,26180
230
230
  quarchpy/connection_specific/mDNS.py,sha256=yzI6jkskuW-Ror6wovQc9e9V1Ma2x5AEA-O1k45galE,5739
231
231
  quarchpy/connection_specific/QPS/InstallType.dat,sha256=HsQ1rDwJ3gtYiDSbNQyrtFNHXPBnApYwQpDWyMOv0Vk,21
@@ -573,7 +573,7 @@ quarchpy/connection_specific/QPS/resources/profiles/3_PHASE_PAM_AC_FULL.rcf,sha2
573
573
  quarchpy/connection_specific/QPS/resources/profiles/3_PHASE_PAM_AC_FULL.scf,sha256=4QhGAeC0XqEZXq6r5SBE9oJ-O7b-CjsK4wUwYBg8zQ4,9955
574
574
  quarchpy/connection_specific/QPS/resources/profiles/PAM_EXAMPLE_CONFIG.rcf,sha256=TbQXrBOKkU8pIWNar5Yg7opUZfLZnDEMxvDuLP5rLa0,8269
575
575
  quarchpy/connection_specific/jdk_jres/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
576
- quarchpy/connection_specific/jdk_jres/fix_permissions.py,sha256=PD9MvYomVhhg74BRMikKaln9Urmn7nknwNmAWM1ShaU,1720
576
+ quarchpy/connection_specific/jdk_jres/fix_permissions.py,sha256=WonVdbVH9VQBW3YGeats-vNyEsbu_XC1fjL931_xA2Y,1645
577
577
  quarchpy/connection_specific/serial/__init__.py,sha256=2MXI5_UH-k_ebcv8Gx5LwIBTv4ysX3AyNt6RpYEeTTE,3165
578
578
  quarchpy/connection_specific/serial/rfc2217.py,sha256=RyONj4vDqVjCGqoq1Atu1H_SwHOlPNo_xQqjxYwI4_E,59394
579
579
  quarchpy/connection_specific/serial/rs485.py,sha256=O2YbxLMlziEX1N39WOukrlhMWcYzVwiP95FBhMmUIHc,3265
@@ -601,21 +601,21 @@ quarchpy/connection_specific/serial/urlhandler/protocol_rfc2217.py,sha256=886ex7
601
601
  quarchpy/connection_specific/serial/urlhandler/protocol_socket.py,sha256=iqC8W0kphMlEbVZDYpKuAX4_TT1uWw7Lty9ROHRr6jg,14087
602
602
  quarchpy/connection_specific/serial/urlhandler/protocol_spy.py,sha256=BoFWB9CJHdYjM4kdvxhYAnAJLqy8aiWyhTbtuFioA9w,8847
603
603
  quarchpy/connection_specific/usb_libs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
604
- quarchpy/connection_specific/usb_libs/libusb1.py,sha256=hwqR1G1G2dtla9_TQipz43hT1VHDANnjwIqdes_2qCg,50528
604
+ quarchpy/connection_specific/usb_libs/libusb1.py,sha256=fBsmVtR1-nU_6i4pQhTsXLoey3LnElXwSzkdR1NYL0U,51202
605
605
  quarchpy/connection_specific/usb_libs/usb1.py,sha256=1y8hNPFLiDpU2uwPkrGHASsBxqQzZ4Rbb9nlFHq0T9Y,83376
606
606
  quarchpy/connection_specific/usb_libs/MS32/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
607
607
  quarchpy/connection_specific/usb_libs/MS32/libusb-1.0.dll,sha256=I-lcEsC7bWOoTGACmNzenKnKlZxeOXv_fs4O2UqDwuo,97280
608
608
  quarchpy/connection_specific/usb_libs/MS64/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
609
609
  quarchpy/connection_specific/usb_libs/MS64/libusb-1.0.dll,sha256=kkMfbwPZWak7xgeZH4IYcxc6xXd764fgqQF5T_9z8yg,116224
610
- quarchpy/debug/SystemTest.py,sha256=aJx-FKcY3jvBsSKciKBqe_2goqqbBMHvOwt3zyYiVng,10270
610
+ quarchpy/debug/SystemTest.py,sha256=rUnzas3HOoXvUmGFny_2-dwCfFVuQvrvhfw6DcCQ5vI,12470
611
611
  quarchpy/debug/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
612
612
  quarchpy/debug/__main__.py,sha256=-7ofWPl6ihnVHs1xWyYzpIwzc2-qpW9GhUYV09_xl-k,48
613
- quarchpy/debug/module_debug.py,sha256=zCL4zIfM_N7W43LeqbhpXwldr7pvT_HU8Y4Tvcopg0I,9316
613
+ quarchpy/debug/module_debug.py,sha256=17rWsjMkTG1aYn0GPzvCR0MEWBy5mhrUJVNlqreFogA,9733
614
614
  quarchpy/debug/simple_terminal.py,sha256=FzAdoDluGgW6z_K864SVyyc13TU8ayGBlt_JfUdrQEk,2164
615
615
  quarchpy/debug/upgrade_quarchpy.py,sha256=V_a04-MqhA1dxJEoKy0kWwtIEC6kyvQHBdqOk6pRygc,4235
616
616
  quarchpy/debug/versionCompare.py,sha256=1s6w0tkoKd_1byOb312UqOIwF_1S3C66fqN2YkxIHlE,2434
617
617
  quarchpy/device/__init__.py,sha256=TrJ-62vByGipaYMHZ0_-NT6w10WCFrGcBgC6SFj7gx4,971
618
- quarchpy/device/device.py,sha256=SVlulpT129ulFiBC8vXqMlN5EghheBLZboAmoxFSiC8,65870
618
+ quarchpy/device/device.py,sha256=yTi0Z9DhyKIokC_GO1Lb0PxCsZgNA26105rkTdcdLRo,68075
619
619
  quarchpy/device/device_fixture_idn_info.py,sha256=NnvbTsrYqX6Gx98UwQ5WbPij2rTuJMDdriSw28J4jug,311
620
620
  quarchpy/device/device_idn_info.py,sha256=Iv5NPo8s1P2YE6-R954Z5rcm5v6M2E0iXdgwgd5iEPI,3670
621
621
  quarchpy/device/device_network_info.py,sha256=6OV9bmJMnZbv0x_VN3Z7Fah2ru6ThOjGC_cgtqarLOQ,728
@@ -624,7 +624,7 @@ quarchpy/device/packet_processing.py,sha256=PX9-nRi9pzuruc_t0gvXxHF5pT1PXir2ILTH
624
624
  quarchpy/device/quarchArray.py,sha256=kq3cuOV89Yd3xPoW3_i1_6FpTk4Kh6gxeInNF2wknZs,3001
625
625
  quarchpy/device/quarchPPM.py,sha256=mQxXu49p8ww8s89oehqCEQ_jEb7uCpyt3Y0PK1P00WU,16891
626
626
  quarchpy/device/quarchQPS.py,sha256=cbIh2xgadgeC1MUq1O80d_MChF07ql2cu-0Ihd7vN7g,35939
627
- quarchpy/device/scanDevices.py,sha256=c8_szYUdMx1jhpA2DGnXeiFV1ZZFf17HiJm_ynW0N58,32387
627
+ quarchpy/device/scanDevices.py,sha256=UEbhsIsf_E5Oop7l94s0xM5uRfCJ8PhOWMCBEd7VWcY,33890
628
628
  quarchpy/disk_test/AbsDiskFinder.py,sha256=QhtekaSSKubikGM7aqZ916u7Cc22FLEB7CqGiEvdByc,377
629
629
  quarchpy/disk_test/DiskTargetSelection.py,sha256=BY3zc7mg7FPxEp9OB2yRkyYIHRwrAB6U0XrsSWZrKU4,925
630
630
  quarchpy/disk_test/__init__.py,sha256=3-LXyQMX5macnPaHc8J3mcJQ7faTInycD8-skQYyFbE,59
@@ -747,9 +747,9 @@ quarchpy/iometer/gen_iometer_template.py,sha256=f0YM786dG4c1Bioq6zeclG83r8HBaffO
747
747
  quarchpy/iometer/iometerFuncs.py,sha256=qc0GK2SiCUHU_7mGL0z35MyNCdTcfSEf2wR1zti6KDY,14178
748
748
  quarchpy/qis/StreamHeaderInfo.py,sha256=InbVGRGrLCcIISZHb-IMmLu3gLx5RkAO1tUnEqM-pHM,8185
749
749
  quarchpy/qis/__init__.py,sha256=QRVPy96G7RUx6ldofcD-xNN4NHeNjkasSu8DXkyRB0k,307
750
- quarchpy/qis/qisFuncs.py,sha256=oVrGmGzfwv0xy4GV4jPPs44SqWd5ywA5of78WzSqQAk,13219
750
+ quarchpy/qis/qisFuncs.py,sha256=KRlpISvCpTnqqhaEFpsT5eG0ELglZhGTU-XWOEZ2w0w,16239
751
751
  quarchpy/qps/__init__.py,sha256=Kq5Ae1hy6c0nw26OwY1X31e72-wZ4C8RraTku6pvEfw,270
752
- quarchpy/qps/qpsFuncs.py,sha256=8a29CzMSi6AmJnHhPP2B4seYPnm2I-8yoVSu1i00nwc,12244
752
+ quarchpy/qps/qpsFuncs.py,sha256=d8FP4XT7F7MyryBl0cu7ErSLwC8BxtsM7myjqaRRCa8,14320
753
753
  quarchpy/user_interface/__init__.py,sha256=ix0icQvmKUTRgvfhXK3PxiDGyITkPYY-08hFjuhbupo,298
754
754
  quarchpy/user_interface/user_interface.py,sha256=NvN-9yL8jMn6DwY9KN1oQKXELDa3v3iVvqblsi9ZZVQ,29586
755
755
  quarchpy/utilities/BitManipulation.py,sha256=vLw2PF5z-d-2MY_yEU0l9FEBYTlCklM336XU2vPKAas,1016
@@ -757,7 +757,8 @@ quarchpy/utilities/TestCenter.py,sha256=5D63n-Wh1ADR5XSzxq1PAfynSEW-eN7fy9yMo3fI
757
757
  quarchpy/utilities/TimeValue.py,sha256=GJ5uxMkcnpRMFst5hoArZiPsUqLieLcKhMn_OdOmZwI,2192
758
758
  quarchpy/utilities/Version.py,sha256=i57qRgHwGSXf2wPVVNUZfG9Tu6f5hWxZLPy7XCw2WkQ,1578
759
759
  quarchpy/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
760
- quarchpy-2.2.17.dev2.dist-info/METADATA,sha256=uOp1z1MyIk2ZnF7sK5bXeYuJwA-3xsplwH_GOu566Rk,10982
761
- quarchpy-2.2.17.dev2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
762
- quarchpy-2.2.17.dev2.dist-info/top_level.txt,sha256=Vc7qsvkVax7oeBaBy_e7kvJvqb_VAAJcW_MuDMmi5W8,9
763
- quarchpy-2.2.17.dev2.dist-info/RECORD,,
760
+ quarchpy-2.2.17.dev3.dist-info/licenses/LICENSE.txt,sha256=J7M5LonAD_ayP8wONOX7bcr5ByY463vuNYbjI23Xo4M,1076
761
+ quarchpy-2.2.17.dev3.dist-info/METADATA,sha256=m2sBb8ikREqRaBx0vxZprWBIE7WtnK6K64FB2qkqRTI,11122
762
+ quarchpy-2.2.17.dev3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
763
+ quarchpy-2.2.17.dev3.dist-info/top_level.txt,sha256=Vc7qsvkVax7oeBaBy_e7kvJvqb_VAAJcW_MuDMmi5W8,9
764
+ quarchpy-2.2.17.dev3.dist-info/RECORD,,