Device Access in Python
The Python Module devacc
Access to devices in the GSI control system is provided by the Python module
devacc
.
An introduction to device acces in the GSI control system is given on the wiki page
Device Access in the GSI Control System.
Preconditions
To be able to use the device access Python module
devacc
, the environment has to be set up. The set up is described in the
Preconditions-section of the wiki page
CSCOFE Tools Overview.
General
The basic concepts of the module
devacc
are
- For communication with a device in the GSI control system a Python proxy object has to be created. Such proxy objects are defined by the devacc-class
Device
. Instances are identified by the nomenclature of the device, given as a string.
- Device proxy objects of class
Device
provides methods for device access, one for each of the device access operations of the GSI control system, which are read/write/call for synchronous access, requestRead/requestWrite/requestCall for asynchronous access and connectRead/connectWrite/connectCall for subscriptions.
- Information returned as a result of a device access is provided in objects of classes which are related to the operation. Appropriate methods are provided get returned information, like execution status, stamps, and returned device data.
- Device data is exchanged in containers, defined by class
AccData
, and its derivatives.AccData objects implement the main features of Python's list
objects. Data objects, returned as a result of a read operation, can be used as a parameter in a write operation.
- The virtual accelerator is selected by a global element
vrtacc
- Nomenclatures and property names are not case sensitive, they are internally converted to upper case letters.
Online Help
More information on the implemented classes can be found in the Python-help, like:
>>> import devacc
>>> help(devacc)
>>> help(devacc.Device)
>>> help(devacc.Device.read)
Central Class: Device
The
Device
class is the central class to access front-end devices. The objects of this class establish proxies of the front-end devices, identified by the device nomenclature.
>>> d = devacc.Device("gtl1mu1")
The
Device
class objects provide methods for synchronous access (
read/
write/
call), asynchronous requests (
requestRead/
requestWrite/
requestCall) and subscriptions (called conections,
connectRead/
connectWrite/
connectCall).
Example, for synchronous access:
For device GTL1MU1 read property CURRENTS for virtual accelerator 5,
print the value(s) and set for virtual accelerator 11 to the same device and property.
>>> import devacc
>>> d = devacc.Device("gtl1mu1")
>>> devacc.vrtacc.set(5)
>>> r = d.read("currents")
>>> for v in r:
... print v
...
47.11
>>> devacc.vrtacc.set(11)
>>> d.write("currents", r)
Virtual Accelerator Selection
As it was in the former Nodal device access, the selection of the virtual accelerator is a global setting. The virtual accelerator is selected by the global variable
vrtacc
. The virtual accelerator variable provides
set
and
get
methods and is in addition callable. The following two selections of the virtual accelerator are equivalent:
>>> devacc.vrtacc.set(9)
>>> devacc.vrtacc(9)
The current setting of the virtual accelerator can be obtained by the equivalent commands
>>> v = devacc.vrtacc.get()
>>> v = devacc.vrtacc()
Data in Device Access
The access methods of class
Device support property data as well as property parameters. In general, property data (and property parameters) are handled by
AccData
objects. For simplification, on input (data send to a device during write command, of for property parameters), data can be specified as single value or lists of integer or float data.
The following actions on a device proxy object 'd' will result in the same device setting:
>>> d = devacc.Device("gtl1mu1")
>>> d.write("currents", 47.11)
>>> d.write("currents", 47.11)
>>> v = devacc.AccData(47.11)
>>> d.write("currents", v)
Similar mechanisms are supported by the class 'AccData'.
The following constructions of the 'AccData' object 'a' are equivalent:
>>> a = devacc.AccData( 0.815 )
>>> a = devacc.AccData( [0.815] )
>>> t = devacc.AccData( 0.815 )
>>> a = devacc.AccData( t )
Device Parameters
GSI control system allows to exchange two type of data with a device: property data (read or write) and property parameters (always write).
Property parameters can be specified as additional method parameter in device access.
When no property parameter is given, or when it is specified as 'None',
no property parameter is send to the device.
>>> d = devacc.Device("gtl1mu1")
>>> d.read("fieldi") # no parameter
>>> d.read("fieldi", None) # no parameter
>>> d.read("fieldi", 1) # one parameter, value 1
>>> d.read("myprop", [7, 8, 9]) # three parameters, values 7, 8, and 9
>>> d.write("myprop", [1, 2, 3], [8, 9]) # three data values, two parameters
Asynchronous Access and Subscription (Connected Requests)
Such requests set up an action (read, write, call) in the (front-end) device
and return to the caller immediately, providing the result of the set-up operation.
When the action in the front-end device is finished,
the result is returned by a callback object which had to be provided during set-up of the request.
Data Returned in Asynchronous Access and Subcriptions
The callback object used in such access has to implement two methods,
response and error, with one parameter each.
This parameter will be supplied with the result of the asynchronous action:
>>> class MyCallback:
... def response(self, result):
... # evaluate 'result'
... def error(self, result):
... # evaluate 'result'
...
>>> cb = MyCallback()
>>> d = devacc.Device("gtl1mu1")
>>> d.requestRead("currents", cb)
>>> # and now wait for execution of the callback...
To ease access, especially in Python's interactive mode,
the module 'devacc' provides a very simple callback class 'devacc.Callback',
which only prints some of the data provided in the execution of the callback.
For read access, the 'devacc.Callback' class will print the values read from the device.
>>> d = devacc.Device("gtl1mu1")
>>> cb = devacc.Callback()
>>> d.requestRead("currents", cb)
>>> # and now wait for execution of the callback...
Subscriptions
GSI control system provides two types of subscriptions, called in GSI terminology connections:
periodical connections and event connections.
Both subscriptions methods have to be defined by corresponding classes of the module 'devacc',
'ConnectionPeri' specifies periodic connections, 'ConnectionEvent' specifies event connections.
Objects of both connection classes can be used as parameters
in the connectRead/connectWrite/connectCall methods of 'Device' proxy objects.
Example:
Set up a subscription with periodic update (periodic connection) every 3 seconds
with the callback provided by 'devacc':
>>> conn = devacc.ConnectionPeri(3)
>>> cb = devacc.Callback()
>>> d = devacc.Device("gtl1mu1")
>>> d.connectRead("currenti", conn, cb)
>>> # wait for results
Cancelation of Asynchonous Requests and Subscriptions
Each asynchonous or connected command is marked by an identifier which is returned during set-up of the command. Methods 'cancelRequest' or 'disconnect', taking this identifier, cancel the pending command.
>>> conn = devacc.ConnectionPeri(3)
>>> cb = devacc.Callback()
>>> d = devacc.Device("gtl1mu1")
>>> id = d.connectRead("currenti", conn, cb)
>>> import time # for function 'sleep'
>>> time.sleep(10) # wait some time
>>> d.disconnect(id)