Parcourir la source

染整线新功能

wukai il y a 6 mois
Parent
commit
205af76186
27 fichiers modifiés avec 2622 ajouts et 13 suppressions
  1. 14 0
      devices_array.txt
  2. 391 0
      jjt-admin/src/test/java/com/jjt/data/DataPTest.java
  3. 74 0
      jjt-admin/src/test/java/com/jjt/dyeing/EnergyTest.java
  4. 6 5
      jjt-admin/src/test/java/com/jjt/order/OrderTest.java
  5. 192 0
      jjt-admin/src/test/java/com/jjt/rziot/JdlTest.java
  6. 3 3
      jjt-admin/src/test/java/com/jjt/rziot/SgtgjTest.java
  7. 3 3
      jjt-admin/src/test/java/com/jjt/rziot/TangJianJiTest.java
  8. 1 1
      jjt-admin/src/test/java/com/jjt/wk/EmpCalcTest.java
  9. 113 0
      jjt-biz/src/main/java/com/jjt/dyeing/controller/DyeingDeviceController.java
  10. 113 0
      jjt-biz/src/main/java/com/jjt/dyeing/controller/DyeingHourAvgController.java
  11. 113 0
      jjt-biz/src/main/java/com/jjt/dyeing/controller/DyeingHourEnergyController.java
  12. 138 0
      jjt-biz/src/main/java/com/jjt/dyeing/domain/DyeingDevice.java
  13. 89 0
      jjt-biz/src/main/java/com/jjt/dyeing/domain/DyeingHourAvg.java
  14. 79 0
      jjt-biz/src/main/java/com/jjt/dyeing/domain/DyeingHourEnergy.java
  15. 62 0
      jjt-biz/src/main/java/com/jjt/dyeing/mapper/DyeingDeviceMapper.java
  16. 70 0
      jjt-biz/src/main/java/com/jjt/dyeing/mapper/DyeingHourAvgMapper.java
  17. 71 0
      jjt-biz/src/main/java/com/jjt/dyeing/mapper/DyeingHourEnergyMapper.java
  18. 69 0
      jjt-biz/src/main/java/com/jjt/dyeing/service/IDyeingDeviceService.java
  19. 74 0
      jjt-biz/src/main/java/com/jjt/dyeing/service/IDyeingHourAvgService.java
  20. 77 0
      jjt-biz/src/main/java/com/jjt/dyeing/service/IDyeingHourEnergyService.java
  21. 101 0
      jjt-biz/src/main/java/com/jjt/dyeing/service/impl/DyeingDeviceServiceImpl.java
  22. 204 0
      jjt-biz/src/main/java/com/jjt/dyeing/service/impl/DyeingHourAvgServiceImpl.java
  23. 183 0
      jjt-biz/src/main/java/com/jjt/dyeing/service/impl/DyeingHourEnergyServiceImpl.java
  24. 1 1
      jjt-biz/src/main/java/com/jjt/nccloud/utils/NccloudUtils.java
  25. 129 0
      jjt-biz/src/main/resources/mapper/dyeing/DyeingDeviceMapper.xml
  26. 132 0
      jjt-biz/src/main/resources/mapper/dyeing/DyeingHourAvgMapper.xml
  27. 120 0
      jjt-biz/src/main/resources/mapper/dyeing/DyeingHourEnergyMapper.xml

+ 14 - 0
devices_array.txt

@@ -0,0 +1,14 @@
+// 设备信息数组
+String[][] devices = {
+    {"双棍烫光机_8线_前整_12号", "root.tl.suxi.sgtgjLine8ForwardNo12_PLC1"},
+    {"双棍烫光机_8线_前整_13号", "root.tl.suxi.sgtgjLine8ForwardNo13_PLC1"},
+    {"双棍烫光机_8线_前整_4号", "root.tl.suxi.sgtgjLine8ForwardNo4_PLC1"},
+    {"双棍烫光机_8线_前整_5号", "root.tl.suxi.sgtgjLine8ForwardNo5_PLC1"},
+    {"双棍烫光机_8线_前整_6号", "root.tl.suxi.sgtgjLine8ForwardNo6_PLC1"},
+    {"双棍烫光机_8线_后整_12号", "root.tl.suxi.sgtgjLine8BackNo12_PLC1"},
+    {"双棍烫光机_8线_后整_7号", "root.tl.suxi.sgtgjLine8BackNo7_PLC1"},
+    {"双棍烫光机_8线_后整_9号", "root.tl.suxi.sgtgjLine8BackNo9_PLC1"},
+    {"烫剪机_8线_后整_8号", "root.tl.suxi.tangJianJiLine8BackNo8_PLC1"},
+    {"烫剪机_8线_后整_10号", "root.tl.suxi.tangJianJiLine8BackNo10_PLC1"},
+    {"烫剪机_8线_后整_13号", "root.tl.suxi.tangJianJiLine8BackNo13_PLC1"}
+};

+ 391 - 0
jjt-admin/src/test/java/com/jjt/data/DataPTest.java

@@ -0,0 +1,391 @@
+package com.jjt.data;
+
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import com.jjt.JjtApplication;
+import com.jjt.biz.domain.TwinDevice;
+import com.jjt.biz.service.ITwinDeviceService;
+import com.jjt.common.utils.DateUtils;
+import com.jjt.utils.IotService;
+import javafx.util.Pair;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * DataPTest$
+ *
+ * @author wukai
+ * @date 2025/9/25 20:58
+ */
+@SpringBootTest(classes = JjtApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class DataPTest {
+    @Resource
+    IotService iotService;
+    @Resource
+    private ITwinDeviceService twinDeviceService;
+    private final String[] dFields = {
+            "Capacity_data_177 AS Capacity_data_2", "Capacity_data_15", "Capacity_data_16", "Capacity_data_17",
+            "Capacity_data_18", "Capacity_data_19", "Capacity_data_118 AS Capacity_data_48",
+            "Formula_data_43 AS Formula_data_3", "Formula_data_55 AS Formula_data_15", "Capacity_data_112 AS Formula_data_24"
+    };
+
+    @Test
+    void test() {
+        iotService.setToken();
+        TwinDevice search = new TwinDevice();
+        //查询所有在线的设备
+        search.setOnline("1");
+        List<TwinDevice> deviceList = twinDeviceService.selectTwinDeviceList(search);
+        deviceList.forEach(device -> {
+            float flag = md(device);
+            device.setRemark(flag + "");
+        });
+
+//        for (TwinDevice device : deviceList) {
+//            System.err.println(device.getDeviceId() + "\t" + device.getDeviceName() + "\t" + device.getDeviceCode() + "\t" + device.getRemark());
+//        }
+
+
+    }
+
+    @Test
+    void test1() {
+        iotService.setToken();
+        TwinDevice search = new TwinDevice();
+        //查询所有在线的设备
+        search.setOnline("1");
+        List<TwinDevice> deviceList = twinDeviceService.selectTwinDeviceList(search);
+        deviceList.forEach(device -> {
+//            Pair<Float, Float> pair = data2(device);
+//            System.err.println(device.getDeviceId() + "\t" + device.getDeviceName() + "\t" + device.getDeviceCode() + "\t" + pair.getKey() + "\t" + pair.getValue());
+            Map<String, Object> map = data(device);
+            System.err.println(device.getDeviceId() + "\t" + device.getDeviceName() + "\t" + device.getDeviceCode() + "\t" + map.get("first") + "\t" + map.get("end") + "\t" + map.get("flag"));
+
+        });
+    }
+
+    Map<String, Object> data(TwinDevice device) {
+        Map<String, Object> map = new HashMap<>();
+        boolean flag = device.getDeviceCode().startsWith("C_");
+        String filed = flag ? "Capacity_data_2" : "Capacity_data_177";
+        String table = device.getDevicePath();
+        String where = " time>2025-09-25T01:00:00 and time <=2025-09-25T07:00:00";
+        String sql = "select %s from %s where %s";
+        sql = String.format(sql, filed, table, where);
+        JSONObject jsonObject = iotService.query(sql);
+        long e = System.currentTimeMillis();
+        JSONObject data = jsonObject.getJSONObject("data");
+        JSONArray values = data.getJSONArray("values");
+
+        JSONArray timestamps = data.getJSONArray("timestamps");
+        float first = values.getJSONArray(0).getFloat(0);
+        float last = first;
+        float end = values.getJSONArray(values.size() - 1).getFloat(0);
+
+        boolean xflag = false;
+        for (int i = 1; i < values.size(); i++) {
+            JSONArray da = values.getJSONArray(i);
+            float curr = da.getFloat(0);
+            if (curr < last-100) {
+                xflag = true;
+                break;
+            }
+            last = curr;
+        }
+        map.put("first", first);
+        map.put("end", end);
+        map.put("flag", xflag);
+        return map;
+    }
+
+    @Test
+    void get() {
+        Map<String, Object> map = new HashMap<>();
+        String table = "root.tl.suxi.knittings34_plc1";
+        String where = " time>2025-09-25T01:00:00 and time <=2025-09-25T07:00:00";
+        String sql = "select Capacity_data_2,Formula_data_24 from %s where %s";
+        sql = String.format(sql, table, where);
+        JSONObject jsonObject = iotService.query(sql);
+        long e = System.currentTimeMillis();
+        JSONObject data = jsonObject.getJSONObject("data");
+        JSONArray values = data.getJSONArray("values");
+
+        JSONArray timestamps = data.getJSONArray("timestamps");
+        float first = values.getJSONArray(0).getFloat(0);
+        float last = first;
+        float end = values.getJSONArray(values.size() - 1).getFloat(0);
+
+        boolean xflag = false;
+        for (int i = 0; i < values.size(); i++) {
+            long time = timestamps.getLong(i) / 1000 * 1000;
+            JSONArray da = values.getJSONArray(i);
+            float ms = da.getFloat(0);
+            float md = da.getFloat(1);
+            System.err.println(DateUtils.parseDateToStr("HH:mm:ss",new Date(time))+"\t"+ms+"\t"+md);
+        }
+    }
+
+    Pair<Float, Float> data2(TwinDevice device) {
+        boolean flag = device.getDeviceCode().startsWith("C_");
+        String filed = flag ? "Capacity_data_2" : "Capacity_data_177";
+        String table = device.getDevicePath();
+        String where = " time>2025-09-25T07:00:00 and time <=2025-09-25T08:00:00";
+        String sql = "select %s from %s where %s";
+        sql = String.format(sql, filed, table, where);
+        JSONObject jsonObject = iotService.query(sql);
+        JSONObject data = jsonObject.getJSONObject("data");
+        JSONArray values = data.getJSONArray("values");
+
+        JSONArray timestamps = data.getJSONArray("timestamps");
+        float s = values.getJSONArray(0).getFloat(0);
+        float e = values.getJSONArray(values.size() - 1).getFloat(0);
+        return new Pair<>(s, e);
+    }
+
+    float md(TwinDevice device) {
+        boolean flag = device.getDeviceCode().startsWith("C_");
+        String filed = flag ? "Formula_data_24" : "Capacity_data_112";
+        String table = device.getDevicePath();
+        String where = " time>2025-09-25T02:00:00 and time <=2025-09-25T07:00:00";
+        String sql = "select %s from %s where %s";
+        sql = String.format(sql, filed, table, where);
+        JSONObject jsonObject = iotService.query(sql);
+        long e = System.currentTimeMillis();
+        JSONObject data = jsonObject.getJSONObject("data");
+        JSONArray values = data.getJSONArray("values");
+
+        JSONArray timestamps = data.getJSONArray("timestamps");
+        float last = 0f;
+        for (int i = 0; i < values.size(); i++) {
+            JSONArray da = values.getJSONArray(i);
+            float curr = da.getFloat(0);
+            return curr;
+//            if (i == 0) {
+//                last = curr;
+//                continue;
+//            }
+//            if (curr != last) {
+//                return false;
+//            }
+        }
+        return last;
+    }
+
+    /**
+     * 落布米长
+     *
+     * @param device
+     * @return
+     */
+    float xb(TwinDevice device) {
+        boolean flag = device.getDeviceCode().startsWith("C_");
+        String filed = flag ? "Capacity_data_4" : "Capacity_data_177+Capacity_data_178";
+        String table = device.getDevicePath();
+        String where = " time>2025-09-25T02:00:00 and time <=2025-09-25T07:00:00";
+        String sql = "select %s from %s where %s";
+        sql = String.format(sql, filed, table, where);
+        JSONObject jsonObject = iotService.query(sql);
+        long e = System.currentTimeMillis();
+        JSONObject data = jsonObject.getJSONObject("data");
+        JSONArray values = data.getJSONArray("values");
+
+        JSONArray timestamps = data.getJSONArray("timestamps");
+        float last = 0f;
+        for (int i = 0; i < values.size(); i++) {
+            JSONArray da = values.getJSONArray(i);
+            float curr = da.getFloat(0);
+//            if (curr >100) {
+            return curr;
+//            }
+        }
+        return last;
+    }
+
+    public static final Map<String, Integer> DEVICE_VALUES = new HashMap<String, Integer>() {{
+        // C系列设备数值
+        put("C_1", 265);
+        put("C_2", 430);
+        put("C_3", 415);
+        put("C_4", 200);
+        put("C_5", 175);
+        put("C_6", 410);
+        put("C_7", 770);
+        put("C_8", 416);
+        put("C_9", 273);
+        put("C_10", 566);
+        put("C_11", 580);
+        put("C_12", 415);
+        put("C_13", 413);
+        put("C_14", 272);
+        put("C_15", 365);
+        put("C_16", 275);
+        put("C_17", 413);
+        put("C_18", 270);
+        put("C_19", 415);
+        put("C_20", 413);
+        put("C_21", 180);
+        put("C_22", 273);
+        put("C_23", 413);
+        put("C_24", 413);
+        put("C_25", 270);
+        put("C_26", 270);
+        put("C_27", 415);
+        put("C_28", 410);
+        put("C_29", 735);
+        put("C_30", 270);
+        put("C_31", 425);
+        put("C_32", 418);
+        put("C_33", 365);
+        put("C_34", 270);
+        put("C_35", 365);
+        put("C_36", 365);
+        put("C_37", 270);
+        put("C_38", 415);
+        put("C_39", 270);
+        put("C_40", 270);
+        put("C_41", 415);
+        put("C_42", 415);
+        put("C_43", 265);
+        put("C_44", 728);
+        put("C_45", 725);
+        put("C_46", 415);
+        put("C_47", 263);
+        put("C_48", 410);
+        put("C_49", 582);
+        put("C_50", 720);
+        put("C_51", 725);
+        put("C_52", 420);
+        put("C_53", 420);
+        put("C_54", 572);
+        put("C_55", 270);
+        put("C_56", 410);
+        put("C_57", 365);
+        put("C_58", 415);
+        put("C_59", 365);
+        put("C_60", 415);
+        put("C_61", 430);
+        put("C_62", 415);
+        put("C_63", 275);
+        put("C_64", 410);
+        put("C_65", 273);
+        put("C_66", 176);
+        put("C_67", 410);
+        put("C_68", 265);
+        put("C_69", 575);
+        put("C_70", 413);
+        put("C_71", 270);
+        put("C_72", 410);
+        put("C_73", 405);
+        put("C_74", 263);
+        put("C_75", 410);
+        put("C_76", 263);
+        put("C_77", 738);
+        put("C_78", 270);
+        put("C_79", 270);
+        put("C_80", 265);
+        put("C_81", 360);
+        put("C_82", 265);
+        put("C_83", 265);
+        put("C_84", 182);
+        put("C_85", 265);
+        put("C_86", 265);
+        put("C_87", 263);
+        put("C_88", 265);
+        put("C_89", 263);
+        put("C_90", 365);
+        put("C_91", 370);
+        put("C_92", 170);
+        put("C_93", 415);
+        put("C_95", 566);
+        put("C_97", 179);
+        put("C_98", 190);
+        put("C_99", 725);
+        put("C_100", 572);
+        put("C_101", 275);
+        put("C_102", 365);
+        put("C_103", 365);
+        put("C_104", 365);
+        put("C_105", 410);
+        put("C_106", 365);
+        put("C_107", 360);
+        put("C_108", 415);
+        put("C_109", 270);
+        put("C_110", 180);
+        put("C_111", 566);
+        put("C_112", 410);
+        put("C_113", 275);
+        put("C_114", 413);
+        put("C_115", 415);
+        put("C_116", 410);
+        put("C_117", 408);
+        put("C_118", 270);
+        put("C_119", 415);
+        put("C_120", 406);
+        put("C_121", 370);
+        put("C_122", 262);
+        put("C_123", 360);
+        put("C_124", 410);
+        put("C_125", 410);
+        put("C_126", 183);
+        put("C_127", 365);
+        put("C_128", 365);
+        put("C_129", 365);
+        put("C_130", 263);
+        put("C_131", 205);
+        put("C_132", 408);
+        put("C_133", 728);
+        put("C_134", 572);
+        put("C_135", 265);
+        put("C_136", 270);
+        put("C_137", 263);
+        put("C_138", 572);
+
+        // D系列设备数值
+        put("D_141", 430);
+        put("D_142", 275);
+        put("D_143", 290);
+        put("D_144", 275);
+        put("D_145", 278);
+        put("D_146", 173);
+        put("D_147", 275);
+        put("D_148", 425);
+        put("D_149", 425);
+        put("D_150", 425);
+        put("D_151", 570);
+        put("D_152", 425);
+        put("D_153", 425);
+        put("D_154", 425);
+        put("D_155", 273);
+        put("D_156", 290);
+        put("D_157", 420);
+        put("D_158", 270);
+        put("D_159", 172);
+        put("D_160", 273);
+        put("D_161", 430);
+        put("D_162", 580);
+        put("D_163", 425);
+        put("D_164", 425);
+        put("D_165", 425);
+        put("D_166", 425);
+        put("D_167", 275);
+        put("D_168", 275);
+        put("D_169", 275);
+        put("D_170", 290);
+        put("D_171", 175);
+        put("D_172", 173);
+        put("D_173", 176);
+        put("D_174", 173);
+        put("D_175", 428);
+        put("D_176", 570);
+        put("D_177", 580);
+        put("D_178", 580);
+        put("D_179", 425);
+        put("D_180", 576);
+    }};
+}

+ 74 - 0
jjt-admin/src/test/java/com/jjt/dyeing/EnergyTest.java

@@ -0,0 +1,74 @@
+package com.jjt.dyeing;
+
+import com.jjt.JjtApplication;
+import com.jjt.dyeing.service.IDyeingHourAvgService;
+import com.jjt.dyeing.service.IDyeingHourEnergyService;
+import com.jjt.utils.IotService;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import javax.annotation.Resource;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+
+/**
+ * EnergyTest$
+ *
+ * @author wukai
+ * @date 2025/10/19 03:38
+ */
+@SpringBootTest(classes = JjtApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class EnergyTest {
+    @Resource
+    private IotService iotService;
+    @Resource
+    private IDyeingHourEnergyService energyService;
+    @Resource
+    private IDyeingHourAvgService avgService;
+    @Resource
+    private SqlSessionFactory factory;
+
+    @Test
+    public void testCalc() {
+        iotService.setToken();
+        String st = "2025-10-12";
+        String ed = "2025-10-19";
+        LocalDate localDate = LocalDate.parse(st);
+        LocalDate endDate = LocalDate.parse(ed);
+        LocalDateTime start = LocalDateTime.of(localDate, LocalTime.MIN).plusHours(7);
+        LocalDateTime end = LocalDateTime.of(endDate.plusDays(1), LocalTime.MIN).plusHours(6);
+        LocalDateTime curr = LocalDateTime.now();
+        if (end.isAfter(curr)) {
+            end = curr.minusHours(1);
+        }
+        do {
+            int i = start.getHour();
+            System.err.println(start.toLocalDate().toString() + "\t" + i);
+            avgService.calc(start.toLocalDate(), i);
+            start = start.plusHours(1);
+        } while (!start.isAfter(end));
+    }
+
+    @Test
+    public void testEnergy() {
+        iotService.setToken();
+        String st = "2025-10-12";
+        String ed = "2025-10-19";
+        LocalDate localDate = LocalDate.parse(st);
+        LocalDate endDate = LocalDate.parse(ed);
+        LocalDateTime start = LocalDateTime.of(localDate, LocalTime.MIN).plusHours(7);
+        LocalDateTime end = LocalDateTime.of(endDate.plusDays(1), LocalTime.MIN).plusHours(6);
+        LocalDateTime curr = LocalDateTime.now();
+        if (end.isAfter(curr)) {
+            end = curr.minusHours(1);
+        }
+        do {
+            int i = start.getHour();
+            System.err.println(start.toLocalDate().toString() + "\t" + i);
+            energyService.calc(start.toLocalDate(), i);
+            start = start.plusHours(1);
+        } while (!start.isAfter(end));
+    }
+}

+ 6 - 5
jjt-admin/src/test/java/com/jjt/order/OrderTest.java

@@ -29,13 +29,14 @@ public class OrderTest {
 
     @Test
     void test() {
-        String d = "2025-02-18";
+        String d = "2025-10-17";
         LocalDate start = LocalDate.parse(d);
-        LocalDate end = LocalDate.now().minusDays(1);
-        do {
             orderService.getOrder(start);
-            start = start.plusDays(1);
-        } while (start.isBefore(end));
+//        LocalDate end = LocalDate.now().minusDays(1);
+//        do {
+//            orderService.getOrder(start);
+//            start = start.plusDays(1);
+//        } while (start.isBefore(end));
     }
 
 //    @Test

+ 192 - 0
jjt-admin/src/test/java/com/jjt/rziot/JdlTest.java

@@ -0,0 +1,192 @@
+package com.jjt.rziot;
+
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import com.jjt.JjtApplication;
+import com.jjt.calc.domain.TwinRecordStop;
+import com.jjt.common.utils.DateUtils;
+import com.jjt.utils.IotService;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import javax.annotation.Resource;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneOffset;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * 后整烫剪机
+ */
+@SpringBootTest(classes = JjtApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class JdlTest {
+    @Resource
+    private IotService iotService;
+
+    /**
+     * 印花设备数据
+     */
+    @Test
+    void test() {
+        iotService.setToken();
+        // 设备信息数组
+        String[][] devices = {
+                {"双棍烫光机_8线_前整_4号", "sgtgjLine8ForwardNo4_PLC1"},
+                {"双棍烫光机_8线_前整_5号", "sgtgjLine8ForwardNo5_PLC1"},
+                {"双棍烫光机_8线_前整_6号", "sgtgjLine8ForwardNo6_PLC1"},
+                {"双棍烫光机_8线_前整_8号", "sgtgjLine8ForwardNo8_PLC1"},
+                {"双棍烫光机_8线_前整_9号", "sgtgjLine8ForwardNo9_PLC1"},
+                {"双棍烫光机_8线_前整_10号", "sgtgjLine8ForwardNo10_PLC1"},
+                {"双棍烫光机_8线_后整_7号", "sgtgjLine8BackNo7_PLC1"},
+                {"双棍烫光机_8线_后整_9号", "sgtgjLine8BackNo9_PLC1"},
+                {"双棍烫光机_8线_后整_12号", "sgtgjLine8BackNo12_PLC1"},
+                {"烫剪机_8线_后整_8号", "tangJianJiLine8BackNo8_PLC1"},
+                {"烫剪机_8线_后整_10号", "tangJianJiLine8BackNo10_PLC1"},
+                {"烫剪机_8线_后整_13号", "tangJianJiLine8BackNo13_PLC1"}
+        };
+
+        String prefix = "root.tl.suxi.";
+
+
+        String st = "2025-09-17";
+        String ed = "2025-09-17";
+        LocalDate localDate = LocalDate.parse(st);
+        LocalDate endDate = LocalDate.parse(ed);
+        LocalDateTime start = LocalDateTime.of(localDate, LocalTime.MIN).plusHours(7);
+        LocalDateTime end = LocalDateTime.of(endDate.plusDays(1), LocalTime.MIN).plusHours(6);
+        LocalDateTime curr = LocalDateTime.now();
+        if (end.isAfter(curr)) {
+            end = curr.minusHours(1);
+        }
+        Map<String, List<TwinRecordStop>> resultMap = new HashMap<>();
+        do {
+            Long startTime = start.toInstant(ZoneOffset.of("+8")).toEpochMilli();
+            Long endTime = start.plusHours(1).toInstant(ZoneOffset.of("+8")).toEpochMilli();
+            for (String[] device : devices) {
+                String deviceName = device[0];
+                String deviceCode = device[1];
+                String fullPath = prefix + deviceCode;
+                List<TwinRecordStop> records = new ArrayList<>();
+
+                System.out.println("设备名称: " + deviceName + ", 设备路径: " + fullPath + ",时间:" + start);
+                String sql = "select Capacity_data_1 from %s where time>%s and time <=%s";
+                sql = String.format(sql, fullPath, startTime, endTime);
+                JSONObject jsonObject = iotService.query(sql);
+                JSONObject data = jsonObject.getJSONObject("data");
+                JSONArray values = data.getJSONArray("values");
+                JSONArray columnNames = data.getJSONArray("columnNames");
+                JSONArray timestamps = data.getJSONArray("timestamps");
+                int last = 0;
+                for (int i = 0; i < values.size(); i++) {
+                    JSONArray da = values.getJSONArray(i);
+                    long time = timestamps.getLong(i) / 1000 * 1000;
+                    int value = da.getInt(0);
+                    if (i == 0) {
+                        last = value;
+                        continue;
+                    }
+                    TwinRecordStop stop = new TwinRecordStop();
+                    if (value != 6) {
+                        if (value != last) {
+                            if (last != 6) {
+                                //记录上个停机类型的结束时间
+                                stop.setStopType(last);
+                                stop.setEndTime(new Date(time));
+                                records.add(stop);
+                            }
+                            stop = new TwinRecordStop();
+                            //记录停机开始时间
+                            stop.setStopType(value);
+                            stop.setStartTime(new Date(time));
+                            records.add(stop);
+                        }
+                    } else if (last != 6) {
+                        //判断停机结束之后的开机
+                        stop.setStopType(last);
+                        stop.setEndTime(new Date(time));
+                        records.add(stop);
+                    }
+                    last = value;
+                }
+                List<TwinRecordStop> newStopRecord = resultMap.get(deviceName);
+                if (newStopRecord == null) {
+                    newStopRecord = new ArrayList<>();
+                    resultMap.put(deviceName, newStopRecord);
+                }
+                Map<Integer, TwinRecordStop> stopMap = new HashMap<>();
+
+                List<TwinRecordStop> finalNewStopRecord = new ArrayList<>();
+                records.forEach(stop -> {
+                    if (stop.getStartTime() != null) {
+                        //将开始时间不为空的放入map
+                        stopMap.put(stop.getStopType(), stop);
+                    }
+                    if (stop.getEndTime() != null) {
+                        //将结束时间不为空组合,然后删除map中的对象,加入到新的List
+                        TwinRecordStop rs = stopMap.get(stop.getStopType());
+                        if (rs != null) {
+                            rs.setEndTime(stop.getEndTime());
+                            rs.setCalcStatus("0");
+                            finalNewStopRecord.add(rs);
+                        }
+                        stopMap.remove(stop.getStopType());
+                    }
+                });
+
+                newStopRecord.addAll(finalNewStopRecord);
+
+                //最后再补一次 没有结束时间的为当前时间
+                for (TwinRecordStop stop : stopMap.values()) {
+                    stop.setCalcStatus("1");
+                    stop.setEndTime(DateUtils.toDate(start.plusHours(1)));
+                    newStopRecord.add(stop);
+                }
+
+            }
+            start = start.plusHours(1);
+
+
+        } while (!start.isAfter(end));
+
+
+        try (Workbook workbook = new XSSFWorkbook(); FileOutputStream outputStream = new FileOutputStream("D:\\SYSTEM\\Desktop\\temp\\excel\\染整停机记录" + st + System.currentTimeMillis() / 1000 + ".xlsx")) {
+            String[] names = {"状态", "开始时间", "结束时间", "持续时间"};
+            for (int j = 0; j < devices.length; j++) {
+                String deviceName = devices[j][0];
+                Sheet sheet = workbook.createSheet();
+                workbook.setSheetName(j, deviceName);
+                Row title = sheet.createRow(0);
+                for (int i = 0; i < names.length; i++) {
+                    Cell cell = title.createCell(i);
+                    cell.setCellValue(names[i]);
+                }
+                List<TwinRecordStop> newStopRecord = resultMap.get(deviceName);
+                AtomicInteger index = new AtomicInteger(1);
+                newStopRecord.forEach(stop -> {
+                    Row row = sheet.createRow(index.get());
+                    Cell[] cells = new Cell[names.length];
+                    for (int i = 0; i < names.length; i++) {
+                        cells[i] = row.createCell(i);
+                    }
+                    cells[0].setCellValue(stop.getStopType());
+                    cells[1].setCellValue(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", stop.getStartTime()));
+                    cells[2].setCellValue(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", stop.getEndTime()));
+                    cells[3].setCellValue((stop.getEndTime().getTime() - stop.getStartTime().getTime()) / 1000);
+                    index.getAndIncrement();
+                });
+            }
+            workbook.write(outputStream);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 3 - 3
jjt-admin/src/test/java/com/jjt/rziot/SgtgjTest.java

@@ -41,10 +41,10 @@ public class SgtgjTest {
     @Test
     void test() {
         iotService.setToken();
-        String st = "2025-02-28";
+        String st = "2025-09-17";
         LocalDate localDate = LocalDate.parse(st);
-        LocalDateTime start = LocalDateTime.of(localDate, LocalTime.MIN).plusHours(19);
-        LocalDateTime end = start.plusHours(11);
+        LocalDateTime start = LocalDateTime.of(localDate, LocalTime.MIN).plusHours(7);
+        LocalDateTime end = start.plusHours(23);
         List<Pair<String, String>> list = new ArrayList<>();
         Long startTime = start.toInstant(ZoneOffset.of("+8")).toEpochMilli();
         Long endTime = end.toInstant(ZoneOffset.of("+8")).toEpochMilli();

+ 3 - 3
jjt-admin/src/test/java/com/jjt/rziot/TangJianJiTest.java

@@ -39,10 +39,10 @@ public class TangJianJiTest {
     @Test
     void test() {
         iotService.setToken();
-        String st = "2025-02-28";
+        String st = "2025-09-17";
         LocalDate localDate = LocalDate.parse(st);
-        LocalDateTime start = LocalDateTime.of(localDate, LocalTime.MIN).plusHours(19);
-        LocalDateTime end = start.plusHours(11);
+        LocalDateTime start = LocalDateTime.of(localDate, LocalTime.MIN).plusHours(7);
+        LocalDateTime end = start.plusHours(23);
         List<Pair<String, String>> list = new ArrayList<>();
         Long startTime = start.toInstant(ZoneOffset.of("+8")).toEpochMilli();
         Long endTime = end.toInstant(ZoneOffset.of("+8")).toEpochMilli();

+ 1 - 1
jjt-admin/src/test/java/com/jjt/wk/EmpCalcTest.java

@@ -34,7 +34,7 @@ public class EmpCalcTest {
 
     @Test
     public void test() {
-        String s = "2025-08-10";
+        String s = "2025-10-05";
         Date date = DateUtils.parseDate(s);
         empCalcService.calc(date);
     }

+ 113 - 0
jjt-biz/src/main/java/com/jjt/dyeing/controller/DyeingDeviceController.java

@@ -0,0 +1,113 @@
+package com.jjt.dyeing.controller;
+
+import java.util.List;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.jjt.common.annotation.Log;
+import com.jjt.common.core.controller.BaseController;
+import com.jjt.common.core.domain.AjaxResult;
+import com.jjt.common.enums.BusinessType;
+import com.jjt.dyeing.domain.DyeingDevice;
+import com.jjt.dyeing.service.IDyeingDeviceService;
+import com.jjt.common.utils.poi.ExcelUtil;
+import com.jjt.common.core.page.TableDataInfo;
+
+/**
+ * 染整线设备管理Controller
+ *
+ * @author wukai
+ * @date 2025-10-19
+ */
+@Api(tags="染整线设备管理")
+@RestController
+@RequestMapping("/dyeing/rzDevice")
+public class DyeingDeviceController extends BaseController{
+    @Resource
+    private IDyeingDeviceService dyeingDeviceService;
+
+    /**
+     * 查询染整线设备管理列表
+     */
+    @ApiOperation("查询染整线设备管理列表")
+    @PreAuthorize("@ss.hasPermi('dyeing:rzDevice:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(DyeingDevice dyeingDevice)
+    {
+        startPage();
+        List<DyeingDevice> list = dyeingDeviceService.selectDyeingDeviceList(dyeingDevice);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出染整线设备管理列表
+     */
+    @ApiOperation("导出染整线设备管理列表")
+    @PreAuthorize("@ss.hasPermi('dyeing:rzDevice:export')")
+    @Log(title = "染整线设备管理", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, DyeingDevice dyeingDevice)
+    {
+        List<DyeingDevice> list = dyeingDeviceService.selectDyeingDeviceList(dyeingDevice);
+        ExcelUtil<DyeingDevice> util = new ExcelUtil<DyeingDevice>(DyeingDevice.class);
+        util.exportExcel(response, list, "染整线设备管理数据");
+    }
+
+    /**
+     * 获取染整线设备管理详细信息
+     */
+    @ApiOperation("获取染整线设备管理详细信息")
+    @PreAuthorize("@ss.hasPermi('dyeing:rzDevice:query')")
+    @GetMapping(value = "/{deviceId}")
+    public AjaxResult getInfo(@PathVariable("deviceId") Long deviceId)
+    {
+        return success(dyeingDeviceService.selectDyeingDeviceByDeviceId(deviceId));
+    }
+
+    /**
+     * 新增染整线设备管理
+     */
+    @ApiOperation("新增染整线设备管理")
+    @PreAuthorize("@ss.hasPermi('dyeing:rzDevice:add')")
+    @Log(title = "染整线设备管理", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody DyeingDevice dyeingDevice)
+    {
+        return toAjax(dyeingDeviceService.insertDyeingDevice(dyeingDevice));
+    }
+
+    /**
+     * 修改染整线设备管理
+     */
+    @ApiOperation("修改染整线设备管理")
+    @PreAuthorize("@ss.hasPermi('dyeing:rzDevice:edit')")
+    @Log(title = "染整线设备管理", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody DyeingDevice dyeingDevice)
+    {
+        return toAjax(dyeingDeviceService.updateDyeingDevice(dyeingDevice));
+    }
+
+    /**
+     * 删除染整线设备管理
+     */
+    @ApiOperation("删除染整线设备管理")
+    @PreAuthorize("@ss.hasPermi('dyeing:rzDevice:remove')")
+    @Log(title = "染整线设备管理", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{deviceIds}")
+    public AjaxResult remove(@PathVariable Long[] deviceIds)
+    {
+        return toAjax(dyeingDeviceService.deleteDyeingDeviceByDeviceIds(deviceIds));
+    }
+}

+ 113 - 0
jjt-biz/src/main/java/com/jjt/dyeing/controller/DyeingHourAvgController.java

@@ -0,0 +1,113 @@
+package com.jjt.dyeing.controller;
+
+import java.util.List;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.jjt.common.annotation.Log;
+import com.jjt.common.core.controller.BaseController;
+import com.jjt.common.core.domain.AjaxResult;
+import com.jjt.common.enums.BusinessType;
+import com.jjt.dyeing.domain.DyeingHourAvg;
+import com.jjt.dyeing.service.IDyeingHourAvgService;
+import com.jjt.common.utils.poi.ExcelUtil;
+import com.jjt.common.core.page.TableDataInfo;
+
+/**
+ * 染整线小时平均统计数据Controller
+ *
+ * @author wukai
+ * @date 2025-10-19
+ */
+@Api(tags="染整线小时平均统计数据")
+@RestController
+@RequestMapping("/dyeing/rzAvg")
+public class DyeingHourAvgController extends BaseController{
+    @Resource
+    private IDyeingHourAvgService dyeingHourAvgService;
+
+    /**
+     * 查询染整线小时平均统计数据列表
+     */
+    @ApiOperation("查询染整线小时平均统计数据列表")
+    @PreAuthorize("@ss.hasPermi('dyeing:rzAvg:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(DyeingHourAvg dyeingHourAvg)
+    {
+        startPage();
+        List<DyeingHourAvg> list = dyeingHourAvgService.selectDyeingHourAvgList(dyeingHourAvg);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出染整线小时平均统计数据列表
+     */
+    @ApiOperation("导出染整线小时平均统计数据列表")
+    @PreAuthorize("@ss.hasPermi('dyeing:rzAvg:export')")
+    @Log(title = "染整线小时平均统计数据", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, DyeingHourAvg dyeingHourAvg)
+    {
+        List<DyeingHourAvg> list = dyeingHourAvgService.selectDyeingHourAvgList(dyeingHourAvg);
+        ExcelUtil<DyeingHourAvg> util = new ExcelUtil<DyeingHourAvg>(DyeingHourAvg.class);
+        util.exportExcel(response, list, "染整线小时平均统计数据数据");
+    }
+
+    /**
+     * 获取染整线小时平均统计数据详细信息
+     */
+    @ApiOperation("获取染整线小时平均统计数据详细信息")
+    @PreAuthorize("@ss.hasPermi('dyeing:rzAvg:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(dyeingHourAvgService.selectDyeingHourAvgById(id));
+    }
+
+    /**
+     * 新增染整线小时平均统计数据
+     */
+    @ApiOperation("新增染整线小时平均统计数据")
+    @PreAuthorize("@ss.hasPermi('dyeing:rzAvg:add')")
+    @Log(title = "染整线小时平均统计数据", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody DyeingHourAvg dyeingHourAvg)
+    {
+        return toAjax(dyeingHourAvgService.insertDyeingHourAvg(dyeingHourAvg));
+    }
+
+    /**
+     * 修改染整线小时平均统计数据
+     */
+    @ApiOperation("修改染整线小时平均统计数据")
+    @PreAuthorize("@ss.hasPermi('dyeing:rzAvg:edit')")
+    @Log(title = "染整线小时平均统计数据", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody DyeingHourAvg dyeingHourAvg)
+    {
+        return toAjax(dyeingHourAvgService.updateDyeingHourAvg(dyeingHourAvg));
+    }
+
+    /**
+     * 删除染整线小时平均统计数据
+     */
+    @ApiOperation("删除染整线小时平均统计数据")
+    @PreAuthorize("@ss.hasPermi('dyeing:rzAvg:remove')")
+    @Log(title = "染整线小时平均统计数据", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(dyeingHourAvgService.deleteDyeingHourAvgByIds(ids));
+    }
+}

+ 113 - 0
jjt-biz/src/main/java/com/jjt/dyeing/controller/DyeingHourEnergyController.java

@@ -0,0 +1,113 @@
+package com.jjt.dyeing.controller;
+
+import java.util.List;
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.jjt.common.annotation.Log;
+import com.jjt.common.core.controller.BaseController;
+import com.jjt.common.core.domain.AjaxResult;
+import com.jjt.common.enums.BusinessType;
+import com.jjt.dyeing.domain.DyeingHourEnergy;
+import com.jjt.dyeing.service.IDyeingHourEnergyService;
+import com.jjt.common.utils.poi.ExcelUtil;
+import com.jjt.common.core.page.TableDataInfo;
+
+/**
+ * 染整线小时能耗统计数据Controller
+ *
+ * @author wukai
+ * @date 2025-10-19
+ */
+@Api(tags="染整线小时能耗统计数据")
+@RestController
+@RequestMapping("/dyeing/rzEnergy")
+public class DyeingHourEnergyController extends BaseController{
+    @Resource
+    private IDyeingHourEnergyService dyeingHourEnergyService;
+
+    /**
+     * 查询染整线小时能耗统计数据列表
+     */
+    @ApiOperation("查询染整线小时能耗统计数据列表")
+    @PreAuthorize("@ss.hasPermi('dyeing:rzEnergy:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(DyeingHourEnergy dyeingHourEnergy)
+    {
+        startPage();
+        List<DyeingHourEnergy> list = dyeingHourEnergyService.selectDyeingHourEnergyList(dyeingHourEnergy);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出染整线小时能耗统计数据列表
+     */
+    @ApiOperation("导出染整线小时能耗统计数据列表")
+    @PreAuthorize("@ss.hasPermi('dyeing:rzEnergy:export')")
+    @Log(title = "染整线小时能耗统计数据", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, DyeingHourEnergy dyeingHourEnergy)
+    {
+        List<DyeingHourEnergy> list = dyeingHourEnergyService.selectDyeingHourEnergyList(dyeingHourEnergy);
+        ExcelUtil<DyeingHourEnergy> util = new ExcelUtil<DyeingHourEnergy>(DyeingHourEnergy.class);
+        util.exportExcel(response, list, "染整线小时能耗统计数据数据");
+    }
+
+    /**
+     * 获取染整线小时能耗统计数据详细信息
+     */
+    @ApiOperation("获取染整线小时能耗统计数据详细信息")
+    @PreAuthorize("@ss.hasPermi('dyeing:rzEnergy:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id)
+    {
+        return success(dyeingHourEnergyService.selectDyeingHourEnergyById(id));
+    }
+
+    /**
+     * 新增染整线小时能耗统计数据
+     */
+    @ApiOperation("新增染整线小时能耗统计数据")
+    @PreAuthorize("@ss.hasPermi('dyeing:rzEnergy:add')")
+    @Log(title = "染整线小时能耗统计数据", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody DyeingHourEnergy dyeingHourEnergy)
+    {
+        return toAjax(dyeingHourEnergyService.insertDyeingHourEnergy(dyeingHourEnergy));
+    }
+
+    /**
+     * 修改染整线小时能耗统计数据
+     */
+    @ApiOperation("修改染整线小时能耗统计数据")
+    @PreAuthorize("@ss.hasPermi('dyeing:rzEnergy:edit')")
+    @Log(title = "染整线小时能耗统计数据", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody DyeingHourEnergy dyeingHourEnergy)
+    {
+        return toAjax(dyeingHourEnergyService.updateDyeingHourEnergy(dyeingHourEnergy));
+    }
+
+    /**
+     * 删除染整线小时能耗统计数据
+     */
+    @ApiOperation("删除染整线小时能耗统计数据")
+    @PreAuthorize("@ss.hasPermi('dyeing:rzEnergy:remove')")
+    @Log(title = "染整线小时能耗统计数据", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids)
+    {
+        return toAjax(dyeingHourEnergyService.deleteDyeingHourEnergyByIds(ids));
+    }
+}

+ 138 - 0
jjt-biz/src/main/java/com/jjt/dyeing/domain/DyeingDevice.java

@@ -0,0 +1,138 @@
+package com.jjt.dyeing.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.jjt.common.annotation.Excel;
+import com.jjt.common.core.domain.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 染整线设备管理对象 DYEING_DEVICE
+ *
+ * @author wukai
+ * @date 2025-10-19
+ */
+@ApiModel(value = "DyeingDevice", description = "染整线设备管理")
+@Data
+public class DyeingDevice extends BaseEntity {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    @ApiModelProperty("ID")
+    @TableId
+    private Long deviceId;
+
+    /**
+     * 车间
+     */
+    @ApiModelProperty("车间")
+    @Excel(name = "车间")
+    private String wsName;
+
+    /**
+     * 产线编号
+     */
+    @ApiModelProperty("产线编号")
+    @Excel(name = "产线编号")
+    private String line;
+
+    /**
+     * ID
+     */
+    @ApiModelProperty("ID")
+    @Excel(name = "ID")
+    private Long typeId;
+
+    /**
+     * 类型名称
+     */
+    @ApiModelProperty("类型名称")
+    @Excel(name = "类型名称")
+    private String typeName;
+
+    /**
+     * 设备编码
+     */
+    @ApiModelProperty("设备编码")
+    @Excel(name = "设备编码")
+    private String deviceCode;
+
+    /**
+     * 设备名称
+     */
+    @ApiModelProperty("设备名称")
+    @Excel(name = "设备名称")
+    private String deviceName;
+
+    /**
+     * 设备路径
+     */
+    @ApiModelProperty("设备路径")
+    private String devicePath;
+
+    /**
+     * 米长表达式
+     */
+    @ApiModelProperty("米长表达式")
+    private String lengthExp;
+
+    /**
+     * 状态表达式
+     */
+    @ApiModelProperty("状态表达式")
+    private String statusExp;
+
+    /**
+     * 速度表达式
+     */
+    @ApiModelProperty("速度表达式")
+    private String speedExp;
+
+    /**
+     * 温度表达式
+     */
+    @ApiModelProperty("温度表达式")
+    private String tmpExp;
+
+    /**
+     * 电量表达式
+     */
+    @ApiModelProperty("电量表达式")
+    private String energyExp;
+
+    /**
+     * 电流表达式
+     */
+    @ApiModelProperty("电流表达式")
+    private String ampExp;
+
+    /**
+     * 创建人
+     */
+    @ApiModelProperty("创建人")
+    private String createdBy;
+
+    /**
+     * 创建时间
+     */
+    @ApiModelProperty("创建时间")
+    private Date createdTime;
+
+    /**
+     * 更新人
+     */
+    @ApiModelProperty("更新人")
+    private String updatedBy;
+
+    /**
+     * 更新时间
+     */
+    @ApiModelProperty("更新时间")
+    private Date updatedTime;
+
+}

+ 89 - 0
jjt-biz/src/main/java/com/jjt/dyeing/domain/DyeingHourAvg.java

@@ -0,0 +1,89 @@
+package com.jjt.dyeing.domain;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.baomidou.mybatisplus.annotation.TableId;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.jjt.common.annotation.Excel;
+import com.jjt.common.core.domain.BaseEntity;
+
+/**
+ * 染整线小时平均统计数据对象 DYEING_HOUR_AVG
+ *
+ * @author wukai
+ * @date 2025-10-19
+ */
+@ApiModel(value = "DyeingHourAvg", description = "染整线小时平均统计数据")
+@Data
+public class DyeingHourAvg extends BaseEntity{
+    private static final long serialVersionUID = 1L;
+
+    /** ID */
+    @ApiModelProperty("ID")
+    @TableId
+    private Long id;
+
+    /** 日期 */
+    @ApiModelProperty("日期")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "日期", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date dataDate;
+
+    /** 小时;0-23 */
+    @ApiModelProperty("小时;0-23")
+    @Excel(name = "小时;0-23")
+    private Integer hour;
+
+    /** 设备ID */
+    @ApiModelProperty("设备ID")
+    @Excel(name = "设备ID")
+    private Long deviceId;
+
+    /** 停机时间 */
+    @ApiModelProperty("停机时间")
+    @Excel(name = "停机时间")
+    private Long online;
+
+    /** 长度 */
+    @ApiModelProperty("长度")
+    @Excel(name = "长度")
+    private BigDecimal length;
+
+    /** 温度 */
+    @ApiModelProperty("温度")
+    @Excel(name = "温度")
+    private BigDecimal tmp;
+
+    /** 速度 */
+    @ApiModelProperty("速度")
+    @Excel(name = "速度")
+    private BigDecimal speed;
+
+    /** 创建人 */
+    @ApiModelProperty("创建人")
+    @Excel(name = "创建人")
+    private String createdBy;
+
+    /** 创建时间 */
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date createdTime;
+
+    /** 更新人 */
+    @ApiModelProperty("更新人")
+    @Excel(name = "更新人")
+    private String updatedBy;
+
+    /** 更新时间 */
+    @ApiModelProperty("更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date updatedTime;
+
+}

+ 79 - 0
jjt-biz/src/main/java/com/jjt/dyeing/domain/DyeingHourEnergy.java

@@ -0,0 +1,79 @@
+package com.jjt.dyeing.domain;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.baomidou.mybatisplus.annotation.TableId;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.jjt.common.annotation.Excel;
+import com.jjt.common.core.domain.BaseEntity;
+
+/**
+ * 染整线小时能耗统计数据对象 DYEING_HOUR_ENERGY
+ *
+ * @author wukai
+ * @date 2025-10-19
+ */
+@ApiModel(value = "DyeingHourEnergy", description = "染整线小时能耗统计数据")
+@Data
+public class DyeingHourEnergy extends BaseEntity{
+    private static final long serialVersionUID = 1L;
+
+    /** ID */
+    @ApiModelProperty("ID")
+    @TableId
+    private Long id;
+
+    /** 日期 */
+    @ApiModelProperty("日期")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "日期", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date dataDate;
+
+    /** 小时;0-23 */
+    @ApiModelProperty("小时;0-23")
+    @Excel(name = "小时;0-23")
+    private Integer hour;
+
+    /** 设备ID */
+    @ApiModelProperty("设备ID")
+    @Excel(name = "设备ID")
+    private Long deviceId;
+
+    /** 电量 */
+    @ApiModelProperty("电量")
+    @Excel(name = "电量")
+    private BigDecimal energy;
+
+    /** 电流 */
+    @ApiModelProperty("电流")
+    @Excel(name = "电流")
+    private BigDecimal amp;
+
+    /** 创建人 */
+    @ApiModelProperty("创建人")
+    @Excel(name = "创建人")
+    private String createdBy;
+
+    /** 创建时间 */
+    @ApiModelProperty("创建时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date createdTime;
+
+    /** 更新人 */
+    @ApiModelProperty("更新人")
+    @Excel(name = "更新人")
+    private String updatedBy;
+
+    /** 更新时间 */
+    @ApiModelProperty("更新时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date updatedTime;
+
+}

+ 62 - 0
jjt-biz/src/main/java/com/jjt/dyeing/mapper/DyeingDeviceMapper.java

@@ -0,0 +1,62 @@
+package com.jjt.dyeing.mapper;
+
+import java.util.List;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jjt.dyeing.domain.DyeingDevice;
+
+/**
+ * 染整线设备管理Mapper接口
+ * 
+ * @author wukai
+ * @date 2025-10-19
+ */
+public interface DyeingDeviceMapper extends BaseMapper<DyeingDevice>
+{
+    /**
+     * 查询染整线设备管理
+     * 
+     * @param deviceId 染整线设备管理主键
+     * @return 染整线设备管理
+     */
+    public DyeingDevice selectDyeingDeviceByDeviceId(Long deviceId);
+
+    /**
+     * 查询染整线设备管理列表
+     * 
+     * @param dyeingDevice 染整线设备管理
+     * @return 染整线设备管理集合
+     */
+    public List<DyeingDevice> selectDyeingDeviceList(DyeingDevice dyeingDevice);
+
+    /**
+     * 新增染整线设备管理
+     * 
+     * @param dyeingDevice 染整线设备管理
+     * @return 结果
+     */
+    public int insertDyeingDevice(DyeingDevice dyeingDevice);
+
+    /**
+     * 修改染整线设备管理
+     * 
+     * @param dyeingDevice 染整线设备管理
+     * @return 结果
+     */
+    public int updateDyeingDevice(DyeingDevice dyeingDevice);
+
+    /**
+     * 删除染整线设备管理
+     * 
+     * @param deviceId 染整线设备管理主键
+     * @return 结果
+     */
+    public int deleteDyeingDeviceByDeviceId(Long deviceId);
+
+    /**
+     * 批量删除染整线设备管理
+     * 
+     * @param deviceIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteDyeingDeviceByDeviceIds(Long[] deviceIds);
+}

+ 70 - 0
jjt-biz/src/main/java/com/jjt/dyeing/mapper/DyeingHourAvgMapper.java

@@ -0,0 +1,70 @@
+package com.jjt.dyeing.mapper;
+
+import java.util.Date;
+import java.util.List;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jjt.dyeing.domain.DyeingHourAvg;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 染整线小时平均统计数据Mapper接口
+ *
+ * @author wukai
+ * @date 2025-10-19
+ */
+public interface DyeingHourAvgMapper extends BaseMapper<DyeingHourAvg>
+{
+    /**
+     * 查询染整线小时平均统计数据
+     *
+     * @param id 染整线小时平均统计数据主键
+     * @return 染整线小时平均统计数据
+     */
+    public DyeingHourAvg selectDyeingHourAvgById(Long id);
+
+    /**
+     * 查询染整线小时平均统计数据列表
+     *
+     * @param dyeingHourAvg 染整线小时平均统计数据
+     * @return 染整线小时平均统计数据集合
+     */
+    public List<DyeingHourAvg> selectDyeingHourAvgList(DyeingHourAvg dyeingHourAvg);
+
+    /**
+     * 新增染整线小时平均统计数据
+     *
+     * @param dyeingHourAvg 染整线小时平均统计数据
+     * @return 结果
+     */
+    public int insertDyeingHourAvg(DyeingHourAvg dyeingHourAvg);
+
+    /**
+     * 修改染整线小时平均统计数据
+     *
+     * @param dyeingHourAvg 染整线小时平均统计数据
+     * @return 结果
+     */
+    public int updateDyeingHourAvg(DyeingHourAvg dyeingHourAvg);
+
+    /**
+     * 删除染整线小时平均统计数据
+     *
+     * @param id 染整线小时平均统计数据主键
+     * @return 结果
+     */
+    public int deleteDyeingHourAvgById(Long id);
+
+    /**
+     * 批量删除染整线小时平均统计数据
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteDyeingHourAvgByIds(Long[] ids);
+    /**
+     * 按小时删除数据
+     * @param date 时间
+     * @param hour 小时
+     */
+    void deleteByHour(@Param("date") Date date,@Param("hour") int hour);
+}

+ 71 - 0
jjt-biz/src/main/java/com/jjt/dyeing/mapper/DyeingHourEnergyMapper.java

@@ -0,0 +1,71 @@
+package com.jjt.dyeing.mapper;
+
+import java.util.Date;
+import java.util.List;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jjt.dyeing.domain.DyeingHourEnergy;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 染整线小时能耗统计数据Mapper接口
+ *
+ * @author wukai
+ * @date 2025-10-19
+ */
+public interface DyeingHourEnergyMapper extends BaseMapper<DyeingHourEnergy>
+{
+    /**
+     * 查询染整线小时能耗统计数据
+     *
+     * @param id 染整线小时能耗统计数据主键
+     * @return 染整线小时能耗统计数据
+     */
+    public DyeingHourEnergy selectDyeingHourEnergyById(Long id);
+
+    /**
+     * 查询染整线小时能耗统计数据列表
+     *
+     * @param dyeingHourEnergy 染整线小时能耗统计数据
+     * @return 染整线小时能耗统计数据集合
+     */
+    public List<DyeingHourEnergy> selectDyeingHourEnergyList(DyeingHourEnergy dyeingHourEnergy);
+
+    /**
+     * 新增染整线小时能耗统计数据
+     *
+     * @param dyeingHourEnergy 染整线小时能耗统计数据
+     * @return 结果
+     */
+    public int insertDyeingHourEnergy(DyeingHourEnergy dyeingHourEnergy);
+
+    /**
+     * 修改染整线小时能耗统计数据
+     *
+     * @param dyeingHourEnergy 染整线小时能耗统计数据
+     * @return 结果
+     */
+    public int updateDyeingHourEnergy(DyeingHourEnergy dyeingHourEnergy);
+
+    /**
+     * 删除染整线小时能耗统计数据
+     *
+     * @param id 染整线小时能耗统计数据主键
+     * @return 结果
+     */
+    public int deleteDyeingHourEnergyById(Long id);
+
+    /**
+     * 批量删除染整线小时能耗统计数据
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteDyeingHourEnergyByIds(Long[] ids);
+
+    /**
+     * 按小时删除数据
+     * @param date 时间
+     * @param hour 小时
+     */
+    void deleteByHour(@Param("date") Date date, @Param("hour") int hour);
+}

+ 69 - 0
jjt-biz/src/main/java/com/jjt/dyeing/service/IDyeingDeviceService.java

@@ -0,0 +1,69 @@
+package com.jjt.dyeing.service;
+
+import com.jjt.dyeing.domain.DyeingDevice;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 染整线设备管理Service接口
+ *
+ * @author wukai
+ * @date 2025-10-19
+ */
+public interface IDyeingDeviceService {
+    /**
+     * 查询染整线设备管理
+     *
+     * @param deviceId 染整线设备管理主键
+     * @return 染整线设备管理
+     */
+    public DyeingDevice selectDyeingDeviceByDeviceId(Long deviceId);
+
+    /**
+     * 查询染整线设备管理列表
+     *
+     * @param dyeingDevice 染整线设备管理
+     * @return 染整线设备管理集合
+     */
+    public List<DyeingDevice> selectDyeingDeviceList(DyeingDevice dyeingDevice);
+
+    /**
+     * 新增染整线设备管理
+     *
+     * @param dyeingDevice 染整线设备管理
+     * @return 结果
+     */
+    public int insertDyeingDevice(DyeingDevice dyeingDevice);
+
+    /**
+     * 修改染整线设备管理
+     *
+     * @param dyeingDevice 染整线设备管理
+     * @return 结果
+     */
+    public int updateDyeingDevice(DyeingDevice dyeingDevice);
+
+    /**
+     * 批量删除染整线设备管理
+     *
+     * @param deviceIds 需要删除的染整线设备管理主键集合
+     * @return 结果
+     */
+    public int deleteDyeingDeviceByDeviceIds(Long[] deviceIds);
+
+    /**
+     * 删除染整线设备管理信息
+     *
+     * @param deviceId 染整线设备管理主键
+     * @return 结果
+     */
+    public int deleteDyeingDeviceByDeviceId(Long deviceId);
+
+    /**
+     * 获取按产线分组的设备列表
+     *
+     * @return 结果
+     */
+    Map<String, List<DyeingDevice>> deviceByLine();
+}

+ 74 - 0
jjt-biz/src/main/java/com/jjt/dyeing/service/IDyeingHourAvgService.java

@@ -0,0 +1,74 @@
+package com.jjt.dyeing.service;
+
+import java.time.LocalDate;
+import java.util.List;
+import com.jjt.dyeing.domain.DyeingHourAvg;
+
+/**
+ * 染整线小时平均统计数据Service接口
+ *
+ * @author wukai
+ * @date 2025-10-19
+ */
+public interface IDyeingHourAvgService {
+    /**
+     * 查询染整线小时平均统计数据
+     *
+     * @param id 染整线小时平均统计数据主键
+     * @return 染整线小时平均统计数据
+     */
+    public DyeingHourAvg selectDyeingHourAvgById(Long id);
+
+    /**
+     * 查询染整线小时平均统计数据列表
+     *
+     * @param dyeingHourAvg 染整线小时平均统计数据
+     * @return 染整线小时平均统计数据集合
+     */
+    public List<DyeingHourAvg> selectDyeingHourAvgList(DyeingHourAvg dyeingHourAvg);
+
+    /**
+     * 新增染整线小时平均统计数据
+     *
+     * @param dyeingHourAvg 染整线小时平均统计数据
+     * @return 结果
+     */
+    public int insertDyeingHourAvg(DyeingHourAvg dyeingHourAvg);
+
+    /**
+     * 修改染整线小时平均统计数据
+     *
+     * @param dyeingHourAvg 染整线小时平均统计数据
+     * @return 结果
+     */
+    public int updateDyeingHourAvg(DyeingHourAvg dyeingHourAvg);
+
+    /**
+     * 批量删除染整线小时平均统计数据
+     *
+     * @param ids 需要删除的染整线小时平均统计数据主键集合
+     * @return 结果
+     */
+    public int deleteDyeingHourAvgByIds(Long[] ids);
+
+    /**
+     * 删除染整线小时平均统计数据信息
+     *
+     * @param id 染整线小时平均统计数据主键
+     * @return 结果
+     */
+    public int deleteDyeingHourAvgById(Long id);
+
+    /**
+     * 计算上一小时数据
+     */
+    void calcLastHour();
+
+    /**
+     * 计算指定时间指定小时数据
+     *
+     * @param date 时间
+     * @param hour 小时
+     */
+    void calc(LocalDate date, int hour);
+}

+ 77 - 0
jjt-biz/src/main/java/com/jjt/dyeing/service/IDyeingHourEnergyService.java

@@ -0,0 +1,77 @@
+package com.jjt.dyeing.service;
+
+import com.jjt.dyeing.domain.DyeingHourEnergy;
+
+import java.time.LocalDate;
+import java.util.List;
+
+/**
+ * 染整线小时能耗统计数据Service接口
+ *
+ * @author wukai
+ * @date 2025-10-19
+ */
+public interface IDyeingHourEnergyService {
+    /**
+     * 查询染整线小时能耗统计数据
+     *
+     * @param id 染整线小时能耗统计数据主键
+     * @return 染整线小时能耗统计数据
+     */
+    public DyeingHourEnergy selectDyeingHourEnergyById(Long id);
+
+    /**
+     * 查询染整线小时能耗统计数据列表
+     *
+     * @param dyeingHourEnergy 染整线小时能耗统计数据
+     * @return 染整线小时能耗统计数据集合
+     */
+    public List<DyeingHourEnergy> selectDyeingHourEnergyList(DyeingHourEnergy dyeingHourEnergy);
+
+    /**
+     * 新增染整线小时能耗统计数据
+     *
+     * @param dyeingHourEnergy 染整线小时能耗统计数据
+     * @return 结果
+     */
+    public int insertDyeingHourEnergy(DyeingHourEnergy dyeingHourEnergy);
+
+    /**
+     * 修改染整线小时能耗统计数据
+     *
+     * @param dyeingHourEnergy 染整线小时能耗统计数据
+     * @return 结果
+     */
+    public int updateDyeingHourEnergy(DyeingHourEnergy dyeingHourEnergy);
+
+    /**
+     * 批量删除染整线小时能耗统计数据
+     *
+     * @param ids 需要删除的染整线小时能耗统计数据主键集合
+     * @return 结果
+     */
+    public int deleteDyeingHourEnergyByIds(Long[] ids);
+
+    /**
+     * 删除染整线小时能耗统计数据信息
+     *
+     * @param id 染整线小时能耗统计数据主键
+     * @return 结果
+     */
+    public int deleteDyeingHourEnergyById(Long id);
+
+    /**
+     * 计算上一小时数据
+     */
+    void calcLastHour();
+
+    /**
+     * 计算指定时间指定小时数据
+     *
+     * @param date 时间
+     * @param hour 小时
+     */
+    void calc(LocalDate date, int hour);
+
+
+}

+ 101 - 0
jjt-biz/src/main/java/com/jjt/dyeing/service/impl/DyeingDeviceServiceImpl.java

@@ -0,0 +1,101 @@
+package com.jjt.dyeing.service.impl;
+
+import com.jjt.dyeing.domain.DyeingDevice;
+import com.jjt.dyeing.mapper.DyeingDeviceMapper;
+import com.jjt.dyeing.service.IDyeingDeviceService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * 染整线设备管理Service业务层处理
+ *
+ * @author wukai
+ * @date 2025-10-19
+ */
+@Service
+public class DyeingDeviceServiceImpl implements IDyeingDeviceService {
+    @Resource
+    private DyeingDeviceMapper dyeingDeviceMapper;
+
+    /**
+     * 查询染整线设备管理
+     *
+     * @param deviceId 染整线设备管理主键
+     * @return 染整线设备管理
+     */
+    @Override
+    public DyeingDevice selectDyeingDeviceByDeviceId(Long deviceId) {
+        return dyeingDeviceMapper.selectDyeingDeviceByDeviceId(deviceId);
+    }
+
+    /**
+     * 查询染整线设备管理列表
+     *
+     * @param dyeingDevice 染整线设备管理
+     * @return 染整线设备管理
+     */
+    @Override
+    public List<DyeingDevice> selectDyeingDeviceList(DyeingDevice dyeingDevice) {
+        return dyeingDeviceMapper.selectDyeingDeviceList(dyeingDevice);
+    }
+
+    /**
+     * 新增染整线设备管理
+     *
+     * @param dyeingDevice 染整线设备管理
+     * @return 结果
+     */
+    @Override
+    public int insertDyeingDevice(DyeingDevice dyeingDevice) {
+        return dyeingDeviceMapper.insertDyeingDevice(dyeingDevice);
+    }
+
+    /**
+     * 修改染整线设备管理
+     *
+     * @param dyeingDevice 染整线设备管理
+     * @return 结果
+     */
+    @Override
+    public int updateDyeingDevice(DyeingDevice dyeingDevice) {
+        return dyeingDeviceMapper.updateDyeingDevice(dyeingDevice);
+    }
+
+    /**
+     * 批量删除染整线设备管理
+     *
+     * @param deviceIds 需要删除的染整线设备管理主键
+     * @return 结果
+     */
+    @Override
+    public int deleteDyeingDeviceByDeviceIds(Long[] deviceIds) {
+        return dyeingDeviceMapper.deleteDyeingDeviceByDeviceIds(deviceIds);
+    }
+
+    /**
+     * 删除染整线设备管理信息
+     *
+     * @param deviceId 染整线设备管理主键
+     * @return 结果
+     */
+    @Override
+    public int deleteDyeingDeviceByDeviceId(Long deviceId) {
+        return dyeingDeviceMapper.deleteDyeingDeviceByDeviceId(deviceId);
+    }
+
+    /**
+     * 获取按产线分组的设备列表
+     *
+     * @return 结果
+     */
+    @Override
+    public Map<String, List<DyeingDevice>> deviceByLine() {
+        List<DyeingDevice> list = selectDyeingDeviceList(new DyeingDevice());
+        // 按照line字段对设备进行分组
+        return list.stream().collect(Collectors.groupingBy(DyeingDevice::getLine));
+    }
+}

+ 204 - 0
jjt-biz/src/main/java/com/jjt/dyeing/service/impl/DyeingHourAvgServiceImpl.java

@@ -0,0 +1,204 @@
+package com.jjt.dyeing.service.impl;
+
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import com.jjt.common.utils.DateUtils;
+import com.jjt.common.utils.StringUtils;
+import com.jjt.dyeing.domain.DyeingDevice;
+import com.jjt.dyeing.domain.DyeingHourAvg;
+import com.jjt.dyeing.mapper.DyeingHourAvgMapper;
+import com.jjt.dyeing.service.IDyeingDeviceService;
+import com.jjt.dyeing.service.IDyeingHourAvgService;
+import com.jjt.utils.IotService;
+import com.jjt.utils.Tools;
+import org.apache.ibatis.session.ExecutorType;
+import org.apache.ibatis.session.SqlSession;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 染整线小时平均统计数据Service业务层处理
+ *
+ * @author wukai
+ * @date 2025-10-19
+ */
+@Service
+public class DyeingHourAvgServiceImpl implements IDyeingHourAvgService {
+    @Resource
+    private DyeingHourAvgMapper dyeingHourAvgMapper;
+    @Resource
+    private IDyeingDeviceService dyeingDeviceService;
+    @Resource
+    private IotService iotService;
+    @Resource
+    private SqlSessionFactory factory;
+
+    /**
+     * 查询染整线小时平均统计数据
+     *
+     * @param id 染整线小时平均统计数据主键
+     * @return 染整线小时平均统计数据
+     */
+    @Override
+    public DyeingHourAvg selectDyeingHourAvgById(Long id) {
+        return dyeingHourAvgMapper.selectDyeingHourAvgById(id);
+    }
+
+    /**
+     * 查询染整线小时平均统计数据列表
+     *
+     * @param dyeingHourAvg 染整线小时平均统计数据
+     * @return 染整线小时平均统计数据
+     */
+    @Override
+    public List<DyeingHourAvg> selectDyeingHourAvgList(DyeingHourAvg dyeingHourAvg) {
+        return dyeingHourAvgMapper.selectDyeingHourAvgList(dyeingHourAvg);
+    }
+
+    /**
+     * 新增染整线小时平均统计数据
+     *
+     * @param dyeingHourAvg 染整线小时平均统计数据
+     * @return 结果
+     */
+    @Override
+    public int insertDyeingHourAvg(DyeingHourAvg dyeingHourAvg) {
+        return dyeingHourAvgMapper.insertDyeingHourAvg(dyeingHourAvg);
+    }
+
+    /**
+     * 修改染整线小时平均统计数据
+     *
+     * @param dyeingHourAvg 染整线小时平均统计数据
+     * @return 结果
+     */
+    @Override
+    public int updateDyeingHourAvg(DyeingHourAvg dyeingHourAvg) {
+        return dyeingHourAvgMapper.updateDyeingHourAvg(dyeingHourAvg);
+    }
+
+    /**
+     * 批量删除染整线小时平均统计数据
+     *
+     * @param ids 需要删除的染整线小时平均统计数据主键
+     * @return 结果
+     */
+    @Override
+    public int deleteDyeingHourAvgByIds(Long[] ids) {
+        return dyeingHourAvgMapper.deleteDyeingHourAvgByIds(ids);
+    }
+
+    /**
+     * 删除染整线小时平均统计数据信息
+     *
+     * @param id 染整线小时平均统计数据主键
+     * @return 结果
+     */
+    @Override
+    public int deleteDyeingHourAvgById(Long id) {
+        return dyeingHourAvgMapper.deleteDyeingHourAvgById(id);
+    }
+
+    /**
+     * 计算上一小时数据
+     */
+    @Override
+    public void calcLastHour() {
+        LocalDateTime end = Tools.currWholeTime();
+        LocalDateTime start = end.minusHours(1);
+        calc(start.toLocalDate(), start.getHour());
+    }
+
+    /**
+     * 计算指定时间指定小时数据
+     *
+     * @param date 时间
+     * @param hour 小时
+     */
+    @Override
+    public void calc(LocalDate date, int hour) {
+        LocalDateTime start = LocalDateTime.of(date, LocalTime.MIN).plusHours(hour);
+        LocalDateTime end = start.plusHours(1);
+        dyeingHourAvgMapper.deleteByHour(DateUtils.toDate(date), hour);
+        Map<String, List<DyeingDevice>> deviceByLine = dyeingDeviceService.deviceByLine();
+        deviceByLine.forEach((line, devices) -> {
+            Map<Long, DyeingHourAvg> avgMap = new HashMap<>();
+            List<String> fieldList = new ArrayList<>();
+            devices.forEach(device -> {
+                if (StringUtils.isNotEmpty(device.getLengthExp())) {
+                    String tmp = device.getLengthExp().replace("${code}", device.getDeviceCode()) + " AS " + device.getDeviceId() + "_length";
+                    fieldList.add(tmp);
+                }
+                if (StringUtils.isNotEmpty(device.getStatusExp())) {
+                    String statusExp = device.getStatusExp().replace("${code}", device.getDeviceCode()) + " AS " + device.getDeviceId() + "_status";
+                    fieldList.add(statusExp);
+                }
+                if (StringUtils.isNotEmpty(device.getSpeedExp())) {
+                    String speedExp = device.getSpeedExp().replace("${code}", device.getDeviceCode()) + " AS " + device.getDeviceId() + "_speed";
+                    fieldList.add(speedExp);
+                }
+                if (StringUtils.isNotEmpty(device.getTmpExp())) {
+                    String tmp = device.getTmpExp().replace("${code}", device.getDeviceCode()) + " AS " + device.getDeviceId() + "_tmp";
+                    fieldList.add(tmp);
+                }
+                DyeingHourAvg energy = new DyeingHourAvg();
+                energy.setDeviceId(device.getDeviceId());
+                energy.setDataDate(DateUtils.toDate(date));
+                energy.setHour(start.getHour());
+                avgMap.put(device.getDeviceId(), energy);
+            });
+            String sql = "select %s from root.tl.suxi where time>%s and time <=%s";
+            sql = String.format(sql, String.join(",", fieldList), DateUtils.parseIso(start), DateUtils.parseIso(end));
+            iotService.query(sql);
+            JSONObject jsonObject = iotService.query(sql);
+            JSONObject data = jsonObject.getJSONObject("data");
+            JSONArray values = data.getJSONArray("values");
+            JSONArray columnNames = data.getJSONArray("columnNames");
+            if (values.size() == 1) {
+                JSONArray da = values.getJSONArray(0);
+                for (int i = 0; i < da.size(); i++) {
+                    String field = columnNames.getStr(i);
+                    String[] split = field.split("_");
+                    Long id = Long.parseLong(split[0]);
+                    String type = split[1];
+                    if (da.getDouble(i) != null) {
+                        Double v = da.getDouble(i);
+                        DyeingHourAvg energy = avgMap.get(id);
+                        if ("length".equals(type)) {
+                            energy.setLength(BigDecimal.valueOf(v));
+                        }
+                        if ("status".equals(type)) {
+                            energy.setOnline(BigDecimal.valueOf(v).divide(BigDecimal.valueOf(1000), 0, RoundingMode.HALF_UP).longValue());
+                        }
+                        if ("speed".equals(type)) {
+                            energy.setSpeed(BigDecimal.valueOf(v));
+                        }
+                        if ("tmp".equals(type)) {
+                            energy.setTmp(BigDecimal.valueOf(v));
+                        }
+                    }
+                }
+            }
+            List<DyeingHourAvg> dyeingHourEnergies = new ArrayList<>(avgMap.values());
+
+            try (SqlSession sqlSession = factory.openSession(ExecutorType.BATCH, false)) {
+                if (dyeingHourEnergies.size() > 0) {
+                    DyeingHourAvgMapper mapper = sqlSession.getMapper(DyeingHourAvgMapper.class);
+                    dyeingHourEnergies.forEach(mapper::insertDyeingHourAvg);
+                    sqlSession.commit();
+                }
+            }
+        });
+    }
+}

+ 183 - 0
jjt-biz/src/main/java/com/jjt/dyeing/service/impl/DyeingHourEnergyServiceImpl.java

@@ -0,0 +1,183 @@
+package com.jjt.dyeing.service.impl;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import com.jjt.common.utils.DateUtils;
+import com.jjt.dyeing.domain.DyeingDevice;
+import com.jjt.dyeing.service.IDyeingDeviceService;
+import com.jjt.utils.IotService;
+import com.jjt.utils.Tools;
+import org.apache.ibatis.session.ExecutorType;
+import org.apache.ibatis.session.SqlSession;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.springframework.stereotype.Service;
+import com.jjt.dyeing.mapper.DyeingHourEnergyMapper;
+import com.jjt.dyeing.domain.DyeingHourEnergy;
+import com.jjt.dyeing.service.IDyeingHourEnergyService;
+import javax.annotation.Resource;
+
+/**
+ * 染整线小时能耗统计数据Service业务层处理
+ *
+ * @author wukai
+ * @date 2025-10-19
+ */
+@Service
+public class DyeingHourEnergyServiceImpl implements IDyeingHourEnergyService {
+    @Resource
+    private DyeingHourEnergyMapper dyeingHourEnergyMapper;
+    @Resource
+    private IDyeingDeviceService dyeingDeviceService;
+    @Resource
+    private IotService iotService;
+    @Resource
+    private SqlSessionFactory factory;
+    /**
+     * 查询染整线小时能耗统计数据
+     *
+     * @param id 染整线小时能耗统计数据主键
+     * @return 染整线小时能耗统计数据
+     */
+    @Override
+    public DyeingHourEnergy selectDyeingHourEnergyById(Long id) {
+        return dyeingHourEnergyMapper.selectDyeingHourEnergyById(id);
+    }
+
+    /**
+     * 查询染整线小时能耗统计数据列表
+     *
+     * @param dyeingHourEnergy 染整线小时能耗统计数据
+     * @return 染整线小时能耗统计数据
+     */
+    @Override
+    public List<DyeingHourEnergy> selectDyeingHourEnergyList(DyeingHourEnergy dyeingHourEnergy) {
+        return dyeingHourEnergyMapper.selectDyeingHourEnergyList(dyeingHourEnergy);
+    }
+
+    /**
+     * 新增染整线小时能耗统计数据
+     *
+     * @param dyeingHourEnergy 染整线小时能耗统计数据
+     * @return 结果
+     */
+    @Override
+    public int insertDyeingHourEnergy(DyeingHourEnergy dyeingHourEnergy) {
+            return dyeingHourEnergyMapper.insertDyeingHourEnergy(dyeingHourEnergy);
+    }
+
+    /**
+     * 修改染整线小时能耗统计数据
+     *
+     * @param dyeingHourEnergy 染整线小时能耗统计数据
+     * @return 结果
+     */
+    @Override
+    public int updateDyeingHourEnergy(DyeingHourEnergy dyeingHourEnergy) {
+        return dyeingHourEnergyMapper.updateDyeingHourEnergy(dyeingHourEnergy);
+    }
+
+    /**
+     * 批量删除染整线小时能耗统计数据
+     *
+     * @param ids 需要删除的染整线小时能耗统计数据主键
+     * @return 结果
+     */
+    @Override
+    public int deleteDyeingHourEnergyByIds(Long[] ids) {
+        return dyeingHourEnergyMapper.deleteDyeingHourEnergyByIds(ids);
+    }
+
+    /**
+     * 删除染整线小时能耗统计数据信息
+     *
+     * @param id 染整线小时能耗统计数据主键
+     * @return 结果
+     */
+    @Override
+    public int deleteDyeingHourEnergyById(Long id) {
+        return dyeingHourEnergyMapper.deleteDyeingHourEnergyById(id);
+    }
+
+    /**
+     * 计算上一小时数据
+     */
+    @Override
+    public void calcLastHour() {
+        LocalDateTime end = Tools.currWholeTime();
+        LocalDateTime start = end.minusHours(1);
+        calc(start.toLocalDate(), start.getHour());
+    }
+
+    /**
+     * 计算指定时间指定小时数据
+     *
+     * @param date 时间
+     * @param hour 小时
+     */
+    @Override
+    public void calc(LocalDate date, int hour) {
+        LocalDateTime start = LocalDateTime.of(date, LocalTime.MIN).plusHours(hour);
+        LocalDateTime end = start.plusHours(1);
+        dyeingHourEnergyMapper.deleteByHour(DateUtils.toDate(date), hour);
+        Map<String, List<DyeingDevice>> deviceByLine = dyeingDeviceService.deviceByLine();
+        deviceByLine.forEach((line, devices) -> {
+            Map<Long, DyeingHourEnergy> energyMap = new HashMap<>();
+            List<String> fieldList = new ArrayList<>();
+            devices.forEach(device -> {
+                String energyExp = device.getEnergyExp() + " AS " + device.getDeviceId() + "_energy";
+                fieldList.add(energyExp);
+                String ampExp = device.getAmpExp() + " AS " + device.getDeviceId() + "_amp";
+                fieldList.add(ampExp);
+                DyeingHourEnergy energy = new DyeingHourEnergy();
+                energy.setDeviceId(device.getDeviceId());
+                energy.setDataDate(DateUtils.toDate(start.toLocalDate()));
+                energy.setHour(start.getHour());
+                energyMap.put(device.getDeviceId(), energy);
+            });
+            String sql = "select %s from root.tl.suxi where time>%s and time <=%s";
+            sql = String.format(sql, String.join(",", fieldList), DateUtils.parseIso(start), DateUtils.parseIso(end));
+            iotService.query(sql);
+            JSONObject jsonObject = iotService.query(sql);
+            JSONObject data = jsonObject.getJSONObject("data");
+            JSONArray values = data.getJSONArray("values");
+            JSONArray columnNames = data.getJSONArray("columnNames");
+            if (values.size() == 1) {
+                JSONArray da = values.getJSONArray(0);
+                for (int i = 0; i < da.size(); i++) {
+                    String field = columnNames.getStr(i);
+                    String[] split = field.split("_");
+                    Long id = Long.parseLong(split[0]);
+                    String type = split[1];
+                    if (da.getDouble(i) != null) {
+                        Double v = da.getDouble(i);
+                        DyeingHourEnergy energy = energyMap.get(id);
+                        if ("energy".equals(type)) {
+                            energy.setEnergy(BigDecimal.valueOf(v));
+                        }
+                        if ("amp".equals(type)) {
+                            energy.setAmp(BigDecimal.valueOf(v));
+                        }
+                    }
+                }
+            }
+            List<DyeingHourEnergy> dyeingHourEnergies = new ArrayList<>(energyMap.values());
+
+            try (SqlSession sqlSession = factory.openSession(ExecutorType.BATCH, false)) {
+                if (dyeingHourEnergies.size() > 0) {
+                    DyeingHourEnergyMapper mapper = sqlSession.getMapper(DyeingHourEnergyMapper.class);
+                    dyeingHourEnergies.forEach(mapper::insertDyeingHourEnergy);
+                    sqlSession.commit();
+                }
+            }
+        });
+    }
+}

+ 1 - 1
jjt-biz/src/main/java/com/jjt/nccloud/utils/NccloudUtils.java

@@ -55,7 +55,7 @@ public class NccloudUtils {
     private static String token = null;
 
     public static void main(String[] args) throws Exception {
-        String requestBody = "{\"pk_org\":\"100101\",\"dbilldate\":\"2024-12-16 00:00:00~2024-12-17 00:00:00\"}";
+        String requestBody = "{\"pk_org\":\"100101\",\"dbilldate\":\"2025-10-17 00:00:00~2025-10-18 00:00:00\"}";
         String jsonStr = getData(requestBody);
         JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
         if (!jsonObject.getBool("success")) {

+ 129 - 0
jjt-biz/src/main/resources/mapper/dyeing/DyeingDeviceMapper.xml

@@ -0,0 +1,129 @@
+<?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.jjt.dyeing.mapper.DyeingDeviceMapper">
+
+    <resultMap type="DyeingDevice" id="DyeingDeviceResult">
+        <result property="deviceId"    column="DEVICE_ID"    />
+        <result property="wsName"    column="WS_NAME"    />
+        <result property="line"    column="LINE"    />
+        <result property="typeId"    column="TYPE_ID"    />
+        <result property="typeName"    column="TYPE_NAME"    />
+        <result property="deviceCode"    column="DEVICE_CODE"    />
+        <result property="deviceName"    column="DEVICE_NAME"    />
+        <result property="devicePath"    column="DEVICE_PATH"    />
+        <result property="lengthExp"    column="LENGTH_EXP"    />
+        <result property="statusExp"    column="STATUS_EXP"    />
+        <result property="speedExp"    column="SPEED_EXP"    />
+        <result property="tmpExp"    column="TMP_EXP"    />
+        <result property="energyExp"    column="ENERGY_EXP"    />
+        <result property="ampExp"    column="AMP_EXP"    />
+        <result property="createdBy"    column="CREATED_BY"    />
+        <result property="createdTime"    column="CREATED_TIME"    />
+        <result property="updatedBy"    column="UPDATED_BY"    />
+        <result property="updatedTime"    column="UPDATED_TIME"    />
+        <result property="remark"    column="REMARK"    />
+    </resultMap>
+
+    <sql id="selectDyeingDeviceVo">
+        select DEVICE_ID, WS_NAME, LINE, TYPE_ID, TYPE_NAME, DEVICE_CODE, DEVICE_NAME, DEVICE_PATH, LENGTH_EXP, STATUS_EXP, SPEED_EXP, TMP_EXP, ENERGY_EXP, AMP_EXP, CREATED_BY, CREATED_TIME, UPDATED_BY, UPDATED_TIME, REMARK from DYEING_DEVICE
+    </sql>
+
+    <select id="selectDyeingDeviceList" parameterType="DyeingDevice" resultMap="DyeingDeviceResult">
+        <include refid="selectDyeingDeviceVo"/>
+        <where>
+            <if test="wsName != null  and wsName != ''"> and WS_NAME like concat('%', #{wsName}, '%')</if>
+            <if test="line != null  and line != ''"> and LINE = #{line}</if>
+            <if test="typeId != null "> and TYPE_ID = #{typeId}</if>
+            <if test="typeName != null  and typeName != ''"> and TYPE_NAME like concat('%', #{typeName}, '%')</if>
+            <if test="deviceCode != null  and deviceCode != ''"> and DEVICE_CODE = #{deviceCode}</if>
+            <if test="deviceName != null  and deviceName != ''"> and DEVICE_NAME like concat('%', #{deviceName}, '%')</if>
+        </where>
+    </select>
+
+    <select id="selectDyeingDeviceByDeviceId" parameterType="Long" resultMap="DyeingDeviceResult">
+        <include refid="selectDyeingDeviceVo"/>
+        where DEVICE_ID = #{deviceId}
+    </select>
+
+    <insert id="insertDyeingDevice" parameterType="DyeingDevice" useGeneratedKeys="true" keyProperty="deviceId">
+        insert into DYEING_DEVICE
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="wsName != null">WS_NAME,</if>
+            <if test="line != null">LINE,</if>
+            <if test="typeId != null">TYPE_ID,</if>
+            <if test="typeName != null">TYPE_NAME,</if>
+            <if test="deviceCode != null">DEVICE_CODE,</if>
+            <if test="deviceName != null">DEVICE_NAME,</if>
+            <if test="devicePath != null">DEVICE_PATH,</if>
+            <if test="lengthExp != null">LENGTH_EXP,</if>
+            <if test="statusExp != null">STATUS_EXP,</if>
+            <if test="speedExp != null">SPEED_EXP,</if>
+            <if test="tmpExp != null">TMP_EXP,</if>
+            <if test="energyExp != null">ENERGY_EXP,</if>
+            <if test="ampExp != null">AMP_EXP,</if>
+            <if test="createdBy != null">CREATED_BY,</if>
+            <if test="createdTime != null">CREATED_TIME,</if>
+            <if test="updatedBy != null">UPDATED_BY,</if>
+            <if test="updatedTime != null">UPDATED_TIME,</if>
+            <if test="remark != null">REMARK,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="wsName != null">#{wsName},</if>
+            <if test="line != null">#{line},</if>
+            <if test="typeId != null">#{typeId},</if>
+            <if test="typeName != null">#{typeName},</if>
+            <if test="deviceCode != null">#{deviceCode},</if>
+            <if test="deviceName != null">#{deviceName},</if>
+            <if test="devicePath != null">#{devicePath},</if>
+            <if test="lengthExp != null">#{lengthExp},</if>
+            <if test="statusExp != null">#{statusExp},</if>
+            <if test="speedExp != null">#{speedExp},</if>
+            <if test="tmpExp != null">#{tmpExp},</if>
+            <if test="energyExp != null">#{energyExp},</if>
+            <if test="ampExp != null">#{ampExp},</if>
+            <if test="createdBy != null">#{createdBy},</if>
+            <if test="createdTime != null">#{createdTime},</if>
+            <if test="updatedBy != null">#{updatedBy},</if>
+            <if test="updatedTime != null">#{updatedTime},</if>
+            <if test="remark != null">#{remark},</if>
+        </trim>
+    </insert>
+
+    <update id="updateDyeingDevice" parameterType="DyeingDevice">
+        update DYEING_DEVICE
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="wsName != null">WS_NAME = #{wsName},</if>
+            <if test="line != null">LINE = #{line},</if>
+            <if test="typeId != null">TYPE_ID = #{typeId},</if>
+            <if test="typeName != null">TYPE_NAME = #{typeName},</if>
+            <if test="deviceCode != null">DEVICE_CODE = #{deviceCode},</if>
+            <if test="deviceName != null">DEVICE_NAME = #{deviceName},</if>
+            <if test="devicePath != null">DEVICE_PATH = #{devicePath},</if>
+            <if test="lengthExp != null">LENGTH_EXP = #{lengthExp},</if>
+            <if test="statusExp != null">STATUS_EXP = #{statusExp},</if>
+            <if test="speedExp != null">SPEED_EXP = #{speedExp},</if>
+            <if test="tmpExp != null">TMP_EXP = #{tmpExp},</if>
+            <if test="energyExp != null">ENERGY_EXP = #{energyExp},</if>
+            <if test="ampExp != null">AMP_EXP = #{ampExp},</if>
+            <if test="createdBy != null">CREATED_BY = #{createdBy},</if>
+            <if test="createdTime != null">CREATED_TIME = #{createdTime},</if>
+            <if test="updatedBy != null">UPDATED_BY = #{updatedBy},</if>
+            <if test="updatedTime != null">UPDATED_TIME = #{updatedTime},</if>
+            <if test="remark != null">REMARK = #{remark},</if>
+        </trim>
+        where DEVICE_ID = #{deviceId}
+    </update>
+
+    <delete id="deleteDyeingDeviceByDeviceId" parameterType="Long">
+        delete from DYEING_DEVICE where DEVICE_ID = #{deviceId}
+    </delete>
+
+    <delete id="deleteDyeingDeviceByDeviceIds" parameterType="String">
+        delete from DYEING_DEVICE where DEVICE_ID in
+        <foreach item="deviceId" collection="array" open="(" separator="," close=")">
+            #{deviceId}
+        </foreach>
+    </delete>
+</mapper>

+ 132 - 0
jjt-biz/src/main/resources/mapper/dyeing/DyeingHourAvgMapper.xml

@@ -0,0 +1,132 @@
+<?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.jjt.dyeing.mapper.DyeingHourAvgMapper">
+
+    <resultMap type="DyeingHourAvg" id="DyeingHourAvgResult">
+        <result property="id" column="ID"/>
+        <result property="dataDate" column="DATA_DATE"/>
+        <result property="hour" column="HOUR"/>
+        <result property="deviceId" column="DEVICE_ID"/>
+        <result property="online" column="ONLINE"/>
+        <result property="length" column="LENGTH"/>
+        <result property="tmp" column="TMP"/>
+        <result property="speed" column="SPEED"/>
+        <result property="createdBy" column="CREATED_BY"/>
+        <result property="createdTime" column="CREATED_TIME"/>
+        <result property="updatedBy" column="UPDATED_BY"/>
+        <result property="updatedTime" column="UPDATED_TIME"/>
+        <result property="remark" column="REMARK"/>
+    </resultMap>
+
+    <sql id="selectDyeingHourAvgVo">
+        select ID,
+               DATA_DATE,
+               HOUR,
+               DEVICE_ID,
+               ONLINE,
+               LENGTH,
+               TMP,
+               SPEED,
+               CREATED_BY,
+               CREATED_TIME,
+               UPDATED_BY,
+               UPDATED_TIME,
+               REMARK
+        from DYEING_HOUR_AVG
+    </sql>
+
+    <select id="selectDyeingHourAvgList" parameterType="DyeingHourAvg" resultMap="DyeingHourAvgResult">
+        <include refid="selectDyeingHourAvgVo"/>
+        <where>
+            <if test="dataDate != null ">and DATA_DATE = #{dataDate}</if>
+            <if test="hour != null ">and HOUR = #{hour}</if>
+            <if test="deviceId != null ">and DEVICE_ID = #{deviceId}</if>
+            <if test="online != null ">and ONLINE = #{online}</if>
+            <if test="length != null ">and LENGTH = #{length}</if>
+            <if test="tmp != null ">and TMP = #{tmp}</if>
+            <if test="speed != null ">and SPEED = #{speed}</if>
+            <if test="createdBy != null  and createdBy != ''">and CREATED_BY = #{createdBy}</if>
+            <if test="createdTime != null ">and CREATED_TIME = #{createdTime}</if>
+            <if test="updatedBy != null  and updatedBy != ''">and UPDATED_BY = #{updatedBy}</if>
+            <if test="updatedTime != null ">and UPDATED_TIME = #{updatedTime}</if>
+            <if test="remark != null  and remark != ''">and REMARK = #{remark}</if>
+        </where>
+    </select>
+
+    <select id="selectDyeingHourAvgById" parameterType="Long" resultMap="DyeingHourAvgResult">
+        <include refid="selectDyeingHourAvgVo"/>
+        where ID = #{id}
+    </select>
+
+    <insert id="insertDyeingHourAvg" parameterType="DyeingHourAvg">
+        insert into DYEING_HOUR_AVG
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="dataDate != null">DATA_DATE,</if>
+            <if test="hour != null">HOUR,</if>
+            <if test="deviceId != null">DEVICE_ID,</if>
+            <if test="online != null">ONLINE,</if>
+            <if test="length != null">LENGTH,</if>
+            <if test="tmp != null">TMP,</if>
+            <if test="speed != null">SPEED,</if>
+            <if test="createdBy != null">CREATED_BY,</if>
+            <if test="createdTime != null">CREATED_TIME,</if>
+            <if test="updatedBy != null">UPDATED_BY,</if>
+            <if test="updatedTime != null">UPDATED_TIME,</if>
+            <if test="remark != null">REMARK,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="dataDate != null">#{dataDate},</if>
+            <if test="hour != null">#{hour},</if>
+            <if test="deviceId != null">#{deviceId},</if>
+            <if test="online != null">#{online},</if>
+            <if test="length != null">#{length},</if>
+            <if test="tmp != null">#{tmp},</if>
+            <if test="speed != null">#{speed},</if>
+            <if test="createdBy != null">#{createdBy},</if>
+            <if test="createdTime != null">#{createdTime},</if>
+            <if test="updatedBy != null">#{updatedBy},</if>
+            <if test="updatedTime != null">#{updatedTime},</if>
+            <if test="remark != null">#{remark},</if>
+        </trim>
+    </insert>
+
+    <update id="updateDyeingHourAvg" parameterType="DyeingHourAvg">
+        update DYEING_HOUR_AVG
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="dataDate != null">DATA_DATE = #{dataDate},</if>
+            <if test="hour != null">HOUR = #{hour},</if>
+            <if test="deviceId != null">DEVICE_ID = #{deviceId},</if>
+            <if test="online != null">ONLINE = #{online},</if>
+            <if test="length != null">LENGTH = #{length},</if>
+            <if test="tmp != null">TMP = #{tmp},</if>
+            <if test="speed != null">SPEED = #{speed},</if>
+            <if test="createdBy != null">CREATED_BY = #{createdBy},</if>
+            <if test="createdTime != null">CREATED_TIME = #{createdTime},</if>
+            <if test="updatedBy != null">UPDATED_BY = #{updatedBy},</if>
+            <if test="updatedTime != null">UPDATED_TIME = #{updatedTime},</if>
+            <if test="remark != null">REMARK = #{remark},</if>
+        </trim>
+        where ID = #{id}
+    </update>
+
+    <delete id="deleteDyeingHourAvgById" parameterType="Long">
+        delete
+        from DYEING_HOUR_AVG
+        where ID = #{id}
+    </delete>
+
+    <delete id="deleteDyeingHourAvgByIds" parameterType="String">
+        delete from DYEING_HOUR_AVG where ID in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+    <delete id="deleteByHour">
+        delete
+        from DYEING_HOUR_AVG
+        where DATA_DATE = #{date}
+          and HOUR = #{hour}
+    </delete>
+</mapper>

+ 120 - 0
jjt-biz/src/main/resources/mapper/dyeing/DyeingHourEnergyMapper.xml

@@ -0,0 +1,120 @@
+<?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.jjt.dyeing.mapper.DyeingHourEnergyMapper">
+
+    <resultMap type="DyeingHourEnergy" id="DyeingHourEnergyResult">
+        <result property="id" column="ID"/>
+        <result property="dataDate" column="DATA_DATE"/>
+        <result property="hour" column="HOUR"/>
+        <result property="deviceId" column="DEVICE_ID"/>
+        <result property="energy" column="ENERGY"/>
+        <result property="amp" column="AMP"/>
+        <result property="createdBy" column="CREATED_BY"/>
+        <result property="createdTime" column="CREATED_TIME"/>
+        <result property="updatedBy" column="UPDATED_BY"/>
+        <result property="updatedTime" column="UPDATED_TIME"/>
+        <result property="remark" column="REMARK"/>
+    </resultMap>
+
+    <sql id="selectDyeingHourEnergyVo">
+        select ID,
+               DATA_DATE,
+               HOUR,
+               DEVICE_ID,
+               ENERGY,
+               AMP,
+               CREATED_BY,
+               CREATED_TIME,
+               UPDATED_BY,
+               UPDATED_TIME,
+               REMARK
+        from DYEING_HOUR_ENERGY
+    </sql>
+
+    <select id="selectDyeingHourEnergyList" parameterType="DyeingHourEnergy" resultMap="DyeingHourEnergyResult">
+        <include refid="selectDyeingHourEnergyVo"/>
+        <where>
+            <if test="dataDate != null ">and DATA_DATE = #{dataDate}</if>
+            <if test="hour != null ">and HOUR = #{hour}</if>
+            <if test="deviceId != null ">and DEVICE_ID = #{deviceId}</if>
+            <if test="energy != null ">and ENERGY = #{energy}</if>
+            <if test="amp != null ">and AMP = #{amp}</if>
+            <if test="createdBy != null  and createdBy != ''">and CREATED_BY = #{createdBy}</if>
+            <if test="createdTime != null ">and CREATED_TIME = #{createdTime}</if>
+            <if test="updatedBy != null  and updatedBy != ''">and UPDATED_BY = #{updatedBy}</if>
+            <if test="updatedTime != null ">and UPDATED_TIME = #{updatedTime}</if>
+            <if test="remark != null  and remark != ''">and REMARK = #{remark}</if>
+        </where>
+    </select>
+
+    <select id="selectDyeingHourEnergyById" parameterType="Long" resultMap="DyeingHourEnergyResult">
+        <include refid="selectDyeingHourEnergyVo"/>
+        where ID = #{id}
+    </select>
+
+    <insert id="insertDyeingHourEnergy" parameterType="DyeingHourEnergy">
+        insert into DYEING_HOUR_ENERGY
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="dataDate != null">DATA_DATE,</if>
+            <if test="hour != null">HOUR,</if>
+            <if test="deviceId != null">DEVICE_ID,</if>
+            <if test="energy != null">ENERGY,</if>
+            <if test="amp != null">AMP,</if>
+            <if test="createdBy != null">CREATED_BY,</if>
+            <if test="createdTime != null">CREATED_TIME,</if>
+            <if test="updatedBy != null">UPDATED_BY,</if>
+            <if test="updatedTime != null">UPDATED_TIME,</if>
+            <if test="remark != null">REMARK,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="dataDate != null">#{dataDate},</if>
+            <if test="hour != null">#{hour},</if>
+            <if test="deviceId != null">#{deviceId},</if>
+            <if test="energy != null">#{energy},</if>
+            <if test="amp != null">#{amp},</if>
+            <if test="createdBy != null">#{createdBy},</if>
+            <if test="createdTime != null">#{createdTime},</if>
+            <if test="updatedBy != null">#{updatedBy},</if>
+            <if test="updatedTime != null">#{updatedTime},</if>
+            <if test="remark != null">#{remark},</if>
+        </trim>
+    </insert>
+
+    <update id="updateDyeingHourEnergy" parameterType="DyeingHourEnergy">
+        update DYEING_HOUR_ENERGY
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="dataDate != null">DATA_DATE = #{dataDate},</if>
+            <if test="hour != null">HOUR = #{hour},</if>
+            <if test="deviceId != null">DEVICE_ID = #{deviceId},</if>
+            <if test="energy != null">ENERGY = #{energy},</if>
+            <if test="amp != null">AMP = #{amp},</if>
+            <if test="createdBy != null">CREATED_BY = #{createdBy},</if>
+            <if test="createdTime != null">CREATED_TIME = #{createdTime},</if>
+            <if test="updatedBy != null">UPDATED_BY = #{updatedBy},</if>
+            <if test="updatedTime != null">UPDATED_TIME = #{updatedTime},</if>
+            <if test="remark != null">REMARK = #{remark},</if>
+        </trim>
+        where ID = #{id}
+    </update>
+
+    <delete id="deleteDyeingHourEnergyById" parameterType="Long">
+        delete
+        from DYEING_HOUR_ENERGY
+        where ID = #{id}
+    </delete>
+
+    <delete id="deleteDyeingHourEnergyByIds" parameterType="String">
+        delete from DYEING_HOUR_ENERGY where ID in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+    <delete id="deleteByHour">
+        delete
+        from DYEING_HOUR_ENERGY
+        where DATA_DATE = #{date}
+          and HOUR = #{hour}
+    </delete>
+</mapper>