; TestController must be restarted before any changes in this file will be used.
; Manual is here: https://lygte-info.dk/project/TestControllerConfigDevice%20UK.html
; 

; UNTESTED
#metadef
#idString RIGOL TECHNOLOGIES,DL3021,
#name Rigol DL3021
#handle DL3021
#replaceText MaxPower 200

; UNTESTED
#metadef
#idString RIGOL TECHNOLOGIES,DL3021A,
#name Rigol DL3021A
#handle DL3021A
#replaceText MaxPower 200

; UNTESTED
#metadef
#idString RIGOL TECHNOLOGIES,DL3031,
#name Rigol DL3031
#handle DL3031
#replaceText MaxPower 300

#metadef
#idString RIGOL TECHNOLOGIES,DL3031A,
#name Rigol DL3031A
#handle DL3031A
#replaceText MaxPower 300

#meta
#idString RIGOL TECHNOLOGIES,DL30x1x,
#name Rigol DL30x1x
#handle DL30x1x
#port 5555
#driver SCPIx
#Author WS



#notes 
Used Siglent SDL10xxXxx.txt as Template
Only the Operation Modes CI, CU, CR, CP, Battery, OCP, OPP are implemented
todo: implement CON, PUL, TOG mode, short Button

Currently only tested with the DL3021A, which is returned as DL3021A

; A list of possible column name with unit and formatter (SI, Time, Int, D0..D6) 
; Format: #value ColumnName Unit Format {Selector}
; Selector is only used when column layout varies with mode, this often require the use of #cmdMode
#value Voltage V D4
#value Current A D4
#value Power W D3
#value Resistance R D3
#value Capacity mAh D0
#value WattHours Wh D4

; How to poll for data, this is used for table and #values?
; a #askMode, #cmdMode and #prepareSample is used before this string is used.
; Number of returned values must match number of columns defined with #value
; This is a single line command
#askValues MEAS:VOLT:DC?; MEAS:CURR:DC?; MEAS:POW:DC?; MEAS:RES:DC?; MEAS:CAP?; MEAS:WATT?

; Format of answer: f=float, u=remove trailing letters, x=skip, *=Zero upper case values if this value is 0
#askValuesReadFormat ffffff

; Accept this delay when reading values (seconds)
#readingDelay 2

; Mode change have a longer delay on reading values (seconds)
#modeChangeDelay 5

; String to ask about actual meter mode, it is mostly used for DMM's
; This is a single line command
#askMode :SOUR:FUNC?

; When one of these commands are used through the command interface a new configuration will be done before using #askMode
; Only one word for each #mayModifyMode
; Specify command without initial colon and in the shortest possible form
;#mayModifyMode 

; Prepare the meter to response to #askValues
;#prepareSample arm:sour imm;:arm:count 1;:trig:sour imm;:trig:count 1;:trig:samp:count 1;init

; Initial commands to meter when establishing connection, used to disable local control - Sets Instrument and local flag to CC on app connection
#initCmd :SOUR:FUNC CURR;[*OPC];ModeCC

; Final command to meter before breaking connection, used to restore local control
;#finalCmd *CLS;*RST

; Used to turn output off for power supplies, generators and electronic loads
#outputOff :SOUR:INP::STAT OFF

; This type will specify the handle name for the first device with this type
; This makes it possible to easy get generic handle names for a setup, that will work with a script
#interfaceType LOAD

; These function will adjust settings
; These may not even be needed, as I am not referencing the interface variables anywhere, BUT TC might use them internally ?
#interface setVoltage :SOUR:VOLT:LEV:IMM (value)
#interface setCurrent :SOUR:CURR:LEV:IMM (value)
#interface setPower :SOUR:POW:LEV:IMM (value)
#interface setResistance :SOUR:RES:LEV:IMM (value)
#interface setOn :SOUR:INP:STAT (value)
#interface setMode :SOUR:FUNC (value)

; These function will return the value applied with the set function
; These may not even be needed, as I am not referencing the interface variables anywhere, BUT TC might use them internally ?
#interface getVoltage :SOUR:VOLT:LEV:IMM?
#interface getCurrent :SOUR:CURR:LEV:IMM?
#interface getPower :SOUR:POW:LEV:IMM?
#interface getResistance :SOUR:RES:LEV:IMM?
#interface getOn :SOUR:INP:STAT?
#interface getMode :SOUR:FUNC?

; These functions will read the actual values
; These can either contain a number that will reference to a data column or they can contain a command to read the value
; These may not even be needed, as I am not referencing the interface variables anywhere, BUT TC might use them internally ?
#interface readVoltage 0
#interface readCurrent 1
#interface readPower 2
#interface readCAP 3
#interface readWATT 4





;********************************************************
; Handle mode selection tracking
;********************************************************
; Hack to determine and track what mode the instrument is in as there are several parallel modes,
; Siglents weird arrangement makes it impossible to just ask the instrument !
; It intercepts the ModeCC, ModeCV etc. SCPI command sent to the intrument,
; blocks it, and sets a local variable so we can track the last selected mode.
; I am setting the mode in two variables, to allow for switching to the utility pane and back again.
; :SOUR:FUNC - Constant modes - CC,CV,CR,CP
; :SOUR:FUNC:MODE BATT, OCP, OPP
;********************************************************
#scpiCmd ModeCC none?
:setvar: myMode="CC",myMode2="CC"

#scpiCmd ModeCV none?
:setvar: myMode="CV",myMode2="CV"

#scpiCmd ModeCR none?
:setvar: myMode="CR",myMode2="CR"

#scpiCmd ModeCP none?
:setvar: myMode="CP",myMode2="CP"

#scpiCmd ModeBATT none?
:setvar: myMode="BATT",myMode2="BATT"

#scpiCmd ModeOCP none?
:setvar: myMode="OCP",myMode2="OCP"

#scpiCmd ModeOPP none?
:setvar: myMode="OPP",myMode2="OPP"

; handle the myMode query, killing it, and returning the value
#scpiCmd myMode? none?
:readmath: myMode

; handle the myMode2 query, killing it, and returning the value
#scpiCmd myMode2? none?
:readmath: myMode2

;#initCmd :SOUR:FUNC CURR




;********************************************************
; Create the MODE window and functions
;********************************************************
; The ModeCC, ModeCV etc. are used to set the local variable myMode, and are sent out via SCPI, 
; these are then intercepted by SCPIx on the way out and filtered, 
; which then sets the myMode variable value to flag the last selected mode.
; Yes its a hack, but it works !
;********************************************************
; define the Mode button layout
#cmdModeLayout 4 4

; Strings to configure device in different modes
; First parameter must match a #value (4 parameter) and second parameter must match what #askMode returns
; First parameter is also used in shortcut menu

#cmdMode Constant_Current CURRENT
:SOUR:FUNC CURR;[*OPC];ModeCC

#cmdMode Constant_Voltage VOLTAGE
:SOUR:FUNC VOLT;[*OPC];ModeCV

#cmdMode Constant_Resistance RESISTANCE
:SOUR:FUNC RES;[*OPC];ModeCR

#cmdMode Constant_Power POWER
:SOUR:FUNC POW;[*OPC];ModeCP

#cmdMode Battery BATT
:SOUR:FUNC:MODE BATT;[*OPC];ModeBATT

#cmdMode OCP OCP
:SOUR:FUNC:MODE OCP;[*OPC];ModeOCP

#cmdMode OPP OPP
:SOUR:FUNC:MODE OPP;[*OPC];ModeOPP







;*********************************************************
; View selectors for the setup window,
; triggered from the Mode window
; :SOUR:FUNC - Constant modes - CC,CV,CR,CP,BATT, OCP, OPP
;*********************************************************

; reads the myMode variable and uses that to change the Setup window views when modes are changed to reduce clutter.
#cmdSetup selector Mode_settings
:read: myMode?
:updatemodechange:
CC CC.
CV CV.
CR CR.
CP CP.
BATT BATT.
OCP OCP.
OPP OPP.




;*******************************************************************
; Create the SETUP window and functions
;*******************************************************************


#cmdSetup info Active_Mode Info
:read: myMode2?
:readmath: getElement("Constant Current;Constant Voltage;Constant Resistance;Constant Power;Battery;OCP;OPP",listIndex(unQuote(value),"CC CV CR CP BATT OCP OPP"," "),";")
:updatemodechange:
:layout:

;The first number is thickness of line, the second number is percentage of window width.
;The third value is: Solid, Dual, DashedShort, DashedLong, Raised, Sunken
#cmdSetup separator Line Info
2 95 Sunken




;*********************************************************
; CC panel
;*********************************************************
;#cmdSetup info CC_Mode_Settings CC
;:layout:

#cmdSetup number Current CC
:read: :SOUR:CURR:LEV:IMM?
:write: :SOUR:CURR:LEV:IMM
:update: Current
:buttontext: Set
A 0 40

#cmdSetup radio Range CC
:read: :SOUR:CURR:RANG?
:write: :SOUR:CURR:RANG
4A 4
40A 40

#cmdSetup number Slew_Rate CC
:read: :SOUR:CURR:SLEW:BOTH?
:write: :SOUR:CURR:SLEW:BOTH
:buttontext: Set
A/us 0.001 3.00

#cmdSetup number V_on CC
:read: :SOUR:CURR:VON?
:write: :SOUR:CURR:VON
:buttontext: Set
V 0 150

#cmdSetup number V_limit CC
:read: :SOUR:CURR:VLIM?
:write: :SOUR:CURR:VLIM
:buttontext: Set
V 0 155

#cmdSetup number I_limit CC
:read: :SOUR:CURR:ILIM?
:write: :SOUR:CURR:ILIM
:buttontext: Set
A 0 70




;*********************************************************
; CV panel
;*********************************************************
;#cmdSetup info CV_Mode_Settings CV
;:layout:

#cmdSetup number Voltage CV
:read: :SOUR:VOLT:LEV:IMM?
:write: :SOUR:VOLT:LEV:IMM
;:updatemodechange:
:update: Voltage
:buttontext: Set
V 0.000 150.000

#cmdSetup number V_limit CV
:read: :SOUR:VOLT:VLIM?
:write: :SOUR:VOLT:VLIM
:buttontext: Set
V 0 155

#cmdSetup number I_limit CV
:read: :SOUR:VOLT:ILIM?
:write: :SOUR:VOLT:ILIM
:buttontext: Set
A 0 70





;*********************************************************
; CR panel
;*********************************************************
;#cmdSetup info CR_Mode_Settings CR
;:layout:

#cmdSetup number Resistance CR
:read: :SOUR:RES:LEV:IMM?
:write: :SOUR:RES:LEV:IMM
;:updatemodechange:
:update: Resistance
:buttontext: Set
Ohm 0 15000

#cmdSetup radio Range CR
:read: :SOUR:RES:RANG?
:write: :SOUR:RES:RANG
;:updatemodechange:
15Ohm 15
15kOhm 15000

#cmdSetup number V_limit CR
:read: :SOUR:RES:VLIM?
:write: :SOUR:RES:VLIM
:buttontext: Set
V 0 155

#cmdSetup number I_limit CR
:read: :SOUR:RES:ILIM?
:write: :SOUR:RES:ILIM
:buttontext: Set
A 0 70




;*********************************************************
; CP panel
;*********************************************************
;#cmdSetup info CP_Mode_Settings CP
;:layout:

#cmdSetup number Power CP
:read: :SOUR:POW:LEV:IMM?
:write: :SOUR:POW:LEV:IMM
;:updatemodechange:
:update: Power
:buttontext: Set
W 0 MaxPower

#cmdSetup number V_limit CP
:read: :SOUR:POW:VLIM?
:write: :SOUR:POW:VLIM
:buttontext: Set
V 0 155

#cmdSetup number I_limit CP
:read: :SOUR:POW:ILIM?
:write: :SOUR:POW:ILIM
:buttontext: Set
A 0 70




;*********************************************************
; BATT panel
;*********************************************************
;#cmdSetup info CP_Mode_Settings BATT
;:layout:

#cmdSetup number Current BATT
:read: :SOUR:CURR:LEV:IMM?
:write: :SOUR:CURR:LEV:IMM
:update: Current
:buttontext: Set
A 0 40

#cmdSetup radio Range BATT
:read: :SOUR:BATT:RANG?
:write: :SOUR:BATT:RANG
4A 4
40A 40

#cmdSetup number V_stop BATT
:read: :SOUR:BATT:VST?
:write: :SOUR:BATT:VST
:buttontext: Set
V 0 150

#cmdSetup radio V_stop_Enable BATT
:read: :SOUR:BATT:VEN?
:write: :SOUR:BATT:VEN
off 0
on 1

#cmdSetup number C_stop BATT
:read: :SOUR:BATT:CST?
:write: :SOUR:BATT:CST
:buttontext: Set
mAh 0 99999999

#cmdSetup radio C_stop_Enable BATT
:read: :SOUR:BATT:CEN?
:write: :SOUR:BATT:CEN
off 0
on 1

#cmdSetup number T_stop BATT
:read: :SOUR:BATT:TIM?
:write: :SOUR:BATT:TIM
:buttontext: Set
s 0 99999999

#cmdSetup radio T_stop_Enable BATT
:read: :SOUR:BATT:TEN?
:write: :SOUR:BATT:TEN
off 0
on 1

#cmdSetup number V_on BATT
:read: :SOUR:BATT:VON?
:write: :SOUR:BATT:VON
:buttontext: Set
V 0 150




;*********************************************************
; OCP panel
;*********************************************************
;#cmdSetup info OCP_Mode_Settings OCP
;:layout:

#cmdSetup radio Range OCP
:read: :SOUR:OCP:RANG?
:write: :SOUR:OCP:RANG
4A 4
40A 40

#cmdSetup number V_on OCP
:read: :SOUR:OCP:VON?
:write: :SOUR:OCP:VON
:buttontext: Set
V 0 150

#cmdSetup number V_on_delay OCP
:read: :SOUR:OCP:VOND?
:write: :SOUR:OCP:VOND
:buttontext: Set
ms 0 9999

#cmdSetup number Current_step OCP
:read: :SOUR:OCP:IST?
:write: :SOUR:OCP:IST
:buttontext: Set
A 0 40

#cmdSetup number Current_step_delay OCP
:read: :SOUR:OCP:IDEL?
:write: :SOUR:OCP:IDEL
:buttontext: Set
ms 0 9999

#cmdSetup number Current_max OCP
:read: :SOUR:OCP:IMAX?
:write: :SOUR:OCP:IMAX
:buttontext: Set
A 0 40

#cmdSetup number Current_min OCP
:read: :SOUR:OCP:IMIN?
:write: :SOUR:OCP:IMIN
:buttontext: Set
A 0 40

#cmdSetup number V_protection OCP
:read: :SOUR:OCP:VOCP?
:write: :SOUR:OCP:VOCP
:buttontext: Set
V 0 150

#cmdSetup number Overcurrent_protection_time OCP
:read: :SOUR:OCP:TOCP?
:write: :SOUR:OCP:TOCP
:buttontext: Set
us 0 9999

;*********************************************************
; OPP panel
;*********************************************************
;#cmdSetup info OPP_Mode_Settings OPP
;:layout:

#cmdSetup number V_on OPP
:read: :SOUR:OPP:VON?
:write: :SOUR:OPP:VON
:buttontext: Set
V 0 150

#cmdSetup number V_on_delay OPP
:read: :SOUR:OPP:VOND?
:write: :SOUR:OPP:VOND
:buttontext: Set
ms 0 9999

#cmdSetup number Power_set OPP
:read: :SOUR:OPP:PSET?
:write: :SOUR:OPP:PSET
:buttontext: Set
W 0 MaxPower

#cmdSetup number Power_step OPP
:read: :SOUR:OPP:PST?
:write: :SOUR:OPP:PST
:buttontext: Set
W 0 MaxPower

#cmdSetup number Power_step_delay OPP
:read: :SOUR:OPP:PDEL?
:write: :SOUR:OPP:PDEL
:buttontext: Set
ms 0 9999

#cmdSetup number Power_max OPP
:read: :SOUR:OPP:PMAX?
:write: :SOUR:OPP:PMAX
:buttontext: Set
W 0 MaxPower

#cmdSetup number Power_min OPP
:read: :SOUR:OPP:PMIN?
:write: :SOUR:OPP:PMIN
:buttontext: Set
W 0 MaxPower

#cmdSetup number V_protection OPP
:read: :SOUR:OPP:VOPP?
:write: :SOUR:OPP:VOPP
:buttontext: Set
V 0 150

#cmdSetup number Overpower_protection_time OPP
:read: :SOUR:OPP:TOPP?
:write: :SOUR:OPP:TOPP
:buttontext: Set
us 0 9999

;*********************************************************
; General window contents
;*********************************************************
;The first number is thickness of line, the second number is percentage of window width.
;The third value is: Solid, Dual, DashedShort, DashedLong, Raised, Sunken
#cmdSetup separator - 
2 99 Dual


#cmdSetup buttonsOn Load
:read: :SOUR:INP:STAT?
:write: :SOUR:INP:STAT
:updatemodechange:
Off 0
On 1

#cmdSetup buttonsOn Sense
:read: :SOUR:SENS?
:write: :SOUR:SENS
:updatemodechange:
Off 0
On 1




;*********************************************************
; Active Modes - needs improving as the SDL does not use
; a unique mode flag for the actual mod it is currently in
; it has different mode systems all in parallel !
; :SOUR:FUNC - Constant modes - CC,CV,CR,CP
; :SOUR:FUNC:MODE - BATT, OCP, OPP

;*********************************************************


