using Aurora.Api; using Aurora.Api.Devices; using Hermes; using Newtonsoft.Json.Linq; using Opc.Ua; using Opc.Ua.Client; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.Remoting.Contexts; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Documents; namespace AuroraLaser.Trumpf { /// /// TruDisk와 Input Word, Output Word가 많이 다름 확인 /// 그에 따라, class 추가하였음. /// 1. Address 수정 필요함. /// 2. ID, PW는 확인 필요함. /// public partial class LaserTruFiber : SocketConn, ILaser { private Session _session = null; private Subscription _subscription = null; // 해당 부분도 하드 코딩 되어 있음 변경 필요함. public string strServerAddress = @"opc.tcp://172.29.3.1:4840"; public string strID = "060"; public string strPW = "060a342"; public bool IsConnect { get { if (_session == null) return false; return _session.Connected; } } private bool _IsSimul; private bool _isReconnecting = false; public enum eSeqStep : int { SEQ_NONE = 0, SEQ_LASER_ON_START, SEQ_LASER_ON_EXT_ACTIVE_CHK, SEQ_LASER_RESET_ON_CHK, SEQ_LASER_RESET_ON_DELAY, SEQ_LASER_RESET_OFF_CHK, SEQ_LASER_ON_LASER_ON_CHK, SEQ_LASER_ON_READY_CHK, SEQ_LASER_ON_STATICAL_ON_CHK, SEQ_LASER_ON_PROG_ACTIVE_CHK, SEQ_LASER_ON_DEACTIVATE, SEQ_LASER_ON_CHANGE_PROG_INFO, SEQ_LASER_OFF_START, SEQ_LASER_OFF_PROG_STOP_ON_CHK, SEQ_LASER_OFF_PROG_STOP_ON_DELAY, SEQ_LASER_OFF_PROG_STOP_OFF_CHK, SEQ_LASER_PILOT_LASER_ON_START, SEQ_LASER_PILOT_LASER_ON_EXT_ACTIVE_CHK, SEQ_LASER_PILOT_LASER_ON_RESET_ON_CHK, SEQ_LASER_PILOT_LASER_ON_RESET_ON_DELAY, SEQ_LASER_PILOT_LASER_ON_RESET_OFF_CHK, SEQ_LASER_PILOT_LASER_ON_PILOT_LASER_ON_CHK, SEQ_LASER_PILOT_LASER_OFF_START, SEQ_LASER_PILOT_LASER_OFF_CHK, SEQ_LASER_PILOT_LASER_OFF_REQUEST_LASER_ON_CHK, SEQ_LASER_PILOT_LASER_OFF_REQUEST_LASER_DELAY, SEQ_LASER_PILOT_LASER_OFF_REQUEST_LASER_OFF_CHK, }; private eSeqStep nSequence; public eLaserStatus nLaserStatus; public bool AutoProgramStart { get; set; } = true; Thread m_threadTruFiberSeq = null; List readNodeIdList = null; List writeNodeIdList = null; // Read/Write node information public sNodeInfo[] ReadNode = new sNodeInfo[100]; public sNodeInfo[] WriteNode = new sNodeInfo[100]; protected readonly object readNodeLock = new object(); protected readonly object writeNodeLock = new object(); protected readonly object sessionLock = new object(); public LaserTruFiber(string deviceid, bool isSimul, string slotNo, SocketProtocol type, bool isCallBack = false) : base(deviceid, isSimul, type) { _IsSimul = isSimul; nLaserStatus = eLaserStatus.STATUS_NONE; nSequence = eSeqStep.SEQ_NONE; for (int i = 0; i < 100; i++) { ReadNode[i].nExist = 0; ReadNode[i].IsCallBack = isCallBack ? 1 : 0; ReadNode[i].nDigit = 1; ReadNode[i].priority = 1; // 기본값 WriteNode[i].nExist = 0; WriteNode[i].IsCallBack = isCallBack ? 1 : 0; WriteNode[i].nDigit = 1; ReadNode[i].priority = 1; // 기본값 } string strHead = "ns=2;s="; string strSlotNo = string.Format("MPI-Slot0{0}", slotNo); //---------- Read NODE ReadNode[csReadNodeNo.EXT_ACTIVATION_ACTIVE].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word00.EXT_ACTIVATION_ACTIVE"; ReadNode[csReadNodeNo.EXT_ACTIVATION_ACTIVE].strDisplayNodeName = "EXT ACTIVATION ACTIVE"; ReadNode[csReadNodeNo.EXT_ACTIVATION_ACTIVE].nNodeType = csNodeType.BOOL; ReadNode[csReadNodeNo.EXT_ACTIVATION_ACTIVE].nExist = 1; ReadNode[csReadNodeNo.EXT_ACTIVATION_ACTIVE].strKey = "0"; ReadNode[csReadNodeNo.EXT_ACTIVATION_ACTIVE].priority = 0; ReadNode[csReadNodeNo.LASER_WARNING_LAMP_IS_ON].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word00.LASER_WARNINGLAMP_IS_ON"; ReadNode[csReadNodeNo.LASER_WARNING_LAMP_IS_ON].strDisplayNodeName = "LASER WARNING LAMP IS ON"; ReadNode[csReadNodeNo.LASER_WARNING_LAMP_IS_ON].nNodeType = csNodeType.BOOL; ReadNode[csReadNodeNo.LASER_WARNING_LAMP_IS_ON].nExist = 1; ReadNode[csReadNodeNo.LASER_WARNING_LAMP_IS_ON].strKey = "1"; ReadNode[csReadNodeNo.LASER_WARNING_LAMP_IS_ON].priority = 0; ReadNode[csReadNodeNo.LASER_READY].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word00.LASER_READY"; ReadNode[csReadNodeNo.LASER_READY].strDisplayNodeName = "LASER READY"; ReadNode[csReadNodeNo.LASER_READY].nNodeType = csNodeType.BOOL; ReadNode[csReadNodeNo.LASER_READY].nExist = 1; ReadNode[csReadNodeNo.LASER_READY].strKey = "2"; ReadNode[csReadNodeNo.LASER_READY].priority = 0; ReadNode[csReadNodeNo.LASER_IS_ON].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word00.LASER_IS_ON"; ReadNode[csReadNodeNo.LASER_IS_ON].strDisplayNodeName = "LASER IS ON"; ReadNode[csReadNodeNo.LASER_IS_ON].nNodeType = csNodeType.BOOL; ReadNode[csReadNodeNo.LASER_IS_ON].nExist = 1; ReadNode[csReadNodeNo.LASER_IS_ON].strKey = "3"; ReadNode[csReadNodeNo.LASER_IS_ON].priority = 0; ReadNode[csReadNodeNo.LASER_ASSIGNED].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word00.LASER_ASSIGNED"; ReadNode[csReadNodeNo.LASER_ASSIGNED].strDisplayNodeName = "LASER ASSIGNED"; ReadNode[csReadNodeNo.LASER_ASSIGNED].nNodeType = csNodeType.BOOL; ReadNode[csReadNodeNo.LASER_ASSIGNED].nExist = 1; ReadNode[csReadNodeNo.LASER_ASSIGNED].strKey = "4"; ReadNode[csReadNodeNo.LASER_ASSIGNED].priority = 0; ReadNode[csReadNodeNo.PILOT_LASER_IS_ON].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word00.PILOT_LASER_IS_ON"; ReadNode[csReadNodeNo.PILOT_LASER_IS_ON].strDisplayNodeName = "PILOT LASER IS ON"; ReadNode[csReadNodeNo.PILOT_LASER_IS_ON].nNodeType = csNodeType.BOOL; ReadNode[csReadNodeNo.PILOT_LASER_IS_ON].nExist = 1; ReadNode[csReadNodeNo.PILOT_LASER_IS_ON].strKey = "5"; ReadNode[csReadNodeNo.PILOT_LASER_IS_ON].priority = 0; ReadNode[csReadNodeNo.PROG_COMPLETED].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word00.PROG_COMPLETED"; ReadNode[csReadNodeNo.PROG_COMPLETED].strDisplayNodeName = "PROG COMPLETED"; ReadNode[csReadNodeNo.PROG_COMPLETED].nNodeType = csNodeType.BOOL; ReadNode[csReadNodeNo.PROG_COMPLETED].nExist = 1; ReadNode[csReadNodeNo.PROG_COMPLETED].strKey = "6"; ReadNode[csReadNodeNo.PROG_COMPLETED].priority = 0; ReadNode[csReadNodeNo.FAULT_LASER].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word00.FAULT_LASER"; ReadNode[csReadNodeNo.FAULT_LASER].strDisplayNodeName = "FAULT LASER"; ReadNode[csReadNodeNo.FAULT_LASER].nNodeType = csNodeType.BOOL; ReadNode[csReadNodeNo.FAULT_LASER].nExist = 1; ReadNode[csReadNodeNo.FAULT_LASER].strKey = "7"; ReadNode[csReadNodeNo.FAULT_LASER].priority = 0; ReadNode[csReadNodeNo.PROG_ACTIVE].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word00.PROG_ACTIV"; ReadNode[csReadNodeNo.PROG_ACTIVE].strDisplayNodeName = "PROG ACTIVE"; ReadNode[csReadNodeNo.PROG_ACTIVE].nNodeType = csNodeType.BOOL; ReadNode[csReadNodeNo.PROG_ACTIVE].nExist = 1; ReadNode[csReadNodeNo.PROG_ACTIVE].strKey = "8"; ReadNode[csReadNodeNo.PROG_ACTIVE].priority = 0; ReadNode[csReadNodeNo.PROG_CANCELLED].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word00.PROG_CANCELLED"; ReadNode[csReadNodeNo.PROG_CANCELLED].strDisplayNodeName = "PROG CANCELLED"; ReadNode[csReadNodeNo.PROG_CANCELLED].nNodeType = csNodeType.BOOL; ReadNode[csReadNodeNo.PROG_CANCELLED].nExist = 1; ReadNode[csReadNodeNo.PROG_CANCELLED].strKey = "9"; ReadNode[csReadNodeNo.PROG_CANCELLED].priority = 0; ReadNode[csReadNodeNo.PROGRAM_NO].strNodeName = strHead + "ProgramNo"; ReadNode[csReadNodeNo.PROGRAM_NO].strDisplayNodeName = "PROGRAM NO"; ReadNode[csReadNodeNo.PROGRAM_NO].nNodeType = csNodeType.UINT16; ReadNode[csReadNodeNo.PROGRAM_NO].nExist = 1; ReadNode[csReadNodeNo.PROGRAM_NO].strKey = "10"; ReadNode[csReadNodeNo.PROGRAM_NO].priority = 0; ReadNode[csReadNodeNo.PROGRAM_LINE_NO].strNodeName = strHead + "ProgramLineNo"; ReadNode[csReadNodeNo.PROGRAM_LINE_NO].strDisplayNodeName = "PROGRAM LINE NO"; ReadNode[csReadNodeNo.PROGRAM_LINE_NO].nNodeType = csNodeType.UINT16; ReadNode[csReadNodeNo.PROGRAM_LINE_NO].nExist = 1; ReadNode[csReadNodeNo.PROGRAM_LINE_NO].strKey = "11"; ReadNode[csReadNodeNo.PROGRAM_LINE_NO].priority = 0; ReadNode[csReadNodeNo.MAINTENANCE].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word03.MAINTENANCE"; ReadNode[csReadNodeNo.MAINTENANCE].strDisplayNodeName = "MAINTENANCE"; ReadNode[csReadNodeNo.MAINTENANCE].nNodeType = csNodeType.BOOL; ReadNode[csReadNodeNo.MAINTENANCE].nExist = 1; ReadNode[csReadNodeNo.MAINTENANCE].strKey = "16"; ReadNode[csReadNodeNo.MONITORING].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word00.MONITORING"; ReadNode[csReadNodeNo.MONITORING].strDisplayNodeName = "MONITORING"; ReadNode[csReadNodeNo.MONITORING].nNodeType = csNodeType.BOOL; ReadNode[csReadNodeNo.MONITORING].nExist = 1; ReadNode[csReadNodeNo.MONITORING].strKey = "17"; ReadNode[csReadNodeNo.MONITORING].priority = 0; ReadNode[csReadNodeNo.POWER_LIMIT].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word00.POWER_LIMIT"; ReadNode[csReadNodeNo.POWER_LIMIT].strDisplayNodeName = "POWER LIMIT"; ReadNode[csReadNodeNo.POWER_LIMIT].nNodeType = csNodeType.BOOL; ReadNode[csReadNodeNo.POWER_LIMIT].nExist = 1; ReadNode[csReadNodeNo.POWER_LIMIT].strKey = "18"; ReadNode[csReadNodeNo.SIK_OPEN].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word00.SIK_OPEN"; ReadNode[csReadNodeNo.SIK_OPEN].strDisplayNodeName = "SIK OPEN"; ReadNode[csReadNodeNo.SIK_OPEN].nNodeType = csNodeType.BOOL; ReadNode[csReadNodeNo.SIK_OPEN].nExist = 1; ReadNode[csReadNodeNo.SIK_OPEN].strKey = "21"; ReadNode[csReadNodeNo.SYS_LASER_ESTOP_OPEN].strNodeName = strHead + "SystemState.ESTOP_OPEN"; ReadNode[csReadNodeNo.SYS_LASER_ESTOP_OPEN].strDisplayNodeName = "SYS LASER ESTOP OPEN"; ReadNode[csReadNodeNo.SYS_LASER_ESTOP_OPEN].nNodeType = csNodeType.BOOL; ReadNode[csReadNodeNo.SYS_LASER_ESTOP_OPEN].nExist = 1; ReadNode[csReadNodeNo.SYS_LASER_ESTOP_OPEN].strKey = "25"; ReadNode[csReadNodeNo.PULSE_POWER].strNodeName = strHead + "PulseData.PulsePower"; ReadNode[csReadNodeNo.PULSE_POWER].strDisplayNodeName = "PULSE POWER"; ReadNode[csReadNodeNo.PULSE_POWER].nNodeType = csNodeType.DOUBLE; ReadNode[csReadNodeNo.PULSE_POWER].nExist = 1; ReadNode[csReadNodeNo.PULSE_POWER].nDigit = 1000; ReadNode[csReadNodeNo.PULSE_POWER].strKey = "26"; ReadNode[csReadNodeNo.PULSE_POWER_NOMINAL].strNodeName = strHead + "PulseData.PulsePowerNominal"; ReadNode[csReadNodeNo.PULSE_POWER_NOMINAL].strDisplayNodeName = "PULSE POWER NOMINAL"; ReadNode[csReadNodeNo.PULSE_POWER_NOMINAL].nNodeType = csNodeType.DOUBLE; ReadNode[csReadNodeNo.PULSE_POWER_NOMINAL].nExist = 1; ReadNode[csReadNodeNo.PULSE_POWER_NOMINAL].nDigit = 1000; ReadNode[csReadNodeNo.PULSE_POWER_NOMINAL].strKey = "27"; ReadNode[csReadNodeNo.CW_POWER].strNodeName = strHead + "PulseData.CwPower"; ReadNode[csReadNodeNo.CW_POWER].strDisplayNodeName = "CW POWER"; ReadNode[csReadNodeNo.CW_POWER].nNodeType = csNodeType.DOUBLE; ReadNode[csReadNodeNo.CW_POWER].nExist = 1; ReadNode[csReadNodeNo.CW_POWER].strKey = "28"; ReadNode[csReadNodeNo.POWER].strNodeName = strHead + "PulseData.Power"; ReadNode[csReadNodeNo.POWER].strDisplayNodeName = "POWER"; ReadNode[csReadNodeNo.POWER].nNodeType = csNodeType.DOUBLE; ReadNode[csReadNodeNo.POWER].nExist = 1; ReadNode[csReadNodeNo.POWER].strKey = "29"; ReadNode[csReadNodeNo.ENERGEY].strNodeName = strHead + "PulseData.Energy"; ReadNode[csReadNodeNo.ENERGEY].strDisplayNodeName = "ENERGY"; ReadNode[csReadNodeNo.ENERGEY].nNodeType = csNodeType.UINT64; ReadNode[csReadNodeNo.ENERGEY].nExist = 1; ReadNode[csReadNodeNo.ENERGEY].strKey = "30"; ReadNode[csReadNodeNo.FREQUENCY].strNodeName = strHead + "PulseData.Frequency"; ReadNode[csReadNodeNo.FREQUENCY].strDisplayNodeName = "FREQUENCY"; ReadNode[csReadNodeNo.FREQUENCY].nNodeType = csNodeType.DOUBLE; ReadNode[csReadNodeNo.FREQUENCY].nExist = 1; ReadNode[csReadNodeNo.FREQUENCY].strKey = "31"; ReadNode[csReadNodeNo.FREQUENCY_NOMINAL].strNodeName = strHead + "PulseData.FrequencyNominal"; ReadNode[csReadNodeNo.FREQUENCY_NOMINAL].strDisplayNodeName = "FREQUENCY NOMINAL"; ReadNode[csReadNodeNo.FREQUENCY_NOMINAL].nNodeType = csNodeType.DOUBLE; ReadNode[csReadNodeNo.FREQUENCY_NOMINAL].nExist = 1; ReadNode[csReadNodeNo.FREQUENCY_NOMINAL].strKey = "32"; ReadNode[csReadNodeNo.PULSE_DURATION].strNodeName = strHead + "PulseData.PulseDuration"; ReadNode[csReadNodeNo.PULSE_DURATION].strDisplayNodeName = "PULSE DURATION"; ReadNode[csReadNodeNo.PULSE_DURATION].nNodeType = csNodeType.UINT32; ReadNode[csReadNodeNo.PULSE_DURATION].nExist = 1; ReadNode[csReadNodeNo.PULSE_DURATION].strKey = "33"; ReadNode[csReadNodeNo.PULSE_DURATION_NOMINAL].strNodeName = strHead + "PulseData.PulseDurationNominal"; ReadNode[csReadNodeNo.PULSE_DURATION_NOMINAL].strDisplayNodeName = "PULSE DURATION NOMINAL"; ReadNode[csReadNodeNo.PULSE_DURATION_NOMINAL].nNodeType = csNodeType.DOUBLE; ReadNode[csReadNodeNo.PULSE_DURATION_NOMINAL].nExist = 1; ReadNode[csReadNodeNo.PULSE_DURATION_NOMINAL].strKey = "34"; ReadNode[csReadNodeNo.PULSE_NUMBER].strNodeName = strHead + "PulseData.PulseNumber"; ReadNode[csReadNodeNo.PULSE_NUMBER].strDisplayNodeName = "PULSE NUMBER"; ReadNode[csReadNodeNo.PULSE_NUMBER].nNodeType = csNodeType.UINT16; ReadNode[csReadNodeNo.PULSE_NUMBER].nExist = 1; ReadNode[csReadNodeNo.PULSE_NUMBER].strKey = "35"; ReadNode[csReadNodeNo.PULSE_NUMBER_NOMINAL].strNodeName = strHead + "PulseData.PulseNumberNominal"; ReadNode[csReadNodeNo.PULSE_NUMBER_NOMINAL].strDisplayNodeName = "PULSE NUMBER NOMINAL"; ReadNode[csReadNodeNo.PULSE_NUMBER_NOMINAL].nNodeType = csNodeType.UINT16; ReadNode[csReadNodeNo.PULSE_NUMBER_NOMINAL].nExist = 1; ReadNode[csReadNodeNo.PULSE_NUMBER_NOMINAL].strKey = "36"; ReadNode[csReadNodeNo.COOLING_DI_PRESSURE_DIFF].strNodeName = strHead + "Cooling.DIPressureDiff"; ReadNode[csReadNodeNo.COOLING_DI_PRESSURE_DIFF].strDisplayNodeName = "DI PRESSURE DIFF"; ReadNode[csReadNodeNo.COOLING_DI_PRESSURE_DIFF].nNodeType = csNodeType.DOUBLE; ReadNode[csReadNodeNo.COOLING_DI_PRESSURE_DIFF].nExist = 1; ReadNode[csReadNodeNo.COOLING_DI_PRESSURE_DIFF].strKey = "37"; ReadNode[csReadNodeNo.OW06].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word06"; ReadNode[csReadNodeNo.OW06].strDisplayNodeName = "OW06"; ReadNode[csReadNodeNo.OW06].nNodeType = csNodeType.UINT16; ReadNode[csReadNodeNo.OW06].nExist = 1; ReadNode[csReadNodeNo.OW06].strKey = "66"; ReadNode[csReadNodeNo.OW06].priority = 0; ReadNode[csReadNodeNo.OW07].strNodeName = strHead +"Production." + strSlotNo + ".Output.Word07"; ReadNode[csReadNodeNo.OW07].strDisplayNodeName = "OW07"; ReadNode[csReadNodeNo.OW07].nNodeType = csNodeType.UINT16; ReadNode[csReadNodeNo.OW07].nExist = 1; ReadNode[csReadNodeNo.OW07].strKey = "67"; ReadNode[csReadNodeNo.OW07].priority = 0; ReadNode[csReadNodeNo.OW08].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word08"; ReadNode[csReadNodeNo.OW08].strDisplayNodeName = "OW08"; ReadNode[csReadNodeNo.OW08].nNodeType = csNodeType.UINT16; ReadNode[csReadNodeNo.OW08].nExist = 1; ReadNode[csReadNodeNo.OW08].strKey = "68"; ReadNode[csReadNodeNo.OW08].priority = 0; ReadNode[csReadNodeNo.OW09].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word09"; ReadNode[csReadNodeNo.OW09].strDisplayNodeName = "OW09"; ReadNode[csReadNodeNo.OW09].nNodeType = csNodeType.UINT16; ReadNode[csReadNodeNo.OW09].nExist = 1; ReadNode[csReadNodeNo.OW09].strKey = "69"; ReadNode[csReadNodeNo.OW09].priority = 0; ReadNode[csReadNodeNo.OW10].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word10"; ReadNode[csReadNodeNo.OW10].strDisplayNodeName = "OW10"; ReadNode[csReadNodeNo.OW10].nNodeType = csNodeType.UINT16; ReadNode[csReadNodeNo.OW10].nExist = 1; ReadNode[csReadNodeNo.OW10].strKey = "70"; ReadNode[csReadNodeNo.OW10].priority = 0; ReadNode[csReadNodeNo.OW11].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word11"; ReadNode[csReadNodeNo.OW11].strDisplayNodeName = "OW11"; ReadNode[csReadNodeNo.OW11].nNodeType = csNodeType.UINT16; ReadNode[csReadNodeNo.OW11].nExist = 1; ReadNode[csReadNodeNo.OW11].strKey = "71"; ReadNode[csReadNodeNo.OW11].priority = 0; ReadNode[csReadNodeNo.OW12].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word12"; ReadNode[csReadNodeNo.OW12].strDisplayNodeName = "OW12"; ReadNode[csReadNodeNo.OW12].nNodeType = csNodeType.UINT16; ReadNode[csReadNodeNo.OW12].nExist = 1; ReadNode[csReadNodeNo.OW12].strKey = "72"; ReadNode[csReadNodeNo.OW12].priority = 0; ReadNode[csReadNodeNo.OW13].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word13"; ReadNode[csReadNodeNo.OW13].strDisplayNodeName = "OW13"; ReadNode[csReadNodeNo.OW13].nNodeType = csNodeType.UINT16; ReadNode[csReadNodeNo.OW13].nExist = 1; ReadNode[csReadNodeNo.OW13].strKey = "73"; ReadNode[csReadNodeNo.OW13].priority = 0; ReadNode[csReadNodeNo.OW14].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word14"; ReadNode[csReadNodeNo.OW14].strDisplayNodeName = "OW14"; ReadNode[csReadNodeNo.OW14].nNodeType = csNodeType.UINT16; ReadNode[csReadNodeNo.OW14].nExist = 1; ReadNode[csReadNodeNo.OW14].strKey = "74"; ReadNode[csReadNodeNo.OW14].priority = 0; ReadNode[csReadNodeNo.OW15].strNodeName = strHead + "Production." + strSlotNo + ".Output.Word15"; ReadNode[csReadNodeNo.OW15].strDisplayNodeName = "OW15"; ReadNode[csReadNodeNo.OW15].nNodeType = csNodeType.UINT16; ReadNode[csReadNodeNo.OW15].nExist = 1; ReadNode[csReadNodeNo.OW15].strKey = "75"; ReadNode[csReadNodeNo.OW15].priority = 0; ReadNode[csReadNodeNo.LASTMESSAGE_TYPE].strNodeName = strHead + "LastMessage.Type"; ReadNode[csReadNodeNo.LASTMESSAGE_TYPE].strDisplayNodeName = "LASTMESSAGE_TYPE"; ReadNode[csReadNodeNo.LASTMESSAGE_TYPE].nNodeType = csNodeType.INT; ReadNode[csReadNodeNo.LASTMESSAGE_TYPE].nExist = 1; ReadNode[csReadNodeNo.LASTMESSAGE_TYPE].strKey = "90"; ReadNode[csReadNodeNo.LASTMESSAGE_COMPID].strNodeName = strHead + "LastMessage.CompID"; ReadNode[csReadNodeNo.LASTMESSAGE_COMPID].strDisplayNodeName = "LASTMESSAGE_COMPID"; ReadNode[csReadNodeNo.LASTMESSAGE_COMPID].nNodeType = csNodeType.BYTE; ReadNode[csReadNodeNo.LASTMESSAGE_COMPID].nExist = 1; ReadNode[csReadNodeNo.LASTMESSAGE_COMPID].strKey = "91"; ReadNode[csReadNodeNo.LASTMESSAGE_COMPNUM].strNodeName = strHead + "LastMessage.CompNUM"; ReadNode[csReadNodeNo.LASTMESSAGE_COMPNUM].strDisplayNodeName = "LASTMESSAGE_COMPNUM"; ReadNode[csReadNodeNo.LASTMESSAGE_COMPNUM].nNodeType = csNodeType.BYTE; ReadNode[csReadNodeNo.LASTMESSAGE_COMPNUM].nExist = 1; ReadNode[csReadNodeNo.LASTMESSAGE_COMPNUM].strKey = "92"; ReadNode[csReadNodeNo.LASTMESSAGE_MSGCODE].strNodeName = strHead + "LastMessage.MsgCode"; ReadNode[csReadNodeNo.LASTMESSAGE_MSGCODE].strDisplayNodeName = "LASTMESSAGE_MSGCODE"; ReadNode[csReadNodeNo.LASTMESSAGE_MSGCODE].nNodeType = csNodeType.UINT16; ReadNode[csReadNodeNo.LASTMESSAGE_MSGCODE].nExist = 1; ReadNode[csReadNodeNo.LASTMESSAGE_MSGCODE].strKey = "93"; ReadNode[csReadNodeNo.LASTMESSAGE_SHORTTEXT].strNodeName = strHead + "LastMessage.ShortText"; ReadNode[csReadNodeNo.LASTMESSAGE_SHORTTEXT].strDisplayNodeName = "LASTMESSAGE_SHORTTEXT"; ReadNode[csReadNodeNo.LASTMESSAGE_SHORTTEXT].nNodeType = csNodeType.STRING; ReadNode[csReadNodeNo.LASTMESSAGE_SHORTTEXT].nExist = 1; ReadNode[csReadNodeNo.LASTMESSAGE_SHORTTEXT].strKey = "94"; ReadNode[csReadNodeNo.LASTMESSAGE_TIMESTAMP].strNodeName = strHead + "LastMessage.Timestamp"; ReadNode[csReadNodeNo.LASTMESSAGE_TIMESTAMP].strDisplayNodeName = "LASTMESSAGE_TIMESTAMP"; ReadNode[csReadNodeNo.LASTMESSAGE_TIMESTAMP].nNodeType = csNodeType.STRING; ReadNode[csReadNodeNo.LASTMESSAGE_TIMESTAMP].nExist = 1; ReadNode[csReadNodeNo.LASTMESSAGE_TIMESTAMP].strKey = "95"; //---------- Write NODE strHead = "ns=2;s="; WriteNode[csWriteNodeNo.EXT_ACTIVATION].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word00.EXT_ACTIVATION"; WriteNode[csWriteNodeNo.EXT_ACTIVATION].strDisplayNodeName = "EXT ACTIVATION"; WriteNode[csWriteNodeNo.EXT_ACTIVATION].nNodeType = csNodeType.BOOL; WriteNode[csWriteNodeNo.EXT_ACTIVATION].nExist = 1; WriteNode[csWriteNodeNo.EXT_ACTIVATION].strKey = "100"; WriteNode[csWriteNodeNo.EXT_ACTIVATION].priority = 0; WriteNode[csWriteNodeNo.LASER_RESET].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word00.RESET"; WriteNode[csWriteNodeNo.LASER_RESET].strDisplayNodeName = "LASER RESET"; WriteNode[csWriteNodeNo.LASER_RESET].nNodeType = csNodeType.BOOL; WriteNode[csWriteNodeNo.LASER_RESET].nExist = 1; WriteNode[csWriteNodeNo.LASER_RESET].strKey = "101"; WriteNode[csWriteNodeNo.LASER_RESET].priority = 0; WriteNode[csWriteNodeNo.LASER_ON].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word00.LASER_ON"; WriteNode[csWriteNodeNo.LASER_ON].strDisplayNodeName = "LASER ON"; WriteNode[csWriteNodeNo.LASER_ON].nNodeType = csNodeType.BOOL; WriteNode[csWriteNodeNo.LASER_ON].nExist = 1; WriteNode[csWriteNodeNo.LASER_ON].strKey = "102"; WriteNode[csWriteNodeNo.LASER_ON].priority = 0; WriteNode[csWriteNodeNo.PROG_STOP].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word00.PROG_STOP"; WriteNode[csWriteNodeNo.PROG_STOP].strDisplayNodeName = "PROG STOP"; WriteNode[csWriteNodeNo.PROG_STOP].nNodeType = csNodeType.BOOL; WriteNode[csWriteNodeNo.PROG_STOP].nExist = 1; WriteNode[csWriteNodeNo.PROG_STOP].strKey = "103"; WriteNode[csWriteNodeNo.PROG_STOP].priority = 0; WriteNode[csWriteNodeNo.PSTART_DYN].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word00.PSTART_DYN"; WriteNode[csWriteNodeNo.PSTART_DYN].strDisplayNodeName = "PSTART DYN"; WriteNode[csWriteNodeNo.PSTART_DYN].nNodeType = csNodeType.BOOL; WriteNode[csWriteNodeNo.PSTART_DYN].nExist = 1; WriteNode[csWriteNodeNo.PSTART_DYN].strKey = "104"; WriteNode[csWriteNodeNo.PSTART_DYN].priority = 0; WriteNode[csWriteNodeNo.REQUEST_LASER].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word00.REQUEST_LASER"; WriteNode[csWriteNodeNo.REQUEST_LASER].strDisplayNodeName = "REQUEST LASER"; WriteNode[csWriteNodeNo.REQUEST_LASER].nNodeType = csNodeType.BOOL; WriteNode[csWriteNodeNo.REQUEST_LASER].nExist = 1; WriteNode[csWriteNodeNo.REQUEST_LASER].strKey = "105"; WriteNode[csWriteNodeNo.REQUEST_LASER].priority = 0; WriteNode[csWriteNodeNo.PSTART_STATICAL].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word00.PSTART_STATICAL"; WriteNode[csWriteNodeNo.PSTART_STATICAL].strDisplayNodeName = "PSTART STATICAL"; WriteNode[csWriteNodeNo.PSTART_STATICAL].nNodeType = csNodeType.BOOL; WriteNode[csWriteNodeNo.PSTART_STATICAL].nExist = 1; WriteNode[csWriteNodeNo.PSTART_STATICAL].strKey = "106"; WriteNode[csWriteNodeNo.INQUIRY_1].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word00.INQUIRY_1"; WriteNode[csWriteNodeNo.INQUIRY_1].strDisplayNodeName = "INQUIRY 1"; WriteNode[csWriteNodeNo.INQUIRY_1].nNodeType = csNodeType.BOOL; WriteNode[csWriteNodeNo.INQUIRY_1].nExist = 1; WriteNode[csWriteNodeNo.INQUIRY_1].strKey = "107"; WriteNode[csWriteNodeNo.INQUIRY_2].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word00.INQUIRY_2"; WriteNode[csWriteNodeNo.INQUIRY_2].strDisplayNodeName = "INQUIRY 2"; WriteNode[csWriteNodeNo.INQUIRY_2].nNodeType = csNodeType.BOOL; WriteNode[csWriteNodeNo.INQUIRY_2].nExist = 1; WriteNode[csWriteNodeNo.INQUIRY_2].strKey = "108"; WriteNode[csWriteNodeNo.PILOT_LASER_ON].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word00.PILOT_LASER_ON"; WriteNode[csWriteNodeNo.PILOT_LASER_ON].strDisplayNodeName = "PILOT LASER ON"; WriteNode[csWriteNodeNo.PILOT_LASER_ON].nNodeType = csNodeType.BOOL; WriteNode[csWriteNodeNo.PILOT_LASER_ON].nExist = 1; WriteNode[csWriteNodeNo.PILOT_LASER_ON].strKey = "109"; WriteNode[csWriteNodeNo.PILOT_LASER_ON].priority = 0; WriteNode[csWriteNodeNo.FAULT_EXT].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word00.FAULT_EXT"; WriteNode[csWriteNodeNo.FAULT_EXT].strDisplayNodeName = "FAULT EXT"; WriteNode[csWriteNodeNo.FAULT_EXT].nNodeType = csNodeType.BOOL; WriteNode[csWriteNodeNo.FAULT_EXT].nExist = 1; WriteNode[csWriteNodeNo.FAULT_EXT].strKey = "110"; WriteNode[csWriteNodeNo.FAULT_EXT].priority = 0; WriteNode[csWriteNodeNo.LOCK_OPERATING_PANEL].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word00.LOCK_OPERATING_PANEL"; WriteNode[csWriteNodeNo.LOCK_OPERATING_PANEL].strDisplayNodeName = "LOCK OPERATING PANEL"; WriteNode[csWriteNodeNo.LOCK_OPERATING_PANEL].nNodeType = csNodeType.BOOL; WriteNode[csWriteNodeNo.LOCK_OPERATING_PANEL].nExist = 1; WriteNode[csWriteNodeNo.LOCK_OPERATING_PANEL].strKey = "111"; WriteNode[csWriteNodeNo.PROGRAM_NO].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word01.PROGRAM_No"; WriteNode[csWriteNodeNo.PROGRAM_NO].strDisplayNodeName = "PROGRAM NO"; WriteNode[csWriteNodeNo.PROGRAM_NO].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.PROGRAM_NO].nExist = 1; WriteNode[csWriteNodeNo.PROGRAM_NO].strKey = "112"; WriteNode[csWriteNodeNo.PROGRAM_NO].priority = 0; WriteNode[csWriteNodeNo.LIGHT_PATH_NO].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word01.LIGH_PATH_No"; WriteNode[csWriteNodeNo.LIGHT_PATH_NO].strDisplayNodeName = "LIGHT PATH NO"; WriteNode[csWriteNodeNo.LIGHT_PATH_NO].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.LIGHT_PATH_NO].nExist = 1; WriteNode[csWriteNodeNo.LIGHT_PATH_NO].strKey = "112"; WriteNode[csWriteNodeNo.LIGHT_PATH_NO].priority = 0; WriteNode[csWriteNodeNo.IW03].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word03"; WriteNode[csWriteNodeNo.IW03].strDisplayNodeName = "IW03"; WriteNode[csWriteNodeNo.IW03].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.IW03].nExist = 1; WriteNode[csWriteNodeNo.IW03].strKey = "113"; WriteNode[csWriteNodeNo.IW03].priority = 0; WriteNode[csWriteNodeNo.IW04].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word04"; WriteNode[csWriteNodeNo.IW04].strDisplayNodeName = "IW04"; WriteNode[csWriteNodeNo.IW04].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.IW04].nExist = 1; WriteNode[csWriteNodeNo.IW04].strKey = "114"; WriteNode[csWriteNodeNo.IW04].priority = 0; WriteNode[csWriteNodeNo.IW05].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word05"; WriteNode[csWriteNodeNo.IW05].strDisplayNodeName = "IW05"; WriteNode[csWriteNodeNo.IW05].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.IW05].nExist = 1; WriteNode[csWriteNodeNo.IW05].strKey = "115"; WriteNode[csWriteNodeNo.IW05].priority = 0; WriteNode[csWriteNodeNo.IW06].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word06"; WriteNode[csWriteNodeNo.IW06].strDisplayNodeName = "IW06"; WriteNode[csWriteNodeNo.IW06].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.IW06].nExist = 1; WriteNode[csWriteNodeNo.IW06].strKey = "116"; WriteNode[csWriteNodeNo.IW06].priority = 0; WriteNode[csWriteNodeNo.IW07].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word07"; WriteNode[csWriteNodeNo.IW07].strDisplayNodeName = "IW07"; WriteNode[csWriteNodeNo.IW07].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.IW07].nExist = 1; WriteNode[csWriteNodeNo.IW07].strKey = "117"; WriteNode[csWriteNodeNo.IW07].priority = 0; WriteNode[csWriteNodeNo.IW08].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word08"; WriteNode[csWriteNodeNo.IW08].strDisplayNodeName = "IW08"; WriteNode[csWriteNodeNo.IW08].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.IW08].nExist = 1; WriteNode[csWriteNodeNo.IW08].strKey = "118"; WriteNode[csWriteNodeNo.IW08].priority = 0; WriteNode[csWriteNodeNo.IW09].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word09"; WriteNode[csWriteNodeNo.IW09].strDisplayNodeName = "IW09"; WriteNode[csWriteNodeNo.IW09].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.IW09].nExist = 1; WriteNode[csWriteNodeNo.IW09].strKey = "119"; WriteNode[csWriteNodeNo.IW09].priority = 0; WriteNode[csWriteNodeNo.IW10].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word10"; WriteNode[csWriteNodeNo.IW10].strDisplayNodeName = "IW10"; WriteNode[csWriteNodeNo.IW10].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.IW10].nExist = 1; WriteNode[csWriteNodeNo.IW10].strKey = "120"; WriteNode[csWriteNodeNo.IW10].priority = 0; WriteNode[csWriteNodeNo.IW11].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word11"; WriteNode[csWriteNodeNo.IW11].strDisplayNodeName = "IW11"; WriteNode[csWriteNodeNo.IW11].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.IW11].nExist = 1; WriteNode[csWriteNodeNo.IW11].strKey = "121"; WriteNode[csWriteNodeNo.IW11].priority = 0; WriteNode[csWriteNodeNo.IW12].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word12"; WriteNode[csWriteNodeNo.IW12].strDisplayNodeName = "IW12"; WriteNode[csWriteNodeNo.IW12].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.IW12].nExist = 1; WriteNode[csWriteNodeNo.IW12].strKey = "122"; WriteNode[csWriteNodeNo.IW12].priority = 0; WriteNode[csWriteNodeNo.IW13].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word13"; WriteNode[csWriteNodeNo.IW13].strDisplayNodeName = "IW13"; WriteNode[csWriteNodeNo.IW13].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.IW13].nExist = 1; WriteNode[csWriteNodeNo.IW13].strKey = "123"; WriteNode[csWriteNodeNo.IW13].priority = 0; WriteNode[csWriteNodeNo.IW14].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word14"; WriteNode[csWriteNodeNo.IW14].strDisplayNodeName = "IW14"; WriteNode[csWriteNodeNo.IW14].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.IW14].nExist = 1; WriteNode[csWriteNodeNo.IW14].strKey = "124"; WriteNode[csWriteNodeNo.IW14].priority = 0; WriteNode[csWriteNodeNo.IW15].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word15"; WriteNode[csWriteNodeNo.IW15].strDisplayNodeName = "IW15"; WriteNode[csWriteNodeNo.IW15].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.IW15].nExist = 1; WriteNode[csWriteNodeNo.IW15].strKey = "125"; WriteNode[csWriteNodeNo.IW15].priority = 0; WriteNode[csWriteNodeNo.IW16].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word16"; WriteNode[csWriteNodeNo.IW16].strDisplayNodeName = "IW16"; WriteNode[csWriteNodeNo.IW16].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.IW16].nExist = 1; WriteNode[csWriteNodeNo.IW16].strKey = "126"; WriteNode[csWriteNodeNo.IW16].priority = 0; WriteNode[csWriteNodeNo.IW17].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word17"; WriteNode[csWriteNodeNo.IW17].strDisplayNodeName = "IW17"; WriteNode[csWriteNodeNo.IW17].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.IW17].nExist = 1; WriteNode[csWriteNodeNo.IW17].strKey = "127"; WriteNode[csWriteNodeNo.IW17].priority = 0; WriteNode[csWriteNodeNo.IW18].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word18"; WriteNode[csWriteNodeNo.IW18].strDisplayNodeName = "IW18"; WriteNode[csWriteNodeNo.IW18].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.IW18].nExist = 1; WriteNode[csWriteNodeNo.IW18].strKey = "128"; WriteNode[csWriteNodeNo.IW18].priority = 0; WriteNode[csWriteNodeNo.IW19].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word19"; WriteNode[csWriteNodeNo.IW19].strDisplayNodeName = "IW19"; WriteNode[csWriteNodeNo.IW19].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.IW19].nExist = 1; WriteNode[csWriteNodeNo.IW19].strKey = "129"; WriteNode[csWriteNodeNo.IW19].priority = 0; WriteNode[csWriteNodeNo.IW20].strNodeName = strHead + "Activation." + strSlotNo + ".Input.Word20"; WriteNode[csWriteNodeNo.IW20].strDisplayNodeName = "IW20"; WriteNode[csWriteNodeNo.IW20].nNodeType = csNodeType.UINT16; WriteNode[csWriteNodeNo.IW20].nExist = 1; WriteNode[csWriteNodeNo.IW20].strKey = "130"; WriteNode[csWriteNodeNo.IW20].priority = 0; #region 읽어올 Node ID를 배열에 미리 넣어둔다(ReadNodeData 함수에서 사용) if (isCallBack) { readNodeIdList = null; writeNodeIdList = null; } else { readNodeIdList = new List(); for (int nTarget = 0; nTarget < 100; nTarget++) { if (ReadNode[nTarget].nExist != 1) continue; else if (ReadNode[nTarget].IsCallBack == 1) continue; NodeId nodeId = new NodeId(ReadNode[nTarget].strNodeName); readNodeIdList.Add(nodeId); } writeNodeIdList = new List(); for (int nTarget = 0; nTarget < 100; nTarget++) { if (WriteNode[nTarget].nExist != 1) continue; else if (WriteNode[nTarget].IsCallBack == 1) continue; NodeId nodeId = new NodeId(WriteNode[nTarget].strNodeName); writeNodeIdList.Add(nodeId); } } #endregion } public int Open(LaserConfig Config) { if (ConnectServer() == 1) { m_threadTruFiberSeq = new Thread(new ThreadStart(TruFiberThread_Seq)); m_threadTruFiberSeq.Start(); return E1.OK; } else return E1.NETWORK; } public void DisConnect() { try { if (IsConnect == true) { SetData(csWriteNodeNo.PROG_STOP, 1); Thread.Sleep(500); SetData(csWriteNodeNo.PROG_STOP, 0); SetData(csWriteNodeNo.PSTART_STATICAL, 0); SetData(csWriteNodeNo.PSTART_DYN, 0); SetData(csWriteNodeNo.REQUEST_LASER, 0); SetData(csWriteNodeNo.LASER_ON, 0); SetData(csWriteNodeNo.EXT_ACTIVATION, 0); } if (m_threadTruFiberSeq != null) { m_threadTruFiberSeq.Join(500); m_threadTruFiberSeq.Abort(); } try { if (IsConnect) { _session.RemoveSubscription(_subscription); StatusCode result = _session.Close(); } } catch (Exception ex) { throw ex; } } catch { } return; } public bool GetConnected() { return IsConnect; } public int SetDWord(int nTarget, int value) { if (!IsConnect) return 0; try { List nodes = new List(); nodes.Add(new NodeId(WriteNode[nTarget].strNodeName)); nodes.Add(new NodeId(WriteNode[nTarget + 1].strNodeName)); WriteNodesValue(nodes, value); return 1; } catch (Exception ex) { throw ex; } } public int SetMultiWord(int StartNode, int wordCount, ulong value) { if (!IsConnect) return 0; try { List nodes = new List(); for(int i = 0; i= 0 && nTarget < 100) { lock (readNodeLock) { nArrayNo = nTarget; if (ReadNode[nArrayNo].nExist != 1) return strRet; switch (ReadNode[nArrayNo].nNodeType) { case csNodeType.INT: strRet = string.Format("{0:D0}", ReadNode[nArrayNo].nRet); break; case csNodeType.DOUBLE: strRet = string.Format("{0:F2}", ReadNode[nArrayNo].dRet); break; case csNodeType.STRING: strRet = ReadNode[nArrayNo].strRet; break; case csNodeType.UINT16: strRet = string.Format("{0:D0}", (int)ReadNode[nArrayNo].n16Ret); break; case csNodeType.UINT32: strRet = string.Format("{0:D0}", (int)ReadNode[nArrayNo].n32Ret); break; case csNodeType.UINT64: strRet = string.Format("{0:D0}", (int)ReadNode[nArrayNo].n64Ret); break; case csNodeType.BOOL: strRet = ReadNode[nArrayNo].nRet == 1 ? "1" : "0"; break; case csNodeType.BYTE: strRet = string.Format("{0:D0}", (int)ReadNode[nArrayNo].nRet); break; default: break; } } } else { lock (writeNodeLock) { nArrayNo = nTarget - 100; if (WriteNode[nArrayNo].nExist != 1) return strRet; switch (WriteNode[nArrayNo].nNodeType) { case csNodeType.INT: strRet = string.Format("{0:D0}", WriteNode[nArrayNo].nRet); break; case csNodeType.DOUBLE: strRet = string.Format("{0:F2}", WriteNode[nArrayNo].dRet); break; case csNodeType.STRING: strRet = WriteNode[nArrayNo].strRet; break; case csNodeType.UINT16: strRet = string.Format("{0:D0}", (int)WriteNode[nArrayNo].n16Ret); break; case csNodeType.UINT32: strRet = string.Format("{0:D0}", (int)WriteNode[nArrayNo].n32Ret); break; case csNodeType.UINT64: strRet = string.Format("{0:D0}", (int)WriteNode[nArrayNo].n64Ret); break; case csNodeType.BOOL: strRet = WriteNode[nArrayNo].nRet == 1 ? "1" : "0"; break; case csNodeType.BYTE: strRet = string.Format("{0:D0}", (int)WriteNode[nArrayNo].nRet); break; default: break; } } } } catch (Exception ex) { throw ex; } return strRet; } // 바뀐지 확인해주는 부분은 테스트 필요함. public bool UpdatesDatasIfChanged(List<(int wordNo, int input, bool isWriteValue)> values) { if (_IsSimul) return true; // 데이터가 변하면 값 업데이트 하는 함수 // 값 업데이트 하기 위해서 레이저를 Ready 상태로 변경해야 한다 bool isChanged = false; foreach (var value in values) { if (GetData(value.wordNo + (value.isWriteValue ? 100 : 0)) != value.input.ToString()) { SetData(value.wordNo , value.input); Log.D($"Data Changed; {value.wordNo};{value.input}"); isChanged = true; } } if (isChanged) { Log.D($"Laser On Deactive Request. Because of Parameter Changed."); // 테스트 필요함... // Tact Time 때문에 굳이 확인하지 않아도 될 듯 함. // 값 변경되는지 확인하는 테스트 코드 Stopwatch sw = Stopwatch.StartNew(); foreach (var value in values) { bool isChangeComplete = false; while (!isChangeComplete) { // 완료될 때 혹은 타임 아웃이 지났을 경우 if (GetData(value.wordNo + (value.isWriteValue ? 100 : 0)) == value.input.ToString()) { Log.D($"Data Completion Checked.;{value.wordNo};{value.input.ToString()}"); isChangeComplete = true; } else if (sw.ElapsedMilliseconds > 3000) { Log.E($"Data doesn't change yet. but, it need to pass.. {value.wordNo};{value.input.ToString()}"); isChangeComplete = true; } Thread.Sleep(10); } } nSequence = eSeqStep.SEQ_LASER_ON_DEACTIVATE; } return isChanged; } public bool UpdatesDatas(List<(int wordNo, int input, bool isWriteValue)> values) { // 데이터가 변하면 값 업데이트 하는 함수 // 값 업데이트 하기 위해서 레이저를 Ready 상태로 변경해야 한다 bool isChanged = false; foreach (var value in values) { if (GetData(value.wordNo + (value.isWriteValue ? 100 : 0)) != value.input.ToString()) { SetData(value.wordNo, value.input); Log.D($"Data Changed; {value.wordNo};{value.input}"); isChanged = true; } } if (isChanged) { Log.D($"Laser On Deactive Request. Because of Parameter Changed."); // 테스트 필요함... // Tact Time 때문에 굳이 확인하지 않아도 될 듯 함. // 값 변경되는지 확인하는 테스트 코드 Stopwatch sw = Stopwatch.StartNew(); foreach (var value in values) { bool isChangeComplete = false; while (!isChangeComplete) { // 완료될 때 혹은 타임 아웃이 지났을 경우 if (GetData(value.wordNo + (value.isWriteValue ? 100 : 0)) == value.input.ToString()) { Log.D($"Data Completion Checked.;{value.wordNo};{value.input.ToString()}"); isChangeComplete = true; } else if (sw.ElapsedMilliseconds > 3000) { Log.E($"Data doesn't change yet. but, it need to pass.. {value.wordNo};{value.input.ToString()}"); isChangeComplete = true; } Thread.Sleep(10); } } } return isChanged; } public int LaserOn() { if (nSequence != (int)eSeqStep.SEQ_NONE) return 0; nSequence = eSeqStep.SEQ_LASER_ON_START; return 1; } public int LaserOff() { if (nSequence != (int)eSeqStep.SEQ_NONE) return 0; nSequence = eSeqStep.SEQ_LASER_OFF_START; return 1; } public int PilotLaserOn() { if (nSequence != (int)eSeqStep.SEQ_NONE) return 0; nSequence = eSeqStep.SEQ_LASER_PILOT_LASER_ON_START; return 1; } public int PilotLaserOff() { if (nSequence != (int)eSeqStep.SEQ_NONE) return 0; nSequence = eSeqStep.SEQ_LASER_PILOT_LASER_OFF_START; return 1; } public bool GetInitCommunication() { // 업데이트 예정 return false; } public bool GetEmissionStatus() { // 테스트 필요 return GetLaserEmissionOn(); } public bool GetWariningStatus() { // 테스트 필요 return GetLaserError(); } // MAINS_STATUS, ERROR_STATUS 는 위에 있음 public bool GetPilotLaserStatus() { // 테스트 필요 return GetPilotLaserOn(); } public string GetControlMode() { // 업데이트 예정 return ""; } public string GetPowerCenter() { // 테스트 필요 // 원래는 PULSE_POWER도 유의미한 값으로 보이는데, TruFiber에서는 그렇지 않았음. return GetCenterPower(); } public string GetPowerRing() { // 테스트 필요 return GetRingPower(); } #region Set 명령 나간 bit 를 모니터링 public bool GetStartLaserSetBitStatus() { // Laser Start 명령 // 테스트 필요 lock (readNodeLock) { NodeId id = new NodeId(ReadNode[csWriteNodeNo.LASER_ON].strNodeName); return Convert.ToBoolean(ReadNodeValue(id).Value); } } public bool GetLaserStartSetBitStatus() { // Laser On 명령. Laser Emission Ready 를 위한 bit // 테스트 필요 lock (readNodeLock) { NodeId id = new NodeId(ReadNode[csWriteNodeNo.REQUEST_LASER].strNodeName); return Convert.ToBoolean(ReadNodeValue(id).Value); } } public bool GetPilotLaserSetBitStatus() { // Pilot Laser On 명령. // 테스트 필요 return GetPilotLaserOn(); } public bool GetLaserResetSetBitStatus() { // Laser Reset 명령. // 테스트 필요 lock (readNodeLock) { NodeId id = new NodeId(ReadNode[csWriteNodeNo.LASER_RESET].strNodeName); return Convert.ToBoolean(ReadNodeValue(id).Value); } } public bool GetControlModeSetStatus() { // Control mode Local(false) Remote(true) // 업데이트 예정 return false; } #endregion public int ConnectServer() // Connect OPC UA Server, Resist Read Nodes. { if (_session != null && _session.Connected) return 2; #region Opc Ua 새로운 API 사용 try { ApplicationConfiguration config = new Opc.Ua.ApplicationConfiguration() { ApplicationName = "OPCClientTest", ApplicationType = ApplicationType.Client, SecurityConfiguration = new SecurityConfiguration { ApplicationCertificate = new CertificateIdentifier(), AutoAcceptUntrustedCertificates = true, }, ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 5000 }, }; config.Validate(ApplicationType.Client); if (config.SecurityConfiguration.AutoAcceptUntrustedCertificates) { config.CertificateValidator.CertificateValidation += (s, ex) => { ex.Accept = (ex.Error.StatusCode == StatusCodes.BadCertificateUntrusted); }; } // 연결 Url 설정 string endpointUrl = strServerAddress; // 연결 시작(Session 연결) var userIdentity = new UserIdentity(strID, strPW); //var selectedEndPoint = CoreClientUtils.SelectEndpoint(endpointUrl, useSecurity: false); //var endconf = new ConfiguredEndpoint(null, selectedEndPoint, EndpointConfiguration.Create(config)); // version 1 //var endconf = new ConfiguredEndpoint(null, new EndpointDescription(endpointUrl)); // version 2 var endpointConfig = EndpointConfiguration.Create(config); endpointConfig.OperationTimeout = 3000; // 3초 var endpointDescription = CoreClientUtils.SelectEndpoint(endpointUrl, false); var endconf = new ConfiguredEndpoint(null, endpointDescription, endpointConfig); // version3 _session = Session.Create(config, endconf, true, "session", 5000, userIdentity, null).GetAwaiter().GetResult(); //_session.KeepAlive += KeepAliveSession; // Keep Alive 관련 함수 추가 _session.KeepAliveInterval = 2000; _session.KeepAlive += KeepAliveSessionFunc; } catch (Exception ex) { Debug.WriteLine("TruDisk.ConnectServer() - Exception : " + ex.Message); } #endregion if (IsConnect == false) return 0; System.Threading.Thread.Sleep(500); RegistReadNodes(); return 1; } private void KeepAliveSessionFunc(ISession session, KeepAliveEventArgs e) { if (ServiceResult.IsBad(e.Status)) { Log.E("KeepAlive failed: " + e.Status); if (!_isReconnecting) ReconnectServer(); } else if (session.KeepAliveStopped) { Log.E($"timeout : {session.SessionTimeout} / KeepAliveInterval : {session.KeepAliveInterval}"); if (!_isReconnecting) ReconnectServer(); } } public void ReconnectServer() { _isReconnecting = true; Log.D($"Laser TruFiber Reconnecting"); _session.KeepAlive -= KeepAliveSessionFunc; //_session.RemoveSubscription(_subscription); DisConnect(); ConnectServer(); _isReconnecting = false; } public int RegistReadNodes() { try { if (_session == null || !_session.Connected) return 0; if (_subscription != null) { _session.RemoveSubscription(_subscription); _subscription = null; } // 모니터링 설정 _subscription = new Subscription(_session.DefaultSubscription) { PublishingEnabled = true, PublishingInterval = 50, // TruDisk 2021 최소값은 50ms KeepAliveCount = 40, // 해당 값들이 적절한지는 모르겠음. LifetimeCount = 120 }; // 모니터링 할 Item List var listRead = new List { }; var listWrite = new List { }; // List 추가 for (int i = 0; i < 100; i++) { if (ReadNode[i].nExist == 0) continue; //if (ReadNode[i].IsCallBack != 1) continue; listRead.Add(new MonitoredItem() { DisplayName = ReadNode[i].strDisplayNodeName, StartNodeId = ReadNode[i].strNodeName, // 단위는 ms, 100ms씩 증가, 0은 Server에서 가능한 가장 빠른 Interval(100ms)로 Sampling SamplingInterval = ReadNode[i].priority == 0 ? 100 : 200, }); } for (int i = 0; i < 100; i++) { if (WriteNode[i].nExist == 0) continue; //if (WriteNode[i].IsCallBack != 1) continue; listWrite.Add(new MonitoredItem() { DisplayName = WriteNode[i].strDisplayNodeName, StartNodeId = WriteNode[i].strNodeName, // 단위는 ms, 100ms씩 증가, 0은 Server에서 가능한 가장 빠른 Interval(100ms)로 Sampling SamplingInterval = WriteNode[i].priority == 0 ? 100 : 200, }); } // 각각의 Item에 Event 추가 listRead.ForEach(i => i.Notification += new MonitoredItemNotificationEventHandler(OnNotificationRead)); listWrite.ForEach(i => i.Notification += new MonitoredItemNotificationEventHandler(OnNotificationWrite)); // Subscription에 List 추가 _subscription.AddItems(listRead); _subscription.AddItems(listWrite); // Session에 Subscription 추가 _session.AddSubscription(_subscription); // Subscription 생성 _subscription.Create(); } catch (Exception ex) { return E2.ABORTED; throw ex; } return 1; } private Variant WriteNodeValue(NodeId nodeId, object value) { try { // cast the value to a string. //object value = TypeInfo.Cast(ValueTB.Text, TypeInfo.Scalars.String, m_sourceType.BuiltInType); // build list of attributes to read. WriteValueCollection nodesToWrite = new WriteValueCollection(); WriteValue nodeToWrite = new WriteValue(); nodeToWrite.NodeId = nodeId; nodeToWrite.AttributeId = Attributes.Value; // using the WrappedValue instead of the Value property because we know the TypeInfo. // this makes the assignment more efficient by avoiding reflection to determine type. //nodeToWrite.Value.WrappedValue = new Variant(value, m_sourceType); nodeToWrite.Value.WrappedValue = new Variant(value); nodesToWrite.Add(nodeToWrite); // override the diagnostic masks (other parameters are set to defaults). RequestHeader requestHeader = new RequestHeader(); requestHeader.ReturnDiagnostics = (uint)DiagnosticsMasks.All; // read the attributes. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; lock (sessionLock) { ResponseHeader responseHeader = _session.Write(requestHeader, nodesToWrite, out results, out diagnosticInfos); // 밑에 부분은 lock에서 빼보고 싶음.. ClientBase.ValidateResponse(results, nodesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite); // check status. if (StatusCode.IsBad(results[0])) { // embed the diagnostic information in a exception. throw ServiceResultException.Create(results[0], 0, diagnosticInfos, responseHeader.StringTable); } // return valid value. return nodeToWrite.Value.WrappedValue; } } catch (Exception ex) { throw ex; } } private bool WriteNodesValue(List nodesId, int value) { try { // cast the value to a string. //object value = TypeInfo.Cast(ValueTB.Text, TypeInfo.Scalars.String, m_sourceType.BuiltInType); // build list of attributes to read. WriteValueCollection nodesToWrite = new WriteValueCollection(); for (int i = 0; i < nodesId.Count; i++) { WriteValue nodeToWrite = new WriteValue(); nodeToWrite.NodeId = nodesId[i]; nodeToWrite.AttributeId = Attributes.Value; var word = (short)((value >> (16 * i)) & 0xFFFF); nodeToWrite.Value.WrappedValue = new Variant((object)word); nodesToWrite.Add(nodeToWrite); } // override the diagnostic masks (other parameters are set to defaults). RequestHeader requestHeader = new RequestHeader(); requestHeader.ReturnDiagnostics = (uint)DiagnosticsMasks.All; // read the attributes. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; lock (sessionLock) { ResponseHeader responseHeader = _session.Write(requestHeader, nodesToWrite, out results, out diagnosticInfos); // 밑에 부분은 lock에서 빼보고 싶음.. ClientBase.ValidateResponse(results, nodesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite); // check status. if (StatusCode.IsBad(results[0])) { // embed the diagnostic information in a exception. throw ServiceResultException.Create(results[0], 0, diagnosticInfos, responseHeader.StringTable); } // return valid value. return true; } } catch (Exception ex) { throw ex; } } private bool WriteNodesValue(List nodesId, ulong value) { try { // cast the value to a string. //object value = TypeInfo.Cast(ValueTB.Text, TypeInfo.Scalars.String, m_sourceType.BuiltInType); // build list of attributes to read. WriteValueCollection nodesToWrite = new WriteValueCollection(); for (int i = 0; i < nodesId.Count; i++) { WriteValue nodeToWrite = new WriteValue(); nodeToWrite.NodeId = nodesId[i]; nodeToWrite.AttributeId = Attributes.Value; var word = (short)((value >> (16 * i)) & 0xFFFF); nodeToWrite.Value.WrappedValue = new Variant((object)word); nodesToWrite.Add(nodeToWrite); } // override the diagnostic masks (other parameters are set to defaults). RequestHeader requestHeader = new RequestHeader(); requestHeader.ReturnDiagnostics = (uint)DiagnosticsMasks.All; // read the attributes. StatusCodeCollection results = null; DiagnosticInfoCollection diagnosticInfos = null; lock (sessionLock) { ResponseHeader responseHeader = _session.Write(requestHeader, nodesToWrite, out results, out diagnosticInfos); // 밑에 부분은 lock에서 빼보고 싶음.. ClientBase.ValidateResponse(results, nodesToWrite); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, nodesToWrite); // check status. if (StatusCode.IsBad(results[0])) { // embed the diagnostic information in a exception. throw ServiceResultException.Create(results[0], 0, diagnosticInfos, responseHeader.StringTable); } // return valid value. return true; } } catch (Exception ex) { throw ex; } } private void OnNotificationRead(MonitoredItem item, MonitoredItemNotificationEventArgs e) { try { MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification; foreach (var value in item.DequeueValues()) { // 상태가 정상일 경우 if (StatusCode.IsGood(value.StatusCode)) { lock (readNodeLock) { int nArrayNo = -1; for (int i = 0; i < 100; i++) { if (ReadNode[i].nExist == 1 && ReadNode[i].strDisplayNodeName == item.DisplayName) { nArrayNo = i; break; } } if (0 <= nArrayNo && nArrayNo < 100) { string strReturnData = value.Value.ToString(); switch (ReadNode[nArrayNo].nNodeType) { case csNodeType.INT: ReadNode[nArrayNo].nRet = int.Parse(strReturnData) * ReadNode[nArrayNo].nDigit; break; case csNodeType.DOUBLE: ReadNode[nArrayNo].dRet = (double.Parse(strReturnData) * ReadNode[nArrayNo].nDigit); break; case csNodeType.STRING: ReadNode[nArrayNo].strRet = strReturnData; break; case csNodeType.UINT16: ReadNode[nArrayNo].n16Ret = (ushort)(int.Parse(strReturnData) * ReadNode[nArrayNo].nDigit); break; case csNodeType.UINT32: ReadNode[nArrayNo].n32Ret = (uint)(uint.Parse(strReturnData) * ReadNode[nArrayNo].nDigit); break; case csNodeType.UINT64: ReadNode[nArrayNo].n64Ret = ulong.Parse(strReturnData) * (ulong)ReadNode[nArrayNo].nDigit; break; case csNodeType.BOOL: if (strReturnData == "True") ReadNode[nArrayNo].nRet = 1; else ReadNode[nArrayNo].nRet = 0; break; case csNodeType.BYTE: ReadNode[nArrayNo].nRet = byte.Parse(strReturnData) * ReadNode[nArrayNo].nDigit; break; default: break; } } } } } } catch (Exception ex) { throw ex; } } private void OnNotificationWrite(MonitoredItem item, MonitoredItemNotificationEventArgs e) { try { MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification; foreach (var value in item.DequeueValues()) { // 상태가 정상일 경우 if (StatusCode.IsGood(value.StatusCode)) { lock (writeNodeLock) { int nArrayNo = -1; for (int i = 0; i < 100; i++) { if (WriteNode[i].nExist == 1 && WriteNode[i].strDisplayNodeName == item.DisplayName) { nArrayNo = i; break; } } if (0 <= nArrayNo && nArrayNo < 100) { string strReturnData = value.Value.ToString(); switch (WriteNode[nArrayNo].nNodeType) { case csNodeType.INT: WriteNode[nArrayNo].nRet = int.Parse(strReturnData) * WriteNode[nArrayNo].nDigit; break; case csNodeType.DOUBLE: WriteNode[nArrayNo].dRet = (double.Parse(strReturnData) * WriteNode[nArrayNo].nDigit); break; case csNodeType.STRING: WriteNode[nArrayNo].strRet = strReturnData; break; case csNodeType.UINT16: WriteNode[nArrayNo].n16Ret = (ushort)(int.Parse(strReturnData) * WriteNode[nArrayNo].nDigit); break; case csNodeType.UINT32: WriteNode[nArrayNo].n32Ret = (uint)(uint.Parse(strReturnData) * WriteNode[nArrayNo].nDigit); break; case csNodeType.UINT64: WriteNode[nArrayNo].n64Ret = ulong.Parse(strReturnData) * (ulong)WriteNode[nArrayNo].nDigit; break; case csNodeType.BOOL: if (strReturnData == "True") WriteNode[nArrayNo].nRet = 1; else WriteNode[nArrayNo].nRet = 0; break; case csNodeType.BYTE: WriteNode[nArrayNo].nRet = byte.Parse(strReturnData) * WriteNode[nArrayNo].nDigit; break; default: break; } } } } } } catch (Exception ex) { throw ex; } } public void TruFiberThread_Seq() { int timeOut = 10; DateTime startTime = DateTime.Now; while (true) { Thread.Sleep(20); try { if (nSequence == eSeqStep.SEQ_NONE) { if (ReadNode[csReadNodeNo.FAULT_LASER].nRet == 1 || ReadNode[csReadNodeNo.LIGHTPATH_BLOCKED].nRet == 1) { nLaserStatus = eLaserStatus.STATUS_LASER_ERROR; } } switch (nSequence) { case eSeqStep.SEQ_NONE: break; #region Laser On 시퀀스 case eSeqStep.SEQ_LASER_ON_START: nLaserStatus = eLaserStatus.STATUS_LASER_ON_STEP; SetData(csWriteNodeNo.EXT_ACTIVATION, 1); startTime = DateTime.Now; nSequence = eSeqStep.SEQ_LASER_ON_EXT_ACTIVE_CHK; break; case eSeqStep.SEQ_LASER_ON_EXT_ACTIVE_CHK: if (ReadNode[csReadNodeNo.EXT_ACTIVATION_ACTIVE].nRet == 1) { startTime = DateTime.Now; SetData(csWriteNodeNo.PROGRAM_NO, 0); SetData(csWriteNodeNo.PILOT_LASER_ON, 0); SetData(csWriteNodeNo.LASER_RESET, 1); nSequence = eSeqStep.SEQ_LASER_RESET_ON_CHK; } else if (timeOut < DateTime.Now.Subtract(startTime).TotalSeconds) { nLaserStatus = eLaserStatus.STATUS_LASER_ERROR; nSequence = eSeqStep.SEQ_NONE; } break; case eSeqStep.SEQ_LASER_RESET_ON_CHK: if (WriteNode[csWriteNodeNo.LASER_RESET].nRet == 1) { startTime = DateTime.Now; nSequence = eSeqStep.SEQ_LASER_RESET_ON_DELAY; } else if (timeOut < DateTime.Now.Subtract(startTime).TotalSeconds) { nLaserStatus = eLaserStatus.STATUS_LASER_ERROR; nSequence = eSeqStep.SEQ_NONE; } break; case eSeqStep.SEQ_LASER_RESET_ON_DELAY: if (ReadNode[csReadNodeNo.FAULT_LASER].nRet == 0 || 0.5 < DateTime.Now.Subtract(startTime).TotalSeconds) { startTime = DateTime.Now; SetData(csWriteNodeNo.LASER_RESET, 0); nSequence = eSeqStep.SEQ_LASER_RESET_OFF_CHK; } else if (timeOut < DateTime.Now.Subtract(startTime).TotalSeconds) { nLaserStatus = eLaserStatus.STATUS_LASER_ERROR; nSequence = eSeqStep.SEQ_NONE; } break; case eSeqStep.SEQ_LASER_RESET_OFF_CHK: if (WriteNode[csWriteNodeNo.LASER_RESET].nRet == 0) { startTime = DateTime.Now; SetData(csWriteNodeNo.LASER_ON, 1); nSequence = eSeqStep.SEQ_LASER_ON_LASER_ON_CHK; } else if (timeOut < DateTime.Now.Subtract(startTime).TotalSeconds) { nLaserStatus = eLaserStatus.STATUS_LASER_ERROR; nSequence = eSeqStep.SEQ_NONE; } break; case eSeqStep.SEQ_LASER_ON_LASER_ON_CHK: if (ReadNode[csReadNodeNo.LASER_IS_ON].nRet == 1) { startTime = DateTime.Now; SetData(csWriteNodeNo.REQUEST_LASER, 1); nSequence = eSeqStep.SEQ_LASER_ON_READY_CHK; } else if (timeOut < DateTime.Now.Subtract(startTime).TotalSeconds) { nLaserStatus = eLaserStatus.STATUS_LASER_ERROR; nSequence = eSeqStep.SEQ_NONE; } break; case eSeqStep.SEQ_LASER_ON_READY_CHK: if (ReadNode[csReadNodeNo.LASER_READY].nRet == 1) { Log.D("Laser Ready OK"); if (AutoProgramStart) { startTime = DateTime.Now; SetData(csWriteNodeNo.PSTART_STATICAL, 1); Log.D("Laser Pstart Statical OK"); nSequence = eSeqStep.SEQ_LASER_ON_PROG_ACTIVE_CHK; } else { nLaserStatus = eLaserStatus.STATUS_LASER_READY; nSequence = eSeqStep.SEQ_NONE; } } else if (timeOut < DateTime.Now.Subtract(startTime).TotalSeconds) { nLaserStatus = eLaserStatus.STATUS_LASER_ERROR; nSequence = eSeqStep.SEQ_NONE; } break; case eSeqStep.SEQ_LASER_ON_PROG_ACTIVE_CHK: if (ReadNode[csReadNodeNo.PROG_ACTIVE].nRet == 1) { nLaserStatus = eLaserStatus.STATUS_LASER_READY; nSequence = eSeqStep.SEQ_NONE; }else if (timeOut < DateTime.Now.Subtract(startTime).TotalSeconds) { nLaserStatus = eLaserStatus.STATUS_LASER_ERROR; nSequence = eSeqStep.SEQ_NONE; } break; #endregion Laser On 시퀀스 #region Word 값 변경 시, 프로그램 재시작 시퀸스 case eSeqStep.SEQ_LASER_ON_DEACTIVATE: // 프로그램 활성화되있는 상태 아니라면, 처음 상태에서 대기. if (ReadNode[csReadNodeNo.PROG_ACTIVE].nRet == 1) { SetData(csWriteNodeNo.PSTART_STATICAL, 0); startTime = DateTime.Now; nSequence = eSeqStep.SEQ_LASER_ON_CHANGE_PROG_INFO; }else { nLaserStatus = eLaserStatus.STATUS_LASER_ERROR; nSequence = eSeqStep.SEQ_NONE; } break; case eSeqStep.SEQ_LASER_ON_CHANGE_PROG_INFO: if (ReadNode[csReadNodeNo.PROG_COMPLETED].nRet == 1) { nLaserStatus = eLaserStatus.STATUS_LASER_INFO_CHANGE; nSequence = eSeqStep.SEQ_LASER_ON_READY_CHK; } else if (timeOut < DateTime.Now.Subtract(startTime).TotalSeconds) { SetData(csWriteNodeNo.LASER_RESET, 1); nLaserStatus = eLaserStatus.STATUS_LASER_ERROR; nSequence = eSeqStep.SEQ_NONE; } break; #endregion #region Laser Off 시퀀스 case eSeqStep.SEQ_LASER_OFF_START: nLaserStatus = eLaserStatus.STATUS_LASER_OFF_STEP; SetData(csWriteNodeNo.PSTART_STATICAL, 0); SetData(csWriteNodeNo.PROG_STOP, 1); SetData(csWriteNodeNo.PILOT_LASER_ON, 0); startTime = DateTime.Now; nSequence = eSeqStep.SEQ_LASER_OFF_PROG_STOP_ON_CHK; break; case eSeqStep.SEQ_LASER_OFF_PROG_STOP_ON_CHK: if (WriteNode[csWriteNodeNo.PROG_STOP].nRet == 1) { startTime = DateTime.Now; nSequence = eSeqStep.SEQ_LASER_OFF_PROG_STOP_ON_DELAY; } else if (timeOut < DateTime.Now.Subtract(startTime).TotalSeconds) { nLaserStatus = eLaserStatus.STATUS_LASER_ERROR; nSequence = eSeqStep.SEQ_NONE; } break; case eSeqStep.SEQ_LASER_OFF_PROG_STOP_ON_DELAY: if (ReadNode[csReadNodeNo.PROG_ACTIVE].nRet == 0 || 0.5 < DateTime.Now.Subtract(startTime).TotalSeconds) { startTime = DateTime.Now; SetData(csWriteNodeNo.PROG_STOP, 0); nSequence = eSeqStep.SEQ_LASER_OFF_PROG_STOP_OFF_CHK; } break; case eSeqStep.SEQ_LASER_OFF_PROG_STOP_OFF_CHK: if (WriteNode[csWriteNodeNo.PROG_STOP].nRet == 0) { SetData(csWriteNodeNo.REQUEST_LASER, 0); SetData(csWriteNodeNo.LASER_ON, 0); SetData(csWriteNodeNo.EXT_ACTIVATION, 0); nSequence = eSeqStep.SEQ_NONE; } else if (timeOut < DateTime.Now.Subtract(startTime).TotalSeconds) { nLaserStatus = eLaserStatus.STATUS_LASER_ERROR; nSequence = eSeqStep.SEQ_NONE; } break; #endregion Laser Off 시퀀스 #region Pilot Laser On 시퀀스 case eSeqStep.SEQ_LASER_PILOT_LASER_ON_START: nLaserStatus = eLaserStatus.STATUS_LASER_ON_STEP; SetData(csWriteNodeNo.EXT_ACTIVATION, 1); SetData(csWriteNodeNo.LASER_ON, 0); SetData(csWriteNodeNo.PROGRAM_NO, 35); // Laser Program 1번 광경로가 Absorber로 되어 있어야 함 startTime = DateTime.Now; nSequence = eSeqStep.SEQ_LASER_PILOT_LASER_ON_EXT_ACTIVE_CHK; break; case eSeqStep.SEQ_LASER_PILOT_LASER_ON_EXT_ACTIVE_CHK: if (ReadNode[csReadNodeNo.EXT_ACTIVATION_ACTIVE].nRet == 1) { startTime = DateTime.Now; SetData(csWriteNodeNo.LASER_RESET, 1); nSequence = eSeqStep.SEQ_LASER_PILOT_LASER_ON_RESET_ON_CHK; } else if (DateTime.Now.Subtract(startTime).TotalMilliseconds > (timeOut * 1000)) { nLaserStatus = eLaserStatus.STATUS_LASER_ERROR; nSequence = eSeqStep.SEQ_NONE; } break; case eSeqStep.SEQ_LASER_PILOT_LASER_ON_RESET_ON_CHK: if (WriteNode[csWriteNodeNo.LASER_RESET].nRet == 1) { startTime = DateTime.Now; nSequence = eSeqStep.SEQ_LASER_PILOT_LASER_ON_RESET_ON_DELAY; } else if (DateTime.Now.Subtract(startTime).TotalMilliseconds > (timeOut * 1000 * 2)) { nLaserStatus = eLaserStatus.STATUS_LASER_ERROR; nSequence = eSeqStep.SEQ_NONE; } break; case eSeqStep.SEQ_LASER_PILOT_LASER_ON_RESET_ON_DELAY: if (DateTime.Now.Subtract(startTime).TotalMilliseconds > 500) { startTime = DateTime.Now; SetData(csWriteNodeNo.LASER_RESET, 0); nSequence = eSeqStep.SEQ_LASER_PILOT_LASER_ON_RESET_OFF_CHK; } break; case eSeqStep.SEQ_LASER_PILOT_LASER_ON_RESET_OFF_CHK: if (WriteNode[csWriteNodeNo.LASER_RESET].nRet == 0) { startTime = DateTime.Now; SetData(csWriteNodeNo.REQUEST_LASER, 1); SetData(csWriteNodeNo.PILOT_LASER_ON, 1); nSequence = eSeqStep.SEQ_LASER_PILOT_LASER_ON_PILOT_LASER_ON_CHK; } else if (DateTime.Now.Subtract(startTime).TotalMilliseconds > (timeOut * 1000 * 2)) { nLaserStatus = eLaserStatus.STATUS_LASER_ERROR; nSequence = eSeqStep.SEQ_NONE; } break; case eSeqStep.SEQ_LASER_PILOT_LASER_ON_PILOT_LASER_ON_CHK: if (ReadNode[csReadNodeNo.PILOT_LASER_IS_ON].nRet == 1) { nLaserStatus = eLaserStatus.STATUS_NONE; nSequence = eSeqStep.SEQ_NONE; } else if (DateTime.Now.Subtract(startTime).TotalMilliseconds > (timeOut * 1000)) { nLaserStatus = eLaserStatus.STATUS_LASER_ERROR; nSequence = eSeqStep.SEQ_NONE; } break; #endregion Pilot Laser On 시퀀스 #region Pilot Laser Off 시퀀스 case eSeqStep.SEQ_LASER_PILOT_LASER_OFF_START: nLaserStatus = eLaserStatus.STATUS_LASER_ON_STEP; SetData(csWriteNodeNo.LASER_ON, 0); SetData(csWriteNodeNo.PROGRAM_NO, 35); SetData(csWriteNodeNo.REQUEST_LASER, 0); SetData(csWriteNodeNo.PILOT_LASER_ON, 0); startTime = DateTime.Now; nSequence = eSeqStep.SEQ_LASER_PILOT_LASER_OFF_CHK; break; case eSeqStep.SEQ_LASER_PILOT_LASER_OFF_CHK: if (ReadNode[csReadNodeNo.PILOT_LASER_IS_ON].nRet == 0) { SetData(csWriteNodeNo.REQUEST_LASER, 1); startTime = DateTime.Now; nSequence = eSeqStep.SEQ_LASER_PILOT_LASER_OFF_REQUEST_LASER_ON_CHK; } else if (DateTime.Now.Subtract(startTime).TotalMilliseconds > (timeOut * 1000)) { nLaserStatus = eLaserStatus.STATUS_LASER_ERROR; nSequence = eSeqStep.SEQ_NONE; } break; case eSeqStep.SEQ_LASER_PILOT_LASER_OFF_REQUEST_LASER_ON_CHK: if (WriteNode[csWriteNodeNo.REQUEST_LASER].nRet == 1) { startTime = DateTime.Now; nSequence = eSeqStep.SEQ_LASER_PILOT_LASER_OFF_REQUEST_LASER_DELAY; } else if (DateTime.Now.Subtract(startTime).TotalMilliseconds > (timeOut * 1000)) { nLaserStatus = eLaserStatus.STATUS_LASER_ERROR; nSequence = eSeqStep.SEQ_NONE; } break; case eSeqStep.SEQ_LASER_PILOT_LASER_OFF_REQUEST_LASER_DELAY: if (DateTime.Now.Subtract(startTime).TotalMilliseconds > 500) { SetData(csWriteNodeNo.REQUEST_LASER, 0); nSequence = eSeqStep.SEQ_LASER_PILOT_LASER_OFF_REQUEST_LASER_OFF_CHK; } break; case eSeqStep.SEQ_LASER_PILOT_LASER_OFF_REQUEST_LASER_OFF_CHK: SetData(csWriteNodeNo.EXT_ACTIVATION, 0); nSequence = eSeqStep.SEQ_NONE; break; #endregion Pilot Laser Off 시퀀스 default: break; } } catch { } } } public DataValue ReadNodeValue(NodeId nodeId) { try { ReadValueIdCollection itemsToRead = new ReadValueIdCollection(); ReadValueId itemToRead = new ReadValueId() { NodeId = nodeId, AttributeId = Attributes.Value, }; itemsToRead.Add(itemToRead); // read from server. //DataValueCollection values = null; //DiagnosticInfoCollection diagnosticInfos = null; var requestHeader = new RequestHeader { Timestamp = DateTime.UtcNow, TimeoutHint = 10000, ReturnDiagnostics = 0 }; //ResponseHeader responseHeader = _session.Read(null, 0, TimestampsToReturn.Both, itemsToRead, out values, out diagnosticInfos); // 왜 이게 되지........... lock (sessionLock) { ResponseHeader responseHeader = _session.Read(null, 0, TimestampsToReturn.Both, itemsToRead, out DataValueCollection values, out DiagnosticInfoCollection diagnosticInfos); // 이 밑은 속도 때문에 빼보고 싶긴하지만 일단 넣고 해보자.. ClientBase.ValidateResponse(values, itemsToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, itemsToRead); if (StatusCode.IsBad(values[0].StatusCode)) { ServiceResult result = ClientBase.GetResult(values[0].StatusCode, 0, diagnosticInfos, responseHeader); throw new ServiceResultException(result); } return values[0]; } } catch (Exception ex) { //throw ex; Log.I($"TruFiber ReadNode Exception ; {ex.Message}"); return null; } } public List ReadNodeListValue(List nodeIdList) { try { ReadValueIdCollection itemsToRead = new ReadValueIdCollection(); foreach (NodeId id in nodeIdList) { ReadValueId itemToRead = new ReadValueId() { NodeId = id, AttributeId = Attributes.Value, }; itemsToRead.Add(itemToRead); } // read from server. DataValueCollection values = null; DiagnosticInfoCollection diagnosticInfos = null; lock (sessionLock) { ResponseHeader responseHeader = _session.Read(null, 0, TimestampsToReturn.Both, itemsToRead, out values, out diagnosticInfos); // 이 밑에 lock 부분에서 빼버리고 싶음.. ClientBase.ValidateResponse(values, itemsToRead); ClientBase.ValidateDiagnosticInfos(diagnosticInfos, itemsToRead); foreach (DataValue value in values) { if (StatusCode.IsBad(value.StatusCode)) { ServiceResult result = ClientBase.GetResult(value.StatusCode, 0, diagnosticInfos, responseHeader); throw new ServiceResultException(result); } } return values; } } catch (Exception ex) { throw ex; } } #region Read/Write Node 호출 함수 public bool GetLaserEmissionEnable() { lock (readNodeLock) { if (AutoProgramStart) { return ReadNode[csReadNodeNo.PROG_ACTIVE].nRet == 1 ? true : false; } else { return ReadNode[csReadNodeNo.LASER_READY].nRet == 1 ? true : false; } } } public bool GetLaserEmissionOn() { lock (readNodeLock) { // 구현 필요 !!!! NodeId id = new NodeId(ReadNode[csReadNodeNo.EMISSION_ON].strNodeName); return Convert.ToBoolean(ReadNodeValue(id).Value) ? true : false; } } public bool GetPilotLaserOn() { lock (readNodeLock) { return ReadNode[csReadNodeNo.PILOT_LASER_IS_ON].nRet == 1 ? true : false; } } public bool GetLaserError() { lock (readNodeLock) { int ret = 0; ret += (ReadNode[csReadNodeNo.FAULT_LASER].nRet == 1 ? 1 : 0); ret += ReadNode[csReadNodeNo.SIK_OPEN].nRet == 1 ? 2 : 0; return ret == 0 ? false : true; } } public bool GetExternalActivation() { lock (readNodeLock) { return ReadNode[csReadNodeNo.EXT_ACTIVATION_ACTIVE].nRet == 1 ? true : false; } } public bool GetLaserIsOn() { lock (readNodeLock) { return ReadNode[csReadNodeNo.LASER_IS_ON].nRet == 1 ? true : false; } } public bool GetLaserAssigned() { lock (readNodeLock) { return ReadNode[csReadNodeNo.LASER_ASSIGNED].nRet == 1 ? true : false; } } public bool GetLaserReady() { if (_IsSimul) return true; lock (readNodeLock) { if (AutoProgramStart) { return ReadNode[csReadNodeNo.PROG_ACTIVE].nRet == 1 ? true : false; } else { return ReadNode[csReadNodeNo.LASER_READY].nRet == 1 ? true : false; } } } public bool GetProgramActive() { lock (readNodeLock) { return ReadNode[csReadNodeNo.PROG_ACTIVE].nRet == 1 ? true : false; } } public bool GetProgramCompleted() { if (_IsSimul) return true; lock (readNodeLock) { return ReadNode[csReadNodeNo.PROG_COMPLETED].nRet == 1 ? true : false; } } public bool GetProgramCancelled() { lock (readNodeLock) { return ReadNode[csReadNodeNo.PROG_CANCELLED].nRet == 1 ? true : false; } } public int GetProgramNo() { lock (readNodeLock) { return ReadNode[csReadNodeNo.PROGRAM_NO].n16Ret; } } public bool GetMonitoring() { lock (readNodeLock) { return ReadNode[csReadNodeNo.MONITORING].nRet == 1 ? true : false; } } public bool GetFaultLaser() { lock (readNodeLock) { return ReadNode[csReadNodeNo.FAULT_LASER].nRet == 1 ? true : false; } } public bool GetEStopOpen() { lock (readNodeLock) { return ReadNode[csReadNodeNo.SYS_LASER_ESTOP_OPEN].nRet == 1 ? true : false; } } public bool GetLastMessageType() { lock (readNodeLock) { return ReadNode[csReadNodeNo.LASTMESSAGE_TYPE].nRet == 1 ? true : false; } } public int GetLastMessageCompID() { lock (readNodeLock) { return ReadNode[csReadNodeNo.LASTMESSAGE_COMPID].nRet; } } public int GetLastMessageCompNum() { lock (readNodeLock) { return ReadNode[csReadNodeNo.LASTMESSAGE_COMPNUM].nRet; } } public int GetLastMessageMsgCode() { lock (readNodeLock) { return ReadNode[csReadNodeNo.LASTMESSAGE_MSGCODE].n16Ret; } } public string GetLastMessageShortText() { lock (readNodeLock) { return ReadNode[csReadNodeNo.LASTMESSAGE_SHORTTEXT].strRet; } } public string GetLastMessageTimeStamp() { lock (readNodeLock) { return ReadNode[csReadNodeNo.LASTMESSAGE_TIMESTAMP].strRet; } } public bool WaitLaserActivate() { DateTime startTime = DateTime.Now; while (ReadNode[csReadNodeNo.PROG_ACTIVE].nRet != 1) { Thread.Sleep(10); if (10 * 1000 < DateTime.Now.Subtract(startTime).TotalMilliseconds) return false; } return true; } public void SetIsSeqRunning(bool bOn) { Log.D($"Set Is Seq Runng {bOn}"); AutoProgramStart = bOn; } public int GetProgramLineNo() { lock (readNodeLock) { return ReadNode[csReadNodeNo.PROGRAM_LINE_NO].n16Ret; } } public int GetWriteInputWord(int no) { lock (writeNodeLock) { //int val = csWriteNodeNo.IW03 - 3 + no; //NodeId id = new NodeId(WriteNode[val].strNodeName); //return Convert.ToInt32(ReadNodeValue(id).Value); return WriteNode[no].n16Ret; } } public string GetCenterPower() { lock (readNodeLock) { // 구현 필요 //NodeId id = new NodeId(ReadNode[csReadNodeNo.LASER_POWER].strNodeName); //return Convert.ToString(Convert.ToDouble(ReadNodeValue(id).Value)); return ""; } } public string GetRingPower() { // 구현 필요 return null; } public int SetExternalActivation(bool bOn) { return SetData(csWriteNodeNo.EXT_ACTIVATION, bOn ? 1 : 0); } public int SetLaserReset(bool bOn) { return SetData(csWriteNodeNo.LASER_RESET, bOn ? 1 : 0); } public int SetLaserOn(bool bOn) { return SetData(csWriteNodeNo.LASER_ON, bOn ? 1 : 0); } public int SetRequestLaser(bool bOn) { return SetData(csWriteNodeNo.REQUEST_LASER, bOn ? 1 : 0); } public int SetProgramStartDynamic(bool bOn) { return SetData(csWriteNodeNo.PSTART_DYN, bOn ? 1 : 0); } public int SetPStartStatical(bool bOn) { return SetData(csWriteNodeNo.PSTART_STATICAL, bOn ? 1 : 0); } public int SetProgramStop(bool bOn) { return SetData(csWriteNodeNo.PROG_STOP, bOn ? 1 : 0); } public void SetReset() { nSequence = eSeqStep.SEQ_LASER_OFF_START; } public void SetProgEnd() { nSequence = eSeqStep.SEQ_LASER_ON_CHANGE_PROG_INFO; } public int SetProgramNo(int no) { return SetData(csWriteNodeNo.PROGRAM_NO, no); } /// /// Max Power을 레이저 내에서 알아야될 듯 함. /// 알고 있다면, value1 / (value1 + value2)에 해당 하는 값을 iw03에 넣어주어야 함. /// 이 때 CenterMax = Max * value1 / (value1 + value2)임. /// DesiredCenter = CenterMax * X /// X = DesiredCenter / CenterMax /// WriteDA에 (10 * X) Volt 만큼 되게끔 넣어주면 됨. /// /// /// public int SetPowerInInputWord3(int value1) { return SetData(csWriteNodeNo.IW03, value1); } public int SetPowerInInputWord4(int value1) { return SetData(csWriteNodeNo.IW04, value1); } #region Browser Test public void ExplorerNodes(NodeId startNode) { // 노드 트리 탐색 시작 BrowseTree(_session, startNode, 0); } public ReferenceDescriptionCollection references; private void BrowseTree(Session session, NodeId nodeId, int level) { byte[] continuationPoint; session.Browse(null, null, nodeId, 0u, BrowseDirection.Forward, ReferenceTypeIds.HierarchicalReferences, true, (uint)NodeClass.Object | (uint)NodeClass.Variable, out continuationPoint, out references); // >> 데이터 로그 생성 foreach (var rd in references) { Log.I($"{new string(' ', level * 2)} : {rd.DisplayName.Text} (NodeId: {rd.NodeId})"); if (!rd.NodeId.IsAbsolute) { BrowseTree(session, ExpandedNodeId.ToNodeId(rd.NodeId, session.NamespaceUris), level + 1); } } } #endregion #endregion } }