using Aurora.Api; using Aurora.Api.Devices; using Hermes; using System.Collections.Generic; using System.IO.Ports; using System.Text; namespace AuroraLaser.Coherent { // HR-NX 355 30 (UV) public partial class HyperRapidLaser : SerialPortDevice { private const int MAX_DIODE_NUMBER = 3; public enum _tagLaserState { LASER_STATE_BOOT = -1, LASER_STATE_READY, LASER_STATE_ON, LASER_STATE_FAULT, }; private int _LaserNo; private const int MAX_RECV_BUFF_SIZE = 50; private int _FailCount; private int _LaserState; // simul private bool IsShutterOpen = false; private double LaserPower = 0; // Monitoring Value; private double HeadOperatingHours; private double ModuleOperatingHours; private double SeederOperatingHours; private double SeederDiode; private double AttenuatorTransmission = 0; private bool IsKeySwitch; private bool IsLaserPowerOn; private double[] DiodeOperatingHours = new double[MAX_DIODE_NUMBER]; public HyperRapidLaser(string deviceId, int laserNo, bool isSimulation) : base(deviceId, isSimulation) { _FailCount = 0; _LaserState = 0; _LaserNo = laserNo; } protected override int DoActivate(IDeviceConfig config) { if (IsPortOpen()) { if (IsSimul) { _LaserState = (int)_tagLaserState.LASER_STATE_ON; } return E1.OK; } var result = Open((config as Config).ConnConfig as SerialConnConfig); if (result == E1.OK) { return Init(); } return result; } private int Init() { LaserPower = GetOutputAomPercentage(); return E1.OK; } protected override int DoDeactivate() { IsLaserPowerOn = false; return Close(); } public bool UpdateMonitoringValue() { if (!IsActivated) { return false; } if (GetLaserState() == (int)_tagLaserState.LASER_STATE_ON) { IsLaserPowerOn = true; } else { IsLaserPowerOn = false; } if (IsSimul) { IsKeySwitch = true; return true; } IsKeySwitch = GetMonitorData(("K")) == 1 ? true : false; AttenuatorTransmission = GetMonitorData(CMD_ATTENUATOR_TRANSMISSION); HeadOperatingHours = GetMonitorData(CMD_HEAD_OPERATINGHOURS); ModuleOperatingHours = GetMonitorData(CMD_MODULE_OPERATINGHOURS); SeederOperatingHours = GetMonitorData(CMD_SEEDER_OPERATINGHOURS); SeederDiode = GetMonitorData(CMD_SEEDER_DIODE); for (int i = 0; i < MAX_DIODE_NUMBER; i++) { DiodeOperatingHours[i] = GetMonitorData(string.Format("{0}{1}H", CMD_DIODE_OPERATINGHOURS, i + 1)); } return true; } private string GetMonitorDataString(string strCMD) { if (IsSimul) { return string.Empty; } strCMD = "?" + strCMD; var strReceive = SendCMD(strCMD); if (strReceive == null) { Log.E($"{strCMD} 명령 실행에 실패했습니다."); return string.Empty; } if (string.IsNullOrEmpty(strReceive)) { Log.FuncE($"{strCMD}명령 실행에 대한 응답에 오류가 있습니다."); return string.Empty; } if (strReceive.Contains(strCMD)) { strReceive = strReceive.Replace(strCMD, ("")); // 명령어가 에코로 오면 제거한다. strReceive = strReceive.Trim((" ").ToCharArray()); } strReceive.Trim(("\t\n\r ").ToCharArray()); return strReceive; } private double GetMonitorData(string strSend) { string strReceive = GetMonitorDataString(strSend); if (string.IsNullOrEmpty(strReceive)) return -100; if (double.TryParse(strReceive, out double value)) { return value; } return -100; } private string GetData() { if (_FailCount > 5) { Deactivate(); Log.E("Fail count is bigger than 5"); return string.Empty; } var Receive_buff = new byte[MAX_RECV_BUFF_SIZE]; var dw = Read(Receive_buff); string strReceive; if (0 < dw && dw < MAX_RECV_BUFF_SIZE) { Receive_buff[dw] = 0; strReceive = Encoding.Default.GetString(Receive_buff); _FailCount = 0; } else { _FailCount++; return string.Empty; } int iPos = strReceive.IndexOf("?"); string str = strReceive.Substring(iPos); str.Replace("HyperNX>", ""); // PROMPT 문자 확인해서 대체해 준다. str.Trim("\t\n\r ".ToCharArray()); return str; } private string SendCMD(string strCMD, string strVal) => SendCMD(string.Format("{0}={1}", strCMD, strVal)); private string SendCMD(string strCMD, bool bVal) => SendCMD(strCMD, bVal ? 1 : 0); private string SendCMD(string strCMD, int iVal) => SendCMD(string.Format("{0}={1}", strCMD, iVal)); private string SendCMD(string strCMD, double dVal) => SendCMD(string.Format("{0}={1:0.000}", strCMD, dVal)); private string SendCMD(string strCMD) { if (!IsActivated) { return null; } // -- 연결 확인 if (!IsPortOpen()) return null; int nSize = strCMD.Length; if (nSize == 0) return null; var Send_buff = new byte[nSize + 2]; strCMD += "\r\n"; //byte[] StrByte = Encoding.UTF8.GetBytes(strCMD); //Array.Copy(StrByte, Send_buff, StrByte.Length); //Send_buff[nSize] = Convert.ToByte('\r'); //Send_buff[nSize + 1] = Convert.ToByte('\n'); return WriteAndReadLine(strCMD); // if (!SendNReply(Send_buff, nSize + 2)) { // Deactivate(); // return false; // } //return true; } public double GetDiodeOperatingHours(int iDiodeNo) // ?DnH(n:1,2,3) { if (IsSimul) { return 0; } if (iDiodeNo < 1 || iDiodeNo > MAX_DIODE_NUMBER) { Log.FuncE("존재하지 않는 번호입니다."); return -100; } return DiodeOperatingHours[iDiodeNo - 1]; } public bool GetSwitchOnState() { return IsKeySwitch; } public bool IsLaserOn() { if (IsSimul) { return IsLaserPowerOn; } return IsLaserPowerOn; } public string SetHeartBeatTimeout(int iSecs) { if (IsSimul) return string.Empty; return SendCMD(CMD_HEARTBEAT, iSecs); } public double GetHeadOperatingHours() => HeadOperatingHours; public double GetModuleOperatingHours() => ModuleOperatingHours; public double GetSeederOperatingHours() => SeederOperatingHours; public double GetSeederDiode() => SeederDiode; public bool IsKeySwitchOn() => IsKeySwitch; public double GetAttenuatorTransmission() => AttenuatorTransmission; public string ClearSystemFault() => SendCMD("FACK", 1); // FACK 1 public double GetPM() { if (IsSimul) { return 0; } return GetMonitorData(CMD_PM); } public string SetPM(double dVal) { if (IsSimul) { return string.Empty; } return SendCMD(CMD_PM, dVal); } public double GetOutputPower() { if (IsSimul) { return 5; } return GetMonitorData(CMD_OUTPUTPOWER); } public double GetOutputAomPercentage() { if (IsSimul) { return LaserPower; } return GetMonitorData(CMD_OUTPUTAOMPERCENTAGE); } public bool IsInternalShutterOpened() { if (IsSimul) { return IsShutterOpen; } return GetMonitorData(CMD_SHUTTEROPEN) == 1; } // S=%d public bool SetInternalShutterOpen(bool bOpen) { if (IsSimul) { IsShutterOpen = bOpen; return true; } return SendCMD(CMD_SHUTTEROPEN, bOpen) != null; } // START / STOP public bool SetLaserOn(bool bOn) { if (IsSimul) { IsLaserPowerOn = bOn; return true; } return SendCMD(bOn ? CMD_LASER_ON : CMD_LASER_OFF) != null; } public int GetLaserState() { if (IsSimul) { return (int)_tagLaserState.LASER_STATE_ON; } return (int)GetMonitorData(CMD_STATE); } public void CheckAlarm() { _LaserState = GetLaserState(); } public const int _SEQ_M1_LASER_POWER_OFF_ALARM = 15801; public List GetAlarms() { if (!IsActivated) { return new List { _SEQ_M1_LASER_POWER_OFF_ALARM }; } if (_LaserState != (int)_tagLaserState.LASER_STATE_ON) { return new List { _SEQ_M1_LASER_POWER_OFF_ALARM }; } return new List(); } public int GetLaserNo() //gdgoo 추가 { return _LaserNo; } public class Config : IDeviceConfig { public IConnConfig ConnConfig { get; set; } public Config() { ConnConfig = new SerialConnConfig() { BaudRate = 19200, DataBits = 8, StopBits = StopBits.One, Parity = Parity.None, PortNum = 1, NewLine = "\r\n" }; } public static Config GetDefaultConfig() { return new Config(); } } } }