documentation

This commit is contained in:
Michael Davidsaver
2013-04-01 09:16:59 -04:00
parent 2cc7c7ce26
commit 4facd4339a
10 changed files with 1105 additions and 23 deletions

View File

@ -0,0 +1,149 @@
Support Modules
===============
An EPICS Record definition for most record types will
include setting the DTYP and INP or OUT fields.
An example with the longin would be: ::
record(longin, "instance:name") {
field(DTYP, "Python Device")
field(INP , "pymodule some other string")
}
This minimal example will attempt to import a Python
module named 'pymodule'. This module is expected
to provide a :func:`build` function.
:func:`build` Function
----------------------
.. function:: build(record, args)
Called when the IOC requests a device support instance
for the given record. This function should return
an object providing the methods of a
:class:`DeviceSupport`.
:param record: The :class:`Record <devsup.db.Record>` instance to which this support
will be attached. May be used to introspect and
query initial field values.
:param args: The remainder of the INP or OUT field string.
::
def build(record, args):
print 'Need device support for', record.name()
print 'Provided:', args
raise RuntimeError("Not support found!")
:class:`DeviceSupport` Interface
--------------------------------
.. class:: DeviceSupport
``DeviceSupport`` is not an actually class. Rather it is a description
of the methods which all Python device support instances must provide.
These methods will be called during the course of IOC processing.
Execptions raised by these methods will be printed to the IOC console,
but will otherwise be ignored.
The module :mod:`devsup.interfaces` provides a Zope Interface
definition by this name which may be referenced.
.. method:: process(record, reason)
:param record: :class:`Record <devsup.db.Record>` from which the request originated.
:param reason: ``None`` or an object provided when processing was requested.
This method is called whenever the associated record needs to be updated
in responce to a request. The souce of this request is typically determined
by the record's SCAN field.
The actions taken by this method will depend heavily the application.
Typically this will include reading or writing values from fields.
Record fields can be access through the provided ``Record`` instance.
.. method:: detach(record)
:param record: :class:`Record <devsup.db.Record>` from which the request originated.
Called when a device support instance is being dis-associated
from its Record. This will occur when the IOC is shutdown.
It can also occur when the INP or OUT field of a record
is modified.
No further calls to this object will be made in relation
to *record*.
.. method:: allowScan(record)
:param record: :class:`Record <devsup.db.Record>` from which the request originated.
:rtype: bool or Callable
Called when an attempt is made to set the record's SCAN field
to "I/O Intr" either at startup, or during runtime.
To permit this the return value of this function must
evaluate to *True*.
If not then the attempt will fail and SCAN will revert to
"Passive".
If a callable object is return, then it will be invoked
when SCAN is changed again, or just before :meth:`detach`
is called.
This method will typically be implemented using the
``add`` method of an I/O scan list object.
(:meth:`IOScanListBlock <devsup.db.IOScanListBlock.add>`
or :meth:`IOScanListThread <devsup.db.IOScanListThread.add>`) ::
class MySup(object):
def __init__(self):
self.a_scan = devsup.db.IOScanListThread()
def allowScan(self, record):
return self.a_scan.add(record)
Example
-------
A simple counter. The processing action is to increment the value
of the VAL field.
The following code should be placed in a file named *counter.py*
which should be placed in the Python module import path. ::
class MySupport(object):
def detach(self, record):
pass # no cleanup needed
def allowScan(self, record):
return False # I/O Intr not supported
def process(self, record, reason):
record.VAL = record.VAL + 1
try:
record.UDF = 0
except AttributeError:
pass # not all record types implement this
def build(record, args):
if not args.startswith('hello'):
raise RuntimeError('%s is not friendly.'%record)
return MySupport()
This support code can then be referenced from records. ::
record(longin, "my:int:counter") {
field(DTYP, "Python Device")
field(INP , "counter hello world")
}
record(ai, "my:float:counter") {
field(DTYP, "Raw Python Device")
field(INP , "counter hello there")
}
The following will fail to associate. ::
record(longin, "my:int:counter") {
field(DTYP, "Python Device")
field(INP , "counter do what I say")
}