429 lines
13 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|