You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

461 lines
18 KiB
C#

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
{
/// <summary>
/// 航班任务业务类
/// </summary>
public class BaseTaskInfoBusiness
{
public const int AMRStackNumber = 10;
public const int DeliverStackNumber = 15;
private TcpServer _tcpServer = null;
public Action<AirportTask> _Taskaction;
public Action<string> _RefreshLogMessageAction;
private static BaseTaskInfoBusiness instance;
private ILogger<BaseTaskInfoBusiness> _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<BaseTaskInfoBusiness> 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<BaseTaskInfoBusiness> 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;
}
/// <summary>
/// 从航班接口获取到新任务插入数据库
/// </summary>
/// <returns></returns>
public async Task<bool> 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;
}
}
/// <summary>
/// AGV状态查询控制
/// </summary>
/// <param name="state"></param>
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);
}
}
/// <summary>
/// Timer刷新任务状态, 有新任务初次下发AGV
/// </summary>
public void RefreshTaskState()
{
try
{
//获取任务列表
List<AirportTask> 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}");
}
}
/// <summary>
/// 获取任务列表向待执行任务派发AGV (定期执行)
/// </summary>
private void GetAGVTaskInfo(object source, ElapsedEventArgs e)
{
try
{
//获取任务列表
List<AirportTask> 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($"正在为AGVAMR分配任务...");
_logger.LogInformation($"正在为AGVAMR分配任务");
//查询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)
{
}
}
/// <summary>
/// 调用接口更新指定的任务状态
/// </summary>
/// <param name="request"></param>
public void RefreshTaskStateForResopnse(AGVRequestTaskStateDetailEntity request)
{
AGVResponseEntity<ResponseTaskStateDetailDataEntity> response = _airpttpClient.AGVGetTaskStateDetailRequest(request);
if (response.code == 1)
{
_logger.LogError("返回错误:" + response.message);
return;
}
if (response.code == 0)
{
AirportTask record = new AirportTask();
List<AirportTask> list = _Taskservice.GetTaskInfos();
//list.Where(x => x.taskno == response.Data
}
}
/// <summary>
/// 持续读取AGV状态信息
/// </summary>
private void doWhileGetAGVTaskInfo()
{
try
{
Task.Run(() =>
{
while (true)
{
GetAGVTaskInfo(null, null);
Task.Delay(1000);
}
});
}
catch (Exception ex)
{
}
}
/// <summary>
/// 清理Timer
/// </summary>
private void InitClearTimer()
{
System.Timers.Timer timer = new System.Timers.Timer
{
Interval = 1000, // 每天执行一次
AutoReset = true,
};
timer.Elapsed += GetAGVTaskInfo;
timer.Start();
}
/// <summary>
/// 向AMR派发任务
/// </summary>
/// <param name="AirportTask"></param>
/// <returns></returns>
private bool CreateAMRTask(AirportTask AirportTask)
{
bool iflag = false;
try
{
iflag = true;
//获取AMR设备状态
List<AGVState> 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;
}
}
/// <summary>
/// 向DeliverAGV派发任务
/// </summary>
/// <returns></returns>
private bool CreateAGVTask(AirportTask AirportTask)
{
bool iflag = false;
try
{
iflag = true;
//获取DeliverAGV设备状态
List<AGVState> 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;
}
}
/// <summary>
/// 获取任务状态详情
/// </summary>
private void GetTaskStateDetail()
{
try
{
Task.Run(() =>
{
List<AirportTask> 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)
{
}
}
}
}