package com.mes.connect.s7;
|
|
import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType;
|
import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
|
import com.mes.connect.IndustrialInterface.AddressParser;
|
import com.mes.connect.IndustrialInterface.IndustrialClient;
|
import com.mes.connect.addressParser.S7AddressParser;
|
import com.mes.connect.addressParser.S7OldAddressParser;
|
import com.mes.connect.protocol.ProtocolAddress;
|
import lombok.extern.slf4j.Slf4j;
|
|
import java.io.DataInputStream;
|
import java.io.DataOutputStream;
|
import java.io.IOException;
|
import java.net.Socket;
|
import java.util.Random;
|
import java.util.logging.Logger;
|
|
/**
|
* S7协议客户端实现
|
*/
|
@Slf4j
|
public class S7ClientOld implements IndustrialClient {
|
private static final Logger logger = Logger.getLogger(S7ClientOld.class.getName());
|
private final String host;
|
private final int port;
|
private final int rack;
|
private final int slot;
|
private boolean connected;
|
private S7PLC s7PLC;
|
private final AddressParser addressParser = new S7OldAddressParser();
|
private EPlcType ePlcType;
|
|
public S7ClientOld(String plcType,String host, int port, int rack, int slot) {
|
this.host = host;
|
this.port = port;
|
this.rack = rack;
|
this.slot = slot;
|
switch (plcType) {
|
case "S200_SMART":
|
ePlcType=EPlcType.S200_SMART;
|
break;
|
case "S200":
|
ePlcType=EPlcType.S200;
|
break;
|
case "S300":
|
ePlcType=EPlcType.S300;
|
break;
|
case "S400":
|
ePlcType=EPlcType.S400;
|
break;
|
case "S1200":
|
ePlcType=EPlcType.S1200;
|
break;
|
case "S1500":
|
ePlcType=EPlcType.S1500;
|
break;
|
default:
|
throw new IllegalArgumentException("无效的西门子PLC类型: " + plcType);
|
}
|
}
|
|
@Override
|
public synchronized void connect() throws IOException {
|
if (!connected) {
|
this.s7PLC = new S7PLC(this.ePlcType, this.host, port, rack, slot);
|
connected = true;
|
logger.info("Connected to S7 server: " + host + ":" + port);
|
}
|
}
|
|
@Override
|
public synchronized void disconnect() {
|
if (connected) {
|
this.s7PLC.close();
|
}
|
}
|
|
@Override
|
public boolean isConnected() {
|
return this.connected;
|
}
|
|
@Override
|
public boolean readBit(String address) throws IOException {
|
ProtocolAddress parsedAddress = addressParser.parse(address);
|
int dbNumber = parsedAddress.getDbNumber();
|
int area = parsedAddress.getFunctionCode();
|
int startAddress = parsedAddress.getAddress();
|
int bit = parsedAddress.getBit();
|
return this.s7PLC.readBoolean(getAddress(parsedAddress));
|
}
|
|
@Override
|
public void writeBit(String address, boolean value) throws IOException {
|
ProtocolAddress parsedAddress = addressParser.parse(address);
|
int dbNumber = parsedAddress.getDbNumber();
|
int area = parsedAddress.getFunctionCode();
|
int startAddress = parsedAddress.getAddress();
|
int bit = parsedAddress.getBit();
|
this.s7PLC.writeBoolean(getAddress(parsedAddress),value);
|
}
|
|
@Override
|
public int readRegister(String address) throws IOException {
|
ProtocolAddress parsedAddress = addressParser.parse(address);
|
return this.s7PLC.readUInt16(getAddress(parsedAddress));
|
}
|
|
@Override
|
public void writeRegister(String address, int value) throws IOException {
|
ProtocolAddress parsedAddress = addressParser.parse(address);
|
this.s7PLC.writeUInt16(getAddress(parsedAddress),value);
|
}
|
|
@Override
|
public int[] readRegisters(String address, int quantity) throws IOException {
|
ProtocolAddress parsedAddress = addressParser.parse(address);
|
int dbNumber = parsedAddress.getDbNumber();
|
int area = parsedAddress.getFunctionCode();
|
int startAddress = parsedAddress.getAddress();
|
// 计算需要读取的字节数 (每个UInt16占用2字节)
|
int byteCount = quantity * 2;
|
// 读取字节数组
|
byte[] bytes = this.s7PLC.readByte(getAddress(parsedAddress), byteCount);
|
// 将字节转换为无符号整数数组
|
int[] result = new int[quantity];
|
for (int i = 0; i < quantity; i++) {
|
int index = i * 2;
|
// 组合两个字节为一个无符号16位整数
|
result[i] = ((bytes[index] & 0xFF) << 8) | (bytes[index + 1] & 0xFF);
|
}
|
return result;
|
}
|
|
@Override
|
public void writeRegisters(String address, int[] values) throws IOException {
|
ProtocolAddress parsedAddress = addressParser.parse(address);
|
int dbNumber = parsedAddress.getDbNumber();
|
int area = parsedAddress.getFunctionCode();
|
int startAddress = parsedAddress.getAddress();
|
// 转换整数数组为字节数组
|
byte[] bytes = new byte[values.length * 2];
|
for (int i = 0; i < values.length; i++) {
|
int index = i * 2;
|
// 将整数拆分为两个字节
|
bytes[index] = (byte) ((values[i] >> 8) & 0xFF);
|
bytes[index + 1] = (byte) (values[i] & 0xFF);
|
}
|
this.s7PLC.writeByte(getAddress(parsedAddress),bytes);
|
}
|
@Override
|
public float readFloat(String address) throws IOException {
|
int[] registers = readRegisters(address, 2);
|
int intBits = (registers[0] << 16) | registers[1];
|
return Float.intBitsToFloat(intBits);
|
}
|
@Override
|
public void writeFloat(String address, float value) throws IOException {
|
int intBits = Float.floatToIntBits(value);
|
int highWord = (intBits >> 16) & 0xFFFF;
|
int lowWord = intBits & 0xFFFF;
|
writeRegisters(address, new int[]{highWord, lowWord});
|
}
|
|
@Override
|
public String readString(String address, int length) throws IOException {
|
ProtocolAddress parsedAddress = addressParser.parse(address);
|
return this.s7PLC.readString(getAddress(parsedAddress));
|
}
|
|
@Override
|
public void writeString(String address, String value) throws IOException {
|
ProtocolAddress parsedAddress = addressParser.parse(address);
|
this.s7PLC.writeString(getAddress(parsedAddress),value);
|
}
|
|
@Override
|
public void close() throws IOException {
|
disconnect();
|
}
|
private String getAddress(ProtocolAddress parsedAddress){
|
return "DB"+parsedAddress.getDbNumber()+"."+parsedAddress.getAddress();
|
}
|
}
|