Ver Fonte

1.添加IHDSDK
2.L2调整与优化

wangxiaofei há 3 semanas atrás
pai
commit
afdc1b0f04
86 ficheiros alterados com 1564 adições e 299 exclusões
  1. 5 0
      taphole-admin/src/main/resources/application-prod.yml
  2. 5 0
      taphole-admin/src/main/resources/application-test.yml
  3. 8 0
      taphole-iron/pom.xml
  4. 17 6
      taphole-iron/src/main/java/com/sckj/iron/controller/TIronModelController.java
  5. 1 1
      taphole-iron/src/main/java/com/sckj/iron/entity/TIronData.java
  6. 4 2
      taphole-iron/src/main/java/com/sckj/iron/entity/TIronModel.java
  7. 1 1
      taphole-iron/src/main/java/com/sckj/iron/entity/TIronParam.java
  8. 3 3
      taphole-iron/src/main/java/com/sckj/iron/entity/TIronSchedule.java
  9. 1 1
      taphole-iron/src/main/java/com/sckj/iron/entity/TIronStepLog.java
  10. 65 2
      taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronModelServiceImpl.java
  11. 142 50
      taphole-iron/src/main/java/com/sckj/iron/socketio/DeviceEventListener.java
  12. 27 1
      taphole-iron/src/main/java/com/sckj/iron/socketio/PushData.java
  13. 1 1
      taphole-iron/src/main/java/com/sckj/iron/validate/TIronDataSearchScreenValidate.java
  14. 1 1
      taphole-iron/src/main/java/com/sckj/iron/validate/TIronDataSearchValidate.java
  15. 4 4
      taphole-iron/src/main/java/com/sckj/iron/validate/TIronModelCreateValidate.java
  16. 5 3
      taphole-iron/src/main/java/com/sckj/iron/validate/TIronModelSearchValidate.java
  17. 29 0
      taphole-iron/src/main/java/com/sckj/iron/validate/TIronModelTestValidate.java
  18. 4 3
      taphole-iron/src/main/java/com/sckj/iron/validate/TIronModelUpdateValidate.java
  19. 1 1
      taphole-iron/src/main/java/com/sckj/iron/validate/TL2DataCreateValidate.java
  20. 1 1
      taphole-iron/src/main/java/com/sckj/iron/validate/TL2DataSearchValidate.java
  21. 1 1
      taphole-iron/src/main/java/com/sckj/iron/validate/TL2DataUpdateValidate.java
  22. 1 1
      taphole-iron/src/main/java/com/sckj/iron/vo/TIronDataDetailVo.java
  23. 1 1
      taphole-iron/src/main/java/com/sckj/iron/vo/TIronDataListedVo.java
  24. 4 3
      taphole-iron/src/main/java/com/sckj/iron/vo/TIronModelDetailVo.java
  25. 4 3
      taphole-iron/src/main/java/com/sckj/iron/vo/TIronModelListedVo.java
  26. 1 1
      taphole-iron/src/main/java/com/sckj/iron/vo/TIronParamDetailVo.java
  27. 1 1
      taphole-iron/src/main/java/com/sckj/iron/vo/TIronParamListedVo.java
  28. 1 1
      taphole-iron/src/main/java/com/sckj/iron/vo/TL2DataDetailVo.java
  29. 1 1
      taphole-iron/src/main/java/com/sckj/iron/vo/TL2DataListedVo.java
  30. BIN
      taphole-iron/src/main/resources/jar/hd-datasdk-3.9.3.jar
  31. 12 0
      taphole-l2/src/main/java/com/sckj/l2/controller/TL2DataController.java
  32. 94 80
      taphole-l2/src/main/java/com/sckj/l2/dto/L2Data.java
  33. 1 26
      taphole-l2/src/main/java/com/sckj/l2/dto/L2Material.java
  34. 48 0
      taphole-l2/src/main/java/com/sckj/l2/dto/L2Properties.java
  35. 1 1
      taphole-l2/src/main/java/com/sckj/l2/entity/TL2Data.java
  36. 2 9
      taphole-l2/src/main/java/com/sckj/l2/entity/TL2Material.java
  37. 101 61
      taphole-l2/src/main/java/com/sckj/l2/service/impl/L2DataServiceImpl.java
  38. 1 1
      taphole-opc-start/src/main/java/com/sckj/opcstart/TapholeOpcStartApplication.java
  39. 7 1
      taphole-opc/pom.xml
  40. 1 1
      taphole-opc/src/main/java/com/sckj/opc/controller/OPCDAController.java
  41. 1 1
      taphole-opc/src/main/java/com/sckj/opc/controller/OPCUAController.java
  42. 194 0
      taphole-opc/src/main/java/com/sckj/opc/controller/THdTagController.java
  43. 191 0
      taphole-opc/src/main/java/com/sckj/opc/dataservice/HDServiceImpl.java
  44. 1 1
      taphole-opc/src/main/java/com/sckj/opc/dataservice/OPCDAServiceImpl.java
  45. 1 1
      taphole-opc/src/main/java/com/sckj/opc/dataservice/OPCUAServiceImpl.java
  46. 32 0
      taphole-opc/src/main/java/com/sckj/opc/dto/HdTagDTO.java
  47. 1 2
      taphole-opc/src/main/java/com/sckj/opc/entity/OPCPoint.java
  48. 4 2
      taphole-opc/src/main/java/com/sckj/opc/entity/OPCServer.java
  49. 66 0
      taphole-opc/src/main/java/com/sckj/opc/entity/THdTag.java
  50. 29 0
      taphole-opc/src/main/java/com/sckj/opc/mapper/THdTagMapper.java
  51. 173 0
      taphole-opc/src/main/java/com/sckj/opc/service/THdTagServiceImpl.java
  52. 39 0
      taphole-opc/src/main/java/com/sckj/opc/validate/THdTagCreateValidate.java
  53. 39 0
      taphole-opc/src/main/java/com/sckj/opc/validate/THdTagSearchValidate.java
  54. 46 0
      taphole-opc/src/main/java/com/sckj/opc/validate/THdTagUpdateValidate.java
  55. 5 3
      taphole-opc/src/main/java/com/sckj/opc/validate/TOpcServerCreateValidate.java
  56. 5 3
      taphole-opc/src/main/java/com/sckj/opc/validate/TOpcServerSearchValidate.java
  57. 3 0
      taphole-opc/src/main/java/com/sckj/opc/validate/TOpcServerUpdateValidate.java
  58. 45 0
      taphole-opc/src/main/java/com/sckj/opc/vo/THdTagDetailVo.java
  59. 45 0
      taphole-opc/src/main/java/com/sckj/opc/vo/THdTagListedVo.java
  60. BIN
      taphole-opc/src/main/resources/jar/hd-datasdk-3.9.3.jar
  61. BIN
      taphole-opc/src/main/resources/lib/hd/linux/libLogC.so.1.0.0
  62. BIN
      taphole-opc/src/main/resources/lib/hd/linux/libhdDNAPI.so.1.0.0
  63. BIN
      taphole-opc/src/main/resources/lib/hd/linux/libhdDataSDK.so.1.0.0
  64. BIN
      taphole-opc/src/main/resources/lib/hd/linux/libhdKingAPI.so.1.0.0
  65. BIN
      taphole-opc/src/main/resources/lib/hd/linux/libhdNetClient.so.1.0.0
  66. BIN
      taphole-opc/src/main/resources/lib/hd/linux/libhdOS.so.1.0.0
  67. BIN
      taphole-opc/src/main/resources/lib/hd/linux/libhdProcComm.so.1.0.0
  68. BIN
      taphole-opc/src/main/resources/lib/hd/win/hdBufferAPI.lib
  69. BIN
      taphole-opc/src/main/resources/lib/hd/win/hdDNAPI.dll
  70. BIN
      taphole-opc/src/main/resources/lib/hd/win/hdDataSDK.dll
  71. BIN
      taphole-opc/src/main/resources/lib/hd/win/hdKingAPI.dll
  72. BIN
      taphole-opc/src/main/resources/lib/hd/win/hdKingAPI.lib
  73. BIN
      taphole-opc/src/main/resources/lib/hd/win/hdNetClient.dll
  74. BIN
      taphole-opc/src/main/resources/lib/hd/win/hdOS.dll
  75. BIN
      taphole-opc/src/main/resources/lib/hd/win/hdOS.lib
  76. BIN
      taphole-opc/src/main/resources/lib/hd/win/hdProcComm.dll
  77. 25 0
      taphole-opc/src/main/resources/mapper/HdTagMapper.xml
  78. 1 1
      taphole-warn/src/main/java/com/sckj/warn/entity/TExceptionLog.java
  79. 2 1
      taphole-warn/src/main/java/com/sckj/warn/service/impl/TExceptionLogServiceImpl.java
  80. 2 3
      taphole-warn/src/main/java/com/sckj/warn/validate/TAudioCreateValidate.java
  81. 0 1
      taphole-warn/src/main/java/com/sckj/warn/validate/TAudioUpdateValidate.java
  82. 1 1
      taphole-warn/src/main/java/com/sckj/warn/validate/TExceptionLogCreateValidate.java
  83. 1 1
      taphole-warn/src/main/java/com/sckj/warn/validate/TExceptionLogSearchValidate.java
  84. 1 1
      taphole-warn/src/main/java/com/sckj/warn/vo/TExceptionLogDetailVo.java
  85. 2 2
      taphole-warn/src/main/java/com/sckj/warn/vo/TExceptionLogExportVo.java
  86. 1 1
      taphole-warn/src/main/java/com/sckj/warn/vo/TExceptionLogListedVo.java

+ 5 - 0
taphole-admin/src/main/resources/application-prod.yml

@@ -1,6 +1,11 @@
 # 项目配置
 like:
   upload-directory: /home/taphole/upload # 上传目录
+  l2:
+    host: 168.15.14.1
+    port: 4567
+    maxRetries: 10
+    retryInterval: 5000
 
 # 服务配置
 server:

+ 5 - 0
taphole-admin/src/main/resources/application-test.yml

@@ -1,6 +1,11 @@
 # 项目配置
 like:
   upload-directory: /home/document/taphole/target/ # 上传目录
+  l2:
+    host: 168.15.14.1
+    port: 4567
+    maxRetries: 10
+    retryInterval: 5000
 
 # 服务配置
 server:

+ 8 - 0
taphole-iron/pom.xml

@@ -65,6 +65,14 @@
             <scope>system</scope>
             <systemPath>${project.basedir}/src/main/resources/jar/examples.jar</systemPath>
         </dependency>
+
+<!--        <dependency>-->
+<!--            <groupId>com.baosight</groupId>-->
+<!--            <artifactId>jna</artifactId>-->
+<!--            <version>3.9.3</version>-->
+<!--            <scope>system</scope>-->
+<!--            <systemPath>${project.basedir}/src/main/resources/jar/hd-datasdk-3.9.3.jar</systemPath>-->
+<!--        </dependency>-->
     </dependencies>
 
 </project>

+ 17 - 6
taphole-iron/src/main/java/com/sckj/iron/controller/TIronModelController.java

@@ -4,16 +4,15 @@ import com.sckj.common.aop.Log;
 import com.sckj.common.aop.NotPower;
 import com.sckj.common.core.AjaxResult;
 import com.sckj.common.core.PageResult;
-import com.sckj.common.enums.RefreshItemEnum;
 import com.sckj.common.validate.commons.IdValidate;
 import com.sckj.common.validate.commons.PageValidate;
-import com.sckj.common.validator.annotation.IDMust;
 import com.sckj.iron.service.impl.TIronModelServiceImpl;
-import com.sckj.iron.validate.*;
+import com.sckj.iron.validate.TIronModelCreateValidate;
+import com.sckj.iron.validate.TIronModelSearchValidate;
+import com.sckj.iron.validate.TIronModelTestValidate;
+import com.sckj.iron.validate.TIronModelUpdateValidate;
 import com.sckj.iron.vo.TIronModelDetailVo;
 import com.sckj.iron.vo.TIronModelListedVo;
-import com.sckj.iron.vo.TIronParamDetailVo;
-import com.sckj.iron.vo.TIronParamListedVo;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.validation.annotation.Validated;
@@ -21,7 +20,6 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
-import java.util.List;
 
 @RestController
 @RequestMapping("api/model")
@@ -80,4 +78,17 @@ public class TIronModelController {
         return AjaxResult.success(LocalDateTime.now());
     }
 
+
+    @Log(title = "出铁相关模型测试")
+    @PostMapping("/test")
+    @ApiOperation(value = "出铁相关模型编辑")
+    public AjaxResult test(@Validated @RequestBody TIronModelTestValidate testValidate) {
+        try {
+            return AjaxResult.success(iTIronModelService.test(testValidate));
+        } catch (Exception e) {
+            e.printStackTrace();
+            return AjaxResult.failed(e.getMessage());
+        }
+    }
+
 }

+ 1 - 1
taphole-iron/src/main/java/com/sckj/iron/entity/TIronData.java

@@ -36,7 +36,7 @@ public class TIronData implements Serializable {
     @ExcelIgnore
     private Long id;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     @ExcelIgnore
     private String boilerId;
 

+ 4 - 2
taphole-iron/src/main/java/com/sckj/iron/entity/TIronModel.java

@@ -8,7 +8,6 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.io.Serializable;
-import java.util.Date;
 
 @Data
 @ApiModel("出铁相关模型")
@@ -36,7 +35,7 @@ public class TIronModel implements Serializable {
     @ApiModelProperty(value = "铁口区域编号")
     private String tapholeId;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @ApiModelProperty(value = "参数名称")
@@ -57,4 +56,7 @@ public class TIronModel implements Serializable {
     @ApiModelProperty(value = "排序")
     private Integer sort;
 
+    @ApiModelProperty(value = "音频外键")
+    private Long audioId;
+
 }

+ 1 - 1
taphole-iron/src/main/java/com/sckj/iron/entity/TIronParam.java

@@ -37,7 +37,7 @@ public class TIronParam implements Serializable {
     @ApiModelProperty(value = "铁口区域编号")
     private String tapholeId;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @ApiModelProperty(value = "参数类型")

+ 3 - 3
taphole-iron/src/main/java/com/sckj/iron/entity/TIronSchedule.java

@@ -51,11 +51,11 @@ public class TIronSchedule implements Serializable {
     @ApiModelProperty(value = "排序")
     private Long sort;
 
-    @ApiModelProperty(value = "炉编号")
-    private Long boilerId;
+    @ApiModelProperty(value = "炉编号")
+    private String boilerId;
 
     @ApiModelProperty(value = "铁口区域编号")
-    private Long tapholeId;
+    private String tapholeId;
 
     @ApiModelProperty(value = "备注信息")
     private String remark;

+ 1 - 1
taphole-iron/src/main/java/com/sckj/iron/entity/TIronStepLog.java

@@ -54,7 +54,7 @@ public class TIronStepLog  implements Serializable {
     @ApiModelProperty(value = "通过结果(1通过、0未通过)")
     private int passResult;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     @ExcelIgnore
     private String boilerId;
 

+ 65 - 2
taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronModelServiceImpl.java

@@ -17,12 +17,16 @@ import com.sckj.iron.entity.TIronParam;
 import com.sckj.iron.mapper.TIronModelMapper;
 import com.sckj.iron.validate.TIronModelCreateValidate;
 import com.sckj.iron.validate.TIronModelSearchValidate;
+import com.sckj.iron.validate.TIronModelTestValidate;
 import com.sckj.iron.validate.TIronModelUpdateValidate;
 import com.sckj.iron.vo.TIronModelDetailVo;
 import com.sckj.iron.vo.TIronModelListedVo;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.beans.BeanUtils;
+import org.springframework.expression.Expression;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
 import org.springframework.stereotype.Service;
 import org.springframework.util.Assert;
 
@@ -34,6 +38,7 @@ import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 参数设定实现类
@@ -120,6 +125,13 @@ public class TIronModelServiceImpl extends ServiceImpl<TIronModelMapper, TIronMo
      * @author LikeAdmin
      */
     public void add(TIronModelCreateValidate createValidate) {
+        TIronModel repeatModel = tIronModelMapper.selectOne(
+                new QueryWrapper<TIronModel>()
+                        .eq("model_name", createValidate.getModelName())
+                        .last("limit 1"));
+
+        Assert.notNull(repeatModel, "模型名称不能重复!");
+
         TIronModel model = new TIronModel();
         model.setCreateBy(String.valueOf(TapholeAdminThreadLocal.getAdminUsername()));
         model.setModelName(createValidate.getModelName());
@@ -173,7 +185,7 @@ public class TIronModelServiceImpl extends ServiceImpl<TIronModelMapper, TIronMo
                 for (String line : lines) {
                     content.append(line);
                 }
-                log.info("读取的模型文件为:{}",content.toString());
+                log.info("读取的模型文件为:{}", content.toString());
                 //随机生成密码
 //                String generateRandomKey = AES.generateRandomKey();
                 //加密
@@ -181,7 +193,7 @@ public class TIronModelServiceImpl extends ServiceImpl<TIronModelMapper, TIronMo
                 //解密
                 TIronParam modelKey = ironParamService.lambdaQuery().eq(TIronParam::getParamName, "model_key").one();
                 String key = "bg@CN_9999_8888";
-                if(ObjectUtils.isNotEmpty(modelKey) && ObjectUtils.isNotEmpty(modelKey.getParamValue()) ){
+                if (ObjectUtils.isNotEmpty(modelKey) && ObjectUtils.isNotEmpty(modelKey.getParamValue())) {
                     key = modelKey.getParamValue();
                 }
                 String decrypt = AES.decrypt(content.toString(), key);
@@ -219,4 +231,55 @@ public class TIronModelServiceImpl extends ServiceImpl<TIronModelMapper, TIronMo
         asyncEventBus.post(RefreshItemEnum.PARAM);
     }
 
+
+    /**
+     * 出铁相关模型测试
+     *
+     * @param testValidate 参数
+     * @author LikeAdmin
+     */
+    public Object test(TIronModelTestValidate testValidate) {
+        log.info("加载到了{}", testValidate);
+        TIronModel model = tIronModelMapper.selectOne(
+                new QueryWrapper<TIronModel>()
+                        .eq("id", testValidate.getId())
+                        .last("limit 1"));
+
+        Assert.notNull(model, "数据不存在!");
+
+        String modelExpression = model.getModelExpression();
+        log.info("打泥量计算公式:{}", modelExpression);
+        SpelExpressionParser parser = new SpelExpressionParser();
+        Expression expression = parser.parseExpression(modelExpression);
+        StandardEvaluationContext context = new StandardEvaluationContext();
+
+        for (Map<String, Object> entry : testValidate.getKeyValue()) {
+            Object value = entry.get("value");
+            // 设置占位符对应的值
+            switch (entry.getOrDefault("type", "0").toString()) {
+                case "0":
+                    value = value.toString();
+                    break;
+                case "1":
+                    value = Long.valueOf(value.toString());
+                    break;
+                case "2":
+                    value = Double.valueOf(value.toString());
+                    break;
+                case "3":
+                    value= Boolean.valueOf(value.toString());
+                    break;
+            }
+            context.setVariable(entry.getOrDefault("name","").toString(), value);
+        }
+        //计算打泥量
+        //计算理论铁量= 矿批 × 综合品位 × 1.06,其中矿批是指L2中的干量
+        Object result = expression.getValue(context);
+
+        log.info(">>>{}", result);
+
+        return result;
+
+    }
+
 }

+ 142 - 50
taphole-iron/src/main/java/com/sckj/iron/socketio/DeviceEventListener.java

@@ -31,7 +31,7 @@ import com.sckj.l2.entity.TL2Material;
 import com.sckj.l2.service.impl.L2DataServiceImpl;
 import com.sckj.l2.service.impl.TL2DataServiceImpl;
 import com.sckj.l2.service.impl.TL2MaterialServiceImpl;
-import com.sckj.opc.dauaservice.OPCDAServiceImpl;
+import com.sckj.opc.dataservice.OPCDAServiceImpl;
 import com.sckj.opc.entity.OPCData;
 import com.sckj.opc.service.OPCDataServiceImpl;
 import com.sckj.opc.utils.CustomUtil;
@@ -59,7 +59,6 @@ import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
@@ -174,23 +173,17 @@ public class DeviceEventListener extends EventListener { //
 
     //铁口出铁状态
     //1 出铁中    0 出铁结束
-    private AtomicBoolean ironLoading1 = new AtomicBoolean(false);
+    private AtomicInteger ironLoading1 = new AtomicInteger(0);
     //
-    private AtomicBoolean ironLoading2 = new AtomicBoolean(false);
+    private AtomicInteger ironLoading2 = new AtomicInteger(0);
     //
-    private AtomicBoolean ironLoading3 = new AtomicBoolean(false);
+    private AtomicInteger ironLoading3 = new AtomicInteger(0);
     //
-    private AtomicBoolean ironLoading4 = new AtomicBoolean(false);
+    private AtomicInteger ironLoading4 = new AtomicInteger(0);
 
     //出铁步骤
     private List<IronStepVO> mSteps;
 
-    //出铁参数
-//    private Map<String, TIronParam> mIronParamMap;
-
-    //出铁参数
-//    private Map<String, TAudio> mIronAlarmMap;
-
     private String openAlarmUrl;
 
     private String closureAlarmUrl;
@@ -221,13 +214,20 @@ public class DeviceEventListener extends EventListener { //
     //出铁时间
     private AtomicDouble IRON_TIME = new AtomicDouble(0);
 
+    //实时温度最大值
+    private AtomicDouble tempMax = new AtomicDouble(0);
+
+    //实时温度最小值
+    private AtomicDouble tempMin = new AtomicDouble(0);
+
+
     private String SERVER_URL = "";
 
     //实时出铁总重量/总流量
     private BigDecimal mTotalWeight = BigDecimal.ZERO;
     //总干量
 //    private BigDecimal mTotalDry = BigDecimal.ZERO;
-    //耗时(单位:s)
+    //出铁耗时(单位:秒)
     private AtomicInteger mSecondsElapsed = new AtomicInteger(0);
 
     //redis保存最多数量数据
@@ -270,20 +270,30 @@ public class DeviceEventListener extends EventListener { //
     //打泥量选择公式
     private TIronModel modelHitMud;
 
+    /// 堵口预警
+    private TIronModel modelClosureWarn1;
+    private TIronModel modelClosureWarn2;
+    private TIronModel modelClosureWarn3;
+
+    //出铁诊断
+    private TIronModel modelTappingTest;
+
+
     /***
      * 更新模型
      */
     private void getModels() {
-        modelHitMud = ironModelService.getById(1);
+        modelHitMud = ironModelService.lambdaQuery().eq(TIronModel::getModelName, "hit_mud").one();
+        modelClosureWarn1 = ironModelService.lambdaQuery().eq(TIronModel::getModelName, "closure_warn1").one();
+        modelClosureWarn2 = ironModelService.lambdaQuery().eq(TIronModel::getModelName, "closure_warn2").one();
+        modelClosureWarn3 = ironModelService.lambdaQuery().eq(TIronModel::getModelName, "closure_warn3").one();
+        modelTappingTest = ironModelService.lambdaQuery().eq(TIronModel::getModelName, "tapping_test").one();
     }
 
     private void getAudios() {
         List<TAudio> list = audioService.lambdaQuery().eq(TAudio::getStatus, "1").eq(TAudio::getDelFlag, "1").list();
         if (ObjectUtils.isNotEmpty(list)) {
             for (TAudio tAudio : list) {
-//                if (Objects.equals(tAudio.getExceptionType(), TaskNameConstants.TASKNAME_OPEN_WARN)) {
-//                    alarmUrlOpen = SERVER_URL + "/" + GlobalConfig.publicPrefix + File.separator + tAudio.getPath();
-//                } else
                 if (Objects.equals(tAudio.getExceptionType(), "100")) {
                     closureAlarmUrl = SERVER_URL + "/" + GlobalConfig.publicPrefix + File.separator + tAudio.getPath();
                 } else if (Objects.equals(tAudio.getExceptionType(), "200")) {
@@ -389,7 +399,7 @@ public class DeviceEventListener extends EventListener { //
     }
 
     //出铁次数编号
-    private Long mIronNo;
+    private String mIronNo;
 
     /***
      * L2数据项
@@ -518,6 +528,14 @@ public class DeviceEventListener extends EventListener { //
     }
 
     /***
+     * 返回出铁计时开始,单位分钟
+     * @return
+     */
+    private int getIronElapsedMinute() {
+        return mSecondsElapsed.get() / 60;
+    }
+
+    /***
      * 出铁计时
      */
     private void getIronTime() {
@@ -558,36 +576,77 @@ public class DeviceEventListener extends EventListener { //
             //堵口预警
             scheduledTaskManager.addTask(scheduleClosureWarn.getName(), scheduleClosureWarn.getDelay(), scheduleClosureWarn.getPeriod(), TimeUnit.SECONDS, () -> {
                 //堵口预警
-
-                if (speed1.get() > STANDARD_SPEED.get() || speed2.get() > STANDARD_SPEED.get()) {
-                    log.info("堵口预警:【speed1】:{},【speed2】:{},【standard_speed】:{},", speed1.get(), speed2.get(), STANDARD_SPEED.get());
-
+                String modelExpression1 = modelClosureWarn1.getModelExpression();
+
+                SpelExpressionParser parser = new SpelExpressionParser();
+                Expression expression1 = parser.parseExpression(modelExpression1);
+
+                StandardEvaluationContext context = new StandardEvaluationContext();
+                // 设置占位符对应的值
+                context.setVariable("ironSpeed", speed1.get() > speed2.get() ? speed1.get() : speed2.get());
+                context.setVariable("iron01State", ironLoading1);
+                context.setVariable("iron02State", ironLoading2);
+                context.setVariable("iron03State", ironLoading3);
+                context.setVariable("iron04State", ironLoading4);
+                context.setVariable("standardSpeed", STANDARD_SPEED.get());
+                //计算打泥量
+                //计算理论铁量= 矿批 × 综合品位 × 1.06,其中矿批是指L2中的干量
+                boolean result1 = expression1.getValue(context, Boolean.class);
+
+                if (result1) {
                     //流速过大可能是由于铁口深度不足或发生跑大流问题,则提示将当前铁口堵口
                     PushData.send2Warn(WarnData.warnClose("流速过快,请将当前铁口堵口", closureAlarmUrl));
                     taskExecutor.submit(() -> {
                         exceptionLogService.add(TExceptionLogCreateValidate.builder().exceptionType("4").exceptionDesc("流速过快,请将当前铁口堵口").build());
                     });
-                } else if ((speed1.get() < STANDARD_SPEED.get() || speed2.get() < STANDARD_SPEED.get()) && (ironLoading2.get() || ironLoading3.get() || ironLoading4.get())) {
-                    log.info("堵口预警一:【speed1】:{},【speed2】:{},【standard_speed】:{},", speed1.get(), speed2.get(), STANDARD_SPEED.get());
-                    log.info("堵口预警一:【ironLoading1】:{},【ironLoading2】:{},【ironLoading3】:{},【ironLoading4】:{}", ironLoading1.get(), ironLoading2.get(), ironLoading3.get(), ironLoading4.get());
+                    return;
+                }
 
+                String modelExpression2 = modelClosureWarn2.getModelExpression();
+                Expression expression2 = parser.parseExpression(modelExpression2);
+                boolean result2 = expression2.getValue(context, Boolean.class);
+                if (result2) {
 
-                    //若流速过小,但其它铁口正在出铁,则提示将当前铁口堵口
-                    PushData.send2Warn(WarnData.warnClose("流速过小,请将当前铁口堵口", closureAlarmUrl));
-                    taskExecutor.submit(() -> {
-                        exceptionLogService.add(TExceptionLogCreateValidate.builder().exceptionType("4").exceptionDesc("流速过小,请将当前铁口堵口").build());
-                    });
-                } else if ((speed1.get() < STANDARD_SPEED.get() || speed2.get() < STANDARD_SPEED.get()) && (!ironLoading2.get() && !ironLoading3.get() && !ironLoading4.get())) {
-                    log.info("堵口预警二:【speed1】:{},【speed2】:{},【standard_speed】:{},", speed1.get(), speed2.get(), STANDARD_SPEED.get());
-                    log.info("堵口预警二:【ironLoading1】:{},【ironLoading2】:{},【ironLoading3】:{},【ironLoading4】:{}", ironLoading1.get(), ironLoading2.get(), ironLoading3.get(), ironLoading4.get());
+                    return;
+                }
 
+                String modelExpression3 = modelClosureWarn3.getModelExpression();
+                Expression expression3 = parser.parseExpression(modelExpression3);
+                boolean result3 = expression3.getValue(context, Boolean.class);
+
+                if (result3) {
 
-                    //若流速过小且其他铁口均未出铁,则提示先将其它铁口打开,再进行堵口
-                    PushData.send2Warn(WarnData.warnClose("请先打开其它铁口,再堵口", closureAlarmUrl));
-                    taskExecutor.submit(() -> {
-                        exceptionLogService.add(TExceptionLogCreateValidate.builder().exceptionType("4").exceptionDesc("请先打开其它铁口,再堵口").build());
-                    });
                 }
+
+//                if (speed1.get() > STANDARD_SPEED.get() || speed2.get() > STANDARD_SPEED.get()) {
+//                    log.info("堵口预警:【speed1】:{},【speed2】:{},【standard_speed】:{},", speed1.get(), speed2.get(), STANDARD_SPEED.get());
+//
+//                    //流速过大可能是由于铁口深度不足或发生跑大流问题,则提示将当前铁口堵口
+//                    PushData.send2Warn(WarnData.warnClose("流速过快,请将当前铁口堵口", closureAlarmUrl));
+//                    taskExecutor.submit(() -> {
+//                        exceptionLogService.add(TExceptionLogCreateValidate.builder().exceptionType("4").exceptionDesc("流速过快,请将当前铁口堵口").build());
+//                    });
+//                } else if ((speed1.get() < STANDARD_SPEED.get() || speed2.get() < STANDARD_SPEED.get()) && (ironLoading2.get() || ironLoading3.get() || ironLoading4.get())) {
+//                    log.info("堵口预警一:【speed1】:{},【speed2】:{},【standard_speed】:{},", speed1.get(), speed2.get(), STANDARD_SPEED.get());
+//                    log.info("堵口预警一:【ironLoading1】:{},【ironLoading2】:{},【ironLoading3】:{},【ironLoading4】:{}", ironLoading1.get(), ironLoading2.get(), ironLoading3.get(), ironLoading4.get());
+//
+//
+//                    //若流速过小,但其它铁口正在出铁,则提示将当前铁口堵口
+//                    PushData.send2Warn(WarnData.warnClose("流速过小,请将当前铁口堵口", closureAlarmUrl));
+//                    taskExecutor.submit(() -> {
+//                        exceptionLogService.add(TExceptionLogCreateValidate.builder().exceptionType("4").exceptionDesc("流速过小,请将当前铁口堵口").build());
+//                    });
+//                } else if ((speed1.get() < STANDARD_SPEED.get() || speed2.get() < STANDARD_SPEED.get()) && (!ironLoading2.get() && !ironLoading3.get() && !ironLoading4.get())) {
+//                    log.info("堵口预警二:【speed1】:{},【speed2】:{},【standard_speed】:{},", speed1.get(), speed2.get(), STANDARD_SPEED.get());
+//                    log.info("堵口预警二:【ironLoading1】:{},【ironLoading2】:{},【ironLoading3】:{},【ironLoading4】:{}", ironLoading1.get(), ironLoading2.get(), ironLoading3.get(), ironLoading4.get());
+//
+//
+//                    //若流速过小且其他铁口均未出铁,则提示先将其它铁口打开,再进行堵口
+//                    PushData.send2Warn(WarnData.warnClose("请先打开其它铁口,再堵口", closureAlarmUrl));
+//                    taskExecutor.submit(() -> {
+//                        exceptionLogService.add(TExceptionLogCreateValidate.builder().exceptionType("4").exceptionDesc("请先打开其它铁口,再堵口").build());
+//                    });
+//                }
             });
         }
 
@@ -602,7 +661,7 @@ public class DeviceEventListener extends EventListener { //
                 if (ObjectUtils.isNotEmpty(tappingData) && ObjectUtils.isNotEmpty(modelHitMud)) {
                     log.info("开口深度openDepth(mm):{}", tappingData.getOpenDepth());
                     log.info("Tap对应铁水估计铁量ironWeight(t): {}", tappingData.getTheoryWeight());
-                    log.info("出铁时间ironCosttime(min): {}", mSecondsElapsed.get() / 60);
+                    log.info("出铁时间ironCosttime(min): {}", getIronElapsedMinute());
                     log.info("平均流速ironSpeed(t/s): {}", speed1.get() > speed2.get() ? speed1.get() : speed2.get());
 
                     try {
@@ -614,7 +673,7 @@ public class DeviceEventListener extends EventListener { //
                         // 设置占位符对应的值
                         context.setVariable("openDepth", tappingData.getOpenDepth());
                         context.setVariable("ironWeight", tappingData.getTheoryWeight());
-                        context.setVariable("ironCosttime", mSecondsElapsed.get() / 60);
+                        context.setVariable("ironCosttime", getIronElapsedMinute());
                         context.setVariable("ironSpeed", speed1.get() > speed2.get() ? speed1.get() : speed2.get());
                         //计算打泥量
                         //计算理论铁量= 矿批 × 综合品位 × 1.06,其中矿批是指L2中的干量
@@ -623,6 +682,7 @@ public class DeviceEventListener extends EventListener { //
 //                    DecimalFormat decimalFormat = new DecimalFormat("#.00");
 //                    String formattedResult = decimalFormat.format(result);
                         log.info("计算结果: {}", result);
+                        PushData.send2IronHitMud(result);
                     } catch (Exception e) {
                         e.printStackTrace();
                     }
@@ -648,7 +708,6 @@ public class DeviceEventListener extends EventListener { //
             });
         }
 
-
     }
 
 
@@ -690,13 +749,35 @@ public class DeviceEventListener extends EventListener { //
                 //出铁时间
                 //String ironCosttime = fixedLatestElement.getI
                 //实际出铁量
-                Double ironWeight = fixedLatestElement.getIronWeight();
+                String ironWeight = fixedLatestElement.getIronWeight();
 
 //            TIronData ironData = new TIronData();
 //            BeanUtils.copyProperties(ironData, fixedLatestElement);
 //
 //            ironDataService.save(ironData);
 
+                try {
+                    String modelExpression = modelTappingTest.getModelExpression();
+                    if (ObjectUtils.isNotEmpty(modelExpression)) {
+                        log.info("出铁诊断计算公式:{}", modelExpression);
+                        SpelExpressionParser parser = new SpelExpressionParser();
+                        Expression expression = parser.parseExpression(modelExpression);
+                        StandardEvaluationContext context = new StandardEvaluationContext();
+                        // 设置占位符对应的值
+                        context.setVariable("ironTime", getIronElapsedMinute());
+                        context.setVariable("ironWeight", mTotalWeight.doubleValue());
+                        context.setVariable("ironSpeed", mTotalWeight.doubleValue() / (getIronElapsedMinute() == 0 ? 1 : getIronElapsedMinute()));
+                        context.setVariable("ironTempChange", tempMax.get() - tempMin.get());
+                        String result = expression.getValue(context, String.class);
+                        // 使用 DecimalFormat 保留两位小数
+//                      DecimalFormat decimalFormat = new DecimalFormat("#.00");
+//                      String formattedResult = decimalFormat.format(result);
+                        log.info("出铁诊断结果:{}", result);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+
                 scheduledTaskManager.cancelTask(TaskNameConstants.TASKNAME_TAPPING_TEST);
             });
         }
@@ -708,7 +789,7 @@ public class DeviceEventListener extends EventListener { //
                 double ldyl = Double.parseDouble(ObjectUtils.defaultIfNull(mContext.lookupVariable("ldyl"), "0").toString());
                 double yc = sfyl - ldyl;
                 log.info("出铁预警:压差:{},标准压差:{},L1出铁状态:{}", yc, PRESSURE_DIFF_VALUE.get(), ironLoading1.get());
-                if (PRESSURE_DIFF_VALUE.get() < yc && !ironLoading1.get()) {
+                if (PRESSURE_DIFF_VALUE.get() < yc && ironLoading1.get() == 0) {
                     PushData.send2Warn(WarnData.warnTapping("压差超过阈值,请出铁", tappingAlramUrl));
                     exceptionLogService.add(TExceptionLogCreateValidate.builder().exceptionType("4").exceptionDesc("压差超过阈值,请出铁").build());
                 } else {
@@ -750,6 +831,17 @@ public class DeviceEventListener extends EventListener { //
                 realtimeData.setTime(LocalDateUtils.formatDate(opcData.getServerTime()));
                 mRealtimeData.put(IRON_TEMP, realtimeData);
 
+                double tempNow = Double.parseDouble(opcData.getData().toString());
+
+                if (tempMax.get() == 0 || tempNow > tempMax.get()) {
+                    tempMax.set(tempNow);
+                }
+
+                if (tempMin.get() == 0 || tempNow < tempMin.get()) {
+                    tempMin.set(tempNow);
+                }
+
+
             } else if (opcData.getPointName().contains(L1TagConstants.TAG_CAR11) || opcData.getPointName().contains(L1TagConstants.TAG_CAR12)) {
                 //1TH-1号车受铁速度
                 RealtimeData realtimeData = new RealtimeData();
@@ -792,22 +884,22 @@ public class DeviceEventListener extends EventListener { //
                 realtimeData.setDesc("出铁状态");
                 mRealtimeStatus.put(IRON_STATUS, realtimeData);
 
-                ironLoading1.set("1".equals(opcData.getData().toString()));
+                ironLoading1.set(Integer.parseInt(opcData.getData().toString()));
 
-                if (ironLoading1.get()) {
+                if (ironLoading1.get() == 1) {
                     taphole1Start();
                 } else {
                     taphole1End();
                 }
 
             } else if (opcData.getPointName().contains(L1TagConstants.TAG_TAPHOLE2_STATUS)) {
-                ironLoading2.set("1".equals(opcData.getData().toString()));
+                ironLoading2.set(Integer.parseInt(opcData.getData().toString()));
 
             } else if (opcData.getPointName().contains(L1TagConstants.TAG_TAPHOLE3_STATUS)) {
-                ironLoading3.set("1".equals(opcData.getData().toString()));
+                ironLoading3.set(Integer.parseInt(opcData.getData().toString()));
 
             } else if (opcData.getPointName().contains(L1TagConstants.TAG_TAPHOLE4_STATUS)) {
-                ironLoading4.set("1".equals(opcData.getData().toString()));
+                ironLoading4.set(Integer.parseInt(opcData.getData().toString()));
 
             } else if (opcData.getPointName().contains(L1TagConstants.TAG_IRON_WEIGHT11) || opcData.getPointName().contains(L1TagConstants.TAG_IRON_WEIGHT12)) {
                 //铁水流量
@@ -1020,7 +1112,7 @@ public class DeviceEventListener extends EventListener { //
         String userId;
         if (ObjectUtils.isEmpty(client) || ObjectUtils.isEmpty(userId = SocketUtil.clientUserIds.get(client))) {
             log.info("该客户已下线");
-            PushData.send2Operation("该客户已下线", false);
+            PushData.send2Operation("该客户已下线", 0);
             return null;
         }
         return userId;
@@ -1041,7 +1133,7 @@ public class DeviceEventListener extends EventListener { //
 
         if (ObjectUtils.isEmpty(message)) {
             log.info("请求数据为空");
-            PushData.send2Operation("请求数据为空", false);
+            PushData.send2Operation("请求数据为空", 0);
             return;
         }
 

+ 27 - 1
taphole-iron/src/main/java/com/sckj/iron/socketio/PushData.java

@@ -68,6 +68,16 @@ public class PushData {
      */
     public static final String IRON_TIME_NO = "IRON_TIME_NO";
 
+    /***
+     * 打泥量计算
+     */
+    public static final String IRON_HIT_MUD = "IRON_HIT_MUD";
+
+    /***
+     * 出铁工作诊断
+     */
+    public static final String IRON_TAPPING_TEST = "IRON_TAPPING_TEST";
+
     /**
      * 出铁操作
      *
@@ -113,7 +123,7 @@ public class PushData {
      * @param message 发送的消息内容
      * @param isStopSendMsg  是否停止发送信息
      */
-    public static void send2Operation(Object message, boolean isStopSendMsg) {
+    public static void send2Operation(Object message, Integer isStopSendMsg) {
         if (SocketUtil.connectMap.isEmpty()) {//|| isStopSendMsg
             return;
         }
@@ -220,5 +230,21 @@ public class PushData {
         }
     }
 
+    /**
+     * 打泥量计算
+     *
+     * @return
+     * @Param
+     **/
+    public static void send2IronHitMud(Object message) {
+        if (SocketUtil.connectMap.isEmpty()) {
+            return;
+        }
+        //
+        for (Map.Entry<String, SocketIOClient> entry : SocketUtil.connectMap.entrySet()) {
+            entry.getValue().sendEvent(PushData.IRON_HIT_MUD, AjaxResult.success(message));
+        }
+    }
+
 
 }

+ 1 - 1
taphole-iron/src/main/java/com/sckj/iron/validate/TIronDataSearchScreenValidate.java

@@ -15,7 +15,7 @@ public class TIronDataSearchScreenValidate implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @ApiModelProperty(value = "铁口区域编号")

+ 1 - 1
taphole-iron/src/main/java/com/sckj/iron/validate/TIronDataSearchValidate.java

@@ -13,7 +13,7 @@ public class TIronDataSearchValidate implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @ApiModelProperty(value = "铁口区域编号")

+ 4 - 4
taphole-iron/src/main/java/com/sckj/iron/validate/TIronModelCreateValidate.java

@@ -3,10 +3,9 @@ package com.sckj.iron.validate;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+
+import javax.validation.constraints.NotNull;
 import java.io.Serializable;
-import java.util.Date;
-import java.util.Date;
-import javax.validation.constraints.*;
 
 @Data
 @ApiModel("出铁相关模型创建参数")
@@ -35,5 +34,6 @@ public class TIronModelCreateValidate implements Serializable {
     @ApiModelProperty(value = "排序")
     private Integer sort;
 
-
+    @ApiModelProperty(value = "音频外键")
+    private Long audioId;
 }

+ 5 - 3
taphole-iron/src/main/java/com/sckj/iron/validate/TIronModelSearchValidate.java

@@ -3,9 +3,8 @@ package com.sckj.iron.validate;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+
 import java.io.Serializable;
-import java.util.Date;
-import java.util.Date;
 
 @Data
 @ApiModel("出铁相关模型搜素参数")
@@ -40,7 +39,10 @@ public class TIronModelSearchValidate implements Serializable {
     @ApiModelProperty(value = "铁口区域编号")
     private String tapholeId;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
+    @ApiModelProperty(value = "音频外键")
+    private Long audioId;
+
 }

+ 29 - 0
taphole-iron/src/main/java/com/sckj/iron/validate/TIronModelTestValidate.java

@@ -0,0 +1,29 @@
+package com.sckj.iron.validate;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 出铁相关模型参数
+ * @author LikeAdmin
+ */
+@Data
+@ApiModel("出铁相关模型测试参数")
+public class TIronModelTestValidate implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "模型ID")
+    private Long id;
+
+    @ApiModelProperty(value = "模型执行参数")
+    private List<Map<String,Object>> keyValue;
+
+
+
+}

+ 4 - 3
taphole-iron/src/main/java/com/sckj/iron/validate/TIronModelUpdateValidate.java

@@ -1,11 +1,11 @@
 package com.sckj.iron.validate;
 
-import com.sckj.common.validator.annotation.IDMust;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+
+import javax.validation.constraints.NotNull;
 import java.io.Serializable;
-import javax.validation.constraints.*;
 
 /**
  * 出铁相关模型参数
@@ -41,6 +41,7 @@ public class TIronModelUpdateValidate implements Serializable {
     @ApiModelProperty(value = "排序")
     private Integer sort;
 
-
+    @ApiModelProperty(value = "音频外键")
+    private Long audioId;
 
 }

+ 1 - 1
taphole-iron/src/main/java/com/sckj/iron/validate/TL2DataCreateValidate.java

@@ -14,7 +14,7 @@ public class TL2DataCreateValidate implements Serializable {
     private static final long serialVersionUID = 1L;
 
     @NotNull(message = "boilerId参数缺失")
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @NotNull(message = "tapholeId参数缺失")

+ 1 - 1
taphole-iron/src/main/java/com/sckj/iron/validate/TL2DataSearchValidate.java

@@ -12,7 +12,7 @@ public class TL2DataSearchValidate implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @ApiModelProperty(value = "铁口区域编号")

+ 1 - 1
taphole-iron/src/main/java/com/sckj/iron/validate/TL2DataUpdateValidate.java

@@ -23,7 +23,7 @@ public class TL2DataUpdateValidate implements Serializable {
     private Long id;
 
     @NotNull(message = "boilerId参数缺失")
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @NotNull(message = "tapholeId参数缺失")

+ 1 - 1
taphole-iron/src/main/java/com/sckj/iron/vo/TIronDataDetailVo.java

@@ -17,7 +17,7 @@ public class TIronDataDetailVo implements Serializable {
     @ApiModelProperty(value = "")
     private Long id;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @ApiModelProperty(value = "铁口区域编号")

+ 1 - 1
taphole-iron/src/main/java/com/sckj/iron/vo/TIronDataListedVo.java

@@ -17,7 +17,7 @@ public class TIronDataListedVo implements Serializable {
     @ApiModelProperty(value = "")
     private Long id;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @ApiModelProperty(value = "铁口区域编号")

+ 4 - 3
taphole-iron/src/main/java/com/sckj/iron/vo/TIronModelDetailVo.java

@@ -5,8 +5,6 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.io.Serializable;
-import java.util.Date;
-import java.util.Date;
 
 @Data
 @ApiModel("出铁相关模型详情Vo")
@@ -44,8 +42,11 @@ public class TIronModelDetailVo implements Serializable {
     @ApiModelProperty(value = "铁口区域编号")
     private String tapholeId;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
+    @ApiModelProperty(value = "音频外键")
+    private Long audioId;
+
 
 }

+ 4 - 3
taphole-iron/src/main/java/com/sckj/iron/vo/TIronModelListedVo.java

@@ -5,8 +5,6 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.io.Serializable;
-import java.util.Date;
-import java.util.Date;
 
 @Data
 @ApiModel("出铁相关模型列表Vo")
@@ -50,8 +48,11 @@ public class TIronModelListedVo implements Serializable {
     @ApiModelProperty(value = "铁口区域编号")
     private String tapholeId;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
+    @ApiModelProperty(value = "音频外键")
+    private Long audioId;
+
 
 }

+ 1 - 1
taphole-iron/src/main/java/com/sckj/iron/vo/TIronParamDetailVo.java

@@ -25,7 +25,7 @@ public class TIronParamDetailVo implements Serializable {
     @ApiModelProperty(value = "铁口区域编号")
     private String tapholeId;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @ApiModelProperty(value = "参数类型")

+ 1 - 1
taphole-iron/src/main/java/com/sckj/iron/vo/TIronParamListedVo.java

@@ -25,7 +25,7 @@ public class TIronParamListedVo implements Serializable {
     @ApiModelProperty(value = "铁口区域编号")
     private String tapholeId;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @ApiModelProperty(value = "参数类型")

+ 1 - 1
taphole-iron/src/main/java/com/sckj/iron/vo/TL2DataDetailVo.java

@@ -16,7 +16,7 @@ public class TL2DataDetailVo implements Serializable {
     @ApiModelProperty(value = "")
     private Long id;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @ApiModelProperty(value = "铁口区域编号")

+ 1 - 1
taphole-iron/src/main/java/com/sckj/iron/vo/TL2DataListedVo.java

@@ -19,7 +19,7 @@ public class TL2DataListedVo implements Serializable {
     @ApiModelProperty(value = "")
     private Long id;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @ApiModelProperty(value = "铁口区域编号")

BIN
taphole-iron/src/main/resources/jar/hd-datasdk-3.9.3.jar


+ 12 - 0
taphole-l2/src/main/java/com/sckj/l2/controller/TL2DataController.java

@@ -6,6 +6,7 @@ import com.sckj.common.aop.NotPower;
 import com.sckj.common.core.AjaxResult;
 import com.sckj.common.core.PageResult;
 import com.sckj.common.validate.commons.PageValidate;
+import com.sckj.l2.service.impl.L2DataServiceImpl;
 import com.sckj.l2.service.impl.TL2DataServiceImpl;
 import com.sckj.l2.validate.TL2DataSearchValidate;
 import com.sckj.l2.vo.TL2DataDetailVo;
@@ -26,6 +27,9 @@ public class TL2DataController {
     @Resource
     TL2DataServiceImpl iTL2DataService;
 
+    @Resource
+    L2DataServiceImpl l2DataService;
+
     @NotPower
     @GetMapping("/list")
     @ApiOperation(value = "出铁数据列表")
@@ -50,6 +54,14 @@ public class TL2DataController {
         iTL2DataService.exportL2DataList(searchValidate, response);
     }
 
+    @Log(title = "数据统计")
+    @PostMapping("/connect")
+    @ApiOperation(value = "连接L2")
+    public void connect() {
+//        iTL2DataService.
+    }
+
+
 //
 //
 //    @PostMapping("/add")

+ 94 - 80
taphole-l2/src/main/java/com/sckj/l2/dto/L2Data.java

@@ -1,11 +1,9 @@
 package com.sckj.l2.dto;
 
-import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
-import java.io.Serializable;
 
 /**
  * @Author feng
@@ -13,134 +11,150 @@ import java.io.Serializable;
  * @Description TODO
  */
 @Data
-public class L2Data implements Serializable {
+public class L2Data {
+    //下料批次
+    private String chargeNo;
 
-    @ApiModelProperty(value = "铁口区域编号")
-    private String tapholeId;
+    //理论出铁量
+    private String theoryWeight;
 
-    @ApiModelProperty(value = "出铁次数编号")
-    private Long ironNo;
+    //装入时间点
+    private String loadMaterialTime;
 
-    @ApiModelProperty(value = "出铁时间")
-    private Integer ironCosttime;
+    //高炉号
+    private String boilerId;
 
-    @ApiModelProperty(value = "实际出铁量")
-    private Double ironWeight;
+    //铁口号
+    private String tapholeId;
 
-    @ApiModelProperty(value = "实际渣量")
-    private String slagWeight;
+    //铁次号
+    private String ironNo;
 
-    @ApiModelProperty(value = "铁水平均温度")
-    private String avgTemp;
+    //铁水成分 硅
+    private String elementSi;
 
-    @ApiModelProperty(value = "泥炮量")
-    private String mudWeight;
+    //铁水成分 硫
+    private String elementS;
 
-    @ApiModelProperty(value = "钻杆直径")
-    private String pollMm;
+    //铁水成分 钛
+    private String elementTi;
 
-    @ApiModelProperty(value = "开口深度")
-    private String openDepth;
+    //铁水成分 磷
+    private String elementP;
 
-    @ApiModelProperty(value = "上料总干量")
-    private String totalDry;
+    //铁水成分 锰
+    private String elementMn;
 
-    @ApiModelProperty(value = "开始时间")
+    //铁水成分 碳
+    private String elementC;
+
+    //出铁开始时间
     private String ironStarttime;
 
-    @ApiModelProperty(value = "结束时间")
+    //出铁结束时间
     private String ironEndtime;
 
-    //铁水成分 碳
-    @ApiModelProperty(value = "碳")
-    private String elementC;
+    //出铁时间
+    private String ironCosttime;
 
-    //铁水成分 硅
-    @ApiModelProperty(value = "硅")
-    private String elementSi;
+    //实际出铁量
+    private String ironWeight;
 
-    //铁水成分 锰
-    @ApiModelProperty(value = "锰")
-    private String elementMn;
+    //估计出铁量
+    private String calcWeight;
 
-    //铁水成分 磷
-    @ApiModelProperty(value = "磷")
-    private String elementP;
+    //实际渣量
+    private String slagWeight;
 
-    //铁水成分 硫
-    @ApiModelProperty(value = "硫")
-    private String elementS;
+    //泥炮量
+    private String mudWeight;
 
-    //铁水成分 钛
-    @ApiModelProperty(value = "钛")
-    private String elementTi;
+    // 钻杆直径
+    private String pollMm;
 
+    //开口深度
+    private String openDepth;
+
+    //铁水平均温度
+    private String avgTemp;
 
     public void toDataStream(DataOutputStream dos) throws Exception {
+        dos.writeUTF(chargeNo);
+        dos.writeUTF(theoryWeight);
+        dos.writeUTF(loadMaterialTime);
+        dos.writeUTF(boilerId);
         dos.writeUTF(tapholeId);
-        dos.writeLong(ironNo);
-        dos.writeInt(ironCosttime);
-        dos.writeDouble(ironWeight);
+        dos.writeUTF(ironNo);
+        dos.writeUTF(elementSi);
+        dos.writeUTF(elementS);
+        dos.writeUTF(elementTi);
+        dos.writeUTF(elementP);
+        dos.writeUTF(elementMn);
+        dos.writeUTF(elementC);
+        dos.writeUTF(ironStarttime);
+        dos.writeUTF(ironEndtime);
+        dos.writeUTF(ironCosttime);
+        dos.writeUTF(ironWeight);
+        dos.writeUTF(calcWeight);
         dos.writeUTF(slagWeight);
-        dos.writeUTF(avgTemp);
         dos.writeUTF(mudWeight);
         dos.writeUTF(pollMm);
         dos.writeUTF(openDepth);
-        dos.writeUTF(totalDry);
-        dos.writeUTF(ironStarttime);
-        dos.writeUTF(ironEndtime);
-        dos.writeUTF(elementC);
-        dos.writeUTF(elementSi);
-        dos.writeUTF(elementMn);
-        dos.writeUTF(elementP);
-        dos.writeUTF(elementS);
-        dos.writeUTF(elementTi);
+        dos.writeUTF(avgTemp);
     }
 
     public static L2Data fromDataStream(DataInputStream dis) throws Exception {
         L2Data data = new L2Data();
+        data.chargeNo = dis.readUTF();
+        data.theoryWeight = dis.readUTF();
+        data.loadMaterialTime = dis.readUTF();
+        data.boilerId = dis.readUTF();
         data.tapholeId = dis.readUTF();
-        data.ironNo = dis.readLong();
-        data.ironCosttime = dis.readInt();
-        data.ironWeight = dis.readDouble();
+        data.ironNo = dis.readUTF();
+        data.elementSi = dis.readUTF();
+        data.elementS = dis.readUTF();
+        data.elementTi = dis.readUTF();
+        data.elementP = dis.readUTF();
+        data.elementMn = dis.readUTF();
+        data.elementC = dis.readUTF();
+        data.ironStarttime = dis.readUTF();
+        data.ironEndtime = dis.readUTF();
+        data.ironCosttime = dis.readUTF();
+        data.ironWeight = dis.readUTF();
+        data.calcWeight = dis.readUTF();
         data.slagWeight = dis.readUTF();
-        data.avgTemp = dis.readUTF();
         data.mudWeight = dis.readUTF();
         data.pollMm = dis.readUTF();
         data.openDepth = dis.readUTF();
-        data.totalDry = dis.readUTF();
-        data.ironStarttime = dis.readUTF();
-        data.ironEndtime = dis.readUTF();
-        data.elementC = dis.readUTF();
-        data.elementSi = dis.readUTF();
-        data.elementMn = dis.readUTF();
-        data.elementP = dis.readUTF();
-        data.elementS = dis.readUTF();
-        data.elementTi = dis.readUTF();
+        data.avgTemp = dis.readUTF();
         return data;
     }
 
     @Override
     public String toString() {
         return "L2Data{" +
-                "tapholeId='" + tapholeId + '\'' +
+                "chargeNo='" + chargeNo + '\'' +
+                ", theoryWeight='" + theoryWeight + '\'' +
+                ", loadMaterialTime='" + loadMaterialTime + '\'' +
+                ", boilerId='" + boilerId + '\'' +
+                ", tapholeId='" + tapholeId + '\'' +
                 ", ironNo='" + ironNo + '\'' +
+                ", elementSi='" + elementSi + '\'' +
+                ", elementS='" + elementS + '\'' +
+                ", elementTi='" + elementTi + '\'' +
+                ", elementP='" + elementP + '\'' +
+                ", elementMn='" + elementMn + '\'' +
+                ", elementC='" + elementC + '\'' +
+                ", ironStarttime='" + ironStarttime + '\'' +
+                ", ironEndtime='" + ironEndtime + '\'' +
                 ", ironCosttime='" + ironCosttime + '\'' +
                 ", ironWeight='" + ironWeight + '\'' +
+                ", calcWeight='" + calcWeight + '\'' +
                 ", slagWeight='" + slagWeight + '\'' +
-                ", avgTemp='" + avgTemp + '\'' +
                 ", mudWeight='" + mudWeight + '\'' +
                 ", pollMm='" + pollMm + '\'' +
                 ", openDepth='" + openDepth + '\'' +
-                ", totalDry='" + totalDry + '\'' +
-                ", ironStarttime='" + ironStarttime + '\'' +
-                ", ironEndtime='" + ironEndtime + '\'' +
-                ", elementC='" + elementC + '\'' +
-                ", elementSi='" + elementSi + '\'' +
-                ", elementMn='" + elementMn + '\'' +
-                ", elementP='" + elementP + '\'' +
-                ", elementS='" + elementS + '\'' +
-                ", elementTi='" + elementTi + '\'' +
+                ", avgTemp='" + avgTemp + '\'' +
                 '}';
     }
 }

+ 1 - 26
taphole-l2/src/main/java/com/sckj/l2/dto/L2Material.java

@@ -5,8 +5,6 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
 import java.io.Serializable;
 import java.util.Date;
 
@@ -22,7 +20,7 @@ public class L2Material implements Serializable {
     @ApiModelProperty(value = "id")
     private Long id;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @ApiModelProperty(value = "铁口区域编号")
@@ -50,27 +48,4 @@ public class L2Material implements Serializable {
     private String compositeTaste;
 
 
-    public void toDataStream(DataOutputStream dos) throws Exception {
-        dos.writeUTF(chargeNo);
-        dos.writeUTF(downTime);
-        dos.writeUTF(dryWeight);
-        dos.writeUTF(oreWeight);
-        dos.writeUTF(cokeWeight);
-        dos.writeUTF(asstmaterialWeight);
-        dos.writeUTF(compositeTaste);
-    }
-
-    public static L2Material fromDataStream(DataInputStream dis) throws Exception {
-        L2Material data = new L2Material();
-        data.chargeNo = dis.readUTF();
-        data.downTime = dis.readUTF();
-        data.dryWeight = dis.readUTF();
-        data.oreWeight = dis.readUTF();
-        data.cokeWeight = dis.readUTF();
-        data.asstmaterialWeight = dis.readUTF();
-        data.compositeTaste = dis.readUTF();
-        return data;
-    }
-
-
 }

+ 48 - 0
taphole-l2/src/main/java/com/sckj/l2/dto/L2Properties.java

@@ -0,0 +1,48 @@
+package com.sckj.l2.dto;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "like.l2")
+public class L2Properties {
+    private String host;
+
+    private Integer port;
+
+    private Integer maxRetries;
+
+    private Long retryInterval;
+
+    public String getHost() {
+        return host;
+    }
+
+    public void setHost(String host) {
+        this.host = host;
+    }
+
+    public Integer getPort() {
+        return port;
+    }
+
+    public void setPort(Integer port) {
+        this.port = port;
+    }
+
+    public Integer getMaxRetries() {
+        return maxRetries;
+    }
+
+    public void setMaxRetries(Integer maxRetries) {
+        this.maxRetries = maxRetries;
+    }
+
+    public Long getRetryInterval() {
+        return retryInterval;
+    }
+
+    public void setRetryInterval(Long retryInterval) {
+        this.retryInterval = retryInterval;
+    }
+}

+ 1 - 1
taphole-l2/src/main/java/com/sckj/l2/entity/TL2Data.java

@@ -35,7 +35,7 @@ public class TL2Data implements Serializable {
     @ExcelIgnore
     private Long id;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     @ExcelIgnore
     private String boilerId;
 

+ 2 - 9
taphole-l2/src/main/java/com/sckj/l2/entity/TL2Material.java

@@ -1,12 +1,5 @@
 package com.sckj.l2.entity;
 
-import com.alibaba.excel.annotation.ExcelIgnore;
-import com.alibaba.excel.annotation.ExcelProperty;
-import com.alibaba.excel.annotation.write.style.ColumnWidth;
-import com.alibaba.excel.annotation.write.style.HeadFontStyle;
-import com.alibaba.excel.annotation.write.style.HeadRowHeight;
-import com.alibaba.excel.annotation.write.style.HeadStyle;
-import com.alibaba.excel.enums.poi.FillPatternTypeEnum;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
@@ -34,14 +27,14 @@ public class TL2Material implements Serializable {
     @ApiModelProperty(value = "id")
     private Long id;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @ApiModelProperty(value = "铁口区域编号")
     private String tapholeId;
 
     @ApiModelProperty(value = "出铁次数编号")
-    private Long ironNo;
+    private String ironNo;
 
     @ApiModelProperty(value = "L1发过来的charge号")
     private String chargeNo;

+ 101 - 61
taphole-l2/src/main/java/com/sckj/l2/service/impl/L2DataServiceImpl.java

@@ -2,7 +2,7 @@ package com.sckj.l2.service.impl;
 
 import com.google.common.eventbus.AsyncEventBus;
 import com.sckj.l2.dto.L2Data;
-import com.sckj.l2.dto.L2Material;
+import com.sckj.l2.dto.L2Properties;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@@ -10,11 +10,12 @@ import org.springframework.stereotype.Service;
 
 import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
+import java.io.ByteArrayInputStream;
 import java.io.DataInputStream;
-import java.io.DataOutputStream;
+import java.io.EOFException;
 import java.io.IOException;
-import java.net.Socket;
-import java.net.UnknownHostException;
+import java.net.*;
+import java.time.LocalDateTime;
 
 /**
  * @Author feng
@@ -31,34 +32,101 @@ public class L2DataServiceImpl {
     @Resource(name = "taskExecutor")
     ThreadPoolTaskExecutor taskExecutor;
 
+    @Resource
+    L2Properties l2Properties;
+
+    //客户端最大重试次数
+    private int maxRetries;
+
+    //客户端重试间隔时间(毫秒)
+    private long retryInterval;
+
+    //服务端访问地址
+    private String host;
+
+    // 服务端端口/客户端访问端口
+    private Integer port;
+
+    //客户端尝试连接次数
+    int attempt = 0;
+
     @PostConstruct
-    private void init() {
-        taskExecutor.submit(this::initTCP);
+    public void init() {
+        maxRetries = l2Properties.getMaxRetries();
+        retryInterval = l2Properties.getRetryInterval();
+        host = l2Properties.getHost();
+        port = l2Properties.getPort();
+//        taskExecutor.submit(this::connectL2);
+        taskExecutor.submit(this::startTCPServer);
+        taskExecutor.submit(this::startUDPServer);
     }
 
-    /***
-     * L2数据源
+    /**
+     * 服务端TCP
      */
+    public void startTCPServer() {
+        try (ServerSocket serverSocket = new ServerSocket(port)) {
+            System.out.println("TCP 服务器已启动,等待客户端连接...");
+            while (true) {
+                try (Socket socket = serverSocket.accept();
+                     DataInputStream dis = new DataInputStream(socket.getInputStream())) {
+                    System.out.println(LocalDateTime.now() + ",TCP客户端已连接:" + socket.getInetAddress());
+                    while (true) {
+                        // 从输入流读取L2Data对象
+                        L2Data data = L2Data.fromDataStream(dis);
+                        System.out.println(LocalDateTime.now() + "TCP接收到的数据: " + data);
+                        asyncEventBus.post(data); //L2出铁数据
+                    }
+                } catch (EOFException e) {
+                    // 客户端正常关闭连接
+                    System.out.println("TCP客户端断开连接");
+                } catch (Exception e) {
+                    System.err.println("TCP处理客户端连接时出错: " + e.getMessage());
+                    e.printStackTrace();
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
 
-    private void initTCP() {
-        System.out.println("TCP start");
+    /***
+     * 服务端UDP
+     */
+    public void startUDPServer() {
+        try (DatagramSocket socket = new DatagramSocket(port)) {
+            System.out.println("UDP 服务器已启动,监听端口 " + port);
+            byte[] buffer = new byte[65507];
+            while (true) {
+                DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
+                socket.receive(packet);
+                ByteArrayInputStream bais = new ByteArrayInputStream(packet.getData(), 0, packet.getLength());
+                DataInputStream dis = new DataInputStream(bais);
+                try {
+                    L2Data data = L2Data.fromDataStream(dis);
+                    System.out.println(LocalDateTime.now() + " 接收到数据: " + data);
+                    asyncEventBus.post(data); //L2出铁数据
+                } catch (Exception e) {
+                    System.err.println("反序列化数据时出错: " + e.getMessage());
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
 
-        final String serverIP = "192.168.110.65"; // 服务端IP地址
-        final int serverPort = 8888; // 服务端端口号
-        final int maxRetries = 10; // 最大重试次数
-        final long retryInterval = 5000; // 重试间隔时间(毫秒)
 
+    public Socket connect() {
+        System.out.println("TCP start connect");
+        final String serverIP = host; // 服务端IP地址
+        final int serverPort = port; // 服务端端口号
         Socket socket = null;
-        DataOutputStream dos;
-        DataInputStream dis;
-        int attempt = 0;
-
         // 连接重试机制
         while (attempt < maxRetries) {
             try {
                 socket = new Socket(serverIP, serverPort);
                 System.out.println("Connected to server at " + serverIP + ":" + serverPort);
-                break;
+                return socket;
             } catch (UnknownHostException e) {
                 System.err.println("Unknown host: " + serverIP);
                 break;
@@ -77,59 +145,31 @@ public class L2DataServiceImpl {
 
         if (socket == null) {
             System.err.println("Failed to connect to server after " + maxRetries + " attempts.");
-            return;
         }
+        return socket;
+    }
+
+    /***
+     * L2数据源
+     */
+    public void readObject() {
+        Socket socket = connect();
+        DataInputStream dis;
         try {
-            dos = new DataOutputStream(socket.getOutputStream());
             dis = new DataInputStream(socket.getInputStream());
             while (true) {
                 try {
                     // 从输入流读取L2Data对象
-                    // 新增:读取数据类型标识(需要服务端配合发送类型头)
-                    String dataType = dis.readUTF();
-                    if ("L2Data".equals(dataType)) {
-                        L2Data receivedData = L2Data.fromDataStream(dis);
-                        asyncEventBus.post(receivedData); //出铁操作
-//                        System.out.println("Received L2Data from server: \n" + receivedData);
-                    } else if ("L2Material".equals(dataType)) {
-                        L2Material receivedMaterial = L2Material.fromDataStream(dis);
-                        // 新增材料处理逻辑,例如:
-                        asyncEventBus.post(receivedMaterial);
-//                        System.out.println("Received L2Material from server: \n" + receivedMaterial);
-                    }
+                    L2Data receivedData = L2Data.fromDataStream(dis);
+                    asyncEventBus.post(receivedData); //出铁操作
                 } catch (IOException e) {
                     System.err.println("Connection lost. Attempting to reconnect...");
                     socket.close();
                     socket = null;
                     attempt = 0;
-
-                    // 重新连接重试机制
-                    while (attempt < maxRetries) {
-                        try {
-                            socket = new Socket(serverIP, serverPort);
-                            System.out.println("Reconnected to server at " + serverIP + ":" + serverPort);
-                            dos = new DataOutputStream(socket.getOutputStream());
-                            dis = new DataInputStream(socket.getInputStream());
-                            break;
-                        } catch (UnknownHostException ex) {
-                            System.err.println("Unknown host: " + serverIP);
-                            break;
-                        } catch (IOException ex) {
-                            attempt++;
-                            System.err.println("Attempt " + attempt + ": Reconnection failed. Retrying in " + retryInterval / 1000 + " seconds...");
-                            try {
-                                Thread.sleep(retryInterval);
-                            } catch (InterruptedException ie) {
-                                Thread.currentThread().interrupt();
-                                System.err.println("Thread interrupted while sleeping.");
-                                break;
-                            }
-                        }
-                    }
-
-                    if (socket == null) {
-                        System.err.println("Failed to reconnect to server after " + maxRetries + " attempts.");
-                        return;
+                    socket = connect();
+                    if (socket != null) {
+                        dis = new DataInputStream(socket.getInputStream());
                     }
                 }
             }

+ 1 - 1
taphole-opc-start/src/main/java/com/sckj/opcstart/TapholeOpcStartApplication.java

@@ -1,6 +1,6 @@
 package com.sckj.opcstart;
 
-import com.sckj.opc.dauaservice.OPCDAServiceImpl;
+import com.sckj.opc.dataservice.OPCDAServiceImpl;
 import lombok.extern.log4j.Log4j2;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;

+ 7 - 1
taphole-opc/pom.xml

@@ -20,7 +20,13 @@
             <groupId>com.sckj</groupId>
             <artifactId>taphole-common</artifactId>
         </dependency>
-
+        <dependency>
+            <groupId>com.baosight</groupId>
+            <artifactId>jna</artifactId>
+            <version>3.9.3</version>
+            <scope>system</scope>
+            <systemPath>${project.basedir}/src/main/resources/jar/hd-datasdk-3.9.3.jar</systemPath>
+        </dependency>
     </dependencies>
 
 </project>

+ 1 - 1
taphole-opc/src/main/java/com/sckj/opc/controller/OPCDAController.java

@@ -5,7 +5,7 @@ import com.sckj.common.core.AjaxResult;
 import com.sckj.common.enums.ErrorEnum;
 import com.sckj.opc.entity.OPCPoint;
 import com.sckj.opc.entity.OPCServer;
-import com.sckj.opc.dauaservice.OPCDAServiceImpl;
+import com.sckj.opc.dataservice.OPCDAServiceImpl;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.web.bind.annotation.PostMapping;

+ 1 - 1
taphole-opc/src/main/java/com/sckj/opc/controller/OPCUAController.java

@@ -4,7 +4,7 @@ import com.sckj.common.aop.NotLogin;
 import com.sckj.common.core.AjaxResult;
 import com.sckj.opc.entity.OPCPoint;
 import com.sckj.opc.entity.OPCServer;
-import com.sckj.opc.dauaservice.OPCUAServiceImpl;
+import com.sckj.opc.dataservice.OPCUAServiceImpl;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.web.bind.annotation.PostMapping;

+ 194 - 0
taphole-opc/src/main/java/com/sckj/opc/controller/THdTagController.java

@@ -0,0 +1,194 @@
+package com.sckj.opc.controller;
+
+import com.sckj.common.aop.Log;
+import com.sckj.common.aop.NotLogin;
+import com.sckj.common.core.AjaxResult;
+import com.sckj.common.core.PageResult;
+import com.sckj.common.enums.ErrorEnum;
+import com.sckj.common.validate.commons.IdValidate;
+import com.sckj.common.validate.commons.PageValidate;
+import com.sckj.common.validator.annotation.IDMust;
+import com.sckj.opc.dataservice.HDServiceImpl;
+import com.sckj.opc.entity.OPCServer;
+import com.sckj.opc.entity.THdTag;
+import com.sckj.opc.service.THdTagServiceImpl;
+import com.sckj.opc.validate.THdTagCreateValidate;
+import com.sckj.opc.validate.THdTagSearchValidate;
+import com.sckj.opc.validate.THdTagUpdateValidate;
+import com.sckj.opc.vo.THdTagDetailVo;
+import com.sckj.opc.vo.THdTagListedVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+
+@RestController
+@RequestMapping("api/tag")
+@Api(tags = "IHD标记管理")
+public class THdTagController {
+
+    @Resource
+    THdTagServiceImpl iTHdTagService;
+
+    @Resource
+    HDServiceImpl hdService;
+
+    @GetMapping("/list")
+    @ApiOperation(value="TAG标记列表")
+    public AjaxResult<PageResult<THdTagListedVo>> list(@Validated PageValidate pageValidate,
+                                                       @Validated THdTagSearchValidate searchValidate) {
+        PageResult<THdTagListedVo> list = iTHdTagService.list(pageValidate, searchValidate);
+        return AjaxResult.success(list);
+    }
+
+    @GetMapping("/detail")
+    @ApiOperation(value="TAG标记详情")
+    public AjaxResult<THdTagDetailVo> detail(@Validated @IDMust() @RequestParam("id") Integer id) {
+        THdTagDetailVo detail = iTHdTagService.detail(id);
+        return AjaxResult.success(detail);
+    }
+
+    @Log(title = "TAG标记新增")
+    @PostMapping("/add")
+    @ApiOperation(value="IHD标记新增")
+    public AjaxResult<Object> add(@Validated @RequestBody THdTagCreateValidate createValidate) {
+        iTHdTagService.add(createValidate);
+        return AjaxResult.success();
+    }
+
+    @Log(title = "TAG标记编辑")
+    @PostMapping("/edit")
+    @ApiOperation(value="IHD标记编辑")
+    public AjaxResult<Object> edit(@Validated @RequestBody THdTagUpdateValidate updateValidate) {
+        iTHdTagService.edit(updateValidate);
+        return AjaxResult.success();
+    }
+
+    @Log(title = "TAG标记删除")
+    @PostMapping("/del")
+    @ApiOperation(value="IHD标记删除")
+    public AjaxResult<Object> del(@Validated @RequestBody IdValidate idValidate) {
+        iTHdTagService.del(idValidate.getId());
+        return AjaxResult.success();
+    }
+
+
+    /**
+     * @return
+     * @MethodName: connect
+     * @Description: opcua连接
+     */
+    @PostMapping("/connect")
+    @ResponseBody
+    @NotLogin
+    @ApiOperation(value = "连接")
+    public AjaxResult connect(OPCServer opcServer) {
+        try {
+            hdService.createServer(opcServer);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return AjaxResult.failed(e.getMessage());
+        }
+        return AjaxResult.success("连接成功");
+    }
+
+
+
+    /**
+     * @return
+     * @MethodName: subscribe
+     * @Description: 订阅所有可用的订阅点
+     */
+    @PostMapping("/subscribeAvailable")
+    @ResponseBody
+    @NotLogin
+    @ApiOperation(value = "订阅可用订阅点")
+    public AjaxResult subscribeAvailable() {
+        try {
+            hdService.subscribeAvailable();
+        } catch (Exception e) {
+            e.printStackTrace();
+            return AjaxResult.failed(e.getMessage());
+        }
+        return AjaxResult.success();
+    }
+
+    /**
+     * @return
+     * @MethodName: subscribe
+     * @Description: 订阅所有可用的订阅点
+     */
+    @PostMapping("/unsubscribeAvailable")
+    @ResponseBody
+    @NotLogin
+    @ApiOperation(value = "取消订阅可用订阅点")
+    public AjaxResult unsubscribeAvailable() {
+        try {
+            hdService.unsubscribeAvailable();
+        } catch (Exception e) {
+            e.printStackTrace();
+            return AjaxResult.failed(e.getMessage());
+        }
+        return AjaxResult.success();
+    }
+
+
+    /**
+     * @return
+     * @MethodName: subscribe
+     * @Description: 订阅
+     */
+    @PostMapping("/subscribe")
+    @ResponseBody
+    @NotLogin
+    @ApiOperation(value = "订阅")
+    public AjaxResult subscribe(THdTag hdTag) {
+        try {
+            return  AjaxResult.success(hdService.subscribe(hdTag));
+        } catch (Exception e) {
+            e.printStackTrace();
+            return AjaxResult.failed(e.getMessage());
+        }
+    }
+
+    /**
+     * @return
+     * @MethodName: unsubscribe
+     * @Description: 取消订阅
+     */
+    @PostMapping("/unsubscribe")
+    @ResponseBody
+    @NotLogin
+    @ApiOperation(value = "取消订阅")
+    public AjaxResult unsubscribe(THdTag hdTag) {
+        try {
+            hdService.unsubscribe(hdTag);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return AjaxResult.failed(e.getMessage());
+        }
+        return AjaxResult.success();
+    }
+
+
+    /**
+     * @return
+     * @MethodName: subscribe
+     * @Description: 读取节点数据
+     */
+    @PostMapping("/readNodeValue")
+    @ResponseBody
+    @NotLogin
+    @ApiOperation(value = "读取节点数据")
+    public AjaxResult readNodeValue(THdTag hdTag) {
+        try {
+            return AjaxResult.success(ErrorEnum.SUCCESS.getCode(), ErrorEnum.SUCCESS.getMsg(), hdService.readNodeValue(hdTag));
+        } catch (Exception e) {
+            e.printStackTrace();
+            return AjaxResult.failed(e.getMessage());
+        }
+    }
+
+}

+ 191 - 0
taphole-opc/src/main/java/com/sckj/opc/dataservice/HDServiceImpl.java

@@ -0,0 +1,191 @@
+package com.sckj.opc.dataservice;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baosight.hdsdk.HDConnectionFactory;
+import com.baosight.hdsdk.HDDataProvider;
+import com.baosight.hdsdk.HDServerFactory;
+import com.baosight.hdsdk.domain.data.HDDataConnection;
+import com.baosight.hdsdk.domain.data.HDDataServer;
+import com.baosight.hdsdk.domain.data.HDRecord;
+import com.baosight.hdsdk.exception.HDSdkException;
+import com.google.common.eventbus.AsyncEventBus;
+import com.sckj.common.manager.ScheduledTaskManager;
+import com.sckj.opc.dto.HdTagDTO;
+import com.sckj.opc.entity.OPCServer;
+import com.sckj.opc.entity.THdTag;
+import com.sckj.opc.service.OPCDataServiceImpl;
+import com.sckj.opc.service.OPCServerServiceImpl;
+import com.sckj.opc.service.THdTagServiceImpl;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PreDestroy;
+import javax.annotation.Resource;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+
+@Service
+@Slf4j
+public class HDServiceImpl {
+
+    @Resource
+    OPCServerServiceImpl opcServerService;
+
+    @Resource
+    THdTagServiceImpl hdTagService;
+
+    @Resource
+    OPCDataServiceImpl opcDataService;
+
+    @Resource
+    private AsyncEventBus asyncEventBus;
+
+    @Resource(name = "taskExecutor")
+    ThreadPoolTaskExecutor taskExecutor;
+
+
+    //定时器
+    @Resource
+    private ScheduledTaskManager scheduledTaskManager;
+
+    private ConcurrentHashMap<Long, HDDataConnection> mOPCDaClientMap = new ConcurrentHashMap<>();
+
+    private Set<String> taskNameSet = new HashSet<>();
+
+    /**
+     * 获得基础的连接信息
+     */
+    public HDDataConnection createServer(OPCServer opcServer) {
+        return mOPCDaClientMap.computeIfAbsent(opcServer.getId(), id -> {
+            HDDataServer server = HDServerFactory.getHDDataServer(opcServer.getIp(), opcServer.getPort(), "", opcServer.getPort());
+            HDDataConnection dataConn = null;
+            try {
+                dataConn = HDConnectionFactory.getHDDataConnection(server);
+                dataConn.loginToServer(opcServer.getUsername(), opcServer.getPassword());
+                dataConn.dispose();
+            } catch (HDSdkException e) {
+                e.printStackTrace();
+            }
+            return dataConn;
+        });
+    }
+
+
+    public Object createSubscription(OPCServer opcServer, THdTag hdTag) {
+        StringBuilder sb = new StringBuilder();
+        if (ObjectUtils.isNotEmpty(hdTag)) {
+            scheduledTaskManager.addTask(hdTag.getTagName(), 0, hdTag.getPeriod(), TimeUnit.SECONDS, () -> {
+                HDDataConnection connection = createServer(opcServer);
+                HDDataProvider dp = new HDDataProvider(connection);
+                try {
+                    HDRecord hdRecord = dp.querySnapshotByTagID(hdTag.getTagId());
+                    asyncEventBus.post(hdRecord);
+                } catch (HDSdkException e) {
+                    e.printStackTrace();
+                    log.info("{}订阅异常:{}", hdTag.getTagName(), e.getMessage());
+                }
+            });
+        }
+        return sb;
+    }
+
+    public Object subscribe(THdTag hdTag) {
+        try {
+            HdTagDTO opcPointDTO = hdTagService.selectInfoWithServer(hdTag);
+            QueryWrapper<HdTagDTO> pointQueryWrapper = new QueryWrapper<>();
+            pointQueryWrapper.lambda().eq(HdTagDTO::getStatus, "1");
+            OPCServer opcServer = new OPCServer();
+            BeanUtils.copyProperties(opcPointDTO, opcServer);
+            return createSubscription(opcServer, opcPointDTO);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
+    /***
+     * 取消订阅
+     * @param tHdTag
+     */
+    public void unsubscribe(THdTag tHdTag) {
+        taskNameSet.remove(tHdTag.getTagName());
+        scheduledTaskManager.cancelTask(tHdTag.getTagName());
+    }
+
+    /***
+     * 取消可用订阅
+     */
+    public void unsubscribeAvailable() {
+        for (String taskName : taskNameSet) {
+            scheduledTaskManager.cancelTask(taskName);
+        }
+        taskNameSet.clear();
+    }
+
+    /**
+     * 项目启动时自动创建 PLC连接并订阅节点
+     */
+    public void subscribeAvailable() {
+        QueryWrapper<OPCServer> serverQueryWrapper = new QueryWrapper<>();
+        serverQueryWrapper.lambda().eq(OPCServer::getStatus, "1");
+        List<OPCServer> opcServerList = opcServerService.list(serverQueryWrapper);
+        if (ObjectUtils.isEmpty(opcServerList)) {
+            return;
+        }
+        for (OPCServer opcServer : opcServerList) {
+            QueryWrapper<THdTag> pointQueryWrapper = new QueryWrapper<>();
+            pointQueryWrapper.lambda().eq(THdTag::getOpcServerId, opcServer.getId()).eq(THdTag::getStatus, "1");
+            List<THdTag> opcPointList = hdTagService.list(pointQueryWrapper);
+            if (ObjectUtils.isNotEmpty(opcPointList)) {
+                log.info("start point list:");
+                for (THdTag opcPoint : opcPointList) {
+                    log.info(opcPoint.getTagName());
+                    createSubscription(opcServer, opcPoint);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * 读取节点数据
+     * <p>
+     * identifier也可以通过UaExpert客户端去查询,这个值=通道名称.设备名称.标记名称
+     *
+     * @param opcPoint
+     * @throws Exception
+     */
+    public HDRecord readNodeValue(THdTag opcPoint) throws Exception {
+        HdTagDTO opcPointDTO = hdTagService.selectInfoWithServer(opcPoint);
+        if (ObjectUtils.isEmpty(opcPointDTO)) {
+            return null;
+        }
+        OPCServer opcServer = new OPCServer();
+        BeanUtils.copyProperties(opcPointDTO, opcServer);
+        HDDataConnection connection = createServer(opcServer);
+        HDDataProvider dp = new HDDataProvider(connection);
+        HDRecord hdRecord = dp.querySnapshotByTagID(opcPoint.getTagId());
+        return hdRecord;
+    }
+
+    @PreDestroy
+    public void releaseServer() {
+        if (ObjectUtils.isNotEmpty(mOPCDaClientMap)) {
+            for (HDDataConnection server : mOPCDaClientMap.values()) {
+                try {
+                    server.dispose();
+                } catch (HDSdkException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+}

+ 1 - 1
taphole-opc/src/main/java/com/sckj/opc/dauaservice/OPCDAServiceImpl.java → taphole-opc/src/main/java/com/sckj/opc/dataservice/OPCDAServiceImpl.java

@@ -1,4 +1,4 @@
-package com.sckj.opc.dauaservice;
+package com.sckj.opc.dataservice;
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.google.common.eventbus.AsyncEventBus;

+ 1 - 1
taphole-opc/src/main/java/com/sckj/opc/dauaservice/OPCUAServiceImpl.java → taphole-opc/src/main/java/com/sckj/opc/dataservice/OPCUAServiceImpl.java

@@ -1,4 +1,4 @@
-package com.sckj.opc.dauaservice;
+package com.sckj.opc.dataservice;
 
 import com.alibaba.fastjson2.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

+ 32 - 0
taphole-opc/src/main/java/com/sckj/opc/dto/HdTagDTO.java

@@ -0,0 +1,32 @@
+package com.sckj.opc.dto;
+
+import com.sckj.opc.entity.THdTag;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @Author feng
+ * @Date 2024-11-21 上午 11:32
+ * @Description TODO
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class HdTagDTO extends THdTag {
+
+    @ApiModelProperty(value = "用户名")
+    private String username;
+
+    @ApiModelProperty(value = "密码")
+    private String password;
+
+    @ApiModelProperty(value = "IP地址")
+    private String ip;
+
+    @ApiModelProperty(value = "端口号")
+    private Integer port;
+}

+ 1 - 2
taphole-opc/src/main/java/com/sckj/opc/entity/OPCPoint.java

@@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
-import lombok.Builder;
 import lombok.Data;
 
 /**
@@ -25,7 +24,7 @@ public class OPCPoint {
     @ApiModelProperty(value = "所属opcserver")
     private Long opcServerId;
 
-    @ApiModelProperty(value = "所属炉")
+    @ApiModelProperty(value = "所属炉")
     private String boilerId;
 
     @ApiModelProperty(value = "命名空间,默认为2")

+ 4 - 2
taphole-opc/src/main/java/com/sckj/opc/entity/OPCServer.java

@@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
-import lombok.Builder;
 import lombok.Data;
 
 import javax.validation.constraints.NotNull;
@@ -53,7 +52,7 @@ public class OPCServer {
     @ApiModelProperty(value = "KEPServer的注册表ID")
     private String clsid;
 
-    @ApiModelProperty(value = "所属炉")
+    @ApiModelProperty(value = "所属炉")
     private String boilerId;
 
     @ApiModelProperty(value = "铁口区域编号")
@@ -68,4 +67,7 @@ public class OPCServer {
     @ApiModelProperty(value = "创建人")
     private String createBy;
 
+    @ApiModelProperty(value = "端口号")
+    private Integer port;
+
 }

+ 66 - 0
taphole-opc/src/main/java/com/sckj/opc/entity/THdTag.java

@@ -0,0 +1,66 @@
+package com.sckj.opc.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@TableName(value = "t_hd_tag")
+@Data
+@ApiModel("IHD标记实体")
+public class THdTag implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value="id", type= IdType.AUTO)
+    @ApiModelProperty(value = "")
+    private Long id;
+
+    @ApiModelProperty(value = "所属server地址")
+    private Long opcServerId;
+
+    @ApiModelProperty(value = "铁口区域编号")
+    private String tapholeId;
+
+    @ApiModelProperty(value = "所属高炉")
+    private String boilerId;
+
+    @ApiModelProperty(value = "状态")
+    private String status;
+
+    @ApiModelProperty(value = "请求频率(秒)")
+    private Integer period;
+
+    @ApiModelProperty(value = "tag点id")
+    private Integer tagId;
+
+    @ApiModelProperty(value = "tag点名称")
+    private String tagName;
+
+    @ApiModelProperty(value = "数据类型")
+    private String tagType;
+
+    @ApiModelProperty(value = "订阅点说明")
+    private String tagDesc;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    @ApiModelProperty(value = "创建人")
+    private String createBy;
+
+    @ApiModelProperty(value = "创建时间")
+    private Date createTime;
+
+    @ApiModelProperty(value = "更新人")
+    private String updateBy;
+
+    @ApiModelProperty(value = "更新时间")
+    private Date updateTime;
+
+}

+ 29 - 0
taphole-opc/src/main/java/com/sckj/opc/mapper/THdTagMapper.java

@@ -0,0 +1,29 @@
+package com.sckj.opc.mapper;
+
+import com.sckj.common.core.basics.IBaseMapper;
+import com.sckj.opc.dto.HdTagDTO;
+import com.sckj.opc.entity.THdTag;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * IHD标记Mapper
+ * @author LikeAdmin
+ */
+@Mapper
+public interface THdTagMapper extends IBaseMapper<THdTag> {
+    /***
+     * 获取带有server信息的订阅点
+     * @param opcPoint
+     * @return
+     */
+    HdTagDTO selectInfoWithServer(THdTag opcPoint);
+
+
+    /***
+     * 获取可用的订阅点
+     * @return
+     */
+    List<HdTagDTO> getAvailablePoints();
+}

+ 173 - 0
taphole-opc/src/main/java/com/sckj/opc/service/THdTagServiceImpl.java

@@ -0,0 +1,173 @@
+package com.sckj.opc.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.sckj.common.core.PageResult;
+import com.sckj.common.validate.commons.PageValidate;
+import com.sckj.opc.dto.HdTagDTO;
+import com.sckj.opc.entity.THdTag;
+import com.sckj.opc.mapper.THdTagMapper;
+import com.sckj.opc.validate.THdTagCreateValidate;
+import com.sckj.opc.validate.THdTagSearchValidate;
+import com.sckj.opc.validate.THdTagUpdateValidate;
+import com.sckj.opc.vo.THdTagDetailVo;
+import com.sckj.opc.vo.THdTagListedVo;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.util.Assert;
+
+import javax.annotation.Resource;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * IHD标记实现类
+ * @author LikeAdmin
+ */
+@Service
+public class THdTagServiceImpl  extends ServiceImpl<THdTagMapper, THdTag> {
+        
+    @Resource
+    THdTagMapper tHdTagMapper;
+
+    /**
+     * IHD标记列表
+     *
+     * @author LikeAdmin
+     * @param pageValidate 分页参数
+     * @param searchValidate 搜索参数
+     * @return PageResult<THdTagListedVo>
+     */
+    
+    public PageResult<THdTagListedVo> list(PageValidate pageValidate, THdTagSearchValidate searchValidate) {
+        Integer page  = pageValidate.getPageNo();
+        Integer limit = pageValidate.getPageSize();
+
+        QueryWrapper<THdTag> queryWrapper = new QueryWrapper<>();
+        queryWrapper.orderByDesc("id");
+
+        tHdTagMapper.setSearch(queryWrapper, searchValidate, new String[]{
+            "=:opcServerId@opc_server_id:long",
+            "=:status:str",
+            "=:period:int",
+            "=:tagId@tag_id:int",
+            "like:tagName@tag_name:str",
+            "=:tagType@tag_type:str",
+            "like:tagDesc@tag_desc:str",
+            "like:remark:str",
+        });
+
+        IPage<THdTag> iPage = tHdTagMapper.selectPage(new Page<>(page, limit), queryWrapper);
+
+        List<THdTagListedVo> list = new LinkedList<>();
+        for(THdTag item : iPage.getRecords()) {
+            THdTagListedVo vo = new THdTagListedVo();
+            BeanUtils.copyProperties(item, vo);
+            list.add(vo);
+        }
+
+        return PageResult.iPageHandle(iPage.getTotal(), iPage.getCurrent(), iPage.getSize(), list);
+    }
+
+    /**
+     * IHD标记详情
+     *
+     * @author LikeAdmin
+     * @param id 主键参数
+     * @return THdTag
+     */
+    
+    public THdTagDetailVo detail(Integer id) {
+        THdTag model = tHdTagMapper.selectOne(
+                new QueryWrapper<THdTag>()
+                    .eq("id", id)
+                    .last("limit 1"));
+
+        Assert.notNull(model, "数据不存在");
+
+        THdTagDetailVo vo = new THdTagDetailVo();
+        BeanUtils.copyProperties(model, vo);
+        return vo;
+    }
+
+    /**
+     * IHD标记新增
+     *
+     * @author LikeAdmin
+     * @param createValidate 参数
+     */
+    
+    public void add(THdTagCreateValidate createValidate) {
+        THdTag model = new THdTag();
+        model.setOpcServerId(createValidate.getOpcServerId());
+        model.setStatus(createValidate.getStatus());
+        model.setPeriod(createValidate.getPeriod());
+        model.setTagId(createValidate.getTagId());
+        model.setTagName(createValidate.getTagName());
+        model.setTagType(createValidate.getTagType());
+        model.setTagDesc(createValidate.getTagDesc());
+        model.setRemark(createValidate.getRemark());
+        tHdTagMapper.insert(model);
+    }
+
+    /**
+     * IHD标记编辑
+     *
+     * @author LikeAdmin
+     * @param updateValidate 参数
+     */
+    
+    public void edit(THdTagUpdateValidate updateValidate) {
+        THdTag model = tHdTagMapper.selectOne(
+                new QueryWrapper<THdTag>()
+                    .eq("id",  updateValidate.getId())
+                    .last("limit 1"));
+
+        Assert.notNull(model, "数据不存在!");
+
+        model.setOpcServerId(updateValidate.getOpcServerId());
+        model.setStatus(updateValidate.getStatus());
+        model.setPeriod(updateValidate.getPeriod());
+        model.setTagId(updateValidate.getTagId());
+        model.setTagName(updateValidate.getTagName());
+        model.setTagType(updateValidate.getTagType());
+        model.setTagDesc(updateValidate.getTagDesc());
+        model.setRemark(updateValidate.getRemark());
+        tHdTagMapper.updateById(model);
+    }
+
+    /**
+     * IHD标记删除
+     *
+     * @author LikeAdmin
+     * @param id 主键ID
+     */
+    
+    public void del(Integer id) {
+        THdTag model = tHdTagMapper.selectOne(
+                new QueryWrapper<THdTag>()
+                    .eq("id", id)
+                    .last("limit 1"));
+
+        Assert.notNull(model, "数据不存在!");
+
+        tHdTagMapper.delete(new QueryWrapper<THdTag>().eq("id", id));
+    }
+
+    public HdTagDTO selectInfoWithServer(THdTag opcPoint) {
+        return tHdTagMapper.selectInfoWithServer(opcPoint);
+    }
+
+
+    /***
+     * 获取可用的订阅点
+     * @return
+     */
+    public List<HdTagDTO> getAvailablePoints(){
+        return tHdTagMapper.getAvailablePoints();
+    }
+
+
+}

+ 39 - 0
taphole-opc/src/main/java/com/sckj/opc/validate/THdTagCreateValidate.java

@@ -0,0 +1,39 @@
+package com.sckj.opc.validate;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+@ApiModel("IHD标记创建参数")
+public class THdTagCreateValidate implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "所属server地址")
+    private Long opcServerId;
+
+    @ApiModelProperty(value = "状态")
+    private String status;
+
+    @ApiModelProperty(value = "请求频率(秒)")
+    private Integer period;
+
+    @ApiModelProperty(value = "tag点id")
+    private Integer tagId;
+
+    @ApiModelProperty(value = "tag点名称")
+    private String tagName;
+
+    @ApiModelProperty(value = "数据类型")
+    private String tagType;
+
+    @ApiModelProperty(value = "订阅点说明")
+    private String tagDesc;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+}

+ 39 - 0
taphole-opc/src/main/java/com/sckj/opc/validate/THdTagSearchValidate.java

@@ -0,0 +1,39 @@
+package com.sckj.opc.validate;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+@ApiModel("IHD标记搜素参数")
+public class THdTagSearchValidate implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "所属server地址")
+    private Long opcServerId;
+
+    @ApiModelProperty(value = "状态")
+    private String status;
+
+    @ApiModelProperty(value = "请求频率(秒)")
+    private Integer period;
+
+    @ApiModelProperty(value = "tag点id")
+    private Integer tagId;
+
+    @ApiModelProperty(value = "tag点名称")
+    private String tagName;
+
+    @ApiModelProperty(value = "数据类型")
+    private String tagType;
+
+    @ApiModelProperty(value = "订阅点说明")
+    private String tagDesc;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+}

+ 46 - 0
taphole-opc/src/main/java/com/sckj/opc/validate/THdTagUpdateValidate.java

@@ -0,0 +1,46 @@
+package com.sckj.opc.validate;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * IHD标记参数
+ * @author LikeAdmin
+ */
+@Data
+@ApiModel("IHD标记更新参数")
+public class THdTagUpdateValidate implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "")
+    private Long id;
+
+    @ApiModelProperty(value = "所属server地址")
+    private Long opcServerId;
+
+    @ApiModelProperty(value = "状态")
+    private String status;
+
+    @ApiModelProperty(value = "请求频率(秒)")
+    private Integer period;
+
+    @ApiModelProperty(value = "tag点id")
+    private Integer tagId;
+
+    @ApiModelProperty(value = "tag点名称")
+    private String tagName;
+
+    @ApiModelProperty(value = "数据类型")
+    private String tagType;
+
+    @ApiModelProperty(value = "订阅点说明")
+    private String tagDesc;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+}

+ 5 - 3
taphole-opc/src/main/java/com/sckj/opc/validate/TOpcServerCreateValidate.java

@@ -3,10 +3,9 @@ package com.sckj.opc.validate;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+
+import javax.validation.constraints.NotNull;
 import java.io.Serializable;
-import java.util.Date;
-import java.util.Date;
-import javax.validation.constraints.*;
 
 @Data
 @ApiModel("opc服务器创建参数")
@@ -62,4 +61,7 @@ public class TOpcServerCreateValidate implements Serializable {
     @ApiModelProperty(value = "opc标准")
     private String type;
 
+    @ApiModelProperty(value = "端口号")
+    private String port;
+
 }

+ 5 - 3
taphole-opc/src/main/java/com/sckj/opc/validate/TOpcServerSearchValidate.java

@@ -3,9 +3,8 @@ package com.sckj.opc.validate;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+
 import java.io.Serializable;
-import java.util.Date;
-import java.util.Date;
 
 @Data
 @ApiModel("opc服务器搜素参数")
@@ -37,7 +36,7 @@ public class TOpcServerSearchValidate implements Serializable {
     @ApiModelProperty(value = "KEPServer的注册表ID(暂不用)")
     private String clsid;
 
-    @ApiModelProperty(value = "认证证书路径(暂不用,空表示不使用)D:/project/xiha/opcserver/D:/project/xiha/opcserver/")
+    @ApiModelProperty(value = "认证证书路径")
     private String certPath;
 
     @ApiModelProperty(value = "状态(1正常 0停用)")
@@ -49,4 +48,7 @@ public class TOpcServerSearchValidate implements Serializable {
     @ApiModelProperty(value = "opc标准")
     private String type;
 
+    @ApiModelProperty(value = "端口号")
+    private String port;
+
 }

+ 3 - 0
taphole-opc/src/main/java/com/sckj/opc/validate/TOpcServerUpdateValidate.java

@@ -69,4 +69,7 @@ public class TOpcServerUpdateValidate implements Serializable {
     @ApiModelProperty(value = "opc标准")
     private String type;
 
+    @ApiModelProperty(value = "端口号")
+    private String port;
+
 }

+ 45 - 0
taphole-opc/src/main/java/com/sckj/opc/vo/THdTagDetailVo.java

@@ -0,0 +1,45 @@
+package com.sckj.opc.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Date;
+
+@Data
+@ApiModel("IHD标记详情Vo")
+public class THdTagDetailVo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "")
+    private Long id;
+
+    @ApiModelProperty(value = "所属server地址")
+    private Long opcServerId;
+
+    @ApiModelProperty(value = "状态")
+    private String status;
+
+    @ApiModelProperty(value = "请求频率(秒)")
+    private Integer period;
+
+    @ApiModelProperty(value = "tag点id")
+    private Integer tagId;
+
+    @ApiModelProperty(value = "tag点名称")
+    private String tagName;
+
+    @ApiModelProperty(value = "数据类型")
+    private String tagType;
+
+    @ApiModelProperty(value = "订阅点说明")
+    private String tagDesc;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 45 - 0
taphole-opc/src/main/java/com/sckj/opc/vo/THdTagListedVo.java

@@ -0,0 +1,45 @@
+package com.sckj.opc.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Date;
+
+@Data
+@ApiModel("IHD标记列表Vo")
+public class THdTagListedVo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "")
+    private Long id;
+
+    @ApiModelProperty(value = "所属server地址")
+    private Long opcServerId;
+
+    @ApiModelProperty(value = "状态")
+    private String status;
+
+    @ApiModelProperty(value = "请求频率(秒)")
+    private Integer period;
+
+    @ApiModelProperty(value = "tag点id")
+    private Integer tagId;
+
+    @ApiModelProperty(value = "tag点名称")
+    private String tagName;
+
+    @ApiModelProperty(value = "数据类型")
+    private String tagType;
+
+    @ApiModelProperty(value = "订阅点说明")
+    private String tagDesc;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+
+}

BIN
taphole-opc/src/main/resources/jar/hd-datasdk-3.9.3.jar


BIN
taphole-opc/src/main/resources/lib/hd/linux/libLogC.so.1.0.0


BIN
taphole-opc/src/main/resources/lib/hd/linux/libhdDNAPI.so.1.0.0


BIN
taphole-opc/src/main/resources/lib/hd/linux/libhdDataSDK.so.1.0.0


BIN
taphole-opc/src/main/resources/lib/hd/linux/libhdKingAPI.so.1.0.0


BIN
taphole-opc/src/main/resources/lib/hd/linux/libhdNetClient.so.1.0.0


BIN
taphole-opc/src/main/resources/lib/hd/linux/libhdOS.so.1.0.0


BIN
taphole-opc/src/main/resources/lib/hd/linux/libhdProcComm.so.1.0.0


BIN
taphole-opc/src/main/resources/lib/hd/win/hdBufferAPI.lib


BIN
taphole-opc/src/main/resources/lib/hd/win/hdDNAPI.dll


BIN
taphole-opc/src/main/resources/lib/hd/win/hdDataSDK.dll


BIN
taphole-opc/src/main/resources/lib/hd/win/hdKingAPI.dll


BIN
taphole-opc/src/main/resources/lib/hd/win/hdKingAPI.lib


BIN
taphole-opc/src/main/resources/lib/hd/win/hdNetClient.dll


BIN
taphole-opc/src/main/resources/lib/hd/win/hdOS.dll


BIN
taphole-opc/src/main/resources/lib/hd/win/hdOS.lib


BIN
taphole-opc/src/main/resources/lib/hd/win/hdProcComm.dll


+ 25 - 0
taphole-opc/src/main/resources/mapper/HdTagMapper.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.sckj.opc.mapper.THdTagMapper">
+
+
+    <select id="selectInfoWithServer" resultType="com.sckj.opc.dto.HdTagDTO">
+        select a.*,b.ip ip,b.username,b.password,b.port port
+        from t_hd_tag a left join t_opc_server b on a.opc_server_id=b.id
+        <where>
+            <if test="id != null">
+                a.id = #{id}
+            </if>
+        </where>
+        limit 1
+    </select>
+
+    <select id="getAvailablePoints" resultType="com.sckj.opc.dto.HdTagDTO">
+        select a.*,b.ip ip,b.username,b.password,b.port port
+        from t_hd_tag a
+          inner join (select * from t_opc_server where status='1') b on a.opc_server_id=b.id
+        where a.status = '1'
+    </select>
+
+
+</mapper>

+ 1 - 1
taphole-warn/src/main/java/com/sckj/warn/entity/TExceptionLog.java

@@ -48,7 +48,7 @@ public class TExceptionLog implements Serializable {
     @ApiModelProperty(value = "上报状态,将异常事件上报至视频以及 AI 融合系统(1是 0否)")
     private String reportedStatus;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @ApiModelProperty(value = "铁口区域编号")

+ 2 - 1
taphole-warn/src/main/java/com/sckj/warn/service/impl/TExceptionLogServiceImpl.java

@@ -127,6 +127,7 @@ public class TExceptionLogServiceImpl  {
         model.setExceptionLevel(createValidate.getExceptionLevel());
         model.setReportedStatus(createValidate.getReportedStatus());
         model.setBoilerId(createValidate.getBoilerId());
+        model.setExceptionDesc(createValidate.getExceptionDesc());
         tExceptionLogMapper.insert(model);
     }
 
@@ -204,7 +205,7 @@ public class TExceptionLogServiceImpl  {
 
         // 创建标题行
         Row headerRow = sheet.createRow(0);
-        String[] columnNames = {"炉编号", "异常类型", "异常区域", "危害程度", "上报状态", "创建时间"};
+        String[] columnNames = {"炉编号", "异常类型", "异常区域", "危害程度", "上报状态", "创建时间"};
         for (int i = 0; i < columnNames.length; i++) {
             Cell cell = headerRow.createCell(i);
             cell.setCellValue(columnNames[i]);

+ 2 - 3
taphole-warn/src/main/java/com/sckj/warn/validate/TAudioCreateValidate.java

@@ -3,10 +3,9 @@ package com.sckj.warn.validate;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
+
+import javax.validation.constraints.NotNull;
 import java.io.Serializable;
-import java.util.Date;
-import java.util.Date;
-import javax.validation.constraints.*;
 
 @Data
 @ApiModel("音频创建参数")

+ 0 - 1
taphole-warn/src/main/java/com/sckj/warn/validate/TAudioUpdateValidate.java

@@ -1,6 +1,5 @@
 package com.sckj.warn.validate;
 
-import com.sckj.common.validator.annotation.IDMust;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;

+ 1 - 1
taphole-warn/src/main/java/com/sckj/warn/validate/TExceptionLogCreateValidate.java

@@ -38,7 +38,7 @@ public class TExceptionLogCreateValidate implements Serializable {
     private String reportedStatus;
 
     @NotNull(message = "boilerId参数缺失")
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
 

+ 1 - 1
taphole-warn/src/main/java/com/sckj/warn/validate/TExceptionLogSearchValidate.java

@@ -22,7 +22,7 @@ public class TExceptionLogSearchValidate implements Serializable {
     @ApiModelProperty(value = "危害程度(轻微、中等、重度)")
     private String exceptionLevel;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @ApiModelProperty(value = "铁口区域编号")

+ 1 - 1
taphole-warn/src/main/java/com/sckj/warn/vo/TExceptionLogDetailVo.java

@@ -27,7 +27,7 @@ public class TExceptionLogDetailVo implements Serializable {
     @ApiModelProperty(value = "上报状态,将异常事件上报至视频以及 AI 融合系统(1是 0否)")
     private String reportedStatus;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @ApiModelProperty(value = "铁口区域编号")

+ 2 - 2
taphole-warn/src/main/java/com/sckj/warn/vo/TExceptionLogExportVo.java

@@ -36,9 +36,9 @@ public class TExceptionLogExportVo implements Serializable {
     @ApiModelProperty(value = "危害程度")
     private String exceptionLevelName;
 
-    @ExcelProperty("炉编号")
+    @ExcelProperty("炉编号")
     @ColumnWidth(25)
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerName;
 
     @ExcelProperty("铁口区域编号")

+ 1 - 1
taphole-warn/src/main/java/com/sckj/warn/vo/TExceptionLogListedVo.java

@@ -30,7 +30,7 @@ public class TExceptionLogListedVo implements Serializable {
     @ApiModelProperty(value = "上报状态,将异常事件上报至视频以及 AI 融合系统(1是 0否)")
     private String reportedStatus;
 
-    @ApiModelProperty(value = "炉编号")
+    @ApiModelProperty(value = "炉编号")
     private String boilerId;
 
     @ApiModelProperty(value = "铁口区域编号")