|
|
using log4net.Util;
|
|
|
using NPOI.SS.Format;
|
|
|
using NPOI.SS.Formula.Functions;
|
|
|
using NPOI.SS.Formula.PTG;
|
|
|
using Rs.Framework;
|
|
|
using Rs.MotionPlat.Commom;
|
|
|
using Rs.MotionPlat.Flow;
|
|
|
using Rs.MotionPlat.Flow.NormalFlow;
|
|
|
using Rs.MotionPlat.Vision;
|
|
|
using System;
|
|
|
using System.Collections.Concurrent;
|
|
|
using System.Collections.Generic;
|
|
|
using System.ComponentModel;
|
|
|
using System.Data;
|
|
|
using System.IO;
|
|
|
using System.Linq;
|
|
|
using System.Net;
|
|
|
using System.Net.Sockets;
|
|
|
using System.Text;
|
|
|
using System.Threading;
|
|
|
using System.Threading.Tasks;
|
|
|
using System.Web;
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
namespace Rs.MotionPlat.Entitys
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 测试治具状态
|
|
|
/// </summary>
|
|
|
public enum ETestFixtureStatus
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 未连接
|
|
|
/// </summary>
|
|
|
NoConnect,
|
|
|
/// <summary>
|
|
|
/// 未知
|
|
|
/// </summary>
|
|
|
None,
|
|
|
/// <summary>
|
|
|
/// 空闲
|
|
|
/// </summary>
|
|
|
IDLE,
|
|
|
/// <summary>
|
|
|
/// 测试中
|
|
|
/// </summary>
|
|
|
Testing,
|
|
|
/// <summary>
|
|
|
/// 报警中
|
|
|
/// </summary>
|
|
|
Warning,
|
|
|
/// <summary>
|
|
|
/// 暂停
|
|
|
/// </summary>
|
|
|
Pause,
|
|
|
/// <summary>
|
|
|
/// 回原中
|
|
|
/// </summary>
|
|
|
Homing
|
|
|
}
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 测试治具
|
|
|
/// </summary>
|
|
|
public class TestFixture:INotifyPropertyChanged
|
|
|
{
|
|
|
bool exit = false;
|
|
|
public TestFixture()
|
|
|
{
|
|
|
//PrintCommunitionLog();
|
|
|
QueryStatus();
|
|
|
StartRecive();
|
|
|
}
|
|
|
public event Action<string, object> OnProChange;
|
|
|
|
|
|
private TestProduct _Product;
|
|
|
|
|
|
public TestProduct Product
|
|
|
{
|
|
|
get { return _Product; }
|
|
|
set
|
|
|
{
|
|
|
if (_Product != value)
|
|
|
{
|
|
|
_Product = value;
|
|
|
if(OnProChange != null)
|
|
|
{
|
|
|
OnProChange(nameof(Product), value);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public void AddTestRecordToProduct()
|
|
|
{
|
|
|
if (Product != null && !string.IsNullOrEmpty(Result))
|
|
|
{
|
|
|
Product.AddResult(this.Index, "", "");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public void Clear()
|
|
|
{
|
|
|
this.Product = null;
|
|
|
//this.Result = "";
|
|
|
}
|
|
|
|
|
|
public void ClearData()
|
|
|
{
|
|
|
this.Product = null;
|
|
|
this.Result = "";
|
|
|
this.PassCount = 0;
|
|
|
this.TotalCount = 0;
|
|
|
this.LastCT = 0;
|
|
|
this.Yield = 0;
|
|
|
}
|
|
|
|
|
|
private int _Index;
|
|
|
/// <summary>
|
|
|
/// 治具序号
|
|
|
/// </summary>
|
|
|
public int Index {
|
|
|
get { return _Index; }
|
|
|
set
|
|
|
{
|
|
|
if (_Index != value)
|
|
|
{
|
|
|
_Index = value;
|
|
|
if (OnProChange != null)
|
|
|
{
|
|
|
OnProChange(nameof(Index), value);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public string _MachineID;
|
|
|
/// <summary>
|
|
|
/// 机器编码
|
|
|
/// </summary>
|
|
|
public string MachineID
|
|
|
{
|
|
|
get { return _MachineID; }
|
|
|
set
|
|
|
{
|
|
|
if (_MachineID != value)
|
|
|
{
|
|
|
_MachineID = value;
|
|
|
OnPropertyChanged(nameof(MachineID));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 放料偏移X
|
|
|
/// </summary>
|
|
|
public double PlaceProductOffsetX { get; set; }
|
|
|
/// <summary>
|
|
|
/// 放料偏移Y
|
|
|
/// </summary>
|
|
|
public double PlaceProductOffsetY { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// 连接状态
|
|
|
/// </summary>
|
|
|
public bool Connected { get; set; } = false;
|
|
|
|
|
|
private ETestFixtureStatus _Status;
|
|
|
/// <summary>
|
|
|
/// 治具状态
|
|
|
/// </summary>
|
|
|
|
|
|
public ETestFixtureStatus Status
|
|
|
{
|
|
|
get { return _Status; }
|
|
|
set {
|
|
|
if(_Status != value)
|
|
|
{
|
|
|
_Status = value;
|
|
|
OnProChange?.Invoke(nameof(Status), value);
|
|
|
//OnPropertyChanged(nameof(Status));
|
|
|
//if (OnProChange != null)
|
|
|
//{
|
|
|
// OnProChange(nameof(Status), value);
|
|
|
//}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 开始测试时间
|
|
|
/// </summary>
|
|
|
public DateTime StartTestTime { get; set; }
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 结束测试时间
|
|
|
/// </summary>
|
|
|
public DateTime EndTestTime { get; set; }
|
|
|
|
|
|
|
|
|
private double _LastCT;
|
|
|
public double LastCT
|
|
|
{
|
|
|
get { return _LastCT; }
|
|
|
set
|
|
|
{
|
|
|
if (_LastCT != value)
|
|
|
{
|
|
|
_LastCT = value;
|
|
|
OnProChange?.Invoke(nameof(LastCT), value);
|
|
|
//OnPropertyChanged(nameof(LastCT));
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public string Lot { get; set; }
|
|
|
|
|
|
private bool _Enable = false;
|
|
|
/// <summary>
|
|
|
/// 是否启用
|
|
|
/// </summary>
|
|
|
public bool Enable {
|
|
|
get { return _Enable; }
|
|
|
set
|
|
|
{
|
|
|
//if (_Enable != value)
|
|
|
{
|
|
|
_Enable = value;
|
|
|
OnProChange?.Invoke(nameof(Enable), value);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private int _PassCount;
|
|
|
/// <summary>
|
|
|
/// OK数量
|
|
|
/// </summary>
|
|
|
public int PassCount
|
|
|
{
|
|
|
get { return _PassCount; }
|
|
|
set
|
|
|
{
|
|
|
if (_PassCount != value)
|
|
|
{
|
|
|
_PassCount = value;
|
|
|
OnPropertyChanged(nameof(PassCount));
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private int _TotalCount;
|
|
|
/// <summary>
|
|
|
/// 总数量
|
|
|
/// </summary>
|
|
|
public int TotalCount
|
|
|
{
|
|
|
get { return _TotalCount; }
|
|
|
set
|
|
|
{
|
|
|
if (_TotalCount != value)
|
|
|
{
|
|
|
_TotalCount = value;
|
|
|
OnPropertyChanged(nameof(TotalCount));
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private double _Yield;
|
|
|
/// <summary>
|
|
|
/// 良率
|
|
|
/// </summary>
|
|
|
public double Yield
|
|
|
{
|
|
|
get { return _Yield; }
|
|
|
set
|
|
|
{
|
|
|
if (_Yield != value)
|
|
|
{
|
|
|
_Yield = value;
|
|
|
OnProChange?.Invoke(nameof(Yield), value);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private string _Result;
|
|
|
/// <summary>
|
|
|
/// 测试结果
|
|
|
/// </summary>
|
|
|
public string Result
|
|
|
{
|
|
|
get { return _Result; }
|
|
|
set
|
|
|
{
|
|
|
//if (_Result != value)
|
|
|
{
|
|
|
_Result = value;
|
|
|
// OnPropertyChanged(nameof(Result));
|
|
|
OnProChange?.Invoke(nameof(Result), value);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 是否是第一个启用的治具
|
|
|
/// </summary>
|
|
|
public bool IsFirstFixture { get; set; } = false;
|
|
|
/// <summary>
|
|
|
/// CSV文件标题
|
|
|
/// </summary>
|
|
|
public string CsvTitle { get; set; }
|
|
|
|
|
|
private Socket _socket;
|
|
|
|
|
|
|
|
|
public void SetSocket(Socket socket)
|
|
|
{
|
|
|
_socket = socket;
|
|
|
}
|
|
|
|
|
|
List<byte> data = new List<byte>();
|
|
|
public int Send(string content)
|
|
|
{
|
|
|
byte[] data=Encoding.ASCII.GetBytes(content);
|
|
|
return _socket.Send(data);
|
|
|
}
|
|
|
|
|
|
//ManualResetEvent dataEvent=new ManualResetEvent(true);
|
|
|
AutoResetEvent dataEvent = new AutoResetEvent(true);
|
|
|
|
|
|
public event PropertyChangedEventHandler PropertyChanged;
|
|
|
|
|
|
protected virtual void OnPropertyChanged(string propertyName)
|
|
|
{
|
|
|
if (PropertyChanged != null)
|
|
|
{
|
|
|
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public void SetEvent()
|
|
|
{
|
|
|
dataEvent.Set();
|
|
|
}
|
|
|
|
|
|
public void QueryStatus()
|
|
|
{
|
|
|
Task.Run(() => {
|
|
|
while (!exit)
|
|
|
{
|
|
|
if(!Connected)
|
|
|
{
|
|
|
Thread.Sleep(50);
|
|
|
continue;
|
|
|
}
|
|
|
while (true)
|
|
|
{
|
|
|
if (dataEvent.WaitOne(100))
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Thread.Sleep(100);
|
|
|
}
|
|
|
}
|
|
|
Send("Status$");
|
|
|
//dataEvent.Reset();
|
|
|
if (CheckPrintLog())
|
|
|
{
|
|
|
AddLog($"<<< TC{Index} status$");
|
|
|
//logs.Enqueue($"<<< TC{Index} status$");
|
|
|
//lock(this)
|
|
|
//{
|
|
|
// File.AppendAllText($"d:\\1\\{Index}.txt", $"<<< 治具{Index} status$\r\n");
|
|
|
//}
|
|
|
|
|
|
}
|
|
|
Thread.Sleep(100);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 通知治具回原
|
|
|
/// </summary>
|
|
|
public void Home()
|
|
|
{
|
|
|
while (true)
|
|
|
{
|
|
|
if (dataEvent.WaitOne(100))
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Thread.Sleep(100);
|
|
|
}
|
|
|
}
|
|
|
Send($"Reset$");
|
|
|
Result = "";
|
|
|
if (CheckPrintLog())
|
|
|
{
|
|
|
AddLog($"<<< TC{Index} Reset$");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 通知治具暂停
|
|
|
/// </summary>
|
|
|
public void Pause()
|
|
|
{
|
|
|
while (true)
|
|
|
{
|
|
|
if (dataEvent.WaitOne(100))
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Thread.Sleep(100);
|
|
|
}
|
|
|
}
|
|
|
Send($"Pause#1$");
|
|
|
if (CheckPrintLog())
|
|
|
{
|
|
|
AddLog($"<<< TC{Index} Pause#1$");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 通知治具启动测试
|
|
|
/// </summary>
|
|
|
public void StartTest(string sn="")
|
|
|
{
|
|
|
while (true)
|
|
|
{
|
|
|
if (dataEvent.WaitOne(100))
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Thread.Sleep(100);
|
|
|
}
|
|
|
}
|
|
|
//先把侧相机数据清空
|
|
|
VisionHelper.sideCameraVision.ClearQueue(this.Index);
|
|
|
int noise = GlobalVar.Noise ? 1 : 0;
|
|
|
int mtcp=GlobalVar.Mtcp ? 1 : 0;
|
|
|
int isFirstFixture = IsFirstFixture ? 1 : 0;
|
|
|
string msg = string.Empty;
|
|
|
if(string.IsNullOrEmpty(sn))
|
|
|
{
|
|
|
//StartTest#SN#Machine#User#Config#Lot#Mode#SiteID#ProjectID#RetryMode#Mes#Mtcp#configD#DualMode#TakeIndex#SubLotName$
|
|
|
//msg = $"StartTest#{Product.SN}#MS001#OP#DXD#GRR_GRR_DXD_202203120320#Production#LF1#MOS#T1#0#0#Paint#0#R1C5#SP0012#1$";
|
|
|
msg = $"StartTest#{Product.SN}#{GlobalVar.MachineID}#op#{GlobalVar.Config}#{GlobalVar.LotName}#{GlobalVar.TestMode}#{GlobalVar.SiteID}#{GlobalVar.ProjectID}#T1#0#{mtcp}#{GlobalVar.ConfigName}#0#{Product.From}#{GlobalVar.SubLotName}#{noise}#{isFirstFixture}#{GlobalVar.RelCategory}#{GlobalVar.RelCp}#{GlobalVar.HostType}$";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
msg = $"StartTest#{sn}#MS001#OP#DXD#GRR_GRR_DXD_202203120320#Production#LF1#MOS#T1#0#0#Paint#0#R1C5#SP0012#1$";
|
|
|
}
|
|
|
LogHelper.Debug(msg);
|
|
|
// string msg = $"StartTest#123#{GlobalVar.MachineID}#op#{GlobalVar.Config}#Lot#Mode#SiteID#ProjectID#RetryMode#{mtcp}#Mtcp#configD#DualMode#R1C1#SubLotName#{noise}$";
|
|
|
//msg = $"StartTest#{Product.SN}#MS001#OP#DXD#GRR_GRR_DXD_202203120320#Production#LF1#MOS#T1#0#0#Paint#0#R1C5#SP0012#1$";
|
|
|
Send(msg);
|
|
|
if(CheckPrintLog())
|
|
|
{
|
|
|
AddLog($"<<< TC{Index} {msg}");
|
|
|
}
|
|
|
}
|
|
|
private ConcurrentQueue<string> logs = new ConcurrentQueue<string>();
|
|
|
public void StartRecive()
|
|
|
{
|
|
|
Task.Run(() => {
|
|
|
while (!exit)
|
|
|
{
|
|
|
if(!Connected)
|
|
|
{
|
|
|
Thread.Sleep(100);
|
|
|
continue;
|
|
|
}
|
|
|
byte[] bytes=new byte[1024 *10];
|
|
|
try
|
|
|
{
|
|
|
int len = _socket.Receive(bytes);
|
|
|
if (len > 0)
|
|
|
{
|
|
|
for(int i=0;i<len;i++)
|
|
|
{
|
|
|
if (bytes[i] != (byte)'$')
|
|
|
{
|
|
|
data.Add(bytes[i]);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
MessageParse();
|
|
|
data.Clear();
|
|
|
}
|
|
|
}
|
|
|
//string data = Encoding.ASCII.GetString(bytes, 0, len);
|
|
|
//MessageQueue.Instance.Insert(data);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
MessageQueue.Instance.Warn($"TC{Index} disconned!");
|
|
|
Status = ETestFixtureStatus.NoConnect;
|
|
|
Connected = false;
|
|
|
}
|
|
|
}
|
|
|
catch (SocketException ex)
|
|
|
{
|
|
|
Status = ETestFixtureStatus.NoConnect;
|
|
|
MessageQueue.Instance.Warn($"TC{Index} disconned!");
|
|
|
Connected = false;
|
|
|
}
|
|
|
Thread.Sleep(10);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
private void MessageParse()
|
|
|
{
|
|
|
if(data!=null&&data.Count>0)
|
|
|
{
|
|
|
string content = Encoding.ASCII.GetString(data.ToArray());
|
|
|
if (CheckPrintLog())
|
|
|
{
|
|
|
AddLog($">>> TC{Index},{content}");
|
|
|
}
|
|
|
string[] items = content.Split('#');
|
|
|
string command = items[0];
|
|
|
|
|
|
switch (command)
|
|
|
{
|
|
|
case "Status":
|
|
|
switch (items[1])
|
|
|
{
|
|
|
case "0":
|
|
|
//非就绪状态,查询错误代码
|
|
|
Send("ErrorCode$");
|
|
|
if (CheckPrintLog())
|
|
|
{
|
|
|
//lock (this)
|
|
|
//{
|
|
|
// File.AppendAllText($"d:\\1\\{Index}.txt", $"<<< 治具{Index} ErrorCode$\r\n");
|
|
|
//}
|
|
|
|
|
|
AddLog($"<<< TC{Index} ErrorCode$");
|
|
|
}
|
|
|
break;
|
|
|
case "1":
|
|
|
//就绪状态,如果有产品就查询测试结果
|
|
|
if(Status == ETestFixtureStatus.Testing ||(Status== ETestFixtureStatus.IDLE && Product!=null &&String.IsNullOrEmpty(Result)))
|
|
|
{
|
|
|
Send("Result$");
|
|
|
LogHelper.Debug($"<<< TC{Index} Result$");
|
|
|
if (CheckPrintLog())
|
|
|
{
|
|
|
//lock (this)
|
|
|
//{
|
|
|
// File.AppendAllText($"d:\\1\\{Index}.txt", $"<<< 治具{Index} Result$\r\n");
|
|
|
//}
|
|
|
AddLog($"<<< TC{Index} Result$");
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
dataEvent.Set();
|
|
|
Status = ETestFixtureStatus.IDLE;
|
|
|
}
|
|
|
break;
|
|
|
case "2":
|
|
|
dataEvent.Set();
|
|
|
Status = ETestFixtureStatus.Homing;
|
|
|
break;
|
|
|
case "3":
|
|
|
//侧相机测试失败
|
|
|
EButtonType sideCameraSelect = Msgbox.ShowTipDialog(EButtonType.Retry | EButtonType.Cancel, $"Please check DUT{Index} is placed ok,ok continue test click retry,stop test click Cancel","warn",true);
|
|
|
if(sideCameraSelect== EButtonType.Retry)
|
|
|
{
|
|
|
string msg = "ContinueTest#1$";
|
|
|
Send(msg);
|
|
|
}
|
|
|
else if(sideCameraSelect== EButtonType.Cancel)
|
|
|
{
|
|
|
string msg = "ContinueTest#0$";
|
|
|
Send(msg);
|
|
|
}
|
|
|
dataEvent.Set();
|
|
|
break;
|
|
|
}
|
|
|
break;
|
|
|
case "StartTest":
|
|
|
//if (writeLogs.Contains(Index))
|
|
|
//{
|
|
|
// LogHelper.Info($">>> 治具{Index} StartTest");
|
|
|
//}
|
|
|
this.Result = "";
|
|
|
this.StartTestTime=DateTime.Now;
|
|
|
this.Status= ETestFixtureStatus.Testing;
|
|
|
dataEvent.Set();
|
|
|
break;
|
|
|
case "Result":
|
|
|
//if(items!=null && items.Length>=6)
|
|
|
{
|
|
|
lock(this)
|
|
|
{
|
|
|
if (Product != null)
|
|
|
{
|
|
|
LogHelper.Debug($"治具{Index}测试完成,测试总数量由{TotalCount}增加到{TotalCount + 1}");
|
|
|
|
|
|
if (items[2] == "1")
|
|
|
{
|
|
|
Result = "PASS";
|
|
|
PassCount++;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Result = "NG";
|
|
|
}
|
|
|
Product.Result = Result;
|
|
|
Product.Bin = items[6];
|
|
|
this.EndTestTime = DateTime.Now;
|
|
|
this.LastCT = (EndTestTime - StartTestTime).TotalSeconds;
|
|
|
TotalCount++;
|
|
|
Yield = (double)((double)PassCount / TotalCount);
|
|
|
AddTestRecordToProduct();
|
|
|
//this.Product.AddResult(this.Index, Result, items[6]);
|
|
|
}
|
|
|
string csvContent = string.Join(",", items[3], items[4], items[5]);
|
|
|
LogHelper.Debug($"Result:{items[2]},{items[3]}");
|
|
|
DevLog.Summary(CsvTitle, csvContent);
|
|
|
Status = ETestFixtureStatus.IDLE;
|
|
|
dataEvent.Set();
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
case "ErrorCode":
|
|
|
//if (writeLogs.Contains(Index))
|
|
|
//{
|
|
|
// LogHelper.Info($">>> 治具{Index} ErrorCode");
|
|
|
//}
|
|
|
string code = items[1];
|
|
|
if(code!="0")
|
|
|
{
|
|
|
if(Status != ETestFixtureStatus.Warning)
|
|
|
{
|
|
|
Status = ETestFixtureStatus.Warning;
|
|
|
Task.Run(() => {
|
|
|
string errInfo = $"tc{Index} test,code:{items[1]},desc:{items[2]}";
|
|
|
MessageQueue.Instance.Warn(errInfo);
|
|
|
Msgbox.ShowTipDialog(EButtonType.Ok, errInfo,"testfixture error",true);
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Status = ETestFixtureStatus.Testing;
|
|
|
}
|
|
|
dataEvent.Set();
|
|
|
break;
|
|
|
case "Grip":
|
|
|
dataEvent.Set();
|
|
|
break;
|
|
|
case "Vlog":
|
|
|
//dataEvent.Set();
|
|
|
DevLog.Breakdown(items[1], items[2]);
|
|
|
break;
|
|
|
case "Reset":
|
|
|
dataEvent.Set();
|
|
|
break;
|
|
|
case "GR":
|
|
|
VisionHelper.sideCameraVision.Grab(Index, items[1]);
|
|
|
//dataEvent.Set();
|
|
|
break;
|
|
|
case "Pause":
|
|
|
dataEvent.Set();
|
|
|
break;
|
|
|
case "ReadIO":
|
|
|
// dataEvent.Set();
|
|
|
try
|
|
|
{
|
|
|
string ioname = items[1];
|
|
|
int value = Ops.IsOutOn(ioname)?1:0;
|
|
|
Send($"ReadIO#{value}$");
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
LogHelper.Error($"ReadIO error:{ex.Message}");
|
|
|
}
|
|
|
break;
|
|
|
case "WriteIO":
|
|
|
try
|
|
|
{
|
|
|
string ioname = items[1];
|
|
|
int value = int.Parse(items[2]);
|
|
|
if (value == 1)
|
|
|
Ops.On(ioname);
|
|
|
else
|
|
|
Ops.Off(ioname);
|
|
|
Send($"WriteIO#0$");
|
|
|
}
|
|
|
catch (Exception)
|
|
|
{
|
|
|
Send($"WriteIO#-1$");
|
|
|
}
|
|
|
break;
|
|
|
case "TrayInfo":
|
|
|
try
|
|
|
{
|
|
|
string splitChar = ";";
|
|
|
string title = $"TrayInfo#LotName,TrayType,Endtime,SerialNumber,Tray_X_O,Tray_Y_O{splitChar}";
|
|
|
List<string> dataList = new List<string>();
|
|
|
string lotname = items[1];
|
|
|
string querySql = $"select * from records where lotname='{lotname}'";
|
|
|
DataSet ds = MySqlHelper.GetDataSet(querySql);
|
|
|
if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
|
|
|
{
|
|
|
foreach (DataRow row in ds.Tables[0].Rows)
|
|
|
{
|
|
|
(int r, int c) = TrayHelper.GetRC(int.Parse(row["toIndex"].ToString()),16,16);
|
|
|
string data = $"{row["lotname"].ToString()},{row["traytype"].ToString()},{row["placetime"].ToString()},{row["sn"].ToString()},{r + 1},{c + 1}";
|
|
|
dataList.Add(data);
|
|
|
}
|
|
|
}
|
|
|
string sendData = $"{title}{string.Join($"{splitChar}", dataList)},$";
|
|
|
Send(sendData);
|
|
|
}
|
|
|
catch (Exception ex)
|
|
|
{
|
|
|
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public void AddLog(string log)
|
|
|
{
|
|
|
if(logs.Count>500)
|
|
|
{
|
|
|
int i = 0;
|
|
|
while (true)
|
|
|
{
|
|
|
i++;
|
|
|
logs.TryDequeue(out string msg);
|
|
|
if(i>=500)
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
logs.Enqueue(log);
|
|
|
}
|
|
|
|
|
|
public string GetLog()
|
|
|
{
|
|
|
StringBuilder msg = new StringBuilder();
|
|
|
while (logs.Count > 0)
|
|
|
{
|
|
|
bool b = logs.TryDequeue(out string content);
|
|
|
if(b)
|
|
|
{
|
|
|
msg.Append($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} {content}\r\n");
|
|
|
}
|
|
|
}
|
|
|
return msg.ToString();
|
|
|
}
|
|
|
//private void PrintCommunitionLog()
|
|
|
//{
|
|
|
// Task.Run(() => {
|
|
|
// while (true)
|
|
|
// {
|
|
|
// if(logs.Count > 0)
|
|
|
// {
|
|
|
// bool ret = logs.TryDequeue(out string log);
|
|
|
// if (ret)
|
|
|
// {
|
|
|
// //打印日志
|
|
|
// string logDir = $"d:\\Communition\\{DateTime.Now.ToString("yyyyMMdd")}";
|
|
|
// if(!Directory.Exists(logDir))
|
|
|
// {
|
|
|
// Directory.CreateDirectory(logDir);
|
|
|
// }
|
|
|
// string logFileName = $"{logDir}\\{Index}.txt";
|
|
|
// File.AppendAllText(logFileName, $"{DateTime.Now.ToString("HH:mm:ss fff")} {log}\r\n");
|
|
|
// }
|
|
|
// }
|
|
|
// else
|
|
|
// {
|
|
|
// Thread.Sleep(100);
|
|
|
// }
|
|
|
// }
|
|
|
// });
|
|
|
//}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 检测是否需要打印日志
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
private bool CheckPrintLog()
|
|
|
{
|
|
|
return true;
|
|
|
switch (Index)
|
|
|
{
|
|
|
case 1:
|
|
|
return GlobalVar.PrintTC1Communicate;
|
|
|
case 2:
|
|
|
return GlobalVar.PrintTC2Communicate;
|
|
|
case 3:
|
|
|
return GlobalVar.PrintTC3Communicate;
|
|
|
case 4:
|
|
|
return GlobalVar.PrintTC4Communicate;
|
|
|
case 5:
|
|
|
return GlobalVar.PrintTC5Communicate;
|
|
|
case 6:
|
|
|
return GlobalVar.PrintTC6Communicate;
|
|
|
default: return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 夹头夹紧
|
|
|
/// </summary>
|
|
|
public void ColletOn(string className)
|
|
|
{
|
|
|
Ops.On($"治具夹{Index}");
|
|
|
string logInfo = $"{className} 治具夹{Index}夹紧";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
Thread.Sleep(GlobalVar.ColletCloseDelaytime);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 夹头松开
|
|
|
/// </summary>
|
|
|
public void ColletOff(string className)
|
|
|
{
|
|
|
Ops.Off($"治具夹{Index}");
|
|
|
Thread.Sleep(GlobalVar.ColletOpenDelaytime);
|
|
|
string logInfo = $"{className} 治具夹{Index}松开";
|
|
|
MessageQueue.Instance.Insert(logInfo);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取拍照位置
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public TargetPosition GetGrabPos()
|
|
|
{
|
|
|
TargetPosition targetPos = new TargetPosition();
|
|
|
switch (Index)
|
|
|
{
|
|
|
case 1:
|
|
|
targetPos.X = GlobalVar.Fixture1GrabImageX;
|
|
|
targetPos.Y1 = GlobalVar.FixtureSideY1;
|
|
|
targetPos.Y2 = GlobalVar.Fixture1GrabImageY2;
|
|
|
break;
|
|
|
case 2:
|
|
|
targetPos.X = GlobalVar.Fixture2GrabImageX;
|
|
|
targetPos.Y1 = GlobalVar.FixtureSideY1;
|
|
|
targetPos.Y2 = GlobalVar.Fixture2GrabImageY2;
|
|
|
break;
|
|
|
case 3:
|
|
|
targetPos.X = GlobalVar.Fixture3GrabImageX;
|
|
|
targetPos.Y1 = GlobalVar.FixtureSideY1;
|
|
|
targetPos.Y2 = GlobalVar.Fixture3GrabImageY2;
|
|
|
break;
|
|
|
case 4:
|
|
|
targetPos.X = GlobalVar.Fixture4GrabImageX;
|
|
|
targetPos.Y1 = GlobalVar.FixtureSideY1;
|
|
|
targetPos.Y2 = GlobalVar.Fixture4GrabImageY2;
|
|
|
break;
|
|
|
case 5:
|
|
|
targetPos.X = GlobalVar.Fixture5GrabImageX;
|
|
|
targetPos.Y1 = GlobalVar.FixtureSideY1;
|
|
|
targetPos.Y2 = GlobalVar.Fixture5GrabImageY2;
|
|
|
break;
|
|
|
case 6:
|
|
|
targetPos.X = GlobalVar.Fixture6GrabImageX;
|
|
|
targetPos.Y1 = GlobalVar.FixtureSideY1;
|
|
|
targetPos.Y2 = GlobalVar.Fixture6GrabImageY2;
|
|
|
break;
|
|
|
}
|
|
|
return targetPos;
|
|
|
}
|
|
|
}
|
|
|
public class TestFixtureManager
|
|
|
{
|
|
|
TestFixture[] testFixtures=new TestFixture[6];
|
|
|
private TestFixtureManager()
|
|
|
{
|
|
|
for (int i = 1; i <= 6; i++)
|
|
|
{
|
|
|
testFixtures[i-1] = new TestFixture();
|
|
|
testFixtures[i-1].Index = i;
|
|
|
|
|
|
}
|
|
|
|
|
|
serverSocket=new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
|
|
}
|
|
|
private static TestFixtureManager instance;
|
|
|
public static TestFixtureManager Instance
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
if(instance == null)
|
|
|
instance = new TestFixtureManager();
|
|
|
return instance;
|
|
|
}
|
|
|
}
|
|
|
Socket serverSocket;
|
|
|
List<Socket> clientSockets = new List<Socket>();
|
|
|
public TestFixture GetTestFixture(int index)
|
|
|
{
|
|
|
return testFixtures.Where(t => t.Index == index).FirstOrDefault();
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 查询有产品的治具列表
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public List<TestFixture> GetHaveProductFixtureList()
|
|
|
{
|
|
|
return testFixtures.Where(t=>t.Enable&&t.Product!=null).ToList();
|
|
|
}
|
|
|
|
|
|
public void StartLister()
|
|
|
{
|
|
|
Task.Run(() => {
|
|
|
MessageQueue.Instance.Insert("start lister");
|
|
|
serverSocket.Bind(new IPEndPoint(IPAddress.Any, 6050));
|
|
|
serverSocket.Listen(10);
|
|
|
while (true)
|
|
|
{
|
|
|
Socket clientSocket = serverSocket.Accept();
|
|
|
clientSockets.Add(clientSocket);
|
|
|
IPEndPoint endPoint = ((IPEndPoint)clientSocket.RemoteEndPoint);
|
|
|
MessageQueue.Instance.Insert($"ip:{endPoint.Address.ToString()},port:{endPoint.Port.ToString()} connected!");
|
|
|
ThreadPool.QueueUserWorkItem((obj) => {
|
|
|
List<byte> registData=new List<byte>();
|
|
|
Socket soct=(Socket)obj;
|
|
|
IPEndPoint ep = ((IPEndPoint)soct.RemoteEndPoint);
|
|
|
byte[] buffer = new byte[1024 * 10];
|
|
|
bool stop = false;
|
|
|
while (!stop)
|
|
|
{
|
|
|
int len = soct.Receive(buffer);
|
|
|
if (len > 0)
|
|
|
{
|
|
|
for(int i=0;i<len;i++)
|
|
|
{
|
|
|
if (buffer[i] !=36)
|
|
|
{
|
|
|
registData.Add(buffer[i]);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
|
|
|
string content=Encoding.ASCII.GetString(registData.ToArray());
|
|
|
//MessageQueue.Instance.Insert($">>> ip:{ep.Address.ToString()},port:{ep.Port.ToString()},{content}");
|
|
|
string[] items = content.TrimEnd(new char[] { '$' }).Split('#');
|
|
|
Thread.Sleep(500);
|
|
|
string reg = "Register#1$";
|
|
|
int sendLen = clientSocket.Send(Encoding.ASCII.GetBytes(reg));
|
|
|
MessageQueue.Instance.Insert($"<<< ip:{ep.Address.ToString()},port:{ep.Port.ToString()},{reg}");
|
|
|
TestFixture tf = GetTestFixture(int.Parse(items[2]));
|
|
|
tf.SetSocket(soct);
|
|
|
tf.AddLog(" <<< " + content);
|
|
|
tf.AddLog(" >>> " + reg);
|
|
|
tf.MachineID = items[1];
|
|
|
tf.Connected = true;
|
|
|
tf.Status = ETestFixtureStatus.None;
|
|
|
tf.CsvTitle = items[3];
|
|
|
tf.SetEvent();
|
|
|
stop = true;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
Thread.Sleep(10);
|
|
|
}
|
|
|
|
|
|
}, clientSocket);
|
|
|
Thread.Sleep(10);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取启用的治具列表
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public List<TestFixture> GetEnableFixtureList()
|
|
|
{
|
|
|
return testFixtures.Where(t=>t.Enable).ToList();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取有产品治具数量
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public int GetHasProuctFixtureCount()
|
|
|
{
|
|
|
return testFixtures.Where(t=>t.Enable && t.Product!=null).Count();
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取空闲的治具
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
public TestFixture GetIdleFixture()
|
|
|
{
|
|
|
List<TestFixture> lt = testFixtures.Where(t => t.Enable && t.Product == null).ToList();
|
|
|
if(lt!=null&<.Count>0)
|
|
|
{
|
|
|
return lt.First();
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
}
|