2026-01-26 18:56:53 +09:00

429 lines
13 KiB
C#

using Aurora.Api;
using Aurora.Api.Devices;
using AuroraLaser.Trumpf.TruDisk;
using Hermes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AuroraLaser.Trumpf.TruPulseNano
{
public partial class LaserDeviceTruPulseNano : Device, ILaserDeviceTrumpf
{
private const int TimeOut = 3000;
private string _deviceId;
public LaserTruPulseNanoConfig Config { get; set; }
private SocketConn _socketConn;
public LaserDeviceTruPulseNano(string deviceId)
{
_deviceId = deviceId;
_socketConn = new SocketConn(deviceId, IsSimul);
}
protected override int DoActivate(IDeviceConfig config)
{
Config = config as LaserTruPulseNanoConfig;
return ActivateDevice();
//if (IsSimul) {
// return E1.OK;
//}
//var socketconfig = config.ConnConfig as SocketConnConfig;
//return _socketConn.Connect(socketconfig);
}
protected override int DoDeactivate()
{
return DeactivateDevice();
//if (IsSimul) {
// return E1.OK;
//}
//var res = _socketConn.Close();
//return res;
}
public int ActivateDevice()
{
if (IsSimul) {
return E1.OK;
}
var socketconfig = Config.ConnConfig as SocketConnConfig;
return _socketConn.Connect(socketconfig);
}
public int DeactivateDevice()
{
if (IsSimul) {
return E1.OK;
}
var res = _socketConn.Close();
return res;
}
public Task<byte[]> SendandReceiveAsync(byte[] bytearray)
{
return Task.Run(() => SendandReceive(bytearray));
}
public byte[] SendandReceive(byte[] bytearray)
{
if (IsSimul) {
return bytearray;
}
byte[] result = null;
var res = _socketConn.SendAndRecieve(bytearray, out result, 3000);
return result;
}
public byte[] CreateCommandPacket(TrupulseNanoCommand command, string[] arguments)
{
if (!CommandArguments.TryGetValue(command, out var argInfo)) {
throw new ArgumentException("Invalid command");
}
var argTypes = argInfo.ArgumentTypes;
// arguments가 null이면 빈 배열로 처리
if (arguments == null)
arguments = new string[0];
// ArgumentTypes가 null(즉, 인자가 필요 없는 명령어)이면 arguments 없이 패킷 생성
if (argTypes == null) {
byte[] packet = new byte[6];
packet[0] = 0x1B; // Start byte
packet[1] = 2; // Number of command bytes (명령어만 2바이트)
packet[2] = 0x09; // Command start byte
packet[3] = (byte)command;
packet[4] = 0x0D; // Stop byte
packet[5] = CalculateChecksum(packet);
return packet;
}
// argument 개수 체크: 둘 다 0이면 허용
if (argTypes.Length != arguments.Length) {
if (argTypes.Length == 0 && (arguments.Length == 0 || (arguments.Length == 1 && string.IsNullOrEmpty(arguments[0])))) {
// 인자가 필요 없는 명령어, arguments가 빈 배열 또는 [""]인 경우 허용
} else {
throw new ArgumentException("Argument count mismatch");
}
}
var argList = new List<byte>();
for (int i = 0; i < argTypes.Length; i++) {
string arg = arguments[i];
Type t = argTypes[i];
if (t == typeof(byte)) {
if (byte.TryParse(arg, out byte b)) {
argList.Add(b);
} else {
argList.Add(0);
}
} else if (t == typeof(UInt16) || t == typeof(ushort)) {
ushort us = 0;
ushort.TryParse(arg, out us);
var bytes = BitConverter.GetBytes(us);
Array.Reverse(bytes); // Big Endian
argList.AddRange(bytes);
} else if (t == typeof(UInt32) || t == typeof(uint)) {
uint ui = 0;
uint.TryParse(arg, out ui);
var bytes = BitConverter.GetBytes(ui);
Array.Reverse(bytes); // Big Endian
argList.AddRange(bytes);
} else {
argList.Add(0);
}
}
byte[] packetWithArgs = new byte[argList.Count + 6];
packetWithArgs[0] = 0x1B; // Start byte
packetWithArgs[1] = (byte)(argList.Count + 2); // Number of command bytes
packetWithArgs[2] = 0x09; // Command start byte
packetWithArgs[3] = (byte)command;
if (argList.Count > 0) {
Array.Copy(argList.ToArray(), 0, packetWithArgs, 4, argList.Count);
}
packetWithArgs[packetWithArgs.Length - 2] = 0x0D; // Stop byte
packetWithArgs[packetWithArgs.Length - 1] = CalculateChecksum(packetWithArgs);
return packetWithArgs;
}
#region Processing Received Message
private byte CalculateChecksum(byte[] packet)
{
byte checksum = 0;
for (int i = 0; i < packet.Length - 1; i++) {
checksum += packet[i];
}
return checksum;
}
public bool IsValidResponse(byte[] responsePacket)
{
if (responsePacket.Length < 6) {
return false;
}
byte startByte = responsePacket[0];
byte commandnumber = responsePacket[1];
byte stopByte = responsePacket[responsePacket.Length - 2];
byte checksum = responsePacket[responsePacket.Length - 1];
if (startByte != 0x1B || stopByte != 0x0D) {
return false;
}
if (commandnumber != (responsePacket.Length - 4)) {
return false;
}
byte calculatedChecksum = CalculateChecksum(responsePacket);
if (checksum != calculatedChecksum) {
return false;
}
return true;
}
public (byte commandNumber, byte[] arguments, string error) ParseResponse(byte[] responsePacket)
{
if (!IsValidResponse(responsePacket)) {
return ((byte)0x00, null, "Invalid response packet.");
}
byte responseProtocolCommandByte = responsePacket[2];
byte responseValue = responsePacket[3];
byte commandNumber = responsePacket[4];
if (responseProtocolCommandByte == 0x00) {
string errorMessage = Enum.GetName(typeof(ResponseCheck), responseValue) ?? "UnknownError";
return (commandNumber, null, errorMessage);
}
if (commandNumber == 0) {
byte commandcheck = responsePacket[5];
string errorMessage = Enum.GetName(typeof(CommandCheck), commandcheck) ?? "UnknownCommandError";
return (commandNumber, null, errorMessage);
}
if (responseProtocolCommandByte == 0x09 && responseValue == 0) {
// Command transferred to Laser correctly
int argumentCount = responsePacket.Length - 7;
byte[] arguments = new byte[argumentCount];
Array.Copy(responsePacket, 5, arguments, 0, argumentCount);
return (commandNumber, arguments, null);
}
return (commandNumber, null, "Unknown response error");
}
public object[] ParseArguments(TrupulseNanoCommand command, byte[] arguments)
{
if (!ResponseArguments.TryGetValue(command, out var respInfo) || respInfo.ArgumentTypes == null) {
return new object[0];
}
var result = new List<object>();
int argCount = respInfo.ArgumentCount;
var types = respInfo.ArgumentTypes;
if (argCount == -1) {
// 가변 개수, 타입 하나 반복
var type = types[0];
int size = GetTypeSize(type);
int count = arguments.Length / size;
for (int i = 0; i < count; i++) {
result.Add(ParseSingle(arguments, i * size, type));
}
} else {
int offset = 0;
for (int i = 0; i < types.Length && offset < arguments.Length; i++) {
var type = types[i];
int size = GetTypeSize(type);
if (offset + size > arguments.Length) {
break;
}
result.Add(ParseSingle(arguments, offset, type));
offset += size;
}
}
return result.ToArray();
}
private int GetTypeSize(Type type)
{
if (type == typeof(byte) || type == typeof(char)) {
return 1;
}
if (type == typeof(UInt16) || type == typeof(ushort)) {
return 2;
}
if (type == typeof(UInt32) || type == typeof(uint)) {
return 4;
}
return 1;
}
private object ParseSingle(byte[] data, int offset, Type type)
{
if (type == typeof(byte)) {
return data[offset];
}
if (type == typeof(UInt16) || type == typeof(ushort)) {
return (UInt16)((data[offset] << 8) | data[offset + 1]); // Big Endian
}
if (type == typeof(UInt32) || type == typeof(uint)) {
return (UInt32)((data[offset] << 24) | (data[offset + 1] << 16) | (data[offset + 2] << 8) | data[offset + 3]); // Big Endian
}
if (type == typeof(char)) {
return (char)data[offset];
}
return data[offset];
}
#endregion
///////////////////////////////////////////////////////////
// Laser Interface 추가
// All LaserDevice 에서 선택하여 Device 가 생성될 때 사용되며, All LaserDevice 가 Activated 일 때만 true 가 됨.
public bool IsActivated_InAllLaserDevice = false;
private bool CanCallLaserFunction()
{
throw new NotImplementedException();
}
public int LaserOn()
{
throw new NotImplementedException();
}
public int LaserOff()
{
throw new NotImplementedException();
}
public int PilotLaserOn()
{
throw new NotImplementedException();
}
public int PilotLaserOff()
{
throw new NotImplementedException();
}
public bool GetPilotLaserStatus()
{
throw new NotImplementedException();
}
public bool GetLaserReady()
{
throw new NotImplementedException();
}
public bool GetPilotLaserSetBitStatus()
{
throw new NotImplementedException();
}
public bool GetConnected()
{
throw new NotImplementedException();
}
public int SetData(int nTarget, int value)
{
throw new NotImplementedException();
}
public int ResetLaser()
{
throw new NotImplementedException();
}
public string GetControlMode()
{
throw new NotImplementedException();
}
public bool GetControlModeSetStatus()
{
throw new NotImplementedException();
}
public bool GetEmissionStatus()
{
throw new NotImplementedException();
}
public bool GetEStop()
{
throw new NotImplementedException();
}
public bool GetInitCommunication()
{
throw new NotImplementedException();
}
public bool GetLaserError()
{
throw new NotImplementedException();
}
public bool GetLaserResetSetBitStatus()
{
throw new NotImplementedException();
}
public bool GetLaserStartSetBitStatus()
{
throw new NotImplementedException();
}
public string GetPowerCenter()
{
throw new NotImplementedException();
}
public string GetPowerRing()
{
throw new NotImplementedException();
}
public bool GetStartLaserSetBitStatus()
{
throw new NotImplementedException();
}
public bool GetWarningStatus()
{
throw new NotImplementedException();
}
public bool GetLaserInterlock()
{
throw new NotImplementedException();
}
}
}