TOPAS example

This commit is contained in:
2025-12-11 16:19:19 +01:00
parent cadc46381d
commit 4a70231ccf
5 changed files with 625 additions and 0 deletions
+110
View File
@@ -0,0 +1,110 @@
#caqtdm -macro IOC=SLAAR21-LTOP-TOPHE SLG-L-TOPAS-MAIN.ui&
#caqtdm -macro SYS1=SLAAR21-LTOP-TOPHE,SYS2=SLAAR21-LTOP-TOPNOPA,SYS3=SLAAR21-LTOP-TOPTWS,SYS4=SLAAR21-LTOP-TOPTWP SLAAR21-L-TOPAS-MAIN-ALL.ui&
#$(TOP_DEV) =16448
#$(HOST) =129.129.243.70:8004
#$(TOPAS) =Device to talk to from startup script
#-------------------------- T O P A S - H E -----------------------------------------129.129.243.70:8004/16448
file TOPAS_API_MAIN.template
{pattern
{ SYSTEM DESC TOP_DEV HOST TOPAS NUM_MOTORS }
{ "SLAAR21-LTOP-TOPHE" "TOPAS-HE" "16448" "129.129.243.70:8004" "TOPAS8004" "12" }
}
file TOPAS_API_MOTOR.template
{pattern
{ SYSTEM DESC TOP_DEV HOST TOPAS MOT }
{ "SLAAR21-LTOP-TOPHE" "system" "16448" "129.129.243.70:8004" "TOPAS8004" "1" }
{ "SLAAR21-LTOP-TOPHE" "system" "16448" "129.129.243.70:8004" "TOPAS8004" "2" }
{ "SLAAR21-LTOP-TOPHE" "system" "16448" "129.129.243.70:8004" "TOPAS8004" "3" }
{ "SLAAR21-LTOP-TOPHE" "system" "16448" "129.129.243.70:8004" "TOPAS8004" "4" }
{ "SLAAR21-LTOP-TOPHE" "system" "16448" "129.129.243.70:8004" "TOPAS8004" "5" }
{ "SLAAR21-LTOP-TOPHE" "system" "16448" "129.129.243.70:8004" "TOPAS8004" "6" }
{ "SLAAR21-LTOP-TOPHE" "system" "16448" "129.129.243.70:8004" "TOPAS8004" "7" }
{ "SLAAR21-LTOP-TOPHE" "system" "16448" "129.129.243.70:8004" "TOPAS8004" "8" }
{ "SLAAR21-LTOP-TOPHE" "system" "16448" "129.129.243.70:8004" "TOPAS8004" "9" }
{ "SLAAR21-LTOP-TOPHE" "system" "16448" "129.129.243.70:8004" "TOPAS8004" "10" }
{ "SLAAR21-LTOP-TOPHE" "system" "16448" "129.129.243.70:8004" "TOPAS8004" "11" }
{ "SLAAR21-LTOP-TOPHE" "system" "16448" "129.129.243.70:8004" "TOPAS8004" "12" }
}
#----------------------------------------- N O P A ----------------------------------129.129.243.70:8016/N05034
file TOPAS_API_MAIN.template
{pattern
{ SYSTEM DESC TOP_DEV HOST TOPAS NUM_MOTORS }
{ "SLAAR21-LTOP-TOPNOPA" "TOPAS-NOPA" "N05034" "129.129.243.70:8016" "TOPAS8016" "4" }
}
file TOPAS_API_MOTOR.template
{pattern
{ SYSTEM DESC TOP_DEV HOST TOPAS MOT }
{ "SLAAR21-LTOP-TOPNOPA" "system" "N05034" "129.129.243.70:8016" "TOPAS8016" "1" }
{ "SLAAR21-LTOP-TOPNOPA" "system" "N05034" "129.129.243.70:8016" "TOPAS8016" "2" }
{ "SLAAR21-LTOP-TOPNOPA" "system" "N05034" "129.129.243.70:8016" "TOPAS8016" "3" }
{ "SLAAR21-LTOP-TOPNOPA" "system" "N05034" "129.129.243.70:8016" "TOPAS8016" "4" }
}
#----------------------------------------- T W I N - S E E D ----------------------------------129.129.243.70:8012/A8729
file TOPAS_API_MAIN.template
{pattern
{ SYSTEM DESC TOP_DEV HOST TOPAS NUM_MOTORS }
{ "SLAAR21-LTOP-TOPTWS" "TWIN-SEED" "A8729" "129.129.243.70:8012" "TOPAS8012" "8" }
}
file TOPAS_API_MOTOR.template
{pattern
{ SYSTEM DESC TOP_DEV HOST TOPAS MOT }
{ "SLAAR21-LTOP-TOPTWS" "system" "A8729" "129.129.243.70:8012" "TOPAS8012" "1" }
{ "SLAAR21-LTOP-TOPTWS" "system" "A8729" "129.129.243.70:8012" "TOPAS8012" "2" }
{ "SLAAR21-LTOP-TOPTWS" "system" "A8729" "129.129.243.70:8012" "TOPAS8012" "3" }
{ "SLAAR21-LTOP-TOPTWS" "system" "A8729" "129.129.243.70:8012" "TOPAS8012" "4" }
{ "SLAAR21-LTOP-TOPTWS" "system" "A8729" "129.129.243.70:8012" "TOPAS8012" "5" }
{ "SLAAR21-LTOP-TOPTWS" "system" "A8729" "129.129.243.70:8012" "TOPAS8012" "6" }
{ "SLAAR21-LTOP-TOPTWS" "system" "A8729" "129.129.243.70:8012" "TOPAS8012" "7" }
{ "SLAAR21-LTOP-TOPTWS" "system" "A8729" "129.129.243.70:8012" "TOPAS8012" "8" }
}
#----------------------------------------- T W I N - P U M P ----------------------------------129.129.243.70:8000/18729
file TOPAS_API_MAIN.template
{pattern
{ SYSTEM DESC TOP_DEV HOST TOPAS NUM_MOTORS }
{ "SLAAR21-LTOP-TOPTWP" "TWIN-PUMP" "18729" "129.129.243.70:8000" "TOPAS8000" "6" }
}
file TOPAS_API_MOTOR.template
{pattern
{ SYSTEM DESC TOP_DEV HOST TOPAS MOT }
{ "SLAAR21-LTOP-TOPTWP" "system" "18729" "129.129.243.70:8000" "TOPAS8000" "1" }
{ "SLAAR21-LTOP-TOPTWP" "system" "18729" "129.129.243.70:8000" "TOPAS8000" "2" }
{ "SLAAR21-LTOP-TOPTWP" "system" "18729" "129.129.243.70:8000" "TOPAS8000" "3" }
{ "SLAAR21-LTOP-TOPTWP" "system" "18729" "129.129.243.70:8000" "TOPAS8000" "4" }
{ "SLAAR21-LTOP-TOPTWP" "system" "18729" "129.129.243.70:8000" "TOPAS8000" "5" }
{ "SLAAR21-LTOP-TOPTWP" "system" "18729" "129.129.243.70:8000" "TOPAS8000" "6" }
}
@@ -0,0 +1,14 @@
require "stream"
epicsEnvSet STREAM_PROTOCOL_PATH :protocols:./cfg
#All devices on same machine, but use different ports
drvAsynIPPortConfigure ("TOPAS8000", "129.129.243.70:8000 HTTP")
drvAsynIPPortConfigure ("TOPAS8004", "129.129.243.70:8004 HTTP")
drvAsynIPPortConfigure ("TOPAS8012", "129.129.243.70:8012 HTTP")
drvAsynIPPortConfigure ("TOPAS8016", "129.129.243.70:8016 HTTP")
+160
View File
@@ -0,0 +1,160 @@
# Main Template for TOPAS API
# Communications for generic functions..
# i.e. Wavelength, Shutter control NOT for motors
#Typical curl commands
#curl http://129.129.243.70:8012/A8729/v0/PublicAPI/Motors/AllProperties
#need some macros:-
#$(TOP_DEV) =A8729
#$(HOST) =129.129.243.70:8012
#$(TOPAS) =Device to talk to from startup script
record(stringin, "$(SYSTEM):HOST"){
field(DESC, "$(DESC)")
field(VAL, "$(HOST)")
}
record(stringin, "$(SYSTEM):TOPAS_DEVICE"){
field(DESC, "Topas Device")
field(VAL, "$(TOP_DEV)")
}
record(ai, "$(SYSTEM):NUM_MOTORS"){
field(DESC, "number of motors")
field(VAL, "$(NUM_MOTORS=20)")
}
###########################################
# Counter
###########################################
record(ao,"$(SYSTEM):LIVE_CNTR_ENA"){
field(DESC, "0 to stop counter")
field(VAL, "1")
}
record(calcout,"$(SYSTEM):LIVE_CNTR"){ #for live readings ctsly
field(DESC, "Cycle round all channels")
field(SCAN, ".5 second")
field(INPA, "$(SYSTEM):LIVE_CNTR")
field(INPB, "$(SYSTEM):LIVE_CNTR_ENA")
field(INPC, "$(SYSTEM):NUM_MOTORS")
field(CALC, "B=0?-5:A<C?A+1:0")
}
record(calcout, "$(SYSTEM):SYS_LIVE_READ"){ #Trigger a live reading
field(DESC, "Read live data")
field(INPA, "$(SYSTEM):LIVE_CNTR CP")
field(INPB, "0")
field(CALC, "A=B?1:0")
field(OOPT, "When Non-zero")
field(OUT, "$(SYSTEM):GET_WAVELENGTH.PROC PP")
}
record(calcout, "$(SYSTEM):TRIG_SEQ"){ #Trigger an init sequence to reread everything
field(DESC, "reread settings")
field(PINI, "YES")
field(INPA, "$(SYSTEM):TRIG_SEQ")
field(CALC, "A+1")
field(FLNK, "$(SYSTEM):INTERACTION")
}
# -------- Wavelength
# will all Topas to choose the interaction type
record(ao, "$(SYSTEM):GET_WAVELENGTH"){
field(DESC, "Read motor n pos")
field(DTYP, "stream")
field(EGU, "nm")
field(PREC, "2")
field(OUT, "@topas_api GetWavelength($(SYSTEM),$(HOST),$(TOP_DEV)) $(TOPAS)")
# File Unit
field(FLNK, "$(SYSTEM):GET_SHUTTER")
}
record(ao, "$(SYSTEM):SET_WAVELENGTH"){
field(DESC, "Set the wavelength")
field(DTYP, "stream")
field(EGU, "steps")
field(PREC, "2")
field(OUT, "@topas_api SetWavelength($(SYSTEM),$(HOST),$(TOP_DEV)) $(TOPAS)")
# File Unit
field(FLNK, "$(SYSTEM):INTERACTION")
}
record(stringin, "$(SYSTEM):INTERACTION"){
field(DESC, "Interaction")
field(DTYP, "stream")
field(INP, "@topas_api Interaction($(SYSTEM),$(HOST),$(TOP_DEV)) $(TOPAS)")
# File Unit
field(FLNK, "$(SYSTEM):GET_WAVELENGTH")
}
#----------- Shutter ---------
record(ao, "$(SYSTEM):OPEN_SHUTTER"){
field(DESC, "Read motor n pos")
field(DTYP, "stream")
field(EGU, "steps")
field(PREC, "0")
field(OUT, "@topas_api OpenShutter($(SYSTEM),$(HOST),$(TOP_DEV)) $(TOPAS)")
# File Unit
field(FLNK, "$(SYSTEM):GET_SHUTTER")
}
record(ao, "$(SYSTEM):CLOSE_SHUTTER"){
field(DESC, "Read motor n pos")
field(DTYP, "stream")
field(EGU, "steps")
field(PREC, "0")
field(OUT, "@topas_api CloseShutter($(SYSTEM),$(HOST),$(TOP_DEV)) $(TOPAS)")
# File Unit
field(FLNK, "$(SYSTEM):GET_SHUTTER")
}
record(mbbi, "$(SYSTEM):GET_SHUTTER"){
field(DESC, "shutter position ")
field(DTYP, "stream")
field(INP, "@topas_api GetShutterState($(SYSTEM),$(HOST),$(TOP_DEV)) $(TOPAS)")
field(NOBT, "2")
field(ZRVL, "0")
field(ONVL, "1")
field(ZRST, "Shut")
field(ONST, "Open")
}
# ----------------------------------
record(ao, "$(SYSTEM):STOP_ALL"){
field(DESC, "stop all")
field(DTYP, "stream")
field(OUT, "@topas_api StopAll($(SYSTEM),$(HOST),$(TOP_DEV)) $(TOPAS)")
# File Unit
}
+149
View File
@@ -0,0 +1,149 @@
# Motor Template for TOPAS API
# Communications for motor specific functions..
# i.e. read / set position
#Typical curl commands
#curl -X PUT http://129.129.243.70:8004/16448/v0/PublicAPI/Motors/TargetPosition?id=1 -H "Content-Type: application/json" -d "9796"
#need some macros:-
#$(TOP_DEV) =16448
#$(HOST) =129.129.243.70:8004
#$(TOPAS) =Device to talk to from startup script
#$(MOT) =Motor number after the id= [1..N]
###########################################
# Counter
###########################################
record(calcout, "$(SYSTEM):MOT$(MOT)_LIVE_READ"){ #Trigger a live reading
field(DESC, "Read live data")
field(INPA, "$(SYSTEM):LIVE_CNTR CP")
field(INPB, "$(MOT)")
field(CALC, "A=B?1:0")
field(OOPT, "When Non-zero")
field(OUT, "$(SYSTEM):MOT$(MOT)_GET_POS_CAL.PROC PP")
}
#Ttile and Unit - read once at beginning or if triggered
record(ai, "$(SYSTEM):MOT$(MOT)_TRIG_SEQ"){
field(DESC, "trigger init seq")
field(INP, "$(SYSTEM):TRIG_SEQ CP")
field(FLNK, "$(SYSTEM):MOT$(MOT)_INIT_SEQ")
}
record(seq, "$(SYSTEM):MOT$(MOT)_INIT_SEQ"){
field(DESC, "Startup sequence")
field(SCAN, "Passive")
field(SELM, "All")
field(PINI, "YES")
field(DLY1, "$(MOT)")
field(DO1, "1")
field(LNK1, "$(SYSTEM):MOT$(MOT)_TITLE.PROC")
}
record(stringin, "$(SYSTEM):MOT$(MOT)_TITLE"){
field(DESC, "Read motor n pos")
field(DTYP, "stream")
field(INP, "@topas_api MotorTitleUnit($(SYSTEM),$(HOST),$(TOP_DEV),$(MOT)) $(TOPAS)")
# File Unit
}
record(stringin, "$(SYSTEM):MOT$(MOT)_UNIT"){ #currently not working as there are 2 UnitNames in response
field(DESC, "hold motor unit")
}
# -------- Positions
record(ao, "$(SYSTEM):MOT$(MOT)_GET_POS_CAL"){
field(DESC, "Read motor n pos")
field(DTYP, "stream")
field(EGU, "Units")
field(PREC, "3")
field(OUT, "@topas_api ActualPosUnits($(SYSTEM),$(HOST),$(TOP_DEV),$(MOT)) $(TOPAS)")
field(FLNK, "$(SYSTEM):MOT$(MOT)_GET_POS")
}
record(ao, "$(SYSTEM):MOT$(MOT)_GET_POS"){
field(DESC, "Read motor n pos")
field(DTYP, "stream")
field(EGU, "steps")
field(PREC, "0")
field(OUT, "@topas_api ActualPos($(SYSTEM),$(HOST),$(TOP_DEV),$(MOT)) $(TOPAS)")
}
record(ao, "$(SYSTEM):MOT$(MOT)_SET_ABS_STEPS"){
field(DESC, "Set absolute pos")
field(DTYP, "stream")
field(EGU, "units")
field(PREC, "0")
field(OUT, "@topas_api SetAbsSteps($(SYSTEM),$(HOST),$(TOP_DEV),$(MOT)) $(TOPAS)")
field(FLNK, "$(SYSTEM):MOT$(MOT)_GET_POS_CAL")
}
record(ao, "$(SYSTEM):MOT$(MOT)_SET_REL_STEPS"){
field(DESC, "set relative pos")
field(DTYP, "stream")
field(EGU, "units")
field(PREC, "0")
field(OUT, "@topas_api SetRelSteps($(SYSTEM),$(HOST),$(TOP_DEV),$(MOT)) $(TOPAS)")
field(FLNK, "$(SYSTEM):MOT$(MOT)_GET_POS_CAL")
}
#- Tweaking
record(ao, "$(SYSTEM):MOT$(MOT)_TW_VAL"){
field(DESC, "tweak value (steps)")
field(EGU, "steps")
field(VAL, "1")
}
record(calcout, "$(SYSTEM):MOT$(MOT)_TWL"){ #Tweak left
field(DESC, "tweak left (lower)")
field(INPA, "$(SYSTEM):MOT$(MOT)_TW_VAL")
field(CALC, "-A")
field(OUT, "$(SYSTEM):MOT$(MOT)_SET_REL_STEPS PP")
}
record(calcout, "$(SYSTEM):MOT$(MOT)_TWR"){ #Tweak right
field(DESC, "tweak right (raise)")
field(INPA, "$(SYSTEM):MOT$(MOT)_TW_VAL")
field(CALC, "A")
field(OUT, "$(SYSTEM):MOT$(MOT)_SET_REL_STEPS PP")
}
#- Home
record(ao, "$(SYSTEM):MOT$(MOT)_HOME"){
field(DESC, "stop motor")
field(DTYP, "stream")
field(OUT, "@topas_api HomeMotor($(SYSTEM),$(HOST),$(TOP_DEV),$(MOT)) $(TOPAS)")
}
+192
View File
@@ -0,0 +1,192 @@
#
# Commands to communicate with TOPAS API
# Tested with WinTOPAS 4 1.153.2.0
#PollPeriod = 4000; #readall on 5 second scan
ReplyTimeout = 500;
ReadTimeout = 500;
WriteTimeout = 500;
LockTimeout = 500;
OutTerminator= "";
InTerminator = "";
#InTerminator = LF;
ExtraInput = Ignore;
TestComms {
out "GET / HTTP/1.1\r\n\r\n"; #test read - should reply with 'Remote control REST app (Jun 3 2019).'
in "%#s";
}
#[saresb-cons-01 ~]$ curl -X PUT http://129.129.243.70:8004/16448/v0/PublicAPI/ShutterInterlock/OpenShutter --data ''
#[saresb-cons-01 ~]$ curl -X PUT http://129.129.243.70:8004/16448/v0/PublicAPI/ShutterInterlock/^Cutter --data ''
#[saresb-cons-01 ~]$ curl -X PUT http://129.129.243.70:8004/16448/v0/PublicAPI/ShutterInterlock/CloseShutter --data ''
#curl http://129.129.243.70:8000/18729/v0/PublicAPI/ShutterInterlock/IsInterlockOpen 5<0d><0a>false<00>
#paramerters passed from record $(SYSTEM),$(HOST),$(TOP_DEV),$(MOT)
#Shutter Control
GetShutterState { out "GET /\$3/v0/PublicAPI/ShutterInterlock/IsShutterOpen\r\n\r\n"; #Shutter state
InTerminator = "\r\n";
in "%*s";in "%{false|true}";
}
OpenShutter { OutTerminator = CR LF;
out "PUT /\$3/v0/PublicAPI/ShutterInterlock/OpenShutter HTTP/1.1";
out "Host: \$2";
# out "Accept: */*";
# out "Content-Type: application/x-www-form-urlencoded";
out "Content-Length: 4";
out "";
out "{''}\r\n";
wait 100;
}
CloseShutter { OutTerminator = CR LF;
out "PUT /\$3/v0/PublicAPI/ShutterInterlock/CloseShutter HTTP/1.1";
out "Host: \$2";
out "Content-Length: 4";
out "";
out "{''}\r\n";
wait 100;
}
#Wavelength control - curl http://129.129.243.70:8000/18729/v0/PublicAPI/Optical/WavelengthControl/Output/Wavelength
GetWavelength { out "GET /\$3/v0/PublicAPI/Optical/WavelengthControl/Output/Wavelength\r\n\r\n"; #Wavelength
InTerminator = "\r\n";
in "%*s";in "%f";
}
SetWavelength { OutTerminator = CR LF;
out "PUT /\$3/v0/PublicAPI/Optical/WavelengthControl/SetWavelength HTTP/1.1";
out "Host: \$2";
out "Content-Type: application/json";
out "Content-Length: 240";#233
out "";
out '{ "DontTouchShutterOnInteractionChange": false,"IgnoreSeparation": false, "SetForBackground": false, "Wavelength": %f,"Interaction": "*","Priorities":[{"Priority": 30,"Type": "art"},{"Priority": 63, "Type": "dreamcatcher" } ] } \r\n';
# 12345678901234567890123456789012345678901234567 501234567890123456789012345678901234567890123456 10012345678901234567890123456789012345678901234567 5012345678901234567890123456789012345678901234567 5012345678901234567890123456789012345
wait 100;
}
Interaction { out "GET /\$3/v0/PublicAPI/Optical/WavelengthControl/Output\r\n\r\n"; #Title
InTerminator = "\r\n";
in "%*s";
in "%*/" 0x22 "ActualInteraction" 0x22 ":" 0x22 "/%[^" 0x22 "]"; #Read chars while not an " for title
}
#Motors
MotorTitle { out "GET /\$3/v0/PublicAPI/Motors/?id=\$4\r\n\r\n"; #Title
InTerminator = "\r\n";
in "%*s";
in "%*/" 0x22 "Title" 0x22 ":" 0x22 "/%[^" 0x22 "]"; #Read chars while not an " for title
}
MotorTitleUnit { out "GET /\$3/v0/PublicAPI/Motors/?id=\$4\r\n\r\n"; #read both Title and unit
InTerminator = "\r\n";
in "%*s";
in "%*/" 0x22 "Title" 0x22 ":" 0x22 "/%[^" 0x22 "]" 0x22 "," 0x22 "UnitName" 0x22 ":" 0x22 "%(\$1:MOT\$4_UNIT)[^" 0x22 "]" ; #Read chars while not an " for title
}
#MotorUnit { out "GET /\$3/v0/PublicAPI/Motors/?id=\$4\r\n\r\n"; #UnitName
# InTerminator = "\r\n";
# in "%*s";
# in "%*/" 0x22 "Title" 0x22 ":" 0x22 "/%[^" 0x22 "]," 0x22 "UnitName" 0x22 ":" 0x22 "/%[^" 0x22 "]" ;
# #in "%*/" 0x22 "UnitName" 0x22 ":" 0x22 "/%[^" 0x22 "]"; #there are 2 "UnitNames" - problem is finding he second one...
# }
ActualPos { out "GET /\$3/v0/PublicAPI/Motors/?id=\$4\r\n\r\n"; #position in steps
InTerminator = "\r\n";
in "%*s";
in "%*/ActualPosition" 0x22 ":/%f"; #floating pt
}
ActualPosUnits { out "GET /\$3/v0/PublicAPI/Motors/?id=\$4\r\n\r\n"; #position in egu
InTerminator = "\r\n";
in "%*s";
in "%*/ActualPositionInUnits" 0x22 ":/%f"; #floating pt
}
# curl -X PUT http://129.129.243.70:8004/16448/v0/PublicAPI/Motors/TargetPosition?id=1 -H "Content-Type: application/json" -d "9796"
SetAbsSteps { OutTerminator = CR LF;
out "PUT /\$3/v0/PublicAPI/Motors/TargetPosition?id=\$4 HTTP/1.1";
out "Host: \$2";
out "Content-Type: application/json";
out "Content-Length: 8";
out "";
out "%d \r\n";
wait 100;
}
SetRelSteps { OutTerminator = CR LF;
out "PUT /\$3/v0/PublicAPI/Motors/TargetPositionRelative?id=\$4 HTTP/1.1";
out "Host: \$2";
out "Content-Type: application/json";
out "Content-Length: 6";
out "";
out "%d \r\n";
wait 100;
}
#Uri: http://129.129.243.70:8016/N05034/v0/PublicAPI/Motors/StopAll
#Home a motor
#Uri: http://129.129.243.70:8016/N05034/v0/PublicAPI/Motors/Home?id={motorIndex}
HomeMotor { OutTerminator = CR LF;
out "POST /\$3/v0/PublicAPI/Motors/Home?id=\$4 HTTP/1.1";
out "Host: \$2";
#out "Content-Type: application/json";
out "Content-Length: 4";
out "";
out "{''}\r\n";
wait 100;
}
StopAll { OutTerminator = CR LF;
out "POST /\$3/v0/PublicAPI/Motors/StopAll HTTP/1.1";
out "Host: \$2";
# out "Accept: */*";
# out "Content-Type: application/x-www-form-urlencoded";
out "Content-Length: 4";
out "";
out "{''}\r\n";
wait 100;
}