diff --git a/src/main/java/com/qgs/dc/mq/consumer/PID00BReceived.java b/src/main/java/com/qgs/dc/mq/consumer/PID00BReceived.java index 618f74f..35429fe 100644 --- a/src/main/java/com/qgs/dc/mq/consumer/PID00BReceived.java +++ b/src/main/java/com/qgs/dc/mq/consumer/PID00BReceived.java @@ -39,6 +39,8 @@ public class PID00BReceived { private static final Logger logger = LoggerFactory.getLogger(PID00BReceived.class); + + @Autowired MQMessageHandler mqMessageHandler; diff --git a/src/main/java/com/qgs/dc/mq/entity/MQMessage.java b/src/main/java/com/qgs/dc/mq/entity/MQMessage.java index 11cae15..79f4036 100644 --- a/src/main/java/com/qgs/dc/mq/entity/MQMessage.java +++ b/src/main/java/com/qgs/dc/mq/entity/MQMessage.java @@ -1,10 +1,13 @@ package com.qgs.dc.mq.entity; +import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.annotation.JSONType; import com.qgs.dc.mq.entity.common.Header; import com.qgs.dc.mq.entity.common.Returns; import lombok.Data; +import java.util.HashMap; + /** * @Desc: "" * @Author: caixiang diff --git a/src/main/java/com/qgs/dc/s7/controller/S7DemoController.java b/src/main/java/com/qgs/dc/s7/controller/S7DemoController.java index f660ab3..c484d22 100644 --- a/src/main/java/com/qgs/dc/s7/controller/S7DemoController.java +++ b/src/main/java/com/qgs/dc/s7/controller/S7DemoController.java @@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.*; import java.io.UnsupportedEncodingException; import java.text.ParseException; import java.util.List; +import java.util.Random; @RestController @RequestMapping("/s7") @@ -27,7 +28,7 @@ public class S7DemoController { @PostMapping("/testReadAll") public R testReadAll() throws UnsupportedEncodingException, ParseException { 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(); } @@ -35,34 +36,77 @@ public class S7DemoController { //demo2 @PostMapping("/readTest") public R getTestForS7() throws UnsupportedEncodingException, ParseException { - Boolean heartBeat = (Boolean)s7Service.read(PlcVarActual.HeartBeat,S7Client.S7_1200); - String ddtl = (String)s7Service.read(PlcVarActual.DTL,S7Client.S7_1200); - List characters = (List)s7Service.read(PlcVarActual.CharArrays,S7Client.S7_1200); + Boolean heartBeat = (Boolean)s7Service.read(PlcVarActual.HeartBeat,S7Client.S7_1500); + String ddtl = (String)s7Service.read(PlcVarActual.DTL,S7Client.S7_1500); + List characters = (List)s7Service.read(PlcVarActual.CharArrays,S7Client.S7_1500); - List booleans = (List)s7Service.read(PlcVarActual.BooleanArrays,S7Client.S7_1200); - String stri = (String)s7Service.read(PlcVarActual.STRING1,S7Client.S7_1200); + List booleans = (List)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); } + @PostMapping("/readTest2") + public R getTest2ForS7() throws UnsupportedEncodingException, ParseException { +// List characters = (List)s7Service.read(PlcVarActual.CharArrays,S7Client.S7_1500); +// +// List booleans = (List)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 @PostMapping("/writeTest") 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]; charArrays_content[0] = '1'; 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]; boolArrays_content[0] = true; 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"; //todo string 的读写有问题 待会看看 - s7Service.write(PlcVarActual.STRING1, str, S7Client.S7_1200); + s7Service.write(PlcVarActual.STRING1, str, S7Client.S7_1500); return R.ok().put("res",true); } diff --git a/src/main/java/com/qgs/dc/s7/my/s7connector/MainForRead.java b/src/main/java/com/qgs/dc/s7/my/s7connector/MainForRead.java index 438cd82..72cb0c1 100644 --- a/src/main/java/com/qgs/dc/s7/my/s7connector/MainForRead.java +++ b/src/main/java/com/qgs/dc/s7/my/s7connector/MainForRead.java @@ -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.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.enmuc.S7Client; @@ -28,7 +27,7 @@ public class MainForRead { // .withSlot(0) //optional slot 是插槽号 // .build(); - S7Connector connector = S7Client.S7_1200.getConnector(); + S7Connector connector = S7Client.S7_1500.getConnector(); // // [0] diff --git a/src/main/java/com/qgs/dc/s7/my/s7connector/MainForReadDemo.java b/src/main/java/com/qgs/dc/s7/my/s7connector/MainForReadDemo.java new file mode 100644 index 0000000..4c93eaf --- /dev/null +++ b/src/main/java/com/qgs/dc/s7/my/s7connector/MainForReadDemo.java @@ -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); + + } + + + +} diff --git a/src/main/java/com/qgs/dc/s7/my/s7connector/api/utils/ByteUtils.java b/src/main/java/com/qgs/dc/s7/my/s7connector/api/utils/ByteUtils.java index 6c9f782..b8fb1ab 100644 --- a/src/main/java/com/qgs/dc/s7/my/s7connector/api/utils/ByteUtils.java +++ b/src/main/java/com/qgs/dc/s7/my/s7connector/api/utils/ByteUtils.java @@ -208,6 +208,16 @@ public class ByteUtils { // String s = new String(content); 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 toBoolArray(byte[] b) throws UnsupportedEncodingException { List res = new ArrayList<>(); @@ -653,6 +663,10 @@ public class ByteUtils { return charToByte(c); } + //如果plc中没有设置 strSize,那么 这个字符串变量的 最大长度默认是 254(字节就是-2 ) + /** + * 这个函数就用于 非str类型转bytes使用,string类型转bytes 用strToBytes(String s,Integer strSize) 这个方法。 + * */ public static byte[] strToBytes(String s) { byte[] bytes = s.getBytes(StandardCharsets.UTF_8); byte[] res = new byte[bytes.length+2]; @@ -661,8 +675,78 @@ public class ByteUtils { for(int i=0;istrSize){ + res[1] = strSize.byteValue(); + for(int i=0;i 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 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 1 代表数组 ;; 注意 length这个参数 是实际plc中 数据的长度,和read操作相关 + //length = 1代表 非数组;;; length > 1 代表数组 ;; 注意 length这个参数 是实际plc中 数组的长度,和read操作相关 //如果是String 类型不用填length 只需要填string类型的起始位置就行了,我会自己去取数据长度(也就是说这里的length并不是string 的长度)。 private Integer length; + //这个字段只是给 字符串变量 和 字符串数组 用, 这个字段是plc中设置的最大String长度 + private Integer strSize; + PlcVarActual(String name, PlcVar type,Integer length, DaveArea area, Integer areaNumber, Integer byteOffset, Integer bitOffset){ this.name = name; this.type = type; @@ -39,7 +54,24 @@ public enum PlcVarActual { this.byteOffset = byteOffset; 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() { return name; diff --git a/src/main/java/com/qgs/dc/s7/my/s7connector/enmuc/S7Client.java b/src/main/java/com/qgs/dc/s7/my/s7connector/enmuc/S7Client.java index b6d52d2..97e7f8f 100644 --- a/src/main/java/com/qgs/dc/s7/my/s7connector/enmuc/S7Client.java +++ b/src/main/java/com/qgs/dc/s7/my/s7connector/enmuc/S7Client.java @@ -17,7 +17,10 @@ import java.util.concurrent.ScheduledExecutorService; */ public enum S7Client { //TODO 步骤1 这里是配置多PLC 的,,,有多个plc 就在这里配置一个枚举类 - S7_1200("192.168.0.51",0,0,3,PlcVarActual.HeartBeat) + //1500 虽然设备上显示机架-0 插槽-1(这个是默认的) 但是我们这里 rack、slot 都是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应用。 @@ -38,6 +41,10 @@ public enum S7Client { //pickOne 就是一个初始化 的轮询取余值 private int pickOne; private static final Logger logger = LoggerFactory.getLogger(S7Client.class); + + private ScheduledExecutorService executor; + private ScheduledExecutorService ping_fail_check; + //coreSize 是线程池的数量 S7Client(String host, Integer rack, Integer slot,Integer coreSize,PlcVarActual heartBeat){ this.host = host; @@ -45,6 +52,9 @@ public enum S7Client { this.slot = slot; this.pickOne = 0; + this.executor = Executors.newScheduledThreadPool(1); + this.ping_fail_check = Executors.newScheduledThreadPool(1); + this.coreSize = coreSize; this.heartBeat = heartBeat; 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() { @@ -68,7 +77,7 @@ public enum S7Client { pickOne = (pickOne)%size; return s7Connector; } - public S7Connector connect(String host,Integer rack,Integer slot ){ + private S7Connector connect(String host,Integer rack,Integer slot ){ try { S7Connector connector = S7ConnectorFactory .buildTCPConnector() @@ -101,10 +110,10 @@ public enum S7Client { for(int z=0;z Character * WChar ===> Character - * String ===> String + * String ===> String //注意: String类型 不能用枚举类里的 toObject() / toBytes() 的方法,具体方式看Demo * 数组变量 @@ -322,7 +326,7 @@ public enum PlcVar { * UIntArray ===> List * USIntArray ===> List * UDIntArray ===> List - * + * StringArray ===> List //注意: String类型 不能用枚举类里的 toObject() / toBytes() 的方法,具体方式看Demo * * * */ @@ -501,6 +505,8 @@ public enum PlcVar { case 12: //后续有其他数组类型 ,再补充好了,先列出一些常用的。 + //本来这里 是吧byte[] => String[] 的,但是这里拿不到 String[] 的length 和 strSize, 所以就不在这里解析了在外面解析 + break; default: //什么也不做