using Quartz; using SqlSugar; using System.Net; using System.Threading.Tasks; using WIDESEAWCS_Common; using WIDESEAWCS_Common.Helper; using WIDESEAWCS_Core; using WIDESEAWCS_Core.BaseRepository; using WIDESEAWCS_Core.Helper; using WIDESEAWCS_ITaskInfoService; using WIDESEAWCS_Model.Models; using WIDESEAWCS_QuartzJob; using WIDESEAWCS_QuartzJob.DTO; using WIDESEAWCS_QuartzJob.Repository; using WIDESEAWCS_QuartzJob.Service; using WIDESEAWCS_Tasks.ConveyorLineJob; using ICacheService = WIDESEAWCS_Core.Caches.ICacheService; namespace WIDESEAWCS_Tasks { [DisallowConcurrentExecution] public class CommonConveyorLineJob : JobBase, IJob { private readonly ICacheService _cacheService; private readonly ITaskService _taskService; private readonly ITaskExecuteDetailService _taskExecuteDetailService; private readonly IRouterRepository _routerRepository; private readonly IRouterService _routerService; private readonly IRepository _taskRepository; private readonly IRepository _stationMangerRepository; private readonly ITaskHtyService _taskHtyService; public CommonConveyorLineJob(ICacheService cacheService, ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, IRepository stationMangerRepository, IRepository taskRepository, IRouterRepository routerRepository, IRouterService routerService, ITaskHtyService taskHtyService) { _cacheService = cacheService; _taskService = taskService; _taskExecuteDetailService = taskExecuteDetailService; _routerRepository = routerRepository; _routerService = routerService; _stationMangerRepository = stationMangerRepository; _taskRepository = taskRepository; _taskHtyService = taskHtyService; } public Task Execute(IJobExecutionContext context) { bool flag = context.JobDetail.JobDataMap.TryGetValue("JobParams", out object? value); if (flag && value != null) { OtherDevice device = (OtherDevice)value; List deviceStations = device.DeviceProDTOs.Select(x => x.DeviceChildCode).Distinct().ToList();//获取设备下的站台 List stationMangers = _stationMangerRepository.QueryData(x => x.StationDeviceCode == device.DeviceCode); //获取设备下的站台 try { foreach (var item in stationMangers.Where(x => deviceStations.Contains(x.StationCode))) //循环设备下的站台 { DeviceProDTO? deviceProRead = device.DeviceProDTOs.Where(x => x.DeviceChildCode == item.StationCode && x.DeviceProParamType == nameof(R_ConveyorLineDB)).OrderBy(x => x.DeviceProOffset).FirstOrDefault(); //输送线读取的全部协议 DeviceProDTO? deviceProWrite = device.DeviceProDTOs.Where(x => x.DeviceChildCode == item.StationCode && x.DeviceProParamType == nameof(W_ConveyorLineDB)).OrderBy(x => x.DeviceProOffset).FirstOrDefault(); //输送线写入的全部协议 if (deviceProRead != null && deviceProWrite != null) //读取写入的协议判断是否为null { R_ConveyorLineInfo conveyorLineInfoRead = device.Communicator.ReadCustomer(deviceProRead.DeviceProAddress); //读取协议 W_ConveyorLineInfo conveyorLineInfoWrite = device.Communicator.ReadCustomer(deviceProWrite.DeviceProAddress); //写入协议 if (conveyorLineInfoRead == null || conveyorLineInfoWrite == null) { continue; } R_ConveyorLineStatus conveyorLineStatus = conveyorLineInfoRead.Status.ByteToBoolObject(); //获取设备状态 ConveyorLineSignal conveyorLineSignalRead = conveyorLineInfoRead.Signal.ByteToBoolObject(); //获取设备信号 bool ACK = device.GetValue(W_ConveyorLineDB.ACK, item.StationCode); //获取ACK确认信息 bool STB = device.GetValue(W_ConveyorLineDB.STB, item.StationCode); //获取STB请求信息 //ConveyorLineSignal conveyorLineSignalWrite = conveyorLineInfoWrite.Signal.ByteToBoolObject(); //出库站台 if (item.StationType == StationTypeEnum.StationType_OnlyOutbound.ObjToInt()) //2007交互口进入 { //WriteLog.Write_Log("2楼出库2007交互流程,堆垛机完成出库任务完成", $"{item.StationType}库流程", $"与2007进行交互,站台编号:{item.StationCode}",item.StationType); // 出库 if (conveyorLineSignalRead.STB && !conveyorLineSignalRead.ACK && conveyorLineStatus.Online && conveyorLineStatus.Goods && !conveyorLineStatus.Alarm && !STB && !ACK)//2楼出库 { if (!string.IsNullOrEmpty(conveyorLineInfoRead.Barcode)) { Dt_Task dt_Ta = _taskService.GetOutTaskInfo2(conveyorLineInfoRead.Barcode); WriteLog.Write_Log("2楼出库流程", $"{item.StationCode}出库流程", $"获取2楼出库任务,托盘条码:{dt_Ta.PalletCode}", dt_Ta); if (dt_Ta != null) { WriteLog.Write_Log("2出库流程", $"{item.StationCode}出库流程",$"获取出库任务成功开始向plc写入命令,托盘条码:taskno:{dt_Ta.TaskNum}------endpos:{dt_Ta.OutboundPlatform}--------stb:{ACK}"); device.SetValue(W_ConveyorLineDB.TaskNo, dt_Ta.TaskNum, item.StationCode); bool endpos = device.SetValue(W_ConveyorLineDB.EndPos, dt_Ta.OutboundPlatform, item.StationCode); device.SetValue(W_ConveyorLineDB.ACK, true, item.StationCode); WriteLog.Write_Log("2楼出库流程", $"{item.StationCode}出库流程", $"开始删除任务,托盘条码:{dt_Ta.PalletCode}"); //删除任务 _taskRepository.DeleteData(dt_Ta); _taskHtyService.AddTaskHistory(dt_Ta, "自动完成"); } } } else if (!conveyorLineSignalRead.STB && !conveyorLineSignalRead.ACK && conveyorLineStatus.Online && conveyorLineStatus.Goods && !conveyorLineStatus.Alarm && !STB && ACK) { device.SetValue(W_ConveyorLineDB.ACK, false, item.StationCode); } } //出入库站台 else if (item.StationType == StationTypeEnum.StationType_InboundAndOutbound.ObjToInt()) { //输送线完成修改成输送线完成状态待堆垛机执行任务 if (conveyorLineSignalRead.STB && conveyorLineStatus.Online && conveyorLineStatus.Goods && !conveyorLineStatus.Alarm && !ACK) { Dt_Task dt_Task = _taskService.GetTaskIninfo(conveyorLineInfoRead.Barcode); WriteLog.Write_Log("1-2-3-4-5入库流程", $"{item.StationCode}入库流程", $"获取入库任务,托盘条码:{dt_Task.PalletCode}", dt_Task); if (!string.IsNullOrEmpty(conveyorLineInfoRead.Barcode)&& dt_Task !=null) { bool ack = device.SetValue(W_ConveyorLineDB.ACK, true, item.StationCode); bool taskno = device.SetValue(W_ConveyorLineDB.TaskNo,1, item.StationCode); WriteLog.Write_Log("1-3-4-5出入库流程", $"{item.StationCode}出库流程", $"获取出库任务成功开始向plc写入命令,托盘条码:{dt_Task.PalletCode},taskno:{taskno}------ack:{ack}"); WebResponseContent contentweb = _taskService.UpdateTaskIninfo(conveyorLineInfoRead.Barcode,item.StationCode); //根据条码跟设备编号去查询并修改任务 WriteLog.Write_Log("1-3-4-5出入库流程", $"{item.StationCode}入库流程", $"向plc写入成功开始修改任务,托盘条码:{dt_Task.PalletCode},修改任务是否成功{contentweb.Status}"); if (contentweb.Status) { } } } else if (!conveyorLineSignalRead.STB && conveyorLineStatus.Online && conveyorLineStatus.Goods && !conveyorLineStatus.Alarm && ACK) { device.SetValue(W_ConveyorLineDB.ACK, false, item.StationCode); } /*else if (!conveyorLineSignalRead.STB && !conveyorLineSignalRead.ACK && conveyorLineStatus.Online && conveyorLineStatus.Free && !conveyorLineStatus.Goods && !conveyorLineStatus.Alarm && !STB && !ACK && conveyorLineInfoRead.TaskNo == 0)//出库 { Dt_Task task = _taskRepository.QueryFirst(x => x.CurrentAddress == item.StationCode && x.TaskState == TaskStatusEnum.New.ObjToInt() && x.DeviceCode == item.StationDeviceCode && _taskService.TaskOutboundTypes.Contains(x.TaskType)); if (task != null ) { Dt_Router routers = _routerRepository.QueryFirst(x => x.StartPosi == item.StationCode); if (routers != null) { deviceProRead = device.DeviceProDTOs.Where(x => x.DeviceChildCode == routers.NextPosi && x.DeviceProParamType == nameof(R_ConveyorLineDB)).OrderBy(x => x.DeviceProOffset).FirstOrDefault(); if (deviceProRead != null) { R_ConveyorLineInfo conveyorLineInfoRead2 = device.Communicator.ReadCustomer(deviceProRead.DeviceProAddress); ConveyorLineSignal conveyorLineSignalRead2 = conveyorLineInfoRead2.Signal.ByteToBoolObject(); R_ConveyorLineStatus conveyorLineStatus2 = conveyorLineInfoRead2.Status.ByteToBoolObject(); if (!conveyorLineSignalRead2.STB && !conveyorLineSignalRead2.ACK && conveyorLineStatus.Online && conveyorLineStatus2.Free && !conveyorLineStatus2.Goods && !conveyorLineStatus2.Alarm && !STB && !ACK)//判断出库口是否空闲 { Dt_StationManger? stationManger = stationMangers.FirstOrDefault(x => x.StationCode == item.StationCode); if (stationManger == null) { WriteError(item.StationName, $"未找到对应站台信息,设备编号:{item.StationCode},任务号:{task.TaskNum}"); continue; } _taskService.UpdateTask(task, TaskStatusEnum.SC_Execute, nextAddress: routers.NextPosi, targetAddress: routers.NextPosi); } } } } }*/ Dt_Task dt_Tas = _taskService.GetOutTaskInfo(item.StationCode); //获取出库任务 if (dt_Tas != null) { WriteLog.Write_Log("1-3-4-5出库流程", $"{item.StationCode}出库流程", $"获取出库任务,托盘条码:{dt_Tas.PalletCode}", new { 取反conveyorLineSignalReadSTB = !conveyorLineSignalRead.STB, 取反conveyorLineSignalReadACK = !conveyorLineSignalRead.ACK, 联机conveyorLineStatusOnline = conveyorLineStatus.Online, 有无货conveyorLineStatusGoods = conveyorLineStatus.Goods, 故障或正常取反conveyorLineStatusAlarm = !conveyorLineStatus.Alarm, 取反本地STB = !STB, 取反本地ACK = !ACK }); } else if (!conveyorLineSignalRead.STB && !conveyorLineSignalRead.ACK && conveyorLineStatus.Online && conveyorLineStatus.Goods && !conveyorLineStatus.Alarm && !STB && !ACK)//其他楼层出库 { Dt_Task dt_Ta = _taskService.GetOutTaskInfo(item.StationCode); //获取出库任务 WriteLog.Write_Log("1-3-4-5出库流程",$"{item.StationCode}出库流程",$"获取出库任务,托盘条码:{dt_Ta.PalletCode}",dt_Ta); if (dt_Ta != null) { bool taskno = device.SetValue(W_ConveyorLineDB.TaskNo, dt_Ta.TaskNum, item.StationCode); bool endpos = device.SetValue(W_ConveyorLineDB.EndPos, dt_Ta.OutboundPlatform, item.StationCode); bool stb = device.SetValue(W_ConveyorLineDB.STB, true, item.StationCode); WriteLog.Write_Log("1-3-4-5出库流程", $"{item.StationCode}出库流程",$"获取出库任务成功开始向plc写入命令,托盘条码:{dt_Ta.PalletCode},taskno:{taskno}------endpos:{endpos}--------stb:{stb}"); if (taskno && endpos && stb) { //堆垛机任务完成下一地址改成输送线下一地址,设备编号改成输送线 WebResponseContent webResponse = _taskService.UpdateTaskStatusToNext(dt_Ta.TaskNum); WriteLog.Write_Log("1-3-4-5出库流程",$"{item.StationCode}出库流程",$"向plc写入成功开始修改任务,托盘条码:{dt_Ta.PalletCode},修改任务是否成功{webResponse.Status}"); if (webResponse.Status) { if (dt_Ta.TargetAddress != "2021" && dt_Ta.TargetAddress != "2020") { //删除任务 bool res = _taskRepository.DeleteData(dt_Ta); WriteLog.Write_Log("1-3-4-5出库流程", $"{item.StationCode}出库流程",$"修改任务成功开始删除任务,托盘条码:{dt_Ta.PalletCode},删除任务是否成功{res}"); if (res) { _taskHtyService.AddTaskHistory(dt_Ta, "自动完成"); } } } } } } else if (!conveyorLineSignalRead.STB && conveyorLineSignalRead.ACK && conveyorLineStatus.Online && conveyorLineStatus.Goods && !conveyorLineStatus.Alarm && STB && !ACK) { device.SetValue(W_ConveyorLineDB.STB, false, item.StationCode); }//清楚确认信号 } //入库站台 else if (item.StationType == StationTypeEnum.StationType_OnlyInbound.ObjToInt()) //2014交互口 { if (conveyorLineSignalRead.STB && conveyorLineStatus.Online && conveyorLineStatus.Goods && !conveyorLineStatus.Alarm && !ACK) { Dt_Task dt_Task = _taskService.GetTaskIninfo(conveyorLineInfoRead.Barcode); WriteLog.Write_Log("2楼入库流程", $"{item.StationCode}入库流程", $"托盘条码:{dt_Task.PalletCode},任务{dt_Task}"); if (conveyorLineInfoRead.TaskNo == 0 && !string.IsNullOrEmpty(conveyorLineInfoRead.Barcode)&& dt_Task != null)//采购入库 { Dt_Task dt_Ta = _taskService.GetTaskIninfo(conveyorLineInfoRead.Barcode); //通过条码去查询任务 if (dt_Ta != null) { bool endpos = device.SetValue(W_ConveyorLineDB.EndPos, dt_Ta.SourceAddress, item.StationCode); bool taskno = device.SetValue(W_ConveyorLineDB.TaskNo, dt_Ta.TaskNum, item.StationCode); bool ack = device.SetValue(W_ConveyorLineDB.ACK, true, item.StationCode); WriteLog.Write_Log("2楼入库流程", $"{item.StationCode}入库流程", $"获取入库任务成功开始向plc写入命令,托盘条码:{dt_Ta.PalletCode},taskno:{taskno}------endpos:{endpos}--------ack:{ack}"); } } } if (!conveyorLineSignalRead.STB && conveyorLineStatus.Online && conveyorLineStatus.Goods && !conveyorLineStatus.Alarm && ACK) { device.SetValue(W_ConveyorLineDB.ACK, false, item.StationCode); } } } } } catch (Exception ex) { //throw; } } return Task.CompletedTask; } //获取拣选状态有无货状态 public static bool GetPick() { //bool IsOccupied2008 = device.GetValue(W_ConveyorLineDB.IsOccupied, "2008"); //bool IsOccupied2009 = device.GetValue(W_ConveyorLineDB.IsOccupied, "2009"); //bool IsOccupied2015 = device.GetValue(W_ConveyorLineDB.IsOccupied, "2015"); //bool IsOccupied2016 = device.GetValue(W_ConveyorLineDB.IsOccupied, "2016"); ////判断是否成立 //if (IsOccupied2008&&IsOccupied2009&&IsOccupied2015&&IsOccupied2016) //{ // return false; //} //else //{ // return true; //} return true; } } }