using HH.WCS.Mobox3.NFLZ.device;
|
using HH.WCS.Mobox3.NFLZ.dispatch;
|
using HH.WCS.Mobox3.NFLZ.util;
|
using HH.WCS.Mobox3.NFLZ.wms;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Threading;
|
|
namespace HH.WCS.Mobox3.NFLZ.process
|
{
|
/// <summary>
|
/// 设备信号处理,主要是tcp信号,我们做server被动接收信号来处理,根据项目定制的
|
/// </summary>
|
internal class DeviceProcess
|
{
|
|
private static Dictionary<string, statemodel> LineState = new Dictionary<string, statemodel>();
|
|
|
public class statemodel
|
{
|
public string status { get; set; }
|
public DateTime modify { get; set; }
|
}
|
|
|
internal static void Analysis(string data, string ip) {
|
if (data.Length >= 6) {
|
//去掉消息头3F 00
|
data = data.Substring(4);
|
//Console.WriteLine($"{ip}-{data}");
|
var plc = Settings.deviceInfos.Where(a => a.address == ip && a.enable == 1).FirstOrDefault();
|
if (plc != null) {
|
LinZhiAnalysisDeviceChange(data, plc);
|
}
|
else {
|
Console.WriteLine($"TCP信号处理:未查询到IP为{ip}的数据,请检查deviceInfo配置中心是否存在该IP的数据!");
|
}
|
}
|
|
}
|
|
/// <summary>
|
/// 农夫林芝不同项目设备特殊处理
|
/// </summary>
|
/// <param name="data"></param>
|
/// <param name="plc"></param>
|
/// <exception cref="NotImplementedException"></exception>
|
private static void LinZhiAnalysisDeviceChange(string data, Settings.deviceInfo plc)
|
{
|
if (plc.deviceType == 1) AnalysisDoor(data, plc);//自动门处理
|
//if (plc.deviceType == 2) LinJiangAnalysisProductLine(data, plc);//输送线处理 -- 成品下线
|
//if (plc.deviceType == 3) LinJiangAnalysisProductLine(data, plc);//输送线处理 -- 空托上线
|
if (plc.deviceType == 4) LinZhiAnalysisPreform(data, plc);//瓶坯机
|
if (plc.deviceType == 5) LinZhiAnalysisPGDump(data, plc);//瓶盖翻斗机
|
if (plc.deviceType == 6) LinZhiAnalysisPPDump(data, plc);//瓶坯翻斗机
|
}
|
/// <summary>
|
/// 瓶坯翻斗机空托下线
|
/// </summary>
|
/// <param name="data"></param>
|
/// <param name="plc"></param>
|
/// <exception cref="NotImplementedException"></exception>
|
private static void LinZhiAnalysisPPDump(string data, Settings.deviceInfo plc)
|
{
|
LogHelper.Info($"瓶坯翻斗机,查询任务终点:{plc.TN_Location[0]}");
|
if (LineState.Keys.Contains(plc.TN_Location[0]))
|
{
|
LogHelper.Info("瓶坯翻斗机包含该任务终点");
|
LineState[plc.TN_Location[0]].status = data;
|
LineState[plc.TN_Location[0]].modify = DateTime.Now;
|
}
|
else
|
{
|
LogHelper.Info("瓶坯翻斗机未包含该任务终点");
|
LineState.Add(plc.TN_Location[0], new statemodel { status = data, modify = DateTime.Now });
|
}
|
LogHelper.Info($"{plc.deviceName}-{plc.address}-{data}", "瓶坯翻斗机");
|
var db = new SqlHelper<object>().GetInstance();
|
var workInfo = db.Queryable<LinZhiBCPWorkOrder>().Where(a => a.S_PLineNo == plc.deviceName).First();
|
if (workInfo != null && workInfo.S_WorkState == "执行中")
|
{
|
LogHelper.Info($"查询到执行中的工单,工单类型:{workInfo.S_PLineNo}");
|
string startArea = "";
|
string endArea = "";
|
string fullTaskType = "";
|
string emptyTaskType = "";
|
if (workInfo.S_UsingNow == "Y")
|
{
|
LogHelper.Info("即产即用工单");
|
//即产即用在起点为线边
|
var bcpInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯即产即用A" && a.enable == 1).FirstOrDefault();
|
if (bcpInfo != null)
|
{
|
startArea = bcpInfo.areaCode;
|
}
|
fullTaskType = "翻斗机即产满托上线(瓶坯)";
|
emptyTaskType = "翻斗机即产空托下线(瓶坯)";
|
}
|
else
|
{
|
LogHelper.Info("非即产即用工单");
|
//非即产即用起点为库区
|
var bcpInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯非即产即用" && a.enable == 1).FirstOrDefault();
|
if (bcpInfo != null)
|
{
|
startArea = bcpInfo.areaCode;
|
}
|
fullTaskType = "翻斗机库存满托上线(瓶坯)";
|
emptyTaskType = "翻斗机库存空托下线(瓶坯)";
|
}
|
|
endArea = Settings.areaInfos.Where(a => a.areaName == "瓶坯翻斗机空托" && a.enable == 1).FirstOrDefault().areaCode;
|
|
if (data.Length == 6)
|
{
|
if (data.Substring(0, 2) == "11")
|
{
|
if (LocationHelper.CheckLocFree(plc.TN_Location[0]))
|
{
|
var bit = plc.TN_Location[0];
|
LogHelper.Info($"翻斗机点位:{bit}");
|
bool flag = true;
|
var cgInfo = db.Queryable<CGTTable>().Where(a => a.Bit == bit).First();
|
if (cgInfo != null)
|
{
|
LogHelper.Info($"查询到中间表数据CGTTable:{cgInfo.Bit},{cgInfo.time}");
|
LogHelper.Info($"当前时间:{DateTime.Now}");
|
if (cgInfo.time.AddSeconds(10) > DateTime.Now)
|
{
|
flag = false;
|
}
|
}
|
else LogHelper.Info($"未查询到中间表数据CGTTable:{bit}");
|
if (flag)
|
{
|
//判断当前翻斗机是否有送过满托 S_NOTE 字段默认空字符串,满托卸货完成之后会标记为满托,空托取货完成复位为空字符串
|
Location startLoca = null;
|
var locCode = plc.TN_Location[0];
|
var plcLoca = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == locCode).ToList();
|
if (plcLoca.Count <= 0)
|
{
|
LogHelper.Info($"瓶坯翻斗机上无托盘,生成满托上线任务,瓶坯翻斗机点位:{plc.TN_Location[0]}");
|
//初始状态,无托盘,直接上满托(非即产即用需要校验 套袋完成,即产即用直接使用)
|
if (workInfo.S_UsingNow == "Y")
|
{
|
LogHelper.Info($"瓶坯即产即用A库区查找");
|
startLoca = getFDSXArea(db, workInfo, startArea);
|
if (startLoca == null)
|
{
|
LogHelper.Info($"瓶坯即产即用A库区未找到满托,去瓶坯即产即用B库区查找");
|
startLoca = TaskProcess.BCPInOrOut(db, false, "", "瓶坯即产即用B", workInfo);
|
}
|
}
|
else
|
{
|
startLoca = getFDSXArea(db, workInfo, startArea);
|
}
|
|
if (startLoca != null)
|
{
|
//创建作业
|
WMSHelper.CreateOpTask(startLoca.S_CODE, locCode, "出库", fullTaskType, startLoca.LocCntrRel.S_CNTR_CODE);
|
}
|
}
|
else
|
{
|
LogHelper.Info($"瓶坯翻斗机上有空托盘,生成空托下线任务,瓶坯翻斗机点位:{plc.TN_Location[0]}");
|
|
//创建作业
|
WMSHelper.CreateOpTask(locCode, "", "入库", emptyTaskType, plcLoca[0].S_CNTR_CODE);
|
}
|
}
|
}
|
else LogHelper.Info($"瓶坯翻斗机:{plc.deviceName} 当前位置{plc.TN_Location[0]}有任务,不可触发空托下线或满托上线任务", "瓶坯翻斗机");
|
}
|
}
|
}
|
else LogHelper.Info($"瓶坯翻斗机:{plc.deviceName} 未开启工单,不可触发满托下线", "瓶坯翻斗机");
|
}
|
|
/// <summary>
|
/// 瓶盖翻斗机空托下线 瓶盖只有非即产即用
|
/// </summary>
|
/// <param name="data"></param>
|
/// <param name="plc"></param>
|
/// <exception cref="NotImplementedException"></exception>
|
private static void LinZhiAnalysisPGDump(string data, Settings.deviceInfo plc)
|
{
|
LogHelper.Info($"{plc.deviceName}-{plc.address}-{data}", "瓶盖翻斗机");
|
|
//var doorPlc = Settings.GetDeviceInfoList().Where(a => a.address == plc.address && a.deviceType == 1 && a.enable == 1).FirstOrDefault();
|
//AnalysisDoor(data, doorPlc);
|
|
LogHelper.Info($"瓶盖翻斗机,查询任务终点:{plc.TN_Location[0]}");
|
if (LineState.Keys.Contains(plc.TN_Location[0]))
|
{
|
LogHelper.Info("瓶盖翻斗机包含该任务终点");
|
LineState[plc.TN_Location[0]].status = data;
|
LineState[plc.TN_Location[0]].modify = DateTime.Now;
|
}
|
else
|
{
|
LogHelper.Info("瓶盖翻斗机未包含该任务终点");
|
LineState.Add(plc.TN_Location[0], new statemodel { status = data, modify = DateTime.Now });
|
}
|
|
var db = new SqlHelper<object>().GetInstance();
|
var workInfo = db.Queryable<LinZhiBCPWorkOrder>().Where(a => a.S_PLineNo == plc.deviceName).First();
|
if (workInfo != null && workInfo.S_WorkState == "执行中")
|
{
|
LogHelper.Info($"查询到执行中的工单,工单类型:{workInfo.S_PLineNo}");
|
string startArea = "";
|
string endArea = "";
|
string fullTaskType = "";
|
string emptyTaskType = "";
|
LogHelper.Info("非即产即用工单");
|
//非即产即用起点为库区
|
var bcpInfo = Settings.areaInfos.Where(a => a.areaName == "瓶盖非即产即用" && a.enable == 1).FirstOrDefault();
|
if (bcpInfo != null)
|
{
|
startArea = bcpInfo.areaCode;
|
}
|
|
fullTaskType = "翻斗机库存满托上线(瓶盖)";
|
emptyTaskType = "翻斗机库存空托下线(瓶盖)";
|
|
endArea = Settings.areaInfos.Where(a => a.areaCode == "瓶盖空托" && a.enable == 1).FirstOrDefault().areaCode;
|
|
if (data.Length == 6)
|
{
|
if (data.Substring(0, 2) == "11")
|
{
|
if (LocationHelper.CheckLocFree(plc.TN_Location[0]))
|
{
|
var bit = plc.TN_Location[0];
|
|
bool flag = true;
|
var cgInfo = db.Queryable<CGTTable>().Where(a => a.Bit == bit).First();
|
if (cgInfo != null)
|
{
|
if (cgInfo.time.AddSeconds(10) > DateTime.Now)
|
{
|
flag = false;
|
}
|
|
}
|
if (flag)
|
{
|
//判断当前翻斗机是否有送过满托 S_NOTE 字段默认空字符串,满托卸货完成之后会标记为满托,空托取货完成复位为空字符串
|
bool result = false;
|
Location startLoca = null;
|
Location endLoca = null;
|
|
var locCode = plc.TN_Location[0];
|
var plcLoca = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == locCode).ToList();
|
if (plcLoca.Count <= 0)
|
{
|
LogHelper.Info($"瓶盖翻斗机上无托盘,生成满托上线任务,瓶盖翻斗机点位:{plc.TN_Location[0]}");
|
//初始状态,无托盘,直接上满托(非即产即用需要校验 套袋完成,即产即用直接使用)
|
startLoca = getFDSXArea(db, workInfo, startArea);
|
|
if (startLoca != null)
|
{
|
//创建作业
|
WMSHelper.CreateOpTask(startLoca.S_CODE, locCode, "出库", fullTaskType, startLoca.LocCntrRel.S_CNTR_CODE);
|
}
|
}
|
else
|
{
|
LogHelper.Info($"瓶盖翻斗机上有空托盘,生成空托下线任务,瓶盖翻斗机点位:{plc.TN_Location[0]}");
|
//创建作业
|
WMSHelper.CreateOpTask(plc.TN_Location[0],"", "入库", emptyTaskType, startLoca.LocCntrRel.S_CNTR_CODE);
|
}
|
}
|
}
|
else LogHelper.Info($"瓶盖翻斗机:{plc.deviceName} 当前位置{plc.TN_Location[0]}有任务,不可触发空托下线或满托上线任务", "瓶盖翻斗机");
|
}
|
}
|
}
|
else LogHelper.Info($"瓶盖翻斗机:{plc.deviceName} 未开启工单,不可触发满托下线", "瓶盖翻斗机");
|
}
|
|
private static Location getFDSXArea(SqlSugar.SqlSugarClient db, LinZhiBCPWorkOrder workInfo, string startArea)
|
{
|
Location result = null;
|
var locList = db.Queryable<Location>().Where(a => a.S_AREA_CODE == startArea && a.N_CURRENT_NUM > 0).Includes(a => a.LocCntrRel).ToList();
|
if(locList.Count > 0)
|
{
|
foreach(var a in locList)
|
{
|
if(a.S_LOCK_STATE == "无")
|
{
|
var cntrInfo = db.Queryable<LocCntrRel>().Where(b => b.S_LOC_CODE == a.S_CODE).First();
|
if(cntrInfo != null)
|
{
|
var itemInfo = db.Queryable<CntrItemRel>().Where(b => b.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First();
|
if(itemInfo != null)
|
{
|
if(itemInfo.S_ITEM_CODE == workInfo.S_ItemCode)
|
{
|
result = a;
|
break;
|
}
|
}
|
|
}
|
}
|
}
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 瓶坯机满托下线
|
/// </summary>
|
/// <param name="data"></param>
|
/// <param name="plc"></param>
|
/// <exception cref="NotImplementedException"></exception>
|
private static void LinZhiAnalysisPreform(string data, Settings.deviceInfo plc)
|
{
|
LogHelper.Info($"{plc.deviceName}-{plc.address}-{data}", "瓶坯机");
|
var db = new SqlHelper<object>().GetInstance();
|
var workInfo = db.Queryable<LinZhiBCPWorkOrder>().Where(a => a.S_PLineNo == plc.deviceName).First();
|
if (workInfo != null && workInfo.S_WorkState == "执行中")
|
{
|
LogHelper.Info($"查询到执行中的工单,工单类型:{workInfo.S_PLineNo}");
|
string endArea = "";
|
string taskType = "";
|
if (workInfo.S_UsingNow.ToString() == "Y")
|
{
|
LogHelper.Info("即产即用工单");
|
taskType = "注塑即产满托下线(瓶坯)";
|
}
|
else
|
{
|
LogHelper.Info("非即产即用工单");
|
taskType = "注塑库存满托下线(瓶坯)";
|
}
|
//endArea = Settings.GetLinJiangBCPAreaList().Where(a => a.AreaName == "瓶坯满托" && a.Enable == "1").FirstOrDefault().AreaNo;
|
|
if (data.Length == 4)
|
{
|
if (data == "1122") LinZhialysisBottleCapAndPreformTwo(plc, db, workInfo, endArea, taskType, plc.TN_Location[0], "瓶坯机");
|
|
if (data == "1221") LinZhialysisBottleCapAndPreformTwo(plc, db, workInfo, endArea, taskType, plc.TN_Location[1], "瓶坯机");
|
}
|
}
|
else LogHelper.Info($"瓶坯机:{plc.deviceName} 未开启工单,不可触发满托下线", "瓶坯机");
|
}
|
|
|
/// <summary>
|
/// 注塑机下线流程
|
/// </summary>
|
/// <param name="plc"></param>
|
/// <param name="db"></param>
|
/// <param name="workInfo"></param>
|
/// <param name="endArea"></param>
|
/// <param name="taskType"></param>
|
/// <param name="deviceBit"></param>
|
/// <param name="type"></param>
|
private static void LinZhialysisBottleCapAndPreformTwo(Settings.deviceInfo plc, SqlSugar.SqlSugarClient db, LinZhiBCPWorkOrder workInfo, string endArea, string taskType, string deviceBit, string type)
|
{
|
LogHelper.Info($"{type}注塑机任务处理开始");
|
//再次判断信号
|
if (LocationHelper.CheckLocFree(deviceBit))
|
{
|
bool flag = true;
|
LogHelper.Info($"deviceBit:{deviceBit}");
|
var cgInfo = db.Queryable<CGTTable>().Where(a => a.Bit == deviceBit).First();
|
if (cgInfo != null)
|
{
|
if (cgInfo.time.AddSeconds(10) > DateTime.Now)
|
{
|
flag = false;
|
}
|
|
}
|
if (flag)
|
{
|
LogHelper.Info($"{type}{deviceBit}无任务,可触发下线任务");
|
var locInfo = db.Queryable<Location>().Where(a => a.S_CODE == deviceBit).First();
|
if(locInfo != null)
|
{
|
if(locInfo.N_CURRENT_NUM == 0)
|
{
|
LogHelper.Info($"{type}注塑机上未绑定托盘,生成空托上线任务");
|
string machine = type.Substring(0, type.Length - 1);
|
if (workInfo.S_UsingNow == "Y")
|
{
|
taskType = $"注塑即产空托上线({machine})";
|
}
|
else
|
{
|
taskType = $"注塑库存空托上线({machine})";
|
}
|
|
Location startLoca = TaskProcess.getMStartLoc(db);
|
//创建作业
|
WMSHelper.CreateOpTask(startLoca.S_CODE, deviceBit, "出库", taskType, startLoca.LocCntrRel.S_CNTR_CODE);
|
}
|
else
|
{
|
LogHelper.Info($"{type}注塑机上未绑定托盘,自动绑定托盘");
|
string cntrCode = Guid.NewGuid().ToString("N");
|
var cntrInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == deviceBit).First();
|
if(cntrInfo == null)
|
{
|
LocCntrRel cntr = new LocCntrRel
|
{
|
S_LOC_CODE = deviceBit,
|
S_CNTR_CODE = cntrCode,
|
};
|
if (db.Insertable(cntr).ExecuteCommand() > 0)
|
{
|
locInfo.N_CURRENT_NUM = locInfo.N_CURRENT_NUM + 1;
|
db.Updateable(locInfo).UpdateColumns(a => a.N_CURRENT_NUM).ExecuteCommand();
|
LogHelper.Info($"起点成功绑定托盘,起点:{deviceBit},托盘号:{cntrCode}");
|
|
}
|
}
|
else
|
{
|
cntrCode = cntrInfo.S_CNTR_CODE;
|
}
|
//创建作业
|
WMSHelper.CreateOpTask(deviceBit, "", "入库", taskType, cntrCode);
|
}
|
}
|
}
|
}
|
}
|
|
/// <summary>
|
/// 自动门
|
/// </summary>
|
/// <param name="data"></param>
|
/// <param name="plc"></param>
|
internal static void AnalysisDoor(string data, Settings.deviceInfo plc)
|
{
|
LogHelper.Info($"自动门状态:{data},地址为:{plc.address}", "自动门");
|
if (data.Length / 2 == plc.deviceNo.Length * 2 || data.Length / 2 == plc.deviceNo.Length * 3)//2 2
|
{
|
LogHelper.Info("自动门状态正确");
|
for (int i = 0; i < plc.deviceNo.Length; i++)
|
{
|
var state = data.Substring(3, 1);
|
LogHelper.Info($"门{plc.deviceNo[i]}的状态{state}");
|
if (doorStatus.Keys.Contains(plc.deviceNo[i]))
|
{
|
doorStatus[plc.deviceNo[i]].info = state;
|
doorStatus[plc.deviceNo[i]].modify = DateTime.Now;
|
}
|
else
|
{
|
doorStatus.Add(plc.deviceNo[i], new signalInfo { info = state, modify = DateTime.Now });
|
}
|
}
|
}
|
}
|
|
#region 自动门--通用
|
private static Dictionary<string, signalInfo> doorStatus = new Dictionary<string, signalInfo>();//普通自动门字典
|
public class signalInfo
|
{
|
public string info { get; set; }
|
public DateTime modify { get; set; }
|
}
|
|
#endregion
|
|
|
internal static void Traffic(string forkliftNo, string lockNo, bool v) {
|
}
|
}
|
}
|