using HH.WCS.NongFuChaYuan.DeviceService;
|
using HH.WCS.NongFuChaYuan.DispatchService;
|
using HH.WCS.NongFuChaYuan.OtherService;
|
using HH.WCS.NongFuChaYuan.WmsService;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Threading;
|
using System.Timers;
|
using static System.Runtime.CompilerServices.RuntimeHelpers;
|
|
namespace HH.WCS.NongFuChaYuan.TaskController
|
{
|
/// <summary>
|
/// 设备信号处理--特殊设备处理需增加项目名配置
|
/// </summary>
|
internal class DeviceProcess
|
{
|
private static ModbusHelper modbusHelper = new ModbusHelper();
|
|
private static Dictionary<string, statemodel> LineState = new Dictionary<string, statemodel>();
|
|
public class statemodel
|
{
|
public string status { get; set; }
|
public DateTime modify { get; set; }
|
public int error { 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.GetDeviceInfoList().Where(a => a.address == ip && a.enable == 1).FirstOrDefault();
|
|
|
//if (data.Length == 6)
|
//{
|
// if (data.Substring(4, 2) == "32")
|
// {
|
// //输送线第二个口
|
// plc = Settings.GetDeviceInfoList().Where(a => a.address == ip && a.location.Contains("") && a.enable == 1).FirstOrDefault();
|
// }
|
// else if(data.Substring(0,2)=="12")
|
// {
|
// //输送线第一个口
|
// plc = Settings.GetDeviceInfoList().Where(a => a.address == ip && a.location.Contains("") && a.enable == 1).FirstOrDefault();
|
// }
|
//}
|
|
|
if (plc != null)
|
{
|
alysisDeviceChange(data, plc);
|
}
|
//else { }//Console.WriteLine($"TCP信号处理:未查询到IP为{ip}的数据,请检查deviceInfo配置中心是否存在该IP的数据!");
|
}
|
}
|
|
private static void alysisDeviceChange(string data, Settings.deviceInfo plc)
|
{
|
if (plc.deviceType == 1) AnalysisDoor(data, plc);//自动门处理
|
else if (plc.deviceType == 2) DaMingShanAnalysisBottleCapmolding(data, plc);//注塑机处理
|
else if (plc.deviceType == 3) DaMingShanAnalysisBottleCapTipper(data, plc);//瓶盖翻斗机处理
|
else if (plc.deviceType == 6) DaMingShanAnalysisBottleCapmoldTipper(data, plc);//瓶坯翻斗机处理
|
else if (plc.deviceType == 4) DaMingShanAnalysisBottleCap(data, plc);//瓶盖机处理
|
else if (plc.deviceType == 5) DaMingShanAnalysisProductLine(data, plc);//输送线处理
|
else if (plc.deviceType == 7) Roboticarm(data, plc);//机械臂处理
|
}
|
|
private static void Roboticarm(string data, Settings.deviceInfo plc)
|
{
|
LogHelper.Info($"{plc.deviceName}--IP={plc.address}--msg={data}");
|
if (data.Length == 4)
|
{
|
if (data.Substring(0, 2) == "12")
|
{
|
//空框下线
|
RoboticarmEmpty(plc, plc.location[0]);
|
}
|
if (data.Substring(2, 2) == "21")
|
{
|
//满框上线
|
RoboticarmFull(plc, plc.location[0]);
|
}
|
}
|
}
|
|
private static void RoboticarmEmpty(Settings.deviceInfo plc, string location)
|
{
|
var result = false;
|
try
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
if (location != "")
|
{
|
if (LocationHelper.CheckLocFree(location))
|
{
|
//查询工单
|
var endinfo = Settings.GetDaMingShanPriProLineList().Where(a => a.deviceName == plc.deviceName && a.ItemTrayType == "空").FirstOrDefault();
|
if (endinfo != null)
|
{
|
var workorder = db.Queryable<PGWorkOrder>().Where(a => a.S_PLineNo == plc.deviceName && a.S_WorkState == "执行中").First();
|
if (workorder != null)
|
{
|
var trayNo = "";
|
var cntr = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == location).First();
|
if (cntr != null)
|
{
|
trayNo = cntr.S_CNTR_CODE;
|
}
|
else
|
{
|
trayNo = ContainerHelper.GenerateCntrNo();
|
}
|
var endarea = endinfo.ProductArea[0];
|
var endbit = db.Queryable<Location>().Where(a => a.S_AREA_CODE == endarea && a.N_CURRENT_NUM == 0 && a.S_LOCK_STATE == "无").First();
|
if (endbit != null)
|
{
|
var endlocation = endbit.S_LOC_CODE.Trim();
|
result = IntensiveArea.DaMingShanCreateTransport(location, endlocation, "机械臂空框下线", trayNo, 1, 1, plc.deviceName, 1);
|
if (result)
|
{
|
//绑定货位与托盘
|
LocCntrRel cn = new LocCntrRel
|
{
|
S_LOC_CODE = location,
|
S_CNTR_CODE = trayNo
|
};
|
db.Insertable(cn).ExecuteCommand();
|
}
|
else LogHelper.Info($"机械臂下空任务 任务创建失败");
|
}
|
else LogHelper.Info($"机械臂下空任务 查询不到可用货位");
|
}
|
else LogHelper.Info($"机械臂下空任务 查询不到执行中的工单");
|
}
|
else
|
{
|
LogHelper.Info($"机械臂下空任务 找不到终点配置");
|
}
|
}
|
else LogHelper.Info($"机械臂任务 当前点位{location} 有未完成的任务");
|
}
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Error($"机械臂消息处理异常 异常信息={ex.Message}", ex);
|
}
|
|
}
|
|
private static void RoboticarmFull(Settings.deviceInfo plc, string location)
|
{
|
try
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
if (location != "")
|
{
|
if (LocationHelper.CheckLocFree(location))
|
{
|
//查询工单
|
var startinfo = Settings.GetDaMingShanPriProLineList().Where(a => a.deviceName == plc.deviceName && a.ItemTrayType == "满").FirstOrDefault();
|
if (startinfo != null)
|
{
|
var workorder = db.Queryable<PGWorkOrder>().Where(a => a.S_PLineNo == plc.deviceName && a.S_WorkState == "执行中").First();
|
if (workorder != null)
|
{
|
var startarea = startinfo.ProductArea[0];
|
var startbit = IntensiveArea.DaMingShanGetCacheLocationOut(startarea);
|
if (startbit != null)
|
{
|
var startlocation = startbit.S_LOC_CODE.Trim();
|
if (startbit.LocCntrRel != null)
|
{
|
var trayNo = startbit.LocCntrRel.S_CNTR_CODE;
|
IntensiveArea.DaMingShanCreateTransport(startlocation, location, "机械臂满框上线", trayNo, 1, 1, plc.deviceName, 1);
|
}
|
else
|
{
|
LogHelper.Info($"机械臂呼满任务 起点{startlocation} 没有绑定托盘信息");
|
}
|
}
|
else
|
{
|
LogHelper.Info($"机械臂呼满任务 查询不到可用货位");
|
}
|
}
|
else
|
{
|
LogHelper.Info($"机械臂呼满任务 查询不到执行中的工单");
|
}
|
}
|
else
|
{
|
LogHelper.Info($"机械臂下空任务 找不到终点配置");
|
}
|
}
|
else LogHelper.Info($"货位{location} 当前状态不能生成任务");
|
}
|
else LogHelper.Info($"货位配置站点为空");
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Error($"机械臂消息处理异常 异常信息={ex.Message}", ex);
|
}
|
}
|
|
private static void DaMingShanAnalysisBottleCapmoldTipper(string data, Settings.deviceInfo plc)
|
{
|
LogHelper.Info($"{plc.deviceName}--IP={plc.address}--msg={data}", "翻斗机");
|
//翻斗机下空筐 分配终点解绑起点物料
|
if (data.Substring(1, 1) == "1")
|
{
|
if (TipperEmpty2(plc, plc.location[0]))
|
{
|
|
}
|
}
|
|
var error = data.Substring(data.Length - 2);
|
if (LineState.Keys.Contains(plc.location[0]))
|
{
|
LineState[plc.location[0]].status = data;
|
LineState[plc.location[0]].modify = DateTime.Now;
|
LineState[plc.location[0]].error = int.Parse(error);
|
}
|
else
|
{
|
LineState.Add(plc.location[0], new statemodel { status = data, modify = DateTime.Now, error = int.Parse(error) });
|
}
|
|
|
data = data.Substring(2);
|
LogHelper.Info($"自动门状态:{data},地址为:{plc.address}", "自动门");
|
//if (data.Length / 2 == plc.deviceNo.Length)//2 2
|
//{
|
for (int i = 0; i < plc.deviceNo.Length; i++)
|
{
|
var state = data.Substring(i * 2 + 1, 1);
|
////Console.WriteLine($"门{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 大明山信号处理流程
|
|
/// <summary>
|
/// 注塑机、翻斗机二段任务
|
/// </summary>
|
/// <param name="mst"></param>
|
/// <exception cref="NotImplementedException"></exception>
|
internal static void Secondstagetask(WMSTask mst, bool type)
|
{
|
LogHelper.Info($"大明山设备任务 二段处理");
|
var info = Settings.GetDeviceInfoList().Where(a => a.location.Contains(mst.S_START_LOC.Trim()) || a.location.Contains(mst.S_END_LOC.Trim())).FirstOrDefault();
|
if (info != null)
|
{
|
try
|
{
|
if (info.location.Contains(mst.S_START_LOC.Trim()))
|
{
|
if (type)
|
{
|
//取货完成
|
//注塑机二段任务
|
if (info.deviceType == 2)
|
{
|
//如果取满任务在A口 送空任务分配在B口
|
if (info.location[0] == mst.S_START_LOC.Trim())
|
{
|
//A口
|
if (moldingEmpty(info, info.location[0]))
|
{
|
LogHelper.Info($"当前位置{info.location[1]} :创建注塑机送空筐任务成功", "注塑机");
|
}
|
}
|
else
|
{
|
//B口
|
if (moldingEmpty(info, info.location[1]))
|
{
|
LogHelper.Info($"当前位置{info.location[0]} :创建注塑机送空筐任务成功", "注塑机");
|
}
|
}
|
}
|
else if (info.deviceType == 3)
|
{
|
//翻斗机二段任务 翻斗机只有一个口 取空送满
|
if (TipperFull2(info, info.location[0], false))
|
{
|
//创建任务成功
|
LogHelper.Info($"当前位置{info.location[0]} :创建翻斗机补满筐任务成功", "翻斗机");
|
}
|
}
|
else if (info.deviceType == 6)
|
{
|
//翻斗机二段任务 翻斗机只有一个口 取空送满
|
if (TipperFull2(info, info.location[0], true))
|
{
|
//创建任务成功
|
LogHelper.Info($"当前位置{info.location[0]} :创建翻斗机补满筐任务成功", "翻斗机");
|
}
|
}
|
else if (info.deviceType == 5)
|
{
|
if (mst.S_START_LOC.Trim() == info.location[0])
|
{
|
//一号口
|
PlcHelper.SendHex(info.address, "3F00100D0A");
|
}
|
else
|
{
|
//二号口
|
PlcHelper.SendHex(info.address, "3F00300D0A");
|
}
|
}
|
else if (info.deviceType == 4)
|
{
|
//如果取满任务在A口 送空任务分配在B口
|
if (info.location[0] == mst.S_START_LOC.Trim())
|
{
|
//A口
|
if (moldingEmpty2(info, info.location[0]))
|
{
|
LogHelper.Info($"当前位置{info.location[0]} :创建瓶盖机送空筐任务成功", "瓶盖机");
|
}
|
}
|
else
|
{
|
//B口
|
if (moldingEmpty2(info, info.location[1]))
|
{
|
LogHelper.Info($"当前位置{info.location[1]} :创建瓶盖机送空筐任务成功", "瓶盖机");
|
}
|
}
|
}
|
}
|
}
|
else
|
{
|
if (!type)
|
{
|
if (info.deviceType == 5)
|
{
|
PlcHelper.SendHex(info.address, "3F00200D0A");
|
}
|
if (info.deviceType == 4 || info.deviceType == 2)
|
{
|
if (mst.S_END_LOC == info.location[0])
|
{
|
PlcHelper.SendHex(info.address, "3F00100D0A");
|
LogHelper.Info($"当前位置{info.location[0]} :注塑机复位信号成功");
|
}
|
if (mst.S_END_LOC == info.location[1])
|
{
|
PlcHelper.SendHex(info.address, "3F00200D0A");
|
LogHelper.Info($"当前位置{info.location[1]} :注塑机复位信号成功");
|
|
}
|
}
|
if (info.deviceType == 3 || info.deviceType == 6)
|
{
|
LogHelper.Info($"翻斗机卸货完成 发送重置信号");
|
PlcHelper.SendHex(info.address, "3F00100D0A");
|
}
|
}
|
else
|
{
|
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Error("设备二段处理异常" + ex.Message, ex);
|
}
|
|
}
|
}
|
|
/// <summary>
|
/// 瓶坯翻斗机上满筐
|
/// </summary>
|
/// <param name="info"></param>
|
/// <param name="v"></param>
|
/// <returns></returns>
|
private static bool TipperFull2(Settings.deviceInfo plc, string location, bool v)
|
{
|
//通过站点编号查询工单
|
//通过工单获取物料编码、批号(前期富勒没上线批号自行编写)
|
var result = false;
|
|
var db = new SqlHelper<object>().GetInstance();
|
if (location != "")
|
{
|
if (LocationHelper.CheckLocFree(location))
|
{
|
LogHelper.Info($"翻斗机:{plc.deviceName} 下线信号:{location} 查询工单", "翻斗机");
|
var workOrder = WCSHelper.GetPGWorkOrder(plc.deviceName);
|
if (workOrder != null)
|
{
|
LogHelper.Info($"查到了工单{workOrder.S_WorkNo} 工单状态为: {workOrder.S_WorkState }", "翻斗机");
|
if (workOrder.S_WorkState == "执行中")
|
{
|
var trayInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == location).ToList();
|
if (trayInfo.Count() == 0)
|
{
|
if (v)
|
{
|
//瓶坯翻斗机叫料
|
result = IntensiveArea.DaMingShanPLCOut3(plc, location, true, workOrder);
|
}
|
else
|
{
|
//瓶盖翻斗机叫料
|
result = IntensiveArea.DaMingShanPLCOut3(plc, location, false, workOrder);
|
}
|
}
|
else
|
{
|
LogHelper.Info($"当前位置{location} :托盘未解绑", "翻斗机");
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info($"翻斗机:{plc.deviceName} 下线信号:{location} 未找到工单", "翻斗机");
|
}
|
}
|
else
|
{
|
LogHelper.Info($"翻斗机:{plc.deviceName} 当前位置{location}有任务,不可触发补满筐任务", "翻斗机");
|
}
|
}
|
return result;
|
}
|
|
private static void DaMingShanAnalysisBottleCap(string data, Settings.deviceInfo plc)
|
{
|
LogHelper.Info($"{plc.deviceName}--IP={plc.address}--msg={data}", "瓶盖机");
|
//下满筐信号生成下满筐任务 待取货完成解绑起点货位 生成送空任务
|
if (data.Substring(0, 2) == "11")
|
{
|
if (moldingFull2(plc, plc.location[0]))
|
{
|
LogHelper.Info($"{plc.deviceName}--IP={plc.address}--msg=瓶盖机A口生成取满任务", "注塑机");
|
}
|
}
|
if (data.Substring(2, 2) == "21")
|
{
|
if (moldingFull2(plc, plc.location[1]))
|
{
|
LogHelper.Info($"{plc.deviceName}--IP={plc.address}--msg=瓶盖机B口生成取满任务", "注塑机");
|
}
|
}
|
data = data.Substring(4);
|
LogHelper.Info($"自动门状态:{data},地址为:{plc.address}", "自动门");
|
if (data.Length / 2 == plc.deviceNo.Length)//2 2
|
{
|
for (int i = 0; i < plc.deviceNo.Length; i++)
|
{
|
var state = data.Substring(i * 2 + 1, 1);
|
////Console.WriteLine($"门{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 });
|
}
|
}
|
}
|
}
|
|
|
/// <summary>
|
/// 接收PLC翻斗机信号
|
/// </summary>
|
/// <param name="data"></param>
|
/// <param name="plc"></param>
|
/// <exception cref="NotImplementedException"></exception>
|
private static void DaMingShanAnalysisBottleCapTipper(string data, Settings.deviceInfo plc)
|
{
|
LogHelper.Info($"{plc.deviceName}--IP={plc.address}--msg={data}", "翻斗机");
|
//翻斗机下空筐 分配终点解绑起点物料
|
if (data.Substring(1, 1) == "1")
|
{
|
if (TipperEmpty(plc, plc.location[0]))
|
{
|
|
}
|
}
|
|
var error = data.Substring(data.Length - 2);
|
if (LineState.Keys.Contains(plc.location[0]))
|
{
|
LineState[plc.location[0]].status = data;
|
LineState[plc.location[0]].modify = DateTime.Now;
|
LineState[plc.location[0]].error = int.Parse(error);
|
}
|
else
|
{
|
LineState.Add(plc.location[0], new statemodel { status = data, modify = DateTime.Now, error = int.Parse(error) });
|
}
|
|
|
LogHelper.Info($"自动门状态:{data},地址为:{plc.address}", "自动门");
|
data = data.Substring(2);
|
//if (data.Length / 2 == plc.deviceNo.Length)//2 2
|
//{
|
for (int i = 0; i < plc.deviceNo.Length; i++)
|
{
|
var state = data.Substring(i * 2 + 1, 1);
|
////Console.WriteLine($"门{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 });
|
}
|
}
|
//}
|
}
|
private static void DaMingShanAnalysisProductLine(string data, Settings.deviceInfo plc)
|
{
|
LogHelper.Info($"输送线:{plc.deviceName} 下线信号:{data} 查询工单", "输送线");
|
if (data.Substring(0, 2) == "12")
|
{
|
var info = Settings.GetDeviceInfoList().Where(a => a.address == "" && a.location.Contains(plc.location[0]) && a.enable == 1).FirstOrDefault();
|
if (info != null)
|
{
|
var positionCode = "";
|
if (info.location.Length > 1)
|
{
|
positionCode = info.location[1];
|
}
|
ProductLineFull(info, info.location[0], positionCode);
|
}
|
}
|
|
//补空板||允许补空
|
if (data.Substring(2, 2) == "21")
|
{
|
var info = Settings.GetDeviceInfoList().Where(a => a.address == "" && a.location.Contains(plc.location[1]) && a.enable == 1).FirstOrDefault();
|
if (info != null)
|
{
|
ProductLineEmpty(info, info.location[0]);
|
}
|
}
|
|
if (data.Length == 6)
|
{
|
if (data.Substring(4, 2) == "32")
|
{
|
var info = Settings.GetDeviceInfoList().Where(a => a.address == "" && a.location.Contains(plc.location[2]) && a.enable == 1).FirstOrDefault();
|
if (info != null)
|
{
|
var positionCode = "";
|
if (info.location.Length > 1)
|
{
|
positionCode = info.location[1];
|
}
|
ProductLineFull(info, info.location[0], positionCode);
|
}
|
else
|
{
|
LogHelper.Info($"没有找到location {plc.location[2]} 的配置文件");
|
}
|
}
|
}
|
|
|
|
if (LineState.Keys.Contains(plc.location[0]))
|
{
|
LineState[plc.location[0]].modify = DateTime.Now;
|
LineState[plc.location[0]].status = data;
|
}
|
else
|
{
|
LineState.Add(plc.location[0], new statemodel { modify = DateTime.Now, status = data });
|
}
|
|
if (LineState.Keys.Contains(plc.location[1]))
|
{
|
LineState[plc.location[1]].modify = DateTime.Now;
|
LineState[plc.location[1]].status = data;
|
}
|
else
|
{
|
LineState.Add(plc.location[1], new statemodel { modify = DateTime.Now, status = data });
|
}
|
|
if (plc.location.Length > 2)
|
{
|
if (LineState.Keys.Contains(plc.location[2]))
|
{
|
LineState[plc.location[2]].modify = DateTime.Now;
|
LineState[plc.location[2]].status = data;
|
}
|
else
|
{
|
LineState.Add(plc.location[2], new statemodel { modify = DateTime.Now, status = data });
|
}
|
}
|
}
|
|
|
|
|
/// <summary>
|
/// 输送线补空托
|
/// </summary>
|
/// <param name="plc"></param>
|
/// <param name="location"></param>
|
private static void ProductLineEmpty(Settings.deviceInfo plc, string location)
|
{
|
try
|
{
|
if (location != "")
|
{
|
if (LocationHelper.CheckLocFree(location))
|
{
|
LogHelper.Info($"输送线:{plc.deviceName} 补空信号:{location} 查询工单", "输送线");
|
var list = plc.deviceName.Split(',').ToList();
|
foreach (var item in list)
|
{
|
var workorder = WCSHelper.GetWorkOrder(item);
|
if (workorder != null && workorder.S_WorkState.Trim() == "执行中")
|
{
|
LogHelper.Info($"输送线:{item} 下线信号:{location} 找到工单", "输送线");
|
ProductLineempty(plc, location, workorder, item);
|
break;
|
}
|
else
|
{
|
LogHelper.Info($"输送线:{plc.deviceName} 下线信号:{location} 未找到工单", "输送线");
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info($"输送线:{plc.deviceName} 当前位置{location}有任务,不可触发栈板上线", "输送线");
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
//Console.WriteLine($"输送线呼叫空托异常! 异常信息={ex.Message}");
|
}
|
}
|
|
private static void ProductLineempty(Settings.deviceInfo plc, string location, WorkOrder workorder, string deviceName)
|
{
|
bool result = false;
|
var db = new SqlHelper<object>().GetInstance();
|
try
|
{
|
LogHelper.Info($"输送线:{deviceName} 下线信号:{location} 查询空托库区", "输送线");
|
var info = Settings.GetDaMingShanPriProLineList().Where(a => a.deviceName == deviceName && a.ItemTrayType == "空").FirstOrDefault();
|
if (info != null)
|
{
|
for (int i = 0; i < info.ProductArea.Length; i++)
|
{
|
string AreaCode = info.ProductArea[i];
|
var startLocation = IntensiveArea.GetEmptyOut(AreaCode, workorder.S_TrayType);
|
if (startLocation != null)
|
{
|
var iteminfo = db.Queryable<ItemRel>().Where(a => a.S_ITEM_CODE == workorder.S_ItemCode && a.S_ITEM_MODEL == workorder.S_ItemLayer).First();
|
if (iteminfo != null)
|
{
|
result = IntensiveArea.DaMingShanCreateTransport(startLocation.S_LOC_CODE, location, "栈板上线", startLocation.LocCntrRel.S_CNTR_CODE, 1, 1, deviceName, 1, 1, int.Parse(iteminfo.S_ITEM_LAYER), workorder.S_WorkNo, "", "", workorder.S_TrayType);
|
if (result)
|
{
|
break;
|
}
|
}
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info($"输送线:{plc.deviceName} 下线信号:{location} 未找到空托库区配置文件", "输送线");
|
}
|
}
|
catch (Exception ex)
|
{
|
//Console.WriteLine($"查询补空库区配置文件异常,异常原因={ex.Message}");
|
}
|
}
|
|
internal static void QuLiao(WMSTask mst, bool v)
|
{
|
var info = Settings.GetDeviceInfoList().Where(a => a.location.Contains(mst.S_START_LOC) && a.address != "").FirstOrDefault();
|
if (info != null)
|
{
|
LogHelper.Info($"安全交互开始 任务号={mst.S_TASK_NO}", "安全交互");
|
if (info.location[0] == mst.S_START_LOC)
|
{
|
//一号口
|
if (v)
|
{
|
if (LineState.Keys.Contains(mst.S_START_LOC.Trim()))
|
{
|
LogHelper.Info($"查询输送线允许取满信号 允许取满信号={LineState[mst.S_START_LOC.Trim()].status} 时间间隔={DateTime.Now.Subtract(LineState[mst.S_START_LOC.Trim()].modify).TotalSeconds}", "安全交互");
|
if (LineState[mst.S_START_LOC.Trim()].status.Substring(0, 2) == "12" && DateTime.Now.Subtract(LineState[mst.S_START_LOC.Trim()].modify).TotalSeconds < 10)
|
{
|
NDCHelper.ChangeParam(mst.S_TASK_NO.Trim(), 1101, 18);
|
PlcHelper.SendHex(info.address, "3F00110D0A");
|
}
|
}
|
}
|
else
|
{
|
PlcHelper.SendHex(info.address, "3F00100D0A");
|
}
|
}
|
else
|
{
|
//二号口
|
if (v)
|
{
|
if (LineState.Keys.Contains(mst.S_START_LOC.Trim()))
|
{
|
LogHelper.Info($"查询输送线允许取满信号 允许取满信号={LineState[mst.S_START_LOC.Trim()].status} 时间间隔={DateTime.Now.Subtract(LineState[mst.S_START_LOC.Trim()].modify).TotalSeconds}", "安全交互");
|
if (LineState[mst.S_START_LOC.Trim()].status.Substring(4, 2) == "32" && DateTime.Now.Subtract(LineState[mst.S_START_LOC.Trim()].modify).TotalSeconds < 10)
|
{
|
NDCHelper.ChangeParam(mst.S_TASK_NO.Trim(), 1101, 18);
|
PlcHelper.SendHex(info.address, "3F00310D0A");
|
}
|
}
|
}
|
else
|
{
|
PlcHelper.SendHex(info.address, "3F00300D0A");
|
}
|
}
|
|
}
|
else
|
{
|
LogHelper.Info($"任务号 {mst.S_TASK_NO} 找不到起点{mst.S_START_LOC} 对应的IP配置文件");
|
}
|
}
|
|
internal static void Xieliao(WMSTask mst, bool v = false)
|
{
|
var info = Settings.GetDeviceInfoList().Where(a => a.location.Contains(mst.S_END_LOC) && a.address != "").FirstOrDefault();
|
if (info != null)
|
{
|
LogHelper.Info($"安全交互开始 任务号={mst.S_TASK_NO}", "安全交互");
|
if (info.deviceType == 5)
|
{
|
if (v)
|
{
|
if (LineState.Keys.Contains(mst.S_END_LOC.Trim()))
|
{
|
LogHelper.Info($"查询输送线允许补空信号 允许补空信号={LineState[mst.S_END_LOC.Trim()].status} 时间间隔={DateTime.Now.Subtract(LineState[mst.S_END_LOC.Trim()].modify).TotalSeconds}", "安全交互");
|
if (LineState[mst.S_END_LOC.Trim()].status.Substring(2, 2) == "21" && DateTime.Now.Subtract(LineState[mst.S_END_LOC.Trim()].modify).TotalSeconds < 10)
|
{
|
NDCHelper.ChangeParam(mst.S_TASK_NO.Trim(), 1103, 18);
|
PlcHelper.SendHex(info.address, "3F00210D0A");
|
}
|
}
|
}
|
else
|
{
|
PlcHelper.SendHex(info.address, "3F00200D0A");
|
}
|
}
|
else if (info.deviceType == 3 || info.deviceType == 6)
|
{
|
if (v)
|
{
|
if (LineState.Keys.Contains(mst.S_END_LOC.Trim()))
|
{
|
LogHelper.Info($"查询翻斗机允许卸货信号 允许卸货信号={LineState[mst.S_END_LOC.Trim()].status} 时间间隔={DateTime.Now.Subtract(LineState[mst.S_END_LOC.Trim()].modify).TotalSeconds}", "安全交互");
|
if (LineState[mst.S_END_LOC.Trim()].error ==0 && DateTime.Now.Subtract(LineState[mst.S_END_LOC.Trim()].modify).TotalSeconds < 10)
|
{
|
NDCHelper.ChangeParam(mst.S_TASK_NO.Trim(), 1103, 18);
|
}
|
}
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info($"任务号 {mst.S_TASK_NO} 找不到终点{mst.S_END_LOC} 对应的IP配置文件");
|
}
|
}
|
|
private static bool ProductLineFull(Settings.deviceInfo plc, string location, string positionCode = "")
|
{
|
var result = false;
|
try
|
{
|
if (location != "")
|
{
|
//取满,需要根据工单以及产线信息,判断当前产线应该下发到哪个库区,以及是什么托盘类型下线
|
if (LocationHelper.CheckLocFree(location))
|
{
|
LogHelper.Info($"输送线:{plc.deviceName} 下线信号:{location} 查询工单", "输送线");
|
//1.查询当前产线工单信息
|
var list = plc.deviceName.Split(',').ToList();
|
foreach (var item in list)
|
{
|
var deviceName = item;
|
//plc.deviceName = item;
|
var workOrder = WCSHelper.GetWorkOrder(deviceName);//初始工单由富勒WMS传输,后续读取工单读取MOBOX工单表
|
if (workOrder != null && workOrder.S_WorkState.Trim() == "执行中")
|
{
|
LogHelper.Info($"输送线:{deviceName} 查询到执行中的工单 查询工单", "输送线");
|
string DeviceStartTime = DateTime.Now.ToString();//当前设备第一次收到下线信号时间
|
string TrayCode = "";//托盘编码--多个编码用 英文逗号隔开
|
string BatchNo = string.IsNullOrEmpty(workOrder.S_BatchNo) ? "" : workOrder.S_BatchNo.Trim();//批次号
|
string ItemLayer = string.IsNullOrEmpty(workOrder.S_ItemLayer) ? "10" : workOrder.S_ItemLayer.Trim();//物料层数
|
string ItemTrayType = string.IsNullOrEmpty(workOrder.S_TrayType) ? "" : workOrder.S_TrayType.Trim();//货物大小板--大板、小板
|
string StartBit = plc.location[0];
|
string EndBit = "";
|
string StartLayer = "1";//成品下线-起点层数默认为1
|
string EndLayer = "";
|
|
string plineNo = workOrder.S_PLineNo;
|
//产线下线流程----正常流程下线
|
if (workOrder.S_ORDER_TYPE.Trim() != "无码入库")
|
{
|
bool full = true;
|
//判断当前货位是否存在托盘,如果存在则 无需从托盘信息中间表获取
|
var db = new SqlHelper<object>().GetInstance();
|
var trayInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == StartBit).ToList();
|
if (trayInfo.Count() > 0)
|
{
|
BatchNo = workOrder.S_BatchNo.Trim();
|
ItemLayer = workOrder.S_ItemLayer.Trim();
|
string trayNo = "";
|
trayInfo.ForEach(a =>
|
{
|
trayNo = a.S_CNTR_CODE;
|
TrayCode = TrayCode + a.S_CNTR_CODE + ",";
|
});
|
//获取工单号
|
var task = db.Queryable<WMSTask>().Where(a => a.S_CNTRS.Contains(trayNo)).OrderByDescending(a => a.T_CREATE).First();
|
if (task != null)
|
{
|
LogHelper.Info($"获取任务{task.S_TASK_NO} 工单号{task.S_SRC_NO}");
|
workOrder.S_WorkNo = task.S_SRC_NO;
|
}
|
else
|
{
|
LogHelper.Info($"未获取到工单号");
|
full = false;
|
}
|
}
|
else
|
{
|
//2.获取设备第一次下线时间
|
bool IsTime = true;
|
DeviceStartTime = ConveryInfoFullTwo(plc, DeviceStartTime, deviceName);
|
|
if (IsTime)
|
{
|
//3.处理 工单信息表数据--托规、批次号、物料层数
|
full = ConveryInfoFullThree(plc, location, workOrder, DeviceStartTime, positionCode, deviceName, ref TrayCode, ref BatchNo, ref ItemLayer);
|
}
|
else full = false;
|
}
|
|
if (full)
|
{
|
//5.正常产线下线
|
ProductLineFull(plc, location, workOrder, TrayCode, BatchNo, ItemLayer, ItemTrayType, StartBit, deviceName);
|
}
|
else LogHelper.Info($"输送线:{deviceName} 下线信号:{location},下线时间:{DeviceStartTime},托盘信息存在异常,请查询异常日志!", "输送线");
|
}
|
//无码入库流程----人工创建工单时----工单类型 应选择 无码入库
|
else
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
var trayInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == location).ToList();
|
if (trayInfo.Count() == 0) TrayCode = Guid.NewGuid().ToString("N") + "," + Guid.NewGuid().ToString("N");
|
else
|
{
|
trayInfo.ForEach(a =>
|
{
|
TrayCode = TrayCode + "," + a.S_CNTR_CODE.Trim();
|
});
|
}
|
LogHelper.Info($"输送线:{deviceName} 下线信号:{location} 无码入库!", "输送线");
|
//Console.WriteLine($"输送线:{plc.deviceName} 下线信号:{location} 无码入库!");
|
ProductLineFull(plc, location, workOrder, TrayCode, BatchNo, ItemLayer, ItemTrayType, StartBit, deviceName);
|
}
|
}
|
else LogHelper.Info($"输送线:{deviceName} 下线信号:{location} 未找到工单", "输送线");
|
}
|
}
|
else LogHelper.Info($"输送线:{plc.deviceName} 当前位置{location}有任务,不可触发满托下线", "输送线");
|
}
|
}
|
catch (Exception ex)
|
{
|
//Console.WriteLine($"输送线处理异常:{ex.Message}");
|
LogHelper.Error($"输送线处理异常:{ex.Message}", ex);
|
}
|
|
return result;
|
}
|
|
|
public static void ProductLineFull(Settings.deviceInfo plc, string location, WorkOrder workOrder, string TrayCode, string BatchNo, string ItemLayer, string ItemTrayType, string StartBit, string deviceName, bool ProType = true)
|
{
|
//5.根据配置文件获取当前产线优先下发库区,再连同物料、大小板、批次,获取此库区 可用货位
|
// 遍历库区查询-判断排锁-表名: RowLock
|
var creResult = false;
|
LogHelper.Info($"输送线:{deviceName} 查询入库终点货位 批次号{BatchNo}", "输送线");
|
var db = new SqlHelper<object>().GetInstance();
|
////Console.WriteLine($"输送线:{plc.deviceName} 查询入库终点货位");
|
//string ItemNameLayer = workOrder.S_ItemCode.Trim() + workOrder.S_ItemLayer.Trim();
|
//var PriProLineInfo = Settings.GetDaMingShanPriProLineList().Where(a => a.deviceName == plc.deviceName && a.ItemTrayType == "满" && a.ItemName == workOrder.S_ItemCode.Trim()).FirstOrDefault();
|
var PriProLineInfo = db.Queryable<ItemArea>().Where(a => a.S_ITEM_CODE == workOrder.S_ItemCode.Trim() && a.S_TRAY_TYPE == ItemTrayType).OrderByDescending(a => a.S_PRIORITY).ToList();
|
if (PriProLineInfo != null)
|
{
|
if (ProType)
|
{
|
LogHelper.Info($"输送线:{deviceName} 查询到配置文件", "输送线");
|
////Console.WriteLine($"输送线:{plc.deviceName} 查询到配置文件");
|
for (int i = 0; i < PriProLineInfo.Count(); i++)
|
{
|
string areaCode = PriProLineInfo[i].S_AREA_CODE;
|
if (!creResult) creResult = IntensiveArea.DaMingShanPlcTask(StartBit, "成品下线", TrayCode, areaCode, workOrder.S_ItemCode.Trim(), BatchNo, ItemLayer, ItemTrayType, deviceName, true, workOrder.S_WorkNo.Trim());
|
}
|
}
|
//else
|
//{
|
// for (int i = 0; i < PriProLineInfo.Count(); i++)
|
// {
|
// string areaCode = PriProLineInfo[i].S_AREA_CODE;
|
// if (!creResult) creResult = IntensiveArea.DaMingShanPlcTask(StartBit, "零头下线", TrayCode, areaCode, workOrder.S_ItemCode.Trim(), BatchNo, ItemLayer, ItemTrayType, plc.deviceName, true, workOrder.S_WorkNo.Trim());
|
// }
|
//}
|
|
if (creResult)
|
{
|
//任务创建成功 绑定起点托盘表,托盘物料表
|
LogHelper.Info("绑定货位容器");
|
IntensiveArea.BindLocCntr(StartBit, TrayCode, workOrder.S_ItemCode.Trim(), BatchNo, deviceName, ItemLayer, ItemTrayType);
|
}
|
}
|
else LogHelper.Info($"输送线:{deviceName} 下线信号:{location} 未获取到当前产线的优先下线库区 DaMingShanPriProLine 配置项。该物料不存在:{workOrder.S_ItemCode.Trim()}", "输送线");
|
}
|
|
|
/// <summary>
|
/// 农夫大明山 处理翻斗机下空筐请求
|
/// </summary>
|
/// <param name="plc">配置信息</param>
|
/// <param name="location">下件口</param>
|
/// <returns></returns>
|
private static bool TipperEmpty(Settings.deviceInfo plc, string location)
|
{
|
//通过站点编号查询工单
|
//通过工单获取物料编码、批号(前期富勒没上线批号自行编写)
|
var result = false;
|
|
var db = new SqlHelper<object>().GetInstance();
|
if (location != "")
|
{
|
if (LocationHelper.CheckLocFree(location))
|
{
|
var taskFree = db.Queryable<WMSTask>().Where(a => a.S_START_LOC == location && a.S_B_STATE != "取消" && a.S_B_STATE != "完成" && a.S_B_STATE != "失败").First();
|
if (taskFree == null)
|
{
|
LogHelper.Info($"翻斗机:{plc.deviceName} 下线信号:{location} 查询工单", "翻斗机");
|
var workOrder = WCSHelper.GetPGWorkOrder(plc.deviceName);
|
if (workOrder != null)
|
{
|
LogHelper.Info($"查到了工单{workOrder.S_WorkNo} 工单状态为: {workOrder.S_WorkState} 即产即用={workOrder.S_UsingNow}", "翻斗机");
|
if (workOrder.S_WorkState == "执行中")
|
{
|
var trayInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == location).ToList();
|
if (trayInfo.Count() > 0)
|
{
|
string TrayCode = "";
|
//string newbatchNo = DateTime.Now.Year.ToString() + "-" + DateTime.Now.Month.ToString() + "-" + DateTime.Now.Day.ToString() + "-" + SYSHelper.GenerateUniqueText(8);
|
//string BatchNo = string.IsNullOrEmpty(workOrder.S_BatchNo) ? newbatchNo : workOrder.S_BatchNo;
|
foreach (var b in trayInfo)
|
{
|
TrayCode = TrayCode + "," + b.S_CNTR_CODE.Trim();
|
}
|
if (!string.IsNullOrEmpty(TrayCode))
|
{
|
LogHelper.Info($"翻斗机 货位托盘号={TrayCode}");
|
if (workOrder.S_UsingNow == "Y")
|
{
|
result = IntensiveArea.DaMingShanPLCIn3(plc, location, TrayCode, "", true);
|
}
|
else
|
{
|
result = IntensiveArea.DaMingShanPLCIn3(plc, location, TrayCode, "", false);
|
}
|
}
|
}
|
else
|
{
|
//自动生成托盘码
|
string TrayCode = Guid.NewGuid().ToString().Replace("-", "");
|
if (!string.IsNullOrEmpty(TrayCode))
|
{
|
LogHelper.Info($"翻斗机 货位托盘号={TrayCode}");
|
if (workOrder.S_UsingNow == "Y")
|
{
|
result = IntensiveArea.DaMingShanPLCIn3(plc, location, TrayCode, "", true);
|
}
|
else
|
{
|
result = IntensiveArea.DaMingShanPLCIn3(plc, location, TrayCode, "", false);
|
}
|
}
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info($"翻斗机:{plc.deviceName} 下线信号:{location} 未找到工单", "翻斗机");
|
}
|
}
|
else LogHelper.Info($"该点位有未完成的任务 不允许重复生成任务 任务号{taskFree.S_TASK_NO}");
|
}
|
else
|
{
|
LogHelper.Info($"翻斗机:{plc.deviceName} 当前位置{location}有任务,不可触发空托下线", "翻斗机");
|
}
|
}
|
else
|
{
|
LogHelper.Info($"翻斗机:{plc.deviceName} 点位为空", "翻斗机");
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 农夫大明山 处理翻斗机下空筐请求
|
/// </summary>
|
/// <param name="plc">配置信息</param>
|
/// <param name="location">下件口</param>
|
/// <returns></returns>
|
private static bool TipperEmpty2(Settings.deviceInfo plc, string location)
|
{
|
//通过站点编号查询工单
|
//通过工单获取物料编码、批号(前期富勒没上线批号自行编写)
|
var result = false;
|
try
|
{
|
var db = new SqlHelper<object>().GetInstance();
|
if (location != "")
|
{
|
if (LocationHelper.CheckLocFree(location))
|
{
|
var taskFree = db.Queryable<WMSTask>().Where(a => a.S_START_LOC == location && a.S_B_STATE != "取消" && a.S_B_STATE != "完成" && a.S_B_STATE != "失败").First();
|
if (taskFree == null)
|
{
|
LogHelper.Info($"翻斗机:{plc.deviceName} 下线信号:{location} 查询工单", "翻斗机");
|
var workOrder = WCSHelper.GetPGWorkOrder(plc.deviceName);
|
if (workOrder != null)
|
{
|
LogHelper.Info($"查到了工单{workOrder.S_WorkNo} 工单状态为: {workOrder.S_WorkState} 即产即用={workOrder.S_UsingNow}", "翻斗机");
|
if (workOrder.S_WorkState == "执行中")
|
{
|
var trayInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == location).ToList();
|
if (trayInfo.Count() > 0)
|
{
|
string TrayCode = "";
|
//string newbatchNo = DateTime.Now.Year.ToString() + "-" + DateTime.Now.Month.ToString() + "-" + DateTime.Now.Day.ToString() + "-" + SYSHelper.GenerateUniqueText(8);
|
//string BatchNo = string.IsNullOrEmpty(workOrder.S_BatchNo) ? newbatchNo : workOrder.S_BatchNo;
|
foreach (var b in trayInfo)
|
{
|
TrayCode = TrayCode + "," + b.S_CNTR_CODE.Trim();
|
}
|
if (!string.IsNullOrEmpty(TrayCode))
|
{
|
LogHelper.Info($"翻斗机 货位托盘号={TrayCode}");
|
if (workOrder.S_UsingNow == "Y")
|
{
|
result = IntensiveArea.DaMingShanPLCIn4(plc, location, TrayCode, workOrder, true);
|
}
|
else
|
{
|
result = IntensiveArea.DaMingShanPLCIn4(plc, location, TrayCode, workOrder, false);
|
}
|
}
|
}
|
else
|
{
|
//自动生成托盘码
|
string TrayCode = Guid.NewGuid().ToString().Replace("-", "");
|
if (!string.IsNullOrEmpty(TrayCode))
|
{
|
LogHelper.Info($"翻斗机 货位托盘号={TrayCode}");
|
if (workOrder.S_UsingNow == "Y")
|
{
|
result = IntensiveArea.DaMingShanPLCIn4(plc, location, TrayCode, workOrder, true);
|
}
|
else
|
{
|
result = IntensiveArea.DaMingShanPLCIn4(plc, location, TrayCode, workOrder, false);
|
}
|
}
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info($"翻斗机:{plc.deviceName} 下线信号:{location} 未找到工单", "翻斗机");
|
}
|
}
|
else LogHelper.Info($"该点位有未完成的任务 不允许重复生成任务 任务号{taskFree.S_TASK_NO}");
|
}
|
else
|
{
|
LogHelper.Info($"翻斗机:{plc.deviceName} 当前位置{location}有任务,不可触发空托下线", "翻斗机");
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Error($"瓶坯翻斗机异常 异常信息={ex.Message}", ex);
|
}
|
|
return result;
|
}
|
|
|
|
|
/// <summary>
|
/// 接收PLC注塑机信号
|
/// </summary>
|
/// <param name="data"></param>
|
/// <param name="plc"></param>
|
private static void DaMingShanAnalysisBottleCapmolding(string data, Settings.deviceInfo plc)
|
{
|
LogHelper.Info($"{plc.deviceName}--IP={plc.address}--msg={data}", "注塑机");
|
//下满筐信号生成下满筐任务 待取货完成解绑起点货位 生成送空任务
|
if (data.Substring(0, 2) == "11")
|
{
|
if (moldingFull(plc, plc.location[0]))
|
{
|
LogHelper.Info($"{plc.deviceName}--IP={plc.address}--msg=注塑机A口生成取满任务", "注塑机");
|
}
|
}
|
if (data.Substring(2, 2) == "21")
|
{
|
if (moldingFull(plc, plc.location[1]))
|
{
|
LogHelper.Info($"{plc.deviceName}--IP={plc.address}--msg=注塑机B口生成取满任务", "注塑机");
|
}
|
}
|
|
LogHelper.Info($"自动门状态:{data},地址为:{plc.address}", "自动门");
|
data = data.Substring(4);
|
if (data.Length / 2 == plc.deviceNo.Length)//2 2
|
{
|
for (int i = 0; i < plc.deviceNo.Length; i++)
|
{
|
var state = data.Substring(i * 2 + 1, 1);
|
////Console.WriteLine($"门{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 });
|
}
|
}
|
}
|
|
}
|
|
/// <summary>
|
/// 农夫大明山--处理注塑机满托请求
|
/// </summary>
|
/// <param name="plc"></param>
|
/// <param name="location"></param>
|
private static bool moldingFull(Settings.deviceInfo plc, string location)
|
{
|
//通过站点编号查询工单
|
//通过工单获取物料编码、批号(前期富勒没上线批号自行编写)
|
var result = false;
|
|
var db = new SqlHelper<object>().GetInstance();
|
if (location != "")
|
{
|
if (LocationHelper.CheckLocFree(location))
|
{
|
LogHelper.Info($"瓶盖机:{plc.deviceName} 下线信号:{location} 查询工单", "瓶盖机");
|
var workOrder = WCSHelper.GetPGWorkOrder(plc.deviceName);
|
if (workOrder != null)
|
{
|
LogHelper.Info($"查到了工单{workOrder.S_WorkNo} 工单状态为: {workOrder.S_WorkState} 即产即用={workOrder.S_UsingNow} 连接区域={workOrder.S_LinkLineNo}", "瓶盖机");
|
if (workOrder.S_WorkState.Trim() == "执行中")
|
{
|
LogHelper.Info($"查询当前货位 托盘数量 货位编码={location}");
|
var trayInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == location).ToList();
|
if (trayInfo.Count() > 0)
|
{
|
LogHelper.Info($"当前货位托盘数量大于0");
|
string TrayCode = trayInfo[0].S_CNTR_CODE;
|
//string newbatchNo = DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString() + SYSHelper.GenerateUniqueText(8);
|
//string BatchNo = string.IsNullOrEmpty(workOrder.) ? newbatchNo : workOrder.S_BatchNo;
|
if (!string.IsNullOrEmpty(TrayCode))
|
{
|
if (workOrder.S_UsingNow == "Y")
|
{
|
result = IntensiveArea.DaMingShanPLCIn(plc, location, TrayCode, "", workOrder, true);
|
}
|
else
|
{
|
result = IntensiveArea.DaMingShanPLCIn(plc, location, TrayCode, "", workOrder, false);
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info($"瓶盖机:{plc.deviceName} 下线信号:{location} 该站点没有托盘无法取满", "瓶盖机");
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info($"瓶盖机:{plc.deviceName} 下线信号:{location} 未找到工单", "瓶盖机");
|
}
|
}
|
else
|
{
|
LogHelper.Info($"瓶盖机:{plc.deviceName} 当前位置{location}有任务,不可触发满托下线", "瓶盖机");
|
}
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 农夫大明山--处理瓶盖机满托请求
|
/// </summary>
|
/// <param name="plc"></param>
|
/// <param name="location"></param>
|
private static bool moldingFull2(Settings.deviceInfo plc, string location)
|
{
|
//通过站点编号查询工单
|
//通过工单获取物料编码、批号(前期富勒没上线批号自行编写)
|
var result = false;
|
|
var db = new SqlHelper<object>().GetInstance();
|
if (location != "")
|
{
|
if (LocationHelper.CheckLocFree(location))
|
{
|
LogHelper.Info($"瓶盖机:{plc.deviceName} 下线信号:{location} 查询工单", "瓶盖机");
|
var workOrder = WCSHelper.GetPGWorkOrder(plc.deviceName);
|
if (workOrder != null)
|
{
|
LogHelper.Info($"查到了工单{workOrder.S_WorkNo} 工单状态为: {workOrder.S_WorkState} 即产即用={workOrder.S_UsingNow}", "瓶盖机");
|
if (workOrder.S_WorkState.Trim() == "执行中")
|
{
|
LogHelper.Info($"查询当前货位 托盘数量 货位编码={location}");
|
var trayInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == location).ToList();
|
if (trayInfo.Count() > 0)
|
{
|
LogHelper.Info($"当前货位托盘数量大于0");
|
string TrayCode = trayInfo[0].S_CNTR_CODE;
|
//string newbatchNo = DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString() + SYSHelper.GenerateUniqueText(8);
|
//string BatchNo = string.IsNullOrEmpty(workOrder.S_BatchNo) ? newbatchNo : workOrder.S_BatchNo;
|
if (!string.IsNullOrEmpty(TrayCode))
|
{
|
if (workOrder.S_UsingNow == "Y")
|
{
|
result = IntensiveArea.DaMingShanPLCIn2(plc, location, TrayCode, "", workOrder.S_ItemCode, true);
|
}
|
else
|
{
|
result = IntensiveArea.DaMingShanPLCIn2(plc, location, TrayCode, "", workOrder.S_ItemCode, false);
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info($"瓶盖机:{plc.deviceName} 下线信号:{location} 该站点没有托盘无法取满", "瓶盖机");
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info($"瓶盖机:{plc.deviceName} 下线信号:{location} 未找到工单", "瓶盖机");
|
}
|
}
|
else
|
{
|
LogHelper.Info($"瓶盖机:{plc.deviceName} 当前位置{location}有任务,不可触发满托下线", "瓶盖机");
|
}
|
}
|
return result;
|
}
|
|
private static bool moldingEmpty(Settings.deviceInfo plc, string location)
|
{
|
//通过站点编号查询工单
|
//通过工单获取物料编码、批号(前期富勒没上线批号自行编写)
|
var result = false;
|
|
var db = new SqlHelper<object>().GetInstance();
|
if (location != "")
|
{
|
if (LocationHelper.CheckLocFree(location))
|
{
|
LogHelper.Info($"注塑机:{plc.deviceName} 下线信号:{location} 查询工单", "注塑机");
|
var workOrder = WCSHelper.GetPGWorkOrder(plc.deviceName);
|
if (workOrder != null)
|
{
|
LogHelper.Info($"查到了工单{workOrder.S_WorkNo} 工单状态为: {workOrder.S_WorkState}", "注塑机");
|
if (workOrder.S_WorkState.Trim() == "执行中")
|
{
|
var trayInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE.Trim() == location).ToList();
|
if (trayInfo.Count() == 0)
|
{
|
result = IntensiveArea.DaMingShanPLCOut(plc, location, true, workOrder);
|
}
|
else
|
{
|
LogHelper.Info($"注塑机:{plc.deviceName} 下线信号:{location} 该站点有托盘无法送空", "注塑机");
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info($"注塑机:{plc.deviceName} 下线信号:{location} 未找到工单", "注塑机");
|
}
|
}
|
else
|
{
|
LogHelper.Info($"注塑机:{plc.deviceName} 当前位置{location}有任务,不可触发栈板上线", "注塑机");
|
}
|
}
|
return result;
|
}
|
|
private static bool moldingEmpty2(Settings.deviceInfo plc, string location)
|
{
|
//通过站点编号查询工单
|
//通过工单获取物料编码、批号(前期富勒没上线批号自行编写)
|
var result = false;
|
|
var db = new SqlHelper<object>().GetInstance();
|
if (location != "")
|
{
|
if (LocationHelper.CheckLocFree(location))
|
{
|
LogHelper.Info($"瓶盖机:{plc.deviceName} 下线信号:{location} 查询工单", "瓶盖机");
|
var workOrder = WCSHelper.GetPGWorkOrder(plc.deviceName);
|
if (workOrder != null)
|
{
|
LogHelper.Info($"查到了工单{workOrder.S_WorkNo} 工单状态为: {workOrder.S_WorkState}", "瓶盖机");
|
if (workOrder.S_WorkState.Trim() == "执行中")
|
{
|
var trayInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE.Trim() == location).ToList();
|
if (trayInfo.Count() == 0)
|
{
|
//if (workOrder.S_UsingNo == "Y")
|
//{
|
result = IntensiveArea.DaMingShanPLCOut2(plc, location, true, workOrder);
|
//}
|
//else
|
//{
|
// result = IntensiveArea.DaMingShanPLCOut2(plc, location, false);
|
//}
|
if (!result)
|
{
|
LogHelper.Info($"空筐缓存区无可用空筐");
|
}
|
}
|
else
|
{
|
LogHelper.Info($"瓶盖机:{plc.deviceName} 下线信号:{location} 该站点有托盘无法送空", "瓶盖机");
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info($"瓶盖机:{plc.deviceName} 下线信号:{location} 未找到工单", "瓶盖机");
|
}
|
}
|
else
|
{
|
LogHelper.Info($"瓶盖机:{plc.deviceName} 当前位置{location}有任务,不可触发栈板上线", "瓶盖机");
|
}
|
}
|
return result;
|
}
|
#endregion
|
|
#region 自动门--通用
|
|
private static Dictionary<string, signalInfo> doorStatus = new Dictionary<string, signalInfo>();//普通自动门字典
|
private static Dictionary<string, DateTime> doorRecord = new Dictionary<string, DateTime>();
|
private static Dictionary<string, DateTime> elevatorRecord = new Dictionary<string, DateTime>();//电梯安全门字典
|
public class signalInfo
|
{
|
public string info { get; set; }
|
public DateTime modify { get; set; }
|
public int error { get; set; } = 0;
|
}
|
|
/// <summary>
|
/// 交管信号处理
|
/// </summary>
|
/// <param name="agvNo"></param>
|
/// <param name="lockNo"></param>
|
/// <param name="state"></param>
|
internal static void SpecialTraffic(string agvNo, string lockNo, int state)
|
{
|
if (state == 1023 || state == 1025)
|
{
|
Traffic(agvNo, lockNo, state == 1023);//标准交管处理 1023 1025
|
}
|
|
if (state == 1120)
|
{
|
tiqianopen(agvNo, lockNo);
|
}
|
}
|
|
private static void tiqianopen(string agvNo, string lockNo)
|
{
|
LogHelper.Info($"安全门开门请求 车号={agvNo} 门号={lockNo}");
|
var plc = Settings.GetDeviceInfoList().Where(a => a.deviceNo.Contains(lockNo)).FirstOrDefault();
|
if (plc != null)
|
{
|
LogHelper.Info($"找到配置文件");
|
var index = 1;
|
for (int i = 0; i < plc.deviceNo.Length; i++)
|
{
|
if (plc.deviceNo[i] == lockNo)
|
{
|
index = i + 1;
|
break;
|
}
|
}
|
index = index + plc.location.Length;
|
LogHelper.Info($"安全门对接:门号:{lockNo},index:{index}", "自动门");
|
|
|
//开门请求 3F 00 11 20 0d 0a( 3F 00 10 21 0d 0a)
|
var req = $"3f 00 {index}1 0d 0a";
|
PlcHelper.SendHex(plc.address, req);
|
var msg = $"安全门开门请求,门号:{lockNo},index:{index},ip={plc.address}, data={req}";
|
LogHelper.Info(msg, "自动门");
|
|
|
}
|
}
|
|
/// <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 2
|
{
|
for (int i = 0; i < plc.deviceNo.Length; i++)
|
{
|
var state = data.Substring(i * 2 + 1, 1);
|
////Console.WriteLine($"门{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 });
|
}
|
}
|
}
|
}
|
|
/// <summary>
|
/// TcpServer-交管请求
|
/// </summary>
|
/// <param name="agv"></param>
|
/// <param name="zone"></param>
|
/// <param name="occupy"></param>
|
internal static void Traffic(string agv, string zone, bool occupy)
|
{
|
LogHelper.Info($"安全门开门请求 车号={agv} 门号={zone} 开门请求={occupy}");
|
var plc = Settings.GetDeviceInfoList().Where(a => a.deviceNo.Contains(zone)).FirstOrDefault();
|
if (plc != null)
|
{
|
LogHelper.Info($"找到配置文件");
|
var index = 1;
|
for (int i = 0; i < plc.deviceNo.Length; i++)
|
{
|
if (plc.deviceNo[i] == zone)
|
{
|
index = i + 1;
|
break;
|
}
|
}
|
index = index + plc.location.Length;
|
LogHelper.Info($"安全门对接:门号:{zone},index:{index}", "自动门");
|
|
if (occupy)
|
{
|
//开门请求 3F 00 11 20 0d 0a( 3F 00 10 21 0d 0a)
|
var req = $"3f 00 {index}1 0d 0a";
|
PlcHelper.SendHex(plc.address, req);
|
var msg = $"安全门开门请求,门号:{zone},index:{index},ip={plc.address}, data={req}";
|
LogHelper.Info(msg, "自动门");
|
|
//车子请求一次就发一次开门请求
|
if (doorStatus.Keys.Contains(zone) && DateTime.Now.Subtract(doorStatus[zone].modify).TotalSeconds < 5)
|
{
|
if (doorStatus[zone].info == "1")
|
{
|
LogHelper.Info($"安全门已经打开:门号:{zone},index:{index}", "自动门");
|
NDCHelper.Traffic(zone);
|
}
|
}
|
}
|
else
|
{
|
//关门信号 3F 00 10 20 0d 0a
|
var req = $"3f 00 {index}0 0d 0a";
|
PlcHelper.SendHex(plc.address, req);
|
var msg = $"安全门关门请求,门号:{zone},index:{index},ip={plc.address}, data={req}";
|
LogHelper.Info(msg, "自动门");
|
}
|
}
|
}
|
|
/// <summary>
|
/// ModBusTcp-交管请求
|
/// </summary>
|
/// <param name="agv"></param>
|
/// <param name="zone"></param>
|
/// <param name="occupy"></param>
|
internal static void ModBusTraffic(string agv, string zone, bool occupy)
|
{
|
LogHelper.Info($"安全门对接:收到信号:{occupy},备注:真为1023,假为1025,门号:{zone},车号:{agv}", "自动门");
|
var plc = Settings.GetModBusTcpPlc().Where(a => a.location == zone).FirstOrDefault();
|
if (plc != null)
|
{
|
if (occupy)
|
{
|
int[] result = modbusHelper.ReadHoldingRegisters(plc.readAddr + 2, 1, plc.ip, plc.port);
|
if (result[0] == 1)
|
{
|
NDCHelper.Traffic(zone);
|
}
|
else
|
{
|
modbusHelper.WriteSingleRegister(plc.readAddr + 2, 1, plc.ip, plc.port);
|
}
|
}
|
else
|
{
|
modbusHelper.WriteSingleRegister(plc.readAddr + 2, 2, plc.ip, plc.port);
|
}
|
}
|
else
|
{
|
LogHelper.Info($"请检查配置文件:未在配置文件中查询到该门号的信息。当前门号:{zone}", "自动门");
|
}
|
}
|
|
/// <summary>
|
/// 十字路口安全交互
|
/// </summary>
|
/// <param name="agv"></param>
|
/// <param name="zone"></param>
|
/// <param name="occupy"></param>
|
internal static void Crossroads(string agv, string zone, bool occupy)
|
{
|
LogHelper.Info($"十字路口安全交互:收到信号:{occupy},备注:真为1101,假为1102,门号:{zone},车号:{agv}", "自动门");
|
var plc = Settings.GetModBusTcpPlc().Where(a => a.location == zone).FirstOrDefault();
|
if (plc != null)
|
{
|
if (occupy)
|
{
|
modbusHelper.WriteSingleRegister(plc.readAddr + 3, 1, plc.ip, plc.port);
|
}
|
else
|
{
|
modbusHelper.WriteSingleRegister(plc.readAddr + 3, 2, plc.ip, plc.port);
|
}
|
}
|
else
|
{
|
LogHelper.Info($"请检查配置文件:未在配置文件中查询到该门号的信息。当前门号:{zone}", "自动门");
|
}
|
}
|
|
/*
|
IO模块1 只用02功能码读取
|
1x0000 一楼开门到位信号
|
1x0001 二楼开门到位信号
|
|
|
IO模块2 只用05功能码写入
|
0x0000 一楼楼层按钮信号
|
0x0001 二楼楼层按钮信号
|
*/
|
/// <summary>
|
/// 电梯只需要开门,不需要关门
|
/// </summary>
|
/// <param name="zone"></param>
|
/// <param name="occupy"></param>
|
private static void TrafficElevator(string zone, bool occupy)
|
{
|
//判断是否时电梯门
|
var elevatorDoor = Settings.GetelEvatorDoorList().Where(a => a.door == zone).FirstOrDefault();
|
if (elevatorDoor != null)
|
{
|
//oitcp中转 modbus rtu 方式开电梯
|
//BitConverter.ToString(CRC16LH(Hex2Bytes("01 02 00 03 00 01"))).Replace("-", string.Empty).ToLower()
|
LogHelper.Info($"收到agv开电梯门请求{zone}", "电梯");
|
if (occupy)
|
{
|
var readAddr = elevatorDoor.addr == 1 ? 0 : 1;
|
var read = $"01 02 00 0{readAddr} 00 01 ";
|
read += BitConverter.ToString(PlcHelper.CRC16LH(PlcHelper.Hex2Bytes(read))).Replace("-", " ").ToLower();
|
LogHelper.Info($"查询电梯门{zone}状态发送{read}", "电梯");
|
var res = OITcpHelper.HexTransit(new OITcpHelper.StrTransitData { host = Settings.ElevatorIP, data = read, port = 8899 });
|
if (res != null && res.errCode == 0 && res.result.Replace(" ", "").Substring(7, 1) == "1")
|
{
|
//判断门开了,通知agv走
|
LogHelper.Info($"电梯门{zone}开了,通知agv进去", "电梯");
|
NDCHelper.Traffic(zone);
|
}
|
else
|
{
|
if (!elevatorRecord.Keys.Contains(zone) || DateTime.Now.Subtract(elevatorRecord[zone]).TotalSeconds < 8)
|
{
|
//开门是一次吸合,一次断开
|
var write = $"01 05 00 0{elevatorDoor.addr} ff 00 ";
|
write += BitConverter.ToString(PlcHelper.CRC16LH(PlcHelper.Hex2Bytes(write))).Replace("-", " ").ToLower();
|
LogHelper.Info($"发送电梯{zone}开门请求{write},吸合", "电梯");
|
res = OITcpHelper.HexTransit(new OITcpHelper.StrTransitData { host = Settings.ElevatorIP, data = write, port = 8899 });
|
if (res != null && res.errCode == 0)
|
{
|
//Console.WriteLine("准备发送断开信号");
|
Thread.Sleep(1000);
|
write = $"01 05 00 0{elevatorDoor.addr} 00 00 ";
|
write += BitConverter.ToString(PlcHelper.CRC16LH(PlcHelper.Hex2Bytes(write))).Replace("-", " ").ToLower();
|
LogHelper.Info($"发送电梯{zone}开门请求{write},断开", "电梯");
|
OITcpHelper.HexTransit(new OITcpHelper.StrTransitData { host = Settings.ElevatorIP, data = write, port = 8899 });
|
Thread.Sleep(1000);
|
LogHelper.Info($"发送电梯{zone}开门请求{write},断开", "电梯");
|
OITcpHelper.HexTransit(new OITcpHelper.StrTransitData { host = Settings.ElevatorIP, data = write, port = 8899 });
|
Thread.Sleep(1000);
|
LogHelper.Info($"发送电梯{zone}开门请求{write},断开", "电梯");
|
OITcpHelper.HexTransit(new OITcpHelper.StrTransitData { host = Settings.ElevatorIP, data = write, port = 8899 });
|
|
if (!elevatorRecord.Keys.Contains(zone))
|
{
|
elevatorRecord.Add(zone, DateTime.Now);
|
}
|
else
|
{
|
elevatorRecord[zone] = DateTime.Now;
|
}
|
}
|
else
|
{
|
//Console.WriteLine("发送吸合信号失败");
|
}
|
}
|
}
|
}
|
}
|
}
|
|
#endregion
|
|
#region 瓶盖机
|
//记录当前瓶盖机是即产即用还是入库模式,后面空托开始卸货时,如果模式有变需要通知设备
|
private static Dictionary<string, string> bottleCapState = new Dictionary<string, string>();
|
|
/// <summary>
|
/// 瓶盖机 3F 00 11(设备1) 22(设备2) 01(1塑料筐、2铁筐) 0d 0a
|
/// </summary>
|
/// <param name="data"></param>
|
/// <param name="plc"></param>
|
internal static void JunZhouAnalysisBottleCap(string data, Settings.deviceInfo plc)
|
{
|
LogHelper.Info($"{plc.deviceName}-{plc.address}-{data}", "瓶盖机");
|
|
/*
|
状态1 满托产生,需要取满送空,从满托产生到满托取走一直维持状态1
|
状态2 送空完成之后为状态2
|
状态3 满托取走,送空之前为状态3,开机默认状态也为状态3
|
*/
|
|
|
|
//信号出错
|
if (data.Substring(0, 1) != "1" || data.Substring(2, 1) != "2")
|
{
|
//判断哪边没有托盘
|
if (ContainerHelper.CheckEmpty(plc.location[0]))
|
{
|
PlcHelper.SendHex(plc.address, "3F00110d0a");
|
}
|
if (ContainerHelper.CheckEmpty(plc.location[1]))
|
{
|
PlcHelper.SendHex(plc.address, "3F00210d0a");
|
}
|
}
|
}
|
|
#endregion
|
|
#region 输送线
|
|
/* 淳安大小版处理:
|
1.入库计算货位获取到空排,需判断另一个 版位所对应的排 是否存在货位,以及无锁定 ----------OVER
|
2.移库工单点击执行中时:需要拿出所有的 起点库位以及终点库位,判断后缀必须一致 ----------OVER
|
3.小板库区库位 需要 在大板的库区库位上加上后缀 -XB ----------OVER
|
4.进行库位锁定解锁回报时,需要去除后缀 -XB ----------OVER
|
5.大板的库区库位需要与富勒WMS同步 ----------OVER
|
*/
|
|
|
|
|
private static string ConveryInfoFullTwo(Settings.deviceInfo plc, string DeviceStartTime, string deviceName)
|
{
|
//2.获取当前产线 设备中间表 对应信息 ChunAnDeviceState
|
//2-1.有数据,判断当前是否为第一次收到下线信号
|
// 第一次:更新 DeviceState = 1,DeviceStartTime = 当前时间
|
// 第N次:判断当前 DeviceState 是否为1,不为1,更新 DeviceState 以及 DeviceStartTime
|
//2-2.无数据,插入 DeviceName ,DeviceState = 1,DeviceStartTime = 当前时间 数据
|
var deviceTableInfo = WCSHelper.GetDaMingShanDeviceState(deviceName);
|
if (deviceTableInfo != null)
|
{
|
if (deviceTableInfo.DeviceState != "1") WCSHelper.UpdateDaMingShanDeviceState(deviceTableInfo, "1", DeviceStartTime);
|
else DeviceStartTime = deviceTableInfo.DeviceTime;
|
}
|
else
|
{
|
WCSHelper.DaMingShangInsertDeviceState(new DaMingShanDeviceState
|
{
|
DeviceName = deviceName,
|
DeviceTime = DeviceStartTime,
|
DeviceState = "1"
|
});
|
}
|
|
return DeviceStartTime;
|
}
|
private static bool ConveryInfoFullThree(Settings.deviceInfo plc, string location, WorkOrder workOrder, string DeviceStartTime, string positionCode, string deviceName, ref string TrayCode, ref string BatchNo, ref string ItemLayer)
|
{
|
bool result = true;
|
var db = new SqlHelper<object>().GetInstance();
|
//3.从 富勒托盘信息中间表 获取 dateTime < DeviceStartTime 的数据 ChunAnTrayInfo
|
// 有两条:进入第 3-1 步
|
// 小于两条:异常-连接 报警器 进行声光报警
|
//3-1.判断托盘信息中 托规、批次号、物料层数 是否有值---------根据 托规 判断当前托盘是否为零头
|
// 有值:判断当前值是否与 工单信息 相同,不同代表 当前产线切换了生产类型或首次下线,需同步更新 工单信息
|
// 无值:判断工单是否存在对应值,不存在 即 异常
|
if (!string.IsNullOrEmpty(DeviceStartTime))
|
{
|
LogHelper.Info($"输送线:{deviceName} 获取托盘数据 位置代码{positionCode}");
|
var trayTableInfo = WCSHelper.GetDaMingShanTrayInfoList(positionCode, deviceName);
|
if (trayTableInfo != null)
|
{
|
trayTableInfo = trayTableInfo.OrderBy(a => Convert.ToDateTime(a.dateTime)).ToList();
|
if (trayTableInfo.Count == 2)
|
{
|
string trayCode = ""; string batchNo = ""; string itemLayer = "";
|
//1-首先判断工单 托规、批次号、物料层数 三个参数是否有值
|
// 有值:判断和当前值是否相同,不同 即 更新 UpdateWorkInfo
|
// 无值:更新工单对应信息
|
trayTableInfo.ForEach(a =>
|
{
|
LogHelper.Info($"托盘号{a.trayCode} 批次号{a.batchNo} 物料层数{a.itemLayer}");
|
trayCode = trayCode + "," + a.trayCode;
|
string TrayRule = "";
|
string UpdateWorkOn = "";//更新工单信息开关 默认为空 1-需要更新 托规、批次号、物料层数 信息
|
|
//成品下线:首托下线 必须 传输全部信息-托规、批次号、物料层数;否则 第一托就无法下线
|
// 之后如果缺少信息,可以从工单获取
|
//工单初始状态:托规、批次号、物料层数 必然有一个值为空;后续会一直有值
|
if (string.IsNullOrEmpty(workOrder.S_BatchNo) || string.IsNullOrEmpty(workOrder.S_ItemLayer))
|
{
|
WCSHelper.UpdateWorkInfo(workOrder, a.batchNo, a.itemLayer);
|
batchNo = a.batchNo; itemLayer = a.itemLayer;
|
}
|
//处理 当前托盘 托规、批次号、物料层数 信息
|
ConveryInfoFullThreeS(plc, location, a, workOrder, DeviceStartTime, ref batchNo, ref itemLayer, ref TrayRule, ref UpdateWorkOn);
|
if (UpdateWorkOn == "1") WCSHelper.UpdateWorkInfo(workOrder, batchNo, itemLayer);
|
|
//零头物料判断
|
//if (TrayRule != a.trayNum)
|
//{
|
// result = false;
|
// LogHelper.Info($"输送线:{plc.deviceName} 下线信号:{location},下线时间:{DeviceStartTime},成品下线-当前物料箱数:{a.itemLayer}与标准托规:{TrayRule}不符,标准托规信息异常!", "输送线");
|
// //正常下线-不是整托下线 连接报警器 报警
|
// //Console.WriteLine($"输送线:{plc.deviceName} 下线信号:{location},下线时间:{DeviceStartTime},成品下线-当前物料箱数:{a.itemLayer}与标准托规:{TrayRule}不符,标准托规信息异常!");
|
//}
|
workOrder.S_WorkNo = a.workNo;
|
});
|
|
var trayAll = WCSHelper.GetDaMingShanTrayInfoAllList(deviceName);
|
if (trayTableInfo.Count != trayAll.Count && trayTableInfo.Count == 1)
|
{
|
result = false;
|
LogHelper.Info($"输送线:{deviceName} 下线信号:{location},下线时间:{DeviceStartTime},第一次下线时间之前只获得{trayTableInfo.Count}条托盘信息,记录托盘信息为{trayAll.Count}条,托盘信息异常!", "输送线");
|
//连接报警器 进行异常报警
|
SendErrorTcpMsg(plc, DeviceStartTime);
|
db.Deleteable<DaMingShanDeviceState>().Where(a => a.DeviceName.Trim() == deviceName).ExecuteCommand();
|
//Console.WriteLine($"输送线:{plc.deviceName} 下线信号:{location},下线时间:{DeviceStartTime},第一次下线时间之前只获得{trayTableInfo.Count}条托盘信息,记录托盘信息为{trayAll.Count}条,托盘信息异常!");
|
}
|
TrayCode = trayCode; BatchNo = batchNo; ItemLayer = itemLayer;
|
}
|
else
|
{
|
result = false;
|
LogHelper.Info($"输送线:{deviceName} 下线信号:{location},下线时间:{DeviceStartTime},第一次下线时间之前只获得{trayTableInfo.Count}条托盘信息,托盘信息异常!", "输送线");
|
//连接报警器 进行异常报警
|
SendErrorTcpMsg(plc, DeviceStartTime);
|
db.Deleteable<DaMingShanDeviceState>().Where(a => a.DeviceName.Trim() == deviceName).ExecuteCommand();
|
//Console.WriteLine($"输送线:{plc.deviceName} 下线信号:{location},下线时间:{DeviceStartTime},第一次下线时间之前只获得{trayTableInfo.Count}条托盘信息,托盘信息异常!");
|
}
|
}
|
else
|
{
|
result = false;
|
LogHelper.Info($"输送线:{deviceName} 下线信号:{location},下线时间:{DeviceStartTime},第一次下线时间之前只获得{trayTableInfo.Count}条托盘信息,托盘信息异常!", "输送线");
|
SendErrorTcpMsg(plc, DeviceStartTime);
|
db.Deleteable<DaMingShanDeviceState>().Where(a => a.DeviceName.Trim() == deviceName).ExecuteCommand();
|
}
|
}
|
else LogHelper.Info($"输送线:{deviceName} 下线信号:{location} ,DeviceStartTime 设备第一次下线时间为空,程序异常!", "输送线");
|
return result;
|
}
|
|
|
|
|
/// <summary>
|
/// 输送线托盘信息异常-向输送线发送异常信号
|
/// 1、下线时间前的托盘数小于2
|
/// 2、托规不等于当前数量
|
/// </summary>
|
/// <param name="plc"></param>
|
public static void SendErrorTcpMsg(Settings.deviceInfo plc, string deviceStartTime)
|
{
|
if ((DateTime.Now - Convert.ToDateTime(deviceStartTime)).TotalSeconds > 60) PlcHelper.SendHex(plc.address, "3F00600d0a");
|
}
|
|
private static void ConveryInfoFullThreeS(Settings.deviceInfo plc, string location, DaMingShanTrayInfo a, WorkOrder workOrder, string DeviceStartTime, ref string BatchNo, ref string ItemLayer, ref string TrayRule, ref string UpdateWorkOn)
|
{
|
//if (string.IsNullOrEmpty(a.trayRule))
|
//{
|
// //传输缺少 标准托规信息,需要从工单获取
|
// if (!string.IsNullOrEmpty(workOrder.S_TrayRules)) TrayRule = workOrder.S_TrayRules;
|
// else LogHelper.Info($"输送线:{plc.deviceName} 下线信号:{location},下线时间:{DeviceStartTime},托盘信息表无标准托规信息且工单:{workOrder.S_WorkNo}也没有标准托规信息,标准托规信息异常!", "输送线");
|
//}
|
//else
|
//{
|
// //中途切换了 生产物料,需要更新 工单信息
|
// if (workOrder.S_TrayRules != a.trayRule)
|
// {
|
// TrayRule = a.trayRule;
|
// UpdateWorkOn = "1";
|
// }
|
// else TrayRule = a.trayRule;
|
//}
|
if (string.IsNullOrEmpty(a.batchNo))
|
{
|
//传输缺少 批次号信息,需要从工单获取
|
if (!string.IsNullOrEmpty(workOrder.S_BatchNo)) BatchNo = workOrder.S_BatchNo;
|
else LogHelper.Info($"输送线:{plc.deviceName} 下线信号:{location},下线时间:{DeviceStartTime},托盘信息表无批次号信息且工单:{workOrder.S_WorkNo}也没有批次号信息,批次号信息异常!", "输送线");
|
}
|
else
|
{
|
//中途切换了 生产物料,需要更新 工单信息
|
if (workOrder.S_BatchNo != a.batchNo)
|
{
|
BatchNo = a.batchNo;
|
UpdateWorkOn = "1";
|
}
|
else BatchNo = a.batchNo;
|
}
|
if (string.IsNullOrEmpty(a.itemLayer))
|
{
|
//传输缺少 批次号信息,需要从工单获取
|
if (!string.IsNullOrEmpty(workOrder.S_ItemLayer)) ItemLayer = workOrder.S_ItemLayer;
|
else LogHelper.Info($"输送线:{plc.deviceName} 下线信号:{location},下线时间:{DeviceStartTime},托盘信息表无物料层数信息且工单:{workOrder.S_WorkNo}也没有物料层数信息,物料层数信息异常!", "输送线");
|
}
|
else
|
{
|
//中途切换了 生产物料,需要更新 工单信息
|
if (workOrder.S_ItemLayer != a.itemLayer)
|
{
|
ItemLayer = a.itemLayer;
|
UpdateWorkOn = "1";
|
}
|
else ItemLayer = a.itemLayer;
|
}
|
}
|
#endregion
|
|
#region 其他设备
|
private static void AnalysisDevice()
|
{
|
|
}
|
|
|
#endregion
|
|
}
|
|
}
|