Epics PV Holder (V7 Protocol)
EpicsPvHolder is the per-variable bridge object used by the EPICS V7
integration layer. Each holder binds one PyRogue Variable or Command to one
EPICS record and remains owned by EpicsPvServer for the server lifetime.
The holder infers the record type from Variable metadata, uses the softioc
builder to create the backing record, installs the on-put callback, subscribes
to PyRogue variable updates with addListener(), and forwards alarm state
plus display metadata for numeric types.
Type Mapping and Updates
EpicsPvHolder handles several important translation cases:
Integer variables (int, uint) are published as longIn/longOut record pairs (read and write records respectively).
Float variables are published as ai/ao record pairs.
Enum variables are published using softioc enum record support with the Variable’s display choices.
NumPy arrays are published as waveform records.
Numeric scalars carry alarm status and severity when those values are present in the tree.
Strings, lists, dictionaries, and unsupported native types fall back to a string-oriented EPICS representation.
PV Name Hashing and PVA Alias
When the full PV name base:path exceeds EPICS CA’s 60-character limit,
EpicsPvServer assigns the softioc record a hashed short name of the form
tail_XXXXXXXXXX. The holder stores this short name and transparently
manages both the CA record and a PVA alias for the full long name.
For hashed PVs, the holder additionally owns a p4p.server.SharedPV served
under the full long name via a dedicated p4p.server.Server. Variable
updates fan out to both:
The softioc CA record (existing behavior — unchanged for all PVs).
The
SharedPVviapost(), so PVA clients on the long name see the new value immediately.
Writes arriving on the PVA long name are routed through the same _on_put
path as CA writes, updating the PyRogue variable exactly once with no feedback
loop.
PVs whose names are 60 characters or fewer have no SharedPV and behave
identically to before this change.
Command Behavior
PyRogue Commands (LocalCommand and RemoteCommand) are exposed as
longOut records. When an EPICS client writes to the record (caput), the
holder’s on-put callback fires:
If the written value is zero, the command is invoked with no argument.
If the written value is non-zero, the value is forwarded to the command as the
argparameter.
This means commands are invoked with a plain ctxt.put() call from any
EPICS client — no RPC protocol is involved.
Invoking a No-Arg Command
from p4p.client.thread import Context
ctxt = Context('pva')
ctxt.put('MyIoc:MyRoot:MyDevice:ResetCounter', 0)
Invoking a Command With an Argument
from p4p.client.thread import Context
ctxt = Context('pva')
ctxt.put('MyIoc:MyRoot:MyDevice:SetThreshold', 42)
The value 42 is forwarded to the PyRogue command as its argument.
Lifecycle Role in the Server
EpicsPvHolder instances are created and owned by EpicsPvServer. Each
holder binds one tree Variable or Command to one EPICS record and remains
active for the server lifetime.
Logging
EpicsPvHolder reuses the server logger passed in from EpicsPvServer:
Logger name:
pyrogue.EpicsPvServerConfiguration API:
logging.getLogger('pyrogue.EpicsPvServer').setLevel(logging.DEBUG)
Put-handling errors reported by a holder appear under the server logger.
What To Explore Next
Server setup and mapping control: Epics PV Server (V7 Protocol)
API Reference
Generated API page: EpicsPvHolder