Skip to main content

Helper module for creating EPICS PVAccess servers using p4p

Project description

epicsdev

epicsdev is a small Python toolkit for building EPICS PVAccess servers with p4p.

It is intended for fast development of simulated devices, instrument front ends, and stress-test servers that publish scalars, waveforms, and images.

Background reading: Why Python-based servers are essential for large EPICS facility like future EIC

What epicsdev provides

  • A simple API for defining and hosting PVs
  • Built-in IOC-style helper PVs for status and basic statistics
  • Autosave/restore of writable PV values
  • Optional logging of put operations to a separate PV
  • Example applications for waveforms, images, and text logging

In practice, it combines a Python helper library with a few services commonly expected from EPICS IOCs:

  • Autosave: save writable PV values and restore them on restart
  • IOC-stats-style PVs: host name, uptime, heartbeat, CPU load, and related PVs
  • Put logging: optional forwarding of put activity to a logging PV

Package contents

Module Purpose
epicsdev.epicsdev Core helper functions for creating PVAccess servers
epicsdev.imagegen Synthetic image generator for high-throughput testing
epicsdev.putlog Text logger driven by a writable PV
config/ Example pypeto pages and a Phoebus display

Installation

Install the base package:

python -m pip install epicsdev

Optional tools for GUI pages and plotting:

python -m pip install pypeto pvplot

Quick start

Start the built-in demo server:

python -m epicsdev.epicsdev

The demo uses the default PV prefix:

epicsDev0:

Open the example control page

python -m pypeto -c config -f epicsdev

This page gives you:

  • basic server control
  • live parameter monitoring
  • waveform plotting helpers

Screenshots:

Phoebus display

An example Phoebus display file is included at config/epicsdev.bob. Screenshot: Phoebus display

Minimal programming model

The typical workflow is:

  1. define PVs
  2. initialize the server with init_epicsdev()
  3. start a p4p.server.Server
  4. publish updates from your polling loop

PV definitions are lists with this shape:

[name, description, initial_value, extra]

Where extra is optional and may include keys such as:

  • features: PV features such as writable or discrete
  • type: explicit EPICS type, for example u32 or f32
  • units: engineering units
  • limitLow, limitHigh: write limits
  • setter: callback invoked on writes
  • valueAlarm: value alarm configuration

Normative Type (NT) selection from initial_value

epicsdev selects the underlying PV normative type from initial_value (unless overridden by extra["type"]).

Current behavior:

initial_value features Chosen NT Notes
NumPy ndarray any NTNDArray Current implementation routes any NumPy array to NTNDArray.
list of choices contains D NTEnum Value is stored as {choices, index}; initial index is 0.
scalar (int, float, str) no D NTScalar Default scalar mappings: int -> i32, float -> f32, str -> s.
iterable (for example list/tuple) no D NTScalarArray Element type is inferred from the first item.

Type-code mapping follows p4p scalar codes (for example i32, u32, f32, f64, s8, ...). You can force a specific type using extra["type"].

Examples:

  • 42 -> NTScalar(i32)
  • 3.14 -> NTScalar(f32)
  • [1, 2, 3] -> NTScalarArray(i32)
  • ['OFF', 'ON'] with {"features": "D"} -> NTEnum
  • np.zeros((120, 120), dtype=np.int16) -> NTNDArray

Notes:

  • For discrete PVs (D), autosave stores the enum index rather than the choice text, so updated choice lists can still be restored predictably.
  • For iterable non-NumPy values, keep the initial sequence non-empty so element type inference is unambiguous.

Minimal example:

from p4p.server import Server
from epicsdev.epicsdev import init_epicsdev, publish, pvv, set_server, sleep

pv_defs = [
   ["temperature", "Simulated temperature", 25.0, {"features": "W", "units": "C"}],
   ["waveform", "Example waveform", [0.0], {"units": "V"}],
]

pvs = init_epicsdev("demo0:", pv_defs, verbose=1)
server = Server(providers=[pvs])
set_server("Start")

while True:
   publish("temperature", pvv("temperature") + 0.01)
   if not sleep():
      pass

Example applications

epicsdev.imagegen

imagegen generates synthetic 2D images with a grid of Gaussian blobs and optional per-row PVs.

It publishes:

  • a noisy image
  • PVs that control image size, blob count, blob width, and noise level
  • 10,000 of dynamicaly-changed waveform int16 PVs, each representing 1000-point row.
  • The publishing performance is 55,000 of PVs per second (110 MB/s).

The generated data is intended for high-throughput testing of EPICS clients, transport, and visualization tools.

example

epicsdev.putlog

putlog hosts a writable PV named dump and appends received text to a file.

Start the logger:

python -m epicsdev.putlog /tmp/putlog.txt

By default, the logger prefix is:

putlog0:

Write text to it with:

pvput putlog0:dump "hello from client"

Notes on autosave and helper PVs

When you initialize a server with init_epicsdev(), epicsdev automatically adds a standard set of helper PVs before your application-specific PVs. These include PVs such as:

  • HOSTNAME
  • VERSION
  • HEARTBEAT
  • UPTIME
  • CPU_LOAD
  • status
  • server
  • verbose
  • sleep
  • cycle
  • cycleTime

Writable PV values can be stored in an autosave file and restored on restart. This makes epicsdev practical for interactive development and lab setups where operator-tuned values should survive process restarts.

AI-assisted device support workflow

epicsdev is intentionally small and explicit, which makes it convenient for AI-assisted code generation and device support prototyping.

Typical workflow:

  1. identify a device API or programming manual
  2. define PVs and their setter callbacks
  3. generate a first server implementation from an existing epicsdev example
  4. review, test, and refine

One example built this way is epicsdev_tektronix.

Requirements

  • Python 3.7+
  • p4p>=4.2.2
  • psutil

Optional:

  • pypeto
  • pvplot
  • Phoebus for .bob display files

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

epicsdev-3.2.1.tar.gz (248.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

epicsdev-3.2.1-py3-none-any.whl (18.4 kB view details)

Uploaded Python 3

File details

Details for the file epicsdev-3.2.1.tar.gz.

File metadata

  • Download URL: epicsdev-3.2.1.tar.gz
  • Upload date:
  • Size: 248.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.5

File hashes

Hashes for epicsdev-3.2.1.tar.gz
Algorithm Hash digest
SHA256 ee46c3cf90b91f03f19618f95811d3ff58af331fc88d1a722be03c2d2de0c3b1
MD5 c1f566396f3e341e312de51312ced6b8
BLAKE2b-256 9f42133b633ac52dd36e2f7c38576ebbc26ac0f168d952f4e8cacc22eabbd37a

See more details on using hashes here.

File details

Details for the file epicsdev-3.2.1-py3-none-any.whl.

File metadata

  • Download URL: epicsdev-3.2.1-py3-none-any.whl
  • Upload date:
  • Size: 18.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.11.5

File hashes

Hashes for epicsdev-3.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b6a0e04c54ea4f6390e4cd2210b1a7d7ec7642153cd621a2244f6c9920b73391
MD5 d7abab48e207ea5c0b2fabc23cf4f24d
BLAKE2b-256 4c271b39d7515a4aaa1b37623425dd5edab2de35f9a9c606b71d24d8a4010326

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page