Răsfoiți Sursa

1.优化定时器执行异常的打印
2.数据推送添加出铁工作诊断列表
3.数据推送-出铁状态集合添加出渣时间

wangxiaofei 2 luni în urmă
părinte
comite
b2f840e27e
19 a modificat fișierele cu 255 adăugiri și 145 ștergeri
  1. 17 2
      taphole-common/src/main/java/com/sckj/common/manager/ScheduledTaskManager.java
  2. 3 0
      taphole-iron/src/main/java/com/sckj/iron/constant/TaskNameConstants.java
  3. 8 0
      taphole-iron/src/main/java/com/sckj/iron/controller/TIronVisualScreenController.java
  4. 1 1
      taphole-iron/src/main/java/com/sckj/iron/dto/IronTrendL2DTO.java
  5. 1 1
      taphole-iron/src/main/java/com/sckj/iron/entity/TIronData.java
  6. 7 1
      taphole-iron/src/main/java/com/sckj/iron/entity/TIronTest.java
  7. 6 0
      taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronTestServiceImpl.java
  8. 137 112
      taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronVisualScreenServiceImpl.java
  9. 48 15
      taphole-iron/src/main/java/com/sckj/iron/socketio/DeviceEventListener.java
  10. 17 1
      taphole-iron/src/main/java/com/sckj/iron/socketio/PushData.java
  11. 1 1
      taphole-iron/src/main/java/com/sckj/iron/validate/TIronDataSearchValidate.java
  12. 1 1
      taphole-iron/src/main/java/com/sckj/iron/validate/TL2DataCreateValidate.java
  13. 1 1
      taphole-iron/src/main/java/com/sckj/iron/validate/TL2DataSearchValidate.java
  14. 1 1
      taphole-iron/src/main/java/com/sckj/iron/validate/TL2DataUpdateValidate.java
  15. 1 3
      taphole-iron/src/main/java/com/sckj/iron/vo/TIronTestListedVo.java
  16. 1 1
      taphole-iron/src/main/java/com/sckj/iron/vo/TL2DataDetailVo.java
  17. 1 1
      taphole-iron/src/main/java/com/sckj/iron/vo/TL2DataListedVo.java
  18. 2 2
      taphole-l2/src/main/java/com/sckj/l2/entity/TL2Data.java
  19. 1 1
      taphole-l2/src/main/java/com/sckj/l2/vo/TL2DataListedVo.java

+ 17 - 2
taphole-common/src/main/java/com/sckj/common/manager/ScheduledTaskManager.java

@@ -8,15 +8,27 @@ import java.util.concurrent.*;
 @Component
 public class ScheduledTaskManager {
 
-    private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5);
+    private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(100);
     private final Map<String, ScheduledFuture<?>> tasks = new ConcurrentHashMap<>();
 
     // 添加定时任务
     public void addTask(String taskName, long initialDelay, long period, TimeUnit unit, Runnable task) {
         ScheduledFuture<?> future = tasks.get(taskName);
+        //System.out.println("[ScheduledTaskManager] addTask: " + taskName + ", future=" + future + ", isShutdown=" + executorService.isShutdown());
         if (future == null) {
-            future = executorService.scheduleAtFixedRate(task, initialDelay, period, unit);
+            future = executorService.scheduleAtFixedRate(() -> {
+                //System.out.println("[ScheduledTaskManager] 定时任务[" + taskName + "] 执行一次, 线程: " + Thread.currentThread().getName());
+                try {
+                    task.run();
+                } catch (Exception e) {
+                    System.err.println("[ScheduledTaskManager] 定时任务[" + taskName + "] 执行异常: " + e.getMessage());
+                    e.printStackTrace();
+                }
+            }, initialDelay, period, unit);
             tasks.put(taskName, future);
+            //System.out.println("[ScheduledTaskManager] 定时任务[" + taskName + "] 已添加到线程池");
+        } else {
+            //System.out.println("[ScheduledTaskManager] 定时任务[" + taskName + "] 已存在,未重复添加");
         }
     }
 
@@ -26,6 +38,9 @@ public class ScheduledTaskManager {
         if (future != null) {
             future.cancel(true);
             tasks.remove(taskName);
+            System.out.println("[ScheduledTaskManager] 定时任务[" + taskName + "] 已取消");
+        } else {
+            System.out.println("[ScheduledTaskManager] 定时任务[" + taskName + "] 不存在,无法取消");
         }
     }
 }

+ 3 - 0
taphole-iron/src/main/java/com/sckj/iron/constant/TaskNameConstants.java

@@ -38,4 +38,7 @@ public class TaskNameConstants {
     //L2定时拉取
     public static final String TASKNAME_IRON_L2 = "iron_l2";
 
+    //诊断定时拉取
+    public static final String TASKNAME_IRON_TEST = "iron_test";
+
 }

+ 8 - 0
taphole-iron/src/main/java/com/sckj/iron/controller/TIronVisualScreenController.java

@@ -228,6 +228,14 @@ public class TIronVisualScreenController {
     }
 
     @NotPower
+    @PostMapping("/getLatest3")
+    @ApiOperation(value = "最新出铁诊断前3条")
+    public AjaxResult getLatest3() {
+        List<TIronTest> one = iTIronTestService.getLatest3();
+        return AjaxResult.success(one);
+    }
+
+    @NotPower
     @PostMapping("/getIronLegend")
     @ApiOperation(value = "实时数据图图例")
     public AjaxResult getIronLegend() {

+ 1 - 1
taphole-iron/src/main/java/com/sckj/iron/dto/IronTrendL2DTO.java

@@ -15,7 +15,7 @@ public class IronTrendL2DTO {
 //    @ApiModelProperty(value = "出铁开始时间(格式:yyyyMMddHHmmss)")
 //    private String createTime;
 
-    @ApiModelProperty(value = "泥量")
+    @ApiModelProperty(value = "泥量")
     private Double mudWeight;
 
     @ApiModelProperty(value = "钻杆直径")

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

@@ -69,7 +69,7 @@ public class TIronData implements Serializable {
     @ExcelIgnore
     private String avgTemp;
 
-    @ApiModelProperty(value = "泥量")
+    @ApiModelProperty(value = "泥量")
     @ExcelIgnore
     private String mudWeight;
 

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

@@ -3,6 +3,7 @@ package com.sckj.iron.entity;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
@@ -21,12 +22,14 @@ public class TIronTest implements Serializable {
     private String createBy;
 
     @ApiModelProperty(value = "创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date createTime;
 
     @ApiModelProperty(value = "更新人")
     private String updateBy;
 
     @ApiModelProperty(value = "更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date updateTime;
 
     @TableId(value="id", type= IdType.AUTO)
@@ -39,10 +42,13 @@ public class TIronTest implements Serializable {
     @ApiModelProperty(value = "鱼雷罐车车号")
     private String testDesc;
 
-    @ApiModelProperty(value = "铁口区域编号")
+    @ApiModelProperty(value = "铁口编号")
     private String tapholeId;
 
     @ApiModelProperty(value = "高炉编号")
     private String boilerId;
 
+    @ApiModelProperty(value = "出铁次数编号")
+    private String ironNo;
+
 }

+ 6 - 0
taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronTestServiceImpl.java

@@ -151,4 +151,10 @@ public class TIronTestServiceImpl extends ServiceImpl<TIronTestMapper, TIronTest
         return this.lambdaQuery().orderByDesc(TIronTest::getCreateTime).list().stream().findFirst().orElseThrow(()->new OperateException("未查询到数据"));
     }
 
+
+    public List<TIronTest> getLatest3() {
+        return this.lambdaQuery().orderByDesc(TIronTest::getCreateTime).last("limit 3").list();
+    }
+
+
 }

+ 137 - 112
taphole-iron/src/main/java/com/sckj/iron/service/impl/TIronVisualScreenServiceImpl.java

@@ -39,36 +39,29 @@ public class TIronVisualScreenServiceImpl {
      * @return
      */
     public synchronized Map<String, Object> getIronLegend(Map<String, Object> result) {
+        result = new LinkedHashMap<>();
 
-        //最新L2数据
-        CompletableFuture<TL2Data> latestL2Future = CompletableFuture.supplyAsync(() ->
-                tl2DataService.lambdaQuery()
-                        //.le(TL2Data::getIronStarttime, new SimpleDateFormat("yyyyMMddHHmmss").format(new java.util.Date()))
-                        .eq(TL2Data::getTapholeId, "1")
-                        .orderByDesc(TL2Data::getIronStarttime)
-                        .last("limit 1").one()
-        );
-
-        // 1. 计算起止时间
-        int hours = 24;
-        //给固定时间,24小时之内
-        java.util.Date endTime = new java.util.Date();
-        java.util.Calendar cal = java.util.Calendar.getInstance();
-        cal.setTime(endTime);
-        cal.add(java.util.Calendar.HOUR_OF_DAY, -hours);
-        java.util.Date startTime = cal.getTime();
 
 //        // 1. 计算起止时间
-//        // 临时调试用,固定时间范围
-//        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-//        final java.util.Date startTime;
-//        final java.util.Date endTime;
-//        try {
-//            startTime = sdf.parse("2025-07-13 02:15:00");
-//            endTime = sdf.parse("2025-07-14 00:20:00");
-//        } catch (Exception e) {
-//            throw new RuntimeException("时间解析失败", e);
-//        }
+//        int hours = 24;
+//        //给固定时间,24小时之内
+//        java.util.Date endTime = new java.util.Date();
+//        java.util.Calendar cal = java.util.Calendar.getInstance();
+//        cal.setTime(endTime);
+//        cal.add(java.util.Calendar.HOUR_OF_DAY, -hours);
+//        java.util.Date startTime = cal.getTime();
+
+        // 1. 计算起止时间
+        // 临时调试用,固定时间范围
+        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        final java.util.Date startTime;
+        final java.util.Date endTime;
+        try {
+            startTime = sdf.parse("2025-07-13 02:15:00");
+            endTime = sdf.parse("2025-07-14 00:20:00");
+        } catch (Exception e) {
+            throw new RuntimeException("时间解析失败", e);
+        }
 
 
         // 1. 生成完整的每一分钟时间点
@@ -80,6 +73,18 @@ public class TIronVisualScreenServiceImpl {
             cursor.add(java.util.Calendar.MINUTE, 1);
         }
 
+
+        //最新L2数据
+        CompletableFuture<TL2Data> latestL2Future = CompletableFuture.supplyAsync(() ->
+                tl2DataService.lambdaQuery()
+                        //.le(TL2Data::getIronStarttime, new SimpleDateFormat("yyyyMMddHHmmss").format(new java.util.Date()))
+                        .eq(TL2Data::getTapholeId, "1")
+                        .orderByDesc(TL2Data::getIronStarttime)
+                        .last("limit 1").one()
+        );
+
+
+
         //获取指定时间范围内的数据
         CompletableFuture<List<OPCData>> opcDataFuture = CompletableFuture.supplyAsync(() ->
                 opcDataService.lambdaQuery()
@@ -120,20 +125,76 @@ public class TIronVisualScreenServiceImpl {
                         .last("limit 1").one()
         );
 
+        //获取当前有效出铁状态数据
+        CompletableFuture<OPCData> currentTappingFuture = CompletableFuture.supplyAsync(() ->
+                opcDataService.lambdaQuery()
+                        .eq(OPCData::getPointName, "BF4_1_IRONNOTCH_TAPPING")
+                        .isNotNull(OPCData::getData)
+                        .orderByDesc(OPCData::getServerTime)
+                        .last("limit 1").one()
+        );
+
+
         Integer preTappingVal = null;
+        Integer currentTappingVal = 0;
 
         try {
-            CompletableFuture.allOf(preTappingFuture, latestL2Future, opcDataFuture).join();
+            CompletableFuture.allOf(preTappingFuture, latestL2Future, opcDataFuture,currentTappingFuture,l2DataFuture).join();
             Map<String, List<OPCData>> opcDataMap = opcDataFuture.get().stream()
                     .collect(Collectors.groupingBy(OPCData::getPointName));
 
             TL2Data latestL2 = latestL2Future.get();
             result.put("elementS", RealtimeData.builder().desc("铁水成分-硫").value(latestL2.getElementS()).build());
             result.put("elementSi", RealtimeData.builder().desc("铁水成分-硅").value(latestL2.getElementSi()).build());
-            result.put("mudWeight", RealtimeData.builder().desc("泥量").value(latestL2.getMudWeight()).unit("L").build());
+            result.put("mudWeight", RealtimeData.builder().desc("泥量").value(latestL2.getMudWeight()).unit("L").build());
             result.put("pollMm", RealtimeData.builder().desc("钻杆直径").value(latestL2.getPollMm()).unit("mm").build());
             result.put("openDepth", RealtimeData.builder().desc("开口深度").value(latestL2.getOpenDepth()).unit("mm").build());
 
+            OPCData currentTapping = currentTappingFuture.get();
+            if (currentTapping != null && currentTapping.getData() != null) {
+                Object v = currentTapping.getData();
+                if (v instanceof Number) currentTappingVal = ((Number) v).intValue();
+                else if (v instanceof String) {
+                    String str = ((String) v).trim();
+                    if (!str.isEmpty()) {
+                        try {
+                            currentTappingVal = Integer.parseInt(str);
+                        } catch (Exception ignore) {
+                        }
+                    }
+                }
+            }
+
+            List<TL2Data> tl2DataList = l2DataFuture.get();
+            RealtimeData ironCosttime = (RealtimeData) result.getOrDefault("ironCosttime", RealtimeData.builder().desc("出铁时间").unit("min").value(0).build());
+            if (ObjectUtils.isNotEmpty(tl2DataList)) {
+                List<List<Map<String, Object>>> collect = tl2DataList.stream().map(item -> {
+                    List<Map<String, Object>> mapList = new ArrayList<>();
+                    Map<String, Object> map = new HashMap<>();
+                    map.put("name", String.format("第%s次出铁\n(%s号铁口)%s分钟", item.getIronNo(), item.getTapholeId(), item.getIronCosttime()));
+                    map.put("xAxis", TimeUtils.formatPartialDateString(item.getIronStarttime()));
+                    mapList.add(map);
+
+                    map = new HashMap<>();
+                    map.put("xAxis", TimeUtils.formatPartialDateString(item.getIronEndtime()));
+                    mapList.add(map);
+
+                    return mapList;
+                }).collect(Collectors.toList());
+
+                Map<String, Object> extraMap = new HashMap<>();
+                extraMap.put("mark", collect);
+                ironCosttime.setExtra(extraMap);
+            }
+            result.put("ironCosttime", ironCosttime);
+
+            if(0 == currentTappingVal || 1 == currentTappingVal){
+                result.put("ironWeight", RealtimeData.builder().desc("累计出铁量").unit("t").value(0).build());
+                result.put("ironSpeed", RealtimeData.builder().desc("铁水流速").value(0).unit("t/min").build());
+                result.put("ironTemp", RealtimeData.builder().desc("铁水温度").value(0).unit("℃").build());
+//                result.put("ironCosttime", RealtimeData.builder().desc("出铁时间").value(0).unit("min").build());
+                return result;
+            }
 
             //如果开始时间点没有值就从最近的获取
             OPCData preTapping = preTappingFuture.get();
@@ -153,6 +214,9 @@ public class TIronVisualScreenServiceImpl {
             }
 
 
+
+
+
             //BF4_1TH_1_MIR_NWT 1号车净重
             CompletableFuture<List<IronTrendL1DTO>> weight1ListFuture = CompletableFuture.supplyAsync(() ->
                     opcDataMap.getOrDefault("BF4_1TH_1_MIR_NWT", new ArrayList<>())
@@ -279,7 +343,7 @@ public class TIronVisualScreenServiceImpl {
                     }
                 }
 
-                RealtimeData ironWeight = (RealtimeData) result.getOrDefault("ironWeight", RealtimeData.builder().desc("铁水流量").unit("t").value(0).build());
+                RealtimeData ironWeight = (RealtimeData) result.getOrDefault("ironWeight", RealtimeData.builder().desc("累计出铁量").unit("t").value(0).build());
                 Map<String, Object> extraMap = new HashMap<>();
                 extraMap.put("mark",  new ArrayList<>());
                 ironWeight.setExtra(extraMap);
@@ -288,28 +352,10 @@ public class TIronVisualScreenServiceImpl {
             }
 
 
-            List<TL2Data> tl2DataList = l2DataFuture.get();
-            if (ObjectUtils.isNotEmpty(tl2DataList)) {
-                RealtimeData ironCosttime = (RealtimeData) result.getOrDefault("ironCosttime", RealtimeData.builder().desc("出铁时间").unit("min").value(0).build());
-                List<List<Map<String, Object>>> collect = tl2DataList.stream().map(item -> {
-                    List<Map<String, Object>> mapList = new ArrayList<>();
-                    Map<String, Object> map = new HashMap<>();
-                    map.put("name", String.format("第%s次出铁\n(%s号铁口)%s分钟", item.getIronNo(), item.getTapholeId(), item.getIronCosttime()));
-                    map.put("xAxis", TimeUtils.formatPartialDateString(item.getIronStarttime()));
-                    mapList.add(map);
 
-                    map = new HashMap<>();
-                    map.put("xAxis", TimeUtils.formatPartialDateString(item.getIronEndtime()));
-                    mapList.add(map);
 
-                    return mapList;
-                }).collect(Collectors.toList());
 
-                Map<String, Object> extraMap = new HashMap<>();
-                extraMap.put("mark", collect);
-                ironCosttime.setExtra(extraMap);
-                result.put("ironCosttime", ironCosttime);
-            }
+
 
         } catch (Exception e) {
              e.printStackTrace();
@@ -327,29 +373,25 @@ public class TIronVisualScreenServiceImpl {
      * @return
      */
     public synchronized Map<String, Object> getIronChart(TrendRequest queryDateType) {
-        // 1. 计算起止时间
-        int hours = Objects.isNull(queryDateType.getQueryHourBefore()) ? 24 : queryDateType.getQueryHourBefore();
-        //给固定时间,24小时之内
-        java.util.Date endTime = new java.util.Date();
-        java.util.Calendar cal = java.util.Calendar.getInstance();
-        cal.setTime(endTime);
-        cal.add(java.util.Calendar.HOUR_OF_DAY, -hours);
-        java.util.Date startTime = cal.getTime();
-//        // ====== 日志定位时间区间开始 ======
-//        System.out.println("[DEBUG] hours: " + hours);
-//        System.out.println("[DEBUG] startTime: " + sdfMinute.format(startTime));
-//        System.out.println("[DEBUG] endTime: " + sdfMinute.format(endTime));
-        // ====== 日志定位时间区间结束 ======
-        // 临时调试用,固定时间范围
-//        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-//        final java.util.Date startTime;
-//        final java.util.Date endTime;
-//        try {
-//            startTime = sdf.parse("2025-07-13 02:15:00");
-//            endTime = sdf.parse("2025-07-14 00:20:00");
-//        } catch (Exception e) {
-//            throw new RuntimeException("时间解析失败", e);
-//        }
+//        // 1. 计算起止时间
+//        int hours = Objects.isNull(queryDateType.getQueryHourBefore()) ? 24 : queryDateType.getQueryHourBefore();
+//        //给固定时间,24小时之内
+//        java.util.Date endTime = new java.util.Date();
+//        java.util.Calendar cal = java.util.Calendar.getInstance();
+//        cal.setTime(endTime);
+//        cal.add(java.util.Calendar.HOUR_OF_DAY, -hours);
+//        java.util.Date startTime = cal.getTime();
+
+//       临时调试用,固定时间范围
+        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        final java.util.Date startTime;
+        final java.util.Date endTime;
+        try {
+            startTime = sdf.parse("2025-07-13 02:15:00");
+            endTime = sdf.parse("2025-07-14 00:20:00");
+        } catch (Exception e) {
+            throw new RuntimeException("时间解析失败", e);
+        }
 
         // 2. 异步查询所有数据
         CompletableFuture<List<OPCData>> opcDataFuture = CompletableFuture.supplyAsync(() ->
@@ -381,7 +423,6 @@ public class TIronVisualScreenServiceImpl {
 
         // 3. 等待所有查询完成并转换数据
         try {
-            CompletableFuture.allOf(opcDataFuture, l2DataFuture).join();
 
             // 4. 按pointName分类OPC数据并转换为DTO
             Map<String, List<OPCData>> opcDataMap = opcDataFuture.get().stream()
@@ -600,7 +641,7 @@ public class TIronVisualScreenServiceImpl {
             result.put("ironWeight", ironFlowArr);
 
             // 处理铁水流速,出铁中按原逻辑,出铁结束后为0
-            List<List<Object>> ironSpeedArr = buildMinuteArrayForSpeed(xAxis, speed1List, speed2List, preSpeed1 != null ? preSpeed1.getData() : null, preSpeed2 != null ? preSpeed2.getData() : null);
+            List<List<Object>> ironSpeedArr = buildMinuteArrayForSpeed(xAxis, speed1List, speed2List, tappingMap);
             List<List<Object>> ironTempArr = buildMinuteArray(tempList, xAxis, preTemp != null ? preTemp.getData() : null);
 
             for (int i = 0; i < xAxis.size(); i++) {
@@ -668,8 +709,8 @@ public class TIronVisualScreenServiceImpl {
         return arr;
     }
 
-    // 铁水流速
-    private java.util.List<java.util.List<Object>> buildMinuteArrayForSpeed(java.util.List<String> xAxis, java.util.List<IronTrendL1DTO> speed1List, java.util.List<IronTrendL1DTO> speed2List, Object pre1, Object pre2) {
+    // 铁水流速(重写:合并取最大值,出铁周期内补齐空值,且出铁周期内流速不允许为0)
+    private java.util.List<java.util.List<Object>> buildMinuteArrayForSpeed(java.util.List<String> xAxis, java.util.List<IronTrendL1DTO> speed1List, java.util.List<IronTrendL1DTO> speed2List, java.util.Map<String, Integer> tappingMap) {
         java.util.Map<String, Double> speed1Map = new java.util.LinkedHashMap<>();
         java.util.Map<String, Double> speed2Map = new java.util.LinkedHashMap<>();
         for (IronTrendL1DTO e : speed1List) {
@@ -702,47 +743,31 @@ public class TIronVisualScreenServiceImpl {
                 if (value != null) speed2Map.put(min, value);
             }
         }
+        // 合并为最大值map
+        java.util.Map<String, Double> speedMap = new java.util.LinkedHashMap<>();
+        for (String key : speed1Map.keySet()) {
+            speedMap.put(key, speed1Map.get(key));
+        }
+        for (String key : speed2Map.keySet()) {
+            double v2 = speed2Map.get(key);
+            speedMap.put(key, Math.max(speedMap.getOrDefault(key, 0d), v2));
+        }
         java.util.List<java.util.List<Object>> arr = new java.util.ArrayList<>();
         Double last = null;
-        Double pre1Val = null, pre2Val = null;
-        if (pre1 != null) {
-            if (pre1 instanceof Number) pre1Val = ((Number) pre1).doubleValue();
-            else if (pre1 instanceof String) {
-                String str = ((String) pre1).trim();
-                if (!str.isEmpty()) {
-                    try {
-                        pre1Val = Double.parseDouble(str);
-                    } catch (Exception ignore) {
-                    }
-                }
-            }
-        }
-        if (pre2 != null) {
-            if (pre2 instanceof Number) pre2Val = ((Number) pre2).doubleValue();
-            else if (pre2 instanceof String) {
-                String str = ((String) pre2).trim();
-                if (!str.isEmpty()) {
-                    try {
-                        pre2Val = Double.parseDouble(str);
-                    } catch (Exception ignore) {
-                    }
+        for (String t : xAxis) {
+            Integer tapping = tappingMap.getOrDefault(t, 0);
+            Double v = speedMap.get(t);
+            if (tapping == 1) {
+                if (v == null || v == 0) {
+                    // 出铁周期内流速不允许为0,用上一个非0值
+                    v = last != null ? last : 0d;
                 }
+                arr.add(java.util.Arrays.asList(t, v));
+                if (v != null && v != 0) last = v;
+            } else {
+                arr.add(java.util.Arrays.asList(t, 0));
             }
         }
-        if (pre1Val != null && pre2Val != null) last = pre1Val + pre2Val;
-        else if (pre1Val != null) last = pre1Val;
-        else if (pre2Val != null) last = pre2Val;
-        for (String t : xAxis) {
-            Double cur1 = speed1Map.getOrDefault(t, null);
-            Double cur2 = speed2Map.getOrDefault(t, null);
-            Double sum = null;
-            if (cur1 != null && cur2 != null) sum = cur1 + cur2;
-            else if (cur1 != null) sum = cur1;
-            else if (cur2 != null) sum = cur2;
-            else sum = last;
-            arr.add(java.util.Arrays.asList(t, sum));
-            if (sum != null) last = sum;
-        }
         return arr;
     }
 

+ 48 - 15
taphole-iron/src/main/java/com/sckj/iron/socketio/DeviceEventListener.java

@@ -152,6 +152,11 @@ public class DeviceEventListener extends AbstractEventListener { //
     //出渣状态
     private static final String CHUZ_STATUS = "chuz";
 
+    private static final String CHUZ_TIME = "chuzTime";
+
+    //下渣时间
+    private String chuzTime = "";
+
     //存储出渣温度,3个点的温度明显升高即为正在出渣
     private LinkedList<Double> lastChuzTemps = new LinkedList<>();
 
@@ -296,7 +301,7 @@ public class DeviceEventListener extends AbstractEventListener { //
                     if ("prod".equals(activeProfiles)) {
                         log.info("HDC subscribe available");
                         hdService.subscribeAvailable();
-                    } else  if ("test".equals(activeProfiles)) {
+                    } else if ("test".equals(activeProfiles)) {
                         log.info("DA subscribe available");
                         opcuaService.subscribeAvailable();
                     }
@@ -327,11 +332,11 @@ public class DeviceEventListener extends AbstractEventListener { //
             for (TAudio tAudio : list) {
                 if (ExceptionTypeEnum.JI_XU_DU_KOU.equals(ExceptionTypeEnum.fromCode(tAudio.getExceptionType()))) {
                     closureAlarmUrl = SERVER_URL + "/" + GlobalConfig.publicPrefix + File.separator + tAudio.getPath();
-                } else  if (ExceptionTypeEnum.JI_XU_CHU_TIE.equals(ExceptionTypeEnum.fromCode(tAudio.getExceptionType()))) {
+                } else if (ExceptionTypeEnum.JI_XU_CHU_TIE.equals(ExceptionTypeEnum.fromCode(tAudio.getExceptionType()))) {
                     tappingAlramUrl = SERVER_URL + "/" + GlobalConfig.publicPrefix + File.separator + tAudio.getPath();
-                } else  if (ExceptionTypeEnum.CHU_TIE_SHI_JIAN_TAI_CHANG.equals(ExceptionTypeEnum.fromCode(tAudio.getExceptionType()))) {
+                } else if (ExceptionTypeEnum.CHU_TIE_SHI_JIAN_TAI_CHANG.equals(ExceptionTypeEnum.fromCode(tAudio.getExceptionType()))) {
                     tappingTimeoutAlramUrl = SERVER_URL + "/" + GlobalConfig.publicPrefix + File.separator + tAudio.getPath();
-                } else  if (ExceptionTypeEnum.KAI_KOU_CHAO_SHI.equals(ExceptionTypeEnum.fromCode(tAudio.getExceptionType()))) {
+                } else if (ExceptionTypeEnum.KAI_KOU_CHAO_SHI.equals(ExceptionTypeEnum.fromCode(tAudio.getExceptionType()))) {
                     openAlarmUrl = SERVER_URL + "/" + GlobalConfig.publicPrefix + File.separator + tAudio.getPath();
                 }
             }
@@ -1121,13 +1126,13 @@ public class DeviceEventListener extends AbstractEventListener { //
                         realtimeData.setValue(1);
                         realtimeData.setDesc("摆动溜嘴的摆动方向");
                         realtimeData.setExtra(opcData.getData());
-                        mRealtimeStatus.put(CHONGZ_STATUS, realtimeData);
+                        mRealtimeStatus.put(BDLZ_STATUS, realtimeData);
                     } else {
                         RealtimeData realtimeData = new RealtimeData();
                         realtimeData.setValue(0);
                         realtimeData.setDesc("摆动溜嘴的摆动方向");
                         realtimeData.setExtra(opcData.getData());
-                        mRealtimeStatus.put(CHONGZ_STATUS, realtimeData);
+                        mRealtimeStatus.put(BDLZ_STATUS, realtimeData);
                     }
                 } else {
                     // 罐车卸载,累计最大值到总量
@@ -1148,13 +1153,13 @@ public class DeviceEventListener extends AbstractEventListener { //
                         realtimeData.setValue(2);
                         realtimeData.setDesc("摆动溜嘴的摆动方向");
                         realtimeData.setExtra(opcData.getData());
-                        mRealtimeStatus.put(CHONGZ_STATUS, realtimeData);
+                        mRealtimeStatus.put(BDLZ_STATUS, realtimeData);
                     } else {
                         RealtimeData realtimeData = new RealtimeData();
                         realtimeData.setValue(0);
                         realtimeData.setDesc("摆动溜嘴的摆动方向");
                         realtimeData.setExtra(opcData.getData());
-                        mRealtimeStatus.put(CHONGZ_STATUS, realtimeData);
+                        mRealtimeStatus.put(BDLZ_STATUS, realtimeData);
                     }
                 } else {
                     mTotalWeight = mTotalWeight.add(ironWeight12Max);
@@ -1173,17 +1178,34 @@ public class DeviceEventListener extends AbstractEventListener { //
                     double t1 = lastChuzTemps.get(0);
                     double t2 = lastChuzTemps.get(1);
                     double t3 = lastChuzTemps.get(2);
-                    // 设定“明显升高”阈值,比如每次升高10度
+                    // 设定"明显升高"阈值,比如每次升高10度
                     if (t2 - t1 > 10 && t3 - t2 > 10) {
                         isRising = true;
                     }
                 }
 
+                if (isRising) {
+                    if(ObjectUtils.isEmpty(chuzTime)){
+                        chuzTime =  LocalDateUtils.formatDate(opcData.getSourceTime());
+                    }
+                }else{
+                    chuzTime = "";
+                }
+
                 RealtimeData realtimeData = new RealtimeData();
                 realtimeData.setValue(isRising ? 1 : 0);
                 realtimeData.setDesc("出渣状态");
-                realtimeData.setExtra(opcData.getData());
+                Map<String,Object> extraInfo = new HashMap<>();
+                extraInfo.put("chuzTime", chuzTime);
+                extraInfo.put("data", opcData.getData());
+                realtimeData.setExtra(extraInfo);
                 mRealtimeStatus.put(CHUZ_STATUS, realtimeData);
+
+                RealtimeData realtimeDataChuzTime = new RealtimeData();
+                realtimeDataChuzTime.setValue(chuzTime);
+                realtimeDataChuzTime.setDesc("出渣时间");
+                mRealtimeStatus.put(CHUZ_TIME, realtimeDataChuzTime);
+
             } else if (opcData.getPointName().contains(SubscribeTagConstants.TAG_SZB_STATUS(opcData.getServerType()))
                     || opcData.getPointName().contains(SubscribeTagConstants.TAG_CZF_STATUS(opcData.getServerType()))
             ) {
@@ -1195,7 +1217,7 @@ public class DeviceEventListener extends AbstractEventListener { //
                     realtimeData.setExtra(opcData.getData());
                     mRealtimeStatus.put(CHONGZ_STATUS, realtimeData);
                 } catch (Exception e) {
-                    throw new RuntimeException(e);
+
                 }
             } else if (opcData.getPointName().contains(SubscribeTagConstants.TAG_KKJ_STATUS(opcData.getServerType()))) {
                 //开口机状态
@@ -1548,7 +1570,7 @@ public class DeviceEventListener extends AbstractEventListener { //
         }
         if (ObjectUtils.isNotEmpty(message)) {
             log.info("取消预警:{}", message);
-            scheduledTaskManager.cancelTask(message.getType());
+            //scheduledTaskManager.cancelTask(message.getType());
         }
     }
 
@@ -1598,8 +1620,8 @@ public class DeviceEventListener extends AbstractEventListener { //
         TIronSchedule getIronLegend = scheduleMap.get(TaskNameConstants.TASKNAME_IRON_LEGEND);
         if (getIronLegend != null && "1".equals(getIronLegend.getStatus())) {
             scheduledTaskManager.addTask(getIronLegend.getName(), getIronLegend.getDelay(), getIronLegend.getPeriod(), TimeUnit.SECONDS, () -> {
-                mRealtimeLegend.put("ironCosttime", RealtimeData.builder().desc("出铁时间").value(getIronElapsedMinute()).unit("min").build());
-                PushData.send2Legend(tIronVisualScreenService.getIronLegend(mRealtimeLegend));
+                //  mRealtimeLegend.put("ironCosttime", RealtimeData.builder().desc("出铁时间").value(getIronElapsedMinute()).unit("min").build());
+                PushData.send2Legend(tIronVisualScreenService.getIronLegend(null));
             });
         }
 
@@ -1610,6 +1632,17 @@ public class DeviceEventListener extends AbstractEventListener { //
                 getTheoryWeight();
             });
         }
+
+        //L2定时诊断
+        TIronSchedule ironTest = scheduleMap.get(TaskNameConstants.TASKNAME_IRON_TEST);
+        if (ironTest != null && "1".equals(ironTest.getStatus())) {
+            scheduledTaskManager.addTask(ironTest.getName(), ironTest.getDelay(), ironTest.getPeriod(), TimeUnit.SECONDS, () -> {
+                List<TIronTest> latest3 = iTIronTestService.getLatest3();
+                PushData.send2Test(latest3);
+            });
+        } else {
+            System.out.println("[DeviceEventListener] ironTest定时任务未添加,配置为null或status!=1");
+        }
     }
 
 
@@ -1645,7 +1678,7 @@ public class DeviceEventListener extends AbstractEventListener { //
         }
     }
 
-    // 统一关闭所有相关定时任务的方法
+    // 统一关闭所有出铁工作相关定时任务
     private void cancelAllTasks() {
         String[] taskNames = {
                 TaskNameConstants.TASKNAME_CLOSURE_WARN,

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

@@ -76,7 +76,7 @@ public class PushData {
     /***
      * 出铁工作诊断
      */
-    public static final String IRON_TAPPING_TEST = "IRON_TAPPING_TEST";
+    public static final String IRON_TEST = "IRON_TEST";
 
     /***
      * 距离堵口预计还剩:xxxx分钟
@@ -329,5 +329,21 @@ public class PushData {
         }
     }
 
+    /**
+     * 告警列表
+     *
+     * @return
+     * @Param
+     **/
+    public static void send2Test(Object message) {
+        if (SocketUtil.connectMap.isEmpty()) {
+            return;
+        }
+        //
+        for (Map.Entry<String, SocketIOClient> entry : SocketUtil.connectMap.entrySet()) {
+            entry.getValue().sendEvent(PushData.IRON_TEST, AjaxResult.success(message));
+        }
+    }
+
 
 }

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

@@ -34,7 +34,7 @@ public class TIronDataSearchValidate implements Serializable {
     @ApiModelProperty(value = "铁水平均温度")
     private String avgTemp;
 
-    @ApiModelProperty(value = "泥量")
+    @ApiModelProperty(value = "泥量")
     private String mudWeight;
 
     @ApiModelProperty(value = "钻杆直径")

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

@@ -42,7 +42,7 @@ public class TL2DataCreateValidate implements Serializable {
     private String avgTemp;
 
     @NotNull(message = "mudWeight参数缺失")
-    @ApiModelProperty(value = "泥量")
+    @ApiModelProperty(value = "泥量")
     private String mudWeight;
 
     @NotNull(message = "pollMm参数缺失")

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

@@ -33,7 +33,7 @@ public class TL2DataSearchValidate implements Serializable {
     @ApiModelProperty(value = "铁水平均温度")
     private String avgTemp;
 
-    @ApiModelProperty(value = "泥量")
+    @ApiModelProperty(value = "泥量")
     private String mudWeight;
 
     @ApiModelProperty(value = "钻杆直径")

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

@@ -51,7 +51,7 @@ public class TL2DataUpdateValidate implements Serializable {
     private String avgTemp;
 
     @NotNull(message = "mudWeight参数缺失")
-    @ApiModelProperty(value = "泥量")
+    @ApiModelProperty(value = "泥量")
     private String mudWeight;
 
     @NotNull(message = "pollMm参数缺失")

+ 1 - 3
taphole-iron/src/main/java/com/sckj/iron/vo/TIronTestListedVo.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")
@@ -26,7 +24,7 @@ public class TIronTestListedVo implements Serializable {
     @ApiModelProperty(value = "诊断状态(1正常 0异常)")
     private String testStatus;
 
-    @ApiModelProperty(value = "鱼雷罐车车号")
+    @ApiModelProperty(value = "诊断说明")
     private String testDesc;
 
     @ApiModelProperty(value = "铁口区域编号")

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

@@ -37,7 +37,7 @@ public class TL2DataDetailVo implements Serializable {
     @ApiModelProperty(value = "铁水平均温度")
     private String avgTemp;
 
-    @ApiModelProperty(value = "泥量")
+    @ApiModelProperty(value = "泥量")
     private String mudWeight;
 
     @ApiModelProperty(value = "钻杆直径")

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

@@ -40,7 +40,7 @@ public class TL2DataListedVo implements Serializable {
     @ApiModelProperty(value = "铁水平均温度")
     private String avgTemp;
 
-    @ApiModelProperty(value = "泥量")
+    @ApiModelProperty(value = "泥量")
     private String mudWeight;
 
     @ApiModelProperty(value = "钻杆直径")

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

@@ -67,8 +67,8 @@ public class TL2Data implements Serializable {
     @ColumnWidth(30)
     private Double avgTemp;
 
-    @ApiModelProperty(value = "泥量")
-    @ExcelProperty("泥量(L)")
+    @ApiModelProperty(value = "泥量")
+    @ExcelProperty("泥量(L)")
     @ColumnWidth(25)
     private Double mudWeight;
 

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

@@ -33,7 +33,7 @@ public class TL2DataListedVo implements Serializable {
     @ApiModelProperty(value = "铁水平均温度")
     private Double avgTemp;
 
-    @ApiModelProperty(value = "泥量")
+    @ApiModelProperty(value = "泥量")
     private Double mudWeight;
 
     @ApiModelProperty(value = "钻杆直径")