using CentralControl.BaseData; using CommonFunc; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace CentralControl.App_Code { public class LogicLocatorSite { Thread UpMaterialThread; PlcHelper plcHelper; public LogicLocatorSite(PlcHelper plc) { plcHelper = plc; } public LogicLocatorSite() { plcHelper = new PlcHelper(); plcHelper.Connection("127.0.0.1"); } /// /// 启动上件扫描监听 /// public void StartLocatorMaterilMonitor(string lineNo) { //便利所有非上下件区域的节点, foreach (NodeSetting node in StaticData.NodeSettingList) { //剔除上件节点和下件节点,,,,以后可以考虑整合到一起 if (node.NodeType != 1 && node.NodeType != 2) { StaticData.CarLockObjDic.Add(node.NodeNo, new object()); ////创建监控节点线程 Thread nodesThread = new Thread(new ParameterizedThreadStart(MonitorNodeToCar)); nodesThread.IsBackground = true; nodesThread.Start(node); } } } #region 监控除了上件区与下件区的所有点位,如果有小车到位了 ,就处理 /// /// 检查所有到达交互点的 /// private void MonitorNodeToCar(object node) { Logger logger = new Logger(); NodeSetting nodesetting = node as NodeSetting; while (true) { try { lock (StaticData.CarLockObjDic[nodesetting.NodeNo]) { //点位绑定的小车状态plc object carstate = plcHelper.Read(nodesetting.PlcSetting1); //读取小车号 object carno = plcHelper.Read(nodesetting.PlcSetting5); //小车处理状态 object carrun = plcHelper.Read(nodesetting.PlcSetting2); ///上位机写入岔道信息 object wcsstate = plcHelper.Read(nodesetting.PlcSetting3); ///回写plc状态处理完成,plc会清理数据 object wcsend = plcHelper.Read(nodesetting.PlcSetting4); // CanChangeLine //获取小车队列中,根据小车的编号获取小车数据 if (Convert.ToInt32(carno) > 0 && Convert.ToInt32(wcsend) == 0 && Convert.ToInt32(wcsstate) == 0 && Convert.ToInt32(carstate) == 1) { CarRealInfo car = StaticData.CarRealList.Where(t => t.CarNo == carno.ToString()).FirstOrDefault(); if (car != null) { logger.Log("[" + car.CarNo + "]小车到位了 [" + nodesetting.NodeNo + "]"); //修改小车当前节点信息 car.CurrNodeSetting = nodesetting; car.CurrNodeId = nodesetting.Id; //判断小车是否修改库位节点信息,如果 IsStaticNumber>0,说明有区域统计,就更新, 否则不用更新 if (nodesetting.IsStaticNumber > 0) { //修改小车当前节点信息 car.LocatorNodeSetting = nodesetting; car.LocatorNodeId = nodesetting.Id; } car.OptDt = DateTime.Now; NodePrecuss nodeprocess = getNodeDistributionByCarNode(car, nodesetting); if (nodeprocess != null) { car.IsOver = 1; //判断库区点位是否修改 DBService.ModifyRealCarinfoRecord(car); //修改小车离开状态 // DBService.UpdateCarOverState(car.Id, 1); //调用公共分流方法 //根据返回的流向值传给plc plcHelper.Write(nodesetting.PlcSetting3, nodeprocess.NodeValue); //通知plc ,记录成功, 回写plc状态处理完成,plc会清理数据 plcHelper.Write(nodesetting.PlcSetting4, 1); } } } else if (Convert.ToInt32(carno) == 0 && Convert.ToInt32(carstate) == 0 && Convert.ToInt32(carrun) == 1) { logger.Log("小车离开了 [" + nodesetting.NodeNo + "]"); ///回写plc状态,,plc会清理数据 plcHelper.Write(nodesetting.PlcSetting3, 0); ///回写plc状态处理完成,plc会清理数据 plcHelper.Write(nodesetting.PlcSetting4, 0); } } Thread.Sleep(500); } catch (Exception ex) { logger.Log("交互点位监控异常:[" + (nodesetting == null ? node.ToString() : nodesetting.NodeNo) + "]" + ex.Message); } } } #endregion #region 节点分流逻辑 /// /// 根据小车信息和当前节点信息 ,获取节点前置后续关系节点,不同节点类别决定去向 /// /// /// /// /// public NodePrecuss getNodeDistributionByCarNode(CarRealInfo car, NodeSetting currnode) { NodePrecuss ret = new NodePrecuss(); switch (currnode.NodeType) { case 1://入库点位逻辑 ret = getInputLocatorLogic(car, currnode); break; case 2://出库点位逻辑 ret = getOutLocatorPointLogic(car, currnode); break; case 3: // 满车存储前变线节点逻辑 ret = getEndOutLocatorLogic(car, currnode); break; case 4: break; case 5: break; default: break; } return ret; } /// /// 入库点位逻辑 /// /// /// /// public NodePrecuss getInputLocatorLogic(CarRealInfo car, NodeSetting node) { Logger logger = new Logger(); NodePrecuss nodedis = new NodePrecuss(); List listnodeprocess = StaticData.NodeRelation.Where(t => t.PreNodeId == node.Id).ToList(); lock (StaticData.OffLineLockObjDic[node.LineCatchArea.LineNo]) { if (car.LocatorNodeSetting.LineAreaId == node.LineAreaId) { //向库内移动 nodedis = listnodeprocess.Where(t => t.NodeValue == 2).FirstOrDefault(); } else { //继续前进移动 nodedis = listnodeprocess.Where(t => t.NodeValue == 2).FirstOrDefault(); } } return nodedis; } /// /// 出库点位逻辑 /// /// private NodePrecuss getOutLocatorPointLogic(CarRealInfo car, NodeSetting node) { Logger logger = new Logger(); NodePrecuss nodedis = new NodePrecuss(); List listnodeprocess = StaticData.NodeRelation.Where(t => t.PreNodeId == node.Id).ToList(); lock (StaticData.OffLineLockObjDic[node.LineCatchArea.LineNo]) { //查询是否有被设置为当前库区出库的小车 var prooutcar = StaticData.CarRealList.Where(t => t.IsProOutLocator == 1 && t.IsOutLocator != 1 && car.CurrNodeSetting.LineAreaId == node.LineAreaId).OrderBy(t => t.OptDt).ToList(); if (prooutcar.Count > 0) { //库内放行 nodedis = listnodeprocess.Where(t => t.NodeValue == 1).FirstOrDefault(); car.IsProOutLocator = 0; } } return nodedis; } /// /// 出库结束点位逻辑 /// /// /// /// public NodePrecuss getEndOutLocatorLogic(CarRealInfo car, NodeSetting node) { Logger logger = new Logger(); NodePrecuss nodedis = new NodePrecuss(); List listnodeprocess = StaticData.NodeRelation.Where(t => t.PreNodeId == node.Id).ToList(); lock (StaticData.OffLineLockObjDic[node.LineCatchArea.LineNo]) { //小车已经过了出库终点点位 nodedis = listnodeprocess.Where(t => t.NodeValue == 1).FirstOrDefault(); car.IsOutLocator = 1; } return nodedis; } #endregion } }