@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Linq ;
using System.Linq ;
using System.Threading ;
using System.Threading ;
using System.Threading.Tasks ;
using System.Threading.Tasks ;
using static Aucma . Scada . Business . OutStoreTaskHandle ;
namespace Aucma.Scada.Business
namespace Aucma.Scada.Business
{
{
@ -113,7 +114,11 @@ namespace Aucma.Scada.Business
_recordOutStoreService = registerServices . GetService < IRecordOutStoreService > ( ) ;
_recordOutStoreService = registerServices . GetService < IRecordOutStoreService > ( ) ;
_recordProductfinishService = registerServices . GetService < IRecordProductfinishService > ( ) ;
_recordProductfinishService = registerServices . GetService < IRecordProductfinishService > ( ) ;
assemblyPlanBusiness . NextPassExecutePlanInfoEvent + = PlanHandle ;
assemblyPlanBusiness . NextPassExecutePlanInfoEvent + = PlanHandle ;
taskHandleBusiness . OutStoreFinsihEvent + = TaskFeedback ;
//taskHandleBusiness.OutStoreFinsihEvent += TaskFeedback;
taskHandleBusiness . OutStoreAnswerEvent + = OutStoreAnswer ;
taskHandleBusiness . OutStoreFinsihEvent + = OutStoreFinish ;
StartPassDown ( ) ;
StartPassDown ( ) ;
}
}
@ -161,7 +166,15 @@ namespace Aucma.Scada.Business
{
{
PrintLogInfoMessage ( $"匹配货道:{spaceInfo.spaceName}" ) ;
PrintLogInfoMessage ( $"匹配货道:{spaceInfo.spaceName}" ) ;
// RefreshScanMateriaCodeEvent?.Invoke(materiaclCode, materialType, spaceInfo.spaceName, storeCode); //刷新界面扫码信息
// RefreshScanMateriaCodeEvent?.Invoke(materiaclCode, materialType, spaceInfo.spaceName, storeCode); //刷新界面扫码信息
CreateOutStoreTask ( spaceInfo , planCode , taskCode ) ; //创建出库任务
bool result = CreateOutStoreTask ( spaceInfo , planCode , taskCode ) ; //创建出库任务
if ( result )
{
PrintLogInfoMessage ( "出库任务创建成功" ) ;
}
else
{
PrintLogInfoMessage ( "出库任务创建失败" ) ;
}
}
}
else
else
{
{
@ -304,134 +317,183 @@ namespace Aucma.Scada.Business
/// <summary>
/// <summary>
/// 依次获取任务队列进行下发
/// 依次获取任务队列进行下发
/// </summary>
/// </summary>
/// <param name="source"></param>
/// <param name="e"></param>
private void PassDownTaskInfo ( )
private void PassDownTaskInfo ( )
{
{
string taskCode = string . Empty ;
try
string executePlanCode = string . Empty ;
int iFlag = 0 ;
completedTasks = 0 ;
//获取待执行的出库任务下发至PLC,并将任务状态改为执行中
var taskInfoList = GetAwaitSendTask ( ) ;
if ( taskInfoList . Count > 0 )
{
taskAmount = taskInfoList . Count ; //下发的任务数量, 默认2( 泡后、内胆) , 泡后、内胆均执行完成后才会释放信号量
foreach ( var item in taskInfoList )
{
taskCode = item . taskCode ;
executePlanCode = item . planCode ;
if ( taskHandleBusiness . SendFoamTask_OutStore ( item ) )
{
{
PrintLogInfoMessage ( $"下发泡后出库任务:{item.taskCode};仓库{item.storeCode};货道:{item.spaceCode}; 等待PLC执行反馈" ) ;
RealTaskInfo taskInfo = _taskInfoService . GetTaskInfoByStoreCode ( appConfig . foamStoreCode , appConfig . outstoreTaskType ) ;
item . taskStatus = 2 ;
if ( taskInfo ! = null )
iFlag + + ;
}
else
{
{
PrintLogInfoMessage ( $"泡后出库任务:{item.taskCode}; 下发失败, 请排除PLC连接" ) ;
PrintLogInfoMessage ( $"下发出库任务:{taskInfo.taskCode};仓库{taskInfo.storeCode};货道:{taskInfo.spaceCode}" ) ;
continue ;
}
_taskInfoService . UpdateTaskInfo ( item ) ;
RefreshScanMateriaCodeEvent ? . Invoke ( item . materialCode , item . materialType , item . spaceName , item . storeCode ) ;
}
if ( taskHandleBusiness . SendFoamTask_OutStore ( taskInfo ) )
if ( iFlag = = taskInfoList . Count )
{
{
inStoreBusiness . IssueOutTask ( ) ;
PrintLogInfoMessage ( $"出库任务:{taskInfo.taskCode}; 下发成功, 等待PLC执行反馈" ) ;
semaphore . Wait ( ) ; //一直堵塞直到信号量释放
semaphore . Wait ( ) ; //一直堵塞直到信号量释放
inStoreBusiness . IssueInTask ( ) ;
PrintLogInfoMessage ( $"出库任务:{taskInfo.taskCode};开始执行" ) ;
PrintLogInfoMessage ( $"出库任务:{taskCode};执行完成" ) ;
taskInfo . taskStatus = 2 ;
UpdatePlanInfo ( executePlanCode ) ;
_taskInfoService . UpdateTaskInfo ( taskInfo ) ;
RefreshScanMateriaCodeEvent ? . Invoke ( taskInfo . materialCode , taskInfo . materialType , taskInfo . spaceName , taskInfo . storeCode ) ;
RefreshStoreStockEvent ? . Invoke ( ) ;
}
}
}
else
else
{
{
PrintLogInfoMessage ( "未获取到需要下发的出库任务" ) ;
PrintLogInfoMessage ( $"出库任务:{taskInfo.taskCode}; 下发失败, 请排除PLC连接" ) ;
}
}
Thread . Sleep ( 3000 ) ;
}
/// <summary>
/// 获取待执行的出库任务
/// </summary>
/// <returns></returns>
private List < RealTaskInfo > GetAwaitSendTask ( )
{
List < RealTaskInfo > taskInfos = new List < RealTaskInfo > ( ) ;
try
{
RealTaskInfo foamTaskInfo = _taskInfoService . GetTaskInfoByStoreCode ( appConfig . foamStoreCode , 2 ) ;
if ( foamTaskInfo ! = null )
{
taskInfos . Add ( foamTaskInfo ) ;
//获取与泡后任务匹配的内胆任务
RealTaskInfo linerTaskInfo = _taskInfoService . GetTaskInfoByTaskCode ( foamTaskInfo . taskCode , appConfig . linerStoreCode ) ;
if ( linerTaskInfo ! = null ) taskInfos . Add ( linerTaskInfo ) ;
}
}
else
else
{
{
RealTaskInfo linerInfo = _taskInfoService . GetTaskInfoByStoreCode ( appConfig . linerStoreCode , 2 ) ;
PrintLogInfoMessage ( "未获取到需要下发的内胆出库任务" ) ;
if ( linerInfo ! = null ) taskInfos . Add ( linerInfo ) ;
}
}
}
}
catch ( Exception ex )
catch ( Exception ex )
{
{
PrintLogErrorMessage ( " 获取待执行的出库任务 异常", ex ) ;
PrintLogErrorMessage ( "下传出库任务逻辑处理异常" , ex ) ;
}
}
return taskInfos ;
}
}
#region 原下发逻辑 Delete By wenjy 2023-11-15 15:54:00
/// <summary>
/// <summary>
/// PLC任务执行反馈
/// 依次获取任务队列进行下发
/// </summary>
/// </summary>
/// <param name="storeCode"></param>
/// <param name="source"></param>
/// <param name="taskCode"></param>
/// <param name="e"></param>
private void TaskFeedback ( string storeCode , string taskCode )
//private void PassDownTaskInfo()
{
//{
FoamTaskFeedback ( taskCode ) ;
// try
}
// {
// string taskCode = string.Empty;
// string executePlanCode = string.Empty;
// int iFlag = 0;
// completedTasks = 0;
// //获取待执行的出库任务下发至PLC,并将任务状态改为执行中
// var taskInfoList = GetAwaitSendTask();
// if (taskInfoList.Count > 0)
// {
// taskAmount = taskInfoList.Count; //下发的任务数量, 默认2( 泡后、内胆) , 泡后、内胆均执行完成后才会释放信号量
// foreach (var item in taskInfoList)
// {
// taskCode = item.taskCode;
// executePlanCode = item.planCode;
// if (taskHandleBusiness.SendFoamTask_OutStore(item))
// {
// PrintLogInfoMessage($"下发泡后出库任务:{item.taskCode};仓库{item.storeCode};货道:{item.spaceCode}; 等待PLC执行反馈");
// iFlag++;
// item.taskStatus = 2;
// }
// else
// {
// PrintLogInfoMessage($"泡后出库任务:{item.taskCode}; 下发失败, 请排除PLC连接");
// continue;
// }
// _taskInfoService.UpdateTaskInfo(item);
// RefreshScanMateriaCodeEvent?.Invoke(item.materialCode, item.materialType, item.spaceName, item.storeCode);
// }
// if (iFlag == taskInfoList.Count)
// {
// inStoreBusiness.IssueOutTask();
// semaphore.Wait(); //一直堵塞直到信号量释放
// inStoreBusiness.IssueInTask();
// PrintLogInfoMessage($"出库任务:{taskCode};执行完成");
// UpdatePlanInfo(executePlanCode);
// RefreshStoreStockEvent?.Invoke();
// }
// }
// else
// {
// PrintLogInfoMessage("未获取到需要下发的出库任务");
// }
// }catch(Exception ex)
// {
// PrintLogErrorMessage("下传出库任务逻辑处理异常", ex);
// }
// Thread.Sleep(3000);
//}
///// <summary>
///// 获取待执行的出库任务
///// </summary>
///// <returns></returns>
//private List<RealTaskInfo> GetAwaitSendTask()
//{
// List<RealTaskInfo> taskInfos = new List<RealTaskInfo>();
// try
// {
// RealTaskInfo foamTaskInfo = _taskInfoService.GetTaskInfoByStoreCode(appConfig.foamStoreCode, 2);
// if (foamTaskInfo != null)
// {
// taskInfos.Add(foamTaskInfo);
// //获取与泡后任务匹配的内胆任务
// RealTaskInfo linerTaskInfo = _taskInfoService.GetTaskInfoByTaskCode(foamTaskInfo.taskCode, appConfig.linerStoreCode);
// if (linerTaskInfo != null) taskInfos.Add(linerTaskInfo);
// }
// else
// {
// RealTaskInfo linerInfo = _taskInfoService.GetTaskInfoByStoreCode(appConfig.linerStoreCode, 2);
// if (linerInfo != null) taskInfos.Add(linerInfo);
// }
// }
// catch (Exception ex)
// {
// PrintLogErrorMessage("获取待执行的出库任务异常", ex);
// }
// return taskInfos;
//}
# endregion
#region PLC应答反馈
/// <summary>
/// <summary>
/// 泡后执行反馈
/// 出库应答
/// </summary>
/// </summary>
private void FoamTaskFeedback ( string taskCode )
/// <param name="storeCode"></param>
/// <param name="taskCode"></param>
private void OutStoreAnswer ( string storeCode , string taskCode )
{
{
Interlocked . Increment ( ref completedTasks ) ;
PrintLogInfoMessage ( "PLC应答成功, 自动释放信号量, 进行下发新任务" ) ;
CheckCompletedTasks ( ) ;
PrintLogInfoMessage ( "泡后执行完成,自动释放信号量" ) ;
semaphore . Release ( ) ;
OutStoreFinish ( taskCode , appConfig . foamStoreCode ) ;
inStoreBusiness. IssueOutTask ( ) ; //阻塞入库
}
}
/// <summary>
/// <summary>
/// 信号量释放,根据任务完成数量,执行完成后进行释放
/// 出库完成
/// </summary>
/// </summary>
private void CheckCompletedTasks ( )
/// <param name="storeCode"></param>
{
/// <param name="taskCode"></param>
if ( completedTasks = = taskAmount )
private void OutStoreFinish ( string storeCode , string taskCode )
{
{
// 释放信号量
PrintLogInfoMessage ( $"出库任务:{taskCode};执行完成" ) ;
semaphore . Release ( ) ;
OutStoreFinishHandle ( taskCode , appConfig . linerStoreCode ) ;
}
inStoreBusiness . IssueInTask ( ) ; //释放入库
}
}
# endregion
# endregion
# endregion
@ -442,7 +504,7 @@ namespace Aucma.Scada.Business
/// <param name="storeCode"></param>
/// <param name="storeCode"></param>
/// <param name="spaceCode"></param>
/// <param name="spaceCode"></param>
/// <param name="materialType"></param>
/// <param name="materialType"></param>
private void OutStoreFinish ( string taskCode , string storeCode )
private void OutStoreFinish Handle ( string taskCode , string storeCode )
{
{
try
try
{
{
@ -453,6 +515,7 @@ namespace Aucma.Scada.Business
if ( spaceInfo ! = null )
if ( spaceInfo ! = null )
{
{
taskHandleBusiness . WritePlc ( spaceInfo . storeCode , spaceInfo . spaceCode ) ;
//读取PLC获取货道信息: 存放数量、在途数量
//读取PLC获取货道信息: 存放数量、在途数量
spaceInfo . spaceStock - = 1 ;
spaceInfo . spaceStock - = 1 ;
spaceInfo . outRouteAmount - = 1 ;
spaceInfo . outRouteAmount - = 1 ;
@ -470,8 +533,6 @@ namespace Aucma.Scada.Business
}
}
_spaceInfoService . UpdateSpaceInfo ( spaceInfo ) ;
_spaceInfoService . UpdateSpaceInfo ( spaceInfo ) ;
//读取PLC获取物料类型进行绑定
#region 添加出库记录
#region 添加出库记录
RecordOutstore recordOutstore = new RecordOutstore ( ) ;
RecordOutstore recordOutstore = new RecordOutstore ( ) ;
recordOutstore . storeCode = taskInfo . storeCode ;
recordOutstore . storeCode = taskInfo . storeCode ;
@ -484,6 +545,12 @@ namespace Aucma.Scada.Business
_recordOutStoreService . InsertReocrdOutStoreService ( recordOutstore ) ;
_recordOutStoreService . InsertReocrdOutStoreService ( recordOutstore ) ;
# endregion
# endregion
}
}
//更新计划信息
UpdatePlanInfo ( taskInfo . planCode ) ;
RefreshStoreStockEvent ? . Invoke ( ) ;
//清除任务信息
//清除任务信息
_taskInfoService . DeleteTaskInfo ( taskCode , storeCode ) ;
_taskInfoService . DeleteTaskInfo ( taskCode , storeCode ) ;
@ -679,6 +746,8 @@ namespace Aucma.Scada.Business
return materialName ;
return materialName ;
}
}
#region 通过PLC读取货道信息
/// <summary>
/// 通过PLC读取货道信息( 在库数量、货道状态)
/// 通过PLC读取货道信息( 在库数量、货道状态)
/// </summary>
/// </summary>
/// <param name="storeCode"></param>
/// <param name="storeCode"></param>
@ -690,7 +759,7 @@ namespace Aucma.Scada.Business
try
try
{
{
List < BaseSpaceInfo > info = _spaceInfoService . GetBaseSpaceInfosByMaterialTyp e( storeCode , materialType ) ;
List < BaseSpaceInfo > info = _spaceInfoService . OutStoreGetSpaceInfoByMaterialCod e( storeCode , materialType ) ;
if ( info ! = null )
if ( info ! = null )
{
{
@ -702,9 +771,21 @@ namespace Aucma.Scada.Business
item . spaceStock = spaceInfo . spaceStock ;
item . spaceStock = spaceInfo . spaceStock ;
item . onRouteAmount = spaceInfo . onRouteAmount ;
item . onRouteAmount = spaceInfo . onRouteAmount ;
item . spaceStatus = spaceInfo . spaceStatus ;
item . spaceStatus = spaceInfo . spaceStatus ;
PrintLogInfoMessage ( $"通过PLC读取货道信息, 货道: {spaceInfo.spaceName};在库数量:{item.spaceStock};货道状态:{item.spaceStatus}" ) ;
}
}
result = info . Where ( x = > x . spaceStatus = = 1 & & x . spaceStock > 0 ) . OrderBy ( x = > x . spaceStock ) . OrderBy ( x = > x . spaceCode ) . First ( ) ;
//result = info.Where(x => x.spaceStatus == 1 && x.spaceStock > 0).OrderBy(x => x.spaceStock).OrderBy(x => x.spaceCode).First();
var list = info . Where ( x = > x . spaceStatus = = 1 & & x . spaceStock > 0 ) . ToList ( ) ;
if ( list . Count > 0 )
{
result = info . OrderBy ( x = > x . spaceStock ) . OrderBy ( x = > x . spaceCode ) . First ( ) ;
}
else
{
PrintLogInfoMessage ( "未获取到匹配的货道,请排查货道库存及货道状态是否可用" ) ;
}
}
}
}
}
@ -716,5 +797,6 @@ namespace Aucma.Scada.Business
return result ;
return result ;
}
}
# endregion
}
}
}
}