change to web visualizer
This commit is contained in:
1 parent
87be72b52b
commit
417ced90fa
9 files changed
+2580
-680
No files matched your search
@@ -0,0 +1,565 @@
|
||||
# ESP32-S3 LD2453 Radar — Web Visualizer cho Orange Pi
|
||||
|
||||
> **English version** below / Xem bản tiếng Anh ở cuối file.
|
||||
|
||||
Hướng dẫn cài đặt và sử dụng **Web Visualizer** trên Orange Pi (hoặc máy tính bất kỳ có Python 3.8+) để hiển thị dữ liệu radar realtime dưới dạng giao diện web đẹp trên trình duyệt.
|
||||
|
||||
> ✅ **Không cần giao diện desktop (Tkinter/Pygame) nữa.** Visualizer chạy nền dạng Web Server (FastAPI), bạn chỉ cần mở trình duyệt (trên điện thoại, laptop, PC…) là xem được đồ họa.
|
||||
|
||||
---
|
||||
|
||||
## 1. Chuẩn bị
|
||||
|
||||
### 1.1 Yêu cầu hệ thống
|
||||
- Orange Pi / Raspberry Pi / PC bất kỳ có **Python 3.8+**
|
||||
- Cùng mạng LAN với ESP32 (WiFi hoặc cổng LAN)
|
||||
- Biết IP của ESP32 (xem Serial Monitor khi boot, hoặc vào router xem)
|
||||
|
||||
### 1.2 Cấu trúc thư mục
|
||||
```
|
||||
orangepi-server/
|
||||
├── visualizer.py # Web Server (FastAPI): kết nối ESP32 + broadcast tới trình duyệt
|
||||
├── requirements.txt # Python dependencies
|
||||
├── templates/
|
||||
│ └── index.html # Giao diện Web (HTML)
|
||||
└── static/
|
||||
├── style.css # Giao diện (CSS): sáng/tối, responsive, song ngữ
|
||||
└── app.js # Canvas render + WebSocket client trong trình duyệt
|
||||
```
|
||||
|
||||
### 1.3 Copy file lên Orange Pi
|
||||
Copy cả thư mục `orangepi-server/` lên Orange Pi (clone repo, SCP, USB…).
|
||||
|
||||
Ví dụ SCP (chạy từ máy bạn):
|
||||
```bash
|
||||
scp -r orangepi-server/ orangepi@<ORANGE_PI_IP>:/home/orangepi/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Cài đặt Python dependencies
|
||||
|
||||
```bash
|
||||
cd ~/orangepi-server
|
||||
|
||||
# (Tùy chọn nhưng khuyến nghị) Dùng virtual env
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
# Cài dependencies
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
**Cài global (nhanh hơn, không khuyến nghị):**
|
||||
```bash
|
||||
pip3 install -r requirements.txt
|
||||
```
|
||||
|
||||
> Không cần `python3-tk` nữa — toàn bộ chạy trên web.
|
||||
|
||||
---
|
||||
|
||||
## 3. Sử dụng
|
||||
|
||||
### 3.1 Bật ESP32 ở chế độ Full Stage
|
||||
Trong `config.h` trên Arduino IDE:
|
||||
```cpp
|
||||
#define DIAGNOSTIC_MODE 0 // Full mode: WiFi + WebSocket + REST API
|
||||
```
|
||||
Nạp code, mở Serial Monitor lấy IP ESP32. Ví dụ: `192.168.1.100`
|
||||
|
||||
### 3.2 Khởi động Web Visualizer trên Orange Pi
|
||||
|
||||
```bash
|
||||
# Nếu dùng venv:
|
||||
source venv/bin/activate
|
||||
|
||||
# Chạy (thay bằng IP ESP32 của bạn):
|
||||
python3 visualizer.py 192.168.1.100
|
||||
```
|
||||
|
||||
Các tùy chọn lệnh:
|
||||
```bash
|
||||
# Tùy chỉnh port (mặc định 8000):
|
||||
python3 visualizer.py 192.168.1.100 --port 8080
|
||||
|
||||
# Giới hạn truy cập chỉ local (không cho từ ngoài):
|
||||
python3 visualizer.py 192.168.1.100 --host 127.0.0.1
|
||||
|
||||
# Log chi tiết:
|
||||
python3 visualizer.py 192.168.1.100 --verbose
|
||||
```
|
||||
|
||||
Màn hình console sẽ hiển thị:
|
||||
```
|
||||
==============================================================
|
||||
ESP32-S3 LD2453 Radar — Web Visualizer
|
||||
==============================================================
|
||||
ESP32 : ws://192.168.1.100/ws
|
||||
Web UI : http://0.0.0.0:8000/
|
||||
WS UI : ws://<OrangePi_IP>:8000/ws
|
||||
==============================================================
|
||||
```
|
||||
|
||||
### 3.3 Mở trình duyệt xem kết quả
|
||||
Trên **bất kỳ thiết bị nào cùng LAN** (điện thoại, laptop, PC…):
|
||||
```
|
||||
http://<IP_OrangePi>:8000/
|
||||
```
|
||||
Ví dụ: Orange Pi có IP `192.168.1.50` → mở `http://192.168.1.50:8000/`
|
||||
|
||||
---
|
||||
|
||||
## 4. Tính năng giao diện Web
|
||||
|
||||
### 4.1 Tổng quan
|
||||
| Tính năng | Mô tả |
|
||||
|---|---|
|
||||
| 🎨 **Giao diện đẹp** | Chủ đề sáng/tối (Light/Dark), màu sắc theo chuẩn Catppuccin |
|
||||
| 🌐 **Song ngữ** | Bật/tắt Tiếng Việt / English ngay trên header |
|
||||
| 📱 **Responsive** | Xem tốt trên cả mobile, tablet, desktop |
|
||||
| 🧭 **Radar Canvas** | Hiển thị radar, grid 1m, vòng tròn khoảng cách, hiệu ứng quét (sweep) |
|
||||
| 🎯 **Targets** | Lên đến 3 target với màu khác nhau, đường dẫn (trail), mũi tên tốc độ, nhãn tọa độ |
|
||||
| 🟩 **Zones** | 3 vùng hình chữ nhật với màu & trạng thái (Có người / Trống) |
|
||||
| 📊 **Thống kê** | Frames nhận, target hợp lệ, vùng có người, cập nhật lần cuối |
|
||||
| 📝 **Chi tiết** | Thông tin chi tiết từng target & zone ở panel bên phải |
|
||||
| ✏️ **Sửa zones** | Chỉnh tọa độ zones ngay trên web, tự động gửi cập nhật tới ESP32 |
|
||||
| 🔗 **Multi client** | Nhiều trình duyệt xem cùng lúc, dữ liệu đồng bộ realtime |
|
||||
|
||||
### 4.2 Header
|
||||
- 🟢 / 🟡 / 🔴 Trạng thái kết nối **ESP32** và **WebSocket**
|
||||
- ☀️ / 🌙 Nút chuyển Sáng / Tối
|
||||
- `VI / EN` Nút chuyển ngôn ngữ
|
||||
|
||||
### 4.3 Radar View (Canvas)
|
||||
- **Grid**: Mỗi ô = 1 mét, có đánh số (−5m ← 0 → +5m ngang, 0 → 7m thẳng)
|
||||
- **Vòng tròn khoảng cách**: Các vòng tròn nét đứt cách nhau 1m tính từ radar
|
||||
- **Trục Y chính**: Nét đứt màu xanh, chỉ hướng thẳng từ radar
|
||||
- **Radar**: Vị trí radar ở giữa cạnh dưới (điểm đỏ, ghi chữ RADAR)
|
||||
- **Hiệu ứng quét**: Cảm giác radar thực tế, có thể tắt trong công cụ
|
||||
- **Zones (3 hình chữ nhật)**:
|
||||
- Zone 1 (Xanh lá), Zone 2 (Cam), Zone 3 (Đỏ)
|
||||
- Có người → Màu đậm, nét liền, badge `CÓ NGƯỜI`
|
||||
- Trống → Màu nhạt, nét đứt, badge `TRỐNG`
|
||||
- **Targets (3 điểm)**:
|
||||
- Màu: Vàng (Slot 1), Tím (Slot 2), Xanh (Slot 3)
|
||||
- Điểm sáng có viền trắng, bao quanh là hiệu ứng glow
|
||||
- Mũi tên: Tốc độ (độ dài tỉ lệ với cm/s, hướng theo chuyển động)
|
||||
- Nhãn: `T# | X,Y mm | tốc độ cm/s`
|
||||
- Đường dẫn (trail): Mờ dần theo thời gian (tối đa 3.5s)
|
||||
- Target vừa mất dấu: Hiển thị viền đứt mờ trong 3.5s nữa
|
||||
|
||||
### 4.4 Công cụ trên Canvas (bên phải tiêu đề)
|
||||
- ✅ **Hiệu ứng quét** — Bật/tắt hiệu ứng quét radar
|
||||
- ✅ **Đường dẫn target** — Bật/tắt trail fade
|
||||
- ✅ **Hiển thị label** — Bật/tắt nhãn trên zones & targets
|
||||
|
||||
### 4.5 Panel bên phải
|
||||
**Thống kê:**
|
||||
- Frames nhận (tổng cộng)
|
||||
- Cập nhật cách đây bao nhiêu giây
|
||||
- Target hợp lệ / 3
|
||||
- Vùng có người / 3
|
||||
|
||||
**Chi tiết Target:**
|
||||
- Mỗi target có một thẻ màu, hiển thị:
|
||||
- Trạng thái: `Đã phát hiện` / `Vừa mất dấu` / `Trống`
|
||||
- `X, Y (mm)`
|
||||
- `Tốc độ (cm/s)`
|
||||
- `Khoảng cách (m)`
|
||||
- `Góc (°)` — 0° = thẳng, âm = trái, dương = phải
|
||||
|
||||
**Zones:**
|
||||
- Danh sách 3 zones với tọa độ
|
||||
- Nút **Sửa zones** mở form chỉnh sửa từng toạ độ X1/Y1/X2/Y2 (mm)
|
||||
- **Mặc định**: Khôi phục layout gốc
|
||||
- **Hủy**: Bỏ sửa
|
||||
- **Lưu & Áp dụng**: Gửi cập nhật POST `/api/zones` → forward tới ESP32 `/updateZones`, hiển thị toast thành công
|
||||
|
||||
---
|
||||
|
||||
## 5. Kiến trúc & luồng dữ liệu
|
||||
|
||||
```
|
||||
┌───────────┐ WebSocket /ws ┌──────────────────┐ WebSocket /ws ┌──────────────┐
|
||||
│ ESP32-S3 │ ◄──────────────────► │ Orange Pi (WS │ ◄──────────────────► │ Trình duyệt │
|
||||
│ LD2453 │ JSON frame radar │ Server FastAPI) │ JSON state đồng bộ │ (Canvas 2D) │
|
||||
└───────────┘ └──────────────────┘ └──────────────┘
|
||||
▲ ▲ ▲
|
||||
│ REST GET /zones │ GET / → trả về index.html │
|
||||
│ REST POST /updateZones │ GET /static/* → CSS, JS │
|
||||
└───────────────────────────────────┘ REST API /api/* │
|
||||
Visualizer tự động gọi ESP32 khi bạn chỉnh zones trên web │
|
||||
```
|
||||
|
||||
**Các endpoint chính:**
|
||||
| Method | Endpoint | Mục đích |
|
||||
|---|---|---|
|
||||
| GET | `/` | Trả về trang web chính |
|
||||
| GET | `/api/state` | Lấy trạng thái radar hiện tại (JSON) |
|
||||
| GET | `/api/zones` | Lấy danh sách zones |
|
||||
| POST | `/api/zones` | Cập nhật zones (forward tới ESP32 `/updateZones`) |
|
||||
| WS | `/ws` | Endpoint WebSocket cho trình duyệt (broadcast realtime) |
|
||||
|
||||
---
|
||||
|
||||
## 6. Tùy chỉnh & chạy nền
|
||||
|
||||
### 6.1 Chạy nền bằng tmux
|
||||
```bash
|
||||
tmux new -s radar
|
||||
cd ~/orangepi-server && source venv/bin/activate
|
||||
python3 visualizer.py 192.168.1.100
|
||||
# Ctrl+B D → detach (thoát ra mà vẫn chạy)
|
||||
# tmux attach -t radar → quay lại session
|
||||
```
|
||||
|
||||
### 6.2 systemd service (tự chạy khi boot Orange Pi)
|
||||
Tạo file `/etc/systemd/system/radar-web.service`:
|
||||
```ini
|
||||
[Unit]
|
||||
Description=LD2453 Radar Web Visualizer
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=orangepi
|
||||
WorkingDirectory=/home/orangepi/orangepi-server
|
||||
ExecStart=/home/orangepi/orangepi-server/venv/bin/python3 /home/orangepi/orangepi-server/visualizer.py 192.168.1.100 --port 8000
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
Sau đó:
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable radar-web
|
||||
sudo systemctl start radar-web
|
||||
journalctl -u radar-web -f # Xem log realtime
|
||||
```
|
||||
|
||||
### 6.3 Tùy chỉnh giao diện
|
||||
- **Màu sắc & chủ đề**: chỉnh các biến CSS ở đầu file `static/style.css` (định nghĩa `--z1`, `--t1`, `--bg`…)
|
||||
- **Range hiển thị**: chỉnh hằng `MAP.X_MIN/X_MAX/Y_MIN/Y_MAX` trong `static/app.js`
|
||||
- **Mặc định zones**: sửa `DEFAULT_ZONES` trong `static/app.js` và `STATE.zones[0..2]` trong `visualizer.py`
|
||||
|
||||
---
|
||||
|
||||
## 7. Troubleshooting
|
||||
|
||||
### Không mở được trang web
|
||||
1. **Ping Orange Pi**: `ping <OrangePi_IP>`
|
||||
2. **Kiểm tra port đang mở**: `ss -tulpn | grep 8000`
|
||||
3. **Tường lửa?** `sudo ufw allow 8000/tcp` hoặc tạm thời `sudo ufw disable`
|
||||
4. **Visualizer đang chạy?** `ps aux | grep visualizer`
|
||||
|
||||
### Không thấy dữ liệu radar (không có target)
|
||||
1. **Kiểm tra trạng thái ESP32** (chip màu đỏ/xanh trên cùng bên phải trang web)
|
||||
2. **Ping ESP32**: `ping 192.168.1.100`
|
||||
3. **Test REST ESP32**: `curl http://192.168.1.100/status` → phải có JSON `{"status":"ok",...}`
|
||||
4. **ESP32 đang DIAGNOSTIC_MODE 1?** → phải là `0` mới có WiFi/WebSocket
|
||||
5. **Parser ESP32 vẫn là stub?** → Target luôn `INVALID` nếu parser chưa triển khai (thông báo ở README gốc)
|
||||
|
||||
### Tốc độ cập nhật chậm
|
||||
- Mặc định radar LD2453 gửi ~2 frame/giây. Đó là giới hạn phần cứng.
|
||||
- Đảm bảo Orange Pi và ESP32 có tín hiệu WiFi tốt.
|
||||
|
||||
### WebSocket không kết nối (trình duyệt báo lỗi)
|
||||
- Mở DevTools (F12) → Console xem lỗi chi tiết
|
||||
- Kiểm tra trình duyệt truy cập đúng `http://<IP>:8000` (không phải `https://`)
|
||||
- Nếu dùng reverse proxy (Caddy/Nginx): cấu hình WebSocket upgrade (header `Upgrade: websocket`)
|
||||
|
||||
---
|
||||
|
||||
## 8. So sánh với bản cũ (Tkinter/Pygame)
|
||||
|
||||
| Đặc điểm | Tkinter cũ | **Web Visualizer mới** |
|
||||
|---|---|---|
|
||||
| Cần màn hình gắn Orange Pi? | ✅ Có | ❌ **Không** (xem trên trình duyệt bất kỳ đâu) |
|
||||
| Xem trên điện thoại? | ❌ Không | ✅ **Có** |
|
||||
| Nhiều người xem cùng lúc? | ❌ 1 người | ✅ **Không giới hạn** (multi-client) |
|
||||
| Đồ họa đẹp? | ⭐⭐ cơ bản | ⭐⭐⭐⭐⭐ **Canvas2D + hiệu ứng + sáng/tối** |
|
||||
| Chỉnh sửa zones? | Edit code Python | ✅ **Form trên web** |
|
||||
| Song ngữ VI/EN? | ❌ Không | ✅ **Có** |
|
||||
| Responsive mobile? | ❌ Không | ✅ **Có** |
|
||||
|
||||
---
|
||||
---
|
||||
|
||||
# 🇬🇧 English Version
|
||||
|
||||
# ESP32-S3 LD2453 Radar — Orange Pi Web Visualizer
|
||||
|
||||
Installation and usage guide for the **Web Visualizer** on Orange Pi (or any machine with Python 3.8+) to display realtime radar data via a beautiful web interface — **no Tkinter/Pygame desktop required anymore**.
|
||||
|
||||
---
|
||||
|
||||
## 1. Requirements
|
||||
|
||||
- Orange Pi / Raspberry Pi / Any PC with **Python 3.8+**
|
||||
- Same LAN as the ESP32 (Wi-Fi or Ethernet)
|
||||
- ESP32 IP address known (check Serial Monitor at boot, or router admin)
|
||||
|
||||
### 1.1 Folder structure
|
||||
```
|
||||
orangepi-server/
|
||||
├── visualizer.py # FastAPI server: connects to ESP32 + broadcasts to browsers
|
||||
├── requirements.txt # Python dependencies
|
||||
├── templates/
|
||||
│ └── index.html # Web UI HTML
|
||||
└── static/
|
||||
├── style.css # Styling: light/dark, responsive, bilingual
|
||||
└── app.js # Canvas renderer + browser WebSocket client
|
||||
```
|
||||
|
||||
### 1.2 Copy files to Orange Pi
|
||||
Copy the whole `orangepi-server/` folder to the Orange Pi. SCP example:
|
||||
```bash
|
||||
scp -r orangepi-server/ orangepi@<ORANGE_PI_IP>:/home/orangepi/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Install Python dependencies
|
||||
|
||||
```bash
|
||||
cd ~/orangepi-server
|
||||
|
||||
# (Recommended) Use a virtual env
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
# Install dependencies
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
**Global install (faster, not recommended):**
|
||||
```bash
|
||||
pip3 install -r requirements.txt
|
||||
```
|
||||
|
||||
> No `python3-tk` needed — everything runs in the browser.
|
||||
|
||||
---
|
||||
|
||||
## 3. Usage
|
||||
|
||||
### 3.1 Flash ESP32 in Full Stage mode
|
||||
In `config.h` (Arduino IDE):
|
||||
```cpp
|
||||
#define DIAGNOSTIC_MODE 0 // Full mode: WiFi + WebSocket + REST API
|
||||
```
|
||||
Flash the code, grab the ESP32 IP from Serial Monitor. Example: `192.168.1.100`.
|
||||
|
||||
### 3.2 Start the Web Visualizer on Orange Pi
|
||||
|
||||
```bash
|
||||
source venv/bin/activate # if using venv
|
||||
python3 visualizer.py 192.168.1.100
|
||||
```
|
||||
|
||||
CLI options:
|
||||
```bash
|
||||
# Custom port (default 8000):
|
||||
python3 visualizer.py 192.168.1.100 --port 8080
|
||||
|
||||
# Restrict to localhost only:
|
||||
python3 visualizer.py 192.168.1.100 --host 127.0.0.1
|
||||
|
||||
# Verbose logging:
|
||||
python3 visualizer.py 192.168.1.100 --verbose
|
||||
```
|
||||
|
||||
The console will print:
|
||||
```
|
||||
==============================================================
|
||||
ESP32-S3 LD2453 Radar — Web Visualizer
|
||||
==============================================================
|
||||
ESP32 : ws://192.168.1.100/ws
|
||||
Web UI : http://0.0.0.0:8000/
|
||||
WS UI : ws://<OrangePi_IP>:8000/ws
|
||||
==============================================================
|
||||
```
|
||||
|
||||
### 3.3 Open the web UI on any device
|
||||
On **any device on the same LAN** (phone, laptop, desktop…) open:
|
||||
```
|
||||
http://<OrangePi_IP>:8000/
|
||||
```
|
||||
Example: if Orange Pi IP is `192.168.1.50` → `http://192.168.1.50:8000/`
|
||||
|
||||
---
|
||||
|
||||
## 4. Web UI features
|
||||
|
||||
### 4.1 Highlights
|
||||
| Feature | Description |
|
||||
|---|---|
|
||||
| 🎨 **Beautiful UI** | Light/Dark themes with Catppuccin color palette |
|
||||
| 🌐 **Bilingual** | Vietnamese / English toggle in header |
|
||||
| 📱 **Responsive** | Looks great on mobile, tablet, desktop |
|
||||
| 🧭 **Radar Canvas** | Grid, concentric range rings, sweep animation |
|
||||
| 🎯 **Targets** | Up to 3 colored targets, trails, velocity arrows, labels |
|
||||
| 🟩 **Zones** | 3 rectangular zones with occupancy state badges |
|
||||
| 📊 **Stats** | Frames received, valid targets, occupied zones, latency |
|
||||
| 📝 **Details** | Per-target and per-zone info in the right panel |
|
||||
| ✏️ **Zone editor** | Edit zone coordinates directly in the UI → pushes to ESP32 |
|
||||
| 🔗 **Multi-client** | Any number of browser tabs/screens stay in sync |
|
||||
|
||||
### 4.2 Header
|
||||
- 🟢/🟡/🔴 ESP32 + WebSocket connection status chips
|
||||
- ☀️/🌙 Theme toggle (Light/Dark)
|
||||
- `VI / EN` Language toggle
|
||||
|
||||
### 4.3 Radar View (Canvas)
|
||||
- **Grid**: 1m cells with labels (−5m ← 0 → +5m horizontal, 0 → 7m forward)
|
||||
- **Range rings**: Dashed concentric arcs every 1m from the radar
|
||||
- **Radar dot**: Red circle at bottom-center with "RADAR" label
|
||||
- **Sweep effect**: Rotating semi-transparent cone (toggleable)
|
||||
- **Zones (3 rectangles)**:
|
||||
- Z1 (Green), Z2 (Orange), Z3 (Red)
|
||||
- Occupied → solid fill, bold border, `OCCUPIED` badge
|
||||
- Empty → faint fill, dashed border, `EMPTY` badge
|
||||
- **Targets (3 slots)**:
|
||||
- Colors: Yellow (S1), Purple (S2), Cyan (S3)
|
||||
- Glowing dots with white outline
|
||||
- Velocity arrow (length ∝ cm/s, points along direction)
|
||||
- Label: `T# | X,Y mm | speed cm/s`
|
||||
- Fading trail for each target, persists ~3.5s
|
||||
- Recently-lost targets show as dashed ghost circles
|
||||
|
||||
### 4.4 Tool toggles (top-right of canvas)
|
||||
- Sweep effect on/off
|
||||
- Target trails on/off
|
||||
- Zone/target labels on/off
|
||||
|
||||
### 4.5 Side panels (right column)
|
||||
**Statistics:**
|
||||
- Total frames received
|
||||
- Seconds since last frame
|
||||
- Valid targets / 3
|
||||
- Occupied zones / 3
|
||||
|
||||
**Target details:**
|
||||
- Colored cards per target with status badge (`Detected`/`Recently seen`/`Free`)
|
||||
- X/Y (mm), Speed (cm/s), Distance (m), Angle (°)
|
||||
|
||||
**Zones:**
|
||||
- Per-zone list with coordinates and status
|
||||
- **Edit zones** button opens a form (X1/Y1/X2/Y2 in mm):
|
||||
- *Reset defaults* → reload original layout
|
||||
- *Cancel* → close without saving
|
||||
- *Save & Apply* → POST to `/api/zones` → forwarded to ESP32 `/updateZones` with success toast
|
||||
|
||||
---
|
||||
|
||||
## 5. Architecture & data flow
|
||||
|
||||
```
|
||||
┌───────────┐ WebSocket /ws ┌──────────────────┐ WebSocket /ws ┌──────────────┐
|
||||
│ ESP32-S3 │ ◄──────────────────► │ Orange Pi (WS │ ◄──────────────────► │ Browser │
|
||||
│ LD2453 │ JSON radar frames │ FastAPI Server) │ synced state JSON │ (Canvas 2D) │
|
||||
└───────────┘ └──────────────────┘ └──────────────┘
|
||||
▲ ▲ ▲
|
||||
│ REST /zones /updateZones │ GET / → index.html │
|
||||
└───────────────────────────────────┘ GET /static/* → CSS, JS │
|
||||
Zone edits in the UI are forwarded to the ESP32 │
|
||||
```
|
||||
|
||||
**Endpoints:**
|
||||
| Method | Endpoint | Purpose |
|
||||
|---|---|---|
|
||||
| GET | `/` | Main web page |
|
||||
| GET | `/api/state` | Current radar state (fallback poll) |
|
||||
| GET | `/api/zones` | Zones list |
|
||||
| POST | `/api/zones` | Update zones (forwarded to ESP32 `/updateZones`) |
|
||||
| WS | `/ws` | Realtime broadcast for browser clients |
|
||||
|
||||
---
|
||||
|
||||
## 6. Background running & customization
|
||||
|
||||
### 6.1 Run with tmux
|
||||
```bash
|
||||
tmux new -s radar
|
||||
cd ~/orangepi-server && source venv/bin/activate
|
||||
python3 visualizer.py 192.168.1.100
|
||||
# Ctrl+B D → detach; tmux attach -t radar to return
|
||||
```
|
||||
|
||||
### 6.2 systemd service (auto-start at boot)
|
||||
Create `/etc/systemd/system/radar-web.service`:
|
||||
```ini
|
||||
[Unit]
|
||||
Description=LD2453 Radar Web Visualizer
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=orangepi
|
||||
WorkingDirectory=/home/orangepi/orangepi-server
|
||||
ExecStart=/home/orangepi/orangepi-server/venv/bin/python3 /home/orangepi/orangepi-server/visualizer.py 192.168.1.100 --port 8000
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
Environment=PYTHONUNBUFFERED=1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
Then:
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable radar-web
|
||||
sudo systemctl start radar-web
|
||||
journalctl -u radar-web -f # Live logs
|
||||
```
|
||||
|
||||
### 6.3 Customization tips
|
||||
- **Colors/themes**: edit CSS variables at top of `static/style.css` (`--z1`, `--t1`, `--bg`…)
|
||||
- **Display range**: tweak `MAP.X_MIN/X_MAX/Y_MIN/Y_MAX` constants in `static/app.js`
|
||||
- **Default zones**: modify `DEFAULT_ZONES` in `static/app.js` and `STATE.zones[0..2]` in `visualizer.py`
|
||||
|
||||
---
|
||||
|
||||
## 7. Troubleshooting
|
||||
|
||||
### Can't open the web page
|
||||
1. Ping Orange Pi: `ping <OrangePi_IP>`
|
||||
2. Check open port: `ss -tulpn | grep 8000`
|
||||
3. Firewall? `sudo ufw allow 8000/tcp`
|
||||
4. Is visualizer running? `ps aux | grep visualizer`
|
||||
|
||||
### No radar targets visible
|
||||
1. Check ESP32 connection status chip (top-right corner of UI)
|
||||
2. Ping ESP32: `ping 192.168.1.100`
|
||||
3. Test ESP32 REST: `curl http://192.168.1.100/status` → JSON expected
|
||||
4. ESP32 still in `DIAGNOSTIC_MODE 1`? → set to `0` for WiFi/WebSocket
|
||||
5. ESP32 parser is still stubbed? → Targets always `INVALID` until real byte parser is implemented (see main repo README)
|
||||
|
||||
### Slow UI updates
|
||||
- LD2453 radar sends ~2 frames/second by design (hardware limit)
|
||||
- Ensure good Wi-Fi signal on both ESP32 and Orange Pi
|
||||
|
||||
### Browser WebSocket fails to connect
|
||||
- Open DevTools → Console for the exact error
|
||||
- Make sure you visit `http://<IP>:8000` (not `https://`)
|
||||
- If behind Caddy/Nginx: enable WebSocket upgrade headers (`Upgrade: websocket`)
|
||||
|
||||
---
|
||||
|
||||
## 8. Comparison with old Tkinter/Pygame version
|
||||
|
||||
| Aspect | Old Tkinter | **New Web Visualizer** |
|
||||
|---|---|---|
|
||||
| Requires a monitor on Orange Pi? | Yes | ❌ **No** — view anywhere |
|
||||
| View on phone? | No | ✅ **Yes** |
|
||||
| Multiple viewers? | No | ✅ **Unlimited clients** |
|
||||
| Graphics quality | Basic ⭐⭐ | **Canvas + effects + themes ⭐⭐⭐⭐⭐** |
|
||||
| Zone editor | Edit Python | ✅ **In-UI form** |
|
||||
| i18n (VI/EN) | No | ✅ **Built-in** |
|
||||
| Mobile responsive | No | ✅ **Yes** |
|
||||
Reference in new issue
Block a user