A web-based WYSIWYG editor for building EPICS control system dashboards.
- Drag-and-drop dashboard builder — place, resize, and configure widgets on a 12-column grid (Gridstack.js)
- 14 widget types for instrumentation: text/numeric displays, inputs, sliders, toggles, LEDs, gauges, progress bars, motor controls, enum selectors, detector displays, labels, and time-series plots
- Live PV updates via WebSocket — widgets display real-time EPICS Process Variable values
- Time-series plots with configurable windows, max points, and automatic bin-averaging for long-duration trends
- Simulated EPICS mode (default) — 20+ realistic PVs for development without a real EPICS network
- Real EPICS mode via caproto — connect to live IOCs by setting
EIWYG_SIM_MODE=false - Save/load dashboards with custom URL slugs, usernames, and descriptions
- View mode — publish a dashboard to a unique URL for read-only monitoring
- Password-protected dashboards — optional key to prevent accidental edits
- Dashboard variables — template variables for cloning dashboards across beamlines
- Themes — multiple color themes (Blue Dream, Earthy, Light, Pastel, Mondrian)
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
uvicorn backend.main:app --host 0.0.0.0 --port 8080
# Open http://localhost:8080This starts EIWYG in simulated EPICS mode with SQLite storage. No external services required.
| Variable | Default | Description |
|---|---|---|
EIWYG_SIM_MODE |
true |
false to connect to real EPICS IOCs via Channel Access |
EIWYG_BASE_PATH |
(empty) | Serve all routes under a subpath (e.g., /eiwyg) |
EIWYG_ENV |
dev |
Set to production to require PostgreSQL (prevents SQLite fallback) |
PGHOST |
(none) | PostgreSQL host (enables Postgres instead of SQLite) |
PGPORT |
5432 |
PostgreSQL port |
PGUSER |
(none) | PostgreSQL username |
PGPASSWORD |
(none) | PostgreSQL password |
PGDATABASE |
eiwyg |
PostgreSQL database name |
EIWYG uses SQLite by default (zero config, stored in eiwyg.db). Set the PG* environment variables to use PostgreSQL instead.
When EIWYG_ENV=production, PostgreSQL is required. The app will refuse to start without it, preventing silent data loss from ephemeral SQLite inside a container.
docker build -t eiwyg .
docker run -p 8080:8080 eiwygTo serve behind a reverse proxy at a subpath (e.g., https://example.com/eiwyg):
EIWYG_BASE_PATH=/eiwyg uvicorn backend.main:app --host 0.0.0.0 --port 8080The app handles its own path prefixing — no rewrite-target or path stripping in the reverse proxy. Just forward /eiwyg traffic to the app as-is.
Set EIWYG_ENV=production and provide PostgreSQL credentials. A CI/CD workflow (.github/workflows/build-push.yml) builds and pushes Docker images to GHCR on each push to master.
backend/
main.py FastAPI app, routes, WebSocket handler
database.py Database layer (SQLite or PostgreSQL)
epics_manager.py EPICS PV manager (sim + real modes)
ws_manager.py WebSocket connection manager
pv_cache.py Time-series PV value cache with compaction
models.py Pydantic request/response models
test_ioc.py Standalone caproto test IOC
frontend/
index.html Landing page
editor.html Dashboard editor
view.html Read-only dashboard viewer
load.html Dashboard search/load
js/ Editor, viewer, loader, and widget logic
css/ Styles
- Backend: Python, FastAPI, WebSocket, caproto
- Database: SQLite (aiosqlite) or PostgreSQL (asyncpg)
- Frontend: Vanilla JS, Gridstack.js 10, Chart.js 4 (CDN, no build step)