Regulation Tango Device Server¶
Launching the server process¶
(base) user@beamline:~/bliss$ conda activate bliss
(bliss) user@beamline:~/bliss$ export TANGO_HOST=localhost:20000
(bliss) user@beamline:~/bliss$ Regulation -?
usage : Regulation instance_name [-v[trace level]]
[-nodb [-dlist <device name list>]]
Instance name defined in database for server Regulation :
test
(bliss) user@beamline:~/bliss$ Regulation test
Serialization mode set to BY_PROCESS
Ready to accept request
The Tango serialization model can be modified using the --serial_model
option
with one of these values {BY_PROCESS, BY_DEVICE, NO_SYNC}
. The default uses BY_PROCESS
.
Tango Server Configuration¶
Tango devices must be declared in database. Jive wizard can be used for that.
Warning
For now, the 2nd field of tango names must contain "regulation"
.
example: idXX/regulation/output_XXX
.
Note
While exporting a Loop object as a server, the associated Input and Output objects must be exported too. Whereas inputs and outputs can be exported alone.
Regulation
└── test
├── Input
| └── id00/regulation/input
| └── properties
| └── beacon_name: thermo_sample_new
├── Output
| └── id00/regulation/output
| └── properties
| └── beacon_name: heater_new
└── Loop
└── id00/regulation/loop
└── properties
└── beacon_name: sample_regulation_new
beacon_name
: the name of the target object that will be served (object must already existing in the Beacon configuration)
Client Configuration (with Beacon)¶
In a yml file declare the regulation client objects.
- class: TangoInput # The class for an Input as a Tango client
module: tango_ds
name: inputds
tango_name: id00/regulation/input # must correspond to the beacon_name
# of the server object declared above
- class: TangoOutput # The class for an Output as a Tango client
module: tango_ds
name: outputds
tango_name: id00/regulation/output # must correspond to the beacon_name
# of the server object declared above
- class: TangoLoop # The class for a Loop as a Tango client
module: tango_ds
name: loopds
tango_name: id00/regulation/loop # must correspond to the beacon_name
# of the server object declared above
Note
Here if you just need the Loop object (loopds), it is not necessary to declare
the Input and Output objects (inputds, outputds). The input and output associated
to the loop are directly available via the loop itself loppds.input
and loopds.output
.
Usage¶
The client object can now be imported from a Bliss session as usual:
BLISS [1]: loopds=config.get("loopds")
BLISS [2]: loopds
Out [2]:
=== Loop: sample_regulation_new ===
controller: RegulMockup_b8830a0c94c22281512932c6386c072b
Input: thermo_sample_new @ 0.000 deg
output: heater_new @ 0.000 Volt
=== Setpoint ===
setpoint: 0.0 deg
ramprate: 1.0 deg/s
ramping: False
=== PID ===
kp: 0.5
ki: 0.2
kd: 0.0
The client objects share the same API than the genuine objects of the regulation framework for all standard methods.
BLISS [3]: loopds.setpoint
Out [3]: 0.0
BLISS [4]: loopds.setpoint = 10
BLISS [5]: loopds.ramprate
Out [5]: 1.0
BLISS [6]: loopds.axis
Out [6]: AXIS:
name (R): sample_regulation_new_axis
unit (R): deg
offset (R): 0.00000
backlash (R): 0.00000
sign (R): 1
steps_per_unit (R): 1.00
tolerance (R) (to check pos. before a move): 0.05
limits (RW): Low: -inf High: inf
dial (RW): 10.00841
position (RW): 10.00841
state (R): READY (Axis is READY)
acceleration: None
velocity: None
Controller: SoftController_140570134546000 (SoftController)
ERROR: Unable to get axis info from controller
ENCODER:
None
BLISS [7]: loopds.input
Out [7]:
=== Input: thermo_sample_new ===
controller: RegulMockup_b8830a0c94c22281
channel: A
current value: 10.002 deg
BLISS [8]: loopds.output
Out [8]:
=== Output: heater_new ===
controller: RegulMockup_b8830a0c94c22281
channel: A
current value: 9.014 Volt
=== Output.set_value ramping options ===
ramprate: 0.0
ramping: False
limits: (0.0, 100.0)
BLISS [9]: loopds.output.read()
Out [9]: 11.74790420829029
BLISS [10]: loopds.input.read()
Out [10]: 10.01260308409754
For custom methods that are specific to one kind of regulation device
(e.g. Lakshore, Eurotherm), the client objects provide an access to the
DeviceProxy
via the device
attribute:
BLISS [11]: loopds.device
Out [11]: DeviceProxy(id00/regulation/loop,140570137683760)
The DeviceProxy
of each client regulation objects has 4 different methods to
access non-standard-API methods:
@command(dtype_in=str, dtype_out=str)
def target_getattr(self, attr):
""" get a property of the served object.
'attr' is the attribute as a string.
return the attribute value as a string.
"""
@command(dtype_in=str, dtype_out=str)
def target_setattr(self, attr_and_value):
""" set a property of the served object.
'attr_and_value' is a string of the form 'attibute value'.
'value' is converted to a float if possible.
"""
@command(dtype_in=str, dtype_out=str)
def target_call(self, cmd):
""" Call a method of the served object.
'cmd' is a string of the form 'method arg' (arg is optional).
It acts as an equivalent of 'obj.method(arg)'.
'arg' is converted to a float if possible.
"""
@command(dtype_in=str, dtype_out=str)
def controller_cmd(self, cmd):
""" Call a method of the controller of the served object.
'cmd' is a string of the form 'method arg' (arg is optional).
It acts as an equivalent of 'obj.controller.method(arg)'.
'arg' is converted to a float if possible.
"""
BLISS [12]: loopds.device.target_getattr('unit') # Lakeshore Loop
Out [12]: 'K' # specific property
BLISS [13]: loopds.device.target_setattr('unit C') # Lakeshore Loop
Out [13]: 'None' # specific property
BLISS [14]: loopds.device.target_call('hold') # Linkam Loop
Out [14]: 'None' # specific method
BLISS [15]: loopds.device.controller_cmd('purge') # Oxford controller
Out [15]: 'RegulMockup_b883cc072b.purge ' # specific method
BLISS [16]: loopds.device.controller_cmd('cool 10') # Oxford controller
Out [16]: 'RegulMockup_b883cc072b.cool @ 10.0' # specific method with arg
It is also possible to send raw commands to the controller hardware via the
standard WRraw
method that exist on each regulation controller:
BLISS [17]: loopds.device.controller_cmd('WRraw MOUT 10.2') # Lakeshore hardware
Out [17]: 'RegulMockup_b883cc072b.WRraw MOUT 10 1' # controller specific cmd