using Hanhe.iWCS.Business;
using Hanhe.iWCS.Common;
using Hanhe.iWCS.Interface;
using Hanhe.iWCS.MData;
using Hanhe.iWCS.Model;
using Hanhe.iWCS.Model.AMS;
using Microsoft.Owin.Hosting;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using static Hanhe.iWCS.JingmenGEMNorthProtocol.ApiHelper;
using static Hanhe.iWCS.JingmenGEMNorthProtocol.EnentListen;
using static Hanhe.iWCS.JingmenGEMNorthProtocol.MESHelper;
using static Hanhe.iWCS.JingmenGEMNorthProtocol.PLCControl;
using static Hanhe.iWCS.JingmenGEMNorthProtocol.ProcessHelper;
namespace Hanhe.iWCS.JingmenGEMNorthProtocol
{
///
/// 设备协议解析类
///
public class ProtocolAnalysis : IProtocolAnalysis
{
private EquipmentCommandEQBLL CommandEQBLL = new EquipmentCommandEQBLL();
private ICallTaskProcessing iCallTask = new ICallTaskProcessing();
private Logger AMSLoggerAPI = new Logger();
public void StringRequestInfo(string protocolMsg, string address, int port) {
}
public void StringRequestInfo(string protocolMsg, string address, int port, string sessionID) {
//16进制接收
protocolMsg = protocolMsg.Trim();//3f 00 11 20 30 40 50 60 70 80 90 A0 24 24
if (protocolMsg != "") {
}
#region 握手反馈指令
//UpdateHandshakeFeedbackCode(protocolMsg);
PLCControl.Analysis(protocolMsg);
#endregion
}
public void UpdateHandshakeFeedbackCode(string commandText) {
var query = Query.And(Query.EQ("CommandText", commandText + "$$"), Query.EQ("Status", Constants.COMMANDEQ_STATUS_SENDED));
EquipmentCommandEQ eq = MongoDBSingleton.Instance.FindOne(query, typeof(EquipmentCommandEQ).Name);
if (eq != null) {
UpdateBuilder updateBuider = Update.Set("isHandshake", 1).Set("FeedbackCode", commandText);
MongoDBSingleton.Instance.Update(query, updateBuider, UpdateFlags.None);
}
}
private static bool api = false;
public ProtocolAnalysis() {
if (!api) {
Startup();
api = true;
}
}
public static void Startup() {
Console.WriteLine("Startup ApiController");
Task.Run(() => {
var url = "http://+:8801";
using (WebApp.Start(url)) {
Console.WriteLine("Running on {0}", url);
Console.ReadLine();
}
});
}
public int workflowToDeviceDriver(TN_I_TASK_DTL_ACTION action) {
int iResult = 0;
CMMLog.Info($"任务处理:Action Code:{action.CN_N_ACTION_CODE},TaskNo:{action.CN_S_TASK_NO}");
switch (action.CN_N_ACTION_CODE)
{
case 1012: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "起点申请进入"); break;
case 1312: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "电梯安全对接"); break;
case 1112: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "滚筒车起点到位"); break;
case 1212: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "滚筒车取货完成通知PLC"); break;
case 1013: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "终点申请进入"); break;
case 1113: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "滚筒车终点到位"); break;
case 1213: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "滚筒车卸货完成通知PLC"); break;
case 1313: AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), action.CN_N_ACTION_CODE.ToString(), "拍照扫码"); break;
}
if (action.CN_N_ACTION_CODE == 1027) {
var mst = iCallTask.FindTask(action.CN_S_TASK_NO);
if (mst != null ) {
if (ProcessHelper.Intercept(mst)) iResult = 1027;//拦截更改 WCS 任务类型(将 WMS 任务类型更改为 WCS 任务类型,因为 WCS 需要根据任务类型进行对应任务流程处理)
else
{
CMMLog.Info($"推送任务:任务号{mst.CN_S_TASK_NO},任务类型:{mst.CN_S_BUSS_TYPE}");
bool IsSendTask = true;
// 3楼缓存架入叠托 任务 取货完成才允许推送下一条
if (mst.CN_S_BUSS_TYPE.Contains("缓存架入叠托"))
{
var taskInfoList = MongoDBSingleton.Instance.Find(Query.And(Query.NotIn("CN_S_STATUS", new List() { "未执行", "待推送" }), Query.EQ("CN_S_END_BIT", mst.CN_S_END_BIT)), "TN_I_TASK_MST");
if (taskInfoList.Count > 0)
{
// 遍历查询执行中的这些任务是否都已经取货完成,如果都取货完成,则可以推送此任务
for (int i = 0; i < taskInfoList.Count; i++)
{
if (!ProcessHelper.CheckStartFreeTwo(taskInfoList[i].CN_S_START_BIT))
{
IsSendTask = false;
Console.WriteLine($"缓存架入叠托 任务拦截:该任务 :{taskInfoList[i].CN_S_TASK_NO} 未取货完成,不允许推送当前任务:{mst.CN_S_TASK_NO}");
}
}
}
}
if (IsSendTask) ProcessHelper.SendTask(mst);
}
}
iResult = 1027;
}
#region 取消
if (action.CN_N_ACTION_CODE == 7) {
TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO);
string agvNo = action.CN_S_DEVICE_CODE;
if (mst != null) {
//请求前
if (action.CN_N_ORDER == 0)
{
WorkFlowAction.TrackLog(action.CN_S_TASK_NO, 0, 7, "收到ams取消请求");
}
if (action.CN_N_ORDER == 1 || action.CN_N_ORDER == 0) {
ProcessHelper.TaskCancel(mst);
iCallTask.CancelTask(mst.CN_S_TASK_NO, "1");
AMSHelper.SetStatus(action.CN_S_TASK_NO, 1, "7", "0", true);
if (mst.CN_S_BUSS_TYPE != "电梯取货" && mst.CN_S_BUSS_TYPE != "电梯卸货" && !mst.CN_S_BUSS_TYPE.Contains("包装取料"))
WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE);
iCallTask.DeleteTask(mst.CN_S_TASK_NO);
}
if (mst.CN_S_BUSS_TYPE == "电梯取货" || mst.CN_S_BUSS_TYPE == "电梯卸货" || mst.CN_S_BUSS_TYPE == "满托转运" || mst.CN_S_BUSS_TYPE == "空托出库")
{
ProcessHelper.ForceCancel(mst, action);
MongoDBSingleton.Instance.Remove(Query.EQ("timeStamp", mst.CN_S_BATCH_NO), "TimeCuoInfoCom", RemoveFlags.None);
}
if (mst.CN_S_BUSS_TYPE.Contains("包装补空")) PLCControl.PickUpBlankComplete(mst.CN_S_END_BIT);
}
}
#endregion
#region 强制完成
if (action.CN_N_ACTION_CODE == 1022) {
TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO);
if (mst != null) {
ProcessHelper.ForceComplete(mst, action);
if (mst.CN_S_BUSS_TYPE.Contains("缓存架入叠托"))
{
var plc = Settings.GetPlcInfo().Where(a => a.deviceType == "3").FirstOrDefault();
if (plc != null)
{
var machine = MongoDBSingleton.Instance.FindOne(Query.EQ("trayCode", mst.CN_S_BATCH_NO), "WMSInfo");
if (machine != null)
{
#region 写多个MODBUS数据
if (Settings.cacheStackWrite == "0")
{
int[] num = DiePan(machine);
CMMLog.Info($"send num:" + JsonConvert.SerializeObject(num));
var wirteall01 = OITcpHelper.RegisterWriteOutPutMulti(new OITcpHelper.RegisterWriteOutPutModelMulti
{
addr = plc.writeAddr + 10,
host = plc.ip,
port = plc.port,
data = num
});
}
else WriteCacheStackingData(plc, mst, machine);
#endregion
MongoDBSingleton.Instance.Remove(Query.EQ("trayCode", mst.CN_S_BATCH_NO), "WMSInfo", RemoveFlags.Single);
}
}
}
MongoDBSingleton.Instance.Remove(Query.EQ("TaskNo", mst.CN_S_TASK_NO), RemoveFlags.Single);
WorkFlowAction.TrackLog(mst.CN_S_TASK_NO, 1, 1022, "收到ams强制完成请求");
AMSHelper.SetStatus(action.CN_S_TASK_NO, 1, "1022", "0", true);
iCallTask.CancelTask(mst.CN_S_TASK_NO, "1");
if (mst.CN_S_BUSS_TYPE != "电梯取货" && mst.CN_S_BUSS_TYPE != "电梯卸货" && !mst.CN_S_BUSS_TYPE.Contains("包装取料"))
WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE);
//if (mst.CN_S_BUSS_TYPE == "电梯取货" && mst.CN_S_BUSS_TYPE == "电梯卸货")
// MongoDBSingleton.Instance.ReomveAll();
if (mst.CN_S_BUSS_TYPE == "包装线补空") PLCControl.PickUpBlankComplete(mst.CN_S_END_BIT);
if (ERPService.SendERPTaskType.Contains(mst.CN_S_BUSS_TYPE) && ERPService.ERPSwitch01 == "1") ERPService.SendERPTaskInfo(mst);
iCallTask.DeleteTask(mst.CN_S_TASK_NO);
}
}
#endregion
if (action.CN_N_ACTION_CODE == 13) {
var task = iCallTask.FindTask(action.CN_S_TASK_NO);
AMSHelper.TaskTrackLogMessage(action.CN_S_TASK_NO, action.CN_N_ORDER.ToString(), "", "AGV调整任务优先级成功" + action.Ext1);
}
#region 任务状态委托(1-开始;3-开始取货;4-取货完成;5-开始卸货;6-卸货完成;2-完成)
if (action.CN_N_ACTION_CODE == 1 || action.CN_N_ACTION_CODE == 4 || action.CN_N_ACTION_CODE == 5 || action.CN_N_ACTION_CODE == 6 || action.CN_N_ACTION_CODE == 2)
{
WorkFlowAction.TrackLog(action.CN_S_TASK_NO, 1, action.CN_N_ACTION_CODE, "");
AMSHelper.SetStatus(action.CN_S_TASK_NO, 1, action.CN_N_ACTION_CODE.ToString(), action.CN_S_DEVICE_CODE, true);
if (action.CN_N_ACTION_CODE == 2) AMSHelper.SetStatusTwo(action.CN_S_TASK_NO);
TN_I_TASK_MST mst = iCallTask.FindTask(action.CN_S_TASK_NO);
if (mst != null)
{
if (!string.IsNullOrEmpty(action.CN_S_DEVICE_CODE))
{
// 因调用AMSAPI无法在开始取货时更新车号,因此此处直接连接AMS数据库进行更新
MoboxHelper.UpdateEndBit(mst.CN_S_TASK_NO, action.CN_S_DEVICE_CODE);
if (action.CN_N_ACTION_CODE != 1 && action.CN_N_ACTION_CODE != 2) MoboxHelper.UpdateTaskState(mst.CN_S_TASK_NO, action.CN_N_ACTION_CODE);
}
#region 写入小车状态
writeAGVState(action);
#endregion
if (action.CN_N_ACTION_CODE == 1)
{
if (mst.CN_S_BUSS_TYPE != "电梯取货" && mst.CN_S_BUSS_TYPE != "电梯卸货" && !mst.CN_S_BUSS_TYPE.Contains("包装取料"))
WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE);
}
if (action.CN_N_ACTION_CODE == 4)
{
CMMLog.Info($"SetStatus:收到任务号 4:{action.CN_S_TASK_NO}");
CMMLog.Info($"收到信号:{action.CN_N_ACTION_CODE},任务号:{action.CN_S_TASK_NO},开始根据任务号查询主表中对应数据!");
if (mst.CN_S_BUSS_TYPE == "包装线补空") PLCControl.PickUpBlankComplete(mst.CN_S_END_BIT, mst.CN_S_START_BIT);
if (mst.CN_S_BUSS_TYPE.Contains("包装取料")) PLCControl.CheckUpReqUnload(mst.CN_S_END_BIT, mst.CN_S_TASK_NO);
if (mst.CN_S_BUSS_TYPE == "3楼缓存架入叠托") WMSHelper.ExecuteState(mst.CN_S_SOURCE_NO, action.CN_N_ACTION_CODE);
}
if (action.CN_N_ACTION_CODE == 5)
{
}
if (action.CN_N_ACTION_CODE == 6)
{
if (mst.CN_S_BUSS_TYPE.Contains("缓存架入叠托"))
{
CMMLog.Info($"缓存架入叠托:收到信号6,开始准备写入叠盘机数据。");
PLCControl.writeStackingMouth6(mst.CN_S_END_BIT, mst.CN_S_TASK_NO);
}
if (mst.CN_S_BUSS_TYPE.Contains("包装取料"))
{
//卸货完成,中间表SecondWeighState full改为1
string x = mst.CN_S_END_BIT.Contains("2") ? "23" : "2";
string PlcBit02 = Settings.GetPlcInfo().Where(a => a.deviceType == x).FirstOrDefault().location;
UpdateBuilder update = Update.Set("full", 1);
MongoDBSingleton.Instance.Update(Query.EQ("location", PlcBit02), update, "SecondWeighState", UpdateFlags.None);
}
if (mst.CN_S_BUSS_TYPE.Contains("包装补空"))
{
//将数据记录到中间表
var agvloc = Settings.GetAGVLocationList().Where(a => a.location == mst.CN_S_END_BIT).First();
if (agvloc != null)
{
var quantity = agvloc.quantity;
CMMLog.Info($"包装补空,终点{mst.CN_S_END_BIT}站点个数:{quantity}");
var emptyInfo = MongoDBSingleton.Instance.FindOne(Query.EQ("Bit", mst.CN_S_END_BIT), "BZEmptyPoint");
if (emptyInfo != null)
{
MongoDBSingleton.Instance.Update(Query.EQ("Bit", mst.CN_S_END_BIT), Update.Set("Quantity", quantity), UpdateFlags.None);
}
else
{
MongoDBSingleton.Instance.Insert(new BZEmptyPoint { Bit = mst.CN_S_END_BIT, Quantity = quantity });
}
}
}
if (mst.CN_S_BUSS_TYPE.Contains("打包下线"))
{
var connInfo = MongoDBSingleton.Instance.FindOne(Query.EQ("Bit", mst.CN_S_START_BIT), "ConnectingBits");
if (connInfo != null)
{
CMMLog.Info($"connInfo:{connInfo.timeCuo}");
var time = MongoDBSingleton.Instance.FindOne(Query.EQ("timeStamp", int.Parse(connInfo.timeCuo)), "TimeCuoInfoCom");
//var db = new SqlHelper