新增、完善S7协议

This commit is contained in:
caixiang 2022-12-23 13:21:27 +08:00
parent 829c9ce9ca
commit 81dd41be60
6 changed files with 205 additions and 13 deletions

View File

@ -31,7 +31,7 @@ public enum PlcVarActual {
BooleanArrays8("BooleanArrays8",PlcVar.BOOL_Array,1,DaveArea.DB,3,3262,0),
SubIdArrays("SubIdArrays",PlcVar.STRING_Array,60,DaveArea.DB,3,3270,0,18),
SubIdArrays("SubIdArrays",PlcVar.STRING_Array,60,DaveArea.DB,3,3268,0,18),
SubIdArrays1200("SubIdArrays1200",PlcVar.STRING_Array,60,DaveArea.DB,1,20,0,18),

View File

@ -23,8 +23,8 @@ import java.util.List;
public enum S7ClientNew {
//TODO 步骤1 这里是配置多PLC 有多个plc 就在这里配置一个枚举类
//1500 西门子200smart12001500默认的 机架号=0 槽位号=1; 300/400 默认的 机架-0 插槽-2
S7_1200("192.168.0.52",0,1,1,PlcVarActual.HeartBeatFor1200),
// S7_1200("192.168.0.52",0,1,1,PlcVarActual.HeartBeatFor1200),
S7_15001("192.168.0.51",0,1,1,PlcVarActual.HeartBeat),
S7_1500("192.168.0.51",0,1,1,PlcVarActual.HeartBeat),
//1500 机架-0 插槽-1
//后续 在这里扩展 多PLC应用
@ -232,7 +232,7 @@ public enum S7ClientNew {
*
*
* */
public void write(DaveArea area, Integer areaNumber, Integer byteOffset, Integer bitOffset,Integer strSize, PlcVar type, Object newValue) throws Exception {
public void write(DaveArea area, Integer areaNumber, Integer byteOffset, Integer bitOffset,Integer strSize, PlcVar type, Object newValue) {
S7Connector connector = getConnector();
S7RetryTemplate.getInstance().execute(
@ -290,19 +290,32 @@ public enum S7ClientNew {
}
}
);
}
// public void retry1() throws InterruptedException {
// S7RetryTemplate instance = S7RetryTemplate.getInstance();
// System.out.println(instance.hashCode()+ ", "+Thread.currentThread().getName());
// instance.execute(
// retryContext -> {
// System.out.println("retry1 : " + Thread.currentThread().getName() );
// Thread.sleep(10000);
// System.out.println("retry1 sleepdown : " + Thread.currentThread().getName() );
// return true;
// },
// retryContext -> {
// System.out.println("retry1 err: " + Thread.currentThread().getName() );
// return false;
// }
// );
// }
/**
* desc: 传入的connection 是需要被替换的
* return:
* 1 代表替换成功
* -1 代表替换失败创建connection失败原因出现异常.原来的connection也被舍弃掉了
* */
private Integer replaceConnector(S7Connector oldOne){
private synchronized Integer replaceConnector(S7Connector oldOne){
connections.remove(oldOne);
S7Connector connect = connect(host, rack, slot);
if(connect == null){
@ -314,7 +327,8 @@ public enum S7ClientNew {
}
public S7Connector getConnector() {
//虽然是枚举类但这个是对象锁不是类锁
public synchronized S7Connector getConnector() {
int size = connections.size();
S7Connector s7Connector = connections.get((pickOne + size) % size);
pickOne+=1;
@ -322,7 +336,9 @@ public enum S7ClientNew {
return s7Connector;
}
private S7Connector connect(String host,Integer rack,Integer slot ){
private synchronized S7Connector connect(String host,Integer rack,Integer slot ){
try {
S7Connector connector = S7ConnectorFactory
.buildTCPConnector()
@ -343,7 +359,7 @@ public enum S7ClientNew {
connectionPool();
}
private void connectionPool(){
private synchronized void connectionPool(){
for(int i=0;i<coreSize;i++){
S7Connector connect = connect(host, rack, slot);
if(connect!=null){

View File

@ -2,6 +2,7 @@ package com.qgs.dc.s7.retry;
import com.qgs.dc.s7.my.s7connector.exception.S7CheckResultException;
import com.qgs.dc.s7.my.s7connector.exception.S7IOException;
import com.qgs.dc.s7.my.s7connector.exception.S7ParseDataException;
import org.springframework.remoting.RemoteAccessException;
import org.springframework.retry.backoff.FixedBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
@ -33,6 +34,7 @@ public class S7RetryTemplate extends RetryTemplate {
// 代表S7IOException 这个异常是需要重试的(true), 如果你想设置这个异常不去重试那么可以把它设置为false
exceptionMap.put(S7IOException.class,true);
exceptionMap.put(S7CheckResultException.class,true);
exceptionMap.put(S7ParseDataException.class,true);
}
public static int getMaxRetryTimes() {

View File

@ -0,0 +1,123 @@
package com.qgs.dc.s7.retrydemo.forTest;
import com.qgs.dc.s7.my.s7connector.api.S7Connector;
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.S7ClientNew;
import com.qgs.dc.s7.my.s7connector.exception.S7ParseDataException;
import com.qgs.dc.s7.my.s7connector.type.PlcVar;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
/**
* @Desc: ""
* @Author: caixiang
* @DATE: 2022/12/23 12:33
*/
@Component
@Order(value = 1)
public class InitialS7Thread implements ApplicationRunner {
private static final Logger logger = LoggerFactory.getLogger(InitialS7Thread.class);
public InitialS7Thread(){
this.executor = Executors.newScheduledThreadPool(10);
}
private ScheduledExecutorService executor;
private void write(S7ClientNew s7Client,PlcVarActual var,Object newValue) {
if(var.getType().equals(PlcVar.STRING_Array)){
String[] s = (String[])newValue;
String[] ss = (String[])newValue;
if(s.length > var.getLength() ){
ss = new String[var.getLength()];
for(int i=0;i< var.getLength();i++){
ss[i] = s[i];
}
}
s7Client.write(var.getArea(), var.getAreaNumber(), var.getByteOffset(), var.getBitOffset(), var.getStrSize(), var.getType(),ss);
}else {
s7Client.write(var.getArea(), var.getAreaNumber(), var.getByteOffset(), var.getBitOffset(), var.getStrSize(), var.getType(),newValue);
}
}
private Object read(S7ClientNew s7Client,PlcVarActual var) {
try {
return s7Client.read(var.getArea(), var.getAreaNumber(), var.getByteOffset(), var.getBitOffset(), var.getLength(), var.getStrSize(), var.getType());
}catch (Exception e){
logger.error("host:"+s7Client.getHost()+" ; read 操作出现问题: "+e.getMessage());
e.printStackTrace();
return null;
}
}
@Override
public void run(ApplicationArguments args) throws Exception {
executor.execute(new Runnable() {
@Override
public void run() {
while (true){
//read one
logger.info(Thread.currentThread().getName()+" , subId : "+Arrays.toString((String[])read(S7ClientNew.S7_1500,PlcVarActual.SubIdArrays)));
try {
Thread.sleep(300);
} catch (InterruptedException e) {
throw new S7ParseDataException(e);
}
//write one
String[] toWrite = new String[60];
for(int i=0;i<60;i++){
toWrite[i] = RandomStringUtils.randomAlphanumeric(18);
}
try {
write(S7ClientNew.S7_1500,PlcVarActual.SubIdArrays,toWrite);
} catch (Exception e) {
throw new S7ParseDataException(e);
}
}
}
});
executor.execute(new Runnable() {
@Override
public void run() {
while (true){
logger.info(Thread.currentThread().getName()+" , subId : "+Arrays.toString((String[])read(S7ClientNew.S7_1500,PlcVarActual.SubIdArrays)));
try {
Thread.sleep(300);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
//write one
String[] toWrite = new String[60];
for(int i=0;i<60;i++){
toWrite[i] = RandomStringUtils.randomAlphanumeric(18);
}
try {
write(S7ClientNew.S7_15001,PlcVarActual.SubIdArrays,toWrite);
} catch (Exception e) {
throw new S7ParseDataException(e);
}
}
}
});
}
}

View File

@ -0,0 +1,51 @@
package com.qgs.dc.s7.retrydemo.lock;
import com.qgs.dc.s7.my.s7connector.enmuc.S7ClientNew;
/**
* @Desc: ""
* @Author: caixiang
* @DATE: 2022/12/23 12:08
*/
public class LockDemo {
//对象所
public synchronized void func1() {
System.out.println("func1!");
try {
Thread.sleep(10000);
System.out.println("sleep time over!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void func2() {
System.out.println("func2!");
}
public static void main(String[] args) {
LockDemo test = new LockDemo();
LockDemo test2 = new LockDemo();
Thread t1 = new Thread(() -> {
// test.func1();
// try {
// S7ClientNew.S7_1500.retry1();
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
}, "t1");
Thread t2 = new Thread(() -> {
// test2.func2();
// try {
// S7ClientNew.S7_1500.retry1();
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// }
}, "t2");
t1.start();
t2.start();
}
}

View File

@ -8,7 +8,7 @@ server:
spring:
rabbitmq:
# 如果是rabbitmq+haproxy+keepalived集群 那么192.168.0.176是haproxy代理的地址严格来说是keepalived的vip
addresses: 172.16.21.191:5672 # 新版rabbitmq 版本还未测试
addresses: 192.168.0.175:5672 # 新版rabbitmq 版本还未测试
#addresses: 172.16.21.133:5672
username: cigs
password: cigs