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

384 lines
11 KiB
C#

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<int> GetAlarms()
{
if (!IsActivated) {
return new List<int> { _SEQ_M1_LASER_POWER_OFF_ALARM };
}
if (_LaserState != (int)_tagLaserState.LASER_STATE_ON) {
return new List<int> { _SEQ_M1_LASER_POWER_OFF_ALARM };
}
return new List<int>();
}
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();
}
}
}
}