lewis.adapters.epics
Members
Class to represent PVs that are bound to an adapter |
|
This adapter provides ChannelAccess server functionality through the pcaspy module. |
|
Inheriting from this class provides an EPICS-interface to a device for use with |
|
The PV-class is used to declare the EPICS-interface exposed by a sub-class of EpicsAdapter. |
|
|
- class lewis.adapters.epics.BoundPV(pv, target, meta_target=None)[source]
Bases:
object
Class to represent PVs that are bound to an adapter
This class is very similar to
Func
, in that it is the result of a binding operation between a user-specifiedPV
-object and a Device and/or Adapter object. Also, it should rarely be used directly. objects are generated automatically byEpicsAdapter
.The binding happens by supplying a
target
-object which has an attribute or a property named according to the property-name stored in the PV-object, and ameta_target
-object which has an attribute named according to the meta_data_property in PV.The properties
read_only
,config
, andpoll_interval
simply forward the data of PV, whiledoc
uses the target object to potentially obtain the property’s docstring.To get and set the value of the property on the target, the
value
-property of this class can be used, to get the meta data dict, there’s ameta
-property.- Parameters:
pv – PV object to bind to target and meta_target.
target – Object that has an attribute named pv.property.
meta_target – Object that has an attribute named pv.meta_data_property.
- property config
Config dict passed on to pcaspy-machinery.
- property doc
Docstring of property on target or override specified on PV-object.
- property meta
Value of the bound meta-property on the target.
- property poll_interval
Interval at which to update PV in pcaspy.
- property read_only
True if the PV is read-only.
- property value
Value of the bound property on the target.
- class lewis.adapters.epics.EpicsAdapter(options=None)[source]
Bases:
Adapter
This adapter provides ChannelAccess server functionality through the pcaspy module.
It’s possible to configure the prefix for the PVs provided by this adapter. The corresponding key in the
options
dictionary is calledprefix
:options = {"prefix": "PVPREFIX:"}
- Parameters:
options – Dictionary with options.
- property documentation
This property can be overridden in a sub-class to provide protocol documentation to users at runtime. By default it returns the indentation cleaned-up docstring of the class.
- handle(cycle_delay=0.1) None [source]
Call this method to spend about
cycle_delay
seconds processing requests in the pcaspy server. Under load, for example when runningcaget
at a high frequency, the actual time spent in the method may be much shorter. This effect is not corrected for.- Parameters:
cycle_delay – Approximate time to be spent processing requests in pcaspy server.
- property is_running
This property indicates whether the Adapter’s server is running and listening. The result of calls to
start_server()
andstop_server()
should be reflected as expected.
- start_server() None [source]
Creates a pcaspy-server.
Note
The server does not process requests unless
handle()
is called regularly.
- stop_server() None [source]
This method must be re-implemented to stop and tear down anything that has been setup in
start_server()
. This method should close all connections to clients that have been established since the adapter has been started.Note
This method may be called multiple times over the lifetime of the Adapter, so it is important to make sure that this does not cause problems.
- class lewis.adapters.epics.EpicsInterface[source]
Bases:
InterfaceBase
Inheriting from this class provides an EPICS-interface to a device for use with
EpicsAdapter
. In the simplest case all that is required is to inherit from this class and override thepvs
-member. It should be a dictionary that contains PV-names (without prefix) as keys and instances of PV as values. The prefix is handled byEpicsAdapter
.For a simple device with two properties, speed and position, the first of which should be read-only, it’s enough to define the following:
class SimpleDeviceEpicsInterface(EpicsInterface): pvs = {"VELO": PV("speed", read_only=True), "POS": PV("position", lolo=0, hihi=100)}
For more complex behavior, the interface could contain properties that do not exist in the device itself. If the device should also have a PV called STOP that “stops the device”, the interface could look like this:
class SimpleDeviceEpicsInterface(EpicsInterface): pvs = { "VELO": PV("speed", read_only=True), "POS": PV("position", lolo=0, hihi=100), "STOP": PV("stop", type="int"), } @property def stop(self): return 0 @stop.setter def stop(self, value): if value == 1: self.device.halt()
Even though the device does not have a property called
stop
(but a method calledhalt
), issuing the command$ caput STOP 1
will achieve the desired behavior, because
EpicsInterface
merges the properties of the device intoSimpleDeviceEpicsInterface
itself, so that it is does not matter whether the specified property in PV exists in the device or the adapter.The intention of this design is to keep device classes small and free of protocol specific stuff, such as in the case above where stopping a device via EPICS might involve writing a value to a PV, whereas other protocols may offer an RPC-way of achieving the same thing.
- property adapter
Adapter type that is required to process and expose interfaces of this type. Must be implemented in subclasses.
- class lewis.adapters.epics.PV(target_property, poll_interval=1.0, read_only=False, meta_data_property=None, doc=None, **kwargs)[source]
Bases:
object
The PV-class is used to declare the EPICS-interface exposed by a sub-class of EpicsAdapter. The
target_property
argument specifies which property of the adapter the PV maps to. To make development easier it can also be a part of the exposed device. If the property exists on both the Adapter-subclass and the device, the former has precedence. This is useful for overriding behavior for protocol specific “quirks”.If the PV should be read only, this needs to be specified via the corresponding parameter. The information about the poll interval is used py EpicsAdapter to update the PV in regular intervals. All other named arguments are forwarded to the pcaspy server’s pvdb, so it’s possible to pass on limits, types, enum-values and so on.
In case those arguments change at runtime, it’s possible to provide
meta_data_property
, which should contain the name of a property that returns a dict containing these values. For example if limits change:class Interface(EpicsInterface): pvs = {"example": PV("example", meta_data_property="example_meta")} @property def example_meta(self): return { "lolim": self.device._example_low_limit, "hilim": self.device._example_high_limit, }
The PV infos are then updated together with the value, determined by
poll_interval
.In cases where the device is accessed via properties alone, this class provides the possibility to expose methods as PVs. A common use case would be to model a getter:
class SomeDevice(Device): def get_example(self): return 42 class Interface(EpicsInterface): pvs = {"example": PV("get_example")}
It is also possible to model a getter/setter pair, in this case a tuple has to be provided:
class SomeDevice(Device): _ex = 40 def get_example(self): return self._ex + 2 def set_example(self, new_example): self._ex = new_example - 2 class Interface(EpicsInterface): pvs = {"example": PV(("get_example", "set_example"))}
Any of the two members in the tuple can be substituted with
None
in case it does not apply. Besides method names it is also allowed to provide callables. Valid callables are for example bound methods and free functions, but also lambda expressions and partials.There are however restrictions for the supplied functions (be it as method names or directly as callables) with respect to their signature. Getter functions must be callable without any arguments, setter functions must be callable with exactly one argument. The
self
of methods does not count towards this.- Parameters:
target_property – Property or method name, getter function, tuple of getter/setter.
poll_interval – Update interval of the PV.
read_only – Should be True if the PV is read only. If not specified, the PV is read_only if only a getter is supplied.
meta_data_property – Property or method name, getter function, tuple of getter/setter.
doc – Description of the PV. If not supplied, docstring of mapped property is used.
kwargs – Arguments forwarded into pcaspy pvdb-dict.