Skip to main content

iocmng — IOC Manager Framework

A pluggable task/job framework for EPICS soft IOC applications on Kubernetes. Provides base classes for continuous tasks and one-shot jobs, a declarative rule/transform engine, and a REST API for dynamic plugin management at runtime.

Key Features

  • TaskBase — base class for continuous, triggered, or reactive tasks
  • JobBase — base class for one-shot jobs returning structured results
  • DeclarativeTask — zero-code tasks driven entirely by config.yaml rules and transforms
  • Wired inputs/outputs — automatically read/write external PVs (poll or monitor)
  • Connection tracking — CONN_INP / CONN_OUT waveform PVs show live CA/PVA connection state per port
  • Declarative rules — safe boolean expressions that fire actuators and set outputs
  • Output latch — latch: true holds an output value until an operator writes CLEAR; latch_dir selects which transition latches (rise / fall / any)
  • ALARM severity — alarm_on: MAJOR|MINOR wires EPICS alarm fields directly from config
  • Transforms — computed outputs using built-in math/statistics/array functions
  • Ring buffers — buffer_size accumulates time-series data for signal processing
  • Built-in function library — mean, std, sqrt, clamp, moving_avg, derivative, and more
  • Safe expression evaluator — AST-validated expressions; no arbitrary code execution
  • REST API — add/remove/restart plugins at runtime from git repos or local paths
  • EPICS soft IOC PVs — every task gets STATUS, MESSAGE, ENABLE, VERSION, CYCLE_COUNT, CLEAR, RESET PVs
  • Per-plugin config.yaml — parameters, directional PVs, rules, transforms in one file
  • PV client abstraction — transparent PVA (p4p) or CA (PyEPICS) access; ENABLE/CLEAR/RESET polled each cycle to catch external writes
  • Plugin validation — syntax, inheritance, abstract methods checked before acceptance
  • Docker image — ready-to-run container with the REST API
  • Standalone runner — iocmng-run for local development without a server
  • Optional Ophyd — device abstraction via ophyd/infn_ophyd_hal

Quick Start

Install

pip install iocmng

# With all optional dependencies
pip install iocmng[all]

Run the API Server

iocmng-server

# With configuration
IOCMNG_PORT=8080 IOCMNG_PREFIX=SPARC:CONTROL iocmng-server

Create a Task (Python)

my_monitor.py

from iocmng import TaskBase

class MyMonitor(TaskBase):
    def initialize(self):
        self.logger.info("Starting monitor")

    def execute(self):
        value = self.get_pv("READING")
        if value and value > self.parameters.get("threshold", 75):
            self.set_pv("ALARM", 1)

    def cleanup(self):
        pass

config.yaml

parameters:
  mode: continuous
  interval: 1.0
  threshold: 75.0

arguments:
  inputs:
    SETPOINT:
      type: float
      value: 50.0
      unit: "%"
      prec: 2
      low: 0
      high: 100
  outputs:
    READING:
      type: float
      value: 0.0
    ALARM:
      type: bool
      value: 0
      znam: "OK"
      onam: "ALARM"

Create a Declarative Task (Zero Code)

No Python needed — all logic lives in config.yaml:

my_interlock.py

from iocmng import DeclarativeTask

class MyInterlock(DeclarativeTask):
    pass

config.yaml

parameters:
  mode: continuous
  interval: 1.0
  pva: false

arguments:
  inputs:
    temp:
      type: float
      value: 0.0
      link: "DEVICE:TEMP"         # Wired to external PV
      link_mode: monitor           # monitor pushes values; poll reads each cycle
      buffer_size: 100             # Keep last 100 readings
    pressure:
      type: float
      value: 0.0
      link: "DEVICE:PRESSURE"
      link_mode: monitor
  outputs:
    avg_temp:
      type: float
      value: 0.0
    alarm:
      type: bool
      value: 0
      znam: "OK"
      onam: "ALARM"
      latch: true                  # Hold value until CLEAR is written
      latch_dir: "rise"            # Latch on 0→1 transition (default)
      alarm_on: MAJOR              # EPICS ALARM severity when output is 1

transforms:
  - output: avg_temp
    expression: "mean(temp_buf)"

rule_defaults:
  alarm: 0

rules:
  - id: OVER_TEMP
    condition: "mean(temp_buf) > 80 or pressure > 2.0"
    message: "Temperature or pressure limit exceeded"
    outputs:
      alarm: 1

Run Standalone (no server)

iocmng-run -m my_interlock --config config.yaml --prefix MY:IOC --name interlock

Deploy via REST API

curl -X POST http://localhost:8080/api/v1/plugins \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-interlock",
    "git_url": "https://github.com/org/my-tasks.git",
    "path": "plugins/interlock/",
    "auto_start": true
  }'

Documentation

Document Description
MANUAL.md Complete reference: architecture, API, configuration, all features
HOWTO.md Step-by-step recipes for common tasks
INSTALL.md Installation and environment setup

Task Modes

Mode Behavior Use Case
continuous execute() loops with interval sleep Monitoring, polling, periodic updates
triggered triggered() called when RUN PV is written Operator-driven actions from CS-Studio
reactive on_input_changed() fires on wired input change Event-driven interlocks, fast response

Built-in Functions

Available in rule conditions and transform expressions:

Category Functions
Math abs, round, sqrt, log, exp, pow, floor, ceil, clamp
Statistics mean, std, variance, median, rms, min, max
Logic any_of, all_of, count_true
Array length, sum_of, diff, last, moving_avg, derivative

Extend with register("my_fn", callable) from iocmng.core.functions.

Default PVs

Every task automatically gets:

PV Type Description
ENABLE boolOut Enable/disable the task (readable and writable from any CA/PVA client)
STATUS mbbIn INIT / RUN / PAUSED / END / ERROR
MESSAGE stringIn Human-readable status
VERSION stringIn Framework or plugin version string
CYCLE_COUNT longIn Cycle counter (continuous / reactive modes)
RUN boolOut Trigger execution (triggered mode)
CLEAR boolOut Release all latched outputs (write 1 to pulse)
RESET boolOut Clear latches + reset cycle counter + re-init connectivity (write 1 to pulse)
CONN_INP WaveformIn Per-port connection state for wired inputs (1=connected, 0=disconnected)
CONN_OUT WaveformIn Per-port connection state for wired outputs

Environment Variables

Variable Default Description
IOCMNG_PREFIX — Controller PV prefix
IOCMNG_PORT 8080 Server port
IOCMNG_HOST 0.0.0.0 Server bind address
IOCMNG_PLUGINS_DIR /data/plugins Plugin clone directory
IOCMNG_PLUGINS_CONFIG — Startup plugins YAML
IOCMNG_LOG_LEVEL info Logging level
IOCMNG_PVA true Use PVA (true) or CA (false)
IOCMNG_DISABLE_OPHYD true Skip ophyd initialization

Project Structure

src/iocmng/
├── __init__.py           # Exports: TaskBase, JobBase, DeclarativeTask, pv_client, run_ioc
├── declarative.py        # DeclarativeTask (zero-code tasks)
├── runner.py             # Standalone CLI runner (iocmng-run)
├── base/
│   ├── task.py           # TaskBase — continuous/triggered/reactive tasks
│   └── job.py            # JobBase — one-shot jobs
├── core/
│   ├── controller.py     # Central plugin manager
│   ├── loader.py         # Git clone + config loading
│   ├── validator.py      # Plugin validation
│   ├── plugin_spec.py    # PvArgumentSpec, PluginSpec, RuleSpec, TransformSpec
│   ├── safe_eval.py      # AST-validated expression evaluator
│   ├── functions.py      # Built-in function registry
│   └── pv_client.py      # PVA/CA abstraction layer
├── api/
│   ├── app.py            # FastAPI application
│   ├── routes.py         # REST endpoints
│   └── models.py         # Pydantic models
└── ophyd/
    └── factory.py        # Optional ophyd device creation

Development

pip install -e ".[dev]"
pytest tests/ -v
black .
flake8 .

License

MIT

Metadata

Release files for iocmng 2.7.9

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

Source distribution (sdist)

Source distribution for iocmng 2.7.9
File Size Uploaded
iocmng-2.7.9.tar.gz 79.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for iocmng 2.7.9
File Interpreter ABI Platform
iocmng-2.7.9-py3-none-any.whl Python 3 none any Details

Total release size: 141.7 kB

Release files / iocmng-2.7.9.tar.gz

Download URL iocmng-2.7.9.tar.gz
Size 79.1 kB
Tags Source
SHA-256 checksum
How to use checksums
baf17cf54cf2cdb44de2c73ad816a185db4becc6b1427d2b232fbb7563307e0f
BLAKE2b-256 checksum
How to use checksums
0ece57e0a724fb771a6949770e2ea9f211c13e8d3a976868db0b9549e0a1c1dc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / iocmng-2.7.9-py3-none-any.whl

Download URL iocmng-2.7.9-py3-none-any.whl
Size 62.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7554f29e21915a5ae7e388108333ac85cd77bf98fa04a77ea46e42438ce90d09
BLAKE2b-256 checksum
How to use checksums
2efb50830809f1aa2bdf7b9e1f1ab6299570ee7c7bb8fe7892c04a1fb99c8faf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release history Release notifications | RSS feed

This release

2.7.9 This release

2 release files

2.7.8

2 release files

2.7.7

2 release files

2.7.6

2 release files

2.7.5

2 release files

2.7.4

2 release files

2.7.3

2 release files

2.7.2

2 release files

2.7.1

2 release files

2.7.0

2 release files

2.6.2

2 release files

2.6.1

2 release files

2.6.0

2 release files

2.5.2

2 release files

2.5.0

2 release files

2.4.3

2 release files

2.4.1

2 release files

2.4.0

2 release files

2.3.3

2 release files

2.3.2

2 release files

2.3.1

2 release files

2.2.11

2 release files

2.2.10

2 release files

2.2.7

2 release files

2.2.6

2 release files

2.2.4

2 release files

2.2.1

2 release files

2.2.0

2 release files

2.1.0

2 release files

2.0.9

2 release files

2.0.8

2 release files

2.0.7

2 release files

2.0.6

2 release files

2.0.5

2 release files

2.0.4

2 release files

2.0.3

2 release files

2.0.2

2 release files

2.0.1

2 release files

2.0.0

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