🚧 Web UI
This commit is contained in:
+69
-10
@@ -7,7 +7,7 @@
|
||||
| Project | `wago-modbustcp-simulator-py` |
|
||||
| Version | 1.4 (Draft for review) |
|
||||
| Date | 2026-10-03 |
|
||||
| Status | Framework phase; module addressing implemented (FR-4.3.11); service/container deployment implemented (§12); plain-text request tracing implemented (NFR-6.4); clean CLI error handling implemented (NFR-6.5 CLI part); long-duration simulation (§8), bench mode (§9), web UI (§10), runtime device configuration (§11), multi-vendor device profiles (§13) and additional fieldbus protocols PROFINET/COMLI (§14) requested |
|
||||
| Status | Framework phase; module addressing implemented (FR-4.3.11); service/container deployment implemented (§12); plain-text request tracing implemented (NFR-6.4); clean CLI error handling implemented (NFR-6.5 CLI part); web UI §10 in implementation (M1–M5 done: auth, overview, manipulation, diagnostics, configuration; M6 scenario view open); long-duration simulation (§8), bench mode (§9), runtime device configuration (§11 — coupler/module subset now covered by web UI M5), multi-vendor device profiles (§13) and additional fieldbus protocols PROFINET/COMLI (§14) requested |
|
||||
| Target device simulated | WAGO 750-362 / 750-362/0000-0001 FC Modbus TCP (G4) bus coupler |
|
||||
| Reference documents | `docs/m07500362_xxxxxxxx_0en.pdf` (750-362 Modbus TCP manual), Modbus TCP specification (modbus.org) |
|
||||
|
||||
@@ -865,9 +865,11 @@ at runtime without a scenario driving it.
|
||||
|
||||
## 10. Feature Request — Web UI (I/O Overview & Manipulation)
|
||||
|
||||
> **Status: requested 2026-10-03, planned (roadmap phase 5), not yet
|
||||
> implemented.** A browser front-end overlooking and manipulating the
|
||||
> simulated node's I/O values and states at runtime.
|
||||
> **Status: in implementation (2026-10-03).** The implementation
|
||||
> decisions below are binding; milestones M1–M4 are implemented and
|
||||
> verified (M5 configuration and M6 scenario view remain). A browser
|
||||
> front-end overlooking and manipulating the simulated node's I/O
|
||||
> values and states at runtime.
|
||||
|
||||
### 10.1 Motivation
|
||||
|
||||
@@ -918,21 +920,78 @@ Terminal monitors (§9) suffice for single engineers, but FAT benches are
|
||||
overview, address-selection DIP switch) are specified in §11; §10 covers
|
||||
value/state oversight and manipulation.
|
||||
|
||||
### 10.3 Architecture sketch (planned)
|
||||
### 10.3 Implementation decisions (binding, 2026-10-03)
|
||||
|
||||
- **Framework**: FastAPI (Starlette) + Uvicorn, embedded **in-process on
|
||||
the same asyncio event loop** as the Modbus TCP server — a UI write and
|
||||
a Modbus request never race on the datastore.
|
||||
- **Front-end**: single-page vanilla HTML/CSS/JS (no build step) under
|
||||
`src/wago_sim/webui/static/`; realistic node graphics (DIN-rail strip,
|
||||
module bezels, glowing per-channel LEDs for DI/DO, bar/numeric
|
||||
indicators for AI/AO) drawn with inline SVG/CSS.
|
||||
- **Authentication** (user request 2026-10-03): session-cookie login with
|
||||
in-memory token store; default credentials `admin` / `simu`,
|
||||
overridable via env (`WAGO_SIM_WEB_USER` / `WAGO_SIM_WEB_PASSWORD`);
|
||||
optional read-only mode via `WAGO_SIM_WEB_READONLY`. No third-party
|
||||
auth/session dependencies (`hashlib.scrypt` hashing; sessions need not
|
||||
survive restarts on a bench).
|
||||
- **Backend data access** (user request 2026-10-03): the API **never uses
|
||||
Modbus TCP**. It reads via the internal memory handler
|
||||
(`WagoDatastore` getters, `VirtualNode` channel model,
|
||||
`ConfigRegisterBank`, `ModbusWatchdog`, `ModbusStatistics`) and writes
|
||||
via internal paths chosen by role: simulated-field writes go through
|
||||
`set_digital_input_channel()` / `set_input_word()` (as the scenario
|
||||
engine does); master-side forcing goes through the datastore's
|
||||
internal `write_bits()` / `write_words()` dispatch (mirrors, watchdog
|
||||
kicks, and statistics stay consistent, FR-9.2.6 semantics) — but
|
||||
always as direct in-process calls, never via TCP.
|
||||
- **Live updates**: WebSocket push (`/api/ws`) — datastore
|
||||
`add_listener` for output changes plus a 10 Hz snapshot-difference
|
||||
sweep for input-side changes.
|
||||
- **Wiring**: `serve` starts the web UI by default (`--no-web` to
|
||||
disable; `--web-port`, env `WAGO_SIM_WEB_PORT`; default port 8080).
|
||||
|
||||
### 10.4 Architecture sketch (as-built)
|
||||
|
||||
```
|
||||
src/wago_sim/
|
||||
├── webui/
|
||||
│ ├── __init__.py
|
||||
│ ├── app.py # HTTP + WebSocket server (asyncio, same loop as Modbus)
|
||||
│ ├── api.py # REST endpoints: node layout, values, writes, diagnostics
|
||||
│ ├── app.py # build_webui(app, ...) -> FastAPI; API + static
|
||||
│ ├── auth.py # login/logout, scrypt hash, session dependency
|
||||
│ ├── state.py # snapshot builder + change detection
|
||||
│ ├── api.py # REST + WebSocket routes
|
||||
│ └── static/ # single-page front-end (no build step)
|
||||
```
|
||||
|
||||
The web server runs **in the same asyncio event loop** as the Modbus TCP
|
||||
server, so a UI write and a Modbus read never race on the datastore.
|
||||
### 10.5 API surface (as-built)
|
||||
|
||||
### 10.4 Acceptance criteria
|
||||
| Method/Route | Purpose | FR |
|
||||
|---|---|---|
|
||||
| `POST /api/auth/login`, `POST /api/auth/logout` | session cookie (`HttpOnly`) | auth |
|
||||
| `GET /api/node` | module list, channel tables with `DI0.1`-style and Modbus addresses | 10.2.2 |
|
||||
| `GET /api/values` | full channel-value snapshot | 10.2.3 |
|
||||
| `WS /api/ws` | live value/state deltas | 10.2.3, 10.2.7 |
|
||||
| `POST /api/channels/{kind}/{module}/{channel}` | set/toggle/pulse/ramp a channel (field side) | 10.2.4 |
|
||||
| `POST /api/force` | master-side force at a Modbus address (internal dispatch) | 10.2.4 |
|
||||
| `GET /api/diagnostics` | watchdog status, statistics, module diagnosis, LED errors | 10.2.5 |
|
||||
| `POST /api/diagnostics/reset-stats` | statistics reset (0x1029 semantics) | 10.2.5 |
|
||||
| `POST /api/diagnostics/inject-fault`, `POST /api/diagnostics/clear-fault` | LED / module-diagnosis injection | 10.2.5 |
|
||||
| `GET/PUT /api/config/coupler` | watchdog settings, response delay, idle timeout, MAC-ID | §11 subset |
|
||||
| `GET/PUT /api/config/modules` | module list CRUD + process-image rebuild | §11 FR-11.2.1–11.2.4 |
|
||||
|
||||
### 10.6 Milestones
|
||||
|
||||
| # | Deliverable |
|
||||
|---|---|
|
||||
| M1 | WebUI skeleton, in-process FastAPI, CLI/env wiring, authentication (`admin`/`simu`), `GET /api/node` |
|
||||
| M2 | Node overview page — DIN-rail graphics, LEDs, analog indicators, live values (WS) |
|
||||
| M3 | Manipulation — toggle/pulse/ramp, AI engineering units, master-side force |
|
||||
| M4 | Diagnostics — watchdog/statistics/diagnosis view, reset, fault injection |
|
||||
| M5 | Configuration — coupler forms; module CRUD with image rebuild and persistence |
|
||||
| M6 | (deferred) Scenario run view (FR-10.2.6) + alias-ownership rejection (FR-10.2.9) |
|
||||
|
||||
### 10.7 Acceptance criteria
|
||||
|
||||
1. Opening the UI shows the node's module list and channel table exactly
|
||||
as configured, with `DI0.1`-style addresses and Modbus addresses.
|
||||
|
||||
Reference in New Issue
Block a user