Files
I150/srcs/RobotNet10/FleetManager
2026-07-03 16:37:12 +07:00
..
2026-07-03 16:37:12 +07:00
2026-07-03 16:37:12 +07:00
2026-07-03 16:37:12 +07:00
2026-07-03 16:37:12 +07:00
2026-07-03 16:37:12 +07:00
2026-07-03 16:37:12 +07:00
2026-07-03 16:37:12 +07:00

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

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)

{
  "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)

{
  "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

{
  "ScriptEngine": {
    "RuntimeDllFolder": "bin/dlls"
  }
}

Build & Chạy local

1. Clone và di chuyển vào thư mục solution

git clone <repo-url>
cd srcs/RobotNet10

2. Restore packages

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:

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

# 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

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:

# 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

# 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

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

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 quản lý fleet-manager và kết nối đến SQL Server, MinIO, MQTT Broker đã có sẵn bên ngoài.

# 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:

# 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/
# 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

# 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