quarchpy 2.1.13.dev2__py2.py3-none-any.whl → 2.1.14.dev2__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- quarchpy/.idea/modules.xml +1 -0
- quarchpy/.idea/quarchpy.iml +4 -1
- quarchpy/.idea/workspace.xml +149 -11
- quarchpy/_version.py +1 -1
- quarchpy/connection_specific/connection_QIS.py +213 -315
- quarchpy/connection_specific/connection_QIS.py.bak +253 -357
- quarchpy/connection_specific/connection_TCP.py +1 -1
- quarchpy/connection_specific/connection_mDNS.py +46 -0
- quarchpy/device/quarchPPM.py +2 -2
- quarchpy/device/quarchQPS.py +95 -86
- quarchpy/device/scanDevices.py +12 -0
- quarchpy/docs/CHANGES.rst +7 -1
- quarchpy/qps/qpsFuncs.py +7 -4
- quarchpy/run.py +1 -1
- quarchpy/user_interface/user_interface.py.bak +3 -5
- quarchpy/utilities/TestCenter.py +1 -1
- quarchpy/utilities/TestCenter.py.bak +1 -4
- quarchpy/utilities/Version.py +50 -0
- {quarchpy-2.1.13.dev2.dist-info → quarchpy-2.1.14.dev2.dist-info}/METADATA +8 -2
- {quarchpy-2.1.13.dev2.dist-info → quarchpy-2.1.14.dev2.dist-info}/RECORD +22 -79
- quarchpy/.idea/.name +0 -1
- quarchpy/.idea/inspectionProfiles/Project_Default.xml +0 -26
- quarchpy/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/__pycache__/_version.cpython-311.pyc +0 -0
- quarchpy/__pycache__/connection.cpython-311.pyc +0 -0
- quarchpy/__pycache__/run.cpython-311.pyc +0 -0
- quarchpy/config_files/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/config_files/__pycache__/quarch_config_parser.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/StreamChannels.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_QIS.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_QPS.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_ReST.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_Serial.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_USB.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/serialutil.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/serialwin32.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/win32.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports_common.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports_windows.cpython-311.pyc +0 -0
- quarchpy/connection_specific/usb_libs/__pycache__/libusb1.cpython-311.pyc +0 -0
- quarchpy/connection_specific/usb_libs/__pycache__/usb1.cpython-311.pyc +0 -0
- quarchpy/debug/TextScanIP.py +0 -11
- quarchpy/debug/__pycache__/SystemTest.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/module_debug.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/simple_terminal.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/upgrade_quarchpy.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/versionCompare.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/device.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/quarchArray.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/quarchPPM.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/quarchQPS.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/scanDevices.cpython-311.pyc +0 -0
- quarchpy/device/device.py.bak +0 -504
- quarchpy/device/scanDevices.py.bak +0 -661
- quarchpy/disk_test/__pycache__/AbsDiskFinder.cpython-311.pyc +0 -0
- quarchpy/disk_test/__pycache__/DiskTargetSelection.cpython-311.pyc +0 -0
- quarchpy/disk_test/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/disk_test/__pycache__/iometerDiskFinder.cpython-311.pyc +0 -0
- quarchpy/fio/__pycache__/FIO_interface.cpython-311.pyc +0 -0
- quarchpy/fio/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/iometer/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/iometer/__pycache__/gen_iometer_template.cpython-311.pyc +0 -0
- quarchpy/iometer/__pycache__/iometerFuncs.cpython-311.pyc +0 -0
- quarchpy/qis/__pycache__/StreamHeaderInfo.cpython-311.pyc +0 -0
- quarchpy/qis/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/qis/__pycache__/qisFuncs.cpython-311.pyc +0 -0
- quarchpy/qps/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/qps/__pycache__/qpsFuncs.cpython-311.pyc +0 -0
- quarchpy/user_interface/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/user_interface/__pycache__/user_interface.cpython-311.pyc +0 -0
- quarchpy/utilities/__pycache__/TestCenter.cpython-311.pyc +0 -0
- quarchpy/utilities/__pycache__/TimeValue.cpython-311.pyc +0 -0
- quarchpy/utilities/__pycache__/__init__.cpython-311.pyc +0 -0
- {quarchpy-2.1.13.dev2.dist-info → quarchpy-2.1.14.dev2.dist-info}/WHEEL +0 -0
- {quarchpy-2.1.13.dev2.dist-info → quarchpy-2.1.14.dev2.dist-info}/top_level.txt +0 -0
@@ -14,7 +14,7 @@ class TCPConn:
|
|
14
14
|
self.Connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
15
15
|
#Sets buffer size
|
16
16
|
self.BufferSize = 4096
|
17
|
-
#Opens the
|
17
|
+
#Opens the connection
|
18
18
|
self.Connection.connect((self.ConnTarget, TCP_PORT))
|
19
19
|
|
20
20
|
def close(self):
|
@@ -0,0 +1,46 @@
|
|
1
|
+
from zeroconf import Zeroconf
|
2
|
+
|
3
|
+
|
4
|
+
class MyListener:
|
5
|
+
def __init__(self):
|
6
|
+
self.found_devices = {}
|
7
|
+
|
8
|
+
def update_service(self, zc: Zeroconf, type_: str, name: str) -> None:
|
9
|
+
return None
|
10
|
+
|
11
|
+
def remove_service(self, zc: Zeroconf, type_: str, name: str) -> None:
|
12
|
+
print("hello")
|
13
|
+
info = zc.get_service_info(type_, name)
|
14
|
+
if "Quarch:" in str(info):
|
15
|
+
decoded_properties = {key.decode('utf-8'): value.decode('utf-8') for key, value in info.properties.items()}
|
16
|
+
qtl_num = "QTL" + decoded_properties['86'] if '86' in decoded_properties else None
|
17
|
+
for key, value in self.found_devices:
|
18
|
+
if value == qtl_num:
|
19
|
+
print("item deleted")
|
20
|
+
print(self.found_devices)
|
21
|
+
del self.found_devices[key]
|
22
|
+
|
23
|
+
def add_service(self, zc: Zeroconf, type_: str, name: str) -> None:
|
24
|
+
info = zc.get_service_info(type_, name)
|
25
|
+
if "Quarch:" in str(info):
|
26
|
+
# decode the incoming properties from mdns
|
27
|
+
decoded_properties = {key.decode('utf-8'): value.decode('utf-8') for key, value in info.properties.items()}
|
28
|
+
decoded_ip = ".".join(str(byte) for byte in info.addresses[0])
|
29
|
+
self.add_device(decoded_properties, decoded_ip)
|
30
|
+
|
31
|
+
def add_device(self, properties_dict, ip_address):
|
32
|
+
qtl_num = "QTL" + properties_dict['86'] if '86' in properties_dict else None
|
33
|
+
if '84' in properties_dict:
|
34
|
+
if properties_dict['84'] == '80':
|
35
|
+
# print("Rest connection exists for device: " + qtl_num)
|
36
|
+
self.update_device_dict(device_dict={"REST:" + ip_address: qtl_num})
|
37
|
+
if '85' in properties_dict:
|
38
|
+
if properties_dict['85'] == "9760":
|
39
|
+
# print("TCP connection exists for device: " + qtl_num)
|
40
|
+
self.update_device_dict(device_dict={"TCP:" + ip_address: qtl_num})
|
41
|
+
|
42
|
+
def update_device_dict(self, device_dict):
|
43
|
+
self.found_devices.update(device_dict)
|
44
|
+
|
45
|
+
|
46
|
+
listener = MyListener()
|
quarchpy/device/quarchPPM.py
CHANGED
@@ -12,8 +12,8 @@ class quarchPPM(quarchDevice):
|
|
12
12
|
if numb_colons == 1:
|
13
13
|
self.ConString = self.ConString.replace(':', '::')
|
14
14
|
|
15
|
-
def startStream(self, fileName='streamData.txt', fileMaxMB=200000, streamName ='Stream With No Name', streamDuration = None, streamAverage = None, releaseOnData = False, separator=","):
|
16
|
-
return self.connectionObj.qis.startStream(self.ConString, fileName, fileMaxMB, streamName, streamAverage, releaseOnData, separator, streamDuration)
|
15
|
+
def startStream(self, fileName='streamData.txt', fileMaxMB=200000, streamName ='Stream With No Name', streamDuration = None, streamAverage = None, releaseOnData = False, separator=",", inMemoryData = None):
|
16
|
+
return self.connectionObj.qis.startStream(self.ConString, fileName, fileMaxMB, streamName, streamAverage, releaseOnData, separator, streamDuration, inMemoryData)
|
17
17
|
|
18
18
|
def streamRunningStatus(self):
|
19
19
|
return self.connectionObj.qis.streamRunningStatus(self.ConString)
|
quarchpy/device/quarchQPS.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
from quarchpy.device import quarchDevice
|
2
2
|
from quarchpy.qps import toQpsTimeStamp
|
3
|
+
from quarchpy.utilities.Version import Version
|
3
4
|
import os, time, datetime, sys, logging
|
4
5
|
|
5
6
|
if sys.version_info[0] < 3:
|
@@ -7,19 +8,19 @@ if sys.version_info[0] < 3:
|
|
7
8
|
else:
|
8
9
|
from io import StringIO
|
9
10
|
|
10
|
-
current_milli_time = lambda: int
|
11
|
-
current_second_time = lambda: int
|
11
|
+
current_milli_time = lambda: int(round(time.time() * 1000))
|
12
|
+
current_second_time = lambda: int(round(time.time()))
|
13
|
+
|
12
14
|
|
13
15
|
# Using standard Unix time, milliseconds since the epoch (midnight 1 January 1970 UTC)
|
14
16
|
# Should avoid issues with time zones and summer time correction but the local and host
|
15
17
|
# clocks should still be synchronised
|
16
18
|
def qpsNowStr():
|
17
|
-
return current_milli_time()
|
19
|
+
return current_milli_time() # datetime supports microseconds
|
18
20
|
|
19
21
|
|
20
22
|
class quarchQPS(quarchDevice):
|
21
23
|
def __init__(self, quarchDevice):
|
22
|
-
|
23
24
|
self.quarchDevice = quarchDevice
|
24
25
|
self.ConType = quarchDevice.ConType
|
25
26
|
self.ConString = quarchDevice.ConString
|
@@ -33,13 +34,10 @@ class quarchQPS(quarchDevice):
|
|
33
34
|
directory - str - desired stream dir
|
34
35
|
unserInput=True - if a failure occurs userInput=True allows user to rectify problem with user input. set to False if user interaction is not available (automating).
|
35
36
|
"""
|
36
|
-
time.sleep(1)
|
37
|
+
time.sleep(1) # TODO remove this sleep once script->QPS timeing issue resolved. This works fine in the meantime
|
37
38
|
return quarchStream(self.quarchDevice, directory, unserInput)
|
38
39
|
|
39
40
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
41
|
class quarchStream:
|
44
42
|
def __init__(self, quarchQPS, directory, unserInput=True):
|
45
43
|
self.connectionObj = quarchQPS.connectionObj
|
@@ -59,21 +57,23 @@ class quarchStream:
|
|
59
57
|
|
60
58
|
def startQPSStream(self, newDirectory):
|
61
59
|
'''STARTS the stream '''
|
62
|
-
response = self.connectionObj.qps.sendCmdVerbose("$start stream \"" + str(newDirectory)+"\"")
|
60
|
+
response = self.connectionObj.qps.sendCmdVerbose("$start stream \"" + str(newDirectory) + "\"")
|
61
|
+
if "Error" in response:
|
62
|
+
response = self.connectionObj.qps.sendCmdVerbose("$start stream " + str(newDirectory))
|
63
63
|
return response
|
64
64
|
|
65
65
|
def failCheck(self, response):
|
66
66
|
''' handles failed starting of stream that requires input from user to fix.'''
|
67
67
|
while "fail:" in response.lower():
|
68
68
|
if "Fail: Directory already exists" in response:
|
69
|
-
print
|
69
|
+
print(response)
|
70
70
|
print("Please enter a new file name:")
|
71
|
-
if sys.version_info.major==3:
|
71
|
+
if sys.version_info.major == 3:
|
72
72
|
newDir = input()
|
73
73
|
else:
|
74
74
|
newDir = raw_input()
|
75
|
-
response = self.startQPSStream(
|
76
|
-
else: #
|
75
|
+
response = self.startQPSStream(newDir)
|
76
|
+
else: # If its a failure we don't know how to handle.
|
77
77
|
raise Exception(response)
|
78
78
|
return response
|
79
79
|
|
@@ -93,22 +93,23 @@ class quarchStream:
|
|
93
93
|
if format == "df":
|
94
94
|
try:
|
95
95
|
import warnings
|
96
|
+
import pandas as pd
|
96
97
|
warnings.simplefilter(action='ignore', category=FutureWarning)
|
97
|
-
if 'pandas' in sys.modules or 'pd' in sys.modules:
|
98
|
-
logging.debug("Pandas already imported.")
|
99
|
-
else:
|
100
|
-
import pandas as pd
|
101
|
-
pd.set_option('display.max_columns', None)
|
102
|
-
pd.set_option('display.width', 1024)
|
103
98
|
except Exception as e:
|
104
99
|
logging.error(e)
|
105
100
|
logging.warning("pandas not imported correctly. Continuing")
|
106
|
-
|
101
|
+
pd.set_option('display.max_columns', None)
|
102
|
+
pd.set_option('display.width', 1024)
|
107
103
|
test_data = StringIO(command_response)
|
108
|
-
|
104
|
+
|
105
|
+
# pandas.read_csv() replaced error_bad_lines with on_bad_lines from v1.3.0
|
106
|
+
if Version.is_v1_ge_v2(pd.__version__, "1.3.0"):
|
107
|
+
retVal = pd.read_csv(test_data, sep=",", header=[0, 1], on_bad_lines="skip")
|
108
|
+
else:
|
109
|
+
retVal = pd.read_csv(test_data, sep=",", header=[0, 1], error_bad_lines=False)
|
109
110
|
elif format == "list":
|
110
111
|
retVal = []
|
111
|
-
for line in command_response.replace("\r\n","\n").split("\n"):
|
112
|
+
for line in command_response.replace("\r\n", "\n").split("\n"):
|
112
113
|
row = []
|
113
114
|
for element in line.split(","):
|
114
115
|
row.append(element)
|
@@ -116,7 +117,6 @@ class quarchStream:
|
|
116
117
|
|
117
118
|
return retVal
|
118
119
|
|
119
|
-
|
120
120
|
def stats_to_CSV(self, file_name=""):
|
121
121
|
"""
|
122
122
|
Saves the statistics grid to a csv file
|
@@ -132,7 +132,7 @@ class quarchStream:
|
|
132
132
|
|
133
133
|
The response text from QPS. If successful "ok. Saving stats to : file_name" otherwise returns the exception thrown
|
134
134
|
"""
|
135
|
-
command_response = self.connectionObj.qps.sendCmdVerbose("$stats to csv \""+file_name+"\"", timeout=60)
|
135
|
+
command_response = self.connectionObj.qps.sendCmdVerbose("$stats to csv \"" + file_name + "\"", timeout=60)
|
136
136
|
if command_response.startswith("Fail"):
|
137
137
|
raise Exception(command_response)
|
138
138
|
return command_response
|
@@ -158,22 +158,24 @@ class quarchStream:
|
|
158
158
|
"""
|
159
159
|
try:
|
160
160
|
import warnings
|
161
|
+
import pandas as pd
|
161
162
|
warnings.simplefilter(action='ignore', category=FutureWarning)
|
162
|
-
if 'pandas' in sys.modules or 'pd' in sys.modules:
|
163
|
-
logging.debug("Pandas already imported.")
|
164
|
-
else:
|
165
|
-
import pandas as pd
|
166
|
-
pd.set_option('max_columns', None)
|
167
|
-
pd.set_option('display.width', 1024)
|
168
163
|
except:
|
169
164
|
logging.warning("pandas not imported correctly")
|
170
|
-
|
171
|
-
|
165
|
+
command_response = self.connectionObj.qps.sendCmdVerbose(
|
166
|
+
"$get custom stats range " + str(start_time) + " " + str(end_time), timeout=60)
|
172
167
|
if command_response.startswith("Fail"):
|
173
168
|
raise Exception(command_response)
|
174
169
|
test_data = StringIO(command_response)
|
175
170
|
try:
|
176
|
-
|
171
|
+
pd.set_option('display.max_columns', None)
|
172
|
+
pd.set_option('display.width', 1024)
|
173
|
+
# df = pd.read_csv(test_data, sep=",", header=[0,1])
|
174
|
+
# pandas.read_csv() replaced error_bad_lines with on_bad_lines from v1.3.0
|
175
|
+
if Version.is_v1_ge_v2(pd.__version__, "1.3.0"):
|
176
|
+
df = pd.read_csv(test_data, sep=",", header=[0, 1], on_bad_lines="skip")
|
177
|
+
else:
|
178
|
+
df = pd.read_csv(test_data, sep=",", header=[0, 1], error_bad_lines=False)
|
177
179
|
except Exception as e:
|
178
180
|
logging.error("Unable to create pandas data frame from command response :" + str(command_response))
|
179
181
|
raise e
|
@@ -186,7 +188,7 @@ class quarchStream:
|
|
186
188
|
command_response = self.connectionObj.qps.sendCmdVerbose("$take snapshot")
|
187
189
|
if command_response.startswith("Fail"):
|
188
190
|
raise Exception(command_response)
|
189
|
-
return(command_response)
|
191
|
+
return (command_response)
|
190
192
|
|
191
193
|
def getStreamState(self):
|
192
194
|
"""
|
@@ -198,9 +200,10 @@ class quarchStream:
|
|
198
200
|
command_response = self.connectionObj.qps.sendCmdVerbose("$stream state")
|
199
201
|
if command_response.startswith("Fail"):
|
200
202
|
raise Exception(command_response)
|
201
|
-
return(command_response)
|
203
|
+
return (command_response)
|
202
204
|
|
203
|
-
def addAnnotation(self, title, annotationTime
|
205
|
+
def addAnnotation(self, title, annotationTime=0, extraText="", yPos="", titleColor="", annotationColor="",
|
206
|
+
annotationType="", annotationGroup=""):
|
204
207
|
"""
|
205
208
|
Adds a custom annotation to stream with given parameters.
|
206
209
|
|
@@ -232,7 +235,7 @@ class quarchStream:
|
|
232
235
|
if annotationType == "" or annotationType == "annotation":
|
233
236
|
annotationType = "annotate"
|
234
237
|
elif annotationType == "comment":
|
235
|
-
pass
|
238
|
+
pass # already in the correct format for command
|
236
239
|
else:
|
237
240
|
retString = "Fail annotationType must be 'annotation' or 'comment'"
|
238
241
|
logging.warning(retString)
|
@@ -247,14 +250,13 @@ class quarchStream:
|
|
247
250
|
if annotationTime == "0":
|
248
251
|
# Use current time
|
249
252
|
annotationTime = qpsNowStr()
|
250
|
-
elif(annotationTime.startswith("e")):
|
253
|
+
elif (annotationTime.startswith("e")):
|
251
254
|
pass
|
252
255
|
else:
|
253
256
|
# Convert timestamp to QPS format
|
254
|
-
#annotationTime = toQpsTimeStamp(annotationTime)
|
257
|
+
# annotationTime = toQpsTimeStamp(annotationTime)
|
255
258
|
annotationTime = str(annotationTime)
|
256
259
|
|
257
|
-
|
258
260
|
if title != "":
|
259
261
|
annotationString += "<text>" + str(title) + "</text>"
|
260
262
|
if extraText != "":
|
@@ -272,16 +274,20 @@ class quarchStream:
|
|
272
274
|
# command is sent on newline so \n needs to be chnaged to \\n which is changed back just before printing in qps.
|
273
275
|
annotationString = annotationString.replace("\n", "\\n")
|
274
276
|
logging.debug("Time sending to QPS:" + str(annotationTime))
|
275
|
-
return self.connectionObj.qps.sendCmdVerbose(
|
277
|
+
return self.connectionObj.qps.sendCmdVerbose(
|
278
|
+
"$" + annotationType + " " + str(annotationTime) + " " + annotationString)
|
276
279
|
|
277
|
-
def addComment(self, title, commentTime
|
278
|
-
|
279
|
-
#
|
280
|
+
def addComment(self, title, commentTime=0, extraText="", yPos="", titleColor="", commentColor="", annotationType="",
|
281
|
+
annotationGroup=""):
|
282
|
+
# Comments are just annotations that do not affect the statistics grid.
|
283
|
+
# This function was kept to be backwards compatible and is a simple pass through to add annotation.
|
280
284
|
if annotationType == "":
|
281
285
|
annotationType = "comment"
|
282
|
-
return self.addAnnotation(title
|
286
|
+
return self.addAnnotation(title=title, annotationTime=commentTime, extraText=extraText, yPos=yPos,
|
287
|
+
titleColor=titleColor, annotationColor=commentColor, annotationType=annotationType,
|
288
|
+
annotationGroup=annotationGroup)
|
283
289
|
|
284
|
-
def saveCSV(self,filePath, linesPerFile=None, cr=None, delimiter=None, timeout=60):
|
290
|
+
def saveCSV(self, filePath, linesPerFile=None, cr=None, delimiter=None, timeout=60):
|
285
291
|
"""
|
286
292
|
Saves the stream to csv file at specified location
|
287
293
|
|
@@ -306,26 +312,27 @@ class quarchStream:
|
|
306
312
|
args = ""
|
307
313
|
|
308
314
|
if linesPerFile != None:
|
309
|
-
args +=" -l" + str(linesPerFile)
|
310
|
-
if cr !=None:
|
315
|
+
args += " -l" + str(linesPerFile)
|
316
|
+
if cr != None:
|
311
317
|
if cr is True:
|
312
|
-
args+= " -cyes"
|
318
|
+
args += " -cyes"
|
313
319
|
elif cr is False:
|
314
320
|
args += " -cno"
|
315
|
-
if delimiter !=None:
|
316
|
-
args += " -s"+delimiter
|
321
|
+
if delimiter != None:
|
322
|
+
args += " -s" + delimiter
|
317
323
|
|
318
|
-
|
324
|
+
# , filePath, linesPerFile, cr, delimiter
|
319
325
|
return self.connectionObj.qps.sendCmdVerbose("$save csv \"" + filePath + "\" " + args, timeout=timeout)
|
320
326
|
|
321
327
|
def createChannel(self, channelName, channelGroup, baseUnits, usePrefix):
|
322
|
-
#Conditions to convert false / true inputs to specification input
|
323
|
-
if usePrefix == False:
|
328
|
+
# Conditions to convert false / true inputs to specification input
|
329
|
+
if usePrefix == False:
|
324
330
|
usePrefix = "no"
|
325
331
|
if usePrefix == True:
|
326
332
|
usePrefix = "yes"
|
327
333
|
|
328
|
-
return self.connectionObj.qps.sendCmdVerbose(
|
334
|
+
return self.connectionObj.qps.sendCmdVerbose(
|
335
|
+
"$create channel " + channelName + " " + channelGroup + " " + baseUnits + " " + usePrefix)
|
329
336
|
|
330
337
|
def hideChannel(self, channelSpecifier):
|
331
338
|
return self.connectionObj.qps.sendCmdVerbose("$hide channel " + channelSpecifier)
|
@@ -338,7 +345,7 @@ class quarchStream:
|
|
338
345
|
|
339
346
|
def channels(self):
|
340
347
|
return self.connectionObj.qps.sendCmdVerbose("$channels").splitlines()
|
341
|
-
|
348
|
+
|
342
349
|
def stopStream(self):
|
343
350
|
return self.connectionObj.qps.sendCmdVerbose("$stop stream")
|
344
351
|
|
@@ -346,37 +353,37 @@ class quarchStream:
|
|
346
353
|
self.stopStream()
|
347
354
|
streamState = self.getStreamState().lower()
|
348
355
|
while "running" in streamState:
|
349
|
-
logging.debug("Stream buffer still emptying: "+ streamState)
|
356
|
+
logging.debug("Stream buffer still emptying: " + streamState)
|
350
357
|
time.sleep(checkInterval)
|
351
358
|
streamState = self.getStreamState().lower()
|
352
359
|
logging.debug("QPS no longer Streaming: " + streamState)
|
353
360
|
|
354
361
|
def hideAllDefaultChannels(self):
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
self.hideChannel
|
359
|
-
self.hideChannel
|
360
|
-
self.hideChannel
|
361
|
-
self.hideChannel
|
362
|
-
self.hideChannel
|
363
|
-
self.hideChannel
|
364
|
-
self.hideChannel
|
365
|
-
self.hideChannel
|
366
|
-
self.hideChannel
|
367
|
-
self.hideChannel
|
368
|
-
self.hideChannel
|
369
|
-
self.hideChannel
|
370
|
-
self.hideChannel
|
371
|
-
#Default PAM channels
|
372
|
-
self.hideChannel
|
373
|
-
self.hideChannel
|
374
|
-
self.hideChannel
|
375
|
-
self.hideChannel
|
376
|
-
self.hideChannel
|
377
|
-
|
378
|
-
#function to add a data point the the stream
|
379
|
-
#time value will default to current time if none passed
|
362
|
+
|
363
|
+
# TODO query QPS / Device for all channel names and hide all of them
|
364
|
+
# All Default Channels
|
365
|
+
self.hideChannel("3.3v:voltage")
|
366
|
+
self.hideChannel("3v3:voltage")
|
367
|
+
self.hideChannel("5v:voltage")
|
368
|
+
self.hideChannel("12v:voltage")
|
369
|
+
self.hideChannel("3v3:current")
|
370
|
+
self.hideChannel("3.3v:current")
|
371
|
+
self.hideChannel("5v:current")
|
372
|
+
self.hideChannel("12v:current")
|
373
|
+
self.hideChannel("3v3:power")
|
374
|
+
self.hideChannel("3.3v:power")
|
375
|
+
self.hideChannel("5v:power")
|
376
|
+
self.hideChannel("12v:power")
|
377
|
+
self.hideChannel("tot:power")
|
378
|
+
# Default PAM channels
|
379
|
+
self.hideChannel("perst#:digital")
|
380
|
+
self.hideChannel("wake#:digital")
|
381
|
+
self.hideChannel("lkreq#:digital")
|
382
|
+
self.hideChannel("smclk:digital")
|
383
|
+
self.hideChannel("smdat:digital")
|
384
|
+
|
385
|
+
# function to add a data point the the stream
|
386
|
+
# time value will default to current time if none passed
|
380
387
|
def addDataPoint(self, channelName, groupName, dataValue, dataPointTime=0, timeFormat="unix"):
|
381
388
|
'''
|
382
389
|
channelName - str
|
@@ -388,9 +395,11 @@ class quarchStream:
|
|
388
395
|
if dataPointTime == None or dataPointTime == 0:
|
389
396
|
dataPointTime = qpsNowStr()
|
390
397
|
else:
|
391
|
-
dataPointTime = toQpsTimeStamp
|
398
|
+
dataPointTime = toQpsTimeStamp(dataPointTime)
|
392
399
|
|
393
|
-
#print ("printing command: $log " + channelName + " " + groupName + " " + str(dataPointTime) + " " + str(dataValue))
|
394
|
-
#self.connectionObj.qps.sendCmdVerbose("$log " + channelName + " " + groupName + " " + str(dataPointTime) + " " + str(dataValue))
|
400
|
+
# print ("printing command: $log " + channelName + " " + groupName + " " + str(dataPointTime) + " " + str(dataValue))
|
401
|
+
# self.connectionObj.qps.sendCmdVerbose("$log " + channelName + " " + groupName + " " + str(dataPointTime) + " " + str(dataValue))
|
395
402
|
|
396
|
-
self.connectionObj.qps.sendCmdVerbose(
|
403
|
+
self.connectionObj.qps.sendCmdVerbose(
|
404
|
+
"$stream data add " + channelName + " " + groupName + " " + str(dataPointTime) + " " + str(
|
405
|
+
dataValue) + " " + timeFormat)
|
quarchpy/device/scanDevices.py
CHANGED
@@ -20,6 +20,9 @@ from quarchpy.connection_specific.connection_Serial import serialList, serial
|
|
20
20
|
from quarchpy.device.quarchArray import isThisAnArrayController
|
21
21
|
from quarchpy.connection_specific.connection_USB import TQuarchUSB_IF
|
22
22
|
from quarchpy.connection_specific import connection_ReST
|
23
|
+
from quarchpy.connection_specific.connection_mDNS import MyListener
|
24
|
+
|
25
|
+
from zeroconf import ServiceBrowser, Zeroconf
|
23
26
|
|
24
27
|
# TODO: bodge bodge bodge
|
25
28
|
from quarchpy.utilities import TestCenter
|
@@ -455,6 +458,11 @@ def filter_module_type(module_type_filter, found_devices):
|
|
455
458
|
filtered_devices.update({key: value})
|
456
459
|
return filtered_devices
|
457
460
|
|
461
|
+
def scan_mDNS(mdnsListener):
|
462
|
+
zeroconf = Zeroconf()
|
463
|
+
listener = mdnsListener
|
464
|
+
browser = ServiceBrowser(zeroconf, "_http._tcp.local.", listener)
|
465
|
+
|
458
466
|
|
459
467
|
'''
|
460
468
|
Scans for Quarch modules across the given interface(s). Returns a dictionary of module addresses and serial numbers
|
@@ -463,6 +471,9 @@ def scanDevices(target_conn="all", lanTimeout=1, scanInArray=True, favouriteOnly
|
|
463
471
|
module_type_filter=None, ipAddressLookup=None):
|
464
472
|
foundDevices = dict()
|
465
473
|
scannedArrays = list()
|
474
|
+
mdnsListener = MyListener()
|
475
|
+
|
476
|
+
scan_mDNS(mdnsListener)
|
466
477
|
|
467
478
|
if target_conn.lower() == "all":
|
468
479
|
foundDevices = list_USB()
|
@@ -470,6 +481,7 @@ def scanDevices(target_conn="all", lanTimeout=1, scanInArray=True, favouriteOnly
|
|
470
481
|
try:
|
471
482
|
#This will fail if the test machine is not connected to a network
|
472
483
|
foundDevices = mergeDict(foundDevices, list_network("all", ipAddressLookup=ipAddressLookup, lanTimeout=lanTimeout))
|
484
|
+
foundDevices = mergeDict(foundDevices, mdnsListener.found_devices)
|
473
485
|
except Exception as e:
|
474
486
|
logging.error(e)
|
475
487
|
logging.warning("Network scan failed, check network connection")
|
quarchpy/docs/CHANGES.rst
CHANGED
@@ -13,11 +13,17 @@ Quarchpy
|
|
13
13
|
Change Log
|
14
14
|
----------
|
15
15
|
|
16
|
+
2.1.13
|
17
|
+
------
|
18
|
+
- New QPS v1.36
|
19
|
+
- New QIS v1.39
|
20
|
+
- minor bug fixes and logging improvements.
|
21
|
+
|
16
22
|
2.1.12
|
17
23
|
------
|
18
24
|
- New QPS v1.35
|
19
25
|
- New QIS v1.38
|
20
|
-
- minor bug fixes and removal of
|
26
|
+
- minor bug fixes and removal of depracated code.
|
21
27
|
|
22
28
|
2.1.11
|
23
29
|
------
|
quarchpy/qps/qpsFuncs.py
CHANGED
@@ -85,16 +85,19 @@ def startLocalQps(keepQisRunning=False, args=[]):
|
|
85
85
|
|
86
86
|
currentOs = platform.system()
|
87
87
|
|
88
|
-
if
|
89
|
-
command = "start /high /b javaw -Djava.awt.headless=true " + command +" " + str(args)
|
88
|
+
if currentOs in "Windows":
|
89
|
+
command = "start /high /b javaw -Djava.awt.headless=true " + command + " " + str(args)
|
90
|
+
command = command + "-ccs=HIDE" # note: multiple -ccs options ignored
|
90
91
|
os.system(command)
|
91
|
-
elif
|
92
|
+
elif currentOs in "Linux":
|
93
|
+
command = command + "-ccs=HIDE"
|
92
94
|
if sys.version_info[0] < 3:
|
93
95
|
os.popen2("java " + command + " 2>&1")
|
94
96
|
else:
|
95
97
|
os.popen("java " + command + " 2>&1")
|
96
|
-
else:
|
98
|
+
else: # default to Windows
|
97
99
|
command = "start /high /b javaw -Djava.awt.headless=true " + command + " " + str(args)
|
100
|
+
command = command + "-ccs=HIDE"
|
98
101
|
os.system(command)
|
99
102
|
|
100
103
|
while not isQpsRunning():
|
quarchpy/run.py
CHANGED
@@ -10,7 +10,6 @@ and support for both terminal and TestCenter (quarch internal) execution
|
|
10
10
|
# Needed for python2 compatibility
|
11
11
|
# coding: utf-8
|
12
12
|
from __future__ import print_function
|
13
|
-
import tempfile
|
14
13
|
|
15
14
|
import traceback, sys, os, math, logging
|
16
15
|
from quarchpy.utilities import TestCenter
|
@@ -240,7 +239,7 @@ prints a message to the user and waits for acknowledgement
|
|
240
239
|
def showDialog(message="",title=""):
|
241
240
|
|
242
241
|
|
243
|
-
|
242
|
+
if User_interface.instance != None and User_interface.instance.selectedInterface == "testcenter":
|
244
243
|
TestCenter.testPoint ("Quarch_Host.ShowDialog","Title=" + __formatForTestcenter(title),"Message=" + __formatForTestcenter(message), stack_level=2)
|
245
244
|
|
246
245
|
else:
|
@@ -406,7 +405,7 @@ logResults(test,notes)
|
|
406
405
|
'''
|
407
406
|
def logResults(test, notes):
|
408
407
|
|
409
|
-
|
408
|
+
if User_interface.instance != None and User_interface.instance.selectedInterface == "testcenter":
|
410
409
|
TestCenter.testPoint ("Quarch_Internal.ResultDialog","Test="+ __formatForTestcenter(test),"Notes=" + __formatForTestcenter(notes), stack_level=2)
|
411
410
|
|
412
411
|
else:
|
@@ -702,8 +701,7 @@ def get_check_valid_calPath(calPath, message="Enter the desired save path for th
|
|
702
701
|
def check_path_write_permissions(path, message="Please enter a valid path with write permissions: "):
|
703
702
|
import tempfile, errno
|
704
703
|
valid_path=False
|
705
|
-
|
706
|
-
calPath = tempfile.mkdtemp()
|
704
|
+
calPath = os.path.expanduser("~")
|
707
705
|
while valid_path==False:
|
708
706
|
try:
|
709
707
|
if path==None:
|
quarchpy/utilities/TestCenter.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
#!/usr/bin/python
|
2
2
|
"""
|
3
3
|
Implements the standard TestCenter API for Python, allowing a Python script to execute all TestCenter functions.
|
4
4
|
This is Quarch internal use only. Each function uses the stdin/stdout to communicate with the TestCenter process
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#!/usr/bin/python
|
1
|
+
#!/usr/bin/python
|
2
2
|
"""
|
3
3
|
Implements the standard TestCenter API for Python, allowing a Python script to execute all TestCenter functions.
|
4
4
|
This is Quarch internal use only. Each function uses the stdin/stdout to communicate with the TestCenter process
|
@@ -63,9 +63,6 @@ def testPoint (command_name, *command_params, stack_level=1):
|
|
63
63
|
|
64
64
|
"""
|
65
65
|
|
66
|
-
# user_interface adds an extra level to the stack.
|
67
|
-
# TODO: This is non-optimal, perhaps some parameter or targetted test could be used instead
|
68
|
-
# to avoid failing a try/except on every test point? Why is this the only TestCenter function that has this check?
|
69
66
|
caller = getframeinfo(stack()[stack_level][0])
|
70
67
|
|
71
68
|
|
@@ -0,0 +1,50 @@
|
|
1
|
+
"""
|
2
|
+
A utility class for versioning.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import re
|
6
|
+
|
7
|
+
try:
|
8
|
+
from typing import List
|
9
|
+
except ImportError:
|
10
|
+
List = list # For Python 2 compatibility
|
11
|
+
|
12
|
+
class Version:
|
13
|
+
"""
|
14
|
+
Support for Python package version numbering.
|
15
|
+
"""
|
16
|
+
|
17
|
+
@staticmethod
|
18
|
+
def major_number(version_number_string):
|
19
|
+
""" Returns the version major number. """
|
20
|
+
major = int(Version.major_minor_patch_numbers(version_number_string)[0])
|
21
|
+
return major
|
22
|
+
|
23
|
+
@staticmethod
|
24
|
+
def minor_number(version_number_string):
|
25
|
+
""" Returns the version minor number. """
|
26
|
+
minor = int(Version.major_minor_patch_numbers(version_number_string)[1])
|
27
|
+
return minor
|
28
|
+
|
29
|
+
@staticmethod
|
30
|
+
def patch_number(version_number_string):
|
31
|
+
""" Returns the version patch number. """
|
32
|
+
patch = int(Version.major_minor_patch_numbers(version_number_string)[2])
|
33
|
+
return patch
|
34
|
+
|
35
|
+
@staticmethod
|
36
|
+
def major_minor_patch_numbers(version_number_string):
|
37
|
+
""" Returns the version patch number. """
|
38
|
+
v_list = re.split(r"\.", version_number_string)
|
39
|
+
return v_list
|
40
|
+
|
41
|
+
@staticmethod
|
42
|
+
def is_v1_ge_v2(v1, v2):
|
43
|
+
""" Returns true if v1 >= v2, else false. """
|
44
|
+
v1_version_list = Version.major_minor_patch_numbers(v1)
|
45
|
+
v2_version_list = Version.major_minor_patch_numbers(v2)
|
46
|
+
v1_version_number = int(''.join(v1_version_list))
|
47
|
+
v2_version_number = int(''.join(v2_version_list))
|
48
|
+
if v1_version_number >= v2_version_number:
|
49
|
+
return True
|
50
|
+
return False
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: quarchpy
|
3
|
-
Version: 2.1.
|
3
|
+
Version: 2.1.14.dev2
|
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
|
@@ -33,11 +33,17 @@ Quarchpy
|
|
33
33
|
Change Log
|
34
34
|
----------
|
35
35
|
|
36
|
+
2.1.13
|
37
|
+
------
|
38
|
+
- New QPS v1.36
|
39
|
+
- New QIS v1.39
|
40
|
+
- minor bug fixes and logging improvements.
|
41
|
+
|
36
42
|
2.1.12
|
37
43
|
------
|
38
44
|
- New QPS v1.35
|
39
45
|
- New QIS v1.38
|
40
|
-
- minor bug fixes and removal of
|
46
|
+
- minor bug fixes and removal of depracated code.
|
41
47
|
|
42
48
|
2.1.11
|
43
49
|
------
|