using Aurora.Api.Devices; using Hermes; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace AuroraLaser.IPG.YLPP { public enum eCommandYLPP { None, ReadFirmwareVersion, ReadPartNumber, ReadModelNumber, ReadSerialNumber, ReadMaximumCurrentSetPoint, ReadMinimumCurrentSetPoint, SetRepetitionRate, ReadRepetitionRate, SetNumberOfPulses, ReadNumberOfPulses, SetCurrentSetPoint, ReadCurrentSetPoint, StartEmission, StopEmission, ResetErrors, ReadDevicesStatus, ReadEmissionStatus, ReadErrorFlags, ReadOutputPower, ReadPulseEnergy, ReadLaserCaseTemperature, ReadLaserHeadTemperature, ReadBackReflectionLevel, ReadElapsedEmissionEnergy, ReadEmissionTime, ExternalAnalogControlOn, ExternalAnalogControlOff, EnableEmission, DisableEmission, ExternalModulationOn, ExternalModulationOff } public static class YLPPCommandTable { public static readonly Dictionary CommandMap = new Dictionary() { { eCommandYLPP.ReadFirmwareVersion, "RFV" }, { eCommandYLPP.ReadPartNumber, "RPN" }, { eCommandYLPP.ReadModelNumber, "RMN" }, { eCommandYLPP.ReadSerialNumber, "RSN" }, { eCommandYLPP.ReadMaximumCurrentSetPoint, "RMC" }, { eCommandYLPP.ReadMinimumCurrentSetPoint, "RNC" }, { eCommandYLPP.SetRepetitionRate, "RRR" }, { eCommandYLPP.ReadRepetitionRate, "RRR" }, { eCommandYLPP.SetNumberOfPulses, "SNUMP" }, { eCommandYLPP.ReadNumberOfPulses, "RNUMP" }, { eCommandYLPP.SetCurrentSetPoint, "SCS" }, { eCommandYLPP.ReadCurrentSetPoint, "RCS" }, { eCommandYLPP.StartEmission, "EMON" }, { eCommandYLPP.StopEmission, "EMOFF" }, { eCommandYLPP.ResetErrors, "RERR" }, { eCommandYLPP.ReadDevicesStatus, "STA" }, { eCommandYLPP.ReadEmissionStatus, "REM" }, { eCommandYLPP.ReadErrorFlags, "REF" }, { eCommandYLPP.ReadOutputPower, "ROP" }, { eCommandYLPP.ReadPulseEnergy, "RPE" }, { eCommandYLPP.ReadLaserCaseTemperature, "RCT" }, { eCommandYLPP.ReadLaserHeadTemperature, "RHT" }, { eCommandYLPP.ReadBackReflectionLevel, "RBR" }, { eCommandYLPP.ReadElapsedEmissionEnergy, "REE" }, { eCommandYLPP.ReadEmissionTime, "RET" }, { eCommandYLPP.ExternalAnalogControlOn, "EEC" }, { eCommandYLPP.ExternalAnalogControlOff, "DEC" }, { eCommandYLPP.EnableEmission, "ELE" }, { eCommandYLPP.DisableEmission, "DLE" }, { eCommandYLPP.ExternalModulationOn, "EMOD" }, { eCommandYLPP.ExternalModulationOff, "DMOD" }, }; public static readonly Dictionary StatusMap = new Dictionary() { {0, "Emission On" }, {1, "Reserved" }, {2, "Reserved" }, {3, "External Modulation Control"}, {4, "External Analog Control"}, {5, "External Emission Control" }, {6, "Power Supply" }, {7, "Reserved" }, {8, "Reserved" }, {9, "Reserved" }, {10, "Reserved" }, {11, "Reserved" }, {12, "Seed is Starting"}, // 0 = Seed Started. Laser Ready. 1 = Seed is starting. Laser Not Ready. {13, "Seed is On" }, //0 = Seed not on 1 = Seed is ON {14, "Not Ready" }, //0 = Normal Operating Condition. 1 = Not Ready {15, "Error Present"}, //0 = Normal Operating Condition. 1 = Error is Present {16, "Keyswitch Position" }, //0 = Keyswitch in local position (ON). 1 = Keyswitch in remote position (REM) {17, "Front Panel Status" }, // 0 = Front Panel Unlocked. 1 = Front Panel Locked {18, "Reserved"}, {19, "Reserved"}, {20, "Reserved"}, {21, "Reserved"}, {22, "Reserved"}, {23, "Reserved"}, {24, "Reserved"}, {25, "Reserved"}, {26, "Reserved"}, {27, "Reserved"}, {28, "Reserved"}, {29, "Reserved"}, {30, "Reserved"}, {31, "Reserved"} }; } public class LaserYLPPSocketConn : SocketConn { public bool IsEmissionReady { get; set; } private bool _IsSimul; private long _LaserStatus = 0; private long _LaserError = 0; internal bool IsCommError => IsConnected(); private readonly object _sendLock = new object(); Thread m_threadUpdateLaserStatus = null; private bool bPilotLaserOnCmd; private bool bLaserEmissionReadyOnCmd; public LaserYLPPSocketConn(string deviceid, bool isSimul) : base(deviceid, isSimul) { _IsSimul = isSimul; bPilotLaserOnCmd = false; } public int Open(SocketConnConfig Config) { if (_IsSimul) { return E1.OK; } int nRet = Connect(Config); if (nRet == E1.OK) { Thread.Sleep(100); m_threadUpdateLaserStatus = new Thread(new ThreadStart(UpdateLaserStatus)); m_threadUpdateLaserStatus.Start(); } return E1.OK; } public void DisConnect() { if (_IsSimul) { return; } if (IsConnected()) { // 동작중인것을 정지시키는 코드는 여기에 // update 하는 thread 정지 if (m_threadUpdateLaserStatus != null) { m_threadUpdateLaserStatus.Join(500); m_threadUpdateLaserStatus.Abort(); } Close(); } } public string SendCommand(eCommandYLPP command) { lock (_sendLock) { if (!YLPPCommandTable.CommandMap.ContainsKey(command)) return "Invalid Command"; string cmd = YLPPCommandTable.CommandMap[command] + "\r\n"; byte[] send = Encoding.ASCII.GetBytes(cmd); if (SendAndRecieve(send, out byte[] recv) == E1.OK) return Encoding.ASCII.GetString(recv).Trim(); else return "Comm Error"; } } public int LaserOn() { if (_IsSimul) { bLaserEmissionReadyOnCmd = true; return E1.OK; } string Response = SendCommand(eCommandYLPP.StartEmission); if (Response == YLPPCommandTable.CommandMap[eCommandYLPP.StartEmission]) { bLaserEmissionReadyOnCmd = true; return E1.OK; } else { return E1.GENERIC; } } public int LaserOff() { if (_IsSimul) { bLaserEmissionReadyOnCmd = false; return E1.OK; } string Response = SendCommand(eCommandYLPP.StopEmission); if (Response == YLPPCommandTable.CommandMap[eCommandYLPP.StopEmission]) { bLaserEmissionReadyOnCmd = false; return E1.OK; } else { return E1.GENERIC; } } public int PilotLaserOn() { if (_IsSimul) { bPilotLaserOnCmd = true; return E1.OK; } //string Response = SendCommand(eCommandYLPP.AimingBeamOn); //if (Response == YLPPCommandTable.CommandMap[eCommandYLPP.AimingBeamOn]) { // bPilotLaserOnCmd = true; // return E1.OK; //} else { // return E1.GENERIC; //} return E1.OK; } public int PilotLaserOff() { if (_IsSimul) { bPilotLaserOnCmd = false; return E1.OK; } //string Response = SendCommand(eCommandYLPP.AimingBeamOff); //if (Response == YLPPCommandTable.CommandMap[eCommandYLPP.AimingBeamOff]) { // bPilotLaserOnCmd = false; // return E1.OK; //} else { // return E1.GENERIC; //} return E1.OK; } public bool GetConnected() { return IsConnected(); } public int SetData(int nTarget, int value) { // nTarget 이 eSetCommand 로 들어와야지 쓸수있다. // interlock 을 어떻게 할것인지는 고민이 필요하다. if (nTarget < 0 || nTarget > 65) return E2.ABORTED; return E1.OK; //return SendCommand((eSetCommand)nTarget, value) ? E1.OK : E2.ABORTED; } public string GetData(int nTarget) { // nTarget 이 eReadCommand 로 들어와야지 쓸수있다. // interlock 을 어떻게 할것인지는 고민이 필요하다. if (nTarget < 0 || nTarget > 96) return E2.INTERNAL_ERROR.ToString(); return ""; //return bret ? outvalue.ToString() : E2.INTERNAL_ERROR.ToString(); } private bool GetLaserData(out string Response) { if (_IsSimul) { Response = ""; return true; } Response = SendCommand(eCommandYLPP.ReadDevicesStatus); if (Response.StartsWith("STA:")) { return true; } else { return false; } } private bool GetLaserError(out string Response) { if (_IsSimul) { Response = ""; return true; } Response = SendCommand(eCommandYLPP.ReadErrorFlags); if (Response.StartsWith("REF:")) { return true; } else { return false; } } private void GetLaserAllStatus() { string response = ""; if (_IsSimul) return; if (GetLaserData(out response)) { UpdateLaserStatusBit(response); } if (GetLaserError(out response)) { UpdateLaserErrorBit(response); } } private void UpdateLaserStatusBit(string response) { if (_IsSimul) return; string valueStr = response.Replace("STA:", "").Trim(); if (!long.TryParse(valueStr, out long statusBits)) { return; } _LaserStatus = statusBits; } #region Alarm Flag Bit /* 0 24 Volts Missing 1 5 Volts Missing 2 No BUS Voltage 3 Case Temp Too High 4 Head Temp Too High 5 High Back-reflection 6 High Fiber-fuse Power 7 Fiber Interlock 8 Ground Failure 9 Stages Shutdown 10 High Diode Current 11 High Diode Power 12 ~ 14 ------------ Reserved 15 Shutdown Pin On 16 Error Present 17 PD6 Fault 18 Seed Start Error 19 Seed Clock Error 20 ------------ Reserved 21 PD5 Fault 22 Driver Comm 23 PD4 Fault 24 Safety Module 25 Safety Comm 26 Module Comm 27 OpenClose interlocks 28 ~ 31 Reserved */ #endregion private void UpdateLaserErrorBit(string response) { if (_IsSimul) return; string valueStr = response.Replace("REF:", "").Trim(); long ErrorBits = Int16.Parse(valueStr, System.Globalization.NumberStyles.HexNumber); _LaserError = ErrorBits; } private void UpdateLaserStatus() { int UpdateTimeInterval = 300; // 300ms while (GetConnected()) { try { GetLaserAllStatus(); } catch { Thread.Sleep(1000); continue; } Thread.Sleep(UpdateTimeInterval); } } public bool GetInitCommunication() { if (_IsSimul) return false; return false; } public bool GetEmissionStatus() { if (_IsSimul) return false; return ((_LaserStatus & (1 << 0)) > 0) ? true : false; } public bool GetLaserReady() { if (_IsSimul) return true; return ((_LaserStatus & (1 << 0)) > 0) ? true : false; } public bool GetLaserError() { if (_IsSimul) return false; return ((_LaserStatus & (1 << 15)) > 0) ? true : false; } public bool GetWariningStatus() { return false; } public bool GetLaserAssigned() { if (_IsSimul) return true; //return ((_LaserStatus & (1 << 11)) > 0) ? false : true; return false; } public bool GetPilotLaserStatus() { if (_IsSimul) return false; //return ((_LaserStatus & (1 << 8)) > 0) ? true : false; return false; } public string GetControlMode() { if (_IsSimul) { return "Unknown"; } if ((_LaserStatus & (1 << 3)) > 0) { return "External Modulation Control"; } else if ((_LaserStatus & (1 << 4)) > 0) { return "External Analog Control"; } else if ((_LaserStatus & (1 << 5)) > 0) { return "External Emission Control"; } else { return "Local"; } } public string GetPowerCenter() { return ""; } public string GetPowerRing() { return ""; } #region Set 명령 나간 bit 를 모니터링 public bool GetStartLaserSetBitStatus() { if (_IsSimul) return false; return false; } public bool GetLaserStartSetBitStatus() { if (_IsSimul) return false; return false; } public bool GetPilotLaserSetBitStatus() { if (_IsSimul) return false; return false; } public bool GetLaserResetSetBitStatus() { return false; } public bool GetControlModeSetStatus() { return false; } public int ResetLaser() { if (_IsSimul) { return E1.OK; } string Response = SendCommand(eCommandYLPP.ResetErrors); if (Response == YLPPCommandTable.CommandMap[eCommandYLPP.ResetErrors]) { return E1.OK; } else { return E1.GENERIC; } } public bool GetProgramInterrupted() { return false; } public bool GetProgramActived() { return false; } public bool GetEStop() { return ((_LaserError & (1 << 15)) > 0) ? true : false; } public List ErrorString() { List ErrorList = new List(); if (_LaserError == 0) { return ErrorList; } for (int i = 0; i < 32; i++) { if ((_LaserError & (1 << i)) > 0) { //Error String 내용이 필요한지 파악 후 ErrorMap 구현 //ErrorList[i] = YLPPCommandTable.ErrorMap[i] + "\r\n"; } } return ErrorList; } public List StatusString() { List StatusList = new List(); if (_LaserStatus == 0) { return StatusList; } for (int i = 0; i < 32; i++) { if ((_LaserStatus & (1 << i)) > 0) { StatusList[i] = YLPPCommandTable.StatusMap[i] + "\r\n"; } } return StatusList; } #endregion } }