using Aurora.Api.Devices; using Hermes; using System.Collections; namespace AuroraLaser { class LaserIPG_YLPN : SerialConn, 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; internal bool IsCommError => IsConnected(); #region IPG Enumerator Definitions public enum eOperatingModeBit { PowerControl = 0, // 1 : DB-25, 0 : RS-232 AuxOFFControl = 2, // 1 : DB-25, 0 : Disabled GuideLaserControl = 3, // 1 : DB-25, 0 : RS-232 EmissionModulationControl = 7, // 1 : DB-25, 0, RS-232 JumpPRRMode = 8, // 1 : Active, 0 : Inactive BitStream1Mode = 10, // 1 : Activate 0 : Deactivate PRRControlledBySyncLine = 12, // 1 : DB-25, 0: Internal trigger generator RS-232 EmissionEnableControl = 13, // 1 : DB-25, 0 : RS232 APDModeControlled = 14, // 1 : DB-25, 0 : RS232 AutomaticLatch = 15, // 1 : Automatic, 0: DB-25 SweepPRRMode = 19, // 1 : Active , 0: Inactive FollowPRRMode = 20, // 1 : Active, 0 : Inactive ManualPrePumpMode = 21, // 1 : Active, 0 : FactoryCalibratedPrePupump active ManualResidual = 22, // 1 : DB-25 Controlled, 0 : RS-232 Controlled, GuideLaserSafetyFunction = 25, // 1 : Activatee, 0 : Not Activated DischargeCircuitSafetyFunction = 26, // 1 : Activate, 0 : Not Activated } public enum eDeviceStatusBit { RackReflectionAlarm = 0, // 1 : Active, 0 : No BR Alarm LaserModuleTemperatureAlarm = 1, // 1 : Active, 0 : No Alarm LaserRemoteHeadTemperatureAlarm = 2, // 1 : Active, 0 : No Alarm SystemAlarm = 3, // 1 : Active, 0 : No Alarm MainSupply24VAlarm = 4, // 1 : Active, 0: No Alarm, HKSupplyAlarm = 5, // 1 : Active, 0 : No Alarm, LaserEmissionReady = 6, // 1 : Ready, 0 : Not Ready WaringExists = 7, // 1 : at least 1 warning is activated, 0 : No Warnings GuideLaserSafetyLimiterCircuit = 11, // 1 : Malfunction, 0 : Normal, SafetyDischargeCircuit = 12 // 1 : MalFunction, 0 : normal } public enum eAlarmCounterType { MainSupply24V = 1, HouseKeepingSupply24V = 2, System = 3, Temperature = 4, HeadTemperature = 5 } public enum eReadCommand { DeviceID = 1, DeviceSN = 2, FWRevision = 3, Vendor = 99, DeviceStatus = 4, DeviceTemperature = 5, DigitalInterfaceStatus = 10, ExtendedStatus = 11, BRCounter = 12, SessionBRCounter = 13, NominalAveragePower = 14, NominalPulseDuration = 15, NominalPulseEnergy = 16, NominalPeakPower = 17, PRRRange = 18, HeadTemperature = 19, MainSupplyVoltage = 21, HouseKeepingVoltage24V, OperatingMode = 23, InstalledOptions = 25, StartOperatingMode = 27, OperatingPowerWatt = 34, OperatingPowerPercent = 34, OperatingPulseEnergy = 36, PRRMonitor = 38, AlarmCounters = 70, ModuleTemperatureRange = 58, NominalFrequency = 59, CriticalErrorCounter = 95, CriticalErrorCode = 96, ReadPRR = 29, ReadTheNumberOfAPDModes = 55, ReadAPDModeDescription = 56, ReadAPDModeIndex = 68, MaximumPrePump = 63, PrePump = 65, } public enum eSetCommand { OperatingMode = 24, StartOperatingMode = 26, ResetCriticalErrorAlarms = 97, SetPRR = 28, LaserEmissionOn = 30, LaserEmissionOff = 31, OperatingPower = 32, GuideLaserOn = 40, GuideLaserOff = 41, EEON = 42, EEOFF = 43, ResetAlarms = 50, SetAPDModeIndex = 69, SaveAPDModeIndex = 54, PrePump = 64, } #endregion public LaserIPG_YLPN(string deviceid, bool isSimul) : base(deviceid, isSimul) { _IsSimul = isSimul; } public int Open(LaserConfig Config) { if (_IsSimul) { return E1.OK; } return Open(Config); } public void DisConnect() { if (_IsSimul) { return; } Close(); } public int LaserOn() { SetEmissionEnable(true); return 1; } public int LaserOff() { SetEmissionEnable(false); return 1; } public int PilotLaserOn() { SetGuideLaser(true); return 1; } public int PilotLaserOff() { SetGuideLaser(false); return 1; } public bool GetConnected() { return IsConnected(); } public int SetData(int nTarget, int value) { // nTarget 이 eSetCommand 로 들어와야지 쓸수있다. // interlock 을 어떻게 할것인지는 고민이 필요하다. if (nTarget < 0 || nTarget > 65) return E2.INTERNAL_ERROR; 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(); float outvalue; bool bret = SendNReceive((eReadCommand)nTarget, out outvalue); return bret ? outvalue.ToString() : E2.INTERNAL_ERROR.ToString(); } public bool GetInitCommunication() { // 업데이트 예정 return false; } public bool GetEmissionStatus() { // 업데이트 예정 return false; } public bool GetLaserReady() { // 업데이트 예정 return false; } public bool GetLaserError() { // 업데이트 예정 return false; } public bool GetWariningStatus() { // 업데이트 예정 return false; } // MAINS_STATUS, ERROR_STATUS 는 위에 있음 public bool GetPilotLaserStatus() { // 업데이트 예정 return false; } public string GetControlMode() { // 업데이트 예정 return ""; } public string GetPowerCenter() { // 업데이트 예정 return ""; } public string GetPowerRing() { // 업데이트 예정 return ""; } #region Set 명령 나간 bit 를 모니터링 public bool GetStartLaserSetBitStatus() { // Laser Start 명령 // 업데이트 예정 return false; } public bool GetLaserStartSetBitStatus() { // Laser On 명령. Laser Emission Ready 를 위한 bit // 업데이트 예정 return false; } public bool GetPilotLaserSetBitStatus() { // Pilot Laser On 명령. // 업데이트 예정 return false; } public bool GetLaserResetSetBitStatus() { // Laser Reset 명령. // 업데이트 예정 return false; } public bool GetControlModeSetStatus() { // Control mode Local(false) Remote(true) // 업데이트 예정 return false; } #endregion public void UpdateStatus() { if (_IsSimul && IsCommError) { return; } GetDeviceStatus(out _Status); var data = new BitArray(_Status); HasAlarm = data[(int)eDeviceStatusBit.RackReflectionAlarm] | data[(int)eDeviceStatusBit.LaserModuleTemperatureAlarm] | data[(int)eDeviceStatusBit.LaserRemoteHeadTemperatureAlarm] | data[(int)eDeviceStatusBit.SystemAlarm] | data[(int)eDeviceStatusBit.MainSupply24VAlarm] | data[(int)eDeviceStatusBit.HKSupplyAlarm]; IsEmissionReady = data[(int)eDeviceStatusBit.LaserEmissionReady]; } public int SetEmissionEnable(bool isEnable) { if (_IsSimul) { return E1.OK; } if (IsCommError) { return E2.NOT_CONNECTED; } var code = isEnable ? eSetCommand.EEON : eSetCommand.EEOFF; return SendCommand(code) ? E1.OK : E2.ABORTED; } public int SetEmission(bool isOn) { if (_IsSimul) { return E1.OK; } if (IsCommError) { return E2.NOT_CONNECTED; } var code = isOn ? eSetCommand.LaserEmissionOn : eSetCommand.LaserEmissionOff; return SendCommand(code) ? E1.OK : E2.ABORTED; } // Set operating power in [%]. Range 0…100 // resolution 255 levels for the full scale public int SetPower(double power) { if (_IsSimul) { _OperatingPower = power; return E1.OK; } if (IsCommError) { return E2.NOT_CONNECTED; } return SetOperatingPower((float)power) ? E1.OK : E2.ABORTED; } public double GetPower() { if (_IsSimul) { return _OperatingPower; } if (IsCommError) { return -1; } if (GetOperatingPowerInPercent(out float power)) { return power; } return -1; } public double GetPowerInWatt() { if (IsCommError) { return -1; } if (_IsSimul) { return _OperatingPower; } if (GetOperatingPowerInWatt(out float power)) { return power; } return -1; } public double GetPulseEnergy() { if (_IsSimul) { return 0; } if (IsCommError) { return -1; } if (GetOperatingPulseEnergy(out float energy)) { return energy; } return -1; } public int SetPulseRepetitionRate(double repetitionRate) { if (_IsSimul) { _OperatingPower = _RepetitionRate; return E1.OK; } if (IsCommError) { return E2.NOT_CONNECTED; } return SetPulseRepetitionRate((float)repetitionRate) ? E1.OK : E2.ABORTED; } public double GetPulseRepetitionRate() { if (_IsSimul) { return 0; } if (IsCommError) { return -1; } if (GetPulseRepetitionRate(out float repetitionRate)) { return repetitionRate; } return -1; } public double GetTemperature() { if (_IsSimul) { return 0; } if (IsCommError) { return -1; } if (GetDeviceTemperature(out float temp)) { return temp; } return -1; } public int ResetAlarm() { if (_IsSimul) { return E1.OK; } if (IsCommError) { return E2.NOT_CONNECTED; } return SendCommand(eSetCommand.ResetAlarms) ? E1.OK : E2.ABORTED; } private bool SendNReceive(eReadCommand cmd, int parameter, out short retValue) { retValue = 0; var cmdStr = GetCommand((int)cmd, parameter); var receive = WriteAndReadLine(cmdStr); if (string.IsNullOrEmpty(receive)) { return false; } if (!ParseCommand(receive, out string returnStr, cmd)) { return false; } if (!short.TryParse(returnStr, out retValue)) { return false; } return true; } private bool SendNReceive(eReadCommand cmd, int parameter, out string retValue) { var command = GetCommand((int)eReadCommand.ReadAPDModeDescription, parameter); var receive = WriteAndReadLine(command); return ParseCommand(receive, out retValue, eReadCommand.ReadAPDModeDescription); } private bool SendNReceive(eReadCommand cmd, out short retValue) { retValue = 0; if (!SendNReceive(cmd, out string returnStr)) { return false; } if (!short.TryParse(returnStr, out retValue)) { return false; } return true; } private bool SendNReceive(eReadCommand cmd, out int retValue) { retValue = 0; if (!SendNReceive(cmd, out string returnStr)) { return false; } if (!int.TryParse(returnStr, out retValue)) { return false; } return true; } private bool SendNReceive(eReadCommand cmd, out float retValue) { retValue = 0; if (!SendNReceive(cmd, out string returnStr)) { return false; } if (!float.TryParse(returnStr, out retValue)) { return false; } return true; } private bool SendNReceive(eReadCommand cmd, out string returnStr) { returnStr = default; var cmdStr = GetCommand((int)cmd); var receive = WriteAndReadLine(cmdStr); if (string.IsNullOrEmpty(receive)) { return false; } return ParseCommand(receive, out returnStr, cmd); } private bool ParseCommand(string receive, out string returnStr, eReadCommand cmdCode) { returnStr = default; if (string.IsNullOrEmpty(receive)) { return false; } var splited = receive.Split(';'); if (!int.TryParse(splited[0], out int retCmd)) { return false; } if (retCmd != (int)cmdCode) { return false; } if (splited.Length < 2) { return true; } returnStr = splited[1]; return true; } private bool SendCommand(eSetCommand cmdCode) { return Write(GetCommand((int)cmdCode)); } private bool SendCommand(eSetCommand cmdCode, short value) { return Write(GetCommand((int)cmdCode, value)); } private bool SendCommand(eSetCommand cmdCode, int value) { return Write(GetCommand((int)cmdCode, value)); } private bool SendCommand(eSetCommand cmdCode, float value, int digitsAfterPoint = 1) { return Write(GetCommand((int)cmdCode, value, digitsAfterPoint)); } private string GetCommand(int cmdCode) { return $"${cmdCode};\r"; } private string GetCommand(int cmdCode, float value, int digitsAfterPoint = 1) { if (digitsAfterPoint == 1) { return $"${cmdCode};{value:0.0}\r"; } else if (digitsAfterPoint == 2) { return $"${cmdCode};{value:0.00}\r"; } return $"${cmdCode};{value}\r"; } private string GetCommand(int cmdCode, int value) { return $"${cmdCode};{value}\r"; } #region Set Laser internal bool SetGuideLaser(bool bOn) { var code = bOn ? eSetCommand.GuideLaserOn : eSetCommand.GuideLaserOff; return SendCommand(code); } internal bool SetOperatingMode(int mode) => SendCommand(eSetCommand.OperatingMode, mode); internal bool SetStartOperatingMode(int mode) => SendCommand(eSetCommand.StartOperatingMode, mode); internal bool SetOperatingPower(float value) => SendCommand(eSetCommand.OperatingPower, value); #endregion #region Operating Value internal bool GetOperatingMode(out int mode) => SendNReceive(eReadCommand.OperatingMode, out mode); internal bool GetStartOperationMode(out int mode) => SendNReceive(eReadCommand.StartOperatingMode, out mode); internal bool GetInstalledOptions(out int options) => SendNReceive(eReadCommand.InstalledOptions, out options); internal bool GetOperatingPulseEnergy(out float energy) => SendNReceive(eReadCommand.OperatingPulseEnergy, out energy); internal bool GetOperatingPowerInPercent(out float value) => SendNReceive(eReadCommand.OperatingPowerPercent, out value); internal bool GetOperatingPowerInWatt(out float value) => SendNReceive(eReadCommand.OperatingPowerWatt, out value); #endregion #region PRR. PulseRepetitionRate internal bool SetPulseRepetitionRate(float value) => SendCommand(eSetCommand.SetPRR, value); internal bool GetPulseRepetitionRate(out float value) => SendNReceive(eReadCommand.ReadPRR, out value); internal bool GetPRRRange(out float min, out float max) { min = 0; max = 0; if (!SendNReceive(eReadCommand.PRRRange, out string receive)) { return false; } var splited = receive.Split(';'); if (splited.Length < 2) { return false; } if (!float.TryParse(splited[0], out min)) { return false; } return float.TryParse(splited[1], out max); } // Same with GetPulseRepetitionRate internal bool GetPRRMonitor(out float prr) { return SendNReceive(eReadCommand.PRRMonitor, out prr); } #endregion #region Read Nominal value internal bool GetNominalPulseDuration(out float duration) { return SendNReceive(eReadCommand.NominalPulseDuration, out duration); } internal bool GetNominalAveragePower(out float value) { return SendNReceive(eReadCommand.NominalAveragePower, out value); } internal bool GetNominalPeakPower(out float value) { return SendNReceive(eReadCommand.NominalPeakPower, out value); } internal bool GetNominalPulseEnergy(out float value) { return SendNReceive(eReadCommand.NominalPulseEnergy, out value); } #endregion #region Temperature internal bool GetDeviceTemperature(out float temperature) { return SendNReceive(eReadCommand.DeviceTemperature, out temperature); } internal bool GetHeadTemperature(out float temperature) { return SendNReceive(eReadCommand.HeadTemperature, out temperature); } internal bool GetModuleTemperatureRange(out float min, out float max) { min = 0; max = 0; if (!SendNReceive(eReadCommand.ModuleTemperatureRange, out string receive)) { return false; } var splited = receive.Split(';'); if (splited.Length < 2) { return false; } if (!float.TryParse(splited[0], out min)) { return false; } return float.TryParse(splited[1], out max); } #endregion #region Adjustable Pulse Duration (APD) mode internal bool SetAPDModeIndex(short index) { return SendCommand(eSetCommand.SetAPDModeIndex, index); } internal bool SaveAPDModeIndex() { return SendCommand(eSetCommand.SaveAPDModeIndex); } internal bool GetNumberOfAPDModes(out short value) { return SendNReceive(eReadCommand.ReadTheNumberOfAPDModes, out value); } internal bool GetAPDModeDescription(out string desc, int apdModeIndex) { return SendNReceive(eReadCommand.ReadAPDModeDescription, apdModeIndex, out desc); } internal bool GetCurrentAPDModeIndex(out short value) { return SendNReceive(eReadCommand.ReadAPDModeIndex, out value); } #endregion #region Manual Rising Time Compensation (Manual Prepump) mode. // 0...10000 internal bool SetPrePump(short level) { return SendCommand(eSetCommand.PrePump, level); } internal bool GetPrePump(out short level) { return SendNReceive(eReadCommand.PrePump, out level); } internal bool GetMaximumPrePump(out short level) { return SendNReceive(eReadCommand.MaximumPrePump, out level); } #endregion #region Back Reflection internal bool GetBRCounter(out int counter) { return SendNReceive(eReadCommand.BRCounter, out counter); } internal bool GetSessionBRCounter(out int counter) { return SendNReceive(eReadCommand.SessionBRCounter, out counter); } #endregion #region Supply internal bool GetMainSupplyVoltage(out float voltage) { return SendNReceive(eReadCommand.MainSupplyVoltage, out voltage); } internal bool Get24VHousekeepingVoltage(out float voltage) { return SendNReceive(eReadCommand.HouseKeepingVoltage24V, out voltage); } #endregion #region Info & Status internal bool GetDeviceID(out string id) { return SendNReceive(eReadCommand.DeviceID, out id); } internal bool GetDeviceSN(out string serialNumber) { return SendNReceive(eReadCommand.DeviceSN, out serialNumber); } internal bool GetFWRevision(out string revision) { return SendNReceive(eReadCommand.FWRevision, out revision); } internal bool GetVendor(out string vendor) { return SendNReceive(eReadCommand.Vendor, out vendor); } internal bool GetDeviceStatus(out int status) { return SendNReceive(eReadCommand.DeviceStatus, out status); } internal bool GetDigitalInterfaceStatus(out int status) { return SendNReceive(eReadCommand.DigitalInterfaceStatus, out status); } internal bool GetExtendedStatus(out int status) { return SendNReceive(eReadCommand.ExtendedStatus, out status); } #endregion #region Error & Alarms internal bool GetAlarmCounters(eAlarmCounterType type, out short count) { return SendNReceive(eReadCommand.AlarmCounters, (int)type, out count); } internal bool ReadCriticalErrorCounter(out short count) { return SendNReceive(eReadCommand.CriticalErrorCounter, out count); } internal bool ReadCriticalErrorCode(out int code) { return SendNReceive(eReadCommand.CriticalErrorCode, out code); } internal void ResetCriticalErrorAlarms(int code) { SendCommand(eSetCommand.ResetCriticalErrorAlarms, code); } #endregion } }