You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
579 lines
25 KiB
C#
579 lines
25 KiB
C#
using CentralControl.BaseData;
|
|
using CentralControl.DBDAO;
|
|
using CommonFunc;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using Thrift.Protocol;
|
|
using Thrift.Transport;
|
|
using ThriftCommon;
|
|
|
|
namespace CentralControl.App_Code
|
|
{
|
|
/// <summary>
|
|
/// 上件扫描逻辑 上件逻辑: 正常上件 1002 ,自动放行:1003
|
|
/// </summary>
|
|
public class Logic101_104UpLine
|
|
{
|
|
Thread InputMaterialThread;
|
|
Thread UpMaterialThriftThread;
|
|
PlcHelper plcHelper;
|
|
string LineNo { get; set; }
|
|
NodeSetting ScanPoint { get; set; }
|
|
/// <summary>
|
|
/// plc 正在读取
|
|
/// </summary>
|
|
bool IsPlcRead { get; set; }
|
|
|
|
/// <summary>
|
|
/// 客户端thrift端口
|
|
/// </summary>
|
|
int Thriftpoint { get; set; }
|
|
/// <summary>
|
|
/// 是否运行发车中
|
|
/// </summary>
|
|
bool IsRuning { get; set; }
|
|
|
|
public Logic101_104UpLine(PlcHelper plc, string nodeno)
|
|
{
|
|
this.Thriftpoint = 7911;
|
|
//try
|
|
//{
|
|
// this.plcHelper = plc;
|
|
|
|
// this.ScanPoint = StaticData.NodeSettingList.FirstOrDefault(t => t.NodeNo == nodeno);
|
|
|
|
// if (this.ScanPoint != null)
|
|
// {
|
|
// this.Thriftpoint = this.ScanPoint.ServerThriftport;
|
|
|
|
// this.LineNo = this.ScanPoint.LineCatchArea != null ? this.ScanPoint.LineCatchArea.LineNo : "1";
|
|
// ///回写plc状态处理完成,plc会清理数据
|
|
// object wcsend = this.plcHelper.Read(ScanPoint.PlcSetting5);
|
|
// //if (Convert.ToInt32(wcsend) == 1)
|
|
// //{
|
|
// //默认启动,清理plc的上位机写入点位值
|
|
// this.plcHelper.Write(this.ScanPoint.PlcSetting4, 0);
|
|
// this.plcHelper.Write(this.ScanPoint.PlcSetting5, 0);
|
|
// //}
|
|
// }
|
|
// else
|
|
// {
|
|
// Console.WriteLine(nodeno + "号上件点没有加载点位");
|
|
// }
|
|
//}
|
|
//catch (Exception ex)
|
|
//{
|
|
// Console.WriteLine("站点" + nodeno + " 初始化数据异常" + ex.Message);
|
|
// Logger logger = new Logger();
|
|
// logger.Error("站点" + nodeno + " 初始化数据异常" + ex.Message);
|
|
//}
|
|
|
|
|
|
}
|
|
public void StartPoint()
|
|
{
|
|
if (this.Thriftpoint > 0)
|
|
{
|
|
///启动thrift线程监视
|
|
UpMaterialThriftThread = new Thread(new ParameterizedThreadStart(StartScanThriftLogic));
|
|
UpMaterialThriftThread.Start(this.Thriftpoint);
|
|
}
|
|
|
|
if (this.ScanPoint != null && this.ScanPoint.LocalThriftip != "" && this.ScanPoint.LocalThriftport > 0)
|
|
{
|
|
InputMaterialThread = new Thread(new ParameterizedThreadStart(SendCarNoByNode));
|
|
InputMaterialThread.Start(this.ScanPoint);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 上件点扫描小车信息,推送给前端
|
|
/// </summary>
|
|
/// <param name="thriftport"></param>
|
|
private void SendCarNoByNode(object nodesetting)
|
|
{
|
|
|
|
Logger logger = new Logger();
|
|
|
|
while (true)
|
|
{
|
|
var node = nodesetting as NodeSetting;
|
|
///读取小车号
|
|
object carobj = this.plcHelper.Read(this.ScanPoint.PlcSetting1);
|
|
string carno = Common.getCarNoByPlcPoint(carobj);
|
|
//小车是否到位
|
|
object carstate = this.plcHelper.Read(this.ScanPoint.PlcSetting2);
|
|
//小车是否离开
|
|
object carrun = this.plcHelper.Read(this.ScanPoint.PlcSetting3);
|
|
///上位机写入岔道信息
|
|
object wcsstate = this.plcHelper.Read(ScanPoint.PlcSetting4);
|
|
///回写plc状态处理完成,plc会清理数据
|
|
object wcsend = this.plcHelper.Read(ScanPoint.PlcSetting5);
|
|
|
|
try
|
|
{
|
|
if (Convert.ToInt32(carno) > 0 && Convert.ToInt32(wcsend) == 0 && Convert.ToInt32(wcsstate) == 0 && Convert.ToInt32(carstate) == 1 && Convert.ToInt32(carrun) == 0)
|
|
{
|
|
|
|
using (TTransport transport = new TSocket(node.LocalThriftip, Convert.ToInt32(node.LocalThriftport)))
|
|
{
|
|
using (TProtocol protocol = new TBinaryProtocol(transport))
|
|
{
|
|
ThriftService.Client client = new ThriftService.Client(protocol);
|
|
transport.Open();
|
|
string ret = client.GetReceiveCarNo(carno.ToString());
|
|
if (ret == "")
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.Log("客户端未启动thrift" + node.NodeDesc);
|
|
}
|
|
|
|
Thread.Sleep(2000);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// 启动小车扫描监听队列
|
|
/// </summary>
|
|
private void StartScanThriftLogic(object thriftpoint)
|
|
{
|
|
int point = Convert.ToInt32(thriftpoint);
|
|
this.LineNo = this.LineNo;
|
|
XGL.Thrift.ThriftServiceImp business = new XGL.Thrift.ThriftServiceImp();
|
|
business.sendCarMaterialListEvent += SendCar;
|
|
business.SendCheckServerStateEvent += CheckServerState;
|
|
business.sendCheckBarcodeEvent += CheckMaterialCode;
|
|
business.sendMaterialListEvent += CheckProductListByMaterialCode;
|
|
XGL.Thrift.ThriftCommon thriftCommon = new XGL.Thrift.ThriftCommon();
|
|
thriftCommon.Start(business, point);
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查 前端扫描的单个物料信息
|
|
/// </summary>
|
|
/// <param name="materialno"></param>
|
|
/// <returns></returns>
|
|
public string CheckMaterialCode(string materialno)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取物料列表,返回对应的产品列表
|
|
/// </summary>
|
|
/// <param name="materialnolist"></param>
|
|
/// <returns></returns>
|
|
public string CheckProductListByMaterialCode(List<string> materialnolist)
|
|
{
|
|
List<string> materials = new List<string>();
|
|
foreach (string carno in materialnolist)
|
|
{
|
|
int endindex = carno.IndexOf("#");
|
|
if (endindex <= 0)
|
|
{
|
|
endindex = carno.Length > 10 ? 10 : carno.Length;
|
|
}
|
|
string materialno = carno.Substring(0, endindex);
|
|
materials.Add(materialno);
|
|
}
|
|
|
|
string[] materialArr = materials.ToArray();
|
|
var productModel = StaticData.MaterialBomList.Where(t => materialArr.Contains(t.ChildMaterialNo)).GroupBy(t => new { t.MaterialNo, t.ParentMaterialInfo.MaterialNm }).Select(g => new { materialno = g.Key.MaterialNo, materialnm = g.Key.MaterialNm, number = g.Count() }).Where(t => t.number == materialArr.Length).Select(t =>new
|
|
{
|
|
no = t.materialno,
|
|
nm = t.materialnm
|
|
}).ToList();
|
|
|
|
var retsult = new ResultJson();
|
|
retsult.success = 1;
|
|
retsult.message = "";
|
|
retsult.data = JsonHelper.ObjectToJson(productModel);
|
|
return JsonHelper.ObjectToJson(retsult);
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 返回服务器的plc 状态
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string CheckServerState()
|
|
{
|
|
///读取小车号
|
|
object carobj = this.plcHelper.Read(this.ScanPoint.PlcSetting1);
|
|
string carno = Common.getCarNoByPlcPoint(carobj);
|
|
//小车是否到位
|
|
object carstate = this.plcHelper.Read(this.ScanPoint.PlcSetting2);
|
|
//小车是否离开
|
|
object carrun = this.plcHelper.Read(this.ScanPoint.PlcSetting3);
|
|
///上位机写入岔道信息
|
|
object wcsstate = this.plcHelper.Read(ScanPoint.PlcSetting4);
|
|
///回写plc状态处理完成,plc会清理数据
|
|
object wcsend = this.plcHelper.Read(ScanPoint.PlcSetting5);
|
|
if (carobj != null && carno != null && carstate != null && wcsstate != null && wcsend != null)
|
|
{
|
|
return "1";
|
|
}
|
|
return "0";
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 下位机点击发车
|
|
/// </summary>
|
|
/// <param name="carlist"></param>
|
|
/// <returns></returns>
|
|
public string SendCar(List<string> carlist,string order_code)
|
|
{
|
|
List<string> materlist = new List<string>();
|
|
List<UpLineScanCarList> mlist = new List<UpLineScanCarList>();
|
|
Logger logger = new Logger();
|
|
|
|
List<CarMaterial> carMaterials = new List<CarMaterial>();
|
|
List<CarProduct> carProducts = new List<CarProduct>();
|
|
|
|
var ret = new ResultJson();
|
|
|
|
if (carlist.Count == 0)
|
|
{
|
|
ret.success = 0;
|
|
ret.message = "上件物料列表为空";
|
|
ret.data = "";
|
|
return JsonHelper.ObjectToJson(ret);
|
|
}
|
|
|
|
|
|
List<string> productModel = null;
|
|
if (!IsRuning)
|
|
{
|
|
IsRuning = true;
|
|
|
|
try
|
|
{
|
|
|
|
foreach (string carno in carlist)
|
|
{
|
|
int endindex = carno.IndexOf("#");
|
|
if (endindex <= 0)
|
|
{
|
|
endindex = carno.Length > 10 ? 10 : carno.Length;
|
|
}
|
|
|
|
string materialno = carno.Substring(0, endindex);
|
|
materlist.Add(materialno);
|
|
|
|
CarMaterial carMaterial = new CarMaterial();
|
|
carMaterial.IsDeleted = false;
|
|
carMaterial.materialBarno = carno;
|
|
carMaterial.materialNo = materialno;
|
|
int id = DBService.AddCarMaterial(carMaterial);
|
|
carMaterial.id = id;
|
|
carMaterials.Add(carMaterial);
|
|
}
|
|
|
|
//删除相同物料组成 bom的 产品bomid,为了排除,当前物料组成被包含的情况(A:1,2,3 ,B:1,2,3,4)
|
|
string[] boms = StaticData.MaterialBomList.GroupBy(t => t.MaterialNo).Select(g => new { materialno = g.Key, number = g.Count() }).Where(t => t.number == carlist.Count).Select(t => t.materialno).ToArray();
|
|
|
|
if (boms.Length > 0)
|
|
{
|
|
string[] materialArr = materlist.ToArray();
|
|
///根据包含相同物料号的数量的bom产品
|
|
productModel = StaticData.MaterialBomList.Where(t => boms.Contains(t.MaterialNo) && materialArr.Contains(t.ChildMaterialNo)).GroupBy(t => t.MaterialNo).Select(g => new { materialno = g.Key, number = g.Count() }).Where(t => t.number == materialArr.Length).Select(t => t.materialno).ToList();
|
|
//未找到匹配的bom结构信息
|
|
if (productModel != null && productModel.Count > 0)
|
|
{
|
|
|
|
}
|
|
else
|
|
{
|
|
IsRuning = false;
|
|
mlist = null;
|
|
logger = null;
|
|
|
|
ret.success = 0;
|
|
ret.message = "没有匹配到对应的物料BOM";
|
|
ret.data = "";
|
|
return JsonHelper.ObjectToJson(ret); ;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
IsRuning = false;
|
|
mlist = null;
|
|
logger = null;
|
|
|
|
ret.success = 0;
|
|
ret.message = "没有匹配到对应的物料BOM";
|
|
ret.data = "";
|
|
return JsonHelper.ObjectToJson(ret); ;
|
|
}
|
|
|
|
//lock (StaticData.UpMaterialCarLock)
|
|
//{
|
|
|
|
|
|
|
|
//}
|
|
|
|
while (true)
|
|
{
|
|
|
|
|
|
///读取小车号
|
|
object carobj = this.plcHelper.Read(this.ScanPoint.PlcSetting1);
|
|
string carno = Common.getCarNoByPlcPoint(carobj);
|
|
//小车是否到位
|
|
object carstate = this.plcHelper.Read(this.ScanPoint.PlcSetting2);
|
|
//小车是否离开
|
|
object carrun = this.plcHelper.Read(this.ScanPoint.PlcSetting3);
|
|
///上位机写入岔道信息
|
|
object wcsstate = this.plcHelper.Read(ScanPoint.PlcSetting4);
|
|
///回写plc状态处理完成,plc会清理数据
|
|
object wcsend = this.plcHelper.Read(ScanPoint.PlcSetting5);
|
|
|
|
if (carno != null && carstate != null && carrun != null && wcsstate != null && wcsend != null)
|
|
{
|
|
if (Convert.ToInt32(carno) > 0 && Convert.ToInt32(wcsend) == 0 && Convert.ToInt32(wcsstate) == 0 && Convert.ToInt32(carstate) == 1 && Convert.ToInt32(carrun) == 0 && IsPlcRead == false)
|
|
{
|
|
|
|
logger.Log("[" + carno + "]小车到了 [" + this.LineNo + "]号上件点");
|
|
|
|
//清除小车门体对应的产品列表
|
|
bool retma = DBService.DeleteCarMaterialByCarNo(carno);
|
|
//清除小车上的门体数据列表
|
|
bool retpro = DBService.DeleteCarProductByCarNo(carno);
|
|
|
|
///录入系统产品型号
|
|
foreach (var product in productModel)
|
|
{
|
|
var materialproduct = StaticData.MateriaList.FirstOrDefault(t => t.MaterialNo == product);
|
|
CarProduct productcar = new CarProduct();
|
|
productcar.carNo = carno.ToString();
|
|
productcar.CreateTime = DateTime.Now.ToString();
|
|
productcar.productNo = materialproduct.MaterialNo;
|
|
productcar.productNm = materialproduct.MaterialNm;
|
|
productcar.IsDeleted = false;
|
|
int id = DBService.AddCarProduct(productcar);
|
|
productcar.id = id;
|
|
carProducts.Add(productcar);
|
|
|
|
}
|
|
|
|
///维护上件物料和小车对应关系
|
|
foreach (var material in carMaterials)
|
|
{
|
|
material.carNo = carno.ToString();
|
|
DBService.UpdateCarMaterial(material);
|
|
|
|
|
|
UpLineScanCarList uplinmater = new UpLineScanCarList();
|
|
|
|
|
|
string materialno = material.materialNo;
|
|
|
|
uplinmater.CarNo = carno.ToString();
|
|
uplinmater.MaterialNo = materialno;
|
|
uplinmater.MaterialBarCode = material.materialBarno;
|
|
|
|
uplinmater.Number = 1;
|
|
uplinmater.LineNo = this.LineNo;
|
|
mlist.Add(uplinmater);
|
|
int id = DBService.AddUpLineScancar(uplinmater);
|
|
uplinmater.Id = id;
|
|
|
|
|
|
}
|
|
|
|
LineCatchArea area = null;
|
|
// lock(StaticData.CarLock)
|
|
//判断小车号是否存在 ,使用内存记录
|
|
// CarRealInfo car = DBService.GetCarModel(carno.ToString());
|
|
CarRealInfo car = StaticData.CarRealList.Where(t => t.CarNo == carno.ToString()).FirstOrDefault();
|
|
if (car == null)
|
|
{
|
|
car = new CarRealInfo();
|
|
car.CarNo = carno.ToString();
|
|
car.LocatorNodeId = 0;
|
|
car.ProLocatorArea = null;
|
|
//car.MaterialNo = productModel == null ? "" : productModel.materialno;
|
|
car.OptDt = DateTime.Now;
|
|
car.Number = materlist.Count;
|
|
car.HadNumber = materlist.Count;
|
|
car.IsOver = 0;
|
|
// car.MaterialBarNo = materialproduct == null ? "" : materialproduct.MaterialNm;
|
|
car.Id = DBService.AddCarRealRecord(car);
|
|
}
|
|
else
|
|
{
|
|
//小车不存在了, 就插入初始化数据
|
|
car.CarNo = carno.ToString();
|
|
car.LocatorNodeId = 0;
|
|
car.ProLocatorArea = null;
|
|
// car.MaterialNo = productModel == null ? "" : productModel.materialno;
|
|
car.HadNumber = materlist.Count;
|
|
car.OptDt = DateTime.Now;
|
|
car.Number = materlist.Count;
|
|
car.IsOver = 0;
|
|
// car.MaterialBarNo = materialproduct == null ? "" : materialproduct.MaterialNm;
|
|
|
|
}
|
|
|
|
car.LoadingProduct = carProducts;
|
|
car.LoadingMaterial = carMaterials;
|
|
//查找设置的库位物料
|
|
area = StaticData.getCarInputLocator("1", car);
|
|
if (area != null)
|
|
{
|
|
car.LocatorNodeId = area.Id;
|
|
car.ProLocatorArea = area;
|
|
}
|
|
|
|
if (area == null)
|
|
{
|
|
logger.Error("库位已满,请手动设置库位:");
|
|
IsRuning = false;
|
|
mlist = null;
|
|
logger = null;
|
|
|
|
ret.success = 0;
|
|
ret.message = "库位已满,请手动设置库位";
|
|
ret.data = "";
|
|
return JsonHelper.ObjectToJson(ret);
|
|
}
|
|
else
|
|
{
|
|
//小车存在了, 就修改初始化数据
|
|
car.CarNo = carno.ToString();
|
|
//实际入库位置
|
|
car.LocatorId = 0;
|
|
car.LocatorArea = null;
|
|
car.OptDt = DateTime.Now;
|
|
car.IsOver = 0;
|
|
DBService.ModifyRealCarinfoRecord(car);
|
|
|
|
|
|
|
|
|
|
//Productinfo producthistory = new Productinfo();
|
|
//producthistory.CreateTime = DateTime.Now;
|
|
//producthistory.IsDeleted = 0;
|
|
//producthistory.MaterialNo = productModel.materialno;
|
|
////producthistory.ProductBarno = materialproduct != null ? materialproduct.MaterialNm : "";
|
|
///////记录产品信息
|
|
//DBService.AddProductInfo(producthistory);
|
|
|
|
|
|
// 添加小车记录表
|
|
DBService.AddCarHistoryRecord(car);
|
|
|
|
//点位记录小车编号
|
|
ScanPoint.CarNo = car.CarNo;
|
|
///回写plc状态,起点的分支线路为1
|
|
//var processNode = StaticData.NodeRelation.FirstOrDefault(t => t.PreNodeId == ScanPoint.Id && t.NodeValue == 1002);
|
|
//无道岔,直接给固定值
|
|
this.plcHelper.Write(ScanPoint.PlcSetting4, 1);
|
|
///回写plc状态处理完成,plc会清理数据
|
|
this.plcHelper.Write(ScanPoint.PlcSetting5, 1);
|
|
logger.Log("node:" + this.ScanPoint.NodeNo + " plc:" + this.ScanPoint.PlcSetting4.PlcNo + "" + 1);
|
|
DBService.AddSystemLog(this.ScanPoint.NodeNo, car);
|
|
// IsPlcRead = true;
|
|
}
|
|
|
|
|
|
}//小车移动中指定点位后,并且到位了
|
|
else if (Convert.ToInt32(carno) > 0 && Convert.ToInt32(carrun) == 1 && Convert.ToInt32(wcsend) == 1)
|
|
{
|
|
// IsPlcRead = false;
|
|
//string ocarno = ScanPoint.CarNo;
|
|
CarRealInfo car = StaticData.CarRealList.Where(t => t.CarNo == carno.ToString()).FirstOrDefault();
|
|
string locatorno = "";
|
|
if (car != null)
|
|
{
|
|
|
|
// ////删除上件工件队列 ,
|
|
// //DBService.DeleteUpLineMaterial(carInfo.Id);
|
|
// //lock (StaticData.UpMaterialCarLock)
|
|
// //{
|
|
// // mlist.Remove(carInfo);
|
|
|
|
locatorno = car.ProLocatorArea.AreaNo;
|
|
|
|
}
|
|
|
|
|
|
// car.CurrNodeId = null;
|
|
// car.CurrNodeSetting = null;
|
|
// DBService.ModifyRealCarinfoRecord(car);
|
|
///回写plc状态,,plc会清理数据
|
|
this.plcHelper.Write(ScanPoint.PlcSetting4, 0);
|
|
///回写plc状态处理完成,plc会清理数据
|
|
this.plcHelper.Write(ScanPoint.PlcSetting5, 0);
|
|
//}
|
|
//else
|
|
//{
|
|
// logger.Log("[" + this.LineNo + "] 小车已离开,反馈未找到小车");
|
|
//}
|
|
IsRuning = false;
|
|
ret.success = 1;
|
|
ret.message = "发车完成,发往[" + locatorno + "]库位";
|
|
ret.data = "";
|
|
return JsonHelper.ObjectToJson(ret); ;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Thread.Sleep(1000);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.Error("发车操作异常:" + ex.Message + ex.StackTrace);
|
|
IsRuning = false;
|
|
mlist = null;
|
|
logger = null;
|
|
|
|
ret.success = 0;
|
|
ret.message = "系统异常" + ex.Message;
|
|
ret.data = "";
|
|
return JsonHelper.ObjectToJson(ret); ;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("正在发车中,等待plc反馈中");
|
|
logger = null;
|
|
mlist = null;
|
|
|
|
ret.success = 0;
|
|
ret.message = "正在发车中,等待plc反馈中";
|
|
ret.data = "";
|
|
return JsonHelper.ObjectToJson(ret); ;
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
}
|