update
This commit is contained in:
parent
643a34a4b4
commit
aa2146e383
|
|
@ -71,6 +71,7 @@
|
|||
public NavModel[] Navs = [
|
||||
new(){Icon = "mdi-view-dashboard", Path="/", Label = "Dashboard", Match = NavLinkMatch.All},
|
||||
new(){Icon = "mdi-map-legend", Path="/maps-manager", Label = "Mapping", Match = NavLinkMatch.All},
|
||||
new(){Icon = "mdi-application-cog", Path="/robot-config", Label = "Config", Match = NavLinkMatch.All},
|
||||
];
|
||||
|
||||
private bool collapseNavMenu = true;
|
||||
|
|
|
|||
63
RobotApp.Client/Pages/Components/Config/RobotConfig.razor
Normal file
63
RobotApp.Client/Pages/Components/Config/RobotConfig.razor
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
<EditForm Model="@Config" OnValidSubmit="OnSubmit">
|
||||
<DataAnnotationsValidator />
|
||||
<ValidationSummary />
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Navigation Type</label>
|
||||
<InputSelect class="form-select" @bind-Value="Config.NavigationType" TValue="NavigationType">
|
||||
@foreach (var t in NavigationTypes)
|
||||
{
|
||||
<option value="@t">@t</option>
|
||||
}
|
||||
</InputSelect>
|
||||
</div>
|
||||
|
||||
<div class="row g-2 mb-2">
|
||||
<div class="col">
|
||||
<label class="form-label">Radius (wheel)</label>
|
||||
<InputNumber class="form-control" @bind-Value="Config.RadiusWheel" />
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="form-label">Width (m)</label>
|
||||
<InputNumber class="form-control" @bind-Value="Config.Width" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-2 mb-2">
|
||||
<div class="col">
|
||||
<label class="form-label">Length (m)</label>
|
||||
<InputNumber class="form-control" @bind-Value="Config.Length" />
|
||||
</div>
|
||||
<div class="col">
|
||||
<label class="form-label">Height (m)</label>
|
||||
<InputNumber class="form-control" @bind-Value="Config.Height" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Description</label>
|
||||
<InputTextArea class="form-control" @bind-Value="Config.Description" />
|
||||
</div>
|
||||
|
||||
</EditForm>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public RobotConfigDto Model { get; set; } = new();
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<RobotConfigDto> ModelChanged { get; set; }
|
||||
|
||||
private RobotConfigDto Config = new();
|
||||
private IEnumerable<NavigationType> NavigationTypes => Enum.GetValues(typeof(NavigationType)).Cast<NavigationType>();
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
Config = Model ?? new();
|
||||
}
|
||||
|
||||
private async Task OnSubmit()
|
||||
{
|
||||
Model = Config;
|
||||
await ModelChanged.InvokeAsync(Model);
|
||||
}
|
||||
}
|
||||
50
RobotApp.Client/Pages/Components/Config/RobotPLCConfig.razor
Normal file
50
RobotApp.Client/Pages/Components/Config/RobotPLCConfig.razor
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
@using RobotApp.Common.Shares.Dtos
|
||||
|
||||
<EditForm Model="@Local" OnValidSubmit="OnSubmit">
|
||||
<DataAnnotationsValidator />
|
||||
<ValidationSummary />
|
||||
<div class="row g-2 mb-2">
|
||||
<div class="col-md-8">
|
||||
<label class="form-label">PLC Address</label>
|
||||
<InputText class="form-control" @bind-Value="Local.PLCAddress" />
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Port</label>
|
||||
<InputNumber class="form-control" @bind-Value="Local.PLCPort" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-2 mb-2">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Unit Id</label>
|
||||
<InputNumber class="form-control" @bind-Value="Local.PLCUnitId" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Description</label>
|
||||
<InputTextArea class="form-control" @bind-Value="Local.Description" />
|
||||
</div>
|
||||
|
||||
</EditForm>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public RobotPlcConfigDto Model { get; set; } = new();
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<RobotPlcConfigDto> ModelChanged { get; set; }
|
||||
|
||||
private RobotPlcConfigDto Local = new();
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
Local = Model is not null ? Model with { } : new RobotPlcConfigDto();
|
||||
}
|
||||
|
||||
private async Task OnSubmit()
|
||||
{
|
||||
Model = Local;
|
||||
await ModelChanged.InvokeAsync(Model);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<EditForm Model="@Local" OnValidSubmit="OnSubmit">
|
||||
<DataAnnotationsValidator />
|
||||
<ValidationSummary />
|
||||
<div class="row g-2 mb-2">
|
||||
<div class="col-6">
|
||||
<label class="form-label">Very Slow (m/s)</label>
|
||||
<InputNumber class="form-control" @bind-Value="Local.SafetySpeedVerySlow" />
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label">Slow (m/s)</label>
|
||||
<InputNumber class="form-control" @bind-Value="Local.SafetySpeedSlow" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-2 mb-2">
|
||||
<div class="col-6">
|
||||
<label class="form-label">Normal (m/s)</label>
|
||||
<InputNumber class="form-control" @bind-Value="Local.SafetySpeedNormal" />
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label">Medium (m/s)</label>
|
||||
<InputNumber class="form-control" @bind-Value="Local.SafetySpeedMedium" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-2 mb-2">
|
||||
<div class="col-6">
|
||||
<label class="form-label">Optimal (m/s)</label>
|
||||
<InputNumber class="form-control" @bind-Value="Local.SafetySpeedOptimal" />
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label">Fast (m/s)</label>
|
||||
<InputNumber class="form-control" @bind-Value="Local.SafetySpeedFast" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Very Fast (m/s)</label>
|
||||
<InputNumber class="form-control" @bind-Value="Local.SafetySpeedVeryFast" />
|
||||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Description</label>
|
||||
<InputTextArea class="form-control" @bind-Value="Local.Description" />
|
||||
</div>
|
||||
|
||||
</EditForm>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public RobotSafetyConfigDto Model { get; set; } = new();
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<RobotSafetyConfigDto> ModelChanged { get; set; }
|
||||
|
||||
private RobotSafetyConfigDto Local = new();
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
// Work on a shallow copy (record) so parent instance isn't mutated until submit
|
||||
Local = Model is not null ? Model with { } : new RobotSafetyConfigDto();
|
||||
}
|
||||
|
||||
private async Task OnSubmit()
|
||||
{
|
||||
Model = Local;
|
||||
await ModelChanged.InvokeAsync(Model);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
@using RobotApp.Common.Shares.Dtos
|
||||
|
||||
<EditForm Model="@Local" OnValidSubmit="OnSubmit">
|
||||
<DataAnnotationsValidator />
|
||||
<ValidationSummary />
|
||||
<div class="form-check mb-2">
|
||||
<InputCheckbox class="form-check-input" @bind-Value="Local.EnableSimulation" />
|
||||
<label class="form-check-label">Enable Simulation</label>
|
||||
</div>
|
||||
|
||||
<div class="row g-2 mb-2">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Max Velocity (m/s)</label>
|
||||
<InputNumber class="form-control" @bind-Value="Local.SimulationMaxVelocity" />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Max Angular Velocity (rad/s)</label>
|
||||
<InputNumber class="form-control" @bind-Value="Local.SimulationMaxAngularVelocity" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-2 mb-2">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Acceleration (m/s²)</label>
|
||||
<InputNumber class="form-control" @bind-Value="Local.SimulationAcceleration" />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Deceleration (m/s²)</label>
|
||||
<InputNumber class="form-control" @bind-Value="Local.SimulationDeceleration" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Description</label>
|
||||
<InputTextArea class="form-control" @bind-Value="Local.Description" />
|
||||
</div>
|
||||
</EditForm>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public RobotSimulationConfigDto Model { get; set; } = new();
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<RobotSimulationConfigDto> ModelChanged { get; set; }
|
||||
|
||||
private RobotSimulationConfigDto Local = new();
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
// Use record 'with' to create a shallow copy so parent isn't mutated until submit
|
||||
Local = Model is not null ? Model with { } : new RobotSimulationConfigDto();
|
||||
}
|
||||
|
||||
private async Task OnSubmit()
|
||||
{
|
||||
Model = Local;
|
||||
await ModelChanged.InvokeAsync(Model);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
<EditForm Model="@Local" OnValidSubmit="OnSubmit">
|
||||
<DataAnnotationsValidator />
|
||||
<ValidationSummary />
|
||||
<div class="row g-2 mb-2">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Serial Number</label>
|
||||
<InputText class="form-control" @bind-Value="Local.SerialNumber" />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Manufacturer</label>
|
||||
<InputText class="form-control" @bind-Value="Local.VDA5050Manufacturer" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-2 mb-2">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Host</label>
|
||||
<InputText class="form-control" @bind-Value="Local.VDA5050HostServer" />
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Port</label>
|
||||
<InputNumber class="form-control" @bind-Value="Local.VDA5050Port" />
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Publish Repeat</label>
|
||||
<InputNumber class="form-control" @bind-Value="Local.VDA5050PublishRepeat" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-2 mb-2">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Username</label>
|
||||
<InputText class="form-control" @bind-Value="Local.VDA5050UserName" />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Password</label>
|
||||
<InputText class="form-control" @bind-Value="Local.VDA5050Password" type="password" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Version</label>
|
||||
<InputText class="form-control" @bind-Value="Local.VDA5050Version" />
|
||||
</div>
|
||||
|
||||
<div class="form-check mb-2">
|
||||
<InputCheckbox class="form-check-input" @bind-Value="Local.VDA5050EnablePassword" />
|
||||
<label class="form-check-label">Enable Password</label>
|
||||
</div>
|
||||
|
||||
<div class="form-check mb-2">
|
||||
<InputCheckbox class="form-check-input" @bind-Value="Local.VDA5050EnableTls" />
|
||||
<label class="form-check-label">Enable TLS</label>
|
||||
</div>
|
||||
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Description</label>
|
||||
<InputTextArea class="form-control" @bind-Value="Local.Description" />
|
||||
</div>
|
||||
</EditForm>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public RobotVDA5050ConfigDto Model { get; set; } = new();
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<RobotVDA5050ConfigDto> ModelChanged { get; set; }
|
||||
|
||||
private RobotVDA5050ConfigDto Local = new();
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
Local = Model is not null ? Model with { } : new RobotVDA5050ConfigDto();
|
||||
}
|
||||
|
||||
private async Task OnSubmit()
|
||||
{
|
||||
Model = Local;
|
||||
await ModelChanged.InvokeAsync(Model);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,60 @@
|
|||
<div class="view">
|
||||
<h4>Infomations</h4>
|
||||
<h4 class="info-title">Informations</h4>
|
||||
|
||||
<div class="info-grid">
|
||||
<div class="info-col">
|
||||
<dl class="info-list">
|
||||
<dt class="info-term">X (m)</dt>
|
||||
<dd class="info-desc">@Localization.X.ToString("F3")</dd>
|
||||
|
||||
<dt class="info-term">Y (m)</dt>
|
||||
<dd class="info-desc">@Localization.Y.ToString("F3")</dd>
|
||||
|
||||
<dt class="info-term">Theta (rad)</dt>
|
||||
<dd class="info-desc">@Localization.Theta.ToString("F4")</dd>
|
||||
|
||||
<dt class="info-term">Theta (deg)</dt>
|
||||
<dd class="info-desc">@($"{Localization.Theta * 180.0 / Math.PI:F2}°")</dd>
|
||||
|
||||
<dt class="info-term">Ready</dt>
|
||||
<dd class="info-desc">@((Localization.IsReady) ? "Yes" : "No")</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="info-col">
|
||||
<dl class="info-list">
|
||||
<dt class="info-term">SlamState</dt>
|
||||
<dd class="info-desc">@Localization.SlamState</dd>
|
||||
|
||||
<dt class="info-term">SlamDetail</dt>
|
||||
<dd class="info-desc text-truncate" title="@Localization.SlamStateDetail">@Localization.SlamStateDetail</dd>
|
||||
|
||||
<dt class="info-term">Active Map</dt>
|
||||
<dd class="info-desc text-truncate" title="@Localization.CurrentActiveMap">@Localization.CurrentActiveMap</dd>
|
||||
|
||||
<dt class="info-term">Reliability</dt>
|
||||
<dd class="info-desc">@($"{Localization.Reliability:F1}%")</dd>
|
||||
|
||||
<dt class="info-term">MatchingScore</dt>
|
||||
<dd class="info-desc">@($"{Localization.MatchingScore:F1}%")</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
private class LocalizationDto
|
||||
{
|
||||
public bool IsReady { get; set; }
|
||||
public double X { get; set; }
|
||||
public double Y { get; set; }
|
||||
public double Theta { get; set; }
|
||||
public string SlamState { get; set; } = "Localization";
|
||||
public string SlamStateDetail { get; set; } = "/r/n";
|
||||
public string CurrentActiveMap { get; set; } = "Localization";
|
||||
public double Reliability { get; set; }
|
||||
public double MatchingScore { get; set; }
|
||||
}
|
||||
|
||||
private LocalizationDto Localization = new();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,9 +5,117 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
background-color: var(--mud-palette-surface);
|
||||
border-radius: var(--mud-default-borderradius);
|
||||
background-color: var(--mud-palette-surface, #ffffff);
|
||||
border-radius: var(--mud-default-borderradius, 8px);
|
||||
transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
|
||||
box-shadow: var(--mud-elevation-10);
|
||||
padding: 15px;
|
||||
box-shadow: var(--mud-elevation-10, 0 4px 12px rgba(0,0,0,0.08));
|
||||
padding: 12px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid rgba(0,0,0,0.04);
|
||||
}
|
||||
|
||||
.view::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 6px;
|
||||
border-top-left-radius: inherit;
|
||||
border-bottom-left-radius: inherit;
|
||||
background: linear-gradient(180deg, var(--mud-palette-primary, #1976d2), rgba(25,118,210,0.7));
|
||||
}
|
||||
|
||||
.info-title {
|
||||
margin: 0 0 10px 12px;
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
color: var(--mud-palette-primary, #1976d2);
|
||||
}
|
||||
|
||||
.info-grid {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
align-items: flex-start;
|
||||
flex: 1 1 auto;
|
||||
overflow: hidden;
|
||||
padding: 1.5em;
|
||||
}
|
||||
|
||||
.info-col {
|
||||
flex: 1 1 50%;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.info-list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.info-list dt,
|
||||
.info-list dd {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 6px 0;
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.info-term {
|
||||
width: 42%;
|
||||
text-align: right;
|
||||
padding-right: 12px;
|
||||
color: var(--mud-palette-text-secondary, rgba(0,0,0,0.6));
|
||||
font-weight: 600;
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.info-desc {
|
||||
width: 58%;
|
||||
text-align: left;
|
||||
font-weight: 700;
|
||||
color: var(--mud-palette-text-primary, rgba(0,0,0,0.85));
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.text-truncate {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.info-list dt + dd {
|
||||
border-bottom: 1px dashed rgba(0,0,0,0.03);
|
||||
}
|
||||
|
||||
.ready-yes {
|
||||
color: var(--mud-palette-success, #2e7d32);
|
||||
}
|
||||
|
||||
.ready-no {
|
||||
color: var(--mud-palette-error, #d32f2f);
|
||||
}
|
||||
|
||||
.percent {
|
||||
color: var(--mud-palette-primary, #1976d2);
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.info-grid {
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.info-term {
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
.info-desc {
|
||||
width: 55%;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
208
RobotApp.Client/Pages/RobotConfigManager.razor
Normal file
208
RobotApp.Client/Pages/RobotConfigManager.razor
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
@page "/robot-config"
|
||||
@rendermode InteractiveWebAssemblyNoPrerender
|
||||
@attribute [Authorize]
|
||||
|
||||
@using RobotApp.Common.Shares.Dtos
|
||||
@using RobotApp.Common.Shares.Enums
|
||||
@inject HttpClient Http
|
||||
|
||||
<PageTitle>Robot Configuration</PageTitle>
|
||||
|
||||
<div class="d-flex w-100 h-100 p-2 overflow-hidden flex-column">
|
||||
<div class="rcm-toolbar">
|
||||
<div class="rcm-toolbar-left">
|
||||
<label class="rcm-label" for="configType">Config Type</label>
|
||||
<div class="rcm-select-wrapper">
|
||||
<select id="configType" class="form-select rcm-select" @bind="SelectedType">
|
||||
@foreach (var type in Enum.GetValues<RobotConfigType>())
|
||||
{
|
||||
<option value="@type">@type</option>
|
||||
}
|
||||
</select>
|
||||
<span class="rcm-select-icon" aria-hidden="true">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
|
||||
<path d="M7 10l5 5 5-5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rcm-toolbar-right">
|
||||
<div class="rcm-action-group">
|
||||
<button type="button" class="btn rcm-icon-btn" data-tooltip="Add config" aria-label="Add">
|
||||
<i class="mdi mdi-plus" aria-hidden="true"></i>
|
||||
</button>
|
||||
|
||||
<button type="button" class="btn rcm-icon-btn" data-tooltip="Update config" aria-label="Update">
|
||||
<i class="mdi mdi-content-save" aria-hidden="true"></i>
|
||||
</button>
|
||||
|
||||
<button type="button" class="btn rcm-icon-btn rcm-danger" data-tooltip="Delete config" aria-label="Delete">
|
||||
<i class="mdi mdi-delete" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content rcm-content flex-grow-1 d-flex gap-3 mt-3">
|
||||
<div class="card p-2 config-list rcm-config-list">
|
||||
<div class="card-body list-body p-0">
|
||||
@switch (SelectedType)
|
||||
{
|
||||
case RobotConfigType.VDA5050:
|
||||
@RenderList(VdaConfigs, () => SelectVda)
|
||||
break;
|
||||
case RobotConfigType.Safety:
|
||||
@RenderList(SafetyConfigs, () => SelectSafety)
|
||||
break;
|
||||
case RobotConfigType.Simulation:
|
||||
@RenderList(SimulationConfigs, () => SelectSimulation)
|
||||
break;
|
||||
case RobotConfigType.PLC:
|
||||
@RenderList(PlcConfigs, () => SelectPlc)
|
||||
break;
|
||||
case RobotConfigType.Core:
|
||||
@RenderList(CoreConfigs, () => SelectCore)
|
||||
break;
|
||||
default:
|
||||
<div class="p-2">No configs.</div>
|
||||
break;
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card p-2 config-content rcm-config-content">
|
||||
<div class="card-body">
|
||||
@if (!HasSelection)
|
||||
{
|
||||
<div class="text-muted">Select a config from the list or click Add to create one.</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
@switch (SelectedType)
|
||||
{
|
||||
case RobotConfigType.VDA5050:
|
||||
<RobotApp.Client.Pages.Components.Config.RobotVDA5050Config @bind-Model="SelectedVda" />
|
||||
break;
|
||||
case RobotConfigType.Safety:
|
||||
<RobotApp.Client.Pages.Components.Config.RobotSafetyConfig @bind-Model="SelectedSafety" />
|
||||
break;
|
||||
case RobotConfigType.Simulation:
|
||||
<RobotApp.Client.Pages.Components.Config.RobotSimulationConfig @bind-Model="SelectedSimulation" />
|
||||
break;
|
||||
case RobotConfigType.PLC:
|
||||
<RobotApp.Client.Pages.Components.Config.RobotPLCConfig @bind-Model="SelectedPlc" />
|
||||
break;
|
||||
case RobotConfigType.Core:
|
||||
<RobotApp.Client.Pages.Components.Config.RobotConfig @bind-Model="SelectedCore" />
|
||||
break;
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private List<RobotVDA5050ConfigDto> VdaConfigs { get; } = [];
|
||||
private List<RobotSafetyConfigDto> SafetyConfigs { get; } = [];
|
||||
private List<RobotSimulationConfigDto> SimulationConfigs { get; } = [];
|
||||
private List<RobotPlcConfigDto> PlcConfigs { get; } = [];
|
||||
private List<RobotConfigDto> CoreConfigs { get; } = [];
|
||||
|
||||
private RobotVDA5050ConfigDto? SelectedVda { get; set; }
|
||||
private RobotSafetyConfigDto? SelectedSafety { get; set; }
|
||||
private RobotSimulationConfigDto? SelectedSimulation { get; set; }
|
||||
private RobotPlcConfigDto? SelectedPlc { get; set; }
|
||||
private RobotConfigDto? SelectedCore { get; set; }
|
||||
|
||||
private RobotConfigType SelectedType { get; set; } = RobotConfigType.VDA5050;
|
||||
|
||||
private int SelectedIndex { get; set; } = -1;
|
||||
|
||||
private bool HasSelection => SelectedIndex >= 0;
|
||||
|
||||
RenderFragment RenderList<T>(List<T> list, Func<Action<int>> selectFactory) where T : class
|
||||
{
|
||||
return builder =>
|
||||
{
|
||||
if (list is null || !list.Any())
|
||||
{
|
||||
builder.OpenElement(0, "div");
|
||||
builder.AddAttribute(1, "class", "p-2 text-muted");
|
||||
builder.AddContent(2, "No configs found.");
|
||||
builder.CloseElement();
|
||||
return;
|
||||
}
|
||||
|
||||
builder.OpenElement(3, "ul");
|
||||
builder.AddAttribute(4, "class", "list-group list-group-flush");
|
||||
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
{
|
||||
var item = list[i];
|
||||
var idx = i;
|
||||
builder.OpenElement(10 + i * 5, "li");
|
||||
builder.AddAttribute(11 + i * 5, "class", $"list-group-item {(SelectedIndex==idx ? "active" : "")}");
|
||||
builder.AddAttribute(12 + i * 5, "style", "cursor:pointer;padding:0.75rem 1rem;");
|
||||
builder.AddAttribute(13 + i * 5, "onclick", EventCallback.Factory.Create(this, () => selectFactory()(idx)));
|
||||
|
||||
// Only show ConfigName
|
||||
var nameProp = item.GetType().GetProperty("ConfigName");
|
||||
var name = nameProp?.GetValue(item)?.ToString() ?? "Unnamed";
|
||||
builder.AddContent(14 + i * 5, name);
|
||||
|
||||
// Show active badge at end if IsActive == true
|
||||
var isActiveProp = item.GetType().GetProperty("IsActive");
|
||||
var isActive = isActiveProp?.GetValue(item) is bool b && b;
|
||||
if (isActive)
|
||||
{
|
||||
builder.OpenElement(15 + i * 5, "span");
|
||||
builder.AddAttribute(16 + i * 5, "class", "badge bg-success ms-2 float-end");
|
||||
builder.AddContent(17 + i * 5, "Active");
|
||||
builder.CloseElement();
|
||||
}
|
||||
|
||||
builder.CloseElement();
|
||||
}
|
||||
|
||||
builder.CloseElement();
|
||||
};
|
||||
}
|
||||
|
||||
private Action<int> SelectVda => idx =>
|
||||
{
|
||||
SelectedIndex = idx;
|
||||
SelectedVda = idx >= 0 && idx < VdaConfigs.Count ? VdaConfigs[idx] with { } : null;
|
||||
StateHasChanged();
|
||||
};
|
||||
|
||||
private Action<int> SelectSafety => idx =>
|
||||
{
|
||||
SelectedIndex = idx;
|
||||
SelectedSafety = idx >= 0 && idx < SafetyConfigs.Count ? SafetyConfigs[idx] with { } : null;
|
||||
StateHasChanged();
|
||||
};
|
||||
|
||||
private Action<int> SelectSimulation => idx =>
|
||||
{
|
||||
SelectedIndex = idx;
|
||||
SelectedSimulation = idx >= 0 && idx < SimulationConfigs.Count ? SimulationConfigs[idx] with { } : null;
|
||||
StateHasChanged();
|
||||
};
|
||||
|
||||
private Action<int> SelectPlc => idx =>
|
||||
{
|
||||
SelectedIndex = idx;
|
||||
SelectedPlc = idx >= 0 && idx < PlcConfigs.Count ? PlcConfigs[idx] with { } : null;
|
||||
StateHasChanged();
|
||||
};
|
||||
|
||||
private Action<int> SelectCore => idx =>
|
||||
{
|
||||
SelectedIndex = idx;
|
||||
SelectedCore = idx >= 0 && idx < CoreConfigs.Count ? CoreConfigs[idx] with { } : null;
|
||||
StateHasChanged();
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
375
RobotApp.Client/Pages/RobotConfigManager.razor.css
Normal file
375
RobotApp.Client/Pages/RobotConfigManager.razor.css
Normal file
|
|
@ -0,0 +1,375 @@
|
|||
/* Toolbar layout */
|
||||
.rcm-toolbar {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: linear-gradient(180deg, rgba(30,30,30,0.95), rgba(20,20,20,0.95));
|
||||
color: #e6e6e6;
|
||||
padding: 0.75rem 1rem;
|
||||
border-radius: 0.375rem;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.6);
|
||||
border: 1px solid rgba(255,255,255,0.04);
|
||||
}
|
||||
|
||||
/* Content layout: take remaining height */
|
||||
.rcm-content {
|
||||
height: calc(100vh - 90px); /* approximate toolbar + padding height; adjust if needed */
|
||||
min-height: 0; /* allow flex children to shrink properly */
|
||||
}
|
||||
|
||||
/* Config list uses flexible basis and can shrink instead of forcing overflow */
|
||||
.rcm-config-list {
|
||||
/* replace fixed width with flex basis + shrink */
|
||||
flex: 0 1 35%; /* flex-grow:0, flex-shrink:1, flex-basis:35% */
|
||||
min-width: 240px; /* allow smaller than before but keep readable */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* Config content uses remaining space and can shrink/grow */
|
||||
.rcm-config-content {
|
||||
flex: 1 1 65%; /* flex-grow:1 to take remaining, flex-shrink:1 */
|
||||
min-width: 220px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Make card body scrollable if content overflows */
|
||||
.config-list .list-body,
|
||||
.rcm-config-content .card-body,
|
||||
.config-list .list-body ul {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* Ensure list-body and editor body expand to fill container */
|
||||
.config-list .list-body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.rcm-config-content .card-body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* Make config list body fill available height and scroll when content overflows */
|
||||
.rcm-config-list .card-body.list-body {
|
||||
flex: 1 1 auto; /* expand to fill container */
|
||||
min-height: 0; /* allow flex children to shrink in many browsers */
|
||||
overflow: auto; /* enable scrolling when content overflows */
|
||||
padding: 0.25rem 0.5rem; /* keep slight padding for list */
|
||||
}
|
||||
|
||||
/* Ensure the list itself doesn't add extra margins that affect scrolling */
|
||||
.rcm-config-list .list-group {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* Each list item keeps its padding but stays in flow */
|
||||
.rcm-config-list .list-group-item {
|
||||
padding: 0.75rem 1rem;
|
||||
}
|
||||
|
||||
/* List items spacing */
|
||||
.list-group-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Left side controls (robot id + select) */
|
||||
.rcm-toolbar-left {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* Right side action buttons */
|
||||
.rcm-toolbar-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* Group buttons with small spacing */
|
||||
.rcm-action-group {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
/* Inputs sizing */
|
||||
.rcm-input {
|
||||
width: 160px;
|
||||
background: #1a1a1a;
|
||||
border: 1px solid rgba(255,255,255,0.06);
|
||||
color: #e6e6e6;
|
||||
}
|
||||
|
||||
.rcm-select-wrapper {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* Make select background brighter and match button gradients (blue tone similar to Update) */
|
||||
.rcm-select {
|
||||
width: 180px;
|
||||
margin-left: 6px; /* bring select closer to left controls */
|
||||
background: linear-gradient(180deg, #4aa0db, #2b87c9);
|
||||
border: 1px solid rgba(0,0,0,0.12);
|
||||
color: #fff;
|
||||
appearance: none;
|
||||
padding-right: 28px; /* space for icon */
|
||||
box-shadow: 0 1px 0 rgba(255,255,255,0.04) inset;
|
||||
}
|
||||
|
||||
/* Hover effect: slightly brighter */
|
||||
.rcm-select-wrapper:hover .rcm-select {
|
||||
background: linear-gradient(180deg, #5bb6ee, #399ad6);
|
||||
border-color: rgba(58,123,184,0.22);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
/* Select icon color to contrast with brighter select */
|
||||
.rcm-select-icon {
|
||||
position: absolute;
|
||||
right: 6px;
|
||||
pointer-events: none;
|
||||
color: rgba(255,255,255,0.9);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* Toolbar labels */
|
||||
.rcm-label {
|
||||
font-size: 0.9rem;
|
||||
margin-right: 6px;
|
||||
color: #cfcfcf;
|
||||
}
|
||||
|
||||
/* Minor button styling to match toolbar */
|
||||
.rcm-btn {
|
||||
min-width: 84px;
|
||||
}
|
||||
|
||||
/* Icon button styles */
|
||||
.rcm-icon-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 38px;
|
||||
height: 34px;
|
||||
padding: 0.25rem;
|
||||
border-radius: 6px;
|
||||
background: transparent;
|
||||
color: #e6e6e6;
|
||||
border: 1px solid rgba(255,255,255,0.04);
|
||||
}
|
||||
|
||||
.rcm-icon-btn svg {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Icon button hover and focus states */
|
||||
.rcm-icon-btn:hover, .rcm-icon-btn:focus {
|
||||
background: rgba(255,255,255,0.03);
|
||||
color: #fff;
|
||||
border-color: rgba(255,255,255,0.08);
|
||||
}
|
||||
|
||||
.rcm-danger {
|
||||
color: #ffb3b3;
|
||||
border-color: rgba(255,100,100,0.18);
|
||||
}
|
||||
|
||||
/* Adjust bootstrap button colors for dark toolbar when using outline variants */
|
||||
.rcm-toolbar .btn-outline-primary {
|
||||
color: #cfe2ff;
|
||||
border-color: rgba(95,160,255,0.2);
|
||||
}
|
||||
|
||||
.rcm-toolbar .btn-outline-success {
|
||||
color: #d4f5d4;
|
||||
border-color: rgba(60,200,120,0.18);
|
||||
}
|
||||
|
||||
.rcm-toolbar .btn-outline-danger {
|
||||
color: #ffcfcf;
|
||||
border-color: rgba(255,100,100,0.18);
|
||||
}
|
||||
|
||||
/* Specific styles for action buttons (Add, Update, Delete) */
|
||||
.rcm-action-group button[aria-label="Add"] {
|
||||
background: linear-gradient(180deg, #4bb24b, #2f9a2f); /* bright green */
|
||||
color: #fff;
|
||||
border: 1px solid rgba(0,0,0,0.08);
|
||||
box-shadow: 0 1px 0 rgba(255,255,255,0.06) inset;
|
||||
}
|
||||
|
||||
.rcm-action-group button[aria-label="Add"]:hover {
|
||||
background: linear-gradient(180deg, #66d166, #3fb83f);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.rcm-action-group button[aria-label="Add"]:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px rgba(56,160,56,0.18);
|
||||
}
|
||||
|
||||
.rcm-action-group button[aria-label="Update"] {
|
||||
background: linear-gradient(180deg, #4aa0db, #2b87c9); /* bright blue */
|
||||
color: #fff;
|
||||
border: 1px solid rgba(0,0,0,0.08);
|
||||
box-shadow: 0 1px 0 rgba(255,255,255,0.08) inset;
|
||||
}
|
||||
|
||||
.rcm-action-group button[aria-label="Update"]:hover {
|
||||
background: linear-gradient(180deg, #5bb6ee, #399ad6);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.rcm-action-group button[aria-label="Update"]:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px rgba(58,123,184,0.18);
|
||||
}
|
||||
|
||||
.rcm-action-group button[aria-label="Delete"] {
|
||||
background: linear-gradient(180deg, #ff6b6b, #e04848); /* bright red */
|
||||
color: #fff;
|
||||
border: 1px solid rgba(0,0,0,0.08);
|
||||
box-shadow: 0 1px 0 rgba(255,255,255,0.06) inset;
|
||||
}
|
||||
|
||||
.rcm-action-group button[aria-label="Delete"]:hover {
|
||||
background: linear-gradient(180deg, #ff8282, #ec5b5b);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.rcm-action-group button[aria-label="Delete"]:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px rgba(224,72,72,0.18);
|
||||
}
|
||||
|
||||
/* Ensure icons inside the action buttons remain visible */
|
||||
.rcm-action-group button[aria-label="Add"] .mdi,
|
||||
.rcm-action-group button[aria-label="Update"] .mdi,
|
||||
.rcm-action-group button[aria-label="Delete"] .mdi {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Ensure dropdown options use dark theme matching select */
|
||||
.rcm-select option {
|
||||
background-color: #141414 !important;
|
||||
color: #e6e6e6 !important;
|
||||
}
|
||||
|
||||
/* Hover/active state inside dropdown */
|
||||
.rcm-select option:hover,
|
||||
.rcm-select option:checked {
|
||||
background-color: #2b87c9 !important; /* match update button blue */
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
/* Optgroup styling (if used) */
|
||||
.rcm-select optgroup {
|
||||
color: #e6e6e6;
|
||||
background: #141414;
|
||||
}
|
||||
|
||||
/* Tooltip for action buttons using data-tooltip attribute */
|
||||
.rcm-action-group button[data-tooltip] {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.rcm-action-group button[data-tooltip]::after {
|
||||
content: attr(data-tooltip);
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(8px);
|
||||
bottom: -9999px; /* hidden by default below flow */
|
||||
background: rgba(20,20,20,0.98);
|
||||
color: #fff;
|
||||
padding: 6px 10px;
|
||||
border-radius: 6px;
|
||||
font-size: 0.85rem;
|
||||
white-space: nowrap;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.5);
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: opacity 0.12s ease, transform 0.12s ease;
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
/* Arrow below tooltip */
|
||||
.rcm-action-group button[data-tooltip]::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
bottom: -9999px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background: rgba(20,20,20,0.98);
|
||||
transform-origin: center;
|
||||
rotate: 45deg;
|
||||
z-index: 49;
|
||||
}
|
||||
|
||||
/* Show tooltip on hover */
|
||||
.rcm-action-group button[data-tooltip]:hover::after,
|
||||
.rcm-action-group button[data-tooltip]:hover::before {
|
||||
bottom: -45px; /* reduced gap: place tooltip closer to the button */
|
||||
opacity: 1;
|
||||
transform: translateX(-50%) translateY(0);
|
||||
}
|
||||
|
||||
/* Adjust for danger button (slightly different color) */
|
||||
.rcm-action-group button[data-tooltip].rcm-danger::after {
|
||||
background: rgba(224,72,72,0.95);
|
||||
}
|
||||
|
||||
/* Slightly lift the button on hover to match tooltip */
|
||||
.rcm-action-group button[data-tooltip]:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/* Tooltip backgrounds matching their buttons */
|
||||
.rcm-action-group button[aria-label="Add"][data-tooltip]::after {
|
||||
background: linear-gradient(180deg, #4bb24b, #2f9a2f);
|
||||
}
|
||||
.rcm-action-group button[aria-label="Add"][data-tooltip]::before {
|
||||
background: #2f9a2f;
|
||||
}
|
||||
|
||||
.rcm-action-group button[aria-label="Update"][data-tooltip]::after {
|
||||
background: linear-gradient(180deg, #4aa0db, #2b87c9);
|
||||
}
|
||||
.rcm-action-group button[aria-label="Update"][data-tooltip]::before {
|
||||
background: #2b87c9;
|
||||
}
|
||||
|
||||
/* Delete already had a red variant, update the arrow to match precisely */
|
||||
.rcm-action-group button[aria-label="Delete"][data-tooltip]::after,
|
||||
.rcm-action-group button[data-tooltip].rcm-danger::after {
|
||||
background: linear-gradient(180deg, #ff6b6b, #e04848);
|
||||
}
|
||||
.rcm-action-group button[aria-label="Delete"][data-tooltip]::before,
|
||||
.rcm-action-group button[data-tooltip].rcm-danger::before {
|
||||
background: #e04848;
|
||||
}
|
||||
|
||||
/* Ensure tooltip text stays readable on gradients */
|
||||
.rcm-action-group button[data-tooltip]::after {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Active badge in config list: make slightly larger and more visible */
|
||||
.rcm-config-list .list-group-item .badge {
|
||||
font-size: 1.05rem; /* slightly larger */
|
||||
padding: 0.45rem 0.8rem;
|
||||
border-radius: 0.5rem;
|
||||
line-height: 1;
|
||||
margin-left: 0.6rem;
|
||||
opacity: 0.98;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
|
@ -11,3 +11,5 @@
|
|||
@using RobotApp.Client
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
@using MudBlazor
|
||||
@using RobotApp.Common.Shares.Dtos
|
||||
@using RobotApp.Common.Shares.Enums
|
||||
|
|
@ -14,7 +14,29 @@ public record RobotConfigDto
|
|||
public double Height { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
public bool IsActive { get; set; }
|
||||
public string ConfigName { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
||||
public record UpdateRobotConfigDto
|
||||
{
|
||||
public NavigationType NavigationType { get; set; }
|
||||
public double RadiusWheel { get; set; }
|
||||
public double Width { get; set; }
|
||||
public double Length { get; set; }
|
||||
public double Height { get; set; }
|
||||
public string ConfigName { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
||||
public record CreateRobotConfigDto
|
||||
{
|
||||
public NavigationType NavigationType { get; set; }
|
||||
public double RadiusWheel { get; set; }
|
||||
public double Width { get; set; }
|
||||
public double Length { get; set; }
|
||||
public double Height { get; set; }
|
||||
public string ConfigName { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,28 @@ public record RobotPlcConfigDto
|
|||
public Guid Id { get; set; }
|
||||
public string PLCAddress { get; set; }
|
||||
public int PLCPort { get; set; }
|
||||
public byte PLCUnitId { get; set; }
|
||||
public int PLCUnitId { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
public bool IsActive { get; set; }
|
||||
public string ConfigName { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
||||
public record UpdateRobotPlcConfigDto
|
||||
{
|
||||
public string ConfigName { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string PLCAddress { get; set; }
|
||||
public int PLCPort { get; set; }
|
||||
public int PLCUnitId { get; set; }
|
||||
}
|
||||
|
||||
public record CreateRobotPlcConfigDto
|
||||
{
|
||||
public string ConfigName { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string PLCAddress { get; set; }
|
||||
public int PLCPort { get; set; }
|
||||
public int PLCUnitId { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
namespace RobotApp.Common.Shares.Dtos;
|
||||
|
||||
#nullable disable
|
||||
|
||||
public record RobotSafetyConfig
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public double SafetySpeedVerySlow { get; set; }
|
||||
public double SafetySpeedSlow { get; set; }
|
||||
public double SafetySpeedNormal { get; set; }
|
||||
public double SafetySpeedMedium { get; set; }
|
||||
public double SafetySpeedOptimal { get; set; }
|
||||
public double SafetySpeedFast { get; set; }
|
||||
public double SafetySpeedVeryFast { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
public string ConfigName { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
46
RobotApp.Common.Shares/Dtos/RobotSafetyConfigDto.cs
Normal file
46
RobotApp.Common.Shares/Dtos/RobotSafetyConfigDto.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
namespace RobotApp.Common.Shares.Dtos;
|
||||
|
||||
#nullable disable
|
||||
|
||||
public record RobotSafetyConfigDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public double SafetySpeedVerySlow { get; set; }
|
||||
public double SafetySpeedSlow { get; set; }
|
||||
public double SafetySpeedNormal { get; set; }
|
||||
public double SafetySpeedMedium { get; set; }
|
||||
public double SafetySpeedOptimal { get; set; }
|
||||
public double SafetySpeedFast { get; set; }
|
||||
public double SafetySpeedVeryFast { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public string ConfigName { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
||||
public record UpdateRobotSafetyConfigDto
|
||||
{
|
||||
public double SafetySpeedVerySlow { get; set; }
|
||||
public double SafetySpeedSlow { get; set; }
|
||||
public double SafetySpeedNormal { get; set; }
|
||||
public double SafetySpeedMedium { get; set; }
|
||||
public double SafetySpeedOptimal { get; set; }
|
||||
public double SafetySpeedFast { get; set; }
|
||||
public double SafetySpeedVeryFast { get; set; }
|
||||
public string ConfigName { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
||||
public record CreateRobotSafetyConfigDto
|
||||
{
|
||||
public double SafetySpeedVerySlow { get; set; }
|
||||
public double SafetySpeedSlow { get; set; }
|
||||
public double SafetySpeedNormal { get; set; }
|
||||
public double SafetySpeedMedium { get; set; }
|
||||
public double SafetySpeedOptimal { get; set; }
|
||||
public double SafetySpeedFast { get; set; }
|
||||
public double SafetySpeedVeryFast { get; set; }
|
||||
public string ConfigName { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
|
@ -12,7 +12,29 @@ public record RobotSimulationConfigDto
|
|||
public double SimulationDeceleration { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
public bool IsActive { get; set; }
|
||||
public string ConfigName { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
||||
public record UpdateRobotSimulationConfigDto
|
||||
{
|
||||
public bool EnableSimulation { get; set; }
|
||||
public double SimulationMaxVelocity { get; set; }
|
||||
public double SimulationMaxAngularVelocity { get; set; }
|
||||
public double SimulationAcceleration { get; set; }
|
||||
public double SimulationDeceleration { get; set; }
|
||||
public string ConfigName { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
||||
public record CreateRobotSimulationConfigDto
|
||||
{
|
||||
public bool EnableSimulation { get; set; }
|
||||
public double SimulationMaxVelocity { get; set; }
|
||||
public double SimulationMaxAngularVelocity { get; set; }
|
||||
public double SimulationAcceleration { get; set; }
|
||||
public double SimulationDeceleration { get; set; }
|
||||
public string ConfigName { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ public record RobotVDA5050ConfigDto
|
|||
public Guid Id { get; set; }
|
||||
public string SerialNumber { get; set; }
|
||||
public string VDA5050HostServer { get; set; }
|
||||
public int VDA5050Port { get; set; } = 1883;
|
||||
public int VDA5050Port { get; set; }
|
||||
public string VDA5050UserName { get; set; }
|
||||
public string VDA5050Password { get; set; }
|
||||
public string VDA5050Manufacturer { get; set; }
|
||||
|
|
@ -17,7 +17,39 @@ public record RobotVDA5050ConfigDto
|
|||
public bool VDA5050EnableTls { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
public bool IsActive { get; set; } = true;
|
||||
public bool IsActive { get; set; }
|
||||
public string ConfigName { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
||||
public record UpdateRobotVDA5050ConfigDto
|
||||
{
|
||||
public string SerialNumber { get; set; }
|
||||
public string VDA5050HostServer { get; set; }
|
||||
public int VDA5050Port { get; set; }
|
||||
public string VDA5050UserName { get; set; }
|
||||
public string VDA5050Password { get; set; }
|
||||
public string VDA5050Manufacturer { get; set; }
|
||||
public string VDA5050Version { get; set; }
|
||||
public int VDA5050PublishRepeat { get; set; }
|
||||
public bool VDA5050EnablePassword { get; set; }
|
||||
public bool VDA5050EnableTls { get; set; }
|
||||
public string ConfigName { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
||||
public record CreateRobotVDA5050ConfigDto
|
||||
{
|
||||
public string SerialNumber { get; set; }
|
||||
public string VDA5050HostServer { get; set; }
|
||||
public int VDA5050Port { get; set; }
|
||||
public string VDA5050UserName { get; set; }
|
||||
public string VDA5050Password { get; set; }
|
||||
public string VDA5050Manufacturer { get; set; }
|
||||
public string VDA5050Version { get; set; }
|
||||
public int VDA5050PublishRepeat { get; set; }
|
||||
public bool VDA5050EnablePassword { get; set; }
|
||||
public bool VDA5050EnableTls { get; set; }
|
||||
public string ConfigName { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
|
|
|||
10
RobotApp.Common.Shares/Enums/RobotConfigType.cs
Normal file
10
RobotApp.Common.Shares/Enums/RobotConfigType.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
namespace RobotApp.Common.Shares.Enums;
|
||||
|
||||
public enum RobotConfigType
|
||||
{
|
||||
VDA5050,
|
||||
Core,
|
||||
Safety ,
|
||||
Simulation,
|
||||
PLC,
|
||||
}
|
||||
|
|
@ -1,16 +1,956 @@
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotApp.Common.Shares;
|
||||
using RobotApp.Common.Shares.Dtos;
|
||||
using RobotApp.Data;
|
||||
using RobotApp.Services.Robot;
|
||||
|
||||
namespace RobotApp.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class RobotConfigsController(Services.Logger<ImagesController> Logger) : ControllerBase
|
||||
public class RobotConfigsController(Services.Logger<RobotConfigsController> Logger, ApplicationDbContext AppDb, RobotConfiguration RobotConfiguration) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
[Route("plc")]
|
||||
public void GetPLCConfig()
|
||||
public async Task<MessageResult<RobotPlcConfigDto[]>> GetAllPLCConfigs()
|
||||
{
|
||||
try
|
||||
{
|
||||
var configs = await AppDb.RobotPlcConfigs
|
||||
.OrderByDescending(c => c.UpdatedAt)
|
||||
.ToListAsync();
|
||||
if (configs is null || configs.Count == 0) return new(false, "PLC configuration not found.");
|
||||
return new(true)
|
||||
{
|
||||
Data = [.. configs.Select(config => new RobotPlcConfigDto
|
||||
{
|
||||
Id = config.Id,
|
||||
ConfigName = config.ConfigName,
|
||||
Description = config.Description,
|
||||
PLCAddress = config.PLCAddress,
|
||||
PLCPort = config.PLCPort,
|
||||
PLCUnitId = config.PLCUnitId,
|
||||
CreatedAt = config.CreatedAt,
|
||||
UpdatedAt = config.UpdatedAt,
|
||||
IsActive = config.IsActive,
|
||||
})]
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Get PLC Configs: {ex.Message}");
|
||||
return new(false, "An error occurred while retrieving the PLC configuration.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("plc/{id:guid}")]
|
||||
public async Task<MessageResult<RobotPlcConfigDto>> UpdatePLCConfig(Guid id, [FromBody] UpdateRobotPlcConfigDto updateDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
var config = await AppDb.RobotPlcConfigs.FindAsync(id);
|
||||
if (config is null) return new(false, "PLC configuration not found.");
|
||||
|
||||
if (string.IsNullOrEmpty(updateDto.ConfigName)) return new(false, "ConfigName cannot be null or empty.");
|
||||
if (await AppDb.RobotPlcConfigs.AnyAsync(cf => cf.Id != id && cf.ConfigName == updateDto.ConfigName))
|
||||
return new(false, "A PLC configuration with the same name already exists.");
|
||||
|
||||
config.ConfigName = updateDto.ConfigName ?? config.ConfigName;
|
||||
config.Description = updateDto.Description ?? config.Description;
|
||||
config.PLCAddress = updateDto.PLCAddress ?? config.PLCAddress;
|
||||
config.PLCPort = updateDto.PLCPort;
|
||||
config.PLCUnitId = (byte)updateDto.PLCUnitId;
|
||||
config.UpdatedAt = DateTime.Now;
|
||||
|
||||
await AppDb.SaveChangesAsync();
|
||||
|
||||
if (config.IsActive) await RobotConfiguration.LoadRobotPlcConfigAsync();
|
||||
return new(true, "PLC configuration updated successfully.")
|
||||
{
|
||||
Data = new RobotPlcConfigDto
|
||||
{
|
||||
Id = config.Id,
|
||||
ConfigName = config.ConfigName,
|
||||
Description = config.Description,
|
||||
PLCAddress = config.PLCAddress,
|
||||
PLCPort = config.PLCPort,
|
||||
PLCUnitId = config.PLCUnitId,
|
||||
CreatedAt = config.CreatedAt,
|
||||
UpdatedAt = config.UpdatedAt,
|
||||
IsActive = config.IsActive,
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Update PLC Config: {ex.Message}");
|
||||
return new(false, "An error occurred while updating the PLC configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("plc")]
|
||||
public async Task<MessageResult<RobotPlcConfigDto>> CreatePLCConfig([FromBody] CreateRobotPlcConfigDto createDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(createDto.ConfigName)) return new(false, "ConfigName cannot be null or empty.");
|
||||
if (await AppDb.RobotPlcConfigs.AnyAsync(cf => cf.ConfigName == createDto.ConfigName))
|
||||
return new(false, "A PLC configuration with the same name already exists.");
|
||||
|
||||
var config = new RobotPlcConfig
|
||||
{
|
||||
ConfigName = createDto.ConfigName,
|
||||
Description = createDto.Description,
|
||||
PLCAddress = createDto.PLCAddress,
|
||||
PLCPort = createDto.PLCPort,
|
||||
PLCUnitId = (byte)createDto.PLCUnitId,
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now,
|
||||
IsActive = false
|
||||
};
|
||||
|
||||
AppDb.RobotPlcConfigs.Add(config);
|
||||
await AppDb.SaveChangesAsync();
|
||||
|
||||
return new(true, "PLC configuration created successfully.")
|
||||
{
|
||||
Data = new RobotPlcConfigDto
|
||||
{
|
||||
Id = config.Id,
|
||||
ConfigName = config.ConfigName,
|
||||
Description = config.Description,
|
||||
PLCAddress = config.PLCAddress,
|
||||
PLCPort = config.PLCPort,
|
||||
PLCUnitId = config.PLCUnitId,
|
||||
CreatedAt = config.CreatedAt,
|
||||
UpdatedAt = config.UpdatedAt,
|
||||
IsActive = config.IsActive,
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Create PLC Config: {ex.Message}");
|
||||
return new(false, "An error occurred while creating the PLC configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Route("plc/{id:guid}")]
|
||||
public async Task<MessageResult> DeletePLCConfig(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var config = await AppDb.RobotPlcConfigs.FindAsync(id);
|
||||
if (config is null) return new(false, "PLC configuration not found.");
|
||||
if (config.IsActive) return new(false, "Cannot delete an active PLC configuration.");
|
||||
|
||||
AppDb.RobotPlcConfigs.Remove(config);
|
||||
await AppDb.SaveChangesAsync();
|
||||
return new(true, "Configuration deleted successfully.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Delete PLC Config: {ex.Message}");
|
||||
return new(false, "An error occurred while deleting the PLC configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("plc/active/{id:guid}")]
|
||||
public async Task<MessageResult> ActivePLCConfig(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var config = await AppDb.RobotPlcConfigs.FindAsync(id);
|
||||
if (config is null) return new(false, "PLC configuration not found.");
|
||||
|
||||
await AppDb.RobotPlcConfigs.ExecuteUpdateAsync(cf => cf.SetProperty(c => c.IsActive, false));
|
||||
config.IsActive = true;
|
||||
config.UpdatedAt = DateTime.Now;
|
||||
|
||||
await AppDb.SaveChangesAsync();
|
||||
|
||||
await RobotConfiguration.LoadRobotPlcConfigAsync();
|
||||
return new(true, $"PLC configuration {config.ConfigName} activated successfully.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Update Active PLC Config: {ex.Message}");
|
||||
return new(false, "An error occurred while updating the active PLC configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("vda5050")]
|
||||
public async Task<MessageResult<RobotVDA5050ConfigDto[]>> GetAllVDA5050Configs()
|
||||
{
|
||||
try
|
||||
{
|
||||
var configs = await AppDb.RobotVDA5050Configs
|
||||
.OrderByDescending(c => c.UpdatedAt)
|
||||
.ToListAsync();
|
||||
|
||||
if (configs is null || configs.Count == 0) return new(false, "VDA5050 configuration not found.");
|
||||
var configDtos = configs.Select(config => new RobotVDA5050ConfigDto
|
||||
{
|
||||
Id = config.Id,
|
||||
SerialNumber = config.SerialNumber,
|
||||
VDA5050HostServer = config.VDA5050HostServer,
|
||||
VDA5050Port = config.VDA5050Port,
|
||||
VDA5050UserName = config.VDA5050UserName,
|
||||
VDA5050Password = config.VDA5050Password,
|
||||
VDA5050Manufacturer = config.VDA5050Manufacturer,
|
||||
VDA5050Version = config.VDA5050Version,
|
||||
VDA5050PublishRepeat = config.VDA5050PublishRepeat,
|
||||
VDA5050EnablePassword = config.VDA5050EnablePassword,
|
||||
VDA5050EnableTls = config.VDA5050EnableTls,
|
||||
CreatedAt = config.CreatedAt,
|
||||
UpdatedAt = config.UpdatedAt,
|
||||
IsActive = config.IsActive,
|
||||
ConfigName = config.ConfigName,
|
||||
Description = config.Description
|
||||
}).ToArray();
|
||||
|
||||
return new(true) { Data = configDtos };
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Get All VDA5050 Configs: {ex.Message}");
|
||||
return new(false, "An error occurred while retrieving VDA5050 configurations.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("vda5050/{id:guid}")]
|
||||
public async Task<MessageResult<RobotVDA5050ConfigDto>> UpdateVDA5050Config(Guid id, [FromBody] UpdateRobotVDA5050ConfigDto updateDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
var config = await AppDb.RobotVDA5050Configs.FindAsync(id);
|
||||
if (config is null) return new(false, "VDA5050 configuration not found.");
|
||||
|
||||
if (string.IsNullOrEmpty(updateDto.ConfigName)) return new(false, "ConfigName cannot be null or empty.");
|
||||
if (await AppDb.RobotVDA5050Configs.AnyAsync(cf => cf.Id != id && cf.ConfigName == updateDto.ConfigName))
|
||||
return new(false, "A VDA5050 configuration with the same name already exists.");
|
||||
|
||||
config.SerialNumber = updateDto.SerialNumber ?? config.SerialNumber;
|
||||
config.VDA5050HostServer = updateDto.VDA5050HostServer ?? config.VDA5050HostServer;
|
||||
config.VDA5050Port = updateDto.VDA5050Port;
|
||||
config.VDA5050UserName = updateDto.VDA5050UserName ?? config.VDA5050UserName;
|
||||
config.VDA5050Password = updateDto.VDA5050Password ?? config.VDA5050Password;
|
||||
config.VDA5050Manufacturer = updateDto.VDA5050Manufacturer ?? config.VDA5050Manufacturer;
|
||||
config.VDA5050Version = updateDto.VDA5050Version ?? config.VDA5050Version;
|
||||
config.VDA5050PublishRepeat = updateDto.VDA5050PublishRepeat;
|
||||
config.VDA5050EnablePassword = updateDto.VDA5050EnablePassword;
|
||||
config.VDA5050EnableTls = updateDto.VDA5050EnableTls;
|
||||
config.ConfigName = updateDto.ConfigName ?? config.ConfigName;
|
||||
config.Description = updateDto.Description ?? config.Description;
|
||||
config.UpdatedAt = DateTime.Now;
|
||||
|
||||
await AppDb.SaveChangesAsync();
|
||||
|
||||
if (config.IsActive) await RobotConfiguration.LoadVDA5050ConfigAsync();
|
||||
return new(true, "VDA5050 configuration updated successfully.")
|
||||
{
|
||||
Data = new RobotVDA5050ConfigDto
|
||||
{
|
||||
Id = config.Id,
|
||||
SerialNumber = config.SerialNumber,
|
||||
VDA5050HostServer = config.VDA5050HostServer,
|
||||
VDA5050Port = config.VDA5050Port,
|
||||
VDA5050UserName = config.VDA5050UserName,
|
||||
VDA5050Password = config.VDA5050Password,
|
||||
VDA5050Manufacturer = config.VDA5050Manufacturer,
|
||||
VDA5050Version = config.VDA5050Version,
|
||||
VDA5050PublishRepeat = config.VDA5050PublishRepeat,
|
||||
VDA5050EnablePassword = config.VDA5050EnablePassword,
|
||||
VDA5050EnableTls = config.VDA5050EnableTls,
|
||||
CreatedAt = config.CreatedAt,
|
||||
UpdatedAt = config.UpdatedAt,
|
||||
IsActive = config.IsActive,
|
||||
ConfigName = config.ConfigName,
|
||||
Description = config.Description
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Update VDA5050 Config: {ex.Message}");
|
||||
return new(false, "An error occurred while updating the VDA5050 configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("vda5050")]
|
||||
public async Task<MessageResult<RobotVDA5050ConfigDto>> CreateVDA5050Config([FromBody] CreateRobotVDA5050ConfigDto createDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(createDto.ConfigName)) return new(false, "ConfigName cannot be null or empty.");
|
||||
if (await AppDb.RobotVDA5050Configs.AnyAsync(cf => cf.ConfigName == createDto.ConfigName))
|
||||
return new(false, "A VDA5050 configuration with the same name already exists.");
|
||||
|
||||
var config = new RobotVDA5050Config
|
||||
{
|
||||
ConfigName = createDto.ConfigName,
|
||||
Description = createDto.Description,
|
||||
SerialNumber = createDto.SerialNumber,
|
||||
VDA5050HostServer = createDto.VDA5050HostServer,
|
||||
VDA5050Port = createDto.VDA5050Port,
|
||||
VDA5050UserName = createDto.VDA5050UserName,
|
||||
VDA5050Password = createDto.VDA5050Password,
|
||||
VDA5050Manufacturer = createDto.VDA5050Manufacturer,
|
||||
VDA5050Version = createDto.VDA5050Version,
|
||||
VDA5050PublishRepeat = createDto.VDA5050PublishRepeat,
|
||||
VDA5050EnablePassword = createDto.VDA5050EnablePassword,
|
||||
VDA5050EnableTls = createDto.VDA5050EnableTls,
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now,
|
||||
IsActive = false
|
||||
};
|
||||
|
||||
AppDb.RobotVDA5050Configs.Add(config);
|
||||
await AppDb.SaveChangesAsync();
|
||||
|
||||
return new(true, "VDA5050 configuration created successfully.")
|
||||
{
|
||||
Data = new RobotVDA5050ConfigDto
|
||||
{
|
||||
Id = config.Id,
|
||||
ConfigName = config.ConfigName,
|
||||
Description = config.Description,
|
||||
SerialNumber = config.SerialNumber,
|
||||
VDA5050HostServer = config.VDA5050HostServer,
|
||||
VDA5050Port = config.VDA5050Port,
|
||||
VDA5050UserName = config.VDA5050UserName,
|
||||
VDA5050Password = config.VDA5050Password,
|
||||
VDA5050Manufacturer = config.VDA5050Manufacturer,
|
||||
VDA5050Version = config.VDA5050Version,
|
||||
VDA5050PublishRepeat = config.VDA5050PublishRepeat,
|
||||
VDA5050EnablePassword = config.VDA5050EnablePassword,
|
||||
VDA5050EnableTls = config.VDA5050EnableTls,
|
||||
CreatedAt = config.CreatedAt,
|
||||
UpdatedAt = config.UpdatedAt,
|
||||
IsActive = config.IsActive,
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Create VDA5050 Config: {ex.Message}");
|
||||
return new(false, "An error occurred while creating the VDA5050 configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Route("vda5050/{id:guid}")]
|
||||
public async Task<MessageResult> DeleteVDA5050Config(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var config = await AppDb.RobotVDA5050Configs.FindAsync(id);
|
||||
if (config is null) return new(false, "VDA5050 configuration not found.");
|
||||
if (config.IsActive) return new(false, "Cannot delete an active VDA5050 configuration.");
|
||||
|
||||
AppDb.RobotVDA5050Configs.Remove(config);
|
||||
await AppDb.SaveChangesAsync();
|
||||
return new(true, "Configuration deleted successfully.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Delete VDA5050 Config: {ex.Message}");
|
||||
return new(false, "An error occurred while deleting the VDA5050 configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("vda5050/active/{id:guid}")]
|
||||
public async Task<MessageResult> ActiveVDA5050Config(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var config = await AppDb.RobotVDA5050Configs.FindAsync(id);
|
||||
if (config is null) return new(false, "VDA5050 configuration not found.");
|
||||
|
||||
await AppDb.RobotVDA5050Configs.ExecuteUpdateAsync(cf => cf.SetProperty(c => c.IsActive, false));
|
||||
config.IsActive = true;
|
||||
config.UpdatedAt = DateTime.Now;
|
||||
|
||||
await AppDb.SaveChangesAsync();
|
||||
|
||||
await RobotConfiguration.LoadVDA5050ConfigAsync();
|
||||
return new(true, $"VDA5050 configuration {config.ConfigName} activated successfully.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Update Active VDA5050 Config: {ex.Message}");
|
||||
return new(false, "An error occurred while updating the active VDA5050 configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("robot")]
|
||||
public async Task<MessageResult<RobotConfigDto[]>> GetAllRobotConfigs()
|
||||
{
|
||||
try
|
||||
{
|
||||
var configs = await AppDb.RobotConfigs
|
||||
.OrderByDescending(c => c.UpdatedAt)
|
||||
.ToListAsync();
|
||||
if (configs is null || configs.Count == 0) return new(false, "Robot configuration not found.");
|
||||
|
||||
var configDtos = configs.Select(config => new RobotConfigDto
|
||||
{
|
||||
Id = config.Id,
|
||||
NavigationType = config.NavigationType,
|
||||
RadiusWheel = config.RadiusWheel,
|
||||
Width = config.Width,
|
||||
Length = config.Length,
|
||||
Height = config.Height,
|
||||
CreatedAt = config.CreatedAt,
|
||||
UpdatedAt = config.UpdatedAt,
|
||||
IsActive = config.IsActive,
|
||||
ConfigName = config.ConfigName,
|
||||
Description = config.Description
|
||||
}).ToArray();
|
||||
|
||||
return new(true) { Data = configDtos };
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Get All Robot Configs: {ex.Message}");
|
||||
return new(false, "An error occurred while retrieving Robot configurations.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("robot/{id:guid}")]
|
||||
public async Task<MessageResult<RobotConfigDto>> UpdateRobotConfig(Guid id, [FromBody] UpdateRobotConfigDto updateDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
var config = await AppDb.RobotConfigs.FindAsync(id);
|
||||
if (config is null) return new(false, "Robot configuration not found.");
|
||||
|
||||
if (string.IsNullOrEmpty(updateDto.ConfigName)) return new(false, "ConfigName cannot be null or empty.");
|
||||
if (await AppDb.RobotConfigs.AnyAsync(cf => cf.Id != id && cf.ConfigName == updateDto.ConfigName))
|
||||
return new(false, "A Robot configuration with the same name already exists.");
|
||||
|
||||
config.NavigationType = updateDto.NavigationType;
|
||||
config.RadiusWheel = updateDto.RadiusWheel;
|
||||
config.Width = updateDto.Width;
|
||||
config.Length = updateDto.Length;
|
||||
config.Height = updateDto.Height;
|
||||
config.ConfigName = updateDto.ConfigName ?? config.ConfigName;
|
||||
config.Description = updateDto.Description ?? config.Description;
|
||||
config.UpdatedAt = DateTime.Now;
|
||||
|
||||
await AppDb.SaveChangesAsync();
|
||||
|
||||
if (config.IsActive) await RobotConfiguration.LoadRobotConfigAsync();
|
||||
return new(true, "Robot configuration updated successfully.")
|
||||
{
|
||||
Data = new RobotConfigDto
|
||||
{
|
||||
Id = config.Id,
|
||||
NavigationType = config.NavigationType,
|
||||
RadiusWheel = config.RadiusWheel,
|
||||
Width = config.Width,
|
||||
Length = config.Length,
|
||||
Height = config.Height,
|
||||
CreatedAt = config.CreatedAt,
|
||||
UpdatedAt = config.UpdatedAt,
|
||||
IsActive = config.IsActive,
|
||||
ConfigName = config.ConfigName,
|
||||
Description = config.Description
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Update Robot Config: {ex.Message}");
|
||||
return new(false, "An error occurred while updating the Robot configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("robot")]
|
||||
public async Task<MessageResult<RobotConfigDto>> CreateRobotConfig([FromBody] CreateRobotConfigDto createDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(createDto.ConfigName)) return new(false, "ConfigName cannot be null or empty.");
|
||||
if (await AppDb.RobotConfigs.AnyAsync(cf => cf.ConfigName == createDto.ConfigName))
|
||||
return new(false, "A Robot configuration with the same name already exists.");
|
||||
|
||||
var config = new RobotConfig
|
||||
{
|
||||
ConfigName = createDto.ConfigName,
|
||||
Description = createDto.Description,
|
||||
NavigationType = createDto.NavigationType,
|
||||
RadiusWheel = createDto.RadiusWheel,
|
||||
Width = createDto.Width,
|
||||
Length = createDto.Length,
|
||||
Height = createDto.Height,
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now,
|
||||
IsActive = false
|
||||
};
|
||||
|
||||
AppDb.RobotConfigs.Add(config);
|
||||
await AppDb.SaveChangesAsync();
|
||||
|
||||
return new(true, "Robot configuration created successfully.")
|
||||
{
|
||||
Data = new RobotConfigDto
|
||||
{
|
||||
Id = config.Id,
|
||||
ConfigName = config.ConfigName,
|
||||
Description = config.Description,
|
||||
NavigationType = config.NavigationType,
|
||||
RadiusWheel = config.RadiusWheel,
|
||||
Width = config.Width,
|
||||
Length = config.Length,
|
||||
Height = config.Height,
|
||||
CreatedAt = config.CreatedAt,
|
||||
UpdatedAt = config.UpdatedAt,
|
||||
IsActive = config.IsActive,
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Create Robot Config: {ex.Message}");
|
||||
return new(false, "An error occurred while creating the Robot configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Route("robot/{id:guid}")]
|
||||
public async Task<MessageResult> DeleteRobotConfig(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var config = await AppDb.RobotConfigs.FindAsync(id);
|
||||
if (config is null) return new(false, "Robot configuration not found.");
|
||||
if (config.IsActive) return new(false, "Cannot delete an active Robot configuration.");
|
||||
|
||||
AppDb.RobotConfigs.Remove(config);
|
||||
await AppDb.SaveChangesAsync();
|
||||
return new(true, "Configuration deleted successfully.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Delete Robot Config: {ex.Message}");
|
||||
return new(false, "An error occurred while deleting the Robot configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("robot/active/{id:guid}")]
|
||||
public async Task<MessageResult> ActiveRobotConfig(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var config = await AppDb.RobotConfigs.FindAsync(id);
|
||||
if (config is null) return new(false, "Robot configuration not found.");
|
||||
|
||||
await AppDb.RobotConfigs.ExecuteUpdateAsync(cf => cf.SetProperty(c => c.IsActive, false));
|
||||
config.IsActive = true;
|
||||
config.UpdatedAt = DateTime.Now;
|
||||
|
||||
await AppDb.SaveChangesAsync();
|
||||
|
||||
await RobotConfiguration.LoadRobotConfigAsync();
|
||||
return new(true, $"Robot configuration {config.ConfigName} activated successfully.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Update Active Robot Config: {ex.Message}");
|
||||
return new(false, "An error occurred while updating the active Robot configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("simulation")]
|
||||
public async Task<MessageResult<RobotSimulationConfigDto[]>> GetAllSimulationConfigs()
|
||||
{
|
||||
try
|
||||
{
|
||||
var configs = await AppDb.RobotSimulationConfigs
|
||||
.OrderByDescending(c => c.UpdatedAt)
|
||||
.ToListAsync();
|
||||
|
||||
if (configs is null || configs.Count == 0) return new(false, "Simulation configuration not found.");
|
||||
var configDtos = configs.Select(config => new RobotSimulationConfigDto
|
||||
{
|
||||
Id = config.Id,
|
||||
EnableSimulation = config.EnableSimulation,
|
||||
SimulationMaxVelocity = config.SimulationMaxVelocity,
|
||||
SimulationMaxAngularVelocity = config.SimulationMaxAngularVelocity,
|
||||
SimulationAcceleration = config.SimulationAcceleration,
|
||||
SimulationDeceleration = config.SimulationDeceleration,
|
||||
CreatedAt = config.CreatedAt,
|
||||
UpdatedAt = config.UpdatedAt,
|
||||
IsActive = config.IsActive,
|
||||
ConfigName = config.ConfigName,
|
||||
Description = config.Description
|
||||
}).ToArray();
|
||||
|
||||
return new(true) { Data = configDtos };
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Get All Simulation Configs: {ex.Message}");
|
||||
return new(false, "An error occurred while retrieving Simulation configurations.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("simulation/{id:guid}")]
|
||||
public async Task<MessageResult<RobotSimulationConfigDto>> UpdateSimulationConfig(Guid id, [FromBody] UpdateRobotSimulationConfigDto updateDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
var config = await AppDb.RobotSimulationConfigs.FindAsync(id);
|
||||
if (config is null) return new(false, "Simulation configuration not found.");
|
||||
|
||||
if (string.IsNullOrEmpty(updateDto.ConfigName)) return new(false, "ConfigName cannot be null or empty.");
|
||||
if (await AppDb.RobotSimulationConfigs.AnyAsync(cf => cf.Id != id && cf.ConfigName == updateDto.ConfigName))
|
||||
return new(false, "A Simulation configuration with the same name already exists.");
|
||||
|
||||
config.EnableSimulation = updateDto.EnableSimulation;
|
||||
config.SimulationMaxVelocity = updateDto.SimulationMaxVelocity;
|
||||
config.SimulationMaxAngularVelocity = updateDto.SimulationMaxAngularVelocity;
|
||||
config.SimulationAcceleration = updateDto.SimulationAcceleration;
|
||||
config.SimulationDeceleration = updateDto.SimulationDeceleration;
|
||||
config.ConfigName = updateDto.ConfigName ?? config.ConfigName;
|
||||
config.Description = updateDto.Description ?? config.Description;
|
||||
config.UpdatedAt = DateTime.Now;
|
||||
|
||||
await AppDb.SaveChangesAsync();
|
||||
|
||||
if (config.IsActive) await RobotConfiguration.LoadRobotSimulationConfigAsync();
|
||||
return new(true, "Simulation configuration updated successfully.")
|
||||
{
|
||||
Data = new RobotSimulationConfigDto
|
||||
{
|
||||
Id = config.Id,
|
||||
EnableSimulation = config.EnableSimulation,
|
||||
SimulationMaxVelocity = config.SimulationMaxVelocity,
|
||||
SimulationMaxAngularVelocity = config.SimulationMaxAngularVelocity,
|
||||
SimulationAcceleration = config.SimulationAcceleration,
|
||||
SimulationDeceleration = config.SimulationDeceleration,
|
||||
CreatedAt = config.CreatedAt,
|
||||
UpdatedAt = config.UpdatedAt,
|
||||
IsActive = config.IsActive,
|
||||
ConfigName = config.ConfigName,
|
||||
Description = config.Description
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Update Simulation Config: {ex.Message}");
|
||||
return new(false, "An error occurred while updating the Simulation configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("simulation")]
|
||||
public async Task<MessageResult<RobotSimulationConfigDto>> CreateRobotSimulationConfig([FromBody] CreateRobotSimulationConfigDto createDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(createDto.ConfigName)) return new(false, "ConfigName cannot be null or empty.");
|
||||
if (await AppDb.RobotSimulationConfigs.AnyAsync(cf => cf.ConfigName == createDto.ConfigName))
|
||||
return new(false, "A Simulation configuration with the same name already exists.");
|
||||
|
||||
var config = new RobotSimulationConfig
|
||||
{
|
||||
ConfigName = createDto.ConfigName,
|
||||
Description = createDto.Description,
|
||||
EnableSimulation = createDto.EnableSimulation,
|
||||
SimulationMaxVelocity = createDto.SimulationMaxVelocity,
|
||||
SimulationMaxAngularVelocity = createDto.SimulationMaxAngularVelocity,
|
||||
SimulationAcceleration = createDto.SimulationAcceleration,
|
||||
SimulationDeceleration = createDto.SimulationDeceleration,
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now,
|
||||
IsActive = false
|
||||
};
|
||||
|
||||
AppDb.RobotSimulationConfigs.Add(config);
|
||||
await AppDb.SaveChangesAsync();
|
||||
|
||||
return new(true, "Simulation configuration created successfully.")
|
||||
{
|
||||
Data = new RobotSimulationConfigDto
|
||||
{
|
||||
Id = config.Id,
|
||||
ConfigName = config.ConfigName,
|
||||
Description = config.Description,
|
||||
EnableSimulation = config.EnableSimulation,
|
||||
SimulationMaxVelocity = config.SimulationMaxVelocity,
|
||||
SimulationMaxAngularVelocity = config.SimulationMaxAngularVelocity,
|
||||
SimulationAcceleration = config.SimulationAcceleration,
|
||||
SimulationDeceleration = config.SimulationDeceleration,
|
||||
CreatedAt = config.CreatedAt,
|
||||
UpdatedAt = config.UpdatedAt,
|
||||
IsActive = config.IsActive,
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Create Simulation Config: {ex.Message}");
|
||||
return new(false, "An error occurred while creating the Simulation configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Route("simulation/{id:guid}")]
|
||||
public async Task<MessageResult> DeleteRobotSimulationConfig(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var config = await AppDb.RobotSimulationConfigs.FindAsync(id);
|
||||
if (config is null) return new(false, "Simulation configuration not found.");
|
||||
if (config.IsActive) return new(false, "Cannot delete an active Simulation configuration.");
|
||||
|
||||
AppDb.RobotSimulationConfigs.Remove(config);
|
||||
await AppDb.SaveChangesAsync();
|
||||
return new(true, "Configuration deleted successfully.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Delete Simulation Config: {ex.Message}");
|
||||
return new(false, "An error occurred while deleting the Simulation configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("simulation/active/{id:guid}")]
|
||||
public async Task<MessageResult> ActiveSimulationConfig(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var config = await AppDb.RobotSimulationConfigs.FindAsync(id);
|
||||
if (config is null) return new(false, "Simulation configuration not found.");
|
||||
|
||||
await AppDb.RobotSimulationConfigs.ExecuteUpdateAsync(cf => cf.SetProperty(c => c.IsActive, false));
|
||||
config.IsActive = true;
|
||||
config.UpdatedAt = DateTime.Now;
|
||||
|
||||
await AppDb.SaveChangesAsync();
|
||||
|
||||
await RobotConfiguration.LoadRobotSimulationConfigAsync();
|
||||
return new(true, $"Simulation configuration {config.ConfigName} activated successfully.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Update Active Simulation Config: {ex.Message}");
|
||||
return new(false, "An error occurred while updating the active Simulation configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Route("safety")]
|
||||
public async Task<MessageResult<RobotSafetyConfigDto[]>> GetAllSafetyConfigs()
|
||||
{
|
||||
try
|
||||
{
|
||||
var configs = await AppDb.RobotSafetyConfigs
|
||||
.OrderByDescending(c => c.UpdatedAt)
|
||||
.ToListAsync();
|
||||
if (configs is null || configs.Count == 0) return new(false, "Safety configuration not found.");
|
||||
var configDtos = configs.Select(config => new RobotSafetyConfigDto
|
||||
{
|
||||
Id = config.Id,
|
||||
SafetySpeedVerySlow = config.SafetySpeedVerySlow,
|
||||
SafetySpeedSlow = config.SafetySpeedSlow,
|
||||
SafetySpeedNormal = config.SafetySpeedNormal,
|
||||
SafetySpeedMedium = config.SafetySpeedMedium,
|
||||
SafetySpeedOptimal = config.SafetySpeedOptimal,
|
||||
SafetySpeedFast = config.SafetySpeedFast,
|
||||
SafetySpeedVeryFast = config.SafetySpeedVeryFast,
|
||||
CreatedAt = config.CreatedAt,
|
||||
UpdatedAt = config.UpdatedAt,
|
||||
IsActive = config.IsActive,
|
||||
ConfigName = config.ConfigName,
|
||||
Description = config.Description
|
||||
}).ToArray();
|
||||
|
||||
return new(true) { Data = configDtos };
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Get All Safety Configs: {ex.Message}");
|
||||
return new(false, "An error occurred while retrieving Safety configurations.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("safety/{id:guid}")]
|
||||
public async Task<MessageResult<RobotSafetyConfigDto>> UpdateSafetyConfig(Guid id, [FromBody] UpdateRobotSafetyConfigDto updateDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
var config = await AppDb.RobotSafetyConfigs.FindAsync(id);
|
||||
if (config is null) return new(false, "Safety configuration not found.");
|
||||
|
||||
if (string.IsNullOrEmpty(updateDto.ConfigName)) return new(false, "ConfigName cannot be null or empty.");
|
||||
if (await AppDb.RobotSafetyConfigs.AnyAsync(cf => cf.Id != id && cf.ConfigName == updateDto.ConfigName))
|
||||
return new(false, "A Safety configuration with the same name already exists.");
|
||||
|
||||
config.SafetySpeedVerySlow = updateDto.SafetySpeedVerySlow;
|
||||
config.SafetySpeedSlow = updateDto.SafetySpeedSlow;
|
||||
config.SafetySpeedNormal = updateDto.SafetySpeedNormal;
|
||||
config.SafetySpeedMedium = updateDto.SafetySpeedMedium;
|
||||
config.SafetySpeedOptimal = updateDto.SafetySpeedOptimal;
|
||||
config.SafetySpeedFast = updateDto.SafetySpeedFast;
|
||||
config.SafetySpeedVeryFast = updateDto.SafetySpeedVeryFast;
|
||||
config.ConfigName = updateDto.ConfigName ?? config.ConfigName;
|
||||
config.Description = updateDto.Description ?? config.Description;
|
||||
config.UpdatedAt = DateTime.Now;
|
||||
|
||||
await AppDb.SaveChangesAsync();
|
||||
|
||||
if (config.IsActive) await RobotConfiguration.LoadRobotSafetyConfigAsync();
|
||||
return new(true, "Safety configuration updated successfully.")
|
||||
{
|
||||
Data = new RobotSafetyConfigDto
|
||||
{
|
||||
Id = config.Id,
|
||||
SafetySpeedVerySlow = config.SafetySpeedVerySlow,
|
||||
SafetySpeedSlow = config.SafetySpeedSlow,
|
||||
SafetySpeedNormal = config.SafetySpeedNormal,
|
||||
SafetySpeedMedium = config.SafetySpeedMedium,
|
||||
SafetySpeedOptimal = config.SafetySpeedOptimal,
|
||||
SafetySpeedFast = config.SafetySpeedFast,
|
||||
SafetySpeedVeryFast = config.SafetySpeedVeryFast,
|
||||
CreatedAt = config.CreatedAt,
|
||||
UpdatedAt = config.UpdatedAt,
|
||||
IsActive = config.IsActive,
|
||||
ConfigName = config.ConfigName,
|
||||
Description = config.Description
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Update Safety Config: {ex.Message}");
|
||||
return new(false, "An error occurred while updating the Safety configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("safety")]
|
||||
public async Task<MessageResult<RobotSafetyConfigDto>> CreateRobotSafetyConfig([FromBody] CreateRobotSafetyConfigDto createDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(createDto.ConfigName)) return new(false, "ConfigName cannot be null or empty.");
|
||||
if (await AppDb.RobotSafetyConfigs.AnyAsync(cf => cf.ConfigName == createDto.ConfigName))
|
||||
return new(false, "A Safety configuration with the same name already exists.");
|
||||
|
||||
var config = new RobotSafetyConfig
|
||||
{
|
||||
ConfigName = createDto.ConfigName,
|
||||
Description = createDto.Description,
|
||||
SafetySpeedVerySlow = createDto.SafetySpeedVerySlow,
|
||||
SafetySpeedSlow = createDto.SafetySpeedSlow,
|
||||
SafetySpeedNormal = createDto.SafetySpeedNormal,
|
||||
SafetySpeedMedium = createDto.SafetySpeedMedium,
|
||||
SafetySpeedOptimal = createDto.SafetySpeedOptimal,
|
||||
SafetySpeedFast = createDto.SafetySpeedFast,
|
||||
SafetySpeedVeryFast = createDto.SafetySpeedVeryFast,
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now,
|
||||
IsActive = false
|
||||
};
|
||||
|
||||
AppDb.RobotSafetyConfigs.Add(config);
|
||||
await AppDb.SaveChangesAsync();
|
||||
|
||||
return new(true, "Safety configuration created successfully.")
|
||||
{
|
||||
Data = new RobotSafetyConfigDto
|
||||
{
|
||||
Id = config.Id,
|
||||
ConfigName = config.ConfigName,
|
||||
Description = config.Description,
|
||||
SafetySpeedVerySlow = config.SafetySpeedVerySlow,
|
||||
SafetySpeedSlow = config.SafetySpeedSlow,
|
||||
SafetySpeedNormal = config.SafetySpeedNormal,
|
||||
SafetySpeedMedium = config.SafetySpeedMedium,
|
||||
SafetySpeedOptimal = config.SafetySpeedOptimal,
|
||||
SafetySpeedFast = config.SafetySpeedFast,
|
||||
SafetySpeedVeryFast = config.SafetySpeedVeryFast,
|
||||
CreatedAt = config.CreatedAt,
|
||||
UpdatedAt = config.UpdatedAt,
|
||||
IsActive = config.IsActive,
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Create Safety Config: {ex.Message}");
|
||||
return new(false, "An error occurred while creating the Safety configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Route("safety/{id:guid}")]
|
||||
public async Task<MessageResult> DeleteRobotSafetyConfig(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var config = await AppDb.RobotSafetyConfigs.FindAsync(id);
|
||||
if (config is null) return new(false, "Safety configuration not found.");
|
||||
if (config.IsActive) return new(false, "Cannot delete an active Safety configuration.");
|
||||
|
||||
AppDb.RobotSafetyConfigs.Remove(config);
|
||||
await AppDb.SaveChangesAsync();
|
||||
return new(true, "Configuration deleted successfully.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Delete Safety Config: {ex.Message}");
|
||||
return new(false, "An error occurred while deleting the Safety configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[Route("safety/active/{id:guid}")]
|
||||
public async Task<MessageResult> ActiveSafetyConfig(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var config = await AppDb.RobotSafetyConfigs.FindAsync(id);
|
||||
if (config is null) return new(false, "Safety configuration not found.");
|
||||
|
||||
await AppDb.RobotSafetyConfigs.ExecuteUpdateAsync(cf => cf.SetProperty(c => c.IsActive, false));
|
||||
config.IsActive = true;
|
||||
config.UpdatedAt = DateTime.Now;
|
||||
|
||||
await AppDb.SaveChangesAsync();
|
||||
|
||||
await RobotConfiguration.LoadRobotSafetyConfigAsync();
|
||||
return new(true, $"Safety configuration {config.ConfigName} activated successfully.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Error in Update Active Safety Config: {ex.Message}");
|
||||
return new(false, "An error occurred while updating the active Safety configuration.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,14 @@
|
|||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotApp.VDA5050.Order;
|
||||
using RobotApp.VDA5050.State;
|
||||
using static MudBlazor.CategoryTypes;
|
||||
|
||||
namespace RobotApp.Data
|
||||
{
|
||||
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string>
|
||||
public class ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : IdentityDbContext<ApplicationUser, ApplicationRole, string>(options)
|
||||
{
|
||||
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
|
||||
{
|
||||
}
|
||||
|
||||
public DbSet<RobotConfig> RobotConfigs { get; private set; }
|
||||
public DbSet<RobotSimulationConfig> RobotSimulationConfigs { get; private set; }
|
||||
public DbSet<RobotPlcConfig> RobotPlcConfigs { get; private set; }
|
||||
public DbSet<RobotVDA5050Config> RobotVDA5050Configs { get; private set; }
|
||||
public DbSet<RobotSafetyConfig> RobotSafetyConfigs { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -163,5 +163,27 @@ public static class ApplicationDbExtensions
|
|||
appDb.RobotVDA5050Configs.Add(defaultConfig);
|
||||
await appDb.SaveChangesAsync();
|
||||
}
|
||||
|
||||
if (!await appDb.RobotSafetyConfigs.AnyAsync())
|
||||
{
|
||||
var defaultConfig = new RobotSafetyConfig
|
||||
{
|
||||
ConfigName = "Default",
|
||||
Description = "Default robot Safety configuration",
|
||||
SafetySpeedVerySlow = 0.15,
|
||||
SafetySpeedSlow = 0.3,
|
||||
SafetySpeedNormal = 0.6,
|
||||
SafetySpeedMedium = 0.9,
|
||||
SafetySpeedOptimal = 1.2,
|
||||
SafetySpeedFast = 1.5,
|
||||
SafetySpeedVeryFast = 1.9,
|
||||
IsActive = true,
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now,
|
||||
};
|
||||
|
||||
appDb.RobotSafetyConfigs.Add(defaultConfig);
|
||||
await appDb.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
565
RobotApp/Data/Migrations/20251029064620_InitConfigSafetyDb.Designer.cs
generated
Normal file
565
RobotApp/Data/Migrations/20251029064620_InitConfigSafetyDb.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,565 @@
|
|||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using RobotApp.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace RobotApp.Data.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20251029064620_InitConfigSafetyDb")]
|
||||
partial class InitConfigSafetyDb
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "9.0.9");
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotApp.Data.ApplicationRole", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("RoleNameIndex");
|
||||
|
||||
b.ToTable("AspNetRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotApp.Data.ApplicationUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasDatabaseName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("UserNameIndex");
|
||||
|
||||
b.ToTable("AspNetUsers", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotApp.Data.RobotConfig", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("ConfigName")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("ConfigName");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("CreatedAt");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("ntext")
|
||||
.HasColumnName("Description");
|
||||
|
||||
b.Property<double>("Height")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Height");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("IsActive");
|
||||
|
||||
b.Property<double>("Length")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Length");
|
||||
|
||||
b.Property<int>("NavigationType")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("NavigationType");
|
||||
|
||||
b.Property<double>("RadiusWheel")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("RadiusWheel");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("UpdatedAt");
|
||||
|
||||
b.Property<double>("Width")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Width");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("RobotConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotApp.Data.RobotPlcConfig", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("ConfigName")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("ConfigName");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("CreatedAt");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("ntext")
|
||||
.HasColumnName("Description");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("IsActive");
|
||||
|
||||
b.Property<string>("PLCAddress")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("PLCAddress");
|
||||
|
||||
b.Property<int>("PLCPort")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("PLCPort");
|
||||
|
||||
b.Property<byte>("PLCUnitId")
|
||||
.HasColumnType("tinyint")
|
||||
.HasColumnName("PLCUnitId");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("UpdatedAt");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("RobotPlcConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotApp.Data.RobotSafetyConfig", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("ConfigName")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("ConfigName");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("CreatedAt");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("ntext")
|
||||
.HasColumnName("Description");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("IsActive");
|
||||
|
||||
b.Property<double>("SafetySpeedFast")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedFast");
|
||||
|
||||
b.Property<double>("SafetySpeedMedium")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedMedium");
|
||||
|
||||
b.Property<double>("SafetySpeedNormal")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedNormal");
|
||||
|
||||
b.Property<double>("SafetySpeedOptimal")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedOptimal");
|
||||
|
||||
b.Property<double>("SafetySpeedSlow")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedSlow");
|
||||
|
||||
b.Property<double>("SafetySpeedVeryFast")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedVeryFast");
|
||||
|
||||
b.Property<double>("SafetySpeedVerySlow")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedVerySlow");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("UpdatedAt");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("RobotSafetyConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotApp.Data.RobotSimulationConfig", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("ConfigName")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("ConfigName");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("CreatedAt");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("ntext")
|
||||
.HasColumnName("Description");
|
||||
|
||||
b.Property<bool>("EnableSimulation")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("EnableSimulation");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("IsActive");
|
||||
|
||||
b.Property<double>("SimulationAcceleration")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SimulationAcceleration");
|
||||
|
||||
b.Property<double>("SimulationDeceleration")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SimulationDeceleration");
|
||||
|
||||
b.Property<double>("SimulationMaxAngularVelocity")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SimulationMaxAngularVelocity");
|
||||
|
||||
b.Property<double>("SimulationMaxVelocity")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SimulationMaxVelocity");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("UpdatedAt");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("RobotSimulationConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotApp.Data.RobotVDA5050Config", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("ConfigName")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("ConfigName");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("CreatedAt");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("ntext")
|
||||
.HasColumnName("Description");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("IsActive");
|
||||
|
||||
b.Property<string>("SerialNumber")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("SerialNumber");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("UpdatedAt");
|
||||
|
||||
b.Property<bool>("VDA5050EnablePassword")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("VDA5050_EnablePassword");
|
||||
|
||||
b.Property<bool>("VDA5050EnableTls")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("VDA5050_EnableTls");
|
||||
|
||||
b.Property<string>("VDA5050HostServer")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("VDA5050_HostServer");
|
||||
|
||||
b.Property<string>("VDA5050Manufacturer")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("VDA5050_Manufacturer");
|
||||
|
||||
b.Property<string>("VDA5050Password")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("VDA5050_Password");
|
||||
|
||||
b.Property<int>("VDA5050Port")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("VDA5050_Port");
|
||||
|
||||
b.Property<int>("VDA5050PublishRepeat")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("VDA5050_PublishRepeat");
|
||||
|
||||
b.Property<string>("VDA5050UserName")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("VDA5050_UserName");
|
||||
|
||||
b.Property<string>("VDA5050Version")
|
||||
.HasMaxLength(20)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("VDA5050_Version");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("RobotVDA5050Config");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("RobotApp.Data.ApplicationRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("RobotApp.Data.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("RobotApp.Data.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("RobotApp.Data.ApplicationRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("RobotApp.Data.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("RobotApp.Data.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace RobotApp.Data.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class InitConfigSafetyDb : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "RobotSafetyConfig",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
SafetySpeedVerySlow = table.Column<double>(type: "float", nullable: false),
|
||||
SafetySpeedSlow = table.Column<double>(type: "float", nullable: false),
|
||||
SafetySpeedNormal = table.Column<double>(type: "float", nullable: false),
|
||||
SafetySpeedMedium = table.Column<double>(type: "float", nullable: false),
|
||||
SafetySpeedOptimal = table.Column<double>(type: "float", nullable: false),
|
||||
SafetySpeedFast = table.Column<double>(type: "float", nullable: false),
|
||||
SafetySpeedVeryFast = table.Column<double>(type: "float", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime2", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "datetime2", nullable: false),
|
||||
IsActive = table.Column<bool>(type: "bit", nullable: false),
|
||||
ConfigName = table.Column<string>(type: "nvarchar(64)", maxLength: 100, nullable: true),
|
||||
Description = table.Column<string>(type: "ntext", maxLength: 500, nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_RobotSafetyConfig", x => x.Id);
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "RobotSafetyConfig");
|
||||
}
|
||||
}
|
||||
}
|
||||
565
RobotApp/Data/Migrations/20251029064649_InitConfigSafety1Db.Designer.cs
generated
Normal file
565
RobotApp/Data/Migrations/20251029064649_InitConfigSafety1Db.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,565 @@
|
|||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using RobotApp.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace RobotApp.Data.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20251029064649_InitConfigSafety1Db")]
|
||||
partial class InitConfigSafety1Db
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "9.0.9");
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotApp.Data.ApplicationRole", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("RoleNameIndex");
|
||||
|
||||
b.ToTable("AspNetRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotApp.Data.ApplicationUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasDatabaseName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("UserNameIndex");
|
||||
|
||||
b.ToTable("AspNetUsers", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotApp.Data.RobotConfig", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("ConfigName")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("ConfigName");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("CreatedAt");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("ntext")
|
||||
.HasColumnName("Description");
|
||||
|
||||
b.Property<double>("Height")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Height");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("IsActive");
|
||||
|
||||
b.Property<double>("Length")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Length");
|
||||
|
||||
b.Property<int>("NavigationType")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("NavigationType");
|
||||
|
||||
b.Property<double>("RadiusWheel")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("RadiusWheel");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("UpdatedAt");
|
||||
|
||||
b.Property<double>("Width")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("Width");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("RobotConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotApp.Data.RobotPlcConfig", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("ConfigName")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("ConfigName");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("CreatedAt");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("ntext")
|
||||
.HasColumnName("Description");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("IsActive");
|
||||
|
||||
b.Property<string>("PLCAddress")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("PLCAddress");
|
||||
|
||||
b.Property<int>("PLCPort")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("PLCPort");
|
||||
|
||||
b.Property<byte>("PLCUnitId")
|
||||
.HasColumnType("tinyint")
|
||||
.HasColumnName("PLCUnitId");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("UpdatedAt");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("RobotPlcConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotApp.Data.RobotSafetyConfig", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("ConfigName")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("ConfigName");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("CreatedAt");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("ntext")
|
||||
.HasColumnName("Description");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("IsActive");
|
||||
|
||||
b.Property<double>("SafetySpeedFast")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedFast");
|
||||
|
||||
b.Property<double>("SafetySpeedMedium")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedMedium");
|
||||
|
||||
b.Property<double>("SafetySpeedNormal")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedNormal");
|
||||
|
||||
b.Property<double>("SafetySpeedOptimal")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedOptimal");
|
||||
|
||||
b.Property<double>("SafetySpeedSlow")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedSlow");
|
||||
|
||||
b.Property<double>("SafetySpeedVeryFast")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedVeryFast");
|
||||
|
||||
b.Property<double>("SafetySpeedVerySlow")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedVerySlow");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("UpdatedAt");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("RobotSafetyConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotApp.Data.RobotSimulationConfig", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("ConfigName")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("ConfigName");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("CreatedAt");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("ntext")
|
||||
.HasColumnName("Description");
|
||||
|
||||
b.Property<bool>("EnableSimulation")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("EnableSimulation");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("IsActive");
|
||||
|
||||
b.Property<double>("SimulationAcceleration")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SimulationAcceleration");
|
||||
|
||||
b.Property<double>("SimulationDeceleration")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SimulationDeceleration");
|
||||
|
||||
b.Property<double>("SimulationMaxAngularVelocity")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SimulationMaxAngularVelocity");
|
||||
|
||||
b.Property<double>("SimulationMaxVelocity")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SimulationMaxVelocity");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("UpdatedAt");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("RobotSimulationConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotApp.Data.RobotVDA5050Config", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("ConfigName")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("ConfigName");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("CreatedAt");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("ntext")
|
||||
.HasColumnName("Description");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("IsActive");
|
||||
|
||||
b.Property<string>("SerialNumber")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("SerialNumber");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("UpdatedAt");
|
||||
|
||||
b.Property<bool>("VDA5050EnablePassword")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("VDA5050_EnablePassword");
|
||||
|
||||
b.Property<bool>("VDA5050EnableTls")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("VDA5050_EnableTls");
|
||||
|
||||
b.Property<string>("VDA5050HostServer")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("VDA5050_HostServer");
|
||||
|
||||
b.Property<string>("VDA5050Manufacturer")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("VDA5050_Manufacturer");
|
||||
|
||||
b.Property<string>("VDA5050Password")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("VDA5050_Password");
|
||||
|
||||
b.Property<int>("VDA5050Port")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("VDA5050_Port");
|
||||
|
||||
b.Property<int>("VDA5050PublishRepeat")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("VDA5050_PublishRepeat");
|
||||
|
||||
b.Property<string>("VDA5050UserName")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("VDA5050_UserName");
|
||||
|
||||
b.Property<string>("VDA5050Version")
|
||||
.HasMaxLength(20)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("VDA5050_Version");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("RobotVDA5050Config");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("RobotApp.Data.ApplicationRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("RobotApp.Data.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("RobotApp.Data.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("RobotApp.Data.ApplicationRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("RobotApp.Data.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("RobotApp.Data.ApplicationUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace RobotApp.Data.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class InitConfigSafety1Db : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -310,6 +310,68 @@ namespace RobotApp.Migrations
|
|||
b.ToTable("RobotPlcConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotApp.Data.RobotSafetyConfig", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uniqueidentifier")
|
||||
.HasColumnName("Id");
|
||||
|
||||
b.Property<string>("ConfigName")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("nvarchar(64)")
|
||||
.HasColumnName("ConfigName");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("CreatedAt");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("ntext")
|
||||
.HasColumnName("Description");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("bit")
|
||||
.HasColumnName("IsActive");
|
||||
|
||||
b.Property<double>("SafetySpeedFast")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedFast");
|
||||
|
||||
b.Property<double>("SafetySpeedMedium")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedMedium");
|
||||
|
||||
b.Property<double>("SafetySpeedNormal")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedNormal");
|
||||
|
||||
b.Property<double>("SafetySpeedOptimal")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedOptimal");
|
||||
|
||||
b.Property<double>("SafetySpeedSlow")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedSlow");
|
||||
|
||||
b.Property<double>("SafetySpeedVeryFast")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedVeryFast");
|
||||
|
||||
b.Property<double>("SafetySpeedVerySlow")
|
||||
.HasColumnType("float")
|
||||
.HasColumnName("SafetySpeedVerySlow");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime2")
|
||||
.HasColumnName("UpdatedAt");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("RobotSafetyConfig");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("RobotApp.Data.RobotSimulationConfig", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public class RobotConfig
|
|||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
[Column("IsActive", TypeName = "bit")]
|
||||
public bool IsActive { get; set; } = true;
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
[Column("ConfigName", TypeName = "nvarchar(64)")]
|
||||
[MaxLength(100)]
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ public class RobotPlcConfig
|
|||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
[Column("IsActive", TypeName = "bit")]
|
||||
public bool IsActive { get; set; } = true;
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
[Column("ConfigName", TypeName = "nvarchar(64)")]
|
||||
[MaxLength(100)]
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ public class RobotSafetyConfig
|
|||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
[Column("IsActive", TypeName = "bit")]
|
||||
public bool IsActive { get; set; } = true;
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
[Column("ConfigName", TypeName = "nvarchar(64)")]
|
||||
[MaxLength(100)]
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ public class RobotSimulationConfig
|
|||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
[Column("IsActive", TypeName = "bit")]
|
||||
public bool IsActive { get; set; } = true;
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
[Column("ConfigName", TypeName = "nvarchar(64)")]
|
||||
[MaxLength(100)]
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ public class RobotVDA5050Config
|
|||
public string VDA5050HostServer { get; set; }
|
||||
|
||||
[Column("VDA5050_Port", TypeName = "int")]
|
||||
public int VDA5050Port { get; set; } = 1883;
|
||||
public int VDA5050Port { get; set; }
|
||||
|
||||
[Column("VDA5050_UserName", TypeName = "nvarchar(64)")]
|
||||
[MaxLength(50)]
|
||||
|
|
@ -58,7 +58,7 @@ public class RobotVDA5050Config
|
|||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
[Column("IsActive", TypeName = "bit")]
|
||||
public bool IsActive { get; set; } = true;
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
[Column("ConfigName", TypeName = "nvarchar(64)")]
|
||||
[MaxLength(100)]
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ using MQTTnet.Protocol;
|
|||
using RobotApp.Common.Shares;
|
||||
using RobotApp.VDA5050;
|
||||
using System.Net.Security;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
|
||||
namespace RobotApp.Services;
|
||||
|
|
|
|||
|
|
@ -1,30 +1,26 @@
|
|||
using RobotApp.Common.Shares.Enums;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotApp.Common.Shares.Enums;
|
||||
using RobotApp.Interfaces;
|
||||
using RobotApp.Services.Robot.Simulation;
|
||||
|
||||
namespace RobotApp.Services.Robot;
|
||||
|
||||
public class RobotConfiguration
|
||||
public class RobotConfiguration(IServiceProvider ServiceProvider, Logger<RobotConfiguration> Logger) : BackgroundService
|
||||
{
|
||||
public string SerialNumber { get; set; } = "Robot-Demo";
|
||||
public NavigationType NavigationType { get; set; } = NavigationType.Differential;
|
||||
public VDA5050.VDA5050Setting VDA5050Setting { get; set; } = new()
|
||||
{
|
||||
HostServer = "172.20.235.176",
|
||||
Port = 1883,
|
||||
UserName = "robotics",
|
||||
Password = "robotics",
|
||||
Manufacturer = "PhenikaaX",
|
||||
Version = "0.0.1",
|
||||
PublishRepeat = 2,
|
||||
};
|
||||
public string PLCAddress { get; set; } = "127.0.0.1";
|
||||
public int PLCPort { get; set; } = 502;
|
||||
public byte PLCUnitId { get; set; } = 1;
|
||||
public bool IsSimulation { get; set; } = true;
|
||||
public SimulationModel SimulationModel { get; set; } = new();
|
||||
public string XlocAddress { get; set; } = "http://192.168.195.56:50050";
|
||||
public Dictionary<SafetySpeed, double> SafetySpeedMap = new ()
|
||||
public bool IsReady { get; private set; } = false;
|
||||
public string SerialNumber { get; private set; } = "";
|
||||
public double RadiusWheel { get; private set; } = 0.1;
|
||||
public double Width { get; private set; } = 0.606;
|
||||
public double Length { get; private set; } = 1.106;
|
||||
public double Height { get; private set; } = 0.5;
|
||||
public NavigationType NavigationType { get; private set; } = NavigationType.Differential;
|
||||
public VDA5050.VDA5050Setting VDA5050Setting { get; private set; } = new();
|
||||
public string PLCAddress { get; private set; } = "127.0.0.1";
|
||||
public int PLCPort { get; private set; } = 502;
|
||||
public byte PLCUnitId { get; private set; } = 1;
|
||||
public bool IsSimulation { get; private set; } = true;
|
||||
public SimulationModel SimulationModel { get; private set; } = new();
|
||||
public Dictionary<SafetySpeed, double> SafetySpeedMap { get; private set; } = new()
|
||||
{
|
||||
{ SafetySpeed.Very_Slow, 0.15},
|
||||
{ SafetySpeed.Slow, 0.3},
|
||||
|
|
@ -34,4 +30,141 @@ public class RobotConfiguration
|
|||
{ SafetySpeed.Fast, 1.5},
|
||||
{ SafetySpeed.Very_Fast, 1.9},
|
||||
};
|
||||
|
||||
public async Task LoadVDA5050ConfigAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
using var scope = ServiceProvider.CreateAsyncScope();
|
||||
var appDb = scope.ServiceProvider.GetRequiredService<Data.ApplicationDbContext>();
|
||||
var config = await appDb.RobotVDA5050Configs.FirstOrDefaultAsync(c => c.IsActive);
|
||||
if (config is not null)
|
||||
{
|
||||
VDA5050Setting.HostServer = config.VDA5050HostServer;
|
||||
VDA5050Setting.Port = config.VDA5050Port;
|
||||
VDA5050Setting.UserName = config.VDA5050UserName;
|
||||
VDA5050Setting.Password = config.VDA5050Password;
|
||||
VDA5050Setting.Manufacturer = config.VDA5050Manufacturer;
|
||||
VDA5050Setting.Version = config.VDA5050Version;
|
||||
VDA5050Setting.PublishRepeat = config.VDA5050PublishRepeat;
|
||||
VDA5050Setting.EnablePassword = config.VDA5050EnablePassword;
|
||||
VDA5050Setting.EnableTls = config.VDA5050EnableTls;
|
||||
SerialNumber = config.SerialNumber;
|
||||
}
|
||||
else throw new Exception("Chưa có cấu hình VDA5050.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"Có lỗi xảy ra khi tải cấu hình VDA5050: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LoadRobotConfigAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
using var scope = ServiceProvider.CreateAsyncScope();
|
||||
var appDb = scope.ServiceProvider.GetRequiredService<Data.ApplicationDbContext>();
|
||||
var config = await appDb.RobotConfigs.FirstOrDefaultAsync(c => c.IsActive);
|
||||
if (config is not null)
|
||||
{
|
||||
Width = config.Width;
|
||||
Length = config.Length;
|
||||
Height = config.Height;
|
||||
RadiusWheel = config.RadiusWheel;
|
||||
NavigationType = config.NavigationType;
|
||||
}
|
||||
else throw new Exception("Chưa có cấu hình robot.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"Có lỗi xảy ra khi tải cấu hình robot: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LoadRobotSafetyConfigAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
using var scope = ServiceProvider.CreateAsyncScope();
|
||||
var appDb = scope.ServiceProvider.GetRequiredService<Data.ApplicationDbContext>();
|
||||
var config = await appDb.RobotSafetyConfigs.FirstOrDefaultAsync(c => c.IsActive);
|
||||
if (config is not null)
|
||||
{
|
||||
SafetySpeedMap[SafetySpeed.Very_Slow] = config.SafetySpeedVerySlow;
|
||||
SafetySpeedMap[SafetySpeed.Slow] = config.SafetySpeedSlow;
|
||||
SafetySpeedMap[SafetySpeed.Normal] = config.SafetySpeedNormal;
|
||||
SafetySpeedMap[SafetySpeed.Medium] = config.SafetySpeedMedium;
|
||||
SafetySpeedMap[SafetySpeed.Optimal] = config.SafetySpeedOptimal;
|
||||
SafetySpeedMap[SafetySpeed.Fast] = config.SafetySpeedFast;
|
||||
SafetySpeedMap[SafetySpeed.Very_Fast] = config.SafetySpeedVeryFast;
|
||||
}
|
||||
else throw new Exception("Chưa có cấu hình safety robot.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"Có lỗi xảy ra khi tải cấu hình safety robot: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LoadRobotSimulationConfigAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
using var scope = ServiceProvider.CreateAsyncScope();
|
||||
var appDb = scope.ServiceProvider.GetRequiredService<Data.ApplicationDbContext>();
|
||||
var config = await appDb.RobotSimulationConfigs.FirstOrDefaultAsync(c => c.IsActive);
|
||||
if (config is not null)
|
||||
{
|
||||
IsSimulation = config.EnableSimulation;
|
||||
SimulationModel.MaxVelocity = config.SimulationMaxVelocity;
|
||||
SimulationModel.MaxAngularVelocity = config.SimulationMaxAngularVelocity;
|
||||
SimulationModel.Acceleration = config.SimulationAcceleration;
|
||||
SimulationModel.Deceleration = config.SimulationDeceleration;
|
||||
}
|
||||
else throw new Exception("Chưa có cấu hình simulation robot.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"Có lỗi xảy ra khi tải cấu hình simulation robot: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task LoadRobotPlcConfigAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
using var scope = ServiceProvider.CreateAsyncScope();
|
||||
var appDb = scope.ServiceProvider.GetRequiredService<Data.ApplicationDbContext>();
|
||||
var config = await appDb.RobotPlcConfigs.FirstOrDefaultAsync(c => c.IsActive);
|
||||
if (config is not null)
|
||||
{
|
||||
PLCAddress = config.PLCAddress;
|
||||
PLCPort = config.PLCPort;
|
||||
PLCUnitId = config.PLCUnitId;
|
||||
}
|
||||
else throw new Exception("Chưa có cấu hình plc robot.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warning($"Có lỗi xảy ra khi tải cấu hình plc robot: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
await LoadVDA5050ConfigAsync();
|
||||
await LoadRobotConfigAsync();
|
||||
await LoadRobotSimulationConfigAsync();
|
||||
await LoadRobotSafetyConfigAsync();
|
||||
await LoadRobotPlcConfigAsync();
|
||||
IsReady = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Lỗi khởi tạo RobotConfiguration: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,9 @@ public partial class RobotController
|
|||
PeripheralManager.RightMotorReady &&
|
||||
BatteryManager.IsReady &&
|
||||
Localization.IsReady &&
|
||||
NavigationManager.IsReady) break;
|
||||
NavigationManager.IsReady &&
|
||||
RobotConfiguration.IsReady
|
||||
) break;
|
||||
}
|
||||
await Task.Delay(1000, cancellationToken);
|
||||
}
|
||||
|
|
@ -37,7 +39,7 @@ public partial class RobotController
|
|||
|
||||
ConnectionManager.OrderUpdated += NewOrderUpdated;
|
||||
ConnectionManager.ActionUpdated += NewInstantActionUpdated;
|
||||
await ConnectionManager.StartConnection(cancellationToken);
|
||||
//await ConnectionManager.StartConnection(cancellationToken);
|
||||
Logger.Info("Robot đã kết nối tới Fleet Manager.");
|
||||
StateManager.TransitionTo(SystemStateType.Standby);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
using Google.Protobuf.WellKnownTypes;
|
||||
using Grpc.Core;
|
||||
using Grpc.Net.Client;
|
||||
using RobotApp.Common.Shares;
|
||||
using RobotApp.Interfaces;
|
||||
using RobotApp.Services.Robot.Simulation;
|
||||
using System;
|
||||
using Xloc;
|
||||
using static Xloc.XlocDiagnostics.Types;
|
||||
|
||||
|
|
@ -44,7 +42,7 @@ public class RobotLocalization(RobotConfiguration RobotConfiguration, Simulation
|
|||
private readonly XlocData XlocData = new();
|
||||
private readonly bool IsSimulation = RobotConfiguration.IsSimulation;
|
||||
|
||||
private readonly XlocServices.XlocServicesClient XlocClient = new(GrpcChannel.ForAddress(RobotConfiguration.XlocAddress));
|
||||
private readonly XlocServices.XlocServicesClient XlocClient;
|
||||
private WatchTimerAsync<RobotLocalization>? ReaderTimer;
|
||||
private const int ReaderInterval = 50;
|
||||
private int TimerCounter = 0;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ public class RobotNavigation(RobotConfiguration RobotConfiguration, IServiceProv
|
|||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
SimNavigation = SimulationNavigationManager.GetNavigation(RobotConfiguration.SimulationModel.NavigationType, ServiceProvider);
|
||||
SimNavigation = SimulationNavigationManager.GetNavigation(RobotConfiguration.NavigationType, ServiceProvider);
|
||||
SimNavigation.OnNavigationFinished += NavigationFinished;
|
||||
SimNavigation.Move(nodes, edges);
|
||||
}
|
||||
|
|
@ -40,7 +40,7 @@ public class RobotNavigation(RobotConfiguration RobotConfiguration, IServiceProv
|
|||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
SimNavigation = SimulationNavigationManager.GetNavigation(RobotConfiguration.SimulationModel.NavigationType, ServiceProvider);
|
||||
SimNavigation = SimulationNavigationManager.GetNavigation(RobotConfiguration.NavigationType, ServiceProvider);
|
||||
SimNavigation.MoveStraight(x, y);
|
||||
}
|
||||
}
|
||||
|
|
@ -59,7 +59,7 @@ public class RobotNavigation(RobotConfiguration RobotConfiguration, IServiceProv
|
|||
{
|
||||
if (IsSimulation)
|
||||
{
|
||||
SimNavigation = SimulationNavigationManager.GetNavigation(RobotConfiguration.SimulationModel.NavigationType, ServiceProvider);
|
||||
SimNavigation = SimulationNavigationManager.GetNavigation(RobotConfiguration.NavigationType, ServiceProvider);
|
||||
SimNavigation.Rotate(angle * 180 / Math.PI);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -242,6 +242,7 @@ public partial class RobotPeripheral(RobotConfiguration RobotConfiguration, IErr
|
|||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
if(RobotConfiguration.IsSimulation) return;
|
||||
await Task.Yield();
|
||||
while (!stoppingToken.IsCancellationRequested && !RobotConfiguration.IsSimulation)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -54,13 +54,13 @@ public class DifferentialNavigation : SimulationNavigation
|
|||
|
||||
if (NavigationPath[MovePurePursuit.OnNodeIndex].Direction == RobotDirection.FORWARD)
|
||||
{
|
||||
AngularVelocityLeft /= RobotConfiguration.SimulationModel.RadiusWheel;
|
||||
AngularVelocityRight = AngularVelocityRight / RobotConfiguration.SimulationModel.RadiusWheel * -1;
|
||||
AngularVelocityLeft /= RobotConfiguration.RadiusWheel;
|
||||
AngularVelocityRight = AngularVelocityRight / RobotConfiguration.RadiusWheel * -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
AngularVelocityLeft = AngularVelocityLeft / RobotConfiguration.SimulationModel.RadiusWheel * -1;
|
||||
AngularVelocityRight /= RobotConfiguration.SimulationModel.RadiusWheel;
|
||||
AngularVelocityLeft = AngularVelocityLeft / RobotConfiguration.RadiusWheel * -1;
|
||||
AngularVelocityRight /= RobotConfiguration.RadiusWheel;
|
||||
}
|
||||
VelocityController.SetSpeed(AngularVelocityLeft, AngularVelocityRight, CycleHandlerMilliseconds / 1000.0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public class SimulationNavigation : INavigation, IDisposable
|
|||
RobotConfiguration = scope.ServiceProvider.GetRequiredService<RobotConfiguration>();
|
||||
PathPlanner = scope.ServiceProvider.GetRequiredService<RobotPathPlanner>();
|
||||
VelocityController = new(Visualization, RobotConfiguration.SimulationModel);
|
||||
AngularVelocity = RobotConfiguration.SimulationModel.MaxAngularVelocity * RobotConfiguration.SimulationModel.Width / 2 / 2 / RobotConfiguration.SimulationModel.RadiusWheel;
|
||||
AngularVelocity = RobotConfiguration.SimulationModel.MaxAngularVelocity * RobotConfiguration.Width / 2 / 2 / RobotConfiguration.RadiusWheel;
|
||||
}
|
||||
|
||||
protected void HandleNavigationStart()
|
||||
|
|
|
|||
|
|
@ -1,15 +1,9 @@
|
|||
using RobotApp.Common.Shares.Enums;
|
||||
|
||||
namespace RobotApp.Services.Robot.Simulation;
|
||||
namespace RobotApp.Services.Robot.Simulation;
|
||||
|
||||
public class SimulationModel
|
||||
{
|
||||
public readonly double RadiusWheel = 0.1;
|
||||
public readonly double Width = 0.606;
|
||||
public readonly double Length = 1.106;
|
||||
public readonly double MaxVelocity = 1.5;
|
||||
public readonly double MaxAngularVelocity = 0.5;
|
||||
public readonly double Acceleration = 2;
|
||||
public readonly double Deceleration = 10;
|
||||
public readonly NavigationType NavigationType = NavigationType.Differential;
|
||||
public double MaxVelocity { get; set; } = 1.5;
|
||||
public double MaxAngularVelocity { get; set; } = 0.5;
|
||||
public double Acceleration { get; set; } = 2;
|
||||
public double Deceleration { get; set; } = 10;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ public class SimulationVisualization(RobotConfiguration RobotConfiguration)
|
|||
public double Vy { get; private set; }
|
||||
public double Omega { get; private set; }
|
||||
|
||||
private readonly double RadiusWheel = RobotConfiguration.SimulationModel.RadiusWheel;
|
||||
private readonly double RadiusRobot = RobotConfiguration.SimulationModel.Width / 2;
|
||||
private readonly double RadiusWheel = RobotConfiguration.RadiusWheel;
|
||||
private readonly double RadiusRobot = RobotConfiguration.Width / 2;
|
||||
|
||||
public (double x, double y, double angle) UpdatePosition(double wL, double wR, double time)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ public static class RobotExtensions
|
|||
public static IServiceCollection AddRobot(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<RobotStateMachine>();
|
||||
services.AddSingleton<RobotConfiguration>();
|
||||
services.AddSingleton<RobotPathPlanner>();
|
||||
services.AddSingleton<RobotConnection>();
|
||||
services.AddSingleton<RobotActionStorage>();
|
||||
|
|
@ -30,6 +29,7 @@ public static class RobotExtensions
|
|||
services.AddHostedServiceSingleton<RobotVisualization>();
|
||||
services.AddHostedServiceSingleton<RobotStates>();
|
||||
services.AddHostedServiceSingleton<RobotFactsheet>();
|
||||
services.AddHostedServiceSingleton<RobotConfiguration>();
|
||||
return services;
|
||||
}
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue
Block a user