update
This commit is contained in:
parent
6eeed8c7b4
commit
643a34a4b4
20
RobotApp.Common.Shares/Dtos/RobotConfigDto.cs
Normal file
20
RobotApp.Common.Shares/Dtos/RobotConfigDto.cs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
using RobotApp.Common.Shares.Enums;
|
||||
|
||||
namespace RobotApp.Common.Shares.Dtos;
|
||||
|
||||
#nullable disable
|
||||
|
||||
public record RobotConfigDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
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 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; }
|
||||
}
|
||||
16
RobotApp.Common.Shares/Dtos/RobotPlcConfigDto.cs
Normal file
16
RobotApp.Common.Shares/Dtos/RobotPlcConfigDto.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
namespace RobotApp.Common.Shares.Dtos;
|
||||
|
||||
#nullable disable
|
||||
|
||||
public record RobotPlcConfigDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string PLCAddress { get; set; }
|
||||
public int PLCPort { get; set; }
|
||||
public byte PLCUnitId { 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; }
|
||||
}
|
||||
20
RobotApp.Common.Shares/Dtos/RobotSafetyConfig.cs
Normal file
20
RobotApp.Common.Shares/Dtos/RobotSafetyConfig.cs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
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; }
|
||||
}
|
||||
18
RobotApp.Common.Shares/Dtos/RobotSimulationConfigDto.cs
Normal file
18
RobotApp.Common.Shares/Dtos/RobotSimulationConfigDto.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
namespace RobotApp.Common.Shares.Dtos;
|
||||
|
||||
#nullable disable
|
||||
|
||||
public record RobotSimulationConfigDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
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 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; }
|
||||
}
|
||||
23
RobotApp.Common.Shares/Dtos/RobotVDA5050ConfigDto.cs
Normal file
23
RobotApp.Common.Shares/Dtos/RobotVDA5050ConfigDto.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
namespace RobotApp.Common.Shares.Dtos;
|
||||
|
||||
#nullable disable
|
||||
|
||||
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 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 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; }
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
namespace RobotApp.VDA5050;
|
||||
|
||||
|
||||
public class VDA5050Setting
|
||||
{
|
||||
public string HostServer { get; set; } = string.Empty;
|
||||
|
|
@ -7,6 +8,8 @@ public class VDA5050Setting
|
|||
public string UserName { get; set; } = "robotics";
|
||||
public string Password { get; set; } = "robotics";
|
||||
public string Manufacturer { get; set; } = "PhenikaaX";
|
||||
public string Version { get; set; } = "0.0.1";
|
||||
public string Version { get; set; } = "2.1.0";
|
||||
public int PublishRepeat { get; set; } = 2;
|
||||
public bool EnablePassword { get; set; } = false;
|
||||
public bool EnableTls { get; set; } = false;
|
||||
}
|
||||
|
|
|
|||
16
RobotApp/Controllers/RobotConfigsController.cs
Normal file
16
RobotApp/Controllers/RobotConfigsController.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace RobotApp.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
public class RobotConfigsController(Services.Logger<ImagesController> Logger) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
[Route("plc")]
|
||||
public void GetPLCConfig()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RobotApp.VDA5050.Order;
|
||||
using RobotApp.VDA5050.State;
|
||||
using static MudBlazor.CategoryTypes;
|
||||
|
||||
namespace RobotApp.Data
|
||||
{
|
||||
|
|
@ -8,5 +11,10 @@ namespace RobotApp.Data
|
|||
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; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ public static class ApplicationDbExtensions
|
|||
|
||||
await scope.ServiceProvider.SeedRolesAsync();
|
||||
await scope.ServiceProvider.SeedUsersAsync();
|
||||
await scope.ServiceProvider.SeedConfigAsync();
|
||||
}
|
||||
|
||||
private static async Task SeedRolesAsync(this IServiceProvider serviceProvider)
|
||||
|
|
@ -31,6 +32,15 @@ public static class ApplicationDbExtensions
|
|||
NormalizedName = "ADMINISTRATOR",
|
||||
});
|
||||
}
|
||||
|
||||
if (!await roleManager.RoleExistsAsync("Distributor"))
|
||||
{
|
||||
await roleManager.CreateAsync(new ApplicationRole()
|
||||
{
|
||||
Name = "Distributor",
|
||||
NormalizedName = "DISTRIBUTOR",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task SeedUsersAsync(this IServiceProvider serviceProvider)
|
||||
|
|
@ -50,5 +60,108 @@ public static class ApplicationDbExtensions
|
|||
await userManager.CreateAsync(admin, "robotics");
|
||||
await userManager.AddToRoleAsync(admin, "Administrator");
|
||||
}
|
||||
|
||||
if (await userManager.FindByNameAsync("distributor") is null)
|
||||
{
|
||||
var distributor = new ApplicationUser()
|
||||
{
|
||||
UserName = "distributor",
|
||||
Email = "distributor@phenikaa-x.com",
|
||||
NormalizedUserName = "DISTRIBUTOR",
|
||||
NormalizedEmail = "DISTRIBUTOR@PHENIKAA-X.COM",
|
||||
EmailConfirmed = true,
|
||||
};
|
||||
|
||||
await userManager.CreateAsync(distributor, "robotics");
|
||||
await userManager.AddToRoleAsync(distributor, "Distributor");
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task SeedConfigAsync(this IServiceProvider serviceProvider)
|
||||
{
|
||||
using var appDb = serviceProvider.GetRequiredService<ApplicationDbContext>();
|
||||
|
||||
if (!await appDb.RobotConfigs.AnyAsync())
|
||||
{
|
||||
var defaultConfig = new RobotConfig
|
||||
{
|
||||
ConfigName = "Default",
|
||||
Description = "Default robot configuration",
|
||||
NavigationType = Common.Shares.Enums.NavigationType.Differential,
|
||||
RadiusWheel = 0.1,
|
||||
Width = 0.6,
|
||||
Length = 1.1,
|
||||
Height = 0.5,
|
||||
IsActive = true,
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now,
|
||||
};
|
||||
|
||||
appDb.RobotConfigs.Add(defaultConfig);
|
||||
await appDb.SaveChangesAsync();
|
||||
}
|
||||
|
||||
if (!await appDb.RobotPlcConfigs.AnyAsync())
|
||||
{
|
||||
var defaultConfig = new RobotPlcConfig
|
||||
{
|
||||
ConfigName = "Default",
|
||||
Description = "Default robot PLC configuration",
|
||||
PLCAddress = "127.0.0.1",
|
||||
PLCPort = 502,
|
||||
PLCUnitId = 1,
|
||||
IsActive = true,
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now,
|
||||
};
|
||||
|
||||
appDb.RobotPlcConfigs.Add(defaultConfig);
|
||||
await appDb.SaveChangesAsync();
|
||||
}
|
||||
|
||||
if (!await appDb.RobotSimulationConfigs.AnyAsync())
|
||||
{
|
||||
var defaultConfig = new RobotSimulationConfig
|
||||
{
|
||||
ConfigName = "Default",
|
||||
Description = "Default robot simulation configuration",
|
||||
EnableSimulation = false,
|
||||
SimulationMaxVelocity = 1.5,
|
||||
SimulationMaxAngularVelocity = 0.5,
|
||||
SimulationAcceleration = 2,
|
||||
SimulationDeceleration = 10,
|
||||
IsActive = true,
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now,
|
||||
};
|
||||
|
||||
appDb.RobotSimulationConfigs.Add(defaultConfig);
|
||||
await appDb.SaveChangesAsync();
|
||||
}
|
||||
|
||||
if (!await appDb.RobotVDA5050Configs.AnyAsync())
|
||||
{
|
||||
var defaultConfig = new RobotVDA5050Config
|
||||
{
|
||||
ConfigName = "Default",
|
||||
Description = "Default robot VDA5050 configuration",
|
||||
SerialNumber = "T800-002",
|
||||
VDA5050HostServer = "127.0.0.1",
|
||||
VDA5050Port = 1883,
|
||||
VDA5050Version = "2.1.0",
|
||||
VDA5050Manufacturer = "PhenikaaX",
|
||||
VDA5050PublishRepeat = 2,
|
||||
VDA5050EnablePassword = true,
|
||||
VDA5050EnableTls = false,
|
||||
VDA5050UserName = "robotics",
|
||||
VDA5050Password = "robotics",
|
||||
IsActive = true,
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now,
|
||||
};
|
||||
|
||||
appDb.RobotVDA5050Configs.Add(defaultConfig);
|
||||
await appDb.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
503
RobotApp/Data/Migrations/20251028102815_InitConfigDb.Designer.cs
generated
Normal file
503
RobotApp/Data/Migrations/20251028102815_InitConfigDb.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,503 @@
|
|||
// <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("20251028102815_InitConfigDb")]
|
||||
partial class InitConfigDb
|
||||
{
|
||||
/// <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.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
|
||||
}
|
||||
}
|
||||
}
|
||||
118
RobotApp/Data/Migrations/20251028102815_InitConfigDb.cs
Normal file
118
RobotApp/Data/Migrations/20251028102815_InitConfigDb.cs
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace RobotApp.Data.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class InitConfigDb : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "RobotConfig",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
NavigationType = table.Column<int>(type: "int", nullable: false),
|
||||
RadiusWheel = table.Column<double>(type: "float", nullable: false),
|
||||
Width = table.Column<double>(type: "float", nullable: false),
|
||||
Length = table.Column<double>(type: "float", nullable: false),
|
||||
Height = 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_RobotConfig", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "RobotPlcConfig",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
PLCAddress = table.Column<string>(type: "nvarchar(64)", maxLength: 50, nullable: true),
|
||||
PLCPort = table.Column<int>(type: "int", nullable: false),
|
||||
PLCUnitId = table.Column<byte>(type: "tinyint", 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_RobotPlcConfig", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "RobotSimulationConfig",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
EnableSimulation = table.Column<bool>(type: "bit", nullable: false),
|
||||
SimulationMaxVelocity = table.Column<double>(type: "float", nullable: false),
|
||||
SimulationMaxAngularVelocity = table.Column<double>(type: "float", nullable: false),
|
||||
SimulationAcceleration = table.Column<double>(type: "float", nullable: false),
|
||||
SimulationDeceleration = 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_RobotSimulationConfig", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "RobotVDA5050Config",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
|
||||
SerialNumber = table.Column<string>(type: "nvarchar(64)", maxLength: 50, nullable: true),
|
||||
VDA5050_HostServer = table.Column<string>(type: "nvarchar(64)", maxLength: 100, nullable: true),
|
||||
VDA5050_Port = table.Column<int>(type: "int", nullable: false),
|
||||
VDA5050_UserName = table.Column<string>(type: "nvarchar(64)", maxLength: 50, nullable: true),
|
||||
VDA5050_Password = table.Column<string>(type: "nvarchar(64)", maxLength: 50, nullable: true),
|
||||
VDA5050_Manufacturer = table.Column<string>(type: "nvarchar(64)", maxLength: 50, nullable: true),
|
||||
VDA5050_Version = table.Column<string>(type: "nvarchar(64)", maxLength: 20, nullable: true),
|
||||
VDA5050_PublishRepeat = table.Column<int>(type: "int", nullable: false),
|
||||
VDA5050_EnablePassword = table.Column<bool>(type: "bit", nullable: false),
|
||||
VDA5050_EnableTls = table.Column<bool>(type: "bit", 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_RobotVDA5050Config", x => x.Id);
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "RobotConfig");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "RobotPlcConfig");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "RobotSimulationConfig");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "RobotVDA5050Config");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -209,6 +209,241 @@ namespace RobotApp.Migrations
|
|||
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.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)
|
||||
|
|
|
|||
49
RobotApp/Data/RobotConfig.cs
Normal file
49
RobotApp/Data/RobotConfig.cs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
using RobotApp.Common.Shares.Enums;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace RobotApp.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
[Table("RobotConfig")]
|
||||
public class RobotConfig
|
||||
{
|
||||
[Column("Id", TypeName = "uniqueidentifier")]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Key]
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Column("NavigationType", TypeName = "int")]
|
||||
public NavigationType NavigationType { get; set; }
|
||||
|
||||
[Column("RadiusWheel", TypeName = "float")]
|
||||
public double RadiusWheel { get; set; }
|
||||
|
||||
[Column("Width", TypeName = "float")]
|
||||
public double Width { get; set; }
|
||||
|
||||
[Column("Length", TypeName = "float")]
|
||||
public double Length { get; set; }
|
||||
|
||||
[Column("Height", TypeName = "float")]
|
||||
public double Height { get; set; }
|
||||
|
||||
[Column("CreatedAt", TypeName = "datetime2")]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
[Column("UpdatedAt", TypeName = "datetime2")]
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
[Column("IsActive", TypeName = "bit")]
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
[Column("ConfigName", TypeName = "nvarchar(64)")]
|
||||
[MaxLength(100)]
|
||||
public string ConfigName { get; set; }
|
||||
|
||||
[Column("Description", TypeName = "ntext")]
|
||||
[MaxLength(500)]
|
||||
public string Description { get; set; }
|
||||
}
|
||||
43
RobotApp/Data/RobotPlcConfig.cs
Normal file
43
RobotApp/Data/RobotPlcConfig.cs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace RobotApp.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
[Table("RobotPlcConfig")]
|
||||
public class RobotPlcConfig
|
||||
{
|
||||
[Column("Id", TypeName = "uniqueidentifier")]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Key]
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Column("PLCAddress", TypeName = "nvarchar(64)")]
|
||||
[MaxLength(50)]
|
||||
public string PLCAddress { get; set; }
|
||||
|
||||
[Column("PLCPort", TypeName = "int")]
|
||||
public int PLCPort { get; set; }
|
||||
|
||||
[Column("PLCUnitId", TypeName = "tinyint")]
|
||||
public byte PLCUnitId { get; set; }
|
||||
|
||||
[Column("CreatedAt", TypeName = "datetime2")]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
[Column("UpdatedAt", TypeName = "datetime2")]
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
[Column("IsActive", TypeName = "bit")]
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
[Column("ConfigName", TypeName = "nvarchar(64)")]
|
||||
[MaxLength(100)]
|
||||
public string ConfigName { get; set; }
|
||||
|
||||
[Column("Description", TypeName = "ntext")]
|
||||
[MaxLength(500)]
|
||||
public string Description { get; set; }
|
||||
}
|
||||
54
RobotApp/Data/RobotSafetyConfig.cs
Normal file
54
RobotApp/Data/RobotSafetyConfig.cs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace RobotApp.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
[Table("RobotSafetyConfig")]
|
||||
public class RobotSafetyConfig
|
||||
{
|
||||
[Column("Id", TypeName = "uniqueidentifier")]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Key]
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Column("SafetySpeedVerySlow", TypeName = "float")]
|
||||
public double SafetySpeedVerySlow { get; set; }
|
||||
|
||||
[Column("SafetySpeedSlow", TypeName = "float")]
|
||||
public double SafetySpeedSlow { get; set; }
|
||||
|
||||
[Column("SafetySpeedNormal", TypeName = "float")]
|
||||
public double SafetySpeedNormal { get; set; }
|
||||
|
||||
[Column("SafetySpeedMedium", TypeName = "float")]
|
||||
public double SafetySpeedMedium { get; set; }
|
||||
|
||||
[Column("SafetySpeedOptimal", TypeName = "float")]
|
||||
public double SafetySpeedOptimal { get; set; }
|
||||
|
||||
[Column("SafetySpeedFast", TypeName = "float")]
|
||||
public double SafetySpeedFast { get; set; }
|
||||
|
||||
[Column("SafetySpeedVeryFast", TypeName = "float")]
|
||||
public double SafetySpeedVeryFast { get; set; }
|
||||
|
||||
[Column("CreatedAt", TypeName = "datetime2")]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
[Column("UpdatedAt", TypeName = "datetime2")]
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
[Column("IsActive", TypeName = "bit")]
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
[Column("ConfigName", TypeName = "nvarchar(64)")]
|
||||
[MaxLength(100)]
|
||||
public string ConfigName { get; set; }
|
||||
|
||||
[Column("Description", TypeName = "ntext")]
|
||||
[MaxLength(500)]
|
||||
public string Description { get; set; }
|
||||
}
|
||||
48
RobotApp/Data/RobotSimulationConfig.cs
Normal file
48
RobotApp/Data/RobotSimulationConfig.cs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace RobotApp.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
[Table("RobotSimulationConfig")]
|
||||
public class RobotSimulationConfig
|
||||
{
|
||||
[Column("Id", TypeName = "uniqueidentifier")]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Key]
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Column("EnableSimulation", TypeName = "bit")]
|
||||
public bool EnableSimulation { get; set; }
|
||||
|
||||
[Column("SimulationMaxVelocity", TypeName = "float")]
|
||||
public double SimulationMaxVelocity { get; set; }
|
||||
|
||||
[Column("SimulationMaxAngularVelocity", TypeName = "float")]
|
||||
public double SimulationMaxAngularVelocity { get; set; }
|
||||
|
||||
[Column("SimulationAcceleration", TypeName = "float")]
|
||||
public double SimulationAcceleration { get; set; }
|
||||
|
||||
[Column("SimulationDeceleration", TypeName = "float")]
|
||||
public double SimulationDeceleration { get; set; }
|
||||
|
||||
[Column("CreatedAt", TypeName = "datetime2")]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
[Column("UpdatedAt", TypeName = "datetime2")]
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
[Column("IsActive", TypeName = "bit")]
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
[Column("ConfigName", TypeName = "nvarchar(64)")]
|
||||
[MaxLength(100)]
|
||||
public string ConfigName { get; set; }
|
||||
|
||||
[Column("Description", TypeName = "ntext")]
|
||||
[MaxLength(500)]
|
||||
public string Description { get; set; }
|
||||
}
|
||||
70
RobotApp/Data/RobotVDA5050Config.cs
Normal file
70
RobotApp/Data/RobotVDA5050Config.cs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
using RobotApp.Common.Shares.Enums;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace RobotApp.Data;
|
||||
|
||||
#nullable disable
|
||||
|
||||
[Table("RobotVDA5050Config")]
|
||||
public class RobotVDA5050Config
|
||||
{
|
||||
[Column("Id", TypeName = "uniqueidentifier")]
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Key]
|
||||
[Required]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Column("SerialNumber", TypeName = "nvarchar(64)")]
|
||||
[MaxLength(50)]
|
||||
public string SerialNumber { get; set; }
|
||||
|
||||
[Column("VDA5050_HostServer", TypeName = "nvarchar(64)")]
|
||||
[MaxLength(100)]
|
||||
public string VDA5050HostServer { get; set; }
|
||||
|
||||
[Column("VDA5050_Port", TypeName = "int")]
|
||||
public int VDA5050Port { get; set; } = 1883;
|
||||
|
||||
[Column("VDA5050_UserName", TypeName = "nvarchar(64)")]
|
||||
[MaxLength(50)]
|
||||
public string VDA5050UserName { get; set; }
|
||||
|
||||
[Column("VDA5050_Password", TypeName = "nvarchar(64)")]
|
||||
[MaxLength(50)]
|
||||
public string VDA5050Password { get; set; }
|
||||
|
||||
[Column("VDA5050_Manufacturer", TypeName = "nvarchar(64)")]
|
||||
[MaxLength(50)]
|
||||
public string VDA5050Manufacturer { get; set; }
|
||||
|
||||
[Column("VDA5050_Version", TypeName = "nvarchar(64)")]
|
||||
[MaxLength(20)]
|
||||
public string VDA5050Version { get; set; }
|
||||
|
||||
[Column("VDA5050_PublishRepeat", TypeName = "int")]
|
||||
public int VDA5050PublishRepeat { get; set; }
|
||||
|
||||
[Column("VDA5050_EnablePassword", TypeName = "bit")]
|
||||
public bool VDA5050EnablePassword { get; set; }
|
||||
|
||||
[Column("VDA5050_EnableTls", TypeName = "bit")]
|
||||
public bool VDA5050EnableTls { get; set; }
|
||||
|
||||
[Column("CreatedAt", TypeName = "datetime2")]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
[Column("UpdatedAt", TypeName = "datetime2")]
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
[Column("IsActive", TypeName = "bit")]
|
||||
public bool IsActive { get; set; } = true;
|
||||
|
||||
[Column("ConfigName", TypeName = "nvarchar(64)")]
|
||||
[MaxLength(100)]
|
||||
public string ConfigName { get; set; }
|
||||
|
||||
[Column("Description", TypeName = "ntext")]
|
||||
[MaxLength(500)]
|
||||
public string Description { get; set; }
|
||||
}
|
||||
|
|
@ -6,7 +6,6 @@ using RobotApp.Components;
|
|||
using RobotApp.Components.Account;
|
||||
using RobotApp.Data;
|
||||
using RobotApp.Services;
|
||||
using RobotApp.Services.Robot;
|
||||
using RobotApp.Services.Robot.Simulation;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
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;
|
||||
|
|
@ -9,28 +11,31 @@ namespace RobotApp.Services;
|
|||
public class MQTTClient : IAsyncDisposable
|
||||
{
|
||||
private readonly MqttClientFactory MqttClientFactory;
|
||||
private readonly MqttClientOptions MqttClientOptions;
|
||||
private MqttClientOptions MqttClientOptions;
|
||||
private readonly MqttClientSubscribeOptions MqttClientSubscribeOptions;
|
||||
private IMqttClient? MqttClient;
|
||||
|
||||
private readonly Logger<MQTTClient> Logger;
|
||||
private readonly VDA5050Setting VDA5050Setting;
|
||||
private bool IsReconnecing;
|
||||
private readonly string ClientId;
|
||||
private readonly SemaphoreSlim ReconnectionSemaphore = new(1, 1);
|
||||
private volatile bool IsDisposed;
|
||||
|
||||
public event Action<string>? OrderChanged;
|
||||
public event Action<string>? InstanceActionsChanged;
|
||||
public bool IsConnected => !IsReconnecing && MqttClient is not null && MqttClient.IsConnected;
|
||||
public bool IsConnected => !IsDisposed && MqttClient is not null && MqttClient.IsConnected;
|
||||
|
||||
public MQTTClient(string clientId, VDA5050Setting setting, Logger<MQTTClient> logger)
|
||||
{
|
||||
VDA5050Setting = setting;
|
||||
ClientId = clientId;
|
||||
Logger = logger;
|
||||
|
||||
|
||||
MqttClientFactory = new MqttClientFactory();
|
||||
MqttClientOptions = MqttClientFactory.CreateClientOptionsBuilder()
|
||||
.WithTcpServer(setting.HostServer, setting.Port)
|
||||
.WithCredentials(setting.UserName, setting.Password)
|
||||
.WithClientId(clientId)
|
||||
.WithTcpServer(VDA5050Setting.HostServer, VDA5050Setting.Port)
|
||||
.WithClientId(ClientId)
|
||||
.WithCleanSession(true)
|
||||
.Build();
|
||||
MqttClientSubscribeOptions = MqttClientFactory.CreateSubscribeOptionsBuilder()
|
||||
|
|
@ -39,93 +44,231 @@ public class MQTTClient : IAsyncDisposable
|
|||
.Build();
|
||||
}
|
||||
|
||||
public async Task ConnectAsync(CancellationToken cancellationToken = default)
|
||||
private async Task OnDisconnected(MqttClientDisconnectedEventArgs args)
|
||||
{
|
||||
MqttClient = MqttClientFactory.CreateMqttClient();
|
||||
MqttClient.DisconnectedAsync += async delegate (MqttClientDisconnectedEventArgs args)
|
||||
{
|
||||
if (args.ClientWasConnected && !IsReconnecing)
|
||||
{
|
||||
IsReconnecing = true;
|
||||
Logger.Warning("Mất kết nối tới broker, đang cố gắng kết nối lại...");
|
||||
if (MqttClient.IsConnected) await MqttClient.DisconnectAsync();
|
||||
MqttClient.Dispose();
|
||||
if (IsDisposed || !args.ClientWasConnected) return;
|
||||
|
||||
await ConnectAsync();
|
||||
await SubscribeAsync();
|
||||
IsReconnecing = false;
|
||||
}
|
||||
};
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
if (!await ReconnectionSemaphore.WaitAsync(0))
|
||||
{
|
||||
Logger.Info("Reconnection đã đang được thực hiện bởi thread khác");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Logger.Warning("Mất kết nối tới broker, đang cố gắng kết nối lại...");
|
||||
|
||||
await CleanupCurrentClient();
|
||||
|
||||
await ReconnectWithRetry();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Lỗi trong quá trình reconnection: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReconnectionSemaphore.Release();
|
||||
}
|
||||
}
|
||||
private async Task CleanupCurrentClient()
|
||||
{
|
||||
if (MqttClient is not null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var connection = await MqttClient.ConnectAsync(MqttClientOptions, cancellationToken);
|
||||
if (connection.ResultCode != MqttClientConnectResultCode.Success || !MqttClient.IsConnected)
|
||||
Logger.Warning($"Không thể kết nối tới broker do: {connection.ReasonString}");
|
||||
else
|
||||
MqttClient.DisconnectedAsync -= OnDisconnected;
|
||||
MqttClient.ApplicationMessageReceivedAsync -= OnMessageReceived;
|
||||
|
||||
if (MqttClient.IsConnected)
|
||||
{
|
||||
Logger.Info("Kết nối tới broker thành công");
|
||||
break;
|
||||
await MqttClient.DisconnectAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Lỗi khi tạo MQTT client: {ex.Message}");
|
||||
Logger.Warning($"Lỗi khi cleanup client: {ex.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
MqttClient.Dispose();
|
||||
MqttClient = null;
|
||||
}
|
||||
await Task.Delay(3000, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ReconnectWithRetry()
|
||||
{
|
||||
const int maxRetries = 5;
|
||||
const int retryDelayMs = 3000;
|
||||
|
||||
for (int attempt = 1; attempt <= maxRetries && !IsDisposed; attempt++)
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger.Info($"Thử reconnect lần {attempt}/{maxRetries}");
|
||||
|
||||
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
|
||||
await ConnectAsync(cts.Token);
|
||||
|
||||
if (IsConnected)
|
||||
{
|
||||
await SubscribeAsync(cts.Token);
|
||||
Logger.Info("Reconnection thành công");
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
Logger.Warning($"Reconnect attempt {attempt} bị timeout");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Reconnect attempt {attempt} thất bại: {ex.Message}");
|
||||
}
|
||||
|
||||
if (attempt < maxRetries && !IsDisposed)
|
||||
{
|
||||
await Task.Delay(retryDelayMs * attempt);
|
||||
}
|
||||
}
|
||||
|
||||
Logger.Error("Không thể reconnect sau tất cả các attempts");
|
||||
}
|
||||
|
||||
public async Task ConnectAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (!IsDisposed)
|
||||
{
|
||||
BuildMqttClientOptions(VDA5050Setting.EnablePassword, VDA5050Setting.EnableTls);
|
||||
await CleanupCurrentClient();
|
||||
|
||||
MqttClient = MqttClientFactory.CreateMqttClient();
|
||||
MqttClient.DisconnectedAsync += OnDisconnected;
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
var connection = await MqttClient.ConnectAsync(MqttClientOptions, cancellationToken);
|
||||
if (connection.ResultCode != MqttClientConnectResultCode.Success || !MqttClient.IsConnected)
|
||||
Logger.Warning($"Không thể kết nối tới broker do: {connection.ReasonString}");
|
||||
else
|
||||
{
|
||||
Logger.Info("Kết nối tới broker thành công");
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Lỗi khi tạo MQTT client: {ex.Message}");
|
||||
}
|
||||
await Task.Delay(3000, cancellationToken);
|
||||
}
|
||||
}
|
||||
else throw new ObjectDisposedException(nameof(MQTTClient));
|
||||
}
|
||||
|
||||
private void BuildMqttClientOptions(bool enablePassword, bool enableTls)
|
||||
{
|
||||
var builder = MqttClientFactory.CreateClientOptionsBuilder()
|
||||
.WithTcpServer(VDA5050Setting.HostServer, VDA5050Setting.Port)
|
||||
.WithClientId(ClientId)
|
||||
.WithCleanSession(true);
|
||||
if (enablePassword)
|
||||
{
|
||||
builder.WithCredentials(VDA5050Setting.UserName, VDA5050Setting.Password);
|
||||
}
|
||||
|
||||
if (enableTls)
|
||||
{
|
||||
var tlsOptions = new MqttClientTlsOptionsBuilder()
|
||||
.UseTls(true)
|
||||
.WithSslProtocols(System.Security.Authentication.SslProtocols.Tls12)
|
||||
.WithCertificateValidationHandler(context =>
|
||||
{
|
||||
if (context.SslPolicyErrors != SslPolicyErrors.None)
|
||||
{
|
||||
Logger.Warning($"[TLS] Lỗi: {context.SslPolicyErrors}");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.Build();
|
||||
builder.WithTlsOptions(tlsOptions);
|
||||
}
|
||||
MqttClientOptions = builder.Build();
|
||||
}
|
||||
|
||||
private Task OnMessageReceived(MqttApplicationMessageReceivedEventArgs args)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (IsDisposed) return Task.CompletedTask;
|
||||
|
||||
var stringData = Encoding.UTF8.GetString(args.ApplicationMessage.Payload);
|
||||
VDA5050Topic topic = EnumExtensions.ToTopic(args.ApplicationMessage.Topic);
|
||||
|
||||
if (topic == VDA5050Topic.ORDER) OrderChanged?.Invoke(stringData);
|
||||
else if (topic == VDA5050Topic.INSTANTACTIONS) InstanceActionsChanged?.Invoke(stringData);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Lỗi khi xử lý message: {ex.Message}");
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task SubscribeAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (MqttClient is null) throw new Exception("Kết nối tới broker chưa được khởi tạo nhưng đã yêu cầu subscribe");
|
||||
if(!MqttClient.IsConnected) throw new Exception("Kết nối tới broker chưa thành công nhưng đã yêu cầu subscribe");
|
||||
|
||||
MqttClient.ApplicationMessageReceivedAsync += delegate (MqttApplicationMessageReceivedEventArgs args)
|
||||
if (!IsDisposed)
|
||||
{
|
||||
var stringData = Encoding.UTF8.GetString(args.ApplicationMessage.Payload);
|
||||
VDA5050Topic topic = EnumExtensions.ToTopic(args.ApplicationMessage.Topic);
|
||||
if (topic == VDA5050Topic.ORDER) OrderChanged?.Invoke(stringData);
|
||||
else if (topic == VDA5050Topic.INSTANTACTIONS) InstanceActionsChanged?.Invoke(stringData);
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
if (MqttClient is null) throw new Exception("Kết nối tới broker chưa được khởi tạo nhưng đã yêu cầu subscribe");
|
||||
if (!MqttClient.IsConnected) throw new Exception("Kết nối tới broker chưa thành công nhưng đã yêu cầu subscribe");
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
MqttClient.ApplicationMessageReceivedAsync -= OnMessageReceived;
|
||||
MqttClient.ApplicationMessageReceivedAsync += OnMessageReceived;
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
var response = await MqttClient.SubscribeAsync(MqttClientSubscribeOptions, cancellationToken);
|
||||
bool isSuccess = true;
|
||||
foreach (var item in response.Items)
|
||||
try
|
||||
{
|
||||
if (item.ResultCode == MqttClientSubscribeResultCode.GrantedQoS0 ||
|
||||
item.ResultCode == MqttClientSubscribeResultCode.GrantedQoS1 ||
|
||||
item.ResultCode == MqttClientSubscribeResultCode.GrantedQoS2)
|
||||
var response = await MqttClient.SubscribeAsync(MqttClientSubscribeOptions, cancellationToken);
|
||||
bool isSuccess = true;
|
||||
foreach (var item in response.Items)
|
||||
{
|
||||
Logger.Info($"Subscribe thành công cho topic: {item.TopicFilter.Topic} với QoS: {item.ResultCode}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Warning($"Subscribe thất bại cho topic: {item.TopicFilter.Topic}. Lý do: {response.ReasonString}");
|
||||
isSuccess = false;
|
||||
break;
|
||||
if (item.ResultCode == MqttClientSubscribeResultCode.GrantedQoS0 ||
|
||||
item.ResultCode == MqttClientSubscribeResultCode.GrantedQoS1 ||
|
||||
item.ResultCode == MqttClientSubscribeResultCode.GrantedQoS2)
|
||||
{
|
||||
Logger.Info($"Subscribe thành công cho topic: {item.TopicFilter.Topic} với QoS: {item.ResultCode}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Warning($"Subscribe thất bại cho topic: {item.TopicFilter.Topic}. Lý do: {response.ReasonString}");
|
||||
isSuccess = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isSuccess) break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Lỗi khi subscribe: {ex.Message}");
|
||||
}
|
||||
if (!cancellationToken.IsCancellationRequested && !IsDisposed)
|
||||
{
|
||||
await Task.Delay(3000, cancellationToken);
|
||||
}
|
||||
if (isSuccess) break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Lỗi khi subscribe: {ex.Message}");
|
||||
}
|
||||
await Task.Delay(3000, cancellationToken);
|
||||
}
|
||||
else throw new ObjectDisposedException(nameof(MQTTClient));
|
||||
}
|
||||
|
||||
public async Task<MessageResult> PublishAsync(string topic, string data)
|
||||
{
|
||||
if (IsDisposed) return new(false, "Client đã được disposed");
|
||||
var repeat = VDA5050Setting.PublishRepeat;
|
||||
while (repeat-- > 0)
|
||||
while (repeat-- > 0 && !IsDisposed)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -149,12 +292,17 @@ public class MQTTClient : IAsyncDisposable
|
|||
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
if (MqttClient is not null)
|
||||
if (IsDisposed) return;
|
||||
IsDisposed = true;
|
||||
await ReconnectionSemaphore.WaitAsync();
|
||||
try
|
||||
{
|
||||
if (MqttClient.IsConnected) await MqttClient.DisconnectAsync();
|
||||
MqttClient.Dispose();
|
||||
MqttClient = null;
|
||||
await CleanupCurrentClient();
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReconnectionSemaphore.Dispose();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
using RobotApp.Common.Shares.Enums;
|
||||
using RobotApp.Interfaces;
|
||||
using RobotApp.Services.Robot.Simulation;
|
||||
using RobotApp.VDA5050.State;
|
||||
|
||||
namespace RobotApp.Services.Robot;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ using System.Collections.Concurrent;
|
|||
|
||||
namespace RobotApp.Services.State;
|
||||
|
||||
public record RobotStateMachine(Logger<RobotStateMachine> Logger) : IDisposable
|
||||
public class RobotStateMachine(Logger<RobotStateMachine> Logger) : IDisposable
|
||||
{
|
||||
private readonly Lock StateLock = new();
|
||||
private readonly ConcurrentDictionary<Type, Dictionary<Enum, IRobotState>> StateRegistry = [];
|
||||
|
|
|
|||
Binary file not shown.
Loading…
Reference in New Issue
Block a user