quarchpy 2.1.13.dev2__py2.py3-none-any.whl → 2.1.14.dev2__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- quarchpy/.idea/modules.xml +1 -0
- quarchpy/.idea/quarchpy.iml +4 -1
- quarchpy/.idea/workspace.xml +149 -11
- quarchpy/_version.py +1 -1
- quarchpy/connection_specific/connection_QIS.py +213 -315
- quarchpy/connection_specific/connection_QIS.py.bak +253 -357
- quarchpy/connection_specific/connection_TCP.py +1 -1
- quarchpy/connection_specific/connection_mDNS.py +46 -0
- quarchpy/device/quarchPPM.py +2 -2
- quarchpy/device/quarchQPS.py +95 -86
- quarchpy/device/scanDevices.py +12 -0
- quarchpy/docs/CHANGES.rst +7 -1
- quarchpy/qps/qpsFuncs.py +7 -4
- quarchpy/run.py +1 -1
- quarchpy/user_interface/user_interface.py.bak +3 -5
- quarchpy/utilities/TestCenter.py +1 -1
- quarchpy/utilities/TestCenter.py.bak +1 -4
- quarchpy/utilities/Version.py +50 -0
- {quarchpy-2.1.13.dev2.dist-info → quarchpy-2.1.14.dev2.dist-info}/METADATA +8 -2
- {quarchpy-2.1.13.dev2.dist-info → quarchpy-2.1.14.dev2.dist-info}/RECORD +22 -79
- quarchpy/.idea/.name +0 -1
- quarchpy/.idea/inspectionProfiles/Project_Default.xml +0 -26
- quarchpy/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/__pycache__/_version.cpython-311.pyc +0 -0
- quarchpy/__pycache__/connection.cpython-311.pyc +0 -0
- quarchpy/__pycache__/run.cpython-311.pyc +0 -0
- quarchpy/config_files/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/config_files/__pycache__/quarch_config_parser.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/StreamChannels.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_QIS.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_QPS.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_ReST.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_Serial.cpython-311.pyc +0 -0
- quarchpy/connection_specific/__pycache__/connection_USB.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/serialutil.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/serialwin32.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/__pycache__/win32.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports_common.cpython-311.pyc +0 -0
- quarchpy/connection_specific/serial/tools/__pycache__/list_ports_windows.cpython-311.pyc +0 -0
- quarchpy/connection_specific/usb_libs/__pycache__/libusb1.cpython-311.pyc +0 -0
- quarchpy/connection_specific/usb_libs/__pycache__/usb1.cpython-311.pyc +0 -0
- quarchpy/debug/TextScanIP.py +0 -11
- quarchpy/debug/__pycache__/SystemTest.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/module_debug.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/simple_terminal.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/upgrade_quarchpy.cpython-311.pyc +0 -0
- quarchpy/debug/__pycache__/versionCompare.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/device.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/quarchArray.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/quarchPPM.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/quarchQPS.cpython-311.pyc +0 -0
- quarchpy/device/__pycache__/scanDevices.cpython-311.pyc +0 -0
- quarchpy/device/device.py.bak +0 -504
- quarchpy/device/scanDevices.py.bak +0 -661
- quarchpy/disk_test/__pycache__/AbsDiskFinder.cpython-311.pyc +0 -0
- quarchpy/disk_test/__pycache__/DiskTargetSelection.cpython-311.pyc +0 -0
- quarchpy/disk_test/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/disk_test/__pycache__/iometerDiskFinder.cpython-311.pyc +0 -0
- quarchpy/fio/__pycache__/FIO_interface.cpython-311.pyc +0 -0
- quarchpy/fio/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/iometer/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/iometer/__pycache__/gen_iometer_template.cpython-311.pyc +0 -0
- quarchpy/iometer/__pycache__/iometerFuncs.cpython-311.pyc +0 -0
- quarchpy/qis/__pycache__/StreamHeaderInfo.cpython-311.pyc +0 -0
- quarchpy/qis/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/qis/__pycache__/qisFuncs.cpython-311.pyc +0 -0
- quarchpy/qps/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/qps/__pycache__/qpsFuncs.cpython-311.pyc +0 -0
- quarchpy/user_interface/__pycache__/__init__.cpython-311.pyc +0 -0
- quarchpy/user_interface/__pycache__/user_interface.cpython-311.pyc +0 -0
- quarchpy/utilities/__pycache__/TestCenter.cpython-311.pyc +0 -0
- quarchpy/utilities/__pycache__/TimeValue.cpython-311.pyc +0 -0
- quarchpy/utilities/__pycache__/__init__.cpython-311.pyc +0 -0
- {quarchpy-2.1.13.dev2.dist-info → quarchpy-2.1.14.dev2.dist-info}/WHEEL +0 -0
- {quarchpy-2.1.13.dev2.dist-info → quarchpy-2.1.14.dev2.dist-info}/top_level.txt +0 -0
@@ -1,3 +1,4 @@
|
|
1
|
+
import csv
|
1
2
|
import socket
|
2
3
|
import re
|
3
4
|
import time
|
@@ -9,7 +10,7 @@ import threading
|
|
9
10
|
import math
|
10
11
|
import logging
|
11
12
|
import struct
|
12
|
-
from
|
13
|
+
from io import StringIO
|
13
14
|
from quarchpy.user_interface import *
|
14
15
|
import xml.etree.ElementTree as ET
|
15
16
|
from connection_specific.StreamChannels import StreamGroups
|
@@ -46,13 +47,7 @@ class QisInterface:
|
|
46
47
|
self.streamSock.settimeout(5)
|
47
48
|
self.streamSock.connect((self.host, self.port))
|
48
49
|
self.pythonVersion = sys.version[0]
|
49
|
-
|
50
|
-
#time.sleep(3)
|
51
|
-
if self.pythonVersion == '3':
|
52
|
-
temp = '>'
|
53
|
-
self.cursor = temp.encode()
|
54
|
-
else:
|
55
|
-
self.cursor = '>'
|
50
|
+
self.cursor = '>'
|
56
51
|
#clear packets
|
57
52
|
welcomeString = self.streamSock.recv(self.maxRxBytes).rstrip()
|
58
53
|
|
@@ -111,19 +106,15 @@ class QisInterface:
|
|
111
106
|
def closeConnection(self, sock=None, conString=None):
|
112
107
|
if sock == None:
|
113
108
|
sock = self.sock
|
114
|
-
|
115
109
|
if conString is None:
|
116
110
|
cmd="close"
|
117
111
|
else:
|
118
112
|
cmd =conString+" close"
|
119
113
|
|
120
|
-
|
121
|
-
response = self.sendAndReceiveText(sock, cmd).decode()
|
122
|
-
else:
|
123
|
-
response = self.sendAndReceiveText(sock, cmd)
|
114
|
+
response = self.sendAndReceiveText(sock, cmd)
|
124
115
|
return response
|
125
116
|
|
126
|
-
def startStream(self, module, fileName, fileMaxMB, streamName, streamAverage, releaseOnData, separator, streamDuration = None):
|
117
|
+
def startStream(self, module, fileName, fileMaxMB, streamName, streamAverage, releaseOnData, separator, streamDuration = None, inMemoryData = None):
|
127
118
|
self.StreamRunSentSemaphore.acquire()
|
128
119
|
self.deviceDictSetup('QIS')
|
129
120
|
i = self.deviceMulti(module)
|
@@ -133,7 +124,7 @@ class QisInterface:
|
|
133
124
|
|
134
125
|
# Create the thread
|
135
126
|
t1 = threading.Thread(target=self.startStreamThread, name=module,
|
136
|
-
args=(module, fileName, fileMaxMB, streamName, streamAverage, releaseOnData, separator, streamDuration))
|
127
|
+
args=(module, fileName, fileMaxMB, streamName, streamAverage, releaseOnData, separator, streamDuration, inMemoryData))
|
137
128
|
# Start the thread
|
138
129
|
t1.start()
|
139
130
|
|
@@ -163,7 +154,6 @@ class QisInterface:
|
|
163
154
|
pass
|
164
155
|
# just wait until event is cleared
|
165
156
|
|
166
|
-
|
167
157
|
def stopStream(self, module, blocking = True):
|
168
158
|
moduleName=module.ConString
|
169
159
|
i = self.deviceMulti(moduleName)
|
@@ -191,15 +181,20 @@ class QisInterface:
|
|
191
181
|
else:
|
192
182
|
running = False
|
193
183
|
time.sleep(0.1)
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
184
|
+
|
185
|
+
def startStreamThread(self, module, fileName, fileMaxMB, streamName, streamAverage, releaseOnData, separator, streamDuration = None, inMemoryData = None):
|
186
|
+
# This is the function that is run when t1 is created. It is run in a seperate thread from
|
187
|
+
# the main application so streaming can happen without blocking the main application from
|
188
|
+
# doing other things. Within this function/thread you have to be very careful not to try
|
189
|
+
# and 'communicate' with anything from other threads. If you do, you MUST use a thread safe
|
190
|
+
# way of communicating. The thread creates it's own socket and should use that, NOT the objects socket
|
191
|
+
# (which some of the comms with module functions will use by default).
|
192
|
+
|
202
193
|
#Start module streaming and then read stream data
|
194
|
+
if inMemoryData is not None:
|
195
|
+
if not isinstance(inMemoryData, StringIO):
|
196
|
+
print("Error! The parameter 'inMemoryData' is NOT of type StringIO")
|
197
|
+
exit()
|
203
198
|
|
204
199
|
stripes = ['Empty Header']
|
205
200
|
#Send stream command so module starts streaming data into the backends buffer
|
@@ -234,6 +229,8 @@ class QisInterface:
|
|
234
229
|
formatHeader = self.streamHeaderFormat(device=module, sock=self.streamSock)
|
235
230
|
formatHeader = formatHeader.replace(", ", separator)
|
236
231
|
f.write(formatHeader + '\n')
|
232
|
+
inMemoryData.write(formatHeader + '\n')
|
233
|
+
|
237
234
|
numStripesPerRead = 4096
|
238
235
|
maxFileExceeded = False
|
239
236
|
openAttempts = 0
|
@@ -278,7 +275,7 @@ class QisInterface:
|
|
278
275
|
while self.stopFlagList[i] and (not streamOverrun) and (not streamComplete):
|
279
276
|
#now = time.time()
|
280
277
|
streamOverrun, removeChar, newStripes = self.streamGetStripesText(self.streamSock, module, numStripesPerRead)
|
281
|
-
newStripes = newStripes.replace(
|
278
|
+
newStripes = newStripes.replace(' ', separator)
|
282
279
|
#print (time.time() - now)
|
283
280
|
if streamOverrun:
|
284
281
|
self.deviceDict[module][0:3] = [True, 'Stopped', 'Device buffer overrun']
|
@@ -308,22 +305,26 @@ class QisInterface:
|
|
308
305
|
if streamDuration != None:
|
309
306
|
# Get the last data line in the file
|
310
307
|
lastLine = newStripes.splitlines()[-3] # the last data line is followed by 'eof' and '>'
|
311
|
-
lastTime = lastLine.
|
308
|
+
lastTime = lastLine.split(separator)[0] # get the first (time) entry
|
312
309
|
|
313
310
|
# if the last entry is still within the required stream length, write the whole lot
|
314
311
|
if int(lastTime) < int(streamDuration/(10**baseSampleUnitExponent)): # < rather than <= because we start at 0
|
315
312
|
f.write(newStripes[:removeChar])
|
313
|
+
inMemoryData.write(newStripes[:removeChar])
|
314
|
+
|
316
315
|
# else write each line individually until we have reached the desired endpoint
|
317
316
|
else:
|
318
317
|
for thisLine in newStripes.splitlines()[:-2]:
|
319
|
-
lastTime = thisLine.
|
318
|
+
lastTime = thisLine.split(separator)[0]
|
320
319
|
if int(lastTime) < int(streamDuration/(10**baseSampleUnitExponent)):
|
321
320
|
f.write(thisLine + b'\r' + b'\n') # Put the CR back on the end
|
321
|
+
inMemoryData.write(thisLine + b'\r' + b'\n')
|
322
322
|
else:
|
323
323
|
streamComplete = True
|
324
324
|
break
|
325
325
|
else:
|
326
326
|
f.write(newStripes[:removeChar])
|
327
|
+
inMemoryData.write(newStripes[:removeChar])
|
327
328
|
|
328
329
|
else:
|
329
330
|
maxFileExceeded = True
|
@@ -331,6 +332,8 @@ class QisInterface:
|
|
331
332
|
maxFileStatus = self.streamBufferStatus(device=module, sock=self.streamSock)
|
332
333
|
f.write('Warning: Max file size exceeded before end of stream.\n')
|
333
334
|
f.write('Unrecorded stripes in buffer when file full: ' + maxFileStatus + '.')
|
335
|
+
inMemoryData.write('Warning: Max file size exceeded before end of stream.\n')
|
336
|
+
inMemoryData.write('Unrecorded stripes in buffer when file full: ' + maxFileStatus + '.')
|
334
337
|
self.deviceDict[module][0:3] = [True, 'Stopped', 'User defined max filesize reached']
|
335
338
|
break
|
336
339
|
else:
|
@@ -378,8 +381,9 @@ class QisInterface:
|
|
378
381
|
if(streamAverage != None):
|
379
382
|
leftover, remainingStripes = self.averageStripes(leftover, stripesPerAverage, newStripes[:removeChar], f, remainingStripes)
|
380
383
|
else:
|
381
|
-
newStripes = newStripes.replace(
|
384
|
+
newStripes = newStripes.replace(' ',separator)
|
382
385
|
f.write(newStripes[:removeChar])
|
386
|
+
inMemoryData.write(newStripes[:removeChar])
|
383
387
|
else:
|
384
388
|
if not maxFileExceeded:
|
385
389
|
maxFileStatus = self.streamBufferStatus(device=module, sock=self.streamSock)
|
@@ -394,6 +398,8 @@ class QisInterface:
|
|
394
398
|
if maxFileExceeded:
|
395
399
|
f.write(b'Warning: Max file size exceeded before end of stream.\n')
|
396
400
|
f.write(b'Unrecorded stripes in buffer when file full: ' + maxFileStatus + '.')
|
401
|
+
inMemoryData.write(b'Warning: Max file size exceeded before end of stream.\n')
|
402
|
+
inMemoryData.write(b'Unrecorded stripes in buffer when file full: ' + maxFileStatus + '.')
|
397
403
|
logging.warning('Max file size exceeded. Some data has not been saved to file: ' + maxFileStatus + '.')
|
398
404
|
|
399
405
|
#printText('Stripes in buffer now: ' + self.streamBufferStatus(device=module, sock=self.streamSock))
|
@@ -484,7 +490,7 @@ class QisInterface:
|
|
484
490
|
# now = time.time()
|
485
491
|
streamOverrun, removeChar, newStripes = self.streamGetStripesText(self.streamSock, module,
|
486
492
|
numStripesPerRead)
|
487
|
-
newStripes = newStripes.replace(
|
493
|
+
newStripes = newStripes.replace(' ',separator)
|
488
494
|
# print(newStripes)
|
489
495
|
# print(len(newStripes))
|
490
496
|
|
@@ -498,11 +504,7 @@ class QisInterface:
|
|
498
504
|
if isEmpty == False:
|
499
505
|
# Writes in file if not too big else stops streaming
|
500
506
|
# print(newStripes)
|
501
|
-
|
502
|
-
x = newStripes[:removeChar]
|
503
|
-
y = x.decode("utf-8")
|
504
|
-
|
505
|
-
print("decoded stripe : " + y)
|
507
|
+
print("decoded stripe : " + newStripes[:removeChar])
|
506
508
|
|
507
509
|
# Writing multiple stripes
|
508
510
|
if "\r\n" in y:
|
@@ -616,191 +618,6 @@ class QisInterface:
|
|
616
618
|
x = struct.pack(">d", int(stripe[counter]))
|
617
619
|
# logging.debug(item, x)
|
618
620
|
file1.write(x)
|
619
|
-
|
620
|
-
|
621
|
-
# Send text and get the backends response. - acts as wrapper to the sendAndReceiveText, intended to provide some extra convenience
|
622
|
-
# when sending commands to module (as opposed to back end)
|
623
|
-
# If read until cursor is set to True (which is default) then keep reading response until a cursor is returned as the last character of result string
|
624
|
-
# After command is sent wait for betweenCommandDelay which defaults to 0 but can be specified to add a delay between commands
|
625
|
-
# The objects connection needs to be opened (connect()) before this is used
|
626
|
-
def sendCmd(self, device='', cmd='$help', sock=None, readUntilCursor=True, betweenCommandDelay=0.0, expectedResponse = True):
|
627
|
-
if sock==None:
|
628
|
-
sock = self.sock
|
629
|
-
if not (device == ''):
|
630
|
-
self.deviceDictSetup(device)
|
631
|
-
|
632
|
-
if expectedResponse is False:
|
633
|
-
self.sendText(sock, cmd, device)
|
634
|
-
return
|
635
|
-
|
636
|
-
res = self.sendAndReceiveText(sock, cmd, device, readUntilCursor)
|
637
|
-
if (betweenCommandDelay > 0):
|
638
|
-
time.sleep(betweenCommandDelay)
|
639
|
-
#If ends with cursor get rid of it
|
640
|
-
if res[-1:] == self.cursor:
|
641
|
-
res = res[:-3] #remove last three chars - hopefully '\r\n>'
|
642
|
-
# time.sleep(0.1)
|
643
|
-
return res.decode()
|
644
|
-
|
645
|
-
|
646
|
-
def sendAndReceiveCmd(self, sock=None, cmd='$help', device='', readUntilCursor=True, betweenCommandDelay=0.0):
|
647
|
-
if sock==None:
|
648
|
-
sock = self.sock
|
649
|
-
if not (device == ''):
|
650
|
-
self.deviceDictSetup(device)
|
651
|
-
if self.pythonVersion == '3':
|
652
|
-
res = self.sendAndReceiveText(sock, cmd, device, readUntilCursor).decode()
|
653
|
-
else:
|
654
|
-
res = self.sendAndReceiveText(sock, cmd, device, readUntilCursor)
|
655
|
-
if (betweenCommandDelay > 0):
|
656
|
-
time.sleep(betweenCommandDelay)
|
657
|
-
#If ends with cursor get rid of it
|
658
|
-
if res[-1:] == '>':
|
659
|
-
res = res[:-3] #remove last three chars - hopefully '\r\n>'
|
660
|
-
return cmd + ' : ' + res
|
661
|
-
|
662
|
-
# Send text to the back end then read it's response
|
663
|
-
# The objects connection needs to be opened (connect()) before this is used
|
664
|
-
# If read until cursor is set to True (which is default) then keep reading response until a cursor is returned as the last character of result string
|
665
|
-
def sendAndReceiveText(self, sock, sentText='$help', device='', readUntilCursor=True):
|
666
|
-
self.sockSemaphore.acquire()
|
667
|
-
try:
|
668
|
-
self.sendText(sock, sentText, device)
|
669
|
-
if self.pythonVersion == '3':
|
670
|
-
res = bytearray()
|
671
|
-
res.extend(self.rxBytes(sock))
|
672
|
-
#Somtimes we just get one cursor back of currently unknown origins
|
673
|
-
#If that happens discard it and read again
|
674
|
-
if len(res)==0:
|
675
|
-
logging.warning("empty response from QIS. Retrying.")
|
676
|
-
streamResp=self.sendAndReceiveText(sock, "stream?",device,readUntilCursor).lower()
|
677
|
-
if len(streamResp)==0:
|
678
|
-
raise("Empty response from QIS twice in a row")
|
679
|
-
else:
|
680
|
-
logging.warning("Response recovered Successfully. Continuing.")
|
681
|
-
res = bytearray()
|
682
|
-
res.extend(self.rxBytes(sock))
|
683
|
-
if len(res) == 0:
|
684
|
-
raise ("empty response from QIS after second ")
|
685
|
-
if res[0] == self.cursor:
|
686
|
-
#res[0] = self.rxBytes(sock)
|
687
|
-
logging.warning('Only Returned Cursor!!!!!')
|
688
|
-
#If create socked fail (between backend and tcp/ip module)
|
689
|
-
cba = 'Create Socket Fail'
|
690
|
-
if cba.encode() == res[0]:
|
691
|
-
logging.warning(res[0].decode())
|
692
|
-
cba = 'Connection Timeout'
|
693
|
-
if cba.encode() == res[0]:
|
694
|
-
logging.warning(res[0].decode())
|
695
|
-
#If reading until a cursor comes back then keep reading until a cursor appears or max tries exceeded
|
696
|
-
if readUntilCursor:
|
697
|
-
maxReads = 1000
|
698
|
-
count = 1
|
699
|
-
#check for cursor at end of read and if not there read again
|
700
|
-
while res[-1:] != self.cursor:
|
701
|
-
res.extend(self.rxBytes(sock))
|
702
|
-
count += 1
|
703
|
-
if count >= maxReads:
|
704
|
-
raise Exception(' Count = Error: max reads exceeded before cursor returned')
|
705
|
-
return res
|
706
|
-
else:
|
707
|
-
res = self.rxBytes(sock)
|
708
|
-
#Somtimes we just get one cursor back of currently unknown origins
|
709
|
-
#If that happens discard it and read again
|
710
|
-
if res == self.cursor:
|
711
|
-
#printText(" CURSOR ONLY")
|
712
|
-
res = self.rxBytes(sock)
|
713
|
-
#If create socked fail (between backend and tcp/ip module)
|
714
|
-
if 'Create Socket Fail' in res:
|
715
|
-
raise Exception(res)
|
716
|
-
if 'Connection Timeout' in res:
|
717
|
-
raise Exception(res)
|
718
|
-
#If reading until a cursor comes back then keep reading until a cursor appears or max tries exceeded
|
719
|
-
if readUntilCursor:
|
720
|
-
maxReads = 1000
|
721
|
-
count = 1
|
722
|
-
#check for cursor at end of read and if not there read again
|
723
|
-
while res[-1:] != self.cursor:
|
724
|
-
res += self.rxBytes(sock)
|
725
|
-
count += 1
|
726
|
-
if count >= maxReads:
|
727
|
-
raise Exception(' Count = Error: max reads exceeded before cursor returned')
|
728
|
-
return res
|
729
|
-
|
730
|
-
except Exception as e:
|
731
|
-
raise e
|
732
|
-
finally:
|
733
|
-
self.sockSemaphore.release()
|
734
|
-
|
735
|
-
def rxBytes(self,sock):
|
736
|
-
#sock.setblocking(0) #make socket non-blocking
|
737
|
-
#printText('rxBytes')
|
738
|
-
maxExceptions=10
|
739
|
-
exceptions=0
|
740
|
-
maxReadRepeats=50
|
741
|
-
readRepeats=0
|
742
|
-
timeout_in_seconds = 10
|
743
|
-
#Keep trying to read bytes until we get some, unless number of read repeads or exceptions is exceeded
|
744
|
-
while True:
|
745
|
-
try:
|
746
|
-
#select.select returns a list of waitable objects which are ready. On windows it has to be sockets.
|
747
|
-
#The first arguement is a list of objects to wait for reading, second writing, third 'exceptional condition'
|
748
|
-
#We only use the read list and our socket to check if it is readable. if no timeout is specified then it blocks until it becomes readable.
|
749
|
-
ready = select.select([sock], [], [], timeout_in_seconds)
|
750
|
-
#time.sleep(0.1)
|
751
|
-
#ready = [1,2]
|
752
|
-
if ready[0]:
|
753
|
-
ret = sock.recv(self.maxRxBytes)
|
754
|
-
#time.sleep(0.1)
|
755
|
-
return ret
|
756
|
-
else:
|
757
|
-
#printText('rxBytes - readRepeats + 1')
|
758
|
-
|
759
|
-
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
760
|
-
sock.connect((self.host, self.port))
|
761
|
-
sock.settimeout(5)
|
762
|
-
|
763
|
-
try:
|
764
|
-
welcomeString = self.sock.recv(self.maxRxBytes).rstrip()
|
765
|
-
welcomeString = 'Connected@' + self.host + ':' + str(self.port) + ' ' + '\n ' + welcomeString
|
766
|
-
printText('New Welcome:' + welcomeString)
|
767
|
-
except Exception as e:
|
768
|
-
logging.error('tried and failed to get new welcome')
|
769
|
-
raise e
|
770
|
-
|
771
|
-
readRepeats=readRepeats+1
|
772
|
-
time.sleep(0.5)
|
773
|
-
|
774
|
-
except Exception as e:
|
775
|
-
#printText('rxBytes - exceptions + 1')
|
776
|
-
exceptions=exceptions+1
|
777
|
-
time.sleep(0.5)
|
778
|
-
raise e
|
779
|
-
|
780
|
-
#If read repeats has been exceeded we failed to get any data on this read.
|
781
|
-
# !!! This is likely to break whatever called us !!!
|
782
|
-
if readRepeats >= maxReadRepeats:
|
783
|
-
logging.error('Max read repeats exceeded - returning.')
|
784
|
-
return 'No data received from QIS'
|
785
|
-
#If number of exceptions exceeded then give up by exiting
|
786
|
-
if exceptions >= maxExceptions:
|
787
|
-
logging.error('Max exceptions exceeded - exiting') #exceptions are probably 10035 non-blocking socket could not complete immediatley
|
788
|
-
exit()
|
789
|
-
|
790
|
-
# Send text to the back end don't read it's response
|
791
|
-
# The objects connection needs to be opened (connect()) before this is used
|
792
|
-
def sendText(self, sock, message='$help', device=''):
|
793
|
-
if device != '':
|
794
|
-
specialTimeout = '%500000'
|
795
|
-
message = device + specialTimeout + ' ' + message
|
796
|
-
#printText('Sending: "' + message + '" ' + self.host + ':' + str(self.port))
|
797
|
-
|
798
|
-
if self.pythonVersion == 2:
|
799
|
-
sock.sendall(message + '\r\n')
|
800
|
-
else:
|
801
|
-
convM = message + '\r\n'
|
802
|
-
sock.sendall(convM.encode('utf-8'))
|
803
|
-
return 'Sent:' + message
|
804
621
|
|
805
622
|
# Query the backend for a list of connected modules. A $scan command is sent to refresh the list of devices,
|
806
623
|
# Then a wait occurs while the backend discovers devices (network ones can take a while) and then a list of device name strings is returned
|
@@ -809,21 +626,9 @@ class QisInterface:
|
|
809
626
|
|
810
627
|
if sock == None:
|
811
628
|
sock = self.sock
|
812
|
-
|
813
|
-
#printText('Scanning for devices and waiting ' + str(scanWait) + ' seconds.')
|
814
|
-
if self.pythonVersion == '3':
|
815
|
-
#devString = self.sendAndReceiveText(sock, '$scan').decode
|
816
|
-
#time.sleep(scanWait)
|
817
|
-
devString = self.sendAndReceiveText(sock, '$list').decode()
|
818
|
-
else:
|
819
|
-
#devString = self.sendAndReceiveText(sock, '$scan')
|
820
|
-
#time.sleep(scanWait)
|
821
|
-
devString = self.sendAndReceiveText(sock, '$list')
|
822
|
-
|
629
|
+
devString = self.sendAndReceiveText(sock, '$list')
|
823
630
|
devString = devString.replace('>', '')
|
824
|
-
devString = devString.replace(r'\d+\) ', '')
|
825
|
-
|
826
|
-
#printText('"' + devString + '"')
|
631
|
+
devString = devString.replace(r'\d+\) ', '')
|
827
632
|
devString = devString.split('\r\n')
|
828
633
|
devString = filter(None, devString) #remove empty elements
|
829
634
|
return devString
|
@@ -831,21 +636,10 @@ class QisInterface:
|
|
831
636
|
def get_list_details(self, sock=None):
|
832
637
|
if sock == None:
|
833
638
|
sock = self.sock
|
834
|
-
scanWait = 2
|
835
|
-
# printText('Scanning for devices and waiting ' + str(scanWait) + ' seconds.')
|
836
|
-
if self.pythonVersion == '3':
|
837
|
-
# devString = self.sendAndReceiveText(sock, '$scan').decode
|
838
|
-
# time.sleep(scanWait)
|
839
|
-
devString = self.sendAndReceiveText(sock, '$list details').decode()
|
840
|
-
else:
|
841
|
-
# devString = self.sendAndReceiveText(sock, '$scan')
|
842
|
-
# time.sleep(scanWait)
|
843
|
-
devString = self.sendAndReceiveText(sock, '$list details')
|
844
639
|
|
640
|
+
devString = self.sendAndReceiveText(sock, '$list details')
|
845
641
|
devString = devString.replace('>', '')
|
846
642
|
devString = devString.replace(r'\d+\) ', '')
|
847
|
-
|
848
|
-
# printText('"' + devString + '"')
|
849
643
|
devString = devString.split('\r\n')
|
850
644
|
devString = [x for x in devString if x] # remove empty elements
|
851
645
|
return devString
|
@@ -884,9 +678,6 @@ class QisInterface:
|
|
884
678
|
logging.warning(e)
|
885
679
|
logging.warning("No module found at " + ipAddress)
|
886
680
|
|
887
|
-
|
888
|
-
|
889
|
-
|
890
681
|
def GetQisModuleSelection(self, favouriteOnly=True , additionalOptions=['rescan', 'all con types', 'ip scan'], scan=True):
|
891
682
|
tableHeaders =["Modules"]
|
892
683
|
ip_address = None
|
@@ -922,33 +713,19 @@ class QisInterface:
|
|
922
713
|
foundDevices = "1"
|
923
714
|
foundDevices2 = "2" # this is used to check if new modules are being discovered or if all have been found.
|
924
715
|
scanWait = 2 # The number of seconds waited between the two scans.
|
925
|
-
if self.pythonVersion == '3':
|
926
|
-
if scan:
|
927
|
-
if ipAddress == None:
|
928
|
-
devString = self.sendAndReceiveText(self.sock, '$scan').decode
|
929
|
-
else:
|
930
|
-
devString = self.sendAndReceiveText(self.sock, '$scan TCP::' + ipAddress).decode
|
931
|
-
time.sleep(scanWait)
|
932
|
-
while foundDevices not in foundDevices2:
|
933
|
-
foundDevices = self.sendAndReceiveText(self.sock, '$list').decode()
|
934
|
-
time.sleep(scanWait)
|
935
|
-
foundDevices2 = self.sendAndReceiveText(self.sock, '$list').decode()
|
936
|
-
else:
|
937
|
-
foundDevices = self.sendAndReceiveText(self.sock, '$list').decode()
|
938
716
|
|
939
|
-
|
940
|
-
if
|
941
|
-
|
942
|
-
devString = self.sendAndReceiveText(self.sock, '$scan').decode
|
943
|
-
else:
|
944
|
-
devString = self.sendAndReceiveText(self.sock, '$scan TCP::' + ipAddress).decode
|
945
|
-
time.sleep(scanWait)
|
946
|
-
while foundDevices not in foundDevices2:
|
947
|
-
foundDevices = self.sendAndReceiveText(self.sock, '$list')
|
948
|
-
time.sleep(scanWait)
|
949
|
-
foundDevices2 = self.sendAndReceiveText(self.sock, '$list')
|
717
|
+
if scan:
|
718
|
+
if ipAddress == None:
|
719
|
+
devString = self.sendAndReceiveText(self.sock, '$scan')
|
950
720
|
else:
|
721
|
+
devString = self.sendAndReceiveText(self.sock, '$scan TCP::' + ipAddress)
|
722
|
+
time.sleep(scanWait)
|
723
|
+
while foundDevices not in foundDevices2:
|
951
724
|
foundDevices = self.sendAndReceiveText(self.sock, '$list')
|
725
|
+
time.sleep(scanWait)
|
726
|
+
foundDevices2 = self.sendAndReceiveText(self.sock, '$list')
|
727
|
+
else:
|
728
|
+
foundDevices = self.sendAndReceiveText(self.sock, '$list')
|
952
729
|
|
953
730
|
if not "no devices found" in foundDevices.lower():
|
954
731
|
foundDevices = foundDevices.replace('>', '')
|
@@ -998,10 +775,7 @@ class QisInterface:
|
|
998
775
|
if sock == None:
|
999
776
|
sock = self.sock
|
1000
777
|
index = 0 # index of relevant line in split string
|
1001
|
-
|
1002
|
-
streamStatus = self.sendAndReceiveText(sock, 'stream?', device).decode()
|
1003
|
-
else:
|
1004
|
-
streamStatus = self.sendAndReceiveText(sock, 'stream?', device)
|
778
|
+
streamStatus = self.sendAndReceiveText(sock, 'stream?', device)
|
1005
779
|
streamStatus = streamStatus.split('\r\n')
|
1006
780
|
streamStatus[index] = re.sub(r':', '', streamStatus[index]) #remove :
|
1007
781
|
return streamStatus[index]
|
@@ -1012,10 +786,7 @@ class QisInterface:
|
|
1012
786
|
if sock == None:
|
1013
787
|
sock = self.sock
|
1014
788
|
index = 1 # index of relevant line in split string
|
1015
|
-
|
1016
|
-
streamStatus = self.sendAndReceiveText(sock, 'stream?', device).decode()
|
1017
|
-
else:
|
1018
|
-
streamStatus = self.sendAndReceiveText(sock, 'stream?', device)
|
789
|
+
streamStatus = self.sendAndReceiveText(sock, 'stream?', device)
|
1019
790
|
streamStatus = streamStatus.split('\r\n')
|
1020
791
|
streamStatus[index] = re.sub(r'^Stripes Buffered: ', '', streamStatus[index])
|
1021
792
|
return streamStatus[index]
|
@@ -1030,10 +801,7 @@ class QisInterface:
|
|
1030
801
|
if sock == None:
|
1031
802
|
sock = self.sock
|
1032
803
|
index = 2 # index of relevant line in split string
|
1033
|
-
|
1034
|
-
streamStatus = self.sendAndReceiveText(sock, sentText='stream text header', device=device).decode()
|
1035
|
-
else:
|
1036
|
-
streamStatus = self.sendAndReceiveText(sock, sentText='stream text header', device=device)
|
804
|
+
streamStatus = self.sendAndReceiveText(sock, sentText='stream text header', device=device)
|
1037
805
|
|
1038
806
|
self.qps_stream_header = streamStatus
|
1039
807
|
|
@@ -1074,10 +842,7 @@ class QisInterface:
|
|
1074
842
|
if sock == None:
|
1075
843
|
sock = self.sock
|
1076
844
|
index = 0 # index of relevant line in split string
|
1077
|
-
|
1078
|
-
streamStatus = self.sendAndReceiveText(sock,'stream text header', device).decode()
|
1079
|
-
else:
|
1080
|
-
streamStatus = self.sendAndReceiveText(sock,'stream text header', device)
|
845
|
+
streamStatus = self.sendAndReceiveText(sock,'stream text header', device)
|
1081
846
|
streamStatus = streamStatus.split('\r\n')
|
1082
847
|
if 'Header Not Available' in streamStatus[0]:
|
1083
848
|
str = streamStatus[0] + '. Check stream has been ran on device.'
|
@@ -1104,10 +869,7 @@ class QisInterface:
|
|
1104
869
|
if sock == None:
|
1105
870
|
sock = self.sock
|
1106
871
|
index = 1 # index of relevant line in split string STREAM MODE HEADER [?|V1,V2,V3]
|
1107
|
-
|
1108
|
-
streamStatus = self.sendAndReceiveText(sock,'stream text header', device).decode()
|
1109
|
-
else:
|
1110
|
-
streamStatus = self.sendAndReceiveText(sock,'stream text header', device)
|
872
|
+
streamStatus = self.sendAndReceiveText(sock,'stream text header', device)
|
1111
873
|
# Check if this is a new XML form header
|
1112
874
|
if (self.isXmlHeader (streamStatus)):
|
1113
875
|
# Get the basic averaging rate (V3 header)
|
@@ -1142,12 +904,8 @@ class QisInterface:
|
|
1142
904
|
str = streamStatus[0] + '. Check stream has been ran on device.'
|
1143
905
|
logging.error(str)
|
1144
906
|
return str
|
1145
|
-
|
1146
|
-
|
1147
|
-
powerMode = self.sendAndReceiveText(sock,'stream mode power?', device).decode()
|
1148
|
-
else:
|
1149
|
-
outputMode = self.sendAndReceiveText(sock,'Config Output Mode?', device)
|
1150
|
-
powerMode = self.sendAndReceiveText(sock,'stream mode power?', device)
|
907
|
+
outputMode = self.sendAndReceiveText(sock,'Config Output Mode?', device)
|
908
|
+
powerMode = self.sendAndReceiveText(sock,'stream mode power?', device)
|
1151
909
|
format = int(re.sub(r'^Format: ', '', streamStatus[index]))
|
1152
910
|
b0 = 1 #12V_I
|
1153
911
|
b1 = 1 << 1 #12V_V
|
@@ -1188,10 +946,7 @@ class QisInterface:
|
|
1188
946
|
bufferStatus = False
|
1189
947
|
# Allows the status check to be skipped when emptying the buffer after streaming has stopped (saving time)
|
1190
948
|
if (skipStatusCheck == False):
|
1191
|
-
|
1192
|
-
streamStatus = self.sendAndReceiveText(sock, 'stream?', device).decode()
|
1193
|
-
else:
|
1194
|
-
streamStatus = self.sendAndReceiveText(sock, 'stream?', device)
|
949
|
+
streamStatus = self.sendAndReceiveText(sock, 'stream?', device)
|
1195
950
|
if ('Overrun' in streamStatus) or ('8388608 of 8388608' in streamStatus):
|
1196
951
|
bufferStatus = True
|
1197
952
|
stripes = self.sendAndReceiveText(sock, 'stream text all', device, readUntilCursor=True)
|
@@ -1199,11 +954,7 @@ class QisInterface:
|
|
1199
954
|
if stripes[-1:] != self.cursor:
|
1200
955
|
return "Error no cursor returned."
|
1201
956
|
else:
|
1202
|
-
|
1203
|
-
endOfFile = 'eof\r\n>'
|
1204
|
-
genEndOfFile = endOfFile.encode()
|
1205
|
-
else:
|
1206
|
-
genEndOfFile = 'eof\r\n>'
|
957
|
+
genEndOfFile = 'eof\r\n>'
|
1207
958
|
if stripes[-6:] == genEndOfFile:
|
1208
959
|
removeChar = -6
|
1209
960
|
else:
|
@@ -1264,8 +1015,6 @@ class QisInterface:
|
|
1264
1015
|
finalAverage = splitList[0:2] + [str(round(x / streamAverage)) for x in runningAverage]
|
1265
1016
|
for counter in xrange(len(finalAverage)-1):
|
1266
1017
|
finalAverage[counter] = finalAverage[counter] + ' '
|
1267
|
-
if self.pythonVersion == '3':
|
1268
|
-
finalAverage = finalAverage.encode
|
1269
1018
|
for x in finalAverage:
|
1270
1019
|
f.write(x)
|
1271
1020
|
f.write('\r\n')
|
@@ -1350,10 +1099,7 @@ class QisInterface:
|
|
1350
1099
|
sock = self.sock
|
1351
1100
|
|
1352
1101
|
# Get the raw data
|
1353
|
-
|
1354
|
-
headerData = self.sendAndReceiveText(sock, sentText='stream text header', device=device).decode()
|
1355
|
-
else:
|
1356
|
-
headerData = self.sendAndReceiveText(sock, sentText='stream text header', device=device)
|
1102
|
+
headerData = self.sendAndReceiveText(sock, sentText='stream text header', device=device)
|
1357
1103
|
|
1358
1104
|
# The XML can contain the cursor on the end! Trap and remove it here TODO: Needs fixed in the command layer above
|
1359
1105
|
if ('\r\n>' in headerData):
|
@@ -1480,10 +1226,10 @@ class QisInterface:
|
|
1480
1226
|
folder_name = None
|
1481
1227
|
# Checking if there was a directory passed; and if it's a valid directory
|
1482
1228
|
if not directory:
|
1483
|
-
directory = os.path.join(
|
1229
|
+
directory = os.path.join(os.path.expanduser("~"), "AppData", "Local", "Quarch", "QPS", "Recordings")
|
1484
1230
|
logging.debug("No directory specified")
|
1485
1231
|
elif not os.path.isdir(directory):
|
1486
|
-
new_dir = os.path.join(str(
|
1232
|
+
new_dir = os.path.join(str(os.path.expanduser("~"), "AppData", "Local", "Quarch", "QPS", "Recordings"))
|
1487
1233
|
logging.warning(directory+" was not a valid directory, streaming to default location: \n"+new_dir)
|
1488
1234
|
directory = new_dir
|
1489
1235
|
else:
|
@@ -1808,6 +1554,158 @@ class QisInterface:
|
|
1808
1554
|
f.write("Saved: "+x+ "\n")
|
1809
1555
|
|
1810
1556
|
|
1557
|
+
# when sending commands to module (as opposed to back end)
|
1558
|
+
# If read until cursor is set to True (which is default) then keep reading response until a cursor is returned as the last character of result string
|
1559
|
+
# After command is sent wait for betweenCommandDelay which defaults to 0 but can be specified to add a delay between commands
|
1560
|
+
# The objects connection needs to be opened (connect()) before this is used
|
1561
|
+
def sendCmd(self, device='', cmd='$help', sock=None, readUntilCursor=True, betweenCommandDelay=0.0, expectedResponse = True):
|
1562
|
+
'''Send command is used to send a command to QIS and as far as I can see it has no difference than sendAndReceiveCmd'''
|
1563
|
+
if expectedResponse is True:
|
1564
|
+
res = self.sendAndReceiveCmd(device=device, cmd=cmd, sock=sock, readUntilCursor=readUntilCursor, betweenCommandDelay=betweenCommandDelay)
|
1565
|
+
#If ends with cursor get rid of it
|
1566
|
+
if res[-1:] == self.cursor:
|
1567
|
+
res = res[:-3] #remove last three chars - hopefully '\r\n>'
|
1568
|
+
return res
|
1569
|
+
else :
|
1570
|
+
self.sendText(sock, cmd, device)
|
1571
|
+
return
|
1572
|
+
|
1573
|
+
def sendAndReceiveCmd(self, sock=None, cmd='$help', device='', readUntilCursor=True, betweenCommandDelay=0.0):
|
1574
|
+
if sock==None:
|
1575
|
+
sock = self.sock
|
1576
|
+
if not (device == ''):
|
1577
|
+
self.deviceDictSetup(device)
|
1578
|
+
res = self.sendAndReceiveText(sock, cmd, device, readUntilCursor)
|
1579
|
+
if (betweenCommandDelay > 0):
|
1580
|
+
time.sleep(betweenCommandDelay)
|
1581
|
+
#If ends with cursor get rid of it
|
1582
|
+
if res[-1:] == '>':
|
1583
|
+
res = res[:-3] #remove last three chars - hopefully '\r\n>'
|
1584
|
+
return cmd + ' : ' + res
|
1585
|
+
|
1586
|
+
def sendAndReceiveText(self, sock, sentText='$help', device='', readUntilCursor=True):
|
1587
|
+
# Send text to QIS
|
1588
|
+
# The objects connection needs to be opened (connect()) before this is used
|
1589
|
+
# If read until cursor is set to True (which is default) then keep reading response until a cursor is returned as the last character of result string
|
1590
|
+
|
1591
|
+
# do sendText
|
1592
|
+
self.sockSemaphore.acquire()
|
1593
|
+
try:
|
1594
|
+
#Send Text
|
1595
|
+
self.sendText(sock, sentText, device)
|
1596
|
+
#Receive Response
|
1597
|
+
res = self.receiveText(sock)
|
1598
|
+
# Error Check / validate response
|
1599
|
+
if len(res) == 0:
|
1600
|
+
#logging.error("Empty response from QIS.")
|
1601
|
+
raise (Exception("Empty response from QIS. Sent: " +sentText))
|
1602
|
+
if res[0] == self.cursor:
|
1603
|
+
logging.warning('Only Returned Cursor!!!!!')
|
1604
|
+
if 'Create Socket Fail' == res[0]: # If create socked fail (between QIS and tcp/ip module)
|
1605
|
+
logging.warning(res[0])
|
1606
|
+
if 'Connection Timeout' == res[0]:
|
1607
|
+
logging.warning(res[0])
|
1608
|
+
# If reading until a cursor comes back then keep reading until a cursor appears or max tries exceeded
|
1609
|
+
if readUntilCursor:
|
1610
|
+
maxReads = 1000
|
1611
|
+
count = 1
|
1612
|
+
# check for cursor at end of read and if not there read again
|
1613
|
+
while res[-1:] != self.cursor:
|
1614
|
+
res+= self.receiveText(sock) #TODO Confirm this works with multi response CMD Like a $get stats on a large stream with many annos. test with py2 and py3
|
1615
|
+
#res.extend(self.rxBytes(sock))
|
1616
|
+
count += 1
|
1617
|
+
if count >= maxReads:
|
1618
|
+
raise Exception(' Count = Error: max reads exceeded before cursor returned')
|
1619
|
+
return res
|
1620
|
+
|
1621
|
+
except Exception as e:
|
1622
|
+
#something went wrong during send qis cmd
|
1623
|
+
logging.error(e)
|
1624
|
+
raise e
|
1625
|
+
finally:
|
1626
|
+
self.sockSemaphore.release()
|
1627
|
+
|
1628
|
+
|
1629
|
+
def receiveText(self, sock):
|
1630
|
+
if self.pythonVersion == '3':
|
1631
|
+
res = bytearray()
|
1632
|
+
res.extend(self.rxBytes(sock))
|
1633
|
+
res = res.decode()
|
1634
|
+
else:
|
1635
|
+
res = self.rxBytes(sock)
|
1636
|
+
return res
|
1637
|
+
|
1638
|
+
def sendText(self, sock, message='$help', device=''):
|
1639
|
+
# Send text to QIS, don't read it's response
|
1640
|
+
# The objects connection needs to be opened (connect()) before this is used
|
1641
|
+
if device != '':
|
1642
|
+
specialTimeout = '%500000'
|
1643
|
+
message = device + specialTimeout + ' ' + message
|
1644
|
+
#printText('Sending: "' + message + '" ' + self.host + ':' + str(self.port))
|
1645
|
+
|
1646
|
+
if self.pythonVersion == 2:
|
1647
|
+
sock.sendall(message + '\r\n')
|
1648
|
+
else:
|
1649
|
+
convM = message + '\r\n'
|
1650
|
+
sock.sendall(convM.encode('utf-8'))
|
1651
|
+
return 'Sent:' + message
|
1652
|
+
|
1653
|
+
def rxBytes(self,sock):
|
1654
|
+
#sock.setblocking(0) #make socket non-blocking
|
1655
|
+
#printText('rxBytes')
|
1656
|
+
maxExceptions=10
|
1657
|
+
exceptions=0
|
1658
|
+
maxReadRepeats=50
|
1659
|
+
readRepeats=0
|
1660
|
+
timeout_in_seconds = 10
|
1661
|
+
#Keep trying to read bytes until we get some, unless number of read repeads or exceptions is exceeded
|
1662
|
+
while True:
|
1663
|
+
try:
|
1664
|
+
#select.select returns a list of waitable objects which are ready. On windows it has to be sockets.
|
1665
|
+
#The first arguement is a list of objects to wait for reading, second writing, third 'exceptional condition'
|
1666
|
+
#We only use the read list and our socket to check if it is readable. if no timeout is specified then it blocks until it becomes readable.
|
1667
|
+
ready = select.select([sock], [], [], timeout_in_seconds)
|
1668
|
+
#time.sleep(0.1)
|
1669
|
+
#ready = [1,2]
|
1670
|
+
if ready[0]:
|
1671
|
+
ret = sock.recv(self.maxRxBytes)
|
1672
|
+
#time.sleep(0.1)
|
1673
|
+
return ret
|
1674
|
+
else:
|
1675
|
+
#printText('rxBytes - readRepeats + 1')
|
1676
|
+
|
1677
|
+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
1678
|
+
sock.connect((self.host, self.port))
|
1679
|
+
sock.settimeout(5)
|
1680
|
+
|
1681
|
+
try:
|
1682
|
+
welcomeString = self.sock.recv(self.maxRxBytes).rstrip()
|
1683
|
+
welcomeString = 'Connected@' + self.host + ':' + str(self.port) + ' ' + '\n ' + welcomeString
|
1684
|
+
printText('New Welcome:' + welcomeString)
|
1685
|
+
except Exception as e:
|
1686
|
+
logging.error('tried and failed to get new welcome')
|
1687
|
+
raise e
|
1688
|
+
|
1689
|
+
readRepeats=readRepeats+1
|
1690
|
+
time.sleep(0.5)
|
1691
|
+
|
1692
|
+
except Exception as e:
|
1693
|
+
#printText('rxBytes - exceptions + 1')
|
1694
|
+
exceptions=exceptions+1
|
1695
|
+
time.sleep(0.5)
|
1696
|
+
raise e
|
1697
|
+
|
1698
|
+
#If read repeats has been exceeded we failed to get any data on this read.
|
1699
|
+
# !!! This is likely to break whatever called us !!!
|
1700
|
+
if readRepeats >= maxReadRepeats:
|
1701
|
+
logging.error('Max read repeats exceeded - returning.')
|
1702
|
+
return 'No data received from QIS'
|
1703
|
+
#If number of exceptions exceeded then give up by exiting
|
1704
|
+
if exceptions >= maxExceptions:
|
1705
|
+
logging.error('Max exceptions exceeded - exiting') #exceptions are probably 10035 non-blocking socket could not complete immediatley
|
1706
|
+
exit()
|
1707
|
+
|
1708
|
+
|
1811
1709
|
def strToBb(string_in, add_length=True):
|
1812
1710
|
length = len(str(string_in))
|
1813
1711
|
b_array = []
|