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

332 lines
11 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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(() =>
{
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)
// {
// if (_plc.IsConnected)
// {
// 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);
// }
// else
// {
// logHelper.Info($"仓库{appConfig.foamStoreCode}PLC未连接");
// }
// }
// else
// {
// logHelper.Info($"PLC信息为空通过{appConfig.foamStoreCode}未获取到该仓库对应的PLC信息");
// }
// }
// catch (Exception ex)
// {
// logHelper.Error("读取箱壳出库出库完成异常", ex);
// }
// }
//}
}
}