using Aurora; using AuroraIO; using Hermes; using System; using System.Reflection; using System.Threading; using System.Windows; using static AuroraIO.Vendor.PAIX.PAIXIO; namespace AuroraLaser { class LaserTrumpf_IO : ILaser { public bool IsEmissionReady { get; set; } public bool HasAlarm { get; set; } private bool _IsSimul; private int _Status; private double _OperatingPower; private double _RepetitionRate = 0.0; string _deviceId; //internal bool IsCommError => IsConnected(); private IODevice _IO; Thread m_threadUpdateLaserStatus = null; private bool bPilotLaserOnCmd; private bool bLaserEmissionReadyOnCmd; public LaserTrumpf_IO(string deviceid, bool isSimul, IODevice IO_Board) { _deviceId = deviceid; _IsSimul = isSimul; bPilotLaserOnCmd = false; _IO = IO_Board; } public int Open(LaserConfig Config) { if (_IsSimul) { return E1.OK; } int nRet = 0; if (!_IO.IsActivated) nRet = _IO.Activate(); if (nRet == E1.OK) { Thread.Sleep(100); m_threadUpdateLaserStatus = new Thread(new ThreadStart(UpdateLaserStatus)); m_threadUpdateLaserStatus.Start(); return nRet; } else return E1.NETWORK; } public void DisConnect() { if (_IsSimul) { return; } if (_IO._iOUnit.IsConnected()) { // 동작중인것을 정지시키는 코드는 여기에 // update 하는 thread 정지 if (m_threadUpdateLaserStatus != null) { m_threadUpdateLaserStatus.Join(500); m_threadUpdateLaserStatus.Abort(); } _IO._iOUnit.Close(); } } public int LaserOn() { int nRet = SetLaserDOCommand(ePTDOAddress.LASER_READY_ENABLE, true) == true ? E1.OK : E1.NETWORK; if (nRet != 0) return nRet; Thread.Sleep(500); bool bResult = false; nRet = SetProgBit(""); if (nRet != 0) return nRet; TimeSpan spanTime; DateTime startTime = DateTime.Now; int timeOut = 10; // Use System Machine ParametersB while (!bResult) { spanTime = DateTime.Now.Subtract(startTime); if (spanTime.TotalMilliseconds > (timeOut * 1000)) { return E1.NETWORK; } GetLaserDIStatus(ePTDIAddress.LASER_READY, out bResult); if (bResult) break; } nRet = SetLaserDOCommand(ePTDOAddress.PSTART_STATICAL, true) == true ? E1.OK : E1.NETWORK; if (nRet != 0) return nRet; Thread.Sleep(500); startTime = DateTime.Now; timeOut = 10; bResult = false; while (!bResult) { spanTime = DateTime.Now.Subtract(startTime); if (spanTime.TotalMilliseconds > (timeOut * 1000)) { return E1.NETWORK; } GetLaserDIStatus(ePTDIAddress.PROG_ACTIVE, out bResult); if (bResult) break; } //if (nRet != E1.OK || !bResult) // LaserOff(); return nRet; } public int LaserOff() { int nRet = SetLaserDOCommand(ePTDOAddress.PSTART_STATICAL, false) == true ? E1.OK : E1.NETWORK; if (nRet != 0) return nRet; bool bReadyResult = false; bool bCompleteResult = false; Thread.Sleep(500); nRet = GetLaserDIStatus(ePTDIAddress.LASER_READY, out bReadyResult) == true ? E1.OK : E1.NETWORK; if (nRet != 0) return nRet; nRet = GetLaserDIStatus(ePTDIAddress.PROG_COMPLETE, out bCompleteResult) == true ? E1.OK : E1.NETWORK; if (bReadyResult || bCompleteResult) nRet = SetLaserDOCommand(ePTDOAddress.LASER_READY_ENABLE, false) == false ? E1.OK : E1.NETWORK; return nRet; } public int SetProgBit(string PROG_No) { //20241101 gitae.won Program No 파라미터를 어떻게 받아오는지에 대한 확인 필요, 현재는 자동 공백으로 입력되어 config에 있는 No.를 받아옴 if (PROG_No == null || PROG_No.Trim() == "") { var config = (LaserConfig)Application.Current.AuroraEnv().DeviceManager.GetDeviceConfig(_deviceId); PROG_No = config.Program_No; } if (int.TryParse(PROG_No, out int number) && number >= 0 && number < 8) { bool bit0 = (number & 1) != 0; bool bit1 = (number & 2) != 0; bool bit2 = (number & 4) != 0; int nRet = SetLaserDOCommand(ePTDOAddress.PROG_BIT_0, bit0) == true ? E1.OK : E1.NETWORK; if (nRet != E1.OK) return nRet; nRet = SetLaserDOCommand(ePTDOAddress.PROG_BIT_1, bit1) == true ? E1.OK : E1.NETWORK; if (nRet != E1.OK) return nRet; nRet = SetLaserDOCommand(ePTDOAddress.PROG_BIT_2, bit2) == true ? E1.OK : E1.NETWORK; if (nRet != E1.OK) return nRet; return E1.OK; } else return E1.NETWORK; } public int PilotLaserOn() { bool bReadyResult = false; bool bActiveResult = false; Thread.Sleep(500); GetLaserDIStatus(ePTDIAddress.LASER_READY, out bReadyResult); GetLaserDIStatus(ePTDIAddress.PROG_ACTIVE, out bActiveResult); if (bReadyResult || bActiveResult) return E1.NETWORK; int nRet = SetLaserDOCommand(ePTDOAddress.PILOT_LASER_ON, true) == true ? E1.OK : E1.NETWORK; return nRet; } public int PilotLaserOff() { bool bReadyResult = false; bool bActiveResult = false; Thread.Sleep(500); GetLaserDIStatus(ePTDIAddress.LASER_READY, out bReadyResult); GetLaserDIStatus(ePTDIAddress.PROG_ACTIVE, out bActiveResult); if (bReadyResult || bActiveResult) return E1.NETWORK; int nRet = SetLaserDOCommand(ePTDOAddress.PILOT_LASER_ON, false) == true ? E1.OK : E1.NETWORK; return nRet; } public bool GetConnected() { return _IO._iOUnit.IsConnected(); } public int SetData(int nTarget, int value) { SetProgBit(value.ToString()); return E1.OK; } public string GetData(int nTarget) { // 어떻게 쓸지 고민중 return ""; } private void UpdateLaserStatus() { while (GetConnected()) { int UpdateTimeInterval = 300; // 300ms Thread.Sleep(UpdateTimeInterval); GetLaserAllStatus(); } } public bool GetInitCommunication() { // IPG 는 해당 함수 없음 return true; } public bool GetEmissionStatus() { if (_IsSimul) return false; bool bResult; GetLaserDIStatus(ePTDIAddress.PROG_ACTIVE, out bResult); return bResult; } public bool GetLaserReady() { if (_IsSimul) return false; //bool bReadyResult = false; bool bActiveResult = false; //GetLaserDIStatus(ePTDIAddress.LASER_READY, out bReadyResult); GetLaserDIStatus(ePTDIAddress.PROG_ACTIVE, out bActiveResult); // if (bReadyResult || bActiveResult) if (bActiveResult) return true; else return false; } public bool GetLaserError() { if (_IsSimul) return false; bool bResult; //LASRE Error 에 관한 인터페이스가 없음 일단 warning lamp로 확인 GetLaserDIStatus(ePTDIAddress.LASER_WARNING_LAMP_IS_ON, out bResult); return bResult; } public bool GetWariningStatus() { if (_IsSimul) return false; bool bResult; GetLaserDIStatus(ePTDIAddress.LASER_WARNING_LAMP_IS_ON, out bResult); return bResult; } // MAINS_STATUS, ERROR_STATUS 는 위에 있음 public bool GetPilotLaserStatus() { // pilot 신호는 Pin map 배정이 안되어서 DI로 받아오는게 없다. DO 로 대신하자. 밑에 DO 검색이 있어서 보류. if (_IsSimul) return false; bool bResult; GetLaserDoStatus(ePTDOAddress.PILOT_LASER_ON, out bResult); return bResult; } public string GetControlMode() { // Control mode 신호는 Pin map 배정이 안되어서 DI로 받아오는게 없다. return ""; } public string GetPowerCenter() { // IO Board 제어는 파워를 직접 세팅하지 않는다. return ""; } public string GetPowerRing() { // IO Board 제어는 파워를 직접 세팅하지 않는다. return ""; } #region Set 명령 나간 bit 를 모니터링 public bool GetStartLaserSetBitStatus() { if (_IsSimul) return false; // Laser Start 명령. 비슷한 이름이 많은데 기능에 대한 설명이 없으니 유추가 어렵다. return false; } public bool GetLaserStartSetBitStatus() { if (_IsSimul) return false; bool bResult; GetLaserDoStatus(ePTDOAddress.LASER_READY_ENABLE, out bResult); return bResult; } public bool GetPilotLaserSetBitStatus() { if (_IsSimul) return false; bool bResult; GetLaserDoStatus(ePTDOAddress.PILOT_LASER_ON, out bResult); return bResult; } public bool GetLaserResetSetBitStatus() { if (_IsSimul) return false; bool bResult; //Alarm Reset 인터페이스가 없음, 임의로 fault_exe GetLaserDoStatus(ePTDOAddress.FAULT_EXE, out bResult); return bResult; } public bool GetControlModeSetStatus() { // Control mode 는 Pin map 에 없다 // 업데이트 예정 return false; } #endregion #region IO Board Functions private bool GetLaserDIStatus(ePTDIAddress addr, out bool bValue) { if (_IsSimul) { bValue = false; return true; } bool[] arrDI = new bool[Convert.ToInt32(_IO._iOUnit.GetDICount())]; int nRet = _IO._iOUnit.GetDiArray(ref arrDI); if (nRet == E1.OK) { bValue = arrDI[Convert.ToInt32(addr)]; return true; } else { bValue = false; return false; } } private bool GetLaserDoStatus(ePTDOAddress addr, out bool bValue) { if (_IsSimul) { bValue = false; return true; } bool[] arrDO = new bool[Convert.ToInt32(_IO._iOUnit.GetDOCount())]; int nRet = _IO._iOUnit.GetDoArray(ref arrDO); if (nRet == E1.OK) { bValue = arrDO[Convert.ToInt32(addr)]; return true; } else { bValue = false; return false; } } private bool GetLaserAllStatus() { if (_IsSimul) { return true; } if (GetLaserReady()) _IO._iOUnit.WriteDoBit(Convert.ToInt32(ePDOAddress.LaserOnLampOn), true); else _IO._iOUnit.WriteDoBit(Convert.ToInt32(ePDOAddress.LaserOnLampOn), false); bool[] arrDI = new bool[Convert.ToInt32(_IO._iOUnit.GetDICount())]; int nRet = _IO._iOUnit.GetDoArray(ref arrDI); if (nRet == E1.OK) { // 여기에 arrDI 를 저장하는 변수를 assign 하자. return true; } else { return false; } } private bool SetLaserDOCommand(ePTDOAddress addr, bool bSetValue) { if (_IsSimul) { return true; } int nRet = _IO._iOUnit.WriteDoBit(Convert.ToInt32(addr), bSetValue); if (nRet == E1.OK) { return true; } else { return false; } } #endregion public static object GetPropertyValue(object obj, string propertyName) { if (obj == null) throw new ArgumentNullException(nameof(obj)); if (string.IsNullOrEmpty(propertyName)) throw new ArgumentNullException(nameof(propertyName)); Type type = obj.GetType(); PropertyInfo propertyInfo = type.GetProperty(propertyName); if (propertyInfo == null) throw new ArgumentException($"Property '{propertyName}' not found on type '{type.FullName}'"); return propertyInfo.GetValue(obj); } } #region IO Board Communication Format #endregion }