Add separate simulator UI

This commit is contained in:
masterdev
2026-06-17 01:06:21 +01:00
parent e083a22bff
commit e3d8f856e3
16 changed files with 2361 additions and 14 deletions

View File

@@ -37,12 +37,14 @@ Services:
- `backend`: FastAPI API, MQTT consumer, downtime logic, OEE computation, WebSocket notifications
- `edge-simulator`: publishes simulated machine events on MQTT
- `frontend`: React + TypeScript operator/dashboard interface
- `simulator-ui`: separate React + TypeScript test console for sending simulated events
## Repository Layout
```text
/backend
/frontend
/simulator-ui
/edge-simulator
/database/init.sql
/database/seed.sql
@@ -65,6 +67,7 @@ docker compose up --build
Exposed services:
- frontend: `http://localhost:5173`
- simulator UI: `http://localhost:5174`
- backend API: `http://localhost:8000`
- backend health: `http://localhost:8000/health`
- PostgreSQL: `localhost:5432`
@@ -80,6 +83,7 @@ file into the web editor, because the stack also needs these repository files:
- `mqtt/mosquitto.conf`
- `backend/`
- `frontend/`
- `simulator-ui/`
- `edge-simulator/`
### 1. Create The Stack
@@ -116,11 +120,14 @@ POSTGRES_DB=plasttrack
POSTGRES_USER=plasttrack
POSTGRES_PASSWORD=change-this-password
FRONTEND_ORIGIN=http://SERVER_IP:5173
FRONTEND_ORIGINS=http://SERVER_IP:5173,http://localhost:5173,http://127.0.0.1:5173
FRONTEND_ORIGINS=http://SERVER_IP:5173,http://SERVER_IP:5174,http://localhost:5173,http://127.0.0.1:5173,http://localhost:5174,http://127.0.0.1:5174
BACKEND_PORT=8000
VITE_API_BASE_URL=http://SERVER_IP:8000
VITE_WS_URL=ws://SERVER_IP:8000/ws/dashboard
VITE_ALLOWED_HOSTS=SERVER_IP,localhost,127.0.0.1
SIMULATOR_PORT=5174
SIMULATOR_API_BASE_URL=http://SERVER_IP:8000
SIMULATOR_ALLOWED_HOSTS=SERVER_IP,localhost,127.0.0.1
```
For a domain with HTTPS and a reverse proxy, use:
@@ -130,11 +137,14 @@ POSTGRES_DB=plasttrack
POSTGRES_USER=plasttrack
POSTGRES_PASSWORD=change-this-password
FRONTEND_ORIGIN=https://plasttrack.example.com
FRONTEND_ORIGINS=https://plasttrack.example.com
FRONTEND_ORIGINS=https://plasttrack.example.com,https://simulator.plasttrack.example.com
BACKEND_PORT=8000
VITE_API_BASE_URL=https://api.plasttrack.example.com
VITE_WS_URL=wss://api.plasttrack.example.com/ws/dashboard
VITE_ALLOWED_HOSTS=plasttrack.example.com
SIMULATOR_PORT=5174
SIMULATOR_API_BASE_URL=https://api.plasttrack.example.com
SIMULATOR_ALLOWED_HOSTS=simulator.plasttrack.example.com
```
Important: do not keep `localhost` in `VITE_API_BASE_URL` or `VITE_WS_URL`
@@ -151,13 +161,14 @@ change `BACKEND_PORT` instead of editing `docker-compose.yml`. For example:
BACKEND_PORT=8001
VITE_API_BASE_URL=http://SERVER_IP:8001
VITE_WS_URL=ws://SERVER_IP:8001/ws/dashboard
SIMULATOR_API_BASE_URL=http://SERVER_IP:8001
```
If the browser shows a CORS error, make sure the exact frontend origin is in
`FRONTEND_ORIGINS`. Example:
```env
FRONTEND_ORIGINS=https://plasttrack.sable.ynsdev.site
FRONTEND_ORIGINS=https://plasttrack.sable.ynsdev.site,https://simulator.plasttrack.sable.ynsdev.site
```
If the frontend is served over HTTPS, the WebSocket URL must use `wss://`, not
@@ -166,13 +177,15 @@ same-domain reverse proxy variables:
```env
FRONTEND_ORIGIN=https://plasttrack.sable.ynsdev.site
FRONTEND_ORIGINS=https://plasttrack.sable.ynsdev.site
FRONTEND_ORIGINS=https://plasttrack.sable.ynsdev.site,https://simulator.plasttrack.sable.ynsdev.site
VITE_API_BASE_URL=https://plasttrack.sable.ynsdev.site
VITE_WS_URL=wss://plasttrack.sable.ynsdev.site/ws/dashboard
VITE_ALLOWED_HOSTS=plasttrack.sable.ynsdev.site,localhost,127.0.0.1
SIMULATOR_API_BASE_URL=https://plasttrack.sable.ynsdev.site
SIMULATOR_ALLOWED_HOSTS=simulator.plasttrack.sable.ynsdev.site,localhost,127.0.0.1
```
The reverse proxy must route:
The main dashboard reverse proxy must route:
```text
/api/* -> backend:8000
@@ -180,6 +193,14 @@ The reverse proxy must route:
/* -> frontend:5173
```
The simulator must use a separate link, not a tab inside the operator frontend:
```text
https://simulator.plasttrack.example.com -> simulator-ui:5174
```
If `SIMULATOR_API_BASE_URL` points to the main dashboard domain, that dashboard reverse proxy must also route `/api/*` to the backend.
### 3. Deploy
Click `Deploy the stack`.
@@ -187,6 +208,7 @@ Click `Deploy the stack`.
Expected exposed ports:
- frontend: `5173`
- simulator UI: `5174`
- backend API: `8000`
- MQTT: `1883`
- MQTT WebSocket listener: `9001`
@@ -213,6 +235,12 @@ Open:
http://SERVER_IP:5173
```
Open the simulator test console:
```text
http://SERVER_IP:5174
```
Check the backend:
```text
@@ -325,6 +353,11 @@ Reference data:
- `GET /api/reference-data`
Simulator:
- `POST /api/simulator/events`
- `POST /api/simulator/scenarios`
WebSocket:
- `ws://localhost:8000/ws/dashboard`
@@ -400,7 +433,12 @@ Implemented rules:
## How The Simulator Works
The simulator publishes:
There are two simulator components:
- `edge-simulator`: automatic MQTT publisher for continuous demo data
- `simulator-ui`: separate browser console for manually triggering test cases
The edge simulator publishes:
- `digital_input_changed` for `machine_power_on`
- `digital_input_changed` for `cycle_signal`
@@ -408,6 +446,25 @@ The simulator publishes:
Each machine gets a nominal cycle time, a pulse width, and a random stop probability. The backend consumes these MQTT events, detects the configured cycle edge, and updates production data in PostgreSQL.
The separate simulator UI calls backend simulator endpoints and can trigger:
- power on/off
- single normalized cycle
- cycle burst
- passive `cycle_signal` edge using each machine's configured edge
- debounce noise that should be ignored
- forced stop / open downtime
- recovery with a new cycle
- alarm on/off
- raw passive digital input by name and value
Use the simulator UI through its own URL, for example:
```text
http://localhost:5174
https://simulator.plasttrack.example.com
```
## Connecting A Real Passive Gateway Later
To replace the simulator with a real gateway:
@@ -461,6 +518,14 @@ npm install
npm run build
```
Simulator UI build check:
```bash
cd simulator-ui
npm install
npm run build
```
## Current Limits
- No authentication or role management
@@ -469,7 +534,7 @@ npm run build
- No historical reporting endpoints beyond daily OEE/TRS
- No real passive gateway adapter package yet; the simulator publishes normalized MQTT payloads
- WebSocket currently pushes refresh notifications, then the UI refetches data
- The simulator models passive-signal-derived events, not actual electrical IO reads
- The simulators model passive-signal-derived events, not actual electrical IO reads
## Current UI Modules