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.
Files changed (81) hide show
  1. quarchpy/.idea/modules.xml +1 -0
  2. quarchpy/.idea/quarchpy.iml +4 -1
  3. quarchpy/.idea/workspace.xml +149 -11
  4. quarchpy/_version.py +1 -1
  5. quarchpy/connection_specific/connection_QIS.py +213 -315
  6. quarchpy/connection_specific/connection_QIS.py.bak +253 -357
  7. quarchpy/connection_specific/connection_TCP.py +1 -1
  8. quarchpy/connection_specific/connection_mDNS.py +46 -0
  9. quarchpy/device/quarchPPM.py +2 -2
  10. quarchpy/device/quarchQPS.py +95 -86
  11. quarchpy/device/scanDevices.py +12 -0
  12. quarchpy/docs/CHANGES.rst +7 -1
  13. quarchpy/qps/qpsFuncs.py +7 -4
  14. quarchpy/run.py +1 -1
  15. quarchpy/user_interface/user_interface.py.bak +3 -5
  16. quarchpy/utilities/TestCenter.py +1 -1
  17. quarchpy/utilities/TestCenter.py.bak +1 -4
  18. quarchpy/utilities/Version.py +50 -0
  19. {quarchpy-2.1.13.dev2.dist-info → quarchpy-2.1.14.dev2.dist-info}/METADATA +8 -2
  20. {quarchpy-2.1.13.dev2.dist-info → quarchpy-2.1.14.dev2.dist-info}/RECORD +22 -79
  21. quarchpy/.idea/.name +0 -1
  22. quarchpy/.idea/inspectionProfiles/Project_Default.xml +0 -26
  23. quarchpy/__pycache__/__init__.cpython-311.pyc +0 -0
  24. quarchpy/__pycache__/_version.cpython-311.pyc +0 -0
  25. quarchpy/__pycache__/connection.cpython-311.pyc +0 -0
  26. quarchpy/__pycache__/run.cpython-311.pyc +0 -0
  27. quarchpy/config_files/__pycache__/__init__.cpython-311.pyc +0 -0
  28. quarchpy/config_files/__pycache__/quarch_config_parser.cpython-311.pyc +0 -0
  29. quarchpy/connection_specific/__pycache__/StreamChannels.cpython-311.pyc +0 -0
  30. quarchpy/connection_specific/__pycache__/__init__.cpython-311.pyc +0 -0
  31. quarchpy/connection_specific/__pycache__/connection_QIS.cpython-311.pyc +0 -0
  32. quarchpy/connection_specific/__pycache__/connection_QPS.cpython-311.pyc +0 -0
  33. quarchpy/connection_specific/__pycache__/connection_ReST.cpython-311.pyc +0 -0
  34. quarchpy/connection_specific/__pycache__/connection_Serial.cpython-311.pyc +0 -0
  35. quarchpy/connection_specific/__pycache__/connection_USB.cpython-311.pyc +0 -0
  36. quarchpy/connection_specific/serial/__pycache__/__init__.cpython-311.pyc +0 -0
  37. quarchpy/connection_specific/serial/__pycache__/serialutil.cpython-311.pyc +0 -0
  38. quarchpy/connection_specific/serial/__pycache__/serialwin32.cpython-311.pyc +0 -0
  39. quarchpy/connection_specific/serial/__pycache__/win32.cpython-311.pyc +0 -0
  40. quarchpy/connection_specific/serial/tools/__pycache__/__init__.cpython-311.pyc +0 -0
  41. quarchpy/connection_specific/serial/tools/__pycache__/list_ports.cpython-311.pyc +0 -0
  42. quarchpy/connection_specific/serial/tools/__pycache__/list_ports_common.cpython-311.pyc +0 -0
  43. quarchpy/connection_specific/serial/tools/__pycache__/list_ports_windows.cpython-311.pyc +0 -0
  44. quarchpy/connection_specific/usb_libs/__pycache__/libusb1.cpython-311.pyc +0 -0
  45. quarchpy/connection_specific/usb_libs/__pycache__/usb1.cpython-311.pyc +0 -0
  46. quarchpy/debug/TextScanIP.py +0 -11
  47. quarchpy/debug/__pycache__/SystemTest.cpython-311.pyc +0 -0
  48. quarchpy/debug/__pycache__/__init__.cpython-311.pyc +0 -0
  49. quarchpy/debug/__pycache__/module_debug.cpython-311.pyc +0 -0
  50. quarchpy/debug/__pycache__/simple_terminal.cpython-311.pyc +0 -0
  51. quarchpy/debug/__pycache__/upgrade_quarchpy.cpython-311.pyc +0 -0
  52. quarchpy/debug/__pycache__/versionCompare.cpython-311.pyc +0 -0
  53. quarchpy/device/__pycache__/__init__.cpython-311.pyc +0 -0
  54. quarchpy/device/__pycache__/device.cpython-311.pyc +0 -0
  55. quarchpy/device/__pycache__/quarchArray.cpython-311.pyc +0 -0
  56. quarchpy/device/__pycache__/quarchPPM.cpython-311.pyc +0 -0
  57. quarchpy/device/__pycache__/quarchQPS.cpython-311.pyc +0 -0
  58. quarchpy/device/__pycache__/scanDevices.cpython-311.pyc +0 -0
  59. quarchpy/device/device.py.bak +0 -504
  60. quarchpy/device/scanDevices.py.bak +0 -661
  61. quarchpy/disk_test/__pycache__/AbsDiskFinder.cpython-311.pyc +0 -0
  62. quarchpy/disk_test/__pycache__/DiskTargetSelection.cpython-311.pyc +0 -0
  63. quarchpy/disk_test/__pycache__/__init__.cpython-311.pyc +0 -0
  64. quarchpy/disk_test/__pycache__/iometerDiskFinder.cpython-311.pyc +0 -0
  65. quarchpy/fio/__pycache__/FIO_interface.cpython-311.pyc +0 -0
  66. quarchpy/fio/__pycache__/__init__.cpython-311.pyc +0 -0
  67. quarchpy/iometer/__pycache__/__init__.cpython-311.pyc +0 -0
  68. quarchpy/iometer/__pycache__/gen_iometer_template.cpython-311.pyc +0 -0
  69. quarchpy/iometer/__pycache__/iometerFuncs.cpython-311.pyc +0 -0
  70. quarchpy/qis/__pycache__/StreamHeaderInfo.cpython-311.pyc +0 -0
  71. quarchpy/qis/__pycache__/__init__.cpython-311.pyc +0 -0
  72. quarchpy/qis/__pycache__/qisFuncs.cpython-311.pyc +0 -0
  73. quarchpy/qps/__pycache__/__init__.cpython-311.pyc +0 -0
  74. quarchpy/qps/__pycache__/qpsFuncs.cpython-311.pyc +0 -0
  75. quarchpy/user_interface/__pycache__/__init__.cpython-311.pyc +0 -0
  76. quarchpy/user_interface/__pycache__/user_interface.cpython-311.pyc +0 -0
  77. quarchpy/utilities/__pycache__/TestCenter.cpython-311.pyc +0 -0
  78. quarchpy/utilities/__pycache__/TimeValue.cpython-311.pyc +0 -0
  79. quarchpy/utilities/__pycache__/__init__.cpython-311.pyc +0 -0
  80. {quarchpy-2.1.13.dev2.dist-info → quarchpy-2.1.14.dev2.dist-info}/WHEEL +0 -0
  81. {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 ocnnection
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()
@@ -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)
@@ -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 (round (time.time() * 1000))
11
- current_second_time = lambda: int (round (time.time()))
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() # datetime supports microseconds
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) #TODO remove this sleep once script->QPS timeing issue resolved. This works fine in the meantime
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 (response)
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( newDir)
76
- else: # If its a failure we don't know how to handle.
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
- pass
101
+ pd.set_option('display.max_columns', None)
102
+ pd.set_option('display.width', 1024)
107
103
  test_data = StringIO(command_response)
108
- retVal = pd.read_csv(test_data, sep=",", header=[0, 1], error_bad_lines=False)
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
- pass
171
- command_response = self.connectionObj.qps.sendCmdVerbose("$get custom stats range " + str(start_time)+ " " + str(end_time), timeout=60)
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
- df = pd.read_csv(test_data, sep=",", header=[0,1])
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 = 0, extraText="", yPos="", titleColor ="", annotationColor = "", annotationType = "", annotationGroup =""):
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 # already in the correct format for command
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("$" +annotationType+" "+str(annotationTime)+" "+annotationString)
277
+ return self.connectionObj.qps.sendCmdVerbose(
278
+ "$" + annotationType + " " + str(annotationTime) + " " + annotationString)
276
279
 
277
- def addComment(self, title, commentTime = 0, extraText="", yPos="", titleColor ="", commentColor = "", annotationType = "", annotationGroup =""):
278
- #Comments are just annotations that do not affect the statistics grid.
279
- #This function was kept to be backwards compatible and is a simple pass through to add annotation.
280
+ 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 = title, annotationTime=commentTime, extraText=extraText, yPos=yPos, titleColor=titleColor, annotationColor=commentColor, annotationType=annotationType, annotationGroup=annotationGroup)
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
- #, filePath, linesPerFile, cr, delimiter
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("$create channel " + channelName + " " + channelGroup + " " + baseUnits + " " + usePrefix)
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
- #TODO query QPS / Device for all channel names and hide all of them
357
- #All Default Channels
358
- self.hideChannel ("3.3v:voltage")
359
- self.hideChannel ("3v3:voltage")
360
- self.hideChannel ("5v:voltage")
361
- self.hideChannel ("12v:voltage")
362
- self.hideChannel ("3v3:current")
363
- self.hideChannel ("3.3v:current")
364
- self.hideChannel ("5v:current")
365
- self.hideChannel ("12v:current")
366
- self.hideChannel ("3v3:power")
367
- self.hideChannel ("3.3v:power")
368
- self.hideChannel ("5v:power")
369
- self.hideChannel ("12v:power")
370
- self.hideChannel ("tot:power")
371
- #Default PAM channels
372
- self.hideChannel ("perst#:digital")
373
- self.hideChannel ("wake#:digital")
374
- self.hideChannel ("lkreq#:digital")
375
- self.hideChannel ("smclk:digital")
376
- self.hideChannel ("smdat:digital")
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 (dataPointTime)
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("$stream data add " + channelName+ " " + groupName+ " " + str(dataPointTime)+ " " + str(dataValue)+ " " + timeFormat)
403
+ self.connectionObj.qps.sendCmdVerbose(
404
+ "$stream data add " + channelName + " " + groupName + " " + str(dataPointTime) + " " + str(
405
+ dataValue) + " " + timeFormat)
@@ -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 depricated code.
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 (currentOs in "Windows"):
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 (currentOs in "Linux"):
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
@@ -20,7 +20,7 @@ def main(args):
20
20
  """
21
21
 
22
22
  # Run the internal parser
23
- _parse_run_options(args)
23
+ _parse_run_options(args)
24
24
 
25
25
  def _parse_run_options(args):
26
26
  """
@@ -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
- if User_interface.instance != None and User_interface.instance.selectedInterface == "testcenter":
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
- if User_interface.instance != None and User_interface.instance.selectedInterface == "testcenter":
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
- # Create a temporary directory
706
- calPath = tempfile.mkdtemp()
704
+ calPath = os.path.expanduser("~")
707
705
  while valid_path==False:
708
706
  try:
709
707
  if path==None:
@@ -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
@@ -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.13.dev2
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 depricated code.
46
+ - minor bug fixes and removal of depracated code.
41
47
 
42
48
  2.1.11
43
49
  ------