General introduction¶
Controller’s capabilities¶
The way a developer should write a controller in BLISS depends on the controller’s capabilities, which can be split in three main categories:
- communicating with a hardware device
- controlling real axes or virtual axes
- performing measurements with counters during a scanning procedure
Controller’s subitems¶
Another important aspect to consider is the eventual declaration of subitems with a name inside the YAML configuration of a controller. A subitem is defined as an object created and managed by its controller. For example, a controller can declare a list of counters with names.
Controller YAML configuration example
- name: controller_name
class: ControllerClass
plugin: generic
counters:
- name: cnt_1
- name: cnt_2
Important note about the configuration key name
In BLISS configuration files, the key name:
means that the corresponding object can be imported in a session
(via the session configuration file or via the config.get('obj_name')
command).
Remember that the name can be chosen by users and must be unique among all configuration files hosted by one
Beacon server.
When importing a subitem in a session, the controller managing this item must be created first. This can be done automatically using the generic plugin in association with the ConfigItemContainer or BlissController base classes.
By inheriting from one of these two base classes, a new controller will be compatible with the generic plugin. It will ensure that subitems are handled safely and that the controller is always created first and only once.
About controller name
In some cases, it is foreseen to only expose subitems to users and keep the top-controller hidden. In that case, the controller name can be omitted in the configuration file. Still, the generic plugin will generate a unique default controller name for its registration inside BLISS internals.
Controller’s info¶
In the shell, while typing the name of an object and pressing enter, BLISS looks if the object class
implements the __info__()
method to display relevant information from a user point of view.
class FooController:
def __info__(self):
txt = "Relevant information about this controller for users"
return txt
Important note
- Any controller or subitem exposed to users in a session should always implement the
__info__()
method - The return type of
__info__()
must be a string (str
) - If not implemented or failing, the standard built-in
__repr__()
method is used instead - The
print
function still uses the standard built-in__str__()
method of the object
Example with an axis named roby
TEST_SESSION [2]: roby
Out [2]: AXIS:
name (R): roby
unit (R): None
offset (R): 0.00000
backlash (R): 0.00000
sign (R): 1
steps_per_unit (R): 10000.00
tolerance (R) (to check pos. before a move): 0.0001
motion_hooks (R): []
limits (RW): Low: -1000.00000 High: 1000.00000 (config Low: -inf High: inf)
dial (RW): 0.00000
position (RW): 0.00000
state (R): READY (Axis is READY)
acceleration (RW): 1000.00000 (config: 1000.00000)
acctime (RW): 2.50000 (config: 2.50000)
velocity (RW): 2500.00000 (config: 2500.00000)
velocity_low_limit (RW): inf (config: inf)
velocity_high_limit (RW): inf (config: inf)
Controller name: Mockup_a402ba9c27fb546fb4a36ae00e497927
MOCKUP AXIS:
this axis (roby) is a simulation axis
ENCODER:
None
CLOSED LOOP:
None
Auto-completion¶
In BLISS shell, pressing the “Tab” key of the keyboard after the statement object.
,
will display the list of object’s attributes (including methods and properties).
All attributes starting with _
are filtered, except if explicitly asked using the object._
statement.
In examples below “↹” represents the action of pressing the “Tab” key of the keyboard
BLISS shell auto-completion
class FooController:
def __init__(self):
self.mode = 0
self._chan = 1
def acquire(self):
return self.send_cmd(f"ACQ")
@property
def voltage(self):
return self.send_cmd("VLT?")
BLISS [1]: foo. ↹
mode
acquire
voltage
BLISS [2]: foo._ ↹
_chan
How to write a controller¶
- Writing a hardware controller (no counters, no axes)
- Writing a motor controller (axes only)
- Writing a virtual axes controller (virtual axes only)
- Writing a multi channel acquisition controller (MCA)
- Writing a shutter controller
- writing a controller with counters