wanshenmean
2026-03-24 ab2076893b8df3c14f1a126d47e9eee132a38f4b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using Microsoft.Extensions.Options;
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 StackerInteractionProtocolHandlerTests
{
    [Fact]
    public void Process_初始化时应写入固定偏移值()
    {
        var memory = BuildMemory();
        var template = BuildTemplate();
        var state = new ProtocolRuntimeState();
        var handler = BuildHandler();
 
        var changed = handler.Process(memory, template, state);
 
        Assert.True(changed);
        Assert.Equal((byte)5, memory.Read<byte>("DB1.DBB2"));
        Assert.Equal((byte)1, memory.Read<byte>("DB1.DBB4"));
        Assert.Equal((byte)1, memory.Read<byte>("DB1.DBB96"));
    }
 
    [Fact]
    public void Process_当Offset192为1时应设置Offset24和Offset4()
    {
        var memory = BuildMemory();
        var template = BuildTemplate();
        var state = new ProtocolRuntimeState();
        var handler = BuildHandler();
        memory.Write<byte>("DB1.DBB192", 1);
 
        var changed = handler.Process(memory, template, state);
 
        Assert.True(changed);
        Assert.Equal((byte)1, memory.Read<byte>("DB1.DBB24"));
        Assert.Equal((byte)2, memory.Read<byte>("DB1.DBB4"));
    }
 
    [Fact]
    public void Process_当Offset192为2时应复位Offset24和Offset4()
    {
        var memory = BuildMemory();
        var template = BuildTemplate();
        var state = new ProtocolRuntimeState();
        var handler = BuildHandler();
        memory.Write<byte>("DB1.DBB24", 9);
        memory.Write<byte>("DB1.DBB4", 9);
        memory.Write<byte>("DB1.DBB192", 2);
 
        var changed = handler.Process(memory, template, state);
 
        Assert.True(changed);
        Assert.Equal((byte)0, memory.Read<byte>("DB1.DBB24"));
        Assert.Equal((byte)1, memory.Read<byte>("DB1.DBB4"));
    }
 
    [Fact]
    public void Process_初始化只写一次_第二次调用不应覆盖运行值()
    {
        var memory = BuildMemory();
        var template = BuildTemplate();
        var state = new ProtocolRuntimeState();
        var handler = BuildHandler();
 
        var firstChanged = handler.Process(memory, template, state);
        Assert.True(firstChanged);
 
        // 模拟运行中被外部改写后的值。
        memory.Write<byte>("DB1.DBB2", 99);
        memory.Write<byte>("DB1.DBB4", 77);
        memory.Write<byte>("DB1.DBB96", 55);
 
        var secondChanged = handler.Process(memory, template, state);
 
        Assert.False(secondChanged);
        Assert.Equal((byte)99, memory.Read<byte>("DB1.DBB2"));
        Assert.Equal((byte)77, memory.Read<byte>("DB1.DBB4"));
        Assert.Equal((byte)55, memory.Read<byte>("DB1.DBB96"));
    }
 
    private static StackerInteractionProtocolHandler BuildHandler()
    {
        return new StackerInteractionProtocolHandler(
            new MirrorAckProtocolHandler(),
            Options.Create(new ProtocolMonitoringOptions()));
    }
 
    private static MemoryStore BuildMemory()
    {
        return new MemoryStore(new MemoryRegionConfig
        {
            DBBlockCount = 2,
            DBBlockSize = 512
        });
    }
 
    private static ProtocolTemplate BuildTemplate()
    {
        return new ProtocolTemplate
        {
            Id = "stacker-interaction-v1",
            Name = "STACKER_INTERACTION_V1",
            Fields = new List<ProtocolFieldMapping>
            {
                new() { FieldKey = "TRIGGER", DbNumber = 1, Offset = 192, DataType = ProtocolDataType.Byte }
            }
        };
    }
 
    [Fact]
    public void Process_按Int类型配置读写()
    {
        var memory = BuildMemory();
        var template = BuildIntTemplate();
        var state = new ProtocolRuntimeState();
        var handler = BuildHandler();
        memory.Write<short>("DB1.DBW192", 1);
 
        var changed = handler.Process(memory, template, state);
 
        Assert.True(changed);
        Assert.Equal((short)5, memory.Read<short>("DB1.DBW2"));
        Assert.Equal((short)2, memory.Read<short>("DB1.DBW4"));
        Assert.Equal((short)1, memory.Read<short>("DB1.DBW24"));
        Assert.Equal((short)1, memory.Read<short>("DB1.DBW96"));
    }
 
    private static ProtocolTemplate BuildIntTemplate()
    {
        return new ProtocolTemplate
        {
            Id = "stacker-interaction-int-v1",
            Name = "STACKER_INTERACTION_INT_V1",
            Fields = new List<ProtocolFieldMapping>
            {
                new() { FieldKey = "OFFSET2", DbNumber = 1, Offset = 2, DataType = ProtocolDataType.Int },
                new() { FieldKey = "OFFSET4", DbNumber = 1, Offset = 4, DataType = ProtocolDataType.Int },
                new() { FieldKey = "OFFSET24", DbNumber = 1, Offset = 24, DataType = ProtocolDataType.Int },
                new() { FieldKey = "OFFSET96", DbNumber = 1, Offset = 96, DataType = ProtocolDataType.Int },
                new() { FieldKey = "OFFSET192", DbNumber = 1, Offset = 192, DataType = ProtocolDataType.Int }
            }
        };
    }
}