S7协议 大版本合并
This commit is contained in:
parent
81dd41be60
commit
0ad4d2b3e3
@ -1,16 +1,13 @@
|
|||||||
package com.qgs.dc.s7.controller;
|
package com.qgs.dc.s7.controller;
|
||||||
|
|
||||||
import com.influxdb.client.InfluxDBClient;
|
|
||||||
import com.influxdb.client.domain.WritePrecision;
|
|
||||||
import com.influxdb.client.write.Point;
|
|
||||||
import com.qgs.dc.opcua.controller.R;
|
import com.qgs.dc.opcua.controller.R;
|
||||||
import com.qgs.dc.s7.entity.AGVInfoCallBack;
|
import com.qgs.dc.s7.entity.AGVInfoCallBack;
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -154,7 +151,7 @@ public class S7DemoController {
|
|||||||
public R testForString1200() throws Exception {
|
public R testForString1200() throws Exception {
|
||||||
//测试结果 l => 66ms
|
//测试结果 l => 66ms
|
||||||
long l = System.currentTimeMillis();
|
long l = System.currentTimeMillis();
|
||||||
String[] subs = (String[])read(S7Client.S7_1200,PlcVarActual.SubIdArrays1200); //65ms
|
String[] subs = (String[])read(S7Client.S7_1500,PlcVarActual.SubIdArrays1200); //65ms
|
||||||
long l1 = System.currentTimeMillis();
|
long l1 = System.currentTimeMillis();
|
||||||
//System.out.println(Arrays.toString(subs));
|
//System.out.println(Arrays.toString(subs));
|
||||||
|
|
||||||
@ -165,10 +162,10 @@ public class S7DemoController {
|
|||||||
}
|
}
|
||||||
////测试结果 c => 57ms
|
////测试结果 c => 57ms
|
||||||
long c1 = System.currentTimeMillis();
|
long c1 = System.currentTimeMillis();
|
||||||
write(S7Client.S7_1200,PlcVarActual.SubIdArrays1200,toWrite);
|
write(S7Client.S7_1500,PlcVarActual.SubIdArrays1200,toWrite);
|
||||||
long c2 = System.currentTimeMillis();
|
long c2 = System.currentTimeMillis();
|
||||||
|
|
||||||
String[] subs2 = (String[])read(S7Client.S7_1200,PlcVarActual.SubIdArrays1200);
|
String[] subs2 = (String[])read(S7Client.S7_1500,PlcVarActual.SubIdArrays1200);
|
||||||
logger.info("正常测试: l:"+(l1-l)+"c:"+(c2-c1)+";;read1:"+Arrays.toString(subs)+";;read2:"+Arrays.toString(subs2));
|
logger.info("正常测试: l:"+(l1-l)+"c:"+(c2-c1)+";;read1:"+Arrays.toString(subs)+";;read2:"+Arrays.toString(subs2));
|
||||||
|
|
||||||
return R.ok().put("l",(l1-l)).put("c",(c2-c1));
|
return R.ok().put("l",(l1-l)).put("c",(c2-c1));
|
||||||
@ -202,17 +199,17 @@ public class S7DemoController {
|
|||||||
|
|
||||||
@PostMapping("/testFor1200")
|
@PostMapping("/testFor1200")
|
||||||
public R testFor1200() throws Exception {
|
public R testFor1200() throws Exception {
|
||||||
//Object subs = read(PlcVarActual.INT1200, S7Client.S7_1200);
|
//Object subs = read(PlcVarActual.INT1200, S7Client.S7_1500);
|
||||||
Object read = read(S7Client.S7_1200, PlcVarActual.SubIdArrays1200);
|
Object read = read(S7Client.S7_1500, PlcVarActual.SubIdArrays1200);
|
||||||
|
|
||||||
String[] toWrite = new String[60];
|
String[] toWrite = new String[60];
|
||||||
for(int i=0;i<60;i++){
|
for(int i=0;i<60;i++){
|
||||||
int i1 = new Random().nextInt(100);
|
int i1 = new Random().nextInt(100);
|
||||||
toWrite[i] = "2212"+ i1;
|
toWrite[i] = "2212"+ i1;
|
||||||
}
|
}
|
||||||
write(S7Client.S7_1200,PlcVarActual.SubIdArrays1200,toWrite);
|
write(S7Client.S7_1500,PlcVarActual.SubIdArrays1200,toWrite);
|
||||||
|
|
||||||
Object read2 = read(S7Client.S7_1200, PlcVarActual.SubIdArrays1200);
|
Object read2 = read(S7Client.S7_1500, PlcVarActual.SubIdArrays1200);
|
||||||
return R.ok();
|
return R.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,6 @@
|
|||||||
package com.qgs.dc.s7.my.s7connector;
|
package com.qgs.dc.s7.my.s7connector;
|
||||||
|
|
||||||
import com.qgs.dc.common.utils.CommonFunction;
|
|
||||||
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 java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Desc: ""
|
* @Desc: ""
|
||||||
|
@ -4,11 +4,6 @@ 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.api.utils.ByteUtils;
|
||||||
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 java.io.UnsupportedEncodingException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,7 +23,7 @@ import java.io.Closeable;
|
|||||||
public interface S7Connector extends Closeable {
|
public interface S7Connector extends Closeable {
|
||||||
/**
|
/**
|
||||||
* Reads an area
|
* Reads an area
|
||||||
* desc : 只要未抛出异常,都是 操作成功的
|
* desc : 只要未抛出异常,都是 操作成功的 ( 锁 )
|
||||||
* @param area
|
* @param area
|
||||||
* @param areaNumber
|
* @param areaNumber
|
||||||
* @param bytes
|
* @param bytes
|
||||||
@ -34,7 +34,7 @@ public interface S7Connector extends Closeable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads an area 读需要bit 位置的 变量(其实就是 read bool变量的时候调用这个方法。)
|
* Reads an area 读需要bit 位置的 变量(其实就是 read bool变量的时候调用这个方法。)
|
||||||
* desc : 只要未抛出异常,都是 操作成功的
|
* desc : 只要未抛出异常,都是 操作成功的 ( 锁 )
|
||||||
* @param area
|
* @param area
|
||||||
* @param areaNumber
|
* @param areaNumber
|
||||||
* @param bytes
|
* @param bytes
|
||||||
@ -44,7 +44,7 @@ public interface S7Connector extends Closeable {
|
|||||||
public byte[] read(DaveArea area, int areaNumber, int bytes, int offset, int bitOffset, TransportSize transportSize);
|
public byte[] read(DaveArea area, int areaNumber, int bytes, int offset, int bitOffset, TransportSize transportSize);
|
||||||
/**
|
/**
|
||||||
* Writes an area
|
* Writes an area
|
||||||
* desc : 只要未抛出异常,都是 操作成功的
|
* desc : 只要未抛出异常,都是 操作成功的 ( 锁 )
|
||||||
* @param area
|
* @param area
|
||||||
* @param areaNumber
|
* @param areaNumber
|
||||||
* @param offset
|
* @param offset
|
||||||
@ -52,7 +52,7 @@ public interface S7Connector extends Closeable {
|
|||||||
*/
|
*/
|
||||||
public void write(DaveArea area, int areaNumber, int offset, byte[] buffer);
|
public void write(DaveArea area, int areaNumber, int offset, byte[] buffer);
|
||||||
|
|
||||||
//如果 bitOffset 没有 那么就填0
|
//如果 bitOffset 没有 那么就填0 ( 锁 )
|
||||||
public void write(DaveArea area, int areaNumber, int byteOffset, int bitOffset, byte[] buffer, PlcVar var);
|
public void write(DaveArea area, int areaNumber, int byteOffset, int bitOffset, byte[] buffer, PlcVar var);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,11 @@ import com.qgs.dc.s7.my.s7connector.api.utils.ByteUtils;
|
|||||||
import com.qgs.dc.s7.my.s7connector.exception.S7Exception;
|
import com.qgs.dc.s7.my.s7connector.exception.S7Exception;
|
||||||
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.utils.CommonFunctions;
|
import com.qgs.dc.s7.my.s7connector.utils.CommonFunctions;
|
||||||
|
import com.qgs.dc.s7.retry.S7RetryTemplate;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,14 +23,11 @@ import java.util.concurrent.ScheduledExecutorService;
|
|||||||
public enum S7Client {
|
public enum S7Client {
|
||||||
//TODO 步骤1 这里是配置多PLC 的,,,有多个plc 就在这里配置一个枚举类
|
//TODO 步骤1 这里是配置多PLC 的,,,有多个plc 就在这里配置一个枚举类
|
||||||
//1500 西门子200smart、1200、1500默认的 机架号=0 槽位号=1; 300/400 默认的 机架-0 插槽-2
|
//1500 西门子200smart、1200、1500默认的 机架号=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),
|
S7_1500("192.168.0.51",0,1,1,PlcVarActual.HeartBeat),
|
||||||
//1500 机架-0 插槽-1
|
//1500 机架-0 插槽-1
|
||||||
//后续 在这里扩展 多PLC应用。
|
//后续 在这里扩展 多PLC应用。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;
|
;
|
||||||
private String host;
|
private String host;
|
||||||
//默认 0 机架号
|
//默认 0 机架号
|
||||||
@ -49,27 +45,21 @@ public enum S7Client {
|
|||||||
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;
|
||||||
this.rack = rack;
|
this.rack = rack;
|
||||||
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;
|
|
||||||
connections = new ArrayList<>();
|
connections = new ArrayList<>();
|
||||||
connectionPool();
|
connectionPool();
|
||||||
|
|
||||||
ping();
|
|
||||||
//
|
|
||||||
check_ping();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getHost(){
|
public String getHost(){
|
||||||
@ -112,73 +102,87 @@ public enum S7Client {
|
|||||||
* UDIntArray ===> List<Long>
|
* UDIntArray ===> List<Long>
|
||||||
* StringArray ===> String[] (特殊)
|
* StringArray ===> String[] (特殊)
|
||||||
*
|
*
|
||||||
*
|
* 如果返回null,就代表出现了异常,并且尝试了 retryMax 次数,并且尝试重置连接
|
||||||
* */
|
* */
|
||||||
public Object read(DaveArea area, Integer areaNumber, Integer byteOffset, Integer bitOffset, Integer length, Integer strSizes, PlcVar type) throws Exception {
|
public Object read(DaveArea area, Integer areaNumber, Integer byteOffset, Integer bitOffset, Integer length, Integer strSizes, PlcVar type) {
|
||||||
S7Connector connector = getConnector();
|
S7Connector connector = getConnector();
|
||||||
//String 类型比较特殊。 String[] 也是同理,Sring数组里面的子项 也是有两个字节的 readBytes。
|
return S7RetryTemplate.getInstance().execute(
|
||||||
if(type.equals(PlcVar.STRING)){
|
context -> {
|
||||||
Integer readBytes = 2;
|
//String 类型比较特殊。 String[] 也是同理,Sring数组里面的子项 也是有两个字节的 readBytes。
|
||||||
byte[] read = connector.read(
|
if(type.equals(PlcVar.STRING)){
|
||||||
area,
|
Integer readBytes = 2;
|
||||||
areaNumber,
|
byte[] read = connector.read(
|
||||||
readBytes,
|
area,
|
||||||
byteOffset,
|
areaNumber,
|
||||||
bitOffset,
|
readBytes,
|
||||||
type.getTransportSize()
|
byteOffset,
|
||||||
);
|
bitOffset,
|
||||||
|
type.getTransportSize()
|
||||||
|
);
|
||||||
|
|
||||||
Integer allLength = Integer.valueOf(read[1])+2;
|
Integer allLength = Integer.valueOf(read[1])+2;
|
||||||
byte[] readF = connector.read(
|
byte[] readF = connector.read(
|
||||||
area,
|
area,
|
||||||
areaNumber,
|
areaNumber,
|
||||||
allLength,
|
allLength,
|
||||||
byteOffset,
|
byteOffset,
|
||||||
bitOffset,
|
bitOffset,
|
||||||
type.getTransportSize()
|
type.getTransportSize()
|
||||||
);
|
);
|
||||||
return type.toObject(readF);
|
return type.toObject(readF);
|
||||||
}else if(type.equals(PlcVar.BOOL_Array)){
|
}else if(type.equals(PlcVar.BOOL_Array)){
|
||||||
|
|
||||||
byte[] read = connector.read(
|
byte[] read = connector.read(
|
||||||
area,
|
area,
|
||||||
areaNumber,
|
areaNumber,
|
||||||
CommonFunctions.exactDivision(length,8),
|
CommonFunctions.exactDivision(length,8),
|
||||||
byteOffset,
|
byteOffset,
|
||||||
bitOffset,
|
bitOffset,
|
||||||
type.getTransportSize()
|
type.getTransportSize()
|
||||||
);
|
);
|
||||||
List<Boolean> booleans = ByteUtils.toBoolArray(read);
|
List<Boolean> booleans = ByteUtils.toBoolArray(read);
|
||||||
List<Boolean> res = new ArrayList<Boolean>();
|
List<Boolean> res = new ArrayList<Boolean>();
|
||||||
for(int i=0;i<length;i++){
|
for(int i=0;i<length;i++){
|
||||||
res.add(i,booleans.get(i));
|
res.add(i,booleans.get(i));
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}else if(type.equals(PlcVar.STRING_Array)){
|
}else if(type.equals(PlcVar.STRING_Array)){
|
||||||
Integer arrayLength = length;
|
Integer arrayLength = length;
|
||||||
Integer strSize = strSizes;
|
Integer strSize = strSizes;
|
||||||
|
|
||||||
byte[] read = connector.read(
|
byte[] read = connector.read(
|
||||||
area,
|
area,
|
||||||
areaNumber,
|
areaNumber,
|
||||||
arrayLength*(strSize+2),
|
arrayLength*(strSize+2),
|
||||||
byteOffset,
|
byteOffset,
|
||||||
bitOffset,
|
bitOffset,
|
||||||
type.getTransportSize()
|
type.getTransportSize()
|
||||||
);
|
);
|
||||||
return ByteUtils.toStrArray(read, arrayLength, strSize);
|
return ByteUtils.toStrArray(read, arrayLength, strSize);
|
||||||
}else {
|
}else {
|
||||||
Integer readBytes = type.getTransportSize().getSizeInBytes() * length;
|
Integer readBytes = type.getTransportSize().getSizeInBytes() * length;
|
||||||
byte[] read = connector.read(
|
byte[] read = connector.read(
|
||||||
area,
|
area,
|
||||||
areaNumber,
|
areaNumber,
|
||||||
readBytes,
|
readBytes,
|
||||||
byteOffset,
|
byteOffset,
|
||||||
bitOffset,
|
bitOffset,
|
||||||
type.getTransportSize()
|
type.getTransportSize()
|
||||||
);
|
);
|
||||||
return type.toObject(read);
|
return type.toObject(read);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
context -> {
|
||||||
|
logger.info("S7-Retry : 已达到最大重试次数: "+S7RetryTemplate.getMaxRetryTimes()+", 现在尝试重新连接"+" ; 异常原因 : "+context.getLastThrowable().getMessage());
|
||||||
|
if(replaceConnector(connector)==1){
|
||||||
|
logger.info("S7-Retry-Read 现在恢复成功,创建新connection成功");
|
||||||
|
return null;
|
||||||
|
}else {
|
||||||
|
logger.info("S7-Retry-Read 现在恢复失败,创建新connection失败");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -228,53 +232,103 @@ public enum S7Client {
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* */
|
* */
|
||||||
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();
|
S7Connector connector = getConnector();
|
||||||
|
|
||||||
//String 类型比较特殊。 String[] 也是同理,Sring数组里面的子项 也是有两个字节的 readBytes。
|
S7RetryTemplate.getInstance().execute(
|
||||||
if(type.equals(PlcVar.STRING)){
|
context -> {
|
||||||
connector.write(
|
//String 类型比较特殊。 String[] 也是同理,Sring数组里面的子项 也是有两个字节的 readBytes。
|
||||||
area,
|
if(type.equals(PlcVar.STRING)){
|
||||||
areaNumber,
|
connector.write(
|
||||||
byteOffset,
|
area,
|
||||||
bitOffset,
|
areaNumber,
|
||||||
ByteUtils.strToBytes(newValue.toString(), strSize),
|
byteOffset,
|
||||||
type
|
bitOffset,
|
||||||
);
|
ByteUtils.strToBytes(newValue.toString(), strSize),
|
||||||
}else if(type.equals(PlcVar.BOOL_Array)){
|
type
|
||||||
connector.write(
|
);
|
||||||
area,
|
}else if(type.equals(PlcVar.BOOL_Array)){
|
||||||
areaNumber,
|
connector.write(
|
||||||
byteOffset,
|
area,
|
||||||
bitOffset,
|
areaNumber,
|
||||||
ByteUtils.toByteArray((boolean[])newValue),
|
byteOffset,
|
||||||
type
|
bitOffset,
|
||||||
);
|
ByteUtils.toByteArray((boolean[])newValue),
|
||||||
}else if(type.equals(PlcVar.STRING_Array)){
|
type
|
||||||
//todo here 检查 read write service
|
);
|
||||||
connector.write(
|
}else if(type.equals(PlcVar.STRING_Array)){
|
||||||
area,
|
//todo here 检查 read write service
|
||||||
areaNumber,
|
connector.write(
|
||||||
byteOffset,
|
area,
|
||||||
bitOffset,
|
areaNumber,
|
||||||
ByteUtils.strArrayToBytes((String[])newValue, strSize),
|
byteOffset,
|
||||||
type
|
bitOffset,
|
||||||
);
|
ByteUtils.strArrayToBytes((String[])newValue, strSize),
|
||||||
}else {
|
type
|
||||||
byte[] bytes = type.toBytes(newValue);
|
);
|
||||||
connector.write(
|
}else {
|
||||||
area,
|
byte[] bytes = type.toBytes(newValue);
|
||||||
areaNumber,
|
connector.write(
|
||||||
byteOffset,
|
area,
|
||||||
bitOffset,
|
areaNumber,
|
||||||
bytes,
|
byteOffset,
|
||||||
type
|
bitOffset,
|
||||||
);
|
bytes,
|
||||||
}
|
type
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
context -> {
|
||||||
|
logger.info("S7-Retry-Write : 已达到最大重试次数: "+S7RetryTemplate.getMaxRetryTimes()+", 现在尝试重新连接");
|
||||||
|
if( replaceConnector(connector) == 1 ){
|
||||||
|
logger.info("S7-Retry-Write 现在恢复成功,创建新connection成功");
|
||||||
|
return null;
|
||||||
|
}else {
|
||||||
|
logger.info("S7-Retry-Write 现在恢复失败,创建新connection失败");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
public S7Connector getConnector() {
|
/**
|
||||||
|
* desc: 传入的connection 是需要被替换的
|
||||||
|
* return:
|
||||||
|
* 1 代表替换成功
|
||||||
|
* -1 代表替换失败(创建connection失败,原因:出现异常.原来的connection也被舍弃掉了)
|
||||||
|
* */
|
||||||
|
private synchronized Integer replaceConnector(S7Connector oldOne){
|
||||||
|
connections.remove(oldOne);
|
||||||
|
S7Connector connect = connect(host, rack, slot);
|
||||||
|
if(connect == null){
|
||||||
|
return -1;
|
||||||
|
}else {
|
||||||
|
connections.add(connect);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//虽然是枚举类,但这个是对象锁(不是类锁)
|
||||||
|
public synchronized S7Connector getConnector() {
|
||||||
int size = connections.size();
|
int size = connections.size();
|
||||||
S7Connector s7Connector = connections.get((pickOne + size) % size);
|
S7Connector s7Connector = connections.get((pickOne + size) % size);
|
||||||
pickOne+=1;
|
pickOne+=1;
|
||||||
@ -282,7 +336,9 @@ public enum S7Client {
|
|||||||
return s7Connector;
|
return s7Connector;
|
||||||
}
|
}
|
||||||
|
|
||||||
private S7Connector connect(String host,Integer rack,Integer slot ){
|
|
||||||
|
|
||||||
|
private synchronized S7Connector connect(String host,Integer rack,Integer slot ){
|
||||||
try {
|
try {
|
||||||
S7Connector connector = S7ConnectorFactory
|
S7Connector connector = S7ConnectorFactory
|
||||||
.buildTCPConnector()
|
.buildTCPConnector()
|
||||||
@ -303,7 +359,7 @@ public enum S7Client {
|
|||||||
connectionPool();
|
connectionPool();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void connectionPool(){
|
private synchronized void connectionPool(){
|
||||||
for(int i=0;i<coreSize;i++){
|
for(int i=0;i<coreSize;i++){
|
||||||
S7Connector connect = connect(host, rack, slot);
|
S7Connector connect = connect(host, rack, slot);
|
||||||
if(connect!=null){
|
if(connect!=null){
|
||||||
@ -312,101 +368,4 @@ public enum S7Client {
|
|||||||
}
|
}
|
||||||
//todo 在plc上新增一个 变量来解决 心跳问题 okok
|
//todo 在plc上新增一个 变量来解决 心跳问题 okok
|
||||||
}
|
}
|
||||||
|
|
||||||
private void check_ping(){
|
|
||||||
ping_fail_check.execute(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
while (true){
|
|
||||||
try {
|
|
||||||
if(connections.size()!=coreSize){
|
|
||||||
int c = coreSize-connections.size();
|
|
||||||
for(int z=0;z<c;z++){
|
|
||||||
S7Connector connect = connect(host, rack, slot);
|
|
||||||
if(connect!=null){
|
|
||||||
logger.info("host:"+host +" ;;(check_ping()) 检测到有断线 ==》 现在断线恢复成功");
|
|
||||||
connections.add(connect);
|
|
||||||
}else {
|
|
||||||
logger.info("host:"+host +" ;;(check_ping()) 检测到有断线 ==》 现在断线恢复失败");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}catch (Exception e){
|
|
||||||
logger.info(" ( outside check_ping catched ) host:"+host +" ;;(check_ping()) Thread.sleep 异常,异常原因:"+e.getMessage());
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Thread.sleep(10000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//todo 当网络断开之后,下面这个ping() 循环不生效。。 可能是read = connector.read( 出来是null,但还是继续通过了,也可能是 ,,当连接全部断开后 getConnector(); 应该是取不到数据的。。也就会报null。这个明天再看看
|
|
||||||
private void ping(){
|
|
||||||
executor.execute(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
while (true){
|
|
||||||
try {
|
|
||||||
for(int i=0;i<coreSize;i++){
|
|
||||||
S7Connector connector = getConnector();
|
|
||||||
try {
|
|
||||||
//只要没有报异常 都是通讯正常的。
|
|
||||||
byte[] read = connector.read(
|
|
||||||
heartBeat.getArea(),
|
|
||||||
heartBeat.getAreaNumber(),
|
|
||||||
heartBeat.getType().getTransportSize().getSizeInBytes(),
|
|
||||||
heartBeat.getByteOffset(),
|
|
||||||
heartBeat.getBitOffset(),
|
|
||||||
heartBeat.getType().getTransportSize());
|
|
||||||
|
|
||||||
System.out.println("host:"+host +" ;; "+connector.hashCode()+" : ping");
|
|
||||||
Thread.sleep(100);
|
|
||||||
}catch (Exception e){
|
|
||||||
logger.info("host:"+host +" ;;(ping) "+connector.hashCode()+" : connection error"+"errMessage is : "+e.getMessage());
|
|
||||||
//先把 socket close掉
|
|
||||||
try {
|
|
||||||
connector.close();
|
|
||||||
connections.remove(connector);
|
|
||||||
//如果是网络波动照成的socket断开。 等个1S 再重连试试
|
|
||||||
Thread.sleep(100);
|
|
||||||
}catch (Exception ee){
|
|
||||||
logger.info("host:"+host +" ;;(ping) "+"connector.close() 出现异常,errMessage is : "+ee.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//todo 把之前的连接close 掉,然后新增一个连接到connections
|
|
||||||
if(connections.size()!=coreSize){
|
|
||||||
int c = coreSize-connections.size();
|
|
||||||
for(int z=0;z<c;z++){
|
|
||||||
S7Connector connect = connect(host, rack, slot);
|
|
||||||
if(connect!=null){
|
|
||||||
logger.info("host:"+host +" ;;(ping) "+"ping时候出现异常,尝试重连, 重连成功!!");
|
|
||||||
connections.add(connect);
|
|
||||||
}else {
|
|
||||||
logger.info("host:"+host +" ;;(ping) "+"ping时候出现异常,尝试重连, 重连时候还是 出现异常。。");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}catch (Exception e){
|
|
||||||
e.printStackTrace();
|
|
||||||
logger.info(" ( outside ping catched ) host:"+host +" ;;(ping) "+e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Thread.sleep(30000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,371 +0,0 @@
|
|||||||
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.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.exception.S7Exception;
|
|
||||||
import com.qgs.dc.s7.my.s7connector.type.PlcVar;
|
|
||||||
import com.qgs.dc.s7.my.s7connector.utils.CommonFunctions;
|
|
||||||
import com.qgs.dc.s7.retry.S7RetryTemplate;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Desc: ""
|
|
||||||
* @Author: caixiang
|
|
||||||
* @DATE: 2022/1/15 13:01
|
|
||||||
*/
|
|
||||||
public enum S7ClientNew {
|
|
||||||
//TODO 步骤1 这里是配置多PLC 的,,,有多个plc 就在这里配置一个枚举类
|
|
||||||
//1500 西门子200smart、1200、1500默认的 机架号=0 槽位号=1; 300/400 默认的 机架-0 插槽-2
|
|
||||||
// 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应用。
|
|
||||||
;
|
|
||||||
private String host;
|
|
||||||
//默认 0 机架号
|
|
||||||
private Integer rack;
|
|
||||||
//默认 0
|
|
||||||
private Integer slot;
|
|
||||||
|
|
||||||
//心跳变量,如果plc没有让电控的人加一个,这个是必填的
|
|
||||||
private PlcVarActual heartBeat;
|
|
||||||
|
|
||||||
private List<S7Connector> connections;
|
|
||||||
//coreSize 是线程池的大小
|
|
||||||
private Integer coreSize;
|
|
||||||
//pickOne 就是一个初始化 的轮询取余值
|
|
||||||
private int pickOne;
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(S7ClientNew.class);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//coreSize 是线程池的数量
|
|
||||||
S7ClientNew(String host, Integer rack, Integer slot, Integer coreSize, PlcVarActual heartBeat){
|
|
||||||
this.host = host;
|
|
||||||
this.rack = rack;
|
|
||||||
this.slot = slot;
|
|
||||||
this.pickOne = 0;
|
|
||||||
|
|
||||||
this.coreSize = coreSize;
|
|
||||||
|
|
||||||
connections = new ArrayList<>();
|
|
||||||
connectionPool();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHost(){
|
|
||||||
return this.host;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PlcVar(byte[]) 转 java对象 对照表
|
|
||||||
* 单体变量
|
|
||||||
* Bool ===> Boolean
|
|
||||||
* LREAL ===> Double
|
|
||||||
* REAL ===> Float
|
|
||||||
* DATE ===> String(yyyy-MM-dd 这种形式的类型)
|
|
||||||
* DTL ===> String("年-月-日-工作日-时-分-秒" 这种格式)
|
|
||||||
* TIME ===> Integer(单位 ms)
|
|
||||||
* USINT ===> Integer
|
|
||||||
* SINT ===> Integer
|
|
||||||
* UINT ===> Integer
|
|
||||||
* INT ===> Integer
|
|
||||||
* DINT ===> Integer
|
|
||||||
* UINT ===> Long
|
|
||||||
* Byte ===> Integer(有符号)(默认)
|
|
||||||
* Integer(无符号)(后续扩展)
|
|
||||||
* Char ===> Character
|
|
||||||
* WChar ===> Character
|
|
||||||
* String ===> String (特殊)
|
|
||||||
|
|
||||||
|
|
||||||
* 数组变量
|
|
||||||
* BoolArray ===> List<Boolean>
|
|
||||||
* ByteArray ===> List<Byte>
|
|
||||||
* WordArray ===> List<Integer>
|
|
||||||
* DWordArray ===> List<Integer>
|
|
||||||
* CharArray ===> List<Character>
|
|
||||||
* SIntArray ===> List<Integer>
|
|
||||||
* IntArray ===> List<Integer>
|
|
||||||
* DIntArray ===> List<Integer>
|
|
||||||
* UIntArray ===> List<Integer>
|
|
||||||
* USIntArray ===> List<Integer>
|
|
||||||
* UDIntArray ===> List<Long>
|
|
||||||
* StringArray ===> String[] (特殊)
|
|
||||||
*
|
|
||||||
* 如果返回null,就代表出现了异常,并且尝试了 retryMax 次数,并且尝试重置连接
|
|
||||||
* */
|
|
||||||
public Object read(DaveArea area, Integer areaNumber, Integer byteOffset, Integer bitOffset, Integer length, Integer strSizes, PlcVar type) {
|
|
||||||
S7Connector connector = getConnector();
|
|
||||||
return S7RetryTemplate.getInstance().execute(
|
|
||||||
context -> {
|
|
||||||
//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.BOOL_Array)){
|
|
||||||
|
|
||||||
byte[] read = connector.read(
|
|
||||||
area,
|
|
||||||
areaNumber,
|
|
||||||
CommonFunctions.exactDivision(length,8),
|
|
||||||
byteOffset,
|
|
||||||
bitOffset,
|
|
||||||
type.getTransportSize()
|
|
||||||
);
|
|
||||||
List<Boolean> booleans = ByteUtils.toBoolArray(read);
|
|
||||||
List<Boolean> res = new ArrayList<Boolean>();
|
|
||||||
for(int i=0;i<length;i++){
|
|
||||||
res.add(i,booleans.get(i));
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}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);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
context -> {
|
|
||||||
logger.info("S7-Retry : 已达到最大重试次数: "+S7RetryTemplate.getMaxRetryTimes()+", 现在尝试重新连接");
|
|
||||||
if(replaceConnector(connector)==1){
|
|
||||||
logger.info("S7-Retry-Read 现在恢复成功,创建新connection成功");
|
|
||||||
return null;
|
|
||||||
}else {
|
|
||||||
logger.info("S7-Retry-Read 现在恢复失败,创建新connection失败");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* eg :
|
|
||||||
* Object newValue = Boolean.FALSE
|
|
||||||
* s7Service.write(PlcVarActual.HeartBeat, newValue, S7Client.S7_1200);
|
|
||||||
*
|
|
||||||
* PlcVar(byte[]) 转 java对象 对照表
|
|
||||||
* 单体变量
|
|
||||||
* Bool ===> Object newValue = Boolean.FALSE
|
|
||||||
* LREAL ===> Object newValue = Boolean.FALSE
|
|
||||||
* REAL ===> Object newValue = Boolean.FALSE
|
|
||||||
* DATE ===> 暂时没需求(有问题找我)
|
|
||||||
* DTL ===> 暂时没需求(有问题找我)
|
|
||||||
* TIME ===> 暂时没需求(有问题找我)
|
|
||||||
* USINT ===> Object newValue = new Integer(1)
|
|
||||||
* SINT ===> Object newValue = new Integer(1)
|
|
||||||
* UINT ===> Object newValue = new Integer(1)
|
|
||||||
* INT ===> Object newValue = new Integer(1)
|
|
||||||
* DINT ===> Object newValue = new Integer(1)
|
|
||||||
* UINT ===> Object newValue = new Integer(1)
|
|
||||||
* Byte ===> Object newValue = 0x11
|
|
||||||
*
|
|
||||||
* Char ===> Object newValue = 'a'
|
|
||||||
* WChar ===> Object newValue = '菜'
|
|
||||||
* String ===> Object newValue = '你好啊' (特殊)
|
|
||||||
|
|
||||||
|
|
||||||
* 数组变量
|
|
||||||
* 注意:在write的时候,你write的数量 一定要和 plc中存在的数量一一对应
|
|
||||||
* BoolArray ===> boolean[] booleanArray = new boolean[2]; .... 赋予值
|
|
||||||
* ByteArray ===> byte[] write_byteArrays = new byte[2];
|
|
||||||
* WordArray ===> short[] shortArrays_content = new short[2];
|
|
||||||
* DWordArray ===> int[] intArrays_content = new int[2];
|
|
||||||
* CharArray ===> char[] charArrays_content = new char[2];
|
|
||||||
* SIntArray ===> int[] sintArrays_content = new int[2];
|
|
||||||
* IntArray ===> int[] iintArrays_content = new int[2];
|
|
||||||
* DIntArray ===> int[] dintArrays_content = new int[2];
|
|
||||||
* UIntArray ===> int[] uintArrays_content = new int[3];
|
|
||||||
* USIntArray ===> int[] usintArrays_content = new int[3];
|
|
||||||
* UDIntArray ===> int[] udintArrays_content = new int[3];
|
|
||||||
* StringArray ===> String[] stringArrays_content = new String[3];
|
|
||||||
* //如果有其他数据类型 这里没有找我扩展
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
public void write(DaveArea area, Integer areaNumber, Integer byteOffset, Integer bitOffset,Integer strSize, PlcVar type, Object newValue) {
|
|
||||||
S7Connector connector = getConnector();
|
|
||||||
|
|
||||||
S7RetryTemplate.getInstance().execute(
|
|
||||||
context -> {
|
|
||||||
//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.BOOL_Array)){
|
|
||||||
connector.write(
|
|
||||||
area,
|
|
||||||
areaNumber,
|
|
||||||
byteOffset,
|
|
||||||
bitOffset,
|
|
||||||
ByteUtils.toByteArray((boolean[])newValue),
|
|
||||||
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
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
context -> {
|
|
||||||
logger.info("S7-Retry-Write : 已达到最大重试次数: "+S7RetryTemplate.getMaxRetryTimes()+", 现在尝试重新连接");
|
|
||||||
if( replaceConnector(connector) == 1 ){
|
|
||||||
logger.info("S7-Retry-Write 现在恢复成功,创建新connection成功");
|
|
||||||
return null;
|
|
||||||
}else {
|
|
||||||
logger.info("S7-Retry-Write 现在恢复失败,创建新connection失败");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 synchronized Integer replaceConnector(S7Connector oldOne){
|
|
||||||
connections.remove(oldOne);
|
|
||||||
S7Connector connect = connect(host, rack, slot);
|
|
||||||
if(connect == null){
|
|
||||||
return -1;
|
|
||||||
}else {
|
|
||||||
connections.add(connect);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//虽然是枚举类,但这个是对象锁(不是类锁)
|
|
||||||
public synchronized S7Connector getConnector() {
|
|
||||||
int size = connections.size();
|
|
||||||
S7Connector s7Connector = connections.get((pickOne + size) % size);
|
|
||||||
pickOne+=1;
|
|
||||||
pickOne = (pickOne)%size;
|
|
||||||
return s7Connector;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private synchronized S7Connector connect(String host,Integer rack,Integer slot ){
|
|
||||||
try {
|
|
||||||
S7Connector connector = S7ConnectorFactory
|
|
||||||
.buildTCPConnector()
|
|
||||||
.withHost(host)
|
|
||||||
.withRack(rack) //optional rack 是机架号
|
|
||||||
.withSlot(slot) //optional slot 是插槽号
|
|
||||||
.build();
|
|
||||||
return connector;
|
|
||||||
}catch (S7Exception e){
|
|
||||||
// logger.info("创建S7Connector 连接失败,原因:"+e.getMessage());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resetConnetctions(){
|
|
||||||
this.connections = new ArrayList<S7Connector>();
|
|
||||||
connectionPool();
|
|
||||||
}
|
|
||||||
|
|
||||||
private synchronized void connectionPool(){
|
|
||||||
for(int i=0;i<coreSize;i++){
|
|
||||||
S7Connector connect = connect(host, rack, slot);
|
|
||||||
if(connect!=null){
|
|
||||||
connections.add(connect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//todo 在plc上新增一个 变量来解决 心跳问题 okok
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,13 +16,10 @@ limitations under the License.
|
|||||||
package com.qgs.dc.s7.my.s7connector.impl.nodave;
|
package com.qgs.dc.s7.my.s7connector.impl.nodave;
|
||||||
|
|
||||||
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.exception.S7IOException;
|
import com.qgs.dc.s7.my.s7connector.exception.S7IOException;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Class TCPConnection.
|
* The Class TCPConnection.
|
||||||
*/
|
*/
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package com.qgs.dc.s7.retrydemo.forTest;
|
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.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.enmuc.S7ClientNew;
|
|
||||||
import com.qgs.dc.s7.my.s7connector.exception.S7ParseDataException;
|
import com.qgs.dc.s7.my.s7connector.exception.S7ParseDataException;
|
||||||
import com.qgs.dc.s7.my.s7connector.type.PlcVar;
|
import com.qgs.dc.s7.my.s7connector.type.PlcVar;
|
||||||
import org.apache.commons.lang3.RandomStringUtils;
|
import org.apache.commons.lang3.RandomStringUtils;
|
||||||
@ -15,7 +13,6 @@ import org.springframework.core.annotation.Order;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Random;
|
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
|
||||||
@ -35,7 +32,7 @@ public class InitialS7Thread implements ApplicationRunner {
|
|||||||
|
|
||||||
private ScheduledExecutorService executor;
|
private ScheduledExecutorService executor;
|
||||||
|
|
||||||
private void write(S7ClientNew s7Client,PlcVarActual var,Object newValue) {
|
private void write(S7Client s7Client, PlcVarActual var, Object newValue) {
|
||||||
if(var.getType().equals(PlcVar.STRING_Array)){
|
if(var.getType().equals(PlcVar.STRING_Array)){
|
||||||
String[] s = (String[])newValue;
|
String[] s = (String[])newValue;
|
||||||
String[] ss = (String[])newValue;
|
String[] ss = (String[])newValue;
|
||||||
@ -50,14 +47,8 @@ public class InitialS7Thread implements ApplicationRunner {
|
|||||||
s7Client.write(var.getArea(), var.getAreaNumber(), var.getByteOffset(), var.getBitOffset(), var.getStrSize(), var.getType(),newValue);
|
s7Client.write(var.getArea(), var.getAreaNumber(), var.getByteOffset(), var.getBitOffset(), var.getStrSize(), var.getType(),newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private Object read(S7ClientNew s7Client,PlcVarActual var) {
|
private Object read(S7Client s7Client, PlcVarActual var) {
|
||||||
try {
|
return s7Client.read(var.getArea(), var.getAreaNumber(), var.getByteOffset(), var.getBitOffset(), var.getLength(), var.getStrSize(), var.getType());
|
||||||
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
|
@Override
|
||||||
@ -68,7 +59,7 @@ public class InitialS7Thread implements ApplicationRunner {
|
|||||||
public void run() {
|
public void run() {
|
||||||
while (true){
|
while (true){
|
||||||
//read one
|
//read one
|
||||||
logger.info(Thread.currentThread().getName()+" , subId : "+Arrays.toString((String[])read(S7ClientNew.S7_1500,PlcVarActual.SubIdArrays)));
|
logger.info(Thread.currentThread().getName()+" , subId : "+Arrays.toString((String[])read(S7Client.S7_1500,PlcVarActual.SubIdArrays)));
|
||||||
try {
|
try {
|
||||||
Thread.sleep(300);
|
Thread.sleep(300);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@ -83,7 +74,7 @@ public class InitialS7Thread implements ApplicationRunner {
|
|||||||
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
write(S7ClientNew.S7_1500,PlcVarActual.SubIdArrays,toWrite);
|
write(S7Client.S7_1500,PlcVarActual.SubIdArrays,toWrite);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new S7ParseDataException(e);
|
throw new S7ParseDataException(e);
|
||||||
}
|
}
|
||||||
@ -95,7 +86,7 @@ public class InitialS7Thread implements ApplicationRunner {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while (true){
|
while (true){
|
||||||
logger.info(Thread.currentThread().getName()+" , subId : "+Arrays.toString((String[])read(S7ClientNew.S7_1500,PlcVarActual.SubIdArrays)));
|
logger.info(Thread.currentThread().getName()+" , subId : "+Arrays.toString((String[])read(S7Client.S7_1500,PlcVarActual.SubIdArrays)));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Thread.sleep(300);
|
Thread.sleep(300);
|
||||||
@ -110,7 +101,7 @@ public class InitialS7Thread implements ApplicationRunner {
|
|||||||
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
write(S7ClientNew.S7_15001,PlcVarActual.SubIdArrays,toWrite);
|
write(S7Client.S7_15001,PlcVarActual.SubIdArrays,toWrite);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new S7ParseDataException(e);
|
throw new S7ParseDataException(e);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package com.qgs.dc.s7.retrydemo.lock;
|
package com.qgs.dc.s7.retrydemo.lock;
|
||||||
|
|
||||||
import com.qgs.dc.s7.my.s7connector.enmuc.S7ClientNew;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Desc: ""
|
* @Desc: ""
|
||||||
* @Author: caixiang
|
* @Author: caixiang
|
||||||
@ -9,7 +7,7 @@ import com.qgs.dc.s7.my.s7connector.enmuc.S7ClientNew;
|
|||||||
*/
|
*/
|
||||||
public class LockDemo {
|
public class LockDemo {
|
||||||
|
|
||||||
//对象所
|
//对象锁
|
||||||
public synchronized void func1() {
|
public synchronized void func1() {
|
||||||
System.out.println("func1!");
|
System.out.println("func1!");
|
||||||
try {
|
try {
|
||||||
@ -25,7 +23,7 @@ public class LockDemo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
LockDemo test = new LockDemo();
|
|
||||||
LockDemo test2 = new LockDemo();
|
LockDemo test2 = new LockDemo();
|
||||||
Thread t1 = new Thread(() -> {
|
Thread t1 = new Thread(() -> {
|
||||||
// test.func1();
|
// test.func1();
|
||||||
|
Loading…
Reference in New Issue
Block a user