quarchpy 2.1.20.dev1__py2.py3-none-any.whl → 2.1.20.dev3__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/.name +1 -1
- quarchpy/.idea/inspectionProfiles/Project_Default.xml +26 -0
- quarchpy/.idea/modules.xml +0 -1
- quarchpy/.idea/quarchpy.iml +1 -4
- quarchpy/.idea/workspace.xml +25 -230
- 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/_version.py +1 -1
- 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/QPS/qis/help.txt +12 -4
- quarchpy/connection_specific/QPS/qis/qis.jar +0 -0
- quarchpy/connection_specific/QPS/qis/qis_lib/CInterface-1.7.8.jar +0 -0
- quarchpy/connection_specific/QPS/qis/qis_lib/Collections-2.4.jar +0 -0
- quarchpy/connection_specific/QPS/qis/qis_lib/Desktop-1.1.jar +0 -0
- quarchpy/connection_specific/QPS/qis/qis_lib/Executor-3.13.jar +0 -0
- quarchpy/connection_specific/QPS/qis/qis_lib/JNA-1.2.jar +0 -0
- quarchpy/connection_specific/QPS/qis/qis_lib/OS-1.8.jar +0 -0
- quarchpy/connection_specific/QPS/qis/qis_lib/QuarchCommon-0.2.9.jar +0 -0
- quarchpy/connection_specific/QPS/qis/qis_lib/SystemTray-4.4.jar +0 -0
- quarchpy/connection_specific/QPS/qis/qis_lib/Updates-1.1.jar +0 -0
- quarchpy/connection_specific/QPS/qis/qis_lib/Utilities-1.46.jar +0 -0
- quarchpy/connection_specific/QPS/qis/qis_lib/commons-csv-1.8.jar +0 -0
- quarchpy/connection_specific/QPS/qis/qis_lib/javassist-3.29.2-GA.jar +0 -0
- quarchpy/connection_specific/QPS/qis/qis_lib/jna-jpms-5.12.1.jar +0 -0
- quarchpy/connection_specific/QPS/qis/qis_lib/jna-platform-jpms-5.12.1.jar +0 -0
- quarchpy/connection_specific/QPS/qis/qis_lib/kotlin-stdlib-1.9.21.jar +0 -0
- quarchpy/connection_specific/QPS/qis/qis_lib/slf4j-api-2.0.9.jar +0 -0
- quarchpy/connection_specific/QPS/qis/qis_lib/slf4j-simple-2.0.9.jar +0 -0
- quarchpy/connection_specific/QPS/qis/resources/filters/Example.txt +36 -0
- quarchpy/connection_specific/QPS/qis/resources/filters/filters.csv +1004 -0
- quarchpy/connection_specific/QPS/qis/resources/filters/iec_filters.xml +26 -0
- quarchpy/connection_specific/QPS/qis/resources/filters/iec_filters.xml.bak +26 -0
- quarchpy/connection_specific/QPS/qps.jar +0 -0
- quarchpy/connection_specific/QPS/qps_lib/QuarchCommon-0.2.9.jar +0 -0
- quarchpy/connection_specific/QPS/qps_lib/commons-lang3-3.12.0.jar +0 -0
- quarchpy/connection_specific/QPS/qps_lib/opencsv-5.9.jar +0 -0
- quarchpy/connection_specific/QPS/qps_lib/qis-1.40.jar +0 -0
- quarchpy/connection_specific/QPS/scriptCommands.txt +2 -2
- 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_TCP.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_Telnet.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_USB.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_mDNS.cpython-311.pyc +0 -0
- quarchpy/connection_specific/connection_QIS.py +5 -3
- quarchpy/connection_specific/connection_QIS.py.bak +1738 -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 +11 -0
- 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/debug/simple_terminal.py +29 -25
- 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 +504 -0
- quarchpy/device/quarchPPM.py.bak +67 -0
- quarchpy/device/quarchQPS.py.bak +396 -0
- quarchpy/device/scanDevices.py +78 -86
- quarchpy/device/scanDevices.py.bak +126 -106
- 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/docs/CHANGES.rst +10 -0
- quarchpy/docs/CHANGES.rst.bak +364 -0
- quarchpy/docs/_build/doctrees/CHANGES.doctree +0 -0
- quarchpy/docs/_build/doctrees/environment.pickle +0 -0
- quarchpy/docs/_build/doctrees/source/changelog.doctree +0 -0
- quarchpy/docs/_build/doctrees/source/quarchpy.fio.doctree +0 -0
- quarchpy/docs/_build/html/CHANGES.html +121 -113
- quarchpy/docs/_build/html/_sources/CHANGES.rst.txt +6 -1
- quarchpy/docs/_build/html/_static/alabaster.css +14 -9
- quarchpy/docs/_build/html/_static/basic.css +1 -1
- quarchpy/docs/_build/html/_static/pygments.css +1 -1
- quarchpy/docs/_build/html/genindex.html +9 -27
- quarchpy/docs/_build/html/index.html +62 -60
- quarchpy/docs/_build/html/objects.inv +0 -0
- quarchpy/docs/_build/html/py-modindex.html +7 -11
- quarchpy/docs/_build/html/readme.html +7 -6
- quarchpy/docs/_build/html/search.html +7 -6
- quarchpy/docs/_build/html/searchindex.js +1 -1
- quarchpy/docs/_build/html/source/changelog.html +176 -167
- quarchpy/docs/_build/html/source/licenses.html +7 -6
- quarchpy/docs/_build/html/source/modules.html +8 -7
- quarchpy/docs/_build/html/source/quarchpy.calibration.html +7 -6
- quarchpy/docs/_build/html/source/quarchpy.config_files.html +7 -6
- quarchpy/docs/_build/html/source/quarchpy.connection_specific.html +7 -6
- quarchpy/docs/_build/html/source/quarchpy.debug.html +7 -6
- quarchpy/docs/_build/html/source/quarchpy.device.html +7 -6
- quarchpy/docs/_build/html/source/quarchpy.disk_test.html +7 -6
- quarchpy/docs/_build/html/source/quarchpy.fio.html +9 -34
- quarchpy/docs/_build/html/source/quarchpy.html +8 -16
- quarchpy/docs/_build/html/source/quarchpy.iometer.html +7 -6
- quarchpy/docs/_build/html/source/quarchpy.qis.html +7 -6
- quarchpy/docs/_build/html/source/quarchpy.qps.html +7 -6
- quarchpy/docs/_build/html/source/quarchpy.user_interface.html +7 -6
- quarchpy/docs/_build/html/source/quarchpy.utilities.html +7 -6
- quarchpy/docs/_build/html/source/readme.html +7 -6
- quarchpy/fio/__pycache__/FIO_interface.cpython-311.pyc +0 -0
- quarchpy/fio/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/fio/__pycache__/fioDiskFinder.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/qis/qisFuncs.py +48 -14
- quarchpy/qps/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/qps/__pycache__/qpsFuncs.cpython-311.pyc +0 -0
- quarchpy/qps/qpsFuncs.py.bak +28 -68
- quarchpy/user_interface/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/user_interface/__pycache__/user_interface.cpython-311.pyc +0 -0
- quarchpy/user_interface/user_interface.py.bak +749 -0
- quarchpy/utilities/TestCenter.py.bak +150 -0
- quarchpy/utilities/__pycache__/BitManipulation.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__/Version.cpython-311.pyc +0 -0
- quarchpy/utilities/__pycache__/__init__.cpython-311.pyc +0 -0
- {quarchpy-2.1.20.dev1.dist-info → quarchpy-2.1.20.dev3.dist-info}/METADATA +11 -1
- {quarchpy-2.1.20.dev1.dist-info → quarchpy-2.1.20.dev3.dist-info}/RECORD +147 -115
- quarchpy/_version.py.bak +0 -1
- quarchpy/connection_specific/connection_mDNS.py.bak +0 -48
- quarchpy/debug/SystemTest.py.bak +0 -188
- quarchpy/fio/FIO_interface.py.bak +0 -322
- quarchpy/run.py.bak +0 -283
- {quarchpy-2.1.20.dev1.dist-info → quarchpy-2.1.20.dev3.dist-info}/WHEEL +0 -0
- {quarchpy-2.1.20.dev1.dist-info → quarchpy-2.1.20.dev3.dist-info}/top_level.txt +0 -0
quarchpy/device/scanDevices.py
CHANGED
@@ -178,39 +178,32 @@ List all Quarch devices found over LAN, using a UDP broadcast scan
|
|
178
178
|
def list_network(target_conn="all", debugPring=False, lanTimeout=1, ipAddressLookup=None):
|
179
179
|
|
180
180
|
retVal={}
|
181
|
-
|
182
181
|
lan_modules = dict()
|
183
|
-
|
184
182
|
specifiedDevice = None
|
185
|
-
|
186
183
|
# Broadcast the message.
|
187
184
|
logging.debug("Broadcast LAN discovery message for UDP scan to all network interfaces")
|
188
185
|
ipList = socket.gethostbyname_ex(socket.gethostname())
|
189
186
|
logging.debug(os.path.basename(__file__) + ": Discovered the following interfaces: " + str(ipList))
|
190
187
|
|
188
|
+
|
189
|
+
|
191
190
|
for ip in ipList[2]:
|
192
|
-
|
193
191
|
logging.debug(os.path.basename(__file__) + ": Broadcasting on : " + ip)
|
194
|
-
|
195
192
|
try:
|
196
|
-
|
197
193
|
mySocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
198
194
|
mySocket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
199
195
|
mySocket.settimeout(lanTimeout)
|
200
196
|
mySocket.bind((ip,56732))
|
201
|
-
|
202
|
-
if ipAddressLookup is not None:
|
203
|
-
# Attempts to find the device through UDP then REST
|
204
|
-
specifiedDevice = lookupDevice(str(ipAddressLookup).strip(), mySocket, lan_modules)
|
205
|
-
|
206
197
|
except Exception as err:
|
207
|
-
|
208
198
|
logging.debug("Error while trying to bind to network interfaces: "+" Error: "+str(err))
|
209
199
|
|
210
|
-
|
200
|
+
if ipAddressLookup is not None:
|
201
|
+
# Attempts to find the device through UDP then REST
|
202
|
+
specifiedDevice = lookupDevice(str(ipAddressLookup).strip(), mySocket, lan_modules)
|
211
203
|
|
212
|
-
counter = 0
|
213
204
|
|
205
|
+
mySocket.sendto(b'Discovery: Who is out there?\0\n', ('255.255.255.255', 30303))
|
206
|
+
counter = 0
|
214
207
|
# Receive messages until timeout.
|
215
208
|
while True:
|
216
209
|
network_modules = {}
|
@@ -218,7 +211,7 @@ def list_network(target_conn="all", debugPring=False, lanTimeout=1, ipAddressLoo
|
|
218
211
|
# Receive raw message until timeout, then break.
|
219
212
|
try:
|
220
213
|
msg_received = mySocket.recvfrom(256)
|
221
|
-
except:
|
214
|
+
except Exception as e:
|
222
215
|
# check if any a device was targeted directly and allow parse
|
223
216
|
if specifiedDevice is not None:
|
224
217
|
msg_received = specifiedDevice
|
@@ -240,14 +233,10 @@ def list_network(target_conn="all", debugPring=False, lanTimeout=1, ipAddressLoo
|
|
240
233
|
else:
|
241
234
|
index = repr(lines[0]).replace("'", "")
|
242
235
|
data = repr(lines[1:]).replace("'", "").replace("b", "")
|
243
|
-
|
244
236
|
network_modules[index] = data
|
245
|
-
|
246
237
|
module_name = get_user_level_serial_number(network_modules)
|
247
238
|
logging.debug("Found UDP response: " + module_name)
|
248
|
-
|
249
239
|
ip_module = msg_received[1][0].strip()
|
250
|
-
|
251
240
|
try:
|
252
241
|
# Add a QTL before modules without it.
|
253
242
|
if "QTL" not in module_name.decode("utf-8"):
|
@@ -277,15 +266,20 @@ def list_network(target_conn="all", debugPring=False, lanTimeout=1, ipAddressLoo
|
|
277
266
|
# Append the information to the list.
|
278
267
|
lan_modules["TCP:" + ip_module] = module_name
|
279
268
|
logging.debug("Found TCP module: " + module_name)
|
280
|
-
|
281
269
|
mySocket.close()
|
270
|
+
|
282
271
|
logging.debug("Finished UDP scan")
|
283
272
|
retVal.update(lan_modules)
|
284
273
|
return retVal
|
285
274
|
|
286
275
|
|
287
|
-
|
276
|
+
|
288
277
|
def get_user_level_serial_number(network_modules):
|
278
|
+
'''
|
279
|
+
|
280
|
+
:param network_modules:
|
281
|
+
:return:
|
282
|
+
'''
|
289
283
|
list_of_multi_module_units = ["1995"] # List of modules that require enclosure number + Port to be displayed.
|
290
284
|
|
291
285
|
# Filter the raw message to get the module and ip address.
|
@@ -313,54 +307,53 @@ def get_user_level_serial_number(network_modules):
|
|
313
307
|
''''''
|
314
308
|
def lookupDevice(ipAddressLookup, mySocket, lan_modules):
|
315
309
|
try:
|
316
|
-
|
310
|
+
logging.debug("Ipaddress lookup " + ipAddressLookup)
|
317
311
|
# For future reference, 0 is the C terminator for a string
|
318
312
|
mySocket.sendto(b'Discovery: Who is out there?\0\n', (str(ipAddressLookup).strip(), 30303))
|
319
313
|
specifiedDevice = mySocket.recvfrom(256)
|
320
314
|
# Check to see if the response contains the connection protocol
|
321
|
-
|
322
|
-
# If not allow it to fall-back to REST
|
323
|
-
specifiedDevice = None
|
324
|
-
else:
|
325
|
-
# Exit as device was found correctly
|
326
|
-
return specifiedDevice
|
315
|
+
return specifiedDevice
|
327
316
|
except Exception as e:
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
317
|
+
logging.warning("Error during UDP lookup of IP address "+ str(ipAddressLookup) +" Error: " + str(e))
|
318
|
+
logging.warning("No Quarch module found at this address. Please check the IP address and that you can ping it.\r\n")
|
319
|
+
return None
|
320
|
+
#
|
321
|
+
# if specifiedDevice is None: #Only True if TCP not found or errored
|
322
|
+
# try:
|
323
|
+
# restCon = connection_ReST.ReSTConn(str(ipAddressLookup).replace("\r\n", ""))
|
324
|
+
# restDevice = restCon.sendCommand("*enclosure?") #Try use enclosure for PPMs
|
325
|
+
# if "fail" in restDevice.lower(): # This will fail nicely for other modules
|
326
|
+
# restDevice = restCon.sendCommand("*serial?") # and serial number will be used in place.
|
327
|
+
# if not str(restDevice).startswith("QTL"):
|
328
|
+
# restDevice = "QTL" + restDevice
|
329
|
+
# # Exit as device was found correctly
|
330
|
+
# # Add the item to list
|
331
|
+
# lan_modules["REST:" + str(ipAddressLookup).replace("\r\n", "")] = restDevice
|
332
|
+
# specifiedDevice=None # Don't return rest connection, to bypass tcp parsing.
|
333
|
+
# except Exception as e:
|
334
|
+
# logging.warning("Error During REST scan of IP address " + str(ipAddressLookup) + " Error: " + str(e))
|
335
|
+
# logging.warning("Please check the IP address and that you can ping it.\r\n")
|
336
|
+
#
|
337
|
+
# # Needs to return None so previous method will not attempt another lookup.
|
338
|
+
# return specifiedDevice
|
339
|
+
|
332
340
|
|
333
|
-
if specifiedDevice is None:
|
334
|
-
try:
|
335
|
-
restCon = connection_ReST.ReSTConn(str(ipAddressLookup).replace("\r\n", ""))
|
336
|
-
restDevice = restCon.sendCommand("*serial?")
|
337
|
-
if not str(restDevice).startswith("QTL"):
|
338
|
-
restDevice = "QTL" + restDevice
|
339
|
-
# Add the item to list
|
340
|
-
lan_modules["REST:" + str(ipAddressLookup).replace("\r\n", "")] = restDevice
|
341
341
|
|
342
|
-
except Exception as e:
|
343
|
-
printText("Error During REST scan " + str(e))
|
344
|
-
|
345
|
-
# Needs to return None so previous method will not attempt another lookup.
|
346
|
-
return None
|
347
|
-
|
348
|
-
|
349
|
-
"""
|
350
|
-
Takes in the connection target and returns the serial number of a module found on the standard scan.
|
351
|
-
|
352
|
-
Parameters
|
353
|
-
----------
|
354
|
-
connectionTarget= : str
|
355
|
-
The connection target of the module you would like to know the serial number of.
|
356
|
-
|
357
|
-
Returns
|
358
|
-
-------
|
359
|
-
ret_val : str
|
360
|
-
The Serial number of the supplied device.
|
361
|
-
|
362
|
-
"""
|
363
342
|
def getSerialNumberFromConnectionTarget(connectionTarget):
|
343
|
+
"""
|
344
|
+
Takes in the connection target and returns the serial number of a module found on the standard scan.
|
345
|
+
|
346
|
+
Parameters
|
347
|
+
----------
|
348
|
+
connectionTarget= : str
|
349
|
+
The connection target of the module you would like to know the serial number of.
|
350
|
+
|
351
|
+
Returns
|
352
|
+
-------
|
353
|
+
ret_val : str
|
354
|
+
The Serial number of the supplied device.
|
355
|
+
|
356
|
+
"""
|
364
357
|
myDict = scanDevices(favouriteOnly=False)
|
365
358
|
for k,v in myDict.items():
|
366
359
|
if k == connectionTarget:
|
@@ -368,32 +361,31 @@ def getSerialNumberFromConnectionTarget(connectionTarget):
|
|
368
361
|
return None
|
369
362
|
|
370
363
|
|
371
|
-
"""
|
372
|
-
Takes in the connection type and serial number of a module and returns the connection target.
|
373
|
-
|
374
|
-
Parameters
|
375
|
-
----------
|
376
|
-
module_string= : str
|
377
|
-
The connection type and serial number combination eg. TCP:QTL1999-05-005.
|
378
|
-
|
379
|
-
scan_dictionary= :dict, optional
|
380
|
-
A scan dictionary can be passed so that a scan does not need to take place on every call.
|
381
|
-
This would be advised if calling this for every item in a list of serial numbers.
|
382
|
-
|
383
|
-
connection_preference= : list str, optional
|
384
|
-
The preference of which connection type to prioratise if none it given.
|
385
|
-
Defaults to "USB", "TCP", "SERIAL", "REST", "TELNET" in that order.
|
386
|
-
|
387
|
-
include_conn_type = : boolean, optional
|
388
|
-
Decided whether the connection type will appear in the return value eg. TCP:192.168.1.1 vs 192.168.1.1
|
389
|
-
|
390
|
-
Returns
|
391
|
-
-------
|
392
|
-
ret_val : str
|
393
|
-
The Connection target of the supplied device.
|
394
|
-
|
395
|
-
"""
|
396
364
|
def get_connection_target(module_string ,scan_dictionary=None, connection_preference= None, include_conn_type = True):
|
365
|
+
"""
|
366
|
+
Takes in the connection type and serial number of a module and returns the connection target.
|
367
|
+
|
368
|
+
Parameters
|
369
|
+
----------
|
370
|
+
module_string= : str
|
371
|
+
The connection type and serial number combination eg. TCP:QTL1999-05-005.
|
372
|
+
|
373
|
+
scan_dictionary= :dict, optional
|
374
|
+
A scan dictionary can be passed so that a scan does not need to take place on every call.
|
375
|
+
This would be advised if calling this for every item in a list of serial numbers.
|
376
|
+
|
377
|
+
connection_preference= : list str, optional
|
378
|
+
The preference of which connection type to prioratise if none it given.
|
379
|
+
Defaults to "USB", "TCP", "SERIAL", "REST", "TELNET" in that order.
|
380
|
+
|
381
|
+
include_conn_type = : boolean, optional
|
382
|
+
Decided whether the connection type will appear in the return value eg. TCP:192.168.1.1 vs 192.168.1.1
|
383
|
+
|
384
|
+
Returns
|
385
|
+
-------
|
386
|
+
ret_val : str
|
387
|
+
The Connection target of the supplied device.
|
388
|
+
"""
|
397
389
|
logging.debug("Getting connection target for : "+ str(module_string))
|
398
390
|
if connection_preference == None:
|
399
391
|
connection_preference = ["USB", "TCP", "SERIAL", "REST", "TELNET"]
|
@@ -20,7 +20,8 @@ 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
|
-
|
23
|
+
|
24
|
+
# TODO: bodge bodge bodge
|
24
25
|
from quarchpy.utilities import TestCenter
|
25
26
|
|
26
27
|
|
@@ -175,9 +176,25 @@ def list_USB(debuPrint=False):
|
|
175
176
|
'''
|
176
177
|
List all Quarch devices found over LAN, using a UDP broadcast scan
|
177
178
|
'''
|
179
|
+
|
180
|
+
def get_interface_ips():
|
181
|
+
interfaces = socket.if_nameindex()
|
182
|
+
interface_ips = {}
|
183
|
+
for idx, interface in interfaces:
|
184
|
+
try:
|
185
|
+
addresses = socket.getaddrinfo(interface, None)
|
186
|
+
ip_addresses = [addr[4][0] for addr in addresses]
|
187
|
+
interface_ips[interface] = ip_addresses
|
188
|
+
except socket.gaierror:
|
189
|
+
logging.warning(f"Unable to get IP address for interface {interface}")
|
190
|
+
return interface_ips
|
178
191
|
def list_network(target_conn="all", debugPring=False, lanTimeout=1, ipAddressLookup=None):
|
179
192
|
|
180
193
|
retVal={}
|
194
|
+
# Create and configure the socket for broadcast.
|
195
|
+
mySocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
196
|
+
mySocket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
197
|
+
mySocket.settimeout(lanTimeout)
|
181
198
|
|
182
199
|
lan_modules = dict()
|
183
200
|
|
@@ -186,101 +203,96 @@ def list_network(target_conn="all", debugPring=False, lanTimeout=1, ipAddressLoo
|
|
186
203
|
if ipAddressLookup is not None:
|
187
204
|
# Attempts to find the device through UDP then REST
|
188
205
|
specifiedDevice = lookupDevice(str(ipAddressLookup).strip(), mySocket, lan_modules )
|
206
|
+
mySocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
207
|
+
mySocket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
208
|
+
mySocket.settimeout(lanTimeout)
|
209
|
+
|
210
|
+
|
189
211
|
|
190
212
|
# Broadcast the message.
|
191
213
|
logging.debug("Broadcast LAN discovery message for UDP scan to all network interfaces")
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
214
|
+
logging.debug("Available network interfaces before binding:")
|
215
|
+
interfaces = socket.if_nameindex()
|
216
|
+
for idx, interface in interfaces:
|
217
|
+
logging.debug(f"Interface {idx}: {interface}")
|
218
|
+
try:
|
219
|
+
# Bind to all network interfaces using '', same as '0.0.0.0'
|
220
|
+
mySocket.bind(('',56732))
|
221
|
+
except Exception as err:
|
222
|
+
logging.debug("Error while trying to bind to network interfaces: "+" Error: "+str(err))
|
223
|
+
mySocket.sendto(b'Discovery: Who is out there?\0\n', ('255.255.255.255', 30303))
|
224
|
+
#mySocket.sendto(b'Discovery: Who is out there?\0\n', ('255.255.255.255', 30303)) #56732
|
225
|
+
|
226
|
+
counter = 0
|
227
|
+
|
228
|
+
# Receive messages until timeout.
|
229
|
+
while True:
|
230
|
+
network_modules = {}
|
231
|
+
counter += 1
|
232
|
+
# Receive raw message until timeout, then break.
|
199
233
|
try:
|
234
|
+
msg_received = mySocket.recvfrom(256)
|
235
|
+
except:
|
236
|
+
# check if any a device was targeted directly and allow parse
|
237
|
+
if specifiedDevice is not None:
|
238
|
+
msg_received = specifiedDevice
|
239
|
+
specifiedDevice = None
|
240
|
+
else:
|
241
|
+
break
|
242
|
+
cont = 0
|
243
|
+
|
244
|
+
# print(msg_received)
|
245
|
+
# Used split \r\n since values of 13 or 10 were looked at as /r and /n when using splitlines
|
246
|
+
# This fixes for all cases except if 13 is followed by 10.
|
247
|
+
splits = msg_received[0].split(b"\r\n")
|
248
|
+
del splits[-1]
|
249
|
+
for lines in splits:
|
250
|
+
if cont <= 1:
|
251
|
+
index = cont
|
252
|
+
data = repr(lines).replace("'", "").replace("b", "")
|
253
|
+
cont += 1
|
254
|
+
else:
|
255
|
+
index = repr(lines[0]).replace("'", "")
|
256
|
+
data = repr(lines[1:]).replace("'", "").replace("b", "")
|
200
257
|
|
201
|
-
|
202
|
-
mySocket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
203
|
-
mySocket.settimeout(lanTimeout)
|
204
|
-
mySocket.bind((ip,56732))
|
205
|
-
|
206
|
-
except Exception as err:
|
207
|
-
|
208
|
-
logging.debug("Error while trying to bind to network interfaces: "+" Error: "+str(err))
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
mySocket.sendto(b'Discovery: Who is out there?\0\n', ('255.255.255.255', 30303))
|
258
|
+
network_modules[index] = data
|
213
259
|
|
214
|
-
|
260
|
+
module_name = get_user_level_serial_number(network_modules)
|
261
|
+
logging.debug("Found UDP response: " + module_name)
|
215
262
|
|
216
|
-
|
217
|
-
while True:
|
218
|
-
network_modules = {}
|
219
|
-
counter += 1
|
220
|
-
# Receive raw message until timeout, then break.
|
221
|
-
try:
|
222
|
-
msg_received = mySocket.recvfrom(256)
|
223
|
-
except:
|
224
|
-
# check if any a device was targeted directly and allow parse
|
225
|
-
if specifiedDevice is not None:
|
226
|
-
msg_received = specifiedDevice
|
227
|
-
specifiedDevice = None
|
228
|
-
else:
|
229
|
-
break
|
230
|
-
cont = 0
|
231
|
-
|
232
|
-
# print(msg_received)
|
233
|
-
# Used split \r\n since values of 13 or 10 were looked at as /r and /n when using splitlines
|
234
|
-
# This fixes for all cases except if 13 is followed by 10.
|
235
|
-
splits = msg_received[0].split(b"\r\n")
|
236
|
-
del splits[-1]
|
237
|
-
for lines in splits:
|
238
|
-
if cont <= 1:
|
239
|
-
index = cont
|
240
|
-
data = repr(lines).replace("'", "").replace("b", "")
|
241
|
-
cont += 1
|
242
|
-
else:
|
243
|
-
index = repr(lines[0]).replace("'", "")
|
244
|
-
data = repr(lines[1:]).replace("'", "").replace("b", "")
|
245
|
-
|
246
|
-
network_modules[index] = data
|
247
|
-
|
248
|
-
module_name = get_user_level_serial_number(network_modules)
|
249
|
-
logging.debug("Found UDP response: " + module_name)
|
250
|
-
|
251
|
-
ip_module = msg_received[1][0].strip()
|
263
|
+
ip_module = msg_received[1][0].strip()
|
252
264
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
265
|
+
try:
|
266
|
+
# Add a QTL before modules without it.
|
267
|
+
if "QTL" not in module_name.decode("utf-8"):
|
268
|
+
module_name = "QTL" + module_name.decode("utf-8")
|
269
|
+
except:
|
270
|
+
# Add a QTL before modules without it.
|
271
|
+
if "QTL" not in module_name:
|
272
|
+
module_name = "QTL" + module_name
|
273
|
+
|
274
|
+
# Checks if there's a value in the TELNET key.
|
275
|
+
if (target_conn.lower() == "all" or target_conn.lower() == "telnet"):
|
276
|
+
if network_modules.get("\\x8a") or network_modules.get("138"):
|
277
|
+
# Append the information to the list.
|
278
|
+
lan_modules["TELNET:" + ip_module] = module_name
|
279
|
+
logging.debug("Found Telnet module: " + module_name)
|
280
|
+
|
281
|
+
# Checks if there's a value in the REST key.
|
282
|
+
if (target_conn.lower() == "all" or target_conn.lower() == "rest"):
|
283
|
+
if network_modules.get("\\x84") or network_modules.get("132"):
|
284
|
+
# Append the information to the list.
|
285
|
+
lan_modules["REST:" + ip_module] = module_name
|
286
|
+
logging.debug("Found REST module: " + module_name)
|
287
|
+
|
288
|
+
# Checks if there's a value in the TCP key.
|
289
|
+
if (target_conn.lower() == "all" or target_conn.lower() == "tcp"):
|
290
|
+
if network_modules.get("\\x85") or network_modules.get("133"):
|
291
|
+
# Append the information to the list.
|
292
|
+
lan_modules["TCP:" + ip_module] = module_name
|
293
|
+
logging.debug("Found TCP module: " + module_name)
|
294
|
+
|
295
|
+
mySocket.close()
|
284
296
|
logging.debug("Finished UDP scan")
|
285
297
|
retVal.update(lan_modules)
|
286
298
|
return retVal
|
@@ -459,12 +471,6 @@ def filter_module_type(module_type_filter, found_devices):
|
|
459
471
|
filtered_devices.update({key: value})
|
460
472
|
return filtered_devices
|
461
473
|
|
462
|
-
def scan_mDNS(mdnsListener):
|
463
|
-
from zeroconf import ServiceBrowser, Zeroconf
|
464
|
-
zeroconf = Zeroconf()
|
465
|
-
listener = mdnsListener
|
466
|
-
browser = ServiceBrowser(zeroconf, "_http._tcp.local.", listener)
|
467
|
-
|
468
474
|
|
469
475
|
'''
|
470
476
|
Scans for Quarch modules across the given interface(s). Returns a dictionary of module addresses and serial numbers
|
@@ -474,19 +480,12 @@ def scanDevices(target_conn="all", lanTimeout=1, scanInArray=True, favouriteOnly
|
|
474
480
|
foundDevices = dict()
|
475
481
|
scannedArrays = list()
|
476
482
|
|
477
|
-
|
478
483
|
if target_conn.lower() == "all":
|
479
484
|
foundDevices = list_USB()
|
480
485
|
foundDevices = mergeDict(foundDevices, list_serial())
|
481
486
|
try:
|
482
487
|
#This will fail if the test machine is not connected to a network
|
483
488
|
foundDevices = mergeDict(foundDevices, list_network("all", ipAddressLookup=ipAddressLookup, lanTimeout=lanTimeout))
|
484
|
-
try:
|
485
|
-
mdnsListener = MyListener()
|
486
|
-
scan_mDNS(mdnsListener)
|
487
|
-
foundDevices = mergeDict(foundDevices, mdnsListener.found_devices)
|
488
|
-
except Exception as mdnsExcept:
|
489
|
-
logging.debug("An error occurred while trying to use the mdns listner to scan\n" +str(mdnsExcept))
|
490
489
|
except Exception as e:
|
491
490
|
logging.error(e)
|
492
491
|
logging.warning("Network scan failed, check network connection")
|
@@ -513,8 +512,8 @@ def scanDevices(target_conn="all", lanTimeout=1, scanInArray=True, favouriteOnly
|
|
513
512
|
foundDevices = mergeDict(foundDevices, scanDevices)
|
514
513
|
myArrayControler.closeConnection()
|
515
514
|
except Exception as e:
|
516
|
-
logging.
|
517
|
-
logging.
|
515
|
+
logging.error(e, exc_info=True)
|
516
|
+
logging.warning("Cannot get serial number. Quarch device may be in use by another program.")
|
518
517
|
foundDevices[k] = "DEVICE IN USE"
|
519
518
|
|
520
519
|
if (favouriteOnly):
|
@@ -594,7 +593,7 @@ def userSelectDevice(scanDictionary=None, scanFilterStr=None,favouriteOnly=True,
|
|
594
593
|
|
595
594
|
|
596
595
|
if nice: #Prepair the data for niceListSelection using displayTable().
|
597
|
-
if additionalOptions is None: additionalOptions = ["
|
596
|
+
if additionalOptions is None: additionalOptions = ["IP Scan","Rescan","Quit"]
|
598
597
|
tempList = []
|
599
598
|
tempEl = []
|
600
599
|
for k, v in scanDictionary.items():
|
@@ -617,7 +616,7 @@ def userSelectDevice(scanDictionary=None, scanFilterStr=None,favouriteOnly=True,
|
|
617
616
|
devicesString.append(k + '=' + v + ": " + k[:charPos])
|
618
617
|
devicesString = ','.join(devicesString)
|
619
618
|
if additionalOptions is None :
|
620
|
-
additionalOptions = "
|
619
|
+
additionalOptions = "IP Scan=IP Scan,Rescan=Rescan,Quit=Quit"
|
621
620
|
userStr = listSelection(title=title,message=message,selectionList=devicesString, additionalOptions=additionalOptions)
|
622
621
|
|
623
622
|
# Process the user response
|
@@ -631,7 +630,7 @@ def userSelectDevice(scanDictionary=None, scanFilterStr=None,favouriteOnly=True,
|
|
631
630
|
ip_address = None
|
632
631
|
scanDictionary = None
|
633
632
|
favouriteOnly = False
|
634
|
-
elif(userStr.lower() in '
|
633
|
+
elif(userStr.lower() in 'ip scan'):
|
635
634
|
ip_address = requestDialog("Please input IP Address of the module you would like to connect to: ")
|
636
635
|
scanDictionary = None
|
637
636
|
favouriteOnly = False
|
@@ -639,3 +638,24 @@ def userSelectDevice(scanDictionary=None, scanFilterStr=None,favouriteOnly=True,
|
|
639
638
|
# Return the address string of the selected module
|
640
639
|
return userStr
|
641
640
|
|
641
|
+
|
642
|
+
#Not used but could come in usefull in near future.
|
643
|
+
# def userSelectAndReturnDevice(scanDictionary=None, scanFilterStr=None,favouriteOnly=True, message=None, title=None, nice=True, additionalOptions =["rescan","all conn types", "quit"], target_conn="all"):
|
644
|
+
# scanDictionary = scanDevices()
|
645
|
+
# connectionTarget = userSelectDevice(scanDictionary, scanFilterStr, favouriteOnly, message, title, nice,
|
646
|
+
# additionalOptions, target_conn)
|
647
|
+
# serialNumber = getSerialNumberFromConnectionTarget(connectionTarget)
|
648
|
+
#
|
649
|
+
# if connectionTarget.__contains__("<") and connectionTarget.__contains__(">"):
|
650
|
+
# connectionTarget, portNumber = connectionTarget.split("<")
|
651
|
+
# portNumber = portNumber[:-1]
|
652
|
+
# myDevice = quarchDevice(connectionTarget)
|
653
|
+
# myArrayController = quarchArray(myDevice)
|
654
|
+
# mySubDevice = myArrayController.getSubDevice(portNumber)
|
655
|
+
# myDevice = mySubDevice
|
656
|
+
# elif(serialNumber.lower().__contains__("qtl1999") or serialNumber.lower().__contains__("qtl1995") or serialNumber.lower().__contains__("qtl2312")):
|
657
|
+
# myDevice = quarchPPM(quarchDevice(connectionTarget))
|
658
|
+
#
|
659
|
+
# else:
|
660
|
+
# myDevice = quarchDevice(connectionTarget)
|
661
|
+
# return myDevice
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
quarchpy/docs/CHANGES.rst
CHANGED
@@ -13,6 +13,16 @@ Quarchpy
|
|
13
13
|
Change Log
|
14
14
|
----------
|
15
15
|
|
16
|
+
2.1.20
|
17
|
+
------
|
18
|
+
- Improved direct IP scanning for quarch modules.
|
19
|
+
|
20
|
+
2.1.19
|
21
|
+
------
|
22
|
+
- Imporoved QIS streaming
|
23
|
+
- Bug fixes
|
24
|
+
- Added zeroconf, numpy and pandas as requirements
|
25
|
+
|
16
26
|
2.1.18
|
17
27
|
------
|
18
28
|
- Minor bug fix
|