Skip to main content

SGN-EPICS

SGN-EPICS connects SGN-TS streaming pipelines to EPICS Channel Access, using caproto for both client and server roles. It provides four elements:

  • EpicsSource — CA client source: monitors existing PVs (camonitor) and emits their values as a uniformly sampled stream.
  • EpicsIOCSource — CA server source: serves its own soft IOC of writable PVs; values written by external clients (caput) enter the stream.
  • EpicsSink — CA client sink: writes stream values to existing PVs (caput), once per stride.
  • EpicsIOCSink — CA server sink: serves stream values as its own soft IOC of read-only PVs, timestamped with stream time.

Timing model

EPICS PVs update asynchronously; the sources convert them to uniform time series by sample-and-hold: at every tick of a GPS-aligned sample clock (rate, a power of 2, default 16 Hz) the most recent value of each channel is latched into the stream. Ticks before a PV's first value are emitted as gaps (EpicsSource) or carry the initial value (EpicsIOCSource). Channel Access has no history, so the sources are live-only: start must be None; duration/end may bound the stream. Only scalar numeric (or enum) PVs are supported.

The sinks update EPICS once per stride (default 1 s) with the last non-gap sample of each channel; all-gap strides leave the PV holding its previous value.

Data types

Every element accepts channels as either a list of PV names (all float64) or a dict mapping PV name to a numpy dtype. Only dtypes with an exact Channel Access native type are accepted; anything else raises ValueError:

numpy dtype CA native type
uint8 CHAR
int16 SHORT
int32 LONG
float32 FLOAT
float64 DOUBLE

The dtype sets the emitted series dtype (sources), the type values are cast to before writing (EpicsSink), and the served CA native type (IOC elements). ENUM PVs can be monitored by EpicsSource (values arrive as the numeric enum index) but cannot be served, since a bare numpy dtype cannot carry enum strings. String and waveform (array) PVs are not supported.

Alarm severity

EpicsSource honors EPICS alarm severity: monitor events whose severity exceeds max_severity (default 2 = MAJOR) are recorded as gaps, so INVALID-severity values — untrustworthy by definition — never enter the stream, while values merely in MINOR/MAJOR alarm still flow. Set max_severity=3 to disable the filter.

EpicsIOCSink sets severity on the PVs it serves: UDF/INVALID until a channel's first sample arrives (the never-processed convention), TIMEOUT/INVALID while a channel is in gap or after EOS (the last value stays readable but is flagged stale), and NO_ALARM while data flows.

EpicsSink and EpicsIOCSource are unaffected: a Channel Access client write cannot set severity, and caputs to served setpoints carry none.

Caveats

All IOC elements in a process serve their PVs through one shared Channel Access server (one IOC identity: one name-search socket, one TCP port, one beacon stream), started when the first element registers channels and stopped when the last withdraws them. Duplicate PV names across elements are rejected, and interfaces is process-wide: every IOC element must agree on it.

Multiple CA-serving processes on one host still resolve names correctly only when clients search via broadcast addresses (the normal EPICS configuration). With a unicast address list (for example EPICS_CA_ADDR_LIST=127.0.0.1 in loopback test setups) the kernel delivers each search datagram to only one of the sockets sharing the UDP port, so only one process's PVs will resolve — avoid running more than one CA-serving process per host in unicast-only environments. Within one process this is not a concern.

Installation

pip install sgn-epics

Example

Monitor two PVs for 60 seconds and serve a derived value as a soft IOC:

from sgn import Pipeline
from sgnts.transforms import Adder
from sgn_epics import EpicsIOCSink, EpicsSource

src = EpicsSource(
    name="src",
    channels=["H1:PEM-EY_WIND_ROOF_WEATHER_MPH", "H1:PEM-EX_WIND_ROOF_WEATHER_MPH"],
    rate=16,
    duration=60,
)
add = Adder(name="add", sink_pad_names=list(src.channels))
snk = EpicsIOCSink(name="snk", channels=["H1:GRD-WIND_SUM"], stride=1.0)

pipeline = Pipeline()
pipeline.connect(src, add)
pipeline.connect(add, snk, link_map={"H1:GRD-WIND_SUM": add.source_pad_names[0]})
pipeline.run()

Serve writable setpoint PVs as a soft IOC and mirror the values to typed readback PVs on an existing IOC. Operators caput to the served PVs; each value enters the stream sample-and-hold style and is written out once per stride, cast to its channel's dtype (so the offset goes over Channel Access as a native LONG):

from sgn import Pipeline
from sgn_epics import EpicsIOCSource, EpicsSink

settings = EpicsIOCSource(
    name="settings",
    channels={"X2:TST-GAIN": "float32", "X2:TST-OFFSET_CTS": "int32"},
    initial_values={"X2:TST-GAIN": 1.0},
    rate=16,
)
mirror = EpicsSink(
    name="mirror",
    channels={"X2:TST-GAIN_RB": "float32", "X2:TST-OFFSET_CTS_RB": "int32"},
    stride=1.0,
)

Pipeline().connect(
    settings,
    mirror,
    link_map={
        "X2:TST-GAIN_RB": "X2:TST-GAIN",
        "X2:TST-OFFSET_CTS_RB": "X2:TST-OFFSET_CTS",
    },
).run()

Metadata

Release files for sgn-epics 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sgn-epics 0.1.0
File Size Uploaded
sgn_epics-0.1.0.tar.gz 28.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sgn-epics 0.1.0
File Interpreter ABI Platform
sgn_epics-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 65.7 kB

Release files / sgn_epics-0.1.0.tar.gz

Download URL sgn_epics-0.1.0.tar.gz
Size 28.9 kB
Tags Source
SHA-256 checksum
How to use checksums
f9892e38478f0951819ee2d47559ffafa5032f98e043ea82f8e00570514bef0a
BLAKE2b-256 checksum
How to use checksums
63cedae6c057af1f6b0e9a6a277a5e97369e04d909e17b7fd49fd8a7f47347d2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.14

Release files / sgn_epics-0.1.0-py3-none-any.whl

Download URL sgn_epics-0.1.0-py3-none-any.whl
Size 36.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
df7a8b77f8a2b2a6e125484ada432fa605469c944a8e04095d8e7afeebe0617d
BLAKE2b-256 checksum
How to use checksums
182e1b29dac147fcfb88ad9009e14aec529531bf040c0c96ef362f4e47e59f21
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page