Skip to main content

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

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.3.0.tar.gz (251.2 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.3.0-py3-none-any.whl (18.5 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for epicsdev-3.3.0.tar.gz
Algorithm Hash digest
SHA256 2686bcb6df057977cebcf5733d3ce49b06e7efc94413883e30f9b13f12edc5a2
MD5 c03b959858e0248c354e2ffb133eced9
BLAKE2b-256 38f39c9935015d676f747c8f93b8590dcc6d57442c7c92efb35cd40a2fae831e

See more details on using hashes here.

File details

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

File metadata

  • Download URL: epicsdev-3.3.0-py3-none-any.whl
  • Upload date:
  • Size: 18.5 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.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 66ccc32aaaafb78436b6485805222df0dd5370564ecf4950f6bb97d81cfd4073
MD5 3b20f05ab520e778f2217a9bfdc6155b
BLAKE2b-256 8d09d491b20ac29b0333f6a5b3d399b3af1ebcc59ce7ef706f5fd3941fa5f07a

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

3.3.0 This release

2 files

3.2.2

2 files

3.2.1

2 files

3.1.5

2 files

3.1.4

2 files

3.1.3

2 files

3.1.2

2 files

3.1.1

2 files

3.0.1

2 files

2.1.2

2 files

2.1.1

2 files

2.1.0

2 files

2.0.1

2 files

1.0.2

2 files

1.0.1

2 files

1.0.0

2 files

0.0.0

2 files

Supported by

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