Add QRValidation project to repository

- Added QRValidation vision control system
- Includes CapCleaningControl UI components
- WebSocket-based barcode validation system
- Support for Crevis PLC integration
- Test projects for PLC emulator, motion, IO panel, and Modbus

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
atvstdla
2025-10-02 11:38:38 +09:00
parent 3eac3927f8
commit dc66158497
192 changed files with 27168 additions and 0 deletions

View File

@@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Project.Class
{
public class CAmkorSTDBarcode
{
public string Message { get; private set; }
public Boolean isValid = false;
public string SID { get; private set; }
public string VLOT { get; private set; }
public string RID { get; private set; }
public string MFGDate { get; set; }
public string SUPPLY { get; set; }
public int QTY { get; set; }
public string RAW { get; set; }
public Boolean DateError { get; set; }
public CAmkorSTDBarcode()
{
isValid = false;
}
public CAmkorSTDBarcode(string raw)
{
SetBarcode(raw);
}
public void SetBarcodeDemo()
{
SetBarcode("101410653;AG64B3W;SAMSUNG;20000;AG64B3W0031;19000101;");
}
/// <summary>
/// Returns barcode value with current property values.
/// To check the original barcode value, check the RAW property
/// </summary>
/// <returns></returns>
public string GetBarcode()
{
return string.Format("{0};{1};{2};{3};{4};{5};",
SID, VLOT, SUPPLY, QTY, RID, MFGDate);
}
public void SetBarcode(string raw)
{
isValid = false;
this.Message = string.Empty;
this.RAW = raw;
var buf = raw.Split(';');
if (buf.Length < 5)
{
isValid = false;
Message = "buffer len error : " + raw;
return;
}
decimal vSID = 0;
double vQty = 0;
if (decimal.TryParse(buf[0], out vSID) == false)
{
Message = "SID value is not a number. Amkor STD barcode consists of numbers";
return;
}
this.SID = vSID.ToString();
this.VLOT = buf[1];
this.SUPPLY = buf[2];
if (double.TryParse(buf[3], out vQty) == false) return;
this.QTY = (int)vQty;
this.RID = buf[4];
//DateTime vMFGDate;
MFGDate = buf[5].Trim();
DateError = false;
//buf[5] = buf[5].Replace("-", ""); //날짜표식제거
//if (this.SUPPLY.ToUpper() == "SAMSUNG" && buf[5].Length == 4) //삼성은 년도와 주차로 입력한다 210202
//{
// var y = "20" + buf[5].Substring(0, 2);
// MFGDate = new DateTime(int.Parse(y), 1, 1).ToString("yyyyMMdd"); //주차계산무시한다
// DateError = true;
//}
//else if (this.SUPPLY.ToUpper() == "WT" && buf[5].Length == 4) //삼성은 년도와 주차로 입력한다 210202
//{
// var y = "20" + buf[5].Substring(0, 2);
// MFGDate = new DateTime(int.Parse(y), 1, 1).ToString("yyyyMMdd"); //주차계산무시한다
// DateError = true;
//}
//else if (buf[5].Length == 8) //일반적인날짜데이터이며 YYYYMMDD 형태이다
//{
// buf[5] = buf[5].Substring(0, 4) + "-" + buf[5].Substring(4, 2) + "-" + buf[5].Substring(6, 2);
// if (DateTime.TryParse(buf[5], out vMFGDate) == false) return;
// MFGDate = vMFGDate.ToString("yyyyMMdd");
// DateError = false;
//}
////else if (buf[5].Equals("N/A")) //날짜값에 NA
////{
//// MFGDate = "N/A";
//// DateError = false;
////}
////else if (buf[5].Equals("NA")) //날짜값에 NA
////{
//// MFGDate = "NA";
//// DateError = false;
////}
//else
//{
// MFGDate = buf[5].Trim();
// Message = "Date value Length Error : " + buf[5];
// DateError = false;
// //return;
//}
isValid = true;
}
}
}

View File

@@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Project
{
public class CInterLock
{
UInt64 offsetValue = 0x01;
public object Tag { get; set; }
public string errorMessage;
protected UInt64 _value;
public UInt64 Value { get { return _value; } set { _value = value; } }
public event EventHandler<ValueEventArgs> ValueChanged;
public class ValueEventArgs : EventArgs
{
private int _arridx;
private Boolean _oldvalue;
private Boolean _newvalue;
private string _reason;
public int ArrIDX { get { return _arridx; } }
public Boolean OldValue { get { return _oldvalue; } }
public Boolean NewValue { get { return _newvalue; } }
public string Reason { get { return _reason; } }
public Boolean NewOn { get; set; }
public Boolean NewOff { get; set; }
public ValueEventArgs(int arridx, Boolean oldvalue, Boolean newvalue, string reason_, Boolean newon_, Boolean newof_)
{
_arridx = arridx;
_oldvalue = oldvalue;
_newvalue = newvalue;
_reason = reason_;
this.NewOn = newon_;
this.NewOff = newon_;
}
}
public CInterLock(object tag = null)
{
errorMessage = string.Empty;
_value = 0;
this.Tag = tag;
}
public Boolean get(int idx)
{
if (idx >= 64)
throw new Exception("flag는 최대 64개를 지원 합니다");
var offset = (UInt64)(offsetValue << idx);
return (_value & offset) != 0;
}
public void set(int idx, Boolean value, string reason)
{
if (idx >= 64)
throw new Exception("flag는 최대 64개를 지원 합니다");
var oldvalue = get(idx);
var raw_old = _value;
if (value)
{
var offset = (UInt64)(offsetValue << idx);
_value = _value | offset;
}
else
{
var shiftvalue = (UInt64)(offsetValue << idx);
UInt64 offset = ~shiftvalue;
_value = _value & offset;
}
if (oldvalue != value)
{
Boolean NewOn = (raw_old == 0 && _value > 0);
Boolean NewOf = (raw_old != 0 && _value == 0);
if (ValueChanged != null)
ValueChanged(this, new ValueEventArgs(idx, oldvalue, value, reason, NewOn, NewOf));
}
else
{
//Pub.log.Add(" >> SKIP");
//if (string.IsNullOrEmpty(reason) == false)
//Pub.log.Add("#### FLAG변경(값이 같아서 처리 안함) : idx=" + idx.ToString() + ",값:" + value.ToString() + ",사유:" + reason);
}
}
public void Toggle(int idx, string reason = "")
{
var curValue = get(idx);
set(idx, !curValue, reason);
}
}
}

View File

@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Project
{
public enum eFlag
{
CHECKLICENSE=0,
CHECKCAMERAL,
CHECKCAMERAR,
CAMERAINIT,
}
public class Flag : CInterLock
{
public Boolean IsInit; //H/W설정이 안된경우에만 FALSE로 한다
public int PortCount;
public string[] Name;
public Flag()
{
this.Tag = "MAIN";
PortCount = 64;
IsInit = true;
errorMessage = string.Empty;
_value = 0;
Name = new string[PortCount];
for (int i = 0; i < Name.Length; i++)
{
Name[i] = string.Empty;
}
}
public bool get(eFlag flag)
{
return get((int)flag);
}
public void set(eFlag flag, bool value, string reason)
{
var idx = (int)flag;
set(idx, value, reason);
}
public void Toggle(eFlag flag)
{
Toggle((int)flag);
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Project.Class
{
public class WebSocket : WatsonWebsocket.WatsonWsServer
{
public eTarget Target { get; set; }
public int TargetIdx { get; set; }
public WebSocket(string host, int port) : base(host, port) { }
}
}

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Project
{
public static class Win32API
{
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
private static extern int SetActiveWindow(int hwnd);
}
}