using Microsoft.Extensions.Logging; using SlnMesnac.Repository.service; using System; using System.Collections.Generic; using System.Diagnostics; using System.Threading.Tasks; using SlnMesnac.Repository; using SlnMesnac.Repository.service.Impl; using TouchSocket.Sockets; using SlnMesnac.Model.domain; using SlnMesnac.TouchSocket; using System.Timers; using SlnMesnac.Model.Enum; using HslCommunication.Enthernet; using System.Threading; using SlnMesnac.TouchSocket.Entity; using SlnMesnac.Model.AirportApiEntity; using System.Linq; namespace SlnMesnac.Business.@base { /// /// 航班任务业务类 /// public class BaseTaskInfoBusiness { public const int AMRStackNumber = 10; public const int DeliverStackNumber = 15; private TcpServer _tcpServer = null; public Action _Taskaction; public Action _RefreshLogMessageAction; private static BaseTaskInfoBusiness instance; private ILogger _logger; private IAirportTaskService _Taskservice; private IAGVMapPointService _AGVMapPointService; private IAGVStateService _AGVStateService; private IAGVJobService _AGVJobService; private AirPorthttpClient _airpttpClient; private BaseAGVBusiness _baseAGVBusiness; System.Timers.Timer RefreshTimer; public BaseTaskInfoBusiness( ILogger logger, IAirportTaskService Taskservice, IAGVStateService agvService, IAGVMapPointService aGVMapPointService, IAGVJobService agvJobService, TcpServer tcpServer, AirPorthttpClient airPorthttpClient, BaseAGVBusiness baseAGVBusiness) { _logger = logger; _tcpServer = tcpServer; _Taskservice = Taskservice; _AGVStateService = agvService; _airpttpClient = airPorthttpClient; InitClearTimer(); //doWhileGetAGVTaskInfo(); RefreshTimer = new System.Timers.Timer(1000); RefreshTimer.Elapsed += (sender, e) => RefreshTaskState(); _baseAGVBusiness = baseAGVBusiness; _AGVMapPointService = aGVMapPointService; _AGVJobService = agvJobService; } public static BaseTaskInfoBusiness GetInstance( ILogger logger, IAirportTaskService Taskservice, IAGVStateService agvService, IAGVMapPointService aGVMapPointService, IAGVJobService aAGVJobService, TcpServer tcpServer, AirPorthttpClient airPorthttpClient, BaseAGVBusiness baseAGVBusiness) { if (instance == null) { instance = new BaseTaskInfoBusiness(logger, Taskservice, agvService, aGVMapPointService, aAGVJobService, tcpServer, airPorthttpClient, baseAGVBusiness); } return instance; } /// /// 从航班接口获取到新任务插入数据库 /// /// public async Task NewTaskInfo(string taskNo, string conveyNo, string flightNo, int totalCount) { var task = new AirportTask() { taskno = taskNo, conveyorno = conveyNo, //判断条件 flightno = flightNo, amragvno = string.Empty, //需要判断,更新 是否有AMR分配 amragvisarrive = string.Empty, //需要判断,更新 AMR是否到达 deliveragvno = string.Empty, //需要判断,更新 是否有Deliver分配 deliveragvisarrive = string.Empty, //需要判断,更新 Deliver是否到达 totalcount = totalCount, //判断条件 总数量是多少 loadcount = 0, //需要判断,更新 现抓取数量 taskstate = "等待", //需要判断,更新 任务状态 starttime = DateTime.Now, finishtime = null, deliveragvTaskNo = string.Empty, //需要判断,更新 amragvTaskNo = string.Empty, //需要判断,更新 }; try { return await _Taskservice.AddTaskAsync(task); } catch (Exception ex) { _logger.LogError("航班任务新建失败"); return false; } } /// /// AGV状态查询控制 /// /// public void AGVStateUpdateTimerOperation(TimerControl state) { try { switch (state) { case TimerControl.Start: RefreshTimer.Start(); break; case TimerControl.Stop: RefreshTimer.Stop(); break; case TimerControl.Dispose: RefreshTimer.Dispose(); break; default: _logger.LogError("未知状态"); break; } } catch (Exception ex) { _logger.LogError("AGV状态操作失败!" + ex.Message); } } /// /// Timer刷新任务状态, 有新任务初次下发AGV /// public void RefreshTaskState() { try { //获取任务列表 List Task = _Taskservice.GetAGVTaskInfos(); if (Task != null && Task.Count > 0) { //更新前端 _RefreshLogMessageAction?.Invoke("任务数量:" + Task.Count); foreach(AirportTask taskItem in Task) { //查询待执行任务 if (taskItem.taskstate == "等待" || string.IsNullOrEmpty(taskItem.amragvno)) { //首先调一辆最优AMR AGVState firstAMR = _baseAGVBusiness.GetBestAGV(AgvType.AMR); string amrTaskId = _baseAGVBusiness.EndTaskAndClearErrorAndDownloadTask( firstAMR.agvno, _AGVJobService.GetAGVJobListByTypeAndConveyorNo("1000入位", taskItem.conveyorno).JobName); taskItem.amragvTaskNo = amrTaskId; taskItem.amragvno = firstAMR.agvno; taskItem.amragvisarrive = "未到达"; taskItem.taskstate = "执行中"; //需要AGV和AMR才能装下 if (taskItem.totalcount > (AMRStackNumber - firstAMR.stackcount)) { //调一辆最优Deliver AGVState firstDeliver = _baseAGVBusiness.GetBestAGV(AgvType.Deliver); string deliverTaskID = _baseAGVBusiness.EndTaskAndClearErrorAndDownloadTask( firstDeliver.agvno, _AGVJobService.GetAGVJobListByTypeAndConveyorNo("800入位", taskItem.conveyorno).JobName); taskItem.deliveragvTaskNo = amrTaskId; taskItem.deliveragvno = firstDeliver.agvno; taskItem.deliveragvisarrive = "未到达"; } _Taskservice.UpdateTaskAsync(taskItem); } } } } catch (Exception ex) { _logger.LogError($"查询任务列表初次下发任务发生错误Message:{ex.Message}"); } } /// /// 获取任务列表,向待执行任务派发AGV (定期执行) /// private void GetAGVTaskInfo(object source, ElapsedEventArgs e) { try { //获取任务列表 List Task = _Taskservice.GetAGVTaskInfos(); if (Task != null && Task.Count > 0) { //更新前端 _RefreshLogMessageAction?.Invoke("任务数量:" + Task.Count); foreach (AirportTask taskItem in Task) { //判断任务是否未完成 if (taskItem.totalcount < taskItem.loadcount && taskItem.finishtime == null && taskItem.taskstate != "已完成") { //判断任务是否有小车正在执行 if (!string.IsNullOrEmpty(taskItem.deliveragvno) && !string.IsNullOrEmpty(taskItem.amragvno)) { continue; } else { //Deliver未派发,AMR未派发 if (string.IsNullOrEmpty(taskItem.deliveragvno) && string.IsNullOrEmpty(taskItem.amragvno)) { _RefreshLogMessageAction?.Invoke($"正在为AGV,AMR分配任务..."); _logger.LogInformation($"正在为AGV,AMR分配任务"); //查询AGV设备状态及AMR设备状态 //这里要看AGV是否会立刻更新状态 CreateAGVTask(taskItem); //查询机械臂状态 } //Deliver已派发,AMR未派发 if (!string.IsNullOrEmpty(taskItem.deliveragvno) && string.IsNullOrEmpty(taskItem.amragvno)) { _RefreshLogMessageAction?.Invoke($"正在为AMR分配任务..."); _logger.LogInformation($"正在为AMR分配任务"); //查询AMR状态 CreateAMRTask(taskItem); } //Deliver未派发,AMR已派发 if (string.IsNullOrEmpty(taskItem.deliveragvno) && !string.IsNullOrEmpty(taskItem.amragvno)) { _RefreshLogMessageAction?.Invoke($"正在为AGV分配任务..."); _logger.LogInformation($"正在为AGV分配任务"); } } _Taskaction?.Invoke(taskItem); } } } } catch (Exception ex) { } } /// /// 调用接口更新指定的任务状态 /// /// public void RefreshTaskStateForResopnse(AGVRequestTaskStateDetailEntity request) { AGVResponseEntity response = _airpttpClient.AGVGetTaskStateDetailRequest(request); if (response.code == 1) { _logger.LogError("返回错误:" + response.message); return; } if (response.code == 0) { AirportTask record = new AirportTask(); List list = _Taskservice.GetTaskInfos(); //list.Where(x => x.taskno == response.Data } } /// /// 持续读取AGV状态信息 /// private void doWhileGetAGVTaskInfo() { try { Task.Run(() => { while (true) { GetAGVTaskInfo(null, null); Task.Delay(1000); } }); } catch (Exception ex) { } } /// /// 清理Timer /// private void InitClearTimer() { System.Timers.Timer timer = new System.Timers.Timer { Interval = 1000, // 每天执行一次 AutoReset = true, }; timer.Elapsed += GetAGVTaskInfo; timer.Start(); } /// /// 向AMR派发任务 /// /// /// private bool CreateAMRTask(AirportTask AirportTask) { bool iflag = false; try { iflag = true; //获取AMR设备状态 List State = _AGVStateService.GetAgvState(AgvType.AMR); foreach (var AgvItem in State) { //根据规则筛选最优AGV if (AgvItem.agvworkstate == "任务空闲") { _logger.LogInformation($"获取空闲AMR列表"); _RefreshLogMessageAction?.Invoke("执行站台[" + AirportTask.conveyorno + "],下发" + "[" + AirportTask.taskno + "]任务"); //调用派发任务接口,向任务状态为任务空闲的AGV派发任务 bool iTaskflag = true; if (iTaskflag) { _RefreshLogMessageAction?.Invoke("[" + AgvItem.agvno + "]AMR,执行任务[" + AirportTask.taskno + "]"); AgvItem.taskno = AirportTask.taskno; AgvItem.agvworkstate = "任务执行中"; AgvItem.refreshtime = DateTime.Now; _AGVStateService.UpdateAsync(AgvItem); //更新任务信息表状态为执行中 AirportTask.amragvno = AgvItem.agvno; AirportTask.taskstate = "执行中"; _Taskservice.UpdateTaskAsync(AirportTask); break; } } } return iflag; } catch (Exception ex) { return iflag; } } /// /// 向DeliverAGV派发任务 /// /// private bool CreateAGVTask(AirportTask AirportTask) { bool iflag = false; try { iflag = true; //获取DeliverAGV设备状态 List State = _AGVStateService.GetAgvState(AgvType.Deliver); foreach (var AgvItem in State) { //根据规则筛选最优AGV if (AgvItem.agvworkstate == "任务空闲") { _logger.LogInformation($"获取空闲AGV列表"); _RefreshLogMessageAction?.Invoke("执行站台[" + AirportTask.conveyorno + "],下发" + "[" + AirportTask.taskno + "]任务"); //调用派发任务接口,向任务状态为任务空闲的AGV派发任务 bool iTaskflag = true; if (iTaskflag) { _RefreshLogMessageAction?.Invoke("[" + AgvItem.agvno + "]AGV,执行任务[" + AirportTask.taskno + "]"); AgvItem.taskno = AirportTask.taskno; AgvItem.agvworkstate = "任务执行中"; AgvItem.refreshtime = DateTime.Now; _AGVStateService.UpdateAsync(AgvItem); //更新任务信息表状态为执行中 AirportTask.deliveragvno = AgvItem.agvno; AirportTask.taskstate = "执行中"; _Taskservice.UpdateTaskAsync(AirportTask); break; } } } return iflag; } catch (Exception ex) { return iflag; } } /// /// 获取任务状态详情 /// private void GetTaskStateDetail() { try { Task.Run(() => { List Task = _Taskservice.GetAGVTaskInfos(); if (Task.Count > 0) { // 设置计时器 Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); //通过任务编号查询agv任务 // 检查是否超过两秒 if (stopwatch.ElapsedMilliseconds > 2000) { _logger.LogError("超时"); } Thread.Sleep(100); } }); } catch (Exception ex) { } } } }