using HH.WCS.QingXigongchang.device;
|
using HH.WCS.QingXigongchang.dispatch;
|
using HH.WCS.QingXigongchang.util;
|
using HH.WCS.QingXigongchang.wms;
|
using Newtonsoft.Json;
|
using SqlSugar;
|
using System;
|
using System.Collections.Generic;
|
using System.Data;
|
using System.Linq;
|
using System.Threading;
|
using static HH.WCS.QingXigongchang.util.Settings;
|
|
namespace HH.WCS.QingXigongchang.process
|
{
|
public class devINFOS : deviceInfo
|
{
|
public string Infos { get; set; }
|
}
|
/// <summary>
|
/// 设备信号处理
|
/// </summary>
|
internal class DeviceProcess
|
{
|
public static Dictionary<string, dynamic> Deviceooo = new Dictionary<string, dynamic>();
|
public static Dictionary<string, signalInfo> doorStatus = new Dictionary<string, signalInfo>();
|
static object _lock = new object();
|
static bool First = true;
|
internal static void Analysis(string data, string ip)
|
{
|
if (data.Length >= 6)
|
{
|
//去掉消息头3F 00
|
data = data.Substring(4);
|
var plc = Settings.GetDeviceInfoList().Where(a => a.address == ip).FirstOrDefault();
|
if (plc == null)
|
{
|
LogHelper.Warn($"IP:{ip}的plc客户端 不存在配置中。", "机");
|
return;
|
}
|
else if (plc != null && plc.enable != 1)
|
{
|
LogHelper.Warn($"{plc.deviceName}-{plc.address}-{plc.deviceType}-data:{data}- 机器未启用。 ", "机");
|
return;
|
}
|
if (Deviceooo.ContainsKey(ip))
|
{
|
Deviceooo[ip] = new
|
{
|
产线号 = plc.deviceName,
|
富勒产线号 = plc.FuLeLineNo,
|
设备号 = plc.deviceNo,
|
设备类型 = plc.deviceType,
|
货位 = plc.location,
|
任务权重 = plc.taskPri,
|
信号 = data,
|
接收时间 = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
|
};
|
}
|
else Deviceooo.Add(ip, new
|
{
|
产线号 = plc.deviceName,
|
富勒产线号 = plc.FuLeLineNo,
|
设备号 = plc.deviceNo,
|
设备类型 = plc.deviceType,
|
货位 = plc.location,
|
任务权重 = plc.taskPri,
|
信号 = data,
|
接收时间 = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
|
});
|
Console.WriteLine($"接受到设备数据:{plc.deviceName}-{plc.address}-{plc.deviceType}-data:{data}。 ");
|
LogHelper.Info($"{plc.deviceName}-{plc.address}-{plc.deviceType}-data:{data}。 ");
|
if (plc != null)
|
{
|
if (plc.enable == 1)
|
{
|
// 门
|
if (plc.deviceType == 1)
|
{
|
if (!First)
|
{
|
AnalysisDoor(data, plc);
|
}
|
else
|
{
|
lock (_lock)
|
{
|
AnalysisDoor(data, plc);
|
First = false;
|
}
|
}
|
}
|
//瓶盖
|
else if (plc.deviceType <= 3)
|
{
|
AnalysisBottleCap(data, plc);
|
}
|
//翻斗机 - 瓶坯
|
else if (plc.deviceType == 5)
|
{
|
AnalysisBottleCapTipper(data, plc);
|
}
|
//翻斗机 - 瓶盖 4 水盖。6 无菌
|
else if (plc.deviceType <= 6)
|
{
|
// 瓶盖翻斗机.
|
AnalysisBottleCapTipper10(data, plc);
|
}
|
//翻斗机 - 10 水线翻斗机
|
else if (plc.deviceType == 10)
|
{
|
AnalysisBottleCapTipper10(data, plc);
|
}
|
// 瓶坯
|
else if (plc.deviceType == 8)
|
{
|
AnalysisBottlePEM(data, plc);
|
}
|
// 505水线
|
else if (plc.deviceType == 9)
|
{
|
Analysis505(data, plc);
|
}
|
///水线
|
//else if (plc.deviceType == 10)
|
//{
|
// //AnalysisBottleCapTipper10(data, plc);
|
//}
|
// 电梯,提升机。吊机。 管他啥,从一楼搬二楼。
|
else if (plc.deviceType == 11)
|
{
|
Analysis11(data, plc);
|
}
|
else if (plc.deviceType == 13)
|
{
|
Analysis13(data, plc);
|
}
|
}
|
}
|
else
|
{
|
Console.WriteLine($"TCP信号处理:未查询到IP为{ip}的数据,请检查deviceInfo配置中心是否存在该IP的数据!");
|
}
|
}
|
|
}
|
|
private static void Analysis13(string data, deviceInfo plc)
|
{
|
//用于 出库时 是否可以直达 提升机。 00 后面还需增加退料工单处理。
|
|
//一个提升机 兼顾多个产线的原物料纸箱。 所以需要批量YWLWorkOrder 比如一个提升机需要 提供3线和4线2个成品的纸箱。
|
var ooo = LocationHelper.GetList<YWLWorkOrder>(x => x.WorkType == 6 && x.SQL_State == "执行中");
|
var ods = ooo.FindAll(x => x.SQL_PLineNo.Contains(plc.deviceName));
|
if (ods.Count > 0)
|
{
|
foreach (var od in ooo)
|
{
|
if (string.IsNullOrEmpty(od.SQL_charge))
|
continue;
|
var num = od.SQL_charge?.Split(':');
|
var v = Array.ConvertAll(num, Convert.ToInt32);
|
if (v.Length == 2)
|
{
|
if (od.SQL_Total >= v[0])
|
{
|
LogHelper.Info(plc.deviceName + $"已累计信号量{od.SQL_Total} 待领料数{od.OutNum}--开始转换(信号量>{(od.SQL_Total - v[0])} 领料数>{od.OutNum + v[1]}");
|
od.SQL_Total -= v[0];
|
od.OutNum += v[1];
|
WCSHelper.Do(db =>
|
{
|
db.Updateable(od).UpdateColumns(x => new { x.SQL_Total, x.OutNum }).ExecuteCommand();
|
});
|
}
|
else if (od.OutNum % 2 > 0)//奇数
|
{
|
if (v[1] == 2 && v[0] % 2 == 0) // 比如 6:2 可以换算成 3:1
|
{
|
if (od.SQL_Total >= (v[0] / 2))
|
{
|
od.SQL_Total -= (v[0] / 2);
|
od.OutNum += 1;
|
WCSHelper.Do(db =>
|
{
|
db.Updateable(od).UpdateColumns(x => new { x.SQL_Total, x.OutNum }).ExecuteCommand();
|
});
|
}
|
}
|
}
|
}
|
}
|
}
|
var si = data.Substring(1, 1);
|
if (!ods.Any() || data.Contains("21"))
|
si = "0";
|
|
if (data.Contains("11") || data.Contains("21"))
|
{
|
var _cl = LocationHelper.GetLoc(plc.location[0]);
|
if (_cl.S_LOCK_STATE != "无")
|
{
|
goto ballll;
|
}
|
if (_cl == null)
|
{
|
LogHelper.Info($"{plc.deviceName}配置的位置没找到。");
|
|
goto ballll;
|
}
|
var _clrel = LocationHelper.GetLocCntrRel(_cl.S_LOC_CODE);
|
var _clrel0 = _clrel.OrderByDescending(xx => xx.T_CREATE).FirstOrDefault();
|
var od = LocationHelper.GetList<YWLWorkOrder>(x => x.SQL_PLineNo.Contains(plc.deviceName) && x.WorkType == 1 && x.SQL_State == "执行中").FirstOrDefault();
|
if (data.Contains("21"))
|
{
|
double v1 = 0;
|
if (od == null)
|
{
|
Console.WriteLine(plc.deviceName + " 退料信号,但工单未开启。");
|
goto ballll;
|
}
|
if (od.SQL_PLineNo.Contains("标签") || od.SQL_PLineNo.Contains("收缩膜"))
|
{
|
switch (od.S_BQ_TRAY_TYPE)
|
{
|
case "零头板":
|
v1 = .5;
|
break;
|
case "零头板2":
|
v1 = .75;
|
break;
|
case "满板":
|
v1 = 1;
|
break;
|
default: v1 = 0; break;
|
}
|
if (v1 == 0)
|
{
|
LogHelper.CErrorLog($"{od.SQL_WorkNo}-{od.S_BQ_TRAY_TYPE} 转换后为0,无法识别。");
|
goto ballll;
|
}
|
}
|
if (!_clrel.Any())
|
{
|
WMSTask task = null;
|
WCSHelper.Do(db =>
|
{
|
task = db.Queryable<WMSTask>().Where(x => x.S_START_LOC == _cl.S_LOC_CODE).OrderBy(x => x.T_CREATE, OrderByType.Desc).First();
|
});
|
if (task.S_B_STATE != "取消" && task.S_B_STATE != "完成")
|
{
|
goto ballll;
|
}
|
//var enloc = LocationHelper.GetLoc(task.S_END_LOC);
|
//if (enloc.S_LOCK_STATE != "无") return;
|
|
LogHelper.Info(_cl.S_LOC_CODE + $"货位 的没有托盘 没有物料记录 退料,开始写入。");
|
List<CntrItemRel> lirl = new List<CntrItemRel>
|
{
|
new CntrItemRel
|
{
|
S_CNTR_CODE=Settings.GetTimeStamp(),
|
S_ITEM_CODE=od.SQL_ItemCode,
|
S_ITEM_NAME=od.SQL_ItemName,
|
S_CJ_NAME = od.S_CJ_NAME,
|
N_BQ_TRAY_TYPE=v1
|
}
|
};
|
string ma = "";
|
List<string> list = new List<string>();
|
if (!string.IsNullOrEmpty(od.MidArea))
|
list.Add(od.MidArea);
|
if (!string.IsNullOrEmpty(od.S_ROW))
|
list.Add(od.S_ROW);
|
ma = string.Join(",", list);
|
|
List<LocCntrRel> lcrl = new List<LocCntrRel>
|
{
|
new LocCntrRel
|
{
|
S_LOC_CODE=_cl.S_LOC_CODE,
|
S_CNTR_CODE = lirl.FirstOrDefault().S_CNTR_CODE,
|
S_TYPE=v1==0?ma:HH.WCS.QingXigongchang.core.Monitor.BQ_PRA.B
|
}
|
};
|
_cl.N_CURRENT_NUM += 1;
|
WCSHelper.Do(db =>
|
{
|
db.Insertable(lirl).ExecuteCommand();
|
db.Insertable(lcrl).ExecuteCommand();
|
db.Insertable(new Container
|
{
|
S_CNTR_CODE = lirl.FirstOrDefault().S_CNTR_CODE,
|
}).ExecuteCommand();
|
db.Updateable(_cl).UpdateColumns(x => new { x.N_CURRENT_NUM }).ExecuteCommand();
|
});
|
goto ballll;
|
}
|
else if (string.IsNullOrEmpty(_clrel0.S_TYPE))
|
{
|
LocationHelper.DoAction(db =>
|
{
|
//_clrel0.S_TYPE = "YWLYLTKQ";
|
//return db.Updateable(_clrel0).UpdateColumns(it => new { it.S_TYPE }).ExecuteCommand() > 0;
|
return db.Deleteable(_clrel).ExecuteCommand() > 0;
|
});
|
}
|
goto ballll;
|
}
|
|
|
if (od != null)
|
{
|
si = "0";
|
|
}
|
else if (data.Contains("11"))// && (ods.Find(x => x.SQL_PLineNo.Contains("纸箱")) != null || plc.deviceName.Contains("T1"))
|
{
|
//if (!ods.Any())
|
// return;
|
LogHelper.Info($" 数量:{_cl.N_CURRENT_NUM}= 托盘数:{_clrel.Count}");
|
if (_cl.N_CURRENT_NUM > 0 || _clrel.Any())
|
{
|
LogHelper.Info($" time:{_clrel0?.T_CREATE} = s_type:{_clrel0.S_TYPE}");
|
if (_clrel.Any())
|
//if (DateTime.Now.Subtract(_clrel0.T_CREATE).TotalSeconds < 10 || !string.IsNullOrEmpty(_clrel0.S_TYPE))
|
// goto ballll;
|
//plg 2025年6月23日 去除10秒时间限制
|
if (DateTime.Now.Subtract(_clrel0.T_CREATE).TotalSeconds < 3 || !string.IsNullOrEmpty(_clrel0.S_TYPE))
|
goto ballll;
|
|
LocationHelper.DoAction(db =>
|
{
|
db.Deleteable(_clrel).ExecuteCommand();
|
_cl.N_CURRENT_NUM = 0;
|
return db.Updateable(_cl).UpdateColumns(x => new { x.N_CURRENT_NUM }).ExecuteCommand() > 0;
|
});
|
}
|
if (!plc.deviceName.Contains("T1"))
|
goto ballll;
|
else if (!plc.deviceName.Contains("水线标签"))
|
{
|
LogHelper.Info(_cl.S_LOC_CODE + $"货位 找起点");
|
Location sBit = null;
|
foreach (var sRarea in plc.areaPriy)
|
{
|
var arloclist = LocationHelper.GetAreaNormalLocList(sRarea);// LocationHelper.GetList<Location>(x => x.S_AREA_CODE == _clrel0.S_TYPE && x.S_LOCK_STATE != "报废");
|
if (arloclist.Any())
|
{
|
foreach (var rss in arloclist.GroupBy(x => x.N_ROW).OrderBy(x => x.Count(y => y.N_CURRENT_NUM > 0)).ThenBy(xx => xx.Key))
|
{
|
var rowlist = rss.OrderBy(x => x.N_COL).ToList();
|
var _cl2 = rowlist.FindAll(x => x.N_CURRENT_NUM > 0).OrderBy(x => x.N_COL).LastOrDefault();
|
if (_cl2 != null)
|
{
|
_clrel = LocationHelper.GetLocCntrRel(_cl2.S_LOC_CODE);
|
if (!_clrel.Any())
|
{
|
LogHelper.Info(_cl.S_LOC_CODE + $"货位 的没有托盘 没有物料记录");
|
break;
|
}
|
sBit = _cl2;
|
}
|
if (sBit != null) break;
|
}
|
}
|
if (sBit != null) break;
|
}
|
if (sBit != null)
|
{
|
var sign = Settings.GetTimeStamp();
|
var res = TaskProcess.CreateTransport(sign, sBit.S_LOC_CODE, _cl.S_LOC_CODE, "原物料搬运-纸箱", new List<string> { _clrel.FirstOrDefault().S_CNTR_CODE }, sBit.N_CURRENT_NUM, 1, 1, 50);///, EdnRarea == "YWLYLTKQ" ? _clrel0.S_TYPE : "");
|
LogHelper.Info($"原物料搬运 上提升机。 {sign} 任务 ,创建{res} ");
|
//var res = TaskProcess.CreateTransport(sign, sBit.S_LOC_CODE, _cl.S_LOC_CODE, "原物料搬运-纸箱", new List<string> { _clrel.FirstOrDefault().S_CNTR_CODE }, sBit.N_CURRENT_NUM, 1, 1, 50);///, EdnRarea == "YWLYLTKQ" ? _clrel0.S_TYPE : "");
|
//LogHelper.Info($"原物料搬运 上提升机。 {sign} 任务 ,创建{res} ");
|
}
|
}
|
}
|
}
|
ballll:
|
if (doorStatus.ContainsKey(plc.location[0]))
|
{
|
doorStatus[plc.location[0]].info = si;
|
doorStatus[plc.location[0]].modify = DateTime.Now;
|
}
|
else
|
{
|
doorStatus.Add(plc.location[0], new signalInfo
|
{
|
info = si,
|
modify = DateTime.Now
|
});
|
}
|
}
|
|
|
#region 自动门
|
|
/// <summary>
|
/// 自动门
|
/// </summary>
|
/// <param name="data"></param>
|
/// <param name="plc"></param>
|
internal static void AnalysisDoor(string data, Settings.deviceInfo plc)
|
{
|
//LogHelper.Info(plc.deviceName + "自动门状态:" + data + ",地址为:" + plc.address, "自动门");
|
if (data.Length / 2 != plc.deviceNo.Length)
|
{
|
return;
|
}
|
for (int i = 0; i < plc.deviceNo.Length; i++)
|
{
|
string _no = plc.deviceNo[i];
|
if (!string.IsNullOrEmpty(_no))
|
{
|
string state = data.Substring(i * 2 + 1, 1);
|
if (doorStatus.Keys.Contains(_no))
|
{
|
doorStatus[_no].info = state;
|
doorStatus[_no].modify = DateTime.Now;
|
}
|
else
|
{
|
doorStatus.Add(_no, new signalInfo
|
{
|
info = state,
|
modify = DateTime.Now
|
});
|
}
|
}
|
}
|
}
|
|
public class signalInfo
|
{
|
public string info { get; set; }
|
public DateTime modify { get; set; }
|
}
|
|
private static Dictionary<string, DateTime> doorRecord = new Dictionary<string, DateTime>();
|
|
/// <summary>
|
/// 交管请求
|
/// </summary>
|
/// <param name="agv"></param>
|
/// <param name="zone"></param>
|
/// <param name="occupy"></param>
|
internal static void Traffic(string agv, string zone, int occupy)
|
{
|
List<Settings.deviceInfo> plcs = new List<Settings.deviceInfo>();
|
var ppcs = Settings.GetDoorOneToMany().Find(x => x.DoorNo == zone);
|
//if (ppcs != null)
|
//{
|
// foreach (var p in ppcs.deviceNo)
|
// {
|
// Settings.deviceInfo plc = (from a in Settings.GetDeviceInfoList()
|
// where a.deviceNo.Contains(zone)
|
// select a).FirstOrDefault();
|
// if (plc != null)
|
// plcs.Add(plc);
|
// }
|
// if (ppcs.deviceNo.Length == plcs.Count)
|
// {
|
// LogHelper.Info($"{zone}门好对应的 门组:{string.Join(";", ppcs.deviceNo)}, 找到的设备{string.Join(";", plcs.Select(x => x.address))}数量不对, 缺少门地址,中断不开。");
|
// return;
|
// }
|
//}
|
Settings.deviceInfo plc = (from a in Settings.GetDeviceInfoList()
|
where a.deviceNo.Contains(zone)
|
select a).FirstOrDefault();
|
if (plc != null)
|
{
|
int index = 1;
|
for (int i = 0; i < plc.deviceNo.Length; i++)
|
{
|
if (plc.deviceNo[i] == zone)
|
{
|
index = i + 1;
|
break;
|
}
|
}
|
LogHelper.Info($"安全门对接:门号:{zone},index:{index},occupy{occupy}", "自动门");
|
switch (occupy)
|
{
|
case 1023:
|
{
|
string req2 = $"3f 00 {index}1 0d 0a";
|
PlcHelper.SendHex(plc.address, req2);
|
string msg2 = $"安全门开门请求,门号:{zone},index:{index},ip={plc.address}, data={req2}";
|
LogHelper.Info(msg2, "自动门");
|
if (doorStatus.Keys.Contains(zone) && DateTime.Now.Subtract(doorStatus[zone].modify).TotalSeconds < 5.0 && doorStatus[zone].info == "1")
|
{
|
LogHelper.Info($"安全门已经打开:门号:{zone},index:{index}", "自动门");
|
|
NDCHelper.Traffic(zone, agv);
|
}
|
break;
|
}
|
case 1025:
|
{
|
string req = $"3f 00 {index}0 0d 0a";
|
PlcHelper.SendHex(plc.address, req);
|
string msg = $"安全门关门请求,门号:{zone},index:{index},ip={plc.address}, data={req}";
|
LogHelper.Info(msg, "自动门");
|
if (new int[] { 4, 5 }.Contains(plc.deviceType))
|
{
|
var loc = LocationHelper.GetLoc(plc.location[0]);
|
//入库锁,或者没有锁。 货位有货 就翻斗。
|
if (loc.N_CURRENT_NUM == 1 && loc.S_LOCK_STATE.Trim() != "出库锁")
|
{
|
LogHelper.Info($"关门后 翻斗机有货(给翻斗信号。({plc.address})" + $"3f 00 10 0d 0a");
|
PlcHelper.SendHex(plc.address, $"3f 00 10 0d 0a");
|
LocationHelper.UnLockLoc(plc.location[0].Trim());
|
}
|
else
|
{
|
LogHelper.Info($"{loc.S_LOCK_STATE},关门后 翻斗机没有货,不处理");
|
}
|
}
|
break;
|
}
|
}
|
}
|
else if (ppcs != null)
|
{
|
LogHelper.Info($"安全门对接:门号:{zone},门组{string.Join(";", ppcs.deviceNo)},occupy{occupy}", "自动门");
|
switch (occupy)
|
{
|
case 1023:
|
{
|
for (int i = 0; i < ppcs.deviceNo.Length; i++)
|
{
|
var zzz = ppcs.deviceNo[i];
|
//var close = ppcs.SignClose[i];
|
var open = ppcs.SignOpen[i];
|
plc = (from a in Settings.GetDeviceInfoList()
|
where a.deviceNo.Contains(zzz)
|
select a).FirstOrDefault();
|
if (plc == null)
|
{
|
LogHelper.Info($"安全门门号:{zzz},设备不存在", "自动门");
|
return;
|
}
|
|
LogHelper.Info($"安全门对接:门号:{zzz},打开信号{open}", "自动门");
|
string req2 = $"3f 00 {open} 0d 0a";
|
PlcHelper.SendHex(plc.address, req2);
|
string msg2 = $"安全门开门请求,门号:{zzz},index:{open},ip={plc.address}, data={req2}";
|
LogHelper.Info(msg2, "自动门");
|
if (doorStatus.Keys.Contains(zzz) && DateTime.Now.Subtract(doorStatus[zzz].modify).TotalSeconds < 5.0 && doorStatus[zzz].info == "1")
|
{
|
LogHelper.Info($"安全门已经打开:门号:{zzz},index:{open}", "自动门");
|
}
|
else
|
{
|
LogHelper.Info($"安全门未开:门组{zone}门号:{zzz}, 中断。不可入", "自动门");
|
return;
|
}
|
}
|
//if(zoneIn)
|
NDCHelper.Traffic(zone, agv);
|
|
break;
|
}
|
case 1025:
|
{
|
for (int i = 0; i < ppcs.deviceNo.Length; i++)
|
{
|
var zzz = ppcs.deviceNo[i];
|
var close = ppcs.SignClose[i];
|
//var open = ppcs.SignOpen[i];
|
plc = (from a in Settings.GetDeviceInfoList()
|
where a.deviceNo.Contains(zzz)
|
select a).FirstOrDefault();
|
if (plc == null)
|
{
|
LogHelper.Info($"安全门门号:{zzz},设备不存在", "自动门");
|
continue;
|
}
|
//int index = 1;
|
//for (int i = 0; i < plc.deviceNo.Length; i++)
|
//{
|
// if (plc.deviceNo[i] == zzz)
|
// {
|
// index = i + 1;
|
// break;
|
// }
|
//}
|
string req = $"3f 00 {close} 0d 0a";
|
PlcHelper.SendHex(plc.address, req);
|
string msg = $"安全门关门请求,门号:{zzz},index:{close},ip={plc.address}, data={req}";
|
LogHelper.Info(msg, "自动门");
|
}
|
break;
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info("1023 信号 else", "=======");
|
}
|
}
|
|
|
/*
|
IO模块1 只用02功能码读取
|
1x0000 一楼开门到位信号
|
1x0001 二楼开门到位信号
|
|
|
IO模块2 只用05功能码写入
|
0x0000 一楼楼层按钮信号
|
0x0001 二楼楼层按钮信号
|
|
*/
|
|
private static Dictionary<string, DateTime> elevatorRecord = new Dictionary<string, DateTime>();
|
|
/// <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 瓶盖机
|
internal static void AnalysisBottleCap(string data, Settings.deviceInfo plc)
|
{
|
//LogHelper.Info($"{plc.deviceName}-{plc.address}-{data}");
|
|
/*
|
状态1 满托产生,需要取满送空,从满托产生到满托取走一直维持状态1
|
//状态2 送空完成之后为状态2
|
//状态3 满托取走,送空之前为状态3,开机默认状态也为状态3
|
空框放下后。 中间一直给1 写0
|
*/
|
|
if (data.Length == 4)
|
{
|
if (data.Substring(1, 1) == "1")
|
{
|
//BottleCapInfoFull1(plc, plc.location[0]);
|
BottleCapInfoFull(plc, plc.location[0]);
|
}
|
|
if (data.Substring(3, 1) == "1")
|
{
|
//BottleCapInfoFull1(plc, plc.location[1]);
|
if (BottleCapInfoFull(plc, plc.location[1]))
|
{
|
|
}
|
}
|
}
|
}
|
static bool BottleCapInfoFull(Settings.deviceInfo plc, string location)
|
{
|
bool result = false;
|
if (location == "")
|
{
|
Console.WriteLine($"{plc.deviceName} 的setting 没有配置货位数据。 ");
|
return result;
|
}
|
var workOrder = WCSHelper.GetWorkOrder(plc.deviceName);
|
if (workOrder == null)
|
{
|
LogHelper.Info(plc.deviceName + "工单没有【执行中】的工单");
|
return result;
|
}
|
if (workOrder.SQL_Modify_TIme == null)
|
return false;
|
if (DateTime.Now.Subtract(workOrder.SQL_Modify_TIme ?? DateTime.Now).TotalSeconds < 10)
|
return false;
|
LogHelper.Info($"{location} 检验下线数据");
|
//满框下线
|
bool isUsing = workOrder.SQL_UsingNow.Trim() == "Y";
|
var p0 = LocationHelper.GetLoc(location);
|
if (p0 != null && p0.S_LOCK_STATE == "无")
|
{
|
if (p0.T_FULL_TIME == null && p0.N_CURRENT_NUM == 0)
|
{
|
// 瓶盖上空
|
LocationHelper.TakeEmptyToBottleBoyd(new WMSTask
|
{
|
S_START_LOC = location,
|
});
|
return true;
|
}//托盘放下 1分钟内 取货请求,都不处理。
|
else if (p0.N_CURRENT_NUM > 0 && DateTime.Now.Subtract(p0.T_FULL_TIME ?? DateTime.Now).Minutes < 1)
|
{
|
p0.T_FULL_TIME = DateTime.Now;
|
for (var i = 0; i < plc.location.Length; i++)
|
{
|
if (location == plc.location[i])
|
{
|
PlcHelper.SendHex(plc.address, "3F00" + (i + 1) + "0" + "0d0a");
|
LocationHelper.DoAction(db =>
|
{
|
db.Updateable<Location>(p0).UpdateColumns(it => new { it.T_FULL_TIME }).ExecuteCommand();
|
return true;
|
});
|
break;
|
}
|
}
|
return false;
|
}
|
|
LogHelper.Info($"{location}满框下线");
|
Location endBit = null;
|
string TaskDesc = "";
|
var _ctrl = LocationHelper.GetLocCntrRel(location);
|
if (!_ctrl.Any())
|
{
|
LogHelper.Info($"{plc.deviceName}-{location}没绑定托盘");
|
return result;
|
}
|
bool Uisng = false;
|
if (_ctrl.FirstOrDefault().S_CNTR_CODE.StartsWith("J"))
|
{
|
Uisng = true;
|
var LineTo = workOrder.SQL_LinkLineNO;
|
LogHelper.Info($"{location}满框下线 J- " + LineTo);
|
|
var plcTo = Settings.GetDeviceInfoList().Where(a => a.deviceName == LineTo).FirstOrDefault();
|
if (plcTo == null)
|
{
|
LogHelper.Info($"{plc.deviceName}-{workOrder.SQL_WorkNo}链接的产线号{LineTo} 没找到设备");
|
return result;
|
}
|
if (plcTo.deviceType != 4 && plcTo.deviceType != 6)
|
{
|
LogHelper.Info($"{plc.deviceName}-{workOrder.SQL_WorkNo}链接的产线号{LineTo} 不是瓶盖翻斗机。");
|
return result;
|
}
|
var ba = Settings.GetBolAreaList().Find(x => x.DeviceName == plcTo.deviceName && x.deviceType == plcTo.deviceType);
|
if (ba == null)
|
{
|
LogHelper.Info($"{plc.deviceName}-{workOrder.SQL_WorkNo}链接的产线号{LineTo} BolArea 未配置。");
|
return result;
|
}
|
|
var loclist = LocationHelper.GetAreaNormalLocList(ba.UsingBolArea);
|
if (true)
|
{
|
var t = DateTime.Now;
|
var rowlist = LocationHelper.GetRowLock(ba.UsingBolArea);
|
LogHelper.Info($"{location}满框下线 {ba.UsingBolArea}库区, rowlist:{rowlist.Count}");
|
foreach (var itemrs in loclist.GroupBy(x => x.N_ROW).OrderBy(y => rowlist.Find(x => x.S_LOCK_STATE == "入库锁" && x.N_ROW == y.Key)?.T_CREATE ?? t).ThenBy(x => x.Key)) //Descending x.Count(y => y.N_CURRENT_NUM > 0)))
|
{
|
var tnotnull = rowlist.Find(x => x.S_LOCK_STATE == "出库锁" && x.N_ROW == itemrs.Key);
|
LogHelper.Info($"{location}满框下线 第{itemrs.Key}排 是否被出库锁排?:{tnotnull != null}");
|
if (tnotnull != null) continue;
|
var _r = itemrs.ToList();
|
var f = _r.FindAll(x => x.N_CURRENT_NUM > 0).OrderBy(x => x.N_COL).LastOrDefault();
|
if (f != null)
|
{
|
if (f.N_CURRENT_NUM < f.N_CAPACITY)
|
{
|
endBit = f;
|
}
|
else endBit = _r.FindAll(x => x.N_COL > (f?.N_COL ?? 0)).OrderBy(x => x.N_COL).FirstOrDefault();
|
}
|
else
|
{
|
endBit = _r.OrderBy(x => x.N_COL).FirstOrDefault();
|
}
|
|
if (endBit != null)
|
{
|
TaskDesc = "瓶盖即产转翻斗机线边";
|
break;
|
}
|
}
|
}
|
|
if (false)
|
{
|
var allrows = loclist.Select(x => x.N_ROW).Distinct();
|
var hasRows = loclist.FindAll(x => x.N_CURRENT_NUM > 0).OrderByDescending(x => x.T_FULL_TIME);
|
var EptRows = allrows.Except(hasRows.Select(x => x.N_ROW).Distinct());
|
|
//最后一个入的排,如果是满的就找空的。
|
if (hasRows.Any())
|
{
|
var lastFull = hasRows.FirstOrDefault();
|
if (lastFull != null)
|
{
|
//if (lastFull.N_CURRENT_NUM < lastFull.N_CAPACITY)
|
//{
|
// endBit = lastFull;
|
//}
|
//else
|
endBit = loclist.Find(x => x.N_ROW == lastFull.N_ROW && x.N_COL >= lastFull.N_COL && x.N_CURRENT_NUM < x.N_CAPACITY);
|
}
|
}
|
else LogHelper.Info($"{plc.deviceName} - 即产下线,最后入库位是满的 或者 没有曾入库数据。");
|
//如过没有最后一个入排,直接找空的。-- 只需要看endbit 就好了。
|
if (endBit == null && EptRows.Any())
|
{
|
endBit = loclist.FindAll(x => x.N_ROW == EptRows.FirstOrDefault()).OrderBy(x => x.N_COL).FirstOrDefault();
|
}
|
else LogHelper.Info($"{plc.deviceName} -已找到可用位置:{endBit?.S_LOC_CODE},或没有空排可用。 等着吧,不能把要出的堵住。");
|
|
if (endBit != null)
|
{
|
TaskDesc = "瓶盖即产转翻斗机线边";
|
//var cntrEnd2 = LocationHelper.GetLocCntrRel(endBit.S_LOC_CODE);
|
//var citem = ContainerHelper.GetCntrItemRel(cntrEnd2.FirstOrDefault().S_CNTR_CODE);
|
}
|
}
|
|
if (false)
|
foreach (var item in loclist.OrderByDescending(x => x.T_FULL_TIME).GroupBy(x => x.N_ROW))
|
{
|
var ilist = item.OrderBy(x => x.N_COL).ToList();
|
var lastFull = ilist.FindAll(x => x.N_CURRENT_NUM > 0).OrderBy(x => x.N_COL).LastOrDefault();
|
if (lastFull != null)
|
{
|
if (lastFull.N_CURRENT_NUM < lastFull.N_CAPACITY)
|
{
|
endBit = lastFull;
|
var cntrEnd2 = LocationHelper.GetLocCntrRel(endBit.S_LOC_CODE);
|
var citem = ContainerHelper.GetCntrItemRel(cntrEnd2.FirstOrDefault().S_CNTR_CODE);
|
//if (citem.Any() && citem.FirstOrDefault().S_ORDER_NO.Contains(workOrder.SQL_WorkNo))
|
//{
|
// LogHelper.Info($"{lastFull.S_LOC_CODE} 位置数量{lastFull.N_CURRENT_NUM}.已有的托盘不是这个工单的。");
|
// continue;
|
//}
|
}
|
else
|
endBit = ilist.Find(x => x.N_COL > lastFull.N_COL);
|
}
|
else
|
endBit = ilist.FirstOrDefault();
|
if (endBit != null)
|
{
|
TaskDesc = "瓶盖即产转翻斗机线边";
|
break;
|
}
|
}
|
if (false)
|
foreach (var item in loclist.OrderByDescending(x => x.N_CURRENT_NUM).ThenBy(x => x.N_ROW).ThenBy(x => x.N_COL))
|
{
|
if (item.N_CURRENT_NUM < item.N_CAPACITY)
|
{
|
if (item.N_CURRENT_NUM > 0)
|
{
|
var cntrEnd2 = LocationHelper.GetLocCntrRel(endBit.S_LOC_CODE);
|
var citem = ContainerHelper.GetCntrItemRel(cntrEnd2.FirstOrDefault().S_CNTR_CODE);
|
if (citem.Any() && citem.FirstOrDefault().S_ORDER_NO.Contains(workOrder.SQL_WorkNo))
|
{
|
LogHelper.Info($"{item.S_LOC_CODE} 位置数量{item.N_CURRENT_NUM}.已有的托盘不是这个工单的。");
|
continue;
|
}
|
}
|
endBit = item;
|
TaskDesc = "瓶盖即产转翻斗机线边";
|
break;
|
}
|
}
|
|
///按列排序。 最后一个满框。后街接着入。
|
//var loclist = LocationHelper.GetAreaNormalLocList(ba.UsingBolArea);
|
//var locs = LocationHelper.GetLocList(x => x.S_AREA_CODE == ba.UsingBolArea && x.S_LOC_CODE != "报废").OrderBy(x => x.N_COL).ThenBy(x => x.N_ROW).ToList();
|
//var lastffl = locs.FindAll(x => x.N_CURRENT_NUM > 0 && x.T_FULL_TIME != null).OrderBy(x => x.T_FULL_TIME).LastOrDefault();
|
//var lastEmpty = locs.FindAll(x => x.N_CURRENT_NUM == 0 && x.T_EMPTY_TIME != null).OrderBy(x => x.T_EMPTY_TIME).LastOrDefault();
|
|
//if (lastffl != null)
|
//{
|
// if (lastEmpty == null) lastffl = null;
|
// else if (lastffl.N_COL <= lastEmpty.N_COL) { lastffl = null; lastEmpty = null; }
|
// else if (lastffl == locs.LastOrDefault()) lastffl = null;
|
//}
|
/////最后一个满框入库位往后找。
|
//foreach (var item in locs.Skip((lastffl == null || lastffl == locs.LastOrDefault() ? 0 : locs.IndexOf(lastffl))).GroupBy(x => x.N_COL))
|
//{
|
// ///先放小排, 先取大排 取放按列
|
// var collist = item.OrderBy(x => x.N_ROW).ToList();
|
// if (!collist.Any()) continue;
|
// if (collist.Find(x => x.S_LOCK_STATE != "无") != null) continue;
|
// var collastful = collist.Find(x => x.N_CURRENT_NUM > 0);
|
// Location nex = null;
|
// if (collastful == null) nex = collist.FirstOrDefault();
|
// else nex = collist.Find(x => x.N_ROW >= collastful.N_ROW && x.N_CURRENT_NUM < x.N_CAPACITY);
|
// if (nex != null)
|
// {
|
// endBit = nex;
|
// TaskDesc = "瓶盖即产转翻斗机线边";
|
// break;
|
// }
|
//}
|
|
}
|
else if (false)
|
{
|
LogHelper.Info($"{location}满框下线 F");
|
var ba = Settings.GetBolAreaList().Find(x => x.DeviceName == plc.deviceName && x.deviceType == plc.deviceType);
|
if (ba == null)
|
{
|
LogHelper.Info($"{plc.deviceName}-{workOrder.SQL_WorkNo}的 BolArea 未配置。");
|
return result;
|
}
|
var loclist = LocationHelper.GetAreaNormalLocList(ba.NotUsingBolArea);
|
foreach (var item in loclist.OrderByDescending(x => x.N_CURRENT_NUM).ThenBy(x => x.N_ROW).ThenBy(x => x.N_COL))
|
{
|
if (item.N_CURRENT_NUM < item.N_CAPACITY)
|
{
|
if (item.N_CURRENT_NUM > 0)
|
{
|
var cntrEnd2 = LocationHelper.GetLocCntrRel(item.S_LOC_CODE);
|
var citem = ContainerHelper.GetCntrItemRel(cntrEnd2.FirstOrDefault().S_CNTR_CODE);
|
if (citem.Any() && TaskProcess.UPFule && !string.IsNullOrEmpty(citem.FirstOrDefault()?.S_ORDER_NO) && citem.FirstOrDefault().S_ORDER_NO.Contains(workOrder.SQL_WorkNo))
|
{
|
LogHelper.Info($"{item.S_LOC_CODE} 位置数量{item.N_CURRENT_NUM}.已有的托盘不是这个工单的。");
|
continue;
|
}
|
}
|
endBit = item;
|
TaskDesc = "瓶盖非即产线边";
|
break;
|
}
|
}
|
}
|
else
|
{
|
TaskDesc = "瓶盖非即产线边";
|
LogHelper.Info($"{location}满框下线 F 非即产满框下线 按 plc.areaPriy 顺序。"); /*-对应的 翻斗机上线(指定产线号) 也是。*/
|
var db = new SqlHelper<object>().GetInstance();
|
foreach (var item in plc.areaPriy)
|
{
|
var _l = LocationHelper.GetAreaNormalLocList(item);
|
var rowlist = LocationHelper.GetRowLock(item);
|
var t = DateTime.Now;
|
foreach (var itemrs in _l.GroupBy(x => x.N_ROW).OrderBy(y => rowlist.Find(x => x.S_LOCK_STATE == "入库锁" && x.N_ROW == y.Key)?.T_CREATE ?? t).ThenBy(x => x.Key)) //Descending x.Count(y => y.N_CURRENT_NUM > 0)))
|
{
|
if (rowlist.Find(x => x.S_LOCK_STATE == "出库锁" && x.N_ROW == itemrs.Key) != null) continue;
|
var _r = itemrs.ToList();
|
var f = _r.FindAll(x => x.N_CURRENT_NUM > 0).OrderBy(x => x.N_COL).LastOrDefault();
|
if (f != null)
|
{
|
var rel = LocationHelper.GetLocCntrRel(f.S_LOC_CODE);
|
var cntrrel = ContainerHelper.GetCntrItemRel(rel.FirstOrDefault()?.S_CNTR_CODE);
|
if (cntrrel.FirstOrDefault()?.S_ITEM_CODE != $"{workOrder.SQL_PLineNo}>{workOrder.SQL_ItemCode}")
|
{
|
LogHelper.Info($"{f.S_LOC_CODE} 位置的 物料{cntrrel.FirstOrDefault()?.S_ITEM_CODE} 与本次下线{workOrder.SQL_PLineNo}>{workOrder.SQL_ItemCode} 不符。 筛选下一排");
|
continue;
|
}
|
///// 看看是否出库记录
|
//var row = rowlist.FindAll(x => x.S_AREA_CODE == f.S_AREA_CODE && f.N_ROW == x.N_ROW).ToList();//db.Queryable<RowLock>().Where(x => x.S_AREA_CODE == f.S_AREA_CODE && f.N_ROW == x.N_ROW).ToList();
|
//if (row.Any())
|
//{
|
// if (row.FirstOrDefault().S_LOCK_STATE != "入库锁")
|
// continue;
|
//}
|
if (f.N_CURRENT_NUM < f.N_CAPACITY)
|
{
|
endBit = f;
|
}
|
else endBit = _r.FindAll(x => x.N_COL > (f?.N_COL ?? 0)).OrderBy(x => x.N_COL).FirstOrDefault();
|
}
|
else
|
{
|
endBit = _r.OrderBy(x => x.N_COL).FirstOrDefault();
|
}
|
|
if (endBit != null)
|
break;
|
}
|
|
if (endBit != null)
|
break;
|
}
|
}
|
|
LogHelper.Info($"{location}满框下线 终点位:{endBit?.S_LOC_CODE}");
|
if (endBit != null)
|
{
|
int endLayer = endBit.N_CURRENT_NUM + 1;
|
//if (endLayer > 1)
|
//{
|
// var cntrEnd2 = LocationHelper.GetLocCntrRel(endBit.S_LOC_CODE);
|
// var citem = ContainerHelper.GetCntrItemRel(cntrEnd2.FirstOrDefault().S_CNTR_CODE);
|
// if (!cntrEnd2.Any() || !citem.Any())
|
// {
|
// LogHelper.Info($"{endBit.S_LOC_CODE} 位置数量{endBit.N_CURRENT_NUM}.但没有托盘或没有托盘物料数据。");
|
// return false;
|
// }
|
//}
|
var carryCntrs = new List<string> { _ctrl.FirstOrDefault().S_CNTR_CODE };//DateTime.Now.ToString("yyMMddHHmmss") };
|
var bb = TaskProcess.CreateTransport(workOrder.SQL_WorkNo, location, endBit.S_LOC_CODE, TaskDesc, carryCntrs, 1, endLayer, carryCntrs.Count, plc.taskPri);
|
if (bb)
|
{
|
// 写入托盘物料表。
|
LocationHelper.DoAction(db =>
|
{
|
db.Deleteable<CntrItemRel>().Where(it => it.S_CNTR_CODE == _ctrl.FirstOrDefault().S_CNTR_CODE).ExecuteCommand();
|
db.Insertable(new CntrItemRel
|
{
|
S_CNTR_CODE = _ctrl.FirstOrDefault().S_CNTR_CODE,
|
//S_ITEM_CODE = workOrder.SQL_ItemCode,
|
S_ITEM_CODE = $"{workOrder.SQL_PLineNo}>{workOrder.SQL_ItemCode}",
|
F_QTY = Uisng ? workOrder.SQL_PCNumber_using : workOrder.SQL_PCNumber,
|
S_ORDER_NO = workOrder.SQL_WorkNo + ("_" + (workOrder.FromFuLe?.Trim() ?? "")),
|
S_BATCH_NO = workOrder.SQL_BatchNo,
|
}).ExecuteCommand();
|
return true;
|
});
|
LogHelper.Info($"{plc.deviceName} 当前机器{location}位置状态{p0} 正在执行取满任务");
|
}
|
result = bb;
|
}
|
}
|
else LogHelper.Info($"{location}货位状态 {p0?.S_LOCK_STATE} 下线中断");
|
|
return result;
|
}
|
|
static bool BottleCapInfoFull1(Settings.deviceInfo plc, string location)
|
{
|
bool result = false;
|
if (location == "")
|
{
|
Console.WriteLine($"{plc.deviceName} 的setting 没有配置货位数据。 ");
|
return result;
|
}
|
var workOrder = WCSHelper.GetPGWorkOrder(plc.deviceName);
|
if (workOrder == null)
|
{
|
LogHelper.Info(plc.deviceName + "工单没有【执行中】的工单");
|
return result;
|
}
|
LogHelper.Info($"{location} 检验下线数据");
|
|
//满框下线
|
bool isUsing = workOrder.SQL_UsingNow.Trim() == "Y";
|
var p0 = LocationHelper.GetLoc(location);
|
if (p0 != null && p0.S_LOCK_STATE == "无")
|
{
|
if (p0.T_FULL_TIME == null && p0.N_CURRENT_NUM == 0)
|
{
|
// 瓶盖上空
|
LocationHelper.TakeEmptyToBottleBoyd2346(new WMSTask
|
{
|
S_START_LOC = location,
|
});
|
return true;
|
} //托盘放下 1分钟内 取货请求,都不处理。
|
else if (p0.N_CURRENT_NUM > 0 && DateTime.Now.Subtract(p0.T_FULL_TIME ?? DateTime.Now).Minutes < 1)
|
{
|
p0.T_FULL_TIME = DateTime.Now;
|
for (var i = 0; i < plc.location.Length; i++)
|
{
|
if (location == plc.location[i])
|
{
|
PlcHelper.SendHex(plc.address, "3F00" + (i + 1) + "0" + "0d0a");
|
LocationHelper.DoAction(db =>
|
{
|
db.Updateable<Location>(p0).UpdateColumns(it => new { it.T_FULL_TIME }).ExecuteCommand();
|
return true;
|
});
|
break;
|
}
|
}
|
return false;
|
}
|
LogHelper.Info($"{location}满框下线");
|
Location endBit = null;
|
List<Location> _l = new List<Location>();
|
var SQL_ItemCode = workOrder.SQL_ItemCode;
|
string TaskDesc = "";
|
var _ctrl = LocationHelper.GetLocCntrRel(location);
|
if (!_ctrl.Any())
|
{
|
LogHelper.Info($"{plc.deviceName}-{location}没绑定托盘");
|
return result;
|
}
|
bool Uisng = false;
|
if (_ctrl.FirstOrDefault().S_CNTR_CODE.Contains("J"))
|
{
|
TaskDesc = "瓶盖下线即产";
|
_l = LocationHelper.GetLocList(x => x.S_AREA_CODE == workOrder.SQL_Area && x.S_LOCK_STATE != "报废");
|
#region 直接去终点
|
var _arealock = _l.FindAll(x => x.S_LOCK_STATE != "无").Select(x => x.N_ROW).Distinct();
|
if (_arealock.Any()) _l.RemoveAll(x => _arealock.Contains(x.N_ROW));
|
foreach (var itemrs in _l.OrderByDescending(x => x.N_CURRENT_NUM).GroupBy(x => x.N_ROW))
|
{
|
var _r = itemrs.ToList();
|
var f = _r.FindAll(x => x.N_CURRENT_NUM > 0).OrderBy(x => x.N_COL).LastOrDefault();
|
if (f != null)
|
{
|
var rel = LocationHelper.GetLocCntrRel(f.S_LOC_CODE);
|
var cntrrel = ContainerHelper.GetCntrItemRel(rel.FirstOrDefault()?.S_CNTR_CODE);
|
if (cntrrel.FirstOrDefault()?.S_ITEM_CODE != $"{workOrder.SQL_PLineNo}>{SQL_ItemCode}")
|
{
|
LogHelper.Info($"{f.S_LOC_CODE} 位置的 物料{cntrrel.FirstOrDefault()?.S_ITEM_CODE} 与本次下线{workOrder.SQL_PLineNo}>{SQL_ItemCode} 不符。 筛选下一排");
|
continue;
|
}
|
if (f.N_CURRENT_NUM < f.N_CAPACITY)
|
{
|
endBit = f;
|
}
|
|
else endBit = _r.FindAll(x => x.N_COL > (f?.N_COL ?? 0)).OrderBy(x => x.N_COL).FirstOrDefault();
|
}
|
else
|
{
|
endBit = _r.OrderBy(x => x.N_COL).FirstOrDefault();
|
}
|
if (endBit != null)
|
break;
|
}
|
|
#endregion
|
}
|
if (!_ctrl.FirstOrDefault().S_CNTR_CODE.Contains("J"))
|
{
|
LogHelper.Info($"{plc.deviceName} 注塑机下线 目标库区排{workOrder.S_ROW1} .");
|
if (string.IsNullOrEmpty(workOrder.S_ROW1))
|
{
|
return false;
|
}
|
else
|
{
|
TaskDesc = "瓶盖下线非即产";
|
var rs = workOrder.S_ROW1.Split('=');
|
var rows = Array.ConvertAll(rs[rs.Length - 1].Trim().Split('-'), Convert.ToInt32);
|
//_l = LocationHelper.GetLocList(x => x.S_AREA_CODE == rs[0] && rows.Contains(x.N_ROW) && x.S_LOCK_STATE != "报废");
|
|
if (true)
|
{
|
_l = LocationHelper.GetAreaNormalLocList(rs[0]);
|
foreach (var itemrs in _l.FindAll(x => rows.Contains(x.N_ROW)).GroupBy(x => x.N_ROW).OrderBy(x => x.Count(y => y.N_CURRENT_NUM > 0)))
|
{
|
var _r = itemrs.ToList();
|
var f = _r.FindAll(x => x.N_CURRENT_NUM > 0).OrderBy(x => x.N_COL).LastOrDefault();
|
if (f != null)
|
{
|
var rel = LocationHelper.GetLocCntrRel(f.S_LOC_CODE);
|
var cntrrel = ContainerHelper.GetCntrItemRel(rel.FirstOrDefault()?.S_CNTR_CODE);
|
if (cntrrel.FirstOrDefault()?.S_ITEM_CODE != $"{workOrder.SQL_PLineNo}>{SQL_ItemCode}")
|
//if (rel.FirstOrDefault()?.S_TYPE != $"{workOrder.SQL_PLineNo}>{SQL_ItemCode}")
|
{
|
LogHelper.Info($"{f.S_LOC_CODE} 位置的 物料{cntrrel.FirstOrDefault()?.S_ITEM_CODE} 与本次下线{workOrder.SQL_PLineNo}>{SQL_ItemCode} 不符。 筛选下一排");
|
continue;
|
}
|
if (f.N_CURRENT_NUM < f.N_CAPACITY)
|
{
|
endBit = f;
|
}
|
else endBit = _r.FindAll(x => x.N_COL > (f?.N_COL ?? 0)).OrderBy(x => x.N_COL).FirstOrDefault();
|
}
|
else
|
{
|
endBit = _r.OrderBy(x => x.N_COL).FirstOrDefault();
|
}
|
if (endBit != null)
|
break;
|
}
|
}
|
goto vvvvvv;
|
}
|
|
vvvvvv:
|
//if (false)//endBit == null&&
|
if (endBit == null && workOrder.S_Is_Auto.Trim() == "Y")
|
foreach (var item in _l.GroupBy(x => (x.N_ROW + 1) / 2).OrderByDescending(x => x.Count(y => y.N_CURRENT_NUM > 0)))
|
{
|
var lst = item.ToList().Find(x => x.N_CURRENT_NUM > 0);
|
var _r = item.ToList();
|
var f = _r.FindAll(x => x.N_CURRENT_NUM > 0).OrderBy(x => x.N_COL).LastOrDefault();
|
if (f != null)
|
{
|
var rel = LocationHelper.GetLocCntrRel(f.S_LOC_CODE);
|
var cntrrel = ContainerHelper.GetCntrItemRel(rel.FirstOrDefault()?.S_CNTR_CODE);
|
if (cntrrel.FirstOrDefault()?.S_ITEM_CODE != $"{workOrder.SQL_PLineNo}>{SQL_ItemCode}")
|
continue;
|
foreach (var rowlocs in item.GroupBy(x => x.N_ROW))
|
{
|
|
List<Location> _cols = item.OrderBy(x => x.N_COL).ToList();
|
Location e = _cols.FindAll((Location x) => x.N_CURRENT_NUM > 0).LastOrDefault();//从左往右最后一个满位。
|
if (e != null)
|
{
|
rel = LocationHelper.GetLocCntrRel(e.S_LOC_CODE);
|
cntrrel = ContainerHelper.GetCntrItemRel(rel.FirstOrDefault()?.S_CNTR_CODE);
|
if (cntrrel.FirstOrDefault()?.S_ITEM_CODE != $"{workOrder.SQL_PLineNo}>{SQL_ItemCode}")
|
{
|
LogHelper.Info($"{e.S_LOC_CODE} 位置的 物料{cntrrel.FirstOrDefault()?.S_ITEM_CODE} 与本次下线{($"{workOrder.SQL_PLineNo}>{SQL_ItemCode}")} 不符。 筛选下一排");
|
continue;
|
}
|
}
|
|
if (e != null && e.N_CURRENT_NUM < e.N_CAPACITY)
|
{
|
endBit = e;
|
}
|
else
|
{
|
var empT = _cols.FindAll(x => x.N_CURRENT_NUM == 0).FirstOrDefault();//从左往右第一个空位
|
if (empT != null)
|
endBit = empT;
|
}
|
if (endBit != null)
|
break;
|
}
|
}
|
if (endBit != null)
|
break;
|
}
|
}
|
|
LogHelper.Info($"{location}满框下线 终点位:{endBit?.S_LOC_CODE}");
|
if (endBit != null)
|
{
|
int endLayer = endBit.N_CURRENT_NUM + 1;
|
//if (endLayer > 1)
|
//{
|
// var cntrEnd2 = LocationHelper.GetLocCntrRel(endBit.S_LOC_CODE);
|
// var citem = ContainerHelper.GetCntrItemRel(cntrEnd2.FirstOrDefault().S_CNTR_CODE);
|
// if (!cntrEnd2.Any() || !citem.Any())
|
// {
|
// LogHelper.Info($"{endBit.S_LOC_CODE} 位置数量{endBit.N_CURRENT_NUM}.但没有托盘或没有托盘物料数据。");
|
// return false;
|
// }
|
//}
|
var carryCntrs = new List<string> { _ctrl.FirstOrDefault().S_CNTR_CODE };//DateTime.Now.ToString("yyMMddHHmmss") };
|
var bb = TaskProcess.CreateTransport(workOrder.SQL_WorkNo, location, endBit.S_LOC_CODE, TaskDesc, carryCntrs, 1, endLayer, carryCntrs.Count, plc.taskPri);
|
if (bb)
|
{
|
// 写入托盘物料表。
|
LocationHelper.DoAction(db =>
|
{
|
db.Deleteable<CntrItemRel>().Where(it => it.S_CNTR_CODE == _ctrl.FirstOrDefault().S_CNTR_CODE).ExecuteCommand();
|
db.Insertable(new CntrItemRel
|
{
|
S_CNTR_CODE = _ctrl.FirstOrDefault().S_CNTR_CODE,
|
//S_ITEM_CODE = workOrder.SQL_ItemCode,
|
S_ITEM_CODE = $"{workOrder.SQL_PLineNo}>{SQL_ItemCode}",
|
F_QTY = Uisng ? workOrder.SQL_PCNumber_using : workOrder.SQL_PCNumber,
|
S_ORDER_NO = workOrder.SQL_WorkNo + ("_" + (workOrder.FromFuLe?.Trim() ?? "")),
|
S_BATCH_NO = workOrder.SQL_BatchNo,
|
}).ExecuteCommand();
|
return true;
|
});
|
LogHelper.Info($"{plc.deviceName} 当前机器{location}位置状态{p0} 正在执行取满任务");
|
}
|
result = bb;
|
}
|
}
|
else LogHelper.Info($"{location}货位状态 {p0?.S_LOCK_STATE} 下线中断");
|
|
return result;
|
}
|
|
/// <summary>
|
/// 非即产空框堆叠位 入库
|
/// </summary>
|
public static void TakeEmpty2WH()
|
{
|
try
|
{
|
foreach (var areas in Settings.GetBolAreaList().FindAll(x => x.deviceType == 4 || x.deviceType == 10 || x.deviceType == 6))//.Select(x => x.NotUsingEmpty).Distinct())
|
{
|
var area = areas.NotUsingEmpty;
|
var loclist = LocationHelper.GetAreaNormalLocList(area, false);
|
if (loclist.Find(x => x.N_CURRENT_NUM == x.N_CAPACITY && x.S_LOCK_STATE == "出库锁") != null)
|
continue;
|
IEnumerable<int> lockcols = (from x in loclist.FindAll((Location x) => x.S_LOCK_STATE.Trim() != "无" && x.S_LOCK_STATE.Trim() != "报废")
|
select x.N_ROW).Distinct();
|
if (lockcols.Any())
|
{
|
loclist.RemoveAll((Location x) => lockcols.Contains(x.N_ROW));
|
}
|
|
//var bo = Settings.GetBolAreaList().Find(x => x.NotUsingEmpty == area && !new int[] { 4, 6, 10 }.Contains(x.deviceType));
|
//if (bo != null)
|
//{
|
// ///这里空框时翻斗机产生的, 如果瓶盖不需要了,那就都入库去。 瓶盖看工单的, 没开工单不会出库的。
|
// var workOrder = WCSHelper.GetWorkOrder(bo.DeviceName);
|
// if (workOrder != null)
|
// {
|
// if (workOrder.SQL_UsingNow.Trim() != "Y")
|
// {
|
// //瓶盖是非即产的工单。
|
// // 如果有空位,就入了
|
// foreach (var item in loclist.GroupBy(x => x.N_ROW))
|
// {
|
// if (item.ToList().Find(x => x.N_CURRENT_NUM > 0) == null)
|
// {
|
// LogHelper.Info($"{bo.DeviceName} 瓶盖 非即产。线边有空位,不入库");
|
// return;
|
// }
|
// }
|
// LogHelper.Info($"{bo.DeviceName} 瓶盖 非即产。线边没空位了,去入库");
|
// }
|
// }
|
//}
|
|
|
var startBit = loclist.Find(x => x.N_CURRENT_NUM == x.N_CAPACITY);
|
Location endBit = null;
|
int endLayer = 1;
|
if (startBit != null)
|
{
|
// 入库不满排 最晚时间入库的排(先找N排一列。符合机器的。 防止因出库导致的不满排
|
loclist = LocationHelper.GetLocList(x => x.S_AREA_CODE == (areas.deviceType == 6 ? "PGWJCK" : "SGK"));
|
//var oneonelist = loclist.GroupBy(x => x.N_ROW).Select(x => x.ToList().Find(y => y.N_CURRENT_NUM > 0)).ToList();
|
//foreach (var item in oneonelist.OrderByDescending(x => x.T_CREATE).ThenByDescending(x => x.N_ROW))
|
var oneonelist = loclist.OrderByDescending(x => x.T_FULL_TIME).GroupBy(x => x.N_ROW);//.Select(x => x.ToList().Find(y => y.N_CURRENT_NUM > 0)).ToList();
|
LogHelper.Info($"oneonelist非即产空框堆叠位 入库" + oneonelist?.Count());
|
foreach (var itemr in oneonelist)
|
{
|
var item = itemr.ToList().FindAll(x => x.N_CURRENT_NUM > 0).OrderBy(x => x.N_COL).LastOrDefault();
|
if (item == null) continue;
|
LogHelper.Info($"oneonelist非即产空框堆叠位 入库" + JsonConvert.SerializeObject(item));
|
var loccntr = LocationHelper.GetLocCntrRel(item.S_LOC_CODE);
|
if (loccntr.Any() && loccntr.FirstOrDefault()?.S_TYPE == "空框")
|
{
|
//这里就是该机器的最后一次入库列。
|
var rl = loclist.FindAll(x => x.N_ROW == item.N_ROW);
|
if (rl.Find(x => x.S_LOCK_STATE != "无" && x.S_LOCK_STATE != "报废") != null)
|
{
|
break;
|
}
|
var crl = rl.FindAll(x => x.N_CURRENT_NUM > 0).OrderBy(x => x.N_COL).LastOrDefault();
|
if (crl.N_CURRENT_NUM < crl.N_CAPACITY && crl.N_CURRENT_NUM + startBit.N_CURRENT_NUM <= crl.N_CAPACITY)
|
{
|
endBit = crl;
|
break;
|
}
|
var lstE = rl.FindAll(x => x.N_COL > crl.N_COL).OrderBy(x => x.N_COL).FirstOrDefault();
|
if (lstE != null)
|
{
|
endBit = lstE;
|
break;
|
}
|
}
|
}
|
//入空排
|
if (endBit == null)
|
{
|
lockcols = (from x in loclist.FindAll((Location x) => x.N_CURRENT_NUM > 0)
|
select x.N_ROW).Distinct();
|
if (lockcols.Any())
|
{
|
loclist.RemoveAll((Location x) => lockcols.Contains(x.N_ROW));
|
}
|
endBit = loclist.OrderBy(x => x.N_ROW).ThenBy(x => x.N_COL).FirstOrDefault();
|
}
|
}
|
|
if (endBit != null)
|
{
|
var _ctrl = LocationHelper.GetLocCntrRel(startBit.S_LOC_CODE);
|
var carryCntrs = _ctrl.OrderByDescending(x => x.T_CREATE).Select(x => x.S_CNTR_CODE).ToList();//DateTime.Now.ToString("yyMMddHHmmss") };
|
var bb = TaskProcess.CreateTransport("", startBit.S_LOC_CODE, endBit.S_LOC_CODE, "瓶盖空筐转运-J2", carryCntrs, 1, endBit.N_CURRENT_NUM + 1, carryCntrs.Count, 60);
|
continue;
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Error("非即产空框112" + ex.Message, ex);
|
}
|
}
|
|
/// <summary>
|
/// 出非即产瓶盖空框 到 瓶盖线边
|
/// </summary>
|
public static void TakeNotUsing2PGXB()
|
{
|
try
|
{
|
foreach (var plc in Settings.GetDeviceInfoList().FindAll(x => x.enable == 1 && (x.deviceType == 2 || x.deviceType == 3)))
|
{
|
WorkOrder workOrder = WCSHelper.GetWorkOrder(plc.deviceName);
|
if (workOrder == null)
|
continue;
|
var USING = workOrder.SQL_UsingNow?.Trim() == "Y";
|
var bolarea = Settings.GetBolAreaList().Find(x => x.DeviceName == plc.deviceName);
|
if (bolarea == null) continue;
|
if (plc.deviceType == 2)
|
{
|
if (!USING)
|
{
|
LocationHelper.TakeEmpty2PGxb(bolarea, plc, workOrder, "空框", 0);
|
}
|
//else
|
// LocationHelper.TakeEmpty2PGxb(bolarea, plc, workOrder, "空框", 1);
|
}
|
else if (plc.deviceType == 3)
|
{
|
if (!USING)
|
{
|
LocationHelper.TakeEmpty2PGxb(bolarea, plc, workOrder, "空框", 0);
|
}
|
//else
|
// LocationHelper.TakeEmpty2PGxb(bolarea, plc, workOrder, "空框", 1);
|
}
|
else continue;
|
}
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Error("无水出空框" + ex.Message, ex);
|
}
|
}
|
|
/// <summary>
|
/// 非即产满框出翻斗机线边
|
/// </summary>
|
public static void TakeNotUsing2FDJXB()
|
{
|
try
|
{
|
foreach (var plc in Settings.GetDeviceInfoList().FindAll(x => x.enable == 1 && (x.deviceType == 4 || x.deviceType == 6)))
|
{
|
WorkOrder workOrder = WCSHelper.GetWorkOrder(plc.deviceName);
|
if (workOrder == null)
|
continue;
|
var USING = workOrder.SQL_UsingNow?.Trim() == "Y";
|
var bolarea = Settings.GetBolAreaList().Find(x => x.DeviceName == plc.deviceName);
|
if (bolarea == null) continue;
|
if (false)
|
{
|
if (plc.deviceType == 6)
|
{
|
if (!USING)
|
{
|
LocationHelper.WJGTakeFull2FDJXB(bolarea, plc, workOrder);
|
//LocationHelper.TakeEmpty2PGxb(bolarea, plc, workOrder, plc.deviceName, 0);
|
}
|
//else
|
// LocationHelper.TakeEmpty2PGxb(bolarea, plc, workOrder, plc.deviceName, 1);
|
}
|
else if (plc.deviceType == 4)
|
{
|
if (!USING)
|
LocationHelper.SGTakeFull2FDJXB(bolarea, plc, workOrder);
|
//if (!USING)
|
//{
|
// LocationHelper.TakeEmpty2PGxb(bolarea, plc, workOrder, plc.deviceName, 0);
|
//}
|
//else
|
// LocationHelper.TakeEmpty2PGxb(bolarea, plc, workOrder, plc.deviceName, 1);
|
}
|
}
|
else
|
{
|
bool water = plc.deviceType == 4;
|
///领料查询 - - 查看是否有领料
|
///1 有领料。 走领料
|
///2.没有领料- 直接出
|
WorkOrder order = workOrder;
|
LingItemOrder od = null;
|
if (TaskProcess.UPFule)
|
{
|
var dvi = plc;
|
|
LocationHelper.DoAction(db =>
|
{
|
od = db.Queryable<LingItemOrder>().Where(it => dvi.FuLeLineNo.Contains(it.DeviceNo) && it.State == "执行").First();
|
return true;
|
});
|
if (order?.FromFuLe == "Y")
|
{
|
if (od == null)
|
{
|
LogHelper.Info((water ? "水盖" : "无菌") + "翻斗机;富勒工单,无领料单或 领料单已经完成,不出库。");
|
return;
|
}
|
}
|
else
|
{
|
if (od != null)
|
{
|
LogHelper.Info((water ? "水盖" : "无菌") + "翻斗机;非富勒工单,但是有未完成领料单,无法识别出库。");
|
return;
|
}
|
}
|
//至此。 有领料走领料出。 没领料走普通出
|
}
|
|
LogHelper.Info((water ? "水盖" : "无菌") + "出库开始。" + order.FromFuLe);
|
|
LocationHelper.WJGTakeFull2FDJXB(bolarea, plc, workOrder, od);
|
}
|
//else continue;
|
}
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Error("无水出满框" + ex.Message, ex);
|
}
|
}
|
|
/// <summary>
|
/// 非即产瓶盖 入库
|
/// </summary>
|
public static void TakeNotUsing2WH()
|
{
|
TakeNotUsing2WH2();
|
}
|
/// <summary>
|
/// 非即产入库。
|
/// 有入库任务就等完成
|
/// 如果链接的翻斗机开着,且非即产工单,且线边有至少一个空位都不入了。
|
/// 否则,就循环入库。
|
/// </summary>
|
/// <returns></returns>
|
public static bool TakeNotUsing2WH2()
|
{
|
var result = false;
|
var plcl = Settings.GetDeviceInfoList().FindAll(x => x.deviceType == 2 || x.deviceType == 3);
|
|
foreach (var plc in plcl)
|
{
|
//LogHelper.Info($"{plc.deviceName}--入库");
|
var workOrder = WCSHelper.GetWorkOrder(plc.deviceName);
|
//if (workOrder == null) {
|
|
// continue;
|
//}
|
var ba = Settings.GetBolAreaList().Find(x => x.DeviceName == plc.deviceName && x.deviceType == plc.deviceType);
|
if (ba == null)
|
{
|
LogHelper.Info($"{plc.deviceName}-的 BolArea 未配置。");
|
continue;
|
}
|
LogHelper.Info($"{plc.deviceName}--入库" + ba.NotUsingBolArea);
|
var loclist = LocationHelper.GetAreaNormalLocList(ba.NotUsingBolArea, false);
|
|
/// 这里是 合并 出入区域的流程。
|
//if (loclist.Find(x => x.N_CURRENT_NUM == x.N_CAPACITY && x.S_LOCK_STATE == "出库锁") != null)
|
// continue;
|
|
//LogHelper.Info($"{plc.deviceName}--{ba.NotUsingBolArea}入库处理,查看翻斗机状态,如果翻斗机是非即产的,且线边有空位,就不入库。");
|
//{
|
// var bo = Settings.GetBolAreaList().Find(x => x.NotUsingEmpty == ba.NotUsingEmpty && new int[] { 4, 6, 10 }.Contains(x.deviceType));
|
// if (bo != null) /// 如果翻斗机没开 。 那就都入库去吧。
|
// {
|
// ///查看链接的翻斗机。
|
// var Forder = WCSHelper.GetWorkOrder(bo.DeviceName);
|
// if (Forder != null && Forder.SQL_UsingNow.Trim() != "Y")
|
// {
|
// //翻斗机是非即产的工单。
|
// // 如果有空位,就入了
|
// foreach (var item in loclist.GroupBy(x => x.N_ROW))
|
// {
|
// if (item.ToList().Find(x => x.N_CURRENT_NUM > 0) == null)
|
// {
|
// LogHelper.Info($"{plc.deviceName} 链接的{bo.DeviceName} 翻斗机 非即产。线边有空位,不入库");
|
// return false;
|
// }
|
// }
|
// LogHelper.Info($"{plc.deviceName} 链接的{bo.DeviceName} 翻斗机 非即产。线边没空位了,去入库");
|
// }
|
|
// }
|
//}
|
|
IEnumerable<int> lockcols = (from x in loclist.FindAll((Location x) => x.S_LOCK_STATE.Trim() != "无" && x.S_LOCK_STATE.Trim() != "报废")
|
select x.N_ROW).Distinct();
|
if (lockcols.Any())
|
{
|
loclist.RemoveAll((Location x) => lockcols.Contains(x.N_ROW));
|
}
|
var startBit = loclist.Find(x => x.N_CURRENT_NUM == x.N_CAPACITY);
|
Location endBit = null;
|
int endLayer = 1;
|
var brekkkkk = false;//需要中断
|
if (startBit != null)
|
{
|
// 入库不满排 最晚时间入库的排(先找N排一列。符合机器的。 防止因出库导致的不满排
|
loclist = LocationHelper.GetLocList(x => x.S_AREA_CODE == (plc.deviceType == 2 ? "PGWJCK" : "SGK"));
|
var oneonelist = loclist.OrderByDescending(x => x.T_FULL_TIME).GroupBy(x => x.N_ROW);//.Select(x => x.ToList().Find(y => y.N_CURRENT_NUM > 0)).ToList();
|
LogHelper.Info($"非即产入库 。" + oneonelist?.Count());
|
foreach (var itemr in oneonelist)
|
{
|
var item = itemr.ToList().FindAll(x => x.N_CURRENT_NUM > 0).OrderBy(x => x.N_COL).LastOrDefault();
|
if (item == null) continue;
|
LogHelper.Info($"查看PGWJCK 有满框的排" + JsonConvert.SerializeObject(item));
|
var loccntr = LocationHelper.GetLocCntrRel(item.S_LOC_CODE);
|
if (loccntr.Any() && loccntr.FirstOrDefault().S_TYPE.Contains(plc.deviceName))
|
{
|
//这里就是该机器的最后一次入库列。
|
var rl = loclist.FindAll(x => x.N_ROW == itemr.Key);
|
if (rl.Find(x => x.S_LOCK_STATE != "无" && x.S_LOCK_STATE != "报废") != null)
|
{
|
brekkkkk = true;
|
break;
|
}
|
var crl = rl.FindAll(x => x.N_CURRENT_NUM > 0).OrderBy(x => x.N_COL).LastOrDefault();
|
if (crl.N_CURRENT_NUM < crl.N_CAPACITY && crl.N_CURRENT_NUM + startBit.N_CURRENT_NUM <= crl.N_CAPACITY)
|
{
|
endBit = crl;
|
break;
|
}
|
var lstE = rl.FindAll(x => x.N_COL > crl.N_COL).OrderBy(x => x.N_COL).FirstOrDefault();
|
if (lstE != null)
|
{
|
endBit = lstE;
|
break;
|
}
|
}
|
}
|
|
//入空排
|
if (endBit == null && !brekkkkk)
|
{
|
lockcols = (from x in loclist.FindAll((Location x) => x.N_CURRENT_NUM > 0)
|
select x.N_ROW).Distinct();
|
if (lockcols.Any())
|
{
|
loclist.RemoveAll((Location x) => lockcols.Contains(x.N_ROW));
|
}
|
endBit = loclist.OrderBy(x => x.N_ROW).ThenBy(x => x.N_COL).FirstOrDefault();
|
}
|
}
|
else
|
{
|
//LogHelper.Info($"T2WH2-1");//{ba.NotUsingBolArea}满框位,没有可以入库的满框。
|
continue;
|
}
|
|
if (brekkkkk)
|
{
|
//LogHelper.Info($" {ba.NotUsingBolArea} 最后一次仓库入库排,正在任务中。 等待。");
|
continue;
|
}
|
|
if (endBit != null)
|
{
|
var _ctrl = LocationHelper.GetLocCntrRel(startBit.S_LOC_CODE);
|
var carryCntrs = _ctrl.OrderByDescending(x => x.T_CREATE).Select(x => x.S_CNTR_CODE).ToList();//DateTime.Now.ToString("yyMMddHHmmss") };
|
var bb = TaskProcess.CreateTransport(workOrder?.SQL_WorkNo, startBit.S_LOC_CODE, endBit.S_LOC_CODE, "瓶盖入库-J2", carryCntrs, 1, endBit.N_CURRENT_NUM + 1, carryCntrs.Count, plc.taskPri);
|
|
result = bb;
|
continue;
|
}
|
|
}
|
return result;
|
}
|
|
/// <summary>
|
/// 瓶坯机11(设备1) 21(设备2)
|
/// </summary>
|
/// <param name="data"></param>
|
/// <param name="plc"></param>
|
|
internal static void AnalysisBottlePEM(string data, Settings.deviceInfo plc)
|
{
|
//LogHelper.Info($"{plc.deviceName}-{plc.address}-{data}");
|
/*
|
状态1 满托产生,需要取满送空,从满托产生到满托取走一直维持状态1
|
状态2 送空完成之后为状态2
|
状态3 满托取走,送空之前为状态3,开机默认状态也为状态3
|
*/
|
|
if (data.Length == 4)
|
{
|
if (data.Substring(1, 1) == "1")
|
{
|
if (BottlePEMInfoFull(plc, plc.location[0]))
|
{
|
//设备没有托盘,或者已经有任务,不处理满托信号,返回已经取货完成
|
//3F 00 11 0d 0a
|
//PlcHelper.SendHex(plc.address, "3F00110d0a");
|
}
|
}
|
//else if (data.Substring(1, 1) == "3")
|
//{
|
// if (BottleCapInfoEmpty(plc, plc.location[0]))
|
// {
|
// PlcHelper.SendHex(plc.address, "3F00120d0a");
|
// }
|
//}
|
|
if (data.Substring(3, 1) == "1")
|
{
|
if (BottlePEMInfoFull(plc, plc.location[1]))
|
{
|
//PlcHelper.SendHex(plc.address, "3F00210d0a");
|
}
|
}
|
//else if (data.Substring(3, 1) == "3")
|
//{
|
// if (BottleCapInfoEmpty(plc, plc.location[1]))
|
// {
|
// PlcHelper.SendHex(plc.address, "3F00220d0a");
|
// }
|
//}
|
|
//信号出错
|
//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");
|
// }
|
//}
|
}
|
}
|
|
public static bool Analysis5501 = false;
|
public static bool Analysis5L = false;
|
|
internal static void Analysis505(string data, Settings.deviceInfo plc)
|
{
|
/*
|
状态1 满托产生,需要取满送空,从满托产生到满托取走一直维持状态1
|
状态2 送空完成之后为状态2
|
状态3 满托取走,送空之前为状态3,开机默认状态也为状态3
|
*/
|
//LogHelper.Info("成品满框下线信号" + $"{plc.deviceName}-{plc.address}-{data}");
|
var add = false;
|
if (doorStatus.ContainsKey(plc.location[0]))
|
{
|
var lat = doorStatus[plc.location[0]].info;
|
if (lat != data.Substring(1, 1) && data.Substring(1, 1) == "1")
|
add = true;
|
doorStatus[plc.location[0]].info = data.Substring(1, 1);
|
doorStatus[plc.location[0]].modify = DateTime.Now;
|
}
|
else
|
{
|
doorStatus.Add(plc.location[0], new signalInfo
|
{
|
info = data.Substring(1, 1),
|
modify = DateTime.Now
|
});
|
if (data.Substring(1, 1) == "1")
|
add = true;
|
}
|
if (add)
|
{
|
LogHelper.Info($@"{plc.deviceName}新到位信号。 执行YWL工单信号量增加1");
|
var ods = LocationHelper.GetList<YWLWorkOrder>(x => x.SQL_State == "执行中" && x.WorkType == 6 && x.SQL_LinkLineNO == plc.deviceName);//.FirstOrDefault();
|
if (ods.Any())
|
{
|
LogHelper.Info($@"{plc.deviceName}新到位信号,找到工单{JsonConvert.SerializeObject(ods.Select(x => new
|
{
|
x.SQL_PLineNo,
|
x.SQL_LinkLineNO,
|
x.SQL_Total,
|
x.OutNum
|
}))}");
|
|
foreach (var od in ods)
|
{
|
od.SQL_Total += 1;
|
WCSHelper.Do(db => db.Updateable(od).UpdateColumns(x => new { x.SQL_Total }).ExecuteCommand());
|
}
|
}
|
}
|
|
if (data.Length == 4)
|
{
|
if (data.Substring(1, 1) == "1" && !Analysis5501)// 满框下线
|
{
|
//Analysis5501 = true;
|
LogHelper.Info(plc.deviceName + "成品满框下线开始");
|
var A = Analysis505(plc, 0);
|
LogHelper.Info(plc.deviceName + "成品满框下线结束");
|
//Analysis5501 = false;
|
}
|
|
if (data.Substring(3, 1) == "1")//空框上线
|
{
|
if (Analysis505(plc, 1))
|
{
|
//PlcHelper.SendHex(plc.address, "3F00210d0a");
|
}
|
}
|
else // 到位后 删掉数据。 这是生产线, 变了说明现场识别到了筐。 机可以删掉了
|
{
|
//清溪逻辑流程开发
|
var loc = LocationHelper.GetLoc(plc.location[1]);
|
if (loc?.N_CURRENT_NUM > 0)
|
{
|
LogHelper.Info(plc.deviceName + "成品空框2信号 ,重置货位数据");
|
|
LocationHelper.lOCReSetValue(x => x.S_LOC_CODE == plc.location[1].Trim(), x =>
|
{
|
x.T_FULL_TIME = null;
|
x.N_CURRENT_NUM = 0;
|
});
|
}
|
}
|
}
|
|
else if (data.Length == 6)
|
{
|
if (data.Substring(1, 1) == "1" && !Analysis5L)// 满框下线
|
{
|
//Analysis5L = true;
|
LogHelper.Info(plc.deviceName + "成品满框下线开始");
|
var A = Analysis505(plc, 0);
|
LogHelper.Info(plc.deviceName + "成品满框下线结束");
|
//Analysis5L = false;
|
}
|
|
if (data.Substring(3, 1) == "1")//空框上线
|
{
|
if (Analysis505(plc, 1))
|
{
|
//PlcHelper.SendHex(plc.address, "3F00210d0a");
|
}
|
}
|
|
else // 到位后 删掉数据。 这是生产线, 变了说明现场识别到了筐。 机可以删掉了
|
{
|
//清溪逻辑流程开发
|
var loc = LocationHelper.GetLoc(plc.location[1]);
|
if (loc.N_CURRENT_NUM > 0)
|
{
|
LogHelper.Info(plc.deviceName + "成品空框2信号 ,重置货位数据");
|
|
LocationHelper.lOCReSetValue(x => x.S_LOC_CODE == plc.location[1].Trim(), x =>
|
{
|
x.T_FULL_TIME = null;
|
x.N_CURRENT_NUM = 0;
|
});
|
}
|
}
|
|
if (data.Substring(5, 1) == "1")//套版上线 // 4L.
|
{
|
if (Analysis505(plc, 2, "超托板/套板"))
|
{
|
//PlcHelper.SendHex(plc.address, "3F00210d0a");
|
}
|
}
|
else // 到位后 删掉数据。 这是生产线, 变了说明现场识别到了筐。 机可以删掉了
|
{
|
//清溪逻辑流程开发
|
var loc = LocationHelper.GetLoc(plc.location[2]);
|
if (loc.N_CURRENT_NUM > 0)
|
{
|
LogHelper.Info("成品套版2信号 ,重置货位数据");
|
|
LocationHelper.lOCReSetValue(x => x.S_LOC_CODE == plc.location[2].Trim(), x =>
|
{
|
x.T_FULL_TIME = null;
|
x.N_CURRENT_NUM = 0;
|
});
|
}
|
}
|
}
|
}
|
|
internal static void Analysis11(string data, Settings.deviceInfo plc)
|
{
|
LogHelper.Info("一楼搬2楼信号" + $"{plc.deviceName}-{plc.address}-{data}");
|
if (data.Length == 4)
|
{
|
if (data[1] == 1 || data[3] == 1)
|
{
|
var location = LocationHelper.GetLoc(plc.location[0]);
|
if (location == null)
|
{
|
LogHelper.Info(plc.deviceName + "的货位数据不存在!");
|
return;
|
}
|
if (location.S_LOCK_STATE != "无")
|
return;
|
if (data.Substring(1, 1) == "1")
|
{
|
if (location.N_CURRENT_NUM == 1)
|
{
|
PlcHelper.SendHex(plc.address, "3F00100D0A");
|
}
|
|
}
|
if (data.Substring(3, 1) == "1")
|
{
|
if (location.N_CURRENT_NUM == 0)
|
{
|
PlcHelper.SendHex(plc.address, "3F00200D0A");
|
}
|
}
|
}
|
}
|
}
|
|
|
//瓶坯满入库
|
static bool BottlePEMInfoFull(Settings.deviceInfo plc, string location)
|
{
|
var result = false;
|
if (location != "")
|
{
|
var workOrder = WCSHelper.GetWorkOrder(plc.deviceName);
|
if (workOrder == null)
|
{
|
LogHelper.Info(plc.deviceName + "没有【执行中】的工单");
|
return false;
|
}
|
|
//Console.WriteLine($"瓶盖机:{plc.deviceName} 下线信号:{location}");
|
//判断上次卸货完成时间,如果5分钟内,不处理请求,可能是设备请求还没有重置
|
|
// 同机器走一排。 两个位置一个一个来。 都没有锁才行。
|
string p0 = LocationHelper.CheckLocState(location).Trim(); // LocationHelper.CheckLocState(plc.location[0]);
|
string p1 = ""; // LocationHelper.CheckLocState(plc.location[1]);
|
if (plc.location[0] == location)
|
p1 = plc.location[1];
|
else
|
p1 = plc.location[0];
|
string p1s = LocationHelper.CheckLocState(p1);
|
if (p0 == "无")//&& (p1s == "无" || p1s == "入库锁"))
|
{
|
var time = LocationHelper.GetT_FULL_TIME(location);
|
var _loc = LocationHelper.GetLoc(location);
|
LogHelper.Info(location + ":托盘放置时间:(" + time + ") 货位托盘数量(" + _loc.N_CURRENT_NUM + ")");
|
if (time == null || _loc == null || _loc.N_CURRENT_NUM == 0)
|
{
|
// TODO - 送空框任务。
|
LocationHelper.TakeEmptyToBottleBoyd(new WMSTask
|
{
|
S_START_LOC = location,
|
});
|
return true;
|
}
|
//托盘放下 1分钟内 取货请求,都不处理。
|
else if (DateTime.Now.Subtract(time ?? DateTime.Now).TotalMinutes < 1)
|
{
|
for (var i = 0; i < plc.location.Length; i++)
|
{
|
if (location == plc.location[i])
|
{
|
PlcHelper.SendHex(plc.address, "3F00" + (i + 1) + "0" + "0d0a");
|
break;
|
}
|
}
|
return false;
|
}
|
|
LogHelper.Info($"PEM机:{plc.deviceName} 下线信号:{location} 查询工单", "PEM机");
|
//var workOrder = WCSHelper.GetWorkOrder(plc.deviceName);
|
if (workOrder != null)
|
{
|
LogHelper.Info($"查到了工单{workOrder.SQL_WorkNo}", "PEM机");
|
//var cntrStart = LocationHelper.GetLocCntr(location);
|
//取满,需要中间表查询,当前工位的容器是铁框还是塑料框
|
//判断是无菌盖还是水盖
|
if (true)
|
{
|
LogHelper.Info($"查找{location}对应终点->", "PEM机");
|
|
//var locationType = plc.deviceType == 2 ? 2 : 5;
|
//var endBit = Settings.GetInStockCacheList().Where(a => a.deviceName == plc.deviceName && a.locationType == locationType).FirstOrDefault();
|
Location endBit = null;
|
List<Location> _l = new List<Location>();
|
|
var SQL_ItemCode = workOrder.SQL_ItemCode;
|
var _ctrl = LocationHelper.GetLocCntrRel(location);
|
if (_ctrl.FirstOrDefault().S_CNTR_CODE.Contains("J"))
|
{
|
_l = LocationHelper.GetLocList(x => x.S_AREA_CODE == workOrder.SQL_Area && x.S_LOCK_STATE != "报废");
|
#region 直接去终点
|
//var loc_list_PEM = _l.FindAll(x => x.S_LOCK_STATE == "无" && x.N_CURRENT_NUM == 0).ToList();
|
//LogHelper.Info("即产空货位数量:" + loc_list_PEM.Count);
|
//if (loc_list_PEM.Count == 0)
|
//{
|
// LogHelper.Info($"查找{location}对应终点(库区没有货位了。)", "PEM机");
|
// return false;
|
//}
|
//var local_ = loc_list_PEM.FirstOrDefault();
|
//LogHelper.Info($"{local_.N_ROW}-{local_.N_COL}");
|
//// 所有排的 第一列 有值且不是这个机器的。 就remove整排
|
////if(local_.N_CURRENT_NUM==0)
|
//endBit = local_;
|
var _arealock = _l.FindAll(x => x.S_LOCK_STATE != "无").Select(x => x.N_ROW).Distinct();
|
if (_arealock.Any()) _l.RemoveAll(x => _arealock.Contains(x.N_ROW));
|
foreach (var itemrs in _l.OrderByDescending(x => x.N_CURRENT_NUM).GroupBy(x => x.N_ROW))
|
{
|
var _r = itemrs.ToList();
|
var f = _r.FindAll(x => x.N_CURRENT_NUM > 0).OrderBy(x => x.N_COL).LastOrDefault();
|
if (f != null)
|
{
|
var rel = LocationHelper.GetLocCntrRel(f.S_LOC_CODE);
|
if (rel.FirstOrDefault()?.S_TYPE != $"{workOrder.SQL_PLineNo}>{SQL_ItemCode}")
|
{
|
LogHelper.Info($"{f.S_LOC_CODE} 位置的 物料{rel.FirstOrDefault()?.S_TYPE} 与本次下线{workOrder.SQL_PLineNo}>{SQL_ItemCode} 不符。 筛选下一排");
|
continue;
|
}
|
if (f.N_CURRENT_NUM < f.N_CAPACITY)
|
{
|
endBit = f;
|
}
|
else endBit = _r.FindAll(x => x.N_COL > (f?.N_COL ?? 0)).OrderBy(x => x.N_COL).FirstOrDefault();
|
}
|
else
|
{
|
endBit = _r.OrderBy(x => x.N_COL).FirstOrDefault();
|
}
|
if (endBit != null)
|
break;
|
}
|
|
#endregion
|
}
|
else if (!string.IsNullOrEmpty("2024年7月3日 变更 2排专供一个机器. 暂不更新.加了!非"))
|
{
|
if (false)
|
{
|
if (SQL_ItemCode.Contains("5L"))
|
{
|
//_l = LocationHelper.GetAllLocListByAreaCode("PPMKRK", 3, 4);
|
_l = LocationHelper.GetLocList(x => x.S_AREA_CODE == "PPMKRK" && new int[] { 3, 4, 7, 8 }.Contains(x.N_ROW));
|
}
|
else
|
//_l = LocationHelper.GetAllLocListByAreaCode("PPMKRK", 1, 2);
|
_l = LocationHelper.GetLocList(x => x.S_AREA_CODE == "PPMKRK" && new int[] { 1, 2, 5, 6 }.Contains(x.N_ROW));
|
}
|
|
LogHelper.Info($"{plc.deviceName} 注塑机下线 目标库区排{workOrder.S_ROW1} .");
|
if (string.IsNullOrEmpty(workOrder.S_ROW1))
|
{
|
return false;
|
}
|
else
|
{
|
|
//_l = LocationHelper.GetLocList(x => x.S_AREA_CODE == rs[0] && rows.Contains(x.N_ROW) && x.S_LOCK_STATE != "报废");
|
|
if (false)
|
{
|
_l = LocationHelper.GetAreaNormalLocList("");//rs[0]).FindAll(x => rows.Contains(x.N_ROW)).OrderBy(x => x.N_COL).ThenBy(x => x.N_ROW).ToList();
|
var _lful = _l.FindLastIndex(x => x.N_CURRENT_NUM > 0);
|
Location _lsf = null;//
|
if (_lful > -1)
|
_lsf = _l[_lful];
|
|
LogHelper.Info($"{plc.deviceName}筛选到 可用排{JsonConvert.SerializeObject(_l.Select(x => x.N_ROW).Distinct())} 货位编码{_lsf?.S_LOC_CODE} 所在索引{_lful}");
|
int li____ = 0;
|
foreach (var item in _l.Skip(_lful))
|
{
|
if (li____ == 0)
|
{
|
LogHelper.Info($@"入库筛选,第一个位置是{JsonConvert.SerializeObject(new
|
{
|
item.S_LOC_CODE,
|
item.N_CURRENT_NUM,
|
item.S_LOCK_STATE
|
})}");
|
li____++;
|
}
|
if (item.N_CURRENT_NUM < item.N_CAPACITY)
|
{
|
var rel = LocationHelper.GetLocCntrRel(item.S_LOC_CODE);
|
if (rel.Any())
|
{
|
if (rel.FirstOrDefault()?.S_TYPE != $"{workOrder.SQL_PLineNo}>{SQL_ItemCode}")
|
{
|
LogHelper.Info($"{item.S_LOC_CODE} 位置的 物料{rel.FirstOrDefault()?.S_TYPE} 与本次下线{workOrder.SQL_PLineNo}>{SQL_ItemCode} 不符。 筛选下一排");
|
continue;
|
}
|
}
|
endBit = item;
|
}
|
if (endBit != null) break;
|
}
|
}
|
|
if (true)
|
{
|
var nextArea = "";
|
var areaRows = workOrder.S_ROW1.Split('$');
|
//foreach (var item2 in areaRows)
|
//{
|
var item2 = areaRows.First();
|
var rs = item2.Split('=');
|
bool wait = true;// 如果给的2排并没满,这时候切不合适,等满了再切
|
var rows = Array.ConvertAll(rs[rs.Length - 1].Trim().Split('-'), Convert.ToInt32).Reverse();
|
if (string.IsNullOrEmpty(nextArea))
|
nextArea = rs[0];
|
_l = LocationHelper.GetAreaNormalLocList(rs[0]);
|
|
var rowlist = LocationHelper.GetRowLock(rs[0]);
|
LogHelper.Info($"{location}满框下线 {rs[0]}库区, rowlist:{rowlist.Count}");
|
foreach (var itemrs in _l.FindAll(x => rows.Take(2).Contains(x.N_ROW)).GroupBy(x => x.N_ROW).OrderBy(x => x.Count(y => y.N_CURRENT_NUM > 0)).ThenBy(x => x.Key))
|
{
|
var tnotnull = rowlist.Find(x => x.S_LOCK_STATE == "出库锁" && x.N_ROW == itemrs.Key);
|
if (tnotnull != null) continue;
|
|
var _r = itemrs.ToList();
|
var f = _r.FindAll(x => x.N_CURRENT_NUM > 0).OrderBy(x => x.N_COL).LastOrDefault();
|
if (f != null)
|
{
|
var rel = LocationHelper.GetLocCntrRel(f.S_LOC_CODE);
|
if (rel.FirstOrDefault()?.S_TYPE != $"{workOrder.SQL_PLineNo}>{SQL_ItemCode}")
|
{
|
LogHelper.Info($"{f.S_LOC_CODE} 位置的 物料{rel.FirstOrDefault()?.S_TYPE} 与本次下线{workOrder.SQL_PLineNo}>{SQL_ItemCode} 不符。 筛选下一排");
|
continue;
|
}
|
if (f.N_CURRENT_NUM < f.N_CAPACITY)
|
{
|
endBit = f;
|
}
|
else endBit = _r.FindAll(x => x.N_COL > (f?.N_COL ?? 0)).OrderBy(x => x.N_COL).FirstOrDefault();
|
}
|
else
|
{
|
endBit = _r.OrderBy(x => x.N_COL).FirstOrDefault();
|
}
|
if (endBit != null)
|
goto vvvvvv;
|
}
|
if (endBit == null && wait)
|
{
|
_l = LocationHelper.GetList<Location>(x => x.S_AREA_CODE == nextArea && x.S_LOCK_STATE != "报废");
|
|
if (wait)
|
{
|
//如果之前的 还有空位,那就不切了。
|
var _ll = _l.FindAll(x => rows.Take(2).Contains(x.N_ROW));
|
if (_ll.Find(x => x.N_CURRENT_NUM == 0) != null)
|
goto vvvvvv;
|
}
|
|
var rowtuplist = SequentialGrouping(_l.Select(x => x.N_ROW).Max());
|
foreach (var group in rowtuplist)
|
{
|
var gn = _l.FindAll(x => x.N_ROW == group.Item1 || x.N_ROW == group.Item2);
|
if (gn.Find(x => x.S_LOCK_STATE != "无" || x.N_CURRENT_NUM != 0) != null) //不是空排或有锁 ,歇。 下一个。
|
continue;
|
|
endBit = gn.FindAll(x => x.N_ROW == group.Item1).OrderBy(x => x.N_COL).FirstOrDefault();
|
if (endBit != null)
|
{
|
var v1 = new List<int>();// rows.Where(x => x != group.Item1 && x != group.Item2).ToList();
|
v1.Add(group.Item1);
|
v1.Add(group.Item2);
|
workOrder.S_ROW1 = nextArea + "=" + (string.Join("-", v1));
|
new SqlHelper<object>().GetInstance().Updateable<WorkOrder>(workOrder).UpdateColumns(x => new { x.S_ROW1 }).ExecuteCommand();
|
goto vvvvvv;
|
}
|
}
|
}
|
}
|
|
goto vvvvvv;
|
}
|
|
#region vvv
|
|
//_l = LocationHelper.GetLocList(x => x.S_AREA_CODE == "PPMKRK" && x.S_LOCK_STATE != "报废");
|
|
//List<int> lockcols = new List<int>(); ;// = (from x in _l.FindAll((Location x) => x.S_LOCK_STATE.Trim() != "无" && x.S_LOCK_STATE.Trim() != "报废")
|
/// select x.N_ROW).Distinct();
|
//int MaxRow = 0;
|
//foreach (var item in _l.GroupBy(x => x.N_ROW))
|
//{
|
// if (MaxRow < item.Key) MaxRow = item.Key;
|
// if (item.ToList().Find(x => x.S_LOCK_STATE.Trim() != "无") != null)
|
// lockcols.Add(item.Key);
|
//}
|
//if (lockcols.Any())
|
//{
|
// _l.RemoveAll((Location x) => lockcols.Contains(x.N_ROW));
|
//}
|
//1 是否存在 n 与 n+1 排都空且入库的情况, 如果存在,无法确认物料。 就等待
|
//var twoEmptyandLockin = false;
|
//foreach (var r in _l.FindAll(x => x.S_LOCK_STATE.Trim() == "入库锁").Select(x => x.N_ROW).Distinct())
|
//{
|
// var _r = _l.FindAll(x => x.N_ROW == r);
|
// var _radd1 = _l.FindAll(x => x.N_ROW == ((r % 2 == 1) ? (r + 1) : (r - 1)));
|
|
|
|
// if (_r.Find(x => x.N_CURRENT_NUM > 0) == null && _radd1.Find(x => x.N_CURRENT_NUM > 0) == null)
|
// {
|
// LogHelper.Info($"{r}排和 乡邻组排,是双空排,且有入库,因无法确认物料,故此等待其完成后,再执行入库。");
|
// //var _lockloc = _r.Find(x => x.S_LOCK_STATE == "入库锁");
|
// //LocationHelper.DoAction(db =>
|
// //{
|
// // var task = db.Queryable<WMSTask>().Where(x => x.S_END_LOC.Trim() == _lockloc.S_LOC_CODE && "未执行,已推送,执行中,开始取货,取货完成,开始卸货".Contains(x.S_B_STATE)).First();
|
// // LogHelper.Info(location + "起点(工单N_LimitNum:" + mmmmmnum + ")的运行中任务数量" + tasks.Count);
|
// // //foreach (var task in tasks)
|
// // {
|
// // var _tloc = LocationHelper.GetLoc(task.S_END_LOC);
|
// // LogHelper.Info(location + $"起点的运行中任务{task.S_TASK_NO}-{task.S_END_LOC}{_tloc.S_LOCK_STATE}");
|
// // if (_tloc != null && _tloc.S_LOCK_STATE == "入库锁")
|
// // {
|
// // string si = _tloc.S_AREA_CODE + "_" + _tloc.N_ROW;
|
// // if (!AlTask.Contains(si)) { AlTask.Add(si); }
|
// // }
|
// // }
|
// // LogHelper.Info($"{workOrder.FuLe_PLine_No}{workOrder.SQL_PLineNo}成品任务中锁排{JsonConvert.SerializeObject(AlTask)}");
|
// // return true;
|
// //});
|
// twoEmptyandLockin = true;
|
// }
|
//}
|
//if (twoEmptyandLockin)
|
//{
|
// return false;
|
//}
|
if (false)
|
{
|
var rowlist = _l.OrderByDescending(x => x.N_CURRENT_NUM).Select(x => x.N_ROW);
|
|
List<int> rl = new List<int>();
|
foreach (var r in rowlist)
|
{
|
if (rl.Contains(r)) continue;
|
//if (r % 2 == 1)
|
{
|
var _r = _l.FindAll(x => x.N_ROW == r);
|
var r22 = ((r % 2 == 1) ? (r + 1) : (r - 1));
|
var _radd1 = _l.FindAll(x => x.N_ROW == r22);
|
rl.Add(r);
|
rl.Add(r22);
|
var f1 = _r.FindAll(x => x.N_CURRENT_NUM > 0).OrderBy(x => x.N_COL).LastOrDefault();
|
var f2 = _radd1.FindAll(x => x.N_CURRENT_NUM > 0).OrderBy(x => x.N_COL).LastOrDefault();
|
if (f1 != null || f2 != null)
|
{
|
var f = f1 != null ? f1 : f2;
|
var rel = LocationHelper.GetLocCntrRel(f.S_LOC_CODE);
|
if (rel.FirstOrDefault()?.S_TYPE != $"{workOrder.SQL_PLineNo}>{SQL_ItemCode}")
|
{
|
LogHelper.Info($"{f.S_LOC_CODE} 位置的 物料{rel.FirstOrDefault()?.S_TYPE} 与本次下线{workOrder.SQL_PLineNo}>{SQL_ItemCode} 不符。 筛选下一排");
|
continue;
|
}
|
else
|
{
|
var lockkk = false;
|
if (_r.Find(x => x.S_LOCK_STATE.Trim() != "无") == null)
|
{
|
LogHelper.Info($"{plc.deviceName} PPMKRK {r}排无锁 分析中...");
|
//if (f1 != null)
|
if (f1 != null && f1.N_CURRENT_NUM < f1.N_CAPACITY)
|
{
|
endBit = f1;
|
}
|
else endBit = _r.FindAll(x => x.N_COL > (f1?.N_COL ?? 0)).OrderBy(x => x.N_COL).FirstOrDefault();
|
}
|
else lockkk = true;
|
if (endBit == null)
|
{
|
if (_radd1.Find(x => x.S_LOCK_STATE.Trim() != "无") == null)
|
{
|
LogHelper.Info($"{plc.deviceName} PPMKRK {r22}排无锁 分析中...");
|
//if (f2 != null)
|
if (f2 != null && f2.N_CURRENT_NUM < f2.N_CAPACITY)
|
{
|
endBit = f2;
|
}
|
else endBit = _radd1.FindAll(x => x.N_COL > (f2?.N_COL ?? 0)).OrderBy(x => x.N_COL).FirstOrDefault();
|
}
|
else lockkk = true;
|
}
|
if (endBit == null)
|
{
|
if (lockkk)
|
{
|
LogHelper.Info($"{plc.deviceName} 将要下在{r}排或者{r + 1}排。 但是现在排有锁。 等待...");
|
return false;
|
}
|
LogHelper.Info($"{plc.deviceName} 的 {r}排或者{r + 1}排。都没位置了, 找其他空排了");
|
}
|
}
|
}
|
else if (_r.Find(x => x.S_LOCK_STATE.Trim() == "入库锁") != null || _radd1.Find(x => x.S_LOCK_STATE.Trim() == "入库锁") != null)
|
{
|
//看一下这个这任务的起点是不是当前机器的另一个口。如果不是,那就continue;
|
//否则,就下在没任务的那一排。
|
var locklocs = new List<Location>()
|
{
|
_r.Find(x => x.S_LOCK_STATE == "入库锁"),
|
_radd1.Find(x => x.S_LOCK_STATE == "入库锁")
|
}.Where(x => x != null);
|
bool Errcnil = false;
|
bool SameandNotEnd = false;
|
LocationHelper.DoAction(db =>
|
{
|
foreach (var _lockloc in locklocs)
|
{
|
if (_lockloc == null) continue;
|
var task = db.Queryable<WMSTask>().Where(x => x.S_END_LOC.Trim() == _lockloc.S_LOC_CODE && "未执行,已推送,执行中,开始取货,取货完成,开始卸货".Contains(x.S_B_STATE)).First();
|
LogHelper.Info($"空排锁点{_lockloc.S_LOC_CODE}, 的所在任务为{task?.S_TASK_NO} 如果没找到,则异常锁");
|
if (task == null)
|
{
|
Errcnil = true;
|
continue;
|
}
|
|
if (plc.location.Contains(task.S_START_LOC.Trim()))
|
{
|
if (locklocs.Count() == 2)
|
{
|
SameandNotEnd = true;
|
break;
|
}
|
else
|
{
|
if (_lockloc.N_ROW == r)
|
endBit = _radd1.OrderBy(x => x.N_COL).FirstOrDefault();
|
else _r.OrderBy(x => x.N_COL).FirstOrDefault();
|
break;
|
}
|
}
|
}
|
return true;
|
});
|
|
if (SameandNotEnd)
|
{
|
LogHelper.Info($"将要下在{{{r} or {r22}双空有任务排,任务点符合。等待其完成就可入;");
|
break;
|
}
|
if (Errcnil)
|
{
|
LogHelper.Info($"{r} and {r22}双空有任务排,点所在任务未找到;continue;");
|
continue;
|
}
|
;
|
if (endBit == null)
|
{
|
LogHelper.Info($"{r} and {r22}双空有任务排,任务点不符合。 等一会再看;");
|
break;
|
}
|
}
|
else
|
{
|
LogHelper.Info($"按 将要下在{r}排或者{r + 1}排。 双空排!");
|
|
//从大到小排。 2个都空。就可以入了
|
endBit = _r.OrderBy(x => x.N_COL).FirstOrDefault();
|
}
|
if (endBit != null) break;
|
}
|
}
|
}
|
//for (int i = 1; i <= MaxRow; i += 2)
|
//{
|
// var _i = _l.FindAll(x => x.N_ROW == i);
|
// var _iadd1 = _l.FindAll(x => x.N_ROW == (i + 1));
|
|
// if (!_i.Any() || !_iadd1.Any())
|
// {
|
// LogHelper.Info($"Attention:注塑机满入库,第{i}或{(i + 1)} 没有排数据。无法入库。");
|
// }
|
//}
|
//
|
|
/// 。未满货位。
|
//endBit = _l?.OrderBy(x => x.N_ROW).ThenBy(x => x.N_COL).ToList().Find(x => x.N_CURRENT_NUM > 0 && x.N_CURRENT_NUM < x.N_CAPACITY);
|
//var lrowlist = _l?.OrderBy(x => x.N_ROW).GroupBy(x=>x.N_ROW);
|
|
#endregion
|
vvvvvv:
|
//if (false)//endBit == null&&
|
if (endBit == null && workOrder.S_Is_Auto.Trim() == "Y")
|
foreach (IGrouping<int, Location> item in _l.GroupBy(x => x.N_ROW))
|
{
|
List<Location> _cols = item.OrderBy(x => x.N_COL).ToList();
|
Location e = _cols.FindAll((Location x) => x.N_CURRENT_NUM > 0).LastOrDefault();//从左往右最后一个满位。
|
if (e != null)
|
{
|
var rel = LocationHelper.GetLocCntrRel(e.S_LOC_CODE);
|
//if (rel.FirstOrDefault()?.S_TYPE != SQL_ItemCode)
|
if (rel.FirstOrDefault()?.S_TYPE != $"{workOrder.SQL_PLineNo}>{SQL_ItemCode}")
|
{
|
LogHelper.Info($"{e.S_LOC_CODE} 位置的 物料{rel.FirstOrDefault()?.S_TYPE} 与本次下线{($"{workOrder.SQL_PLineNo}>{SQL_ItemCode}")} 不符。 筛选下一排");
|
continue;
|
}
|
}
|
|
if (e != null && e.N_CURRENT_NUM < e.N_CAPACITY)
|
{
|
endBit = e;
|
}
|
else
|
{
|
var empT = _cols.FindAll(x => x.N_CURRENT_NUM == 0).FirstOrDefault();//从左往右第一个空位
|
if (empT != null)
|
endBit = empT;
|
}
|
if (endBit != null)
|
break;
|
}
|
}
|
else
|
{
|
|
/// 筛选完后的货位数据。 可以用原来的入库方法,
|
if (!string.IsNullOrEmpty(workOrder.S_ROW1))
|
{
|
var rs = workOrder.S_ROW1.Split('=');
|
var rows = Array.ConvertAll(rs[rs.Length - 1].Split('-'), Convert.ToInt32);
|
|
_l = LocationHelper.GetLocList(x => x.S_AREA_CODE == rs[0] && rows.Contains(x.N_ROW) && x.S_LOCK_STATE != "报废");
|
}
|
}
|
#region 筛选终点
|
|
if (endBit != null)
|
{
|
int endLayer = endBit.N_CURRENT_NUM + 1;
|
var carryCntrs = new List<string> { _ctrl.FirstOrDefault().S_CNTR_CODE };//DateTime.Now.ToString("yyMMddHHmmss") };
|
var bb = TaskProcess.CreateTransport(workOrder.SQL_WorkNo, location, endBit.S_LOC_CODE, "满瓶坯-入库", carryCntrs, 1, endLayer, carryCntrs.Count, plc.taskPri);
|
if (bb)
|
{
|
LogHelper.Info($"{plc.deviceName} 当前机器{location}位置状态{p0} 正在执行取满任务");
|
}
|
result = bb;
|
}
|
else
|
{
|
LogHelper.Info($"瓶p机{plc.deviceName} 没有找到可用的满托终点", "瓶坯机");
|
}
|
|
#endregion
|
}
|
else
|
{
|
LogHelper.Info($"瓶盖机{plc.deviceName}起点没有托盘,不可以生成任务", "瓶盖机");
|
result = true;
|
}
|
|
}
|
else
|
{
|
LogHelper.Info($"瓶坯机:{plc.deviceName} 下线信号:{location} 未找到工单", "瓶坯机");
|
}
|
}
|
else
|
{
|
//LogHelper.Info($"瓶PEM机:{plc.deviceName} 当前机器2个位置 有一个有任务,不可触发满托下线", "瓶坯机");
|
//if (p0 != "无")
|
LogHelper.Info($"{plc.deviceName} {location}位置状态{p0} 正在执行{(p0.Replace("锁", "") == "入库" ? "送空" : "取满")}任务");
|
//if (!(p1s == "无" || p1s == "入库锁"))
|
//{
|
// LogHelper.Info($"{plc.deviceName} 另外一个位置{p1}状态{p1s} 有任务,不可触发满托下线");
|
//}
|
}
|
}
|
return result;
|
}
|
|
|
//LookShort 找不满排。
|
static Location GetareaLocationByBtypeandBatch(ItemInfo item1, string are, string Btype, string Batch, bool isFule, int MaxLayer, WorkOrder workOrder, bool LookShort = false, int row = 0)
|
{
|
LogHelper.Info("GetareaLocationByBtypeandBatch" + $"{item1.S_ITEM_CODE}-{item1.S_ITEM_NAME}-{are}-{Btype}-{Batch} {LookShort}");
|
var _tempList = new List<Location>();
|
List<string> bts = new List<string> { "大板", "小板", "集化板" };
|
Location endBit = null;
|
bts.Remove(Btype);
|
string area = are + Settings.areaSuffix(Btype);
|
LogHelper.Info(area + " 库区的板型" + Btype);
|
if (!area.Contains("_")) LogHelper.Info(area + " 库区的板型" + Btype + "不正确");
|
//找当前库区无锁不满的排
|
var _arealist = LocationHelper.GetLocList(x => x.S_AREA_CODE == area && x.S_LOCK_STATE != "报废");
|
|
if (!LookShort)
|
goto Empty;
|
var _arealock = _arealist.FindAll(x => x.S_LOCK_STATE != "无").Select(x => x.N_ROW).Distinct();
|
LogHelper.Info(area + " 库区 非报废货位量" + _arealist.Count + ":非正常货位锁排" + JsonConvert.SerializeObject(_arealock));
|
|
var lcollist = LocationHelper.GetRowLock(area)?.Select(x => x.N_ROW);
|
_arealock = _arealock.Concat(lcollist).Distinct();
|
if (_arealock.Any())
|
_arealist.RemoveAll(x => x.N_ROW != row && _arealock.Contains(x.N_ROW));
|
if (!_arealist.Any())
|
return null;
|
LogHelper.Info(area + "=可用排=" + JsonConvert.SerializeObject(_arealist.Select(x => x.N_ROW).Distinct()));
|
//看看有没有 同物料 同板子 同批次 不满的,
|
//
|
foreach (var x in _arealist.OrderBy(x => x.N_ROW).GroupBy(x => x.N_ROW))
|
{
|
//排最外侧有货位fz
|
var xlist = x.OrderBy(xx => xx.N_COL).ToList();
|
var _cl = xlist.FindAll(xx => xx.N_CURRENT_NUM > 0).LastOrDefault();
|
//LogHelper.Info(" for 是否有货排!" + (_cl != null));
|
if (_cl == null)
|
{
|
//这是一个空排
|
//_tempList.AddRange(xlist);
|
if (row == 0)
|
continue;
|
else
|
{
|
return xlist.FirstOrDefault();
|
}
|
}
|
//LogHelper.Info(" for 查看货位托盘!" + _cl.S_LOC_CODE);
|
// 最外侧货位是是同.. 的话 就可以入了。
|
var _clrel = LocationHelper.GetLocCntrRel(_cl.S_LOC_CODE);
|
if (!_clrel.Any())
|
{
|
LogHelper.Info(_cl.S_LOC_CODE + " 没有货位托盘信息!");
|
continue;
|
}
|
//LogHelper.Info(" for 查看货位托盘版型!" + _cl.S_LOC_CODE);
|
//板型相同
|
|
LogHelper.Info(_cl.S_LOC_CODE + $" 货位托盘信息{_clrel[0].S_CNTR_CODE}!isFule" + isFule);
|
if (_clrel[0].S_CNTR_CODE.StartsWith("TP") && isFule)
|
{
|
continue;
|
}
|
if (!_clrel[0].S_CNTR_CODE.StartsWith("TP") && !isFule)
|
{
|
continue;
|
}
|
LogHelper.Info("识别托盘类型。");
|
if (_clrel[0].S_TYPE == Btype)
|
{
|
var _clcntitem = ContainerHelper.GetCntrItemRel(_clrel[0].S_CNTR_CODE.Trim());
|
if (!_clcntitem.Any())
|
{
|
LogHelper.Info(_cl.S_LOC_CODE + $"货位 的托盘{_clrel[0].S_CNTR_CODE} 没有物料记录");
|
continue;
|
}
|
var _ci = _clcntitem.OrderByDescending(xx => xx.T_CREATE).First();
|
if ((_ci.S_ITEM_CODE == item1.S_ITEM_CODE || _ci.S_ITEM_CODE == item1.S_ITEM_NAME) && _ci.ItemLayer == workOrder.ItemLayer)
|
{
|
bool sameBatch = string.IsNullOrEmpty(_ci.S_BATCH_NO) ? true : _ci.S_BATCH_NO == Batch;
|
//not full
|
if (_cl.N_CURRENT_NUM < _cl.N_CAPACITY && (MaxLayer == 0 || (MaxLayer > 0 && _cl.N_CURRENT_NUM < MaxLayer)))
|
// if (_cl.N_CURRENT_NUM < _cl.N_CAPACITY && (MaxLayer == 0 || (MaxLayer > 0 && _cl.N_CURRENT_NUM / 2 < MaxLayer)))
|
{
|
if (sameBatch)
|
endBit = _cl;
|
else
|
{
|
var empty = xlist.FindAll(xx => xx.N_CURRENT_NUM == 0 && xx.N_COL > _cl.N_COL);
|
if (!empty.Any())
|
{
|
//这一排没有空位
|
}
|
else
|
{
|
//endBit = empty.FirstOrDefault();
|
if (empty.Count > 1)
|
{
|
endBit = empty.Skip(1).FirstOrDefault();
|
}
|
}
|
}
|
}
|
else//full
|
{
|
var empty = xlist.FindAll(xx => xx.N_CURRENT_NUM == 0 && xx.N_COL > _cl.N_COL);
|
if (!empty.Any())
|
{
|
//这一排没有空位
|
}
|
else
|
{
|
if (sameBatch)
|
endBit = empty.FirstOrDefault();
|
else
|
{ //满了, 中间间隔一个空位。
|
if (empty.Count > 1)
|
{
|
endBit = empty.Skip(1).FirstOrDefault();
|
}
|
}
|
}
|
}
|
}
|
//Task = null;
|
if (false)
|
{
|
bool thisDay = true;
|
LocationHelper.DoAction(db =>
|
{
|
WMSTask Task = db.Queryable<WMSTask>().Where(t => t.S_TYPE.Contains("成品满框-入库") && t.S_CNTRS.Contains(_ci.S_CNTR_CODE)).ToList().FirstOrDefault();
|
thisDay = Task?.T_CREATE.Date == DateTime.Now.Date;
|
return true;
|
});
|
if (_ci.S_ITEM_CODE == item1?.ToString() && _ci.S_BATCH_NO == Batch)
|
{
|
//同物料同批次。
|
if (_cl.N_CURRENT_NUM < _cl.N_CAPACITY && (MaxLayer == 0 || MaxLayer > 0 && _cl.N_CURRENT_NUM < MaxLayer))
|
{
|
//if (MaxLayer > 0)
|
//{
|
// if (_cl.N_CURRENT_NUM < MaxLayer)
|
// {
|
// endBit = _cl;
|
// }
|
// else
|
// continue;
|
//}
|
//else
|
if (thisDay)
|
endBit = _cl;
|
else
|
{ //没满, 直接用下一个位置。 等于 间隔
|
var empty = xlist.FindAll(xx => xx.N_CURRENT_NUM == 0 && xx.N_COL > _cl.N_COL);
|
if (!empty.Any())
|
{
|
//这一排没有空位
|
}
|
else
|
{
|
//endBit = empty.FirstOrDefault();
|
if (empty.Count > 1)
|
{
|
endBit = empty.Skip(1).FirstOrDefault();
|
}
|
}
|
}
|
}
|
else //找空位
|
{
|
var empty = xlist.FindAll(xx => xx.N_CURRENT_NUM == 0 && xx.N_COL > _cl.N_COL);
|
if (!empty.Any())
|
{
|
//这一排没有空位
|
}
|
else
|
{
|
if (thisDay)
|
endBit = empty.FirstOrDefault();
|
else
|
{ //满了, 中间间隔一个空位。
|
if (empty.Count > 1)
|
{
|
endBit = empty.Skip(1).FirstOrDefault();
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
if (endBit != null)
|
break;
|
}
|
LogHelper.Info(" for over!" + endBit?.S_LOC_CODE);
|
//就查看有没有空的排了。
|
//if (endBit != null) /// 寻找未满排, 直接返回结果。
|
return endBit;
|
//LogHelper.Info(" _tempList over!");
|
|
//这里开始 寻找空排
|
Empty:
|
var _arealock1 = _arealist.FindAll(x => x.S_LOCK_STATE != "无" || x.N_CURRENT_NUM > 0).Select(x => x.N_ROW).Distinct();
|
|
var lcollist1 = LocationHelper.GetRowLock(area)?.Select(x => x.N_ROW);
|
_arealock1 = _arealock1.Concat(lcollist1).Distinct();
|
if (_arealock1.Any())
|
_arealist.RemoveAll(x => _arealock1.Contains(x.N_ROW));
|
_tempList = _arealist;
|
if (!_tempList.Any())//该库区的空排。
|
return endBit;
|
//没有空的就返回空。 (三板合一库的情况下, 一个库区没有空的了,说明都呗一种板子占了)
|
//有空的就查看 其他版型库区都空且不锁定的排。 三板空排取交集,就是可用排
|
|
//foreach (var _a in bts)
|
//{
|
// string ar_ = are + Settings.areaSuffix(Btype);
|
// if (!ar_.Contains("_"))
|
// {
|
// continue;
|
// }
|
// var ar_loclist = LocationHelper.GetLocList(x => x.S_AREA_CODE == ar_ && x.S_LOCK_STATE != "报废");
|
// //锁定排和有货的排汇集
|
// var ar_row = ar_loclist.FindAll(x => x.S_LOCK_STATE != "无" || x.N_CURRENT_NUM > 0).Select(x => x.N_ROW).Distinct();
|
// if (ar_row.Any())
|
// _tempList.RemoveAll(x => ar_row.Contains(x.N_ROW));
|
//}
|
|
LogHelper.Info(" ar_RplaceRow over!");
|
var ar_RplaceRows = LocationHelper.GetLocList(x => x.S_AREA_CODE != area && x.S_AREA_CODE.Contains(are) && x.S_LOCK_STATE != "报废");//.Select(x => x.N_ROW).Distinct();
|
IEnumerable<int> ar_RplaceRow1 = ar_RplaceRows.FindAll(x => "入库锁;出库锁".Contains(x.S_LOCK_STATE?.Trim())).Select(x => x.N_ROW).Distinct();
|
LogHelper.Info(" 有锁排 - " + JsonConvert.SerializeObject(ar_RplaceRow1));
|
var ar_RplaceRow2 = ar_RplaceRows.FindAll(x => x.N_CURRENT_NUM > 0).Select(x => x.N_ROW).Distinct();
|
LogHelper.Info(" 有货排: - " + JsonConvert.SerializeObject(ar_RplaceRow2));
|
//var ar_RplaceRow_rowlock = LocationHelper.GetRowLock(x => x.S_AREA_CODE.Contains(are))?.Select(x => x.N_ROW);
|
|
if (Btype != "小板" && "QX-02,QX-09".IndexOf(are) > -1)
|
{
|
ar_RplaceRow1 = ar_RplaceRow1.Concat(new int[] { 1, 2, 3, 4 });
|
LogHelper.Info(" QX-02,QX-09 非小板。 有锁排 增加1-4 : " + JsonConvert.SerializeObject(ar_RplaceRow1));
|
}
|
|
var db1 = new SqlHelper<Object>().GetInstance();
|
var OtherArows = new List<int>();
|
//var orders = db1.Queryable<WorkOrder>().Where(x => x.SQL_State == "执行中" && !string.IsNullOrEmpty(x.S_ROW) && x.SQL_Area.Contains(are)).ToList();
|
//{
|
// foreach (var ar in orders)
|
// {
|
// var rs = ar.S_ROW.Split('=');
|
// int[] Irs = Array.ConvertAll(rs[rs.Length - 1].Split('-'), Convert.ToInt32);
|
// foreach (var r in Irs)
|
// {
|
// if (!OtherArows.Contains(r))
|
// {
|
// OtherArows.Add(r);
|
// }
|
// }
|
// }
|
//}
|
var orders = db1.Queryable<WorkOrder>().Where(x => x.SQL_State == "执行中" && !string.IsNullOrEmpty(x.S_ROW)).ToList();
|
{
|
foreach (var ar in orders)
|
{
|
var rs = ar.S_ROW.Split('=');
|
if (rs.Length < 2)
|
{
|
if (!ar.SQL_Area.Contains(are)) continue;
|
}
|
var areaRows = ar.S_ROW.Split('$');
|
foreach (var item2 in areaRows)
|
{
|
if (!item2.Contains(are)) continue;
|
rs = item2.Split('=');
|
int[] Irs = Array.ConvertAll(rs[rs.Length - 1].Split('-'), Convert.ToInt32);
|
foreach (var r in Irs)
|
{
|
if (!OtherArows.Contains(r))
|
{
|
OtherArows.Add(r);
|
}
|
}
|
}
|
}
|
}
|
LogHelper.Info(" 所有工单该库区独占排: - " + JsonConvert.SerializeObject(OtherArows));
|
var ar_RplaceRow = ar_RplaceRow1.Concat(ar_RplaceRow2).Concat(OtherArows).Distinct();//.Concat(ar_RplaceRow_rowlock)
|
//_arealock = _arealock.Concat(lcollist).Distinct();
|
{
|
|
//用排锁表。 这里不用再管 移库 分拣出库 等的排锁定问题。
|
//var Tsr = WCSHelper.GetWorkOrder2(x => x.SQL_State == "执行中" && x.start_area.Contains(are)).Select(x => Convert.ToInt32(x.start_row)).Distinct();
|
////LogHelper.Info(" Tsr - " + JsonConvert.SerializeObject(Tsr));
|
//var Ter = WCSHelper.GetWorkOrder2(x => x.SQL_State == "执行中" && x.end_area.Contains(are)).Select(x => Convert.ToInt32(x.end_row)).Distinct();
|
////LogHelper.Info(" Ter - " + JsonConvert.SerializeObject(Ter));
|
//ar_RplaceRow = ar_RplaceRow.Concat(Tsr).Concat(Ter);
|
}
|
if (ar_RplaceRow.Any())
|
{
|
LogHelper.Info("排除非空排 - " + JsonConvert.SerializeObject(ar_RplaceRow));
|
_tempList.RemoveAll(x => ar_RplaceRow.Contains(x.N_ROW));
|
}
|
|
|
if (_tempList.Any())//三个库区的交集空排
|
{
|
//if (MaxLayer > 0) 这里是三个库区的空排交集。 肯定是没有货在这里的。
|
//{
|
// endBit = _tempList.OrderBy(x => x.N_ROW).ThenBy(x => x.N_COL).FirstOrDefault(x => x.N_CURRENT_NUM < x.N_CAPACITY && x.N_CURRENT_NUM < MaxLayer);
|
//}
|
//else
|
endBit = _tempList.OrderBy(x => x.N_ROW).ThenBy(x => x.N_COL).FirstOrDefault();
|
}
|
else
|
{
|
LogHelper.Info($"{are},库区3板空排交集null");
|
}
|
return endBit;
|
}
|
|
static bool Analysis505(Settings.deviceInfo plc, int _li, string banziType = null)
|
{
|
var location = plc.location[_li];
|
var result = false;
|
if (location != "")
|
{
|
var workOrder = WCSHelper.GetWorkOrder(plc.deviceName);
|
if (workOrder == null)
|
{
|
LogHelper.Info(plc.deviceName + "没有【执行中】的工单");
|
return false;
|
}
|
|
|
|
var size = banziType ?? workOrder.B_Type;
|
|
var ItemName = workOrder.SQL_ItemName;
|
var ItemCode = workOrder.SQL_ItemCode;
|
var Batch = workOrder.SQL_BatchNo ?? "";
|
//if (string.IsNullOrEmpty(Batch))
|
//{
|
// workOrder.SQL_BatchNo = "";// DateTime.Now.ToString("yyMMdd");
|
// WCSHelper.Do(db =>
|
// {
|
// db.Updateable<WorkOrder>().UpdateColumns(it => new
|
// {
|
// it.SQL_BatchNo
|
// }).ExecuteCommand();
|
// Batch = workOrder.SQL_BatchNo;
|
// });
|
//}
|
|
if (string.IsNullOrEmpty(size))
|
{
|
LogHelper.Info(plc.deviceName + "工单 没有指定版型");
|
return false;
|
}
|
if (string.IsNullOrEmpty(ItemCode))
|
{
|
LogHelper.Info(plc.deviceName + "工单 没有指定物料");
|
return false;
|
}
|
//Console.WriteLine($"瓶盖机:{plc.deviceName} 下线信号:{location}");
|
//判断上次卸货完成时间,如果5分钟内,不处理请求,可能是设备请求还没有重置
|
|
string p0 = LocationHelper.CheckLocState(location).Trim(); // LocationHelper.CheckLocState(plc.location[0]);
|
|
if (p0 == "无")
|
{
|
LogHelper.Info($"{plc.deviceName} {(_li == 0 ? "满框下线" : "空筐上线")}信号:{location} 查询工单");
|
if (_li > 0)
|
{
|
var time = LocationHelper.GetT_FULL_TIME(location);
|
var _loc = LocationHelper.GetLoc(location);
|
LogHelper.Info(location + ":托盘放置时间:(" + time + ") 货位托盘数量(" + _loc.N_CURRENT_NUM + ")");
|
if (_loc == null)
|
{
|
LogHelper.Info(location + " 货位数据不存在。 请确认!");
|
return false;
|
}
|
if (time == null || _loc.N_CURRENT_NUM == 0)
|
{
|
if (_loc.N_CURRENT_NUM > 0)
|
{
|
LogHelper.Info(location + "有筐但没有时间数据");
|
time = DateTime.Now;
|
LocationHelper.SetT_FULL_TIME(location, time);
|
}
|
else
|
{
|
if (time != null)
|
{
|
time = null;
|
LocationHelper.SetT_FULL_TIME(location, time);
|
}
|
// 这里可以进行送空了。
|
LogHelper.Info(location + "没有筐 - 送空框");
|
|
#region 505 送空。
|
var _kk = LocationHelper.GetLocList(x => x.S_AREA_CODE == "KTQ" && x.N_CURRENT_NUM > 0 && x.S_LOCK_STATE != "报废");
|
var _lockkk = _kk.FindAll(x => x.S_LOCK_STATE != "无").Select(x => x.N_ROW).Distinct();
|
if (_lockkk.Any())
|
{
|
_kk.RemoveAll(x => _lockkk.Contains(x.N_ROW));
|
}
|
if (!_kk.Any())
|
{
|
LogHelper.Info("去除锁定排后,没有可用空框排了"); return false;
|
}
|
Location stabit = null;
|
|
//foreach (var item in _kk.GroupBy(x => x.N_ROW).OrderBy(x => x.Count(y => y.N_CURRENT_NUM > 0)).ThenBy(x => x.Key))
|
//{
|
// var _ll = item.OrderBy(x => x.N_COL).ToList();
|
// var fulast = _ll.FindAll(x => x.N_CURRENT_NUM > 0).LastOrDefault();
|
// if (fulast != null)
|
// {
|
// var cntrEnd = LocationHelper.GetLocCntrRel(fulast.S_LOC_CODE);
|
// if (cntrEnd.Any())
|
// {
|
// if (cntrEnd[0].S_TYPE == size)
|
// {
|
// stabit = fulast;
|
// break;
|
// }
|
// else
|
// continue;
|
// }
|
// else
|
// {
|
// LogHelper.Info(fulast.S_LOC_CODE + "该位置有数量,但是没有托盘数据。需要核对。");
|
// continue;
|
// }
|
// }
|
// if (stabit != null) { break; }
|
//}
|
|
while (_kk.Any() && stabit == null)
|
{
|
var _kkk = _kk.OrderBy(x => x.N_ROW).ThenBy(x => x.N_COL).FirstOrDefault();
|
var cntr = LocationHelper.GetLocCntrRel(_kkk.S_LOC_CODE);
|
//LogHelper.Info("去除锁定排后,没有可用空框排了" + _kkk.S_LOC_CODE + JsonConvert.SerializeObject(cntr));
|
if (!cntr.Any())
|
{
|
LogHelper.Info(_kkk.S_LOC_CODE + "该位置有数量,但是没有托盘数据。需要核对。");
|
_kk.Remove(_kkk);
|
continue;
|
}
|
if (cntr[0].S_TYPE == size)
|
{
|
stabit = _kkk;
|
break;
|
}
|
else
|
//版型不合 ,移除一排
|
_kk.RemoveAll(x => x.N_ROW == _kkk.N_ROW);
|
|
}
|
;
|
|
if (stabit != null)
|
{
|
var carryCntrs = LocationHelper.GetLocCntrRel(stabit.S_LOC_CODE).Select(x => x.S_CNTR_CODE).ToList();
|
var bb = TaskProcess.CreateTransport(workOrder.SQL_WorkNo, stabit.S_LOC_CODE, location, "成品-空托上线" + size, carryCntrs, 1, 1, carryCntrs.Count, plc.taskPri);
|
LogHelper.Info($"{plc.deviceName} 当前机器{location}位置状态 创建“空托上线" + size + "”任务" + bb);
|
}
|
else
|
{
|
LogHelper.Info($"{plc.deviceName} 没有找到可用{size}空框");
|
}
|
#endregion
|
|
return true;
|
}
|
}
|
|
//托盘放下 1分钟内 取货请求,都不处理。
|
if (time != null)
|
if (DateTime.Now.Subtract(time ?? DateTime.Now).TotalSeconds < 30)
|
{
|
for (var i = 0; i < plc.location.Length; i++)
|
{
|
if (location == plc.location[i])
|
{
|
PlcHelper.SendHex(plc.address, "3F00" + (i + 1) + "0" + "0d0a");
|
break;
|
}
|
}
|
}
|
LogHelper.Info(location + "空框位 防止时间够了。");
|
//else //
|
//{
|
// //有筐 时间到了 清掉吧 , 不然下一个空框送不过来了。
|
// LocationHelper.lOCReSetValue(x => x.S_LOC_CODE == location, x =>
|
// {
|
// x.T_FULL_TIME = null;
|
// x.N_CURRENT_NUM = 0;
|
// });
|
//}
|
return false;
|
}
|
LogHelper.Info($"查到了工单{workOrder.SQL_WorkNo}");
|
//满框下线
|
if (_li == 0)
|
{
|
var _loc = LocationHelper.GetLoc(location);
|
if (_loc.T_EMPTY_TIME != null)
|
{
|
if (DateTime.Now.Subtract(Convert.ToDateTime(_loc.T_EMPTY_TIME)).TotalSeconds < 30)
|
{
|
PlcHelper.SendHex(plc.address, "3F00100d0A");
|
LogHelper.Info($"{plc.address} 水线 取货完成。 30秒缓冲 写取货完成。3F00100d0A ");
|
return false;
|
}
|
}
|
//查询起点托盘
|
var ItemInfo = ContainerHelper.GetItem(workOrder.SQL_ItemName);
|
var rel = LocationHelper.GetLocCntrRel(location);
|
|
if (rel.Count > 0)
|
{
|
//if (!rel.FirstOrDefault().S_CNTR_CODE.Contains("TP" + Settings._TPcc))
|
//{
|
// //不是今天的托盘 - 大概率 还是 之前任务没执行成功,没取货。
|
// LocationHelper.UnBindingLoc(location, rel.Select(x => x.S_CNTR_CODE).ToList());
|
//}
|
LocationHelper.UnBindingLoc(location, rel.Select(x => x.S_CNTR_CODE).ToList());
|
rel = new List<LocCntrRel> { };
|
}
|
var _bbbb = workOrder.FromFuLe?.Trim() == "Y";
|
var fuletraycodes = LocationHelper.GetFuLeTrayCodeList(X => X.SQL_State == "下发" && X.workNo == workOrder.SQL_WorkNo && X.deviceName == workOrder.FuLe_PLine_No);
|
|
//LogHelper.Info($"{workOrder.SQL_WorkNo} -FromFuLe? {_bbbb}");
|
if (_bbbb)
|
{
|
if (rel.Count > 0)
|
{
|
LocationHelper.UnBindingLoc(location, rel.Select(x => x.S_CNTR_CODE).ToList());
|
rel = new List<LocCntrRel> { };
|
}
|
|
if (fuletraycodes.Count != 2)
|
{
|
LogHelper.Info($"富勒工单成品下线,托盘数量{fuletraycodes.Count},不足2。 ");
|
return false;
|
}
|
|
else if (string.IsNullOrEmpty(Batch))
|
{
|
if (fuletraycodes[0].batchNo != fuletraycodes[1].batchNo)
|
{
|
LogHelper.Info($"富勒工单成品下线,托盘数量2 ,单批次不同。 最后一个为准");
|
//return false;
|
Batch = fuletraycodes.OrderByDescending(x => x.T_CREATE).FirstOrDefault().batchNo;
|
}
|
else
|
Batch = fuletraycodes[0].batchNo;
|
//if (fuletraycodes[0].batchNo != fuletraycodes[1].batchNo)
|
//{
|
// LogHelper.Info($"富勒工单成品下线,托盘数量2 ,单批次不同。 ");
|
// return false;
|
//}
|
//Batch = fuletraycodes[0].batchNo;
|
}
|
}
|
else
|
{
|
if (rel.Count > 0)
|
{
|
if (!rel.FirstOrDefault().S_CNTR_CODE.Contains("TP" + Settings._TPcc))
|
{
|
//不是今天的托盘 - 大概率 还是 之前任务没执行成功,没取货。
|
LocationHelper.UnBindingLoc(location, rel.Select(x => x.S_CNTR_CODE).ToList());
|
rel = new List<LocCntrRel> { };
|
}
|
}
|
}
|
//LogHelper.Info($"{workOrder.SQL_WorkNo} -rel.count? {rel.Count}");
|
// List<LocCntrRel> locr = null;
|
// List<CntrItemRel> cnir = null;
|
LocCntrRel locr = null;
|
CntrItemRel cnir = null;
|
if (rel.Count == 0)
|
{
|
LogHelper.Info("满眶下线 - ");
|
//if (_bbbb)
|
//{
|
// rel = new List<LocCntrRel>
|
// {
|
// new LocCntrRel { S_LOC_CODE = location, S_CNTR_CODE = fuletraycodes[0].trayCode,S_TYPE=size },
|
// new LocCntrRel { S_LOC_CODE = location, S_CNTR_CODE = fuletraycodes[1].trayCode,S_TYPE=size }
|
// };
|
// locr = new List<LocCntrRel>
|
// {
|
// new LocCntrRel { S_LOC_CODE = location, S_CNTR_CODE = fuletraycodes[0].trayCode,S_TYPE=size },
|
// new LocCntrRel { S_LOC_CODE = location, S_CNTR_CODE = fuletraycodes[1].trayCode,S_TYPE=size }
|
// };
|
// cnir = new List<CntrItemRel>
|
// {
|
// new CntrItemRel { S_CNTR_CODE = fuletraycodes[0].trayCode, S_BATCH_NO = Batch, F_QTY = Convert.ToInt32(fuletraycodes[0].trayNum.Split('.')[0])+"", B_TYPE = size, ItemLayer = workOrder.ItemLayer, S_ITEM_CODE = ItemCode, S_ITEM_NAME = ItemName },
|
// new CntrItemRel { S_CNTR_CODE = fuletraycodes[1].trayCode, S_BATCH_NO = Batch, F_QTY = Convert.ToInt32(fuletraycodes[1].trayNum.Split('.')[0])+"", B_TYPE = size, ItemLayer = workOrder.ItemLayer, S_ITEM_CODE = ItemCode, S_ITEM_NAME = ItemName }
|
// };
|
//}
|
//else
|
//{
|
// var tp1 = Settings.TPnum();
|
|
// rel = new List<LocCntrRel>
|
// {
|
// new LocCntrRel { S_LOC_CODE = location, S_CNTR_CODE = tp1 + "_1",S_TYPE=size },
|
// new LocCntrRel { S_LOC_CODE = location, S_CNTR_CODE = tp1 + "_2",S_TYPE=size }
|
// };
|
// locr = new List<LocCntrRel>
|
// {
|
// new LocCntrRel { S_LOC_CODE = location, S_CNTR_CODE = tp1 + "_1",S_TYPE=size },
|
// new LocCntrRel { S_LOC_CODE = location, S_CNTR_CODE = tp1 + "_2",S_TYPE=size }
|
// };
|
// cnir = new List<CntrItemRel>
|
// {
|
// new CntrItemRel { S_CNTR_CODE = tp1 + "_1", S_BATCH_NO = Batch, F_QTY = "0", S_ITEM_CODE = ItemName },
|
// new CntrItemRel { S_CNTR_CODE = tp1 + "_2", S_BATCH_NO = Batch, F_QTY = "0", S_ITEM_CODE = ItemName }
|
// };
|
//}
|
|
//创建容器-写货品容器-托盘容器
|
var tp1 = Settings.TPnum();
|
var cntr = tp1 + "_1v" + tp1 + "_2";
|
LogHelper.Info($"{workOrder.SQL_WorkNo} -tp1 {tp1}-{cntr}");
|
string qty = "0";
|
if (_bbbb)
|
{
|
cntr = "F" + fuletraycodes[0].trayCode + "v" + fuletraycodes[1].trayCode;
|
qty = Convert.ToInt32(fuletraycodes[0].trayNum.Split('.')[0]) + Convert.ToInt32(fuletraycodes[1].trayNum.Split('.')[0]) + "";
|
}
|
|
LogHelper.Info("满眶下线 - " + cntr);
|
var tp2 = Settings.TPnum();
|
rel = new List<LocCntrRel>
|
{
|
new LocCntrRel { S_LOC_CODE = location, S_CNTR_CODE = cntr,S_TYPE=size }
|
};
|
locr = new LocCntrRel { S_LOC_CODE = location, S_CNTR_CODE = cntr, S_TYPE = size };
|
cnir = new CntrItemRel { S_CNTR_CODE = cntr, S_BATCH_NO = Batch, F_QTY = qty, B_TYPE = size, ItemLayer = workOrder.ItemLayer, S_ITEM_CODE = ItemCode, S_ITEM_NAME = ItemName };
|
|
/*
|
UPDATE 托盘物料表
|
SET S_ITEM_CODE = A.S_ITEM_CODE, S_ITEM_NAME = A.S_ITEM_NAME
|
FROM 物料表 A
|
JOIN 托盘物料表 B ON A.S_ITEM_CODE=B.S_ITEM_CODE or A.S_ITEM_CODE=B.S_ITEM_NAME
|
*/
|
|
//var res = LocationHelper.DoAction(db =>
|
//{
|
// try
|
// {
|
// //db.BeginTran();
|
// db.Insertable<LocCntrRel>(new LocCntrRel { S_LOC_CODE = location, S_CNTR_CODE = cntr, S_TYPE = size }).ExecuteCommand();
|
|
// db.Insertable<CntrItemRel>(new CntrItemRel { S_CNTR_CODE = cntr, S_BATCH_NO = Batch, F_QTY = qty, S_ITEM_CODE = ItemName }).ExecuteCommand();
|
// //db.Ado.CommitTran();
|
// return true;
|
// }
|
// catch (Exception ex)
|
// {
|
// LogHelper.Info("成品满框下线口,初始化托盘数据失败," + ex.Message + ex.StackTrace);
|
// return false;
|
// }
|
//});
|
//if (!res)
|
//{
|
// return false;
|
//}
|
}
|
|
LogHelper.Info($"查找{location}对应终点->");
|
Location endBit = null;
|
|
|
int mmmmmnum = workOrder.N_LimitNum;
|
|
//bool SendAudio = true;
|
//var _audiolist = TaskHelper.GetTList<TaskAudio>(x => x.S_PlineNo == plc.deviceName && x.N_AUDIO < 3);
|
//if (_audiolist.Any())
|
//{
|
// if (_audiolist.Find(x => x.N_AUDIO == 0) != null)
|
// {
|
// LogHelper.Info($"{plc.deviceName} - {location}->有目标区域等待审核。");
|
// return false;
|
// }
|
//}
|
|
|
int MaxLayer = ItemInfo?.MaxLayer ?? 0;
|
{
|
var area = workOrder.SQL_Area;
|
var areaLi = plc.areaPriy;
|
|
#region oooo
|
|
//if (false) //flword != null &&
|
//{
|
// var t1 = flword.T_MODIFY.Date != DateTime.Now.Date;
|
// var row = int.Parse(flword.N_ROW);
|
// var areacode = flword.S_AREA_CODE;
|
// if (areacode.IndexOf(Settings.areaSuffix(size)) != -1)// 过了12点, 版型没变。 原来的排上找空一个位置。 换排就不需要空位置了
|
// {
|
// var rowlist = LocationHelper.GetLocList(x => x.S_AREA_CODE == areacode && x.S_LOCK_STATE != "报废" && x.N_ROW == row);
|
// if (rowlist.Find((Location x) => x.S_LOCK_STATE != "无") != null) goto NormalArea;
|
// var last = rowlist.FindAll(x => x.N_CURRENT_NUM > 0).OrderBy(X => X.N_COL).LastOrDefault();// 该排最后一次入库位。
|
// if (last == null) goto NormalArea;
|
|
// var _clrel = LocationHelper.GetLocCntrRel(last.S_LOC_CODE);
|
// if (!_clrel.Any())
|
// {
|
// LogHelper.Info(last.S_LOC_CODE + " 没有货位托盘信息!");
|
// goto NormalArea;
|
// }
|
// //LogHelper.Info(" for 查看货位托盘版型!" + _cl.S_LOC_CODE);
|
// //板型相同
|
|
// //LogHelper.Info(last.S_LOC_CODE + $" 货位托盘信息{_clrel[0].S_CNTR_CODE}!isFule" + _bbbb);
|
// if (_clrel[0].S_CNTR_CODE.StartsWith("TP") && _bbbb)
|
// {
|
// goto NormalArea;
|
// }
|
// if (!_clrel[0].S_CNTR_CODE.StartsWith("TP") && !_bbbb)
|
// {
|
// goto NormalArea;
|
// }
|
// LogHelper.Info("识别托盘类型。");
|
// if (_clrel[0].S_TYPE == size)
|
// {
|
// var _clcntitem = ContainerHelper.GetCntrItemRel(_clrel[0].S_CNTR_CODE.Trim());
|
// if (!_clcntitem.Any())
|
// {
|
// LogHelper.Info(last.S_LOC_CODE + $"货位 的托盘{_clrel[0].S_CNTR_CODE} 没有物料记录");
|
// goto NormalArea;
|
// }
|
// var _ci = _clcntitem[0];
|
// if (_ci.S_ITEM_CODE == ItemName && _ci.S_BATCH_NO == Batch)
|
// {
|
// ////不 用 管。
|
// }
|
// else
|
// goto NormalArea;
|
// }
|
// if (last != null)
|
// {
|
// var emptyList = rowlist.FindAll(x => x.N_COL > last.N_COL).OrderBy(x => x.N_COL).ToList();
|
// if (!t1)
|
// {
|
// if (last.N_CURRENT_NUM < last.N_CAPACITY && (MaxLayer == 0 || last.N_CURRENT_NUM < MaxLayer))
|
// endBit = last;
|
// else if (emptyList.Any())
|
// endBit = emptyList.FirstOrDefault();
|
// goto NormalArea;
|
// }
|
// // ↓↓↓ 变天了。 需要空位置了
|
// if (last.N_CURRENT_NUM < last.N_CAPACITY && (MaxLayer == 0 || last.N_CURRENT_NUM < MaxLayer))
|
// {
|
// if (emptyList.Any())
|
// {
|
// endBit = emptyList.First();
|
// goto NormalArea;
|
// }
|
// last.S_LOCK_STATE = "报废";
|
// last.T_EMPTY_TIME = new DateTime(1970, 1, 1, 1, 1, 1);
|
// LocationHelper.DoAction(db =>
|
// {
|
// db.Updateable(last).UpdateColumns(it => new { it.S_LOCK_STATE, it.T_EMPTY_TIME }).ExecuteCommand();
|
// return true;
|
// });
|
// }
|
// else if (emptyList.Count() == 0) goto NormalArea;// 一排已经满了, 不用隔了
|
// else
|
// {
|
// var e = emptyList.FirstOrDefault();
|
// if (emptyList.Count() == 1) //需要隔的是最后一个位子,就需要报废掉。 中间隔离就不用了。
|
// {
|
// e.S_LOCK_STATE = "报废";
|
// e.T_EMPTY_TIME = new DateTime(1970, 1, 1, 1, 1, 1);
|
// LocationHelper.DoAction(db =>
|
// {
|
// db.Updateable(e).UpdateColumns(it => new { it.S_LOCK_STATE, it.T_EMPTY_TIME }).ExecuteCommand();
|
// return true;
|
// });
|
// }
|
// else
|
// {
|
// emptyList.Remove(e);
|
// endBit = emptyList.First();
|
// goto NormalArea;
|
// }
|
// }
|
// }
|
// }
|
//}
|
|
#endregion
|
|
List<string> AlTask = new List<string>();
|
if (mmmmmnum > 0)
|
{
|
LocationHelper.DoAction(db =>
|
{
|
var tasks = db.Queryable<WMSTask>().Where(x => x.S_START_LOC == location && "未执行,已推送,执行中,开始取货,取货完成,开始卸货,卸货完成".Contains(x.S_B_STATE)).ToList();
|
LogHelper.Info(location + "起点(工单N_LimitNum:" + mmmmmnum + ")的运行中任务数量" + tasks.Count);
|
foreach (var task in tasks)
|
{
|
var _tloc = LocationHelper.GetLoc(task.S_END_LOC);
|
LogHelper.Info(location + $"起点的运行中任务{task.S_TASK_NO}-{task.S_END_LOC}{_tloc.S_LOCK_STATE}");
|
if (_tloc != null && _tloc.S_LOCK_STATE == "入库锁")
|
{
|
string si = _tloc.S_AREA_CODE + "_" + _tloc.N_ROW;
|
if (!AlTask.Contains(si)) { AlTask.Add(si); }
|
}
|
}
|
LogHelper.Info($"{workOrder.FuLe_PLine_No}{workOrder.SQL_PLineNo}成品任务中锁排{JsonConvert.SerializeObject(AlTask)}");
|
return true;
|
});
|
if (AlTask.Count() >= mmmmmnum)
|
{
|
LogHelper.Info($"{workOrder.FuLe_PLine_No}{workOrder.SQL_PLineNo}成品任务中锁排数{AlTask.Count()}不小于限制数{mmmmmnum},不在进行任务");
|
return false;
|
}
|
}
|
|
var Auto = true;//workOrder.S_Is_Auto.Trim() == "Y";
|
int[] rows = null;
|
///有指定排, 就入指定排。非auto ,找不到位置就return;
|
///没有指定排
|
if (!string.IsNullOrEmpty(workOrder.S_ROW))
|
{
|
var areaRows = workOrder.S_ROW.Split('$');
|
foreach (var item in areaRows)
|
{
|
if (string.IsNullOrEmpty(item.Trim()))
|
continue;
|
var rs = item.Split('=');
|
rows = Array.ConvertAll(rs[rs.Length - 1].Split('-'), Convert.ToInt32);
|
|
#region 优先指定排,有补就补,没补入空。
|
var _tempList = new List<Location>();
|
var Btype = size;
|
//var bbbbbbbbt = LocationHelper.GetList<BXJHB>(X => X.B_TYPE == Btype).FirstOrDefault();
|
//if (bbbbbbbbt == null)
|
//{
|
// LogHelper.Debug(Btype + "满框下线 没有配置版型集合对应");
|
// return false;
|
//}
|
string usffix = Settings.areaSuffix(Btype); // bbbbbbbbt.S_B_TYPE;
|
string are = rs.Length > 1 ? rs[0] : area; //area;
|
string area1 = are + usffix;
|
LogHelper.Info(area1 + " 库区的板型" + Btype);
|
if (!area1.Contains("_")) LogHelper.Info(area1 + " 库区的板型" + Btype + "不正确");
|
//找当前库区无锁不满的排
|
var _arealist = LocationHelper.GetLocList(x => x.S_AREA_CODE == area1 && x.S_LOCK_STATE != "报废");
|
|
var _arealock = _arealist.FindAll(x => x.S_LOCK_STATE != "无").Select(x => x.N_ROW).Distinct();
|
LogHelper.Info(area1 + " 库区 非报废货位量" + _arealist.Count + ":非正常货位锁排" + JsonConvert.SerializeObject(_arealock));
|
var lcollist = LocationHelper.GetRowLock(area1)?.Select(x => x.N_ROW);
|
_arealock = _arealock.Concat(lcollist).Distinct();
|
if (_arealock.Any())
|
_arealist.RemoveAll(x => _arealock.Contains(x.N_ROW));
|
|
var isFule = _bbbb;
|
var thisrowlocli = _arealist.FindAll(x => rows.Contains(x.N_ROW));
|
if (thisrowlocli.Any())
|
foreach (var x in thisrowlocli.OrderBy(x => x.N_ROW).GroupBy(x => x.N_ROW))
|
{
|
//排最外侧有货位
|
var xlist = x.OrderBy(xx => xx.N_COL).ToList();
|
var _cl = xlist.FindAll(xx => xx.N_CURRENT_NUM > 0).LastOrDefault();
|
if (_cl == null)
|
{
|
//这是一个空排
|
_tempList.AddRange(xlist);
|
continue;
|
}
|
// 最外侧货位是是同.. 的话 就可以入了。
|
var _clrel = LocationHelper.GetLocCntrRel(_cl.S_LOC_CODE);
|
if (!_clrel.Any())
|
{
|
LogHelper.Info(_cl.S_LOC_CODE + " 没有货位托盘信息!");
|
continue;
|
}
|
//板型相同
|
var _clrel0 = _clrel.OrderByDescending(xx => xx.T_CREATE).First();
|
LogHelper.Info(_cl.S_LOC_CODE + $" 货位托盘信息{_clrel0.S_CNTR_CODE}!isFule" + isFule);
|
if (_clrel0.S_CNTR_CODE.StartsWith("TP") && isFule)
|
{
|
continue;
|
}
|
if (!_clrel0.S_CNTR_CODE.StartsWith("TP") && !isFule)
|
{
|
continue;
|
}
|
LogHelper.Info("识别托盘类型。");
|
if (_clrel0.S_TYPE == Btype)
|
{
|
var _clcntitem = ContainerHelper.GetCntrItemRel(_clrel0.S_CNTR_CODE.Trim());
|
if (!_clcntitem.Any())
|
{
|
LogHelper.Info(_cl.S_LOC_CODE + $"货位 的托盘{_clrel0.S_CNTR_CODE} 没有物料记录");
|
continue;
|
}
|
var _ci = _clcntitem.OrderByDescending(xx => xx.T_CREATE).First();
|
if ((_ci.S_ITEM_CODE == ItemName || _ci.S_ITEM_CODE == ItemCode) && _ci.ItemLayer == workOrder.ItemLayer)
|
{
|
DateTime bft = DateTime.Now;
|
var Before_task = TaskHelper.GetTask(z => z.S_CNTRS.Contains(_ci.S_CNTR_CODE), y => y.T_CREATE, SqlSugar.OrderByType.Desc);
|
|
LogHelper.Info($"找到匹配货位{_cl.S_LOC_CODE},查看货位最后一个托盘的任务{JsonConvert.SerializeObject(Before_task)} 如果没有,就默认是同一日期,不隔开");
|
|
if (Before_task != null)
|
{
|
bft = Before_task.T_CREATE;
|
}
|
bool sameDate = bft.Date == DateTime.Now.Date;// string.IsNullOrEmpty(_ci.S_BATCH_NO) ? true : _ci.S_BATCH_NO == Batch;
|
//not full
|
LogHelper.Info($"找到匹配货位{_cl.S_LOC_CODE} {bft.Date}=={DateTime.Now.Date}?{sameDate}");
|
if (_cl.N_CURRENT_NUM < _cl.N_CAPACITY && (MaxLayer == 0 || (MaxLayer > 0 && _cl.N_CURRENT_NUM < MaxLayer)))
|
//if (_cl.N_CURRENT_NUM < _cl.N_CAPACITY && (MaxLayer == 0 || (MaxLayer > 0 && _cl.N_CURRENT_NUM / 2 < MaxLayer)))
|
{
|
if (sameDate)
|
endBit = _cl;
|
else
|
{
|
var empty = xlist.FindAll(xx => xx.N_CURRENT_NUM == 0 && xx.N_COL > _cl.N_COL);
|
if (!empty.Any())
|
{
|
//这一排没有空位
|
}
|
else
|
{
|
if (empty.Count > 1)
|
{
|
endBit = empty.Skip(1).FirstOrDefault();
|
}
|
}
|
}
|
}
|
else//full
|
{
|
var empty = xlist.FindAll(xx => xx.N_CURRENT_NUM == 0 && xx.N_COL > _cl.N_COL);
|
if (!empty.Any())
|
{
|
//这一排没有空位
|
}
|
else
|
{
|
if (sameDate)
|
endBit = empty.FirstOrDefault();
|
else
|
{ //满了, 中间间隔一个空位。
|
if (empty.Count > 1)
|
{
|
endBit = empty.Skip(1).FirstOrDefault();
|
}
|
}
|
}
|
}
|
}
|
}
|
if (endBit != null)
|
break;
|
}
|
if (endBit == null && _tempList.Any())
|
{
|
LogHelper.Info(" ar_RplaceRow over!");
|
var ar_RplaceRows = LocationHelper.GetLocList(x => x.S_AREA_CODE != area1 && x.S_AREA_CODE.Contains(are) && x.S_LOCK_STATE != "报废");//.Select(x => x.N_ROW).Distinct();
|
//var ar_RplaceRow1 = ar_RplaceRows.FindAll(x => x.S_LOCK_STATE != "无").Select(x => x.N_ROW).Distinct();
|
IEnumerable<int> ar_RplaceRow1 = ar_RplaceRows.FindAll(x => "入库锁;出库锁".Contains(x.S_LOCK_STATE?.Trim())).Select(x => x.N_ROW).Distinct();
|
LogHelper.Info(" 有锁排 - " + JsonConvert.SerializeObject(ar_RplaceRow1)); //LogHelper.Info(" 有锁排 - " + JsonConvert.SerializeObject(ar_RplaceRow1));
|
var ar_RplaceRow2 = ar_RplaceRows.FindAll(x => x.N_CURRENT_NUM > 0).Select(x => x.N_ROW).Distinct();
|
LogHelper.Info(" 有货排: - " + JsonConvert.SerializeObject(ar_RplaceRow2));
|
var ar_RplaceRow_rowlock = LocationHelper.GetRowLock(x => x.S_AREA_CODE.Contains(are))?.Select(x => x.N_ROW);
|
|
var ar_RplaceRow = ar_RplaceRow1.Concat(ar_RplaceRow2).Concat(ar_RplaceRow_rowlock).Distinct();
|
|
if (ar_RplaceRow.Any())
|
{
|
LogHelper.Info("排除非空排 - " + JsonConvert.SerializeObject(ar_RplaceRow));
|
_tempList.RemoveAll(x => ar_RplaceRow.Contains(x.N_ROW));
|
}
|
if (_tempList.Any())//三个库区的交集空排
|
{
|
endBit = _tempList.OrderBy(x => x.N_ROW).ThenBy(x => x.N_COL).FirstOrDefault();
|
}
|
}
|
|
#endregion
|
|
if (endBit != null)
|
break;
|
}
|
}
|
if (!Auto && endBit == null)
|
{
|
LogHelper.Info($"{plc.deviceName} {location} 非自动入排{workOrder.S_ROW}>.{JsonConvert.SerializeObject(rows)} 没有对应终点,终止!");
|
return false;
|
}
|
|
NormalArea:
|
//任务切面 产线申请的所有 库区和排。
|
//if (_audiolist.Any())
|
//{
|
// var pass = _audiolist.Find(x => x.N_AUDIO == 1);
|
// if (pass != null)
|
// {
|
// endBit = LocationHelper.GetLoc(pass.S_LOC_CODE); //GetareaLocationByBtypeandBatch(ItemName, pass.S_Area, size, Batch, _bbbb, MaxLayer, true, pass.N_ROW);
|
// if (endBit != null)
|
// {
|
// if (endBit.N_CURRENT_NUM == 0)
|
// SendAudio = false;
|
// else
|
// {
|
// endBit = null;
|
// SendAudio = true;
|
// }
|
// }
|
// }
|
//}
|
|
//先找未满和 任务排
|
if (endBit == null && !string.IsNullOrEmpty(area))
|
{
|
endBit = GetareaLocationByBtypeandBatch(ItemInfo, area, size, Batch, _bbbb, MaxLayer, workOrder, true);
|
}
|
if (endBit == null)
|
{
|
foreach (var _ar in areaLi)
|
{
|
if (area == _ar)
|
continue;
|
endBit = GetareaLocationByBtypeandBatch(ItemInfo, _ar, size, Batch, _bbbb, MaxLayer, workOrder, true);
|
if (endBit != null)
|
{ break; }
|
}
|
}
|
//if (endBit != null)
|
// SendAudio = false;
|
|
|
//找空排
|
if (endBit == null && !string.IsNullOrEmpty(area))
|
{
|
endBit = GetareaLocationByBtypeandBatch(ItemInfo, area, size, Batch, _bbbb, MaxLayer, workOrder);
|
}
|
if (endBit == null)
|
{
|
foreach (var _ar in areaLi)
|
{
|
if (area == _ar)
|
continue;
|
endBit = GetareaLocationByBtypeandBatch(ItemInfo, _ar, size, Batch, _bbbb, MaxLayer, workOrder);
|
if (endBit != null)
|
{ break; }
|
}
|
}
|
}
|
|
#region 筛选终点
|
|
if (endBit != null)
|
{
|
//if (SendAudio)
|
//{
|
// TaskHelper.InsertT(new TaskAudio
|
// {
|
// S_LOC_CODE = endBit.S_LOC_CODE,
|
// S_Area = endBit.S_AREA_CODE,
|
// N_AUDIO = 0,
|
// N_ROW = endBit.N_ROW,
|
// S_PlineNo = plc.deviceName,
|
// S_Note = $"[{DateTime.Now}-创建审核]",
|
// CreateTime = DateTime.Now
|
// });
|
// LocationHelper.LockLoc(endBit.S_LOC_CODE, "空间锁");
|
// return false;
|
//}
|
int endLayer = endBit.N_CURRENT_NUM + 1;
|
//int endLayer = endBit.N_CURRENT_NUM /2+ 1;
|
var carryCntrs = rel.Select(x => x.S_CNTR_CODE).ToList();//DateTime.Now.ToString("yyMMddHHmmss") };
|
var bb = TaskProcess.CreateTransport(workOrder.SQL_WorkNo, location, endBit.S_LOC_CODE, (_bbbb ? "Fu" : "") + "成品满框-入库", carryCntrs, 1, endLayer, carryCntrs.Count, plc.taskPri);
|
if (bb)
|
{
|
//if (_audiolist.Any())
|
//{
|
// var _al = _audiolist.FindAll(x => 0 < x.N_AUDIO && x.N_AUDIO < 3);
|
// foreach (var item in _al)
|
// {
|
// LogHelper.Info($"{item.S_PlineNo} {item.CreateTime}任务执行.废弃");
|
// item.S_Note += $"[{DateTime.Now}-任务执行.废弃]";
|
// item.N_AUDIO = 3;
|
// TaskHelper.DoUpdate(item, x => new { x.S_Note, x.N_AUDIO });
|
// }
|
//}
|
|
var flwords = LocationHelper.GetRecord(x => x.S_IP_Address == plc.address);
|
LogHelper.Info(plc.address + "" + JsonConvert.SerializeObject(flwords.Select(x => x.S_AREA_CODE)));
|
InworkRecord flword = new InworkRecord
|
{
|
SQL_PLineNo = workOrder.SQL_PLineNo,
|
S_Fule_Code = workOrder.FuLe_PLine_No,
|
S_IP_Address = plc.address,
|
N_ROW = endBit.N_ROW + "",
|
S_AREA_CODE = endBit.S_AREA_CODE,
|
T_MODIFY = DateTime.Now
|
};
|
LocationHelper.DoAction(db =>
|
{
|
//db.BeginTran();
|
db.Insertable<LocCntrRel>(locr).ExecuteCommand();
|
|
db.Insertable<CntrItemRel>(cnir).ExecuteCommand();
|
//db.Ado.CommitTran();
|
if (!flwords.Any())
|
{
|
db.Insertable<InworkRecord>(flword).ExecuteCommand();
|
}
|
else
|
{
|
var _bb = false;
|
var fd = flwords.Find(x => x.S_AREA_CODE.Trim() == flword.S_AREA_CODE.Trim() && x.N_ROW.Trim() == flword.N_ROW.Trim());
|
LogHelper.Info(plc.address + "限制数:" + mmmmmnum + ";找到已存在记录?" + (fd != null));
|
if (mmmmmnum > 0)
|
{
|
//限制数量。
|
|
if (fd == null)
|
{
|
if (flwords.Count >= mmmmmnum)
|
{
|
LogHelper.Info(plc.address + "超限制数>");
|
var iCount = flwords.Count - mmmmmnum + 1;
|
var fds = flwords.OrderBy(x => x.T_MODIFY).Take(iCount).ToList();
|
LogHelper.Info(plc.address + "超限制数 删除 " + JsonConvert.SerializeObject(fds.Select(x => x.S_AREA_CODE)));
|
db.Deleteable<InworkRecord>(fds).ExecuteCommand();
|
}
|
db.Insertable<InworkRecord>(flword).ExecuteCommand();
|
}
|
else _bb = true;
|
}
|
else
|
{
|
// 只留一条。
|
if (flwords.Count > 1)
|
{
|
db.Deleteable<InworkRecord>(flwords).ExecuteCommand();
|
db.Insertable<InworkRecord>(flword).ExecuteCommand();
|
}
|
else
|
{
|
_bb = true;
|
}
|
}
|
if (_bb)
|
{
|
flword = fd;
|
flword.SQL_PLineNo = workOrder.SQL_PLineNo;
|
flword.S_Fule_Code = workOrder.FuLe_PLine_No;
|
flword.N_ROW = endBit.N_ROW + "";
|
flword.S_AREA_CODE = endBit.S_AREA_CODE;
|
flword.T_MODIFY = DateTime.Now;
|
db.Updateable(flword).UpdateColumns(it => new
|
{
|
it.SQL_PLineNo,
|
it.S_Fule_Code,
|
it.N_ROW,
|
it.S_AREA_CODE,
|
it.T_MODIFY
|
}).ExecuteCommand();
|
}
|
//flword.S_AREA_CODE = endBit.S_AREA_CODE;
|
//flword.N_ROW = endBit.N_ROW + "";
|
//flword.T_MODIFY = DateTime.Now;
|
//db.Updateable<InworkRecord>(flword).UpdateColumns(it => new { it.S_AREA_CODE, it.N_ROW, it.T_MODIFY }).ExecuteCommand();
|
}
|
|
return true;
|
|
});
|
LogHelper.Info($"{plc.deviceName} 当前机器{location}位置状态{p0} 正在执行取满任务");
|
}
|
result = bb;
|
}
|
else
|
{
|
LogHelper.Info($"成品终点没有可用空排,空位");
|
}
|
|
#endregion
|
}
|
}
|
else
|
{
|
//LogHelper.Info($"瓶PEM机:{plc.deviceName} 当前机器2个位置 有一个有任务,不可触发满托下线", "瓶坯机");
|
//if (p0 != "无")
|
LogHelper.Info($"{plc.deviceName} {location}位置状态{p0} 正在执行{(p0.Replace("锁", "") == "入库" ? "送空" : "取满")}任务");
|
|
}
|
|
}
|
return result;
|
}
|
|
|
|
|
///<summary>
|
/// 收到关门22信号以后再发送 翻斗信号。后来。门信号清了以后,直接发翻斗,可以触发关门。
|
/// 所以改为, 收到1025 清了开门信号,就发翻斗。
|
/// </summary>
|
[Obsolete("更换逻辑,不用这个标识了")]
|
public static readonly List<string> FDJ_writeFD = new List<string>();
|
|
//卸货后给 0 收到11 也写0 收到12 开始累加 - 连续10次后的11 才
|
public static Dictionary<string, int> FJD_wwwwFD = new Dictionary<string, int>();
|
|
|
internal static void AnalysisBottleCapTipper(string data, Settings.deviceInfo plc)
|
{
|
//LogHelper.Info($"{plc.deviceName}-{plc.address}-{plc.deviceType}-data:{data}。 ");
|
bool containsKey = true;
|
int llll = 0;
|
if (!FJD_wwwwFD.TryGetValue(plc.deviceName.Trim(), out llll))
|
{
|
containsKey = false;
|
LogHelper.Info(plc.location[0] + "交管缓存 10 信号失败。 数量:" + llll);
|
llll = 6;
|
}
|
else
|
{
|
LogHelper.Info(plc.location[0] + "交管缓存 10 信号成功。 数量:" + llll);
|
}
|
bool flag = data.Length == 2;
|
if (flag)
|
{
|
//LogHelper.Info(string.Concat(new string[]
|
//{
|
// "翻斗机门 ",
|
// plc.deviceNo[1],
|
// " - 信号: ",
|
// data,
|
// " 门状态:(1开2关) ",
|
// data.Substring(3, 1)
|
// }), "自动门");
|
string s = "2";// data.Substring(3, 1);
|
|
//bool flag4 = DeviceProcess.doorStatus.Keys.Contains(plc.deviceNo[1]);
|
//if (flag4)
|
//{
|
// DeviceProcess.doorStatus[plc.deviceNo[1]].info = s;
|
// DeviceProcess.doorStatus[plc.deviceNo[1]].modify = DateTime.Now;
|
//}
|
//else
|
//{
|
// DeviceProcess.doorStatus.Add(plc.deviceNo[1], new DeviceProcess.signalInfo
|
// {
|
// info = data.Substring(3, 1),
|
// modify = DateTime.Now
|
// });
|
//}
|
//if (data.Substring(1, 1) == "1")
|
//{
|
// LogHelper.Info(plc.location[0] + "读到11信号。(12信号持续数量):" + llll);
|
// if (llll < 10)
|
// {
|
// llll = 0;
|
// LogHelper.Info(plc.deviceName + "读到11信号,或连续12信号不足10次");
|
// if (containsKey)
|
// FJD_wwwwFD[plc.deviceName.Trim()] = llll;
|
// else FJD_wwwwFD.Add(plc.deviceName.Trim(), llll);
|
|
// return;
|
// }
|
//}
|
//else
|
if (data.Substring(1, 1) == "0" || data.Substring(1, 1) == "2")
|
{
|
LogHelper.Info(plc.location[0] + $"读到1 0/2信号。(1 0/2信号持续数量):" + llll);
|
llll++;
|
if (containsKey)
|
FJD_wwwwFD[plc.deviceName.Trim()] = llll;
|
else FJD_wwwwFD.Add(plc.deviceName.Trim(), llll);
|
}
|
|
//if (llll < 10)
|
//{
|
// LogHelper.Info(plc.deviceName + "读到11信号 ,或连续12信号不足10次(" + llll + "次)");
|
// return;
|
//}
|
|
LogHelper.Info(plc.deviceName + "查看翻斗鸡空筐位" + (data.Substring(1, 1) == "1").ToString() + LocationHelper.CheckLocFree(plc.location[0]).ToString(), "翻斗机");
|
bool flag5 = data.Substring(1, 1) == "1" && LocationHelper.CheckLocFree(plc.location[0]) && s == "2";
|
if (flag5)
|
{
|
bool flag6 = DeviceProcess.FDJ_writeFD.Contains(plc.deviceName);
|
if (flag6)
|
{
|
LogHelper.Info(plc.deviceName + "翻斗鸡卸货后, 翻斗信号还未重置。", "翻斗机");
|
}
|
else
|
{
|
//if (llll > 10)
|
//{
|
// LogHelper.Info(plc.deviceName + "交管给翻斗信号后还没有翻斗", "翻斗机");
|
// return;
|
//}
|
//else
|
//{
|
// LogHelper.Info(plc.deviceName + "交管给翻斗信号后 已翻斗:" + llll, "翻斗机");
|
//}
|
|
WorkOrder workOrder = WCSHelper.GetWorkOrder(plc.deviceName);
|
bool flag7 = workOrder == null;
|
if (flag7)
|
{
|
LogHelper.Info(plc.deviceName + "没有【执行中】的工单", "翻斗机");
|
if (containsKey)
|
FJD_wwwwFD[plc.deviceName.Trim()] = 1;
|
else FJD_wwwwFD.Add(plc.deviceName.Trim(), 1);
|
}
|
else
|
{
|
Location loc2 = LocationHelper.GetLoc(plc.location[0]);
|
bool flag8 = loc2.S_LOCK_STATE.Trim() != "无";
|
if (flag8)
|
{
|
LogHelper.Info(string.Concat(new string[]
|
{
|
plc.deviceName,
|
" 货位",
|
plc.location[0],
|
"的状态位",
|
loc2.S_LOCK_STATE,
|
",无法生成任务"
|
}), "翻斗机");
|
}
|
else
|
{
|
LogHelper.Info(plc.deviceName + " 翻斗机 呼叫" + ((workOrder.SQL_UsingNow.Trim() == "Y") ? "即产" : "出库") + "任务", "翻斗机");
|
bool flag9 = loc2.N_CURRENT_NUM > 0;
|
if (flag9)
|
{
|
DateTime? time = LocationHelper.GetT_FULL_TIME(plc.location[0]);
|
#region 反编译 日志参数
|
|
string[] array = new string[6];
|
array[0] = plc.location[0];
|
array[1] = ":托盘放置时间:(";
|
int num = 2;
|
DateTime? dateTime = time;
|
array[num] = dateTime.ToString();
|
array[3] = ") 货位托盘数量(";
|
array[4] = loc2.N_CURRENT_NUM.ToString();
|
array[5] = ")";
|
#endregion
|
LogHelper.Info(string.Concat(array), "翻斗机");
|
|
bool flag10 = time == null || loc2 == null || loc2.N_CURRENT_NUM == 0;
|
if (!flag10)
|
{
|
var flag11 = DateTime.Now.Subtract(time ?? DateTime.Now).TotalSeconds;
|
if (flag11 > 30)
|
{
|
|
//if (data.Substring(1, 1) == "1")
|
//{
|
LogHelper.Info(plc.location[0] + "读到11信号。(1 0/2信号持续数量):" + llll);
|
//if (flag11 < 3.0)
|
if (llll < 0)
|
{
|
//llll = 0;
|
LogHelper.Info(plc.deviceName + "读到11信号,但是没出现过1 0/2");
|
//if (containsKey)
|
// FJD_wwwwFD[plc.deviceName.Trim()] = llll;
|
//else FJD_wwwwFD.Add(plc.deviceName.Trim(), llll);
|
|
return;
|
}
|
//}
|
|
var b = TaskProcess.FDJTakeEmpyt2(plc, workOrder);
|
|
LogHelper.Info(plc.location[0] + "读到11信号, 重置1 0/2信号缓存数量 取空任务创建是否成功:" + b);
|
if (b)
|
{
|
if (containsKey)
|
FJD_wwwwFD[plc.deviceName.Trim()] = 1;
|
else FJD_wwwwFD.Add(plc.deviceName.Trim(), 1);
|
}
|
}
|
else
|
{
|
///-
|
LogHelper.Info($"{plc.deviceName} 货位 {plc.location} 满框卸货不足30S缓冲时间。 ");
|
|
//if (time != null && DateTime.Now.Subtract(time ?? DateTime.Now).TotalSeconds < 30)
|
//{
|
LogHelper.Info($"翻斗机满框放下时间{time}不足30秒, 回写翻斗信号", "翻斗机");
|
PlcHelper.SendHex(plc.address, $"3f 00 11 0d 0a");
|
|
if (containsKey)
|
FJD_wwwwFD[plc.deviceName.Trim()] = 0;
|
else FJD_wwwwFD.Add(plc.deviceName.Trim(), 0);
|
|
return;
|
//}
|
}
|
}
|
}
|
else
|
{
|
if (loc2.N_CURRENT_NUM == 0)
|
TaskProcess.TakeFull2FDJ(plc, workOrder);
|
else LogHelper.Info(" 送满任务 无筐或者无置满时间 不生成。" + JsonConvert.SerializeObject(loc2));
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info("翻斗机信号不明!", "翻斗机");
|
}
|
}
|
|
#endregion
|
|
internal static void AnalysisBottleCapTipper10_(string data, Settings.deviceInfo plc)
|
{
|
bool containsKey = true;
|
int llll = 0;
|
if (!FJD_wwwwFD.TryGetValue(plc.deviceName.Trim(), out llll))
|
{
|
containsKey = false;
|
LogHelper.Info(plc.location[0] + "交管缓存 10 信号失败。 数量:" + llll);
|
llll = 6;
|
}
|
else
|
{
|
LogHelper.Info(plc.location[0] + "交管缓存 10 信号成功。 数量:" + llll);
|
}
|
bool flag = data.Length == 2;
|
if (flag)
|
{
|
|
string s = "2";// data.Substring(3, 1);
|
|
if (data.Substring(1, 1) == "0")
|
{
|
LogHelper.Info(plc.location[0] + "读到10信号。(10信号持续数量):" + llll);
|
llll++;
|
if (containsKey)
|
FJD_wwwwFD[plc.deviceName.Trim()] = llll;
|
else FJD_wwwwFD.Add(plc.deviceName.Trim(), llll);
|
}
|
|
LogHelper.Info(plc.deviceName + "查看翻斗鸡空筐位" + (data.Substring(1, 1) == "1").ToString() + LocationHelper.CheckLocFree(plc.location[0]).ToString(), "翻斗机");
|
bool flag5 = data.Substring(1, 1) == "1" && LocationHelper.CheckLocFree(plc.location[0]) && s == "2";
|
if (flag5)
|
{
|
bool flag6 = DeviceProcess.FDJ_writeFD.Contains(plc.deviceName);
|
if (flag6)
|
{
|
LogHelper.Info(plc.deviceName + "翻斗鸡卸货后, 翻斗信号还未重置。", "翻斗机");
|
}
|
else
|
{
|
WorkOrder workOrder = WCSHelper.GetWorkOrder(plc.deviceName);
|
bool flag7 = workOrder == null;
|
if (flag7)
|
{
|
LogHelper.Info(plc.deviceName + "没有【执行中】的工单", "翻斗机");
|
}
|
else
|
{
|
Location loc2 = LocationHelper.GetLoc(plc.location[0]);
|
bool flag8 = loc2.S_LOCK_STATE.Trim() != "无";
|
if (flag8)
|
{
|
LogHelper.Info(string.Concat(new string[]
|
{
|
plc.deviceName,
|
" 货位",
|
plc.location[0],
|
"的状态位",
|
loc2.S_LOCK_STATE,
|
",无法生成任务"
|
}), "翻斗机");
|
}
|
else
|
{
|
LogHelper.Info(plc.deviceName + " 翻斗机 呼叫" + ((workOrder.SQL_UsingNow.Trim() == "Y") ? "即产" : "出库") + "任务", "翻斗机");
|
bool flag9 = loc2.N_CURRENT_NUM > 0;
|
if (flag9)
|
{
|
DateTime? time = LocationHelper.GetT_FULL_TIME(plc.location[0]);
|
#region 反编译 日志参数
|
|
string[] array = new string[6];
|
array[0] = plc.location[0];
|
array[1] = ":托盘放置时间:(";
|
int num = 2;
|
DateTime? dateTime = time;
|
array[num] = dateTime.ToString();
|
array[3] = ") 货位托盘数量(";
|
array[4] = loc2.N_CURRENT_NUM.ToString();
|
array[5] = ")";
|
#endregion
|
LogHelper.Info(string.Concat(array), "翻斗机");
|
|
bool flag10 = time == null || loc2 == null || loc2.N_CURRENT_NUM == 0;
|
if (!flag10)
|
{
|
var flag11 = DateTime.Now.Subtract(time ?? DateTime.Now).TotalSeconds;
|
if (flag11 > 30)
|
{
|
LogHelper.Info(plc.location[0] + "读到11信号。(10信号持续数量):" + llll);
|
if (llll < 1)
|
{
|
LogHelper.Info(plc.deviceName + "读到11信号,但连续10信号不足1次");
|
return;
|
}
|
var b = TaskProcess.FDJTakeEmpyt2(plc, workOrder);
|
LogHelper.Info(plc.location[0] + "读到11信号, 重置10信号缓存数量 取空任务创建是否成功:" + b);
|
if (b)
|
{
|
if (containsKey)
|
FJD_wwwwFD[plc.deviceName.Trim()] = 0;
|
else FJD_wwwwFD.Add(plc.deviceName.Trim(), 0);
|
}
|
}
|
else
|
{
|
LogHelper.Info($"{plc.deviceName} 货位 {plc.location} 满框卸货不足30S缓冲时间。 ");
|
LogHelper.Info($"翻斗机满框放下时间{time}不足30秒, 回写翻斗信号", "翻斗机");
|
PlcHelper.SendHex(plc.address, $"3f 00 11 0d 0a");
|
return;
|
}
|
}
|
}
|
else
|
{
|
if (loc2.N_CURRENT_NUM == 0)
|
{
|
TaskProcess.TakeFull2FDJ(plc, workOrder);
|
}
|
else LogHelper.Info(" 送满任务 无筐或者无置满时间 不生成。" + JsonConvert.SerializeObject(loc2));
|
}
|
}
|
}
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info("翻斗机信号不明!", "翻斗机");
|
}
|
}
|
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="data"></param>
|
/// <param name="plc"></param>
|
internal static void AnalysisBottleCapTipper46(string data, Settings.deviceInfo plc)
|
{
|
//LogHelper.Info($"{plc.deviceName}-{plc.address}-{data}");
|
bool containsKey = true;
|
int llll = 0;
|
if (data.Length > 1 && data.Length % 2 == 0)
|
{
|
|
var workOrder = WCSHelper.GetPGWorkOrder(plc.deviceName);
|
if (workOrder == null)
|
{
|
LogHelper.Info(plc.deviceName + "没有【执行中】的工单", "翻斗机");
|
return;
|
}
|
var USING = workOrder.SQL_UsingNow == "Y";
|
int _sii = 0;
|
if (plc.deviceNo.Length > 0)
|
{
|
for (int i = 0; i < plc.deviceNo.Length; i++)
|
{
|
string _dorNo = plc.deviceNo[i];
|
//LogHelper.Info($"{plc.deviceName}{_dorNo} v {(i + 1) * 2}>-{data.Length}");
|
if (!string.IsNullOrEmpty(_dorNo))
|
{
|
if ((i + 1) * 2 > data.Length) break;
|
|
bool flag4 = DeviceProcess.doorStatus.Keys.Contains(_dorNo);
|
if (flag4)
|
{
|
DeviceProcess.doorStatus[_dorNo].info = data.Substring(2 * i + 1, 1);
|
DeviceProcess.doorStatus[_dorNo].modify = DateTime.Now;
|
}
|
else
|
{
|
DeviceProcess.doorStatus.Add(_dorNo, new DeviceProcess.signalInfo
|
{
|
info = data.Substring(2 * i + 1, 1),
|
modify = DateTime.Now
|
});
|
}
|
LogHelper.Info($"{plc.deviceName}{_dorNo} v {data.Substring(2 * i + 1, 1)}");
|
}
|
else
|
{
|
if (_sii == 0)
|
{
|
_sii = 2 * i + 1;
|
}
|
//LogHelper.Info($"{plc.deviceName}翻斗信号位置 v {_sii}");
|
}
|
}
|
}
|
//if (data.Substring(_sii, 1) == "0")
|
//{
|
// LogHelper.Info(plc.location[0] + "读到10信号。(10信号持续数量):" + llll);
|
// llll++;
|
// if (containsKey)
|
// FJD_wwwwFD[plc.deviceName.Trim()] = llll;
|
// else FJD_wwwwFD.Add(plc.deviceName.Trim(), llll);
|
// return;
|
//}
|
|
var location = plc.location[0];
|
var _loc = LocationHelper.GetLoc(location);
|
|
if (!(_loc.S_LOCK_STATE == "无" && data.Substring(_sii, 1) == "1"))
|
return;
|
|
var time = _loc?.T_FULL_TIME;
|
LogHelper.Info(location + ":托盘放置时间:(" + time + ") 货位托盘数量(" + _loc?.N_CURRENT_NUM + ")");
|
|
List<LocCntrRel> cntrStart = null;
|
if (time == null)
|
{
|
if (_loc.N_CURRENT_NUM == 1)
|
{
|
cntrStart = LocationHelper.GetLocCntrRel(location);
|
time = cntrStart.FirstOrDefault()?.T_CREATE;
|
|
if (time == null)
|
{
|
LogHelper.Info(plc.deviceName + ">>" + location + "货位托盘数量(" + _loc?.N_CURRENT_NUM + ") 但是找不到托盘数据。 终止");
|
return;
|
}
|
}
|
}
|
|
if (_loc.N_CURRENT_NUM == 0)//time == null || _loc == null ||
|
{
|
//搬走了。 如果本来就空的还给11 那就不是我的问题了。
|
// 后改 TODO - 送空框任务。
|
/// 取货时 给个 Empty_time
|
/// 信号不清的, 读到EmptyTime + 满信号 = 送空托。
|
/// 同时清掉EmtpyTimt 这样空托任务取消了,也不会循环触发。
|
//var EMPTYTIME = _loc?.T_EMPTY_TIME;
|
//if (EMPTYTIME == null || _loc == null || _loc?.N_CURRENT_NUM > 0)
|
//{
|
// return;
|
//}
|
|
|
|
LocationHelper.TakeEmptyToBottleBoyd(new WMSTask
|
{
|
S_START_LOC = location,
|
});
|
return;
|
}
|
|
//托盘放下 1分钟内 下空请求,都不处理。
|
else if (DateTime.Now.Subtract((DateTime)time).Minutes < 1)
|
{
|
PlcHelper.SendHex(plc.address, "3F00110d0a");
|
return;
|
}
|
|
LogHelper.Info($"翻斗机:{plc.deviceName} 下线信号:{location} 查询工单{workOrder.SQL_WorkNo}");
|
|
LogHelper.Info(plc.location[0] + "读到11信号。(10信号持续数量):" + llll);
|
var _i = -1;
|
if (llll < _i)
|
{
|
LogHelper.Info(plc.deviceName + $"读到11信号,但连续10信号不足{_i}次");
|
return;
|
}
|
|
if (cntrStart == null)
|
cntrStart = LocationHelper.GetLocCntrRel(location);
|
//关联表。 - 托盘决定去哪 - 工单可能临时切换。
|
if (cntrStart.Count == 1)
|
{
|
LogHelper.Info($"查找{location}对应终点->即产?{workOrder.SQL_UsingNow.Trim()}");
|
Location endBit = null;
|
var Cont = cntrStart.FirstOrDefault();
|
int endLayer = 1;
|
string Desc = "";
|
var USING2 = false;
|
if (Cont.S_CNTR_CODE.StartsWith("J"))
|
{
|
Desc = "翻斗机即产空筐下线";
|
USING2 = true;
|
}
|
else
|
{
|
USING2 = false;
|
Desc = "翻斗机库存空筐下线";
|
}
|
//var ba = "";
|
var ba2 = Settings.GetBolAreaList().Find(x => x.DeviceName == plc.deviceName && x.deviceType == plc.deviceType);
|
if (ba2 == null)
|
{
|
LogHelper.Info($"{plc.deviceName}-{workOrder.SQL_WorkNo}的BolArea 未配置。");
|
return;
|
}
|
List<string> areaList = new List<string> { (plc.deviceType == 6 ? "WJGRGDKQ" : "SGRGDKQ"), ba2.NotUsingEmpty };
|
if (plc.deviceType == 10)
|
{
|
areaList = new List<string> { ba2.NotUsingEmpty };
|
}
|
goturunnnn:
|
var area = areaList.FirstOrDefault();
|
if (areaList.Count > 0) areaList.Remove(area);
|
|
if (USING2)
|
{
|
areaList.Clear();
|
area = ba2.UsingEmpty;
|
|
LogHelper.Info($"翻斗机{plc.deviceName} 筛选即产终点库区{area}");
|
var _endLoclist = LocationHelper.GetAreaNormalLocList(area);
|
foreach (var item in _endLoclist.OrderBy(x => x.N_ROW).GroupBy(x => x.N_ROW))
|
{
|
var _ll = item.OrderBy(x => x.N_COL).ToList();
|
var fulast = _ll.FindAll(x => x.N_CURRENT_NUM > 0).LastOrDefault();
|
if (fulast != null && fulast.N_CURRENT_NUM < fulast.N_CAPACITY)
|
{
|
endBit = fulast;
|
}
|
else
|
{
|
if (fulast == null) endBit = _ll.FirstOrDefault();
|
else endBit = _ll.Find(x => x.N_COL > fulast.N_COL);
|
}
|
|
if (endBit != null) { break; }
|
}
|
LogHelper.Info($"翻斗机 筛选J终点 endbit:{JsonConvert.SerializeObject(endBit)}");
|
|
}
|
else
|
{
|
LogHelper.Info($"翻斗机{plc.deviceName} 筛选F即产终点库区{area}");
|
var _endLoclist = LocationHelper.GetAreaNormalLocList(area);
|
foreach (var item in _endLoclist.OrderByDescending(x => x.N_CURRENT_NUM).GroupBy(x => x.N_ROW))
|
{
|
var _ll = item.OrderBy(x => x.N_COL).ToList();
|
var fulast = _ll.FindAll(x => x.N_CURRENT_NUM > 0).LastOrDefault();
|
if (fulast != null && fulast.N_CURRENT_NUM < fulast.N_CAPACITY)
|
{
|
endBit = fulast;
|
}
|
else
|
{
|
if (fulast == null) endBit = _ll.FirstOrDefault();
|
else endBit = _ll.Find(x => x.N_COL > fulast.N_COL);
|
}
|
|
if (endBit != null) { break; }
|
}
|
LogHelper.Info($"翻斗机 筛选F终点 endbit:{JsonConvert.SerializeObject(endBit)}");
|
}
|
|
if (endBit != null)
|
{
|
var carryCntrs = new List<string> { Cont.S_CNTR_CODE };
|
var bb = TaskProcess.CreateTransport(workOrder.SQL_WorkNo, location, endBit.S_LOC_CODE, Desc + "(瓶盖)", carryCntrs, 1, endBit.N_CURRENT_NUM + 1, carryCntrs.Count, plc.taskPri);
|
if (bb)
|
{
|
LogHelper.Info($"{plc.deviceName} 当前机器{location} 正在执行下空任务");
|
if (containsKey)
|
FJD_wwwwFD[plc.deviceName.Trim()] = 0;
|
else FJD_wwwwFD.Add(plc.deviceName.Trim(), 0);
|
}
|
}
|
else
|
{
|
if (!USING2 && areaList.Count > 0)
|
goto goturunnnn;
|
LogHelper.Info($"翻斗机{plc.deviceName} 没有可用的空托终点");
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info("翻斗机信号不明!", "翻斗机");
|
}
|
}
|
|
internal static void AnalysisBottleCapTipper462(string data, Settings.deviceInfo plc)
|
{
|
//LogHelper.Info($"{plc.deviceName}-{plc.address}-{data}");
|
bool containsKey = true;
|
int llll = 0;
|
if (data.Length > 1 && data.Length % 2 == 0)
|
{
|
|
var workOrder = WCSHelper.GetPGWorkOrder(plc.deviceName);
|
if (workOrder == null)
|
{
|
LogHelper.Info(plc.deviceName + "没有【执行中】的工单", "翻斗机");
|
return;
|
}
|
var USING = workOrder.SQL_UsingNow == "Y";
|
int _sii = 0;
|
if (plc.deviceNo.Length > 0)
|
{
|
for (int i = 0; i < plc.deviceNo.Length; i++)
|
{
|
string _dorNo = plc.deviceNo[i];
|
//LogHelper.Info($"{plc.deviceName}{_dorNo} v {(i + 1) * 2}>-{data.Length}");
|
if (!string.IsNullOrEmpty(_dorNo))
|
{
|
if ((i + 1) * 2 > data.Length) break;
|
|
bool flag4 = DeviceProcess.doorStatus.Keys.Contains(_dorNo);
|
if (flag4)
|
{
|
DeviceProcess.doorStatus[_dorNo].info = data.Substring(2 * i + 1, 1);
|
DeviceProcess.doorStatus[_dorNo].modify = DateTime.Now;
|
}
|
else
|
{
|
DeviceProcess.doorStatus.Add(_dorNo, new DeviceProcess.signalInfo
|
{
|
info = data.Substring(2 * i + 1, 1),
|
modify = DateTime.Now
|
});
|
}
|
LogHelper.Info($"{plc.deviceName}{_dorNo} v {data.Substring(2 * i + 1, 1)}");
|
}
|
else
|
{
|
if (_sii == 0)
|
{
|
_sii = 2 * i + 1;
|
}
|
//LogHelper.Info($"{plc.deviceName}翻斗信号位置 v {_sii}");
|
}
|
}
|
}
|
//if (data.Substring(_sii, 1) == "0")
|
//{
|
// LogHelper.Info(plc.location[0] + "读到10信号。(10信号持续数量):" + llll);
|
// llll++;
|
// if (containsKey)
|
// FJD_wwwwFD[plc.deviceName.Trim()] = llll;
|
// else FJD_wwwwFD.Add(plc.deviceName.Trim(), llll);
|
// return;
|
//}
|
|
var location = plc.location[0];
|
var _loc = LocationHelper.GetLoc(location);
|
|
if (!(_loc.S_LOCK_STATE == "无" && data.Substring(_sii, 1) == "1"))
|
return;
|
|
var time = _loc?.T_FULL_TIME;
|
LogHelper.Info(location + ":托盘放置时间:(" + time + ") 货位托盘数量(" + _loc?.N_CURRENT_NUM + ")");
|
|
List<LocCntrRel> cntrStart = null;
|
if (time == null)
|
{
|
if (_loc.N_CURRENT_NUM == 1)
|
{
|
cntrStart = LocationHelper.GetLocCntrRel(location);
|
time = cntrStart.FirstOrDefault()?.T_CREATE;
|
|
if (time == null)
|
{
|
LogHelper.Info(plc.deviceName + ">>" + location + "货位托盘数量(" + _loc?.N_CURRENT_NUM + ") 但是找不到托盘数据。 终止");
|
return;
|
}
|
}
|
}
|
|
if (_loc.N_CURRENT_NUM == 0)//time == null || _loc == null ||
|
{
|
//搬走了。 如果本来就空的还给11 那就不是我的问题了。
|
// 后改 TODO - 送空框任务。
|
/// 取货时 给个 Empty_time
|
/// 信号不清的, 读到EmptyTime + 满信号 = 送空托。
|
/// 同时清掉EmtpyTimt 这样空托任务取消了,也不会循环触发。
|
//var EMPTYTIME = _loc?.T_EMPTY_TIME;
|
//if (EMPTYTIME == null || _loc == null || _loc?.N_CURRENT_NUM > 0)
|
//{
|
// return;
|
//}
|
|
LocationHelper.TakeEmptyToBottleBoyd2346(new WMSTask
|
{
|
S_START_LOC = location,
|
});
|
return;
|
}
|
|
//托盘放下 1分钟内 下空请求,都不处理。
|
else if (DateTime.Now.Subtract((DateTime)time).Minutes < 1)
|
{
|
PlcHelper.SendHex(plc.address, "3F00110d0a");
|
return;
|
}
|
|
LogHelper.Info($"翻斗机:{plc.deviceName} 下线信号:{location} 查询工单{workOrder.SQL_WorkNo}");
|
|
LogHelper.Info(plc.location[0] + "读到11信号。(10信号持续数量):" + llll);
|
var _i = -1;
|
if (llll < _i)
|
{
|
LogHelper.Info(plc.deviceName + $"读到11信号,但连续10信号不足{_i}次");
|
return;
|
}
|
|
if (cntrStart == null)
|
cntrStart = LocationHelper.GetLocCntrRel(location);
|
//关联表。 - 托盘决定去哪 - 工单可能临时切换。
|
if (cntrStart.Count == 1)
|
{
|
Location endBit = null;
|
var Cont = cntrStart.FirstOrDefault();
|
LogHelper.Info($"查找{location}对应终点-> 工单类型:{workOrder.SQL_UsingNow.Trim()} 托盘类型:{(Cont.S_CNTR_CODE.StartsWith("J") ? "" : "非")}即产");
|
int endLayer = 1;
|
string Desc = "";
|
var Locations = new List<Location>();
|
var USING2 = false;
|
if (Cont.S_CNTR_CODE.StartsWith("J"))
|
{
|
Desc = "翻斗机即产空筐下线";
|
USING2 = true;
|
}
|
else
|
{
|
USING2 = false;
|
Desc = "翻斗机库存空筐下线";
|
}
|
|
|
//var ba = "";
|
var ba2 = Settings.GetBolAreaList().Find(x => x.DeviceName == plc.deviceName && x.deviceType == plc.deviceType);
|
if (ba2 == null)
|
{
|
LogHelper.Info($"{plc.deviceName}-{workOrder.SQL_WorkNo}的BolArea 未配置。");
|
return;
|
}
|
List<string> areaList = new List<string>();
|
if (USING2)
|
{
|
areaList = ba2.UsingEmpty.Split(';').ToList();
|
}
|
else
|
{
|
areaList = ba2.NotUsingEmpty.Split(';').ToList();
|
}
|
|
goturunnnn:
|
var area = areaList.FirstOrDefault();
|
if (areaList.Count > 0) areaList.Remove(area);
|
var _endLoclist = LocationHelper.GetAreaNormalLocList(area);
|
foreach (var item in _endLoclist.GroupBy(x => x.N_ROW).OrderByDescending(x => x.Count(y => y.N_CURRENT_NUM > 0)))
|
{
|
var _ll = item.OrderBy(x => x.N_COL).ToList();
|
var fulast = _ll.FindAll(x => x.N_CURRENT_NUM > 0).LastOrDefault();
|
if (fulast != null && fulast.N_CURRENT_NUM < fulast.N_CAPACITY)
|
{
|
endBit = fulast;
|
}
|
else
|
{
|
if (fulast == null) endBit = _ll.FirstOrDefault();
|
else endBit = _ll.Find(x => x.N_COL > fulast.N_COL);
|
}
|
|
if (endBit != null) { break; }
|
}
|
|
if (endBit != null)
|
{
|
var carryCntrs = new List<string> { Cont.S_CNTR_CODE };
|
var bb = TaskProcess.CreateTransport(workOrder.SQL_WorkNo, location, endBit.S_LOC_CODE, Desc + "(瓶盖)", carryCntrs, 1, endBit.N_CURRENT_NUM + 1, carryCntrs.Count, plc.taskPri);
|
if (bb)
|
{
|
LocationHelper.DoAction(db => db.Deleteable<CntrItemRel>().Where(x => x.S_CNTR_CODE == Cont.S_CNTR_CODE).ExecuteCommand() > 0);
|
LogHelper.Info($"{plc.deviceName} 当前机器{location} 正在执行下空任务");
|
if (containsKey)
|
FJD_wwwwFD[plc.deviceName.Trim()] = 0;
|
else FJD_wwwwFD.Add(plc.deviceName.Trim(), 0);
|
}
|
}
|
else
|
{
|
if (areaList.Count > 0)
|
goto goturunnnn;
|
LogHelper.Info($"翻斗机{plc.deviceName} 没有可用的空托终点");
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info("翻斗机信号不明!", "翻斗机");
|
}
|
}
|
internal static void AnalysisBottleCapTipper10(string data, Settings.deviceInfo plc)
|
{
|
//LogHelper.Info($"{plc.deviceName}-{plc.address}-{data}");
|
bool containsKey = true;
|
int llll = 0;
|
//if (!FJD_wwwwFD.TryGetValue(plc.deviceName.Trim(), out llll))
|
//{
|
// containsKey = false;
|
// LogHelper.Info(plc.location[0] + "交管缓存 10 信号失败。 数量:" + llll);
|
// llll = 6;
|
//}
|
//else
|
//{
|
// LogHelper.Info(plc.location[0] + "交管缓存 10 信号成功。 数量:" + llll);
|
//}
|
|
if (data.Length > 1 && data.Length % 2 == 0)
|
{
|
|
var workOrder = WCSHelper.GetWorkOrder(plc.deviceName);
|
if (workOrder == null)
|
{
|
LogHelper.Info(plc.deviceName + "没有【执行中】的工单", "翻斗机");
|
return;
|
}
|
var USING = workOrder.SQL_UsingNow == "Y";
|
int _sii = 0;
|
if (plc.deviceNo.Length > 0)
|
{
|
for (int i = 0; i < plc.deviceNo.Length; i++)
|
{
|
string _dorNo = plc.deviceNo[i];
|
//LogHelper.Info($"{plc.deviceName}{_dorNo} v {(i + 1) * 2}>-{data.Length}");
|
if (!string.IsNullOrEmpty(_dorNo))
|
{
|
if ((i + 1) * 2 > data.Length) break;
|
|
bool flag4 = DeviceProcess.doorStatus.Keys.Contains(_dorNo);
|
if (flag4)
|
{
|
DeviceProcess.doorStatus[_dorNo].info = data.Substring(2 * i + 1, 1);
|
DeviceProcess.doorStatus[_dorNo].modify = DateTime.Now;
|
}
|
else
|
{
|
DeviceProcess.doorStatus.Add(_dorNo, new DeviceProcess.signalInfo
|
{
|
info = data.Substring(2 * i + 1, 1),
|
modify = DateTime.Now
|
});
|
}
|
LogHelper.Info($"{plc.deviceName}{_dorNo} v {data.Substring(2 * i + 1, 1)}");
|
}
|
else
|
{
|
if (_sii == 0)
|
{
|
_sii = 2 * i + 1;
|
}
|
//LogHelper.Info($"{plc.deviceName}翻斗信号位置 v {_sii}");
|
}
|
}
|
}
|
//if (data.Substring(_sii, 1) == "0")
|
//{
|
// LogHelper.Info(plc.location[0] + "读到10信号。(10信号持续数量):" + llll);
|
// llll++;
|
// if (containsKey)
|
// FJD_wwwwFD[plc.deviceName.Trim()] = llll;
|
// else FJD_wwwwFD.Add(plc.deviceName.Trim(), llll);
|
// return;
|
//}
|
|
var location = plc.location[0];
|
var _loc = LocationHelper.GetLoc(location);
|
|
if (!(_loc.S_LOCK_STATE == "无" && data.Substring(_sii, 1) == "1"))
|
return;
|
|
var time = _loc?.T_FULL_TIME;
|
LogHelper.Info(location + ":托盘放置时间:(" + time + ") 货位托盘数量(" + _loc?.N_CURRENT_NUM + ")");
|
|
List<LocCntrRel> cntrStart = null;
|
if (time == null)
|
{
|
if (_loc.N_CURRENT_NUM == 1)
|
{
|
cntrStart = LocationHelper.GetLocCntrRel(location);
|
time = cntrStart.FirstOrDefault()?.T_CREATE;
|
|
if (time == null)
|
{
|
LogHelper.Info(plc.deviceName + ">>" + location + "货位托盘数量(" + _loc?.N_CURRENT_NUM + ") 但是找不到托盘数据。 终止");
|
return;
|
}
|
}
|
}
|
|
if (_loc.N_CURRENT_NUM == 0)//time == null || _loc == null ||
|
{
|
//搬走了。 如果本来就空的还给11 那就不是我的问题了。
|
// 后改 TODO - 送空框任务。
|
/// 取货时 给个 Empty_time
|
/// 信号不清的, 读到EmptyTime + 满信号 = 送空托。
|
/// 同时清掉EmtpyTimt 这样空托任务取消了,也不会循环触发。
|
//var EMPTYTIME = _loc?.T_EMPTY_TIME;
|
//if (EMPTYTIME == null || _loc == null || _loc?.N_CURRENT_NUM > 0)
|
//{
|
// return;
|
//}
|
|
|
|
LocationHelper.TakeEmptyToBottleBoyd(new WMSTask
|
{
|
S_START_LOC = location,
|
});
|
return;
|
}
|
|
//托盘放下 1分钟内 下空请求,都不处理。
|
else if (DateTime.Now.Subtract((DateTime)time).Minutes < 1)
|
{
|
PlcHelper.SendHex(plc.address, "3F00110d0a");
|
return;
|
}
|
|
LogHelper.Info($"翻斗机:{plc.deviceName} 下线信号:{location} 查询工单{workOrder.SQL_WorkNo}");
|
|
LogHelper.Info(plc.location[0] + "读到11信号。(10信号持续数量):" + llll);
|
var _i = -1;
|
if (llll < _i)
|
{
|
LogHelper.Info(plc.deviceName + $"读到11信号,但连续10信号不足{_i}次");
|
return;
|
}
|
|
if (cntrStart == null)
|
cntrStart = LocationHelper.GetLocCntrRel(location);
|
//关联表。 - 托盘决定去哪 - 工单可能临时切换。
|
if (cntrStart.Count == 1)
|
{
|
LogHelper.Info($"查找{location}对应终点->即产?{workOrder.SQL_UsingNow.Trim()}");
|
Location endBit = null;
|
var Cont = cntrStart.FirstOrDefault();
|
int endLayer = 1;
|
string Desc = "";
|
var USING2 = false;
|
if (Cont.S_CNTR_CODE.StartsWith("J"))
|
{
|
Desc = "翻斗机即产空筐下线";
|
USING2 = true;
|
}
|
else
|
{
|
USING2 = false;
|
Desc = "翻斗机库存空筐下线";
|
}
|
//var ba = "";
|
var ba2 = Settings.GetBolAreaList().Find(x => x.DeviceName == plc.deviceName && x.deviceType == plc.deviceType);
|
if (ba2 == null)
|
{
|
LogHelper.Info($"{plc.deviceName}-{workOrder.SQL_WorkNo}的BolArea 未配置。");
|
return;
|
}
|
List<string> areaList = new List<string> { (plc.deviceType == 6 ? "WJGRGDKQ" : "SGRGDKQ"), ba2.NotUsingEmpty };
|
areaList = new List<string> { ba2.NotUsingEmpty };
|
if (plc.deviceType == 10)
|
{
|
areaList = new List<string> { ba2.NotUsingEmpty };
|
}
|
goturunnnn:
|
var area = areaList.FirstOrDefault();
|
if (areaList.Count > 0) areaList.Remove(area);
|
|
if (USING2)
|
{
|
areaList.Clear();
|
area = ba2.UsingEmpty;
|
|
LogHelper.Info($"翻斗机{plc.deviceName} 筛选即产终点库区{area}");
|
var _endLoclist = LocationHelper.GetAreaNormalLocList(area);
|
foreach (var item in _endLoclist.OrderBy(x => x.N_ROW).GroupBy(x => x.N_ROW))
|
{
|
var _ll = item.OrderBy(x => x.N_COL).ToList();
|
var fulast = _ll.FindAll(x => x.N_CURRENT_NUM > 0).LastOrDefault();
|
if (fulast != null && fulast.N_CURRENT_NUM < fulast.N_CAPACITY)
|
{
|
endBit = fulast;
|
}
|
else
|
{
|
if (fulast == null) endBit = _ll.FirstOrDefault();
|
else endBit = _ll.Find(x => x.N_COL > fulast.N_COL);
|
}
|
|
if (endBit != null) { break; }
|
}
|
LogHelper.Info($"翻斗机 筛选J终点 endbit:{JsonConvert.SerializeObject(endBit)}");
|
//var locs = LocationHelper.GetLocList(x => x.S_AREA_CODE == ba2.UsingEmpty && x.S_LOC_CODE != "报废").OrderBy(x => x.N_COL).ThenBy(x => x.N_ROW).ToList();
|
//var lastffl = locs.FindAll(x => x.N_CURRENT_NUM > 0 && x.T_FULL_TIME != null).OrderBy(x => x.T_FULL_TIME).LastOrDefault();
|
//var lastEmpty = locs.FindAll(x => x.N_CURRENT_NUM == 0 && x.T_EMPTY_TIME != null).OrderBy(x => x.T_EMPTY_TIME).LastOrDefault();
|
|
//if (lastffl != null)
|
//{
|
// if (lastEmpty == null) lastffl = null;
|
// else if (lastffl.N_COL <= lastEmpty.N_COL) { lastffl = null; lastEmpty = null; }
|
// else if (lastffl == locs.LastOrDefault()) lastffl = null;
|
//}
|
/////最后一个满框入库位往后找。
|
//foreach (var item in locs.Skip((lastffl == null || lastffl == locs.LastOrDefault() ? 0 : locs.IndexOf(lastffl))).GroupBy(x => x.N_COL))
|
//{
|
// ///先放小排, 先取大排 取放按列
|
// var collist = item.OrderBy(x => x.N_ROW).ToList();
|
// if (!collist.Any()) continue;
|
// if (collist.Find(x => x.S_LOCK_STATE != "无") != null) continue;
|
// var collastful = collist.Find(x => x.N_CURRENT_NUM > 0);
|
// Location nex = null;
|
// if (collastful == null) nex = collist.FirstOrDefault();
|
// else nex = collist.Find(x => x.N_ROW >= collastful.N_ROW && x.N_CURRENT_NUM < x.N_CAPACITY);
|
// if (nex != null)
|
// {
|
// endBit = nex;
|
// break;
|
// }
|
//}
|
}
|
else
|
{
|
LogHelper.Info($"翻斗机{plc.deviceName} 筛选F即产终点库区{area}");
|
var _endLoclist = LocationHelper.GetAreaNormalLocList(area);
|
foreach (var item in _endLoclist.OrderByDescending(x => x.N_CURRENT_NUM).GroupBy(x => x.N_ROW))
|
{
|
var _ll = item.OrderBy(x => x.N_COL).ToList();
|
var fulast = _ll.FindAll(x => x.N_CURRENT_NUM > 0).LastOrDefault();
|
if (fulast != null && fulast.N_CURRENT_NUM < fulast.N_CAPACITY)
|
{
|
endBit = fulast;
|
}
|
else
|
{
|
if (fulast == null) endBit = _ll.FirstOrDefault();
|
else endBit = _ll.Find(x => x.N_COL > fulast.N_COL);
|
}
|
|
if (endBit != null) { break; }
|
}
|
LogHelper.Info($"翻斗机 筛选F终点 endbit:{JsonConvert.SerializeObject(endBit)}");
|
}
|
|
if (endBit != null)
|
{
|
var carryCntrs = new List<string> { Cont.S_CNTR_CODE };
|
var bb = TaskProcess.CreateTransport(workOrder.SQL_WorkNo, location, endBit.S_LOC_CODE, Desc + "(瓶盖)", carryCntrs, 1, endBit.N_CURRENT_NUM + 1, carryCntrs.Count, plc.taskPri);
|
if (bb)
|
{
|
LogHelper.Info($"{plc.deviceName} 当前机器{location} 正在执行下空任务");
|
if (containsKey)
|
FJD_wwwwFD[plc.deviceName.Trim()] = 0;
|
else FJD_wwwwFD.Add(plc.deviceName.Trim(), 0);
|
}
|
}
|
else
|
{
|
if (!USING2 && areaList.Count > 0)
|
goto goturunnnn;
|
LogHelper.Info($"翻斗机{plc.deviceName} 没有可用的空托终点");
|
}
|
}
|
}
|
else
|
{
|
LogHelper.Info("翻斗机信号不明!", "翻斗机");
|
}
|
}
|
static List<Tuple<int, int>> SequentialGrouping(int n)
|
{
|
List<Tuple<int, int>> groups = new List<Tuple<int, int>>();
|
|
for (int i = 1; i <= n; i += 2)
|
{
|
if (i + 1 <= n) // 确保不越界
|
{
|
groups.Add(Tuple.Create(i, i + 1));
|
}
|
else
|
{
|
// 如果 n 是奇数,最后一个数字单独一组(可选)
|
groups.Add(Tuple.Create(i, 0)); // -1 表示无配对
|
}
|
}
|
|
return groups;
|
}
|
}
|
}
|