# 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=;Database=RobotNet10.FleetManager;User Id=sa;Password=;TrustServerCertificate=True;MultipleActiveResultSets=true", "MapEditorConnection": "Server=;Database=RobotNet10.Layout;User Id=sa;Password=;TrustServerCertificate=True;MultipleActiveResultSets=true", "ScriptEngineConnection":"Server=;Database=RobotNet10.Script;User Id=sa;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": ":9000", "User": "minio", "Password": "", "EnableSSL": false } }, "LayoutImage": { "UsingLocal": false, "Bucket": "fleet-layout-images", "MinioConfig": { "Endpoint": ":9000", "User": "minio", "Password": "" } }, "RobotModelImage": { "UsingLocal": false, "Bucket": "robotmodel-images", "MinioConfig": { "Endpoint": ":9000", "User": "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 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=;Database=RobotNet10.FleetManager;User Id=sa;Password=;TrustServerCertificate=True;MultipleActiveResultSets=true" \ -e ConnectionStrings__MapEditorConnection="Server=;Database=RobotNet10.Layout;User Id=sa;Password=;TrustServerCertificate=True;MultipleActiveResultSets=true" \ -e ConnectionStrings__ScriptEngineConnection="Server=;Database=RobotNet10.Script;User Id=sa;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://: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: `/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)