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/InStoreTaskHandle.cs

430 lines
16 KiB
C#

using Aucma.Scada.Model.domain;
using HighWayIot.Config;
using HighWayIot.Log4net;
using HighWayIot.Plc;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace Aucma.Scada.Business
{
/// <summary>
/// 入库任务处理
/// </summary>
internal sealed class InStoreTaskHandle
{
#region 单例实现
private static readonly Lazy<InStoreTaskHandle> lazy = new Lazy<InStoreTaskHandle>(() => new InStoreTaskHandle());
public static InStoreTaskHandle Instance
{
get
{
return lazy.Value;
}
}
#endregion
#region 对象引用
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;
#endregion
#region 私有变量
private Dictionary<string, IPlc> _plcDictionary = new Dictionary<string, IPlc>();
/// <summary>
/// 箱壳任务编号,PLC反馈后进行赋值
/// </summary>
private string shellTaskCode = string.Empty;
/// <summary>
/// 内胆任务编号,PLC反馈后进行赋值
/// </summary>
private string linerTaskCode = string.Empty;
#endregion
#region 委托事件
/// <summary>
/// 入库完成
/// </summary>
/// <param name="storeCode"></param>
/// <param name="taskCode"></param>
public delegate void InStoreFinsih(string storeCode, string taskCode);
public event InStoreFinsih InStoreFinsihEvent;
#endregion
private InStoreTaskHandle()
{
_plcDictionary = _pool.GetAll();
}
#region 箱壳入库任务下发处理
public bool SendShellTask_InStore(RealTaskInfo taskInfo)
{
bool result = false;
try
{
IPlc _plc = _plcDictionary[taskInfo.storeCode];
if (_plc != null)
{
if (_plc.IsConnected)
{
//写入货道号
_plc.writeStringByAddress(plcConfig.in_shell_spaceCode, taskInfo.spaceCode);
//写入应答字
_plc.writeInt32ByAddress(plcConfig.in_shell_answer, 1);
//写入任务号
_plc.writeStringByAddress(plcConfig.in_shell_task, taskInfo.taskCode);
//写入完成后读取应答字进行复位
ReadShellAnswer_InStore(taskInfo.taskCode);
result = true;
}
else
{
logHelper.Info($"仓库{taskInfo.storeCode}PLC未连接");
}
}
else
{
logHelper.Info($"PLC信息为空通过{taskInfo.storeCode}未获取到该仓库对应的PLC信息");
}
}
catch (Exception ex)
{
logHelper.Error("箱壳入库任务下发异常", ex);
}
return result;
}
/// <summary>
/// 读取箱壳入库应答
/// </summary>
private void ReadShellAnswer_InStore(string taskCode)
{
lock (string.Empty)
{
bool isFlag = true;
IPlc _plc = _plcDictionary[appConfig.shellStoreCode];
try
{
Task.Run(() =>
{
if (_plc != null)
{
if (_plc.IsConnected)
{
do
{
//读取PLC应答字为2时上位机清空写入的入库内容
if (_plc.readInt32ByAddress(plcConfig.in_shell_answer) == 2)
{
//写入货道号
_plc.writeStringByAddress(plcConfig.in_shell_spaceCode, string.Empty);
//写入应答字
_plc.writeInt32ByAddress(plcConfig.in_shell_answer, 0);
//写入任务号
_plc.writeStringByAddress(plcConfig.in_shell_task, string.Empty);
isFlag = false;
ReadShellFinish_InStore(taskCode);
}
Thread.Sleep(1000);
} while (isFlag);
}
else
{
logHelper.Info($"仓库{appConfig.shellStoreCode}PLC未连接");
}
}
else
{
logHelper.Info($"PLC信息为空通过{appConfig.shellStoreCode}未获取到该仓库对应的PLC信息");
}
});
}
catch (Exception ex)
{
logHelper.Error("读取箱壳入库应答字异常", ex);
}
}
}
/// <summary>
/// 读取箱壳入库完成
/// </summary>
private void ReadShellFinish_InStore(string taskCode)
{
lock (string.Empty)
{
bool isFlag = true;
IPlc _plc = _plcDictionary[appConfig.shellStoreCode];
shellTaskCode = taskCode;
try
{
Task.Run(() =>
{
if (_plc != null)
{
if (_plc.IsConnected)
{
do
{
//读取PLC入库任务完成
if (_plc.readInt32ByAddress(plcConfig.in_shell_finish) == 1)
{
_plc.writeInt32ByAddress(plcConfig.in_shell_finish, 0);
//string taskCode = _plc.readStringByAddress(plcConfig.out_shell_task, 10);
InStoreFinsihEvent?.Invoke(appConfig.shellStoreCode, taskCode);
isFlag = false;
}
Thread.Sleep(1000);
} while (isFlag);
}
else
{
logHelper.Info($"仓库{appConfig.shellStoreCode}PLC未连接");
}
}
else
{
logHelper.Info($"PLC信息为空通过{appConfig.shellStoreCode}未获取到该仓库对应的PLC信息");
}
});
}
catch (Exception ex)
{
logHelper.Error("读取箱壳入库完成异常", ex);
}
}
}
#endregion
#region 内胆入库任务处理
/// <summary>
/// 内胆入库任务下发
/// </summary>
/// <param name="taskInfo"></param>
public bool SendLinerTask_InStore(RealTaskInfo taskInfo)
{
bool result = false;
try
{
IPlc _plc = _plcDictionary[appConfig.linerStoreCode];
if (_plc != null)
{
if (_plc.IsConnected)
{
//写入货道号
_plc.writeStringByAddress(plcConfig.in_liner_spaceCode, taskInfo.spaceCode);
//写入应答字
_plc.writeInt32ByAddress(plcConfig.in_liner_answer, 1);
//写入任务号
_plc.writeStringByAddress(plcConfig.in_liner_task, taskInfo.taskCode);
//写入完成后读取应答字进行复位
ReadLinerAnswer_InStore(taskInfo.taskCode);
result = true;
}
else
{
logHelper.Info($"仓库{taskInfo.storeCode}PLC未连接");
}
}
else
{
logHelper.Info($"PLC信息为空通过{taskInfo.storeCode}未获取到该仓库对应的PLC信息");
}
}
catch (Exception ex)
{
logHelper.Error("内胆入库任务下发异常", ex);
}
return result;
}
/// <summary>
/// 读取内胆入库应答
/// </summary>
private void ReadLinerAnswer_InStore(string taskCode)
{
lock (string.Empty)
{
bool isFlag = true;
IPlc _plc = _plcDictionary[appConfig.linerStoreCode];
linerTaskCode = taskCode;
try
{
Task.Run(() =>
{
if (_plc != null)
{
if (_plc.IsConnected)
{
do
{
//读取PLC应答字为2时上位机清空写入的入库内容
if (_plc.readInt32ByAddress(plcConfig.in_liner_answer) == 2)
{
//写入货道号
_plc.writeStringByAddress(plcConfig.in_liner_spaceCode, string.Empty);
//写入应答字
_plc.writeInt32ByAddress(plcConfig.in_liner_answer, 0);
//写入任务号
_plc.writeStringByAddress(plcConfig.in_liner_task, string.Empty);
isFlag = false;
ReadLinerFinish_InStore(taskCode);
}
Thread.Sleep(1000);
} while (isFlag);
}
else
{
logHelper.Info($"仓库{appConfig.linerStoreCode}PLC未连接");
}
}
else
{
logHelper.Info($"PLC信息为空通过{appConfig.linerStoreCode}未获取到该仓库对应的PLC信息");
}
});
}
catch (Exception ex)
{
logHelper.Error("读取内胆入库应答字异常", ex);
}
}
}
/// <summary>
/// 读取内胆入库完成
/// </summary>
private void ReadLinerFinish_InStore(string taskCode)
{
lock (string.Empty)
{
try
{
Task.Run(() =>
{
bool isFlag = true;
IPlc _plc = _plcDictionary[appConfig.linerStoreCode];
if (_plc != null)
{
if (_plc.IsConnected)
{
do
{
//读取PLC入库任务完成
if (_plc.readInt32ByAddress(plcConfig.in_liner_finish) == 1)
{
_plc.writeInt32ByAddress(plcConfig.in_liner_finish, 0);
//string taskCode = _plc.readStringByAddress(plcConfig.in_liner_task, 10);
InStoreFinsihEvent?.Invoke(appConfig.linerStoreCode, taskCode);
isFlag = false;
}
Thread.Sleep(1000);
} while (isFlag);
}
else
{
logHelper.Info($"仓库{appConfig.linerStoreCode}PLC未连接");
}
}
else
{
logHelper.Info($"PLC信息为空通过{appConfig.linerStoreCode}未获取到该仓库对应的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)
{
if (_plc.IsConnected)
{
spaceInfo.spaceStock = _plc.readInt32ByAddress(spaceAddress.onStore);
spaceInfo.onRouteAmount = _plc.readInt32ByAddress(spaceAddress.onRoute);
spaceInfo.spaceStatus = _plc.readInt32ByAddress(spaceAddress.spaceStatus);
}
}
return spaceInfo;
}
/// <summary>
/// 测试方法,联调时不用
/// </summary>
/// <param name="storeCode"></param>
/// <param name="spaceCode"></param>
/// <param name="flag"></param>
public void WritePlc(string storeCode, string spaceCode, bool flag)
{
var spaceAddress = spaceConfig.GetSpaceAddress(storeCode, spaceCode);
IPlc _plc = _plcDictionary[storeCode];
if (_plc != null)
{
if (_plc.IsConnected)
{
var spaceStock = _plc.readInt32ByAddress(spaceAddress.onStore);
var onRouteAmount = _plc.readInt32ByAddress(spaceAddress.onRoute);
if (flag)
{
_plc.writeInt32ByAddress(spaceAddress.onStore, spaceStock + 1);
_plc.writeInt32ByAddress(spaceAddress.onRoute, onRouteAmount - 1);
}
else
{
_plc.writeInt32ByAddress(spaceAddress.onRoute, onRouteAmount + 1);
}
}
}
}
}
}