Martino Ferrari 986f6cd6d8 Phase 6
2026-04-25 22:56:09 +02:00
2026-04-25 22:56:09 +02:00
2026-04-25 22:56:09 +02:00
2026-04-25 22:56:09 +02:00
2026-04-25 22:56:09 +02:00
2026-04-25 22:56:09 +02:00
2026-04-25 22:56:09 +02:00
2026-04-25 22:56:09 +02:00
2026-04-25 22:56:09 +02:00
2026-04-25 22:56:09 +02:00
2026-04-25 22:56:09 +02:00
2026-04-24 15:09:14 +02:00
2026-04-24 15:09:14 +02:00
2026-04-25 22:56:09 +02:00
2026-04-25 22:56:09 +02:00
2026-04-24 15:09:14 +02:00

uopi

A web-based HMI (Human-Machine Interface) for monitoring and controlling EPICS-based scientific and industrial control systems.

uopi runs as a single portable binary. Access it from any browser — including over an SSH tunnel — with no client-side installation required.


Features

  • Live data from EPICS (Channel Access / PVAccess) and user-defined synthetic signals
  • Web-based HMI editor — drag-and-drop widgets, resize, align, undo/redo — saved as XML
  • Rich widget library — gauges, LEDs, bars, plots (time series, FFT, waterfall, histogram), controls
  • Multiple concurrent clients sharing the same data subscriptions
  • Historical data navigation via EPICS Archive Appliance integration
  • Synthetic signals — compose, filter, and transform existing signals with a DSP pipeline or Lua scripts
  • Single binary with embedded frontend; no runtime dependencies

Quick Start

Prerequisites

  • EPICS Base installed (for the EPICS data source; libca must be linkable)
  • Go 1.22+
  • Node.js 20+ and npm

Build

make all

The binary is written to dist/uopi.

Run

./dist/uopi --config uopi.toml

Then open http://localhost:8080 in your browser.

SSH tunnel example:

ssh -L 8080:localhost:8080 user@controlhost
# then open http://localhost:8080 locally

Configuration

Create uopi.toml (or copy and edit the example):

[server]
listen    = ":8080"
storage_dir = "./interfaces"   # where interface XML files are stored

[datasource.epics]
enabled      = true
ca_addr_list = ""              # overrides EPICS_CA_ADDR_LIST if non-empty
archive_url  = ""              # EPICS Archive Appliance base URL

[datasource.synthetic]
enabled          = true
definitions_file = "./synthetic.json"

All settings can be overridden with environment variables using the prefix UOPI_ and double underscores for nesting, e.g. UOPI_SERVER_LISTEN=":9090".


Development

See docs/TECHNICAL_SPEC.md for full architecture details.

# Backend only (with stub data source)
go run ./cmd/uopi

# Frontend dev server (proxies /api to backend at :8080)
cd web && npm install && npm run dev

# Run backend tests
go test ./...

# Run a single backend test
go test ./internal/broker/... -run TestFanOut

# Frontend type-check
cd web && npm run check

# Frontend lint
cd web && npm run lint

# Full build (frontend + backend)
make all

# Run all tests
make test

Docs

Document Description
docs/FUNCTIONAL_SPEC.md User-facing feature specification
docs/TECHNICAL_SPEC.md Technology choices, architecture, API design
docs/WORK_PLAN.md Phased development plan with milestones

License

TBD

S
Description
uOPI: light, fast, web based OPI
Readme 15 MiB
Languages
Go 47.8%
TypeScript 43.8%
CSS 6.9%
C 0.5%
Shell 0.4%
Other 0.6%