using HH.WCS.ZhongCeJinTan.device; using HH.WCS.ZhongCeJinTan.dispatch; using HH.WCS.ZhongCeJinTan.util; using HH.WCS.ZhongCeJinTan.wms; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using SqlSugar; using System.Security.Policy; using Newtonsoft.Json; using static HH.WCS.ZhongCeJinTan.api.ApiModel; using System.Reflection; using static HH.WCS.ZhongCeJinTan.process.TaskProcess; using static HH.WCS.ZhongCeJinTan.wms.WcsModel; using HH.WCS.Mobox3.ZhongCeJinTan.dispatch; using static HH.WCS.ZhongCeJinTan.util.Settings; namespace HH.WCS.ZhongCeJinTan.process { /// /// 设备信号处理 /// internal class DeviceProcess { private static Dictionary times = new Dictionary(); private static Dictionary LineState = new Dictionary(); public class statemodel { public int 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); var plc = Settings.deviceInfos.Where(a => a.address == ip && a.enable == 1).FirstOrDefault(); if (plc != null) { if (plc.enable == 1) { if (plc.deviceType == 1) { AnalysisDoor(data, plc); } } } else { Console.WriteLine($"TCP信号处理:未查询到IP为{ip}的数据,请检查deviceInfo配置中心是否存在该IP的数据!"); } } } private static Dictionary doorRecord = new Dictionary(); /// /// 交管请求 /// /// /// /// internal static bool Traffic(string zone, int occupy,bool flag) { var plc = Settings.deviceInfos.Where(a => a.location[0].Contains(zone)).FirstOrDefault(); if (plc != null) { LogHelper.Info($"安全门对接:门:{zone}", "自动门"); if (flag) { if (occupy == 1) { //开门请求 3F 00 11 20 0d 0a var req = $"3f 00 11 0d 0a"; PlcHelper.SendHex(plc.address, req); var msg = $"安全门开门请求,门号:{zone},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}", "自动门"); return true; } } } if (occupy == 4) { //关门信号 3F 00 10 20 0d 0a var req = $"3f 00 10 0d 0a"; PlcHelper.SendHex(plc.address, req); var msg = $"安全门关门请求,门号:{zone},ip={plc.address}, data={req}"; LogHelper.Info(msg, "自动门"); return true; } } else { if (occupy == 1) { if (doorStatus[zone].info == "1") { LogHelper.Info($"安全门已经打开:门:{zone}", "自动门"); return true; } else { LogHelper.Info($"安全门已经关闭:门:{zone}", "自动门"); return false; } } if (occupy == 4) { return true; } } } return false; } private static Dictionary doorStatus = new Dictionary(); /// /// 自动门 /// /// /// internal static void AnalysisDoor(string data, Settings.deviceInfo plc) { LogHelper.Info($"自动门状态:{data},地址为:{plc.address}", "自动门"); var state = data.Substring(1, 1); LogHelper.Info($"门{plc.location[0]}的状态{state}", "自动门"); if (doorStatus.Keys.Contains(plc.location[0])) { doorStatus[plc.location[0]].info = state; doorStatus[plc.location[0]].modify = DateTime.Now; } else { doorStatus.Add(plc.location[0] , new signalInfo { info = state, modify = DateTime.Now }); } } internal static void QuLiao(WMSTask mst,string fkNo, int state) { try { var newDb = new SqlHelper().GetInstance(); LogHelper.Info($"安全交互开始 任务号={mst.S_CODE}", "安全交互"); var safety = Settings.safetyLocations.Where(a => a.Area.Contains(mst.S_START_AREA)).FirstOrDefault(); LogHelper.Info($"安全交互开始 任务号={mst.S_CODE},交互配置信息" + JsonConvert.SerializeObject(safety), "安全交互"); if (state == 1101) { //1101取货申请进入 if (safety != null) { //1为接驳位交互 if (safety.type == 1) { var wcsTask1 = TaskHelper.GetTaskByWorkNo(mst.S_OP_CODE, "wcs"); if (wcsTask1 != null) { if (wcsTask1.S_B_STATE != "完成") { return; } } else { return; } LogHelper.Info($"接驳位安全交互开始 任务号={mst.S_CODE},取货库区接驳位交互" , "安全交互"); //先给立库发送卸货通知 WcsTask.WcsCallback(mst, state, fkNo); //查找立库通知确认表 var flag = newDb.Queryable().Where(a => a.requestPk.Contains(mst.S_CODE) && a.trkType=="1").First(); if (flag != null) { if (flag.isAllow == "1") { //立库通知成功修改参数 LogHelper.Info($"立库通知确认,取货交管成功,修改参数", "安全交互"); NDCApi.ChangeOrderParam(mst.S_CODE, 6, "1"); } else { LogHelper.Info($"立库通知确认,任务号={mst.S_CODE},取货交管不允许,不修改参数", "安全交互"); } } else { LogHelper.Info($"立库通知确认,任务号={mst.S_CODE},取货交管失败,未查到立库通知确认记录", "安全交互"); } }//2为胎面交互 else if (safety.type == 2) { var safetyLoc = Settings.TmDeviceInfos.Where(a => a.locCode.Contains(mst.S_START_LOC) && a.deviceType == 1).FirstOrDefault(); if (safetyLoc != null) { LogHelper.Info($"胎面安全交互取货开始,任务号={mst.S_CODE},地址{safetyLoc.writeSafetyAddr}写入1,地址{safetyLoc.writeSafetyAddr1}写入1", "胎面交互"); if (ModbusHelper.WriteSingleRegister(safetyLoc.writeSafetyAddr, 1)&& ModbusHelper.WriteSingleRegister(safetyLoc.writeSafetyAddr1, 1)) { LogHelper.Info($"胎面安全交互取货判断信号,任务号={mst.S_CODE},读取地址{safetyLoc.readSafetyAddr},地址{safetyLoc.readSafetyAddr1}", "胎面交互"); var res = ModbusHelper.ReadHoldingRegisters(safetyLoc.readSafetyAddr, 1); var res1 = ModbusHelper.ReadHoldingRegisters(safetyLoc.readSafetyAddr1, 1); LogHelper.Info($"任务号={mst.S_CODE},取货读取地址{safetyLoc.readSafetyAddr},值{res[0]},地址{safetyLoc.readSafetyAddr1},值{res1[0]}", "胎面交互"); if (res[0] == 1 && res1[0] == 1) { LogHelper.Info($"任务号={mst.S_CODE},取货交管成功,修改参数", "胎面交互"); NDCApi.ChangeOrderParam(mst.S_CODE, 6, "1"); } else { LogHelper.Info($"任务号={mst.S_CODE},取货交管失败,不修改参数", "胎面交互"); } } } else { LogHelper.Info($"胎面安全交互取货,任务号={mst.S_CODE},没找到终点{mst.S_START_LOC}配置", "胎面交互"); } } } }else { if (safety.type == 1) { LogHelper.Info($"接驳位安全交互开始 任务号={mst.S_CODE},交互类型为1,取货完成", "安全交互"); //取货完成通知立库 WcsTask.WcsCallback(mst, state, fkNo); } //1102取货完成 if (safety.type == 2) { var safetyLoc = Settings.TmDeviceInfos.Where(a => a.locCode.Contains(mst.S_START_LOC) && a.deviceType == 1).FirstOrDefault(); if (safetyLoc != null) { LogHelper.Info($"胎面安全交互取货完成,任务号={mst.S_CODE},地址{safetyLoc.endAddr}写入1", "胎面交互"); ModbusHelper.WriteSingleRegister(safetyLoc.endAddr, 1); } } } } catch (Exception ex) { LogHelper.Info($"取料异常{ex.Message}", "安全交互"); } } internal static void XieLiao(WMSTask mst,string fkNo,int state) { try { var newDb = new SqlHelper().GetInstance(); LogHelper.Info($"安全交互开始 任务号={mst.S_CODE}", "安全交互"); var safety = Settings.safetyLocations.Where(a => a.Area.Contains(mst.S_END_AREA)).FirstOrDefault(); if (state==1103) { //1103卸货申请进入 if (safety != null) { //1为接驳位交互 if (safety.type == 1) { LogHelper.Info($"接驳位安全交互开始 任务号={mst.S_CODE},交互类型为1,卸货库区接驳位交互", "安全交互"); //先给立库发送卸货通知 WcsTask.WcsCallback(mst, state, fkNo); //查找立库通知确认表 var flag = newDb.Queryable().Where(a => a.requestPk.Contains(mst.S_CODE) && a.trkType == "2").First(); if (flag != null) { if (flag.isAllow == "1") { //立库通知成功修改参数 LogHelper.Info($"立库通知确认,任务号={mst.S_CODE},卸货交管成功,修改参数", "安全交互"); NDCApi.ChangeOrderParam(mst.S_CODE, 6, "1"); } else { LogHelper.Info($"立库通知确认,任务号={mst.S_CODE},卸货交管不允许,不修改参数", "安全交互"); } } else { LogHelper.Info($"立库通知确认,任务号={mst.S_CODE},卸货交管失败,未查到立库通知确认记录", "安全交互"); } }//2为胎面交互 else if (safety.type == 2) { var safetyLoc = Settings.TmDeviceInfos.Where(a => a.locCode.Contains(mst.S_END_LOC) && a.deviceType == 2).FirstOrDefault(); if (safetyLoc != null) { LogHelper.Info($"胎面安全交互卸货开始,任务号={mst.S_CODE},地址{safetyLoc.writeSafetyAddr}写入1,地址{safetyLoc.writeSafetyAddr1}写入1", "胎面交互"); if (ModbusHelper.WriteSingleRegister(safetyLoc.writeSafetyAddr, 1) && ModbusHelper.WriteSingleRegister(safetyLoc.writeSafetyAddr1, 1)) { var res = ModbusHelper.ReadHoldingRegisters(safetyLoc.readSafetyAddr, 1); var res1 = ModbusHelper.ReadHoldingRegisters(safetyLoc.readSafetyAddr1, 1); LogHelper.Info($"任务号={mst.S_CODE},卸货读取地址{safetyLoc.readSafetyAddr},值{res[0]},地址{safetyLoc.readSafetyAddr1},值{res1[0]}", "胎面交互"); if (res[0] == 1 && res1[0] == 1) { LogHelper.Info($"任务号={mst.S_CODE},卸货交管成功,修改参数", "胎面交互"); NDCApi.ChangeOrderParam(mst.S_CODE, 6, "1"); } else { LogHelper.Info($"任务号={mst.S_CODE},卸货交管失败,不修改参数", "胎面交互"); } } } else { LogHelper.Info($"胎面安全交互卸货,任务号={mst.S_CODE},没找到终点{mst.S_END_LOC}配置", "胎面交互"); } } } } else { if (safety.type == 1) { LogHelper.Info($"接驳位安全交互开始 任务号={mst.S_CODE},交互类型为1,卸货完成", "安全交互"); //卸货完成通知立库 WcsTask.WcsCallback(mst, state, fkNo); } //1104卸货完成 if (safety.type == 2) { var safetyLoc = Settings.TmDeviceInfos.Where(a => a.locCode.Contains(mst.S_END_LOC) && a.deviceType == 2).FirstOrDefault(); if (safetyLoc != null) { LogHelper.Info($"胎面安全交互卸货完成,任务号={mst.S_CODE},地址{safetyLoc.endAddr}写入1", "胎面交互"); ModbusHelper.WriteSingleRegister(safetyLoc.endAddr, 1); } } } } catch (Exception ex) { LogHelper.Info($"卸料异常{ex.Message}", "安全交互"); } } internal static void Door(WMSTask mst, string fkNo, int state) { try { var newDb = new SqlHelper().GetInstance(); LogHelper.Info($"安全交互开始 任务号={mst.S_CODE}", "门交互"); var safety = new safetyLocation(); if (mst.S_TYPE.Contains("出库")) { safety= Settings.safetyLocations.Where(a => a.Area.Contains(mst.S_START_AREA)).FirstOrDefault(); } if (mst.S_TYPE.Contains("入库")) { safety = Settings.safetyLocations.Where(a => a.Area.Contains(mst.S_END_AREA)).FirstOrDefault(); } LogHelper.Info($"安全交互开始 任务号={mst.S_CODE},交互配置信息" + JsonConvert.SerializeObject(safety), "门交互"); //1023开门 1025关门 if (safety != null) { //门交互 if (safety.type == 3) { LogHelper.Info($"门安全交互开始 任务号={mst.S_CODE},交互类型为3,开关门请求信号{state}", "门交互"); if (state != 1023 && state != 1025) { LogHelper.Info($"门安全交互失败 任务号={mst.S_CODE},交互类型为3,开关门请求信号{state}", "门交互"); return; } //先给立库发送开门通知 WcsTask.WcsCallback1(mst, state, fkNo); //查找立库通知确认表 WcsInform flag = null; if (state == 1023) { flag = newDb.Queryable().Where(a => a.requestPk.Contains(mst.S_CODE) && a.trkType == "3").First(); } else { flag = newDb.Queryable().Where(a => a.requestPk.Contains(mst.S_CODE) && a.trkType == "4").First(); } if (flag != null) { if (flag.isAllow == "allow") { //立库通知成功修改参数 LogHelper.Info($"立库通知确认,任务号={mst.S_CODE},开关门交管成功,修改参数", "门交互"); NDCApi.ChangeOrderParam(mst.S_CODE, 6, "1"); } } else { LogHelper.Info($"立库通知确认,任务号={mst.S_CODE},开关门交管失败,未查到立库通知确认记录", "门交互"); } } } } catch (Exception ex) { LogHelper.Info($"门交互异常{ex.Message}", "门交互"); } } } }