using Newtonsoft.Json;
|
using OfficeOpenXml.FormulaParsing.Excel.Functions.Logical;
|
using Quartz;
|
using SqlSugar;
|
using SqlSugar.Extensions;
|
using System.Collections.Generic;
|
using System.Diagnostics.CodeAnalysis;
|
using System.Threading.Tasks;
|
using WIDESEA_Core.Enums;
|
using WIDESEAWCS_Core.Caches;
|
using WIDESEAWCS_Core.Helper;
|
using WIDESEAWCS_Core.HttpContextUser;
|
using WIDESEAWCS_DTO.Enum;
|
using WIDESEAWCS_IBasicInfoRepository;
|
using WIDESEAWCS_ISystemRepository;
|
using WIDESEAWCS_ITaskInfoRepository;
|
using WIDESEAWCS_ITaskInfoService;
|
using WIDESEAWCS_Model.Models;
|
using WIDESEAWCS_QuartzJob;
|
using WIDESEAWCS_QuartzJob.DeviceBase;
|
using WIDESEAWCS_QuartzJob.DTO;
|
using WIDESEAWCS_QuartzJob.Models;
|
using WIDESEAWCS_QuartzJob.Service;
|
using WIDESEAWCS_QuartzJob.StackerCrane;
|
using WIDESEAWCS_QuartzJob.StackerCrane.Enum;
|
using WIDESEAWCS_SignalR;
|
using WIDESEAWCS_Tasks.StackerCraneJob;
|
using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database;
|
using ICacheService = WIDESEAWCS_Core.Caches.ICacheService;
|
|
namespace WIDESEAWCS_Tasks
|
{
|
[DisallowConcurrentExecution]
|
public class CommonStackerCraneJob : IJob
|
{
|
private readonly ITaskService _taskService;
|
private readonly ITaskExecuteDetailService _taskExecuteDetailService;
|
private readonly ITaskRepository _taskRepository;
|
private readonly IDt_StationManagerRepository _stationManagerRepository;
|
private readonly ICacheService _cacheService;
|
private readonly INoticeService _noticeService;
|
|
public CommonStackerCraneJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository,IDt_StationManagerRepository stationManagerRepository, ICacheService cacheService, INoticeService noticeService)
|
{
|
_taskService = taskService;
|
_taskExecuteDetailService = taskExecuteDetailService;
|
_taskRepository = taskRepository;
|
_stationManagerRepository = stationManagerRepository;
|
_cacheService = cacheService;
|
_noticeService = noticeService;
|
}
|
|
public Task Execute(IJobExecutionContext context)
|
{
|
try
|
{
|
CommonStackerCrane commonStackerCrane = (CommonStackerCrane)context.JobDetail.JobDataMap.Get("JobParams");
|
if (commonStackerCrane != null)
|
{
|
if (!commonStackerCrane.IsEventSubscribed)
|
{
|
commonStackerCrane.StackerCraneTaskCompletedEventHandler += CommonStackerCrane_StackerCraneTaskCompletedEventHandler;//订阅任务完成事件
|
}
|
|
if (commonStackerCrane.StackerCraneAutoStatusValue == StackerCraneAutoStatus.Automatic && commonStackerCrane.StackerCraneStatusValue == StackerCraneStatus.Normal)
|
{
|
commonStackerCrane.CheckStackerCraneTaskCompleted();//检测堆垛机任务完成事件
|
|
if (commonStackerCrane.StackerCraneWorkStatusValue == StackerCraneWorkStatus.Idle)
|
{
|
if (commonStackerCrane.GetValue<StackerCraneDBName, float>(StackerCraneDBName.Electricity) > 20)
|
{
|
GetTask(commonStackerCrane);
|
}
|
}
|
}
|
|
#region 调用事件总线通知前端
|
|
var tokenInfos = _cacheService.Get<List<UserInfo>>("Cache_UserToken");
|
if (tokenInfos != null && tokenInfos.Any())
|
{
|
var userTokenIds = tokenInfos?.Select(x => x.Token_ID).ToList();
|
var userIds = tokenInfos?.Select(x => x.UserId).ToList();
|
object obj = new
|
{
|
commonStackerCrane.StackerCraneStatusDes,
|
commonStackerCrane.StackerCraneAutoStatusDes,
|
commonStackerCrane.StackerCraneWorkStatusDes,
|
commonStackerCrane.DeviceCode,
|
commonStackerCrane.DeviceName,
|
commonStackerCrane.CurrentTaskNum,
|
commonStackerCrane.LastTaskNum,
|
SourceAddress = commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.StartAddress),
|
TargetAddress = commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.EndAddress),
|
Command = commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.Command),
|
Electricity = commonStackerCrane.GetValue<StackerCraneDBName, float>(StackerCraneDBName.Electricity),
|
};
|
|
_noticeService.StackerData(userIds?.FirstOrDefault(), userTokenIds, new { commonStackerCrane.DeviceName, data = obj });
|
}
|
|
#endregion 调用事件总线通知前端
|
}
|
}
|
catch (Exception ex)
|
{
|
//Console.WriteLine(nameof(CommonStackerCraneJob) + ":" + ex.ToString());
|
}
|
return Task.CompletedTask;
|
}
|
|
/// <summary>
|
/// 任务完成事件订阅的方法
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
private void CommonStackerCrane_StackerCraneTaskCompletedEventHandler(object? sender, StackerCraneTaskCompletedEventArgs e)
|
{
|
CommonStackerCrane? commonStackerCrane = sender as CommonStackerCrane;
|
if (commonStackerCrane != null)
|
{
|
_taskService.StackCraneTaskCompleted(e.TaskNum);
|
commonStackerCrane.SetValue(StackerCraneDBName.TaskCompleted, 1);
|
|
}
|
}
|
|
/// <summary>
|
/// 获取任务
|
/// </summary>
|
/// <param name="commonStackerCrane">堆垛机对象</param>
|
/// <returns></returns>
|
private void GetTask(CommonStackerCrane commonStackerCrane)
|
{
|
Dt_Task task;
|
task = _taskService.QueryStackerCraneTask(commonStackerCrane.DeviceCode);
|
if (task != null)
|
{
|
if (task.Roadway == "3")
|
{
|
if (AGVToSandyEdgeRead(commonStackerCrane))
|
{
|
WriteAGVTask(task, commonStackerCrane);
|
}
|
else
|
{
|
AGVToSandyEdge(commonStackerCrane);
|
}
|
|
}
|
else if (task.Roadway == "2")
|
{
|
if (AGVToEdgeBandingRead(commonStackerCrane))
|
{
|
WriteAGVTask(task, commonStackerCrane);
|
}
|
else
|
{
|
AGVToEdgeBanding(commonStackerCrane);
|
}
|
}
|
else
|
{
|
WriteAGVTask(task, commonStackerCrane);
|
}
|
|
}
|
}
|
|
public void WriteAGVTask(Dt_Task task, CommonStackerCrane commonStackerCrane)
|
{
|
StackerCraneTaskCommand? stackerCraneTaskCommand = ConvertToStackerCraneTaskCommand(task);
|
if (stackerCraneTaskCommand != null)
|
{
|
bool sendFlag = commonStackerCrane.SendCommand(stackerCraneTaskCommand);
|
Thread.Sleep(2000);
|
if (ReadReceived(commonStackerCrane) == 1)
|
{
|
if (Clear(commonStackerCrane))
|
{
|
_taskService.UpdateTaskStatusToNext(task.TaskNum);
|
}
|
|
}
|
}
|
}
|
|
/// <summary>
|
/// 读取AGV收到作业信号
|
/// </summary>
|
/// <param name="commonStackerCrane"></param>
|
/// <returns></returns>
|
public int ReadReceived(CommonStackerCrane commonStackerCrane)
|
{
|
return commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.Received);
|
}
|
|
/// <summary>
|
/// 调度AGV去封边区域
|
/// </summary>
|
/// <param name="commonStackerCrane"></param>
|
/// <param name="value"></param>
|
public void AGVToEdgeBanding(CommonStackerCrane commonStackerCrane)
|
{
|
DeviceProDTO? devicePro = commonStackerCrane.DeviceProDTOs.Where(x => x.DeviceProParamType == "AreaWrite" && x.DeviceChildCode == commonStackerCrane.DeviceCode && x.DeviceProParamName == "AreaWrite").OrderBy(x => x.DeviceProOffset).FirstOrDefault();
|
commonStackerCrane.Communicator.Write(devicePro.DeviceProAddress, true);
|
commonStackerCrane.SetValue(StackerCraneDBName.WorkType, 3);
|
commonStackerCrane.SetValue(StackerCraneDBName.WriteConfirm, 1);
|
Thread.Sleep(1000);
|
if (ReadReceived(commonStackerCrane) == 1)
|
{
|
Clear(commonStackerCrane);
|
}
|
}
|
|
/// <summary>
|
/// 读取AGV是否在砂边
|
/// </summary>
|
/// <param name="commonStackerCrane"></param>
|
/// <returns></returns>
|
public bool AGVToSandyEdgeRead(CommonStackerCrane commonStackerCrane)
|
{
|
DeviceProDTO? devicePro = commonStackerCrane.DeviceProDTOs.Where(x => x.DeviceProParamType == "AreaRead" && x.DeviceChildCode == commonStackerCrane.DeviceCode && x.DeviceProParamName == "AreaRead").OrderBy(x => x.DeviceProOffset).FirstOrDefault();
|
|
if (devicePro == null)
|
{
|
ConsoleHelper.WriteColorLine($"【未找到配置调度AGV区域协议】", ConsoleColor.Magenta);
|
return false;
|
}
|
|
string[] x = devicePro.DeviceProAddress.Split('.');
|
|
x[x.Length - 1] = (int.Parse(x[x.Length - 1]) + 1).ToString();
|
|
string DeviceProAddress = string.Join(".", x);
|
bool read = commonStackerCrane.Communicator.Read<bool>(DeviceProAddress);
|
|
return read;
|
}
|
|
public bool Clear(CommonStackerCrane commonStackerCrane)
|
{
|
DeviceProDTO? devicePro = commonStackerCrane.DeviceProDTOs.Where(x => x.DeviceProParamType == "WriteConfirm" && x.DeviceChildCode == commonStackerCrane.DeviceCode && x.DeviceProParamName == "WriteConfirm").OrderBy(x => x.DeviceProOffset).FirstOrDefault();
|
|
if (devicePro == null)
|
{
|
ConsoleHelper.WriteColorLine($"【未找到配置调度AGV区域协议】", ConsoleColor.Magenta);
|
return false;
|
}
|
commonStackerCrane.Communicator.Write(devicePro.DeviceProAddress,Convert.ToInt16(0));
|
|
for (int i = 0; i < 6; i++)
|
{
|
if (i == 5)
|
{
|
return false;
|
}
|
else
|
{
|
int read = commonStackerCrane.Communicator.Read<int>(devicePro.DeviceProAddress);
|
if (read == 0)
|
{
|
return true;
|
}
|
else
|
{
|
commonStackerCrane.Communicator.Write(devicePro.DeviceProAddress, Convert.ToInt16(0));
|
}
|
}
|
}
|
return false;
|
}
|
|
/// <summary>
|
/// 读取AGV是否在封边
|
/// </summary>
|
/// <param name="commonStackerCrane"></param>
|
/// <returns></returns>
|
public bool AGVToEdgeBandingRead(CommonStackerCrane commonStackerCrane)
|
{
|
DeviceProDTO? devicePro = commonStackerCrane.DeviceProDTOs.Where(x => x.DeviceProParamType == "AreaRead" && x.DeviceChildCode == commonStackerCrane.DeviceCode && x.DeviceProParamName == "AreaRead").OrderBy(x => x.DeviceProOffset).FirstOrDefault();
|
|
if (devicePro == null)
|
{
|
ConsoleHelper.WriteColorLine($"【未找到配置调度AGV区域协议】", ConsoleColor.Magenta);
|
return false;
|
}
|
return commonStackerCrane.Communicator.Read<bool>(devicePro.DeviceProAddress);
|
}
|
|
/// <summary>
|
/// 调度AGV去砂边区域
|
/// </summary>
|
/// <param name="commonStackerCrane"></param>
|
/// <param name="value"></param>
|
public void AGVToSandyEdge(CommonStackerCrane commonStackerCrane)
|
{
|
DeviceProDTO? devicePro = commonStackerCrane.DeviceProDTOs.Where(x => x.DeviceProParamType == "AreaWrite" && x.DeviceChildCode == commonStackerCrane.DeviceCode && x.DeviceProParamName == "AreaWrite").OrderBy(x => x.DeviceProOffset).FirstOrDefault();
|
|
if (devicePro == null)
|
{
|
ConsoleHelper.WriteColorLine($"【未找到配置调度AGV区域协议】", ConsoleColor.Magenta);
|
return;
|
}
|
|
string[] x = devicePro.DeviceProAddress.Split('.');
|
|
x[x.Length - 1] = (int.Parse(x[x.Length - 1]) + 1).ToString();
|
|
string DeviceProAddress = string.Join(".", x);
|
commonStackerCrane.Communicator.Write(DeviceProAddress, true);
|
commonStackerCrane.SetValue(StackerCraneDBName.WorkType, 4);
|
commonStackerCrane.SetValue(StackerCraneDBName.WriteConfirm, 1);
|
Thread.Sleep(1000);
|
if (ReadReceived(commonStackerCrane) == 1)
|
{
|
Clear(commonStackerCrane);
|
}
|
}
|
/// <summary>
|
/// 任务实体转换成命令Model
|
/// </summary>
|
/// <param name="task">任务实体</param>
|
/// <returns></returns>
|
/// <exception cref="Exception"></exception>
|
public StackerCraneTaskCommand? ConvertToStackerCraneTaskCommand([NotNull] Dt_Task task)
|
{
|
var SourceAddress = _stationManagerRepository.QueryFirst(x => x.stationName == task.SourceAddress);
|
var TargetAddress = _stationManagerRepository.QueryFirst(x => x.stationName == task.TargetAddress);
|
|
if(SourceAddress == null || TargetAddress == null)
|
{
|
ConsoleHelper.WriteColorLine($"【任务{JsonConvert.SerializeObject(task)}未找到站台配置】", ConsoleColor.Magenta);
|
return null;
|
}
|
StackerCraneTaskCommand stackerCraneTaskCommand = new StackerCraneTaskCommand();
|
|
stackerCraneTaskCommand.TaskNum = task.TaskNum;
|
stackerCraneTaskCommand.WorkType = 1;
|
stackerCraneTaskCommand.WriteConfirm = 1;
|
stackerCraneTaskCommand.StartAddress = Convert.ToInt16(SourceAddress.stationCode);
|
stackerCraneTaskCommand.EndAddress = Convert.ToInt16(TargetAddress.stationCode);
|
|
return stackerCraneTaskCommand;
|
}
|
}
|
}
|