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
package com.mes.connect.addressparser;
 
import com.mes.connect.industrialinterface.AddressParser;
import com.mes.connect.protocol.ProtocolAddress;
import com.mes.connect.protocol.ProtocolType;
 
/**
 * S7地址解析器
 *
 * @author yzx
 * @version 1.0
 */
public class S7OldAddressParser implements AddressParser {
    /**
     * modbusTcp协议
     */
    private final String protocolS7 = "S7";
    /**
     * 字符串截取
     */
    private final String protocolS7_ = "S7.";
    /**
     * 地址类型
     */
    private final String addressTypeDB = "DB";
    /**
     * 地址类型
     */
    private final String addressTypeX = "X";
    /**
     * 地址类型
     */
    private final String addressTypeI = "I";
    /**
     * 地址类型
     */
    private final String addressTypeQ = "Q";
    /**
     * 地址类型
     */
    private final String addressTypeM = "M";
 
    /**
     * 地址值类型
     */
    private final String valueTypeDBW = "DBW";
 
    /**
     * 地址值类型
     */
    private final String valueTypeDBX = "DBX";
 
    /**
     * 地址值类型
     */
    private final String valueTypeDBD = "DBD";
 
    /**
     * 离散输入
     */
    private final int functionCode0x84 = 0x84;
    /**
     * 读写功能码
     */
    private final int functionCode4 = 4;
 
    @Override
    public ProtocolAddress parse(String address) {
        // 格式示例: "S7.DB1.DBX10.2" 或 "S7.M100"
        //位地址:S7.DB1.DBX0.0 (DB1 块中的字节 0 的位 0)
        //字节地址:S7.DB1.DBB0 (DB1 块中的字节 0)
        //字地址:S7.DB1.DBW0 (DB1 块中的字 0)
        //双字地址:S7.DB1.DBD0 (DB1 块中的双字 0)
        if (!address.startsWith(protocolS7_)) {
            throw new IllegalArgumentException("Invalid S7 address format: " + address);
        }
 
        String[] parts = address.substring(3).split("\\.");
        // parts =地址类型  字节长度>2
        if (parts.length < 2) {
            throw new IllegalArgumentException("Invalid S7 address format: " + address);
        }
 
        // 解析DB号
        int dbNumber = 0;
        // 默认DB区域
        int area = 0x84;
        if (parts[0].startsWith(addressTypeDB)) {
            dbNumber = Integer.parseInt(parts[0].substring(2));
        } else if (addressTypeI.equals(parts[0])) {
            // 输入区域
            area = 0x81;
        } else if (addressTypeQ.equals(parts[0])) {
            // 输出区域
            area = 0x82;
        } else if (addressTypeM.equals(parts[0])) {
            // 内存区域
            area = 0x83;
        } else {
            throw new IllegalArgumentException("Invalid S7 area: " + parts[0]);
        }
 
        // 解析地址类型和地址值
        String addressPart = parts[1];
        int addressValue = 0;
        int bit = 0;
 
        if (area == functionCode0x84) {
            // DB区域
            if (addressPart.startsWith(valueTypeDBX)) {
                // 位地址
                String[] bitParts = addressPart.substring(3).split("\\.");
                addressValue = Integer.parseInt(bitParts[0]);
                if (bitParts.length > 1) {
                    bit = Integer.parseInt(bitParts[1]);
                }
            } else if (addressPart.startsWith(valueTypeDBW)) {
                // 字地址
                addressValue = Integer.parseInt(addressPart.substring(3));
            } else if (addressPart.startsWith(valueTypeDBD)) {
                // 双字地址
                addressValue = Integer.parseInt(addressPart.substring(3));
            } else {
                throw new IllegalArgumentException("Invalid S7 DB address type: " + addressPart);
            }
        } else {
            // I/Q/M区域
            if (addressPart.startsWith(addressTypeX)) {
                // 位地址
                String[] bitParts = addressPart.substring(1).split("\\.");
                addressValue = Integer.parseInt(bitParts[0]);
                if (bitParts.length > 1) {
                    bit = Integer.parseInt(bitParts[1]);
                }
            } else {
                // 字地址
                addressValue = Integer.parseInt(addressPart);
            }
        }
 
        return new ProtocolAddress(ProtocolType.S7, area, dbNumber, addressValue, bit);
    }
 
}