From 126faa114d29a6cd358394d791aea43af3827508 Mon Sep 17 00:00:00 2001 From: SoulStar Date: Thu, 17 Oct 2024 09:13:08 +0800 Subject: [PATCH] =?UTF-8?q?add=20-=20=E6=89=8B=E5=8A=A8=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=E5=8F=AF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SlnMesnac.Business/base/BaseAGVBusiness.cs | 20 +- .../base/BaseStateRefreshBusiness.cs | 33 ++- .../base/BaseTaskInfoBusiness.cs | 2 +- SlnMesnac.Business/base/VisionBusiness.cs | 25 ++- SlnMesnac.Config/AGVConfig.cs | 2 + .../AGVRobotAtrributeEntity.cs | 2 +- .../service/Impl/AirportTaskServiceImpl.cs | 10 +- SlnMesnac.TouchSocket/AirPorthttpClient.cs | 208 ++++++++++++------ SlnMesnac.WPF/MainWindow.xaml | 22 +- SlnMesnac.WPF/MainWindow.xaml.cs | 15 ++ .../ViewModel/MainWindowViewModel.cs | 125 ++++++++++- SlnMesnac.WPF/appsettings.json | 30 ++- 12 files changed, 392 insertions(+), 102 deletions(-) diff --git a/SlnMesnac.Business/base/BaseAGVBusiness.cs b/SlnMesnac.Business/base/BaseAGVBusiness.cs index 0e4d218..7b4b340 100644 --- a/SlnMesnac.Business/base/BaseAGVBusiness.cs +++ b/SlnMesnac.Business/base/BaseAGVBusiness.cs @@ -117,7 +117,7 @@ namespace SlnMesnac.Business.@base { return false; } - if(agvState.agvworkstate == "忙碌" || agvState.agvalarmstate == "正常") + if(agvState.agvworkstate != "待机") { var response = _airPorthttpClient.AGVOperationalTaskRequest(new AGVRequestOperationalTaskEntity() { @@ -138,7 +138,7 @@ namespace SlnMesnac.Business.@base return false; } } - else if(agvState.agvworkstate == "空闲") + else if(agvState.agvworkstate == "待机") { _logger.LogError($"AGV {agvState.agvno} 现在无任务"); return false; @@ -204,5 +204,21 @@ namespace SlnMesnac.Business.@base return _AGVMapPointService.DeleteAndAddAgvMapPoint(list); } + + public static string AGVTaskStatusSelect(int no) + { + switch (no) + { + case 0: return "已终止"; + case 1: return "待执行"; + case 2: return "正在执行"; + case 3: return "已完成"; + case 4: return "已取消"; + case 5: return "已暂停"; + case 6: return "匹配中"; + case 7: return "核验中"; + default: return "未知代码"; + } + } } } diff --git a/SlnMesnac.Business/base/BaseStateRefreshBusiness.cs b/SlnMesnac.Business/base/BaseStateRefreshBusiness.cs index 791999f..1436f70 100644 --- a/SlnMesnac.Business/base/BaseStateRefreshBusiness.cs +++ b/SlnMesnac.Business/base/BaseStateRefreshBusiness.cs @@ -25,7 +25,7 @@ namespace SlnMesnac.Business.@base _AGVStateService = agvService; _airPorthttpClient = airPorthttpClient; _aGVSettingService = aGVSettingService; - updateTimer = new System.Timers.Timer(2000); + updateTimer = new System.Timers.Timer(1000); updateTimer.Elapsed += async (sender, e) => await TimerUpadteAGVState(); } @@ -71,9 +71,7 @@ namespace SlnMesnac.Business.@base public async Task TimerUpadteAGVState() { - bool result; - result = await UpdateALLAGVStateByResposne(); - if (!result) + if (!await UpdateALLAGVStateByResposne()) { _logger.LogError("AGV状态更新失败"); } @@ -101,7 +99,7 @@ namespace SlnMesnac.Business.@base agvno = entity.Guid, agvalarmstate = entity.AgvMoveStatus != 6 ? "正常" : "异常", agvtype = _aGVSettingService.GetAgvSettingByID(entity.Guid), - agvworkstate = entity.AgvMoveStatus == 1 ? "空闲" : "忙碌", + agvworkstate = AGVStatusSelect(entity.AgvMoveStatus), refreshtime = DateTime.Now, taskno = entity.TaskID, }; @@ -115,6 +113,31 @@ namespace SlnMesnac.Business.@base return false; } } + + /// + /// AGV运动状态对照 + /// + /// + /// + public static string AGVStatusSelect(int no) + { + switch (no) + { + case 0: return "暂无信息"; + case 1: return "待机"; + case 2: return "执行任务"; + case 3: return "充电中"; + case 4: return "暂停"; + case 5: return "急停"; + case 6: return "异常"; + case 7: return "建图中"; + case 8: return "等待"; + case 9: return "调度控制"; + case 51: return "同步"; + case 52: return "脱机"; + default: return "未知代码"; + } + } } public enum TimerControl diff --git a/SlnMesnac.Business/base/BaseTaskInfoBusiness.cs b/SlnMesnac.Business/base/BaseTaskInfoBusiness.cs index 3521149..731ef01 100644 --- a/SlnMesnac.Business/base/BaseTaskInfoBusiness.cs +++ b/SlnMesnac.Business/base/BaseTaskInfoBusiness.cs @@ -105,7 +105,7 @@ namespace SlnMesnac.Business.@base { //获取任务列表 List Task = _Taskservice.GetAGVTaskInfos(); - if (Task != null || Task.Count > 0) + if (Task != null && Task.Count > 0) { //更新前端 _RefreshLogMessageAction?.Invoke("任务数量:" + Task.Count); diff --git a/SlnMesnac.Business/base/VisionBusiness.cs b/SlnMesnac.Business/base/VisionBusiness.cs index bbd1ecd..e7904eb 100644 --- a/SlnMesnac.Business/base/VisionBusiness.cs +++ b/SlnMesnac.Business/base/VisionBusiness.cs @@ -15,7 +15,6 @@ namespace SlnMesnac.Business.@base { private ILogger _logger; private static VisionBusiness instance; - private TcpServer _tcpServer; public VisionBusiness(ILogger logger, TcpServer tcpServer) @@ -58,6 +57,8 @@ namespace SlnMesnac.Business.@base public void RequestVisionReplace(string port) { _tcpServer.SendStackOverRequestVisionSysReplace(port); + VDCount = 1; + VACount = 1; } /// @@ -101,8 +102,9 @@ namespace SlnMesnac.Business.@base } } - int VCount = 1; - + int VDCount = 1; + int VACount = 0; + bool Vjudge = true; /// /// 接受码垛结果 /// @@ -115,29 +117,38 @@ namespace SlnMesnac.Business.@base _logger.LogInformation($"视觉系统一次码垛结束,码垛完成"); //上位机回复收到码垛结果 _tcpServer.SendReplayStackResult(id); - if (VCount < 5) //这里写是否继续下一次码垛的判断条件 + if ((VDCount < 4 && Vjudge == true) || (VACount < 3 && Vjudge == false)) //这里写是否继续下一次码垛的判断条件 { //如果码垛没结束继续发下一次的码垛信号 - if (true) //这里写向哪个机器人码垛的判断条件 + if (Vjudge) //这里写向哪个机器人码垛的判断条件 { //发送向搬运机器人(AGVDeliver)码垛的信号 RequestVisionStartWork(StackState.AGVNoPositioning, id); _logger.LogInformation("下一次码垛开始,方向:搬运机器人"); + VDCount++; + if (VDCount >= 4) + { + Vjudge = false; + + } } else { //发送向复合机器人(AMR)码垛的信号 RequestVisionStartWork(StackState.AMRNoPositioning, id); _logger.LogInformation("下一次码垛开始,方向:复合机器人"); + VACount++; + if (VACount >= 3) + { + Vjudge = true; + } } - VCount++; } else { //如果码垛结束就请求复位 RequestVisionReplace(id); _logger.LogInformation("本次码垛结束,请求复位"); - VCount = 1; } } else if (entity.DataBytes[0] == 0x01) diff --git a/SlnMesnac.Config/AGVConfig.cs b/SlnMesnac.Config/AGVConfig.cs index 6d94856..8734a08 100644 --- a/SlnMesnac.Config/AGVConfig.cs +++ b/SlnMesnac.Config/AGVConfig.cs @@ -9,5 +9,7 @@ namespace SlnMesnac.Config public string AGVGUID { get; set; } public string AGVName { get; set; } + + public string AGVIp { get; set; } } } diff --git a/SlnMesnac.Model/AirportApiEntity/AGVRobotAtrributeEntity.cs b/SlnMesnac.Model/AirportApiEntity/AGVRobotAtrributeEntity.cs index 53e02d4..d2fe666 100644 --- a/SlnMesnac.Model/AirportApiEntity/AGVRobotAtrributeEntity.cs +++ b/SlnMesnac.Model/AirportApiEntity/AGVRobotAtrributeEntity.cs @@ -50,7 +50,7 @@ namespace SlnMesnac.Model.AirportApiEntity /// /// 错误 /// - public List error { get; set; } + public List? error { get; set; } } diff --git a/SlnMesnac.Repository/service/Impl/AirportTaskServiceImpl.cs b/SlnMesnac.Repository/service/Impl/AirportTaskServiceImpl.cs index e1552cf..d8b0000 100644 --- a/SlnMesnac.Repository/service/Impl/AirportTaskServiceImpl.cs +++ b/SlnMesnac.Repository/service/Impl/AirportTaskServiceImpl.cs @@ -51,8 +51,9 @@ namespace SlnMesnac.Repository.service.Impl List taskInfos = null; try { - string sql = "SELECT id,ConveyorNo,TaskNo,FlightNo,DeliverAGVNo, MAX(StartTime) as StartTime,TaskState, TotalCount ,LoadCount FROM AirportTask group by ConveyorNo "; - taskInfos = base._rep.AsTenant().GetConnection("AGV").Ado.SqlQuery(sql); + //string sql = "SELECT id,ConveyorNo,TaskNo,FlightNo,DeliverAGVNo, MAX(StartTime) as StartTime,TaskState, TotalCount ,LoadCount FROM AirportTask group by ConveyorNo "; + //taskInfos = base._rep.AsTenant().GetConnection("AGV").Ado.SqlQuery(sql); + taskInfos = _rep.GetList(); } catch (Exception ex) { @@ -70,8 +71,9 @@ namespace SlnMesnac.Repository.service.Impl List taskInfos = null; try { - string sql = "select *from ( SELECT id, ConveyorNo,TaskNo,FlightNo,DeliverAGVNo, amragvno,MAX(StartTime) as StartTime,TaskState, TotalCount ,LoadCount FROM AirportTask group by ConveyorNo )"; - taskInfos = base._rep.AsTenant().GetConnection("AGV").Ado.SqlQuery(sql); + //string sql = "select *from ( SELECT id, ConveyorNo,TaskNo,FlightNo,DeliverAGVNo, amragvno,MAX(StartTime) as StartTime,TaskState, TotalCount ,LoadCount FROM AirportTask group by ConveyorNo )"; + //taskInfos = base._rep.AsTenant().GetConnection("AGV").Ado.SqlQuery(sql); + taskInfos = _rep.GetList(); } catch (Exception ex) { diff --git a/SlnMesnac.TouchSocket/AirPorthttpClient.cs b/SlnMesnac.TouchSocket/AirPorthttpClient.cs index 6763f44..10cedf9 100644 --- a/SlnMesnac.TouchSocket/AirPorthttpClient.cs +++ b/SlnMesnac.TouchSocket/AirPorthttpClient.cs @@ -20,6 +20,9 @@ using Serilog.Events; using Microsoft.Extensions.Logging; using System.Net.Http; using static System.Net.WebRequestMethods; +using TouchSocket.Http; +using HttpClient = System.Net.Http.HttpClient; +using HttpMethod = System.Net.Http.HttpMethod; namespace SlnMesnac.TouchSocket { @@ -27,6 +30,8 @@ namespace SlnMesnac.TouchSocket { private readonly AppConfig _appConfig; private readonly ILogger _logger; + private System.Net.Http.HttpClient _httpClient; + public string Url = "http://192.168.10.199:5102"; public AirPorthttpClient(AppConfig appConfig, ILogger logger) { @@ -34,51 +39,67 @@ namespace SlnMesnac.TouchSocket _logger = logger; } - public static WebApiClient AirportAGVClient; - - private WebApiClient CreateWebApiClient(string IpHost) - { - var client = new WebApiClient(); - try - { - _logger.LogInformation("正在连接:" + IpHost); - client.Connect(IpHost); - _logger.LogInformation(IpHost + "连接成功"); - return client; - } - catch (Exception ex) - { - _logger.LogError("ERROR: " + ex.Message); - return null; - } - } + //private WebApiClient CreateWebApiClient(string IpHost) + //{ + // var client = new WebApiClient(); + // try + // { + // _logger.LogInformation("正在连接:" + IpHost); + // client.Connect(IpHost); + // _logger.LogInformation(IpHost + "连接成功"); + // return client; + // } + // catch (Exception ex) + // { + // _logger.LogError("ERROR: " + ex.Message); + // return null; + // } + //} public void init() { - try - { - AirportAGVClient = CreateWebApiClient(_appConfig.AGVIpConfig); - } - catch (Exception ex) - { - _logger.LogError("ERROR: " + ex.Message); - } + _httpClient = new HttpClient(); } - /// - /// 获取到的JToken类型转换为实体类 - /// - /// - /// - /// - public AGVResponseEntity JTokenToEntity(JToken value) where T : class + ///// + ///// 获取到的JToken类型转换为实体类 + ///// + ///// + ///// + ///// + //public AGVResponseEntity JTokenToEntity(JToken value) where T : class + //{ + // if (value == null) + // { + // _logger.LogError("返回空数据!"); + // return null; + // } + // string json = value.ToString(); + // if (string.IsNullOrEmpty(json)) + // { + // _logger.LogError("解析数据为空!"); + // return null; + // } + // AGVResponseEntity ResponseEntity; + // try + // { + // ResponseEntity = JsonSerializer.Deserialize>(json); + // return ResponseEntity; + // } + // catch (Exception ex) + // { + // _logger.LogError($"Json反序列化发生错误:{ex.Message}"); + // return null; + // } + //} + + public AGVResponseEntity JsonStringToEntity(string json) where T : class { - if (value == null) + if (json == null) { _logger.LogError("返回空数据!"); return null; } - string json = value.ToString(); if (string.IsNullOrEmpty(json)) { _logger.LogError("解析数据为空!"); @@ -87,7 +108,7 @@ namespace SlnMesnac.TouchSocket AGVResponseEntity ResponseEntity; try { - ResponseEntity = JsonSerializer.Deserialize>(json); + ResponseEntity = JsonConvert.DeserializeObject>(json); return ResponseEntity; } catch (Exception ex) @@ -96,6 +117,8 @@ namespace SlnMesnac.TouchSocket return null; } } + + /// /// AGV下发任务请求 /// @@ -104,12 +127,18 @@ namespace SlnMesnac.TouchSocket /// public AGVResponseEntity AGVAddTaskRequest(AGVRequestAddTaskEntity requestValue) { - if (AirportAGVClient == null) + if(_httpClient == null) { + _logger.LogError("http服务为空"); return null; } - JToken responseValue = AirportAGVClient.InvokeT("POST:/api/task/addTask", null, requestValue); - return JTokenToEntity(responseValue); + //序列化输入数据 + string json = Newtonsoft.Json.JsonConvert.SerializeObject(requestValue); + var context = new StringContent(json, Encoding.UTF8, "application/json"); + var httpContent = _httpClient.PostAsync($"{Url}/api/task/addTask", context).ConfigureAwait(false).GetAwaiter().GetResult().Content; + string result = httpContent.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + //JToken responseValue = AirportAGVClient.InvokeT("POST:/api/task/addTask", null, requestValue); + return JsonStringToEntity(result); } /// @@ -119,12 +148,18 @@ namespace SlnMesnac.TouchSocket /// public AGVResponseEntity AGVOperationalTaskRequest(AGVRequestOperationalTaskEntity requestValue) { - if (AirportAGVClient == null) + if (_httpClient == null) { + _logger.LogError("http服务为空"); return null; } - JToken responseValue = AirportAGVClient.InvokeT("POST:/api/task/operationalTask", null, requestValue); - return JTokenToEntity(responseValue); + //序列化输入数据 + string json = Newtonsoft.Json.JsonConvert.SerializeObject(requestValue); + var context = new StringContent(json, Encoding.UTF8, "application/json"); + var httpContent = _httpClient.PostAsync($"{Url}/api/task/operationalTask", context).ConfigureAwait(false).GetAwaiter().GetResult().Content; + string result = httpContent.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + //JToken responseValue = AirportAGVClient.InvokeT("POST:/api/task/operationalTask", null, requestValue); + return JsonStringToEntity(result); } /// @@ -134,12 +169,18 @@ namespace SlnMesnac.TouchSocket /// public AGVResponseEntity AGVGetTaskStateDetailRequest(AGVRequestTaskStateDetailEntity requestValue) { - if (AirportAGVClient == null) + if (_httpClient == null) { + _logger.LogError("http服务为空"); return null; } - JToken responseValue = AirportAGVClient.InvokeT("PUT:/api/task/getTaskStateDetail", null, requestValue); - return JTokenToEntity(responseValue); + //序列化输入数据 + string json = Newtonsoft.Json.JsonConvert.SerializeObject(requestValue); + var context = new StringContent(json, Encoding.UTF8, "application/json"); + var httpContent = _httpClient.PutAsync($"{Url}/api/task/getTaskStateDetail", context).ConfigureAwait(false).GetAwaiter().GetResult().Content; + string result = httpContent.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + //JToken responseValue = AirportAGVClient.InvokeT("PUT:/api/task/getTaskStateDetail", null, requestValue); + return JsonStringToEntity(result); } /// @@ -148,12 +189,16 @@ namespace SlnMesnac.TouchSocket /// public AGVResponseEntity> AGVAllStateRequest() { - if (AirportAGVClient == null) + if (_httpClient == null) { + _logger.LogError("http服务为空"); return null; } - JToken responseValue = AirportAGVClient.InvokeT("GET:/api/task/robot/getRobot", null); - return JTokenToEntity>(responseValue); + //序列化输入数据 + var httpContent = _httpClient.GetAsync($"{Url}/api/task/robot/getRobot").ConfigureAwait(false).GetAwaiter().GetResult().Content; + string result = httpContent.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + //JToken responseValue = AirportAGVClient.InvokeT("GET:/api/task/robot/getRobot", null); + return JsonStringToEntity>(result); } /// @@ -162,12 +207,15 @@ namespace SlnMesnac.TouchSocket /// public AGVResponseEntity AGVMapActiveRequest() { - if (AirportAGVClient == null) + if (_httpClient == null) { + _logger.LogError("http服务为空"); return null; } - JToken responseValue = AirportAGVClient.InvokeT("GET:/api/v1.0.0/Maps/mapActive", null); - return JTokenToEntity(responseValue); + var httpContent = _httpClient.GetAsync($"{Url}/api/v1.0.0/Maps/mapActive").ConfigureAwait(false).GetAwaiter().GetResult().Content; + string result = httpContent.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + //JToken responseValue = AirportAGVClient.InvokeT("GET:/api/v1.0.0/Maps/mapActive", null); + return JsonStringToEntity(result); } /// @@ -177,32 +225,68 @@ namespace SlnMesnac.TouchSocket /// public AGVResponseEntity> AGVMapPositionRequest(string requestValue) { - if (AirportAGVClient == null) + if (_httpClient == null) { + _logger.LogError("http服务为空"); return null; } - JToken responseValue = AirportAGVClient.InvokeT("GET:/api/v1.0.0/Positions?mapId={0}", null, requestValue); - return JTokenToEntity>(responseValue); + //序列化输入数据 + string json = Newtonsoft.Json.JsonConvert.SerializeObject(requestValue); + var context = new StringContent(json, Encoding.UTF8, "application/json"); + var httpContent = _httpClient.GetAsync($"{Url}/api/v1.0.0/Positions?mapId={requestValue}").ConfigureAwait(false).GetAwaiter().GetResult().Content; + string result = httpContent.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + //JToken responseValue = AirportAGVClient.InvokeT("GET:/api/v1.0.0/Positions?mapId={0}", null, requestValue); + return JsonStringToEntity>(result); } /// - /// 获取当前所有任务模板信息(目前不可用) + /// AGV异常获取清除 /// + /// /// - public AGVResponseEntity AGVJobRequest() + public AGVResponseEntity AGVErrorClear(string agvIp) { - if (AirportAGVClient == null) + if (_httpClient == null) { + _logger.LogError("http服务为空"); return null; } - JToken responseValue = AirportAGVClient.InvokeT("GET:/api/v1.0.0/Positions?mapId={0}", null); - return JTokenToEntity(responseValue); - } + string token = "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiYWRtaW4iLCJyb2xlIjoiMSIsImlzcyI6IlNpbmV2YVNlcnZlciIsImF1ZCI6IlNpbmV2YUNsaWVudCJ9.Ujn-JuQDzA_sloITF84z1pdQvvH8DQ0DSFlhz4zP44M"; - } + var request = new HttpRequestMessage(HttpMethod.Delete, $"http://{agvIp}/api/v1.0.0/ClearException/0"); + // 单独为此请求添加 Authorization 头部 + request.Headers.Add("Authorization", token); + // 发送请求 + var response = _httpClient.SendAsync(request).ConfigureAwait(false).GetAwaiter().GetResult(); + // 读取响应内容 + var httpContent = response.Content; + string result = httpContent.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult(); - //HttpClient client1 = new HttpClient(); + return JsonStringToEntity(result); + } + + ///// + ///// 获取当前所有任务模板信息(目前不可用) + ///// + ///// + //public AGVResponseEntity AGVJobRequest() + //{ + // if (_httpClient == null) + // { + // _logger.LogError("http服务为空"); + // } + // //序列化输入数据 + // string json = Newtonsoft.Json.JsonConvert.SerializeObject(requestValue); + // var context = new StringContent(json, Encoding.UTF8, "application/json"); + // var httpContent = _httpClient.PostAsync($"{Url}/api/task/addTask", context).ConfigureAwait(false).GetAwaiter().GetResult().Content; + // string result = httpContent.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult(); + // AGVResponseEntity responseEntity = JsonConvert.DeserializeObject>(result); + // //JToken responseValue = AirportAGVClient.InvokeT("GET:/api/v1.0.0/Positions?mapId={0}", null); + // return JTokenToEntity(responseValue); + //} + + } //string url = "http://192.168.10.199:5102/api/task/addTask"; diff --git a/SlnMesnac.WPF/MainWindow.xaml b/SlnMesnac.WPF/MainWindow.xaml index 94d9883..f7debaa 100644 --- a/SlnMesnac.WPF/MainWindow.xaml +++ b/SlnMesnac.WPF/MainWindow.xaml @@ -52,28 +52,34 @@ - + - - + + - +