完善 。S7 String、String[] 类型

This commit is contained in:
caixiang 2022-03-31 15:01:56 +08:00
parent aa38946d02
commit 7e9d3ee746
10 changed files with 338 additions and 47 deletions

View File

@ -39,6 +39,8 @@ public class PID00BReceived {
private static final Logger logger = LoggerFactory.getLogger(PID00BReceived.class); private static final Logger logger = LoggerFactory.getLogger(PID00BReceived.class);
@Autowired @Autowired
MQMessageHandler mqMessageHandler; MQMessageHandler mqMessageHandler;

View File

@ -1,10 +1,13 @@
package com.qgs.dc.mq.entity; package com.qgs.dc.mq.entity;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.annotation.JSONType; import com.alibaba.fastjson.annotation.JSONType;
import com.qgs.dc.mq.entity.common.Header; import com.qgs.dc.mq.entity.common.Header;
import com.qgs.dc.mq.entity.common.Returns; import com.qgs.dc.mq.entity.common.Returns;
import lombok.Data; import lombok.Data;
import java.util.HashMap;
/** /**
* @Desc: "" * @Desc: ""
* @Author: caixiang * @Author: caixiang

View File

@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.*;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.text.ParseException; import java.text.ParseException;
import java.util.List; import java.util.List;
import java.util.Random;
@RestController @RestController
@RequestMapping("/s7") @RequestMapping("/s7")
@ -27,7 +28,7 @@ public class S7DemoController {
@PostMapping("/testReadAll") @PostMapping("/testReadAll")
public R testReadAll() throws UnsupportedEncodingException, ParseException { public R testReadAll() throws UnsupportedEncodingException, ParseException {
for(PlcVarActual actual:PlcVarActual.values()){ for(PlcVarActual actual:PlcVarActual.values()){
System.out.println(s7Service.read(actual,S7Client.S7_1200));; System.out.println(s7Service.read(actual,S7Client.S7_1500));;
} }
return R.ok(); return R.ok();
} }
@ -35,34 +36,77 @@ public class S7DemoController {
//demo2 //demo2
@PostMapping("/readTest") @PostMapping("/readTest")
public R getTestForS7() throws UnsupportedEncodingException, ParseException { public R getTestForS7() throws UnsupportedEncodingException, ParseException {
Boolean heartBeat = (Boolean)s7Service.read(PlcVarActual.HeartBeat,S7Client.S7_1200); Boolean heartBeat = (Boolean)s7Service.read(PlcVarActual.HeartBeat,S7Client.S7_1500);
String ddtl = (String)s7Service.read(PlcVarActual.DTL,S7Client.S7_1200); String ddtl = (String)s7Service.read(PlcVarActual.DTL,S7Client.S7_1500);
List<Character> characters = (List<Character>)s7Service.read(PlcVarActual.CharArrays,S7Client.S7_1200); List<Character> characters = (List<Character>)s7Service.read(PlcVarActual.CharArrays,S7Client.S7_1500);
List<Boolean> booleans = (List<Boolean>)s7Service.read(PlcVarActual.BooleanArrays,S7Client.S7_1200); List<Boolean> booleans = (List<Boolean>)s7Service.read(PlcVarActual.BooleanArrays,S7Client.S7_1500);
String stri = (String)s7Service.read(PlcVarActual.STRING1,S7Client.S7_1200); String stri = (String)s7Service.read(PlcVarActual.STRING1,S7Client.S7_1500);
return R.ok().put("res",heartBeat).put("characters",characters).put("ddtl",ddtl).put("bools",booleans).put("str",stri); return R.ok().put("res",heartBeat).put("characters",characters).put("ddtl",ddtl).put("bools",booleans).put("str",stri);
} }
@PostMapping("/readTest2")
public R getTest2ForS7() throws UnsupportedEncodingException, ParseException {
// List<Character> characters = (List<Character>)s7Service.read(PlcVarActual.CharArrays,S7Client.S7_1500);
//
// List<Boolean> booleans = (List<Boolean>)s7Service.read(PlcVarActual.BooleanArrays,S7Client.S7_1500);
// String stri = (String)s7Service.read(PlcVarActual.STRING1,S7Client.S7_1500);
//
// return R.ok().put("res",heartBeat).put("characters",characters).put("ddtl",ddtl).put("bools",booleans).put("str",stri);
String con = "1233ADSDA";
s7Service.write(PlcVarActual.STRING1, con, S7Client.S7_1500);
String read = (String)s7Service.read(PlcVarActual.STRING1, S7Client.S7_1500);
String sub0 = (String)s7Service.read(PlcVarActual.SUBID0, S7Client.S7_1500);
return R.ok().put("str",read).put("sub0",sub0);
}
@PostMapping("/testForString")
public R testForStrings() throws UnsupportedEncodingException, ParseException {
//测试结果 l => 66ms
long l = System.currentTimeMillis();
String string = (String)s7Service.read(PlcVarActual.STRING1, S7Client.S7_1500);
String[] subs = (String[])s7Service.read(PlcVarActual.SubIdArrays, S7Client.S7_1500);
long l1 = System.currentTimeMillis();
String[] toWrite = new String[60];
for(int i=0;i<60;i++){
int i1 = new Random().nextInt(100);
toWrite[i] = "3011001210530111"+ i1;
}
////测试结果 c => 57ms
long c1 = System.currentTimeMillis();
s7Service.write(PlcVarActual.SubIdArrays,toWrite,S7Client.S7_1500);
long c2 = System.currentTimeMillis();
String s = "cai xiang";
s7Service.write(PlcVarActual.STRING1,s,S7Client.S7_1500);
String string2 = (String)s7Service.read(PlcVarActual.STRING1, S7Client.S7_1500);
String[] subs2 = (String[])s7Service.read(PlcVarActual.SubIdArrays, S7Client.S7_1500);
return R.ok().put("l",(l1-l)).put("c",(c2-c1));
}
//demo3 //demo3
@PostMapping("/writeTest") @PostMapping("/writeTest")
public R writeTest() throws PlcConnectionException, UnsupportedEncodingException { public R writeTest() throws PlcConnectionException, UnsupportedEncodingException {
s7Service.write(PlcVarActual.HeartBeat, false, S7Client.S7_1200); s7Service.write(PlcVarActual.HeartBeat, false, S7Client.S7_1500);
char[] charArrays_content = new char[2]; char[] charArrays_content = new char[2];
charArrays_content[0] = '1'; charArrays_content[0] = '1';
charArrays_content[1] = 'c'; charArrays_content[1] = 'c';
s7Service.write(PlcVarActual.CharArrays, charArrays_content, S7Client.S7_1200); s7Service.write(PlcVarActual.CharArrays, charArrays_content, S7Client.S7_1500);
boolean[] boolArrays_content = new boolean[2]; boolean[] boolArrays_content = new boolean[2];
boolArrays_content[0] = true; boolArrays_content[0] = true;
boolArrays_content[1] = false; boolArrays_content[1] = false;
s7Service.write(PlcVarActual.BooleanArrays, boolArrays_content, S7Client.S7_1200); s7Service.write(PlcVarActual.BooleanArrays, boolArrays_content, S7Client.S7_1500);
String str = "你好啊aa"; String str = "你好啊aa";
//todo string 的读写有问题 待会看看 //todo string 的读写有问题 待会看看
s7Service.write(PlcVarActual.STRING1, str, S7Client.S7_1200); s7Service.write(PlcVarActual.STRING1, str, S7Client.S7_1500);
return R.ok().put("res",true); return R.ok().put("res",true);
} }

View File

@ -2,7 +2,6 @@ package com.qgs.dc.s7.my.s7connector;
import com.qgs.dc.s7.my.s7connector.api.DaveArea; import com.qgs.dc.s7.my.s7connector.api.DaveArea;
import com.qgs.dc.s7.my.s7connector.api.S7Connector; import com.qgs.dc.s7.my.s7connector.api.S7Connector;
import com.qgs.dc.s7.my.s7connector.api.factory.S7ConnectorFactory;
import com.qgs.dc.s7.my.s7connector.api.utils.ByteUtils; import com.qgs.dc.s7.my.s7connector.api.utils.ByteUtils;
import com.qgs.dc.s7.my.s7connector.enmuc.S7Client; import com.qgs.dc.s7.my.s7connector.enmuc.S7Client;
@ -28,7 +27,7 @@ public class MainForRead {
// .withSlot(0) //optional slot 是插槽号 // .withSlot(0) //optional slot 是插槽号
// .build(); // .build();
S7Connector connector = S7Client.S7_1200.getConnector(); S7Connector connector = S7Client.S7_1500.getConnector();
// // [0] // // [0]

View File

@ -0,0 +1,75 @@
package com.qgs.dc.s7.my.s7connector;
import com.qgs.dc.s7.my.s7connector.api.DaveArea;
import com.qgs.dc.s7.my.s7connector.api.S7Connector;
import com.qgs.dc.s7.my.s7connector.api.utils.ByteUtils;
import com.qgs.dc.s7.my.s7connector.enmuc.S7Client;
import com.qgs.dc.s7.my.s7connector.type.PlcVar;
import java.io.UnsupportedEncodingException;
import java.util.List;
/**
* @Desc: ""
* @Author: caixiang
* @DATE: 2021/12/10 10:17
*/
public class MainForReadDemo {
public static void main(String[] args) throws UnsupportedEncodingException {
// //1200 部分
// S7Connector connector1200 = S7Client.S7_1200.getConnector();
//
// byte[] bool3_1200 = connector1200.read(DaveArea.DB, 1, 1, 0);
// System.out.println("DB1-bool3_1200 : " + ByteUtils.toBoolean(bool3_1200));
//// byte[] bool4_1200 = connector1200.read(DaveArea.DB, 3, 1, 3267,5,PlcVar.BOOL.getTransportSize());
//// System.out.println("DB1-bool4_1200 : " + ByteUtils.toBoolean(bool4_1200));
//1500 部分
S7Connector connector1500 = S7Client.S7_1500.getConnector();
// byte[] bool11 = connector1500.read(DaveArea.DB, 3, 1, 3267);
// //30110012105301115
// //[18, 17, 51, 48, 49, 49, 48, 48, 49, 50, 49, 48, 53, 51, 48, 49, 49, 49, 53, 0]
// // 3 0
// byte[] str1500 = connector1500.read(DaveArea.DB, 3, 20, 3270);
// byte[] str15001 = connector1500.read(DaveArea.DB, 3, 20, 3290);
// byte[] bool1 = connector1500.read(DaveArea.DB, 3, 1, 3267,4, PlcVar.BOOL.getTransportSize());
// String str1500s = ByteUtils.toStr(str1500);
// System.out.println("DB3.0-str1500 : " + str1500s);
// System.out.println("DB3.0-bool1 : " + ByteUtils.toBoolean(bool1));
//String
//write
String one = "12111";
byte[] bytes1 = ByteUtils.strToBytes(one, 18);
connector1500.write(DaveArea.DB,3,3270,bytes1);
//read
byte[] str_1500 = connector1500.read(DaveArea.DB, 3, 20, 3270);
String string = ByteUtils.toStr(str_1500);
System.out.println(string);
//StringArray
//write
String[] src = new String[3];
src[0]= "1";
src[1]= "30110012105301117222";
src[2]= "3";
byte[] bytes = ByteUtils.strArrayToBytes(src, 18);
connector1500.write(DaveArea.DB,3,3270,bytes);
//read
byte[] strList_1500 = connector1500.read(DaveArea.DB, 3, 60, 3270);
String[] strings = ByteUtils.toStrArray(strList_1500, 3, 18);
System.out.println(strings);
}
}

View File

@ -208,6 +208,16 @@ public class ByteUtils {
// String s = new String(content); // String s = new String(content);
return ascii; return ascii;
} }
public static String[] toStrArray(byte[] b,Integer length,Integer strSize) throws UnsupportedEncodingException {
String[] res = new String[length];
strSize+=2;
for(int i=0;i<length;i++){
byte[] one = new byte[strSize];
System.arraycopy(b,i*strSize,one,0,strSize);
res[i] = toStr(one);
}
return res;
}
public static List<Boolean> toBoolArray(byte[] b) throws UnsupportedEncodingException { public static List<Boolean> toBoolArray(byte[] b) throws UnsupportedEncodingException {
List<Boolean> res = new ArrayList<>(); List<Boolean> res = new ArrayList<>();
@ -653,6 +663,10 @@ public class ByteUtils {
return charToByte(c); return charToByte(c);
} }
//如果plc中没有设置 strSize,那么 这个字符串变量的 最大长度默认是 254字节就是-2
/**
* 这个函数就用于 非str类型转bytes使用string类型转bytes 用strToBytes(String s,Integer strSize) 这个方法
* */
public static byte[] strToBytes(String s) { public static byte[] strToBytes(String s) {
byte[] bytes = s.getBytes(StandardCharsets.UTF_8); byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
byte[] res = new byte[bytes.length+2]; byte[] res = new byte[bytes.length+2];
@ -661,8 +675,78 @@ public class ByteUtils {
for(int i=0;i<bytes.length;i++){ for(int i=0;i<bytes.length;i++){
res[i+2] = bytes[i]; res[i+2] = bytes[i];
} }
return res;
}
/**
* desc
* 入参
* 一般来说 plc中 string变量都是会设置 长度的 var1 = String[18],这里的strSize就是18
* 返回
* 返回的字节流是包含2个头字节的也就是 strSize+2 个长度的字节流
* */
public static byte[] strToBytes(String s,Integer strSize) {
if(s==null || (strSize<=0)){
return null;
}
Integer allStrSize = strSize+2;
byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
byte[] res = new byte[allStrSize];
res[0] = strSize.byteValue();
if(bytes.length>strSize){
res[1] = strSize.byteValue();
for(int i=0;i<strSize;i++){
res[i+2] = bytes[i];
}
}else {
res[1] = Integer.valueOf(bytes.length).byteValue();
for(int i=0;i<bytes.length;i++){
res[i+2] = bytes[i];
}
}
return res;
}
public static void main(String[] args) throws UnsupportedEncodingException {
//stringArray <=> bytes[]
String[] src = new String[3];
src[0]= "1";
src[1]= "30110012105301117222";
src[2]= "3";
byte[] bytes = strArrayToBytes(src, 18);
String[] strings = toStrArray(bytes, 3, 18);
System.out.println(bytes);
//string <=> bytes[]
String s = "12323221";
byte[] bytes1 = strToBytes(s, 18);
String s1 = toStr(bytes1);
System.out.println(s1);
}
/**
* 参数
* desc : 把字符串数组 ==> byte[] [x,x,..,..,..,..,... x,x,..,..,..,..,... ...]
* array : 就是需要被写入plc的内容,, array.length 就是你要写入数组的长度 注意array.length必须小于plc中设置的 数组变量 length
* strSize : 就是数组中某个变量的长度 比如 String str = new String[18] 这里的18就是strSize,但是在博图偏移量地址上可以发现它已经把你+2了,就是你设置最大string长度18 但偏移量=18+2=20;;
* 而上面的array.length是 List<String> list = new ArrayList<>; 的list.length
* 返回
* byte[] 就是整个数组字符串的 总的字节流
*
* */
public static byte[] strArrayToBytes(String[] array,Integer strSize) {
//str0 [18, 17, 51, 48, 49, 49, 48, 48, 49, 50, 49, 48, 53, 51, 48, 49, 49, 49, 53]
//str1 [18, 18, 51, 48, 49, 49, 48, 48, 49, 50, 49, 48, 53, 51, 48, 49, 49, 49, 53, 49]
//str2 [18, 18, 51, 48, 49, 49, 48, 48, 49, 50, 49, 48, 53, 51, 48, 49, 49, 49, 53, 50]
//list [18, 17, 51, 48, 49, 49, 48, 48, 49, 50, 49, 48, 53, 51, 48, 49, 49, 49, 53, 0, 18, 18, 51, 48, 49, 49, 48, 48, 49, 50, 49, 48, 53, 51, 48, 49, 49, 49, 53, 49, 18, 18, 51, 48, 49, 49, 48, 48, 49, 50, 49, 48, 53, 51, 48, 49, 49, 49, 53, 50]
//strSize+2 以后就是 实际plc 变量的字节数了
Integer allStrSize = strSize+2;
byte[] res = new byte[array.length*allStrSize];
for(int i=0;i<array.length;i++){
byte[] bytes = strToBytes(array[i],strSize);
System.arraycopy(bytes,0,res,i*allStrSize,bytes.length);
}
return res; return res;
} }

View File

@ -2,19 +2,31 @@ package com.qgs.dc.s7.my.s7connector.enmuc;
import com.qgs.dc.s7.my.s7connector.api.DaveArea; import com.qgs.dc.s7.my.s7connector.api.DaveArea;
import com.qgs.dc.s7.my.s7connector.type.PlcVar; import com.qgs.dc.s7.my.s7connector.type.PlcVar;
import com.qgs.dc.s7.my.s7connector.type.TransportSize;
import org.omg.CORBA.PRIVATE_MEMBER;
//实际 Plc中的变量 要实现录入到这个枚举类中 为后续做准备 //实际 Plc中的变量 要实现录入到这个枚举类中 为后续做准备
//注意
// 单体变量 length 都是1
// 数组变量 length 就是 你要read 或者write数组的长度
// bitOffset 是针对Bool 来说的其他变量bitOffset 都是0
// strSize 这个字段只是给 String变量 String[]变量 用的, 这个字段是plc中设置的最大String长度
// String类型 在write的时候禁止 write中文因为plc中编码并没有采用UTF-8 而是采用ASCII
// 同理也是当plc中有设置String类型或者StringArray那么告诉他们必须指定长度 通常他们也会指定长度的
public enum PlcVarActual { public enum PlcVarActual {
//心跳变量这个可以要求电控同事加一个不和业务关联只用于通讯
HeartBeat("HeartBeat",PlcVar.BOOL,1,DaveArea.DB,3,3267,5), HeartBeat("HeartBeat",PlcVar.BOOL,1,DaveArea.DB,3,3267,5),
//bitOffset 是针对Bool 来说的 HeartBeatFor1200("HeartBeatFor1200",PlcVar.BOOL,1,DaveArea.DB,1,0,0),
//单体变量
DB54("DB54",PlcVar.BYTE,1,DaveArea.DB,3,3268,0), DB54("DB54",PlcVar.BYTE,1,DaveArea.DB,3,3268,0),
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), STRING1("STRING",PlcVar.STRING,1,DaveArea.DB,3,62,0,20),
SUBID0("SUBID0",PlcVar.STRING,1,DaveArea.DB,3,3270,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)
@ -26,10 +38,13 @@ public enum PlcVarActual {
private Integer byteOffset; private Integer byteOffset;
private Integer bitOffset; private Integer bitOffset;
private PlcVar type; private PlcVar type;
//length = 1代表 非数组;;; length > 1 代表数组 ;; 注意 length这个参数 是实际plc中 的长度和read操作相关 //length = 1代表 非数组;;; length > 1 代表数组 ;; 注意 length这个参数 是实际plc中 的长度和read操作相关
//如果是String 类型不用填length 只需要填string类型的起始位置就行了我会自己去取数据长度也就是说这里的length并不是string 的长度 //如果是String 类型不用填length 只需要填string类型的起始位置就行了我会自己去取数据长度也就是说这里的length并不是string 的长度
private Integer length; private Integer length;
//这个字段只是给 字符串变量 字符串数组 , 这个字段是plc中设置的最大String长度
private Integer strSize;
PlcVarActual(String name, PlcVar type,Integer length, DaveArea area, Integer areaNumber, Integer byteOffset, Integer bitOffset){ PlcVarActual(String name, PlcVar type,Integer length, DaveArea area, Integer areaNumber, Integer byteOffset, Integer bitOffset){
this.name = name; this.name = name;
this.type = type; this.type = type;
@ -39,7 +54,24 @@ public enum PlcVarActual {
this.byteOffset = byteOffset; this.byteOffset = byteOffset;
this.bitOffset = bitOffset; this.bitOffset = bitOffset;
} }
PlcVarActual(String name, PlcVar type,Integer length, DaveArea area, Integer areaNumber, Integer byteOffset, Integer bitOffset,Integer strSize){
this.name = name;
this.type = type;
this.length = length;
this.area = area;
this.areaNumber = areaNumber;
this.byteOffset = byteOffset;
this.bitOffset = bitOffset;
this.strSize = strSize;
}
public Integer getStrSize() {
return strSize;
}
public void setStrSize(Integer strSize) {
this.strSize = strSize;
}
public String getName() { public String getName() {
return name; return name;

View File

@ -17,7 +17,10 @@ import java.util.concurrent.ScheduledExecutorService;
*/ */
public enum S7Client { public enum S7Client {
//TODO 步骤1 这里是配置多PLC 有多个plc 就在这里配置一个枚举类 //TODO 步骤1 这里是配置多PLC 有多个plc 就在这里配置一个枚举类
S7_1200("192.168.0.51",0,0,3,PlcVarActual.HeartBeat) //1500 虽然设备上显示机架-0 插槽-1这个是默认的 但是我们这里 rackslot 都是0反正我们这里就让电控rack和solt都是默认的 然后我们这边都配置0就行了
S7_1500("192.168.0.51",0,0,3,PlcVarActual.HeartBeat),
//1500 机架-0 插槽-1
S7_1200("192.168.0.52",0,0,3,PlcVarActual.HeartBeatFor1200)
//后续 在这里扩展 多PLC应用 //后续 在这里扩展 多PLC应用
@ -38,6 +41,10 @@ public enum S7Client {
//pickOne 就是一个初始化 的轮询取余值 //pickOne 就是一个初始化 的轮询取余值
private int pickOne; private int pickOne;
private static final Logger logger = LoggerFactory.getLogger(S7Client.class); private static final Logger logger = LoggerFactory.getLogger(S7Client.class);
private ScheduledExecutorService executor;
private ScheduledExecutorService ping_fail_check;
//coreSize 是线程池的数量 //coreSize 是线程池的数量
S7Client(String host, Integer rack, Integer slot,Integer coreSize,PlcVarActual heartBeat){ S7Client(String host, Integer rack, Integer slot,Integer coreSize,PlcVarActual heartBeat){
this.host = host; this.host = host;
@ -45,6 +52,9 @@ public enum S7Client {
this.slot = slot; this.slot = slot;
this.pickOne = 0; this.pickOne = 0;
this.executor = Executors.newScheduledThreadPool(1);
this.ping_fail_check = Executors.newScheduledThreadPool(1);
this.coreSize = coreSize; this.coreSize = coreSize;
this.heartBeat = heartBeat; this.heartBeat = heartBeat;
connections = new ArrayList<>(); connections = new ArrayList<>();
@ -57,8 +67,7 @@ public enum S7Client {
private ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
private ScheduledExecutorService ping_fail_check = Executors.newScheduledThreadPool(1);
public S7Connector getConnector() { public S7Connector getConnector() {
@ -68,7 +77,7 @@ public enum S7Client {
pickOne = (pickOne)%size; pickOne = (pickOne)%size;
return s7Connector; return s7Connector;
} }
public S7Connector connect(String host,Integer rack,Integer slot ){ private S7Connector connect(String host,Integer rack,Integer slot ){
try { try {
S7Connector connector = S7ConnectorFactory S7Connector connector = S7ConnectorFactory
.buildTCPConnector() .buildTCPConnector()
@ -101,10 +110,10 @@ public enum S7Client {
for(int z=0;z<c;z++){ for(int z=0;z<c;z++){
S7Connector connect = connect(host, rack, slot); S7Connector connect = connect(host, rack, slot);
if(connect!=null){ if(connect!=null){
logger.info("(check_ping()) 检测到有断线 ==》 现在断线恢复成功"); logger.info("host:"+host +" ;;(check_ping()) 检测到有断线 ==》 现在断线恢复成功");
connections.add(connect); connections.add(connect);
}else { }else {
logger.info("(check_ping()) 检测到有断线 ==》 现在断线恢复失败"); logger.info("host:"+host +" ;;(check_ping()) 检测到有断线 ==》 现在断线恢复失败");
} }
} }
@ -112,7 +121,7 @@ public enum S7Client {
try { try {
Thread.sleep(10000); Thread.sleep(10000);
}catch (Exception e){ }catch (Exception e){
logger.info("(check_ping()) Thread.sleep 异常,异常原因:"+e.getMessage()); logger.info("host:"+host +" ;;(check_ping()) Thread.sleep 异常,异常原因:"+e.getMessage());
} }
} }
} }
@ -136,10 +145,10 @@ public enum S7Client {
heartBeat.getByteOffset(), heartBeat.getByteOffset(),
heartBeat.getBitOffset(), heartBeat.getBitOffset(),
heartBeat.getType().getTransportSize()); heartBeat.getType().getTransportSize());
System.out.println(connector.hashCode()+" : ping"); System.out.println("host:"+host +" ;; "+connector.hashCode()+" : ping");
Thread.sleep(100); Thread.sleep(100);
}catch (Exception e){ }catch (Exception e){
logger.info("(ping) "+connector.hashCode()+" : connection error"+"errMessage is : "+e.getMessage()); logger.info("host:"+host +" ;;(ping) "+connector.hashCode()+" : connection error"+"errMessage is : "+e.getMessage());
//先把 socket close掉 //先把 socket close掉
try { try {
connector.close(); connector.close();
@ -147,7 +156,7 @@ public enum S7Client {
//如果是网络波动照成的socket断开 等个1S 再重连试试 //如果是网络波动照成的socket断开 等个1S 再重连试试
Thread.sleep(100); Thread.sleep(100);
}catch (Exception ee){ }catch (Exception ee){
logger.info("(ping) "+"connector.close() 出现异常errMessage is : "+ee.getMessage()); logger.info("host:"+host +" ;;(ping) "+"connector.close() 出现异常errMessage is : "+ee.getMessage());
} }
} }
@ -157,10 +166,10 @@ public enum S7Client {
for(int z=0;z<c;z++){ for(int z=0;z<c;z++){
S7Connector connect = connect(host, rack, slot); S7Connector connect = connect(host, rack, slot);
if(connect!=null){ if(connect!=null){
logger.info("(ping) "+"ping时候出现异常尝试重连 重连成功!!"); logger.info("host:"+host +" ;;(ping) "+"ping时候出现异常尝试重连 重连成功!!");
connections.add(connect); connections.add(connect);
}else { }else {
logger.info("(ping) "+"ping时候出现异常尝试重连 重连时候还是 出现异常。。"); logger.info("host:"+host +" ;;(ping) "+"ping时候出现异常尝试重连 重连时候还是 出现异常。。");
} }
} }
} }
@ -170,7 +179,7 @@ public enum S7Client {
Thread.sleep(30000); Thread.sleep(30000);
}catch (Exception e){ }catch (Exception e){
e.printStackTrace(); e.printStackTrace();
logger.info("(ping) "+e.getMessage()); logger.info("host:"+host +" ;;(ping) "+e.getMessage());
} }
} }
} }

View File

@ -2,6 +2,7 @@ package com.qgs.dc.s7.my.s7connector.service;
import com.qgs.dc.s7.my.s7connector.api.DaveArea; import com.qgs.dc.s7.my.s7connector.api.DaveArea;
import com.qgs.dc.s7.my.s7connector.api.S7Connector; import com.qgs.dc.s7.my.s7connector.api.S7Connector;
import com.qgs.dc.s7.my.s7connector.api.utils.ByteUtils;
import com.qgs.dc.s7.my.s7connector.enmuc.PlcVarActual; import com.qgs.dc.s7.my.s7connector.enmuc.PlcVarActual;
import com.qgs.dc.s7.my.s7connector.enmuc.S7Client; import com.qgs.dc.s7.my.s7connector.enmuc.S7Client;
import com.qgs.dc.s7.my.s7connector.type.PlcVar; import com.qgs.dc.s7.my.s7connector.type.PlcVar;
@ -66,6 +67,7 @@ public class S7Service {
* */ * */
public Object read(PlcVarActual plcVarActual,S7Client s7Client) throws UnsupportedEncodingException, ParseException { public Object read(PlcVarActual plcVarActual,S7Client s7Client) throws UnsupportedEncodingException, ParseException {
S7Connector connector = s7Client.getConnector(); S7Connector connector = s7Client.getConnector();
//String 类型比较特殊 String[] 也是同理Sring数组里面的子项 也是有两个字节的 readBytes
if(plcVarActual.getType().equals(PlcVar.STRING)){ if(plcVarActual.getType().equals(PlcVar.STRING)){
Integer readBytes = 2; Integer readBytes = 2;
byte[] read = connector.read( byte[] read = connector.read(
@ -87,6 +89,19 @@ public class S7Service {
plcVarActual.getType().getTransportSize() plcVarActual.getType().getTransportSize()
); );
return plcVarActual.getType().toObject(readF); return plcVarActual.getType().toObject(readF);
}else if(plcVarActual.getType().equals(PlcVar.STRING_Array)){
Integer arrayLength = plcVarActual.getLength();
Integer strSize = plcVarActual.getStrSize();
byte[] read = connector.read(
plcVarActual.getArea(),
plcVarActual.getAreaNumber(),
arrayLength*(strSize+2),
plcVarActual.getByteOffset(),
plcVarActual.getBitOffset(),
plcVarActual.getType().getTransportSize()
);
return ByteUtils.toStrArray(read, arrayLength, strSize);
}else { }else {
Integer readBytes = plcVarActual.getType().getTransportSize().getSizeInBytes() * plcVarActual.getLength(); Integer readBytes = plcVarActual.getType().getTransportSize().getSizeInBytes() * plcVarActual.getLength();
byte[] read = connector.read( byte[] read = connector.read(
@ -99,10 +114,6 @@ public class S7Service {
); );
return plcVarActual.getType().toObject(read); return plcVarActual.getType().toObject(read);
} }
} }
/** /**
@ -151,6 +162,28 @@ public class S7Service {
* */ * */
public void write(PlcVarActual plcVarActual,Object newValue,S7Client s7Client){ public void write(PlcVarActual plcVarActual,Object newValue,S7Client s7Client){
S7Connector connector = s7Client.getConnector(); S7Connector connector = s7Client.getConnector();
//String 类型比较特殊 String[] 也是同理Sring数组里面的子项 也是有两个字节的 readBytes
if(plcVarActual.getType().equals(PlcVar.STRING)){
connector.write(
plcVarActual.getArea(),
plcVarActual.getAreaNumber(),
plcVarActual.getByteOffset(),
plcVarActual.getBitOffset(),
ByteUtils.strToBytes(newValue.toString(), plcVarActual.getStrSize()),
plcVarActual.getType()
);
}else if(plcVarActual.getType().equals(PlcVar.STRING_Array)){
//todo here 检查 read write service
connector.write(
plcVarActual.getArea(),
plcVarActual.getAreaNumber(),
plcVarActual.getByteOffset(),
plcVarActual.getBitOffset(),
ByteUtils.strArrayToBytes((String[])newValue, plcVarActual.getStrSize()),
plcVarActual.getType()
);
}else {
byte[] bytes = plcVarActual.getType().toBytes(newValue); byte[] bytes = plcVarActual.getType().toBytes(newValue);
connector.write( connector.write(
plcVarActual.getArea(), plcVarActual.getArea(),
@ -162,4 +195,8 @@ public class S7Service {
); );
} }
}
} }

View File

@ -40,7 +40,6 @@ public enum PlcVar {
DT("DT",TransportSize.DT,26,false), DT("DT",TransportSize.DT,26,false),
DTL("DTL",TransportSize.DTL,27,false), DTL("DTL",TransportSize.DTL,27,false),
//todo DTL 捋清 事件关系
//todo Array 再搞一搞 //todo Array 再搞一搞
BOOL_Array("BOOL",TransportSize.BOOL,1,true), BOOL_Array("BOOL",TransportSize.BOOL,1,true),
BYTE_Array("BYTE",TransportSize.BYTE,2,true), BYTE_Array("BYTE",TransportSize.BYTE,2,true),
@ -53,6 +52,7 @@ public enum PlcVar {
UINT_Array("UINT",TransportSize.UINT,9,true), UINT_Array("UINT",TransportSize.UINT,9,true),
USINT_Array("USINT",TransportSize.USINT,10,true), USINT_Array("USINT",TransportSize.USINT,10,true),
UDINT_Array("UDINT",TransportSize.UDINT,11,true), UDINT_Array("UDINT",TransportSize.UDINT,11,true),
STRING_Array("STRING",TransportSize.STRING,12,true),
; ;
private static final Logger logger = LoggerFactory.getLogger(TransportSize.class); private static final Logger logger = LoggerFactory.getLogger(TransportSize.class);
@ -74,6 +74,8 @@ public enum PlcVar {
private TransportSize transportSize; private TransportSize transportSize;
private Integer dataType; private Integer dataType;
private boolean isArray; private boolean isArray;
PlcVar(String name , TransportSize transportSize, Integer dataType,Boolean isArray){ PlcVar(String name , TransportSize transportSize, Integer dataType,Boolean isArray){
this.name = name; this.name = name;
this.transportSize = transportSize; this.transportSize = transportSize;
@ -278,7 +280,9 @@ public enum PlcVar {
// udintArrays_content[2] = 1; // udintArrays_content[2] = 1;
res = ByteUtils.udintArrayToBytes((int[]) value); res = ByteUtils.udintArrayToBytes((int[]) value);
break; break;
case 12:
break;
default: default:
//什么也不做 //什么也不做
break; break;
@ -307,7 +311,7 @@ public enum PlcVar {
* Integer(无符号)(后续扩展) * Integer(无符号)(后续扩展)
* Char ===> Character * Char ===> Character
* WChar ===> Character * WChar ===> Character
* String ===> String * String ===> String //注意 String类型 不能用枚举类里的 toObject() / toBytes() 的方法具体方式看Demo
* 数组变量 * 数组变量
@ -322,7 +326,7 @@ public enum PlcVar {
* UIntArray ===> List<Integer> * UIntArray ===> List<Integer>
* USIntArray ===> List<Integer> * USIntArray ===> List<Integer>
* UDIntArray ===> List<Long> * UDIntArray ===> List<Long>
* * StringArray ===> List<String> //注意 String类型 不能用枚举类里的 toObject() / toBytes() 的方法具体方式看Demo
* *
* *
* */ * */
@ -501,6 +505,8 @@ public enum PlcVar {
case 12: case 12:
//后续有其他数组类型 再补充好了先列出一些常用的 //后续有其他数组类型 再补充好了先列出一些常用的
//本来这里 是吧byte[] => String[] 但是这里拿不到 String[] 的length strSize, 所以就不在这里解析了在外面解析
break; break;
default: default:
//什么也不做 //什么也不做