using Admin.Core.Common; using Admin.Core.IService; using Admin.Core.Model; using Admin.Core.Service; using Aucma.Core.HwPLc; using Aucma.Core.Scanner; using log4net; using Microsoft.Extensions.DependencyInjection; using NetTaste; using Org.BouncyCastle.Asn1.Tsp; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel; namespace Aucma.Core.Palletiz.Business { /// ///分垛入库业务处理 /// public class InstoreBusiness { #region 单例实现 private static readonly InstoreBusiness lazy = new InstoreBusiness(); public static InstoreBusiness Instance { get { return lazy; } } #endregion #region 变量定义 public readonly List allScanners = Appsettings.app("ScannerServer").ToList(); public readonly string storeCodeA = Appsettings.app("StoreInfo", "PalletizStoreCodeA");//分垛库A public readonly string storeCodeB = Appsettings.app("StoreInfo", "PalletizStoreCodeB");//分垛库B #endregion #region 接口引用 private static readonly log4net.ILog logHelper = LogManager.GetLogger(typeof(InstoreBusiness)); private readonly IBaseSpaceInfoServices? _baseSpaceInfoServices = App.ServiceProvider.GetService(); private readonly ICodeBindingRecordServices? _codeBindingServices = App.ServiceProvider.GetService(); private readonly IRecordInStoreServices? _recordInstoreServices = App.ServiceProvider.GetService(); #endregion public void test() { // B240101 8302501416 0001 SN:16160030000000910999 Task.Run(async () => { Thread.Sleep(3000); await InStore("16160030000000910999", "192.168.1.19"); }); } #region 扫码入库处理 /// /// /// /// 成品码 /// 扫码器ip /// public async Task InStore(string SNCode,string scannerIp) { try { // 刷新页面 List allScanners = Appsettings.app("ScannerServer").ToList(); ScannerModel model = allScanners.FirstOrDefault(x => x.Ip == scannerIp); // plc下发结果 bool plcResult = false; // 下发plc的货道号 List spaceNumList = new List(); // 入库记录 RecordInStore recordInstore = new RecordInStore(); //1.根据成品码找货道 List spaceList = getSpaceBySNCode(SNCode,recordInstore); // 根据货道信息判断下发plc信号 if (spaceList == null || spaceList.Count==0) { logHelper.Error("未找到匹配货道,请手动入库!"); // 刷新页面提示信息 return; } // 过滤货道,找到最终需要下发的货道 BaseSpaceInfo finalSpace = FilterSpace(spaceList); // 大产品占两道 if (finalSpace.IsTwoSpace == 1) { spaceNumList.Add(int.Parse(finalSpace.SpaceCode.Substring(5, 3))); spaceNumList.Add(int.Parse(getOtherSpace(finalSpace, spaceList).SpaceCode.Substring(5, 3))); plcResult = sendAndAnswerPlc(scannerIp, spaceList[0].RotationRange, spaceNumList); recordInstore.SpaceCode = finalSpace.SpaceCode; recordInstore.StoreCode = finalSpace.StoreCode; // 更新货道信息,大产品last存objId大的,如货道7,8存8 BaseSpaceInfo otherSpace = getOtherSpace(finalSpace, spaceList); if (otherSpace != null) { updateSapceList(otherSpace.ObjId,spaceList); } } else { // last不等于自己,可以先入自己,否则入另一条货道 if (isOddNumber(finalSpace)) { spaceNumList.Add(int.Parse(finalSpace.SpaceCode.Substring(5, 3))); spaceNumList.Add(0); plcResult = sendAndAnswerPlc(scannerIp, finalSpace.RotationRange, spaceNumList); updateSapceList(finalSpace.ObjId, spaceList); } else { spaceNumList.Add(0); spaceNumList.Add(int.Parse(finalSpace.SpaceCode.Substring(5, 3))); plcResult = sendAndAnswerPlc(scannerIp, finalSpace.RotationRange, spaceNumList); updateSapceList(finalSpace.ObjId, spaceList); } } if (plcResult==true) { // 更新入库记录,刷新界面 #region 添加入库记录 recordInstore.SpaceCode = finalSpace.SpaceCode; recordInstore.StoreCode = finalSpace.StoreCode; recordInstore.InStoreAmount = 1; recordInstore.InStoreTime = DateTime.Now; recordInstore.CreatedTime = DateTime.Now; recordInstore.UpdateTime = DateTime.Now; _ = _recordInstoreServices.AddAsync(recordInstore).Result; #endregion } else { // 界面提示手动入库 } } catch (Exception ex) { logHelper.Error(ex.Message.ToString()); return; } } /// /// 根据成品码找货道 /// /// /// private List getSpaceBySNCode(string SNCode, RecordInStore recordInstore) { try { CodeBindingRecord bindingRecord = _codeBindingServices.Query(c => c.ProductCode.Equals(SNCode)).FirstOrDefault(); if (bindingRecord == null) return null; recordInstore.BarCodeCode = bindingRecord.BoxCode; recordInstore.MaterialCode = bindingRecord.BoxCode; recordInstore.MaterialType = bindingRecord.BoxCode.Substring(7, 10); recordInstore.MaterialName = bindingRecord.BoxName; return _baseSpaceInfoServices.Query(s => s.MaterialType.Equals(bindingRecord.BoxCode.Substring(7, 10)) && (s.StoreCode.Equals(storeCodeA) || s.StoreCode.Equals(storeCodeB)) ).OrderBy(x=>x.ObjId).ToList(); } catch (Exception ex) { logHelper.Error(ex.Message.ToString()); return null; } } private BaseSpaceInfo FilterSpace(List spaceInfos) { if (spaceInfos.Count == 1 || string.IsNullOrEmpty(spaceInfos[0].LastSpace)) { return spaceInfos[0]; } List spaceList = spaceInfos.Where(s=>s.ObjId> int.Parse(spaceInfos[0].LastSpace)).ToList(); if(spaceList==null|| spaceList.Count == 0) { return spaceInfos[0]; } else { return spaceList[0]; } } /// /// 大产品占据两条货道,根据一条货道找到另一条货道 /// /// private BaseSpaceInfo getOtherSpace(BaseSpaceInfo spaceInfo,List spaceList) { try { // 找到当前货道匹配的另一条货道 int num = int.Parse(spaceInfo.SpaceCode.Substring(5, 3)); string otherSpaceCode = string.Empty; if (num % 2 == 0) // 偶数,如7,8,当前8找7 { otherSpaceCode = spaceInfo.SpaceCode.Substring(0, 5) + (num - 1).ToString("D3"); } else { otherSpaceCode = spaceInfo.SpaceCode.Substring(0, 5) + (num + 1).ToString("D3"); } spaceList = spaceList.Where(s => s.SpaceCode.Equals(otherSpaceCode)).ToList(); if (spaceList.Count > 0) { return spaceList[0]; } else { return null; } } catch (Exception ex) { logHelper.Error(ex.Message.ToString()); return null; } } /// /// 判断货道编号是否为奇数 /// /// /// private bool isOddNumber(BaseSpaceInfo space) { int num = int.Parse(space.SpaceCode.Substring(5, 3)); if(num % 2 == 0) { return false; } else { return true; } } /// /// 将该物料的所有货道列表的last修改为上次入库货道objId /// /// /// /// private bool updateSapceList(int objId,List spaceList) { foreach(BaseSpaceInfo space in spaceList) { space.LastSpace = objId.ToString(); } return _baseSpaceInfoServices.UpdateAsync(spaceList).Result; } #endregion #region plc信号下发 /// /// 下发plc入库信号 /// /// 扫码器ip /// 转向角度 /// 货道号int集合 /// private bool sendAndAnswerPlc(string scannerIp,int range,List spaceNum) { bool result = false; try { PlcModel obj = getPlcByScanner(scannerIp); if (obj != null) { if (sendPlc(obj, range, spaceNum)) { result = waitAnswerPlc(obj); } } else { logHelper.Error("plc未连接"); return false; } return result; } catch (Exception ex) { logHelper.Error(ex.Message.ToString()); return result; } } /// /// 下发plc信号 /// /// /// /// /// private bool sendPlc(PlcModel obj, int range, List spaceNum) { try { bool result = false; DateTime targetTime = DateTime.Now.AddSeconds(8); while (true) { if (DateTime.Now > targetTime) // plc超最大时限无反馈 { logHelper.Error("等待plc放行反馈信号超时"); return false; } // 应答字允许下发 if (obj.plc.ReadInt32("D102") == 1) { //旋转角度 obj.plc.WriteInt32("D110", range); //货道号 obj.plc.WriteInt32("D112", spaceNum[0]); obj.plc.WriteInt32("D114", spaceNum[1]); result = true; break; } Thread.Sleep(500); } return result; } catch (Exception ex) { logHelper.Error(ex.Message); return false; } } /// /// 等待plc信号反馈 /// /// /// private bool waitAnswerPlc(PlcModel obj) { try { bool result = false; DateTime targetTime = DateTime.Now.AddSeconds(8); while (true) { if (DateTime.Now > targetTime) // plc超最大时限无反馈 { logHelper.Error("等待plc放行反馈信号超时"); return false; } // 应答字允许下发 if (obj.plc.ReadInt32("D102") == 2) { result = true; break; } Thread.Sleep(500); } return result; } catch (Exception ex) { logHelper.Error(ex.Message.ToString()); return false; } } /// /// 根据扫码器ip确定是属于哪个plc /// /// /// private PlcModel getPlcByScanner(string scannerIp) { PlcModel obj = null; ScannerModel model = allScanners.FirstOrDefault(x => x.Ip == scannerIp); if (model.Id < 3) { obj = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("A库Plc")); } else { obj = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("B库Plc")); } return obj; } #endregion } }