201 lines
8.4 KiB
Plaintext
201 lines
8.4 KiB
Plaintext
@using MudBlazor
|
|
@using RobotNet.VDA5050.State
|
|
@using RobotNet.VDA5050.Type
|
|
@using RobotNet10.FleetManager.Client.Components.RobotDetail
|
|
@using RobotNet10.FleetManager.Client.Components.RobotMonitor
|
|
@using RobotNet10.FleetManager.Client.Services
|
|
|
|
@implements IDisposable
|
|
|
|
<MudStack Spacing="3">
|
|
<!-- Robot Header Info -->
|
|
<MudPaper Class="pa-3" Elevation="1" Style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);">
|
|
<MudStack Spacing="2">
|
|
<MudText Typo="Typo.h6" Style="color: white;">
|
|
@GetRobotName()
|
|
</MudText>
|
|
<MudText Typo="Typo.body2" Style="color: rgba(255, 255, 255, 0.8);">
|
|
ID: @RobotData.RobotId
|
|
</MudText>
|
|
@if (RobotData.Model != null)
|
|
{
|
|
<MudChip T="string" Size="Size.Small" Style="background: rgba(255, 255, 255, 0.2); color: white;">
|
|
@RobotData.Model.ModelName
|
|
</MudChip>
|
|
}
|
|
@if (RobotData.LastUpdateTime != default)
|
|
{
|
|
<MudText Typo="Typo.caption" Style="color: rgba(255, 255, 255, 0.7);">
|
|
Last update: @RobotData.LastUpdateTime.ToLocalTime().ToString("HH:mm:ss")
|
|
</MudText>
|
|
}
|
|
</MudStack>
|
|
</MudPaper>
|
|
|
|
<!-- Position Info (Quick View) -->
|
|
@if (RobotData.Data != null)
|
|
{
|
|
<MudPaper Class="pa-3" Elevation="1">
|
|
<MudText Typo="Typo.subtitle2" Class="mb-2">Visualization</MudText>
|
|
<MudSimpleTable Dense="true" Elevation="0">
|
|
<tbody>
|
|
<tr>
|
|
<td><strong>X:</strong></td>
|
|
<td>@RobotData.Data.AgvPosition.X.ToString("F2") m</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Y:</strong></td>
|
|
<td>@RobotData.Data.AgvPosition.Y.ToString("F2") m</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Θ:</strong></td>
|
|
<td>@((RobotData.Data.AgvPosition.Theta * 180.0 / Math.PI).ToString("F1"))°</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Vx:</strong></td>
|
|
<td>@RobotData.Data.AgvVelocity.Vx.ToString("F2") m/s</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Vy:</strong></td>
|
|
<td>@RobotData.Data.AgvVelocity.Vy.ToString("F2") m/s</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Omega:</strong></td>
|
|
<td>@RobotData.Data.AgvVelocity.Omega.ToString("F2") rad/s</td>
|
|
</tr>
|
|
<tr>
|
|
<td><strong>Position Initialized:</strong></td>
|
|
<td>
|
|
<MudChip T="string"
|
|
Size="Size.Small"
|
|
Color="@(RobotData.Data.AgvPosition.PositionInitialized ? Color.Success : Color.Warning)">
|
|
@(RobotData.Data.AgvPosition.PositionInitialized ? "Yes" : "No")
|
|
</MudChip>
|
|
</td>
|
|
</tr>
|
|
@if (RobotData.Data.AgvPosition.LocalizationScore >= 0)
|
|
{
|
|
<tr>
|
|
<td><strong>Localization Score:</strong></td>
|
|
<td>@RobotData.Data.AgvPosition.LocalizationScore.ToString("F2")</td>
|
|
</tr>
|
|
}
|
|
@if (RobotData.Data.AgvPosition.DeviationRange >= 0)
|
|
{
|
|
<tr>
|
|
<td><strong>Deviation Range:</strong></td>
|
|
<td>@RobotData.Data.AgvPosition.DeviationRange.ToString("F2") m</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</MudSimpleTable>
|
|
</MudPaper>
|
|
}
|
|
|
|
<!-- Expansion Panels for Detailed Info -->
|
|
<MudExpansionPanels Elevation="0" MultiExpansion="true" Gutters="false">
|
|
<!-- Battery State Panel -->
|
|
<MudExpansionPanel Icon="@Icons.Material.Filled.BatteryChargingFull"
|
|
Expanded="true">
|
|
<TitleContent>
|
|
<MudText>Battery State</MudText>
|
|
</TitleContent>
|
|
<ChildContent>
|
|
<BatteryCard @ref="BatteryCardRef" ShowNameCard="false"/>
|
|
</ChildContent>
|
|
</MudExpansionPanel>
|
|
|
|
<!-- Errors Panel -->
|
|
<MudExpansionPanel Icon="@Icons.Material.Filled.Error"
|
|
Expanded="false">
|
|
<TitleContent>
|
|
<div class="d-flex">
|
|
<MudText>Errors</MudText>
|
|
<MudBadge Content="Errors.Length" Color="Color.Info" Overlap="true" Class="d-flex ml-auto">
|
|
<MudIcon Icon="@Icons.Material.Filled.Info" Color="Color.Secondary" />
|
|
</MudBadge>
|
|
</div>
|
|
</TitleContent>
|
|
<ChildContent>
|
|
<MudPaper Class="pa-4" Elevation="2">
|
|
@foreach (var error in Errors)
|
|
{
|
|
<MudTooltip Text="@error.ErrorDescription" Placement="Placement.Top" Color="Color.Info">
|
|
<MudButton Class="m-2" Color="@(error.ErrorLevel == ErrorLevel.FATAL ? Color.Error : Color.Warning)" Variant="Variant.Filled" Size="Size.Small" Style="text-transform:none">@error.ErrorType</MudButton>
|
|
</MudTooltip>
|
|
}
|
|
</MudPaper>
|
|
</ChildContent>
|
|
</MudExpansionPanel>
|
|
|
|
<!-- Information Panel -->
|
|
<MudExpansionPanel Icon="@Icons.Material.Filled.Info"
|
|
Expanded="false">
|
|
<TitleContent>
|
|
<div class="d-flex">
|
|
<MudText>Notification</MudText>
|
|
<MudBadge Content="Information.Length" Color="Color.Info" Overlap="true" Class="d-flex ml-auto">
|
|
<MudIcon Icon="@Icons.Material.Filled.Notifications" Color="Color.Warning" />
|
|
</MudBadge>
|
|
</div>
|
|
</TitleContent>
|
|
<ChildContent>
|
|
<MudPaper Class="pa-4" Elevation="2">
|
|
<div class="d-flex flex-column">
|
|
@foreach (var info in Information)
|
|
{
|
|
<MudTooltip Text="@info.InfoDescription" Placement="Placement.Top" Color="Color.Info">
|
|
<MudButton Class="m-2" Color="@(info.InfoLevel == InfoLevel.INFO ? Color.Info : Color.Default)" Variant="Variant.Filled" Size="Size.Small" Style="text-transform:none">@info.InfoType</MudButton>
|
|
</MudTooltip>
|
|
}
|
|
</div>
|
|
</MudPaper>
|
|
</ChildContent>
|
|
</MudExpansionPanel>
|
|
</MudExpansionPanels>
|
|
</MudStack>
|
|
|
|
@code {
|
|
[Parameter]
|
|
public RobotMonitorData RobotData { get; set; } = null!;
|
|
|
|
[Parameter]
|
|
public RobotMonitorState State { get; set; } = null!;
|
|
|
|
private BatteryCard BatteryCardRef = default!;
|
|
|
|
private Error[] Errors = [];
|
|
private Information[] Information = [];
|
|
|
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
|
{
|
|
await base.OnAfterRenderAsync(firstRender);
|
|
if (!firstRender) return;
|
|
State.OnDataChanged += OnDataChanged;
|
|
}
|
|
|
|
private void OnDataChanged()
|
|
{
|
|
if (State.SelectedRobotId != null && State.Robots.TryGetValue(State.SelectedRobotId, out var robot))
|
|
{
|
|
BatteryCardRef.Update(robot.Data?.Battery);
|
|
Errors = robot.Data?.Errors ?? [];
|
|
Information = robot.Data?.Infomations ?? [];
|
|
RobotData = robot;
|
|
StateHasChanged();
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
State.OnDataChanged -= OnDataChanged;
|
|
}
|
|
|
|
private string GetRobotName()
|
|
{
|
|
// Try to get robot name from AvailableRobots
|
|
var robot = State.AvailableRobots.FirstOrDefault(r => r.RobotId == RobotData.RobotId);
|
|
return robot?.Name ?? RobotData.RobotId;
|
|
}
|
|
}
|