Files
uopi/docs/FUNCTIONAL_SPEC.md
T
Martino Ferrari 9aa89cc0cf Initial commit
2026-04-24 15:09:14 +02:00

214 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Functional Specification — uopi
## 1. Purpose
uopi is a web-based HMI (Human-Machine Interface) for monitoring and controlling industrial/scientific systems, primarily EPICS-based control systems. It runs as a single server process and is accessed entirely through a web browser, making it suitable for SSH-tunnelled remote access.
---
## 2. Users and Roles
| Role | Description |
|------|-------------|
| Operator | Uses interfaces in View mode; can interact with controls but cannot edit layouts |
| Engineer | Creates and edits interfaces in Edit mode; manages signal lists |
| Administrator | Manages server configuration, data sources, and saved interfaces |
In the initial version all users share the same access level. Role-based access control is deferred to a future release.
---
## 3. System Modes
### 3.1 View Mode (default)
The default mode when opening the application.
**Interface list pane (left, collapsible)**
- Displays all interfaces saved on the server, grouped into a tree by folder.
- Right-click on an interface: options to open in Edit mode or clone it.
- "New interface" button opens Edit mode with a blank canvas.
- "Import" option loads an interface from a local XML file.
**HMI canvas (center)**
- Renders the selected interface as a live, interactive panel.
- Widgets display real-time data; controls (set-value, buttons) are active.
- No drag, resize, or layout operations are possible in this mode.
- Right-clicking any widget opens a context menu:
- **Signal info** — floating window showing DS name, type, unit, range, current value and timestamp.
- **Copy signal name** — copies the signal identifier to the clipboard.
- **Export data to CSV** — downloads buffered/historical data for the signal(s) used by the widget.
**Top toolbar**
- Show/hide interface list pane.
- Time selector: navigate to a past timestamp (enabled only when the server has archive access for all signals on the canvas).
- "Live" button: return to real-time data after historical navigation.
### 3.2 Edit Mode
Activated via the "New interface" button or by right-clicking an existing interface.
**Signal tree pane (left, resizable and collapsible)**
- Shows all signals known to each connected data source.
- Sources are shown as top-level nodes; signals are nested within.
- User can add custom entries:
- For EPICS: manually enter a PV name.
- For Synthetic: define a new synthetic signal (see §5.2).
- User can load a CSV file with columns `NAME, DataSource, DS_PARAMETERS` to import a batch of signals.
- Filter/search box to narrow the list.
**Widget canvas (center)**
- Free-form canvas where widgets can be placed at arbitrary pixel positions.
- Background grid with optional snap-to-grid.
**Properties pane (right, collapsible)**
- Appears when one or more widgets are selected.
- Displays and edits all options for the selected widget (see §4).
**Top toolbar**
- Show/hide signal pane.
- Show/hide properties pane.
- Undo / Redo (also Ctrl+Z / Ctrl+Shift+Z).
- Save interface to server.
- Load interface from server.
- Export interface to local XML file.
- Import interface from local XML file.
- "Add text" tool — inserts a static text label.
- "Add image" tool — inserts a static image (uploaded to server or embedded as base64).
- "Add link" tool — inserts a button that opens another interface.
---
## 4. Widgets
### 4.1 Creating Widgets
Drag a signal from the signal tree and drop it onto the canvas. A picker appears showing all widget types compatible with the signal's data type (iconised). The user selects one and the widget is placed at the drop location with default size.
### 4.2 Selecting Widgets
- Single click: select one widget (deselects others).
- Ctrl+click: add/remove a widget from the current selection.
- Click-drag on empty canvas area: rubber-band area select.
When a widget is selected, a bounding box appears with:
- 8 resize handles (corners + midpoints).
- A delete button (×) in the top-right corner.
- The widget can be moved by dragging its body.
### 4.3 Multi-selection Operations
When multiple widgets are selected:
- Drag any selected widget to move them all together.
- Del key deletes all selected widgets.
- An align/distribute toolbar appears above the canvas with:
- Align left / center horizontal / right.
- Align top / center vertical / bottom.
- Distribute evenly — by center spacing (horizontal/vertical).
- Distribute evenly — by gap size (horizontal/vertical).
### 4.4 Widget Catalogue
| Widget | Compatible signal types | Description |
|--------|-------------------------|-------------|
| Text view | any scalar | Displays `name: value unit` |
| Gauge | numeric scalar | Circular or arc gauge with configurable range |
| Vertical bar | numeric scalar | Vertical level indicator |
| Horizontal bar | numeric scalar | Horizontal level indicator |
| Set value | numeric or string, writable | Shows `name: [input field] current_value unit` + Set button |
| LED | boolean / numeric | Coloured indicator with configurable condition and label |
| Multi-LED | integer (bitset) | One LED per bit with individual labels and conditions |
| Button | writable | Sends a fixed value or command on click |
| Plot | numeric scalar or array | Multi-signal plot; sub-types below |
| Text label | — | Static text annotation |
| Image | — | Static image |
| Link | — | Button navigating to another interface |
**Plot sub-types:**
| Sub-type | Signal requirement |
|----------|--------------------|
| Time series | numeric scalar(s) |
| FFT | 1-D numeric array |
| Waterfall | 1-D numeric array (repeated) |
| Histogram | numeric scalar(s) |
| Bar chart | numeric scalar(s) |
| Logic analyser | boolean / integer (bitset) |
### 4.5 Widget Properties (Properties Pane)
Common to all:
- Label text, font size, text colour.
- Position (X, Y) and size (W, H) — editable numerically.
- Data source and signal name (read-only after creation; reassignable via drag).
Per type:
- **Gauge / Bar**: min value, max value, alert thresholds with colours, unit label.
- **LED / Multi-LED**: condition expression (e.g. `value > 0`), colours for true/false states.
- **Plot**: plot sub-type selector, Y-axis range (auto or manual), time window duration, legend position, colour per signal, line style.
- **Set value**: input type (numeric / string / enum), confirmation prompt toggle.
- **Link**: target interface name.
---
## 5. Data Sources
### 5.1 EPICS
- Connects to an EPICS environment via Channel Access (CA) or PVAccess (PVA).
- On connect, retrieves full metadata from the PV name: data type, engineering units, display range (DRVL/DRVH, LOPR/HOPR), alarm limits, enum strings (for mbbi/mbbo records), read/write mode, acquisition mode.
- Prefers monitor/subscription over polling. Falls back to polling only when monitors are unavailable.
- Attempts to enumerate available PV names from the IOC (e.g. via PV lists or Channel Finder). Unknown PVs can still be manually added by the user.
- When an EPICS Archive Appliance or Channel Archiver is configured, the server can satisfy historical data requests.
### 5.2 Synthetic
A signal defined by composing one or more input signals (from any data source) through a chain of processing functions.
**Built-in processing functions (non-exhaustive):**
- Arithmetic: gain, offset, add, subtract, multiply, divide.
- Signal processing: moving average (N samples or time window), RMS, bandpass filter (IIR/FIR), lowpass / highpass filter, derivative, integral.
- FFT, inverse FFT.
- Peak detection, threshold crossing.
- Custom formula: inline expression (`a * sin(b) + c`).
- Lua script block: arbitrary Lua code with access to input values and state.
**User workflow:**
1. Click "New synthetic signal" in the signal tree.
2. Name the signal and choose input signals.
3. Build a processing pipeline by chaining function blocks (UI similar to a node graph or an ordered list).
4. Optionally write a Lua snippet for custom logic.
5. The synthetic signal appears in the tree and can be used like any other signal.
---
## 6. Interface Persistence
- Interfaces are saved to the server in XML format and are available to all connected clients.
- Export/Import allows local file exchange of XML files.
- The XML schema records: widget type, position, size, signal bindings, and all property values.
---
## 7. Historical Data Navigation
When the server has archive access for all signals on the current canvas:
- The top toolbar shows a date/time picker.
- Selecting a past time replays data from the archive into all widgets.
- The "Live" button resumes real-time streaming.
- Widgets that support time-axis (plots) show the historical range; point-value widgets show the value at the selected time.
---
## 8. Non-functional Requirements
| Requirement | Target |
|-------------|--------|
| Server binary | Single statically-linked executable; no runtime dependencies |
| Target platform | Linux x86-64; also aarch64 optional |
| Minimum server OS | RHEL/CentOS 7 (glibc 2.17) or equivalent |
| Concurrent clients | ≥ 20 simultaneous browser clients |
| Data fan-out latency | < 5 ms added latency vs. raw EPICS update rate |
| Frontend responsiveness | 60 fps canvas rendering during live updates |
| Screen DPI | Frontend adapts to device pixel ratio |