using Hanhe.iWCS.Business;
using Hanhe.iWCS.Common;
using Hanhe.iWCS.Interface;
using Hanhe.iWCS.Model;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using MongoDB.Bson;
using Hanhe.iWCS.MData;
using Newtonsoft.Json;
using MongoDB.Driver.Builders;
using static Hanhe.iWCS.IndonesiaGLMProtocol.MESHelper;
using MongoDB.Driver;
using static Hanhe.iWCS.IndonesiaGLMProtocol.ProcessHelper;
using static Hanhe.iWCS.IndonesiaGLMProtocol.ApiHelper;
using System.Threading;
using Hanhe.iWCS.Model.AMS;
using Hanhe.iWCS.IndonesiaGLMTCP;
using static Hanhe.iWCS.IndonesiaGLMProtocol.ProtocolAnalysis;
using System.Threading.Tasks;
using static System.Runtime.CompilerServices.RuntimeHelpers;
using static Hanhe.iWCS.IndonesiaGLMProtocol.AMSHelper;
using System.Collections;
using log4net.Config;
using System.Text.RegularExpressions;
using static Hanhe.iWCS.IndonesiaGLMProtocol.ERPService;
using System.Globalization;
using System.Security.Cryptography;
namespace Hanhe.iWCS.IndonesiaGLMProtocol
{
public class PLCControl : IPLCControl
{
private EquipmentCommandEQBLL commandBLL = new EquipmentCommandEQBLL();
///
/// PLC 数据发送
///
///
///
public void SendMessage(EquipmentCommandEQ command)
{
bool sended = SessionInstance.Instance.PLCSend(command.EquipmentIP, int.Parse(command.EquipmentPort), command.CommandText);
if (sended)
{
//CMMLog.Info("设备指令发送成功;EquipmentCode=" + command.EquipmentCode + "-指令=" + command.CommandText);
commandBLL.UpdateCommandEQStatus(command._id, Constants.COMMANDEQ_STATUS_SENDED, command.SendCount);
}
else
{
//CMMLog.Info("设备指令发送失败;EquipmentCode=" + command.EquipmentCode + "-指令=" + command.CommandText);
commandBLL.UpdateCommandEQStatus(command._id, Constants.COMMANDEQ_STATUS_SEND_ERRORS, command.SendCount);
}
}
///
/// 处理光电信息
///
///
public static void Analysis(string data) {
//3f 00 01 00 00 00 24 24
}
#region 纯3楼设备任务
#region 3楼包装机取料至复称平台流程——无需回报WMS任务状态——3楼包装取料——已完成(待测试,时间戳处理)
#region 收到包装机下料信号1,开始判断复称平台是否满足条件,选择性下发任务
///
/// 3楼包装机取料至复称平台流程——任务开始前,判断包装机有没有下线信号,并判断当前复称平台是否NG以及有没有任务在进行中
///
///
internal static void CheckPackingMachine(Settings.PlcInfo pmInfo)
{
//var count = MongoDBSingleton.Instance.FindOne<>//occupy
var count = MongoDBSingleton.Instance.FindOne(Query.And(Query.EQ("occupy", "1"),Query.EQ("machineNo", pmInfo.location)), "MachineInfo");
//检查包装机通道0是否有下料信号,如果有生成下料任务。线程循环读取,无需设置循环。——通道0参数为1
if (count == null)
{
if (PickUpStartFree(pmInfo.location) && PickUpEndFree(pmInfo.location))
{
try
{
var result = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
dataNum = 1,
addr = pmInfo.readAddr,
host = pmInfo.ip,
port = pmInfo.port
});
if (result != null && result.errCode == 0)
{
CMMLog.Debug($"包装下线流程-{pmInfo.location}:读取包装机{pmInfo.device}通道号为:{pmInfo.readAddr}的值为:{result.result[0]}");
if (result != null && result.errCode == 0 && result.result.Count() > 0)
{
//1:取料
if (result.result[0] == 1 || result.result[0] == 5)
{
var FCBit = Settings.GetPlcInfo().Where(a => a.deviceType == "2" && a.enable == 1).ToList();
if(FCBit.Count > 0)
{
foreach(var a in FCBit)
{
string PlcBit02 = a.location;
CMMLog.Debug($"复称点位:{PlcBit02}");
//包装下线任务,终点为复称位置(这里判断包装机起点,复称起点终点均无任务,则推送任务)
if (ProcessHelper.PickUpStartFree(pmInfo.location) && ProcessHelper.CheckEndFree(PlcBit02) && ProcessHelper.PickUpStartFree(PlcBit02))
{
//判断复称位置,没有货并且不为NG(ng参数0,1,2——0,不确定(包装机刚开始工作时)1,ok 2,ng)
var state = GetSecondWeighState(pmInfo.location, PlcBit02);
CMMLog.Debug($"包装下线流程:判断复称位置空满状态为:{state.full},ng状态为:{state.ng}");
if (state.full == 0)
{
if (Settings.mesOpen == "0")
{
//可以生成任务,调mes接口获取生产信息 2022.7.28 变更 MES可能需要1~2年才能上线,先把MES功能注销
var info = MESHelper.GetPackingMachineInfo(pmInfo.location);
if (info != null)
{
CMMLog.Debug($"包装下线流程:获取MES之后进入info判断!");
//Console.WriteLine($"包装下线流程:获取MES之后进入info判断!");
var trayCode = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
addr = pmInfo.readAddr + 10,
dataNum = 80,//数据个数要增加 addr以及dataNum的具体数据为16个 现80个参数
host = pmInfo.ip,
port = pmInfo.port
});
if (trayCode.errCode == 0 && trayCode.result.Length == 80)
{
//获取托盘码等信息 读取通道 10、11、12的数据作为托盘码 读取其它通道 重量 叠包等信息 所有数据存入MachineInfo表
GetMachineData(trayCode.result);
var tray = MongoDBSingleton.Instance.FindOne(Query.EQ("machineNo", pmInfo.location), "MachineInfo");
if (tray != null && tray.addState == 0)
{
MongoDBSingleton.Instance.Remove(Query.EQ("machineNo", tray.machineNo), RemoveFlags.Single);
CMMLog.Debug("包装下线任务,叠托层数为0,不生成任务");
}
else if (tray != null)
{
if (tray.trayCode != "0" && tray.trayCode != "" && tray.trayCode != null)
{
//AMSHelper.CreateTask(DateTime.Now.Ticks.ToString(), pmInfo.location, GetSecondWeighBit(), "3楼包装取料", 1, JsonConvert.SerializeObject(info));
int i = 1;
while (i == 1)
{
var amsResult = AMSHelper.CreateTask(DateTime.Now.Ticks.ToString(), pmInfo.location, PlcBit02, "3楼包装取料", 0, tray.trayCode);
if (amsResult.success)
{
i = 2;
CMMLog.Debug($"包装下线流程:AMS调用API成功!");
//记录包装间下料信息
MongoDBSingleton.Instance.Insert(new packageInfoModel { machineNo = tray.machineNo, trayCode = tray.trayCode, time = DateTime.Now.ToString("yyyy-MM-dd"), weight = tray.oneTrayWeight });
break;
}
else CMMLog.Debug($"包装下线流程:AMS调用API失败,开始重新调用!");
}
CMMLog.Debug($"包装下线流程:接受并读取包装机通道里面的物料信息,并将其写入MachineInfo中间表中!接收到的信息:{JsonConvert.SerializeObject(trayCode.result)}");
}
}
else
{
CMMLog.Debug($"包装下线流程:tray==null!");
//Console.WriteLine($"包装下线流程:tray==null!");
}
}
else
{
CMMLog.Debug($"包装下线流程:3楼包装至复称获取MODBUS值错误!trayCode.errCode:{trayCode.errCode},trayCode.result.Length:{trayCode.result.Length}");
//Console.WriteLine($"包装下线流程:3楼包装至复称获取MODBUS值错误!trayCode.errCode:{trayCode.errCode},trayCode.result.Length:{trayCode.result.Length}");
}
}
else CMMLog.Debug($"包装下线流程:MES接口数据返回空值!MES接口数据:{info}");
}
else if (Settings.mesOpen == "1")
{
//可以生成任务,调mes接口获取生产信息 2022.7.28 变更 MES可能需要1~2年才能上线,先把MES功能注销
CMMLog.Debug($"包装下线流程-{pmInfo.location}:获取MES之后进入info判断!");
var trayCode = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
addr = pmInfo.readAddr + 10,
dataNum = 91,////ERP变更:90 原先:80
host = pmInfo.ip,
port = pmInfo.port
});
if (trayCode.errCode == 0 && trayCode.result.Length == 91)
{
//获取托盘码等信息 读取通道 11、12、13的数据作为托盘码 读取其它通道 重量 叠包等信息 所有数据存入MachineInfo表
GetMachineData(trayCode.result, false);
var tray = MongoDBSingleton.Instance.FindOne(Query.EQ("machineNo", pmInfo.location), "MachineInfo");
if (tray != null)
{
if (tray.addState == 0)
{
MongoDBSingleton.Instance.Remove(Query.EQ("machineNo", pmInfo.location), "MachineInfo", RemoveFlags.None);
//if (ERPService.ERPSwitch01 == "0") MongoDBSingleton.Instance.Remove(Query.EQ("machineNo", pmInfo.location), "MachineInfoTwo", RemoveFlags.None);
CMMLog.Debug($"包装下线流程-{pmInfo.location}:叠托层数为0,不允许生成任务");
}
else if (tray.trayCode != "0" && !string.IsNullOrEmpty(tray.trayCode))
{
CMMLog.Info($"物料编码:{tray.materialCode},批次号:{tray.lotNo}");
if(result.result[0] == 1)
{
string timeStamp = ProcessHelper.GetTimeStamp(31, 1, 1);
HHAmsExecuteResult req = AMSHelper.CreateTask(DateTime.Now.Ticks.ToString(), pmInfo.location, PlcBit02, "PackagingMachineMaterialHandling", 0, tray.trayCode, timeStamp);
//记录包装间下料信息
if (req.success)
{
string Weight = (decimal.Parse(tray.oneTrayWeight) / 100).ToString("F2");
MongoDBSingleton.Instance.Insert(new packageInfoModel { machineNo = tray.machineNo, trayCode = tray.trayCode, batchNo = tray.lotNo, time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), weight = Weight });
}
break;
}
else
{
var writeRes0 = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
host = pmInfo.ip,
addr = pmInfo.writeAddr,
data = 5,//原先是1,单个写入
port = pmInfo.port
});
//人工模式,无需生成任务
//删除machineInfo表中的数据
MongoDBSingleton.Instance.Remove(Query.And(Query.EQ("machineNo", pmInfo.location),Query.EQ("trayCode", tray.trayCode)), "MachineInfo", RemoveFlags.None);
//记录包装间下料信息
string Weight = (decimal.Parse(tray.oneTrayWeight) / 100).ToString("F2");
MongoDBSingleton.Instance.Insert(new packageInfoModel { machineNo = tray.machineNo, trayCode = tray.trayCode, batchNo = tray.lotNo, time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), weight = Weight });
break;
}
//包装取料卸货完成,设备生产数量加一
//判断是否有当天的数据,如果没有,则生成数据
#region
var proInfo = MongoDBSingleton.Instance.FindOne(Query.And(Query.EQ("Date", DateTime.Now.ToString("yyyy-MM-dd")), Query.EQ("machine", tray.machineNo)), "ProductList");
if (proInfo != null)
{
proInfo.total = proInfo.total + 1;
proInfo.percentOfPass = Math.Round(((proInfo.qualifiedQuantity / proInfo.total) * 100), 2);
MongoDBSingleton.Instance.Update(Query.And(Query.EQ("Date", DateTime.Now.ToString("yyyy-MM-dd")), Query.EQ("machine", tray.machineNo)), Update.Set("total", proInfo.total).Set("percentOfPass", proInfo.percentOfPass), UpdateFlags.None);
}
else
{
ProductList machine = new ProductList
{
Date = DateTime.Now.ToString("yyyy-MM-dd"),
machine = tray.machineNo,
total = 1,
qualifiedQuantity = 0,
percentOfPass = 0,
overallPassRate = 0
};
MongoDBSingleton.Instance.Insert(machine);
}
#endregion
}
}
else CMMLog.Debug($"包装下线流程-{pmInfo.location}:tray==null!");
}
else CMMLog.Debug($"包装下线流程-{pmInfo.location}:3楼包装至复称获取MODBUS值错误!trayCode.errCode:{trayCode.errCode},trayCode.result.Length:{trayCode.result.Length}");
}
}
else
{
var task = MongoDBSingleton.Instance.FindOne(Query.Or(Query.EQ("CN_S_START_BIT", PlcBit02), Query.EQ("CN_S_END_BIT", PlcBit02)), "TN_I_TASK_MST");
if (task != null) CMMLog.Debug($"包装下线流程-{pmInfo.location}:检查复称中间表是否为空,不为空则检查其数据full以及ng是否为0和1!任务号为:{task.CN_S_TASK_NO}");
else CMMLog.Debug($"包装下线流程-{pmInfo.location}:检查复称中间表是否为空,不为空则检查其数据full以及ng是否为0和1!");
}
}
else
{
var taskNo = MongoDBSingleton.Instance.FindOne(Query.EQ("CN_S_START_BIT", pmInfo.location), "TN_I_TASK_MST");
var taskNo1 = MongoDBSingleton.Instance.FindOne(Query.Or(Query.EQ("CN_S_START_BIT", PlcBit02), Query.EQ("CN_S_END_BIT", PlcBit02)), "TN_I_TASK_MST");
string task = "", startbit = "", endbit = "";
if (taskNo != null)
{
task = taskNo.CN_S_TASK_NO;
startbit = taskNo.CN_S_START_BIT;
endbit = taskNo.CN_S_END_BIT;
}
else if (taskNo1 != null)
{
task = taskNo1.CN_S_TASK_NO;
startbit = taskNo1.CN_S_START_BIT;
endbit = taskNo1.CN_S_END_BIT;
}
CMMLog.Debug($"包装机起点或者复称起点终点有任务在执行中!任务号:{task},起点:{startbit},终点:{endbit}");
}
}
}
}
else CMMLog.Debug($"包装下线流程-{pmInfo.location}:包装机通道0里面的数据不为1!result为:{JsonConvert.SerializeObject(result)}");
}
else CMMLog.Debug($"包装下线流程-{pmInfo.location}:未读取到包装机通道0里面的数据!!!result:{JsonConvert.SerializeObject(result)}");
}
else CMMLog.Debug($"包装下线流程-{pmInfo.location}:未读取到包装机通道0里面的数据!!!result:{JsonConvert.SerializeObject(result)}");
}
catch (Exception ex)
{
CMMLog.Debug($"包装下线流程-{pmInfo.location}:" + ex.Message);
}
}
else CMMLog.Debug($"当前包装机起点终点有任务正在执行,请确认当前包装机的任务是否取货卸货完成!包装机货位编码:{pmInfo.location}");
}
else CMMLog.Debug($"当前machineInfo中间表已存在数据:{JsonConvert.SerializeObject(count)}");
}
#endregion
#region 包装机MODBUS交互(开始取料,取料完成)
/// 小车请求进料 1 AMS写,PLC读 1-请求进入;2-到位后,请求接驳滚动;3-取货完成;4-离开安全门外,清零通道
/// 设备允许出料 1 PLC写,AMS读 1-XXXXXXXX;2-允许进入;3-接驳滚动,送出物料 ;4-结束;5-安全门关闭
///
/// 小车到达包装机安全门口请求进入
/// 判断是否是改道后 复秤入缓存架任务
///
///
internal static void PickUpFullDoorUnload(string ip, string taskNo, string deviceType)
{
if(deviceType != "2")
{
var plc = Settings.GetPlcInfo().Where(a => a.ip == ip).FirstOrDefault();
//ASM写入通道0小车动作,1-取料
int[] num = new int[2] { 1, 1 };
var writeRes0 = OITcpHelper.RegisterWriteOutPutMulti(new OITcpHelper.RegisterWriteOutPutModelMulti
{
host = ip,
addr = plc.writeAddr,
data = num,//原先是1,单个写入
port = plc.port
});
if (writeRes0.errCode == 0)
{
//小车请求进入安全门交互
//小车请求进料,并且查询设备是否允许AGV进入
//读地址1设备是否 2-可以进入
var readRes = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
dataNum = 1,
host = ip,
addr = plc.readAddr + 1,
port = plc.port
});
CMMLog.Debug($"读取设备{plc.location}通道{plc.readAddr + 1}里面数据为{readRes.result[0]}.");
//Console.WriteLine($"读取设备{plc.location}通道{plc.readAddr + 1}里面数据为{readRes.result[0]}.");
if (readRes != null && readRes.errCode == 0)
{
if (readRes.result[0] == 2)
{
//设备允许进入,改参数通知AGV
WorkFlowAction.TrackLog(taskNo, 10, 1012, "success");
TSHelper.GoToAGV(taskNo, 10, 1);
}
}
else CMMLog.Debug($"包装下线:1012,readRes:{readRes},readRes.errCode:{readRes.errCode}");
}
}
else
{
PLCControl.SecondWeightInCache1012(ip, taskNo);//二期:直接改参数
}
}
///
/// 小车请求取货
///
///
///
internal static void PickUpFullUnload(string ip , string taskNo, int port)
{
var plc = Settings.GetPlcInfo().Where(a => a.ip == ip && a.port == port).FirstOrDefault();
if (ip != "")
{
//小车请求出料,并且查询设备是否允许AGV进入
//读地址2设备是否 2-允许进料 保险起见,可以不读
var readRes = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
dataNum = 1,
host = ip,
addr = plc.readAddr + 1,
port = plc.port
});
CMMLog.Debug($"读取设备{plc.location}通道{plc.readAddr + 1}里面数据为{readRes.result[0]}.");
//Console.WriteLine($"读取设备{plc.location}通道{plc.readAddr + 1}里面数据为{readRes.result[0]}.");
if (readRes != null && readRes.errCode == 0)
{
if (readRes.result[0] == 2)
{
//TSHelper.GoToAGV(taskNo, 10, 2);//原先先改AGV参数
var writeRes1 = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
host = ip,
addr = plc.writeAddr + 1,
data = 2,
port = plc.port
});
if(writeRes1.errCode == 0) TSHelper.GoToAGV(taskNo, 10, 2);
CMMLog.Debug($"写入设备{plc.location}通道{plc.writeAddr + 1}里面数据为2.");
//Console.WriteLine($"写入设备{plc.location}通道{plc.writeAddr + 1}里面数据为2.");
}
}
else CMMLog.Debug($"包装下线,1112,readRes={readRes}");
}
else CMMLog.Debug($"包装下线,1112,ip=null!");
}
///
/// 小车取货完成--二期协议无此指令动作
///
///
///
internal static void PickUpFullComplete(string ip, string taskNo)
{
var plc = Settings.GetPlcInfo().Where(a => a.ip == ip).FirstOrDefault();
if (ip != "")
{
//小车请求出料,并且查询设备是否允许AGV进入
//读地址2设备是否 2-允许进料
var readRes = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
dataNum = 1,
host = ip,
addr = plc.readAddr+1,
port = plc.port
});
CMMLog.Debug($"读取设备{plc.location}通道{plc.readAddr + 1}里面数据为{readRes.result[0]}.");
//Console.WriteLine($"读取设备{plc.location}通道{plc.readAddr + 1}里面数据为{readRes.result[0]}.");
DateTime dateTime = DateTime.Now;
if (readRes != null && readRes.errCode == 0)
{
if (readRes.result[0] == 3)
{
var writeRes1 = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
host = ip,
addr = plc.writeAddr+1,
data = 3,
port = plc.port
});
CMMLog.Debug($"写入设备{plc.location}通道{plc.writeAddr + 1}里面数据为3.");
//Console.WriteLine($"写入设备{plc.location}通道{plc.writeAddr + 1}里面数据为3.");
}
else if(readRes.result[0] == 4)
{
WorkFlowAction.TrackLog(taskNo, 10, 1212, "success");
TSHelper.GoToAGV(taskNo, 10, 5);
}
}
else CMMLog.Debug($"包装下线,1212,readRes={readRes}!");
}
else CMMLog.Debug($"包装下线,1212,ip=null!");
}
///
/// 小车卸货完成离开安全门后通知包装机
///
///
///
internal static void PickUpFullDoorComplete(string ip, string taskNo, string deviceType)
{
if(deviceType == "1")
{
var plc = Settings.GetPlcInfo().Where(a => a.ip == ip).FirstOrDefault();
if (plc != null)
{
//写入包装机--安全门关门指令
var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
host = ip,
addr = plc.writeAddr + 1,
data = 3,
port = plc.port
});
CMMLog.Debug($"写入设备{plc.location}通道{plc.writeAddr + 1}里面数据为3.");
//Console.WriteLine($"写入设备{plc.location}通道{plc.writeAddr + 1}里面数据为4.");
}
else CMMLog.Debug($"包装下线,3,ip=null!");
}
else
{
PLCControl.SecondWeightInCache4(deviceType,taskNo);
}
}
#endregion
#region 复称平台交互
///小车请求进料 1 AMS写,PLC读 1-请求进入;2-小车进料,输送托盘;3-XXXXXXX
///设备允许出料 1 PLC写,AMS读 1-XXXXXXXX;2-允许进料,开始滚动;3-上料完成
///复称平台小车动作: 1:上料复称;2:上砝码教称;3:取复称NG托盘,4:取砝码到包装机
///
///复称平台安全请求进入——因为现场需求,所以额外增加一个类似安全门的交互,直接改参数就行
///
internal static void SecondWeightSafe(string ip,string taskNo, int port)
{
var plc = Settings.GetPlcInfo().Where(a => a.ip == ip && a.port == port).FirstOrDefault();
//ASM写入小车动作,1:上料复称;2:上砝码教称;3:取复称NG托盘,4:取砝码到包装机
int[] num = new int[2] { 1, 1 };
var writeRes0 = OITcpHelper.RegisterWriteOutPutMulti(new OITcpHelper.RegisterWriteOutPutModelMulti
{
host = ip,
addr = plc.writeAddr,
data = num,//原先是1,单个写入
port = plc.port
});
CMMLog.Debug($"写入设备{plc.location}通道{plc.writeAddr}里面数据为1.");
//Console.WriteLine($"写入设备{plc.location}通道{plc.writeAddr}里面数据为1.");
///小车和复称位对接
//小车请求进料,并且查询设备是否允许AGV进入
var readRes = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
dataNum = 1,
host = plc.ip,
addr = plc.readAddr + 1,
port = plc.port
});
CMMLog.Debug($"读取设备{plc.location}通道{plc.readAddr + 1}里面数据为{readRes.result[0]}.");
//Console.WriteLine($"读取设备{plc.location}通道{plc.readAddr + 1}里面数据为{readRes.result[0]}.");
if (readRes != null && readRes.errCode == 0)
{
if(readRes.result[0] == 2)
{
WorkFlowAction.TrackLog(taskNo, 10, 1013, "success");
TSHelper.GoToAGV(taskNo, 10, 3);
}
}
//将数据写入通道
}
public static int SecondRelax = 0;
///
/// 请求进入复称取货
///
///
///
internal static void SecondWeightInCache1012(string ip, string taskNo)
{
var plc = Settings.GetPlcInfo().Where(a => a.ip == ip).FirstOrDefault();
if (ip != null)
{
CMMLog.Info($"ip:{ip}");
///小车和复称位对接
if (ip != "")
{
//小车请求进料,并且查询设备是否允许AGV进入
WorkFlowAction.TrackLog(taskNo, 10, 1012, "success");
TSHelper.GoToAGV(taskNo, 10, 1);
SecondRelax = 0;
}
else CMMLog.Info($"复称入缓存架,1012,ip=null!");
}
else CMMLog.Info($"地址{ip}的设备未配置");
}
///
/// 复称卸货
///
///
///
internal static void CheckUpReqUnload(Settings.PlcInfo plc, string taskNo)
{
///小车和复称位对接
if (plc != null)
{
//设备允许进入,改参数通知AGV
//WorkFlowAction.TrackLog(taskNo, 10, 1113, "success");
//TSHelper.GoToAGV(taskNo, 10, 4);
//CMMLog.Debug($"改AGV参数:10,4");
//判断任务起点,找到起点包装机设备号,在中间表MachineInfo中查找上一台设备(包装机)的数据,通过modbus通道传入(数据需要转换,ASCII转16short,可能还需要数据拆分)
var taskInfo = MongoDBSingleton.Instance.FindOne(Query.EQ("CN_S_TASK_NO",taskNo), "TN_I_TASK_MST");
var machine = MongoDBSingleton.Instance.FindOne(Query.EQ("trayCode", taskInfo.CN_S_BATCH_NO), "MachineInfo");
if (machine != null)
{
CMMLog.Debug("进入machine判断");
//向复称卸货复称,并将从包装机获取到的数据写入通道中
#region 多个数据写入MODBUS
var arr = JsonConvert.DeserializeObject>(machine.jsonData);
int[] num = new int[91];
for(int i = 0; i <= 90; i++) num[i] = arr[i];
CMMLog.Debug($"num:{JsonConvert.SerializeObject(num)}");
//Console.WriteLine(num);
var wirteall = OITcpHelper.RegisterWriteOutPutMulti(new OITcpHelper.RegisterWriteOutPutModelMulti
{
addr = plc.writeAddr + 10,
host = plc.ip,
data = num,
port = plc.port
});
//var writeRes1 = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
//{
// host = plc.ip,
// addr = plc.writeAddr + 1,
// data = 2,
// port = plc.port
//});
//CMMLog.Debug($"写入设备{plc.location}通道{plc.writeAddr + 1}里面数据为2.");
//Console.WriteLine($"写入设备{plc.location}通道{plc.writeAddr + 1}里面数据为2.");
#endregion
}
else CMMLog.Debug($"machine判断错误,为null!");
}
else CMMLog.Debug($"包装下线,1113,ip=null!");
}
///
/// 复称卸货完成
///
///
///
///
internal static void CheckUpUnloadComplete(string ip, string cN_S_TASK_NO,string machineNo, int port)
{
var plc = Settings.GetPlcInfo().Where(a => a.ip == ip && a.port == port).FirstOrDefault();
int[] num = new int[1] { 2 };
var writeRes0 = OITcpHelper.RegisterWriteOutPutMulti(new OITcpHelper.RegisterWriteOutPutModelMulti
{
host = ip,
addr = plc.writeAddr + 1,
data = num,//原先是1,单个写入
port = plc.port
});
var tray = MongoDBSingleton.Instance.FindOne(Query.EQ("CN_S_TASK_NO", cN_S_TASK_NO), "TN_I_TASK_MST");
var query = Query.And(Query.EQ("actionNo", "1"), Query.EQ("ext1", ip), Query.EQ("ext2", tray.CN_S_BATCH_NO));
var ActionControlInfo = MongoDBSingleton.Instance.FindOne(query, "ActionControlModel");
if (ActionControlInfo == null)
{
MongoDBSingleton.Instance.Insert(new ActionControlModel
{
actionNo = "1",
ext1 = ip,
ext2 = tray.CN_S_BATCH_NO,
ext3 = plc.port,
machince = machineNo
}, "ActionControlModel");
}
}
///
/// 取货完成,离开复称,复位通道,并读取设备通道数据
///
///
///
internal static void SecondWeightInCache4(string ip, string taskNo)
{
CMMLog.Info("离开复称平台,任务处理开始");
var plc = Settings.GetPlcInfo().Where(a => a.deviceType == ip).FirstOrDefault();
var trayCodeTask = MongoDBSingleton.Instance.FindOne(Query.EQ("CN_S_TASK_NO", taskNo), "TN_I_TASK_MST");
if (trayCodeTask != null)
{
string trayCodeNo = trayCodeTask.CN_S_BATCH_NO;
if (trayCodeNo != "")
{
//var status = MongoDBSingleton.Instance.FindOne(Query.EQ("location", GetSecondWeighBit()), "SecondWeighState");
//UpdateBuilder update = Update.Set("full", 0);
//if (status.ng != 2)
//{
// update = Update.Set("ng", 0).Set("full", 0);
//}
UpdateBuilder update = Update.Set("full", 0).Set("ng", 0);
CMMLog.Info($"开始更改复称状态中间表状态:full:0");
CMMLog.Info($"三楼双层缓存架卸货交互:trayCode:{trayCodeTask.CN_S_BATCH_NO}");
if (MongoDBSingleton.Instance.Remove(Query.EQ("trayCode", trayCodeTask.CN_S_BATCH_NO), "MachineInfo", RemoveFlags.Single))
{
CMMLog.Info($"删除中间表MachineInfo的数据成功,tray:{trayCodeTask.CN_S_BATCH_NO}");
}
else
{
CMMLog.Info($"删除中间表MachineInfo的数据失败,tray:{trayCodeTask.CN_S_BATCH_NO}");
}
if (ERPService.ERPSwitch01 == "0") MongoDBSingleton.Instance.Remove(Query.EQ("trayCode", trayCodeTask.CN_S_BATCH_NO), "MachineInfoTwo", RemoveFlags.Single);
//MongoDBSingleton.Instance.Update(Query.EQ("CN_S_TASK_NO", taskNo), Update.Set("CN_S_BATCH_NO", trayCodeNo), UpdateFlags.None);
MongoDBSingleton.Instance.Update(Query.EQ("location", plc.location), update, "SecondWeighState", UpdateFlags.None);
}
}
if (plc != null)
{
var writeRes1 = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
host = plc.ip,
addr = plc.writeAddr + 3,
data = 1,
port = plc.port
});
CMMLog.Info($"【缓存架入复称】写入通道{plc.writeAddr + 3}的信号为[1]");
}
}
///
/// 复称平台安全退出(已退出)--二期无需执行此指令动作
///
///
///
///
internal static bool SecondWeightSafeComplete(string ip, string cN_S_TASK_NO)
{
var plc = Settings.GetPlcInfo().Where(a => a.ip == ip).FirstOrDefault();
bool result = true;
if(ip != "")
{
//var wirte = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
//{
// addr = plc.writeAddr,
// data = 0,
// host = ip,
// port = plc.port
//});
//CMMLog.Debug($"写入设备{plc.location}通道{plc.writeAddr}里面数据为0.");
////Console.WriteLine($"写入设备{plc.location}通道{plc.writeAddr}里面数据为0.");
//var wirte1 = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
//{
// addr = plc.writeAddr + 1,
// data = 0,
// host = ip,
// port = plc.port
//});
//CMMLog.Debug($"写入设备{plc.location}通道{plc.writeAddr + 1}里面数据为0.");
////Console.WriteLine($"写入设备{plc.location}通道{plc.writeAddr + 1}里面数据为0.");
result = true;
}
else
{
CMMLog.Debug($"包装下线,4,ip=null!");
}
return result;
}
internal static void SecondWeightActionOne(ActionControlModel model)
{
var plc = Settings.GetPlcInfo().Where(a => a.ip == model.ext1 && a.port == model.ext3).FirstOrDefault();
if (plc != null)
{
bool req = false;
var result = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
dataNum = 28,
addr = plc.readAddr + 1,
host = plc.ip,
port = plc.port
});
CMMLog.Info("SecondWeightActionOne----" + JsonConvert.SerializeObject(result) + $"{result.result.Length}");
if(result.result.Length > 0)
{
CMMLog.Debug($"读取设备{plc.location},ip:{plc.ip}通道{plc.readAddr + 1}里面数据为{result.result[2]}.");
MongoDBSingleton.Instance.Update(Query.EQ("trayCode", model.ext2), Update.Set("secondNg", result.result[2]), UpdateFlags.None);
//获取从复称平台读出的 时间戳,并转换处理为 string 字符串
string timeStamp = Convert.ToInt32(Completion(result.result[25]) + Completion(result.result[26]), 2).ToString();
string wmstaskno = "";
string traycode = "";
CMMLog.Info($"SecondWeightActionOne:readData:{JsonConvert.SerializeObject(result.result)},timeStamp:{timeStamp}");
if (result.result[0] == 3)
{
int[] num = new int[1] { 0 };
var writeRes0 = OITcpHelper.RegisterWriteOutPutMulti(new OITcpHelper.RegisterWriteOutPutModelMulti
{
host = plc.ip,
addr = plc.writeAddr + 1,
data = num,//原先是1,单个写入
port = plc.port
});
}
if (result.result[0] == 3 && result.result[2] == 1)
{
CMMLog.Debug($"准备生成复称入缓存架任务,开始确定托盘号:{model.ext2}");
//更新复称平台的数据到中间表
var trayCode = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
addr = plc.readAddr + 8,
dataNum = 12,//数据个数要增加
host = plc.ip,
port = plc.port
});
if (trayCode.errCode == 0 && trayCode.result.Length == 12)
{
//获取复称OK数据存入MachineInfo表
GetOKWeight(trayCode.result, model.ext2);
}
else
{
CMMLog.Debug($"复称OK流程:读取复称平台重量错误!trayCode.errCode:{trayCode.errCode},trayCode.result.Length:{trayCode.result.Length}");
//Console.WriteLine($"复称OK流程:读取复称平台重量错误!trayCode.errCode:{trayCode.errCode},trayCode.result.Length:{trayCode.result.Length}");
}
//req = WMSHelper.WMSIn(plc.location, model.ext2, ref wmstaskno, ref traycode, timeStamp);
req = WMSHelper.WMSIn(plc.location, model.ext2, ref wmstaskno, ref traycode);
//ERPService.updatePackageInfo(model.machince, model.ext2, result.result);
if (req)
{
var queryList = MongoDBSingleton.Instance.Find(Query.And(Query.EQ("machineNo", model.machince), Query.EQ("trayCode", model.ext2), Query.EQ("weight2", "")), "packageInfoModel");
if (queryList.Count > 0)
{
packageInfoModel query = queryList.OrderByDescending(a => a.time).First();
if (query != null)
{
CMMLog.Debug($"machine:{query.machineNo},trayCode:{query.trayCode},weight:{query.weight}");
//读取复称平台的重量
double x = (double)Convert.ToInt32(Completion(result.result[0]) + Completion(result.result[1]), 2) / 100;
//double x = (double)Convert.ToInt32(Completion(result[8]) + Completion(result[9]), 2) / 100;
string weight = x.ToString();
CMMLog.Debug($"读取设备{plc.location},ip:{plc.ip}通道{plc.readAddr + 8}里面数据为{result.result[0]}.");
CMMLog.Debug($"读取设备{plc.location},ip:{plc.ip}通道{plc.readAddr + 9}里面数据为{result.result[1]}.");
CMMLog.Debug($"weight:{weight}");
//重量差值
string weightDifference = Math.Round((double.Parse(query.weight) - x), 2).ToString();
//将复称平台重量写入中间表
MongoDBSingleton.Instance.Update(Query.And(Query.EQ("machineNo", model.machince), Query.EQ("time", query.time), Query.EQ("trayCode", query.trayCode), Query.EQ("weight2", "")), Update.Set("weight2", weight).Set("weightDifference", weightDifference), UpdateFlags.None);
}
else CMMLog.Debug($"数据查询失败");
}
else CMMLog.Debug($"packageInfoModel未找到数据,machineNo:{model.machince},trayCode:{model.ext2}");
var wirte = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
addr = plc.writeAddr + 3,
host = plc.ip,
port = plc.port,
data = 1
});
CMMLog.Debug($"复称任务任务生成完成,ip:{plc.ip},端口:{plc.port},写入通道{plc.writeAddr + 3} 的值为1");
//复称合格,更新表数据
var proInfo = MongoDBSingleton.Instance.FindOne(Query.And(Query.EQ("Date", DateTime.Now.ToString("yyyy-MM-dd")), Query.EQ("machine", model.machince)), "ProductList");
if (proInfo != null)
{
proInfo.qualifiedQuantity = proInfo.qualifiedQuantity + 1;
proInfo.percentOfPass = Math.Round(((proInfo.qualifiedQuantity / proInfo.total) * 100), 2);
MongoDBSingleton.Instance.Update(Query.And(Query.EQ("Date", DateTime.Now.ToString("yyyy-MM-dd")), Query.EQ("machine", model.machince)), Update.Set("percentOfPass", proInfo.percentOfPass).Set("qualifiedQuantity", proInfo.qualifiedQuantity), UpdateFlags.None);
}
}
}
if (result.result[2] == 2)
{
CMMLog.Debug($"准备生成复称入缓存架NG任务,开始确定托盘号:{model.ext2}");
//复称平台复称货物NG——进入NG复称流程 调用WMS接口分配货架库位
//TSHelper.GoToAGV(cN_S_TASK_NO, 10, 6);
req = WMSHelper.WMSIn(plc.location, model.ext2, ref wmstaskno, ref traycode, timeStamp);
//req = WMSHelper.WMSIn(plc.location, model.ext2, ref wmstaskno, ref traycode);
if (req)
{
var wirte = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
addr = plc.writeAddr + 3,
host = plc.ip,
port = plc.port,
data = 1
});
CMMLog.Debug($"复称入缓存架NG流程:WMS生成任务成功!");
//更新复称平台的数据到中间表
var trayCode = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
addr = plc.readAddr + 8,
dataNum = 2,//数据个数要增加
host = plc.ip,
port = plc.port
});
if (trayCode.errCode == 0 && trayCode.result.Length == 2)
{
var queryList = MongoDBSingleton.Instance.Find(Query.And(Query.EQ("machineNo", model.machince), Query.EQ("trayCode", model.ext2), Query.EQ("weight2", "")), "packageInfoModel");
if (queryList.Count > 0)
{
packageInfoModel query = queryList.OrderByDescending(a => a.time).First();
if (query != null)
{
CMMLog.Debug($"machine:{query.machineNo},trayCode:{query.trayCode},weight:{query.weight}");
//读取复称平台的重量
double x = (double)Convert.ToInt32(Completion(trayCode.result[0]) + Completion(trayCode.result[1]), 2) / 100;
//double x = (double)Convert.ToInt32(Completion(result[8]) + Completion(result[9]), 2) / 100;
string weight = x.ToString();
CMMLog.Debug($"读取设备{plc.location},ip:{plc.ip}通道{plc.readAddr + 8}里面数据为{trayCode.result[0]}.");
CMMLog.Debug($"读取设备{plc.location},ip:{plc.ip}通道{plc.readAddr + 9}里面数据为{trayCode.result[1]}.");
CMMLog.Debug($"weight:{weight}");
//重量差值
string weightDifference = Math.Round((double.Parse(query.weight) - x), 2).ToString();
//将复称平台重量写入中间表
MongoDBSingleton.Instance.Update(Query.And(Query.EQ("machineNo", model.machince), Query.EQ("time", query.time), Query.EQ("trayCode", query.trayCode), Query.EQ("weight2", "")), Update.Set("weight2", weight).Set("weightDifference", weightDifference), UpdateFlags.None);
}
else CMMLog.Debug($"数据查询失败");
}
else CMMLog.Debug($"packageInfoModel未找到数据,machineNo:{model.machince},trayCode:{model.ext2}");
}
}
else CMMLog.Debug($"复称入缓存架NG流程:WMS生成任务失败!");
}
string PlcBit02 = Settings.GetPlcInfo().Where(a => a.deviceType == "2").FirstOrDefault().location;
UpdateBuilder update = Update.Set("ng", result.result[2]);
if (MongoDBSingleton.Instance.Update(Query.EQ("location", PlcBit02), update, "SecondWeighState", UpdateFlags.None))
{
CMMLog.Debug($"中间表SecondWeighState数据插入成功,location:{PlcBit02}");
}
if (req)
{
if (MongoDBSingleton.Instance.Remove(Query.EQ("_id", model._id), "ActionControlModel", RemoveFlags.Single))
{
CMMLog.Debug($"中间表ActionControlModel数据删除成功,id:{model._id}");
}
}
}
}
else CMMLog.Debug($"复称平台未配置,ip:{model.ext1},端口:{model.ext3}");
}
private static void GetOKWeight(int[] result, string ItemCode)
{
var info = MongoDBSingleton.Instance.FindOne(Query.EQ("trayCode", ItemCode), "MachineInfo");
if (info != null)
{
CMMLog.Info($"从包装机获取的物料重量:{info.oneTrayWeight}");
var newWeight = Convert.ToInt32(Completion(result[10]) + Completion(result[11]), 2).ToString();
//更新数据
CMMLog.Info($"从复称平台获取的物料重量:{newWeight}");
UpdateBuilder update = Update.Set("oneTrayWeight", newWeight);
MongoDBSingleton.Instance.Update(Query.EQ("trayCode", ItemCode), update, "MachineInfo", UpdateFlags.None);
//MongoDBSingleton.Instance.Update(Query.EQ("trayCode", ItemCode), Update.Set("oneTrayWeight", info.oneTrayWeight), "MachineInfo", UpdateFlags.None);
CMMLog.Info("复称OK的重量更新到中间表MachineInfo");
}
var infoTwo = MongoDBSingleton.Instance.FindOne(Query.EQ("trayCode", ItemCode), "MachineInfo");
if (infoTwo != null)
{
//var newWeight = (Convert.ToInt32(Completion(result[0]) + Completion(result[1]), 2) / 100).ToString();
var newWeight = result[0] + "," + result[1];
//更新数据
CMMLog.Info($"从复称平台获取的物料重量:{newWeight}");
UpdateBuilder update = Update.Set("oneTrayWeightFC", newWeight);
MongoDBSingleton.Instance.Update(Query.EQ("trayCode", ItemCode), update, "MachineInfoTwo", UpdateFlags.None);
CMMLog.Info("复称毛重更新到中间表MachineInfoTwo");
}
}
#endregion
#endregion
#region 3楼双层缓存货架到三楼叠托口——需回报WMS任务状态——3楼缓存架入叠托——半完成(待测试)
///
/// 判断三楼叠托口是否有允许上料请求(通道1参数1),有就调WMS生成缓存架到叠托口任务
///
///
internal static void CacheStackingMouth(Settings.PlcInfo pmInfo)
{
//需要设置时间延迟
try
{
//读取通道1里面参数是否为1,判断叠盘机是否需要上料
var result = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
dataNum = 1,
addr = pmInfo.readAddr + 1,
host = pmInfo.ip,
port = pmInfo.port
});
if (result != null && result.errCode == 0)
{
//参数1表示叠托点申请入料
if (result.result[0] == 1)
{
//var tasks = MongoDBSingleton.Instance.Find(Query.EQ("CN_S_END_BIT", pmInfo.location), "TN_I_TASK_MST");
var tasks = MongoDBSingleton.Instance.Find(Query.EQ("S_END_LOC", pmInfo.location), "elevatorTask");
//判断一下当前叠托点是否有任务占用
if (ProcessHelper.CheckEndFree(pmInfo.location) && tasks.Count == 0)
{
//可以生成任务,调WMS接口获取任务信息
bool req = WMSHelper.WMSOut(pmInfo.location, "");
if (req) CMMLog.Debug($"调用WMS获取碟盘出库生成任务成功!");//现在任务由WMS自己下发,AMS做拦截处理(查询ext1里面对应的任务类型,并更改任务类型)
else CMMLog.Debug($"调用WMS获取碟盘出库生成任务失败!");
}
else CMMLog.Debug($"检查当前叠托点是否有任务占用,或者elevatorTask表中有缓存架入叠盘机的任务!");
}
}
else CMMLog.Debug($"缓存入叠盘机,创建任务,result={result.errMsg}");
}
catch (Exception ex)
{
CMMLog.Error(ex.Message, ex);
}
}
#region 三楼叠托机交互
///
/// 请求进入三楼叠托机
///
///
///
internal static void CacheStackingMouth1013(string ip,string taskNo, string CN_S_END_BIT)
{
CMMLog.Info("【电梯开门】叠盘机任务请求进入电梯,信号1013");
var plc = Settings.GetPlcInfo().Where(a => a.deviceType == ip).FirstOrDefault();
if(plc != null)
{
var readres = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
dataNum = 1,
addr = plc.readAddr + 1,
host = plc.ip,
port = plc.port
});
CMMLog.Info($"【电梯开门】读取通道{plc.readAddr + 1}的信号为[{JsonConvert.SerializeObject(readres)}]");
if (readres.result[0] != 2)
{
var wirte = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
addr = plc.writeAddr + 1,
host = plc.ip,
port = plc.port,
data = 1
});
CMMLog.Info($"【电梯开门】写入通道{plc.writeAddr + 1}的信号为[1]");
}
else
{
TSHelper.GoToAGV(taskNo, 10, 3);
var wirte = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
addr = plc.writeAddr + 1,
host = plc.ip,
port = plc.port,
data = 2
});
CMMLog.Info($"【电梯开门】写入通道{plc.writeAddr + 1}的信号为[2]");
}
}
else CMMLog.Debug($"缓存入叠盘机,1013,plc=null!");
}
///
/// 三楼叠托机扫码
///
///
///
internal static void CacheStackingMouth1313(string dev, TN_I_TASK_MST mst)
{
CMMLog.Info($"【叠包入口】任务流程处理开始------------");
var plc = Settings.GetPlcInfo().Where(a => a.deviceType == dev).FirstOrDefault();
if(plc != null)
{
var readres = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
dataNum = 2,
addr = plc.readAddr + 1,
host = plc.ip,
port = plc.port
});
if(readres != null)
{
var eleInfo = MongoDBSingleton.Instance.FindOne(Query.And(Query.EQ("S_DT_LOC", mst.CN_S_START_BIT),Query.EQ("S_USE", "1")), "elevatorTask");
if(eleInfo != null)
{
var taskInfo = eleInfo.task_mst;
CMMLog.Info($"【叠包入口】读取通道{plc.readAddr + 1}的信号为[{readres.result[0]}],收到通道{plc.readAddr + 2}的信号为[{readres.result[1]}]");
if (readres.result[0] == 3)
{
if (readres.result[1] == 1)
{
CMMLog.Info($"读码信息比对结果:条码与传送的数据一致");
//读码信息比对结果:OK 读到通道2参数为1时,小车将托盘放置在叠盘机上(改参数10为7)
var wirte = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
addr = plc.writeAddr + 1,
host = plc.ip,
data = 3,//4
port = plc.port
});
CMMLog.Info($"【叠包入口】写入通道{plc.writeAddr + 1}的信号为{3},返回值:{wirte.errCode}");
if (wirte.errCode == 0)
{
//并删除WMSInfo中间表中对应托盘号的数据(也可在小车离开叠盘机之后删除,暂定通道2参数1)
CMMLog.Info($"读码信息比对结果:OK ,并删除WMSInfo中间表中对应托盘号的数据");
MongoDBSingleton.Instance.Remove(Query.EQ("trayCode", taskInfo.CN_S_BATCH_NO), RemoveFlags.Single);
TSHelper.GoToAGV(mst.CN_S_TASK_NO, 10, 7);
}
//通道写入4,ok流程可以直接写,ng流程需要等到小车取货完之后写入(注:该流程测试通过,暂时可以不改,现场出现问题在更改)
PLCControl.CacheStackingMouth6(plc);
}
else if (readres.result[1] == 2)
{
CMMLog.Info($"读码信息比对结果:条码与传送的数据不一致");
//二期--调用 WMS 改道接口 获取 目标点位,并 更改 AGV 站点
string ChangeBit = WMSHelper.WmsUpdateWay(taskInfo.CN_S_SOURCE_NO, plc.Extend);
if (!string.IsNullOrEmpty(ChangeBit))
{
CMMLog.Info($"起点:{taskInfo.CN_S_END_BIT}");
CMMLog.Info($"终点:{ChangeBit}");
int[] parms = { StockInstance.Instance.GetAGVCodeForBitCode(taskInfo.CN_S_END_BIT), StockInstance.Instance.GetAGVCodeForBitCode(ChangeBit) };
//TSHelper.ChangeParam(taskNo, 1, StockInstance.Instance.GetAGVCodeForBitCode(taskInfo.CN_S_END_BIT));
//TSHelper.ChangeParam(taskNo, 2, StockInstance.Instance.GetAGVCodeForBitCode(ChangeBit));
TSHelper.ChangeParam(mst.CN_S_TASK_NO, 1, parms);
TSHelper.GoToAGV(mst.CN_S_TASK_NO, 3, 1);
TSHelper.GoToAGV(mst.CN_S_TASK_NO, 10, 8);
MongoDBSingleton.Instance.Update(Query.EQ("CN_S_TASK_NO", mst.CN_S_TASK_NO), Update.Set("CN_S_END_BIT", ChangeBit).Set("CN_S_START_BIT", taskInfo.CN_S_END_BIT), "TN_I_TASK_MST", UpdateFlags.None);
MongoDBSingleton.Instance.Remove(Query.EQ("trayCode", taskInfo.CN_S_BATCH_NO), RemoveFlags.Single);
}
else CMMLog.Debug($"调用WMS改道接口,未获取到可用点位。");
//Console.WriteLine($"读码信息比对结果:条码与传送的数据不一致");
}
}
}
}
}
CMMLog.Info($"【叠包入口】任务流程处理结束------------");
}
///
/// 卸货离开三楼叠托机--二期:需要和TS对接,让小车 卸货完成等到 小车离开之后再发送
///
///
internal static bool CacheStackingMouth6(Settings.PlcInfo plc)
{
bool result = false;
var wirte = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
addr = plc.writeAddr + 1,
data = 4,
host = plc.ip,
port = plc.port
});
if (wirte.errCode == 0) result = true;
return result;
}
#endregion
#endregion
#region 3楼包装机空托补给3楼包装机流程——无需回报WMS任务状态——3楼包装补空——已完成(待测试)
///
/// 3楼包装机补空托流程——任务开始前,判断包装机有没有下线信号,并判断当前包装机对应的地堆位是否有任务占用
///
///
internal static void PickUpBlank(Settings.PlcInfo pmInfo)
{ /* 包装补空流程:
* 先判断包装机是否有任务占用,若无任务占用则判断是否需要补空托
* 判断起点是否有任务占用
* **/
//包装补空缺陷,同时会有两个空托点补一个包装机
try
{
if (ProcessHelper.PickUpEndFree(pmInfo.location))
{
//读取输入寄存器还是输出寄存器待定,读取通道0的数据
var result = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
dataNum = 1,
addr = pmInfo.readAddr,
host = pmInfo.ip,
port = pmInfo.port
});
CMMLog.Info($"包装机补空托流程:包装机号:{pmInfo.location},判断包装机通道{pmInfo.readAddr}值为{JsonConvert.SerializeObject(result)},ip:{pmInfo.ip}");
if (result.result.Count() > 0)
{
if (result != null && result.errCode == 0)
{
//1:取料;3:人工叫空托盘
if (result.result[0] == 3)
{
//包装线补空流程
//判断空托缓存点(5 对 2)是否有空托,有空托判断是否有任务,有任务则判断另一个点位
var locInfo = Settings.GetAGVLocationList().Where(b => b.machineLoc.Contains(pmInfo.location) && b.Enabel == 1).First();
if (locInfo != null)
{
CMMLog.Info($"包装机点位:{pmInfo.location}");
foreach (var a in locInfo.ddLoc)
{
if (ProcessHelper.PickUpEndFree(pmInfo.location) && ProcessHelper.PickUpStartFree(a))
{
var empInfo = MongoDBSingleton.Instance.FindOne(Query.EQ("Bit", a), "BZEmptyPoint");
if (empInfo != null && empInfo.Quantity > 0)
{
CMMLog.Info($"包装线补空任务,包装机点位:{pmInfo.location},周转托盘位:{a},周转托盘位数量:{empInfo.Quantity}");
HHAmsExecuteResult amsResult = AMSHelper.CreateTask(DateTime.Now.Ticks.ToString(), a, pmInfo.location, "PackagingMachineFillsEmptyPallet", 0, "");
if (amsResult.success)
{
CMMLog.Info($"包装线补空任务生成成功");
break;
}
}
}
}
}
else
{
CMMLog.Info("配置文件未配置包装机空托缓存点");
}
}
}
else
{
CMMLog.Info($"err 包装机通道{pmInfo.readAddr} ip:{pmInfo.ip}");
}
}
}
}
catch (Exception ex)
{
CMMLog.Error(ex.Message, ex);
}
}
static object PickUpBlankCompleteLock = new object();
///
/// 包装补空任务完成--复位 收到上空信号 为 0
///
///
internal static void PickUpBlankComplete(string PlcBitCache01,string Extend = "")
{
lock (PickUpBlankCompleteLock)
{
CMMLog.Info("包装线补空流程任务处理");
try
{
if (Extend != "")
{
CMMLog.Info($"当前周转托盘位:{Extend}");
int addr = 0;
int qun = 0;
//修改中间表的值,若中间表的数量为0,则调用解绑方法
var bzEmp = MongoDBSingleton.Instance.FindOne(Query.EQ("Bit", Extend), "BZEmptyPoint");
if (bzEmp != null)
{
CMMLog.Info($"当前货位的数量:{bzEmp.Quantity}");
if (bzEmp.Quantity == 1)
{
CMMLog.Info($"调用解绑接口");
//解绑
if (WMSHelper.WMSEmptyUnbind(Extend))
{
//删除中间表数据
MongoDBSingleton.Instance.Remove(Query.EQ("Bit", Extend), RemoveFlags.Single);
}
}
else
{
var quantity = bzEmp.Quantity - 1;
var updateBuider = Update.Set("Quantity", quantity);
MongoDBSingleton.Instance.Update(Query.EQ("Bit", Extend), updateBuider, UpdateFlags.None);
CMMLog.Info($"减去当前周转托盘位数量之后,数量为:{quantity}");
qun = quantity;
}
}
}
}
catch (Exception ex)
{
CMMLog.Error($"PickUpBlankComplete Error:" + ex.Message);
}
}
}
#endregion
#region 3楼补给成品空托区到3楼拆盘机流程——需回报WMS任务状态——3楼拆盘补空——已完成(待测试)
///
/// 线程循环查询拆盘机是否需要补空托
///
///
internal static void CheckPackingLineEmpty(Settings.PlcInfo plc)
{
//读plc信号,看有没有叫料请求,判断是否已经有任务
//没有任务,调WMS生成空托补充任务
try
{
//RegisterReadInPut 读取输入寄存器还是输出寄存器待定,读取通道1的数据
var result = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
dataNum = 1,
addr = plc.readAddr+1,
host = plc.ip,
port = plc.port
});
if (result != null && result.errCode == 0)
{
//1.补空托盘
if (result.result[0] == 1)
{
//判断3楼拆盘机(补空托盘点位)终点是否有任务占用,没有则生成任务
if (ProcessHelper.CheckEndFree(plc.location))
{
string wmstaskno = "";
string traycode = "";
bool req = WMSHelper.WMSEmptyOut(plc.location, "", ref wmstaskno, ref traycode);
if (req) CMMLog.Debug($"调用WMS获取三楼拆盘机生成任务成功!");
else CMMLog.Debug($"调用WMS获取三楼拆盘机生成任务失败!");
}
}
}
}
catch (Exception ex)
{
CMMLog.Error(ex.Message, ex);
}
}
#region 拆盘机交互
/// 小车请求出料 1 AMS写,PLC读 1-请求出料;2-出料进行中;3-动作完成
/// 设备允许进料 1 PLC写,AMS读 1-允许进料;2-进料进行中;3-动作完成
///
/// 向拆盘机请求卸货
///
///
internal static void DiscRemoverReqUnload(string ip, string taskNo)
{
var plc = Settings.GetPlcInfo().Where(a => a.deviceType == ip).FirstOrDefault();
if (plc != null)
{
var wirte = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
addr = plc.writeAddr + 1,
host = plc.ip,
port = plc.port,
data = 1
});
CMMLog.Info($"写{plc.ip}取通道{plc.writeAddr + 1}的数据为1");
var readRes = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
dataNum = 1,
host = plc.ip,
port = plc.port,
addr = plc.readAddr + 1
});
CMMLog.Info($"读{plc.ip}取通道{plc.readAddr + 1}的数据为{JsonConvert.SerializeObject(readRes)}");
if (readRes != null && readRes.errCode == 0)
{
if (readRes.result[0] == 0 || readRes.result[0] == 1)
{
//不允许进料,ams写入请求出料
var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
host = plc.ip,
port = plc.port,
addr = plc.writeAddr + 1,
data = 1
});
}
else if (readRes.result[0] == 2)
{
//设备允许进料
//改参数通知agv
if (TSHelper.GoToAGV(taskNo, 10, 3))
{
WorkFlowAction.TrackLog(taskNo, 10, 1013, "success");
//改成出料进行中
CMMLog.Debug("三楼拆盘机:小车正在卸空盘中!");
var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
host = plc.ip,
port = plc.port,
addr = plc.writeAddr + 1,
data = 2
});
}
else CMMLog.Debug($"三楼拆盘补空,1013,TS,10,3,false!");
}
}
}
}
///
/// 小车卸货完成离开通知拆盘机
///
///
///
internal static bool DiscRemoverUnloadComplete(string ip, string taskNo)
{
var result = false;
var plc = Settings.GetPlcInfo().Where(a => a.deviceType == ip).FirstOrDefault();
if (plc != null)
{
//1.0 读地址1设备是否动作完成
//var readRes = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
//{
// dataNum = 1,
// host = plc.ip,
// port = plc.port,
// addr = plc.readAddr + 1
//});
//CMMLog.Info($"读{plc.ip}取通道{plc.readAddr + 1}的数据为{readRes.result[0]}");
//if (readRes != null && readRes.errCode == 0)
//{
//if (readRes.result[0] == 2)
//{
var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
host = plc.ip,
port = plc.port,
addr = plc.writeAddr + 1,
data = 3
});
CMMLog.Info($"写入{plc.ip}通道{plc.writeAddr + 1}的数据为{3}");
result = true;
CMMLog.Debug("读取设备【参数不为0】,AMS设置小车【动作完成】,等待设备【参数为0】时再改参数通知agv");
//}
//}
}
else CMMLog.Info($"deviceType:{ip},未找到");
return result;
}
#endregion
#endregion
#region 3楼叠盘机满托下线入库流程——需回报WMS任务状态——3楼叠盘下线--已完成(待测试)
///
/// 线程循环查询叠盘机是否需要下满托
///
///
internal static void StackingLineEmpty(Settings.PlcInfo plc)
{
//读plc信号,看有没有叫料请求,判断是否已经有任务
//没有任务,调WMS生成空托补充任务
try
{
//RegisterReadInPut 读取输入寄存器还是输出寄存器待定,读取通道1的数据
var result = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
dataNum = 1,
addr = plc.readAddr + 1,
host = plc.ip,
port = plc.port
});
if (result != null && result.errCode == 0)
{
//1.满托下线
if (result.result[0] == 1)
{
//判断3楼叠盘起点是否有任务占用,没有则生成任务
if (ProcessHelper.CheckStartFree(plc.location))
{
string wmstaskno = "";
string traycode = "";
bool req = WMSHelper.WMSIn(plc.location, "", ref wmstaskno, ref traycode);
if (req) CMMLog.Debug($"调用WMS获取三楼叠盘机生成任务成功!");
else CMMLog.Debug($"调用WMS获取三楼叠盘机生成任务失败!");
}
}
}
}
catch (Exception ex)
{
CMMLog.Error(ex.Message, ex);
}
}
#region 叠盘机交互
/// 小车请求出料 1 AMS写,PLC读 1-请求出料;2-出料进行中;3-动作完成
/// 设备允许进料 1 PLC写,AMS读 1-允许进料;2-进料进行中;3-动作完成
///
/// 向叠盘机请求取货
///
///
internal static void StackingReqUnload(string ip, string taskNo)
{
var plc = Settings.GetPlcInfo().Where(a => a.deviceType == ip).FirstOrDefault();
if (plc != null)
{
var wirte = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
addr = plc.writeAddr + 1,
host = plc.ip,
port = plc.port,
data = 1
});
CMMLog.Debug($"写入通道号为:{plc.writeAddr + 1},的数据为:1");
var readRes = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
dataNum = 1,
host = plc.ip,
port = plc.port,
addr = plc.readAddr + 1
});
CMMLog.Debug($"读取通道号为:{plc.readAddr + 1},的数据为:{JsonConvert.SerializeObject(readRes)}");
if (readRes != null && readRes.errCode == 0)
{
if (readRes.result[0] == 0 || readRes.result[0] == 1)
{
//不允许进料,ams写入请求出料
var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
host = plc.ip,
port = plc.port,
addr = plc.writeAddr + 1,
data = 1
});
}
else if (readRes.result[0] == 2)
{
//设备允许进料
//改参数通知agv
if (TSHelper.GoToAGV(taskNo, 10, 1))
{
WorkFlowAction.TrackLog(taskNo, 10, 1013, "success");
//改成出料进行中
CMMLog.Debug("三楼叠盘机:小车正在取托盘中!");
var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
host = plc.ip,
port = plc.port,
addr = plc.writeAddr + 1,
data = 2
});
CMMLog.Debug($"写入通道号为:{plc.writeAddr + 1},的数据为:2");
}
else CMMLog.Debug($"三楼叠盘机,1013,TS,10,3,false!");
}
}
}
}
///
/// 小车取货完成离开通知叠盘机
///
///
///
internal static bool StackingComplete(string ip, string taskNo)
{
var result = false;
var plc = Settings.GetPlcInfo().Where(a => a.deviceType == ip).FirstOrDefault();
if (plc != null)
{
//1.0 读地址1设备是否动作完成
var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
host = plc.ip,
port = plc.port,
addr = plc.writeAddr + 1,
data = 3
});
result = true;
CMMLog.Debug("读取设备【参数不为0】,AMS设置小车【动作完成】,等待设备【参数为0】时再改参数通知agv");
}
return result;
}
#endregion
#endregion
#region 包装线补空任务
internal static void PackingLine(string ip, string taskNo)
{
var plc = Settings.GetPlcInfo().Where(a => a.ip == ip).FirstOrDefault();
//ASM写入小车动作,1:上料复称;2:上砝码教称;3:取复称NG托盘,4:取砝码到包装机
int[] num = new int[1] { 1 };
var writeRes0 = OITcpHelper.RegisterWriteOutPutMulti(new OITcpHelper.RegisterWriteOutPutModelMulti
{
host = ip,
addr = plc.writeAddr + 2,
data = num,//原先是1,单个写入
port = plc.port
});
CMMLog.Debug($"写入设备{plc.location}通道{plc.writeAddr + 2}里面数据为1.");
writeRes0 = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
host = ip,
addr = plc.writeAddr,
data = 3,//原先是1,单个写入
port = plc.port
});
CMMLog.Debug($"写入设备{plc.location}通道{plc.writeAddr + 2}里面数据为1.");
//Console.WriteLine($"写入设备{plc.location}通道{plc.writeAddr + 2}里面数据为1.");
///小车和复称位对接
//小车请求进料,并且查询设备是否允许AGV进入
var readRes = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
dataNum = 1,
host = plc.ip,
addr = plc.readAddr + 2,
port = plc.port
});
CMMLog.Debug($"读取设备{plc.location}通道{plc.readAddr + 2}里面数据为{readRes.result[0]}.");
//Console.WriteLine($"读取设备{plc.location}通道{plc.readAddr + 2}里面数据为{readRes.result[0]}.");
if (readRes != null && readRes.errCode == 0)
{
if (readRes.result[0] == 2)
{
var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
host = ip,
addr = plc.writeAddr + 2,
data = 2,
port = plc.port
});
CMMLog.Debug($"写入设备{plc.location}通道{plc.writeAddr + 2}里面数据为2.");
//Console.WriteLine($"写入设备{plc.location}通道{plc.writeAddr + 2}里面数据为2.");
WorkFlowAction.TrackLog(taskNo, 10, 1013, "success");
TSHelper.GoToAGV(taskNo, 10, 3);
}
}
}
#endregion
#endregion
#region 跨楼层任务
#region 货物入库流程——满托入库
#region 收到打包机下线信号,判断条件是否允许,选择性下发任务
internal static void CheckPackingLineFull1(Settings.PlcInfo plc)
{
//读plc信号,看有没有下线请求,判断是否已经有任务
//没有任务,继续plc,包装下线的物料信号
//检查打包机通道1是否有出料任务信号,如果有生成取料任务。
if (CheckStartFree(plc.location))
{
try
{
var result = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
dataNum = 1,
addr = plc.readAddr + 1,
host = plc.ip,
port = plc.port
});
CMMLog.Debug($"打包下线流程:读取通道号为:{plc.readAddr + 1},ip:{plc.ip},端口:{plc.port}");
CMMLog.Debug($"值为:{result.result[0]}");
if (result != null && result.errCode == 0)
{
if (result.result[0] == 1)
{
//获取MODBUS通道里面存放的时间戳
var resultTime = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
addr = plc.readAddr + 10,
host = plc.ip,
port = plc.port,
dataNum = 2
});
if (resultTime.errCode == 0)
{
string wmstaskno = "";
string timeCuoData = (resultTime.result[0] * 65536 + resultTime.result[1]).ToString();
//CMMLog.Info($"获取到的MODBUS时间戳:{timeCuoData},地址:{plc.ip},端口:{plc.port},通道:{plc.readAddr + 10}、{plc.readAddr + 11}");
//Console.WriteLine($"获取到的MODBUS时间戳:{timeCuoData}");
//这里需要调用照相机接口,获取数据存入中间表,等到入库流程完成,将数据传送给WMS
CMMLog.Info($"获取到的MODBUS时间戳:{timeCuoData}");
//Console.WriteLine($"获取到的MODBUS时间戳:{timeCuoData}");
//这里需要调用照相机接口,获取数据存入中间表,等到入库流程完成,将数据传送给WMS
string deviceNo = "";
var timecuo = TimeCuo(timeCuoData, ref deviceNo);
if (timecuo != null)
{
string timeStamp = timecuo.data.First().timeStamp.ToString();
string employeeId = timecuo.data.First().employeeID1.ToString();
WMSHelper.WMSIn(plc.location, "打包下线", ref wmstaskno, ref timeStamp, timeStamp, "CPHJ");
}
else CMMLog.Info($"时间戳接口返回值为空!");
}
}
}
}
catch (Exception ex)
{
CMMLog.Debug(ex.Message+ "CheckPackingLineFull1");
}
}
}
public class MATERIALSync
{
public ObjectId _id { get; set; }
///
/// 名称
///
public string FName { get; set; }
///
/// 流水号
///
public string FNumber { get; set; }
public string FExpUnit { get; set; }
public string FStoreUnit { get; set; }
///
/// 员工编号
///
public string EMP_FNumber { get; set; }
///
/// 员工名称
///
public string EMP_FName { get; set; }
public DateTime time { get; set; }
}
#endregion
#region 打包机出口MODBUS交互(开始取料,取料完成)
/// 小车请求进料 1 AMS写,PLC读 1-AGV到位信号;2-到位后,请求接驳滚动;3-取货完成;
/// 设备允许出料 1 PLC写,AMS读 1-设备请求出料;2-允许进入;3-确认货物取走,送出物料;
///打包线下线——小车开始取货
internal static void PackingLineUnload1012(string ip, string taskNo)
{
CMMLog.Info($"【打包下线】起点安全请求进入流程处理开始--------");
var plc = Settings.GetPlcInfo().Where(a => a.deviceType == "4").FirstOrDefault();
if (plc != null)
{
try
{
var readRes = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
dataNum = 1,
addr = plc.readAddr + 1,
host = plc.ip,
port = plc.port
});
if (readRes != null && readRes.errCode == 0)
{
CMMLog.Info($"【打包下线】读取通道{plc.readAddr + 1}的数据为:{readRes.result[0]}");
if (readRes.result[0] == 1)
{
var write = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
addr = plc.writeAddr + 1,
data = 1,
host = plc.ip,
port = plc.port
});
CMMLog.Info($"【打包下线】写入通道{plc.writeAddr + 1}的数据为:{1}");
}
else if (readRes.result[0] == 2)
{
TSHelper.GoToAGV(taskNo, 10, 1);
var wirte = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
addr = plc.writeAddr + 1,
data = 2,
host = plc.ip,
port = plc.port
});
CMMLog.Info($"【打包下线】写入通道{plc.writeAddr + 1}的数据为:{2}");
}
}
else CMMLog.Info($"【打包下线】读取通道{plc.readAddr + 1}的数据失败");
}
catch (Exception ex)
{
CMMLog.Info(ex.Message);
}
}
else CMMLog.Info($"ip为:{ip}的设备未配置");
CMMLog.Info($"【打包下线】起点安全请求进入流程处理结束--------");
}
///
/// 打包线下线——小车取货完成
///
///
///
internal static void PackingLineComplete4(string ip, string taskNo)
{
CMMLog.Info($"【打包下线】起点安全请求退出流程处理开始-------------");
//取货完成后需要读取设备时间戳里面的数据,并将其暂存至中间表等到入库任务完成传输给WMS
var plc = Settings.GetPlcInfo().Where(a => a.deviceType == "4").FirstOrDefault();
if (plc != null)
{
try
{
//var readRes = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
//{
// dataNum = 1,
// addr = plc.readAddr + 1,
// host = plc.ip,
// port = plc.port
//});
//if (readRes != null && readRes.errCode == 0)
//{
// CMMLog.Info($"【打包下线】读取通道{plc.readAddr + 1}的值为{readRes.result[0]}");
// if (readRes.result[0] == 3)
// {
var write = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
addr = plc.writeAddr + 1,
data = 3,
host = plc.ip,
port = plc.port
});
CMMLog.Info($"【打包下线】写入通道{plc.writeAddr + 1}的值为{3}");
// }
//}
//else CMMLog.Info($"【打包下线】读取通道{plc.readAddr + 1}的值失败");
}
catch (Exception ex)
{
CMMLog.Info(ex.Message);
}
}
else CMMLog.Info($"ip为{ip}的设备未配置");
CMMLog.Info($"【打包下线】起点安全请求退出流程处理结束-------------");
}
#endregion
#endregion
#endregion
public static DateTime TenMin = DateTime.MinValue;
///
/// 每隔十分钟往所有开启的打包下线口MODBUS通道里面写小车电量
/// 其实地址26,连续往里面写入四个值
///
internal static void WriteBattery()
{
CMMLog.Info("写入小车电量:进入写入电量信息流程!");
////Console.WriteLine("写入小车电量:进入写入电量信息流程!");
if(TenMin == DateTime.MinValue) TenMin = DateTime.Now;
else if (DateTime.Now.Subtract(TenMin).TotalMinutes >= 10)
{
//Console.WriteLine("写入小车电量:写入所有开启的打包下线口MODBUS通道电量值,并重置时间为当前时间");
CMMLog.Info("写入小车电量:写入所有开启的打包下线口MODBUS通道电量值,并重置时间为当前时间");
//写入所有开启的打包下线口MODBUS通道电量值,并重置时间为当前时间
//获取所有电量值
int[] num = ProcessHelper.GetBatteryHang();
CMMLog.Info($"写入小车电量:写入数据:{JsonConvert.SerializeObject(num)}");
//Console.WriteLine($"写入小车电量:写入数据:{JsonConvert.SerializeObject(num)}");
var PlcInfo04 = Settings.GetPlcInfo().Where(a => a.enable == 1 && a.deviceType == "4").FirstOrDefault();//plcInfo
if (PlcInfo04 != null)
{
var wirteall = OITcpHelper.RegisterWriteOutPutMulti(new OITcpHelper.RegisterWriteOutPutModelMulti
{
addr = PlcInfo04.writeAddr + 5,
host = PlcInfo04.ip,
data = num,
port = PlcInfo04.port
});
}
TenMin = DateTime.Now;
}
}
#region 数据处理业务
///
/// 获取设备的包装物料信息(并写入中间表)
///
///
///
/// true : MES交互方式 false : 无MES交互方式
private static void GetMachineData(int[] result ,bool noPack = true)
{
//Console.WriteLine($"进入数据处理流程!");
CMMLog.Info($"进入数据处理流程!");
string trayCode = GetTrayCode(result.Take(3).ToArray());//托盘码
//string location = RemoveNull(GetTrayCode(result.Skip(3).Take(1).ToArray()));//设备货位编码
string location = Convert.ToInt32(Completion(result[3]), 2).ToString();
if (trayCode != null && location != null)
{
CMMLog.Info($"trayCode:{trayCode},location:{location}");
var json = "";
if (!noPack)
{
CMMLog.Info($"数据处理流程:包装机无MES情况下,自动生成以当前包装机号{location}为首的数据");
var task = MongoDBSingleton.Instance.FindOne(Query.EQ("machineNo", location), "MachineInfo");
if (task == null)
{
if (MongoDBSingleton.Instance.Insert(new MachineInfo
{
machineNo = location,
})) CMMLog.Info($"MachineInfo中插入数据,包装机号:{location}");
}
else CMMLog.Info($"数据处理流程:包装机无MES情况下,模拟MES数据,中间表中已有当前包装机号{location}为首的数据");
var taskTwo = MongoDBSingleton.Instance.FindOne(Query.EQ("trayCode", trayCode), "MachineInfoTwo");
if (taskTwo != null)
{
MongoDBSingleton.Instance.Update(Query.EQ("trayCode", trayCode), Update.Set("machineNo", location), UpdateFlags.None);
CMMLog.Info($"MachineInfoTwo中更新入数据,托盘号:{trayCode}");
}
else
{
if (MongoDBSingleton.Instance.Insert(new MachineInfoTwo
{
machineNo = location,
trayCode = trayCode,
})) CMMLog.Info($"MachineInfoTwo中插入数据,包装机号:{location}");
}
}
var info = MongoDBSingleton.Instance.FindOne(Query.EQ("machineNo", location), "MachineInfo");
if (info != null)
{
CMMLog.Info($"info:{info}");
#region 获取设备通道信息
#region 转换后
info.location = location;
info.trayCode = trayCode;
//获取重量 叠包等其它信息
info.productWeight = Convert.ToInt32(Completion(result[4]) + Completion(result[5]), 2).ToString();
CMMLog.Info($"获取数据 productWeight:{info.productWeight}");
info.trayCodeWeight = Convert.ToInt32(Completion(result[6]) + Completion(result[7]), 2).ToString();
CMMLog.Info($"获取数据 trayCodeWeight:{info.trayCodeWeight}");
double x = (double)Convert.ToInt32(Completion(result[8]) + Completion(result[9]), 2) / 100;
info.oneTrayWeight = x.ToString();
CMMLog.Info($"获取数据 oneTrayWeight:{info.oneTrayWeight}");
//预留托盘类型 10通道
info.addState = Convert.ToInt32(Completion(result[11]), 2);
CMMLog.Info($"获取数据 addState:{info.addState}");
if (info.addState == 0) CMMLog.Error($"获取MODBUS信息异常:是否叠包值为0.");
info.packageCode = Convert.ToInt32(Completion(result[12]), 2).ToString();
CMMLog.Info($"获取数据 packageCode:{info.packageCode}");
//info.empNum = Convert.ToInt32(Completion(result[13]) + Completion(result[14])+ Completion(result[15]) + Completion(result[16]) + Completion(result[17]), 2).ToString();
info.empNum = RemoveNull(GetTrayCode(result.Skip(13).Take(5).ToArray()));//员工编号
CMMLog.Info($"获取数据 empNum:{info.empNum}");
info.productTime = Convert.ToInt32(Completion(result[18]) + Completion(result[19]), 2).ToString();
CMMLog.Info($"获取数据 productTime:{info.productTime}");
CMMLog.Debug($"获取MODBUS转换后的数据信息:location:{info.location},trayCode:{info.trayCode},productWeight:{info.productWeight}" +
$",trayCodeWeight:{info.trayCodeWeight},oneTrayWeight:{info.oneTrayWeight}" +
$",addState:{info.addState},packageCode:{info.packageCode},empNum:{info.empNum},productTime:{info.productTime}");
#endregion
#region 转换前
for (int i = 0; i <= 90; i++)
{
info.machinedown[i] = result[i];
}
//将数组数据接受转换为JSON数据并在后续方法判断中存入中间表
json = JsonConvert.SerializeObject(info.machinedown);
CMMLog.Debug($"获取MODBUS转换前的数据信息:{json}");
//Console.WriteLine($"获取MODBUS转换前的数据信息:{json}");
#endregion
#endregion
}
else CMMLog.Info($"请查询表中machineNo字段是否为当前包装机号,并且trayCode是否为0");
var infoPack = MongoDBSingleton.Instance.FindOne(Query.And(Query.EQ("machineNo", location), Query.EQ("trayCode", "0")), "MachineInfo");
if (infoPack != null)
{
//包装机下线至复称,读取包装机平台数据
CMMLog.Info("进入info判断01");
//AMS包装机下线首先调用MES,之后获取新的设备数据存入中间表
//根据托盘号获取指定的通道的JSON数据,将其转换为数组类型——写入通道数据时会使用
//var arr = JsonConvert.DeserializeObject>(json);
if(!noPack)
{
CMMLog.Info($"数据处理流程:包装机无MES情况下,获取以往MES传输的数据,并原样写入原先MES字段中。");
info.lotNo = RemoveNull(GetTrayCode(result.Skip(20).Take(20).ToArray()).Trim().ToString());
info.productType = RemoveNull(GetTrayCode(result.Skip(40).Take(10).ToArray()).Trim().ToString());
info.materialCode = RemoveNull(GetTrayCode(result.Skip(50).Take(15).ToArray()).Trim().ToString());
info.materialName = RemoveNull(GetTrayCode(result.Skip(65).Take(20).ToArray()).Trim().ToString());
info.measurementUnit = RemoveNull(GetTrayCode(result.Skip(85).Take(5).ToArray()).Trim().ToString());
//info.organizeCode = RemoveNull(GetTrayCode(result.Skip(90).Take(1).ToArray()).Trim().ToString());
info.organizeCode = result[90].ToString();
CMMLog.Info($"获取包装机的物料编码:{RemoveNull(GetTrayCode(result.Skip(50).Take(20).ToArray()).Trim().ToString())}");
CMMLog.Info($"数据处理流程:包装机无MES情况下,获取以往MES传输的数据,新获得数据,lotNo:{info.lotNo},productType:{info.productType},materialCode:{info.materialCode},materialName:{info.materialName},measurementUnit:{info.measurementUnit},organizeCode:{info.organizeCode}");
//注意:这里赋值中间表参数请对照信息交互表具体通道值对应
UpdateBuilder update = Update.Set("palletLayers", info.secondNg.ToString()).Set("overlappingLayers", info.addState.ToString()).Set("bagNo", info.packageCode).
Set("lotNo", info.lotNo).Set("productType", info.productType).Set("materialCode", info.materialCode).Set("materialName",info.materialName).
Set("measurementUnit", info.measurementUnit).Set("organizeCode", info.organizeCode);
MongoDBSingleton.Instance.Update(Query.EQ("machineNo", location), update, UpdateFlags.None);
MongoDBSingleton.Instance.Update(Query.EQ("trayCode", trayCode), update, UpdateFlags.None);
}
//在中间表中找到刚刚插入的MES数据(目前还没有读取并写入设备数据)
var query1 = Query.And(Query.EQ("machineNo", location), Query.EQ("trayCode", "0"));
UpdateBuilder updateBuider = Update.Set("location", info.location).
Set("trayCode", info.trayCode).Set("productWeight", info.productWeight).
Set("trayCodeWeight", info.trayCodeWeight).Set("oneTrayWeight", info.oneTrayWeight).
Set("addState", info.addState).Set("packageCode", info.packageCode).Set("empNum", info.empNum).Set("productTime", info.productTime).
Set("jsonData", json).Set("modify", DateTime.Now);
MongoDBSingleton.Instance.Update(query1, updateBuider, UpdateFlags.None);
MongoDBSingleton.Instance.Update(Query.EQ("trayCode", trayCode), updateBuider, UpdateFlags.None);
CMMLog.Info($"MachineInfo:更新MachineInfo中间表刚刚插入的MES数据!设备号为:{location},托盘号为:{trayCode}");
CMMLog.Info($"MachineInfo:更新MachineInfoTwo中间表刚刚插入的MES数据!设备号为:{location},托盘号为:{trayCode}");
}
else
{
//复称入缓存架,读取复称平台数据
CMMLog.Info("进入info判断02");
//读取除包装机外其他设备的信息,更新包装机下线时的数据
var query2 = Query.And(Query.EQ("machineNo", location), Query.EQ("trayCode", trayCode));
var info2 = MongoDBSingleton.Instance.FindOne(query2, "MachineInfo");
if (info2 != null)
{
UpdateBuilder updateBuider = Update.Set("location", info.location).
Set("trayCode", info.trayCode).Set("productWeight", info.productWeight).
Set("trayCodeWeight", info.trayCodeWeight).Set("oneTrayWeight", info.oneTrayWeight).
Set("addState", info.addState).Set("packageCode", info.packageCode).Set("empNum", info.empNum).Set("productTime", info.productTime).
Set("jsonData", json).Set("modify", DateTime.Now);
MongoDBSingleton.Instance.Update(query2, updateBuider, UpdateFlags.None);
MongoDBSingleton.Instance.Update(query2, updateBuider, UpdateFlags.None);
CMMLog.Info($"MachineInfo:更新MachineInfo中间表其他设备的数据!设备号为:{location},托盘号为:{trayCode}");
}
else CMMLog.Info($"MachineInfo:无法在MachineInfo中间表中找到当前设备编号的数据!当前设备编号为:{location},托盘码为:{trayCode}");
}
}
else
{
//Console.WriteLine("数据流程处理托盘号或包装机号为空值!");
CMMLog.Info("数据流程处理托盘号或包装机号为空值!");
}
//Console.WriteLine($"数据处理流程结束!");
CMMLog.Info($"数据处理流程结束!");
}
///
/// 获取复称点状态信息
///
///
public static SecondWeighState GetSecondWeighState(string location,string devicetype)
{
CMMLog.Debug($"查询点位:{devicetype}");
//传入当前设备编号,并将传入的设备编号放入复称中间表的来源变量中
string PlcBit02 = Settings.GetPlcInfo().Where(a => a.location == devicetype && a.enable == 1).FirstOrDefault().location;
var query = Query.EQ("location", PlcBit02);
var model = MongoDBSingleton.Instance.FindOne(query, "SecondWeighState");
if (model == null)
{
MongoDBSingleton.Instance.Insert(new SecondWeighState { location = PlcBit02, from = location,full = 0,ng = 1 });
CMMLog.Debug($"判断复称状态信息服务,复称中间表数据为空,开始插入默认值!");
}
else MongoDBSingleton.Instance.Update(query, Update.Set("from", location), "SecondWeighState", UpdateFlags.None);
return model;
}
///
/// 复称平台数据
///
public class SecondWeighState
{
public ObjectId _id { get; set; }
public string location { get; set; }
///
/// 0未知 1合格 2不合格
///
public int ng { get; set; }
///
/// 复称平台货从哪里来的
///
public string from { get; set; }
///
/// 批次号
///
public string batchNo { get; set; }
///
/// 包装机下线重量
///
public int weight { get; set; }
///
/// 1 满 0 空
///
public int full { get; set; }
public string mesInfo { get; set; }
}
///
/// 获取复称点位位置
///
///
///
public static string GetSecondWeighBit()
{
//改成读settings
var plc = Settings.GetPlcInfo().Where(a => a.deviceType == "2").FirstOrDefault();
return plc.location;
}
///
/// 将设备通道里面读取的16位short转成ascii字符串
///
///
///
private static string GetTrayCode(int[] data)
{
StringBuilder sb = new StringBuilder();
data.ToList().ForEach(a => {
var bytes = BitConverter.GetBytes((short)a).Reverse().ToArray();
sb.Append(Encoding.ASCII.GetString(bytes));
});
return sb.ToString();
}
///
/// 十进制转换为2进制(自动补全16位)
///
///
///
public static string Completion(int data)
{
var result = Convert.ToString(data, 2).PadLeft(16, '0');
return result;
}
///
/// ascii转10进制(通过16进制中转)
///
///
///
public static string AsciiToTen(string data)
{
byte[] oneSixbad = System.Text.ASCIIEncoding.Default.GetBytes(data);
StringBuilder oneSixsb = new StringBuilder();
foreach (byte b in oneSixbad)
{
oneSixsb.Append(b.ToString("x"));
}
int oneSixA2 = Convert.ToInt32(oneSixsb.ToString(), 16);
return oneSixA2.ToString();
}
#region 叠盘机批量写入数据
#region 产品型号分离处理方法
//public static int[] DiePan(WMSInfo machine)
//{
// //偏移量 +11 通道范围: 40311 ~ 40370
// CMMLog.Info($"进入DiePan数据处理方法");
// //10~19通道
// int[] num = new int[60];
// int[] num3 = new int[40];
// int a = 0;//托盘码处理
// for (int b = 0; b <= 2; b++)
// {
// num[b] = int.Parse(AsciiToTen(machine.trayCode.Substring(a, 2)));
// a = a + 2;
// }
// num[3] = int.Parse(AsciiToTen(machine.location));//包装机号
// for (int b = 4; b <= 5; b++)
// {
// int k = b % 2 == 0 ? 0 : 16;
// num[b] = Convert.ToInt32(Convert.ToString(int.Parse(machine.productWeight), 2).PadLeft(32, '0').ToString().Substring(k, 16), 2);
// }
// for (int b = 6; b <= 7; b++)
// {
// int k = b % 2 == 0 ? 0 : 16;
// num[b] = Convert.ToInt32(Convert.ToString(int.Parse(machine.trayCodeWeight), 2).PadLeft(32, '0').ToString().Substring(k, 16), 2);
// }
// for (int b = 8; b <= 9; b++)
// {
// int k = b % 2 == 0 ? 0 : 16;
// num[b] = Convert.ToInt32(Convert.ToString(int.Parse(machine.oneTrayWeight), 2).PadLeft(32, '0').ToString().Substring(k, 16), 2);
// }
// for (int b = 10; b <= 12; b++) num[b] = 0;// 叠包后实际重量 && 复称结果 默认:0
// num[13] = string.IsNullOrEmpty(machine.palletLayers) ? 0 : int.Parse(machine.palletLayers);//是否需要叠托盘
// num[14] = machine.addState;//是否需要叠包
// num[15] = int.Parse(machine.packageCode);//袋号
// //时间戳处理
// string timeStamp = ProcessHelper.GetTimeStamp(32, 1, 1);
// for (int b = 16; b <= 17; b++)
// {
// int k = b % 2 == 0 ? 0 : 16;
// num[b] = Convert.ToInt32(Convert.ToString(int.Parse(timeStamp), 2).PadLeft(32, '0').ToString().Substring(k, 16), 2);
// }
// for (int b = 18; b <= 19; b++) num[b] = 0;//预留的两个通道 默认:0
// //19 = 30 31 ~ 60
// //30~59通道 60~70通道
// string pcHead = "";
// string cpHead = "";
// #region 31~60
// string data = machine.itemPCode;
// CMMLog.Info($"31~60data1_1:{data}");
// if (data.Length % 2 != 0)
// {
// data = "0" + machine.itemPCode;
// pcHead = "" + machine.itemPCode.Substring(0, 1);
// }
// CMMLog.Info($"31~60data1_2:{data}");
// int x = data.Length / 2;
// int aa = 0;
// for (int i = 0; i <= x - 1; i++)
// {
// num3[i] = int.Parse(AsciiToTen(data.Substring(aa, 2)));
// aa = aa + 2;
// }
// for (int m = x; m <= 29; m++) num3[m] = 0;//将产品批次号无数据的通道全部置为 0
// CMMLog.Info($"itemPCode:" + JsonConvert.SerializeObject(num3));
// #endregion
// #region 61~70
// string data2 = machine.itemCode;
// CMMLog.Info($"61~70data2_1:{data2}");
// if (data2.Length % 2 != 0)
// {
// data2 = "0" + machine.itemCode;
// cpHead = "" + machine.itemCode.Substring(0, 1);
// }
// CMMLog.Info($"61~70data2_2:{data2}");
// int y = data2.Length / 2;
// CMMLog.Info($"{y}");
// int aaa = 0;
// //4 2 32 9 41
// for (int i = 30; i <= y + 29; i++)
// {
// num3[i] = int.Parse(AsciiToTen(data2.Substring(aaa, 2)));
// CMMLog.Info(JsonConvert.SerializeObject(num3[i]));
// aaa = aaa + 2;
// }
// int mm = y + 30;
// CMMLog.Info($"mm:{mm}");
// for (int mmm = mm; mmm <= 39; mmm++)
// {
// num3[mmm] = 0;
// CMMLog.Info(JsonConvert.SerializeObject(num3[mmm]));
// }
// CMMLog.Info($"itemPCode+itemCode:{JsonConvert.SerializeObject(num3)}");
// #endregion
// for (int i = 20; i <= 60; i++) num[i] = num3[i - 20];
// // 如果 产品批次号 或者 产品型号 位数 为 奇数,则将提前取出的 首字符 重新转码 写入 其所对应通道区域的 首通道
// if (pcHead != "" || cpHead != "")
// {
// if (pcHead != "") num[20] = int.Parse(AsciiToTen(pcHead));
// if (cpHead != "") num[50] = int.Parse(AsciiToTen(cpHead));
// CMMLog.Info($"产品型号或批次号数量为奇数,特将首位取出单独处理,以下为批次号和产品型号的十进制数值{num[20]},{num[50]}");
// }
// CMMLog.Info($"DiePan数据处理方法完毕");
// return num;
//}
#endregion
public static int[] DiePan(WMSInfo machine)
{
//偏移量 +11 通道范围: 40311 ~ 40370
CMMLog.Info($"叠盘机数据处理.");
//10~19通道
int[] num = new int[60];//总长度:60
#region 0~19 => 11~30
int a = 0;//托盘码处理
for (int b = 0; b <= 2; b++)
{
num[b] = int.Parse(AsciiToTen(machine.trayCode.Substring(a, 2)));
a = a + 2;
}
num[3] = int.Parse(AsciiToTen(machine.location));//包装机号
for (int b = 4; b <= 5; b++)
{
int k = b % 2 == 0 ? 0 : 16;
num[b] = Convert.ToInt32(Convert.ToString(int.Parse(machine.productWeight), 2).PadLeft(32, '0').ToString().Substring(k, 16), 2);
}
for (int b = 6; b <= 7; b++)
{
int k = b % 2 == 0 ? 0 : 16;
num[b] = Convert.ToInt32(Convert.ToString(int.Parse(machine.trayCodeWeight), 2).PadLeft(32, '0').ToString().Substring(k, 16), 2);
}
for (int b = 8; b <= 9; b++)
{
int k = b % 2 == 0 ? 0 : 16;
num[b] = Convert.ToInt32(Convert.ToString(int.Parse(machine.oneTrayWeight), 2).PadLeft(32, '0').ToString().Substring(k, 16), 2);
}
for (int b = 10; b <= 12; b++) num[b] = 0;// 叠包后实际重量 && 复称结果 默认:0
num[13] = string.IsNullOrEmpty(machine.palletLayers) ? 0 : int.Parse(machine.palletLayers);//是否需要叠托盘
num[14] = machine.addState;//是否需要叠包
num[15] = int.Parse(machine.packageCode);//袋号
//时间戳处理
string timeStamp = ProcessHelper.GetTimeStamp(32, 1, 1);
for (int b = 16; b <= 17; b++)
{
int k = b % 2 == 0 ? 0 : 16;
num[b] = Convert.ToInt32(Convert.ToString(int.Parse(timeStamp), 2).PadLeft(32, '0').ToString().Substring(k, 16), 2);
}
for (int b = 18; b <= 19; b++) num[b] = 0;//预留的两个通道 默认:0
#endregion
string pcHead = "";
string cpHead = "";
#region 20~49 => 31~60 产品批次号
string data = machine.itemPCode;
CMMLog.Info($"31~60data1_1:{data}");
if (data.Length % 2 != 0)
{
data = "0" + machine.itemPCode;
pcHead = "" + machine.itemPCode.Substring(0, 1);
}
CMMLog.Info($"31~60data1_2:{data}");
//字符串长度 / 2 = 写入通道数量(两位一转) 列: 3L0050 写入三个通道
int maxLength = 19 + (data.Length / 2);// data.Length / 2 至少为 1
int aa = 0;
for (int i = 20; i <= maxLength; i++)
{
num[i] = int.Parse(AsciiToTen(data.Substring(aa, 2)));
aa = aa + 2;
}
for (int x = maxLength + 1; x <= 49; x++) num[x] = 0;//将产品批次号无数据的通道全部置为 0
#endregion
#region 50~59 => 61~70 产品型号
string data2 = machine.itemCode;
CMMLog.Info($"61~70data2_1:{data2}");
if (data2.Length % 2 != 0)
{
data2 = "0" + machine.itemCode;
cpHead = "" + machine.itemCode.Substring(0, 1);
}
CMMLog.Info($"61~70data2_2:{data2}");
maxLength = 49 + (data2.Length / 2);
int aaa = 0;
for (int i = 50; i <= maxLength; i++)
{
num[i] = int.Parse(AsciiToTen(data2.Substring(aaa, 2)));
aaa = aaa + 2;
}
for (int x = maxLength + 1; x <= 59; x++) num[x] = 0;//将产品型号无数据的通道全部置为0
#endregion
// 如果 产品批次号 或者 产品型号 位数 为 奇数,则将提前取出的 首字符 重新转码 写入 其所对应通道区域的 首通道
if (pcHead != "") num[20] = int.Parse(AsciiToTen(pcHead));
if (cpHead != "") num[50] = int.Parse(AsciiToTen(cpHead));
if (pcHead != "" || cpHead != "") CMMLog.Info($"产品型号或批次号数量为奇数,特将首位取出单独处理,以下为批次号和产品型号的十进制数值{num[20]},{num[50]}");
CMMLog.Info($"叠盘机数据处理完毕:{JsonConvert.SerializeObject(num)}");
return num;
}
public static int[] DiePanTwo(MachineInfoTwo machine)
{
//偏移量 +11 通道范围: 40311 ~ 40370
CMMLog.Info($"叠盘机数据处理.");
//10~19通道
int[] num = new int[60];//总长度:60
#region 0~19 => 11~30
// int a = 0;//托盘码处理
// for (int b = 0; b <= 2; b++)
// {
// num[b] = int.Parse(AsciiToTen(machine.trayCode.Substring(a, 2)));
// a = a + 2;
// }
// num[3] = int.Parse(AsciiToTen(machine.location));//包装机号
// for (int b = 4; b <= 5; b++)
// {
// int k = b % 2 == 0 ? 0 : 16;
// num[b] = Convert.ToInt32(Convert.ToString(int.Parse(machine.productWeight), 2).PadLeft(32, '0').ToString().Substring(k, 16), 2);
// }
// for (int b = 6; b <= 7; b++)
// {
// int k = b % 2 == 0 ? 0 : 16;
// num[b] = Convert.ToInt32(Convert.ToString(int.Parse(machine.trayCodeWeight), 2).PadLeft(32, '0').ToString().Substring(k, 16), 2);
// }
// for (int b = 8; b <= 9; b++)
// {
// int k = b % 2 == 0 ? 0 : 16;
// num[b] = Convert.ToInt32(Convert.ToString(int.Parse(machine.oneTrayWeight), 2).PadLeft(32, '0').ToString().Substring(k, 16), 2);
// }
// num[10] = 0; //托盘类型 预留
// num[11] = machine.addState;//是否需要叠包
// num[12] = int.Parse(machine.packageCode);//袋号
// //时间戳处理
// string timeStamp = ProcessHelper.GetTimeStamp(32, 1, 1);
// for (int b = 16; b <= 17; b++)
// {
// int k = b % 2 == 0 ? 0 : 16;
// num[b] = Convert.ToInt32(Convert.ToString(int.Parse(timeStamp), 2).PadLeft(32, '0').ToString().Substring(k, 16), 2);
// }
// for (int b = 18; b <= 19; b++) num[b] = 0;//预留的两个通道 默认:0
//
// #endregion
//
// string pcHead = "";
// string cpHead = "";
//
// #region 20~49 => 31~60 产品批次号
//
// string data = machine.itemPCode;
// CMMLog.Info($"31~60data1_1:{data}");
// if (data.Length % 2 != 0)
// {
// data = "0" + machine.itemPCode;
// pcHead = "" + machine.itemPCode.Substring(0, 1);
// }
// CMMLog.Info($"31~60data1_2:{data}");
// //字符串长度 / 2 = 写入通道数量(两位一转) 列: 3L0050 写入三个通道
// int maxLength = 19 + (data.Length / 2);// data.Length / 2 至少为 1
// int aa = 0;
// for (int i = 20; i <= maxLength; i++)
// {
// num[i] = int.Parse(AsciiToTen(data.Substring(aa, 2)));
// aa = aa + 2;
// }
// for (int x = maxLength + 1; x <= 49; x++) num[x] = 0;//将产品批次号无数据的通道全部置为 0
// #endregion
//
// #region 50~59 => 61~70 产品型号
//
// string data2 = machine.itemCode;
// CMMLog.Info($"61~70data2_1:{data2}");
// if (data2.Length % 2 != 0)
// {
// data2 = "0" + machine.itemCode;
// cpHead = "" + machine.itemCode.Substring(0, 1);
// }
// CMMLog.Info($"61~70data2_2:{data2}");
// maxLength = 49 + (data2.Length / 2);
// int aaa = 0;
// for (int i = 50; i <= maxLength; i++)
// {
// num[i] = int.Parse(AsciiToTen(data2.Substring(aaa, 2)));
// aaa = aaa + 2;
// }
// for (int x = maxLength + 1; x <= 59; x++) num[x] = 0;//将产品型号无数据的通道全部置为0
#endregion
//
// // 如果 产品批次号 或者 产品型号 位数 为 奇数,则将提前取出的 首字符 重新转码 写入 其所对应通道区域的 首通道
// if (pcHead != "") num[20] = int.Parse(AsciiToTen(pcHead));
// if (cpHead != "") num[50] = int.Parse(AsciiToTen(cpHead));
// if (pcHead != "" || cpHead != "") CMMLog.Info($"产品型号或批次号数量为奇数,特将首位取出单独处理,以下为批次号和产品型号的十进制数值{num[20]},{num[50]}");
//
// CMMLog.Info($"叠盘机数据处理完毕:{JsonConvert.SerializeObject(num)}");
return num;
}
internal static void PackingLineComplete(string ip)
{
var plc = Settings.GetPlcInfo().Where(a => a.ip == ip).FirstOrDefault();
if (plc != null)
{
//写入包装机--安全门关门指令
var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
host = ip,
addr = plc.writeAddr + 2,
data = 3,
port = plc.port
});
CMMLog.Debug($"写入设备{plc.location}通道{plc.writeAddr + 2}里面数据为3.");
}
else CMMLog.Debug($"包装线空托上线,3,ip=null!");
}
internal static void BZBKComplete(string PlcBitCache01, string Extend = "")
{
var plcInfo = Settings.GetPlcInfo().Where(a => a.location == PlcBitCache01).FirstOrDefault();
var writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
host = plcInfo.ip,
addr = plcInfo.writeAddr + 2,
data = 3,
port = plcInfo.port
});
CMMLog.Debug($"写入设备{plcInfo.location}通道{plcInfo.writeAddr + 2}里面数据3");
var result = OITcpHelper.RegisterReadOutPut(new OITcpHelper.RegisterReadOutPutModel
{
dataNum = 1,
addr = plcInfo.readAddr + 2,
host = plcInfo.ip,
port = plcInfo.port
});
if (result != null && result.errCode == 0)
{
//3:安全门关闭,等待关闭到位后,清零本通道
if (result.result[0] == 3)
{
CMMLog.Debug($"读取设备{plcInfo.location}通道{plcInfo.readAddr + 2}里面数据3");
writeRes = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
host = plcInfo.ip,
addr = plcInfo.writeAddr + 2,
data = 0,
port = plcInfo.port
});
}
}
}
internal static void writeStackingMouth6(string loca, string taskNo)
{
var plc = Settings.GetPlcInfo().Where(a => a.location == loca && a.enable == 1).FirstOrDefault();
CMMLog.Info($"3楼缓存架入叠托:收到信号6,查询设备信息:{JsonConvert.SerializeObject(plc)}。");
if (plc != null)
{
var eleInfo = MongoDBSingleton.Instance.FindOne("elevatorTask");
if(eleInfo != null)
{
var task = eleInfo.task_mst;
CMMLog.Info($"3楼缓存架入叠托:收到信号6,查询任务信息:{JsonConvert.SerializeObject(task)}。");
var machine = eleInfo.wmsInfo;
CMMLog.Info($"3楼缓存架入叠托:收到信号6,查询WMSInfo表信息:{JsonConvert.SerializeObject(machine)}。");
if (machine != null)
{
int[] num = DiePan(machine);
CMMLog.Info($"send num:{JsonConvert.SerializeObject(num)}");
var wirteall01 = OITcpHelper.RegisterWriteOutPutMulti(new OITcpHelper.RegisterWriteOutPutModelMulti
{
addr = plc.writeAddr + 10,
host = plc.ip,
port = plc.port,
data = num
});
//WriteCacheStackingData(plc, task, machine);
var wirte = OITcpHelper.RegisterWriteOutPut(new OITcpHelper.RegisterWriteOutPutModel
{
addr = plc.writeAddr + 1,
host = plc.ip,
port = plc.port,
data = 2
});
}
}
else
{
CMMLog.Info($"3楼缓存架入叠托:电梯中间表异常");
}
}
}
private static void WriteCacheStackingData(Settings.PlcInfo plc, TN_I_TASK_MST task, WMSInfo machine)
{
var machineTwo = MongoDBSingleton.Instance.FindOne(Query.EQ("trayCode", task.CN_S_BATCH_NO), "MachineInfoTwo");
CMMLog.Info($"3楼缓存架入叠托:收到信号6,查询MachineInfoTwo表信息:{JsonConvert.SerializeObject(machineTwo)}。");
if (machineTwo != null)
{
int[] num = DiePanTwo(machine, machineTwo);
CMMLog.Info($"3楼缓存架入叠托:写入数据:{JsonConvert.SerializeObject(num)},IPort:{plc.ip},{plc.port}");
var wirteall01 = OITcpHelper.RegisterWriteOutPutMulti(new OITcpHelper.RegisterWriteOutPutModelMulti
{
addr = plc.writeAddr + 7,
host = plc.ip,
port = plc.port,
data = num
});
CMMLog.Info($"3楼缓存架入叠托:返回数据:{JsonConvert.SerializeObject(wirteall01)},IPort:{plc.ip},{plc.port}");
if (wirteall01.errCode == 0)
{
MongoDBSingleton.Instance.Remove(Query.EQ("trayCode", task.CN_S_BATCH_NO), "MachineInfoTwo", RemoveFlags.Single);
}
}
}
private static int[] DiePanTwo(WMSInfo machine, MachineInfoTwo machineInfoTwo)
{
var ErpItemInfo = new SqlHelper