using WIDESEAWCS_S7Simulator.Application.Protocol;
|
using WIDESEAWCS_S7Simulator.Core.Entities;
|
using WIDESEAWCS_S7Simulator.Core.Memory;
|
using WIDESEAWCS_S7Simulator.Core.Protocol;
|
|
namespace WIDESEAWCS_S7Simulator.UnitTests.Protocol;
|
|
public class MirrorAckProtocolHandlerTests
|
{
|
[Fact]
|
public void Process_WhenAckIsOne_MirrorsConfiguredFieldsAndResetsStb()
|
{
|
var memory = BuildMemory();
|
var template = BuildTemplate();
|
var state = new ProtocolRuntimeState();
|
var rule = BuildRule();
|
var handler = new MirrorAckProtocolHandler();
|
|
memory.Write<byte>("DB1.DBB0", 1); // WCS 确认位
|
memory.Write<int>("DB1.DBD2", 123456); // WCS 任务号
|
memory.Write<short>("DB1.DBW6", 88); // WCS 目标位
|
memory.Write<byte>("DB1.DBB10", 1); // PLC 状态位
|
|
var changed = handler.Process(memory, template, state, rule);
|
|
Assert.True(changed);
|
Assert.Equal(123456, memory.Read<int>("DB1.DBD20"));
|
Assert.Equal((short)88, memory.Read<short>("DB1.DBW24"));
|
Assert.Equal((byte)0, memory.Read<byte>("DB1.DBB10"));
|
}
|
|
[Fact]
|
public void Process_WhenAckIsTwo_ClearsConfiguredFields()
|
{
|
var memory = BuildMemory();
|
var template = BuildTemplate();
|
var state = new ProtocolRuntimeState();
|
var rule = BuildRule();
|
var handler = new MirrorAckProtocolHandler();
|
|
memory.Write<byte>("DB1.DBB0", 2); // WCS 确认位
|
memory.Write<int>("DB1.DBD20", 1); // PLC 任务号
|
memory.Write<short>("DB1.DBW24", 2); // PLC 目标位
|
memory.Write<byte>("DB1.DBB30", 3); // 托盘号
|
memory.Write<byte>("DB1.DBB10", 1); // PLC 状态位
|
|
var changed = handler.Process(memory, template, state, rule);
|
|
Assert.True(changed);
|
Assert.Equal(0, memory.Read<int>("DB1.DBD20"));
|
Assert.Equal((short)0, memory.Read<short>("DB1.DBW24"));
|
Assert.Equal((byte)0, memory.Read<byte>("DB1.DBB30"));
|
Assert.Equal((byte)0, memory.Read<byte>("DB1.DBB10"));
|
}
|
|
[Fact]
|
public void Process_不同段状态键_相同Ack也可分别处理()
|
{
|
var memory = BuildMemory();
|
var template = BuildTemplate();
|
var state = new ProtocolRuntimeState();
|
var rule = BuildRule();
|
var handler = new MirrorAckProtocolHandler();
|
|
memory.Write<byte>("DB1.DBB0", 1); // WCS 确认位
|
memory.Write<int>("DB1.DBD2", 1001); // WCS 任务号
|
memory.Write<short>("DB1.DBW6", 11); // WCS 目标位
|
memory.Write<byte>("DB1.DBB10", 1); // PLC 状态位
|
|
var changedSeg1 = handler.Process(memory, template, state, rule, "WcsLineProtocol:SEG1");
|
|
// 保持 ACK 不变,改写目标值,模拟另一段线体处理。
|
memory.Write<int>("DB1.DBD2", 2002);
|
memory.Write<short>("DB1.DBW6", 22);
|
var changedSeg2 = handler.Process(memory, template, state, rule, "WcsLineProtocol:SEG2");
|
|
Assert.True(changedSeg1);
|
Assert.True(changedSeg2);
|
Assert.Equal(2002, memory.Read<int>("DB1.DBD20"));
|
Assert.Equal((short)22, memory.Read<short>("DB1.DBW24"));
|
}
|
|
private static MemoryStore BuildMemory()
|
{
|
return new MemoryStore(new MemoryRegionConfig
|
{
|
DBBlockCount = 2,
|
DBBlockSize = 256
|
});
|
}
|
|
private static ProtocolTemplate BuildTemplate()
|
{
|
return new ProtocolTemplate
|
{
|
Id = "wcs-line-v1",
|
Name = "WCS_LINE_V1",
|
Fields = new List<ProtocolFieldMapping>
|
{
|
new() { FieldKey = "WCS_ACK", DbNumber = 1, Offset = 0, DataType = ProtocolDataType.Byte },
|
new() { FieldKey = "WCS_TASK_ID", DbNumber = 1, Offset = 2, DataType = ProtocolDataType.DInt },
|
new() { FieldKey = "WCS_TARGET_ID", DbNumber = 1, Offset = 6, DataType = ProtocolDataType.Int },
|
new() { FieldKey = "PLC_STB", DbNumber = 1, Offset = 10, DataType = ProtocolDataType.Byte },
|
new() { FieldKey = "PLC_TASK_ID", DbNumber = 1, Offset = 20, DataType = ProtocolDataType.DInt },
|
new() { FieldKey = "PLC_TARGET_ID", DbNumber = 1, Offset = 24, DataType = ProtocolDataType.Int },
|
new() { FieldKey = "PALLET_CODE", DbNumber = 1, Offset = 30, DataType = ProtocolDataType.Byte }
|
}
|
};
|
}
|
|
private static MirrorAckRuleOptions BuildRule()
|
{
|
return new MirrorAckRuleOptions
|
{
|
RuleId = "line-default",
|
WcsAckFieldKey = "WCS_ACK",
|
PlcStbFieldKey = "PLC_STB",
|
WcsTaskIdFieldKey = "WCS_TASK_ID",
|
PlcTaskIdFieldKey = "PLC_TASK_ID",
|
WcsTargetIdFieldKey = "WCS_TARGET_ID",
|
PlcTargetIdFieldKey = "PLC_TARGET_ID",
|
ClearFieldKeysOnAck0 = new List<string> { "PLC_TASK_ID", "PLC_TARGET_ID", "PALLET_CODE" },
|
ClearFieldKeysOnAck2 = new List<string> { "PLC_TASK_ID", "PLC_TARGET_ID", "PALLET_CODE" }
|
};
|
}
|
}
|