@page "/robot-state" @using RobotApp.VDA5050.State @rendermode InteractiveWebAssemblyNoPrerender @inject StateMsg RobotState
🤖 VDA 5050 Robot Dashboard @RobotState.Version • @RobotState.Manufacturer @RobotState.SerialNumber
@* @if (RobotState.Current != null) { @(RobotState.Current.IsOnline ? "ONLINE" : "OFFLINE") } *@
@if (RobotState == null) { Waiting for robot state (VDA5050)... } else { var msg = RobotState; HeaderId @msg.HeaderId Timestamp (UTC) @msg.Timestamp Version @msg.Version OrderUpdateId @msg.OrderUpdateId 📍 Position & Velocity NewBase: @(msg.NewBaseRequest ? "TRUE" : "FALSE") X: @msg.AgvPosition.X.ToString("F2") m Y: @msg.AgvPosition.Y.ToString("F2") m θ: @msg.AgvPosition.Theta.ToString("F2") rad Vx: @msg.Velocity.Vx.ToString("F2") m/s Vy: @msg.Velocity.Vy.ToString("F2") m/s Ω: @msg.Velocity.Omega.ToString("F3") rad/s Initialized: @(msg.AgvPosition.PositionInitialized ? "TRUE" : "FALSE") DeviationRange: @msg.AgvPosition.DeviationRange Localization Score: @(msg.AgvPosition.LocalizationScore * 100) % 🔋 Battery @msg.BatteryState.BatteryCharge:F1 % @(msg.BatteryState.Charging ? "⚡ Charging" : "Discharging") Voltage @msg.BatteryState.BatteryVoltage.ToString("F1") V Health @msg.BatteryState.BatteryHealth % Reach @((int)msg.BatteryState.Reach) m 🧭 Order & Path Order ID: @(msg.OrderId ?? "—") Update ID: @msg.OrderUpdateId Last Node: @msg.LastNodeId Seq: @msg.LastNodeSequenceId Distance: @msg.DistanceSinceLastNode:F1 m @{ var nodeReleased = msg.NodeStates?.Count(n => n.Released) ?? 0; var nodeTotal = msg.NodeStates?.Length ?? 0; var edgeReleased = msg.EdgeStates?.Count(e => e.Released) ?? 0; var edgeTotal = msg.EdgeStates?.Length ?? 0; }
Nodes: @nodeReleased / @nodeTotal Edges: @edgeReleased / @edgeTotal @(msg.Driving ? "DRIVING" : "STOPPED") @(msg.Paused ? "PAUSED" : "ACTIVE")
🚨 Errors & Information @{ var rows = new List(); if (msg.Errors != null) { foreach (var err in msg.Errors) { rows.Add(new MessageRow( err.ErrorType ?? "-", err.ErrorLevel ?? "-", err.ErrorDescription ?? "", true )); } } if (msg.Information != null) { foreach (var info in msg.Information) { rows.Add(new MessageRow( info.InfoType ?? "-", info.InfoLevel ?? "-", info.InfoDescription ?? "", false )); } } var sortedMessages = rows .OrderBy(r => r.IsError ? 0 : 1) // Errors trước .ThenBy(r => r.Type) .ToList(); } Type Level Description @context.Type @context.Level @context.Description No errors or information messages ⚙️ Actions Action Action ID Status @context.ActionType @context.ActionId @context.ActionStatus No active actions 🛑 Safety E-STOP: @msg.SafetyState.EStop Field Violation: @(msg.SafetyState.FieldViolation ? "YES" : "NO")
}
@code { private async Task OnStateChanged() => await InvokeAsync(StateHasChanged); private record MessageRow( string Type, string Level, string Description, bool IsError ); }