416 lines
14 KiB
Markdown
416 lines
14 KiB
Markdown
# RobotNet10.FleetManager
|
|
|
|
Hệ thống quản lý và điều phối đội robot AMR (Autonomous Mobile Robot) theo chuẩn **VDA 5050**, xây dựng trên nền tảng **.NET 10 Blazor**.
|
|
|
|
---
|
|
|
|
## Mục lục
|
|
|
|
- [Tổng quan](#tổng-quan)
|
|
- [Yêu cầu hệ thống](#yêu-cầu-hệ-thống)
|
|
- [Cấu trúc project](#cấu-trúc-project)
|
|
- [Cấu hình](#cấu-hình)
|
|
- [Build & Chạy local](#build--chạy-local)
|
|
- [Docker](#docker)
|
|
- [Các services phụ thuộc](#các-services-phụ-thuộc)
|
|
- [Tài khoản mặc định](#tài-khoản-mặc-định)
|
|
|
|
---
|
|
|
|
## Tổng quan
|
|
|
|
FleetManager là ứng dụng **Blazor Web App** chạy trên server nhà máy, cung cấp:
|
|
|
|
| Tính năng | Mô tả |
|
|
|---|---|
|
|
| **Robot Management** | Quản lý kết nối và trạng thái nhiều robot qua MQTT/VDA 5050 |
|
|
| **Traffic Control** | Tự động tính route, phát hiện và giải quyết xung đột |
|
|
| **Map Editor** | Tạo và quản lý bản đồ nhà máy |
|
|
| **Script Engine** | Viết và chạy C# script để tự động hóa mission |
|
|
| **Real-time Monitor** | Theo dõi toàn đội robot qua SignalR |
|
|
| **Web UI** | Giao diện Blazor + MudBlazor (15 trang) |
|
|
|
|
**Tech stack:** .NET 10 · Blazor (Server + WASM) · SignalR · MQTT (MQTTnet 5) · EF Core · SQL Server · MinIO
|
|
|
|
---
|
|
|
|
## Yêu cầu hệ thống
|
|
|
|
### Để build
|
|
|
|
| Yêu cầu | Phiên bản |
|
|
|---|---|
|
|
| .NET SDK | **10.0** trở lên |
|
|
| Git | Bất kỳ |
|
|
|
|
### Để chạy (runtime dependencies)
|
|
|
|
| Service | Mô tả | Cổng mặc định |
|
|
|---|---|---|
|
|
| **SQL Server** | 3 database: App, Layout, Script | 1433 |
|
|
| **MinIO** | Object storage (ảnh robot model, layout, config) | 9000 |
|
|
| **MQTT Broker** | Eclipse Mosquitto hoặc tương đương | 1883 |
|
|
|
|
---
|
|
|
|
## Cấu trúc project
|
|
|
|
```
|
|
srcs/RobotNet10/
|
|
├── FleetManager/
|
|
│ ├── RobotNet10.FleetManager/ # Main web app (backend + Blazor Server)
|
|
│ │ ├── Components/ # Razor components & pages
|
|
│ │ ├── Controllers/ # REST API controllers
|
|
│ │ ├── Data/ # EF Core DbContext & Migrations
|
|
│ │ ├── Events/ # VDA 5050 event bus
|
|
│ │ ├── Hubs/ # SignalR hub
|
|
│ │ ├── Services/
|
|
│ │ │ ├── ConfigManager/ # MQTT/Traffic config
|
|
│ │ │ ├── OpenACS/ # ACS traffic integration
|
|
│ │ │ ├── RobotConnections/ # VDA 5050 MQTT connections
|
|
│ │ │ ├── RobotManager/ # VDA 5050 robot management
|
|
│ │ │ ├── Script/ # Script engine integration
|
|
│ │ │ └── TrafficControl/ # Route planning & conflict resolution
|
|
│ │ ├── appsettings.json
|
|
│ │ ├── nlog.config
|
|
│ │ └── Program.cs
|
|
│ │
|
|
│ ├── RobotNet10.FleetManager.Client/ # Blazor WASM (frontend UI)
|
|
│ │ ├── Pages/ # 15 trang UI
|
|
│ │ └── Services/ # API & SignalR client services
|
|
│ │
|
|
│ ├── RobotNet10.FleetManager.Shared/ # DTOs, Models, Enums dùng chung
|
|
│ ├── RobotNet10.FleetManager.Script/ # Script engine cho FleetManager
|
|
│ └── RobotNet10.FleetManager.Script.Shared/
|
|
│
|
|
├── Commons/ # Các thư viện dùng chung
|
|
│ ├── RobotNet10.MapManager/ # Quản lý bản đồ + EF migrations
|
|
│ ├── RobotNet10.ScriptEngine/ # Script engine core
|
|
│ ├── RobotNet10.MqttConnection/ # MQTT wrapper
|
|
│ └── ...
|
|
│
|
|
├── Shared/
|
|
│ └── RobotNet.VDA5050/ # VDA 5050 standard models
|
|
│
|
|
├── Dockerfile.FleetManager # Docker build file
|
|
└── .dockerignore
|
|
```
|
|
|
|
---
|
|
|
|
## Cấu hình
|
|
|
|
Tất cả cấu hình nằm trong `RobotNet10.FleetManager/appsettings.json`.
|
|
|
|
### Connection Strings (bắt buộc)
|
|
|
|
```json
|
|
{
|
|
"ConnectionStrings": {
|
|
"DefaultConnection": "Server=<SQL_HOST>;Database=RobotNet10.FleetManager;User Id=sa;Password=<PASSWORD>;TrustServerCertificate=True;MultipleActiveResultSets=true",
|
|
"MapEditorConnection": "Server=<SQL_HOST>;Database=RobotNet10.Layout;User Id=sa;Password=<PASSWORD>;TrustServerCertificate=True;MultipleActiveResultSets=true",
|
|
"ScriptEngineConnection":"Server=<SQL_HOST>;Database=RobotNet10.Script;User Id=sa;Password=<PASSWORD>;TrustServerCertificate=True;MultipleActiveResultSets=true"
|
|
}
|
|
}
|
|
```
|
|
|
|
> **Lưu ý:** EF Core sẽ tự tạo database và chạy migration khi khởi động lần đầu.
|
|
|
|
### MinIO (object storage)
|
|
|
|
```json
|
|
{
|
|
"StorageConfig": {
|
|
"UsingLocal": false,
|
|
"Bucket": "fleet-custom-configs",
|
|
"MinioConfig": {
|
|
"Endpoint": "<MINIO_HOST>:9000",
|
|
"User": "minio",
|
|
"Password": "<MINIO_PASSWORD>",
|
|
"EnableSSL": false
|
|
}
|
|
},
|
|
"LayoutImage": {
|
|
"UsingLocal": false,
|
|
"Bucket": "fleet-layout-images",
|
|
"MinioConfig": { "Endpoint": "<MINIO_HOST>:9000", "User": "minio", "Password": "<MINIO_PASSWORD>" }
|
|
},
|
|
"RobotModelImage": {
|
|
"UsingLocal": false,
|
|
"Bucket": "robotmodel-images",
|
|
"MinioConfig": { "Endpoint": "<MINIO_HOST>:9000", "User": "minio", "Password": "<MINIO_PASSWORD>" }
|
|
}
|
|
}
|
|
```
|
|
|
|
> Đặt `"UsingLocal": true` để dùng thư mục local thay vì MinIO (phù hợp môi trường dev).
|
|
|
|
### ScriptEngine DLL folder
|
|
|
|
```json
|
|
{
|
|
"ScriptEngine": {
|
|
"RuntimeDllFolder": "bin/dlls"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Build & Chạy local
|
|
|
|
### 1. Clone và di chuyển vào thư mục solution
|
|
|
|
```bash
|
|
git clone <repo-url>
|
|
cd srcs/RobotNet10
|
|
```
|
|
|
|
### 2. Restore packages
|
|
|
|
```bash
|
|
dotnet restore FleetManager/RobotNet10.FleetManager/RobotNet10.FleetManager.csproj
|
|
```
|
|
|
|
### 3. Cấu hình connection strings
|
|
|
|
Sửa `FleetManager/RobotNet10.FleetManager/appsettings.json` hoặc dùng User Secrets:
|
|
|
|
```bash
|
|
cd FleetManager/RobotNet10.FleetManager
|
|
|
|
dotnet user-secrets set "ConnectionStrings:DefaultConnection" \
|
|
"Server=localhost;Database=RobotNet10.FleetManager;User Id=sa;Password=YourPassword;TrustServerCertificate=True"
|
|
|
|
dotnet user-secrets set "ConnectionStrings:MapEditorConnection" \
|
|
"Server=localhost;Database=RobotNet10.Layout;User Id=sa;Password=YourPassword;TrustServerCertificate=True"
|
|
|
|
dotnet user-secrets set "ConnectionStrings:ScriptEngineConnection" \
|
|
"Server=localhost;Database=RobotNet10.Script;User Id=sa;Password=YourPassword;TrustServerCertificate=True"
|
|
```
|
|
|
|
### 4. Chạy ứng dụng
|
|
|
|
```bash
|
|
# Từ thư mục srcs/RobotNet10/
|
|
dotnet run --project FleetManager/RobotNet10.FleetManager/RobotNet10.FleetManager.csproj
|
|
```
|
|
|
|
Ứng dụng sẽ tự động:
|
|
- Tạo database và chạy EF Core migrations
|
|
- Seed dữ liệu ban đầu (user admin mặc định)
|
|
- Khởi động web server tại `https://localhost:5001` / `http://localhost:5000`
|
|
|
|
### 5. Build Release
|
|
|
|
```bash
|
|
dotnet publish FleetManager/RobotNet10.FleetManager/RobotNet10.FleetManager.csproj \
|
|
-c Release \
|
|
-o ./publish
|
|
```
|
|
|
|
---
|
|
|
|
## Docker
|
|
|
|
### Yêu cầu
|
|
|
|
- Docker Desktop hoặc Docker Engine với Linux containers
|
|
- Build context phải là thư mục `srcs/RobotNet10/`
|
|
|
|
### Chuẩn bị certificate (HTTPS)
|
|
|
|
Đặt file certificate `.pfx` vào thư mục `certs/` trước khi chạy container:
|
|
|
|
```bash
|
|
# Tùy chọn 1 — dùng dotnet dev-certs (self-signed, phù hợp dev/test)
|
|
dotnet dev-certs https -ep certs/fleet-manager.pfx -p YourCertPassword
|
|
|
|
# Tùy chọn 2 — dùng openssl (tự ký)
|
|
openssl req -x509 -newkey rsa:4096 -keyout certs/key.pem -out certs/cert.pem -days 365 -nodes \
|
|
-subj "/CN=fleet-manager"
|
|
openssl pkcs12 -export -out certs/fleet-manager.pfx \
|
|
-inkey certs/key.pem -in certs/cert.pem -passout pass:YourCertPassword
|
|
|
|
# Tùy chọn 3 — dùng certificate thật từ CA (Let's Encrypt, v.v.)
|
|
# Chuyển đổi sang .pfx nếu đang ở dạng .pem:
|
|
openssl pkcs12 -export -out certs/fleet-manager.pfx \
|
|
-inkey certs/privkey.pem -in certs/fullchain.pem -passout pass:YourCertPassword
|
|
```
|
|
|
|
> `certs/*.pfx` đã được loại khỏi `.dockerignore` — certificate **không bao giờ** được copy vào image, chỉ được mount tại runtime.
|
|
|
|
### Build image
|
|
|
|
```bash
|
|
# Chạy từ srcs/RobotNet10/
|
|
docker build -f FleetManager/Dockerfile -t robotnet10-fleet-manager:latest .
|
|
```
|
|
|
|
Quá trình build gồm 2 stage:
|
|
1. **Build stage** (mcr.microsoft.com/dotnet/sdk:10.0): Restore + Publish Release
|
|
2. **Runtime stage** (mcr.microsoft.com/dotnet/aspnet:10.0): Chỉ chứa output đã publish
|
|
|
|
Kích thước image cuối: **~211 MB** (content size) — Ports: HTTP `8080`, HTTPS `8081`
|
|
|
|
### Chạy container
|
|
|
|
```bash
|
|
docker run -d \
|
|
-p 8080:8080 -p 8081:8081 \
|
|
-v ./certs:/app/certs:ro \
|
|
-e ASPNETCORE_Kestrel__Certificates__Default__Path=/app/certs/fleet-manager.pfx \
|
|
-e ASPNETCORE_Kestrel__Certificates__Default__Password="YourCertPassword" \
|
|
-e ConnectionStrings__DefaultConnection="Server=<SQL_HOST>;Database=RobotNet10.FleetManager;User Id=sa;Password=<PASSWORD>;TrustServerCertificate=True;MultipleActiveResultSets=true" \
|
|
-e ConnectionStrings__MapEditorConnection="Server=<SQL_HOST>;Database=RobotNet10.Layout;User Id=sa;Password=<PASSWORD>;TrustServerCertificate=True;MultipleActiveResultSets=true" \
|
|
-e ConnectionStrings__ScriptEngineConnection="Server=<SQL_HOST>;Database=RobotNet10.Script;User Id=sa;Password=<PASSWORD>;TrustServerCertificate=True;MultipleActiveResultSets=true" \
|
|
--name fleet-manager \
|
|
robotnet10-fleet-manager:latest
|
|
```
|
|
|
|
> **Chú ý:** Dùng `__` (hai dấu gạch dưới) thay cho `:` khi truyền environment variable trong Docker.
|
|
|
|
### Gắn volume cho logs
|
|
|
|
```bash
|
|
docker run -d \
|
|
-p 8080:8080 \
|
|
-v /host/path/logs:/app/logs \
|
|
-e ConnectionStrings__DefaultConnection="..." \
|
|
--name fleet-manager \
|
|
robotnet10-fleet-manager:latest
|
|
```
|
|
|
|
### Docker Compose (khuyến nghị)
|
|
|
|
File [docker-compose.yml](docker-compose.yml) quản lý **fleet-manager** và kết nối đến SQL Server, MinIO, MQTT Broker đã có sẵn bên ngoài.
|
|
|
|
```bash
|
|
# 1. Tạo file .env từ template (từ thư mục FleetManager/)
|
|
cp .env.example .env
|
|
# Điền SQL Server host, MinIO host và các thông tin kết nối vào .env
|
|
|
|
# 2. Chạy container
|
|
docker compose up -d
|
|
|
|
# 3. Xem trạng thái
|
|
docker compose ps
|
|
|
|
# 4. Xem log
|
|
docker compose logs -f fleet-manager
|
|
```
|
|
|
|
**Các biến cần thiết trong `.env`:**
|
|
|
|
| Biến | Mô tả |
|
|
|---|---|
|
|
| `DB_DEFAULT_CONNECTION` | Connection string SQL Server (App DB) |
|
|
| `DB_MAP_CONNECTION` | Connection string SQL Server (Layout DB) |
|
|
| `DB_SCRIPT_CONNECTION` | Connection string SQL Server (Script DB) |
|
|
| `MINIO_ENDPOINT` | Địa chỉ MinIO, ví dụ `192.168.1.100:9000` |
|
|
| `MINIO_PASSWORD` | Mật khẩu MinIO |
|
|
| `FLEET_PORT` | Port expose web app (mặc định `8080`) |
|
|
|
|
---
|
|
|
|
## Các services phụ thuộc
|
|
|
|
### SQL Server
|
|
|
|
Ứng dụng cần **3 database** riêng biệt (tự tạo khi khởi động):
|
|
|
|
| Database | Connection String key | Mục đích |
|
|
|---|---|---|
|
|
| `RobotNet10.FleetManager` | `DefaultConnection` | User identity, Robot, RobotModel |
|
|
| `RobotNet10.Layout` | `MapEditorConnection` | Bản đồ nhà máy (nodes, edges, stations) |
|
|
| `RobotNet10.Script` | `ScriptEngineConnection` | Script engine data |
|
|
|
|
### MinIO
|
|
|
|
Tạo 3 bucket sau trong MinIO console (`http://<host>:9001`) trước khi chạy ứng dụng:
|
|
|
|
| Bucket | Config key | Mục đích |
|
|
|---|---|---|
|
|
| `fleet-custom-configs` | `StorageConfig.Bucket` | Custom configuration files |
|
|
| `fleet-layout-images` | `LayoutImage.Bucket` | Ảnh nền bản đồ |
|
|
| `robotmodel-images` | `RobotModelImage.Bucket` | Ảnh robot model |
|
|
|
|
> **Dev mode:** Đặt `"UsingLocal": true` để bỏ qua MinIO, dùng thư mục local.
|
|
|
|
### MQTT Broker
|
|
|
|
FleetManager kết nối đến MQTT Broker theo cấu hình trong **UI** (trang Config Manager), không cần cấu hình trong `appsettings.json`. Broker phổ biến:
|
|
|
|
```bash
|
|
# Eclipse Mosquitto (Docker)
|
|
docker run -d -p 1883:1883 -p 9883:9883 eclipse-mosquitto
|
|
```
|
|
|
|
---
|
|
|
|
## Tài khoản mặc định
|
|
|
|
Khi ứng dụng khởi động lần đầu, seed data sẽ tạo tài khoản admin:
|
|
|
|
| Trường | Giá trị |
|
|
|---|---|
|
|
| **Username/Email** | `admin@robotnet.local` |
|
|
| **Password** | `Admin@123` |
|
|
| **Role** | Administrator |
|
|
|
|
> **Quan trọng:** Đổi mật khẩu ngay sau lần đăng nhập đầu tiên trong môi trường production.
|
|
|
|
---
|
|
|
|
## Logs
|
|
|
|
Log được ghi vào thư mục `logs/` theo cấu hình NLog (`nlog.config`):
|
|
|
|
- Format: JSON, mỗi ngày một file (`YYYY-MM-DD.log`)
|
|
- Giữ tối đa 90 ngày
|
|
- Đường dẫn: `<app_dir>/logs/`
|
|
|
|
```bash
|
|
# Xem log trong container
|
|
docker logs fleet-manager
|
|
docker exec fleet-manager tail -f /app/logs/$(date +%Y-%m-%d).log
|
|
```
|
|
|
|
---
|
|
|
|
## Các lệnh Docker hữu ích
|
|
|
|
```bash
|
|
# Xem danh sách images
|
|
docker images robotnet10-fleet-manager
|
|
|
|
# Xem logs container
|
|
docker logs -f fleet-manager
|
|
|
|
# Vào shell container
|
|
docker exec -it fleet-manager bash
|
|
|
|
# Dừng và xóa container
|
|
docker stop fleet-manager && docker rm fleet-manager
|
|
|
|
# Rebuild image (sau khi cập nhật code)
|
|
docker build -f FleetManager/Dockerfile -t robotnet10-fleet-manager:latest . --no-cache
|
|
|
|
# Export image để chuyển sang máy khác
|
|
docker save robotnet10-fleet-manager:latest | gzip > fleet-manager.tar.gz
|
|
|
|
# Load image từ file
|
|
docker load < fleet-manager.tar.gz
|
|
```
|
|
|
|
---
|
|
|
|
## Tài liệu chi tiết
|
|
|
|
- [Architecture Overview](../../../docs/fleetmanager/README.md)
|
|
- [Traffic Control](../../../docs/fleetmanager/TrafficControl.md)
|
|
- [Robot Connections](../../../docs/fleetmanager/RobotConnections.md)
|
|
- [Script Engine](../../../docs/fleetmanager/ScriptEngine.md)
|
|
- [Map Editor](../../../docs/fleetmanager/MapEditor.md)
|
|
- [Configuration](../../../docs/fleetmanager/FleetManagerConfig.md)
|