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.Threading;
using System.Threading.Tasks;
namespace Aucma.Scada.Business
{
///
/// 入库任务处理
///
internal sealed class InStoreTaskHandle
{
#region 单例实现
private static readonly Lazy lazy = new Lazy(() => 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;
private RegisterServices registerServices = RegisterServices.Instance;
///
/// 实时任务
///
private IRealTaskInfoService _taskInfoService;
#endregion
#region 私有变量
private Dictionary _plcDictionary = new Dictionary();
///
/// 泡后任务编号,PLC反馈后进行赋值
///
private string foamTaskCode = string.Empty;
#endregion
#region 委托事件
///
/// 入库应答,PLC收到下发的入库任务后进行应答
///
///
///
public delegate void InStoreAnswer(string storeCode, string taskCode);
public event InStoreAnswer InStoreAnswerEvent;
///
/// 入库完成
///
///
public delegate void InStoreFinsih(string taskCode);
public event InStoreFinsih InStoreFinsihEvent;
#endregion
private InStoreTaskHandle()
{
_taskInfoService = registerServices.GetService();
_plcDictionary = _pool.GetAll();
List taskList = _taskInfoService.GetTaskInfosForInstore(appConfig.foamStoreCode, appConfig.instoreTaskType, 2);
RealReadFinish();
}
#region 判断入库是否完成
///
/// 实时读取入库完成信号
///
private void RealReadFinish()
{
Task.Run(() =>
{
Thread.Sleep(2000);
while (true)
{
if (_plcDictionary.Count > 0)
{
IPlc _plc = _plcDictionary[appConfig.foamStoreCode];
if (_plc != null && _plc.IsConnected)
{
List taskList = _taskInfoService.GetTaskInfosForInstore(appConfig.foamStoreCode, appConfig.instoreTaskType, 2);
if (taskList != null && taskList.Count > 0)
{
foreach (RealTaskInfo taskInfo in taskList)
{
SpaceAddress spaceAddress = spaceConfig.GetSpaceAddress(appConfig.foamStoreCode, taskInfo.spaceCode);
JudgeIsFinish(taskInfo, _plc, spaceAddress);
}
}
}
else
{
logHelper.Info($"PLC信息为空或连接失败,通过{appConfig.foamStoreCode}未获取到该仓库对应的PLC信息");
}
}
Thread.Sleep(1000);
};
});
}
///
/// 判断该任务对应的货道是否有完成信号
///
///
///
public void JudgeIsFinish(RealTaskInfo taskInfo,IPlc _plc,SpaceAddress spaceAddress)
{
//读取入库完成反馈信号
if (_plc.readInt32ByAddress(spaceAddress.inStoreFinish) == 1)
{
_plc.writeInt32ByAddress(spaceAddress.inStoreFinish, 0);
InStoreFinsihEvent(taskInfo.taskCode);
}
}
#endregion
#region 泡后入库任务下发处理
public int SendFoamTask_InStore(RealTaskInfo taskInfo)
{
int result = 0;
try
{
IPlc _plc = _plcDictionary[taskInfo.storeCode];
if (_plc != null)
{
if (_plc.IsConnected)
{
if (_plc.readInt32ByAddress(plcConfig.in_foam_answer) == 1)
{
logHelper.Info("泡后入库应答字为1,货道号:" + plcConfig.in_foam_spaceCode + ";写" + short.Parse(taskInfo.spaceCode.Substring(5, 1)));
//写入货道号
_plc.writeInt32ByAddress(plcConfig.in_foam_spaceCode, short.Parse(taskInfo.spaceCode.Substring(5, 1)));
//写入应答字
// _plc.writeInt32ByAddress(plcConfig.in_foam_answer, 1);
//写入任务号
// _plc.writeStringByAddress(plcConfig.in_foam_task, taskInfo.taskCode);
//写入完成后读取应答字进行复位
ReadAnswer_InStore(taskInfo);
result = 1;
}
else
{
result = 2;
logHelper.Info("应答字为2,下发新任务plc未就绪");
}
}
else
{
logHelper.Info($"仓库{taskInfo.storeCode};PLC未连接");
}
}
else
{
logHelper.Info($"PLC信息为空,通过{taskInfo.storeCode}未获取到该仓库对应的PLC信息");
}
}
catch (Exception ex)
{
logHelper.Error("泡后入库任务下发异常", ex);
}
return result;
}
///
/// 读取泡后入库应答
///
private void ReadAnswer_InStore(RealTaskInfo taskInfo)
{
lock (string.Empty)
{
bool isFlag = true;
IPlc _plc = _plcDictionary[appConfig.foamStoreCode];
try
{
Task.Run(() =>
{
if (_plc != null)
{
if (_plc.IsConnected)
{
do
{
//读取PLC应答字为2时,上位机清空写入的入库内容
if (_plc.readInt32ByAddress(plcConfig.in_foam_answer) == 2)
{
logHelper.PlcLog("入库应答字为2,货道号:" + plcConfig.in_foam_spaceCode + ";复位写0");
//写入货道号
_plc.writeInt32ByAddress(plcConfig.in_foam_spaceCode, 0);
//写入应答字
// _plc.writeInt32ByAddress(plcConfig.in_foam_answer, 0);
isFlag = false;
InStoreAnswerEvent?.Invoke(appConfig.foamStoreCode, taskInfo.taskCode);
}
Thread.Sleep(500);
} while (isFlag);
}
else
{
logHelper.Info($"仓库{appConfig.foamStoreCode};PLC未连接");
}
}
else
{
logHelper.Info($"PLC信息为空,通过{appConfig.foamStoreCode}未获取到该仓库对应的PLC信息");
}
});
}
catch (Exception ex)
{
logHelper.Error("读取泡后入库应答字异常", ex);
}
}
}
#endregion
///
/// 通过PLC获取货道信息
///
///
///
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;
}
#region 2023-01-04delete 入库逻辑修改,删除引用方法
///
/// 读取泡后入库完成
///
//private void ReadShellFinish_InStore(string taskCode)
//{
// lock (string.Empty)
// {
// bool isFlag = true;
// IPlc _plc = _plcDictionary[appConfig.foamStoreCode];
// foamTaskCode = taskCode;
// try
// {
// Task.Run(() =>
// {
// if (_plc != null)
// {
// if (_plc.IsConnected)
// {
// do
// {
// //读取PLC入库任务完成
// if (_plc.readInt32ByAddress(plcConfig.in_foam_finish) == 1)
// {
// _plc.writeInt32ByAddress(plcConfig.in_foam_finish, 0);
// //string taskCode = _plc.readStringByAddress(plcConfig.out_foam_task, 10);
// InStoreFinsihEvent?.Invoke(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);
// }
// }
//}
#endregion
}
}