235 lines
11 KiB
C#
235 lines
11 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using ln.logging;
|
|
using ln.type;
|
|
|
|
namespace ln.ethercat
|
|
{
|
|
public delegate bool ToEthercatDelegate(object value, out byte[] ethercatBytes);
|
|
public delegate bool FromEthercatDelegate(byte[] ethercatBytes, out object value);
|
|
|
|
public interface IECValueConverter {
|
|
|
|
Type NativeType { get; }
|
|
bool ToEthercat(object value, out byte[] ethercatBytes);
|
|
bool FromEthercat(byte[] ethercatBytes, out object value);
|
|
}
|
|
|
|
public class ECValueConverterAdapter : IECValueConverter
|
|
{
|
|
|
|
public ToEthercatDelegate ToEthercatDelegate { get; }
|
|
public FromEthercatDelegate FromEthercatDelegate { get; }
|
|
|
|
public Type NativeType { get; set; }
|
|
|
|
public ECValueConverterAdapter(Type nativeType, ToEthercatDelegate toEthercatDelegate,FromEthercatDelegate fromEthercatDelegate)
|
|
{
|
|
NativeType = nativeType;
|
|
ToEthercatDelegate = toEthercatDelegate;
|
|
FromEthercatDelegate = fromEthercatDelegate;
|
|
}
|
|
|
|
public bool ToEthercat(object value, out byte[] ethercatBytes) => ToEthercatDelegate(value, out ethercatBytes);
|
|
public bool FromEthercat(byte[] ethercatBytes, out object value) => FromEthercatDelegate(ethercatBytes, out value);
|
|
}
|
|
|
|
public static class ECDataTypeConverter
|
|
{
|
|
static Dictionary<ECDataTypes, IECValueConverter> valueConverters = new Dictionary<ECDataTypes, IECValueConverter>();
|
|
public static void AddConverter(ECDataTypes dataType, IECValueConverter valueConverter) => valueConverters.Add(dataType, valueConverter);
|
|
|
|
public static bool FromEthercat(ECDataTypes dataType, byte[] ethercatBytes, out object value)
|
|
{
|
|
try
|
|
{
|
|
if (valueConverters.TryGetValue(dataType, out IECValueConverter converter))
|
|
return converter.FromEthercat(ethercatBytes, out value);
|
|
} catch (Exception e)
|
|
{
|
|
Logging.Log(LogLevel.ERROR, "Exception caught while converting {0} = {1} from ethercat to native value", dataType, ethercatBytes.ToHexString());
|
|
Logging.Log(e);
|
|
}
|
|
value = null;
|
|
return false;
|
|
}
|
|
|
|
public static bool ToEthercat(ECDataTypes dataType, object value, out byte[] ethercatBytes)
|
|
{
|
|
try
|
|
{
|
|
if (valueConverters.TryGetValue(dataType, out IECValueConverter converter))
|
|
return converter.ToEthercat(Cast.To(value, converter.NativeType), out ethercatBytes);
|
|
} catch (Exception e)
|
|
{
|
|
Logging.Log(LogLevel.ERROR, "Exception caught while converting {0} = {1} to ethercat from native value", dataType, value);
|
|
Logging.Log(e);
|
|
}
|
|
|
|
ethercatBytes = null;
|
|
return false;
|
|
}
|
|
|
|
|
|
public static object FromEthercat(ECDataTypes dataType, byte[] ethercatBytes)
|
|
{
|
|
try{
|
|
if (FromEthercat(dataType, ethercatBytes, out object value))
|
|
return value;
|
|
} catch (Exception e)
|
|
{
|
|
Logging.Log(LogLevel.ERROR, "Exception caught while converting {0} = {1} from ethercat to native value", dataType, ethercatBytes.ToHexString());
|
|
Logging.Log(e);
|
|
}
|
|
throw new NotSupportedException(String.Format("converting {0} is currently not supported", dataType ));
|
|
}
|
|
public static byte[] ToEthercat(ECDataTypes dataType, object value)
|
|
{
|
|
try
|
|
{
|
|
if (ToEthercat(dataType, value, out byte[] ethercatBytes))
|
|
return ethercatBytes;
|
|
|
|
} catch (Exception e)
|
|
{
|
|
Logging.Log(LogLevel.ERROR, "Exception caught while converting {0} = {1} to ethercat from native value", dataType, value);
|
|
Logging.Log(e);
|
|
}
|
|
throw new NotSupportedException(String.Format("converting {0} to {1} is currently not supported", value.GetType().Name, dataType));
|
|
}
|
|
|
|
static ECDataTypeConverter(){
|
|
AddConverter(ECDataTypes.SINT, new ECValueConverterAdapter(
|
|
typeof(sbyte),
|
|
(object value, out byte[] ethercatBytes) => { ethercatBytes = new byte[]{ (byte)(sbyte)value }; return true; },
|
|
(byte[] ethercatBytes, out object value) => { value = (sbyte)ethercatBytes[0]; return true; }
|
|
));
|
|
AddConverter(ECDataTypes.INT, new ECValueConverterAdapter(
|
|
typeof(short),
|
|
(object value, out byte[] ethercatBytes) => { ethercatBytes = BitConverter.GetBytes((short)value); return true; },
|
|
(byte[] ethercatBytes, out object value) => { value = BitConverter.ToInt16(ethercatBytes); return true; }
|
|
));
|
|
AddConverter(ECDataTypes.DINT, new ECValueConverterAdapter(
|
|
typeof(int),
|
|
(object value, out byte[] ethercatBytes) => { ethercatBytes = BitConverter.GetBytes((int)value); return true; },
|
|
(byte[] ethercatBytes, out object value) => { value = BitConverter.ToInt32(ethercatBytes); return true; }
|
|
));
|
|
AddConverter(ECDataTypes.LINT, new ECValueConverterAdapter(
|
|
typeof(long),
|
|
(object value, out byte[] ethercatBytes) => { ethercatBytes = BitConverter.GetBytes((long)value); return true; },
|
|
(byte[] ethercatBytes, out object value) => { value = BitConverter.ToInt64(ethercatBytes); return true; }
|
|
));
|
|
AddConverter(ECDataTypes.USINT, new ECValueConverterAdapter(
|
|
typeof(byte),
|
|
(object value, out byte[] ethercatBytes) => { ethercatBytes = new byte[]{ (byte)value }; return true; },
|
|
(byte[] ethercatBytes, out object value) => { value = ethercatBytes[0]; return true; }
|
|
));
|
|
AddConverter(ECDataTypes.UINT, new ECValueConverterAdapter(
|
|
typeof(ushort),
|
|
(object value, out byte[] ethercatBytes) => { ethercatBytes = BitConverter.GetBytes((ushort)value); return true; },
|
|
(byte[] ethercatBytes, out object value) => { value = BitConverter.ToUInt16(ethercatBytes); return true; }
|
|
));
|
|
AddConverter(ECDataTypes.UDINT, new ECValueConverterAdapter(
|
|
typeof(UInt32),
|
|
(object value, out byte[] ethercatBytes) => { ethercatBytes = BitConverter.GetBytes((UInt32)value); return true; },
|
|
(byte[] ethercatBytes, out object value) => { value = BitConverter.ToUInt32(ethercatBytes); return true; }
|
|
));
|
|
AddConverter(ECDataTypes.ULINT, new ECValueConverterAdapter(
|
|
typeof(UInt64),
|
|
(object value, out byte[] ethercatBytes) => { ethercatBytes = BitConverter.GetBytes((UInt64)value); return true; },
|
|
(byte[] ethercatBytes, out object value) => { value = BitConverter.ToUInt64(ethercatBytes); return true; }
|
|
));
|
|
|
|
AddConverter(ECDataTypes.REAL, new ECValueConverterAdapter(
|
|
typeof(float),
|
|
(object value, out byte[] ethercatBytes) => { ethercatBytes = BitConverter.GetBytes((float)value); return true; },
|
|
(byte[] ethercatBytes, out object value) => { value = BitConverter.ToSingle(ethercatBytes); return true; }
|
|
));
|
|
AddConverter(ECDataTypes.LREAL, new ECValueConverterAdapter(
|
|
typeof(double),
|
|
(object value, out byte[] ethercatBytes) => { ethercatBytes = BitConverter.GetBytes((double)value); return true; },
|
|
(byte[] ethercatBytes, out object value) => { value = BitConverter.ToDouble(ethercatBytes); return true; }
|
|
));
|
|
|
|
AddConverter(ECDataTypes.STRING, new ECValueConverterAdapter(
|
|
typeof(string),
|
|
(object value, out byte[] ethercatBytes) => { ethercatBytes = Encoding.ASCII.GetBytes(value.ToString()); return true; },
|
|
(byte[] ethercatBytes, out object value) => { value = Encoding.ASCII.GetString(ethercatBytes); return true; }
|
|
));
|
|
|
|
AddConverter(ECDataTypes.NONE, new ECValueConverterAdapter(
|
|
typeof(byte[]),
|
|
(object value, out byte[] ethercatBytes) => { ethercatBytes = Extensions.BytesFromHexString(value as string); return true; },
|
|
(byte[] ethercatBytes, out object value) => { value = ethercatBytes.ToHexString(); return true; }
|
|
));
|
|
|
|
|
|
|
|
}
|
|
|
|
/*
|
|
if (rawData == null)
|
|
return null;
|
|
|
|
int offset = 0;
|
|
|
|
switch (dataType)
|
|
{
|
|
case ECDataTypes.NONE:
|
|
return null;
|
|
case ECDataTypes.REAL:
|
|
return rawData.GetSingle(ref offset, Endianess.LITTLE);
|
|
case ECDataTypes.LREAL:
|
|
return rawData.GetDouble(ref offset, Endianess.LITTLE);
|
|
case ECDataTypes.STRING:
|
|
return Encoding.ASCII.GetString(rawData);
|
|
case ECDataTypes.INT:
|
|
return rawData.GetShort(ref offset, Endianess.LITTLE);
|
|
case ECDataTypes.DINT:
|
|
return rawData.GetInt(ref offset, Endianess.LITTLE);
|
|
case ECDataTypes.UINT:
|
|
return rawData.GetUShort(ref offset, Endianess.LITTLE);
|
|
case ECDataTypes.UDINT:
|
|
return rawData.GetUInt(ref offset, Endianess.LITTLE);
|
|
case ECDataTypes.USINT:
|
|
return rawData[offset];
|
|
default:
|
|
return rawData;
|
|
}
|
|
}
|
|
|
|
{
|
|
if (value is byte[] bytes)
|
|
return bytes;
|
|
|
|
switch (dataType)
|
|
{
|
|
case ECDataTypes.NONE:
|
|
return new byte[0];
|
|
case ECDataTypes.REAL:
|
|
return BitConverter.GetBytes((float)(double)value);
|
|
case ECDataTypes.LREAL:
|
|
return BitConverter.GetBytes((double)value);
|
|
case ECDataTypes.STRING:
|
|
return Encoding.ASCII.GetBytes(value.ToString());
|
|
case ECDataTypes.INT:
|
|
return BitConverter.GetBytes((short)value);
|
|
case ECDataTypes.DINT:
|
|
return BitConverter.GetBytes((int)value);
|
|
case ECDataTypes.UINT:
|
|
return BitConverter.GetBytes((ushort)value);
|
|
case ECDataTypes.UDINT:
|
|
return BitConverter.GetBytes((uint)value);
|
|
case ECDataTypes.SINT:
|
|
return BitConverter.GetBytes((byte)value);
|
|
case ECDataTypes.USINT:
|
|
return BitConverter.GetBytes((byte)value);
|
|
default:
|
|
throw new NotImplementedException();
|
|
}
|
|
}
|
|
*/
|
|
|
|
}
|
|
} |