quarchpy 2.1.14.dev1__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 +90 -74
- quarchpy/device/scanDevices.py +12 -0
- quarchpy/qps/qpsFuncs.py +7 -4
- 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.14.dev1.dist-info → quarchpy-2.1.14.dev2.dist-info}/METADATA +1 -1
- {quarchpy-2.1.14.dev1.dist-info → quarchpy-2.1.14.dev2.dist-info}/RECORD +20 -78
- 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/quarchQPS.py.bak +0 -396
- 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.14.dev1.dist-info → quarchpy-2.1.14.dev2.dist-info}/WHEEL +0 -0
- {quarchpy-2.1.14.dev1.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,7 +57,7 @@ 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) + "\"")
|
63
61
|
if "Error" in response:
|
64
62
|
response = self.connectionObj.qps.sendCmdVerbose("$start stream " + str(newDirectory))
|
65
63
|
return response
|
@@ -68,14 +66,14 @@ class quarchStream:
|
|
68
66
|
''' handles failed starting of stream that requires input from user to fix.'''
|
69
67
|
while "fail:" in response.lower():
|
70
68
|
if "Fail: Directory already exists" in response:
|
71
|
-
print
|
69
|
+
print(response)
|
72
70
|
print("Please enter a new file name:")
|
73
|
-
if sys.version_info.major==3:
|
71
|
+
if sys.version_info.major == 3:
|
74
72
|
newDir = input()
|
75
73
|
else:
|
76
74
|
newDir = raw_input()
|
77
|
-
response = self.startQPSStream(
|
78
|
-
else: #
|
75
|
+
response = self.startQPSStream(newDir)
|
76
|
+
else: # If its a failure we don't know how to handle.
|
79
77
|
raise Exception(response)
|
80
78
|
return response
|
81
79
|
|
@@ -102,10 +100,16 @@ class quarchStream:
|
|
102
100
|
logging.warning("pandas not imported correctly. Continuing")
|
103
101
|
pd.set_option('display.max_columns', None)
|
104
102
|
pd.set_option('display.width', 1024)
|
105
|
-
|
103
|
+
test_data = StringIO(command_response)
|
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)
|
106
110
|
elif format == "list":
|
107
111
|
retVal = []
|
108
|
-
for line in command_response.replace("\r\n","\n").split("\n"):
|
112
|
+
for line in command_response.replace("\r\n", "\n").split("\n"):
|
109
113
|
row = []
|
110
114
|
for element in line.split(","):
|
111
115
|
row.append(element)
|
@@ -113,7 +117,6 @@ class quarchStream:
|
|
113
117
|
|
114
118
|
return retVal
|
115
119
|
|
116
|
-
|
117
120
|
def stats_to_CSV(self, file_name=""):
|
118
121
|
"""
|
119
122
|
Saves the statistics grid to a csv file
|
@@ -129,7 +132,7 @@ class quarchStream:
|
|
129
132
|
|
130
133
|
The response text from QPS. If successful "ok. Saving stats to : file_name" otherwise returns the exception thrown
|
131
134
|
"""
|
132
|
-
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)
|
133
136
|
if command_response.startswith("Fail"):
|
134
137
|
raise Exception(command_response)
|
135
138
|
return command_response
|
@@ -159,14 +162,20 @@ class quarchStream:
|
|
159
162
|
warnings.simplefilter(action='ignore', category=FutureWarning)
|
160
163
|
except:
|
161
164
|
logging.warning("pandas not imported correctly")
|
162
|
-
command_response = self.connectionObj.qps.sendCmdVerbose(
|
165
|
+
command_response = self.connectionObj.qps.sendCmdVerbose(
|
166
|
+
"$get custom stats range " + str(start_time) + " " + str(end_time), timeout=60)
|
163
167
|
if command_response.startswith("Fail"):
|
164
168
|
raise Exception(command_response)
|
165
169
|
test_data = StringIO(command_response)
|
166
170
|
try:
|
167
|
-
|
168
|
-
|
169
|
-
|
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)
|
170
179
|
except Exception as e:
|
171
180
|
logging.error("Unable to create pandas data frame from command response :" + str(command_response))
|
172
181
|
raise e
|
@@ -179,7 +188,7 @@ class quarchStream:
|
|
179
188
|
command_response = self.connectionObj.qps.sendCmdVerbose("$take snapshot")
|
180
189
|
if command_response.startswith("Fail"):
|
181
190
|
raise Exception(command_response)
|
182
|
-
return(command_response)
|
191
|
+
return (command_response)
|
183
192
|
|
184
193
|
def getStreamState(self):
|
185
194
|
"""
|
@@ -191,9 +200,10 @@ class quarchStream:
|
|
191
200
|
command_response = self.connectionObj.qps.sendCmdVerbose("$stream state")
|
192
201
|
if command_response.startswith("Fail"):
|
193
202
|
raise Exception(command_response)
|
194
|
-
return(command_response)
|
203
|
+
return (command_response)
|
195
204
|
|
196
|
-
def addAnnotation(self, title, annotationTime
|
205
|
+
def addAnnotation(self, title, annotationTime=0, extraText="", yPos="", titleColor="", annotationColor="",
|
206
|
+
annotationType="", annotationGroup=""):
|
197
207
|
"""
|
198
208
|
Adds a custom annotation to stream with given parameters.
|
199
209
|
|
@@ -225,7 +235,7 @@ class quarchStream:
|
|
225
235
|
if annotationType == "" or annotationType == "annotation":
|
226
236
|
annotationType = "annotate"
|
227
237
|
elif annotationType == "comment":
|
228
|
-
pass
|
238
|
+
pass # already in the correct format for command
|
229
239
|
else:
|
230
240
|
retString = "Fail annotationType must be 'annotation' or 'comment'"
|
231
241
|
logging.warning(retString)
|
@@ -240,14 +250,13 @@ class quarchStream:
|
|
240
250
|
if annotationTime == "0":
|
241
251
|
# Use current time
|
242
252
|
annotationTime = qpsNowStr()
|
243
|
-
elif(annotationTime.startswith("e")):
|
253
|
+
elif (annotationTime.startswith("e")):
|
244
254
|
pass
|
245
255
|
else:
|
246
256
|
# Convert timestamp to QPS format
|
247
|
-
#annotationTime = toQpsTimeStamp(annotationTime)
|
257
|
+
# annotationTime = toQpsTimeStamp(annotationTime)
|
248
258
|
annotationTime = str(annotationTime)
|
249
259
|
|
250
|
-
|
251
260
|
if title != "":
|
252
261
|
annotationString += "<text>" + str(title) + "</text>"
|
253
262
|
if extraText != "":
|
@@ -265,16 +274,20 @@ class quarchStream:
|
|
265
274
|
# command is sent on newline so \n needs to be chnaged to \\n which is changed back just before printing in qps.
|
266
275
|
annotationString = annotationString.replace("\n", "\\n")
|
267
276
|
logging.debug("Time sending to QPS:" + str(annotationTime))
|
268
|
-
return self.connectionObj.qps.sendCmdVerbose(
|
277
|
+
return self.connectionObj.qps.sendCmdVerbose(
|
278
|
+
"$" + annotationType + " " + str(annotationTime) + " " + annotationString)
|
269
279
|
|
270
|
-
def addComment(self, title, commentTime
|
271
|
-
|
272
|
-
#
|
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.
|
273
284
|
if annotationType == "":
|
274
285
|
annotationType = "comment"
|
275
|
-
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)
|
276
289
|
|
277
|
-
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):
|
278
291
|
"""
|
279
292
|
Saves the stream to csv file at specified location
|
280
293
|
|
@@ -299,26 +312,27 @@ class quarchStream:
|
|
299
312
|
args = ""
|
300
313
|
|
301
314
|
if linesPerFile != None:
|
302
|
-
args +=" -l" + str(linesPerFile)
|
303
|
-
if cr !=None:
|
315
|
+
args += " -l" + str(linesPerFile)
|
316
|
+
if cr != None:
|
304
317
|
if cr is True:
|
305
|
-
args+= " -cyes"
|
318
|
+
args += " -cyes"
|
306
319
|
elif cr is False:
|
307
320
|
args += " -cno"
|
308
|
-
if delimiter !=None:
|
309
|
-
args += " -s"+delimiter
|
321
|
+
if delimiter != None:
|
322
|
+
args += " -s" + delimiter
|
310
323
|
|
311
|
-
|
324
|
+
# , filePath, linesPerFile, cr, delimiter
|
312
325
|
return self.connectionObj.qps.sendCmdVerbose("$save csv \"" + filePath + "\" " + args, timeout=timeout)
|
313
326
|
|
314
327
|
def createChannel(self, channelName, channelGroup, baseUnits, usePrefix):
|
315
|
-
#Conditions to convert false / true inputs to specification input
|
316
|
-
if usePrefix == False:
|
328
|
+
# Conditions to convert false / true inputs to specification input
|
329
|
+
if usePrefix == False:
|
317
330
|
usePrefix = "no"
|
318
331
|
if usePrefix == True:
|
319
332
|
usePrefix = "yes"
|
320
333
|
|
321
|
-
return self.connectionObj.qps.sendCmdVerbose(
|
334
|
+
return self.connectionObj.qps.sendCmdVerbose(
|
335
|
+
"$create channel " + channelName + " " + channelGroup + " " + baseUnits + " " + usePrefix)
|
322
336
|
|
323
337
|
def hideChannel(self, channelSpecifier):
|
324
338
|
return self.connectionObj.qps.sendCmdVerbose("$hide channel " + channelSpecifier)
|
@@ -331,7 +345,7 @@ class quarchStream:
|
|
331
345
|
|
332
346
|
def channels(self):
|
333
347
|
return self.connectionObj.qps.sendCmdVerbose("$channels").splitlines()
|
334
|
-
|
348
|
+
|
335
349
|
def stopStream(self):
|
336
350
|
return self.connectionObj.qps.sendCmdVerbose("$stop stream")
|
337
351
|
|
@@ -339,37 +353,37 @@ class quarchStream:
|
|
339
353
|
self.stopStream()
|
340
354
|
streamState = self.getStreamState().lower()
|
341
355
|
while "running" in streamState:
|
342
|
-
logging.debug("Stream buffer still emptying: "+ streamState)
|
356
|
+
logging.debug("Stream buffer still emptying: " + streamState)
|
343
357
|
time.sleep(checkInterval)
|
344
358
|
streamState = self.getStreamState().lower()
|
345
359
|
logging.debug("QPS no longer Streaming: " + streamState)
|
346
360
|
|
347
361
|
def hideAllDefaultChannels(self):
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
self.hideChannel
|
352
|
-
self.hideChannel
|
353
|
-
self.hideChannel
|
354
|
-
self.hideChannel
|
355
|
-
self.hideChannel
|
356
|
-
self.hideChannel
|
357
|
-
self.hideChannel
|
358
|
-
self.hideChannel
|
359
|
-
self.hideChannel
|
360
|
-
self.hideChannel
|
361
|
-
self.hideChannel
|
362
|
-
self.hideChannel
|
363
|
-
self.hideChannel
|
364
|
-
#Default PAM channels
|
365
|
-
self.hideChannel
|
366
|
-
self.hideChannel
|
367
|
-
self.hideChannel
|
368
|
-
self.hideChannel
|
369
|
-
self.hideChannel
|
370
|
-
|
371
|
-
#function to add a data point the the stream
|
372
|
-
#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
|
373
387
|
def addDataPoint(self, channelName, groupName, dataValue, dataPointTime=0, timeFormat="unix"):
|
374
388
|
'''
|
375
389
|
channelName - str
|
@@ -381,9 +395,11 @@ class quarchStream:
|
|
381
395
|
if dataPointTime == None or dataPointTime == 0:
|
382
396
|
dataPointTime = qpsNowStr()
|
383
397
|
else:
|
384
|
-
dataPointTime = toQpsTimeStamp
|
398
|
+
dataPointTime = toQpsTimeStamp(dataPointTime)
|
385
399
|
|
386
|
-
#print ("printing command: $log " + channelName + " " + groupName + " " + str(dataPointTime) + " " + str(dataValue))
|
387
|
-
#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))
|
388
402
|
|
389
|
-
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/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():
|
@@ -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
|