using HslCommunication;
|
using Microsoft.AspNetCore.Components.Routing;
|
using Newtonsoft.Json;
|
using Quartz;
|
using System;
|
using System.Collections.Generic;
|
using System.Diagnostics.CodeAnalysis;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
using WIDESEAWCS_Common.TaskEnum;
|
using WIDESEAWCS_Communicator;
|
using WIDESEAWCS_Core.Enums;
|
using WIDESEAWCS_IBasicRepository;
|
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.Repository;
|
using WIDESEAWCS_QuartzJob.Service;
|
using WIDESEAWCS_QuartzJob.StackerCrane;
|
using WIDESEAWCS_QuartzJob.StackerCrane.Enum;
|
using WIDESEAWCS_TaskInfoService;
|
using WIDESEAWCS_Tasks.StackerCraneJob;
|
|
namespace WIDESEAWCS_Tasks
|
{
|
[DisallowConcurrentExecution]
|
public class DoubleStackerCraneJob : JobBase, IJob
|
{
|
private readonly ITaskService _taskService;
|
private readonly ITaskExecuteDetailService _taskExecuteDetailService;
|
private readonly ITaskRepository _taskRepository;
|
private readonly IRouterService _routerService;
|
private readonly IDeviceInfoService _deviceInfoService;
|
private readonly IDeviceInfoRepository _deviceInfoRepository;
|
private readonly ILocationInfoRepository _locationInfoRepository;
|
|
public DoubleStackerCraneJob(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService, IDeviceInfoService deviceInfoService, IDeviceInfoRepository deviceInfoRepository, ILocationInfoRepository locationInfoRepository)
|
{
|
_taskService = taskService;
|
_taskExecuteDetailService = taskExecuteDetailService;
|
_taskRepository = taskRepository;
|
_routerService = routerService;
|
_deviceInfoService = deviceInfoService;
|
_deviceInfoRepository = deviceInfoRepository;
|
_locationInfoRepository = locationInfoRepository;
|
}
|
|
public Task Execute(IJobExecutionContext context)
|
{
|
|
CommonStackerCrane? stackerCraneOne = Storage.Devices.FirstOrDefault(x => x.DeviceCode == "SC02") as CommonStackerCrane;
|
CommonStackerCrane? stackerCraneTwo = Storage.Devices.FirstOrDefault(x => x.DeviceCode == "SC03") as CommonStackerCrane;
|
|
try
|
{
|
|
Dt_Task? task = GetTask();
|
|
if (task != null)
|
{
|
CommonStackerCrane? StackerCrane = GetStrackerCrane(task, stackerCraneOne, stackerCraneTwo);
|
if (StackerCrane != null)
|
{
|
WriteDebug(nameof(DoubleStackerCraneJob), $"小堆垛机任务号{task.TaskNum}--{StackerCrane.DeviceCode}");
|
StackerCraneTaskCommand? stackerCraneTaskCommand = ConvertToStackerCraneTaskCommand(task);
|
if (stackerCraneTaskCommand != null)
|
{
|
bool sendFlag = StackerCrane.SendCommand(stackerCraneTaskCommand); ;
|
if (sendFlag)
|
{
|
_taskService.UpdateTaskStatus(task.TaskId, (int)TaskOutStatusEnum.SC_OutExecuting);
|
_taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"堆垛机出库执行中");
|
|
}
|
else
|
{
|
_taskService.UpdateTaskExceptionMessage(task.TaskNum, "堆垛机发送任务命令失败!");
|
WriteDebug(nameof(DoubleStackerCraneJob), $"堆垛机发送任务命令失败!{task.TaskNum}");
|
}
|
}
|
|
}
|
else
|
{
|
WriteDebug(nameof(DoubleStackerCraneJob), "未查询到当前可以执行上料任务的小堆垛机!");
|
}
|
|
}
|
|
}
|
catch (Exception ex)
|
{
|
WriteError(nameof(DoubleStackerCraneJob), "小堆垛机执行任务异常!", ex);
|
}
|
|
|
|
try
|
{
|
if (stackerCraneOne != null)//SC02
|
{
|
byte IsOver = stackerCraneOne.Communicator.Read<byte>("DB106.22");
|
int tasknum = stackerCraneOne.Communicator.Read<int>("DB106.18");
|
WriteDebug(nameof(DoubleStackerCraneJob), $"小堆垛机SC02任务号堆垛机任务号:{tasknum}状态:{IsOver}");
|
if (IsOver == 6)
|
{
|
if (stackerCraneOne.GetValue<StackerCraneDBName, short>(StackerCraneDBName.WorkType) != 5)
|
{
|
_taskService.StackCraneTaskCompleted(tasknum);
|
Console.Out.WriteLine("TaskCompleted" + tasknum);
|
bool issuccess = stackerCraneOne.SetValue(StackerCraneDBName.WorkType, 5);
|
|
}
|
}
|
}
|
|
if (stackerCraneTwo != null)//SC03
|
{
|
//读取堆垛机任务号和任务完成确认状态
|
byte IsOver = stackerCraneTwo.Communicator.Read<byte>("DB106.22");
|
int tasknum = stackerCraneTwo.Communicator.Read<int>("DB106.18");
|
WriteDebug(nameof(DoubleStackerCraneJob), $"小堆垛机SC03任务号堆垛机任务号:{tasknum}状态:{IsOver}");
|
if (IsOver == 6)
|
{
|
if (stackerCraneTwo.GetValue<StackerCraneDBName, short>(StackerCraneDBName.WorkType) != 5)
|
{
|
_taskService.StackCraneTaskCompleted(tasknum);
|
Console.Out.WriteLine("TaskCompleted" + tasknum);
|
bool issuccess = stackerCraneTwo.SetValue(StackerCraneDBName.WorkType, 5);
|
|
}
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
WriteError(nameof(DoubleStackerCraneJob), "执行异常!", ex);
|
}
|
|
|
|
return Task.CompletedTask;
|
}
|
|
/// <summary>
|
/// 任务完成事件订阅的方法
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
private void CommonStackerCrane_StackerCraneTaskCompletedEventHandler(object? sender, WIDESEAWCS_QuartzJob.StackerCrane.StackerCraneTaskCompletedEventArgs e)
|
{
|
CommonStackerCrane? commonStackerCrane = sender as CommonStackerCrane;
|
if (commonStackerCrane != null)
|
{
|
if (commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.WorkType) != 5)
|
{
|
Console.Out.WriteLine("TaskCompleted" + e.TaskNum);
|
_taskService.StackCraneTaskCompleted(e.TaskNum);
|
commonStackerCrane.SetValue(StackerCraneDBName.WorkType, 5);
|
}
|
}
|
}
|
|
/// <summary>
|
/// 获取任务
|
/// </summary>
|
/// <param name="commonStackerCrane">堆垛机对象</param>
|
/// <returns></returns>
|
private Dt_Task? GetTask()
|
{
|
Dt_Task task;
|
task = _taskService.QueryStackerCraneTask();
|
return task;
|
}
|
|
/// <summary>
|
/// 查询上料的堆垛机,先查询默认堆垛机,如果不正常,再查询另外一台堆垛机,如果都不正常返回null
|
/// </summary>
|
/// <returns></returns>
|
private CommonStackerCrane? GetStrackerCrane(Dt_Task task, CommonStackerCrane stackerCraneOne, CommonStackerCrane stackerCraneTwo)
|
{
|
if(task.Roadway=="SC02")
|
{
|
if (stackerCraneOne != null)
|
{
|
|
if (stackerCraneOne.StackerCraneAutoStatusValue == StackerCraneAutoStatus.Automatic && stackerCraneOne.StackerCraneStatusValue == StackerCraneStatus.Normal)
|
{
|
if (stackerCraneOne.StackerCraneWorkStatusValue == StackerCraneWorkStatus.Standby)
|
{
|
return stackerCraneOne;
|
}
|
|
}
|
else//SC02不能正常工作状态,这里需要判断sc02是否禁用,如果已禁用,才可以启动sc03
|
{
|
Dt_DeviceInfo deviceSC02 = _deviceInfoRepository.QueryFirst(x => x.DeviceCode == "SC02");
|
|
if (deviceSC02.DeviceStatus=="0"&& stackerCraneTwo != null)
|
{
|
//if (!stackerCraneTwo.IsEventSubscribed)
|
//{
|
// stackerCraneTwo.StackerCraneTaskCompletedEventHandler += CommonStackerCrane_StackerCraneTaskCompletedEventHandler;//订阅任务完成事件
|
//}
|
if (stackerCraneTwo.StackerCraneAutoStatusValue == StackerCraneAutoStatus.Automatic && stackerCraneTwo.StackerCraneStatusValue == StackerCraneStatus.Normal)
|
{
|
//stackerCraneTwo.CheckStackerCraneTaskCompleted();//防止任务完成事件监测超时,再手动触发一次
|
if (stackerCraneTwo.StackerCraneWorkStatusValue == StackerCraneWorkStatus.Standby)
|
{
|
//todo:任务表中的RoadWay切换为SC03
|
|
return stackerCraneTwo;
|
}
|
}
|
|
}
|
|
|
}
|
}
|
else
|
{
|
if(stackerCraneTwo != null)
|
{
|
if (stackerCraneTwo.StackerCraneAutoStatusValue == StackerCraneAutoStatus.Automatic && stackerCraneTwo.StackerCraneStatusValue == StackerCraneStatus.Normal)
|
{
|
if (stackerCraneTwo.StackerCraneWorkStatusValue == StackerCraneWorkStatus.Standby)
|
{
|
//todo:任务表中的RoadWay切换为SC03
|
|
return stackerCraneTwo;
|
}
|
}
|
}
|
|
}
|
}
|
else if (task.Roadway=="SC03")
|
{
|
if (stackerCraneTwo != null)
|
{
|
// if (!stackerCraneTwo.IsEventSubscribed)
|
// {
|
// stackerCraneTwo.StackerCraneTaskCompletedEventHandler += CommonStackerCrane_StackerCraneTaskCompletedEventHandler;//订阅任务完成事件
|
// }
|
if (stackerCraneTwo.StackerCraneAutoStatusValue == StackerCraneAutoStatus.Automatic && stackerCraneOne.StackerCraneStatusValue == StackerCraneStatus.Normal)
|
{
|
//stackerCraneTwo.CheckStackerCraneTaskCompleted();//防止任务完成事件监测超时,再手动触发一次
|
if (stackerCraneTwo.StackerCraneWorkStatusValue == StackerCraneWorkStatus.Standby)
|
{
|
return stackerCraneTwo;
|
}
|
}
|
else//SC03不能正常工作状态,这里需要判断sc03是否禁用,如果已禁用,才可以启动sc02
|
{
|
Dt_DeviceInfo deviceSC03 = _deviceInfoRepository.QueryFirst(x => x.DeviceCode == "SC03");
|
if (deviceSC03.DeviceStatus=="0"&&stackerCraneOne != null)
|
{
|
//if (!stackerCraneOne.IsEventSubscribed)
|
//{
|
// stackerCraneOne.StackerCraneTaskCompletedEventHandler += CommonStackerCrane_StackerCraneTaskCompletedEventHandler;//订阅任务完成事件
|
//}
|
if (stackerCraneOne.StackerCraneAutoStatusValue == StackerCraneAutoStatus.Automatic && stackerCraneTwo.StackerCraneStatusValue == StackerCraneStatus.Normal)
|
{
|
//stackerCraneOne.CheckStackerCraneTaskCompleted();//防止任务完成事件监测超时,再手动触发一次
|
if (stackerCraneOne.StackerCraneWorkStatusValue == StackerCraneWorkStatus.Standby)
|
{
|
//todo:任务表中的RoadWay切换为SC03
|
return stackerCraneOne;
|
}
|
}
|
}
|
|
}
|
}
|
else
|
{
|
if(stackerCraneOne != null)
|
{
|
if (stackerCraneOne.StackerCraneAutoStatusValue == StackerCraneAutoStatus.Automatic && stackerCraneOne.StackerCraneStatusValue == StackerCraneStatus.Normal)
|
{
|
if (stackerCraneOne.StackerCraneWorkStatusValue == StackerCraneWorkStatus.Standby)
|
{
|
return stackerCraneOne;
|
}
|
|
}
|
|
}
|
}
|
|
}
|
return null;
|
}
|
|
|
|
/// <summary>
|
/// 任务实体转换成命令Model
|
/// </summary>
|
/// <param name="task">任务实体</param>
|
/// <returns></returns>
|
/// <exception cref="Exception"></exception>
|
public StackerCraneTaskCommand? ConvertToStackerCraneTaskCommand([NotNull] Dt_Task task)
|
{
|
StackerCraneTaskCommand stackerCraneTaskCommand = new StackerCraneTaskCommand();
|
|
stackerCraneTaskCommand.Barcode = task.PalletCode;
|
stackerCraneTaskCommand.TaskNum = task.TaskNum;
|
stackerCraneTaskCommand.WorkType = 1;
|
if(string.IsNullOrEmpty(task.Remark))//总层数和层数是否为空
|
{
|
return null;
|
}
|
string[] Levels = task.Remark.Split("-");
|
if (Levels.Length == 2)
|
{
|
//托盘类型 1:9层 2:4层
|
if (!string.IsNullOrEmpty(Levels[0]))
|
{
|
if (Levels[0].ToString()=="9")
|
{
|
stackerCraneTaskCommand.TrayType = 1;
|
}
|
else
|
{
|
stackerCraneTaskCommand.TrayType = 2;
|
}
|
}
|
//料车具体的层数
|
if (!string.IsNullOrEmpty(Levels[1]))
|
{
|
stackerCraneTaskCommand.StartLayer =Convert.ToInt16(Levels[1]);
|
}
|
}
|
else
|
{
|
return null;
|
}
|
|
|
string[] SourceCodes = task.SourceAddress.Split("-");
|
if (SourceCodes.Length == 4)
|
{
|
stackerCraneTaskCommand.StartRow = Convert.ToInt16(SourceCodes[1]);
|
stackerCraneTaskCommand.StartColumn = Convert.ToInt16(SourceCodes[2]);
|
// stackerCraneTaskCommand.StartLayer = Convert.ToInt16(SourceCodes[3]);
|
}
|
else
|
{
|
//数据配置错误
|
_taskService.UpdateTaskExceptionMessage(task.TaskNum, $"任务源地址配置错误!");
|
return null;
|
}
|
string[] targetCodes = task.TargetAddress.Split("-");
|
if (targetCodes.Length == 4)
|
{
|
stackerCraneTaskCommand.EndRow = Convert.ToInt16(targetCodes[1]);
|
stackerCraneTaskCommand.EndColumn = Convert.ToInt16(targetCodes[2]);
|
stackerCraneTaskCommand.EndLayer = Convert.ToInt16(targetCodes[3]);
|
}
|
else
|
{
|
//数据配置错误
|
_taskService.UpdateTaskExceptionMessage(task.TaskNum, $"任务目标地址配置错误");
|
return null;
|
}
|
return stackerCraneTaskCommand;
|
}
|
|
|
}
|
}
|