Initial commit

This commit is contained in:
ChiKyun Kim
2025-07-17 16:11:46 +09:00
parent 4865711adc
commit 4a1b1924ba
743 changed files with 230954 additions and 0 deletions

View File

@@ -0,0 +1,187 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Project
{
public static class AmkorReelID
{
/// <summary>
/// 앰코 ID형태인지 확인합니다.
/// </summary>
/// <param name="rid"></param>
/// <param name="yy"></param>
/// <param name="m"></param>
/// <returns></returns>
public static Boolean IsValidID(string rid, out string yy, out string m)
{
yy = string.Empty;
m = string.Empty;
if (rid.Length != 15) return false;
try
{
var custCost = rid.Substring(2, 4);
var site = "K" + rid.Substring(6, 1);
var mc = rid.Substring(7, 1);
yy = rid.Substring(8, 2);
m = rid.Substring(10, 1);
var sn = rid.Substring(11, 4);
return true;
}
catch
{
return false;
}
}
public static string MakeReelID(string customercode, string ym)
{
if (customercode.Length != 4)
{
return String.Empty;//
//throw new Exception("Customer 코드는 4자리 입니다");
}
if (ym.Length != 3)
{
return string.Empty;//
//throw new Exception("Ym 코드는 3자리 입니다");
}
var rid = "RC{CUST}{DEVLOC}{DEVID}{YM}";
rid = rid.Replace("{DEVLOC}", AR.SETTING.Data.ReelIdDeviceLoc);
rid = rid.Replace("{DEVID}", AR.SETTING.Data.ReelIdDeviceID);
rid = rid.Replace("{CUST}", customercode);
rid = rid.Replace("{YM}", ym);
rid += GetNextSNbyYM(ym);
return rid;
}
/// <summary>
/// 입력된 월 기준으로 시리얼 번호를 생성합니다
/// </summary>
/// <param name="ym">21년 1월의 경우 211, 10월의 경우 21A 식으로 표현</param>
/// <param name="removeR">1,2번 위치에 R기호를 제거 할 것인가?</param>
/// <returns></returns>
public static string GetNextSNbyYM(string ym)
{
//서버에서 자료를 조회해서 처리한다.
var db = new EEEntities();
var dr = db.Component_Reel_Result.Where(t => t.PDATE == ym && t.PDATE.Contains("R") == false).OrderByDescending(t => t.RSN).FirstOrDefault();
if (dr == null) return "0001"; //처음쓰는 자료인다.
var curSN = dr.RSN;
return GetNextSNbySN(curSN);
}
/// <summary>
/// 해당월의 리턴릴의 번호를 생성한다
/// </summary>
/// <param name="ym"></param>
/// <returns></returns>
public static string GetNextSNbyYM_Return(string ym)
{
//서버에서 자료를 조회해서 처리한다.
var db = new EEEntities();
var dr = db.Component_Reel_Result.Where(t => t.PDATE == ym && t.PDATE.StartsWith("R")).OrderByDescending(t => t.RSN).FirstOrDefault();
if (dr == null) return "R001"; //처음쓰는 자료인다.
var curSN = dr.RSN;
return GetNextSNbySN_Return(curSN);
}
/// <summary>
/// 중복릴의 다은번호를 생성한다
/// </summary>
/// <param name="ym"></param>
/// <returns></returns>
public static string GetNextSNbyYM_Dup(string ym)
{
//서버에서 자료를 조회해서 처리한다.
var db = new EEEntities();
var dr = db.Component_Reel_Result.Where(t => t.PDATE == ym && t.PDATE.StartsWith("0R")).OrderByDescending(t => t.RSN).FirstOrDefault();
if (dr == null) return "0R01"; //처음쓰는 자료인다.
var curSN = dr.RSN;
return GetNextSNbySN_Dup(curSN);
}
/// <summary>
/// 입력한 시리얼 번호 이후의 번호를 생성합니다(0000~ZZZZ) 까지의 데이터를 가지며 2번쨰짜리까지는 R을 사용하지 못한다
/// </summary>
/// <param name="sn">기준 시리얼번호 4자리</param>
/// <param name="removeR"></param>
/// <returns></returns>
public static string GetNextSNbySN(string sn)
{
//서버에서 자료를 조회해서 처리한다.
string curSN = sn;
if (sn.Length != 4) throw new Exception("s/n length 4");
var buffer = curSN.ToCharArray();
for (int i = buffer.Length; i > 0; i--)
{
if (i <= 2)
if (buffer[i - 1] == 'Q') buffer[i - 1] = 'R';
if (buffer[i - 1] == '9') { buffer[i - 1] = 'A'; break; }
else if (buffer[i - 1] == 'Z') buffer[i - 1] = '0';
else { buffer[i - 1] = (char)((byte)buffer[i - 1] + 1); break; }
}
return string.Join("", buffer);
}
/// <summary>
/// 리턴릴의 다음 번호 생성 R로시작하며 000~ZZZ 영역을 가진다(제외문자 없음)
/// </summary>
/// <param name="sn"></param>
/// <returns></returns>
public static string GetNextSNbySN_Return(string sn)
{
//서버에서 자료를 조회해서 처리한다.
string curSN = sn;
if (sn.Length != 4) throw new Exception("s/n length 4");
var buffer = curSN.ToCharArray();
for (int i = buffer.Length; i > 1; i--)
{
//if (i <= 2) //1,2번 영역에는 R값이 들어가면 안된다.
//{
// if (buffer[i - 1] == 'Q') buffer[i - 1] = 'R';
//}
if (buffer[i - 1] == '9') { buffer[i - 1] = 'A'; break; }
else if (buffer[i - 1] == 'Z') buffer[i - 1] = '0';
else { buffer[i - 1] = (char)((byte)buffer[i - 1] + 1); break; }
}
buffer[0] = 'R';
return string.Join("", buffer);
}
/// <summary>
/// 중복릴의 다음 번호 생성(0R로 시작하며 00~ZZ의 영역을 가진다)
/// </summary>
/// <param name="sn"></param>
/// <returns></returns>
public static string GetNextSNbySN_Dup(string sn)
{
//서버에서 자료를 조회해서 처리한다.
string curSN = sn;
if (sn.Length != 4) throw new Exception("s/n length 4");
var buffer = curSN.ToCharArray();
for (int i = buffer.Length; i > 2; i--)
{
//if (i <= 2) //1,2번 영역에는 R값이 들어가면 안된다.
//{
// if (buffer[i - 1] == 'Q') buffer[i - 1] = 'R';
//}
if (buffer[i - 1] == '9') { buffer[i - 1] = 'A'; break; }
else if (buffer[i - 1] == 'Z') buffer[i - 1] = '0';
else { buffer[i - 1] = (char)((byte)buffer[i - 1] + 1); break; }
}
buffer[0] = '0';
buffer[1] = 'R';
return string.Join("", buffer);
}
}
}

View File

@@ -0,0 +1,168 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
namespace Project.Class
{
public class CHistoryJOB : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
List<JobData> _items;
public CHistoryJOB()
{
_items = new List<JobData>();
}
public void Clear()
{
lock (_items)
{
_items.Clear();
}
OnPropertyChanged("Clear");
}
public int Count
{
get
{
lock (_items)
{
return _items.Count;
}
}
}
public void SetItems(List<JobData> value)
{
lock (_items)
{
this._items = value;
}
OnPropertyChanged("REFRESH");
}
public List<JobData> Items { get { return _items; } }
public void Add(JobData data)
{
lock (_items)
{
data.No = this._items.Count + 1;
_items.Add(data);
}
OnPropertyChanged("Add:" + data.guid);
}
public void Remove(JobData data)
{
lock (_items)
{
_items.Remove(data);
}
OnPropertyChanged("Remove:" + data.guid);
}
public void Remove(string guid)
{
lock (_items)
{
var data = Get(guid);
_items.Remove(data);
}
OnPropertyChanged("Remove:" + guid);
}
public JobData Get(string guid)
{
lock (_items)
{
return _items.Where(t => t.guid == guid).FirstOrDefault();
}
}
public void Set(JobData data)
{
var item = Get(data.guid);
if (item == null) throw new Exception("No data guid:" + data.guid.ToString());
else
{
//item.No = data.No;
//item.JobStart = data.JobStart;
//item.JobEnd = data.JobEnd;
//item.VisionData = data.VisionData;
//item.error = data.error;
//item.Message = data.Message;
OnPropertyChanged("Set:" + data.guid);
}
}
public void RaiseSetEvent(string guid)
{
OnPropertyChanged("Set:" + guid);
}
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
if (PropertyChanged != null)
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(name));
}
}
//[Serializable]
//public class JobData
//{
// //고유식별자
// public string guid { get; private set; }
// //비젼처리값
// public Class.VisionData VisionData { get; set; }
// //언로더포트(L/R)
// public string PortPos { get; set; }
// //프린트위치(U/LO)
// public string PrintPos { get; set; }
// //작업시작시간
// public DateTime JobStart { get; set; }
// //작업종료시간
// public DateTime JobEnd { get; set; }
// /// <summary>
// /// 이전 출고되는 시점과의 시간차 값
// /// </summary>
// public double TackTime { get { return (JobEnd - JobStart).TotalSeconds; } }
// //작업순서
// public int No { get; set; }
// //오류상태
// public eJobResult error { get; set; }
// //메세지
// public string message { get; set; }
// public TimeSpan JobRun
// {
// get
// {
// if (JobEnd.Year == 1982) return new TimeSpan(0);
// else return this.JobEnd - this.JobStart;
// }
// }
// public JobData()
// {
// this.No = 0;
// PortPos = string.Empty;
// PrintPos = string.Empty;
// guid = Guid.NewGuid().ToString();
// VisionData = new VisionData();
// this.JobStart = new DateTime(1982, 11, 23); // DateTime.Parse("1982-11-23");
// this.JobEnd = new DateTime(1982, 11, 23); // DateTime.Parse("1982-11-23");
// error = eJobResult.None;
// message = string.Empty;
// }
//}
}

View File

@@ -0,0 +1,134 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
namespace Project.Class
{
public class CHistorySIDRef : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public Boolean JobSIDRecvError
{
get
{
//아이템이있어야 정상이다
if (_items == null || _items.Count < 1) return true;
else if (JobSIDRecvTime.Year == 1982) return true;
else return false;
}
}
public DateTime JobSIDRecvTime { get; set; }
public string JobSIDRecvMessage { get; set; }
List<SIDDataRef> _items;
public CHistorySIDRef()
{
Clear();
}
public void SetItems(List<SIDDataRef> value)
{
this._items = value;
OnPropertyChanged("REFRESH");
}
public List<SIDDataRef> Items { get { return _items; } }
public int Count
{
get
{
return _items.Count;
}
}
public SIDDataRef Get(string sid_)
{
return _items.Where(t => t.sid == sid_).FirstOrDefault();
}
public void Set(SIDDataRef data)
{
var item = Get(data.sid);
if (item == null) throw new Exception("No data sid:" + data.sid.ToString());
else
{
item.kpc = data.kpc;
item.unit = data.unit;
OnPropertyChanged("Set:" + data.sid);
}
}
public void Set(string sid, int kpc, string unit)
{
var item = Get(sid);
if (item == null)
{
Add(sid, kpc, unit); //없다면 추가해준다
}
else
{
item.kpc = kpc;
item.unit = unit;
OnPropertyChanged("Set:" + sid);
}
}
public void Add(SIDDataRef data)
{
_items.Add(data);
OnPropertyChanged("Add:" + data.sid);
}
public void Add(string sid, int kpc_, string unit)
{
if (string.IsNullOrEmpty(sid))
{
PUB.log.AddAT("SID 추가 실패 SID 값이 입력되지 않았습니다");
return;
}
//if (JobSidList.ContainsKey(sid) == false)
_items.Add(new SIDDataRef(sid, kpc_, unit));
OnPropertyChanged("Add:" + sid);
//else
//{
//이미 데이터가 있다. 중복이므로 누적한다
//JobSidList.TryGetValue()
//}
}
public void Clear()
{
//JobSIDRecvError = false;
JobSIDRecvMessage = string.Empty;
JobSIDRecvTime = DateTime.Parse("1982-11-23");
if (this._items == null) this._items = new List<SIDDataRef>();
else this._items.Clear();
OnPropertyChanged("Clear");
}
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
if (PropertyChanged != null)
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(name));
}
}
[Serializable]
public class SIDDataRef
{
public string guid { get; set; }
public string sid { get; set; }
public string unit { get; set; }
public int kpc { get; set; }
public SIDDataRef(string sid_, int kpc_, string unit_)
{
guid = Guid.NewGuid().ToString();
sid = sid_;
unit = unit_;
kpc = kpc_;
}
public SIDDataRef() : this(string.Empty, 0, string.Empty) { }
}
}

View File

@@ -0,0 +1,549 @@
using AR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Project
{
public class CResult
{
public enum eInspectResult
{
NG = 0,
OK,
ERROR,
NOTSET = 9,
}
public UInt64 OptionValue = 0;
public UInt64 OptionValueData = 0;
public List<Class.RegexPattern> BCDPattern;
public List<Class.RegexPattern> BCDIgnorePattern;
public List<Class.RegexPattern> BCDPrintPattern;
public DateTime ResetButtonDownTime = DateTime.Now;
public Boolean ClearAllSID = false;
public Class.CHistorySIDRef SIDReference; //SIDLIST받은 내역
public List<UIControl.CItem> OUTHistory; //출고포트 처리내역
public DataSet1.SIDHistoryDataTable SIDHistory; //sID별 rid 전체 목록 차수별로만 저장된다
public DataSet1.Component_Reel_SID_ConvertDataTable DTSidConvert;
public List<string> DTSidConvertEmptyList;
public List<string> DTSidConvertMultiList;
public DSList dsList;
public ModelInfoM mModel; //모션 모델
public ModelInfoV vModel; //작업 모델
/// <summary>
/// 아이템의 정보가 담겨있다 (0:왼쪽,1:비젼,2:오른쪽)
/// </summary>
public Class.JobData ItemDataL = new Class.JobData(0);
public Class.JobData ItemDataC = new Class.JobData(1);
public Class.JobData ItemDataR = new Class.JobData(2);
public Guid guid = new Guid();
public string JobType2 = string.Empty;
public Boolean JobFirst
{
get
{
return VAR.I32[(int)eVarInt32.PickOnCount] == 0;
}
}
public Boolean DryRun
{
get
{
if (string.IsNullOrEmpty(JobType2)) return false;
else return JobType2.ToUpper() == "DRY";
}
}
public int OverLoadCountF { get; set; }
public int OverLoadCountR { get; set; }
public UIControl.CItem UnloaderItem = null;
public DateTime LastExtInputTime = DateTime.Parse("1982-11-23");
public DateTime LastOutTime = DateTime.Parse("1982-11-23");
public Single[] PortAlignWaitSec = new float[] { 0, 0, 0, 0 };
public long[] PortAlignTime = new long[] { 0, 0, 0, 0 };
public byte UnloaderSeq = 0;
public DateTime UnloaderSeqTime;
public DateTime UnloaderSendtime = DateTime.Parse("1982-11-23");
/// <summary>
/// 로딩에 사용하는 포트번호 (자동 판단됨)
/// </summary>
public int LoadPortIndex = -1;
/// <summary>
/// 로딩시에 사용한 포트의 번호(이 값으로 수량기록 위치를 결정)
/// </summary>
public int LoadPickIndex = -1;
/// <summary>
/// 최종 할당된 언로딩 포트번호(1~8)
/// </summary>
public int UnloadPortNo = -1;
public byte LiveViewseq = 0;
public string AcceptBcd = string.Empty;
public DateTime AcceptBcdTime = DateTime.Now;
public string AcceptSid = string.Empty;
//작업정보
public eInspectResult Result; //작업결과가 저장됨
public eResult ResultCode;
public eECode ResultErrorCode;
public string ResultMessage;
public string LastSIDFrom = string.Empty;//101 = string.Empty;
public string LastSIDTo = string.Empty; // 103 = string.Empty;
//public string LastSID103_2 = string.Empty;
public string LastVName = string.Empty;
public int LastSIDCnt = 0;
public Dictionary<string, string> PrintPostionList = null;
//작업정보(시간)
public DateTime JobStartTime = DateTime.Parse("1982-11-23");
public DateTime JobEndTime = DateTime.Parse("1982-11-23");
public TimeSpan JobRunTime()
{
if (JobStartTime.Year == 1982) return new TimeSpan(0);
if (JobEndTime.Year == 1982) return DateTime.Now - JobStartTime;
else return JobEndTime - JobStartTime;
}
/// <summary>
/// RUN -> Pause(Wait Start)모드 전환시 저장할 모터의 위치값
/// 조그모드등으로 좌표를 옴길때의 기준 좌표
/// 이 좌표값에서 현재 모션값에 변화가 있으면 프로그램에서는 오류로 처리하게 됨
/// </summary>
public double[] PreventMotionPosition = new double[8];
#region "SetResultMessage"
public void SetResultMessage(eResult code, eECode err, eNextStep systempause, params object[] args)
{
var rltMsg = PUB.GetResultCodeMessage(code);
var codeMSg = $"[E{(int)err}] ";// + Util.GetResultCodeMessage(code);
if (err == eECode.MESSAGE_ERROR)
{
codeMSg = $"[{rltMsg} ERROR MESSAGE]\n";
}
else if (err == eECode.MESSAGE_INFO)
{
codeMSg = $"[{rltMsg} INFORMATION]\n";
}
var erMsg = PUB.GetErrorMessage(err, args);
var msg = codeMSg + erMsg;
this.ResultCode = code;
this.ResultErrorCode = err;
this.ResultMessage = msg;
if (systempause == eNextStep.PAUSENOMESAGE) this.ResultMessage = string.Empty; //210129
PUB.log.AddE(msg);
if (systempause == eNextStep.PAUSE) PUB.sm.SetNewStep(eSMStep.PAUSE);
else if (systempause == eNextStep.PAUSENOMESAGE) PUB.sm.SetNewStep(eSMStep.PAUSE);
else if (systempause == eNextStep.ERROR) PUB.sm.SetNewStep(eSMStep.ERROR);
}
public void SetResultTimeOutMessage(eDOName pinName, Boolean checkState, eNextStep systemPause)
{
var pindef = DIO.Pin[pinName];
if (checkState) SetResultMessage(eResult.SENSOR, eECode.DOON, systemPause, pindef.terminalno, pindef.name);
else SetResultMessage(eResult.SENSOR, eECode.DOOFF, systemPause, pindef.terminalno, pindef.name);
}
public void SetResultTimeOutMessage(eDIName pinName, Boolean checkState, eNextStep systemPause)
{
var pindef = DIO.Pin[pinName];
if (checkState) SetResultMessage(eResult.SENSOR, eECode.DION, systemPause, pindef.terminalno, pindef.name);
else SetResultMessage(eResult.SENSOR, eECode.DIOFF, systemPause, pindef.terminalno, pindef.name);
}
public void SetResultTimeOutMessage(eAxis motAxis, eECode ecode, eNextStep systemPause, string source, double targetpos, string message)
{
SetResultMessage(eResult.TIMEOUT, ecode, systemPause, motAxis, source, targetpos, message);
}
public void SetResultTimeOutMessage(eECode ecode, eNextStep systemPause, params object[] args)
{
SetResultMessage(eResult.TIMEOUT, ecode, systemPause, args);
}
#endregion
public DateTime[] diCheckTime = new DateTime[256];
public DateTime[] doCheckTime = new DateTime[256];
public Boolean isError { get; set; }
// public Boolean isMarkingMode { get; set; }
public int retry = 0;
public DateTime retryTime;
public DateTime[] WaitForVar = new DateTime[255];
public int JoystickAxisGroup = 0;
public int ABCount = 0;
public CResult()
{
mModel = new ModelInfoM();
vModel = new ModelInfoV();
SIDReference = new Class.CHistorySIDRef();
SIDHistory = new DataSet1.SIDHistoryDataTable();
BCDPattern = new List<Class.RegexPattern>();
BCDPrintPattern = new List<Class.RegexPattern>();
OUTHistory = new List<UIControl.CItem>();
this.Clear("Result ctor");
dsList = new DSList();
LoadListDB();
//230509
if(DTSidConvert != null) DTSidConvert.Dispose();
DTSidConvert = new DataSet1.Component_Reel_SID_ConvertDataTable();
DTSidConvertEmptyList = new List<string>();
DTSidConvertMultiList = new List<string>();
}
public void SaveListDB()
{
var finame = System.IO.Path.Combine(UTIL.CurrentPath, "Data", "SavaedList.xml");
var fi = new System.IO.FileInfo(finame);
if (fi.Directory.Exists == false) fi.Directory.Create();
this.dsList.WriteXml(fi.FullName);
PUB.log.Add("사전목록DB를 저장 했습니다" + fi.FullName);
}
public void LoadListDB()
{
var finame = System.IO.Path.Combine(UTIL.CurrentPath, "Data", "SavaedList.xml");
var fi = new System.IO.FileInfo(finame);
if (fi.Directory.Exists == false) fi.Directory.Create();
if (fi.Exists)
{
this.dsList.ReadXml(fi.FullName);
PUB.log.Add("사전목록DB를 불러왔습니다" + fi.FullName);
}
}
///// <summary>
///// 입력한 sid 가 원본에 존재하지 않으면 -1을 존재하면 입력된 수량을 반환합니다
///// </summary>
///// <param name="sid"></param>
///// <returns></returns>
//public int ExistSIDReferenceCheck(string sid)
//{
// var dr = PUB.Result.SIDReference.Items.Where(t => t.sid.EndsWith(sid)).FirstOrDefault();
// if (dr == null) return -1;
// else return dr.kpc;
//}
//public void ClearHistory()
//{
// //this.JObHistory.Clear();
// this.SIDReference.Clear();
// PUB.log.AddI("Clear History");
//}
public void ClearOutPort()
{
OUTHistory.Clear();
}
public void Clear(string Reason)
{
this.guid = Guid.NewGuid();
//프린트위치를 별도로 저장하고 있는다(나중에 추가 활용한다) 231005
if (PrintPostionList == null)
PrintPostionList = new Dictionary<string, string>();
else
PrintPostionList.Clear();
ItemDataL.Clear(Reason);
ItemDataC.Clear(Reason);
ItemDataR.Clear(Reason);
OverLoadCountF = 0;
OverLoadCountR = 0;
ClearOutPort();
LoadPortIndex = -1;
if (PUB.sm != null)
PUB.sm.seq.ClearTime();
isError = false;
ABCount = 0;
///기다림용 변수모듬
for (int i = 0; i < WaitForVar.Length; i++)
WaitForVar[i] = DateTime.Parse("1982-11-23");
//조그모드시 모션이동 감지용 저장 변수
for (int i = 0; i < 6; i++)
PreventMotionPosition[i] = 0.0;
//JobStartTime = DateTime.Parse("1982-11-23");
//JobEndTime = DateTime.Parse("1982-11-23");
//LastOutTime = DateTime.Parse("1982-11-23");
Result = eInspectResult.NOTSET;
ResultCode = eResult.NOERROR;
ResultMessage = string.Empty;
//시간정보값을 초기화함
for (int i = 0; i < 2; i++)
ClearTime(i);
PUB.log.Add("Result 데이터 초기화");
}
public void ClearTime(int shutIdx)
{
//JobStartTime = DateTime.Parse("1982-11-23");
//JobEndTime = DateTime.Parse("1982-11-23");
Result = eInspectResult.NOTSET;
ResultCode = eResult.NOERROR;
ResultMessage = string.Empty;
PUB.log.Add("Result(Clear Time)");
}
public Boolean isSetmModel
{
get
{
if (PUB.Result.mModel == null || PUB.Result.mModel.idx == -1 || PUB.Result.mModel.Title.isEmpty())
return false;
else return true;
}
}
public Boolean isSetvModel
{
get
{
if (PUB.Result.vModel == null || PUB.Result.vModel.idx == -1 || PUB.Result.vModel.Title.isEmpty())
return false;
else return true;
}
}
//public string getErrorMessage(eResult rlt, eECode err, params object[] args)
//{
// switch (err)
// {
// case eECode.RIDDUPL:
// return string.Format(
// "좌측 언로더에 사용되었던 REEL ID 입니다\n" +
// "바코드 오류 가능성이 있습니다\n" +
// "좌측 릴의 바코드를 확인하시기 바랍니다\n" +
// "작업을 계속할 수 없습니다. 취소 후 다시 시도하세요\n{0}", args);
// case eECode.RIDDUPR:
// return string.Format(
// "우측 언로더에 사용되었던 REEL ID 입니다\n" +
// "바코드 오류 가능성이 있습니다\n" +
// "우측 릴의 바코드를 확인하시기 바랍니다\n" +
// "작업을 계속할 수 없습니다. 취소 후 다시 시도하세요\n{0}", args);
// case eECode.BARCODEVALIDERR:
// return string.Format("바코드 데이터 검증 실패\n" +
// "인쇄전 데이터와 인쇄후 데이터가 일치하지 않습니다\n" +
// "ID(O) : {1}\n" +
// "ID(N) : {2}\n" +
// "SID : {5}->{6}\n" +
// "QTY : {3}->{4}\n" +
// "DATE : {7}->{8}\n" +
// "Index : {0}", args);
// case eECode.MOTX_SAFETY:
// return string.Format("PICKER-X 축이 안전위치에 없습니다\n1. 조그를 이용하여 중앙으로 이동 합니다\n2.홈 작업을 다시 실행합니다", args);
// case eECode.NOERROR:
// return string.Format("오류가 없습니다", args);
// case eECode.PORTOVERLOAD:
// return string.Format("PORT OVERLOAD\n위치 : {0}\n" +
// "너무 많은 양이 적재 되었습니다\n" + "상단 LIMIT 센서에 걸리지 않게 적재하세요", args);
// case eECode.EMERGENCY:
// return string.Format("비상정지 버튼을 확인하세요\n" +
// "버튼 : F{0}\n" +
// "메인전원이 OFF 된 경우에도 이 메세지가 표시 됩니다\n" +
// "메인전원은 모니터 하단 AIR버튼 좌측에 있습니다"
// , DIO.GetIOInput(eDIName.BUT_EMGF));
// case eECode.NOMODELM:
// return "모션모델이 선택되지 않았습니다\n" +
// "상단 메뉴 [모션모델]에서 사용할 모델을 선택하세요";
// case eECode.NOMODELV:
// return "작업모델이 선택되지 않았습니다\n" +
// "상단 메뉴 [작업모델]에서 사용할 모델을 선택하세요";
// case eECode.CARTERROR:
// return string.Format("언로더 카트가 없거나 크기 정보가 일치하지 않습니다\n좌측:{0}, 로더:{1}, 우측:{2}", args);
// case eECode.CARTL:
// return string.Format("왼쪽(UNLOAD) 포트에 카트가 감지되지 않습니다\n카트를 장착하세요\n카트크기 : {0}, 릴크기:{1}", args);
// case eECode.CARTC:
// return string.Format("중앙(LOAD) 포트에 카트가 감지되지 않습니다\n카트를 장착하세요\n카트크기 : {0}, 릴크기:{1}", args);
// case eECode.CARTR:
// return string.Format("오른쪽(UNLOAD) 포트에 카트가 감지되지 않습니다\n카트를 장착하세요\n카트크기 : {0}, 릴크기:{1}", args);
// case eECode.CARTLMATCH:
// return string.Format("왼쪽(UNLOAD) 카트와 피커의 릴 크기가 일치하지 않습니다\n카트크기를 확인 하세요\n카트크기 : {0}, 릴크기:{1}", args);
// case eECode.CARTCMATCH:
// return string.Format("중앙(LOAD) 카트와 피커의 릴 크기가 일치하지 않습니다\n카트크기를 확인 하세요\n카트크기 : {0}, 릴크기:{1}", args);
// case eECode.CARTRMATCH:
// return string.Format("오른쪽(UNLOAD) 카트와 피커의 릴 크기가 일치하지 않습니다\n카트크기를 확인 하세요\n카트크기 : {0}, 릴크기:{1}", args);
// case eECode.NOREELSIZE:
// return string.Format("왼쪽포트에 놓을 릴의 크기정보가 없습니다\n프로그램 오류입니다\n개발자에게 해당 메세지를 전달하세요\n" +
// "장치 초기화를 진행 한 후 다시 시도하세요");
// case eECode.VISION_NOCONN:
// return string.Format("카메라({0}) 연결 안됨", args);
// case eECode.INCOMPLETE_LOADERDATA:
// return string.Format("로더 바코드 필수값을 읽지 못했습니다", args);
// case eECode.CAM_NOBARCODEU:
// return string.Format("언로더({0}) 바코드를 읽지 못했습니다", args);
// case eECode.HOME_TIMEOUT:
// return string.Format("홈 진행이 완료되지 않고 있습니다\n" +
// "오류가 발생했다면 '홈' 작업을 다시 진행하세요\n" +
// "대기시간 : {0}초", args);
// case eECode.DOORSAFTY:
// return string.Format("포트 안전센서가 감지 되었습니다\n" +
// "안전센서를 확인한 후 다시 시도하세요\n", args);
// case eECode.AIRNOOUT:
// return "AIR 공급이 차단 되어 있습니다.\n" +
// "전면의 AIR 버튼을 누르세요\n" +
// "공급이 되지 않으면 메인 전원 을 확인하세요\n" +
// "메인 전원은 AIR 버튼 좌측에 있습니다" +
// "메인 전원 공급 실패시 장비 후면의 차단기를 확인하세요";
// case eECode.DOOFF:
// var pinoOf = (eDOName)args[0];
// return string.Format("출력이 OFF 되지 않았습니다.\n" +
// "포트설명 : {0}\n" +
// "포트번호 : {1} ({2})", DIO.getPinDescription(pinoOf), (int)pinoOf, Enum.GetName(typeof(eDOPin), pinoOf));
// case eECode.DOON:
// var pinoOn = (eDOName)args[0];
// return string.Format("출력이 ON 되지 않았습니다.\n" +
// "포트설명 : {0}\n" +
// "포트번호 : {1} ({2})", DIO.getPinDescription(pinoOn), (int)pinoOn, Enum.GetName(typeof(eDOPin), pinoOn));
// case eECode.DIOFF:
// var piniOf = (eDIName)args[0];
// return string.Format("입력이 OFF 되지 않았습니다.\n" +
// "포트설명 : {0}\n" +
// "포트번호 : {1} ({2})", DIO.getPinDescription(piniOf), (int)piniOf, Enum.GetName(typeof(eDIPin), piniOf));
// case eECode.DION:
// var piniOn = (eDIName)args[0];
// return string.Format("입력이 ON 되지 않았습니다.\n" +
// "포트설명 : {0}\n" +
// "포트번호 : {1} ({2})", DIO.getPinDescription(piniOn), (int)piniOn, Enum.GetName(typeof(eDIPin), piniOn));
// case eECode.AZJINIT:
// return string.Format("DIO 혹은 모션카드가 초기화 되지 않았습니다.\n" +
// "DIO : {0}\n" +
// "MOTION : {1}\n" +
// "해당 카드는 본체 내부 PCI 슬롯에 장착 된 장비 입니다\n" +
// "EzConfig AXT 프로그램으로 카드 상태를 확인하세요",
// PUB.dio.IsInit, PUB.mot.IsInit);
// case eECode.MOT_HSET:
// var msg = "모션의 HOME 검색이 완료되지 않았습니다";
// for (int i = 0; i < 6; i++)
// {
// if (PUB.mot.IsUse(i) == false) continue;
// var axis = (eAxis)i;
// var stat = PUB.mot.IsHomeSet(i);
// if (stat == false) msg += string.Format("\n[{0}] {1} : {2}", i, axis, stat);
// }
// msg += "\n장치 초기화를 실행하세요";
// return msg;
// case eECode.MOT_SVOFF:
// var msgsv = "모션 중 SERVO-OFF 된 축이 있습니다";
// for (int i = 0; i < 6; i++)
// {
// if (PUB.mot.IsUse(i) == false) continue;
// var axis = (eAxis)i;
// var stat = PUB.mot.IsServOn(i);
// if (stat == false) msgsv += string.Format("\n[{0}] {1} : {2}", i, axis, stat);
// }
// msgsv += "\nRESET을 누른 후 '모션설정' 화면에서 확인합니다";
// return msgsv;
// case eECode.MOT_HSEARCH:
// return string.Format("모션의 홈 검색이 실패되었습니다\n" +
// "축 : {0}\n" +
// "메세지 : {1}", args);
// case eECode.MOT_CMD:
// var axisNo = (int)((eAxis)args[0]);
// var axisSrc = args[1].ToString();
// return string.Format("모션축 명령이 실패 되었습니다\n축 : {0}\n" +
// "현재위치 : {2}\n" +
// "명령위치 : {3}\n" +
// "소스 : {1}", axisNo, axisSrc, PUB.mot.GetActPos(axisNo), PUB.mot.GetActPos(axisNo));
// //case eECode.timeout_step:
// // return string.Format("스텝당 최대 실행 시간이 초과 되었습니다.\n" +
// // "스텝 : {0}\n" +
// // "최대동작시간 : " + COMM.SETTING.Data.Timeout_StepMaxTime.ToString(), args);
// case eECode.USER_STOP:
// return "'일시정지' 버튼 눌림\n" +
// "사용자에 의해 작동이 중지 되었습니다\n" +
// "'RESET' -> 'START'로 작업을 계속할 수 있습니다";
// case eECode.CAM_RIGHT:
// return "우측카메라가 사용가능한 상태가 아닙니다.\n" +
// "신규 실행시에는 초기화 완료까지 기다려 주세요";
// case eECode.CAM_LEFT:
// return "좌측카메라가 사용가능한 상태가 아닙니다.\n" +
// "신규 실행시에는 초기화 완료까지 기다려 주세요";
// default:
// return err.ToString();
// }
//}
//public string getResultCodeMessage(eResult rltCode)
//{
// //별도 메세지처리없이 그대로 노출한다
// return rltCode.ToString().ToUpper();
//}
}
}

View File

@@ -0,0 +1,459 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AR;
namespace Project.Commands
{
public class CommandBuffer
{
public int Idx { get; set; }
private int REGISTER_VALUE = 0;
private Boolean REGISTER_TRUE = false;
private Boolean REGISTER_FALSE = false;
private Boolean REGISTER_EQUAL = false;
private Boolean REGISTER_ABOVE = false;
private Boolean REGISTER_BELOW = false;
/// <summary>
/// 순차실행명령
/// </summary>
public List<Command> Commands;
/// <summary>
/// 상시실행명령
/// </summary>
public List<Command> SPS;
public CommandBuffer()
{
Commands = new List<Command>();
SPS = new List<Command>();
}
public void AddSeq(Command cmd)
{
cmd.Idx = this.Commands.Count;
this.Commands.Add(cmd);
}
public void AddSPS(Command cmd)
{
cmd.Idx = this.SPS.Count;
this.SPS.Add(cmd);
}
public void Clear()
{
Commands.Clear();
SPS.Clear();
Idx = 0;
}
public StepResult Run()
{
//sps는 모두 실행한다
StepResult rlt;
foreach (var sps in this.SPS)
{
rlt = RunCode(sps);
if (rlt == StepResult.Wait) return StepResult.Wait; //SPS에서 대기 코드가 있다
else if (rlt == StepResult.Error) return StepResult.Error;
}
//sequece 는 현재 것만 실행한다.
if (Idx < 0) Idx = 0;
var cmd = this.Commands[Idx];
rlt = RunCode(cmd);
if (rlt == StepResult.Complete) //이 명령이 완료되면 다음으로 진행한다
{
Idx += 1;
if (Idx >= this.Commands.Count) return StepResult.Complete;
else return StepResult.Wait;
}
return rlt;
}
private StepResult RunCode(Command cmd)
{
switch (cmd.type)
{
case CType.NOP: return StepResult.Complete;
case CType.Wait:
var data0 = cmd.Data as CDWait;
if (data0.Trigger == false)
{
//아직 시작을 안했으니 시작시키고 대기한다
data0.SetTrigger(true);
return StepResult.Wait;
}
else
{
//아직 시간을 다 쓰지 않았다면 넘어간다
if (data0.TimeOver == false) return StepResult.Wait;
}
break;
case CType.Output:
var data1 = cmd.Data as CDOutput;
if (data1.PinIndex < 0) return StepResult.Error;
if (DIO.SetOutput((eDOName)data1.Pin, data1.Value) == false) return StepResult.Error;
break;
case CType.Move:
var data2 = cmd.Data as CDMove;
MOT.Move((eAxis)data2.Axis, data2.Position, data2.Speed, data2.Acc, data2.Relative);
break;
case CType.MoveForece:
var data3 = cmd.Data as CDMove;
MOT.Move((eAxis)data3.Axis, data3.Position, data3.Speed, data3.Acc, data3.Relative, false, false);
break;
case CType.MoveWait:
var data4 = cmd.Data as CDMove;
var axis = (eAxis)data4.Axis;
var mrlt = MOT.CheckMotionPos(axis, new TimeSpan(1), data4.Position, data4.Speed, data4.Acc, data4.Dcc, cmd.description);
if (mrlt == false) return StepResult.Wait;
break;
case CType.GetFlag:
var data5 = cmd.Data as CDFlag;
data5.Value = PUB.flag.get(data5.Flag);
REGISTER_FALSE = data5.Value == false;
REGISTER_TRUE = data5.Value == true;
break;
case CType.SetFlag:
var data6 = cmd.Data as CDFlag;
PUB.flag.set(data6.Flag, data6.Value, cmd.description);
break;
case CType.True:
var data7 = cmd.Data as CDCommand;
if (REGISTER_TRUE) return RunCode(data7.Command);
break;
case CType.False:
var data8 = cmd.Data as CDCommand;
if (REGISTER_FALSE) return RunCode(data8.Command);
break;
case CType.GetVar: //공용변수의값
var data10 = cmd.Data as CDGetVar;
if (data10.Key == "STEPTIME")
{
data10.Confirm = true;
data10.Value = (int)PUB.sm.StepRunTime.TotalMilliseconds;
}
break;
case CType.GetSetVar: //공용변수(설정)의 값
var data11 = cmd.Data as CDGetVar;
if (data11.Key == "TIMEOUT_HOMEFULL")
{
data11.Confirm = true;
data11.Value = 60;// (int)Pub.sm.StepRunTime.TotalMilliseconds;
}
break;
case CType.Compare:
var data9 = cmd.Data as CDCompare<int>;
if (data9 != null)
{
RunCode(data9.Source); //비교값(좌)
RunCode(data9.Target); //비교값(우)
var valS = data9.Source.Data as ICommandValue;
var valT = data9.Target.Data as ICommandValue;
int ValueS = (int)valS.Value;
int ValueT = (int)valT.Value;
REGISTER_ABOVE = ValueS > ValueT;
REGISTER_BELOW = ValueS < ValueT;
REGISTER_EQUAL = ValueS == ValueT;
REGISTER_TRUE = ValueS == ValueT;
REGISTER_FALSE = ValueS != ValueT;
REGISTER_VALUE = ValueS - ValueT;
}
else return StepResult.Error;
break;
case CType.SetError:
var data12 = cmd.Data as CDError;
PUB.Result.SetResultMessage(data12.ResultCode, data12.ErrorCode, data12.NextStep);
break;
}
return StepResult.Complete;
}
}
public enum CType
{
NOP = 0,
/// <summary>
/// motion move
/// </summary>
Move,
MoveForece,
/// <summary>
/// move and wait
/// </summary>
MoveWait,
/// <summary>
/// set digital output
/// </summary>
Output,
Log,
StepChange,
/// <summary>
/// check digital input
/// </summary>
InputCheck,
/// <summary>
/// check digital output
/// </summary>
OutputCheck,
GetFlag,
SetFlag,
Equal,
NotEqual,
True,
False,
Zero,
NonZero,
SetError,
Compare,
SetVar,
GetVar,
GetSetVar,
Above,
Below,
Wait,
Run,
}
public class Command
{
public CType type { get; set; } = CType.NOP;
public int Idx { get; set; }
public string description { get; set; }
public ICommandData Data { get; set; }
public Command(CType type, string desc = "")
{
this.type = type;
this.description = desc;
}
}
public interface ICommandData
{
// string Description { get; set; }
}
public interface ICommandValue
{
object Value { get; set; }
}
public class CDGetVar : ICommandData, ICommandValue
{
public string Key { get; set; }
public object Value { get; set; }
public Boolean Confirm { get; set; }
public CDGetVar(string key)
{
this.Key = key;
}
}
public class CDGetSetVar : ICommandData, ICommandValue
{
public string Key { get; set; }
public object Value { get; set; }
public Boolean Confirm { get; set; }
public CDGetSetVar(string key)
{
this.Key = key;
}
}
public class CDSetVar : ICommandData
{
public string Key { get; set; }
public int Value { get; set; }
public CDSetVar(string key, int value)
{
this.Key = key;
this.Value = Value;
}
}
public class CDFlag : ICommandData
{
public eVarBool Flag { get; set; }
public Boolean Value { get; set; }
public CDFlag(eVarBool flag)
{
this.Flag = flag;
Value = false;
}
}
public class CDSetValI : ICommandData
{
public int Value { get; set; }
public CDSetValI(int idx, int value)
{
this.Value = value;
}
}
public class CDSetValB : ICommandData
{
public bool Value { get; set; }
public CDSetValB(int idx, bool value)
{
this.Value = value;
}
}
public class CDCommand : ICommandData
{
public Command Command { get; set; }
public CDCommand(Command command)
{
this.Command = command;
}
}
public class CDError : ICommandData
{
public eResult ResultCode { get; set; }
public eECode ErrorCode { get; set; }
public eNextStep NextStep { get; set; }
public CDError(eResult resultCode, eECode errorCode, eNextStep nextStep)
{
ResultCode = resultCode;
ErrorCode = errorCode;
NextStep = nextStep;
}
}
//public class CDCompare<T> : ICommandData
//{
// public T Value { get; set; }
// public CDCompare(T value)
// {
// Value = value;
// }
// public CDCompare(Command source, Command target)
// {
// Value = value;
// }
//}
public class CDCompare<T> : ICommandData
{
public Command Source { get; set; }
public Command Target { get; set; }
public CDCompare(Command source, Command target)
{
Source = source;
Target = target;
}
}
public class CDWait : ICommandData
{
public int WaitMS { get; set; }
public DateTime StartTime { get; set; }
public Boolean Trigger { get; set; }
private TimeSpan GetTime { get { return DateTime.Now - StartTime; } }
public Boolean TimeOver { get { return GetTime.TotalMilliseconds > WaitMS; } }
public void SetTrigger(Boolean value)
{
Trigger = value;
StartTime = DateTime.Now;
}
public CDWait() : this(100) { }
public CDWait(int ms)
{
this.WaitMS = ms;
}
}
public class CDMove : ICommandData
{
public int Axis { get; set; }
public double Position { get; set; }
public double Speed { get; set; }
public double Acc { get; set; }
public double Dcc { get; set; }
public Boolean Relative { get; set; }
// public string Description { get; set; }
public CDMove(eAxis axis, double pos, double speed) : this((int)axis, pos, speed, 0) { }
public CDMove(int axis, double pos, double speed, double acc, double dcc = 0, Boolean relatvie = false)
{
Axis = axis;
Position = pos;
Speed = speed;
Acc = acc;
Dcc = dcc == 0 ? acc : dcc;
Relative = relatvie;
}
}
public class CDOutput : ICommandData
{
public eDOName Pin { get; set; }
public int PinIndex { get; set; }
public Boolean Value { get; set; }
// public string Description { get; set; }
//public CDOutput(eDOName pin) : this(pin, false) { }
public CDOutput(eDOName pin, Boolean value)
{
Pin = pin;
PinIndex = (int)pin;
Value = value;
}
public CDOutput(int point, Boolean value)
{
Pin = (eDOName)point;
PinIndex = point;
Value = value;
}
}
public class CDRun : ICommandData
{
public Action Target { get; set; }
public CDRun(Action target)
{
Target = target;
}
}
public class CDRunRet<T> : ICommandData
{
public Func<T> Target { get; set; }
public CDRunRet(Func<T> target)
{
Target = target;
}
}
public class CDLog : ICommandData
{
public string Message { get; set; }
public Boolean IsError { get; set; }
public CDLog(string message, Boolean err = false)
{
Message = message;
IsError = err;
}
}
public class CDStep : ICommandData
{
public eSMStep Step { get; set; }
public Boolean Force { get; set; }
public CDStep(eSMStep step, Boolean force = false)
{
Step = step;
Force = force;
}
}
}

View File

@@ -0,0 +1,390 @@
using Project;
using Project.Device;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Net;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
/// <summary>
/// ============================================================================
/// 장비기술 상태 모니터링 관련 클래스
/// 이 클래스는 SQLfiletoDB 프로그램과 같이 사용하는 것을 권장합니다.
/// 현재 실행 중인 프로그램의 하위 폴더 Status 에 입력된 상태값을 SQL 파일로 기록합니다.
/// SQLfiletoDB는 SQL파일을 실제 DB에 기록하는 프로그램입니다.
/// ============================================================================
/// 작성자 : chi
/// 작성일 : 202-06-15
/// GIT : (none)
/// </summary>
public static partial class EEMStatus
{
static System.Threading.ManualResetEvent mre = new System.Threading.ManualResetEvent(true);
static string ip = string.Empty;
static string mac = string.Empty;
static DateTime StatusChecktime = DateTime.Now;
static DateTime MonitorChecktime = DateTime.Now.AddYears(-1);
static DateTime FileCheckTime = DateTime.Now;
static string monitorfile = string.Empty;
/// <summary>
/// UpdateStatusSQL 명령이 동작하는 간격이며 기본 180초(=3분)로 되어 있습니다.
/// </summary>
public static int UpdateStatusInterval { get; set; } = 180;
public static int UpdateFileInterval { get; set; } = 3;
static bool queryok = false;
static bool UpdateRun = false;
public static string IP
{
get
{
if (queryok == false) GetNetworkInfo();
return ip;
}
set { ip = value; }
}
public static string MAC
{
get
{
if (queryok == false) GetNetworkInfo();
return mac;
}
set
{
mac = value;
}
}
/// <summary>
/// 현재 시스템의 IP/MAC정보를 취득합니다.
/// </summary>
static void GetNetworkInfo()
{
ip = "";
mac = "";
// string prgmName = Application.ProductName;
var nif = NetworkInterface.GetAllNetworkInterfaces();
var host = Dns.GetHostEntry(Dns.GetHostName());
string fullname = System.Net.Dns.GetHostEntry("").HostName;
foreach (IPAddress r in host.AddressList)
{
string str = r.ToString();
if (str != "" && str.Substring(0, 3) == "10.")
{
ip = str;
break;
}
}
string rtn = string.Empty;
ObjectQuery oq = new System.Management.ObjectQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled='TRUE'");
ManagementObjectSearcher query1 = new ManagementObjectSearcher(oq);
foreach (ManagementObject mo in query1.Get())
{
string[] address = (string[])mo["IPAddress"];
if (address[0] == ip && mo["MACAddress"] != null)
{
mac = mo["MACAddress"].ToString();
break;
}
}
queryok = true;
}
public static void UpdateStatusSQL(eSMStep status, bool _extrun = false, string remark = "")
{
var tsrun = DateTime.Now - StatusChecktime;
if (tsrun.TotalSeconds >= UpdateStatusInterval)
{
AddStatusSQL(status, "UPDATE", extrun: _extrun);
StatusChecktime = DateTime.Now;
}
//내부실행모드일때에만 파일을 처리한다
if (_extrun == false)
{
var tsfile = DateTime.Now - FileCheckTime;
if (tsfile.TotalSeconds >= UpdateFileInterval)
{
if (UpdateRun == false)
{
UpdateRun = true;
Task.Run(() =>
{
UpdateFileToDB();
UpdateRun = false;
});
}
FileCheckTime = DateTime.Now;
}
}
}
/// <summary>
/// 상태모니터링 프로그램의 실행파일 명
/// </summary>
static string StatusMonitorFile
{
get
{
if (string.IsNullOrEmpty(monitorfile))
monitorfile = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Status", "SQLFileToDB.exe");
return monitorfile;
}
}
static System.Diagnostics.Process CheckMonitor()
{
if (System.IO.File.Exists(StatusMonitorFile) == false) return null;
var prcs = System.Diagnostics.Process.GetProcesses();
return prcs.Where(t => t.ProcessName.ToLower().StartsWith("sqlfiletodb")).FirstOrDefault();
}
public static bool RunStatusMonitor()
{
//파일이 없으면 실행 불가
if (System.IO.File.Exists(StatusMonitorFile) == false) return false;
//실행프로세스 검사
var prc = CheckMonitor();
if (prc == null)
{
try
{
prc = new System.Diagnostics.Process();
prc.StartInfo = new System.Diagnostics.ProcessStartInfo
{
Arguments = string.Empty,
FileName = StatusMonitorFile,
};
prc.Start();
}
catch
{
return false;
}
}
return true;
}
/// <summary>
/// 작업수량을 입력합니다
/// </summary>
/// <param name="cnt"></param>
/// <returns></returns>
public static string AddStatusCount(int cnt, string remark = "")
{
if (remark.isEmpty()) remark = $"Count Set : {cnt}";
return AddStatusSQL(PUB.sm.Step, remark, count: cnt);
}
/// <summary>
/// 상태메세지를 status 폴더에 기록합니다.
/// </summary>
/// <param name="status">상태머신의 상태값</param>
/// <param name="remark">비고</param>
/// <param name="wdate">기록일시</param>
/// <returns>오류발생시 오류메세지가 반환 됩니다</returns>
public static string AddStatusSQL(eSMStep status, string remark = "", DateTime? wdate = null, bool extrun = false, int? count = null)
{
if (queryok == false || MAC.isEmpty()) GetNetworkInfo();
if (status == eSMStep.CLOSEWAIT || status == eSMStep.CLOSED) return string.Empty;
if (extrun)
{
//상태모니터링 프로그램을 실행합니다.
var tsMon = DateTime.Now - MonitorChecktime;
if (tsMon.TotalMinutes > 5) RunStatusMonitor();
}
try
{
var state = 0;
string cntstr = "null";
if (count != null) cntstr = count.ToString();
var alarmid = string.Empty;
var alarmmsg = string.Empty;
if (string.IsNullOrEmpty(remark)) remark = $"STS:{status}";
if (status == eSMStep.RUN) state = 1;
else if (status == eSMStep.ERROR || status == eSMStep.EMERGENCY)
{
state = 2;
alarmid = PUB.Result.ResultErrorCode.ToString();
alarmmsg = PUB.Result.ResultMessage;
}
else if (status == eSMStep.PAUSE) //일시중지도 오류코드가 포함된다,
{
if (PUB.Result.ResultErrorCode == eECode.USER_STEP || PUB.Result.ResultErrorCode == eECode.USER_STOP || PUB.Result.ResultErrorCode.ToString().StartsWith("MESSAGE"))
{
//사용자에의해 멈추는 것은 오류코드를 넣지 않는다.
}
else
{
alarmid = PUB.Result.ResultErrorCode.ToString();
alarmmsg = PUB.Result.ResultMessage;
}
}
else if (status == eSMStep.INIT) state = 3; //시작
else if (status == eSMStep.CLOSING) state = 4; //종료
//length check
if (alarmid.Length > 10) alarmid = alarmid.Substring(0, 10);
if (remark.Length > 99) remark = remark.Substring(0, 99);
if (alarmmsg.Length > 250) alarmmsg = alarmmsg.Substring(0, 50);
var mcid = AR.SETTING.Data.MCID;// Project.PUB.setting.MCID;//.Data.MCID;
//var mcid = Project.PUB.setting.MCID;//.Data.MCID;
var path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Status");
var file = System.IO.Path.Combine(path, $"{DateTime.Now.ToString("HHmmssfff")}_{status}.sql");
var sql = "insert into MCMonitor_Rawdata(Model,status,remark,ip,mac,time,alarmid,alarmmsg,count,version) " +
" values('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}',{8},'{9}')";
var timestr = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
if (wdate != null) timestr = ((DateTime)wdate).ToString("yyyy-MM-dd HH:mm:ss");
var VersionNumber = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
sql = string.Format(sql, mcid, state, remark.Replace("'", "''"), IP, MAC, timestr, alarmid, alarmmsg, cntstr, VersionNumber);
System.IO.File.WriteAllText(file, sql, System.Text.Encoding.Default);
////만들어진지 3분이 지난 파일은 삭제한다.
//var di = new System.IO.DirectoryInfo(path);
//var fi = di.GetFiles("*.sql", System.IO.SearchOption.TopDirectoryOnly).Where(t => t.LastWriteTime < DateTime.Now.AddMinutes(-3)).FirstOrDefault();
//if (fi != null) fi.Delete();
if (state == 4) UpdateFileToDB();
return string.Empty;
}
catch (Exception ex)
{
return ex.Message;
}
}
static void UpdateFileToDB()
{
if (mre.WaitOne(1000) == false) return;
mre.Reset();
var cs = "Data Source=10.131.15.18;Initial Catalog=EE;Persist Security Info=True;User ID=eeuser;Password=Amkor123!";
var path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Status");
var di = new System.IO.DirectoryInfo(path);
if (di.Exists == false) return;
var file = di.GetFiles("*.sql", System.IO.SearchOption.TopDirectoryOnly)
.Where(t => t.LastWriteTime < DateTime.Now.AddSeconds(-3))
.OrderByDescending(t => t.LastWriteTime).FirstOrDefault();
if (file == null)
{
mre.Set();
return;
}
//파일을 찾아야한다
// PUB.log.Add($">> {file.FullName}");
try
{
var sql = System.IO.File.ReadAllText(file.FullName, System.Text.Encoding.Default);
if (string.IsNullOrEmpty(sql))
{
//비어잇다면
var errpath = System.IO.Path.Combine(di.FullName, "Error");
var errfile = System.IO.Path.Combine(errpath, file.Name);
if (System.IO.Directory.Exists(errpath) == false) System.IO.Directory.CreateDirectory(errpath);
System.IO.File.Move(file.FullName, errfile);// file.MoveTo(errfile);
// ecnt += 1;
}
else
{
// var csstr = PUB.setting.ConnectionString;
// if (string.IsNullOrEmpty(csstr)) csstr = "Data Source=10.131.15.18;Initial Catalog=EE;Persist Security Info=True;User ID=eeuser;Password=Amkor123!";
var cn = new System.Data.SqlClient.SqlConnection(cs);
var cmd = new System.Data.SqlClient.SqlCommand(sql, cn);
cn.Open();
var cnt = cmd.ExecuteNonQuery();
//if (cnt == 0) PUB.log.Add($"Result Empty : {sql}");
cn.Close();
cnt += 1;
var errpath = System.IO.Path.Combine(di.FullName, "Complete");
var errfile = System.IO.Path.Combine(errpath, file.Name);
if (System.IO.Directory.Exists(errpath) == false) System.IO.Directory.CreateDirectory(errpath);
//file.MoveTo(errfile);
System.IO.File.Move(file.FullName, errfile);
}
}
catch (Exception ex)
{
if(ex.Message.Contains("deadlocked") == false)
{
var errpath = System.IO.Path.Combine(di.FullName, "Error");
var errfile = System.IO.Path.Combine(errpath, file.Name);
if (System.IO.Directory.Exists(errpath) == false) System.IO.Directory.CreateDirectory(errpath);
try
{
//file.MoveTo(errfile);
System.IO.File.Move(file.FullName, errfile);
//오류내용도 저장한다..
var errfilename = errfile + "_error.txt";
System.IO.File.WriteAllText(errfilename, ex.Message, System.Text.Encoding.Default);
}
catch (Exception ex2)
{
}
}
else
{
Console.WriteLine("dead lock 오류는 무시한다");
}
//ecnt += 1;
}
//try
//{
// //생성된지 10일이 넘은 자료는 삭제한다.
// //시간소비를 피해서 1개의 파일만 작업한다
// //var sqlfiles = di.GetFiles("*.sql", System.IO.SearchOption.AllDirectories);
// //총3번의 데이터를 처리한다
// //var files = sqlfiles.Where(t => t.LastWriteTime < DateTime.Now.AddDays(-10)).Select(t => t.FullName);
// //int i = 0;
// //var dellist = files.TakeWhile(t => i++ < 3);
// //foreach (var delfile in dellist)
// //System.IO.File.Delete(delfile);
//}
//catch
//{
//}
mre.Set();
}
}
/*
=================================================
변경내역
=================================================
230619 chi UpdateFileToDB 에서 폴더가 없다면 return 하도록 함
230615 chi UpdateFiletoDB의 ManualResetEvent적용
Version 항목 추가
230612 chi 프로그램 시작/종료 alarmid항목 추가
완료된 파일 10일간 보존하도록 함
230522 chi extrun 모드 추가(agv용 - SQL파일을 외부 프로그램에서 처리하도록 함)
230617 chi 파일쓰기함수를 Task 로 처리
3분지난데이터 삭제기능 제거
230516 chi initial commit
*/

View File

@@ -0,0 +1,692 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace Project
{
public enum StepResult
{
Wait = 0,
Complete,
Error,
}
public enum eWorkPort
{
Left = 0,
Right
}
public enum eNormalResult
{
True = 0,
False,
Error,
}
public enum eSMStep : byte
{
NOTSET = 0,
INIT = 1,
IDLE = 10,
RUN = 50,
RUN_ROOT_SEQUENCE_L,
RUN_ROOT_SEQUENCE_R,
RUN_KEYENCE_READ_L,
RUN_KEYENCE_READ_R,
RUN_PICKER_ON_L,
RUN_PICKER_ON_R,
RUN_PICKER_OFF_L,
RUN_PICKER_OFF_R,
RUN_PRINTER_F,
RUN_PRINTER_R,
RUN_PRINTER_ON_F,
RUN_PRINTER_ON_R,
RUN_PRINTER_OFF_F,
RUN_PRINTER_OFF_R,
RUN_QRVALID_F,
RUN_QRVALID_R,
RUN_COM_PT0,
RUN_COM_PT1,
RUN_COM_PT2,
RUN_PICK_RETRY,
//이후에 사용자 런 코드용 스텝을 추가한다.
EMERGENCY = 200,
HOME_FULL = 201,
HOME_DELAY,
HOME_CONFIRM,
HOME_QUICK,
CLOSING = 250,
CLOSEWAIT = 251,
CLOSED = 252,
//사용자영역
FINISH = 100,
PAUSE,
WAITSTART,
ERROR,
SAFTY,
CLEAR,
}
public enum eWaitMessage
{
PX = 0,
PZ,
LMOVE,
LUPDN,
RMOVE,
RUPDN,
LPRINT,
RPRINT,
VIS0,
VIS1,
VIS2,
}
//public enum eJobResult
//{
// None = 0,
// Error,
// ErrorOut,
// MaxCount,
// NotExistSID,
// DisableUnloader,
// MatchFail,
// NoBarcode
//}
public enum eCartSize
{
None = 0,
Inch7 = 7,
Inch13 = 13
}
public enum ePrintPutPos
{
None = 0,
Top,
Middle,
Bottom,
}
public enum ePrintVac
{
inhalation = 0,
exhaust,
off,
}
public enum eJobType : byte
{
Sorter = 0,
Dryrun,
}
public enum eHeaderHandler
{
Ping = 0,
RequestData,
RequstSeqNo,
RequstInputReel,
JobEnd,
JobDelete,
}
public struct sVisionDMResult
{
public Boolean iSystemErr { get; set; }
public Boolean isError { get; set; }
public string DM { get; set; }
public System.Drawing.Rectangle ROS { get; set; }
public System.Drawing.PointF DMCenter { get; set; }
public List<System.Drawing.PointF> DMCorner { get; set; }
public string DMMessage { get; set; }
}
public struct sObjectDetectResult
{
public string Message { get; set; }
public List<System.Drawing.Rectangle> Rect { get; set; }
public List<uint> Areas { get; set; }
public Boolean OK
{
get
{
if (Areas == null || Areas.Count < 1) return false;
else return true;
}
}
}
public enum eGridValue
{
/// <summary>
/// 아직 처리 전(기본 초기화된 상태)
/// </summary>
NotSet = 0,
/// <summary>
/// 원점검사에서 오류 발생
/// </summary>
OrientError,
/// <summary>
/// 아이템검출에서 실패됨
/// </summary>
NoItem,
/// <summary>
/// 아이템검출성공, 데이터매트릭스 검출 실패
/// </summary>
NewItem,
/// <summary>
/// 데이터매트릭스 읽기 실패
/// </summary>
DMReadError,
/// <summary>
/// 데이터매트릭스 관리 횟수가 기준횟수(10) 미만 (아직 정상)
/// </summary>
DMNotmalCount,
/// <summary>
/// 데이터매트릭스 관리 횟수가 기준횟수(10)를 초과한 경우
/// </summary>
DMOverCount,
}
public enum eRoiSeq
{
Area = 0,
DataMatrix,
Orient,
DetectUnit,
DetectDM
}
public enum eWaitType : byte
{
TryLock = 0,
TryUnLock,
AirBlowOn,
AirBlowOff,
AirBlowDustOn,
AirBlowDustOff,
PrintPickLOff,
PrintPickLOn,
PrintPickROff,
PrintPickROn,
PickOff,
PickOn,
AirBlowCoverDn,
AirBlowCoverUp,
UnloaderUp,
UnloaderDn,
LiftUp,
LiftDn,
}
public enum eSensorState : byte
{
Off = 0,
On = 1,
InComplete = 2,
}
public enum eIOCheckResult
{
Wait = 0,
Complete,
Timeout
}
public enum ePort
{
Left = 0,
Right,
}
enum eResultStringType
{
Nomal = 0,
Attention,
Error,
}
public enum eMotDir
{
Stop = 0,
CW = 1,
CCW = 2
}
/// <summary>
/// RUN중일 때 사용되는 세부 시퀀스
/// </summary>
public enum eRunStep : byte
{
NOTSET = 0,
/// <summary>
/// 프로그램 체크
/// </summary>
STARTCHKSW,
/// <summary>
/// 하드웨어 체크
/// </summary>
STARTCHKHW,
/// <summary>
/// 기계장치를 작업 시작 전 상태로 이동합니다
/// </summary>
INITIALHW,
/// <summary>
/// 안전지대(비활성화된경우 발생)
/// </summary>
SAFTYZONE_GO,
SAFTYZONE_RDY,
BEGINLOAD,
/// <summary>
/// 트레이를 로딩하기 위한 로더 이동 및 트레이 추출
/// </summary>
PORTLOAD,
/// <summary>
/// 비젼촬영을위한 위치로 이동
/// </summary>
BEGINPICK,
ENDPICK,
OVERLOAD,
SAVEDATA,
/// <summary>
/// 모션 원위치
/// </summary>
BARCODE,
/// <summary>
/// AIR/BLOW 위치 이동 및 작업
/// </summary>
AIRBLOW,
REELOUT,
TRAYOUT,
/// <summary>
/// 언로드위치로 셔틀을 이동
/// </summary>
BEGINUNLOADER,
/// <summary>
/// 트레이 언로드 작업
/// </summary>
TRAYUNLOAD,
/// <summary>
/// 언로딩하고 다시 로딩존으로 이동하는 시퀀스
/// </summary>
MOVE_TO_LOAD,
}
public enum ePLCIPin : byte
{
X00, X01, X02, X03, X04, X05, X06, X07, X08, X09, X0A,
X10, X11, X12, X13, X14, X15, X16, X17, X18, X19, X1A
}
public enum ePLCOPin : byte
{
Y00, Y01, Y02, Y03, Y04, Y05, Y06, Y07, Y08, Y09, Y0A,
Y10, Y11, Y12, Y13, Y14, Y15, Y16, Y17, Y18, Y19, Y1A
}
public enum ePLCITitle : byte
{
Run, Cart_Status_01, Cart_Status_02, Cart_Status_03, Cart_Status_04,
Machine_Confirm = 19
}
public enum ePLCOTitle : byte
{
Cart_No_Setting = 0,
Handler_Confirm = 19,
}
public enum eResult : byte
{
NOERROR,
EMERGENCY,
SAFTY,
DEVELOP,
SETUP,
HARDWARE,
SENSOR,
MOTION,
OPERATION,
COMMUNICATION,
TIMEOUT,
UNLOADER,
}
public enum eECode : byte
{
NOTSET = 0,
EMERGENCY = 1,
NOMODELV = 2,//작업모델
NOMODELM = 3,//모션모델
DOORSAFTY = 6,
AREASAFTY = 7,
VIS_LICENSE = 8,
HOME_TIMEOUT = 9,
AIRNOOUT = 10,
NOFUNCTION = 11,
AIRNOTDETECT = 12,
DOOFF = 27,//출력 off
DOON = 28,//출력 on
DIOFF = 29,//입력off
DION = 30,//입력 on
MESSAGE_INFO = 32,
MESSAGE_ERROR = 33,
VISION_NOTREADY = 34,
VISION_NOCONN = 35,
VISION_TRIGERROR = 36,
VISION_COMMERROR = 37,
VISION_NORECV = 38,
AZJINIT = 39, //DIO 혹은 모션카드 초기화 X
MOT_HSET = 41,
MOT_SVOFF = 42,
MOT_HSEARCH = 43,
MOT_CMD = 71,
USER_STOP = 72,
USER_STEP = 73,
POSITION_ERROR = 86,
MOTIONMODEL_MISSMATCH = 96,
//여기서부터는 전용코드로한다(소켓은 조금 섞여 있음)
VISCONF = 100,
NEED_AIROFF_L,
NEED_AIROFF_R,
PORTOVERLOAD,
NOPRINTLDATA,
NOPRINTRDATA,
PRINTL,
PRINTR,
CAM_LEFT,
CAM_RIGHT,
INCOMPLETE_LOADERDATA,
NOPUTPOSITION,
NOREELSIZE,
PRINTER,
QRDATAMISSMATCHL,
QRDATAMISSMATCHR,
MOTX_SAFETY,
NO_PAPER_DETECT_L,
NO_PAPER_DETECT_R,
CART_SIZE_ERROR_L,
CART_SIZE_ERROR_R,
PRE_USE_REELID_L,
PRE_USE_REELID_R,
NEED_JOBCANCEL,
LCONVER_REEL_DECTECT_ALL =150,
RCONVER_REEL_DECTECT_ALL,
LCONVER_REEL_DECTECT_IN,
RCONVER_REEL_DECTECT_IN,
LCONVER_MOVING,
RCONVER_MOVING,
NOREADY_KEYENCE,
PRINTER_LPICKER_NOBW,
PRINTER_RPICKER_NOBW,
NOBYPASSSID,
CONFIG_KEYENCE,
PRINTER_LPRINTER_NOUP,
PRINTER_RPRINTER_NOUP,
NOECSDATA,
PICKER_LCYL_NODOWN,
PICKER_RCYL_NODOWN,
PICKER_LCYL_NOUP,
PICKER_RCYL_NOUP,
NOSIDINFOFROMDB,
INBOUNDWEBAPIERROR,
SIDINFORDUP,
NOECSDATAACTIVE,
}
public enum eNextStep : byte
{
NOTHING = 0,
PAUSE,
PAUSENOMESAGE,
ERROR
}
public enum eILock
{
EMG = 0,
PAUSE,
HOMESET,
DOOR,
SAFTYAREA,
DISABLE,
XMOVE,
YMOVE,
ZMOVE,
X_POS,
Y_POS,
Z_POS,
PY_POS,
PZ_POS,
CYL_FORWARD,
MPrint,
}
//public enum eILockPKX
//{
// EMG = 0,
// PAUSE,
// HOMESET,
// DOOR,
// Disable,
// ZL_POS,
// ZR_POS,
// ZMOVE,
// PKZPOS,
//}
//public enum eILockPKZ
//{
// EMG = 0,
// PAUSE,
// HOMESET,
// DOOR,
// Disable,
// Y_POS,
// YMOVE,
// PORTRUN0,
// PORTRUN1,
// PORTRUN2
//}
//public enum eILockPKT
//{
// EMG = 0,
// PAUSE,
// HOMESET,
// DOOR,
// Disable,
// Y_POS,
// Y_MOVE,
// PortRun
//}
///// <summary>
///// PRINT MOVE AXIS (L+R)
///// </summary>
//public enum eILockPRM
//{
// Emergency = 0,
// Pause,
// HomeSet,
// Safty,
// Disable,
// ZMOVE,
// FORWARD,
// ITEMON,
// PKXPOS,
// PRNZPOS,
//}
//public enum eILockPRZ
//{
// EMG = 0,
// PAUSE,
// HOMESET,
// DOOR,
// Disable,
// YMOVE,
// ITEMON,
// PRNYPOS,
//}
public enum eILockPRL
{
EMG = 0,
PAUSE,
HOMESET,
DOOR,
SAFTYAREA,
DISABLE,
PRNYPOS,
PRNZPOS,
}
public enum eILockPRR
{
EMG = 0,
PAUSE,
HOMESET,
DOOR,
SAFTYAREA,
DISABLE,
PRNYPOS,
PRNZPOS,
}
public enum eILockVS0
{
EMG = 0,
PAUSE,
HOMESET,
DOOR,
SAFTYAREA,
DISABLE,
PORTRDY,
PKXPOS, //피커의 위치
PRNYPOS, //프린터Y축 위치
}
public enum eILockVS1
{
EMG = 0,
PAUSE,
HOMESET,
DOOR,
SAFTYAREA,
DISABLE,
PORTRDY,
PKXPOS,
}
public enum eILockVS2
{
EMG = 0,
PAUSE,
HOMESET,
DOOR,
SAFTYAREA,
DISABLE,
PORTRDY,
PKXPOS, //피커의 위치
PRNYPOS, //프린터Y축 위치
}
public enum eILockCV
{
EMG = 0,
PAUSE,
HOMESET,
DOOR,
SAFTYAREA,
/// <summary>
/// 포트를 사용하지 않는경우
/// </summary>
DISABLE,
/// <summary>
/// 카트모드
/// </summary>
CARTMODE,
/// <summary>
/// 업체컨이어의 ready 신호
/// </summary>
EXTBUSY,
/// <summary>
/// 나의 작업 신호
/// </summary>
BUSY,
VISION,
}
}

View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Project
{
/// <summary>
/// 모션 축 정보
/// </summary>
public enum eAxis : byte
{
PX_PICK = 0,
PZ_PICK,
PL_MOVE,
PL_UPDN,
PR_MOVE,
PR_UPDN,
Z_THETA,
}
public enum eAxisName : byte
{
Picker_X = 0,
Picker_Z ,
PrinterL_Move,
PrinterL_UpDn,
PrinterR_Move,
PrinterR_UpDn,
Spare_00,
}
}

View File

@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace Project
{
public enum ePXLoc : byte
{
READYL = 0,
READYR,
PICKON,
PICKOFFL,
PICKOFFR,
}
public enum ePZLoc : byte
{
READY = 0,
PICKON,
PICKOFFL,
PICKOFFR,
}
public enum ePTLoc : byte
{
READY = 0,
}
public enum eLMLoc : byte
{
READY = 0,
PRINTH07,
PRINTL07,
PRINTM07,
PRINTH13,
PRINTL13,
PRINTM13,
}
public enum eLZLoc : byte
{
READY = 0,
PICKON,
PICKOFF,
}
public enum eRMLoc : byte
{
READY = 0,
PRINTH07,
PRINTL07,
PRINTM07,
PRINTH13,
PRINTL13,
PRINTM13,
}
public enum eRZLoc : byte
{
READY = 0,
PICKON,
PICKOFF,
}
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AR.FTPClient
{
public class MessageEventArgs : EventArgs
{
protected Boolean _isError = false;
public Boolean IsError { get { return _isError; } }
protected string _message = string.Empty;
public string Message { get { return _message; } }
public MessageEventArgs(Boolean isError, string Message)
{
_isError = isError;
_message = Message;
}
}
public class ListProgressEventArgs : EventArgs
{
//public long Max { get; set; }
//public long Value { get; set; }
public long TotalRecv { get; set; }
public ListProgressEventArgs(long TotalRecv_)
{
this.TotalRecv = TotalRecv_;
}
}
}

View File

@@ -0,0 +1,574 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
namespace AR.FTPClient
{
public partial class FTPClient : IFTPClient
{
public string errorMessage { get; set; }
private int bufferSize = 2048;
private int timeout = 20000;
#region "Contstruct"
public FTPClient() : this("127.0.0.1", "Anonymous", "") { }
public FTPClient(string Host, string UserID, string UserPass) :
this(Host, UserID, UserPass, 21)
{ }
public FTPClient(string Host, string UserID, string UserPass, bool passive) :
this(Host, UserID, UserPass, 21, passive)
{ }
public FTPClient(string Host, string UserID, string UserPass, int port) :
this(Host, UserID, UserPass, port, false)
{ }
public FTPClient(string host, string userid, string userpass, int port, bool passive)
{
Host = host;
UserID = userid;
UserPassword = userpass;
Port = port;
PassiveMode = passive;
this.TextEncoding = System.Text.Encoding.UTF8;
}
#endregion
public event EventHandler<MessageEventArgs> Message;
public event EventHandler<ListProgressEventArgs> ListPrgress;
#region "Properties"
/// <summary>
/// 접속하려는 FTP서버의 IP혹은 도메인 주소를 입력하세요
/// 기본값 : 127.0.0.1
/// </summary>
public string Host { get; set; }
/// <summary>
/// FTP의 사용자 ID
/// 기본값 : Anonymous
/// </summary>
public string UserID { get; set; }
/// <summary>
/// FTP 사용자 ID의 암호
/// 기본값 : 없음
/// </summary>
public string UserPassword { get; set; }
/// <summary>
/// FTP 접속 포트
/// 기본값 : 21
/// </summary>
public int Port { get; set; }
/// <summary>
/// FTP 접속 방식 (능동형/수동형)
/// </summary>
public bool PassiveMode { get; set; }
/// <summary>
/// 문자수신시 사용할 인코딩 방식
/// </summary>
public System.Text.Encoding TextEncoding { get; set; }
#endregion
public void Dispose()
{
}
/// <summary>
/// 파일을 다운로드 합니다.
/// </summary>
/// <param name="remoteFile">원격위치의 전체 경로</param>
/// <param name="localFile">로컬위치의 전체 경로</param>
public Boolean Download(string remoteFile, string localFile, bool overwrite = false)
{
FtpWebRequest ftpRequest = null;
FtpWebResponse ftpResponse = null;
Stream ftpStream = null;
//overwrite funcion - 190622 - chi
errorMessage = string.Empty;
if (overwrite == false && System.IO.File.Exists(localFile))
{
errorMessage = "Target file alreay exists";
return false;
}
else if (overwrite == true && System.IO.File.Exists(localFile))
{
try
{
System.IO.File.Delete(localFile);
}
catch (Exception ex)
{
errorMessage = ex.Message;
return false;
}
}
bool retval = true;
try
{
long Receive = 0;
var url = CombineUrl(remoteFile);
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(url);
ftpRequest.Credentials = new NetworkCredential(this.UserID, this.UserPassword);
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = this.PassiveMode;
ftpRequest.KeepAlive = true;
ftpRequest.ReadWriteTimeout = this.timeout;
ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpStream = ftpResponse.GetResponseStream();
FileStream localFileStream = new FileStream(localFile, FileMode.Create);
byte[] byteBuffer = new byte[bufferSize];
int bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize);
Receive += bytesRead;
if (ListPrgress != null)
ListPrgress(this, new ListProgressEventArgs(Receive));
try
{
while (bytesRead > 0)
{
localFileStream.Write(byteBuffer, 0, bytesRead);
bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize);
Receive += bytesRead;
if (ListPrgress != null)
ListPrgress(this, new ListProgressEventArgs(Receive));
}
}
catch (Exception ex) { retval = false; Console.WriteLine(ex.ToString()); }
localFileStream.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
}
catch (Exception ex) { retval = false; this.errorMessage = ex.Message; Console.WriteLine(ex.ToString()); }
return retval;
}
/// <summary>
/// 파일을 업로드 합니다.
/// </summary>
/// <param name="remoteFile">원격위치의 전체 경로</param>
/// <param name="localFile">로컬위치의 전체 경로</param>
/// <returns></returns>
public Boolean Upload(string remoteFile, string localFile)
{
FtpWebRequest ftpRequest = null;
FtpWebResponse ftpResponse = null;
Stream ftpStream = null;
try
{
var url = CombineUrl(remoteFile);
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(url);
ftpRequest.Credentials = new NetworkCredential(UserID, UserPassword);
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = PassiveMode;
ftpRequest.KeepAlive = true;
ftpRequest.ReadWriteTimeout = this.timeout;
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
ftpStream = ftpRequest.GetRequestStream();
FileStream localFileStream = new FileStream(localFile, FileMode.Open);
byte[] byteBuffer = new byte[bufferSize];
int bytesSent = localFileStream.Read(byteBuffer, 0, bufferSize);
Boolean bError = false;
try
{
System.Diagnostics.Stopwatch wat = new System.Diagnostics.Stopwatch();
wat.Restart();
while (bytesSent != 0)
{
ftpStream.Write(byteBuffer, 0, bytesSent);
bytesSent = localFileStream.Read(byteBuffer, 0, bufferSize);
}
}
catch (Exception ex)
{
bError = true;
}
localFileStream.Close();
ftpStream.Close();
ftpRequest = null;
if (bError) return false;
else return true;
}
catch (Exception ex)
{
this.errorMessage = ex.Message;
return false;
}
}
/// <summary>
/// 원격파일을 삭제 합니다.
/// </summary>
/// <param name="remotefile"></param>
public Boolean Delete(string remotefile)
{
FtpWebRequest ftpRequest = null;
FtpWebResponse ftpResponse = null;
Stream ftpStream = null;
try
{
var url = CombineUrl(remotefile);
ftpRequest = (FtpWebRequest)WebRequest.Create(url);
ftpRequest.Credentials = new NetworkCredential(UserID, UserPassword);
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = this.PassiveMode;
ftpRequest.KeepAlive = true;
ftpRequest.ReadWriteTimeout = this.timeout;
ftpRequest.Method = WebRequestMethods.Ftp.DeleteFile;
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpResponse.Close();
ftpRequest = null;
return true;
}
catch (Exception ex) { this.errorMessage = ex.Message; return false; }
}
/// <summary>
/// 원격파일의 이름을 변경 합니다.
/// </summary>
/// <param name="currentFileNameAndPath"></param>
/// <param name="newFileName"></param>
public Boolean rename(string currentFileNameAndPath, string newFileName)
{
FtpWebRequest ftpRequest = null;
FtpWebResponse ftpResponse = null;
Stream ftpStream = null;
try
{
var url = CombineUrl(currentFileNameAndPath);
ftpRequest = (FtpWebRequest)WebRequest.Create(url);
ftpRequest.Credentials = new NetworkCredential(UserID, UserPassword);
ftpRequest.UsePassive = this.PassiveMode;
ftpRequest.ReadWriteTimeout = this.timeout;
ftpRequest.UseBinary = true;
ftpRequest.KeepAlive = true;
ftpRequest.Method = WebRequestMethods.Ftp.Rename;
ftpRequest.RenameTo = newFileName;
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpResponse.Close();
ftpRequest = null;
return true;
}
catch (Exception ex) { this.errorMessage = ex.Message; return false; }
}
/// <summary>
/// 원격위치에 폴더를 생성 합니다.
/// 트리구조로 폴더를 생성하지 않습니다. 여러개의 폴더를 생성하려면 각각 호출 해야 합니다.
/// </summary>
/// <param name="newDirectory"></param>
/// <returns></returns>
public bool createDirectory(string newDirectory)
{
FtpWebRequest ftpRequest = null;
FtpWebResponse ftpResponse = null;
Stream ftpStream = null;
try
{
var url = CombineUrl(newDirectory, false);
ftpRequest = (FtpWebRequest)WebRequest.Create(url);
ftpRequest.Credentials = new NetworkCredential(UserID, UserPassword);
ftpRequest.UsePassive = this.PassiveMode;
ftpRequest.UseBinary = true;
ftpRequest.KeepAlive = true;
ftpRequest.ReadWriteTimeout = this.timeout;
ftpRequest.Method = WebRequestMethods.Ftp.MakeDirectory;
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpResponse.Close();
ftpRequest = null;
return true;
}
catch (Exception ex) { this.errorMessage = ex.Message; return false; }
}
/// <summary>
/// 원격위치의 폴더를 삭제합니다. 폴더 삭제 전 대상 폴더는 비어있어야 합니다.
/// </summary>
/// <param name="Directory"></param>
/// <returns></returns>
public bool RemoveDirectory(string Directory)
{
FtpWebRequest ftpRequest = null;
FtpWebResponse ftpResponse = null;
Stream ftpStream = null;
try
{
var url = CombineUrl(Directory, false);
ftpRequest = (FtpWebRequest)WebRequest.Create(url);
ftpRequest.Credentials = new NetworkCredential(UserID, UserPassword);
ftpRequest.UsePassive = this.PassiveMode;
ftpRequest.UseBinary = true;
ftpRequest.KeepAlive = true;
ftpRequest.ReadWriteTimeout = this.timeout;
ftpRequest.Method = WebRequestMethods.Ftp.RemoveDirectory;
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpResponse.Close();
ftpRequest = null;
return true;
}
catch (Exception ex) { this.errorMessage = ex.Message; return false; }
}
/// <summary>
/// 파일의 생성일자 반환
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public string getFileCreatedDateTime(string fileName)
{
FtpWebRequest ftpRequest = null;
FtpWebResponse ftpResponse = null;
Stream ftpStream = null;
try
{
var url = CombineUrl(fileName);
ftpRequest = (FtpWebRequest)WebRequest.Create(url);
ftpRequest.Credentials = new NetworkCredential(UserID, UserPassword);
ftpRequest.UsePassive = this.PassiveMode;
ftpRequest.UseBinary = true;
ftpRequest.KeepAlive = true;
ftpRequest.ReadWriteTimeout = this.timeout;
ftpRequest.Method = WebRequestMethods.Ftp.GetDateTimestamp;
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpStream = ftpResponse.GetResponseStream();
StreamReader ftpReader = new StreamReader(ftpStream, this.TextEncoding);
string fileInfo = null;
try { fileInfo = ftpReader.ReadToEnd(); }
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
ftpReader.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
return fileInfo;
}
catch (Exception ex) { this.errorMessage = ex.Message; Console.WriteLine(ex.ToString()); }
return "";
}
/// <summary>
/// 파일의 크기를 반환
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public string getFileSize(string fileName)
{
FtpWebRequest ftpRequest = null;
FtpWebResponse ftpResponse = null;
Stream ftpStream = null;
try
{
var url = CombineUrl(fileName);
ftpRequest = (FtpWebRequest)WebRequest.Create(url);
ftpRequest.Credentials = new NetworkCredential(UserID, UserPassword);
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = this.PassiveMode;
ftpRequest.KeepAlive = true;
ftpRequest.ReadWriteTimeout = this.timeout;
ftpRequest.Method = WebRequestMethods.Ftp.GetFileSize;
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpStream = ftpResponse.GetResponseStream();
StreamReader ftpReader = new StreamReader(ftpStream, this.TextEncoding);
string fileInfo = null;
try { while (ftpReader.Peek() != -1) { fileInfo = ftpReader.ReadToEnd(); } }
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
ftpReader.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
return fileInfo;
}
catch (Exception ex) { errorMessage = ex.Message; Console.WriteLine(ex.ToString()); }
return "";
}
/// <summary>
/// 폴더와 파일의 이름만 반환 합니다.
/// </summary>
/// <param name="directory"></param>
/// <returns></returns>
public string[] directoryListSimple(string directory)
{
FtpWebRequest ftpRequest = null;
FtpWebResponse ftpResponse = null;
Stream ftpStream = null;
errorMessage = string.Empty;
try
{
var url = CombineUrl(directory, false);
if (url.EndsWith("/") == false) url += "/";
ftpRequest = (FtpWebRequest)WebRequest.Create(url);
ftpRequest.Credentials = new NetworkCredential(UserID, UserPassword);
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = PassiveMode;
ftpRequest.KeepAlive = true;
ftpRequest.ReadWriteTimeout = this.timeout;
ftpRequest.ReadWriteTimeout = 30000;
ftpRequest.Timeout = 30000;
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpStream = ftpResponse.GetResponseStream();
StreamReader ftpReader = new StreamReader(ftpStream, this.TextEncoding);
string directoryRaw = null;
try
{
while (ftpReader.Peek() != -1)
{
var dataLIne = ftpReader.ReadLine();
if (dataLIne.Trim() != "")
{
if (directoryRaw != null && directoryRaw != "") directoryRaw += "|";
directoryRaw += dataLIne;
}
}
}
catch (Exception ex) { errorMessage += "\n" + ex.Message; }
ftpReader.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
try { string[] directoryList = directoryRaw.Split("|".ToCharArray()); return directoryList; }
catch (Exception ex) { errorMessage += "\n" + ex.Message; }
}
catch (Exception ex) { errorMessage = ex.Message; Console.WriteLine(ex.ToString()); }
return new string[] { "" };
}
/// <summary>
/// 폴더 및 파일의 정보를 상세하게 표시합니다.
/// </summary>
/// <param name="directory"></param>
/// <returns></returns>
public FTPdirectory ListDirectoryDetail(string directory)
{
FtpWebRequest ftpRequest = null;
FtpWebResponse ftpResponse = null;
Stream ftpStream = null;
errorMessage = string.Empty;
try
{
var url = CombineUrl(directory, false);
if (url.EndsWith("/") == false) url += "/";
ftpRequest = (FtpWebRequest)WebRequest.Create(url);
ftpRequest.Credentials = new NetworkCredential(UserID, UserPassword);
ftpRequest.UsePassive = true;
ftpRequest.UseBinary = true;
ftpRequest.KeepAlive = false;
ftpRequest.ReadWriteTimeout = this.timeout;
ftpRequest.ReadWriteTimeout = 30000;
ftpRequest.Timeout = 30000;
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectoryDetails;
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
ftpStream = ftpResponse.GetResponseStream();
StreamReader ftpReader = new StreamReader(ftpStream, this.TextEncoding);
string directoryRaw = null;
try { while (ftpReader.Peek() != -1) { directoryRaw += ftpReader.ReadLine() + "\r"; } }
catch (Exception ex) { errorMessage += "\n" + ex.Message; }
ftpReader.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
directoryRaw = directoryRaw.Replace("\r\n", "\r").TrimEnd((char)0x0D);
return new FTPdirectory(directoryRaw, directory);
}
catch (Exception ex) { errorMessage += "\n" + ex.Message; }
return null;
}
#region "utillity"
/// <summary>
/// Url을 Host와 결합하여 생성
/// </summary>
/// <param name="file">경로명</param>
/// <param name="isfile">파일인지 여부</param>
/// <returns></returns>
string CombineUrl(string file, bool isfile = true)
{
file = file.Replace("\\", "/");
string url = this.Host;
if (this.Host.ToLower().StartsWith("ftp://") == false) url = "ftp://" + url;
if (url.Substring(5).LastIndexOf(':') == -1)
url += ":" + this.Port.ToString();
if (this.Host.EndsWith("/")) url = this.Host.Substring(0, Host.Length - 1);
if (file.StartsWith("/"))
url = url + System.Web.HttpUtility.UrlPathEncode(file);
else
url = url + "/" + System.Web.HttpUtility.UrlPathEncode(file);
url = url.Replace("#", "%23");
if (isfile)
return url;
else
return url + "/";
}
public string PathCombine(string path, string add)
{
var newpath = string.Empty;
if (path.EndsWith("/")) newpath = path + add;
else newpath = path + "/" + add;
if (!newpath.EndsWith("/")) newpath += '/';
return newpath;
}
public string PathFileCombine(string path, string add)
{
var newpath = string.Empty;
if (path.EndsWith("/")) newpath = path + add;
else newpath = path + "/" + add;
if (newpath.EndsWith("/")) newpath = newpath.Substring(0, newpath.Length - 1);
return newpath;
}
public string getParent(string path)
{
if (path == "/") return path;
else if (path == "") return "/";
else
{
//서브폴더를 찾아서 처리해준다.
if (path.IndexOf('/') == -1) return "/";
else
{
if (path.EndsWith("/")) path = path.Substring(0, path.Length - 1);
var slashindex = path.LastIndexOf('/');
var parent = path.Substring(0, slashindex);
if (!parent.EndsWith("/")) parent += '/';
return parent;
}
}
}
public void RaiseMessage(Boolean isError, string message)
{
if (isError) errorMessage = message; //170920
if (Message != null) Message(this, new MessageEventArgs(isError, message));
}
#endregion
}
}

View File

@@ -0,0 +1,95 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AR.FTPClient
{
/// <summary>
/// ''' Stores a list of files and directories from an FTP result
/// ''' </summary>
/// ''' <remarks></remarks>
public class FTPdirectory : List<FTPfileInfo>
{
public FTPdirectory()
{
}
/// <summary>
/// ''' Constructor: create list from a (detailed) directory string
/// ''' </summary>
/// ''' <param name="dir">directory listing string</param>
/// ''' <param name="path"></param>
/// ''' <remarks></remarks>
public FTPdirectory(string dir, string path)
{
var lines = dir.Replace("\n","").Split('\r');
foreach (var line in lines)
{
if (line != "")
this.Add(new FTPfileInfo(line, path));
}
}
/// <summary>
/// ''' Filter out only files from directory listing
/// ''' </summary>
/// ''' <param name="ext">optional file extension filter</param>
/// ''' <returns>FTPdirectory listing</returns>
public FTPdirectory GetFiles(string ext = "")
{
return this.GetFileOrDir(FTPfileInfo.DirectoryEntryTypes.File, ext);
}
/// <summary>
/// ''' Returns a list of only subdirectories
/// ''' </summary>
/// ''' <returns>FTPDirectory list</returns>
/// ''' <remarks></remarks>
public FTPdirectory GetDirectories()
{
return this.GetFileOrDir(FTPfileInfo.DirectoryEntryTypes.Directory);
}
// internal: share use function for GetDirectories/Files
private FTPdirectory GetFileOrDir(FTPfileInfo.DirectoryEntryTypes type, string ext = "")
{
FTPdirectory result = new FTPdirectory();
foreach (FTPfileInfo fi in this)
{
if (fi.FileType == type)
{
if (ext == "")
result.Add(fi);
else if (ext == fi.Extension)
result.Add(fi);
}
}
return result;
}
public bool FileExists(string filename)
{
foreach (FTPfileInfo ftpfile in this)
{
if (ftpfile.Filename == filename)
return true;
}
return false;
}
private const char slash = '/';
public static string GetParentDirectory(string dir)
{
string tmp = dir.TrimEnd(slash);
int i = tmp.LastIndexOf(slash);
if (i > 0)
return tmp.Substring(0, i - 1);
else
throw new ApplicationException("No parent for root");
}
}
}

View File

@@ -0,0 +1,216 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace AR.FTPClient
{
/// <summary>
/// ''' Represents a file or directory entry from an FTP listing
/// ''' </summary>
/// ''' <remarks>
/// ''' This class is used to parse the results from a detailed
/// ''' directory list from FTP. It supports most formats of
/// ''' </remarks>
public class FTPfileInfo
{
// Stores extended info about FTP file
public string FullName
{
get
{
var retval = Path + "/" + Filename;
return retval.Replace("//", "/");
}
}
public string Filename
{
get
{
return _filename;
}
}
public string Path
{
get
{
return _path;
}
}
public DirectoryEntryTypes FileType
{
get
{
return _fileType;
}
}
public long Size
{
get
{
return _size;
}
}
public DateTime FileDateTime
{
get
{
return _fileDateTime;
}
}
public string Permission
{
get
{
return _permission;
}
}
public string Extension
{
get
{
int i = this.Filename.LastIndexOf(".");
if (i >= 0 & i < (this.Filename.Length - 1))
return this.Filename.Substring(i + 1);
else
return "";
}
}
public string NameOnly
{
get
{
int i = this.Filename.LastIndexOf(".");
if (i > 0)
return this.Filename.Substring(0, i);
else
return this.Filename;
}
}
private string _filename;
private string _path;
private DirectoryEntryTypes _fileType;
private long _size;
private DateTime _fileDateTime;
private string _permission;
/// <summary>
/// ''' Identifies entry as either File or Directory
/// ''' </summary>
public enum DirectoryEntryTypes
{
File,
Directory,
Link
}
/// <summary>
/// ''' Constructor taking a directory listing line and path
/// ''' </summary>
/// ''' <param name="line">The line returned from the detailed directory list</param>
/// ''' <param name="path">Path of the directory</param>
/// ''' <remarks></remarks>
public FTPfileInfo(string line, string path)
{
// parse line
Match m = GetMatchingRegex(line);
if (m == null)
// failed
throw new ApplicationException("Unable to parse line: " + line);
else
{
_filename = m.Groups["name"].Value;
_path = path;
_permission = m.Groups["permission"].Value;
string _dir = m.Groups["dir"].Value;
if ((_dir != "" & (_dir == "d" || _dir == "D")))
{
_fileType = DirectoryEntryTypes.Directory;
_size = 0; // CLng(m.Groups("size").Value)
}
else if ((_dir != "" & (_dir == "l" || _dir == "L")))
{
_fileType = DirectoryEntryTypes.Link;
_size = 0; // CLng(m.Groups("size").Value)
}
else
{
_fileType = DirectoryEntryTypes.File;
_size = System.Convert.ToInt64(m.Groups["size"].Value);
}
try
{
var timestamp = m.Groups["timestamp"].Value;
if (timestamp.IndexOf(':') == -1)
{
_fileDateTime = DateTime.Parse(timestamp);
}
else
{
_fileDateTime = DateTime.Parse(DateTime.Now.Year + " " + timestamp);
}
}
catch
{
// MsgBox("datetime err=" & Now.Year & Space(1) & "value=" & m.Groups("timestamp").Value & vbCrLf & ex.Message.ToString)
_fileDateTime = DateTime.Parse("1982-11-23");
}
}
}
public FTPfileInfo(string filename, string permission, string dir, int size, DateTime filetime, Boolean isdir, string path)
{
_filename = filename;// m.Groups["name"].Value;
_path = path;
_permission = permission; // m.Groups["permission"].Value;
string _dir = dir;// m.Groups["dir"].Value;
if (isdir == true)
{
_fileType = DirectoryEntryTypes.Directory;
_size = 0; // CLng(m.Groups("size").Value)
}
else
{
_fileType = DirectoryEntryTypes.File;
_size = size;//
}
_fileDateTime = filetime;
}
private Match GetMatchingRegex(string line)
{
Regex rx;
Match m;
for (int i = 0; i <= _ParseFormats.Length - 1; i++)
{
rx = new Regex(_ParseFormats[i]);
m = rx.Match(line);
if (m.Success)
return m;
}
return null;
}
/// <summary>
/// ''' List of REGEX formats for different FTP server listing formats
/// ''' </summary>
/// ''' <remarks>
/// ''' The first three are various UNIX/LINUX formats, fourth is for MS FTP
/// ''' in detailed mode and the last for MS FTP in 'DOS' mode.
/// ''' I wish VB.NET had support for Const arrays like C# but there you go
/// ''' </remarks>
private static string[] _ParseFormats = new[] { @"(?<dir>[\-dl])(?<permission>([\-r][\-w][\-xs]){3})\s+\d+\s+\w+\s+\w+\s+(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{4})\s+(?<name>.+)", @"(?<dir>[\-dl])(?<permission>([\-r][\-w][\-xs]){3})\s+\d+\s+\d+\s+(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{4})\s+(?<name>.+)", @"(?<dir>[\-dl])(?<permission>([\-r][\-w][\-xs]){3})\s+\d+\s+\d+\s+(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{1,2}:\d{2})\s+(?<name>.+)", @"(?<dir>[\-dl])(?<permission>([\-r][\-w][\-xs]){3})\s+\d+\s+\w+\s+\w+\s+(?<size>\d+)\s+(?<timestamp>\w+\s+\d+\s+\d{1,2}:\d{2})\s+(?<name>.+)", @"(?<dir>[\-dl])(?<permission>([\-r][\-w][\-xs]){3})(\s+)(?<size>(\d+))(\s+)(?<ctbit>(\w+\s\w+))(\s+)(?<size2>(\d+))\s+(?<timestamp>\w+\s+\d+\s+\d{2}:\d{2})\s+(?<name>.+)", @"(?<timestamp>\d{2}\-\d{2}\-\d{2}\s+\d{2}:\d{2}[Aa|Pp][mM])\s+(?<dir>\<\w+\>){0,1}(?<size>\d+){0,1}\s+(?<name>.+)" };
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AR.FTPClient
{
public interface IFTPClient
{
void Dispose();
string errorMessage { get; set; }
//string Host { get; set; }
//string UserID { get; set; }
//string UserPassword { get; set; }
//int Port { get; set; }
System.Text.Encoding TextEncoding { get; set; }
Boolean Download(string remoteFile, string localFile,bool overwrite=false);
Boolean Upload(string remoteFile, string localFile);
Boolean Delete(string remotefile);
Boolean rename(string currentFileNameAndPath, string newFileName);
bool createDirectory(string newDirectory);
bool RemoveDirectory(string Directory);
string getFileCreatedDateTime(string fileName);
string getFileSize(string fileName);
string[] directoryListSimple(string directory);
FTPdirectory ListDirectoryDetail(string directory);
event EventHandler<MessageEventArgs> Message;
event EventHandler<ListProgressEventArgs> ListPrgress;
void RaiseMessage(Boolean isError, string message);
string PathCombine(string path, string add);
string PathFileCombine(string path, string add);
string getParent(string path);
}
}

View File

@@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Project.Class
{
public class JobData
{
public enum ErrorCode
{
None = 0,
BarcodeRead,
Print,
Camera,
}
public ErrorCode error = ErrorCode.None;
public int No { get; set; }
public VisionData VisionData;
public DateTime JobStart
{
get
{
if (this.VisionData == null) return new DateTime(1982, 11, 23);
else return VisionData.STime;
}
}
public DateTime JobEnd;
public TimeSpan JobRun
{
get
{
if (JobEnd.Year == 1982) return new TimeSpan(0);
else if (JobStart.Year == 1982) return new TimeSpan(0);
else return JobEnd - JobStart;
}
}
/// <summary>
/// 프린터에 명령을 전송한 시간
/// </summary>
public DateTime PrintTime { get; set; }
/// <summary>
/// 라벨을 추가한 시간
/// </summary>
public DateTime Attachtime { get; set; }
//작업데이터의 GUID(자료식별)
public string guid { get; private set; }
//언로더포트위치(L/R)
public string PortPos;
//동작관련 메세지
public string Message;
int idx;
public JobData(int idx_)
{
this.idx = idx_;
Clear("INIT");
}
public bool PrintAttach { get; set; }
public bool PrintQRValid { get; set; }
public string PrintQRValidResult { get; set; }
public void Clear(string source)
{
No = 0;
//JobStart = new DateTime(1982, 11, 23);
JobEnd = new DateTime(1982, 11, 23);
Attachtime = new DateTime(1982, 11, 23);
PortPos = string.Empty;
guid = Guid.NewGuid().ToString();
Message = string.Empty;
if (VisionData == null)
VisionData = new VisionData(source);
else
VisionData.Clear(source, false);
PrintAttach = false;
PrintQRValid = false;
PrintQRValidResult = string.Empty;
PrintTime = new DateTime(1982, 11, 23);
PUB.AddDebugLog($"item data {idx} clear by {source} guid={guid}");
}
public void CopyTo(ref JobData obj)
{
if (obj == null) return;
obj.No = this.No;
obj.error = this.error;
obj.JobEnd = this.JobEnd;
obj.guid = this.guid;
obj.PortPos = this.PortPos;
obj.Message = this.Message;
obj.PrintAttach = this.PrintAttach;
obj.PrintQRValid = this.PrintQRValid;
obj.PrintQRValidResult = this.PrintQRValidResult;
obj.Attachtime = this.Attachtime;
obj.PrintTime = this.PrintTime;
PUB.AddDebugLog("아이템 복사 전 rid:" + this.VisionData.RID);
this.VisionData.CopyTo(ref obj.VisionData);
PUB.AddDebugLog($"아이템 복사 후 대상 rid : {obj.VisionData.RID}, guid={obj.guid}");
}
}
}

View File

@@ -0,0 +1,275 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using HidSharp;
using HidSharp.Reports;
using HidSharp.Reports.Encodings;
namespace arDev.Joystick
{
public class JoystickRaw : IDisposable
{
HidDevice _dev;
HidStream _hidStream;
public Boolean IsOpen { get; private set; }
public event EventHandler Disconnected;
public event EventHandler Connected;
public event EventHandler Changed;
public delegate void MessageHandler(string msg);
public event MessageHandler Message;
public int InputLength { get; private set; }
public int OutputLength { get; private set; }
public int FeatureLength { get; private set; }
public int vid { get; set; }
public int pid { get; set; }
public Boolean[] Buttons = new bool[64]; //버튼정보를 기록한다
Boolean bListUpdate = false;
public JoystickRaw()
{
vid = -1;
pid = -1;
this.InputLength = 0;
this.OutputLength = 0;
this.FeatureLength = 0;
this.IsOpen = false;
this._dev = null;
this._hidStream = null;
DeviceList.Local.Changed += Local_Changed;
Job = new Task(JobMain, ct);
Job.Start();
for (int i = 0; i < Buttons.Length; i++)
Buttons[i] = false;
}
CancellationToken ct ;
public IEnumerable<HidDevice> GetHidDevices()
{
return DeviceList.Local.GetHidDevices();
}
public void Connect(int vid, int pid)
{
this.vid = vid;
this.pid = pid;
}
public void Connect(HidDevice device)
{
this.vid = device.VendorID;
this.pid = device.ProductID;
}
Task Job = null;
private bool disposed = false;
DateTime LastConnTime = DateTime.Now;
void JobMain()
{
//개체가 소멸하기전까지 진행한다
while (this.disposed == false)
{
if (IsOpen == false)
{
if (this.vid == -1 || this.pid == -1)
{
//아직설정되지 않았으니 대기를한다
System.Threading.Thread.Sleep(3000);
}
else
{
//연결작업을 시작해야한다
if (bListUpdate || (DateTime.Now - LastConnTime).TotalMilliseconds >= 3000)
{
LastConnTime = DateTime.Now;
//연결작업
var list = this.GetHidDevices();
this._dev = list.Where(t => t.VendorID == this.vid && t.ProductID == this.pid).FirstOrDefault();
if (_dev != null)
{
try
{
IsOpen = _dev.TryOpen(out _hidStream);
if (IsOpen)
{
this.InputLength = _dev.GetMaxInputReportLength();
this.OutputLength = _dev.GetMaxOutputReportLength();
this.FeatureLength = _dev.GetMaxFeatureReportLength();
this._hidStream.ReadTimeout = Timeout.Infinite;
Connected?.Invoke(this, null);
var rawReportDescriptor = _dev.GetRawReportDescriptor();
var msg = ("Report Descriptor:");
msg += string.Format(" {0} ({1} bytes)", string.Join(" ", rawReportDescriptor.Select(d => d.ToString("X2"))), rawReportDescriptor.Length);
Message?.Invoke(msg);
}
else
{
if (this._hidStream != null) this._hidStream.Dispose();
}
}
catch { System.Threading.Thread.Sleep(1500); }
}
else System.Threading.Thread.Sleep(1500);
}
else System.Threading.Thread.Sleep(1500);
}
}
else
{
//데이터를 가지고 온다
using (_hidStream)
{
try
{
reportDescriptor = _dev.GetReportDescriptor();
deviceItem = reportDescriptor.DeviceItems[0];
var inputReportBuffer = new byte[_dev.GetMaxInputReportLength()];
var inputReceiver = reportDescriptor.CreateHidDeviceInputReceiver();
var inputParser = deviceItem.CreateDeviceItemInputParser();
inputReceiver.Start(_hidStream);
while (true)
{
if (!inputReceiver.IsRunning) { break; } // Disconnected?
Report report; //
while (inputReceiver.TryRead(inputReportBuffer, 0, out report))
{
if (inputParser.TryParseReport(inputReportBuffer, 0, report))
{
WriteDeviceItemInputParserResult(inputParser);
}
}
System.Threading.Thread.Sleep(20);
}
inputReceiver = null;
IsOpen = false;
}
catch (Exception ex)
{
Message?.Invoke(ex.Message);
}
finally
{
Disconnected?.Invoke(this, null);
IsOpen = false;
}
}
}
}
}
void WriteDeviceItemInputParserResult(HidSharp.Reports.Input.DeviceItemInputParser parser)
{
while (parser.HasChanged)
{
int changedIndex = parser.GetNextChangedIndex();
var previousDataValue = parser.GetPreviousValue(changedIndex);
var dataValue = parser.GetValue(changedIndex);
var oVal = previousDataValue.GetPhysicalValue();
var nVal = dataValue.GetPhysicalValue();
if (double.IsNaN(oVal)) oVal = 0.0;
if (double.IsNaN(nVal)) nVal = 0.0;
var InputMethod = (Usage)dataValue.Usages.FirstOrDefault();
if (InputMethod.ToString().StartsWith("Button"))
{
var butNo = int.Parse(InputMethod.ToString().Substring(6));
this.Buttons[butNo - 1] = nVal > 0; //버튼값은 기록 210107
}
//이벤트발생
InputChanged?.Invoke(this, new InputChangedEventHandler(
InputMethod, oVal, nVal));
//메세지도 발생함
//var msg = (string.Format(" {0}: {1} -> {2}",
// (Usage)dataValue.Usages.FirstOrDefault(),
// previousDataValue.GetPhysicalValue(),
// dataValue.GetPhysicalValue()));
//Message?.Invoke(msg);
}
}
public event EventHandler<InputChangedEventHandler> InputChanged;
public class InputChangedEventHandler : EventArgs
{
public Usage input { get; set; }
public double oldValue { get; set; }
public double newValue { get; set; }
public InputChangedEventHandler(Usage input_, double oValue_, double nValue_)
{
this.input = input_;
this.oldValue = oValue_;
this.newValue = nValue_;
}
}
ReportDescriptor reportDescriptor;
DeviceItem deviceItem;
~JoystickRaw()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if (!this.disposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if (disposing)
{
// Dispose managed resources.
this._dev = null;
}
Job.Wait();
Job.Dispose();
// Call the appropriate methods to clean up
// unmanaged resources here.
// If disposing is false,
// only the following code is executed.
//CloseHandle(handle);
//handle = IntPtr.Zero;
// Note disposing has been done.
DeviceList.Local.Changed -= Local_Changed;
disposed = true;
}
}
private void Local_Changed(object sender, DeviceListChangedEventArgs e)
{
Changed?.Invoke(sender, e);
bListUpdate = true;
}
}
}

View File

@@ -0,0 +1,105 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
namespace Project.Class
{
public class KeyenceBarcodeData
{
public double Angle { get; set; }
public StdLabelPrint.CAmkorSTDBarcode AmkorData { get; set; }
public Point[] vertex { get; set; }
public string Data { get; set; }
public Point CenterPX { get; set; }
public bool Ignore { get; set; }
/// <summary>
/// 1:QR, 11:Code 128(like 1D)
/// </summary>
public string barcodeSymbol { get; set; }
public string barcodeSource { get; set; } //230503
public Boolean UserActive { get; set; }
public Boolean isSTDBarcode
{
get
{
if (AmkorData != null && barcodeSymbol == "1" && AmkorData.isValid) return true;
return false;
}
}
public Boolean isNewLen15
{
get
{
if (AmkorData != null && barcodeSymbol == "1" && AmkorData.isValid && AmkorData.NewLen15Barcode) return true;
return false;
}
}
/// <summary>
/// 라벨의 위치를 표시한다. 8방향이며 키패드 유사하게 설정한다 789/4-6/123
/// </summary>
public byte LabelPosition { get; set; }
/// <summary>
/// regex check ok
/// </summary>
public Boolean RegExConfirm { get; set; }
public Boolean RefExApply { get; set; }
public KeyenceBarcodeData()
{
LabelPosition = 0;
Angle = 0.0;
Data = string.Empty;
CenterPX = Point.Empty;
AmkorData = null;
vertex = null;
barcodeSymbol = string.Empty;
UserActive = false;
RegExConfirm = false;
Ignore = false;
barcodeSource = string.Empty;
}
public override string ToString()
{
return string.Format("{0},Deg={1},Center={2}x{3}", Data, Angle, CenterPX.X, CenterPX.Y);
}
/// <summary>
/// 해당 중심점이 겹치는지 확인합니다.
/// </summary>
/// <param name="Center"></param>
/// <returns></returns>
public Boolean CheckIntersect(Point Center, string data)
{
if (data == null) return false;
if (data.Equals(this.Data) == false) return false; //자료가 다르면 다른 자료로 처리한다
return getInside(Center, vertex);
}
bool getInside(Point pt, Point[] ptArr)
{
int crosses = 0;
for (int i = 0; i < ptArr.Length; i++)
{
int j = (i + 1) % ptArr.Length;
if ((ptArr[i].Y > pt.Y) != (ptArr[j].Y > pt.Y))
{
//atX는 점 B를 지나는 수평선과 선분 (p[i], p[j])의 교점
double atX = (ptArr[j].X - ptArr[i].X) * (pt.Y - ptArr[i].Y) / (ptArr[j].Y - ptArr[i].Y) + ptArr[i].X;
//atX가 오른쪽 반직선과의 교점이 맞으면 교점의 개수를 증가시킨다.
if (pt.X < atX)
crosses++;
}
}
return crosses % 2 > 0;
}
}
}

View File

@@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.ComponentModel;
using System.Web.Services.Protocols;
namespace Project
{
public class ModelInfoM
{
//스피드 값과, 위치값을 저장하면 된다.
public int idx { get; set; }
public string Title { get; set; }
public Dictionary<int, PositionData[]> Position { get; set; }
public ModelInfoM()
{
idx = -1;
Title = string.Empty;
ClearDataPosition();
}
void ClearDataPosition()
{
Position = new Dictionary<int, PositionData[]>();
var motCount = Enum.GetNames(typeof(eAxis)).Length;
for (int i = 0; i < motCount; i++)
{
var datas = new PositionData[64];
for (int j = 0; j < datas.Length; j++)
datas[j] = new PositionData(-1, string.Empty, 0.0);
Position.Add(i, datas);
}
}
public Boolean isSet
{
get
{
if (idx == -1) return false;
else return !Title.isEmpty();
}
}
public void ReadValue(DataSet1.MCModelRow dr)
{
idx = dr.idx;
Title = dr.Title;
ReadValuePosition(idx);
}
public void ReadValue(int index)
{
var dr = PUB.mdm.dataSet.MCModel.Where(t => t.idx == index).FirstOrDefault();
if (dr == null)
{
idx = -1;
Title = string.Empty;
ClearDataPosition();
}
else
{
idx = dr.idx;
Title = dr.Title;
ReadValuePosition(idx);
}
}
public Boolean ReadValue(string title)
{
return ReadValue(title, PUB.mdm.dataSet.MCModel);
}
public Boolean ReadValue(string title, DataSet1.MCModelDataTable dt)
{
var dr = dt.Where(t => t.Title == title).FirstOrDefault();
if (dr == null)
{
idx = -1;
this.Title= string.Empty;
ClearDataPosition();
return false;
}
else
{
idx = dr.idx;
this.Title = dr.Title;
ReadValuePosition(idx);
return true;
}
}
public void ReadValuePosition(int modelidx)
{
ReadValuePosition(modelidx, PUB.mdm.dataSet.MCModel);
}
public void ReadValuePosition(int modelidx, DataSet1.MCModelDataTable dt)
{
ClearDataPosition();
//각 모터별로 데이터를 가져온다
int cnt = 0;
foreach (var data in Position)
{
//해당 모터의 속도값을 가져온다
var drows = dt.Where(t => t.pidx == modelidx && t.PosIndex >= 0 && t.MotIndex == data.Key);
foreach (DataSet1.MCModelRow dr in drows)
{
var item = data.Value[dr.PosIndex];
item.index = dr.PosIndex;
item.title = dr.PosTitle;
item.value = dr.Position;
item.speed = dr.Speed;
item.acc = dr.SpeedAcc;
item.dcc = dr.SpeedDcc;
data.Value[dr.PosIndex] = item;
cnt += 1;
}
}
PUB.log.Add(String.Format("Motion({0}) Data Load : {1}", modelidx, cnt));
}
}
}

View File

@@ -0,0 +1,229 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.ComponentModel;
namespace Project
{
public class ModelInfoV
{
[Browsable(false)]
public string SPN { get; set; }
//[Browsable(false)]
//public Boolean SplitSPN { get; set; }
[Browsable(false)]
public string Title { get; set; }
[Browsable(false)]
public string Code { get; set; }
[Browsable(false)]
public int idx { get; set; }
public string Motion { get; set; }
public Boolean BCD_1D { get; set; }
public Boolean BCD_QR { get; set; }
public Boolean BCD_DM { get; set; }
public UInt16 vOption { get; set; }
public UInt16 vSIDInfo { get; set; }
public UInt16 vJobInfo { get; set; }
public UInt16 vSIDConv1 { get; set; }
public string Def_Vname { get; set; }
public string Def_MFG { get; set; }
public Boolean IgnoreOtherBarcode { get; set; }
public bool DisableCamera { get; set; }
public bool DisablePrinter { get; set; }
public bool CheckSIDExsit { get; set; }
//public string ByPassSID { get; set; }
public ModelInfoV()
{
vOption = vSIDInfo = vJobInfo = vSIDConv1 = 0;
}
public void ReadValue(DataSet1.OPModelRow dr)
{
this.Title = dr.Title;
this.Code = dr.Code;
this.idx = dr.idx;
this.Motion = dr.Motion;
this.BCD_1D = dr.BCD_1D;
this.BCD_QR = dr.BCD_QR;
this.BCD_DM = dr.BCD_DM;
this.vOption = dr.vOption;
this.vJobInfo = dr.vJobInfo;
this.vSIDInfo = dr.vSIDInfo;
this.vSIDConv1 = dr.vSIDConv;
this.Def_MFG = dr.Def_MFG;
this.Def_Vname = dr.Def_VName;
this.IgnoreOtherBarcode = dr.IgnoreOtherBarcode;
this.DisableCamera = dr.DisableCamera;
this.DisablePrinter = dr.DisablePrinter;
this.CheckSIDExsit = dr.CheckSIDExsit;
//this.ByPassSID = dr.ByPassSID;
}
public bool WriteValue()
{
var model = PUB.mdm.GetDataV(this.Title);
return WriteValue(ref model);
}
public bool WriteValue(ref DataSet1.OPModelRow dr)
{
try
{
dr.Title = this.Title;
dr.Code = this.Code;
dr.Motion = this.Motion;
dr.BCD_1D = this.BCD_1D;
dr.BCD_QR = this.BCD_QR;
dr.BCD_DM = this.BCD_DM;
dr.vOption = this.vOption;
dr.vSIDInfo = this.vSIDInfo;
dr.vJobInfo = this.vJobInfo;
dr.vSIDConv = this.vSIDConv1;
dr.Def_MFG = this.Def_MFG;
dr.Def_VName = this.Def_Vname;
dr.IgnoreOtherBarcode = this.IgnoreOtherBarcode;
dr.DisableCamera = this.DisableCamera;
dr.DisablePrinter = this.DisablePrinter;
dr.CheckSIDExsit = this.CheckSIDExsit;
dr.EndEdit();
PUB.mdm.SaveModelV();
return true;
}
catch (Exception ex)
{
PUB.log.AddE("write model error" + ex.Message);
return false;
}
}
}
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public class RoiOffset
{
[DisplayName("Horizon"), Description("수직(Y축) 변화 값(+는 아래쪽,-는 위쪽)")]
public double Y { get; set; }
[DisplayName("Vertical"), Description("수평(X축) 변화 값(+는 오른쪽,-는 왼쪽)")]
public double X { get; set; }
[Browsable(false)]
public bool IsEmpty { get { if (Y == 0 && X == 0) return true; else return false; } }
public RoiOffset(double start = 0.0, double end = 0.0)
{
this.Y = start;
this.X = end;
}
public override string ToString()
{
return string.Format("{0},{1}", Y, X);
}
public string toPointStr()
{
return string.Format("{0};{1}", Y, X);
}
}
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public class Range
{
[DisplayName("시작값")]
public uint Start { get; set; }
[DisplayName("종료값")]
public uint End { get; set; }
[Browsable(false)]
public bool IsEmpty { get { if (Start == 0 && End == 0) return true; else return false; } }
public Range(UInt16 start, UInt16 end) : this((uint)start, (uint)end) { }
public Range(uint start = 0, uint end = 0)
{
this.Start = start;
this.End = end;
}
public static implicit operator RangeF(Range p)
{
return new RangeF((float)p.Start, (float)p.End);
}
public override string ToString()
{
return string.Format("{0}~{1}", Start, End);
}
}
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public class RangeF
{
[DisplayName("시작값")]
public float Start { get; set; }
[DisplayName("종료값")]
public float End { get; set; }
[Browsable(false)]
public bool IsEmpty { get { if (Start == 0f && End == 0f) return true; else return false; } }
public RangeF(float start = 0f, float end = 0f)
{
this.Start = start;
this.End = end;
}
public static implicit operator Range(RangeF p)
{
return new Range((uint)p.Start, (uint)p.End);
}
public override string ToString()
{
return string.Format("{0}~{1}", Start, End);
}
}
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public class CVisionProcess
{
[Category("특수설정(개발자용)"), Description("미사용(DOT 인식시에 사용했음)")]
public UInt16 halfKernel { get; set; }
[Category("특수설정(개발자용)"), Description("미사용(DOT 인식시에 사용했음)")]
public UInt16 Constant { get; set; }
[Category("특수설정(개발자용)"), DisplayName("MP_Dilate"), Description("미사용(DOT 인식시에 사용했음)")]
public UInt16 dilate { get; set; }
[Category("특수설정(개발자용)"), DisplayName("MP_Erode"), Description("미사용(DOT 인식시에 사용했음)")]
public UInt16 erode { get; set; }
[Category("특수설정(개발자용)"), DisplayName("MP_Open"), Description("미사용(DOT 인식시에 사용했음)")]
public UInt16 open { get; set; }
[Category("특수설정(개발자용)"), DisplayName("MP_Open"), Description("미사용(DOT 인식시에 사용했음)")]
public UInt32 segment_threshold { get; set; }
[Category("특수설정(개발자용)"), DisplayName("MP_Open"), Description("미사용(DOT 인식시에 사용했음)")]
public Boolean isBlack { get; set; }
[Category("특수설정(개발자용)"), DisplayName("MP_Open"), Description("미사용(DOT 인식시에 사용했음)")]
public UInt32 judg_runcount { get; set; }
[Category("유닛 감지"), DisplayName("밝기 기준값"), Description("입력된 값 이상의 데이터를 취합니다. 이 값이 낮을 수록 검출값이 높아지게 됩니다. 이 기준값으로 검출된 값으로 판정을 합니다. 유닛은 밝은 데이터를 보고 판정 하므로 이 기준값 이상의 데이터가 검출이 됩니다")]
public byte detect_threhosld { get; set; }
[Category("유닛 감지"), DisplayName("판정 기준값"), Description("판정을 하는 기준 값입니다. 밝기기준값으로 인해 검출된 값이 5000이라면. 이 판정 기준에 입력된 값이 5000보다 크면 유닛이 존재하는 것으로 판정하며, 그 보다 낮을 때에는 유닛이 없는 'Empty' 유닛으로 감지 됩니다")]
public UInt16 detect_count { get; set; }
[Category("유닛 감지"), DisplayName("*예외영역 판정기준"), Description("빈 유닛(=Empty) 일때 셔틀 프레임의 빛 반사가 심할 경우 해당 반사값에 의해 유닛이 감지됩니다. 그러한 데이터를 제거하기위해 이 값이 사용되며, 유닛검출에 사용하는 흰색영역의 값외에 추가로 검은색 덩어리를 검사합니다. 설정한 값사이의 검은색 덩어리가 검출되면 'Empty' 유닛으로 감지 됩니다")]
public Point detect_blobrange { get; set; }
[Category("2D 감지"), DisplayName("밝기 기준값"), Description("입력된 값 이하의 데이터를 취합니다. 이 값이 낮을 수록 검출값도 낮아지게 됩니다. 이 기준값으로 검출된 값으로 판정을 합니다. 2D는 어두운 데이터를 보고 판정 하므로 이 기준값 이하의 데이터가 검출이 됩니다")]
public byte detectDM_threhosld { get; set; }
[Category("2D 감지"), DisplayName("판정 기준값"), Description("판정을 하는 기준 값입니다. 밝기기준값으로 인해 검출된 값이 5000이라면. 이 판정 기준에 입력된 값이 5000보다 크면 ID가 존재하는 것으로 판정하며, 그 보다 낮을 때에는 ID가 없는 'New' 유닛으로 감지 됩니다")]
public UInt16 detectDM_count { get; set; }
public CVisionProcess()
{
}
public override string ToString()
{
return "비젼 설정 값";
}
}
}

View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Project
{
public class PositionData
{
public int index { get; set; }
public string title { get; set; }
public double value { get; set; }
public double speed { get; set; }
public double acc { get; set; }
public double dcc { get; set; }
public PositionData()
{
index = -1;
title = string.Empty;
value = 0.0;
this.speed = 0.0;
this.acc = 100.0;
this.dcc = 0.0;
}
public PositionData(int idx_, string title_, double value_)
{
this.index = idx_;
this.title = title_;
this.value = value_;
}
}
}

View File

@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Project.Class
{
public class Reel
{
public string sid { get; set; }
public string lot { get; set; }
public string mfg { get; set; }
public int qty { get; set; }
public string id { get; set; }
//public string date { get; set; }
public string partnum { get; set; }
public string manu { get; set; }
public Reel()
{
Clear();
}
public void Clear()
{
sid = string.Empty;
lot = string.Empty;
mfg = string.Empty;
lot = string.Empty;
id = string.Empty;
//date = string.Empty;
partnum = string.Empty;
manu = string.Empty;
qty = 0;
}
public Reel(string _sid, string _lot, string _manu, int _qty, string _id, string _mfgdate, string _partnum)
{
int sidNum = 0;
if (int.TryParse(_sid, out sidNum) && sidNum.ToString().Length == 9)
sid = sidNum.ToString();
else
throw new Exception("SID가 숫자가 아니거나 9자리 숫자가 아닙니다.");
lot = _lot;
mfg = _mfgdate;
qty = _qty;
id = _id;
partnum = _partnum;
manu = _manu;
}
public Reel(string qrbarcodestr)
{
var spData = qrbarcodestr.Split(';');
if (spData.Length < 6)
throw new Exception("Barcode Length가 적습니다.");
sid = spData[0];
lot = spData[1];
manu = spData[2];
int _qty = 0;
if (int.TryParse(spData[3], out _qty))
qty = _qty;
else
throw new Exception("수량란에 숫자 정보가 아닙니다.");
id = spData[4];
mfg = spData[5];
if (spData.Length > 6) partnum = spData[6];
else partnum = string.Empty;
}
}
}

View File

@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Project.Class
{
public class RegexPattern
{
public string Customer { get; set; }
public string Pattern { get; set; }
public string Description { get; set; }
public bool IsTrust { get; set; }
public bool IsAmkStd { get; set; }
public Boolean IsEnable { get; set; }
public RegexGroupMatch[] Groups { get; set; }
public string Symbol { get; set; }
public int Seq { get; set; }
public RegexPattern()
{
Seq = 0;
Groups = null;
Pattern = string.Empty;
Description = string.Empty;
Customer = string.Empty;
IsTrust = false;
IsAmkStd = false;
Symbol = string.Empty;
}
}
public class RegexGroupMatch
{
/// <summary>
/// 1~
/// </summary>
public int GroupNo { get; set; }
/// <summary>
/// RID,SID,VLOT,MFG,PART,QTY,CUST,CUSTCODE,VNAME,
/// </summary>
public string TargetPos { get; set; }
public RegexGroupMatch()
{
GroupNo = 0;
TargetPos = string.Empty;
}
}
}

View File

@@ -0,0 +1,184 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Project.Class
{
public enum eStatusMesage : byte
{
Front = 0,
Rear,
TopJig,
Main,
}
public class StatusMessage
{
Dictionary<eStatusMesage, StatusMessageFormat> message;
public StatusMessage()
{
this.message = new Dictionary<eStatusMesage, StatusMessageFormat>();
}
public StatusMessageFormat get(eStatusMesage msg)
{
lock (this.message)
{
if (this.message.ContainsKey(msg) == false)
{
var nemsg = new StatusMessageFormat
{
Message = string.Empty
};
this.message.Add(msg, nemsg);
return nemsg;
}
else
return this.message[msg];
}
}
public void Clear()
{
}
public void set(eStatusMesage msg, StatusMessageFormat data)
{
lock (this.message)
{
if (this.message.ContainsKey(msg) == false)
this.message.Add(msg, data);
else
this.message[msg] = data;
}
}
public void set(eStatusMesage msg, string data, int progval = 0, int progmax = 0)
{
if (data.StartsWith("[") && data.Contains("]"))
{
var buf = data.Split(']');
var cate = buf[0].Substring(1);
var body = string.Join("]", buf, 1, buf.Length - 1);
set(msg, cate, body, Color.Black, progval, progmax);
}
else set(msg, string.Empty, data, Color.Black, progval, progmax);
}
//public void set(eStatusMesage msg, string cate, string data, int progval = 0, int progmax = 0)
//{
// set(msg, cate, data, Color.Black, progval, progmax);
//}
public void set(eStatusMesage msg, string cate, string data, Color fColor, int progval = 0, int progmax = 0)
{
lock (this.message)
{
if (this.message.ContainsKey(msg) == false)
{
var nemsg = new StatusMessageFormat
{
Category = cate,
Message = data,
fColor = fColor,
ProgressMax = progmax,
ProgressValue = progval
};
this.message.Add(msg, nemsg);
}
else
{
var m = this.message[msg];
m.Category = cate;
m.Message = data;
m.fColor = fColor;
if (progval != 0 || progmax != 0)
{
m.ProgressValue = progval;
m.ProgressMax = progmax;
}
}
}
}
public void set(eStatusMesage msg, string data, Color fColor, Color bColor1, Color bColor2)
{
lock (this.message)
{
if (this.message.ContainsKey(msg) == false)
{
var nemsg = new StatusMessageFormat
{
Message = data,
fColor = fColor,
bColor1 = bColor1,
bColor2 = bColor2
};
this.message.Add(msg, nemsg);
}
else
{
var m = this.message[msg];
m.Message = data;
m.fColor = fColor;
m.bColor2 = bColor2;
m.bColor1 = bColor1;
}
}
}
}
public class StatusMessageFormat
{
public string Category { get; set; }
public string Message { get; set; }
public Color fColor { get; set; }
public Color bColor1 { get; set; }
public Color bColor2 { get; set; }
public int ProgressValue { get; set; }
public int ProgressMax { get; set; }
public int ProgressPerc
{
get
{
if (ProgressMax == 0 || ProgressValue == 0) return 0;
return (int)(ProgressValue / (ProgressMax * 1.0));
}
}
public StatusMessageFormat()
{
Clear();
}
void setMessage(string t, string m, Color c)
{
this.Category = t;
this.Message = m;
this.fColor = c;
}
void setMessage(string m, Color c)
{
this.Category = string.Empty;
this.Message = m;
this.fColor = c;
}
public void Clear()
{
ProgressValue = 0;
ProgressMax = 0;
Category = string.Empty;
Message = string.Empty;
fColor = Color.Black;
bColor1 = Color.White;
bColor2 = Color.White;
}
}
}

View File

@@ -0,0 +1,935 @@
using Emgu.CV.Structure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace Project.Class
{
public class VisionData : INotifyPropertyChanged
{
public int RetryLoader { get; set; }
public List<string> bcdMessage { get; set; }
public Boolean LightOn { get; set; }
public DateTime STime; //비젼시작시간
public DateTime ETime; //비젼종료시간
public TimeSpan RunTime { get { return ETime - STime; } } //비젼동작시간
public DateTime GTime; //이미지수집시간
public string FileNameL; //로딩존 촬영
public string FileNameU; //언로딩존 촬영
public Boolean Complete;
//public Boolean AngleQR { get; set; }
//public Boolean AngleSTD { get; set; }
//public double Angle { get; set; }
//public Boolean IsAngleSet
//{
// get
// {
// if (AngleQR == false && AngleSTD == false && Angle == 0.0) return true;
// else return false;
// }
//}
/// <summary>
/// 부착위치에따른 추가회전
/// </summary>
public double PositionAngle { get; set; }
public double ApplyAngle { get; set; } //적용된 회전 각도
public Boolean NeedCylinderForward { get; set; } //부착시 실린더를 올려야하는가
public Boolean ApplyOffset { get; set; }
public Boolean BaseAngle(out string msg, out KeyenceBarcodeData bcd)
{
msg = string.Empty;
bcd = null;
//데이터없다면 회전하지 못한다.
if (this.barcodelist == null || this.barcodelist.Count < 1)
{
msg = "No barcode data";
return false;
}
//사용자가 확정한 코드를 우선으로 한다
KeyValuePair<string, Class.KeyenceBarcodeData> bcddata;
var bcdCanList = barcodelist.Where(t => t.Value.Ignore == false).ToList();
bcddata = bcdCanList.Where(t => t.Value.UserActive).FirstOrDefault();
if (bcddata.Value != null)
{
bcd = bcddata.Value;
msg = "User Active";
return true;
}
//표준바코드를 최우선 으로 사용
//15자리 기존 바코드는 angle 로 사용하지 않는다.
//이것은 각도가 일정치 않게 붙어지기 때문이다
bcddata = bcdCanList.Where(t => t.Value.isSTDBarcode && t.Value.isNewLen15 == false).FirstOrDefault();
if (bcddata.Value != null)
{
bcd = bcddata.Value;
msg = "STD Barcode";
return true;
}
//QR코드를 우선으로 사용 - return 릴은 적용하지 안게한다.
//RQ코드가 적용되지 않게한다 210824
bcddata = bcdCanList.Where(t => t.Value.barcodeSymbol == "1" && t.Value.isNewLen15 == false && t.Value.Data.EndsWith(";;;") == false && t.Value.Data.StartsWith("RQ") == false).FirstOrDefault();
if (bcddata.Value != null)
{
bcd = bcddata.Value;
msg = "QR Code";
return true;
}
//datamatrix, pdf417
bcddata = bcdCanList.Where(t => t.Value.barcodeSymbol != "11" && t.Value.barcodeSymbol != "6" && t.Value.Data.StartsWith("RQ") == false).FirstOrDefault();
if (bcddata.Value != null)
{
bcd = bcddata.Value;
return true;
}
//첫번쨰 아이템을 우선으로 사용
if (bcdCanList.Count == 1)
{
bcd = bcdCanList.First().Value;
msg = "Only One Barcode = " + bcd.Data;
return true;
}
else if (bcdCanList.Count > 1)
{
//여러개가 있음
bcddata = bcdCanList.Where(t => t.Value.barcodeSymbol == "0").FirstOrDefault();
if (bcd != null)
{
bcd = bcddata.Value;
msg = "1D Data";
return true;
}
else
{
bcd = bcdCanList.First().Value;//[0];
msg = $"first({bcd.barcodeSymbol}:{bcd.Data})";
return true;
}
}
else
{
bcd = null;
msg = "no data";
return false;
}
// angle = bcd.Angle;
//return true;
} //모션회전각도
public Boolean Ready { get; set; }
public Boolean ServerUpdate { get; set; }
public Boolean Confirm
{
get
{
return ConfirmAuto || ConfirmUser || ConfirmBypass;
}
}
public Boolean ConfirmUser { get; set; }
public Boolean ConfirmAuto { get; set; }
public bool ConfirmBypass { get; set; }
public Boolean ValidSkipbyUser { get; set; }
private string _rid = string.Empty;
private string _qty = string.Empty;
private string _qty0 = string.Empty;
private string _sid0 = string.Empty;
private string _sid = string.Empty;
private string _rid0 = string.Empty;
private string _vlot = string.Empty;
private string _vname = string.Empty;
private string _mfgdate = string.Empty;
private string _partno = string.Empty;
private string _custcode = string.Empty;
private string _custname = string.Empty;
private string _batch = string.Empty;
private string _qtymax = string.Empty;
private string _mcn = string.Empty;
public bool SID_Trust { get; set; }
public bool RID_Trust { get; set; }
public bool VLOT_Trust { get; set; }
public bool MFGDATE_Trust { get; set; }
public bool QTY_Trust { get; set; }
public bool PARTNO_Trust { get; set; }
public bool VNAME_Trust { get; set; }
public string Target { get; set; }
public string MCN
{
get { return _mcn; }
set { _mcn = value; OnPropertyChanged(); }
}
/// <summary>
/// Original QTY
/// </summary>
public string QTY0
{
get { return _qty0; }
set { _qty0 = value; OnPropertyChanged(); }
}
/// <summary>
/// Qty
/// </summary>
public string QTY
{
get { return _qty; }
set { _qty = value; OnPropertyChanged(); }
}
/// <summary>
/// QTY값이 RQ에서 입력된 데이터인가?
/// </summary>
public Boolean QTYRQ { get; set; }
public string RID0
{
get { return _rid0; }
set { _rid0 = value; OnPropertyChanged(); }
}
public string VLOT
{
get { return _vlot; }
set { _vlot = value; OnPropertyChanged(); }
}
public string VNAME
{
get { return _vname; }
set { _vname = value; OnPropertyChanged(); }
}
public string MFGDATE
{
get { return _mfgdate; }
set { _mfgdate = value; OnPropertyChanged(); }
}
public string PARTNO
{
get { return _partno; }
set { _partno = value; OnPropertyChanged(); }
}
/// <summary>
/// Original SID
/// </summary>
public string SID0
{
get { return _sid0; }
set { _sid0 = value; OnPropertyChanged(); }
}
public string BATCH
{
get
{
return _batch;
}
set
{
_batch = value; OnPropertyChanged();
}
}
public string QTYMAX
{
get
{
return _qtymax;
}
set
{
_qtymax = value; OnPropertyChanged();
}
}
public string SID
{
get { return _sid; }
set { _sid = value; OnPropertyChanged(); }
}
private void OnPropertyChanged([CallerMemberName] string caller = "")
{
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(caller));
}
/// <summary>
/// Reel ID
/// </summary>
public string RID
{
get { return _rid; }
private set { _rid = value; OnPropertyChanged(); }
}
/// <summary>
/// 릴 ID를 설정합니다.trust 상태를 자동으로 true 값으로 전환합니다
/// </summary>
/// <param name="value"></param>
/// <param name="reason"></param>
public void SetRID(string value, string reason)
{
//값이 변경될때 로그에 변경
if (_rid.Equals(value) == false)
{
PUB.AddDebugLog(string.Format("RID 변경 {0} -> {1} by {2}", _rid, value, reason));
}
RID = value;
RID_Trust = true;
}
public Boolean RIDNew { get; set; }
public Boolean HASHEADER { get; set; }
public string CUSTCODE
{
get { return _custcode; }
set { _custcode = value; OnPropertyChanged(); }
}
public string CUSTNAME
{
get { return _custname; }
set { _custname = value; OnPropertyChanged(); }
}
/// <summary>
/// 데이터가 모두존재하는지 확인
/// </summary>
public Boolean DataValid
{
get
{
if (Confirm == false) return false;
return QTY.isEmpty() == false &&
SID.isEmpty() == false &&
RID.isEmpty() == false &&
VLOT.isEmpty() == false &&
VNAME.isEmpty() == false &&
MFGDATE.isEmpty() == false &&
PARTNO.isEmpty();
}
}
public Boolean PrintPositionCheck { get; set; }
public string PrintPositionData { get; set; }
//상단위치에 프린트를 할것인가?
//프린트위치에 따른다
public ePrintPutPos GetPrintPutPosition()
{
//하단에 찍는경우이다
if (PrintPositionData == "1" ||
PrintPositionData == "2" ||
PrintPositionData == "3")
{
return ePrintPutPos.Bottom;
}
else if (PrintPositionData == "7" ||
PrintPositionData == "8" ||
PrintPositionData == "9")
{
return ePrintPutPos.Top;
}
else if (PrintPositionData == "4") //왼쪽
{
if (ReelSize == eCartSize.Inch7)
return ePrintPutPos.Top;
else
return ePrintPutPos.Middle;
}
else if (PrintPositionData == "6") //오른쪽
{
if (ReelSize == eCartSize.Inch7)
return ePrintPutPos.Top;
else
return ePrintPutPos.Middle;
}
else return ePrintPutPos.None;
}
//public string LabelPos { get; set; }
//public Boolean PrintForce { get; set; }
public eCartSize ReelSize { get; set; }
public string QTY2 { get; set; } //바코드수량
public string SID2 { get; set; } //바코드
public string RID2 { get; set; } //바코드
public string VLOT2 { get; set; }
public string VNAME2 { get; set; }
public string MFGDATE2 { get; set; }
public string PARTNO2 { get; set; }
public Emgu.CV.Mat imageF { get; private set; } //최종수집된 이미지
public Emgu.CV.Mat imageR { get; private set; } //최종수집된 이미지
public void SetImage(Emgu.CV.Mat imgF_, Emgu.CV.Mat imgR_)
{
if (this.imageF != null)
{
this.imageF.Dispose();
this.imageF = null;
}
//이미지를 신규로 해석하고 데이터를 복사한다 210121
this.imageF = new Emgu.CV.Mat(imgF_.Size, Emgu.CV.CvEnum.DepthType.Cv8U, 1);
imgF_.CopyTo(this.imageF);
if (this.imageR != null)
{
this.imageR.Dispose();
this.imageR = null;
}
//이미지를 신규로 해석하고 데이터를 복사한다 210121
this.imageR = new Emgu.CV.Mat(imgF_.Size, Emgu.CV.CvEnum.DepthType.Cv8U, 1);
imgR_.CopyTo(this.imageR);
}
public void SetImage(Emgu.CV.Mat img_)
{
if (this.imageF != null)
{
this.imageF.Dispose();
this.imageF = null;
}
if (this.imageR != null)
{
this.imageR.Dispose();
this.imageR = null;
}
//이미지를 신규로 해석하고 데이터를 복사한다 210121
this.imageF = new Emgu.CV.Mat(img_.Size, Emgu.CV.CvEnum.DepthType.Cv8U, 1);
img_.CopyTo(this.imageF);
}
public System.Drawing.Color GetColorByBarcodeCount(int idx)
{
if (QRPositionData[idx] > 0) return Color.Gold; //QR데이터가있다면 금색으로 한다
var Cnt = LabelPositionData[idx];
if (Cnt == MaxBarcodePosData) return Color.Purple;
else if (Cnt == 0) return Color.FromArgb(32, 32, 32);
{
//나머진 숫자별로 데이터를 표시한다 (
var GValue = Cnt * 10;
if (GValue > 255) GValue = 255;
return Color.FromArgb(32, 32, GValue);
}
}
public Boolean isMaxBarcodePosition(int idx)
{
return LabelPositionData[idx] == MaxBarcodePosData;
}
public byte[] QRPositionData { get; private set; }
public byte[] LabelPositionData { get; private set; }
public ConcurrentDictionary<String, Class.KeyenceBarcodeData> barcodelist;
public Boolean BarcodeTouched = false;
public event PropertyChangedEventHandler PropertyChanged;
//리더기로부터 읽은 자료 모두가 들어잇다
//public List<Class.KeyenceBarcodeData> barcodelist
//{
// get { return _barcodelist; }
// set
// {
// this._barcodelist = value;
// UpdateBarcodePositionData();
// }
//}
public byte MaxBarcodePosData { get; private set; }
/// <summary>
/// 바코드목록을 이용해서 라벨위치 분포값을 변경합낟.
/// 해당 위치값은 labelposdata로 접근가능함
/// </summary>
public void UpdateBarcodePositionData()
{
LabelPositionData[0] = (byte)barcodelist.Where(t => t.Value.LabelPosition == 1).Count();
LabelPositionData[1] = (byte)barcodelist.Where(t => t.Value.LabelPosition == 2).Count();
LabelPositionData[2] = (byte)barcodelist.Where(t => t.Value.LabelPosition == 3).Count();
LabelPositionData[3] = (byte)barcodelist.Where(t => t.Value.LabelPosition == 4).Count();
LabelPositionData[4] = (byte)barcodelist.Where(t => t.Value.LabelPosition == 6).Count();
LabelPositionData[5] = (byte)barcodelist.Where(t => t.Value.LabelPosition == 7).Count();
LabelPositionData[6] = (byte)barcodelist.Where(t => t.Value.LabelPosition == 8).Count();
LabelPositionData[7] = (byte)barcodelist.Where(t => t.Value.LabelPosition == 9).Count();
QRPositionData[0] = (byte)barcodelist.Where(t => t.Value.LabelPosition == 1 && t.Value.AmkorData.isValid).Count();
QRPositionData[1] = (byte)barcodelist.Where(t => t.Value.LabelPosition == 2 && t.Value.AmkorData.isValid).Count();
QRPositionData[2] = (byte)barcodelist.Where(t => t.Value.LabelPosition == 3 && t.Value.AmkorData.isValid).Count();
QRPositionData[3] = (byte)barcodelist.Where(t => t.Value.LabelPosition == 4 && t.Value.AmkorData.isValid).Count();
QRPositionData[4] = (byte)barcodelist.Where(t => t.Value.LabelPosition == 6 && t.Value.AmkorData.isValid).Count();
QRPositionData[5] = (byte)barcodelist.Where(t => t.Value.LabelPosition == 7 && t.Value.AmkorData.isValid).Count();
QRPositionData[6] = (byte)barcodelist.Where(t => t.Value.LabelPosition == 8 && t.Value.AmkorData.isValid).Count();
QRPositionData[7] = (byte)barcodelist.Where(t => t.Value.LabelPosition == 9 && t.Value.AmkorData.isValid).Count();
MaxBarcodePosData = LabelPositionData.Max(t => t);
}
/// <summary>
/// Data1(인쇄전 인식데이터) 과 Data2(QR)가 동일한지 비교합니다.
/// </summary>
public Boolean MatchValidation
{
get
{
if (PARTNO == null) this.PARTNO = string.Empty;
if (PARTNO2 == null) this.PARTNO2 = string.Empty;
if (QTY == null) QTY = string.Empty;
if (QTY2 == null) QTY2 = string.Empty;
if (SID == null) SID = string.Empty;
if (SID2 == null) SID2 = string.Empty;
if (VLOT == null) VLOT = string.Empty;
if (VLOT2 == null) VLOT2 = string.Empty;
if (PARTNO == null) PARTNO = string.Empty;
if (PARTNO2 == null) PARTNO2 = string.Empty;
if (QTY.Equals(QTY2) == false)
{
PUB.log.AddE(string.Format("QR검증실패 수량:{0} != {1}", QTY, QTY2));
return false;
}
if (RID.Equals(RID2) == false)
{
PUB.log.AddE(string.Format("QR검증실패 RID:{0} != {1}", RID, RID2));
return false;
}
if (VLOT.Equals(VLOT2) == false)
{
PUB.log.AddE(string.Format("QR검증실패 VLOT:{0} != {1}", VLOT, VLOT2));
return false;
}
if (PARTNO.Equals(PARTNO2) == false)
{
PUB.log.AddE(string.Format("QR검증실패 PARTNO:{0} != {1}", PARTNO, PARTNO2));
return false;
}
if (SID.Equals(SID2) == false)
{
PUB.log.AddE(string.Format("QR검증실패 SID:{0} != {1}", SID, SID2));
return false;
}
return true;
}
}
public string QRInputRaw { get; set; } //입력에 사용한 RAW
public string QROutRaw { get; set; } //부착된 QR코드의 값
public string ZPL { get; set; } //출력시 사용한 ZPL
public string PrintQRData { get; set; } //출력시 사용한 ZPL에 포함된 QR데이터
public string LastQueryString = string.Empty;
public VisionData(string reason)
{
Clear(reason, false);
}
public Boolean isEmpty()
{
return RID.isEmpty();
}
public void Clear(string reason, Boolean timeBackup)
{
LastQueryString = string.Empty;
RetryLoader = 0;
ApplyOffset = false;
var baktime = new DateTime(1982, 11, 23);
if (timeBackup) baktime = this.STime;
bcdMessage = new List<string>();
PositionAngle = 0;
HASHEADER = false;
CUSTCODE = string.Empty;
CUSTNAME = string.Empty;
RID0 = string.Empty;
RIDNew = false;
LightOn = false;
//SCODE = string.Empty;
ValidSkipbyUser = false;
NeedCylinderForward = false;
ApplyAngle = 0;
MaxBarcodePosData = 0;
PrintPositionCheck = false;
LabelPositionData = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
QRPositionData = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
ReelSize = eCartSize.None;
// PrintForce = false;
ConfirmAuto = false;
ConfirmUser = false;
ConfirmBypass = false;
if (imageF != null)
{
imageF.Dispose();
imageF = null;
}
if (imageR != null)
{
imageR.Dispose();
imageR = null;
}
ServerUpdate = false;
PrintPositionData = "";
//LabelPos = "";
if (barcodelist != null) barcodelist.Clear();
else barcodelist = new ConcurrentDictionary<string, KeyenceBarcodeData>();
QRInputRaw = string.Empty;
QROutRaw = string.Empty;
ZPL = string.Empty;
PrintQRData = string.Empty;
STime = baktime;// DateTime.Parse("1982-11-23");
ETime = DateTime.Parse("1982-11-23");
GTime = DateTime.Parse("1982-11-23");
Complete = false;
//Angle = 0.0;
//AngleQR = false;
//AngleSTD = false;
MCN = string.Empty;
Target = string.Empty;
Ready = false;
QTY0 = string.Empty;
QTY = string.Empty;// string.Empty;
QTYRQ = false;
//PUB.log.AddI($"비젼개체 CLEAR 로 RQ 상태 초기화(false)");
BATCH = string.Empty;
QTYMAX = string.Empty;
SID0 = string.Empty;
SID = string.Empty;
//RID = string.Empty;
SetRID(string.Empty, reason);
VLOT = string.Empty;
MFGDATE = string.Empty;
VNAME = string.Empty;
PARTNO = string.Empty;
QTY2 = "0";// string.Empty;
SID2 = string.Empty;
RID2 = string.Empty;
VLOT2 = string.Empty;
MFGDATE2 = string.Empty;
VNAME2 = string.Empty;
PARTNO2 = string.Empty;
FileNameL = string.Empty;
FileNameU = string.Empty;
MFGDATE_Trust = false;
PARTNO_Trust = false;
QTY_Trust = false;
SID_Trust = false;
RID_Trust = false;
VLOT_Trust = false;
VNAME_Trust = false;
BarcodeTouched = false;
MCN = string.Empty;
Target = string.Empty;
PUB.log.Add($"비젼데이터삭제({reason})");
}
public void CopyTo(ref VisionData obj)
{
//바코드메세지 복사
obj.bcdMessage = new List<string>();
foreach (var item in this.bcdMessage)
obj.bcdMessage.Add(item);
obj.ApplyOffset = this.ApplyOffset;
obj.ConfirmAuto = this.ConfirmAuto;
obj.ConfirmUser = this.ConfirmUser;
obj.CUSTCODE = this.CUSTCODE;
obj.CUSTNAME = this.CUSTNAME;
obj.LightOn = this.LightOn;
//obj.SCODE = this.SCODE;
obj.ValidSkipbyUser = this.ValidSkipbyUser;
obj.NeedCylinderForward = this.NeedCylinderForward; //210207
obj.ApplyAngle = this.ApplyAngle; //210207
obj.STime = this.STime;
obj.ETime = this.ETime;
obj.GTime = this.GTime;
obj.FileNameL = this.FileNameL;
obj.FileNameU = this.FileNameU;
obj.Complete = this.Complete;
//obj.Angle = this.Angle;
//obj.AngleQR = this.AngleQR;
//obj.AngleSTD = this.AngleSTD;
obj.BATCH = this.BATCH;
obj.QTYMAX = this.QTYMAX;
obj.Ready = this.Ready;
obj.QTY = this.QTY;
obj.QTYRQ = this.QTYRQ;
obj.SID = this.SID;
obj.SID0 = this.SID0; //210331
obj.SetRID(this.RID, "copy");// obj.RID = this.RID;
obj.RID0 = this.RID0;
obj.RIDNew = this.RIDNew;
obj.VLOT = this.VLOT;
obj.VNAME = this.VNAME;
obj.MFGDATE = this.MFGDATE;
obj.PARTNO = this.PARTNO;
obj.MCN = this.MCN;
obj.Target = this.Target;
obj.QTY2 = this.QTY2;
obj.SID2 = this.SID2;
obj.RID2 = this.RID2;
obj.VLOT2 = this.VLOT2;
obj.VNAME2 = this.VNAME2;
obj.MFGDATE2 = this.MFGDATE;
obj.PARTNO2 = this.PARTNO2;
obj.QRInputRaw = this.QRInputRaw;
obj.QROutRaw = this.QROutRaw;
obj.ZPL = this.ZPL;
obj.PrintQRData = this.PrintQRData;
obj.PrintPositionData = this.PrintPositionData;
//obj.PrintForce = this.PrintForce;
obj.ReelSize = this.ReelSize;
obj.PrintPositionCheck = this.PrintPositionCheck;
obj.BarcodeTouched = this.BarcodeTouched;
//라벨위치값 복사
for (int i = 0; i < obj.LabelPositionData.Length; i++)
obj.LabelPositionData[i] = this.LabelPositionData[i];
for (int i = 0; i < obj.QRPositionData.Length; i++)
obj.QRPositionData[i] = this.QRPositionData[i];
if (obj.imageF != null)
{
obj.imageF.Dispose();
obj.imageF = null;
}
if (obj.imageR != null)
{
obj.imageR.Dispose();
obj.imageR = null;
}
//이미지를 복사해준다. 210121
if (this.imageF != null)
{
obj.imageF = new Emgu.CV.Mat(this.imageF.Size, Emgu.CV.CvEnum.DepthType.Cv8U, 1);
this.imageF.CopyTo(obj.imageF);
}
if (this.imageR != null)
{
obj.imageR = new Emgu.CV.Mat(this.imageR.Size, Emgu.CV.CvEnum.DepthType.Cv8U, 1);
this.imageR.CopyTo(obj.imageR);
}
//바코드 데이터를 복사해준다.
if (obj.barcodelist == null)
obj.barcodelist = new ConcurrentDictionary<string, KeyenceBarcodeData>();// List<KeyenceBarcodeData>();
else
obj.barcodelist.Clear();
foreach (var item in this.barcodelist)
{
var bcd = item.Value;
var newitema = new KeyenceBarcodeData
{
Angle = bcd.Angle,
CenterPX = new Point(bcd.CenterPX.X, bcd.CenterPX.Y),
Data = bcd.Data,
LabelPosition = bcd.LabelPosition,
UserActive = bcd.UserActive,
barcodeSymbol = bcd.barcodeSymbol,
};
newitema.vertex = new Point[bcd.vertex.Length];
bcd.vertex.CopyTo(newitema.vertex, 0);
if (bcd.AmkorData != null) //231006 null error fix
bcd.AmkorData.CopyTo(newitema.AmkorData);
obj.barcodelist.AddOrUpdate(item.Key, newitema,
(key, data) =>
{
data.Angle = newitema.Angle;
data.CenterPX = newitema.CenterPX;
data.Data = newitema.Data;
data.LabelPosition = newitema.LabelPosition;
data.UserActive = newitema.UserActive;
data.barcodeSymbol = newitema.barcodeSymbol;
data.RegExConfirm = newitema.RegExConfirm;
return data;
});
}
}
public void UpdateTo(ref VisionData obj)
{
//바코드메세지 복사
obj.bcdMessage = new List<string>();
foreach (var item in this.bcdMessage)
obj.bcdMessage.Add(item);
obj.ApplyOffset = this.ApplyOffset;
obj.ConfirmAuto = this.ConfirmAuto;
obj.ConfirmUser = this.ConfirmUser;
obj.CUSTCODE = this.CUSTCODE;
obj.CUSTNAME = this.CUSTNAME;
obj.LightOn = this.LightOn;
//obj.SCODE = this.SCODE;
obj.ValidSkipbyUser = this.ValidSkipbyUser;
obj.NeedCylinderForward = this.NeedCylinderForward; //210207
obj.ApplyAngle = this.ApplyAngle; //210207
obj.STime = this.STime;
obj.ETime = this.ETime;
obj.GTime = this.GTime;
obj.FileNameL = this.FileNameL;
obj.FileNameU = this.FileNameU;
obj.Complete = this.Complete;
//obj.Angle = this.Angle;
//obj.AngleQR = this.AngleQR;
//obj.AngleSTD = this.AngleSTD;
obj.Ready = this.Ready;
obj.QTY = this.QTY;
obj.QTYRQ = this.QTYRQ;
obj.SID = this.SID;
obj.SID0 = this.SID0; //210331
obj.SetRID(this.RID, "copy");// obj.RID = this.RID;
obj.RID0 = this.RID0;
obj.RIDNew = this.RIDNew;
obj.VLOT = this.VLOT;
obj.VNAME = this.VNAME;
obj.MFGDATE = this.MFGDATE;
obj.PARTNO = this.PARTNO;
obj.MCN = this.MCN;
obj.Target = this.Target;
obj.BATCH = this.BATCH;
obj.QTYMAX = this.QTYMAX;
obj.QTY2 = this.QTY2;
obj.SID2 = this.SID2;
obj.RID2 = this.RID2;
obj.VLOT2 = this.VLOT2;
obj.VNAME2 = this.VNAME2;
obj.MFGDATE2 = this.MFGDATE;
obj.PARTNO2 = this.PARTNO2;
obj.QRInputRaw = this.QRInputRaw;
obj.QROutRaw = this.QROutRaw;
obj.ZPL = this.ZPL;
obj.PrintQRData = this.PrintQRData;
obj.PrintPositionData = this.PrintPositionData;
//obj.PrintForce = this.PrintForce;
obj.ReelSize = this.ReelSize;
obj.PrintPositionCheck = this.PrintPositionCheck;
obj.BarcodeTouched = this.BarcodeTouched;
//라벨위치값 복사
for (int i = 0; i < obj.LabelPositionData.Length; i++)
obj.LabelPositionData[i] = this.LabelPositionData[i];
for (int i = 0; i < obj.QRPositionData.Length; i++)
obj.QRPositionData[i] = this.QRPositionData[i];
if (obj.imageF != null)
{
obj.imageF.Dispose();
obj.imageF = null;
}
if (obj.imageR != null)
{
obj.imageR.Dispose();
obj.imageR = null;
}
//이미지를 복사해준다. 210121
if (this.imageF != null)
{
obj.imageF = new Emgu.CV.Mat(this.imageF.Size, Emgu.CV.CvEnum.DepthType.Cv8U, 1);
this.imageF.CopyTo(obj.imageF);
}
if (this.imageR != null)
{
obj.imageR = new Emgu.CV.Mat(this.imageR.Size, Emgu.CV.CvEnum.DepthType.Cv8U, 1);
this.imageR.CopyTo(obj.imageR);
}
//바코드 데이터를 복사해준다.
if (obj.barcodelist == null)
obj.barcodelist = new ConcurrentDictionary<string, KeyenceBarcodeData>();// List<KeyenceBarcodeData>();
else
obj.barcodelist.Clear();
foreach (var item in this.barcodelist)
{
var bcd = item.Value;
var newitema = new KeyenceBarcodeData
{
Angle = bcd.Angle,
CenterPX = new Point(bcd.CenterPX.X, bcd.CenterPX.Y),
Data = bcd.Data,
LabelPosition = bcd.LabelPosition,
UserActive = bcd.UserActive,
barcodeSymbol = bcd.barcodeSymbol,
};
newitema.vertex = new Point[bcd.vertex.Length];
bcd.vertex.CopyTo(newitema.vertex, 0);
bcd.AmkorData.CopyTo(newitema.AmkorData);
obj.barcodelist.AddOrUpdate(item.Key, newitema,
(key, data) =>
{
data.Angle = newitema.Angle;
data.CenterPX = newitema.CenterPX;
data.Data = newitema.Data;
data.LabelPosition = newitema.LabelPosition;
data.UserActive = newitema.UserActive;
data.barcodeSymbol = newitema.barcodeSymbol;
data.RegExConfirm = newitema.RegExConfirm;
return data;
});
}
}
}
}

View File

@@ -0,0 +1,86 @@
using System;
namespace Project
{
[Serializable]
public class sPositionData
{
public float inpositionrange { get; set; }
public int Axis;
public double Position { get; set; }
public double Acc;
public double _dcc;
public double Dcc
{
get
{
if (_dcc == 0) return Acc;
else return _dcc;
}
set
{
_dcc = value;
}
}
public double Speed;
public Boolean isError { get { return Speed == 0; } }
public string Message;
public sPositionData(sPositionData baseData)
{
this.Clear();
this.Position = baseData.Position;
this.Acc = baseData.Acc;
this.Dcc = baseData.Dcc;
this._dcc = baseData._dcc;
this.Speed = baseData.Speed;
this.Axis = baseData.Axis;
this.Message = baseData.Message;
this.inpositionrange = baseData.inpositionrange;
}
public sPositionData Clone()
{
return new sPositionData
{
Position = this.Position,
Acc = this.Acc,
Dcc = this.Dcc,
//isError = this.isError,
Message = this.Message,
Speed = this.Speed,
_dcc = this.Dcc,
Axis = this.Axis,
inpositionrange = this.inpositionrange,
};
}
public sPositionData()
{
Clear();
}
public sPositionData(double pos)
{
Clear();
this.Position = pos;
}
//public void SetPosition(double pos) { this.Position = pos; }
public void Clear()
{
Axis = -1;
inpositionrange = 0f;
Position = 0;
Acc = 500;
_dcc = 0;
Speed = 0;
Message = "Not Set";
}
public override string ToString()
{
return $"Pos:{Position},Spd:{Speed}";
}
}
}