完善 。S7 ,不在引用第三方依赖。
This commit is contained in:
parent
7e9d3ee746
commit
dc67660256
@ -88,6 +88,12 @@ public class S7DemoController {
|
|||||||
|
|
||||||
return R.ok().put("l",(l1-l)).put("c",(c2-c1));
|
return R.ok().put("l",(l1-l)).put("c",(c2-c1));
|
||||||
}
|
}
|
||||||
|
@PostMapping("/testFor1200")
|
||||||
|
public R testFor1200() throws UnsupportedEncodingException, ParseException {
|
||||||
|
Object subs = s7Service.read(PlcVarActual.INT1200, S7Client.S7_1200);
|
||||||
|
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
//demo3
|
//demo3
|
||||||
@PostMapping("/writeTest")
|
@PostMapping("/writeTest")
|
||||||
|
@ -0,0 +1,328 @@
|
|||||||
|
package com.qgs.dc.s7.my.s7connector.api.utils;
|
||||||
|
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Desc: ""
|
||||||
|
* @Author: caixiang
|
||||||
|
* @DATE: 2022/4/1 17:32
|
||||||
|
*/
|
||||||
|
//对数字和字节进行转换。 假设数据存储是以大端模式存储的:
|
||||||
|
// byte: 字节类型 占8位二进制 00000000
|
||||||
|
// char: 字符类型 占2个字节 16位二进制 byte[0] byte[1]
|
||||||
|
// int : 整数类型 占4个字节 32位二进制 byte[0] byte[1] byte[2] byte[3]
|
||||||
|
// long: 长整数类型 占8个字节 64位二进制 byte[0] byte[1] byte[2] byte[3] byte[4] byte[5]
|
||||||
|
// long: 长整数类型 占8个字节 64位二进制 byte[0] byte[1] byte[2] byte[3] byte[4] byte[5] byte[6] byte[7]
|
||||||
|
// float: 浮点数(小数) 占4个字节 32位二进制 byte[0] byte[1] byte[2] byte[3]
|
||||||
|
// double: 双精度浮点数(小数) 占8个字节 64位二进制 byte[0] byte[1] byte[2] byte[3] byte[4]byte[5] byte[6] byte[7]
|
||||||
|
|
||||||
|
public class ByteUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* int转byte
|
||||||
|
*
|
||||||
|
* @param intValue int值
|
||||||
|
* @return byte值
|
||||||
|
*/
|
||||||
|
public static byte intToByte(int intValue) {
|
||||||
|
return (byte) intValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* byte转无符号int
|
||||||
|
*
|
||||||
|
* @param byteValue byte值
|
||||||
|
* @return 无符号int值
|
||||||
|
* @since 3.2.0
|
||||||
|
*/
|
||||||
|
public static int byteToUnsignedInt(byte byteValue) {
|
||||||
|
// Java 总是把 byte 当做有符处理;我们可以通过将其和 0xFF 进行二进制与得到它的无符值
|
||||||
|
return byteValue & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* byte数组转short<br>
|
||||||
|
* 默认以小端序转换
|
||||||
|
*
|
||||||
|
* @param bytes byte数组
|
||||||
|
* @return short值
|
||||||
|
*/
|
||||||
|
public static short bytesToShort(byte[] bytes) {
|
||||||
|
return bytesToShort(bytes, ByteOrder.LITTLE_ENDIAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* byte数组转short<br>
|
||||||
|
* 自定义端序
|
||||||
|
*
|
||||||
|
* @param bytes byte数组
|
||||||
|
* @param byteOrder 端序
|
||||||
|
* @return short值
|
||||||
|
*/
|
||||||
|
public static short bytesToShort(byte[] bytes, ByteOrder byteOrder) {
|
||||||
|
if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
|
||||||
|
//小端模式,数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中
|
||||||
|
return (short) (bytes[0] & 0xff | (bytes[1] & 0xff) << Byte.SIZE);
|
||||||
|
} else {
|
||||||
|
return (short) (bytes[1] & 0xff | (bytes[0] & 0xff) << Byte.SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* short转byte数组<br>
|
||||||
|
* 默认以小端序转换
|
||||||
|
*
|
||||||
|
* @param shortValue short值
|
||||||
|
* @return byte数组
|
||||||
|
*/
|
||||||
|
public static byte[] shortToBytes(short shortValue) {
|
||||||
|
return shortToBytes(shortValue, ByteOrder.LITTLE_ENDIAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* short转byte数组<br>
|
||||||
|
* 自定义端序
|
||||||
|
*
|
||||||
|
* @param shortValue short值
|
||||||
|
* @param byteOrder 端序
|
||||||
|
* @return byte数组
|
||||||
|
*/
|
||||||
|
public static byte[] shortToBytes(short shortValue, ByteOrder byteOrder) {
|
||||||
|
byte[] b = new byte[Short.BYTES];
|
||||||
|
if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
|
||||||
|
b[0] = (byte) (shortValue & 0xff);
|
||||||
|
b[1] = (byte) ((shortValue >> Byte.SIZE) & 0xff);
|
||||||
|
} else {
|
||||||
|
b[1] = (byte) (shortValue & 0xff);
|
||||||
|
b[0] = (byte) ((shortValue >> Byte.SIZE) & 0xff);
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* byte[]转int值<br>
|
||||||
|
* 默认以小端序转换
|
||||||
|
*
|
||||||
|
* @param bytes byte数组
|
||||||
|
* @return int值
|
||||||
|
*/
|
||||||
|
public static int bytesToInt(byte[] bytes) {
|
||||||
|
return bytesToInt(bytes, ByteOrder.LITTLE_ENDIAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* byte[]转int值<br>
|
||||||
|
* 自定义端序
|
||||||
|
*
|
||||||
|
* @param bytes byte数组
|
||||||
|
* @param byteOrder 端序
|
||||||
|
* @return int值
|
||||||
|
*/
|
||||||
|
public static int bytesToInt(byte[] bytes, ByteOrder byteOrder) {
|
||||||
|
if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
|
||||||
|
return bytes[0] & 0xFF | //
|
||||||
|
(bytes[1] & 0xFF) << 8 | //
|
||||||
|
(bytes[2] & 0xFF) << 16 | //
|
||||||
|
(bytes[3] & 0xFF) << 24; //
|
||||||
|
} else {
|
||||||
|
return bytes[3] & 0xFF | //
|
||||||
|
(bytes[2] & 0xFF) << 8 | //
|
||||||
|
(bytes[1] & 0xFF) << 16 | //
|
||||||
|
(bytes[0] & 0xFF) << 24; //
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* int转byte数组<br>
|
||||||
|
* 默认以小端序转换
|
||||||
|
*
|
||||||
|
* @param intValue int值
|
||||||
|
* @return byte数组
|
||||||
|
*/
|
||||||
|
public static byte[] intToBytes(int intValue) {
|
||||||
|
return intToBytes(intValue, ByteOrder.LITTLE_ENDIAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* int转byte数组<br>
|
||||||
|
* 自定义端序
|
||||||
|
*
|
||||||
|
* @param intValue int值
|
||||||
|
* @param byteOrder 端序
|
||||||
|
* @return byte数组
|
||||||
|
*/
|
||||||
|
public static byte[] intToBytes(int intValue, ByteOrder byteOrder) {
|
||||||
|
|
||||||
|
if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
|
||||||
|
return new byte[]{ //
|
||||||
|
(byte) (intValue & 0xFF), //
|
||||||
|
(byte) ((intValue >> 8) & 0xFF), //
|
||||||
|
(byte) ((intValue >> 16) & 0xFF), //
|
||||||
|
(byte) ((intValue >> 24) & 0xFF) //
|
||||||
|
};
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return new byte[]{ //
|
||||||
|
(byte) ((intValue >> 24) & 0xFF), //
|
||||||
|
(byte) ((intValue >> 16) & 0xFF), //
|
||||||
|
(byte) ((intValue >> 8) & 0xFF), //
|
||||||
|
(byte) (intValue & 0xFF) //
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* long转byte数组<br>
|
||||||
|
* 默认以小端序转换<br>
|
||||||
|
* from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
|
||||||
|
*
|
||||||
|
* @param longValue long值
|
||||||
|
* @return byte数组
|
||||||
|
*/
|
||||||
|
public static byte[] longToBytes(long longValue) {
|
||||||
|
return longToBytes(longValue, ByteOrder.LITTLE_ENDIAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* long转byte数组<br>
|
||||||
|
* 自定义端序<br>
|
||||||
|
* from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
|
||||||
|
*
|
||||||
|
* @param longValue long值
|
||||||
|
* @param byteOrder 端序
|
||||||
|
* @return byte数组
|
||||||
|
*/
|
||||||
|
public static byte[] longToBytes(long longValue, ByteOrder byteOrder) {
|
||||||
|
byte[] result = new byte[Long.BYTES];
|
||||||
|
if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
|
||||||
|
for (int i = 0; i < result.length; i++) {
|
||||||
|
result[i] = (byte) (longValue & 0xFF);
|
||||||
|
longValue >>= Byte.SIZE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = (result.length - 1); i >= 0; i--) {
|
||||||
|
result[i] = (byte) (longValue & 0xFF);
|
||||||
|
longValue >>= Byte.SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* byte数组转long<br>
|
||||||
|
* 默认以小端序转换<br>
|
||||||
|
* from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
|
||||||
|
*
|
||||||
|
* @param bytes byte数组
|
||||||
|
* @return long值
|
||||||
|
*/
|
||||||
|
public static long bytesToLong(byte[] bytes) {
|
||||||
|
return bytesToLong(bytes, ByteOrder.LITTLE_ENDIAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* byte数组转long<br>
|
||||||
|
* 自定义端序<br>
|
||||||
|
* from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
|
||||||
|
*
|
||||||
|
* @param bytes byte数组
|
||||||
|
* @param byteOrder 端序
|
||||||
|
* @return long值
|
||||||
|
*/
|
||||||
|
public static long bytesToLong(byte[] bytes, ByteOrder byteOrder) {
|
||||||
|
long values = 0;
|
||||||
|
if (ByteOrder.LITTLE_ENDIAN == byteOrder) {
|
||||||
|
for (int i = (Long.BYTES - 1); i >= 0; i--) {
|
||||||
|
values <<= Byte.SIZE;
|
||||||
|
values |= (bytes[i] & 0xff);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < Long.BYTES; i++) {
|
||||||
|
values <<= Byte.SIZE;
|
||||||
|
values |= (bytes[i] & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* double转byte数组<br>
|
||||||
|
* 默认以小端序转换<br>
|
||||||
|
*
|
||||||
|
* @param doubleValue double值
|
||||||
|
* @return byte数组
|
||||||
|
*/
|
||||||
|
public static byte[] doubleToBytes(double doubleValue) {
|
||||||
|
return doubleToBytes(doubleValue, ByteOrder.LITTLE_ENDIAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* double转byte数组<br>
|
||||||
|
* 自定义端序<br>
|
||||||
|
* from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
|
||||||
|
*
|
||||||
|
* @param doubleValue double值
|
||||||
|
* @param byteOrder 端序
|
||||||
|
* @return byte数组
|
||||||
|
*/
|
||||||
|
public static byte[] doubleToBytes(double doubleValue, ByteOrder byteOrder) {
|
||||||
|
return longToBytes(Double.doubleToLongBits(doubleValue), byteOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* byte数组转Double<br>
|
||||||
|
* 默认以小端序转换<br>
|
||||||
|
*
|
||||||
|
* @param bytes byte数组
|
||||||
|
* @return long值
|
||||||
|
*/
|
||||||
|
public static double bytesToDouble(byte[] bytes) {
|
||||||
|
return bytesToDouble(bytes, ByteOrder.LITTLE_ENDIAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* byte数组转double<br>
|
||||||
|
* 自定义端序<br>
|
||||||
|
*
|
||||||
|
* @param bytes byte数组
|
||||||
|
* @param byteOrder 端序
|
||||||
|
* @return long值
|
||||||
|
*/
|
||||||
|
public static double bytesToDouble(byte[] bytes, ByteOrder byteOrder) {
|
||||||
|
return Double.longBitsToDouble(bytesToLong(bytes, byteOrder));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将{@link Number}转换为
|
||||||
|
*
|
||||||
|
* @param number 数字
|
||||||
|
* @return bytes
|
||||||
|
*/
|
||||||
|
public static byte[] numberToBytes(Number number) {
|
||||||
|
return numberToBytes(number, ByteOrder.LITTLE_ENDIAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将{@link Number}转换为
|
||||||
|
*
|
||||||
|
* @param number 数字
|
||||||
|
* @param byteOrder 端序
|
||||||
|
* @return bytes
|
||||||
|
*/
|
||||||
|
public static byte[] numberToBytes(Number number, ByteOrder byteOrder) {
|
||||||
|
if (number instanceof Double) {
|
||||||
|
return doubleToBytes((Double) number, byteOrder);
|
||||||
|
} else if (number instanceof Long) {
|
||||||
|
return longToBytes((Long) number, byteOrder);
|
||||||
|
} else if (number instanceof Integer) {
|
||||||
|
return intToBytes((Integer) number, byteOrder);
|
||||||
|
} else if (number instanceof Short) {
|
||||||
|
return shortToBytes((Short) number, byteOrder);
|
||||||
|
} else {
|
||||||
|
return doubleToBytes(number.doubleValue(), byteOrder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,8 +6,6 @@ package com.qgs.dc.s7.my.s7connector.api.utils;
|
|||||||
* @DATE: 2021/12/16 9:08
|
* @DATE: 2021/12/16 9:08
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import cn.hutool.core.util.ByteUtil;
|
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
@ -21,12 +21,13 @@ public enum PlcVarActual {
|
|||||||
DTL("DTL",PlcVar.DTL,1,DaveArea.DB,3,44,0),
|
DTL("DTL",PlcVar.DTL,1,DaveArea.DB,3,44,0),
|
||||||
STRING1("STRING",PlcVar.STRING,1,DaveArea.DB,3,62,0,20),
|
STRING1("STRING",PlcVar.STRING,1,DaveArea.DB,3,62,0,20),
|
||||||
SUBID0("SUBID0",PlcVar.STRING,1,DaveArea.DB,3,3270,0),
|
SUBID0("SUBID0",PlcVar.STRING,1,DaveArea.DB,3,3270,0),
|
||||||
|
INT1200("INT1200",PlcVar.INT,1,DaveArea.DB,1,2,0),
|
||||||
|
|
||||||
//数组变量
|
//数组变量
|
||||||
CharArrays("CharArrays",PlcVar.CHAR_Array,2,DaveArea.DB,3,834,0),
|
CharArrays("CharArrays",PlcVar.CHAR_Array,2,DaveArea.DB,3,834,0),
|
||||||
BooleanArrays("BooleanArrays",PlcVar.BOOL_Array,2,DaveArea.DB,3,830,0),
|
BooleanArrays("BooleanArrays",PlcVar.BOOL_Array,2,DaveArea.DB,3,830,0),
|
||||||
SubIdArrays("SubIdArrays",PlcVar.STRING_Array,60,DaveArea.DB,3,3270,0,18)
|
SubIdArrays("SubIdArrays",PlcVar.STRING_Array,60,DaveArea.DB,3,3270,0,18),
|
||||||
|
SubIdArrays1200("SubIdArrays1200",PlcVar.STRING_Array,60,DaveArea.DB,1,20,0,18)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -115,6 +115,56 @@ public class S7Service {
|
|||||||
return plcVarActual.getType().toObject(read);
|
return plcVarActual.getType().toObject(read);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public Object read(DaveArea area, Integer areaNumber, Integer byteOffset, Integer bitOffset, Integer length, Integer strSizes, PlcVar type,S7Client s7Client) throws UnsupportedEncodingException, ParseException {
|
||||||
|
S7Connector connector = s7Client.getConnector();
|
||||||
|
//String 类型比较特殊。 String[] 也是同理,Sring数组里面的子项 也是有两个字节的 readBytes。
|
||||||
|
if(type.equals(PlcVar.STRING)){
|
||||||
|
Integer readBytes = 2;
|
||||||
|
byte[] read = connector.read(
|
||||||
|
area,
|
||||||
|
areaNumber,
|
||||||
|
readBytes,
|
||||||
|
byteOffset,
|
||||||
|
bitOffset,
|
||||||
|
type.getTransportSize()
|
||||||
|
);
|
||||||
|
|
||||||
|
Integer allLength = Integer.valueOf(read[1])+2;
|
||||||
|
byte[] readF = connector.read(
|
||||||
|
area,
|
||||||
|
areaNumber,
|
||||||
|
allLength,
|
||||||
|
byteOffset,
|
||||||
|
bitOffset,
|
||||||
|
type.getTransportSize()
|
||||||
|
);
|
||||||
|
return type.toObject(readF);
|
||||||
|
}else if(type.equals(PlcVar.STRING_Array)){
|
||||||
|
Integer arrayLength = length;
|
||||||
|
Integer strSize = strSizes;
|
||||||
|
|
||||||
|
byte[] read = connector.read(
|
||||||
|
area,
|
||||||
|
areaNumber,
|
||||||
|
arrayLength*(strSize+2),
|
||||||
|
byteOffset,
|
||||||
|
bitOffset,
|
||||||
|
type.getTransportSize()
|
||||||
|
);
|
||||||
|
return ByteUtils.toStrArray(read, arrayLength, strSize);
|
||||||
|
}else {
|
||||||
|
Integer readBytes = type.getTransportSize().getSizeInBytes() * length;
|
||||||
|
byte[] read = connector.read(
|
||||||
|
area,
|
||||||
|
areaNumber,
|
||||||
|
readBytes,
|
||||||
|
byteOffset,
|
||||||
|
bitOffset,
|
||||||
|
type.getTransportSize()
|
||||||
|
);
|
||||||
|
return type.toObject(read);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -194,9 +244,41 @@ public class S7Service {
|
|||||||
plcVarActual.getType()
|
plcVarActual.getType()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
public void write(DaveArea area, Integer areaNumber, Integer byteOffset, Integer bitOffset,Integer strSize, PlcVar type, Object newValue, S7Client s7Client){
|
||||||
|
S7Connector connector = s7Client.getConnector();
|
||||||
|
|
||||||
|
//String 类型比较特殊。 String[] 也是同理,Sring数组里面的子项 也是有两个字节的 readBytes。
|
||||||
|
if(type.equals(PlcVar.STRING)){
|
||||||
|
connector.write(
|
||||||
|
area,
|
||||||
|
areaNumber,
|
||||||
|
byteOffset,
|
||||||
|
bitOffset,
|
||||||
|
ByteUtils.strToBytes(newValue.toString(), strSize),
|
||||||
|
type
|
||||||
|
);
|
||||||
|
}else if(type.equals(PlcVar.STRING_Array)){
|
||||||
|
//todo here 检查 read write service
|
||||||
|
connector.write(
|
||||||
|
area,
|
||||||
|
areaNumber,
|
||||||
|
byteOffset,
|
||||||
|
bitOffset,
|
||||||
|
ByteUtils.strArrayToBytes((String[])newValue, strSize),
|
||||||
|
type
|
||||||
|
);
|
||||||
|
}else {
|
||||||
|
byte[] bytes = type.toBytes(newValue);
|
||||||
|
connector.write(
|
||||||
|
area,
|
||||||
|
areaNumber,
|
||||||
|
byteOffset,
|
||||||
|
bitOffset,
|
||||||
|
bytes,
|
||||||
|
type
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user