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.
Aucma.Scada/Aucma.Scada.Business/OutStoreTaskHandle.cs

327 lines
11 KiB
C#

using Aucma.Scada.Model.domain;
using HighWayIot.Config;
using HighWayIot.Log4net;
using HighWayIot.Plc;
using HighWayIot.Repository.service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Aucma.Scada.Business
{
/// <summary>
/// 出库任务处理
/// </summary>
internal sealed class OutStoreTaskHandle
{
#region 单例实现
private static readonly Lazy<OutStoreTaskHandle> lazy = new Lazy<OutStoreTaskHandle>(() => new OutStoreTaskHandle());
public static OutStoreTaskHandle Instance
{
get
{
return lazy.Value;
}
}
#endregion
#region 对象引用
/// <summary>
/// PLC应答
/// </summary>
/// <param name="storeCode"></param>
/// <param name="taskCode"></param>
public delegate void OutStoreAnswer(string storeCode, string taskCode);
public event OutStoreAnswer OutStoreAnswerEvent;
private LogHelper logHelper = LogHelper.Instance;
private AppConfig appConfig = AppConfig.Instance;
private PlcConfig plcConfig = PlcConfig.Instance;
private PlcPool _pool = PlcPool.Instance;
private PlcSpaceConfig spaceConfig = PlcSpaceConfig.Instance;
private RegisterServices registerServices = RegisterServices.Instance;
private IRealTaskInfoService _taskInfoService;
#endregion
#region 私有变量
/// <summary>
/// 字典存放PLC连接
/// </summary>
private Dictionary<string, IPlc> _plcDictionary = new Dictionary<string, IPlc>();
#endregion
#region 委托事件
/// <summary>
/// 出库完成
/// </summary>
/// <param name="storeCode"></param>
/// <param name="taskCode"></param>
public delegate void OutStoreFinsih(string storeCode, string taskCode);
public event OutStoreFinsih OutStoreFinsihEvent;
#endregion
private OutStoreTaskHandle()
{
_plcDictionary = _pool.GetAll();
_taskInfoService = registerServices.GetService<IRealTaskInfoService>();
// RealReadFinish();
}
#region 出库完成
/// <summary>
/// 实时读取出库完成信号
/// </summary>
private void RealReadFinish()
{
Task.Run(() =>
{
10 months ago
Thread.Sleep(2000);
while (true)
{
RealTaskInfo task = GetTaskInfoByTaskStatus(appConfig.foamStoreCode).OrderBy(x => x.createTime).FirstOrDefault();
if(task != null)
{
if (_plcDictionary.Count > 0)
{
IPlc _plc = _plcDictionary[appConfig.foamStoreCode];
if (_plc != null)
{
//出库完成
if (_plc.readInt32ByAddress(plcConfig.out_foam_finish) == 1)
{
_plc.writeInt32ByAddress(plcConfig.out_foam_finish, 0);
OutStoreFinsihEvent?.Invoke(appConfig.foamStoreCode, task.taskCode);
}
}
else
{
logHelper.Info($"PLC信息为空或连接失败通过{appConfig.foamStoreCode}未获取到该仓库对应的PLC信息");
}
}
}
Thread.Sleep(500);
};
});
}
/// <summary>
/// 根据任务状态获取执行中的出库任务
/// </summary>
/// <param name="storeCode"></param>
/// <param name="taskStatus"></param>
private List<RealTaskInfo> GetTaskInfoByTaskStatus(string storeCode, int taskStatus = 2)
{
List<RealTaskInfo> result = null;
try
{
result = _taskInfoService.GetTaskInfosByTaskStatus(new string[] { storeCode }, appConfig.outstoreTaskType, taskStatus);
}
catch (Exception ex)
{
logHelper.Error("根据任务状态获取执行中的任务异常", ex);
}
return result;
}
#endregion
#region 泡后出库任务下发处理
/// <summary>
/// 泡后出库任务下发
/// </summary>
/// <param name="taskInfo"></param>
public int SendFoamTask_OutStore(RealTaskInfo taskInfo)
{
int result = 0;
try
{
IPlc _plc = _plcDictionary[taskInfo.storeCode];
if (_plc != null)
{
if (_plc.readInt32ByAddress(plcConfig.out_foam_answer) == 1)
{
logHelper.Info("泡后出库应答字为1货道号:" + plcConfig.out_foam_spaceCode + ";写" + short.Parse(taskInfo.spaceCode.Substring(5, 1)));
//写入货道号
_plc.writeInt32ByAddress(plcConfig.out_foam_spaceCode, short.Parse(taskInfo.spaceCode.Substring(5, 1)));
//写入出库数量
_plc.writeInt32ByAddress(plcConfig.out_foam_amount, taskInfo.planAmount);
//写入完成后读取应答字进行复位
ReadAnswer_OutStore(taskInfo);
result = 1;
}
else
{
result = 2;
logHelper.Info("应答字为2下发新任务plc未就绪");
}
}
else
{
logHelper.Info($"PLC信息为空通过{taskInfo.storeCode}未获取到该仓库对应的PLC信息");
}
}
catch (Exception ex)
{
logHelper.Error("泡后出库任务下发异常", ex);
}
return result;
}
/// <summary>
/// 读取泡后出库应答
/// </summary>
private void ReadAnswer_OutStore(RealTaskInfo taskInfo)
{
lock (string.Empty)
{
bool isFlag = true;
IPlc _plc = _plcDictionary[appConfig.foamStoreCode];
try
{
Task.Run(() =>
{
if (_plc != null)
{
do
{
//读取PLC应答字为2时上位机清空写入的出库内容
if (_plc.readInt32ByAddress(plcConfig.out_foam_answer) == 2)
{
logHelper.Info("出库应答字写3应答字为2货道号:" + plcConfig.out_foam_spaceCode + ";复位写0");
//写入货道号
_plc.writeInt32ByAddress(plcConfig.out_foam_spaceCode, 0);
//写入应答字3
_plc.writeInt32ByAddress(plcConfig.out_foam_answer, 3);
//写入出库数量
_plc.writeInt32ByAddress(plcConfig.out_foam_amount, 0);
isFlag = false;
OutStoreAnswerEvent?.Invoke(appConfig.foamStoreCode, taskInfo.taskCode);
}
Thread.Sleep(500);
} while (isFlag);
}
else
{
logHelper.Info($"PLC信息为空通过{appConfig.foamStoreCode}未获取到该仓库对应的PLC信息");
}
});
}
catch (Exception ex)
{
logHelper.Error("读取泡后出库应答字异常", ex);
}
}
}
#endregion
/// <summary>
/// 通过PLC获取货道信息
/// </summary>
/// <param name="spaceInfo"></param>
/// <returns></returns>
public BaseSpaceInfo ReadSpaceInfoByPlc(BaseSpaceInfo spaceInfo)
{
var spaceAddress = spaceConfig.GetSpaceAddress(spaceInfo.storeCode, spaceInfo.spaceCode);
IPlc _plc = _plcDictionary[spaceInfo.storeCode];
if (_plc != null)
{
spaceInfo.spaceStock = _plc.readInt32ByAddress(spaceAddress.onStore);
spaceInfo.onRouteAmount = _plc.readInt32ByAddress(spaceAddress.onRoute);
// spaceInfo.spaceStatus = _plc.readInt32ByAddress(spaceAddress.spaceStatus);
}
return spaceInfo;
}
///// <summary>
///// 读取泡后出库完成
///// </summary>
//private void ReadFinish_OutStore(RealTaskInfo taskInfo)
//{
// lock (string.Empty)
// {
// bool isFlag = true;
// IPlc _plc = _plcDictionary[appConfig.foamStoreCode];
// try
// {
// if (_plc != null)
// {
9 months ago
//
// do
// {
// //读取PLC出库任务完成
// if (_plc.readInt32ByAddress(plcConfig.out_foam_finish) == 1)
// {
// _plc.writeInt32ByAddress(plcConfig.out_foam_finish, 0);
// OutStoreFinsihEvent?.Invoke(appConfig.foamStoreCode, taskInfo.taskCode);
// isFlag = false;
// }
// Thread.Sleep(1000);
// } while (isFlag);
9 months ago
//
// }
// else
// {
// logHelper.Info($"PLC信息为空通过{appConfig.foamStoreCode}未获取到该仓库对应的PLC信息");
// }
// }
// catch (Exception ex)
// {
// logHelper.Error("读取箱壳出库出库完成异常", ex);
// }
// }
//}
}
}