2026-01-26 18:56:53 +09:00

1940 lines
86 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Aurora.Api;
using Aurora.Api.Devices;
using Hermes;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
namespace AuroraOCT.IPG
{
#region LDD700 Failure Codes
enum eLDDErr
{
NOERROR = 0,
ACK = 0,
NCK,
INV, // Invalid Argument
NAV, // Not Available
NMM, // Not in Manual Mode
NRM, // Not in Remote Mode
// OmniWELD Failure Codes
DTBR, // Distance Based QA: Below Range - Maximum Total Distance (WU)
DCBR, // Distance Based QA: Below Range - Maximum Consecutive Distance (WU)
DTIR, // Distance Based QA: In Range - Minimum Total Distance (WU)
DCIR, // Distance Based QA: In Range - Minimum Consecutive Distance (WU)
DTAR, // Distance Based QA: Above Range - Maximum Total Distance (WU)
DCAR, // Distance Based QA: Above Range - Maximum Consecutive Distance (WU)
DTOR, // Distance Based QA: Out of Range - Maximum Total Distance (WU)
DCOR, // Distance Based QA: Out of Range - Maximum Consecutive Distance (WU)
DTNS, // Distance Based QA: No Signal - Maximum Total Distance (WU)
DCNS, // Distance Based QA: No Signal - Maximum Consecutive Distance (WU)
// Reference Plane Failure Modes
ISRP, //Incorrect Side of Reference Plane
UNVI, //Unverified Interface
MISS, //Missing Interface
TLCP, //Intensity Threshold Level too Close to Peak
TOUT, //Measurement Time Out
}
#endregion
#region LDD700 Job Results
public enum eLDDResult
{
OK, // Job passed all QA requirements
NOK, // Job failed at least one QA requirement
NOQA, // No QA was enabled in the job or the job was masked during operation
X // Job was not run and was part of a partial sequence (sequence stopped midway through)
}
#endregion
public class LDD700 : SocketConn, IOCT
{
private readonly object _lockObject = new object();
bool IsSimul;
SocketConnConfig config;
public LDD700(string deviceid, bool isSimul) : base(deviceid, isSimul)
{
IsSimul = isSimul;
}
public int Open(OCTConfig Config)
{
if (IsSimul) {
return E1.OK;
}
lock (_lockObject)
{
config = Config.SocketConfig;
return Connect(config);
}
}
public void DisConnect()
{
lock (_lockObject)
{
Close();
}
}
public bool GetConnected()
{
lock (_lockObject)
{
return IsConnected();
}
}
public string GetJobResult()
{
int nRet = -1;
string strResult = "";
//nRet = get_last_seqeunce_result(out strResult);
nRet = get_last_job_result(out strResult);
if (nRet == 0) {
return strResult;
} else {
return "";
}
}
public string GetSequenceResult()
{
int nRet = -1;
string strResult = "";
nRet = get_last_sequence_result(out strResult);
if (nRet == 0) {
return strResult;
} else {
return "";
}
}
public int GetAlarm()
{
/* Error Code , Error Name
* 5022 Reference Plane Connection Error
* 5023 Reference Plane Connection Error
* 5024 Reference Plane Communication Error
* 5100 DeviceNet Error
* 6000 Validation Failure
* 176001 Light Source Toggle Failure
* 176002 I/O Registration Error
*/
int nRet = 0, nErrorCode = 0;
nRet = get_error(out nErrorCode);
if (nRet == (int)eLDDErr.ACK) {
return nErrorCode;
} else {
return 0;
}
}
public int GetEnable()
{
return 0;
}
public int GetRemoteControl()
{
int nRet = 0, nResult = 0;
nRet = get_remote_mode(out nResult);
if (nRet == (int)eLDDErr.ACK) {
return nResult;
} else {
return -1;
}
}
public int GetStatus()
{
int nRet = 0;
string strResult = "";
nRet = get_system_state(out strResult);
if (nRet == (int)eLDDErr.ACK) {
if (strResult == "Ready for Command") {
return 1;
} else if (strResult == "Waiting for Trigger") {
return 2;
} else {
return 0;
}
} else {
return -1;
}
}
public int GetJobComplete()
{
return 0;
}
public int SetProgram(int nProgram) // Set Slot Number And Start
{
int nRet = start(nProgram);
return nRet;
}
public int AddWorkPieceID(string strID)
{
return add_serial_number(strID);
}
public int CheckWorkPieceID(string strID)
{
string strLDDWorkPieceID;
if (get_serial_number(strID, out strLDDWorkPieceID) < 0) {
return -1;
}
if (string.Compare(strID, strLDDWorkPieceID) == 0) {
return 0;
} else {
return -1;
}
}
public int SetRemoteControl(int RemoteMode)
{
int nRet = 0;
nRet = set_remote_mode_type(RemoteMode);
return nRet;
}
public int EnterRemoteMode(int Timeout)
{
int nRet = enter_remote_mode(Timeout);
return nRet;
}
public int ExitRemoteMode()
{
int nRet = exit_remote_mode();
return nRet;
}
#region LDD700 Functions
public int add_serial_number(string strSerialNumber)
{
// Example
//>> add_serial_number “IPGOW SERIAL 001”\r\n
//<< ACK\r\n
//<< “IPGOW SERIAL 001”\r\n
string receivemsg;
int nRet = SendAndRecieveCommand(LDDCommand.ADD_SERIAL_NUMBER, strSerialNumber, out receivemsg);
// receivemsg 처리를 할려면 여기에. strSerialNumber 와 같은 형식으로 오는지 비교를 할 수 있다. 필요하다면..
return nRet;
}
public int get_serial_number(out string strSerialNumber)
{
// Queue 에 여러개 들어가 있어도 맨위에 한개만 가져오는 함수이다. List 를 쓸 필요없음.
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.GET_SERIAL_NUMBER, out receivemsg);
if (nRet == 0) {
strSerialNumber = receivemsg;
} else {
strSerialNumber = ""; // return 은 “<Unassigned>”\r\n 으로 온다. 못받은걸 굳이 보낼필요없을것같다.
}
return nRet;
}
public int get_serial_number(in string strCheckSerialNumber , out string strSerialNumber)
{
// Queue 에 여러개 들어가 있어도 맨위에 한개만 가져오는 함수이다. List 를 쓸 필요없음.
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.GET_SERIAL_NUMBER, strCheckSerialNumber, out receivemsg);
if (nRet == 0) {
strSerialNumber = receivemsg;
} else {
strSerialNumber = ""; // return 은 “<Unassigned>”\r\n 으로 온다. 못받은걸 굳이 보낼필요없을것같다.
}
return nRet;
}
// clear_serial_number() , clear_serial_number(int number)
// serial number 의 clear 를 용접 sw 에서 제어할 것인가? 일단 함수는 만들어둔다.
// clear_serial_number [-e queue_position] , 부분 clear 는 e 옵션.
// ACK : Serial number(s) can be cleared
// NAV : No serial numbers exist in the queue or the system is using internally generated serial numbers
// INV : queue_position exceeds the size of the queue
public int clear_serial_number()
{
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.CLEAR_SERIAL_NUMBER, out receivemsg);
// receivemsg : 지워진 serial들 이름
return nRet;
}
public int clear_serial_number(int nSerialNumber)
{
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.CLEAR_SERIAL_NUMBER, String.Format("-e {0}",nSerialNumber) , out receivemsg);
// receivemsg : 지워진 serial들 이름
return nRet;
}
public int get_lv_ref_plane_pos()
{
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.GET_LIVE_REF_PLANE_POS, out receivemsg);
// receivemsg : numeric , 숫자가 오는데 어떤 data 인지는..
return nRet;
}
// set_lv_ref_plane_pos
// ACK : System in Ready state and not in the Waiting for Trigger state.
// NAV : System is not in the ready state or system is in the waiting for trigger state
// INV : Specified argument is not a numeric value , Number of input arguments is incorrect
public int set_lv_ref_plane_pos(int nRef_Plane_Pos)
{
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.SET_LIVE_REF_PLANE_POS, nRef_Plane_Pos.ToString(), out receivemsg);
// receivemsg : numeric , 제대로 입력되면 입력했던 숫자가 돌아온다. range 초과하면 최대 range 값이 설정되고 돌아온다.
return nRet;
}
// get_error
// ACK : System has errors and will respond with information about the error in the front of the queue.
// NAV : There are no active errors.
// INV : Invalid argument(s) are passed with this command.
// Secondary responses are only sent if the primary response is ACK.
// Error Table:
// 5022 : Reference Plane Connection Error , An attempt was made to move the reference plane when there was no reference plane connection
// 5023 : Reference Plane Connection Error , Unknown error connecting to reference plane motor
// 5024 : Reference Plane Communication Error , Invalid response from reference plane motor
// 5100 : DeviceNet Error , An error has occurred while interfacing the DeviceNet communication driver. More information about this error is included in the error log (please contact an IPGOW technician for assistance). DeviceNet communication has been shut down and will not function until the software is restarted.
// 6000 : Validation Failure , One or more validation checks failed
// 176001 : Light Source Toggle Failure, Timed out waiting for response from RevisionSL2 light source after sending a toggle command
// 176002 : I/O Registration Error, The change detection process did not respond when attempting to change channel registration
public int get_error(out int nErrorCode)
{
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.GET_ERROR, out receivemsg);
// 주의 nRet 가 ACK 가 보통 정상인데, error 는 ACK 가 error 가 정상확인되었다는 뜻임.
// NAV : No Error
// ACK : Error Code 정상 수신
// INV : invaild argument
// Error code parsing 이 귀찮으니까 -desc 옵셧은 생략한다.
if (nRet == (int)eLDDErr.NAV) {
nRet = 0;
nErrorCode = 0;
} else if (nRet == (int)eLDDErr.ACK) {
nRet = 0;
receivemsg.Replace("\r\n", ""); //ex) 5024\r\n 로 오는것을 5024만 남기자
nErrorCode = Convert.ToInt32(receivemsg);
} else {
nRet = (int)eLDDErr.INV;
nErrorCode = 0;
}
return nRet;
}
public int clear_error(bool bCleard)
{
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.GET_ERROR, out receivemsg);
// 주의 nRet 가 ACK 가 보통 정상인데, error 는 ACK 가 error 가 정상확인되었다는 뜻임.
// NAV : No Error
// ACK : Clear 명령 정상 수신
// INV : invaild argument
// Clear Error 를 했는데, Error 가 남아있어도 ACK 로 온다. ACK 가 Error 없음을 뜻하지는 않는다는 뜻.
if (nRet == (int)eLDDErr.NAV) {
// No Error
nRet = 0;
bCleard = true;
} else if (nRet == (int)eLDDErr.ACK) {
nRet = 0;
if (receivemsg.CompareTo("Unhandled Error\r\n") == 0) {
// Clear Error 를 했는데 Error 가 남아있을 경우.
bCleard = false;
} else {
// Error 가 있었는데 Clear 된 경우
// ex) receivemsg : Cleared 5024\r\n
bCleard = true;
}
} else {
nRet = (int)eLDDErr.INV;
bCleard = false;
}
return nRet;
}
public int start_software()
{
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.START_SOFTWARE, out receivemsg);
// Starting Software : Returns this when the software is starting
// ON : Returns this when the software is already running
// Software Executable Missing : The file with the name "IPG OMNIWELD.EXE" does not exist in the expected directory path.
// This command always searches for the software in C:\PROGRAM FILES\IPG PHOTONICS\IPG OMNIWELD\.
// receivemsg 처리 생략
return nRet;
}
public int exit_software()
{
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.EXIT_SOFTWARE, out receivemsg);
// Stopping Software : Returns this when the software is being stopped
// OFF : RReturns this when the software is already off.
// receivemsg 처리 생략
return nRet;
}
public int Restart_software(out bool bRestarted)
{
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.RESTART_SOFTWARE, out receivemsg);
// Restarting Software : Returns this when the software is being restarted
// OFF : Returns this when the software is already off. The software will not be restarted
if (receivemsg.CompareTo("Restarting Software\r\n") == 0) {
bRestarted = true;
} else {
bRestarted = false;
}
return nRet;
}
public int get_software_running(out bool bRunning)
{
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.GET_SOFTWARE_RUNNING, out receivemsg);
if (receivemsg.CompareTo("1\r\n") == 0) {
bRunning = true;
} else {
bRunning = false;
}
return nRet;
}
public int shutdown_computer()
{
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.SHUTDOWN_COMPUTER, out receivemsg);
return nRet;
}
public int restart_computer()
{
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.RESTART_COMPUTER, out receivemsg);
return nRet;
}
public int set_sequence_file(string SeqFileName)
{
//example
//>> set_sequence_file “Sequence File.seq”\r\n
//<< ACK\r\n
//<< Sequence File “Sequence File.seq” Set\r\n
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.SET_SEQUENCE_FILE, SeqFileName, out receivemsg);
return nRet;
}
public int get_remote_mode(out int nRemoteMode)
{
// nRemoteMode = { 0: Not Remote Mode , 1: Remote Job Mode, 2: Remote Sequence Mode.
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.GET_REMOTE_MODE, out receivemsg);
if (receivemsg.CompareTo("OFF\r\n") == 0) {
nRemoteMode = 0;
} else if (receivemsg.CompareTo("Remote Job Mode\r\n") == 0) {
nRemoteMode = 1;
} else if(receivemsg.CompareTo("\"Remote Sequence Mode\r\n") == 0) {
nRemoteMode = 2;
} else {
nRemoteMode = 0;
}
return nRet;
}
public int set_remote_mode_type(int nRemoteMode)
{
// nRemoteMode = { 0: Not Remote Mode , 1: Remote Job Mode, 2: Remote Sequence Mode.
int nRet = 0; // ErrorCode
string receivemsg;
string strArgument;
if (nRemoteMode == 1) {
strArgument = "Job";
} else if (nRemoteMode == 2) {
strArgument = "Sequence";
} else {
return (int)eLDDErr.INV;
}
nRet = SendAndRecieveCommand(LDDCommand.SET_REMOTE_MODE, strArgument, out receivemsg);
return nRet;
}
public int enter_remote_mode(int ntimeout = 30000)
{
//default timeout = 30sec
int nRet = 0; // ErrorCode
string receivemsg;
string strArgument = String.Format("-t {0}",ntimeout);
nRet = SendAndRecieveCommand(LDDCommand.ENTER_REMOTE_MODE, strArgument, out receivemsg);
return nRet;
}
public int exit_remote_mode()
{
//default timeout = 30sec
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.EXIT_REMOTE_MODE, out receivemsg);
return nRet;
}
public int start(int nSlotNumber)
{
// For Remote Job Mode:
// Start X
// For Remote Sequence Mode:
// Start X[-r start_position] [-m mask]
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.START, nSlotNumber.ToString(), out receivemsg);
return nRet;
}
public int start(string strFileName)
{
// For Remote Job Mode:
// Start X
// For Remote Sequence Mode:
// Start X[-r start_position] [-m mask]
// r옵션은 중간 element 부터 시작. 우리 sw 에서 중간부터 시작할 일이 있을까? 중간에 멈췄다면 이미 불량임
// m옵션은 masking 인데 중간 element 를 masking 하고 동작하게 하는것. 역시 필요없을듯.
// m옵션 예를 들면 10개 element 가 있는데 5번, 7번, 10번만 동작하게 하려면 start 1 -m 0000101001\r\n 와 같이 쓴다. 역시 필요없을듯.
// 나중을 위하여 남겨는둔다.
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.START, strFileName, out receivemsg);
return nRet;
}
public int stop()
{
int nRet = 0; // ErrorCode
string receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.STOP, out receivemsg);
return nRet;
}
#region get_last_job_result function descriptions
// 매우 중요 : 마지막 취득했던 job 의 OK/NOK 결과를 받아온다. 즉, 검사 결과를 받아오는 듯함.
// get_last_job_result [-e seq_elem_#]
// Primary Responses
// ACK : Valid Command and data has previously been acquired
// NAV : In Remote Sequence Mode and no sequences have been acquired yet or the last acquisition was done in Remote Job Mode.
// In Remote Job Mode and no jobs have been acquired yet or the last acquisition was done in Remote Sequence Mode.
// INV : Invalid sequence index
// NRM : Software not in Remote Mode
// Secondary Responses:
// Secondary responses are only sent if the primary response is ACK.
// serial_number + result [string +code] : Single job result queried (Remote Job Mode or Remote Sequence Mode)
// serial_number + results [string +code array] : Multiple job results queried in Remote Sequence Mode
// Job Results:
// OK : Job passed all QA requirements
// NOK : Job failed at least one QA requirement
// NOQA : No QA was enabled in the job or the job was masked during operation
// X : Job was not run and was part of a partial sequence (sequence stopped midway through)
#endregion
public int get_last_job_result(out string strResult)
{
int nRet = 0; // ErrorCode
string receivemsg = "";
strResult = "";
nRet = SendAndRecieveCommand(LDDCommand.GET_LAST_JOB_RESULT, out receivemsg);
List<string> ParseData = ParseReceiveMsgVer2(receivemsg);
if (nRet == (int)eLDDErr.ACK) {
if (ParseData != null && ParseData.Count > 1) {
strResult = ParseData[1];
} else {
strResult = "";
return (int)eLDDErr.NAV;
}
} else {
strResult = "";
}
return nRet;
}
public int get_last_job_result(out List<string> lsResult)
{
// output 을 string list 로 받고 싶을때는 이 함수로 쓰자.
int nRet = 0; // ErrorCode
List<string> receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.GET_LAST_JOB_RESULT, out receivemsg);
lsResult = new List<string>();
if (nRet == (int)eLDDErr.ACK) {
// ACK 로 들어왔을 경우에, receivemsg[0] == ACK , receivemsg[1] == Serial Number , 이후에 결과...
if (receivemsg == null || receivemsg.Count < 3) {
// ACK 인데 이렇게 들어올리 없지만 에러처리하자
return (int)eLDDErr.NAV;
}
// ACK 랑 serialnumber 는 삭제하고 결과만 보내자.
for (int i = 2; i < receivemsg.Count; i++) {
lsResult.Add(receivemsg[i]);
}
} else {
// lsResult 를 empty 로 보내자. (null 아님)
// 위에서 초기화 했으므로 이미 empty 임.
}
return nRet;
}
public int get_last_sequence_result(eLDDResult eResult)
{
// output 을 enumerator 로 받고 싶을때는 이 함수로 쓰자.
string strresult;
int nRet = get_last_sequence_result(out strresult);
switch (strresult) {
case "OK":
eResult = eLDDResult.OK;
break;
case "NOQA":
eResult = eLDDResult.NOQA;
break;
case "NOK":
eResult = eLDDResult.NOK;
break;
case "X":
eResult = eLDDResult.X;
break;
default:
eResult = eLDDResult.X;
break;
}
return nRet;
}
public int get_last_sequence_result(out string strResult)
{
#region function descriptions
// 매우 중요 : 마지막 취득했던 sequence 의 OK/NOK 결과를 받아온다. 즉, 검사 결과를 받아오는 듯함.
// get_last_sequence_result
// This command has no associated arguments.
// Primary Responses
// ACK : Valid Command, previous sequence has been run and software is in Remote Sequence Mode.
// NAV : No sequences have been acquired yet
// The system is currently in Remote Job Mode
// The last acquisition was in Remote Job Mode
// NRM : Software not in Remote Mode
// Secondary Responses:
// Secondary responses are only sent if the primary response is ACK.
// serial_number + result [string +code] : ALL
// Job Results:
// OK : Job passed all QA requirements
// NOK : Job failed at least one QA requirement
// NOQA : No QA was enabled in the job or the job was masked during operation
// X : Job was not run and was part of a partial sequence (sequence stopped midway through)
// Example 1
// Sequence 1, Job 1,2,3,4
// 1(OK) , 2(OK), 3(NOQA) 4(OK) : sequence result (OK)
// 1(OK) , 2(NOK), 3(NOQA) 4(OK) : sequence result (NOK)
// 1(NOQA) , 2(NOQA), 3(NOQA) 4(NOQA) : sequence result (NOQA)
// 1(OK) , 2(NOQA), 3(NOQA) 4(OK), masked 1011 : sequence result (OK)
// 1(OK) , 2(NOQA), 3(X) 4(X) : sequence result (X)
// 1(OK) , 2(NOK), 3(X) 4(X) : sequence result (NOK)
#endregion
int nRet = 0; // ErrorCode
string receivemsg = "";
strResult = "";
nRet = SendAndRecieveCommand(LDDCommand.GET_LAST_SEQ_RESULT, out receivemsg);
List<string> ParseData = ParseReceiveMsgVer2(receivemsg);
if (nRet == (int)eLDDErr.ACK) {
if (ParseData != null && ParseData.Count > 1) {
strResult = ParseData[1];
} else {
strResult = "";
return (int)eLDDErr.NAV;
}
} else {
strResult = "";
}
return nRet;
}
#region get_last_job_fail_codes function descriptions
// Gets the failure codes (reasons for failure) for the last acquisition’s job or jobs.
// Failure codes are returned as a comma separated list enclosed by square brackets:
// [KHD - DCIR, FWS - DTBR, SLE - DTOR].
// Primary Responses:
// ACK : Valid Command and data has previously been acquired
// NAV : In Remote Sequence Mode and no sequences have been acquired yet or the last acquisition was done in Remote Job Mode.
// In Remote Job Mode and no jobs have been acquired yet or the last acquisition was done in Remote Sequence Mode.
// INV : Invalid sequence index
// NRM : Software not in Remote Mode
// Secondary Responses:
// serial_number + code [string +code] : Single job result queried (Remote Job Mode or Remote Sequence Mode)
// serial_number + code [string +code array] : Multiple job results queried in Remote Sequence Mode
// OmniWELD Failure Codes -> eLDDErr, OmniWELD Failure Codes
// Reference Plane Failure Modes -> eLDDErr, Reference Plane Failure Modes
// Argument
// -e seq_elem_# [optional numeric] : Index of the job within the sequence. 1 is the first job in the sequence.
// Example 1 : Job Mode
// >> get_last_job_fail_codes\r\n
// << ACK\r\n
// << “IPGOW SERIAL 001”\n[KHD - DCIR, SLE - DTOR]\r\n
// Esample 2 : Sequence Mode no -e switch
// 4 sequence elements
// Job 1 failed with error codes:
// KHD - DCIR
// SLE - DTOR
// Job 2 failed with error codes:
// KHD - DCIR
// Job 3 had no QA enabled
// Job 4 passed
// >> get_last_job_fail_codes\r\n
// << ACK\r\n
// << “IPGOW SERIAL 001”\n[KHD-DCIR, SLE-DTOR]\n[KHD - DCIR]\n[]\n[]\r\n
// Example 3 : Sequence Mode with -e switch
// 4 sequence elements
// Job 1 failed with error codes:
// KHD - DCIR
// SLE - DTOR
// Job 2 failed with error codes:
// KHD - DCIR
// Job 3 had no QA enabled
// Job 4 passed
// >> get_last_job_fail_codes\r\n
// << ACK\r\n
// << “IPGOW SERIAL 001”\n[KHD-DCIR]\r\n , 매뉴얼에는 이렇게 되어있는데 “IPGOW SERIAL 001”\n[KHD-DCIR, SLE-DTOR]\r\n 이게 맞지않나..
// Example 4 : Masked sequence with no -e switc
// run with the mask -m 1011
// 4 sequence elements
// Job 1 failed with error codes:
// KHD - DCIR
// SLE - DTOR
// Job 2 not run
// Job 3 had no QA enabled
// Job 4 passed
// >> get_last_job_fail_codes\r\n
// << ACK\r\n
// << “IPGOW SERIAL 001”\n[KHD-DCIR,SLE-DTOR]\n[]\n[]\n[]\r\n
// Example 5 : Partial sequence with no -e switch
// 4 sequence elements
// Job 1 failed with error codes:
// KHD - DCIR
// SLE - DTOR
// Job 2 not run
// Job 3 not run
// Job 4 not run
// >> get_last_job_fail_codes\r\n
// << ACK\r\n
// << “IPGOW SERIAL 001”\n[KHD-DCIR,SLE-DTOR]\n[X]\n[X]\n[X]\r\n
#endregion
public int get_last_job_fail_codes(out List<string> lsResult)
{
// error code 로 뭔가 별도 처리할거 아니고 그냥 로그 남길거면 job 단위로만 split 하고 내용물은 string 채로 로그 남기면 될듯
int nRet = 0;
List<string> receivemsg;
nRet = SendAndRecieveCommand(LDDCommand.GET_LAST_JOB_FAIL_CODE, out receivemsg);
lsResult = new List<string>();
if (nRet == (int)eLDDErr.ACK) {
// ACK 로 들어왔을 경우에, receivemsg[0] == ACK , receivemsg[1] == Serial Number , 이후에 결과...
if (receivemsg == null || receivemsg.Count < 3) {
// ACK 인데 이렇게 들어올리 없지만 에러처리하자
return (int)eLDDErr.NAV;
}
// ACK 랑 serialnumber 는 삭제하고 결과만 보내자.
for (int i = 2; i < receivemsg.Count; i++) {
lsResult.Add(receivemsg[i]);
}
} else {
// lsResult 를 empty 로 보내자. (null 아님)
// 위에서 초기화 했으므로 이미 empty 임.
}
return nRet;
}
#region get_last_job_metric function descriptions
// see OmniWELD
// see LDDMetricCode
// Command: get_last_job_metric metric_code [-e seq_elem_#]
// Description: Gets the specified metric for the last acquisition’s job or jobs.
// Arguments:
// metric_code [code] : The metric code associated with the metric being queried.
// -e seq_elem_# [optional numeric] : Index of the job within the sequence. 1 is the first job in the sequence.
// Primary Responses:
// ACK : Valid Command and data has previously been acquired
// NAV : In Remote Sequence Mode and no sequences have been acquired yet or the last acquisition was done in Remote Job Mode.
// In Remote Job Mode and no jobs have been acquired yet or the last acquisition was done in Remote Sequence Mode.
// INV : Invalid metric code, Invalid sequence index
// NRM : Software not in Remote Mode
// Secondary Responses:
// Secondary responses are only sent if the primary response is ACK.
// serial_number + result [string +numeric] : Single job result queried (Remote Job Mode or Remote Sequence Mode)
// serial_number + result [string +numeric array] : Multiple job results queried in Remote Sequence Mode
// Example WPH -> see OmniWELD , FTAVG -> LDDMetricCode , WorkPiece Height - Feature Tracking: Average Value (um)
// Example 1: Job Mode :
// >> get_last_job_metric WPH-FTAVG\r\n
// << ACK\r\n
// << “IPGOW Serial 001”\n1234\r\n
// Example 2: Sequence Mode with no -e switch
// 3 sequence elements
// job 1 had the following statistics:
// Average Workpiece Height(um) = 1234
// job 2 had the following statistics:
// Average Workpiece Height(um) = 5678
// job 3 had no Workpiece Height monitoring enabled
// >> get_last_job_metric WPH-FTAVG\r\n
// << ACK\r\n
// << “IPGOW Serial 001”\n1234\n5678\nX\r\n
// Example 3: Sequence Mode with -e switch
// 3 sequence elements
// job 1 had the following statistics:
// Average Workpiece Height(um) = 1234
// job 2 had the following statistics:
// Average Workpiece Height(um) = 5678
// job 3 had no Workpiece Height monitoring enabled
// >> get_last_job_metric WPH-FTAVG -e 1\r\n
// << ACK\r\n
// << “IPGOW Serial 001”\n1234\r\n
// Example 4: A masked sequence with no -e switch
// the mask -m 101
// 3 sequence elements
// job 1 had the following statistics:
// Average Workpiece Height(um) = 1234
// job 2 was not run.
// job 3 had no Workpiece Height monitoring enabled
// >> get_last_job_metric WPH-FTAVG -e 1\r\n
// << ACK\r\n
// << “IPGOW Serial 001”\n1234\nX\nX\r\n
// Example 5: A partial sequence with no -e switch
// In the case where the sequence was stopped after the first sequence element with serial number “IPGOW Serial 001”,
// 3 sequence elements
// job 1 had the following statistics:
// Average Workpiece Height(um) = 1234
// job 2 was not run.
// job 3 was not run.
// >> get_last_job_metric WPH-FTAVG -e 1\r\n
// << ACK\r\n
// << “IPGOW Serial 001”\n1234\nX\nX\r\n
#endregion
public int get_last_job_metric(string strOmniWELDCode, string strLDDMetricCode, out List<string> lsResult, int eSwitch = 0)
{
// error code 로 뭔가 별도 처리할거 아니고 그냥 로그 남길거면 job 단위로만 split 하고 내용물은 string 채로 로그 남기면 될듯
int nRet = 0;
string receivemsg = "";
string strArgument = String.Format("{0}-{1}{2}", strOmniWELDCode, strLDDMetricCode, eSwitch == 0 ? "" : String.Format(" -e {0}", eSwitch));
//nRet = SendAndRecieveCommand(LDDCommand.GET_LAST_JOB_METRIC, strArgument, out receivemsg);
nRet = SendAndRecieveCommand(LDDCommand.GET_LAST_JOB_METRIC, strArgument, out receivemsg);
lsResult = new List<string>();
List<string> ParseData = new List<string>();
ParseData = ParseReceiveMsgVer2(receivemsg);
for (int i = 1; i < ParseData.Count; i++) { // ParseData[0] == Serial Number
lsResult.Add(ParseData[i]);
}
return nRet;
}
public int get_last_job_metric(out List<string> lsResult)
{
// error code 로 뭔가 별도 처리할거 아니고 그냥 로그 남길거면 job 단위로만 split 하고 내용물은 string 채로 로그 남기면 될듯
int nRet = 0;
string receivemsg = "";
string strArgument1 = String.Format("-m {0}-{1},", OmniWELD.KHD, LDDMetricCode.FTAVG);
string strArgument2 = String.Format("{0}-{1},", OmniWELD.KHD, LDDMetricCode.FTMIN);
string strArgument3 = String.Format("{0}-{1},", OmniWELD.KHD, LDDMetricCode.FTMAX);
string strArgument4 = String.Format("{0}-{1},", OmniWELD.KHD, LDDMetricCode.QATDB);
string strArgument5 = String.Format("{0}-{1}", OmniWELD.KHD, LDDMetricCode.QATDA);
string strArgument = strArgument1 + strArgument2 + strArgument3 + strArgument4 + strArgument5;
//nRet = SendAndRecieveCommand(LDDCommand.GET_LAST_JOB_METRIC, strArgument, out receivemsg);
nRet = SendAndRecieveCommand(LDDCommand.GET_LAST_JOB_METRIC, strArgument, out receivemsg);
lsResult = new List<string>();
List<string> ParseData = new List<string>();
ParseData = ParseReceiveMsgVer2(receivemsg);
for (int i = 1; i < ParseData.Count; i++) { // ParseData[0] == Serial Number
lsResult.Add(ParseData[i]);
}
return nRet;
}
#region get_system_state functions Descriptinos
// Description: Returns the current state of the system
// No Argument
// Primary Responses:
// ACK : The command has been properly received by the system
// Secondary Responses:
// Acquiring : The system is acquiring data and cannot accept triggers
// Busy : The system is processing previous commands and cannot accept triggers or commands.
// Initializing : The system is initializing and cannot accept triggers or commands.
// Processing : The system is processing acquired data and cannot accept triggers
// Ready for Command : The system is ready to receive commands but no jobs are being run so the system cannot accept triggers.
// Waiting for Trigger : The system is waiting for a trigger to acquire a job. The system is able to accept triggers or new commands.
// Not in Remote Mode : The system is not in Remote Mode and cannot accept triggers or start job commands.
#endregion
public int get_system_state(out string strResult)
{
int nRet = 0;
nRet = SendAndRecieveCommand(LDDCommand.GET_SYSTEM_STATE, out strResult);
// ACK 면 Secondary Responses 를 바로 받아온다.
// ACK 가 아니면 Primary Response를 받아온다.
return nRet;
}
#region get_waiting_for_trigger functions Descriptinos
// Description: Returns TRUE or FALSE depending on whether or not the system is currently waiting for a trigger.
// No Argument
// Primary Responses:
// ACK : The command has been properly received by the system
// Secondary Responses:
// TRUE : The system is currently in a state where it can accept a trigger. This could be:
// Ready to perform an OMNIWELD acquisition in Remote Job Mode.
// Ready to acquire a sequence element in Remote Sequence Mode.
// FALSE : The system is not currently in a state where it can accept a trigger. This could mean:
// The system is not ready to perform any acquisitions
// The system is currently acquiring data
// The system is currently processing data
#endregion
public int get_waiting_for_trigger(out string strResult)
{
int nRet = 0;
nRet = SendAndRecieveCommand(LDDCommand.GET_WAITING_FOR_TRIGGER, out strResult);
return nRet;
}
public int get_waiting_for_trigger(out bool bResult)
{
string strResult;
int nRet = get_waiting_for_trigger(out strResult);
bResult = strResult == "TRUE" ? true : false;
return nRet;
}
#region get_ready_for_command functions Descriptinos
// Description: Returns TRUE or FALSE depending on whether or not the system can currently accept a command.
// No Argument
// Primary Responses:
// ACK : The command has been properly received by the system
// Secondary Responses:
// TRUE : The system is currently in a state where it can accept a new command. This could be:
// The system has started and is in the Ready state.
// The system has entered Remote Mode, the start command has been called and the system is ready to accept triggers.
// The system is currently acquiring data
// FALSE : The system is not currently in a state where it can accept a command. This could mean:
// The system is in a Busy state
// The system is in a Processing state
#endregion
public int get_ready_for_command(out string strResult)
{
int nRet = 0;
nRet = SendAndRecieveCommand(LDDCommand.GET_READY_FOR_COMMAND, out strResult);
return nRet;
}
public int get_ready_for_command(out bool bResult)
{
string strResult;
int nRet = get_ready_for_command(out strResult);
bResult = strResult == "TRUE" ? true : false;
return nRet;
}
#region get_location_in_sequence function descriptions
// Description: Returns the identifier of the currently running job. If not currently acquiring,
// instead returns next job to be run in a sequence. Without the optional -i flag,
// returns the sequence element location of the job. With the optional -i flag, it returns the:
// Workpiece Identifier, Feature Identifier, and Job File
// Argument : -i options , Used to obtain verbose information
// Primary Responses:
// ACK : The command is received and appropriate; system is in Remote Sequence Mode and a sequence is loaded
// NAV : This command is not valid for the current system state. This could mean:
// - The system is in Remote Job Mode instead of sequence mode.
// - The system is in sequence mode, but no sequence has been loaded.
// NRM : The system is not in Remote Mode.
// Secondary Responses:
// Secondary responses are only sent if the primary response is ACK.
// location_in_sequence [numeric] : This is the number of the currently acquiring job, or if not currently acquiring a job, the number of the next job to be triggered
// location_in_sequence [string] : This is the identifier of the currently running job, or if not currently running a job, the identifier of the next job to be triggered.
// The identifier contains the Workpiece Identifier, the Feature identifier, and the job name.
// Example 1: A sequence has been started, but no sequence elements have been triggered
// >> get_location_in_sequence\r\n
// << ACK\r\n
// << 1\r\n
// Example 2: A sequence has been started, but no sequence elements have been triggered and the -i flag has been used
// >> get_location_in_sequence\r\n // -i 옵션을 쓰는 조건의 예제인데 매뉴얼에는 -i 표시가 없다. -i 를 썼을거라고 추측된다.
// << ACK\r\n
// << Sample Piece\r\n
// << Weld A\r\n
// << Default.ow\r\n
// Example 3: Two sequence elements have been completed and the system is currently acquiring the third sequence element
// >> get_location_in_sequence\r\n
// << ACK\r\n
// << 3\r\n
// Example 4: The last sequence completed and the system is waiting to acquire the next sequence
// >> get_location_in_sequence\r\n
// << ACK\r\n
// << 1\r\n
#endregion
public int get_location_in_sequence(out string strResult)
{
int nRet = 0;
nRet = SendAndRecieveCommand(LDDCommand.GET_LOCATION_IN_SEQ, out strResult);
return nRet;
}
public int get_location_in_sequence(out int nResult)
{
string strResult;
int nRet = get_location_in_sequence(out strResult);
if (nRet == (int)eLDDErr.ACK) {
nResult = Convert.ToInt32(strResult);
} else {
nResult = 0;
}
return nRet;
}
#region get_current_remote_acquisition function descriptions
// Description: Returns the slot number of the currently running sequence in Remote Sequence Mode or the currently running job in Remote Job Mode.
// With the optional -i flag, returns the sequence label or the jobfile name instead of the number.
// Argument : -i options , Used to obtain verbose information
// Primary Responses:
// ACK : The command is received and appropriate; system is in Remote Mode and a job or sequence is loaded
// NAV : This command is not valid for the current system state. This could mean:
// - The system is in Remote Mode, but no job or sequence has been loaded.
// NRM : The system is not in Remote Mode.
// Secondary Responses:
// Secondary responses are only sent if the primary response is ACK.
// current_remote_acquisition [numeric] : This is the number of the currently loaded sequence or job
// current_remote_acquisition [string] : This is the sequence label currently loaded sequence or the jobfile name of the currently loaded job
// Example 1: In Remote Mode, the sequence or job that is currently running has been assigned to slot 1
// >> get_current_remote_acquisition\r\n
// << ACK\r\n
// << 1\r\n
// Example 2: In Remote Job Mode, the job “Sample.ow” is currently running has been assigned to slot 1
// >> get_current_remote_acquisition -i\r\n
// << ACK\r\n
// << Sample.ow\r\n
// Example 3: In Remote Sequence Mode, the sequence with label “Sample” is currently running has been assigned to slot 1
// >> get_current_remote_acquisition -i\r\n
// << ACK\r\n
// << Sample\r\n
#endregion
public int get_current_remote_acquisition(out string strResult, bool b_ioptions = false)
{
int nRet = 0;
if (b_ioptions) {
nRet = SendAndRecieveCommand(LDDCommand.GET_CURRENT_REMOTE_ACQ, " -i", out strResult);
} else {
nRet = SendAndRecieveCommand(LDDCommand.GET_CURRENT_REMOTE_ACQ, out strResult);
}
return nRet;
}
public int get_current_remote_acquisition(out int nResult)
{
string strResult;
int nRet = SendAndRecieveCommand(LDDCommand.GET_CURRENT_REMOTE_ACQ, out strResult);
if (nRet == (int)eLDDErr.ACK) {
nResult = Convert.ToInt32(strResult);
} else {
nResult = 0;
}
return nRet;
}
#region get_current_number_of_elements function descriptions
// Description: Returns the number of elements in the currently called sequence. In the case of a masked sequence, returns the total number of jobs in that sequence regardless of masking.
// With the optional -t flag, returns the number of jobs in a sequence which are triggered jobs, as opposed to timed jobs.
// Argument : -t options , Returns the number of triggered jobs in the sequence.
// Primary Responses:
// ACK : The command is received and appropriate; system is in Remote Sequence Mode and a sequence is loaded
// NAV : This command is not valid for the current system state. This could mean:
// - The system is in Remote Job Mode.
// - The system is in Remote Sequence Mode, but no Sequence has been loaded.
// NRM : The system is not in Remote Mode.
// Secondary Responses:
// Secondary responses are only sent if the primary response is ACK.
// current_number_of_elements [numeric] : Number of elements in the currently loaded sequence.
// current_number_of_elements [string] : Number of triggered elements in the currently loaded sequence.
// Example 1: In Remote Sequence Mode, a sequence with 10 sequence elements have been loaded, 5 of which are triggered
// >> get_current_number_of_elements\r\n
// << ACK\r\n
// << 10\r\n
// Example 2: In Remote Sequence Mode, a sequence with 10 sequence elements have been loaded, 5 of which are triggered
// >> get_current_number_of_elements -t\r\n
// << ACK\r\n
// << 5\r\n
// Example 3: In Remote Sequence Mode, a sequence with 10 sequence elements have been loaded and was started with the mask -m 1010101010
// >> get_current_number_of_elements\r\n
// << ACK\r\n
// << 10\r\
#endregion
public int get_current_number_of_elements(out string strResult, bool b_toptions = false)
{
int nRet = 0;
if (b_toptions) {
nRet = SendAndRecieveCommand(LDDCommand.GET_CURRENT_NUMBER_OF_ELEMENTS, " -t", out strResult);
} else {
nRet = SendAndRecieveCommand(LDDCommand.GET_CURRENT_NUMBER_OF_ELEMENTS, out strResult);
}
return nRet;
}
public int get_current_number_of_elements(out int nResult, bool b_toptions = false)
{
string strResult;
int nRet = get_current_number_of_elements(out strResult, b_toptions);
if (nRet == (int)eLDDErr.ACK) {
nResult = Convert.ToInt32(strResult);
} else {
nResult = 0;
}
return nRet;
}
#region get_last_number_of_elements function descriptions
// Description: Returns the number of elements which were acquired in the last sequence completed. A sequence is considered complete if:
// All the elements in a sequence have been acquired and processe
// Some of the elements in a sequence were acquired, then a new sequence was loaded.
// No Argument
// Primary Responses:
// ACK : The command has been properly received by the system and is appropriate
// NAV : This command is not valid for the current system state. This could mean:
// - The system is in Remote Job Mode.
// - The system is in Remote Sequence Mode, but no Sequence has been loaded.
// NRM : The system is not in Remote Mode.
// Secondary Responses:
// Secondary responses are only sent if the primary response is ACK.
// last_number_of_elements [numeric] : This is the number of elements in last completed sequence.
// Manual 에 get_current_number_of_elements 로 send 하는데 오타가 아닌듯 싶다. get_last_number_of_elements 함수가 맞는듯
// 일단 Manual 대로는 적어둔다.
// Example 1: In Remote Sequence Mode, a sequence with 10 sequence elements is loaded for the first time but no triggers are sent (i.e. no sequence has been completed yet)
// >> get_current_number_of_elements\r\n
// << ACK\r\n
// << 0\r\n
// Example 2: In Remote Sequence Mode, a sequence with 10 sequence elements is loaded for the first time and 5 triggers are sent (i.e. no sequence has been completed yet)
// >> get_current_number_of_elements\r\n
// << ACK\r\n
// << 0\r\n
// Example 3: In Remote Sequence Mode, a sequence with 10 sequence elements is loaded for the first time and 10 triggers are sent, completing the first sequence
// >> get_current_number_of_elements\r\n
// << ACK\r\n
// << 10\r\n
// Example 4: In Remote Sequence Mode, a sequence with 10 sequence elements is loaded for the first time and 10 triggers are sent, completing the first sequence, then 5 triggers are sent to begin a second acquisition of the same sequence
// >> get_current_number_of_elements\r\n
// << ACK\r\n
// << 10\r\n
// Example 5: In Remote Sequence Mode, a sequence with 10 sequence elements is loaded and 10 triggers are sent. Remote mode is exited, then entered again
// >> get_current_number_of_elements\r\n
// << ACK\r\n
// << 10\r\n
#endregion
public int get_last_number_of_elements(out string strResult)
{
int nRet = SendAndRecieveCommand(LDDCommand.GET_LAST_NUMBER_OF_ELEMENTS, out strResult);
return nRet;
}
public int get_last_number_of_elements(out int nResult)
{
string strResult;
int nRet = get_last_number_of_elements(out strResult);
if (nRet == (int)eLDDErr.ACK) {
nResult = Convert.ToInt32(strResult);
} else {
nResult = 0;
}
return nRet;
}
#region get_job_parameter function descriptions
// Description: Returns the value of the job file parameter, parameter, from the specified job file job_file. The job file does not need to be mapped.
// This command can only be called when in Manual Mode (i.e., not in Remote Mode).
// Arguments
// job_file [string] : String containing the job file name and corresponding extension: “Job File 1.ow”
// parameter [code] : Code representing the job parameter. See Job File Parameter Designations. (See LDDGeneralPrameter)
// Primary Responses:
// ACK : Valid command arguments and in Manual Mode
// INV :
// - Fewer than two arguments specified.
// - Invalid job file specified.
// - Invalid parameter specified (unrecognized parameter or invalid parameter for specified job type).
// NMM : Software not in Manual Mode
// Secondary Responses:
// Secondary responses are only sent if the primary response is ACK.
// parameter_value [string or numeric] : Specified parameter, which can be a numeric (e.g. WELDING SPEED) or a string (e.g. FILE SEED).
// For Parameters are returned as numeric values, they are returned as floating point numbers with trailing zeros removed after the decimal place. (e.g. 1000000 or 0.00000123456).
// Example 1: String Type Parameter
// Job File Name = OmniWELD Job.ow
// File Name = Data File Name
// >> get_job_parameter “OmniWELD Job.ow” FileName\r\n
// << ACK\r\n
// << “Data File Name”\r\n
// Example 2: Numeric Type Parameter
// Job File Name = OmniWELD Job.ow
// Welding Speed = 50mm/s
// >> get_job_parameter “OmniWELD Job.ow” WeldSpeed\r\n
// << ACK\r\n
// << 50\r\n
// Example 3: QA Bound Parameter
// Job File Name = OmniWELD Job.ow
// Finished Weld Surface Lower QA Bound = 100 um
// >> get_job_parameter “OmniWELD Job.ow” FWS-MIN\r\n
// << ACK\r\n
// << 100\r\n
#endregion
public int get_job_parameter(string strjobfile, string strParameter, out string strResult)
{
string strArgument = string.Format("{0} {1}", strjobfile, strParameter);
int nRet = SendAndRecieveCommand(LDDCommand.GET_JOB_PARAMETER, strArgument, out strResult);
return nRet;
}
public int get_job_parameter(string strjobfile, string strParameter, out int nResult)
{
// strjobfile : file name
// strParameter : string of LDDGeneralPrameter or QA Bound
if (strParameter == LDDGeneralPrameter.FileName) {
// parameter 가 filename 으로 올때는 output 이 string 인 함수로만 들어와야한다.
nResult = 0;
return (int)eLDDErr.INV;
}
string strResult;
int nRet = get_job_parameter(strjobfile, strParameter, out strResult);
if (nRet == (int)eLDDErr.ACK) {
nResult = Convert.ToInt32(strResult);
} else {
nResult = 0;
}
return nRet;
}
#region set_job_parameter function descriptions
// Description: Sets the current value of the job file parameter, parameter, in the job file job_file to value.
// This command can only be called when in Manual Mode (i.e., not in Remote Mode).
// Note that it is possible to set out of range values using this command. Out of range values are validated the next time Remote Mode is entered and validation is performed.
// Arguments
// job_file [string] : String containing the job file name and corresponding extension: “Job File 1.ow”
// parameter [code] : Code representing the job parameter. See Job File Parameter Designations. (See LDDGeneralPrameter)
// parameter_value [string or numeric] : Value to set for the specified parameter. This argument must be a string for string-based parameters (e.g., file names) and a floating point numeric for numeric-based parameters.
// Primary Responses:
// ACK : Valid command arguments and in Manual Mode
// INV :
// - More/Fewer than three arguments specified
// - Invalid job file specified.
// - Invalid parameter specified (unrecognized parameter or invalid parameter for specified job type)
// - Invalid parameter value specified
// NMM : Software not in Manual Mode
// Secondary Responses:
// Secondary responses are only sent if the primary response is ACK.
// parameter_value [string or numeric] : Specified parameter, which can be a numeric (e.g. WELDING SPEED) or a string (e.g. FILE SEED).
// For Parameters are returned as numeric values, they are returned as floating point numbers with trailing zeros removed after the decimal place. (e.g. 1000000 or 0.00000123456).
// Example 1: String Type Parameter
// Job File Name = OmniWELD Job.ow
// File Name = Data File Name
// >> set_job_parameter “OmniWELD Job.ow” FileName “New Name”\r\n
// << ACK\r\n
// << “New Name”\r\n
// Example 2: Numeric Type Parameter
// Job File Name = OmniWELD Job.ow
// Welding Speed = 50mm/s
// >> set_job_parameter “OmniWELD Job.ow” WeldSpeed 50\r\n
// << ACK\r\n
// << 50\r\n
// Example 3: QA Bound Parameter
// Job File Name = OmniWELD Job.ow
// Finished Weld Surface Lower QA Bound = 100 um
// >> set_job_parameter “OmniWELD Job.ow” FWS-MIN 100\r\n
// << ACK\r\n
// << 100\r\n
#endregion
public int set_job_parameter(string strjobfile, string strParameter, string strValue, out string strResult)
{
string strArgument = string.Format("{0} {1} {2}", strjobfile, strParameter, strValue);
int nRet = SendAndRecieveCommand(LDDCommand.SET_JOB_PARAMETER, strArgument, out strResult);
return nRet;
}
public int set_job_parameter(string strjobfile, string strParameter, string strValue, out int nResult)
{
// strjobfile : file name
// strParameter : string of LDDGeneralPrameter or QA Bound
// strValue : string of parameter value
if (strParameter == LDDGeneralPrameter.FileName) {
// parameter 가 filename 으로 올때는 output 이 string 인 함수로만 들어와야한다.
nResult = 0;
return (int)eLDDErr.INV;
}
string strResult;
int nRet = set_job_parameter(strjobfile, strParameter, strValue, out strResult);
if (nRet == (int)eLDDErr.ACK) {
nResult = Convert.ToInt32(strResult);
} else {
nResult = 0;
}
return nRet;
}
#endregion
#region Make TCPIP Command String Functions
// 직접 string 을 넣어도 되지만 실수할수도 있기 때문에 약속된 string 으로만 넣도록 하자
// See LDDCommand
public string MakeSendCommand(string strCommand)
{
return strCommand + "\r\n";
}
public string MakeSendCommand(string strCommand, string strAgument)
{
return strCommand + " " + strAgument + "\r\n";
}
public string MakeSendCommand(string strCommand, int strAgument)
{
return strCommand + " " + strAgument.ToString() + "\r\n";
}
public string MakeSendCommand(string strCommand, double strAgument)
{
return strCommand + " " + strAgument.ToString() + "\r\n";
}
private List<string> ParseReceiveMsg(string strTarget)
{
List<string> strDest = new List<string>();
//strTarget.Replace("\r\n", "\n");
string[] strSplited = strTarget.Split(new[] { "\r\n" }, StringSplitOptions.None);
foreach (string str in strSplited) {
strDest.Add(str);
}
return strDest;
}
private List<string> ParseReceiveMsgVer2(string strTarget)
{
List<string> strDest = new List<string>();
//strTarget.Replace("\r\n", "\n");
string[] strSplited = strTarget.Split(new[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
foreach (string str in strSplited) {
strDest.Add(str);
}
return strDest;
}
private int SendAndRecieveCommand(string strCommand, string strArgument, out string strReceive)
{
lock (_lockObject)
{
byte[] receiveMsg;
string sendmsg = MakeSendCommand(strCommand, strArgument);
strReceive = "";
if (0 == SendAndRecieve(sendmsg, out receiveMsg)) { // if return success
string strRecieveMsg = Encoding.UTF8.GetString(receiveMsg);
List<string> strRecived = ParseReceiveMsg(strRecieveMsg);
if (strRecived.Count < 0) {
return (int)eLDDErr.NCK;
} else {
int nRet = -1;
if (strRecived[0].CompareTo(LDDCommand.ACK) == 0) nRet = (int)eLDDErr.ACK;
else if (strRecived[0].CompareTo(LDDCommand.INV) == 0) nRet = (int)eLDDErr.INV;
else if (strRecived[0].CompareTo(LDDCommand.NAV) == 0) nRet = (int)eLDDErr.NAV;
else if (strRecived[0].CompareTo(LDDCommand.NMM) == 0) nRet = (int)eLDDErr.NMM;
else if (strRecived[0].CompareTo(LDDCommand.NRM) == 0) nRet = (int)eLDDErr.NRM;
else nRet = (int)eLDDErr.NCK;
if (nRet == (int)eLDDErr.ACK) {
if (strRecived.Count > 1 && strRecived[1].Trim() == "") {
if (0 == Recieve(out receiveMsg, 1000)) {
string strSecondRecieveMsg = Encoding.UTF8.GetString(receiveMsg);
List<string> strSecondRecived = ParseReceiveMsg(strSecondRecieveMsg);
strReceive = strSecondRecived[0];
}
} else {
strReceive = strRecived[1];
}
} else {
strReceive = strRecived[0];
}
return nRet;
}
} else {
return -1;
}
}
}
private int SendAndRecieveCommand(string strCommand, out string strReceive)
{
lock (_lockObject)
{
byte[] receiveMsg;
string sendmsg = MakeSendCommand(strCommand);
strReceive = "";
if (0 == SendAndRecieve(sendmsg, out receiveMsg)) { // if return success
string strRecieveMsg = Encoding.UTF8.GetString(receiveMsg);
List<string> strRecived = ParseReceiveMsg(strRecieveMsg);
if (strRecived.Count < 0) {
return (int)eLDDErr.NCK;
} else {
int nRet = -1;
if (strRecived[0].CompareTo(LDDCommand.ACK) == 0) nRet = (int)eLDDErr.ACK;
else if (strRecived[0].CompareTo(LDDCommand.INV) == 0) nRet = (int)eLDDErr.INV;
else if (strRecived[0].CompareTo(LDDCommand.NAV) == 0) nRet = (int)eLDDErr.NAV;
else if (strRecived[0].CompareTo(LDDCommand.NMM) == 0) nRet = (int)eLDDErr.NMM;
else if (strRecived[0].CompareTo(LDDCommand.NRM) == 0) nRet = (int)eLDDErr.NRM;
else nRet = (int)eLDDErr.NCK;
if (nRet == (int)eLDDErr.ACK) {
if (strRecived.Count > 1 && strRecived[1].Trim() == "") {
if (0 == Recieve(out receiveMsg, 1000)) {
string strSecondRecieveMsg = Encoding.UTF8.GetString(receiveMsg);
List<string> strSecondRecived = ParseReceiveMsg(strSecondRecieveMsg);
strReceive = strSecondRecived[0];
}
} else {
strReceive = strRecived[1];
}
} else {
strReceive = strRecived[0];
}
return nRet;
}
} else
return -1;
}
}
private int SendAndRecieveCommand(string strCommand, out List<string> lsstrReceive)
{
lock (_lockObject)
{
byte[] receiveMsg;
string sendmsg = MakeSendCommand(strCommand);
if (0 == SendAndRecieve(sendmsg, out receiveMsg)) {
// if return success
string strRecieveMsg = Encoding.UTF8.GetString(receiveMsg);
lsstrReceive = ParseReceiveMsg(strRecieveMsg);
if (lsstrReceive.Count < 0) {
return (int)eLDDErr.NCK;
} else {
int nRet = -1;
if (lsstrReceive[0].CompareTo(LDDCommand.ACK) == 0) nRet = (int)eLDDErr.ACK;
else if (lsstrReceive[0].CompareTo(LDDCommand.INV) == 0) nRet = (int)eLDDErr.INV;
else if (lsstrReceive[0].CompareTo(LDDCommand.NAV) == 0) nRet = (int)eLDDErr.NAV;
else if (lsstrReceive[0].CompareTo(LDDCommand.NMM) == 0) nRet = (int)eLDDErr.NMM;
else if (lsstrReceive[0].CompareTo(LDDCommand.NRM) == 0) nRet = (int)eLDDErr.NRM;
else nRet = (int)eLDDErr.NCK;
return nRet;
}
} else {
lsstrReceive = null; // return nullptr
return -1;
}
}
}
private int SendAndRecieveCommand(string strCommand, string strArgument, out List<string> lsstrReceive)
{
lock (_lockObject)
{
byte[] receiveMsg;
string sendmsg = MakeSendCommand(strCommand, strArgument);
if (0 == SendAndRecieve(sendmsg, out receiveMsg)) {
// if return success
string strRecieveMsg = Encoding.UTF8.GetString(receiveMsg);
lsstrReceive = ParseReceiveMsg(strRecieveMsg);
if (lsstrReceive.Count < 1) {
return (int)eLDDErr.NCK;
} else {
int nRet = -1;
if (lsstrReceive[0].CompareTo(LDDCommand.ACK) == 0) nRet = (int)eLDDErr.ACK;
else if (lsstrReceive[0].CompareTo(LDDCommand.INV) == 0) nRet = (int)eLDDErr.INV;
else if (lsstrReceive[0].CompareTo(LDDCommand.NAV) == 0) nRet = (int)eLDDErr.NAV;
else if (lsstrReceive[0].CompareTo(LDDCommand.NMM) == 0) nRet = (int)eLDDErr.NMM;
else if (lsstrReceive[0].CompareTo(LDDCommand.NRM) == 0) nRet = (int)eLDDErr.NRM;
else nRet = (int)eLDDErr.NCK;
return nRet;
}
} else {
lsstrReceive = null; // return nullptr
return -1;
}
}
}
public string GetKHD_AVG()
{
List<string> resultList = new List<string>();
string result = "";
int resultdata = 0;
int index = 0;
int nRet = get_last_job_metric(OmniWELD.KHD, LDDMetricCode.FTAVG, out resultList, 0);
for (int i = 0; i < resultList.Count; i++) {
if (resultList[i].CompareTo("X") == 0) {
index++;
continue;
}
int.TryParse(resultList[i], out int number);
resultdata += number;
}
double devisionindex = resultList.Count - index;
if (devisionindex != 0) {
result = (resultdata / devisionindex).ToString();
} else {
result = "0";
}
if (nRet == (int)eLDDErr.ACK) {
return result;
} else {
return "0";
}
}
public string GetKHD_MIN()
{
List<string> resultList = new List<string>();
string result = "";
int resultdata = 0;
int nRet = get_last_job_metric(OmniWELD.KHD, LDDMetricCode.FTMIN, out resultList, 0);
for (int i = 0; i < resultList.Count; i++) {
if (resultList[i].CompareTo("X") == 0) {
continue;
}
int.TryParse(resultList[i], out int number);
if (resultdata > number || resultdata == 0) {
resultdata = number;
}
}
result = resultdata.ToString();
if (nRet == (int)eLDDErr.ACK) {
return result;
} else {
return "0";
}
}
public string GetKHD_MAX()
{
List<string> resultList = new List<string>();
string result = "";
int resultdata = 0;
int nRet = get_last_job_metric(OmniWELD.KHD, LDDMetricCode.FTMAX, out resultList, 0);
for (int i = 0; i < resultList.Count; i++) {
if (resultList[i].CompareTo("X") == 0) {
continue;
}
int.TryParse(resultList[i], out int number);
if (resultdata < number || resultdata == 0) {
resultdata = number;
}
}
result = resultdata.ToString();
if (nRet == (int)eLDDErr.ACK) {
return result;
} else {
return "0";
}
}
public string GetKHD_LowSum()
{
List<string> resultList = new List<string>();
string result = "";
int resultdata = 0;
int nRet = get_last_job_metric(OmniWELD.KHD, LDDMetricCode.QATDB, out resultList, 0);
for (int i = 0; i < resultList.Count; i++) {
if (resultList[i].CompareTo("X") == 0) {
continue;
}
int.TryParse(resultList[i], out int number);
resultdata += number;
}
result = resultdata.ToString();
if (nRet == (int)eLDDErr.ACK) {
return result;
} else {
return "0";
}
}
public string GetKHD_HighSum()
{
List<string> resultList = new List<string>();
string result = "";
int resultdata = 0;
int nRet = get_last_job_metric(OmniWELD.KHD, LDDMetricCode.QATDA, out resultList, 0);
for (int i = 0; i < resultList.Count; i++) {
if (resultList[i].CompareTo("X") == 0) {
continue;
}
int.TryParse(resultList[i], out int number);
resultdata += number;
}
result = resultdata.ToString();
if (nRet == (int)eLDDErr.ACK) {
return result;
} else {
return "0";
}
}
public List<string> GetKHD_Total()
{
List<string> resultList = new List<string>();
List<string> DataList = new List<string>();
string[] strSplited = null;
int nRet = get_last_job_metric(out resultList);
for (int i = 0; i < resultList.Count; i++) {
strSplited = resultList.ElementAt(i).Split(new[] { "," }, StringSplitOptions.None);
for (int j = 0; j < strSplited.Length; j++) {
DataList.Add(strSplited[j]);
}
}
return DataList;
}
#endregion
}
#region TCPIP Command Set
// Base Communications
// 1. Send Command
// 2. Recieve Primary Response
// 3. Recieve Responses
internal class LDDCommand
{
// Primary Response
public const string ACK = "ACK"; // Valid command argument
public const string INV = "INV"; // InValid command argument
public const string NAV = "NAV"; // The system is not ready for command
public const string NMM = "NMM"; // Software not in Manual Mode
//public const string NRM = "NRM"; // Software not in Remote Mode
public const string NRM = "Not in Remote Mode"; // Software not in Remote Mode
public const string OK = "OK"; // Job passed all QA requirements
public const string NOK = "NOK"; // Job failed at least one QA requirement
public const string NOQA = "NOK"; // No QA was enabled in the job or the job was masked during operation
public const string X = "X"; // Job was not run and was part of a partial sequence
// Commands
public const string ADD_SERIAL_NUMBER = "add_serial_number";
public const string GET_SERIAL_NUMBER = "get_serial_number";
public const string CLEAR_SERIAL_NUMBER = "clear_serial_number";
public const string GET_LIVE_REF_PLANE_POS = "get_lv_ref_plane_pos";
public const string SET_LIVE_REF_PLANE_POS = "set_lv_ref_plane_pos";
public const string GET_ERROR = "get_error";
public const string CLEAR_ERROR = "clear_error";
public const string START_SOFTWARE = "start_software";
public const string EXIT_SOFTWARE = "exit_software";
public const string RESTART_SOFTWARE = "Restart_software";
public const string GET_SOFTWARE_RUNNING = "get_software_running";
public const string SHUTDOWN_COMPUTER = "shutdown_computer";
public const string RESTART_COMPUTER = "restart_computer";
public const string SET_SEQUENCE_FILE = "set_sequence_file";
public const string GET_REMOTE_MODE = "get_remote_mode";
public const string SET_REMOTE_MODE = "set_remote_mode_type";
public const string ENTER_REMOTE_MODE = "enter_remote_mode";
public const string EXIT_REMOTE_MODE = "exit_remote_mode";
public const string START = "Start"; // Start Job or Sequence
public const string STOP = "Stop"; // Stop Job or Sequence
public const string GET_LAST_JOB_RESULT = "get_last_job_result";
public const string GET_LAST_SEQ_RESULT = "get_last_sequence_result";
public const string GET_LAST_JOB_FAIL_CODE = "get_last_job_fail_codes";
public const string GET_LAST_JOB_METRIC = "get_last_job_metric";
public const string GET_SYSTEM_STATE = "get_system_state";
public const string GET_WAITING_FOR_TRIGGER = "get_waiting_for_trigger";
public const string GET_READY_FOR_COMMAND = "get_ready_for_command";
public const string GET_LOCATION_IN_SEQ = "get_location_in_sequence";
public const string GET_CURRENT_REMOTE_ACQ = "get_current_remote_acquisition";
public const string GET_CURRENT_NUMBER_OF_ELEMENTS = "get_current_number_of_elements";
public const string GET_LAST_NUMBER_OF_ELEMENTS = "get_last_number_of_elements";
public const string GET_JOB_PARAMETER = "get_job_parameter";
public const string SET_JOB_PARAMETER = "set_job_parameter";
}
#region Measurement Designations
internal class OmniWELD
{
// OmniWELD
public const string KHD = "KHD"; // Keyhole: Keyhole Depth Measurement
public const string FWS = "FWS"; // Finished Weld Surface: Finished Weld Surface Height Measurement
public const string XSP = "XSP"; // Keyhole/Finished Weld Surface: Cross-Sectional Parameter Measurement
public const string SPO = "SPO"; // Seam Profile: 1 Edge Scheme - Seam Position Measurement
public const string SLE = "SLE"; // Seam Profile: 2 Edge Scheme - Seam Left Edge Position Measurement
public const string SRE = "SRE"; // Seam Profile: 2 Edge Scheme - Seam Right Edge Position Measurement
public const string SLH = "SLH"; // Seam Profile: 2 Edge Scheme - Seam Left Edge Height Measurement
public const string SRH = "SRH"; // Seam Profile: 2 Edge Scheme - Seam Left Edge Height Measurement
public const string SHH = "SHH"; // Seam Profile: 2 Edge Scheme - Seam Step Height Measurement
public const string SCP = "SCP"; // Seam Profile: 2 Edge Scheme - Seam Centre Position Measurement
public const string SGP = "SGP"; // Seam Profile: 2 Edge Scheme - Seam Gap Width Measurement
public const string SJP = "SJP"; // Seam Profile: 2 Edge Scheme - Seam Joint Feature Position Measurement
public const string SJH = "SJH"; // Seam Profile: 2 Edge Scheme - Seam Joint Feature Height Measurement
public const string WPH = "WPH"; // Workpiece Height: Workpiece Height Measurement
public const string TLE = "TLE"; // Transverse Profile: Transverse Profile Left Edge Position Measurement
public const string TRE = "TRE"; // Transverse Profile: Transverse Profile Right Edge Position Measurement
public const string TBC = "TBC"; // Transverse Profile: Weld Bead Centre Measurement
public const string TBW = "TBW"; // Transverse Profile: Weld Bead Width Measurement
// Reference Plane Calibration
public const string RPC = "RPC"; // Reference Plane Calibration
// Noise Calibration
public const string NSC = "NSC"; // Noise Calibration
// QA Bound Parameters
public const string MIN = "MIN"; // Noise Calibration
public const string MAX = "MAX"; // Noise Calibration
// QA Bound Parameter Designations BBB
// KHD-MAX : Keyhole depth shallowest depth
// KHD-MIN : Keyhole depth deepest depth
// FWS-MAX : Finished weld surface highest height
// FWS-MIN : Finished weld surface lowest height
// SLE-MIN : Seam left edge leftmost position
// SLE-MAX : Seam left edge rightmost position
}
#endregion
#region Metric Codes
internal class LDDMetricCode
{
// Feature Tracking Metric Codes
public const string FTNTP = "FTNTP"; // Feature Tracking: Number of Tracked Points
public const string FTMIN = "FTMIN"; // Feature Tracking: Lowest Value (um)
public const string FTMAX = "FTMAX"; // Feature Tracking: Highest Value (um)
public const string FTAVG = "FTAVG"; // Feature Tracking: Average Value (um)
public const string FTSTD = "FTSTD"; // Feature Tracking: Standard Deviation (um)
// Quality Assurance Metric Codes
public const string QATDB = "QATDB"; // QA: Total Distance Below Range (WU)
public const string QATDI = "QATDI"; // QA: Total Distance In Range (WU)
public const string QATDA = "QATDA"; // QA: Total Distance Above Range (WU)
public const string QATDO = "QATDO"; // QA: Total Distance Outside of Range (WU)
public const string QATDN = "QATDN"; // QA: Total Distance No Signal (WU)
}
#endregion
#region Job File Parameter Designations
internal class LDDGeneralPrameter
{
public const string FileName = "FileName"; // File name seed used for all saved data files. Note that this is not the full file path.
public const string WeldSpeed = "WeldSpeed"; // Welding speed in mm/s or rpm depending on motion path (linear vs radial).
public const string RefPlanePos = "RefPlanePos"; // Reference plane position in um. This is the position used during OmniWELD if USE LIVE VIEWING POSITION is not TRUE.
public const string KeyholeLagDist = "KeyholeLagDist"; // Keyhole lag distance (from process beam origin) in um.
public const string KeyholeLagDir = "KeyholeLagDir"; // Keyhole lag angle (from +x axis) in degrees.
public const string OmniWELDOrient = "OmniWELDOrient"; // OmniWELD orientation angle (from +x axis) in degrees.
public const string WHLagDist = "WHLagDist"; // Workpiece Height point measurement lag distance (from process beam origin) in um.
public const string WHLagDir = "WHLagDir"; // Workpiece Height Point measurement lag angle (from +x axis) in degrees.
public const string TiltAngle = "TiltAngle"; // Imaging beam incident angle from the perpendicular.
}
#endregion
#endregion
#region EIP Command Tag
internal class LDDTag
{
// Input
public const string ACQ_N = "LDD_acq_n"; // Instructs the IPG OmniWELD software to load the specified sequence or job number.
public const string ACQ_N_LATCH = "LDD_acq_latch"; // Latching this tag indicates that the mapped job/sequence specified by LDD_acq_n should be started.
// Output
public const string READY_CMD = "LDD_ready_cmd"; // If true, indicates that the ICI system is ready to receive a command.
public const string WAIT_TRIG = "LDD_wait_trig"; // If true, indicates that the ICI system is ready to receive a trigger.
public const string SYS_OK = "LDD_sys_ok"; // If true, indicates that the IPG OmniWELD software is running and not in an error state.
public const string ACQ = "LDD_acq"; // If true, indicates that the ICI system is currently acquiring data.
public const string REMOTE_CONTROL = "LDD_remote_control"; // If true, indicates that the IPG OmniWELD software is currently in remote mode.
public const string JOB_OK = "LDD_job_ok"; // Indicates whether the last job passed on all failure QA metrics.
public const string JOB_NOK = "LDD_job_nok"; // Indicates whether the last job failed on any failure QA metrics.
public const string JOB_NO_WARN = "LDD_job_no_warn"; // Indicates whether the last job passed on all warning QA metrics.
public const string JOB_WARN = "LDD_job_warn"; // Indicates whether the last job failed on any warning QA metrics.
public const string JOB_FAIL_ENABLED = "LDD_fail_enabled"; // Indicates whether failure QA was enabled on the last completed job.
public const string JOB_WARN_ENABLED = "LDD_job_warn_enabled"; // Indicates whether warning QA was enabled on the last completed job.
public const string JOB_COMPLETE = "LDD_job_complete"; // Indicates that the job has been completed and the QA results are ready
public const string JOB_PROC = "LDD_job_proc"; // The current job number (if in remote job file mode). A value of 0 indicates that no job is running.
public const string SEQ_PROC = "LDD_seq_proc"; // The current sequence number (if in remote sequence mode). A value of 0 indicates that no sequence is running.
public const string SEQ_COMPLETE = "LDD_seq_complete"; // Indicates that the last sequence has completed all acquisitions
public const string SEQ_FAIL = "LDD_seq_fail"; // Indicates the overall fail QA result for the last completed sequence.
public const string SEQ_PASS = "LDD_seq_pass"; // Indicates the overall pass QA result for the last completed sequence.
public const string CURRENT_JOB = "LDD_current_job"; // Indicates the current job number within the active sequence.
public const string CURRENT_SEQ = "LDD_current_seq"; // Indicates the current job/sequence number that is running in remote mode.
public const string CURRENT_WORKPIECE = "LDD_current_workpiece";// Indicates the assigned Workpiece ID Number of the current job number that is running in remote mode.
public const string CURRENT_FEATURE = "LDD_current_feature"; // Indicates the assigned Feature ID Number of the current job number that is running in remote mode.
public const string WORKPIECE_PROC = "LDD_workpiece_proc"; // Indicates the Assigned Workpiece ID Number of the last processed/completed job.
public const string FEATURE_PROC = "LDD_feature_proc"; // Indicates the Assigned Feature ID Number of the last processed/completed job.
public const string SERIAL_COUNTER = "LDD_serial_counter"; // Indicates the next Workpiece serial number in the buffer.
public const string ANALOG_C_ENABLED = "LDD_analog_c_enabled"; // Indicates if an analog output is enabled on BNC C
public const string ANALOG_D_ENABLED = "LDD_analog_d_enabled"; // Indicates if an analog output is enabled on BNC D
// Command Line Interface
public const string COMMAND = "LDD_command"; // Used for sending CL commands to the ICI system.
public const string PRIMARY_RESP = "LDD_primary_resp"; // Used to receive the primary response.
public const string SECONDARY_RESP = "LDD_secondary_resp"; // Used to receive the secondary response.
}
#endregion
}