You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

265 lines
9.9 KiB
C#

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");
}
/// <summary>
/// 启动上件扫描监听
/// </summary>
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 监控除了上件区与下件区的所有点位,如果有小车到位了 ,就处理
/// <summary>
/// 检查所有到达交互点的
/// </summary>
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 节点分流逻辑
/// <summary>
/// 根据小车信息和当前节点信息 ,获取节点前置后续关系节点,不同节点类别决定去向
/// </summary>
/// <param name="car"></param>
/// <param name="currnode"></param>
/// <param name="procuss"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 入库点位逻辑
/// </summary>
/// <param name="car"></param>
/// <param name="node"></param>
/// <returns></returns>
public NodePrecuss getInputLocatorLogic(CarRealInfo car, NodeSetting node)
{
Logger logger = new Logger();
NodePrecuss nodedis = new NodePrecuss();
List<NodePrecuss> 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;
}
/// <summary>
/// 出库点位逻辑
/// </summary>
/// <returns></returns>
private NodePrecuss getOutLocatorPointLogic(CarRealInfo car, NodeSetting node)
{
Logger logger = new Logger();
NodePrecuss nodedis = new NodePrecuss();
List<NodePrecuss> 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;
}
/// <summary>
/// 出库结束点位逻辑
/// </summary>
/// <param name="car"></param>
/// <param name="node"></param>
/// <returns></returns>
public NodePrecuss getEndOutLocatorLogic(CarRealInfo car, NodeSetting node)
{
Logger logger = new Logger();
NodePrecuss nodedis = new NodePrecuss();
List<NodePrecuss> 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
}
}