using Aurora.Api; using Aurora.Api.Devices; using AuroraPowerMeter.Coherent; using AuroraPowerMeter.Gentec; using Hermes; using System.IO.Ports; using System.Threading; namespace AuroraPowerMeter { public enum ePowerMeter { PowerMax, Gentec } public interface IPowerMeter { bool Measure(out double power); bool SetZero(); int Connect(SerialConnConfig config); int Disconnect(); bool IsConnected(); int Reconnect(); bool WaveLengthCorrection(int nLength); } public class PowerMeter : Device { Logger Log = new Logger("PowerMeter"); // MeasureResult 와 MeasuredPower 는 비슷하다고 함. 실제 장비에 써보고 불필요한 부분은 정리하자 public double MeasureResult { get; private set; } IPowerMeter _PowerMeter; // Simul //public static bool IsFired; // 레이저를 쐈다는 정보라고 함, 실제 장비에 써보고 불필요하면 삭제 검토 public static double MeasuredPower; protected bool _isSimulBySetting; // 시스템 세팅의 simul flag 저장. Activate 시, Config 의 시뮬 flag 와 조합하여 최종 결정 #region 생성자 public PowerMeter(string deviceId, ePowerMeter powerMeter, bool isSimul) { DeviceId = deviceId; CommType = CommunicationType.Serial; Type = DeviceType.PowerMeter; _isSimulBySetting = isSimul; // 주의: 생성자에서 config 값을 가져오기 번거로우니 아래와 같이 처리 // 생성자에서는 시스템 세팅의 Simul 정보만 사용 (시리얼포트의 IsSimul 까지 처리됨) // 상위단(여기)에서 DoActivate 시, simul flag 를 최종 결정 // 방침: 시뮬은 상위단에서 처리하는 구조 (내부 _PowerMeter 사용안함 (= 시리얼포트 사용안함)) switch (powerMeter) { case ePowerMeter.PowerMax: _PowerMeter = new PowerMeterPowerMax(deviceId, isSimul); break; case ePowerMeter.Gentec: _PowerMeter = new PowerMeterGT(deviceId, isSimul); break; } } #endregion protected override int DoActivate(IDeviceConfig config) { var l_config = config as PowerMeterConfig; IsSimul = l_config.IsSimul || _isSimulBySetting; var l_connConfig = l_config.ConnConfig as SerialConnConfig; if (IsSimul == false) { return _PowerMeter.Connect(l_connConfig); } else { // 시뮬레이션 return E1.OK; } } protected override int DoDeactivate() { if (IsSimul == false) { return _PowerMeter.Disconnect(); } else { return E1.OK; } } public void Update() { if (!IsActivated) { return; } if (Measure(out double value) != E1.OK) { return; } MeasureResult = value; } public int Measure(out double power) { power = 0; if (!IsActivated) { return E2.NOT_CONNECTED; } if (IsSimul) { /* if (!IsFired) { MeasureResult = 1; } else { // 시뮬레이션: 파워 [W] 값은 SimSetActualPowerWatt 메서드로부터 업데이트해서 받는다. power = MeasuredPower; MeasureResult = power; } */ // 시뮬레이션: 파워 [W] 값은 SimSetActualPowerWatt 메서드로부터 업데이트해서 받는다. power = MeasuredPower; MeasureResult = power; return E1.OK; } IsCommError = !_PowerMeter.IsConnected(); if (IsCommError) { return E2.NOT_CONNECTED; } if (!_PowerMeter.Measure(out power)) { return E2.INTERNAL_ERROR; } MeasureResult = power; return E1.OK; } public int SetZero() { if (!IsActivated) { return E2.NOT_CONNECTED; } if (IsSimul) { MeasuredPower = 0.0; return E1.OK; } IsCommError = !_PowerMeter.IsConnected(); if (IsCommError) { return E2.NOT_CONNECTED; } return _PowerMeter.SetZero() ? E1.OK : E2.INTERNAL_ERROR; } public bool WaveLengthCorrection(int length) { if (!IsActivated) { return false; } if (IsSimul) { return true; } IsCommError = !_PowerMeter.IsConnected(); if (IsCommError) { return false; } return _PowerMeter.WaveLengthCorrection(length); } #region Alarm private const int _alarmPrefix = 35; private object _alarmObject = new object(); private readonly object _alarmLockReconnectObj = new object(); public bool Reconnect() { if (Monitor.TryEnter(_alarmLockReconnectObj) && IsCommError) { if (_PowerMeter.Reconnect() == E1.OK) { ClearAlarm(CreateAlarmCode(99)); ClearAlarm(CreateAlarmCode(98)); return true; } return false; } return false; // Reconnect 외부에서 진행중. } public override void ClearAlarms() { if (IsActivated) { lock (_alarmObject) { var list = GetAlarmList().ToArray(); foreach (var alarmCode in list) { switch (alarmCode % 100) { case 99: case 98: Reconnect(); break; default: ClearAlarm(alarmCode); break; } } } } else { base.ClearAlarms(); } } private int CreateAlarmCode(int alarmCode) { return _alarmPrefix * 1000 + alarmCode; } #endregion #region Simulation 관련 public void SimSetActualPowerWatt(double laserPowerWatt) { if (IsSimul) { MeasuredPower = laserPowerWatt; } else { Log.E("Error: Only simulation mode is available"); } } #endregion } }