Add separate simulator UI
This commit is contained in:
79
README.md
79
README.md
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user