This commit is contained in:
2022-08-11 16:24:40 +02:00
commit f55fbfce38
21 changed files with 6836 additions and 0 deletions

49
config/config.properties Normal file
View File

@@ -0,0 +1,49 @@
#Thu Aug 11 16:23:50 CEST 2022
autoSaveScanData=true
simulation=false
dataScanSaveOutput=false
userAuthenticator=
dataScanSaveScript=false
notifiedTasks=
parallelInitialization=false
fdaSerialization=false
dataTransferPath=
saveConsoleSessionFiles=false
hostName=
disableEmbeddedAttributes=false
serverPort=8080
versionTrackingEnabled=true
dataPath={data}/{year}_{month}/{date}/{date}_{time}_{name}
serverEnabled=false
depthDimension=0
logLevel=Fine
dataLayout=default
disableDataFileLogs=false
sessionHandling=Off
terminalEnabled=false
notificationLevel=Off
terminalPort=3579
dataTransferUser=
versionTrackingLogin=
noBytecodeFiles=false
versionTrackingRemote=
logDaysToLive=-1
logLevelConsole=Off
filePermissionsConfig=Default
scanStreamerPort=-1
dataScanSaveSetpoints=false
versionTrackingManual=false
dataTransferMode=Off
userManagement=false
instanceName=PIDE
dataServerPort=-1
hideServerMessages=false
dataScanReleaseRecords=false
dataScanPreserveTypes=false
dataScanFlushRecords=false
filePermissionsLogs=Default
logPath={logs}/{date}_{time}
filePermissionsScripts=Default
filePermissionsData=Default
dataProvider=h5
saveCommandStatistics=false

View File

9
config/mail.properties Normal file
View File

@@ -0,0 +1,9 @@
#Wed Aug 10 10:57:13 CEST 2022
auth=None
from=
host=
port=0
pwd=
smsSuffix=@sms.switch.ch
to=
usr=

View File

@@ -0,0 +1 @@
ScreenPanel10.java=enabled

123
config/preferences.json Normal file
View File

@@ -0,0 +1,123 @@
{
"fontShellPanel" : {
"name" : "Monospaced",
"style" : 0,
"size" : 13
},
"fontShellCommand" : {
"name" : "SansSerif",
"style" : 0,
"size" : 13
},
"fontOutput" : {
"name" : "Monospaced",
"style" : 0,
"size" : 13
},
"fontEditor" : {
"name" : "Monospaced",
"style" : 0,
"size" : 13
},
"fontPlotLabel" : {
"name" : "SansSerif",
"style" : 0,
"size" : 11
},
"fontPlotTick" : {
"name" : "SansSerif",
"style" : 0,
"size" : 10
},
"fontPlotTitle" : {
"name" : "SansSerif",
"style" : 1,
"size" : 13
},
"fontTerminal" : {
"name" : "Menlo",
"style" : 0,
"size" : 14
},
"tabSize" : 4,
"contentWidth" : 0,
"editorBackground" : null,
"editorForeground" : null,
"simpleEditor" : false,
"hideEditorLineNumbers" : false,
"hideEditorContextMenu" : false,
"consoleLocation" : "Left",
"dataPanelLocation" : "Status",
"openDataFilesInDocTab" : false,
"noVariableEvaluationPropagation" : false,
"processingScripts" : [ ],
"asyncViewersUpdate" : false,
"scanPlotDisabled" : false,
"scanTableDisabled" : false,
"cachedDataPanel" : false,
"dataExtensions" : null,
"dataSubFiles" : null,
"hideFileName" : false,
"showEmergencyStop" : false,
"showHomingButtons" : false,
"showJogButtons" : false,
"hideScanPanel" : false,
"hideOutputPanel" : false,
"showXScanFileBrowser" : false,
"showQueueBrowser" : false,
"backgroundRendering" : false,
"showImageStatusBar" : true,
"persistRendererWindows" : false,
"defaultRendererColormap" : "Grayscale",
"linePlot" : "ch.psi.pshell.plot.LinePlotJFree",
"matrixPlot" : "ch.psi.pshell.plot.MatrixPlotJFree",
"surfacePlot" : null,
"timePlot" : "ch.psi.pshell.plot.TimePlotJFree",
"plotsDetached" : false,
"plotLayout" : "Vertical",
"quality" : "High",
"defaultPlotColormap" : "Temperature",
"markerSize" : 0,
"plotBackground" : null,
"gridColor" : null,
"outlineColor" : null,
"disableOffscreenBuffer" : false,
"defaultPanels" : [ {
"deviceClassName" : "ch.psi.pshell.epics.Scaler",
"panelClassName" : "ch.psi.pshell.swing.ScalerPanel"
}, {
"deviceClassName" : "ch.psi.pshell.epics.Scienta",
"panelClassName" : "ch.psi.pshell.swing.ScientaPanel"
}, {
"deviceClassName" : "ch.psi.pshell.device.Motor",
"panelClassName" : "ch.psi.pshell.swing.MotorPanel"
}, {
"deviceClassName" : "ch.psi.pshell.device.MasterPositioner",
"panelClassName" : "ch.psi.pshell.swing.MasterPositionerPanel"
}, {
"deviceClassName" : "ch.psi.pshell.device.ProcessVariable",
"panelClassName" : "ch.psi.pshell.swing.ProcessVariablePanel"
}, {
"deviceClassName" : "ch.psi.pshell.device.MotorGroup",
"panelClassName" : "ch.psi.pshell.swing.MotorGroupPanel"
}, {
"deviceClassName" : "ch.psi.pshell.device.DiscretePositioner",
"panelClassName" : "ch.psi.pshell.swing.DiscretePositionerPanel"
}, {
"deviceClassName" : "ch.psi.pshell.device.Camera",
"panelClassName" : "ch.psi.pshell.swing.CameraPanel"
}, {
"deviceClassName" : "ch.psi.pshell.device.Slit",
"panelClassName" : "ch.psi.pshell.swing.SlitPanel"
}, {
"deviceClassName" : "ch.psi.pshell.device.HistogramGenerator",
"panelClassName" : "ch.psi.pshell.swing.HistogramGeneratorPanel"
}, {
"deviceClassName" : "ch.psi.pshell.device.ReadonlyRegister$ReadonlyRegisterArray",
"panelClassName" : "ch.psi.pshell.swing.DeviceValueChart"
}, {
"deviceClassName" : "ch.psi.pshell.device.ReadonlyRegister$ReadonlyRegisterMatrix",
"panelClassName" : "ch.psi.pshell.swing.DeviceValueChart"
} ],
"scriptPopupDialog" : "None"
}

25
config/setup.properties Normal file
View File

@@ -0,0 +1,25 @@
#Wed Aug 10 10:57:13 CEST 2022
configFile={config}/config.properties
configFileDevices={config}/devices.properties
configFilePlugins={config}/plugins.properties
configFileSessions={config}/sessions.properties
configFileSettings={config}/settings.properties
configFileTasks={config}/tasks.properties
configFileVariables={config}/variables.properties
configPath={home}/config
consoleSessionsPath={sessions}/console
contextPath={outp}/context
dataPath={outp}/data
devicesPath={home}/devices
extensionsPath={home}/extensions
imagesPath={outp}/images
libraryPath={script}; {script}/Lib
logPath={outp}/log
pluginsPath={home}/plugins
queuePath={script}
scriptPath={home}/script
scriptType=cpy
sessionsPath={outp}/sessions
userSessionsPath={sessions}/user
wwwPath={home}/www
xscanPath={script}

View File

@@ -0,0 +1,25 @@
#Wed Aug 10 11:25:14 CEST 2022
spatialCalOffsetY=NaN
spatialCalOffsetX=NaN
colormapLogarithmic=false
scale=1.0
grayscale=false
spatialCalScaleX=NaN
spatialCalScaleY=NaN
colormapMax=NaN
rescaleOffset=0.0
roiWidth=-1
colormap=Grayscale
invert=false
colormapMin=NaN
rotation=0.0
rotationCrop=false
rescaleFactor=1.0
spatialCalUnits=mm
flipVertically=false
roiHeight=-1
flipHorizontally=false
colormapAutomatic=false
roiY=0
roiX=0
transpose=false

View File

@@ -0,0 +1,25 @@
#Wed Aug 10 12:34:59 CEST 2022
spatialCalOffsetY=-485.427166868422
spatialCalOffsetX=-638.5965043983313
colormapLogarithmic=false
scale=1.0
grayscale=false
spatialCalScaleX=-35.21126791588346
spatialCalScaleY=-48.38709170854271
colormapMax=255.0
rescaleOffset=0.0
roiWidth=-1
colormap=Flame
invert=false
colormapMin=0.0
rotation=0.0
rotationCrop=false
rescaleFactor=1.0
spatialCalUnits=mm
flipVertically=false
roiHeight=-1
flipHorizontally=false
colormapAutomatic=true
roiY=0
roiX=0
transpose=false

View File

@@ -0,0 +1,5 @@
#Thu Aug 11 14:19:59 CEST 2022
socketType=SUB
keepListeningOnStop=false
byteBufferAllocator=false
parallelHandlerProcessing=true

1347
plugins/ScreenPanel10.form Normal file

File diff suppressed because it is too large Load Diff

4712
plugins/ScreenPanel10.java Normal file

File diff suppressed because it is too large Load Diff

BIN
script/.DS_Store vendored Normal file

Binary file not shown.

3
script/local.groovy Normal file
View File

@@ -0,0 +1,3 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
// Deployment specific global definitions - executed after startup.groovy
///////////////////////////////////////////////////////////////////////////////////////////////////

4
script/local.js Normal file
View File

@@ -0,0 +1,4 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
// Deployment specific global definitions - executed after startup.js
///////////////////////////////////////////////////////////////////////////////////////////////////

100
script/local.py Normal file
View File

@@ -0,0 +1,100 @@
###################################################################################################
# Deployment specific global definitions - executed after startup.py
###################################################################################################
import numpy
from threading import Thread
import threading
import traceback
import queue
#import multiprocessing
#Workaround for zmq being a java package and having priority for import over python zmq package
from importlib._bootstrap import _load
from importlib import util
PYHOME = os.environ["PYTHONHOME"]
PYVER = str(sys.version_info[0]) + "." + str(sys.version_info[1])
_load(util.spec_from_file_location("zmq", PYHOME + "/lib/python" + PYVER + "/site-packages/zmq/__init__.py"))
from bsread import source, Source, PUB, SUB, PUSH, PULL, DEFAULT_DISPATCHER_URL
from cam_server import CamClient, PipelineClient, ProxyClient, config
from cam_server.utils import get_host_port_from_stream_address
from cam_server.pipeline.configuration import PipelineConfig
#from cam_server.pipeline.types.processing import run as processing_pipeline
from processing import run as processing_pipeline
from cam_server.pipeline.types.store import run as store_pipeline
from cam_server.start_camera_server import start_camera_server
camera_client = CamClient("http://" + App.getArgumentValue("cam_srv_url"))
class Namespace(object):
def __init__(self, **kwds):
self.__dict__.update(kwds)
def __repr__(self):
items = self.__dict__.items()
temp = []
for name, value in items:
if not name.startswith('_'):
temp.append('%s=%r' % (name, value))
temp.sort()
return 'Namespace(%s)' % str.join(', ', temp)
class Viewer():
def __init__(self):
app=App.getInstance()
c=get_context()
self.plugin=c.getPlugin("ScreenPanel10")
def show_stream(self, url):
self.plugin.initStream(url)
def show_pipeline(self, name):
self.plugin.initPipeline(name)
def show_camera(self, name):
self.plugin.initCamera(name)
def stop(self):
self.plugin.initCamera("")
viewer = Viewer()
class MockBackgroundManager:
def __init__(self):
self.backgrounds = {}
def get_background(self, background_name):
if not background_name:
return None
if background_name not in self.backgrounds:
raise ValueError("Requested background '%s' does not exist." % background_name)
return self.backgrounds[background_name]
def save_background(self, background_name, image, append_timestamp=True):
if append_timestamp:
background_name += datetime.now().strftime("_%Y%m%d_%H%M%S_%f")
self.backgrounds[background_name] = image
return background_name
def get_latest_background_id(self, background_prefix):
raise NotImplementedError("This cannot work in the mock.")
def get_background_ids(self, background_prefix):
raise NotImplementedError("This cannot work in the mock.")
def dont_exit(status):
print ("Exit status: ", status)
sys.exit = dont_exit

306
script/processing.py Normal file
View File

@@ -0,0 +1,306 @@
from cam_server.pipeline.utils import *
from logging import getLogger
import time
import sys
import os
from collections import deque, OrderedDict
import threading
from threading import Thread
import numpy
from cam_server import config
from cam_server.pipeline.data_processing.pre_processor import process_image as pre_process_image
from cam_server.utils import init_statistics
from cam_server.writer import LAYOUT_DEFAULT, LOCALTIME_DEFAULT, CHANGE_DEFAULT
from cam_server.pipeline.data_processing.functions import is_number, binning, copy_image
_logger = getLogger(__name__)
def run(stop_event, statistics, parameter_queue, cam_client, pipeline_config, output_stream_port,
background_manager, user_scripts_manager=None):
camera_name = pipeline_config.get_camera_name()
set_log_tag(" [" + str(camera_name) + " | " + str(pipeline_config.get_name()) + ":" + str(output_stream_port) + "]")
exit_code = 0
def process_bsbuffer(bs_buffer, bs_img_buffer):
i = 0
while i < len(bs_buffer):
bs_pid, bsdata = bs_buffer[i]
for j in range(len(bs_img_buffer)):
img_pid = bs_img_buffer[0][0]
if img_pid < bs_pid:
bs_img_buffer.popleft()
elif img_pid == bs_pid:
[pulse_id, [global_timestamp, image, x_axis, y_axis, additional_data]] = bs_img_buffer.popleft()
stream_data = OrderedDict()
stream_data.update(bsdata)
for key, value in bsdata.items():
stream_data[key] = value.value
if additional_data is not None:
try:
stream_data.update(additional_data)
except:
pass
process_data(process_image, pulse_id, global_timestamp, image,x_axis, y_axis, stream_data)
for k in range(i):
bs_buffer.popleft()
i = -1
break
else:
break
i = i + 1
def bs_send_task(bs_buffer, bs_img_buffer, stop_event):
global sender
if number_processing_threads <= 0:
_logger.info("Start bs send thread")
sender = create_sender(output_stream_port, stop_event)
try:
with connect_to_stream() as stream:
while not stop_event.is_set():
message = stream.receive()
if not message or stop_event.is_set():
if abort_on_timeout():
stop_event.set()
continue
bs_buffer.append([message.data.pulse_id, message.data.data])
try:
process_bsbuffer(bs_buffer, bs_img_buffer)
except Exception as e:
_logger.error("Error processing bs buffer: " + str(e))
except Exception as e:
_logger.error("Error on bs_send_task: " + str(e))
finally:
stop_event.set()
if sender:
try:
sender.close()
except:
pass
_logger.info("Exit bs send thread")
def process_pipeline_parameters():
parameters = get_parameters()
_logger.debug("Processing pipeline parameters %s. %s" % (parameters, log_tag))
background_array = None
if parameters.get("image_background_enable"):
background_id = pipeline_config.get_background_id()
_logger.debug("Image background enabled. Using background_id %s. %s" %(background_id, log_tag))
try:
background_array = background_manager.get_background(background_id)
parameters["image_background_ok"] = True
except:
_logger.warning("Invalid background_id: %s. %s" % (background_id, log_tag))
#if abort_on_error():
# raise
parameters["image_background_ok"] = False
if background_array is not None:
background_array = background_array.astype("uint16",copy=False)
size_x, size_y = cam_client.get_camera_geometry(pipeline_config.get_camera_name())
by, bx = int(parameters.get("binning_y", 1)), int(parameters.get("binning_x", 1))
bm = parameters.get("binning_mean", False)
if (by > 1) or (bx > 1):
size_x, size_y = int(size_x / bx), int(size_y / by)
if background_array is not None:
background_array, _, _ = binning(background_array, None, None, bx, by, bm)
if background_array.shape != (size_y, size_x):
_logger.warning("Bad background shape: %s instead of %s. %s" % (image_background_array.shape, (size_y, size_x), log_tag))
image_region_of_interest = parameters.get("image_region_of_interest")
if image_region_of_interest:
_, size_x, _, size_y = image_region_of_interest
if size_x and size_y:
_logger.debug("Image width %d and height %d. %s" % (size_x, size_y, log_tag))
if parameters.get("rotation"):
if not isinstance(parameters.get("rotation"), dict):
parameters["rotation"] = {"angle":float(parameters.get("rotation")), "order":1, "mode":"0.0"}
if not parameters["rotation"].get("angle"):
parameters["rotation"] = None
elif not is_number(parameters["rotation"]["angle"]) or (float(parameters["rotation"]["angle"]) == 0):
parameters["rotation"] = None
else:
if not parameters["rotation"].get("order"):
parameters["rotation"]["order"] = 1
if not parameters["rotation"].get("mode"):
parameters["rotation"]["mode"] = "0.0"
if parameters.get("averaging"):
try:
parameters["averaging"] = int(parameters.get("averaging"))
except:
parameters["averaging"] = None
if parameters["mode"] == "FILE":
if parameters.get("layout") is None:
parameters["layout"] = LAYOUT_DEFAULT
if parameters.get("localtime") is None:
parameters["localtime"] = LOCALTIME_DEFAULT
if parameters.get("change") is None:
parameters["change"] = CHANGE_DEFAULT
if parameters.get("bsread_address"):
if parameters.get("bsread_image_buf"):
parameters["bsread_image_buf"] = min(parameters.get("bsread_image_buf"), config.BSREAD_IMAGE_BUFFER_SIZE_MAX)
else:
parameters["bsread_image_buf"] =config.BSREAD_IMAGE_BUFFER_SIZE_DEFAULT
if parameters.get("bsread_data_buf"):
parameters["bsread_data_buf"] = min(parameters.get("bsread_data_buf"), config.BSREAD_DATA_BUFFER_SIZE_MAX)
else:
parameters["bsread_data_buf"] =config.BSREAD_DATA_BUFFER_SIZE_DEFAULT
return parameters, background_array
def process_image(pulse_id, global_timestamp, function, image, x_axis, y_axis, bsdata):
pars = get_parameters()
try:
image, x_axis, y_axis = pre_process_image(image, pulse_id, global_timestamp, x_axis, y_axis, pars, image_background_array)
processed_data = function(image, pulse_id, global_timestamp, x_axis, y_axis, pars, bsdata)
#print("Processing PID %d at proc %d thread %d" % (pulse_id, os.getpid(), threading.get_ident()))
return processed_data
except Exception as e:
_logger.warning("Error processing PID %d at proc %d thread %d: %s" % (pulse_id, os.getpid(), threading.get_ident(), str(e)))
if abort_on_error():
raise
bs_buffer, bs_img_buffer, bs_send_thread = None, None, None
try:
init_statistics(statistics)
init_pipeline_parameters(pipeline_config, parameter_queue, user_scripts_manager, process_pipeline_parameters)
pipeline_parameters, image_background_array = process_pipeline_parameters()
connect_to_camera(cam_client)
_logger.debug("Opening output stream on port %d. %s" % (output_stream_port, log_tag))
# Indicate that the startup was successful.
stop_event.clear()
image_with_stream = has_stream()
if image_with_stream:
bs_buffer = deque(maxlen=pipeline_parameters["bsread_data_buf"])
bs_img_buffer = deque(maxlen=pipeline_parameters["bsread_image_buf"])
bs_send_thread = Thread(target=bs_send_task, args=(bs_buffer, bs_img_buffer,stop_event))
bs_send_thread.start()
if number_processing_threads > 0:
setup_sender(output_stream_port, stop_event, process_image, user_scripts_manager)
else:
setup_sender(output_stream_port, stop_event, process_image, user_scripts_manager)
_logger.debug("Transceiver started. %s" % (log_tag))
last_sent_timestamp = 0
image_buffer = []
while not stop_event.is_set():
try:
ret = check_parameters_changes()
if ret is not None:
pipeline_parameters, image_background_array = ret
assert_function_defined()
pulse_id, global_timestamp, data = receive_stream(True)
if not data:
continue
image = data["image"].value
if image is None:
continue
x_axis = data["x_axis"].value
y_axis = data["y_axis"].value
if pipeline_parameters.get("rotation"):
if pipeline_parameters["rotation"]["mode"] == "ortho":
rotation_angle = int(pipeline_parameters["rotation"]["angle"] / 90) % 4
if rotation_angle==1:
x_axis,y_axis = y_axis, numpy.flip(x_axis)
if rotation_angle == 2:
x_axis, y_axis = numpy.flip(x_axis), numpy.flip(y_axis)
if rotation_angle == 3:
x_axis, y_axis = numpy.flip(y_axis), x_axis
averaging = pipeline_parameters.get("averaging")
if averaging:
continuous = averaging < 0
averaging = abs(averaging)
if continuous and (len(image_buffer) >= averaging):
image_buffer.pop(0)
image_buffer.append(image)
if (len(image_buffer) >= averaging) or (continuous):
try:
frames = numpy.array(image_buffer)
image = numpy.average(frames, 0)
except:
#Different shapes
image_buffer = []
continue
else:
continue
else:
if pipeline_parameters.get("copy"):
image = copy_image(image)
if (not averaging) or (not continuous):
image_buffer = []
#Check maximum frame rate parameter
max_frame_rate = pipeline_parameters.get("max_frame_rate")
if max_frame_rate:
min_interval = 1.0 / max_frame_rate
if (time.time() - last_sent_timestamp) < min_interval:
continue
additional_data = {}
if len(data) != len(config.CAMERA_STREAM_REQUIRED_FIELDS):
for key, value in data.items():
if not key in config.CAMERA_STREAM_REQUIRED_FIELDS:
additional_data[key] = value.value
pars = [global_timestamp, image, x_axis, y_axis, additional_data]
if image_with_stream:
bs_img_buffer.append([pulse_id, pars])
else:
process_data(process_image, pulse_id, *pars)
last_sent_timestamp = time.time()
except ProcessingCompleted:
break
except Exception as e:
exit_code = 2
_logger.exception("Could not process message %s: %s" % (log_tag, str(e)))
break
except Exception as e:
exit_code = 1
_logger.exception("Exception while trying to start the receive and process thread %s: %s" % (log_tag, str(e)))
raise
finally:
_logger.info("Stopping transceiver. %s" % log_tag)
stop_event.set()
if bs_send_thread:
try:
bs_send_thread.join(0.1)
except:
pass
cleanup()
_logger.debug("Exiting process. %s" % log_tag)
sys.exit(exit_code)

View File

@@ -0,0 +1,24 @@
from imp import load_package
try:
load_package("zmq","/Users/gobbo_a/opt/anaconda3/envs/pide/lib/python3.8/site-packages/zmq")
except:
pass
import zmq.backend
import zmq.utils
import zmq.sugar
#import zmq.PUB
#import zmq.Poller
#import zmq._future
load_package("zmq","/Users/gobbo_a/opt/anaconda3/envs/pide/lib/python3.8/site-packages/zmq")
#from cam_server import CameraClient

View File

@@ -0,0 +1,15 @@
import base64
import numpy
#"localhost:5554”
pipeline_client = PipelineClient("http://0.0.0.0:8889")
instance_id, pipeline_stream_address = pipeline_client.create_instance_from_name("simulation_sp", "simulation_sp3")
pipeline_host, pipeline_port = get_host_port_from_stream_address(pipeline_stream_address)
# Subscribe to the stream.
with source(host=pipeline_host, port=pipeline_port, mode=SUB) as stream:
# Receive next message.
data = stream.receive()

9
script/test/test_proc.py Normal file
View File

@@ -0,0 +1,9 @@
from multiprocessing import Process
def f(name):
print('hello', name)
p = Process(target=f, args=('bob',))
p.start()
p.join()

View File

@@ -0,0 +1,35 @@
#stop_event = multiprocessing.Event()
#parameter_queue = multiprocessing.Queue()
#manager = multiprocessing.Manager()
#statistics = manager.Namespace()
stop_event = threading.Event()
parameter_queue = queue.Queue()
statistics=Namespace()
OUTPUT_PORT = 12005
viewer.show_stream("tcp://localhost:" + str(OUTPUT_PORT))
pipeline_config = PipelineConfig("test_pipeline", parameters={"camera_name": "simulation", "function":"transparent"})
def send():
print ("Startint pipeline on port: ", OUTPUT_PORT)
try:
processing_pipeline(stop_event, statistics, parameter_queue, camera_client, pipeline_config, OUTPUT_PORT, MockBackgroundManager())
except:
traceback.print_exc()
thread = Thread(target=send)
thread.start()
with source(host="127.0.0.1", port=OUTPUT_PORT, mode=SUB, receive_timeout = 3000) as stream:
data = stream.receive()
if not data:
raise Exception("Received None message.")
print (data.data.data.keys())
stop_event.set()
thread.join(5.0)

View File

@@ -0,0 +1,19 @@
url="tcp://localhost:10100"
st1 = Stream("st1", Provider("provider", url, False))
st1.initialize()
st1.start()
st1.waitCacheChange(20000)
try:
bscan (st1, 5, 5, save=False)
finally:
st1.close()
try:
print (st1.getValues())
finally:
st1.close()