diff --git a/config/config.properties b/config/config.properties
index 9d4e353..9e1d7db 100644
--- a/config/config.properties
+++ b/config/config.properties
@@ -1,4 +1,4 @@
-#Thu Oct 09 08:44:46 CEST 2025
+#Fri Mar 13 14:50:44 CET 2026
autoSaveScanData=true
commandBusSize=-1
commandBusTimeToLive=600000
@@ -12,12 +12,13 @@ consoleJournal=false
dataDepthDimension=0
dataEmbeddedAttributes=false
dataFormat=h5
-dataLayout=table
+dataLayout=default
dataPath={data}/{year}_{month}/{date}/{date}_{time}_{name}
dataServerPort=-1
dataTransferMode=Off
dataTransferPath=
dataTransferUser=
+dataTruncate=true
depthDimension=0
disableDataFileLogs=false
disableEmbeddedAttributes=false
@@ -55,9 +56,10 @@ scanSaveScript=true
scanSaveSetpoints=true
scanSaveTimestamps=false
scanStreamerPort=-1
-serverCommandsHidden=true
+serverCommandsHidden=false
serverEnabled=true
-serverHostName=null
+serverHostName=
+serverHttps=false
serverLight=true
serverPort=8080
sessionHandling=Off
@@ -67,7 +69,7 @@ terminalPort=3579
userAuthenticator=
userManagement=false
versionTrackingEnabled=true
-versionTrackingLogin=auto
+versionTrackingLogin=
versionTrackingManual=true
versionTrackingRemote=https\://gitea.psi.ch/pshell_config/tst.git
xscanAppendSuffix=true
diff --git a/config/devices.properties b/config/devices.properties
index e831de1..2a009d4 100644
--- a/config/devices.properties
+++ b/config/devices.properties
@@ -1 +1,4 @@
sin=ch.psi.pshell.epics.ChannelDouble|TESTIOC:TESTSINUS:SinCalc|Read||true
+out=ch.psi.pshell.epics.ReadonlyProcessVariable|TESTIOC:TESTCALCOUT2:Output|Read||true
+inp=ch.psi.pshell.epics.ProcessVariable|TESTIOC:TESTCALCOUT2:Input|||true
+cam_server=ch.psi.pshell.camserver.PipelineSource|localhost:8889|||true
diff --git a/config/jcae.properties b/config/jcae.properties
index 97245f2..840508c 100644
--- a/config/jcae.properties
+++ b/config/jcae.properties
@@ -1,5 +1,5 @@
-#Wed Mar 19 11:12:57 CET 2025
-ch.psi.jcae.ContextFactory.addressList=localhost\:54321 sls-cagw.psi.ch\:5062
+#Tue Nov 11 13:47:56 CET 2025
+ch.psi.jcae.ContextFactory.addressList=localhost localhost\:54321
ch.psi.jcae.ContextFactory.serverPort=
ch.psi.jcae.ContextFactory.maxArrayBytes=20000000
ch.psi.jcae.ContextFactory.maxSendArrayBytes=20000000
diff --git a/config/preferences.json b/config/preferences.json
index ee0520c..d92c2e3 100644
--- a/config/preferences.json
+++ b/config/preferences.json
@@ -52,7 +52,7 @@
"noVariableEvaluationPropagation" : false,
"processingScripts" : [ ],
"asyncViewersUpdate" : false,
- "asyncHistoryPlotsUpdate" : false,
+ "asyncHistoryPlotsUpdate" : true,
"scanPlotDisabled" : false,
"scanTableDisabled" : false,
"cachedDataPanel" : false,
@@ -81,7 +81,7 @@
"plotBackground" : null,
"gridColor" : null,
"outlineColor" : null,
- "disableOffscreenBuffer" : false,
+ "directRendering" : false,
"defaultPanels" : [ {
"deviceClassName" : "ch.psi.pshell.epics.Scaler",
"panelClassName" : "ch.psi.pshell.swing.ScalerPanel"
diff --git a/config/tasks.properties b/config/tasks.properties
new file mode 100644
index 0000000..cbd80e6
--- /dev/null
+++ b/config/tasks.properties
@@ -0,0 +1 @@
+#test_camserver=5.0;1.0
diff --git a/config/variables.properties b/config/variables.properties
index a7f181a..56cf4ea 100644
--- a/config/variables.properties
+++ b/config/variables.properties
@@ -1,6 +1,6 @@
-#Tue Oct 21 16:12:23 CEST 2025
+#Thu Mar 12 15:49:20 CET 2026
=2
-DaySequentialNumber=1
-FileSequentialNumber=1797
-LastRunDate=251021
+DaySequentialNumber=30
+FileSequentialNumber=2382
+LastRunDate=260312
r=2
diff --git a/devices/CurrentCamera.properties b/devices/CurrentCamera.properties
index 31c2ad4..47d9b8a 100644
--- a/devices/CurrentCamera.properties
+++ b/devices/CurrentCamera.properties
@@ -1,13 +1,14 @@
-#Thu May 08 14:06:17 CEST 2025
-colormap=Grayscale
-colormapAutomatic=false
+#Thu Dec 11 11:29:17 CET 2025
+colormap=Flame
+colormapAutomatic=true
colormapLogarithmic=false
-colormapMax=NaN
-colormapMin=NaN
+colormapMax=255.0
+colormapMin=0.0
flipHorizontally=false
flipVertically=false
grayscale=false
invert=false
+lse=
rescaleFactor=1.0
rescaleOffset=0.0
roiHeight=-1
@@ -17,9 +18,9 @@ roiY=0
rotation=0.0
rotationCrop=false
scale=1.0
-spatialCalOffsetX=-637.0000131373355
-spatialCalOffsetY=-483.0000310340799
-spatialCalScaleX=-35.21126791588346
-spatialCalScaleY=-48.38709170854271
+spatialCalOffsetX=-123.99999389793373
+spatialCalOffsetY=-90.99999980402927
+spatialCalScaleX=-2.6978416539937182
+spatialCalScaleY=-2.162849850124783
spatialCalUnits=mm
transpose=false
diff --git a/devices/Time.properties b/devices/Time.properties
index 244cae7..dc85b74 100644
--- a/devices/Time.properties
+++ b/devices/Time.properties
@@ -4,7 +4,7 @@ maxValue=NaN
minValue=NaN
offset=0.0
precision=-1
-resolution=NaN
+deadband=NaN
rotation=false
scale=1.0
sign_bit=0
diff --git a/devices/cam_server.properties b/devices/cam_server.properties
new file mode 100644
index 0000000..77f1a65
--- /dev/null
+++ b/devices/cam_server.properties
@@ -0,0 +1,26 @@
+#Fri Mar 06 15:44:07 CET 2026
+colormap=Grayscale
+colormapAutomatic=false
+colormapLogarithmic=false
+colormapMax=NaN
+colormapMin=NaN
+flipHorizontally=false
+flipVertically=false
+grayscale=false
+invert=false
+rescaleFactor=1.0
+rescaleOffset=0.0
+roiHeight=-1
+roiWidth=-1
+roiX=0
+roiY=0
+rotation=0.0
+rotationCrop=false
+scale=1.0
+serverURL=localhost\:8889
+spatialCalOffsetX=-123.99999389793373
+spatialCalOffsetY=-90.99999980402927
+spatialCalScaleX=-2.6978416539937182
+spatialCalScaleY=-2.162849850124783
+spatialCalUnits=mm
+transpose=false
diff --git a/devices/dispatcher.properties b/devices/dispatcher.properties
new file mode 100644
index 0000000..47a105e
--- /dev/null
+++ b/devices/dispatcher.properties
@@ -0,0 +1,13 @@
+#Tue Jan 13 17:11:55 CET 2026
+analizeHeader=false
+disableCompression=false
+headerReservingAllocator=false
+keepListeningOnStop=false
+mappingIncomplete=fill_null
+parallelHandlerProcessing=true
+sendAwaitFirstMessage=false
+sendBuildChannelConfig=at_startup
+sendStrategy=complete_all
+sendSyncTimeout=0
+socketType=DEFAULT
+validationInconsistency=keep_as_is
diff --git a/devices/inp.properties b/devices/inp.properties
new file mode 100644
index 0000000..3d8946d
--- /dev/null
+++ b/devices/inp.properties
@@ -0,0 +1,10 @@
+#Thu Mar 12 13:34:04 CET 2026
+deadband=NaN
+description=Test Calcout Inopput
+maxValue=1000.0
+minValue=-1000.0
+offset=0.0
+precision=5
+scale=1.0
+sign_bit=0
+unit=mm
diff --git a/devices/m1.properties b/devices/m1.properties
index 7832097..8e41083 100644
--- a/devices/m1.properties
+++ b/devices/m1.properties
@@ -1,4 +1,5 @@
-#Tue Mar 18 14:13:39 CET 2025
+#Mon Dec 01 16:57:52 CET 2025
+deadband=NaN
defaultSpeed=1.0
description=null
estbilizationDelay=0
@@ -8,8 +9,7 @@ minSpeed=0.1
minValue=-10.0
monitorByPosition=false
offset=0.0
-precision=2
-resolution=NaN
+precision=3
rotation=false
scale=1.0
sign_bit=0
diff --git a/devices/m2.properties b/devices/m2.properties
index 7832097..b58419e 100644
--- a/devices/m2.properties
+++ b/devices/m2.properties
@@ -1,4 +1,5 @@
-#Tue Mar 18 14:13:39 CET 2025
+#Mon Dec 01 16:58:07 CET 2025
+deadband=NaN
defaultSpeed=1.0
description=null
estbilizationDelay=0
@@ -8,8 +9,7 @@ minSpeed=0.1
minValue=-10.0
monitorByPosition=false
offset=0.0
-precision=2
-resolution=NaN
+precision=3
rotation=false
scale=1.0
sign_bit=0
diff --git a/devices/motor.properties b/devices/motor.properties
index 87c32ab..65e70b9 100644
--- a/devices/motor.properties
+++ b/devices/motor.properties
@@ -9,7 +9,7 @@ minValue=-10.0
monitorByPosition=false
offset=0.0
precision=2
-resolution=NaN
+deadband=NaN
rotation=false
scale=1.0
sign_bit=0
diff --git a/devices/out.properties b/devices/out.properties
new file mode 100644
index 0000000..1d08141
--- /dev/null
+++ b/devices/out.properties
@@ -0,0 +1,7 @@
+#Thu Mar 12 13:34:04 CET 2026
+description=Test Calcout Output
+offset=0.0
+precision=5
+scale=1.0
+sign_bit=0
+unit=mm
diff --git a/devices/p1.properties b/devices/p1.properties
index d4f7619..a22c43a 100644
--- a/devices/p1.properties
+++ b/devices/p1.properties
@@ -4,7 +4,7 @@ maxValue=1000.0
minValue=0.0
offset=0.0
precision=-1
-resolution=NaN
+deadband=NaN
rotation=false
scale=1.0
sign_bit=0
diff --git a/devices/positioner.properties b/devices/positioner.properties
index a7f9256..d27d222 100644
--- a/devices/positioner.properties
+++ b/devices/positioner.properties
@@ -4,7 +4,7 @@ maxValue=1000.0
minValue=-1000.0
offset=0.0
precision=5
-resolution=Infinity
+deadband=Infinity
scale=1.0
sign_bit=0
unit=mm
diff --git a/plugins/TestScript.form b/plugins/TestScript.form
new file mode 100644
index 0000000..94f292e
--- /dev/null
+++ b/plugins/TestScript.form
@@ -0,0 +1,51 @@
+
+
+
diff --git a/plugins/TestScript.java b/plugins/TestScript.java
new file mode 100644
index 0000000..97e96e7
--- /dev/null
+++ b/plugins/TestScript.java
@@ -0,0 +1,121 @@
+
+import ch.psi.pshell.framework.ScriptProcessor;
+import ch.psi.pshell.framework.Task;
+import ch.psi.pshell.utils.State;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ */
+public class TestScript extends ScriptProcessor {
+
+ //TODO: set script name
+ public static final String SCRIPT_NAME = "TestScript";
+
+ public TestScript() {
+ initComponents();
+ }
+
+ //Overridable callbacks
+ @Override
+ public void onInitialize(int runCount) {
+
+ }
+
+ @Override
+ public void onStateChange(State state, State former) {
+
+ }
+
+ @Override
+ public void onExecutedFile(String fileName, Object result) {
+ }
+
+ @Override
+ public void onTaskFinished(Task task) {
+ }
+
+ @Override
+ protected void onTimer() {
+ }
+
+ @Override
+ protected void onLoaded() {
+ scanPlot.initialize();
+ scanPlot.setActive(true);
+ System.out.println("OK");
+ }
+
+ @Override
+ protected void onUnloaded() {
+
+ }
+
+
+ @Override
+ protected void onStartingExecution(Map args) throws Exception{
+ }
+
+ @Override
+ protected void onFinishedExecution(Map args, Object ret, Throwable t) throws Exception{
+ }
+
+
+ //Invoked by 'update()' to update components in the event thread
+ @Override
+ protected void doUpdate() {
+ }
+
+
+ @Override
+ public String getScript(){
+ return SCRIPT_NAME;
+ }
+
+
+
+ @Override
+ public Map getArgs(){
+ //TODO: add script arguments
+ Map ret = new HashMap<>();
+ return ret;
+ }
+
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ scanPlot = new ch.psi.pshell.swing.PlotPanel();
+
+ javax.swing.GroupLayout scanPlotLayout = new javax.swing.GroupLayout(scanPlot);
+ scanPlot.setLayout(scanPlotLayout);
+ scanPlotLayout.setHorizontalGroup(
+ scanPlotLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 476, Short.MAX_VALUE)
+ );
+ scanPlotLayout.setVerticalGroup(
+ scanPlotLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 394, Short.MAX_VALUE)
+ );
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 476, Short.MAX_VALUE)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(scanPlot, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 394, Short.MAX_VALUE)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(scanPlot, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+ }// //GEN-END:initComponents
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private ch.psi.pshell.swing.PlotPanel scanPlot;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/script/TestScript.py b/script/TestScript.py
new file mode 100644
index 0000000..7f54e89
--- /dev/null
+++ b/script/TestScript.py
@@ -0,0 +1 @@
+tscan(ai1, 10, 1.0)
diff --git a/script/cpython2.py b/script/cpython2.py
new file mode 100644
index 0000000..1209deb
--- /dev/null
+++ b/script/cpython2.py
@@ -0,0 +1,116 @@
+###################################################################################################
+# This moddule is called by demo scripts to execute and embed CPython.
+# Must be put in the scripts folder, or else in the python path.
+###################################################################################################
+
+import sys
+import os
+
+#import matplotlib
+#matplotlib.use('TkAgg')
+
+import pandas as pd
+import numpy as np
+import matplotlib.pyplot as plt
+
+#try:
+# import tkinter as tk
+#except:
+# import Tkinter as tk
+
+
+def calc(array):
+ return np.transpose(array + array)
+
+
+def test_pandas():
+ s = pd.Series([1,3,5,np.nan,6,8])
+ print (s)
+ dates = pd.date_range('20130101', periods=6)
+ print (dates)
+ df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD'))
+ print (df)
+ df2 = pd.DataFrame({ 'A' : 1.,
+ 'B' : pd.Timestamp('20130102'),
+ 'C' : pd.Series(1,index=list(range(4)),dtype='float32'),
+ 'D' : np.array([3] * 4,dtype='int32'),
+ 'E' : pd.Categorical(["test","train","test","train"]),
+ 'F' : 'foo' })
+ print (df2)
+ print (df2.dtypes)
+ print (df.head())
+ print (df.tail(3))
+ print (df.values)
+ print (df.describe())
+ print (df.T)
+ print (df.sort_index(axis=1, ascending=False))
+ #print (df.sort_values(by='B'))
+ print (df['A'])
+ print (df[0:3])
+ print (df.mean())
+ return str(df.mean())
+
+
+def test_tkinter():
+ root = tk.Tk()
+ listb = tk.Listbox(root)
+ for item in ["Hello", "World"]:
+ listb.insert(0,item)
+ listb.pack()
+ root.mainloop()
+
+
+def test_matplotlib(start,stop,step):
+ import threading
+ x = np.arange(start,stop,step)
+ y = np.exp(-x)
+
+ # example variable error bar values
+ yerr = 0.1 + 0.2*np.sqrt(x)
+ xerr = 0.1 + yerr
+
+ # First illustrate basic pyplot interface, using defaults where possible.
+ plt.figure()
+ plt.errorbar(x, y, xerr=0.2, yerr=0.4)
+ plt.title("Simplest errorbars, 0.2 in x, 0.4 in y")
+
+ # Now switch to a more OO interface to exercise more features.
+ fig, axs = plt.subplots(nrows=2, ncols=2, sharex=True)
+ ax = axs[0,0]
+ ax.errorbar(x, y, yerr=yerr, fmt='o')
+ ax.set_title('Vert. symmetric')
+
+ # With 4 subplots, reduce the number of axis ticks to avoid crowding.
+ ax.locator_params(nbins=4)
+
+ ax = axs[0,1]
+ ax.errorbar(x, y, xerr=xerr, fmt='o')
+ ax.set_title('Hor. symmetric')
+
+ ax = axs[1,0]
+ ax.errorbar(x, y, yerr=[yerr, 2*yerr], xerr=[xerr, 2*xerr], fmt='--o')
+ ax.set_title('H, V asymmetric')
+
+ ax = axs[1,1]
+ ax.set_yscale('log')
+ # Here we have to be careful to keep all y values positive:
+ ylower = np.maximum(1e-2, y - yerr)
+ yerr_lower = y - ylower
+
+ ax.errorbar(x, y, yerr=[yerr_lower, 2*yerr], xerr=xerr,
+ fmt='o', ecolor='g', capthick=2)
+ ax.set_title('Mixed sym., log y')
+
+ fig.suptitle('Variable errorbars')
+
+ plt.show()
+ return [start,stop,step]
+
+
+if __name__ == "__main__":
+ x = np.arange(0, 5, 0.1)
+ y = np.sin(x)
+ plt.plot(x, y)
+ plt.show()
+
+
diff --git a/script/methood.py b/script/methood.py
index 42e40c6..753ef22 100644
--- a/script/methood.py
+++ b/script/methood.py
@@ -1,3 +1,4 @@
+1/0
def test():
###
pass
\ No newline at end of file
diff --git a/script/test_camserver.py b/script/test_camserver.py
new file mode 100644
index 0000000..2be05d0
--- /dev/null
+++ b/script/test_camserver.py
@@ -0,0 +1,82 @@
+#START AS: pshell console -dev -v -k -b -g -t test_camserver,1,5 -r false (-cl FINE)(--debug -y)
+import ch.psi.pshell.screenpanel.CamServerViewer as CamServerViewer
+import traceback
+
+SHOW_RENDERER=False
+CAMERA="simulation"
+CHANNEL_IMG = "TEST:FPICTURE"
+CHANNEL_WIDTH = "TEST:WIDTH"
+CHANNEL_HEIGHT = "TEST:HEIGHT"
+INTERVAL = 1.0
+SHOW_PROFILE = False
+SHOW_FIT = True
+#IMAGE_TYPE = PV.Type.SHORT
+IMAGE_TYPE = PV.Type.BYTE
+#IMAGE_SIZE = Dimension(500,500)
+#IMAGE_SIZE = Dimension(255,255)
+IMAGE_SIZE = Dimension(300,218)
+MAX_IMAGE_SIZE = 65500 if PV.Type.BYTE else 65500/2
+DEBUG = (not Setup.isServerMode()) or Setup.isDebug()
+PLOT = DEBUG
+
+img = PV.waveform(CHANNEL_IMG, IMAGE_TYPE, MAX_IMAGE_SIZE)
+width = PV.scalar(CHANNEL_WIDTH, PV.Type.INT)
+height = PV.scalar(CHANNEL_HEIGHT, PV.Type.INT)
+
+viewer = CamServerViewer()
+viewer.applyOptions();
+viewer.initialize(CamServerViewer.SourceSelecionMode.Single);
+viewer.setStream(CAMERA)
+viewer.camera.config.colormap=Colormap.Flame
+viewer.camera.config.colormapAutomatic = True
+
+viewer.setShowProfile(SHOW_PROFILE)
+viewer.setShowFit(SHOW_FIT)
+r=viewer.renderer
+r.setPenProfile(Pen(Color.GRAY, 0))
+viewer.setPenFit(Pen(Color.WHITE, 0))
+viewer.setPenCross(Pen(Color.WHITE, 0))
+
+if SHOW_RENDERER:
+ f=SwingUtils.showFrame(App.getMainFrame(), "CamServerViewer", Dimension(450,250), r)
+ f.setAlwaysOnTop(True)
+else:
+ r.device.addListener(r)
+p=None
+
+try:
+ r.waitImage(10000)
+ while True:
+ i=r.getImage(True, IMAGE_SIZE)
+ i=ImagingUtils.grayscale(i)
+ d = Data(i)
+ a = d.array
+ if IMAGE_TYPE != PV.Type.BYTE:
+ a=Convert.toUnsigned(a)
+ img.write(a)
+ width.write(d.width)
+ height.write(d.height)
+ if PLOT:
+ matrix = Convert.reshape(a, d.height, d.width)
+ if IMAGE_TYPE == PV.Type.BYTE:
+ matrix=Convert.toUnsigned(matrix)
+ #p=plot(matrix)[0]
+ if p is None or (s.numberOfBinsX!=d.width) []or (s.numberOfBinsY!=d.height):
+ p=plot(matrix)[0]
+ p.setColormap(Colormap.Grayscale)
+ p.getAxis(p.AxisId.Y).inverted=True
+ s=p.getSeries(0)
+ else:
+ s.setData(Convert.toDouble(matrix))
+ if INTERVAL:
+ time.sleep(INTERVAL)
+ r.waitNext(10000) #If stops receiving, tries restarting
+except:
+ width.write(0)
+ height.write(0)
+ if DEBUG:
+ print "Camera image processing exception:"
+ print sys.exc_info()[1]
+ traceback.print_exc()
+finally:
+ viewer.setStream(None)
\ No newline at end of file
diff --git a/script/test_channels.py b/script/test_channels.py
new file mode 100644
index 0000000..9d32ae5
--- /dev/null
+++ b/script/test_channels.py
@@ -0,0 +1,90 @@
+if not "_pvs" in globals():
+ _pvs = {}
+
+def get_waveform_pv(name, typ='double', size=None):
+ if name not in _pvs:
+ class Waveform(RegisterBase, RegisterArray):
+ def __init__(self, name):
+ RegisterBase.__init__(self, name)
+ self.fixed_size = None
+ self.clear()
+
+ def clear(self):
+ self.val = None
+ #if self.fixed_size:
+ # self.val = [float("nan")] * self.fixed_size
+ #else:
+ # self.val = [float("nan")]
+
+ def doRead(self):
+ return self.val
+
+ def doWrite(self, val):
+ if val is None or len(val) == 0:
+ self.clear()
+ elif self.fixed_size:
+ self.clear()
+ del val[self.fixed_size:]
+ self.val[:len(val)] = val
+ else:
+ self.val = val
+ print self.val
+
+ def getSize(self):
+ return len(self.val)
+
+ def fixSize(self, size):
+ self.fixed_size = size
+ self.clear()
+
+ waveform = Waveform(name)
+ #waveform.fixSize(size)
+ waveform.initialize()
+ cas = CAS(name, waveform, typ)
+ _pvs[name] = [waveform, cas]
+ return _pvs[name][0]
+
+
+def get_scalar_pv(name, typ='double', size=None):
+ if name not in _pvs:
+ class Scalar(RegisterBase):
+ def __init__(self, name):
+ RegisterBase.__init__(self, name)
+ self.fixed_size = None
+ self.clear()
+
+ def clear(self):
+ self.val = float("nan")
+
+ def doRead(self):
+ return self.val
+
+ def doWrite(self, val):
+ if val is None:
+ self.clear()
+ else:
+ self.val = val
+
+ scalar = Scalar(name)
+ scalar.initialize()
+ cas = CAS(name, scalar, typ)
+ _pvs[name] = [scalar, cas]
+ return _pvs[name][0]
+
+
+pv = get_waveform_pv("TEST_CHANNELS:ai1","double")
+sc = get_scalar_pv("TEST_CHANNELS:ai2","double")
+
+
+def after_read(record, scan):
+ #print scan.result[ai1] + [record[ai1],]
+ pv.write(scan.result[ai1])
+ sc.write(record.index)
+
+
+r= tscan((ai1, ai1), 5, 0.1, after_read=after_read, save=False)
+pv.write(r[ai1])
+sc.write(len(r))
+
+print pv.read()
+print sc.read()
\ No newline at end of file
diff --git a/script/test_channels2.py b/script/test_channels2.py
new file mode 100644
index 0000000..e069acc
--- /dev/null
+++ b/script/test_channels2.py
@@ -0,0 +1,22 @@
+wf = PV.waveform("TEST:WAVEFORM", PV.Type.DOUBLE, 5)
+sc = PV.scalar("TEST:SCALAR", PV.Type.DOUBLE)
+st = PV.scalar("TEST:STATE", PV.Type.STRING)
+
+if st.read()=="Busy":
+ print "Ongoing operation"
+ raise Exception ("Ongoing operation")
+st.write("Busy")
+
+def after_read(record, scan):
+ #print scan.result[ai1] + [record[ai1],]
+ wf.write(scan.result[ai1])
+ sc.write(record.index)
+
+try:
+ r= tscan((ai1, ai1), 5, 1.5, after_read=after_read, save=False)
+ wf.write(r[ai1])
+ sc.write(len(r))
+ print wf.read()
+ print sc.read()
+finally:
+ st.write("Ready")
\ No newline at end of file
diff --git a/script/test_data_txt.py b/script/test_data_txt.py
index 5a4afef..ebe4e2f 100644
--- a/script/test_data_txt.py
+++ b/script/test_data_txt.py
@@ -2,11 +2,12 @@
data2d = [ [1.0, 2.0, 3.0, 4.0, 5.0], [2.0, 3.0, 4.0, 5.0, 6.0, ], [3.0, 4.0, 5.0, 6.0, 7.0]]
-path = "group/data4"
+path = "group/data4"+ str(time.time())
create_dataset(path, 'd', False, (0,0))
for row in data2d:
append_dataset(path, row)
read =load_data(path)
print read.tolist()
plot(read)
+run("test_sleep")
set_return(True)
\ No newline at end of file
diff --git a/script/test_list.py b/script/test_list.py
index 2260324..d909784 100644
--- a/script/test_list.py
+++ b/script/test_list.py
@@ -3,7 +3,7 @@ a = [1,2,3]
d = to_array(a)
l=to_list(d)
-print (a)
+print (d)
print (l)
print (type(a)==type(l))
print (a==l)
diff --git a/script/test_nested.py b/script/test_nested.py
index ca17f98..6b0d689 100644
--- a/script/test_nested.py
+++ b/script/test_nested.py
@@ -1,3 +1,4 @@
+print "->START"
run("test_data_txt")
time.sleep(0.5)
run("test_data_txt")
@@ -7,4 +8,5 @@ time.sleep(0.5)
run("test_data_txt")
time.sleep(0.5)
run("test_data_txt")
-set_return(True)
\ No newline at end of file
+print "->FINISH"
+set_return(True)
diff --git a/script/test_plot_type.py b/script/test_plot_type.py
new file mode 100644
index 0000000..00a8071
--- /dev/null
+++ b/script/test_plot_type.py
@@ -0,0 +1,3 @@
+ascan([m1,m2], [ai1], [0.0, 0.0], [1.0, 1.0], [2,4], latency=0.1,zigzag=True, plot_types={"ai1":1}, passes=2)
+lscan(m1, wf1, 0.0, 1.0,5, latency=0.2, plot_types={"wf1":1})
+
diff --git a/script/test_sleep.py b/script/test_sleep.py
index dfc95b4..4b16875 100644
--- a/script/test_sleep.py
+++ b/script/test_sleep.py
@@ -1,2 +1,3 @@
print "Sleeping"
sleep(1.0)
+print "Done"
\ No newline at end of file
diff --git a/script/test_snapshot.py b/script/test_snapshot.py
new file mode 100644
index 0000000..c34ec25
--- /dev/null
+++ b/script/test_snapshot.py
@@ -0,0 +1,64 @@
+###################################################################################################
+# Use of Snapshot class to read and restore the state of devices
+###################################################################################################
+
+#Initial state
+ao1.write(1.0)
+ao2.write(2.0)
+
+#Snapshot creation: list of read-writable devices and an optional name.
+#The name is only needed for saving/loading from files, so multiple different snapshots can be saved at a time.
+#If ommited then name is set to "default", and it will overrite other snapshotws when saved.
+s=Snapshot([ao1, ao2], "snapshot1")
+
+#Take snapshot
+errors = s.take(Snapshot.Mode.PARALLEL)
+if len(errors)>0: #take() returns return errors as a dict device -> exception. If empty then all devices were successfully read.
+ device, e = errors.keys()[0], errors[device]
+ raise Exception("Error taking " + device.name + " - " + str(e.message))
+#Do stuff
+ao1.write(4.0)
+ao2.write(5.0)
+time.sleep(2.0)
+
+#Restore
+errors = s.restore(Snapshot.Mode.PARALLEL)
+if len(errors)>0: #restore() returns errors as a dict device -> exception. If empty then all devices were successfully restored.
+ device, e = errors.keys()[0], errors[device]
+ raise Exception("Error restoring " + device.name + " - " + str(e))
+
+#Mode for take and restore can be:
+#Snapshot.Mode.PARALLEL: all the devices are accessed in parallel, returning all errors.
+#Snapshot.Mode.SERIES: all the devices are accessed sequentially, returning all errors.
+#Snapshot.Mode.STOP_ON_ERROR: all the devices are access sequentially, but stops upon the first error.
+
+#Saving and loading from files
+errors = s.take(Snapshot.Mode.PARALLEL)
+if len(errors)>0:
+ raise errors[0]
+timestamp = s.save()
+
+#Do stuff
+ao1.write(8.0)
+ao2.write(9.0)
+time.sleep(2.0)
+
+#If you had still the reference to s when loading, you could use it to load
+s.load(timestamp) #Loads the snapshot from that timestamp, or the most recent if timestamp is ommited
+s.restore()
+if len(errors)>0:
+ raise errors.values(0)
+
+ao1.write(6.0)
+ao2.write(4.0)
+time.sleep(2.0)
+
+#If you must load from file in a different script, then you must create a snapshot having the same name and set of devices.
+
+s2=Snapshot([ao1, ao2], "snapshot1")
+s2.load() #Loads the last snapshot sved
+s2.restore()
+if len(errors)>0:
+ raise errors.values(0)
+
+