using MECF.Framework.Common.Net;
using MECF.Framework.Simulator.Core.Driver;
using System;
using System.Collections.Generic;
namespace CyberX8_Simulator.Devices
{
public class FestoSocketSimulator : SocketDeviceSimulator
{
//Write Address
private const ushort MODULE_0_OUTPUT_DATA_ADDRESS = 0x9C42;//FB36(16bit)
private const ushort MODULE_1_OUTPUT_DATA_ADDRESS = 0x9C43;//MPA1气动模块(8bit,x 6 x 4 x 2 x 0)
private const ushort MODULE_2_OUTPUT_DATA_ADDRESS = 0x9C44;//MPA1气动模块(8bit,7 ... 0)
private const ushort MODULE_3_OUTPUT_DATA_ADDRESS = 0x9C45;//MPA1气动模块(8bit,3 ... 0)
//Read Address
private const ushort MODULE_0_ECHO_OUTPUT_DATA_ADDRESS = 0xB151;//FB36(16bit)
private const ushort MODULE_1_ECHO_OUTPUT_DATA_ADDRESS = 0xB153;//MPA1气动模块(8bit)
private const ushort MODULE_2_ECHO_OUTPUT_DATA_ADDRESS = 0xB155;//MPA1气动模块(8bit)
private const ushort MODULE_3_ECHO_OUTPUT_DATA_ADDRESS = 0xB157;//MPA1气动模块(8bit)
private IByteTransform byteTransform = new BigEndianByteTransformBase();
///
/// 数据字典
///
Dictionary _festoOutputDataDic = new Dictionary();
///
/// 构造函数
///
///
public FestoSocketSimulator(int port) : base(port)
{
_festoOutputDataDic[0] = 0x00;//Module0
_festoOutputDataDic[1] = 0x00;//Module1 (6 x 4 x 2 x 0)
_festoOutputDataDic[2] = 0x00;//Mdoule2 (7 ... 0)
_festoOutputDataDic[3] = 0x00;//Module3 (3 ... 0)
}
///
/// 解析信息
///
///
protected override void ProcessUnsplitMessage(byte[] data)
{
short flag = byteTransform.TransInt16(data, 0);//事务标识符
byte channel = data[6];//单元标识符
byte command = data[7];//功能码
if (command == 0x03)//读取
{
ushort startAddress = byteTransform.TransUInt16(data, 8);//起始寄存器地址
short registerCount = byteTransform.TransInt16(data, 10);//寄存器数量
byte[] bytes = new byte[2 * registerCount];//读取2 Byte数据
switch (startAddress)
{
case MODULE_0_OUTPUT_DATA_ADDRESS:
for(int i = 0; i < registerCount; i++)
{
Array.Copy(byteTransform.GetBytes(_festoOutputDataDic[0]), 0, bytes, i*2, 2);
}
break;
case MODULE_1_OUTPUT_DATA_ADDRESS:
for (int i = 0; i < registerCount; i++)
{
Array.Copy(byteTransform.GetBytes(_festoOutputDataDic[1]), 0, bytes, i*2, 2);
}
break;
case MODULE_2_OUTPUT_DATA_ADDRESS:
Array.Copy(byteTransform.GetBytes(_festoOutputDataDic[2]), 0, bytes, 0, 2);
break;
case MODULE_3_OUTPUT_DATA_ADDRESS:
Array.Copy(byteTransform.GetBytes(_festoOutputDataDic[3]), 0, bytes, 0, 2);
break;
default:
break;
}
OnWriteMessage(CreateReadResponse(flag, channel, command, registerCount, bytes));
}
else if(command == 0x06)//写入
{
ushort startAddress = byteTransform.TransUInt16(data, 8);//起始寄存器地址
short value = byteTransform.TransInt16(data, 10);//写入的值(2 Byte)
switch (startAddress)
{
case MODULE_0_ECHO_OUTPUT_DATA_ADDRESS:
_festoOutputDataDic[0] = value;
break;
case MODULE_1_ECHO_OUTPUT_DATA_ADDRESS:
_festoOutputDataDic[1] = value;
break;
case MODULE_2_ECHO_OUTPUT_DATA_ADDRESS:
_festoOutputDataDic[2] = value;
break;
case MODULE_3_ECHO_OUTPUT_DATA_ADDRESS:
_festoOutputDataDic[3] = value;
break;
default:
break;
}
OnWriteMessage(CreateWriteResponse(flag, channel, command, startAddress, value));
}
else
{
OnWriteMessage(CreateError(flag, channel, command, 0x84));
}
}
///
/// 读回复
///
///
///
///
///
///
///
private byte[] CreateReadResponse(short flag, byte channel, byte command, short registerCount, byte[] values)
{
byte[] bytes = new byte[6 + 3 + values.Length];
Array.Copy(byteTransform.GetBytes(flag), 0, bytes, 0, 2);
bytes[2] = 0x00;
bytes[3] = 0x00;
short dataLength = (short)(3 + values.Length);
Array.Copy(byteTransform.GetBytes(dataLength), 0, bytes, 4, 2);
bytes[6] = channel;
bytes[7] = command;
bytes[8] = (byte)(2 * registerCount);
Array.Copy(values, 0, bytes, 9, values.Length);
return bytes;
}
///
/// 写回复
///
///
///
///
///
///
///
private byte[] CreateWriteResponse(short flag, byte channel, byte command, ushort startAddress, short value)
{
byte[] bytes = new byte[12];
Array.Copy(byteTransform.GetBytes(flag), 0, bytes, 0, 2);
bytes[2] = 0x00;
bytes[3] = 0x00;
bytes[4] = 0x00;
bytes[5] = 0x06;
bytes[6] = channel;
bytes[7] = command;
byte[] addressByt = byteTransform.GetBytes(startAddress);
Array.Copy(addressByt, 0, bytes, 8, 2);
byte[] valueByt = byteTransform.GetBytes(value);
Array.Copy(valueByt, 0, bytes, 10, 2);
return bytes;
}
///
/// 多重写回复
///
///
///
///
///
///
///
private byte[] CreateMultiWriteResponse(short flag, byte channel, byte command, short startAddress, short count)
{
byte[] byt = new byte[1];
return byt;
}
///
/// 错误回复
///
///
///
///
///
///
private byte[] CreateError(short flag, byte channel, byte command, byte error)
{
byte[] bytes = new byte[9];
Array.Copy(byteTransform.GetBytes(flag), 0, bytes, 0, 2);
bytes[2] = 0x00;
bytes[3] = 0x00;
bytes[4] = 0x00;
bytes[5] = 0x03;
bytes[6] = channel;
bytes[7] = (byte)(command | 0x80);
bytes[8] = error;
return bytes;
}
}
}