|
@@ -0,0 +1,145 @@
|
|
|
|
+package com.ruoyi.system.init;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
|
+import com.github.rholder.retry.*;
|
|
|
|
+import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
|
|
|
|
+import com.ruoyi.common.exception.ServiceException;
|
|
|
|
+import com.ruoyi.common.utils.StringUtils;
|
|
|
|
+import com.ruoyi.system.config.PlcConfig;
|
|
|
|
+import com.ruoyi.system.config.PlcProperties;
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
+import org.springframework.boot.CommandLineRunner;
|
|
|
|
+import org.springframework.core.annotation.Order;
|
|
|
|
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
|
+
|
|
|
|
+import javax.annotation.Resource;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.HashMap;
|
|
|
|
+import java.util.concurrent.ExecutionException;
|
|
|
|
+import java.util.concurrent.ScheduledExecutorService;
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ * plc连接
|
|
|
|
+ */
|
|
|
|
+@Component
|
|
|
|
+@Order(1)
|
|
|
|
+@Slf4j
|
|
|
|
+public class PlcConnectServiceRunner implements CommandLineRunner {
|
|
|
|
+
|
|
|
|
+ @Resource
|
|
|
|
+ private PlcProperties plcProperties;
|
|
|
|
+
|
|
|
|
+ @Resource
|
|
|
|
+ ThreadPoolTaskExecutor threadPoolTaskExecutor;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ @Resource
|
|
|
|
+ private ScheduledExecutorService scheduledExecutorService;
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void run(String... args) throws Exception {
|
|
|
|
+ initConnect();
|
|
|
|
+ log.info("PLC initialization complete!");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private HashMap<String, S7PLC> plcToolsMap = new HashMap<>();
|
|
|
|
+
|
|
|
|
+ private ArrayList<String> reTryPlc = new ArrayList<>();
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ * 初始化
|
|
|
|
+ */
|
|
|
|
+ private void initConnect() throws InterruptedException {
|
|
|
|
+ for (PlcConfig plcConfig : plcProperties.getPlcList()) {
|
|
|
|
+ if (plcConfig.getEnable()) {
|
|
|
|
+ log.info("初始化:{},ip:{}", plcConfig.getName(), plcConfig.getIp());
|
|
|
|
+ try {
|
|
|
|
+ S7PLC s7PLC = new S7PLC(plcConfig.getEPlcType(), plcConfig.getIp());
|
|
|
|
+ s7PLC.connect();
|
|
|
|
+ if (s7PLC.checkConnected()){
|
|
|
|
+ plcToolsMap.put(plcConfig.getName(),s7PLC);
|
|
|
|
+ log.info("plc:{},ip:{},The connection was successful",plcConfig.getName(),plcConfig.getIp());
|
|
|
|
+ }
|
|
|
|
+ }catch (Exception e){
|
|
|
|
+ log.info("plc:{},ip:{},Connection failed",plcConfig.getName(),plcConfig.getIp());
|
|
|
|
+ retry(plcConfig);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void retry(PlcConfig plcConfig) {
|
|
|
|
+ reTryPlc.add(plcConfig.getName());
|
|
|
|
+ threadPoolTaskExecutor.execute (() -> {
|
|
|
|
+ Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
|
|
|
|
+ .retryIfResult(Boolean.FALSE::equals)
|
|
|
|
+ .retryIfExceptionOfType(Exception.class)
|
|
|
|
+ .withStopStrategy(StopStrategies.neverStop())
|
|
|
|
+ .withWaitStrategy(WaitStrategies.fixedWait(7, TimeUnit.SECONDS))
|
|
|
|
+ .build();
|
|
|
|
+ try {
|
|
|
|
+ retryer.call(() -> {
|
|
|
|
+ log.info("重试:{},ip:{}", plcConfig.getName(), plcConfig.getIp());
|
|
|
|
+ try {
|
|
|
|
+ S7PLC s7PLC = new S7PLC(plcConfig.getEPlcType(), plcConfig.getIp());
|
|
|
|
+ s7PLC.connect();
|
|
|
|
+ if (s7PLC.checkConnected()){
|
|
|
|
+ plcToolsMap.put(plcConfig.getName(),s7PLC);
|
|
|
|
+ log.info("plc:{},ip:{},Retry the connection succeeded",plcConfig.getName(),plcConfig.getIp());
|
|
|
|
+ reTryPlc.remove(plcConfig.getName());
|
|
|
|
+ plcConnectsTheHeartbeat(plcConfig,s7PLC);
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }catch (Exception e){
|
|
|
|
+ log.info("plc:{},ip:{},Retry connection failed,meg:{}",plcConfig.getName(),plcConfig.getIp(),e.getMessage());
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ });
|
|
|
|
+ } catch (RetryException | ExecutionException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ * plc连接心跳
|
|
|
|
+ * @param plcConfig
|
|
|
|
+ * @param s7PLC
|
|
|
|
+ */
|
|
|
|
+ private void plcConnectsTheHeartbeat(PlcConfig plcConfig,S7PLC s7PLC){
|
|
|
|
+ String heartbeatAdd = plcConfig.getHeartbeat();
|
|
|
|
+ if (StringUtils.isNotEmpty(heartbeatAdd)){
|
|
|
|
+ scheduledExecutorService.scheduleWithFixedDelay(()->{
|
|
|
|
+ if (!reTryPlc.contains(plcConfig.getName())){
|
|
|
|
+ try {
|
|
|
|
+ byte b = s7PLC.readByte(plcConfig.getHeartbeat());
|
|
|
|
+ s7PLC.writeByte(plcConfig.getConfirmTheStatus(),b);
|
|
|
|
+ }catch (Exception e){
|
|
|
|
+ log.error("device:{},The connection is lost",plcConfig.getName());
|
|
|
|
+ retry(plcConfig);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },0,3,TimeUnit.SECONDS);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ *
|
|
|
|
+ * @param pclName plc设备名
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public S7PLC getPlcServer(String pclName) {
|
|
|
|
+ S7PLC s7PLC = plcToolsMap.get(pclName);
|
|
|
|
+ if(ObjectUtil.isNull(s7PLC)){
|
|
|
|
+ throw new ServiceException("The device is not connected");
|
|
|
|
+ }
|
|
|
|
+ return plcToolsMap.get(pclName);
|
|
|
|
+ }
|
|
|
|
+}
|