update
This commit is contained in:
parent
30732b4b9f
commit
e4e135e35f
|
|
@ -77,6 +77,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.ScrollToBottom = (element) => {
|
||||||
|
if (element) {
|
||||||
|
element.scrollTop = element.scrollHeight;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private DateTime DateLog = DateTime.Today;
|
private DateTime DateLog = DateTime.Today;
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
.log-level {
|
.log-level {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 46px;
|
width: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.log-head {
|
.log-head {
|
||||||
|
|
|
||||||
|
|
@ -560,10 +560,14 @@ public partial class RobotConfigManager
|
||||||
|
|
||||||
private async Task LoadConfig()
|
private async Task LoadConfig()
|
||||||
{
|
{
|
||||||
|
IsLoading = true;
|
||||||
|
StateHasChanged();
|
||||||
var response = await (await Http.PostAsync($"api/RobotConfigs/load", null)).Content.ReadFromJsonAsync<MessageResult>();
|
var response = await (await Http.PostAsync($"api/RobotConfigs/load", null)).Content.ReadFromJsonAsync<MessageResult>();
|
||||||
if (response is null) Snackbar.Add("Failed to load config", Severity.Warning);
|
if (response is null) Snackbar.Add("Failed to load config", Severity.Warning);
|
||||||
else if (!response.IsSuccess) Snackbar.Add(response.Message ?? "Failed to load config", Severity.Warning);
|
else if (!response.IsSuccess) Snackbar.Add(response.Message ?? "Failed to load config", Severity.Warning);
|
||||||
else Snackbar.Add("Config loaded", Severity.Success);
|
else Snackbar.Add("Config loaded", Severity.Success);
|
||||||
|
|
||||||
|
IsLoading = false;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -147,11 +147,11 @@ public class MQTTClient : IAsyncDisposable
|
||||||
|
|
||||||
MqttClient = MqttClientFactory.CreateMqttClient();
|
MqttClient = MqttClientFactory.CreateMqttClient();
|
||||||
|
|
||||||
//MqttClient.ApplicationMessageReceivedAsync -= OnMessageReceived;
|
MqttClient.ApplicationMessageReceivedAsync -= OnMessageReceived;
|
||||||
MqttClient.ApplicationMessageReceivedAsync += OnMessageReceived;
|
MqttClient.ApplicationMessageReceivedAsync += OnMessageReceived;
|
||||||
//MqttClient.DisconnectedAsync -= OnDisconnected;
|
MqttClient.DisconnectedAsync -= OnDisconnected;
|
||||||
MqttClient.DisconnectedAsync += OnDisconnected;
|
MqttClient.DisconnectedAsync += OnDisconnected;
|
||||||
while (!cancellationToken.IsCancellationRequested)
|
while (!cancellationToken.IsCancellationRequested && !IsDisposed)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -168,7 +168,11 @@ public class MQTTClient : IAsyncDisposable
|
||||||
{
|
{
|
||||||
Logger.Error($"Lỗi khi tạo MQTT client: {ex.Message}");
|
Logger.Error($"Lỗi khi tạo MQTT client: {ex.Message}");
|
||||||
}
|
}
|
||||||
await Task.Delay(3000, cancellationToken);
|
try
|
||||||
|
{
|
||||||
|
await Task.Delay(3000, cancellationToken);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else throw new ObjectDisposedException(nameof(MQTTClient));
|
else throw new ObjectDisposedException(nameof(MQTTClient));
|
||||||
|
|
@ -219,10 +223,10 @@ public class MQTTClient : IAsyncDisposable
|
||||||
var tlsOptions = new MqttClientTlsOptionsBuilder()
|
var tlsOptions = new MqttClientTlsOptionsBuilder()
|
||||||
.UseTls(true)
|
.UseTls(true)
|
||||||
.WithSslProtocols(System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls13)
|
.WithSslProtocols(System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls13)
|
||||||
//.WithCertificateValidationHandler(ValidateCertificates)
|
.WithCertificateValidationHandler(ValidateCertificates)
|
||||||
.WithClientCertificatesProvider(new MQTTClientCertificatesProvider(VDA5050Setting.CerFile, VDA5050Setting.KeyFile))
|
.WithClientCertificatesProvider(new MQTTClientCertificatesProvider(VDA5050Setting.CerFile, VDA5050Setting.KeyFile))
|
||||||
.Build();
|
.Build();
|
||||||
builder = builder.WithTlsOptions(tlsOptions);
|
builder = builder.WithTlsOptions(tlsOptions);
|
||||||
}
|
}
|
||||||
MqttClientOptions = builder.Build();
|
MqttClientOptions = builder.Build();
|
||||||
}
|
}
|
||||||
|
|
@ -251,42 +255,42 @@ public class MQTTClient : IAsyncDisposable
|
||||||
{
|
{
|
||||||
//if (!IsDisposed)
|
//if (!IsDisposed)
|
||||||
//{
|
//{
|
||||||
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 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");
|
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)
|
while (!cancellationToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
try
|
var response = await MqttClient.SubscribeAsync(MqttClientSubscribeOptions, cancellationToken);
|
||||||
|
bool isSuccess = true;
|
||||||
|
foreach (var item in response.Items)
|
||||||
{
|
{
|
||||||
var response = await MqttClient.SubscribeAsync(MqttClientSubscribeOptions, cancellationToken);
|
if (item.ResultCode == MqttClientSubscribeResultCode.GrantedQoS0 ||
|
||||||
bool isSuccess = true;
|
item.ResultCode == MqttClientSubscribeResultCode.GrantedQoS1 ||
|
||||||
foreach (var item in response.Items)
|
item.ResultCode == MqttClientSubscribeResultCode.GrantedQoS2)
|
||||||
{
|
{
|
||||||
if (item.ResultCode == MqttClientSubscribeResultCode.GrantedQoS0 ||
|
Logger.Info($"Subscribe thành công cho topic: {item.TopicFilter.Topic} với QoS: {item.ResultCode}");
|
||||||
item.ResultCode == MqttClientSubscribeResultCode.GrantedQoS1 ||
|
}
|
||||||
item.ResultCode == MqttClientSubscribeResultCode.GrantedQoS2)
|
else
|
||||||
{
|
{
|
||||||
Logger.Info($"Subscribe thành công cho topic: {item.TopicFilter.Topic} với QoS: {item.ResultCode}");
|
Logger.Warning($"Subscribe thất bại cho topic: {item.TopicFilter.Topic}. Lý do: {response.ReasonString}");
|
||||||
}
|
isSuccess = false;
|
||||||
else
|
break;
|
||||||
{
|
|
||||||
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}");
|
||||||
|
}
|
||||||
|
if (!cancellationToken.IsCancellationRequested && !IsDisposed)
|
||||||
|
{
|
||||||
|
await Task.Delay(3000, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
//}
|
//}
|
||||||
//else throw new ObjectDisposedException(nameof(MQTTClient));
|
//else throw new ObjectDisposedException(nameof(MQTTClient));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,8 +57,8 @@ public class RobotConfiguration(IServiceProvider ServiceProvider, Logger<RobotCo
|
||||||
if (IsReady)
|
if (IsReady)
|
||||||
{
|
{
|
||||||
var robotConnection = scope.ServiceProvider.GetRequiredService<RobotConnection>();
|
var robotConnection = scope.ServiceProvider.GetRequiredService<RobotConnection>();
|
||||||
await robotConnection.StopConnection();
|
|
||||||
robotConnection.StartConnection();
|
robotConnection.StartConnection();
|
||||||
|
await Task.Delay(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else throw new Exception("Chưa có cấu hình VDA5050.");
|
else throw new Exception("Chưa có cấu hình VDA5050.");
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using RobotApp.VDA5050;
|
||||||
using RobotApp.VDA5050.InstantAction;
|
using RobotApp.VDA5050.InstantAction;
|
||||||
using RobotApp.VDA5050.Order;
|
using RobotApp.VDA5050.Order;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace RobotApp.Services.Robot;
|
namespace RobotApp.Services.Robot;
|
||||||
|
|
||||||
|
|
@ -10,12 +11,13 @@ public class RobotConnection(RobotConfiguration RobotConfiguration,
|
||||||
Logger<RobotConnection> Logger,
|
Logger<RobotConnection> Logger,
|
||||||
Logger<MQTTClient> MQTTClientLogger)
|
Logger<MQTTClient> MQTTClientLogger)
|
||||||
{
|
{
|
||||||
private readonly VDA5050Setting VDA5050Setting = RobotConfiguration.VDA5050Setting;
|
|
||||||
private MQTTClient? MqttClient;
|
private MQTTClient? MqttClient;
|
||||||
|
|
||||||
public bool IsConnected => MqttClient is not null && MqttClient.IsConnected;
|
public bool IsConnected => MqttClient is not null && MqttClient.IsConnected;
|
||||||
public event Action<OrderMsg>? OrderUpdated;
|
public event Action<OrderMsg>? OrderUpdated;
|
||||||
public event Action<InstantActionsMsg>? ActionUpdated;
|
public event Action<InstantActionsMsg>? ActionUpdated;
|
||||||
|
private readonly SemaphoreSlim _connectionSemaphore = new(1, 1);
|
||||||
|
private CancellationTokenSource? _connectionCancel;
|
||||||
|
|
||||||
|
|
||||||
private void OrderChanged(string data)
|
private void OrderChanged(string data)
|
||||||
|
|
@ -50,7 +52,7 @@ public class RobotConnection(RobotConfiguration RobotConfiguration,
|
||||||
|
|
||||||
public async Task<MessageResult> Publish(string topic, string data)
|
public async Task<MessageResult> Publish(string topic, string data)
|
||||||
{
|
{
|
||||||
if (MqttClient is not null && MqttClient.IsConnected) return await MqttClient.PublishAsync($"{VDA5050Setting.TopicPrefix}/{VDA5050Setting.Manufacturer}/{RobotConfiguration.SerialNumber}/{topic}", data);
|
if (MqttClient is not null && MqttClient.IsConnected) return await MqttClient.PublishAsync($"{RobotConfiguration.VDA5050Setting.TopicPrefix}/{RobotConfiguration.VDA5050Setting.Manufacturer}/{RobotConfiguration.SerialNumber}/{topic}", data);
|
||||||
return new(false, "Chưa có kết nối tới broker");
|
return new(false, "Chưa có kết nối tới broker");
|
||||||
}
|
}
|
||||||
public void StartConnection()
|
public void StartConnection()
|
||||||
|
|
@ -58,16 +60,29 @@ public class RobotConnection(RobotConfiguration RobotConfiguration,
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await StartConnectionAsync(CancellationToken.None);
|
await StartConnectionAsync(CancellationToken.None);
|
||||||
Logger.Info("Robot đã kết nối tới Fleet Manager.");
|
if(IsConnected)Logger.Info("Robot đã kết nối tới Fleet Manager.");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
public async Task StartConnectionAsync(CancellationToken cancellationToken)
|
public async Task StartConnectionAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
MqttClient = new MQTTClient(RobotConfiguration.SerialNumber, VDA5050Setting, MQTTClientLogger);
|
try
|
||||||
MqttClient.OrderChanged += OrderChanged;
|
{
|
||||||
MqttClient.InstanceActionsChanged += InstanceActionsChanged;
|
await StopConnection();
|
||||||
await MqttClient.ConnectAsync(cancellationToken);
|
_connectionCancel?.Cancel();
|
||||||
await MqttClient.SubscribeAsync(cancellationToken);
|
if (_connectionSemaphore.Wait(1000, cancellationToken))
|
||||||
|
{
|
||||||
|
_connectionCancel = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
|
||||||
|
MqttClient = new MQTTClient(RobotConfiguration.SerialNumber, RobotConfiguration.VDA5050Setting, MQTTClientLogger);
|
||||||
|
MqttClient.OrderChanged += OrderChanged;
|
||||||
|
MqttClient.InstanceActionsChanged += InstanceActionsChanged;
|
||||||
|
await MqttClient.ConnectAsync(_connectionCancel.Token);
|
||||||
|
if(MqttClient is not null) await MqttClient.SubscribeAsync(_connectionCancel.Token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_connectionSemaphore.Release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task StopConnection()
|
public async Task StopConnection()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user