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)
Topic revision: r11 - 17 Dec 2019, UdoKrause
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback