2026-06-05 13:44:39 +09:00

233 lines
6.9 KiB
C#

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
}
}