RobotNet/RobotNet.RobotManager/Services/OpenACS/TrafficACS.cs
2025-10-15 15:15:53 +07:00

109 lines
6.4 KiB
C#

using NLog.Targets;
using RobotNet.MapShares.Dtos;
using RobotNet.RobotShares.OpenACS;
using RobotNet.Shares;
using System.Text.Json;
namespace RobotNet.RobotManager.Services.OpenACS;
public class TrafficACS(OpenACSManager OpenACSManager, IConfiguration Configuration, LoggerController<TrafficACS> Logger)
{
public bool Enable => OpenACSManager.TrafficEnable;
private readonly double TrafficCheckingDistanceMin = Configuration.GetValue("TrafficConfig:CheckingDistanceMin", 3);
public readonly double DeviationDistance = Configuration.GetValue("TrafficConfig:DeviationDistance", 0.5);
private static readonly JsonSerializerOptions jsonSerializeOptions = new() {
WriteIndented = true,
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
public async Task<MessageResult<bool>> RequestIn(string robotId, string zoneId)
{
try
{
if (!OpenACSManager.TrafficEnable) return new(true, "Kết nối với hệ thống traffic ACS không được bật") { Data = true };
using var HttpClient = new HttpClient() { Timeout = TimeSpan.FromSeconds(15) };
var model = new TrafficACSRequestV2(robotId, zoneId, TrafficRequestType.IN.ToInOutString());
var response = await (await HttpClient.PostAsJsonAsync(OpenACSManager.TrafficURL, model)).Content.ReadFromJsonAsync<TrafficACSResponseV2>() ??
throw new OpenACSException("Lỗi giao tiếp với hệ thống traffic ACS");
if (response.Body.AgvId != robotId) throw new OpenACSException($"Dữ liệu hệ thống traffic ACS agv_id trả về {response.Body.AgvId} không trùng với dữ liệu gửi đi {robotId}");
if (response.Body.TrafficZoneId != zoneId) throw new OpenACSException($"Dữ liệu hệ thống traffic ACS traffic_zone_id trả về {response.Body.TrafficZoneId} không trùng với dữ liệu gửi đi {zoneId}");
if (response.Body.InOut != TrafficRequestType.IN.ToInOutString()) throw new OpenACSException($"Dữ liệu hệ thống traffic ACS inout trả về {response.Body.InOut} không trùng với dữ liệu gửi đi in");
Logger.Info($"{robotId} yêu cầu vào traffic zone {zoneId} \nRequest: {JsonSerializer.Serialize(model, jsonSerializeOptions)}\n trả về kết quả: {JsonSerializer.Serialize(response, jsonSerializeOptions)}");
return new(true, "Yêu cầu vào traffic zone thành công") { Data = response.Body.Result == TrafficACSResult.GO };
}
catch (OpenACSException ex)
{
Logger.Warning($"{robotId} request in xảy ra lỗi: {ex.Message}");
return new(false, ex.Message);
}
catch (Exception ex)
{
Logger.Warning($"{robotId} request In xảy ra lỗi: {ex.Message}");
return new(false, "Lỗi giao tiếp với hệ thống traffic ACS");
}
}
public async Task<MessageResult<bool>> RequestOut(string robotId, string zoneId)
{
try
{
if (!OpenACSManager.TrafficEnable) return new(true, "Kết nối với hệ thống traffic ACS không được bật") { Data = true};
using var HttpClient = new HttpClient() { Timeout = TimeSpan.FromSeconds(15) };
var model = new TrafficACSRequestV2(robotId, zoneId, TrafficRequestType.OUT.ToInOutString());
var response = await (await HttpClient.PostAsJsonAsync(OpenACSManager.TrafficURL, model)).Content.ReadFromJsonAsync<TrafficACSResponseV2>() ??
throw new OpenACSException("Lỗi giao tiếp với hệ thống traffic ACS");
if (response.Body.AgvId != robotId) throw new OpenACSException($"Dữ liệu hệ thống traffic ACS agv_id trả về {response.Body.AgvId} không trùng với dữ liệu gửi đi {robotId}");
if (response.Body.TrafficZoneId != zoneId) throw new OpenACSException($"Dữ liệu hệ thống traffic ACS traffic_zone_id trả về {response.Body.TrafficZoneId} không trùng với dữ liệu gửi đi {zoneId}");
if (response.Body.InOut != TrafficRequestType.OUT.ToInOutString()) throw new OpenACSException($"Dữ liệu hệ thống traffic ACS inout trả về {response.Body.InOut} không trùng với dữ liệu gửi đi out");
Logger.Info($"{robotId} yêu cầu ra khỏi traffic zone {zoneId} \nRequest: {JsonSerializer.Serialize(model, jsonSerializeOptions)}\n trả về kết quả: {JsonSerializer.Serialize(response, jsonSerializeOptions)}");
return new(true, "Yêu cầu ra khỏi traffic zone thành công") { Data = response.Body.Result == TrafficACSResult.GO };
}
catch (OpenACSException ex)
{
Logger.Warning($"{robotId} request out xảy ra lỗi: {ex.Message}");
return new(false, ex.Message);
}
catch (Exception ex)
{
Logger.Warning($"{robotId} request Out xảy ra lỗi: {ex.Message}");
return new(false, "Lỗi giao tiếp với hệ thống traffic ACS");
}
}
public Dictionary<Guid, ZoneDto[]> GetZones(Guid inNodeId, NodeDto[] nodes, Dictionary<Guid, ZoneDto[]> zones)
{
int inNodeIndex = Array.FindIndex(nodes, n => n.Id == inNodeId);
if (inNodeId == Guid.Empty || (inNodeIndex != -1 && inNodeIndex < nodes.Length - 1))
{
List<NodeDto> baseNodes = [];
List<ZoneDto> basezones = [];
double distance = 0;
int index = inNodeIndex != -1 ? inNodeIndex + 1 : 1;
for (; index < nodes.Length; index++)
{
baseNodes.Add(nodes[index]);
distance += Math.Sqrt(Math.Pow(nodes[index].X - nodes[index - 1].X, 2) + Math.Pow(nodes[index].Y - nodes[index - 1].Y, 2));
if (distance > TrafficCheckingDistanceMin) break;
}
Dictionary<Guid, ZoneDto[]> nodeZones = [];
foreach (var node in baseNodes)
{
if (zones.TryGetValue(node.Id, out ZoneDto[]? zone) && zone is not null && zone.Length > 0) nodeZones.Add(node.Id, zone);
else nodeZones.Add(node.Id, []);
}
return nodeZones;
}
else if (inNodeIndex == nodes.Length - 1) return [];
else
{
Logger.Warning($"Không tìm thấy node {inNodeId} trong danh sách nodes hoặc node này.");
return [];
}
}
}