109 lines
6.4 KiB
C#
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 [];
|
|
}
|
|
}
|
|
}
|