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
|
@@ -263,12 +260,11 @@ class QisInterface:
|
|
263
260
|
|
264
261
|
baseSamplePeriodS = int(re.search('^\d*\.?\d*', baseSamplePeriod).group())*(10**baseSampleUnitExponent)
|
265
262
|
|
266
|
-
# TODO: MD Thinks this implements software averaging, is unused and now performed in QIS
|
267
|
-
if streamAverage != None:
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
stripesPerAverage = float(streamAverage) / (float(baseSamplePeriod) * 4e-6)
|
263
|
+
# # TODO: MD Thinks this implements software averaging, is unused and now performed in QIS
|
264
|
+
# if streamAverage != None:
|
265
|
+
# #Matt converting streamAveraging into number
|
266
|
+
# streamAverage = self.convertStreamAverage(streamAverage)
|
267
|
+
# stripesPerAverage = float(streamAverage) / (float(baseSamplePeriodS) * 4e-6)
|
272
268
|
isRun = True
|
273
269
|
while isRun:
|
274
270
|
try:
|
@@ -279,7 +275,7 @@ class QisInterface:
|
|
279
275
|
while self.stopFlagList[i] and (not streamOverrun) and (not streamComplete):
|
280
276
|
#now = time.time()
|
281
277
|
streamOverrun, removeChar, newStripes = self.streamGetStripesText(self.streamSock, module, numStripesPerRead)
|
282
|
-
newStripes = newStripes.replace(
|
278
|
+
newStripes = newStripes.replace(' ', separator)
|
283
279
|
#print (time.time() - now)
|
284
280
|
if streamOverrun:
|
285
281
|
self.deviceDict[module][0:3] = [True, 'Stopped', 'Device buffer overrun']
|
@@ -309,22 +305,26 @@ class QisInterface:
|
|
309
305
|
if streamDuration != None:
|
310
306
|
# Get the last data line in the file
|
311
307
|
lastLine = newStripes.splitlines()[-3] # the last data line is followed by 'eof' and '>'
|
312
|
-
lastTime = lastLine.
|
308
|
+
lastTime = lastLine.split(separator)[0] # get the first (time) entry
|
313
309
|
|
314
310
|
# if the last entry is still within the required stream length, write the whole lot
|
315
311
|
if int(lastTime) < int(streamDuration/(10**baseSampleUnitExponent)): # < rather than <= because we start at 0
|
316
312
|
f.write(newStripes[:removeChar])
|
313
|
+
inMemoryData.write(newStripes[:removeChar])
|
314
|
+
|
317
315
|
# else write each line individually until we have reached the desired endpoint
|
318
316
|
else:
|
319
317
|
for thisLine in newStripes.splitlines()[:-2]:
|
320
|
-
lastTime = thisLine.
|
318
|
+
lastTime = thisLine.split(separator)[0]
|
321
319
|
if int(lastTime) < int(streamDuration/(10**baseSampleUnitExponent)):
|
322
320
|
f.write(thisLine + b'\r' + b'\n') # Put the CR back on the end
|
321
|
+
inMemoryData.write(thisLine + b'\r' + b'\n')
|
323
322
|
else:
|
324
323
|
streamComplete = True
|
325
324
|
break
|
326
325
|
else:
|
327
326
|
f.write(newStripes[:removeChar])
|
327
|
+
inMemoryData.write(newStripes[:removeChar])
|
328
328
|
|
329
329
|
else:
|
330
330
|
maxFileExceeded = True
|
@@ -332,6 +332,8 @@ class QisInterface:
|
|
332
332
|
maxFileStatus = self.streamBufferStatus(device=module, sock=self.streamSock)
|
333
333
|
f.write('Warning: Max file size exceeded before end of stream.\n')
|
334
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 + '.')
|
335
337
|
self.deviceDict[module][0:3] = [True, 'Stopped', 'User defined max filesize reached']
|
336
338
|
break
|
337
339
|
else:
|
@@ -379,8 +381,9 @@ class QisInterface:
|
|
379
381
|
if(streamAverage != None):
|
380
382
|
leftover, remainingStripes = self.averageStripes(leftover, stripesPerAverage, newStripes[:removeChar], f, remainingStripes)
|
381
383
|
else:
|
382
|
-
newStripes = newStripes.replace(
|
384
|
+
newStripes = newStripes.replace(' ',separator)
|
383
385
|
f.write(newStripes[:removeChar])
|
386
|
+
inMemoryData.write(newStripes[:removeChar])
|
384
387
|
else:
|
385
388
|
if not maxFileExceeded:
|
386
389
|
maxFileStatus = self.streamBufferStatus(device=module, sock=self.streamSock)
|
@@ -395,6 +398,8 @@ class QisInterface:
|
|
395
398
|
if maxFileExceeded:
|
396
399
|
f.write(b'Warning: Max file size exceeded before end of stream.\n')
|
397
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 + '.')
|
398
403
|
logging.warning('Max file size exceeded. Some data has not been saved to file: ' + maxFileStatus + '.')
|
399
404
|
|
400
405
|
#printText('Stripes in buffer now: ' + self.streamBufferStatus(device=module, sock=self.streamSock))
|
@@ -466,11 +471,10 @@ class QisInterface:
|
|
466
471
|
leftover = 0
|
467
472
|
remainingStripes = []
|
468
473
|
streamOverrun = False
|
469
|
-
if streamAverage != None:
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
stripesPerAverage = float(streamAverage) / (float(baseSamplePeriod) * 4e-6)
|
474
|
+
# if streamAverage != None:
|
475
|
+
# # Matt converting streamAveraging into number
|
476
|
+
# streamAverage = self.convertStreamAverage(streamAverage)
|
477
|
+
# stripesPerAverage = float(streamAverage) / (float(baseSamplePeriodS) * 4e-6)
|
474
478
|
|
475
479
|
isRun = True
|
476
480
|
|
@@ -486,7 +490,7 @@ class QisInterface:
|
|
486
490
|
# now = time.time()
|
487
491
|
streamOverrun, removeChar, newStripes = self.streamGetStripesText(self.streamSock, module,
|
488
492
|
numStripesPerRead)
|
489
|
-
newStripes = newStripes.replace(
|
493
|
+
newStripes = newStripes.replace(' ',separator)
|
490
494
|
# print(newStripes)
|
491
495
|
# print(len(newStripes))
|
492
496
|
|
@@ -500,11 +504,7 @@ class QisInterface:
|
|
500
504
|
if isEmpty == False:
|
501
505
|
# Writes in file if not too big else stops streaming
|
502
506
|
# print(newStripes)
|
503
|
-
|
504
|
-
x = newStripes[:removeChar]
|
505
|
-
y = x.decode("utf-8")
|
506
|
-
|
507
|
-
print(f"decoded stripe : {y}")
|
507
|
+
print("decoded stripe : " + newStripes[:removeChar])
|
508
508
|
|
509
509
|
# Writing multiple stripes
|
510
510
|
if "\r\n" in y:
|
@@ -582,7 +582,7 @@ class QisInterface:
|
|
582
582
|
if index == 0:
|
583
583
|
continue
|
584
584
|
with open(os.path.join(self.qps_record_dir_path, "data000",
|
585
|
-
|
585
|
+
"data000_00" + index - 1 + "_000000000"),
|
586
586
|
"ab") as file1:
|
587
587
|
|
588
588
|
x = struct.pack(">d", int(item))
|
@@ -605,7 +605,7 @@ class QisInterface:
|
|
605
605
|
if group.group_id == 0:
|
606
606
|
|
607
607
|
with open(os.path.join(self.qps_record_dir_path, "data000",
|
608
|
-
|
608
|
+
"data000_"+x+"_000000000"),
|
609
609
|
"ab") as file1:
|
610
610
|
x = struct.pack(">d", int(stripe[counter]))
|
611
611
|
# logging.debug(item, x)
|
@@ -613,196 +613,11 @@ class QisInterface:
|
|
613
613
|
else:
|
614
614
|
# Write all in group 1 to digital
|
615
615
|
with open(os.path.join(self.qps_record_dir_path, "data101",
|
616
|
-
|
616
|
+
"data101_"+x+"_000000000"),
|
617
617
|
"ab") as file1:
|
618
618
|
x = struct.pack(">d", int(stripe[counter]))
|
619
619
|
# logging.debug(item, x)
|
620
620
|
file1.write(x)
|
621
|
-
|
622
|
-
|
623
|
-
# Send text and get the backends response. - acts as wrapper to the sendAndReceiveText, intended to provide some extra convenience
|
624
|
-
# when sending commands to module (as opposed to back end)
|
625
|
-
# 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
|
626
|
-
# After command is sent wait for betweenCommandDelay which defaults to 0 but can be specified to add a delay between commands
|
627
|
-
# The objects connection needs to be opened (connect()) before this is used
|
628
|
-
def sendCmd(self, device='', cmd='$help', sock=None, readUntilCursor=True, betweenCommandDelay=0.0, expectedResponse = True):
|
629
|
-
if sock==None:
|
630
|
-
sock = self.sock
|
631
|
-
if not (device == ''):
|
632
|
-
self.deviceDictSetup(device)
|
633
|
-
|
634
|
-
if expectedResponse is False:
|
635
|
-
self.sendText(sock, cmd, device)
|
636
|
-
return
|
637
|
-
|
638
|
-
res = self.sendAndReceiveText(sock, cmd, device, readUntilCursor)
|
639
|
-
if (betweenCommandDelay > 0):
|
640
|
-
time.sleep(betweenCommandDelay)
|
641
|
-
#If ends with cursor get rid of it
|
642
|
-
if res[-1:] == self.cursor:
|
643
|
-
res = res[:-3] #remove last three chars - hopefully '\r\n>'
|
644
|
-
# time.sleep(0.1)
|
645
|
-
return res.decode()
|
646
|
-
|
647
|
-
|
648
|
-
def sendAndReceiveCmd(self, sock=None, cmd='$help', device='', readUntilCursor=True, betweenCommandDelay=0.0):
|
649
|
-
if sock==None:
|
650
|
-
sock = self.sock
|
651
|
-
if not (device == ''):
|
652
|
-
self.deviceDictSetup(device)
|
653
|
-
if self.pythonVersion == '3':
|
654
|
-
res = self.sendAndReceiveText(sock, cmd, device, readUntilCursor).decode()
|
655
|
-
else:
|
656
|
-
res = self.sendAndReceiveText(sock, cmd, device, readUntilCursor)
|
657
|
-
if (betweenCommandDelay > 0):
|
658
|
-
time.sleep(betweenCommandDelay)
|
659
|
-
#If ends with cursor get rid of it
|
660
|
-
if res[-1:] == '>':
|
661
|
-
res = res[:-3] #remove last three chars - hopefully '\r\n>'
|
662
|
-
return cmd + ' : ' + res
|
663
|
-
|
664
|
-
# Send text to the back end then read it's response
|
665
|
-
# The objects connection needs to be opened (connect()) before this is used
|
666
|
-
# 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
|
667
|
-
def sendAndReceiveText(self, sock, sentText='$help', device='', readUntilCursor=True):
|
668
|
-
self.sockSemaphore.acquire()
|
669
|
-
try:
|
670
|
-
self.sendText(sock, sentText, device)
|
671
|
-
if self.pythonVersion == '3':
|
672
|
-
res = bytearray()
|
673
|
-
res.extend(self.rxBytes(sock))
|
674
|
-
#Somtimes we just get one cursor back of currently unknown origins
|
675
|
-
#If that happens discard it and read again
|
676
|
-
if len(res)==0:
|
677
|
-
logging.warning("empty response from QIS. Retrying.")
|
678
|
-
streamResp=self.sendAndReceiveText(sock, "stream?",device,readUntilCursor).lower()
|
679
|
-
if len(streamResp)==0:
|
680
|
-
raise("Empty response from QIS twice in a row")
|
681
|
-
else:
|
682
|
-
logging.warning("Response recovered Successfully. Continuing.")
|
683
|
-
res = bytearray()
|
684
|
-
res.extend(self.rxBytes(sock))
|
685
|
-
if len(res) == 0:
|
686
|
-
raise ("empty response from QIS after second ")
|
687
|
-
if res[0] == self.cursor:
|
688
|
-
#res[0] = self.rxBytes(sock)
|
689
|
-
logging.warning('Only Returned Cursor!!!!!')
|
690
|
-
#If create socked fail (between backend and tcp/ip module)
|
691
|
-
cba = 'Create Socket Fail'
|
692
|
-
if cba.encode() == res[0]:
|
693
|
-
logging.warning(res[0].decode())
|
694
|
-
cba = 'Connection Timeout'
|
695
|
-
if cba.encode() == res[0]:
|
696
|
-
logging.warning(res[0].decode())
|
697
|
-
#If reading until a cursor comes back then keep reading until a cursor appears or max tries exceeded
|
698
|
-
if readUntilCursor:
|
699
|
-
maxReads = 1000
|
700
|
-
count = 1
|
701
|
-
#check for cursor at end of read and if not there read again
|
702
|
-
while res[-1:] != self.cursor:
|
703
|
-
res.extend(self.rxBytes(sock))
|
704
|
-
count += 1
|
705
|
-
if count >= maxReads:
|
706
|
-
raise Exception(' Count = Error: max reads exceeded before cursor returned')
|
707
|
-
return res
|
708
|
-
else:
|
709
|
-
res = self.rxBytes(sock)
|
710
|
-
#Somtimes we just get one cursor back of currently unknown origins
|
711
|
-
#If that happens discard it and read again
|
712
|
-
if res == self.cursor:
|
713
|
-
#printText(" CURSOR ONLY")
|
714
|
-
res = self.rxBytes(sock)
|
715
|
-
#If create socked fail (between backend and tcp/ip module)
|
716
|
-
if 'Create Socket Fail' in res:
|
717
|
-
raise Exception(res)
|
718
|
-
if 'Connection Timeout' in res:
|
719
|
-
raise Exception(res)
|
720
|
-
#If reading until a cursor comes back then keep reading until a cursor appears or max tries exceeded
|
721
|
-
if readUntilCursor:
|
722
|
-
maxReads = 1000
|
723
|
-
count = 1
|
724
|
-
#check for cursor at end of read and if not there read again
|
725
|
-
while res[-1:] != self.cursor:
|
726
|
-
res += self.rxBytes(sock)
|
727
|
-
count += 1
|
728
|
-
if count >= maxReads:
|
729
|
-
raise Exception(' Count = Error: max reads exceeded before cursor returned')
|
730
|
-
return res
|
731
|
-
|
732
|
-
except Exception as e:
|
733
|
-
raise e
|
734
|
-
finally:
|
735
|
-
self.sockSemaphore.release()
|
736
|
-
|
737
|
-
def rxBytes(self,sock):
|
738
|
-
#sock.setblocking(0) #make socket non-blocking
|
739
|
-
#printText('rxBytes')
|
740
|
-
maxExceptions=10
|
741
|
-
exceptions=0
|
742
|
-
maxReadRepeats=50
|
743
|
-
readRepeats=0
|
744
|
-
timeout_in_seconds = 10
|
745
|
-
#Keep trying to read bytes until we get some, unless number of read repeads or exceptions is exceeded
|
746
|
-
while True:
|
747
|
-
try:
|
748
|
-
#select.select returns a list of waitable objects which are ready. On windows it has to be sockets.
|
749
|
-
#The first arguement is a list of objects to wait for reading, second writing, third 'exceptional condition'
|
750
|
-
#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.
|
751
|
-
ready = select.select([sock], [], [], timeout_in_seconds)
|
752
|
-
#time.sleep(0.1)
|
753
|
-
#ready = [1,2]
|
754
|
-
if ready[0]:
|
755
|
-
ret = sock.recv(self.maxRxBytes)
|
756
|
-
#time.sleep(0.1)
|
757
|
-
return ret
|
758
|
-
else:
|
759
|
-
#printText('rxBytes - readRepeats + 1')
|
760
|
-
|
761
|
-
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
762
|
-
sock.connect((self.host, self.port))
|
763
|
-
sock.settimeout(5)
|
764
|
-
|
765
|
-
try:
|
766
|
-
welcomeString = self.sock.recv(self.maxRxBytes).rstrip()
|
767
|
-
welcomeString = 'Connected@' + self.host + ':' + str(self.port) + ' ' + '\n ' + welcomeString
|
768
|
-
printText('New Welcome:' + welcomeString)
|
769
|
-
except Exception as e:
|
770
|
-
logging.error('tried and failed to get new welcome')
|
771
|
-
raise e
|
772
|
-
|
773
|
-
readRepeats=readRepeats+1
|
774
|
-
time.sleep(0.5)
|
775
|
-
|
776
|
-
except Exception as e:
|
777
|
-
#printText('rxBytes - exceptions + 1')
|
778
|
-
exceptions=exceptions+1
|
779
|
-
time.sleep(0.5)
|
780
|
-
raise e
|
781
|
-
|
782
|
-
#If read repeats has been exceeded we failed to get any data on this read.
|
783
|
-
# !!! This is likely to break whatever called us !!!
|
784
|
-
if readRepeats >= maxReadRepeats:
|
785
|
-
logging.error('Max read repeats exceeded - returning.')
|
786
|
-
return 'No data received from QIS'
|
787
|
-
#If number of exceptions exceeded then give up by exiting
|
788
|
-
if exceptions >= maxExceptions:
|
789
|
-
logging.error('Max exceptions exceeded - exiting') #exceptions are probably 10035 non-blocking socket could not complete immediatley
|
790
|
-
exit()
|
791
|
-
|
792
|
-
# Send text to the back end don't read it's response
|
793
|
-
# The objects connection needs to be opened (connect()) before this is used
|
794
|
-
def sendText(self, sock, message='$help', device=''):
|
795
|
-
if device != '':
|
796
|
-
specialTimeout = '%500000'
|
797
|
-
message = device + specialTimeout + ' ' + message
|
798
|
-
#printText('Sending: "' + message + '" ' + self.host + ':' + str(self.port))
|
799
|
-
|
800
|
-
if self.pythonVersion == 2:
|
801
|
-
sock.sendall(message + '\r\n')
|
802
|
-
else:
|
803
|
-
convM = message + '\r\n'
|
804
|
-
sock.sendall(convM.encode('utf-8'))
|
805
|
-
return 'Sent:' + message
|
806
621
|
|
807
622
|
# Query the backend for a list of connected modules. A $scan command is sent to refresh the list of devices,
|
808
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
|
@@ -811,21 +626,9 @@ class QisInterface:
|
|
811
626
|
|
812
627
|
if sock == None:
|
813
628
|
sock = self.sock
|
814
|
-
|
815
|
-
#printText('Scanning for devices and waiting ' + str(scanWait) + ' seconds.')
|
816
|
-
if self.pythonVersion == '3':
|
817
|
-
#devString = self.sendAndReceiveText(sock, '$scan').decode
|
818
|
-
#time.sleep(scanWait)
|
819
|
-
devString = self.sendAndReceiveText(sock, '$list').decode()
|
820
|
-
else:
|
821
|
-
#devString = self.sendAndReceiveText(sock, '$scan')
|
822
|
-
#time.sleep(scanWait)
|
823
|
-
devString = self.sendAndReceiveText(sock, '$list')
|
824
|
-
|
629
|
+
devString = self.sendAndReceiveText(sock, '$list')
|
825
630
|
devString = devString.replace('>', '')
|
826
|
-
devString = devString.replace(r'\d+\) ', '')
|
827
|
-
|
828
|
-
#printText('"' + devString + '"')
|
631
|
+
devString = devString.replace(r'\d+\) ', '')
|
829
632
|
devString = devString.split('\r\n')
|
830
633
|
devString = filter(None, devString) #remove empty elements
|
831
634
|
return devString
|
@@ -833,21 +636,10 @@ class QisInterface:
|
|
833
636
|
def get_list_details(self, sock=None):
|
834
637
|
if sock == None:
|
835
638
|
sock = self.sock
|
836
|
-
scanWait = 2
|
837
|
-
# printText('Scanning for devices and waiting ' + str(scanWait) + ' seconds.')
|
838
|
-
if self.pythonVersion == '3':
|
839
|
-
# devString = self.sendAndReceiveText(sock, '$scan').decode
|
840
|
-
# time.sleep(scanWait)
|
841
|
-
devString = self.sendAndReceiveText(sock, '$list details').decode()
|
842
|
-
else:
|
843
|
-
# devString = self.sendAndReceiveText(sock, '$scan')
|
844
|
-
# time.sleep(scanWait)
|
845
|
-
devString = self.sendAndReceiveText(sock, '$list details')
|
846
639
|
|
640
|
+
devString = self.sendAndReceiveText(sock, '$list details')
|
847
641
|
devString = devString.replace('>', '')
|
848
642
|
devString = devString.replace(r'\d+\) ', '')
|
849
|
-
|
850
|
-
# printText('"' + devString + '"')
|
851
643
|
devString = devString.split('\r\n')
|
852
644
|
devString = [x for x in devString if x] # remove empty elements
|
853
645
|
return devString
|
@@ -886,9 +678,6 @@ class QisInterface:
|
|
886
678
|
logging.warning(e)
|
887
679
|
logging.warning("No module found at " + ipAddress)
|
888
680
|
|
889
|
-
|
890
|
-
|
891
|
-
|
892
681
|
def GetQisModuleSelection(self, favouriteOnly=True , additionalOptions=['rescan', 'all con types', 'ip scan'], scan=True):
|
893
682
|
tableHeaders =["Modules"]
|
894
683
|
ip_address = None
|
@@ -924,33 +713,19 @@ class QisInterface:
|
|
924
713
|
foundDevices = "1"
|
925
714
|
foundDevices2 = "2" # this is used to check if new modules are being discovered or if all have been found.
|
926
715
|
scanWait = 2 # The number of seconds waited between the two scans.
|
927
|
-
if self.pythonVersion == '3':
|
928
|
-
if scan:
|
929
|
-
if ipAddress == None:
|
930
|
-
devString = self.sendAndReceiveText(self.sock, '$scan').decode
|
931
|
-
else:
|
932
|
-
devString = self.sendAndReceiveText(self.sock, '$scan TCP::' + ipAddress).decode
|
933
|
-
time.sleep(scanWait)
|
934
|
-
while foundDevices not in foundDevices2:
|
935
|
-
foundDevices = self.sendAndReceiveText(self.sock, '$list').decode()
|
936
|
-
time.sleep(scanWait)
|
937
|
-
foundDevices2 = self.sendAndReceiveText(self.sock, '$list').decode()
|
938
|
-
else:
|
939
|
-
foundDevices = self.sendAndReceiveText(self.sock, '$list').decode()
|
940
716
|
|
941
|
-
|
942
|
-
if
|
943
|
-
|
944
|
-
devString = self.sendAndReceiveText(self.sock, '$scan').decode
|
945
|
-
else:
|
946
|
-
devString = self.sendAndReceiveText(self.sock, '$scan TCP::' + ipAddress).decode
|
947
|
-
time.sleep(scanWait)
|
948
|
-
while foundDevices not in foundDevices2:
|
949
|
-
foundDevices = self.sendAndReceiveText(self.sock, '$list')
|
950
|
-
time.sleep(scanWait)
|
951
|
-
foundDevices2 = self.sendAndReceiveText(self.sock, '$list')
|
717
|
+
if scan:
|
718
|
+
if ipAddress == None:
|
719
|
+
devString = self.sendAndReceiveText(self.sock, '$scan')
|
952
720
|
else:
|
721
|
+
devString = self.sendAndReceiveText(self.sock, '$scan TCP::' + ipAddress)
|
722
|
+
time.sleep(scanWait)
|
723
|
+
while foundDevices not in foundDevices2:
|
953
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')
|
954
729
|
|
955
730
|
if not "no devices found" in foundDevices.lower():
|
956
731
|
foundDevices = foundDevices.replace('>', '')
|
@@ -1000,10 +775,7 @@ class QisInterface:
|
|
1000
775
|
if sock == None:
|
1001
776
|
sock = self.sock
|
1002
777
|
index = 0 # index of relevant line in split string
|
1003
|
-
|
1004
|
-
streamStatus = self.sendAndReceiveText(sock, 'stream?', device).decode()
|
1005
|
-
else:
|
1006
|
-
streamStatus = self.sendAndReceiveText(sock, 'stream?', device)
|
778
|
+
streamStatus = self.sendAndReceiveText(sock, 'stream?', device)
|
1007
779
|
streamStatus = streamStatus.split('\r\n')
|
1008
780
|
streamStatus[index] = re.sub(r':', '', streamStatus[index]) #remove :
|
1009
781
|
return streamStatus[index]
|
@@ -1014,10 +786,7 @@ class QisInterface:
|
|
1014
786
|
if sock == None:
|
1015
787
|
sock = self.sock
|
1016
788
|
index = 1 # index of relevant line in split string
|
1017
|
-
|
1018
|
-
streamStatus = self.sendAndReceiveText(sock, 'stream?', device).decode()
|
1019
|
-
else:
|
1020
|
-
streamStatus = self.sendAndReceiveText(sock, 'stream?', device)
|
789
|
+
streamStatus = self.sendAndReceiveText(sock, 'stream?', device)
|
1021
790
|
streamStatus = streamStatus.split('\r\n')
|
1022
791
|
streamStatus[index] = re.sub(r'^Stripes Buffered: ', '', streamStatus[index])
|
1023
792
|
return streamStatus[index]
|
@@ -1032,10 +801,7 @@ class QisInterface:
|
|
1032
801
|
if sock == None:
|
1033
802
|
sock = self.sock
|
1034
803
|
index = 2 # index of relevant line in split string
|
1035
|
-
|
1036
|
-
streamStatus = self.sendAndReceiveText(sock, sentText='stream text header', device=device).decode()
|
1037
|
-
else:
|
1038
|
-
streamStatus = self.sendAndReceiveText(sock, sentText='stream text header', device=device)
|
804
|
+
streamStatus = self.sendAndReceiveText(sock, sentText='stream text header', device=device)
|
1039
805
|
|
1040
806
|
self.qps_stream_header = streamStatus
|
1041
807
|
|
@@ -1076,10 +842,7 @@ class QisInterface:
|
|
1076
842
|
if sock == None:
|
1077
843
|
sock = self.sock
|
1078
844
|
index = 0 # index of relevant line in split string
|
1079
|
-
|
1080
|
-
streamStatus = self.sendAndReceiveText(sock,'stream text header', device).decode()
|
1081
|
-
else:
|
1082
|
-
streamStatus = self.sendAndReceiveText(sock,'stream text header', device)
|
845
|
+
streamStatus = self.sendAndReceiveText(sock,'stream text header', device)
|
1083
846
|
streamStatus = streamStatus.split('\r\n')
|
1084
847
|
if 'Header Not Available' in streamStatus[0]:
|
1085
848
|
str = streamStatus[0] + '. Check stream has been ran on device.'
|
@@ -1106,10 +869,7 @@ class QisInterface:
|
|
1106
869
|
if sock == None:
|
1107
870
|
sock = self.sock
|
1108
871
|
index = 1 # index of relevant line in split string STREAM MODE HEADER [?|V1,V2,V3]
|
1109
|
-
|
1110
|
-
streamStatus = self.sendAndReceiveText(sock,'stream text header', device).decode()
|
1111
|
-
else:
|
1112
|
-
streamStatus = self.sendAndReceiveText(sock,'stream text header', device)
|
872
|
+
streamStatus = self.sendAndReceiveText(sock,'stream text header', device)
|
1113
873
|
# Check if this is a new XML form header
|
1114
874
|
if (self.isXmlHeader (streamStatus)):
|
1115
875
|
# Get the basic averaging rate (V3 header)
|
@@ -1144,12 +904,8 @@ class QisInterface:
|
|
1144
904
|
str = streamStatus[0] + '. Check stream has been ran on device.'
|
1145
905
|
logging.error(str)
|
1146
906
|
return str
|
1147
|
-
|
1148
|
-
|
1149
|
-
powerMode = self.sendAndReceiveText(sock,'stream mode power?', device).decode()
|
1150
|
-
else:
|
1151
|
-
outputMode = self.sendAndReceiveText(sock,'Config Output Mode?', device)
|
1152
|
-
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)
|
1153
909
|
format = int(re.sub(r'^Format: ', '', streamStatus[index]))
|
1154
910
|
b0 = 1 #12V_I
|
1155
911
|
b1 = 1 << 1 #12V_V
|
@@ -1190,10 +946,7 @@ class QisInterface:
|
|
1190
946
|
bufferStatus = False
|
1191
947
|
# Allows the status check to be skipped when emptying the buffer after streaming has stopped (saving time)
|
1192
948
|
if (skipStatusCheck == False):
|
1193
|
-
|
1194
|
-
streamStatus = self.sendAndReceiveText(sock, 'stream?', device).decode()
|
1195
|
-
else:
|
1196
|
-
streamStatus = self.sendAndReceiveText(sock, 'stream?', device)
|
949
|
+
streamStatus = self.sendAndReceiveText(sock, 'stream?', device)
|
1197
950
|
if ('Overrun' in streamStatus) or ('8388608 of 8388608' in streamStatus):
|
1198
951
|
bufferStatus = True
|
1199
952
|
stripes = self.sendAndReceiveText(sock, 'stream text all', device, readUntilCursor=True)
|
@@ -1201,11 +954,7 @@ class QisInterface:
|
|
1201
954
|
if stripes[-1:] != self.cursor:
|
1202
955
|
return "Error no cursor returned."
|
1203
956
|
else:
|
1204
|
-
|
1205
|
-
endOfFile = 'eof\r\n>'
|
1206
|
-
genEndOfFile = endOfFile.encode()
|
1207
|
-
else:
|
1208
|
-
genEndOfFile = 'eof\r\n>'
|
957
|
+
genEndOfFile = 'eof\r\n>'
|
1209
958
|
if stripes[-6:] == genEndOfFile:
|
1210
959
|
removeChar = -6
|
1211
960
|
else:
|
@@ -1266,8 +1015,6 @@ class QisInterface:
|
|
1266
1015
|
finalAverage = splitList[0:2] + [str(round(x / streamAverage)) for x in runningAverage]
|
1267
1016
|
for counter in xrange(len(finalAverage)-1):
|
1268
1017
|
finalAverage[counter] = finalAverage[counter] + ' '
|
1269
|
-
if self.pythonVersion == '3':
|
1270
|
-
finalAverage = finalAverage.encode
|
1271
1018
|
for x in finalAverage:
|
1272
1019
|
f.write(x)
|
1273
1020
|
f.write('\r\n')
|
@@ -1352,10 +1099,7 @@ class QisInterface:
|
|
1352
1099
|
sock = self.sock
|
1353
1100
|
|
1354
1101
|
# Get the raw data
|
1355
|
-
|
1356
|
-
headerData = self.sendAndReceiveText(sock, sentText='stream text header', device=device).decode()
|
1357
|
-
else:
|
1358
|
-
headerData = self.sendAndReceiveText(sock, sentText='stream text header', device=device)
|
1102
|
+
headerData = self.sendAndReceiveText(sock, sentText='stream text header', device=device)
|
1359
1103
|
|
1360
1104
|
# The XML can contain the cursor on the end! Trap and remove it here TODO: Needs fixed in the command layer above
|
1361
1105
|
if ('\r\n>' in headerData):
|
@@ -1420,7 +1164,7 @@ class QisInterface:
|
|
1420
1164
|
inner_path_analogues = os.path.join(directory, in_folder_analogue)
|
1421
1165
|
os.mkdir(inner_path_analogues)
|
1422
1166
|
except:
|
1423
|
-
logging.warning(
|
1167
|
+
logging.warning("Failed to make inner directory for analogue signals " + inner_path_analogues)
|
1424
1168
|
return False
|
1425
1169
|
|
1426
1170
|
in_folder_digitals = "data101"
|
@@ -1429,26 +1173,26 @@ class QisInterface:
|
|
1429
1173
|
inner_path_digitals = os.path.join(directory, in_folder_digitals)
|
1430
1174
|
os.mkdir(inner_path_digitals)
|
1431
1175
|
except:
|
1432
|
-
logging.warning(
|
1176
|
+
logging.warning("Failed to make inner directory for digital signals "+ inner_path_digitals)
|
1433
1177
|
return False
|
1434
1178
|
|
1435
|
-
logging.debug(
|
1179
|
+
logging.debug("Steaming to : " + self.qps_record_dir_path)
|
1436
1180
|
|
1437
1181
|
logging.debug("Creating qps data files")
|
1438
1182
|
try:
|
1439
1183
|
for i in range(non_dig_counter):
|
1440
|
-
file_name =
|
1184
|
+
file_name = "data000_00"+i+"_000000000"
|
1441
1185
|
f = open(os.path.join(inner_path_analogues, file_name), "w")
|
1442
1186
|
f.close()
|
1443
1187
|
for i in range(digital_count):
|
1444
1188
|
x = i
|
1445
1189
|
while len(str(x)) < 3:
|
1446
1190
|
x = "0" + str(x)
|
1447
|
-
file_name =
|
1191
|
+
file_name = "data101_"+x+"_000000000"
|
1448
1192
|
f = open(os.path.join(inner_path_digitals, file_name), "w")
|
1449
1193
|
f.close()
|
1450
1194
|
except:
|
1451
|
-
logging.warning(
|
1195
|
+
logging.warning("failed to create qps data files for analogue signals")
|
1452
1196
|
return False
|
1453
1197
|
|
1454
1198
|
logging.debug("Finished creating qps data files")
|
@@ -1460,7 +1204,7 @@ class QisInterface:
|
|
1460
1204
|
f = open(os.path.join(self.qps_record_dir_path, file_nome), "w")
|
1461
1205
|
f.close()
|
1462
1206
|
except Exception as err:
|
1463
|
-
logging.warning(
|
1207
|
+
logging.warning("failed to create qps upper level files, "+err)
|
1464
1208
|
return False
|
1465
1209
|
|
1466
1210
|
try:
|
@@ -1471,7 +1215,7 @@ class QisInterface:
|
|
1471
1215
|
f = open(os.path.join(self.qps_record_dir_path, "data101.idx"), "wb")
|
1472
1216
|
f.close()
|
1473
1217
|
except Exception as err:
|
1474
|
-
logging.warning(
|
1218
|
+
logging.warning("failed to create data000.idx file, "+err)
|
1475
1219
|
return False
|
1476
1220
|
|
1477
1221
|
logging.debug("Finished creating QPS dir structure")
|
@@ -1482,11 +1226,11 @@ class QisInterface:
|
|
1482
1226
|
folder_name = None
|
1483
1227
|
# Checking if there was a directory passed; and if it's a valid directory
|
1484
1228
|
if not directory:
|
1485
|
-
directory = os.path.join(
|
1229
|
+
directory = os.path.join(os.path.expanduser("~"), "AppData", "Local", "Quarch", "QPS", "Recordings")
|
1486
1230
|
logging.debug("No directory specified")
|
1487
1231
|
elif not os.path.isdir(directory):
|
1488
|
-
new_dir = os.path.join(str(
|
1489
|
-
logging.warning(
|
1232
|
+
new_dir = os.path.join(str(os.path.expanduser("~"), "AppData", "Local", "Quarch", "QPS", "Recordings"))
|
1233
|
+
logging.warning(directory+" was not a valid directory, streaming to default location: \n"+new_dir)
|
1490
1234
|
directory = new_dir
|
1491
1235
|
else:
|
1492
1236
|
# Split the directory into a path of folders
|
@@ -1499,7 +1243,7 @@ class QisInterface:
|
|
1499
1243
|
# If no folder name for the stream was passed, then default to 'quarchpy_recording' and a timestamp
|
1500
1244
|
if not folder_name:
|
1501
1245
|
folder_name = "quarchpy_recording"
|
1502
|
-
folder_name =
|
1246
|
+
folder_name = folder_name + "-" + time.time()
|
1503
1247
|
path = os.path.join(directory, self.qps_stream_folder_name)
|
1504
1248
|
os.mkdir(path)
|
1505
1249
|
self.qps_record_dir_path = path
|
@@ -1547,15 +1291,15 @@ class QisInterface:
|
|
1547
1291
|
raise "No data written to file"
|
1548
1292
|
|
1549
1293
|
num_records = len(data) / 8
|
1550
|
-
logging.debug(
|
1294
|
+
logging.debug("num_record = " + num_records)
|
1551
1295
|
return_b_array.append(int(num_records).to_bytes(4, byteorder='big'))
|
1552
1296
|
|
1553
1297
|
start_number = 0
|
1554
|
-
logging.debug(
|
1298
|
+
logging.debug("start_record = " + start_number)
|
1555
1299
|
return_b_array.append(start_number.to_bytes(8, byteorder='big'))
|
1556
1300
|
|
1557
1301
|
num_records = num_records - 1
|
1558
|
-
logging.debug(
|
1302
|
+
logging.debug("last_Record_number = "+num_records)
|
1559
1303
|
return_b_array.append(int(num_records).to_bytes(8, byteorder='big'))
|
1560
1304
|
|
1561
1305
|
# Add names of every file in data000 dir here.
|
@@ -1611,15 +1355,15 @@ class QisInterface:
|
|
1611
1355
|
raise "No data written to file"
|
1612
1356
|
|
1613
1357
|
num_records = len(data) / 8
|
1614
|
-
logging.debug(
|
1358
|
+
logging.debug("num_record = "+ num_records)
|
1615
1359
|
return_b_array.append(int(num_records).to_bytes(4, byteorder='big'))
|
1616
1360
|
|
1617
1361
|
start_number = 0
|
1618
|
-
logging.debug(
|
1362
|
+
logging.debug("start_record = "+start_number)
|
1619
1363
|
return_b_array.append(start_number.to_bytes(8, byteorder='big'))
|
1620
1364
|
|
1621
1365
|
num_records = num_records - 1
|
1622
|
-
logging.debug(
|
1366
|
+
logging.debug("last_Record_number = "+ num_records)
|
1623
1367
|
return_b_array.append(int(num_records).to_bytes(8, byteorder='big'))
|
1624
1368
|
|
1625
1369
|
# Add names of every file in data000 dir here.
|
@@ -1735,30 +1479,30 @@ class QisInterface:
|
|
1735
1479
|
def add_header_to_buffer(self, outBuffer, return_b_array, stream_header_size, temp_dict):
|
1736
1480
|
number = 2
|
1737
1481
|
outBuffer.append(number.to_bytes(4, byteorder='big'))
|
1738
|
-
logging.debug(
|
1482
|
+
logging.debug("indexVersion : "+ number)
|
1739
1483
|
|
1740
1484
|
number = 1 if self.has_digitals else 0
|
1741
1485
|
outBuffer.append(number.to_bytes(4, byteorder='big'))
|
1742
|
-
logging.debug(
|
1486
|
+
logging.debug("value0 : "+ number)
|
1743
1487
|
number = stream_header_size
|
1744
1488
|
outBuffer.append(number.to_bytes(4, byteorder='big'))
|
1745
|
-
logging.debug(
|
1746
|
-
logging.debug(
|
1489
|
+
logging.debug("header_size : "+number)
|
1490
|
+
logging.debug("legacyVersion : "+ temp_dict['legacyVersion'])
|
1747
1491
|
outBuffer.append(int(temp_dict["legacyVersion"]).to_bytes(4, byteorder='big'))
|
1748
|
-
logging.debug(
|
1492
|
+
logging.debug("legacyAverage : " + temp_dict['legacyAverage'])
|
1749
1493
|
outBuffer.append(int(temp_dict["legacyAverage"]).to_bytes(4, byteorder='big'))
|
1750
|
-
logging.debug(
|
1494
|
+
logging.debug("legacyFormat : "+temp_dict['legacyFormat'])
|
1751
1495
|
outBuffer.append(int(temp_dict["legacyFormat"]).to_bytes(4, byteorder='big'))
|
1752
|
-
logging.debug(
|
1496
|
+
logging.debug("mainPeriod : "+temp_dict['mainPeriod'])
|
1753
1497
|
outBuffer.append(int(temp_dict["mainPeriod"]).to_bytes(4, byteorder='big'))
|
1754
|
-
logging.debug(
|
1498
|
+
logging.debug("channels : "+temp_dict['channels'])
|
1755
1499
|
outBuffer.append(int(temp_dict["channels"]).to_bytes(4, byteorder='big'))
|
1756
1500
|
return_b_array.append(int(self.qps_record_start_time).to_bytes(8, byteorder='big'))
|
1757
1501
|
index_record_state = True
|
1758
1502
|
logging.debug(int(1))
|
1759
1503
|
return_b_array.append(int(1).to_bytes(1, byteorder='big'))
|
1760
1504
|
record_type = 1
|
1761
|
-
logging.debug(
|
1505
|
+
logging.debug("record type : "+int(index_record_state))
|
1762
1506
|
return_b_array.append(int(record_type).to_bytes(1, byteorder='big'))
|
1763
1507
|
|
1764
1508
|
def write_b_array_to_idx_file(self, f, return_b_array):
|
@@ -1799,15 +1543,167 @@ class QisInterface:
|
|
1799
1543
|
x = str(x).split(".")
|
1800
1544
|
x = x[0]
|
1801
1545
|
x = x.replace("-", " ")
|
1802
|
-
f.write(
|
1803
|
-
f.write(
|
1546
|
+
f.write("Started: "+x+"\n")
|
1547
|
+
f.write("Device: " + module + "\n")
|
1804
1548
|
f.write("Fixture: \n")
|
1805
1549
|
|
1806
1550
|
x = datetime.datetime.now()
|
1807
1551
|
x = str(x).split(".")
|
1808
1552
|
x = x[0]
|
1809
1553
|
x = x.replace("-", " ")
|
1810
|
-
f.write(
|
1554
|
+
f.write("Saved: "+x+ "\n")
|
1555
|
+
|
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 #Format for py2/3 and return.
|
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()
|
1811
1707
|
|
1812
1708
|
|
1813
1709
|
def strToBb(string_in, add_length=True):
|