瀏覽代碼

水力模型相关 : 自来水泵原始数据采集, 水位预测逻辑编写

1037015548@qq.com 6 月之前
父節點
當前提交
2ad73bd3e8

+ 188 - 0
dc3-gateway/src/main/java/io/github/pnoker/gateway/bizmgr/KprZilaishuiLevelBizFun.java

@@ -0,0 +1,188 @@
+package io.github.pnoker.gateway.bizmgr;
+
+import com.alibaba.fastjson.JSONObject;
+import io.github.pnoker.gateway.comtool.TimeTool;
+import io.github.pnoker.gateway.dbdao.DBMgrProxy;
+import io.github.pnoker.gateway.dbdao.zilaishuiSource.service.ZilaishuiRealListService;
+import org.influxdb.dto.QueryResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.ObjectUtils;
+
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.stream.Collectors;
+
+/**
+ * @ClassName KprZilaishuiLevelBizFun
+ * @Description: TODO 市自来水水位预测
+ * @Author LX
+ * @Date 2024/12/11
+ * @Version V1.0
+ **/
+public class KprZilaishuiLevelBizFun {
+    private static final Logger log = LoggerFactory.getLogger(KprZilaishuiLevelBizFun.class);
+
+    private final static String mStrClassName = "KprZilaishuiLevelBizFun";
+    private final static String EMPTY_NULL = "NULL";
+
+    public static ZilaishuiRealListService getZilaishuiApi(){
+        return DBMgrProxy.getInstance().applyZilaishuiDbApi();
+    }
+    static DateTimeFormatter formater = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+    //TODO 初始化添加计算每个液位计站点每日的每小时液位量计算
+    public static void initWaterLevelReacordAll(String startFindTime){
+        //TODO ① 首先查询水厂设备配置信息
+        try {
+
+            System.out.println("计算小时液位开始时间:"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
+            System.out.println("计算小时液位起始时间:("+startFindTime+")进行中:......");
+            List<Map<String, Object>> configList = getZilaishuiApi().getWaterLevelCollectionConfigList(null);
+            if (!CollectionUtils.isEmpty(configList)) {
+                //TODO 按照设备分组
+                Map<Object, List<Map<String, Object>>> groupedData =
+                        configList.stream().collect(Collectors.groupingBy(item -> item.get("device_code")));
+                final CountDownLatch latch = new CountDownLatch(groupedData.keySet().size());
+
+                //TODO 外层循环组织机构
+                for (Object key:groupedData.keySet()){
+                    try{
+                        new Thread(() -> {
+                            //TODO 根据当前配置信息item 查询远通数据中的历史数据
+                            //TODO 首先查询当前水厂设备的从startFindTime之后到得到数据
+                            LocalDateTime startDateTime = LocalDateTime.parse(startFindTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+
+                            //TODO 需计算的循环天数
+                            Long days = 0L;
+                            days = Duration.between(startDateTime, LocalDateTime.now()).toDays();
+                            days+=1;
+
+                            //TODO 此循环天数每一天所查的是所有设备每小时数据合
+                            final CountDownLatch latch2 = new CountDownLatch(days.intValue());
+                            for(Long k = 0L;k<days;k++) {
+                                LocalDateTime newStartDateTime = startDateTime.minusDays(-k.intValue());
+                                String startDate = newStartDateTime.format(formater);
+                                String endDate = newStartDateTime.minusDays(-1).format(formater);
+                                try {
+                                    new Thread(() -> {
+
+                                        List<Map<String, Object>> deviceList = groupedData.get(key);
+
+                                        //TODO 循环获取该天该水厂每个设备数据
+
+                                        //TODO 查询当前天日期内每小时的设备数据
+                                        for (int i = 0; i < 24; i++) {
+                                            String startTime = newStartDateTime.withHour(i).format(formater);
+                                            //TODO 需要加个05分把endTime的整点数据查出来
+                                            String endTime = newStartDateTime.minusHours(-(i + 1)).withMinute(5).withSecond(0).format(formater);
+                                            //TODO 此循环计算该小时所有设备的用水量
+                                            for (Map<String, Object> item : deviceList) {
+                                                // 定义字符串日期时间的格式
+                                                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+                                                // 解析字符串以创建 LocalDateTime 实例
+                                                LocalDateTime dateTime = LocalDateTime.parse(endTime, formatter);
+                                                Integer itemCount = getZilaishuiApi().getTabWaterHistoryCount(
+                                                        " AND TAG_CODE = '" + item.get("collcation_tag") + "' " +
+                                                                " and QCQUISITION_TIME >= to_date('" + startDate + "', 'yyyy-mm-dd hh24:mi:ss')" +
+                                                                " and QCQUISITION_TIME <= to_date('" + endDate + "', 'yyyy-mm-dd hh24:mi:ss')" +
+                                                                " AND ABS(" +
+                                                                "        (QCQUISITION_TIME - TRUNC(QCQUISITION_TIME, 'HH')) * 24 * 60 " +
+                                                                "      ) <= 5");//查询 -- 采集时间接近整点,误差在5分钟内
+                                                if (itemCount != null && itemCount > 0) {
+                                                    List<Map<String, Object>> tapWaterHistoryList = getZilaishuiApi().getPageZILAISHUI_HISTORY2(itemCount, 0,
+                                                            " AND TAG_CODE = '" + item.get("collcation_tag") + "' " +
+                                                                    " and QCQUISITION_TIME >= to_date('" + startTime + "', 'yyyy-mm-dd hh24:mi:ss')" +
+                                                                    " and QCQUISITION_TIME <= to_date('" + endTime + "', 'yyyy-mm-dd hh24:mi:ss')" +
+                                                                    " AND ABS( " +
+                                                                    "        (QCQUISITION_TIME - TRUNC(QCQUISITION_TIME, 'HH')) * 24 * 60 " +
+                                                                    "      ) <= 5 " +
+                                                                    " order by QCQUISITION_TIME");
+                                                    //TODO 直接插入即可 查询已经筛选出两条了
+                                                    if (!CollectionUtils.isEmpty(tapWaterHistoryList) && tapWaterHistoryList.size() > 1) {
+                                                        //TODO 数据库操作
+                                                        for (Map<String,Object> mapEntity:tapWaterHistoryList) {
+                                                            Map<String, Object> recordAllEntity = new HashMap<>();//需要添加的实体数据
+                                                            recordAllEntity.put("device_code", groupedData.get(key).get(0).get("device_code"));
+                                                            recordAllEntity.put("value", mapEntity.get("VAL"));
+                                                            recordAllEntity.put("time", LocalDateTime.parse(mapEntity.get("QCQUISITION_TIME").toString(), formatter)
+                                                                    .withMinute(0).withSecond(0).format(formatter));//采集时间(小时的最后时间)
+                                                            recordAllEntity.put("value_tag", "level");
+                                                            List<Map<String, Object>> queryLevelRecord = getZilaishuiApi().getWaterLevelRecordAllList(1, 0,
+                                                                    " WHERE device_code = '" + recordAllEntity.get("device_code")
+                                                                            + "' AND time = '" + recordAllEntity.get("time") + "' AND value_tag = '" + recordAllEntity.get("value_tag") + "'");
+                                                            if (CollectionUtils.isEmpty(queryLevelRecord)) {
+                                                                //TODO 说明不存在,进行插入
+                                                                if(!ObjectUtils.isEmpty(recordAllEntity.get("value"))) {
+                                                                    int insertCode = getZilaishuiApi().insertWaterLevelRecordAll(" (" +
+                                                                            "'" + recordAllEntity.get("device_code") + "'," +
+                                                                            "'" + recordAllEntity.get("value") + "'," +
+                                                                            "'" + recordAllEntity.get("value_tag") + "'," +
+                                                                            "'" + recordAllEntity.get("time") + "'" +
+                                                                            ") ");
+                                                                    if (insertCode < 0) {
+                                                                        log.error(String.format("Batch insertWaterLevelRecordAll 未成功:{%s} ",
+                                                                                JSONObject.toJSON(recordAllEntity)));
+                                                                    }
+                                                                }
+                                                            }else{
+                                                                //TODO 说明存在,进行修改
+                                                                if(!ObjectUtils.isEmpty(recordAllEntity.get("value"))) {
+                                                                    int updateCode = getZilaishuiApi().updateWaterLevelRecordAll(String.valueOf(recordAllEntity.get("value"))," WHERE " +
+                                                                            "(" +
+                                                                            " device_code = '" + recordAllEntity.get("device_code") + "' and" +
+                                                                            " \"time\" = '" + recordAllEntity.get("time") + "' and" +
+                                                                            " value_tag = '" + recordAllEntity.get("value_tag") + "'" +
+                                                                            ") ");
+                                                                    if (updateCode < 0) {
+                                                                        log.error(String.format("Batch updateWaterLevelRecordAll 未成功:{%s} ",
+                                                                                JSONObject.toJSON(recordAllEntity)));
+                                                                    }
+                                                                }
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                        latch2.countDown();
+
+                                    }).start();
+                                }catch(Exception ex){
+
+                                }
+                            }
+                            try {
+                                latch2.await();
+                            }catch(Exception ex){
+
+                            }
+                            latch.countDown();
+
+                        }).start();
+                    }catch(Exception ex){
+                        log.error(String.format("Batch" +
+                                        " initWaterReacordAll ERROR:{%s} "
+                                , ex.getLocalizedMessage()));
+                    }
+                }
+                latch.await();
+                System.out.println("计算小时液位检查机制("+startFindTime+")结束时间:"+TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
+            }
+        }catch(Exception ex){
+            log.error(String.format("Batch initWaterCollecationReacordAll ERROR:{%s} "
+                    , ex.getLocalizedMessage()));
+        }
+    }
+    public static void insertDailyData(){
+        KprZilaishuiLevelBizFun.getZilaishuiApi().insertDailyData();
+    }
+    public static void insertForecastData(){
+        KprZilaishuiLevelBizFun.getZilaishuiApi().insertForecastData();
+    }
+}

+ 167 - 0
dc3-gateway/src/main/java/io/github/pnoker/gateway/bizmgr/KprZilaishuiPumpBizFun.java

@@ -0,0 +1,167 @@
+package io.github.pnoker.gateway.bizmgr;
+
+import com.alibaba.fastjson.JSONObject;
+import io.github.pnoker.gateway.comtool.TimeTool;
+import io.github.pnoker.gateway.dbdao.DBMgrProxy;
+import io.github.pnoker.gateway.dbdao.zilaishuiSource.service.ZilaishuiRealListService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.ObjectUtils;
+
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
+import java.util.stream.Collectors;
+
+/**
+ * @ClassName KprZilaishuiPumpBizFun
+ * @Description: TODO 自来水泵组优化
+ * @Author LX
+ * @Date 2024/12/12
+ * @Version V1.0
+ **/
+public class KprZilaishuiPumpBizFun {
+    private static final Logger log = LoggerFactory.getLogger(KprZilaishuiPumpBizFun.class);
+
+    private final static String mStrClassName = "KprZilaishuiPumpBizFun";
+    private final static String EMPTY_NULL = "NULL";
+
+    public static ZilaishuiRealListService getZilaishuiApi(){
+        return DBMgrProxy.getInstance().applyZilaishuiDbApi();
+    }
+
+    static DateTimeFormatter formater = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+    //TODO 初始化添加计算泵每日的小时数据
+    public static void initWaterPumpReacordAll(String startFindTime){
+        //TODO ① 首先查询水厂设备配置信息
+        try {
+
+            System.out.println("添加小时泵数据开始时间:"+ TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
+            System.out.println("添加小时泵数据起始时间:("+startFindTime+")进行中:......");
+            List<Map<String, Object>> configList = getZilaishuiApi().getWaterPumpCollectionConfigList(null);
+            if (!CollectionUtils.isEmpty(configList)) {
+                //TODO 按照设备分组
+                Map<Object, List<Map<String, Object>>> groupedData =
+                        configList.stream().collect(Collectors.groupingBy(item -> item.get("device_code")));
+                final CountDownLatch latch = new CountDownLatch(groupedData.keySet().size());
+
+                //TODO 外层循环组织机构
+                for (Object key:groupedData.keySet()){
+                    try{
+                        new Thread(() -> {
+                            //TODO 根据当前配置信息item 查询远通数据中的历史数据
+                            //TODO 首先查询当前水厂设备的从startFindTime之后到得到数据
+                            LocalDateTime startDateTime = LocalDateTime.parse(startFindTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+
+                            //TODO 需计算的循环天数
+                            Long days = 0L;
+                            days = Duration.between(startDateTime, LocalDateTime.now()).toDays();
+                            days+=1;
+
+                            //TODO 此循环天数每一天所查的是所有设备每小时数据合
+                            final CountDownLatch latch2 = new CountDownLatch(days.intValue());
+                            for(Long k = 0L;k<days;k++) {
+                                LocalDateTime newStartDateTime = startDateTime.minusDays(-k.intValue());
+                                String startDate = newStartDateTime.format(formater);
+                                String endDate = newStartDateTime.minusDays(-1).format(formater);
+                                try {
+                                    new Thread(() -> {
+
+                                        List<Map<String, Object>> deviceList = groupedData.get(key);
+
+                                        //TODO 循环获取该天该水厂每个设备数据
+
+                                        //TODO 查询当前天日期内每小时的设备数据
+                                        for (int i = 0; i < 24; i++) {
+                                            String startTime = newStartDateTime.withHour(i).format(formater);
+                                            //TODO 需要加个05分把endTime的整点数据查出来
+                                            String endTime = newStartDateTime.minusHours(-(i + 1)).withMinute(5).withSecond(0).format(formater);
+                                            //TODO 此循环计算该小时所有设备的泵数据
+                                            for (Map<String, Object> item : deviceList) {
+                                                // 定义字符串日期时间的格式
+                                                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+                                                // 解析字符串以创建 LocalDateTime 实例
+                                                LocalDateTime dateTime = LocalDateTime.parse(endTime, formatter);
+                                                Integer itemCount = getZilaishuiApi().getTabWaterHistoryCount(
+                                                        " AND TAG_CODE = '" + item.get("collcation_tag") + "' " +
+                                                                " and QCQUISITION_TIME >= to_date('" + startDate + "', 'yyyy-mm-dd hh24:mi:ss')" +
+                                                                " and QCQUISITION_TIME <= to_date('" + endDate + "', 'yyyy-mm-dd hh24:mi:ss')" +
+                                                                " AND ABS(" +
+                                                                "        (QCQUISITION_TIME - TRUNC(QCQUISITION_TIME, 'HH')) * 24 * 60 " +
+                                                                "      ) <= 5");//查询 -- 采集时间接近整点,误差在5分钟内
+                                                if (itemCount != null && itemCount > 0) {
+                                                    List<Map<String, Object>> tapWaterHistoryList = getZilaishuiApi().getPageZILAISHUI_HISTORY2(itemCount, 0,
+                                                            " AND TAG_CODE = '" + item.get("collcation_tag") + "' " +
+                                                                    " and QCQUISITION_TIME >= to_date('" + startTime + "', 'yyyy-mm-dd hh24:mi:ss')" +
+                                                                    " and QCQUISITION_TIME <= to_date('" + endTime + "', 'yyyy-mm-dd hh24:mi:ss')" +
+                                                                    " AND ABS( " +
+                                                                    "        (QCQUISITION_TIME - TRUNC(QCQUISITION_TIME, 'HH')) * 24 * 60 " +
+                                                                    "      ) <= 5 " +
+                                                                    " order by QCQUISITION_TIME");
+                                                    //TODO 这里需要注意泵数据的采集配置表设备号可能有多个,因此,要判断对应的standard_code做对应处理
+                                                    if (!CollectionUtils.isEmpty(tapWaterHistoryList) && tapWaterHistoryList.size() > 1) {
+                                                        //TODO 数据库操作
+                                                        for (Map<String,Object> mapEntity:tapWaterHistoryList) {
+                                                            Map<String, Object> recordAllEntity = new HashMap<>();//需要添加的实体数据
+                                                            recordAllEntity.put("device_code", groupedData.get(key).get(0).get("device_code"));
+                                                            recordAllEntity.put("time", LocalDateTime.parse(mapEntity.get("QCQUISITION_TIME").toString(), formatter)
+                                                                    .withMinute(0).withSecond(0).format(formatter));//采集时间(小时的最后时间)
+                                                            if(item.get("standard_code").equals("active_energy")){
+                                                                recordAllEntity.put("active_energy",mapEntity.get("VAL"));
+                                                            }
+                                                            if(item.get("standard_code").equals("startup_state")){
+                                                                recordAllEntity.put("startup_state",mapEntity.get("VAL"));
+                                                            }
+                                                            if(item.get("standard_code").equals("phase_a_current")){
+                                                                if(ObjectUtils.isEmpty(mapEntity.get("VAL"))||"0".equals(mapEntity.get("VAL").toString())) {
+                                                                    recordAllEntity.put("startup_state", 0);
+                                                                }else{
+                                                                    recordAllEntity.put("startup_state", 1);
+                                                                }
+                                                            }
+                                                            //TODO 直接调用插入或者新增方法
+                                                            int insertCode = KprZilaishuiPumpBizFun.getZilaishuiApi().insertOrUpdateWaterPumpRecordAll(recordAllEntity);
+                                                            if (insertCode < 0) {
+                                                                log.error(String.format("Batch insertOrUpdateWaterPumpRecordAll 未成功:{%s} ",
+                                                                        JSONObject.toJSON(recordAllEntity)));
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                        latch2.countDown();
+
+                                    }).start();
+                                }catch(Exception ex){
+
+                                }
+                            }
+                            try {
+                                latch2.await();
+                            }catch(Exception ex){
+
+                            }
+                            latch.countDown();
+
+                        }).start();
+                    }catch(Exception ex){
+                        log.error(String.format("Batch" +
+                                        " initWaterReacordAll ERROR:{%s} "
+                                , ex.getLocalizedMessage()));
+                    }
+                }
+                latch.await();
+                System.out.println("添加小时泵数据检查机制("+startFindTime+")结束时间:"+TimeTool.convertUTC2DateStr(TimeTool.getCurMsUTC(),TimeTool.TIMESTAMP_FORMAT));
+            }
+        }catch(Exception ex){
+            log.error(String.format("Batch initWaterCollecationReacordAll ERROR:{%s} "
+                    , ex.getLocalizedMessage()));
+        }
+    }
+}

+ 225 - 153
dc3-gateway/src/main/java/io/github/pnoker/gateway/comtool/ScheduleTaskMgr.java

@@ -2,10 +2,7 @@ package io.github.pnoker.gateway.comtool;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import io.github.pnoker.gateway.bizmgr.KprDangyangWaterBizFun;
-import io.github.pnoker.gateway.bizmgr.KprJiangjinAimWaterBizFun;
-import io.github.pnoker.gateway.bizmgr.KprJiangjinWaterBizfun;
-import io.github.pnoker.gateway.bizmgr.KprZilaishuiWaterBizFun;
+import io.github.pnoker.gateway.bizmgr.*;
 import io.github.pnoker.gateway.dbdao.DBMgrProxy;
 import io.github.pnoker.gateway.utils.InfulxDbUtil;
 import io.github.pnoker.gateway.utils.InfulxJiangjinDbUtil;
@@ -26,6 +23,7 @@ import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.format.DateTimeFormatter;
+import java.time.temporal.TemporalAdjusters;
 import java.util.Timer;
 import java.util.TimerTask;
 import java.util.concurrent.Executors;
@@ -221,44 +219,191 @@ public class ScheduleTaskMgr {
 
     //TODO 江津相关
 
-    @Resource(name = "infulxJiangjinDbUtil")
-    private InfulxJiangjinDbUtil infulxJiangjinDbUtil;
+//    @Resource(name = "infulxJiangjinDbUtil")
+//    private InfulxJiangjinDbUtil infulxJiangjinDbUtil;
+//
+//    //TODO 启动后5秒初始化所有配置参数
+//    @PostConstruct
+//    public void initJiangjinApplication(){
+//        new Timer().schedule(new TimerTask() {
+//            @Override
+//            public void run() {
+//                try {
+//                    infulxJiangjinDbUtil.initInfluxDataBase();
+//                    KprJiangjinWaterBizfun.infulxJiangjinDbUtil = infulxJiangjinDbUtil;
+//                }catch(Exception ex){
+//                    log.error("江津启动时初始化配置参数失败:"+ex.getLocalizedMessage());
+//                }
+//            }
+//        },5000);
+//    }
+//
+//    @PostConstruct
+//    public void initJiangjinHisData(){
+//        new Timer().schedule(new TimerTask() {
+//            @Override
+//            public void run() {
+//                try {
+//                    KprJiangjinWaterBizfun.InitRealDb();
+////                    KprJiangjinWaterBizfun.InitDeviceFrequency();
+//                }catch(Exception ex){
+//
+//                }
+//            }
+//        },7000,60000);
+//        //TODO 启动时同步当前月一号到当前时间的所有历史数据
+//        new Timer().schedule(new TimerTask() {
+//            @Override
+//            public void run() {
+//                try {
+//                    KprJiangjinWaterBizfun.initHistoryDb(LocalDate.now().withDayOfMonth(1).atStartOfDay());
+//                }catch(Exception ex){
+//
+//                }
+//            }
+//        },8000);
+//    }
+//
+//    //TODO 每分钟的第五秒执行
+//    @Scheduled(cron = "5 * * * * ?")
+//    public void executeTask() {
+//        KprJiangjinWaterBizfun.InitRealDb();
+//    }
+//
+//    //TODO 每天凌晨1点执行前一天的
+//    @Scheduled(cron = "0 0 1 * * ?")
+//    public void executeHistoryTask() {
+//        //TODO 执行前一天的数据到当前
+//        KprJiangjinWaterBizfun.initHistoryDb(LocalDate.now().minusDays(1).atStartOfDay());
+//    }
+//
+//    //TODO 江津水量预测相关
+//    //每天每个整点的5分
+//    @Scheduled(cron = "0 5 * * * *")
+//    public void executeRecord() {
+//        String formattedDateTime = LocalDate.now().minusDays(1)
+//                .atStartOfDay()
+//                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+//        KprJiangjinAimWaterBizFun.initTapWaterData(formattedDateTime);
+//    }
+//    //每天每个整点的5分
+//    @Scheduled(cron = "0 10 * * * *")
+//    public void executeRecordAll() {
+//        String formattedDateTime = LocalDate.now().minusDays(1)
+//                .atStartOfDay()
+//                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+//        KprJiangjinAimWaterBizFun.initWaterCollecationReacordAll(formattedDateTime);
+//    }
+//    //TODO 每天每小时的21分执行预测当前月日小时数据
+//    @Scheduled(cron = "0 21 * * * *")
+//    public void executeTbMHourWaterNow() {
+//        String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
+////        KprJiangjinAimWaterBizFun.insertYuceHourAddData(time);
+//        KprJiangjinAimWaterBizFun.insertYuceHourDataScheduled(time);
+//    }
+//    //TODO 启动时执行一次
+//    @PostConstruct
+//    public void initExecuteRecordAndAll(){
+//        String formattedDateTime = LocalDate.now().minusDays(1)
+//                .atStartOfDay()
+//                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+//        Timer timer = new Timer();
+//        // 创建定时器任务
+//        TimerTask timerTask = new TimerTask() {
+//            @Override
+//            public void run() {
+//                KprJiangjinAimWaterBizFun.initTapWaterData(formattedDateTime);
+//            }
+//        };
+//        timer.schedule(timerTask, 10000); // 10秒后执行一次
+//        Timer timer1 = new Timer();
+//        // 创建定时器任务
+//        TimerTask timerTask1 = new TimerTask() {
+//            @Override
+//            public void run() {
+//                KprJiangjinAimWaterBizFun.initWaterCollecationReacordAll(formattedDateTime);
+//            }
+//        };
+//        timer1.schedule(timerTask1, 10000); // 10秒后执行一次
+//    }
+//
+//    @PostConstruct
+//    public void initOneTapWater(){
+//        Timer timer = new Timer();
+//        // 创建定时器任务
+//        TimerTask timerTask = new TimerTask() {
+//            @Override
+//            public void run() {
+//                KprJiangjinAimWaterBizFun.initTapWaterData("2023-11-01 00:00:00");
+//            }
+//        };
+//        timer.schedule(timerTask, 10000); // 10秒后执行一次
+//    }
+//
+//    @PostConstruct
+//    public void initWaterRecordAll(){
+//        Timer timer = new Timer();
+//        TimerTask timerTask1 = new TimerTask() {
+//            @Override
+//            public void run() {
+//                KprJiangjinAimWaterBizFun.initWaterCollecationReacordAll("2023-11-01 00:00:00");
+//            }
+//        };
+//        timer.schedule(timerTask1,11000);//11秒后执行一次
+//    }
+//    @PostConstruct
+//    public void initWaterHour(){
+//        Timer timer = new Timer();
+//        TimerTask timerTask1 = new TimerTask() {
+//            @Override
+//            public void run() {
+//                String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
+//                KprJiangjinAimWaterBizFun.insertYuceHourDataScheduled(time);
+//            }
+//        };
+//        timer.schedule(timerTask1,9000);//9秒后执行一次
+//    }
+
+
+    /**
+     * TODO 自来水相关
+     */
+    @Resource(name = "infulxZilaishuiDbUtil")
+    private InfulxZilaishuiDbUtil infulxZilaishuiDbUtil;
 
     //TODO 启动后5秒初始化所有配置参数
     @PostConstruct
-    public void initJiangjinApplication(){
+    public void initZilaishuiApplication(){
         new Timer().schedule(new TimerTask() {
             @Override
             public void run() {
                 try {
-                    infulxJiangjinDbUtil.initInfluxDataBase();
-                    KprJiangjinWaterBizfun.infulxJiangjinDbUtil = infulxJiangjinDbUtil;
+                    infulxZilaishuiDbUtil.initInfluxDataBase();
+                    KprZilaishuiWaterBizFun.infulxZilaishuiDbUtil= infulxZilaishuiDbUtil;
                 }catch(Exception ex){
-                    log.error("江津启动时初始化配置参数失败:"+ex.getLocalizedMessage());
+                    log.error("自来水启动时初始化配置参数失败:"+ex.getLocalizedMessage());
                 }
             }
         },5000);
     }
 
     @PostConstruct
-    public void initJiangjinHisData(){
+    public void initZilaishuiHisData(){
+        //TODO 启动时同步当前月一号到当前时间的所有历史数据
         new Timer().schedule(new TimerTask() {
             @Override
             public void run() {
                 try {
-                    KprJiangjinWaterBizfun.InitRealDb();
-//                    KprJiangjinWaterBizfun.InitDeviceFrequency();
+                    KprZilaishuiWaterBizFun.initHistoryDb(LocalDate.now().withDayOfMonth(1).atStartOfDay());
                 }catch(Exception ex){
 
                 }
             }
-        },7000,60000);
-        //TODO 启动时同步当前月一号到当前时间的所有历史数据
+        },7000);
         new Timer().schedule(new TimerTask() {
             @Override
             public void run() {
                 try {
-                    KprJiangjinWaterBizfun.initHistoryDb(LocalDate.now().withDayOfMonth(1).atStartOfDay());
                 }catch(Exception ex){
 
                 }
@@ -266,169 +411,96 @@ public class ScheduleTaskMgr {
         },8000);
     }
 
-    //TODO 每分钟的第五秒执行
-    @Scheduled(cron = "5 * * * * ?")
-    public void executeTask() {
-        KprJiangjinWaterBizfun.InitRealDb();
+    //TODO 每小时的第 0, 5, 10, 15, ..., 55 分钟执行一次
+    @Scheduled(cron = "0 0/5 * * * ?")
+    public void executeZilaishuiTask() {
+        KprZilaishuiWaterBizFun.initHistoryDb(LocalDateTime.now()
+                .withMinute(0)
+                .withSecond(0)
+                .withNano(0));
     }
 
     //TODO 每天凌晨1点执行前一天的
     @Scheduled(cron = "0 0 1 * * ?")
-    public void executeHistoryTask() {
+    public void executeZilaishuiHistoryTask() {
         //TODO 执行前一天的数据到当前
-        KprJiangjinWaterBizfun.initHistoryDb(LocalDate.now().minusDays(1).atStartOfDay());
-    }
-
-    //TODO 江津水量预测相关
-    //每天每个整点的5分
-    @Scheduled(cron = "0 5 * * * *")
-    public void executeRecord() {
-        String formattedDateTime = LocalDate.now().minusDays(1)
-                .atStartOfDay()
-                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
-        KprJiangjinAimWaterBizFun.initTapWaterData(formattedDateTime);
-    }
-    //每天每个整点的5分
-    @Scheduled(cron = "0 10 * * * *")
-    public void executeRecordAll() {
-        String formattedDateTime = LocalDate.now().minusDays(1)
-                .atStartOfDay()
-                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
-        KprJiangjinAimWaterBizFun.initWaterCollecationReacordAll(formattedDateTime);
-    }
-    //TODO 每天每小时的21分执行预测当前月日小时数据
-    @Scheduled(cron = "0 21 * * * *")
-    public void executeTbMHourWaterNow() {
-        String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
-//        KprJiangjinAimWaterBizFun.insertYuceHourAddData(time);
-        KprJiangjinAimWaterBizFun.insertYuceHourDataScheduled(time);
+        KprZilaishuiWaterBizFun.initHistoryDb(LocalDate.now()
+                .minusDays(1)
+                .atStartOfDay());
     }
-    //TODO 启动时执行一次
+    //TODO 市自来水水位预测相关
     @PostConstruct
-    public void initExecuteRecordAndAll(){
-        String formattedDateTime = LocalDate.now().minusDays(1)
-                .atStartOfDay()
-                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
-        Timer timer = new Timer();
-        // 创建定时器任务
-        TimerTask timerTask = new TimerTask() {
+    public void initWaterCollecationReacordAll(){
+        new Timer().schedule(new TimerTask() {
             @Override
             public void run() {
-                KprJiangjinAimWaterBizFun.initTapWaterData(formattedDateTime);
+                LocalDateTime firstDayOfLastMonth = LocalDateTime.now()
+                        .minusMonths(1)
+                        .with(TemporalAdjusters.firstDayOfMonth())
+                        .withHour(0)
+                        .withMinute(0)
+                        .withSecond(0)
+                        .withNano(0);//上个月0点
+
+                String formattedDate = firstDayOfLastMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+                KprZilaishuiLevelBizFun.initWaterLevelReacordAll(formattedDate);
             }
-        };
-        timer.schedule(timerTask, 10000); // 10秒后执行一次
-        Timer timer1 = new Timer();
-        // 创建定时器任务
-        TimerTask timerTask1 = new TimerTask() {
+        },5000);
+    }
+    //TODO 每小时的10分执行原始小时液位数据计算
+    @Scheduled(cron = "0 10 * * * *")
+    public void initHourWaterCollecationReacordAll(){
+        new Timer().schedule(new TimerTask() {
             @Override
             public void run() {
-                KprJiangjinAimWaterBizFun.initWaterCollecationReacordAll(formattedDateTime);
+                String formattedDate = LocalDate.now().atStartOfDay().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+                KprZilaishuiLevelBizFun.initWaterLevelReacordAll(formattedDate);
             }
-        };
-        timer1.schedule(timerTask1, 10000); // 10秒后执行一次
+        },5000);
     }
-
-    @PostConstruct
-    public void initOneTapWater(){
-        Timer timer = new Timer();
-        // 创建定时器任务
-        TimerTask timerTask = new TimerTask() {
+    //TODO 每小时的10分执行原始小时液位数据计算
+    @Scheduled(cron = "0 15 * * * *")
+    public void initYuceLevel(){
+        new Timer().schedule(new TimerTask() {
             @Override
             public void run() {
-                KprJiangjinAimWaterBizFun.initTapWaterData("2023-11-01 00:00:00");
+                KprZilaishuiLevelBizFun.insertDailyData();
+                KprZilaishuiLevelBizFun.insertForecastData();
             }
-        };
-        timer.schedule(timerTask, 10000); // 10秒后执行一次
+        },5000);
     }
 
+    //TODO 市自来水泵数据采集
     @PostConstruct
-    public void initWaterRecordAll(){
-        Timer timer = new Timer();
-        TimerTask timerTask1 = new TimerTask() {
+    public void initPumpRecordAll(){
+        new Timer().schedule(new TimerTask() {
             @Override
             public void run() {
-                KprJiangjinAimWaterBizFun.initWaterCollecationReacordAll("2023-11-01 00:00:00");
+                //当前时间到去年对应月份1号0点开始
+                LocalDateTime firstDayOfLastMonth = LocalDateTime.now()
+                        .minusYears(1)
+                        .with(TemporalAdjusters.firstDayOfMonth())
+                        .withHour(0)
+                        .withMinute(0)
+                        .withSecond(0)
+                        .withNano(0);//上个月0点
+                String formattedDate = firstDayOfLastMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+                KprZilaishuiPumpBizFun.initWaterPumpReacordAll(formattedDate);
             }
-        };
-        timer.schedule(timerTask1,11000);//11秒后执行一次
+        },5000);
     }
-    @PostConstruct
-    public void initWaterHour(){
-        Timer timer = new Timer();
-        TimerTask timerTask1 = new TimerTask() {
+
+    //TODO 每小时的10分执行原始小时泵数据计算
+    @Scheduled(cron = "0 10 * * * *")
+    public void checkPumpRecordAll(){
+        new Timer().schedule(new TimerTask() {
             @Override
             public void run() {
-                String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
-                KprJiangjinAimWaterBizFun.insertYuceHourDataScheduled(time);
+                //当前时间到今天的0点开始
+                LocalDateTime firstDayOfLastMonth = LocalDate.now().atStartOfDay();//上个月0点
+                String formattedDate = firstDayOfLastMonth.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
+                KprZilaishuiPumpBizFun.initWaterPumpReacordAll(formattedDate);
             }
-        };
-        timer.schedule(timerTask1,9000);//9秒后执行一次
+        },5000);
     }
-
-
-//    /**
-//     * TODO 自来水相关
-//     */
-//    @Resource(name = "infulxZilaishuiDbUtil")
-//    private InfulxZilaishuiDbUtil infulxZilaishuiDbUtil;
-//
-//    //TODO 启动后5秒初始化所有配置参数
-//    @PostConstruct
-//    public void initZilaishuiApplication(){
-//        new Timer().schedule(new TimerTask() {
-//            @Override
-//            public void run() {
-//                try {
-//                    infulxZilaishuiDbUtil.initInfluxDataBase();
-//                    KprZilaishuiWaterBizFun.infulxZilaishuiDbUtil= infulxZilaishuiDbUtil;
-//                }catch(Exception ex){
-//                    log.error("自来水启动时初始化配置参数失败:"+ex.getLocalizedMessage());
-//                }
-//            }
-//        },5000);
-//    }
-//
-//    @PostConstruct
-//    public void initZilaishuiHisData(){
-//        //TODO 启动时同步当前月一号到当前时间的所有历史数据
-//        new Timer().schedule(new TimerTask() {
-//            @Override
-//            public void run() {
-//                try {
-//                    KprZilaishuiWaterBizFun.initHistoryDb(LocalDate.now().withDayOfMonth(1).atStartOfDay());
-//                }catch(Exception ex){
-//
-//                }
-//            }
-//        },7000);
-//        new Timer().schedule(new TimerTask() {
-//            @Override
-//            public void run() {
-//                try {
-//                }catch(Exception ex){
-//
-//                }
-//            }
-//        },8000);
-//    }
-//
-//    //TODO 每小时的第 0, 5, 10, 15, ..., 55 分钟执行一次
-//    @Scheduled(cron = "0 0/5 * * * ?")
-//    public void executeZilaishuiTask() {
-//        KprZilaishuiWaterBizFun.initHistoryDb(LocalDateTime.now()
-//                .withMinute(0)
-//                .withSecond(0)
-//                .withNano(0));
-//    }
-//
-//    //TODO 每天凌晨1点执行前一天的
-//    @Scheduled(cron = "0 0 1 * * ?")
-//    public void executeZilaishuiHistoryTask() {
-//        //TODO 执行前一天的数据到当前
-//        KprZilaishuiWaterBizFun.initHistoryDb(LocalDate.now()
-//                .minusDays(1)
-//                .atStartOfDay());
-//    }
-
 }

+ 106 - 0
dc3-gateway/src/main/java/io/github/pnoker/gateway/config/Child2SourceConfiguration.java

@@ -0,0 +1,106 @@
+package io.github.pnoker.gateway.config;
+
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+
+import javax.annotation.PostConstruct;
+import javax.sql.DataSource;
+
+@Configuration
+@MapperScan(basePackages = "io.github.pnoker.gateway.dbdao.mapper", sqlSessionTemplateRef = "child2SqlSessionTemplate")
+public class Child2SourceConfiguration {
+    @Value("${spring.datasource.child2pg.driver-class-name:}")
+    private String driveClass = "org.postgresql.Driver";
+
+    @Value("${spring.datasource.child2pg.jdbc-url:}")
+    private String url = "";
+
+    @Value("${spring.datasource.child2pg.username:}")
+    private String username = "";
+
+    @Value("${spring.datasource.child2pg.password:}")
+    private String password = "";
+
+    @Value("${spring.datasource.data.maximum-pool-size:200}")
+    private Integer maxPoolSize;
+
+    @Value("${spring.datasource.data.minimum-idle:1}")
+    private Integer minIdle;
+
+    @Value("${spring.datasource.data.connection-test-query:}")
+    private String connectionTestQuery;
+
+    @Value("${spring.datasource.data.max-lifetime:120000}")
+    private Long maxLifetime;
+
+    @Value("${spring.datasource.data.idle-timeout:30000}")
+    private Long idleTimeout;
+
+    @Value("${spring.datasource.data.connection-timeout:30000}")
+    private Long connectionTimeout;
+
+    @Value("${spring.datasource.data.validation-timeout:30000}")
+    private Long validTimeout;
+
+    @Bean(name = "child2Datasource")
+    //@ConfigurationProperties(prefix = "spring.datasource.data")
+    public DataSource mainDataSource() {
+        return new HikariDataSource(getConfig());
+        //return DataSourceBuilder.create().build();
+        //Spring Boot 2.x默认使用HikariCP
+    }
+
+    private HikariConfig getConfig() {
+        HikariConfig hikariConfig = new HikariConfig();
+        hikariConfig.setDriverClassName(driveClass);
+        hikariConfig.setJdbcUrl(url);
+        hikariConfig.setUsername(username);
+        hikariConfig.setPassword(password);
+
+        hikariConfig.setMaximumPoolSize(maxPoolSize);
+        hikariConfig.setMinimumIdle(minIdle);
+        hikariConfig.setConnectionTestQuery(connectionTestQuery);
+        hikariConfig.setMaxLifetime(maxLifetime);
+        hikariConfig.setIdleTimeout(idleTimeout);
+        hikariConfig.setConnectionTimeout(connectionTimeout);
+        hikariConfig.setValidationTimeout(validTimeout);
+        return hikariConfig;
+    }
+
+    @Bean("child2SqlSessionFactory")
+    public SqlSessionFactory child2SqlSessionFactoryBean(@Qualifier("child2Datasource") DataSource dataSource) throws Exception {
+        SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
+        sessionFactoryBean.setDataSource(dataSource);
+
+        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
+        configuration.setCallSettersOnNulls(true);       //数据库中字段值为null时也要求返回
+        configuration.setMapUnderscoreToCamelCase(true); //开启驼峰映射
+        configuration.setCacheEnabled(false);
+        sessionFactoryBean.setConfiguration(configuration);
+        return sessionFactoryBean.getObject();
+    }
+
+    @Bean("child2SqlSessionTemplate")
+    public SqlSessionTemplate child2SqlSessionTemplate(@Qualifier("child2SqlSessionFactory") SqlSessionFactory sessionFactory) {
+        return new SqlSessionTemplate(sessionFactory);
+    }
+
+    @Bean(name = "child2DbTransactionManager")
+    public DataSourceTransactionManager child2DbTransactionManager(@Qualifier("child2Datasource") DataSource dataSource){
+        return new DataSourceTransactionManager(dataSource);
+    }
+
+    @PostConstruct
+    public void init(){
+        GlobalData.getInstance().setPostGisValid("org.postgis.DriverWrapper".equals(driveClass));
+    }
+}

+ 106 - 0
dc3-gateway/src/main/java/io/github/pnoker/gateway/config/Child3SourceConfiguration.java

@@ -0,0 +1,106 @@
+package io.github.pnoker.gateway.config;
+
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionFactoryBean;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+
+import javax.annotation.PostConstruct;
+import javax.sql.DataSource;
+
+@Configuration
+@MapperScan(basePackages = "io.github.pnoker.gateway.dbdao.mapper", sqlSessionTemplateRef = "child3SqlSessionTemplate")
+public class Child3SourceConfiguration {
+    @Value("${spring.datasource.child3pg.driver-class-name:}")
+    private String driveClass = "org.postgresql.Driver";
+
+    @Value("${spring.datasource.child3pg.jdbc-url:}")
+    private String url = "";
+
+    @Value("${spring.datasource.child3pg.username:}")
+    private String username = "";
+
+    @Value("${spring.datasource.child3pg.password:}")
+    private String password = "";
+
+    @Value("${spring.datasource.data.maximum-pool-size:200}")
+    private Integer maxPoolSize;
+
+    @Value("${spring.datasource.data.minimum-idle:1}")
+    private Integer minIdle;
+
+    @Value("${spring.datasource.data.connection-test-query:}")
+    private String connectionTestQuery;
+
+    @Value("${spring.datasource.data.max-lifetime:120000}")
+    private Long maxLifetime;
+
+    @Value("${spring.datasource.data.idle-timeout:30000}")
+    private Long idleTimeout;
+
+    @Value("${spring.datasource.data.connection-timeout:30000}")
+    private Long connectionTimeout;
+
+    @Value("${spring.datasource.data.validation-timeout:30000}")
+    private Long validTimeout;
+
+    @Bean(name = "child3Datasource")
+    //@ConfigurationProperties(prefix = "spring.datasource.data")
+    public DataSource mainDataSource() {
+        return new HikariDataSource(getConfig());
+        //return DataSourceBuilder.create().build();
+        //Spring Boot 2.x默认使用HikariCP
+    }
+
+    private HikariConfig getConfig() {
+        HikariConfig hikariConfig = new HikariConfig();
+        hikariConfig.setDriverClassName(driveClass);
+        hikariConfig.setJdbcUrl(url);
+        hikariConfig.setUsername(username);
+        hikariConfig.setPassword(password);
+
+        hikariConfig.setMaximumPoolSize(maxPoolSize);
+        hikariConfig.setMinimumIdle(minIdle);
+        hikariConfig.setConnectionTestQuery(connectionTestQuery);
+        hikariConfig.setMaxLifetime(maxLifetime);
+        hikariConfig.setIdleTimeout(idleTimeout);
+        hikariConfig.setConnectionTimeout(connectionTimeout);
+        hikariConfig.setValidationTimeout(validTimeout);
+        return hikariConfig;
+    }
+
+    @Bean("child3SqlSessionFactory")
+    public SqlSessionFactory child3SqlSessionFactoryBean(@Qualifier("child3Datasource") DataSource dataSource) throws Exception {
+        SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
+        sessionFactoryBean.setDataSource(dataSource);
+
+        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
+        configuration.setCallSettersOnNulls(true);       //数据库中字段值为null时也要求返回
+        configuration.setMapUnderscoreToCamelCase(true); //开启驼峰映射
+        configuration.setCacheEnabled(false);
+        sessionFactoryBean.setConfiguration(configuration);
+        return sessionFactoryBean.getObject();
+    }
+
+    @Bean("child3SqlSessionTemplate")
+    public SqlSessionTemplate child3SqlSessionTemplate(@Qualifier("child3SqlSessionFactory") SqlSessionFactory sessionFactory) {
+        return new SqlSessionTemplate(sessionFactory);
+    }
+
+    @Bean(name = "child3DbTransactionManager")
+    public DataSourceTransactionManager child3DbTransactionManager(@Qualifier("child3Datasource") DataSource dataSource){
+        return new DataSourceTransactionManager(dataSource);
+    }
+
+    @PostConstruct
+    public void init(){
+        GlobalData.getInstance().setPostGisValid("org.postgis.DriverWrapper".equals(driveClass));
+    }
+}

+ 333 - 0
dc3-gateway/src/main/java/io/github/pnoker/gateway/dbdao/zilaishuiSource/ZilaishuiRealListDao.java

@@ -1,12 +1,17 @@
 package io.github.pnoker.gateway.dbdao.zilaishuiSource;
 
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
 import org.springframework.stereotype.Repository;
+import org.springframework.util.ObjectUtils;
 import org.springframework.util.StringUtils;
 
 import javax.annotation.Resource;
+import javax.sql.DataSource;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -24,6 +29,14 @@ public class ZilaishuiRealListDao {
     @Resource
     private JdbcTemplate twoTemplate;
 
+    @Autowired
+    @Qualifier("child2Datasource")
+    private DataSource child2DataSource;
+
+    @Autowired
+    @Qualifier("child3Datasource")
+    private DataSource child3DataSource;
+
     //TODO orcale相关
     public Integer getTabWaterHistoryCount(String extend){
         try {
@@ -59,4 +72,324 @@ public class ZilaishuiRealListDao {
         }
     }
 
+    //TODO pgsql 相关
+    //TODO 查询设备关系表信息·不分页
+    public List<Map<String,Object>> getWaterLevelCollectionConfigList(String extend){
+        try{
+            String sql = "SELECT * FROM water_level_collection_config ";
+            if(!StringUtils.isEmpty(extend)){
+                sql+=extend;
+            }
+            JdbcTemplate pgJdbc = new JdbcTemplate(child2DataSource);
+            List<Map<String, Object>> tableData = pgJdbc.queryForList(sql);
+            return tableData;
+        }catch(Exception ex){
+            return null;
+        }
+    }
+
+    //TODO 查询市自来水小时液位记录表·分页
+    public List<Map<String,Object>> getWaterLevelRecordAllList(int limit,int offset,String extend){
+        try{
+            String sql = "SELECT * FROM water_level_record_all ";
+            if(!StringUtils.isEmpty(extend)){
+                sql += extend;
+            }
+            sql += " LIMIT " + limit + " OFFSET "+ offset;
+            JdbcTemplate pgJdbc = new JdbcTemplate(child2DataSource);
+            List<Map<String,Object>> tableData = pgJdbc.queryForList(sql);
+            return tableData;
+        }catch(Exception ex){
+            return null;
+        }
+    }
+
+    //TODO 查询市自来水小时液位记录表·不分页
+    public List<Map<String,Object>> getWaterLevelRecordAllListAll(String extend){
+        try{
+            String sql = "SELECT * FROM water_level_record_all ";
+            if(!StringUtils.isEmpty(extend)){
+                sql += extend;
+            }
+            JdbcTemplate pgJdbc = new JdbcTemplate(child2DataSource);
+            List<Map<String,Object>> tableData = pgJdbc.queryForList(sql);
+            return tableData;
+        }catch(Exception ex){
+            return null;
+        }
+    }
+
+    //TODO 插入自来水小时液位记录表
+    public int insertWaterLevelRecordAll(String extend){
+        try{
+            String sql = "INSERT INTO water_level_record_all " +
+                    "(device_code,value,value_tag,time) VALUES ";
+            if(StringUtils.isEmpty(extend)){
+                return -1;
+            }
+            sql+=extend;
+            JdbcTemplate pgJdbc = new JdbcTemplate(child2DataSource);
+            Integer resCode = pgJdbc.update(sql);
+            return resCode;
+        }catch(Exception ex){
+            return -1;
+        }
+    }
+
+    //TODO 修改自来水小时液位记录表value
+    public int updateWaterLevelRecordAll(String value,String extend){
+        try{
+            String sql = "UPDATE water_level_record_all " +
+                    " SET \"value\" =  "+value+" " +
+                    " ";
+            if(!StringUtils.isEmpty(extend)){
+                sql = sql +extend;
+            }
+            JdbcTemplate pgJdbc = new JdbcTemplate(child2DataSource);
+            Integer resCode = pgJdbc.update(sql);
+            return resCode;
+        }catch(Exception ex){
+            return -1;
+        }
+    }
+
+    //TODO 添加或修改日小时预测数据
+    public int insertOrUpdateTbmHourLevel(Map<String,Object> value){
+        try{
+            String sql = "INSERT INTO tb_m_hourlevel " +
+                    "(\"date\",\"hour\"";
+            if(!ObjectUtils.isEmpty(value.get("hourForecastActualLevel"))){
+                sql +=  " , \"hour_forecast_actual_level\" ";
+            }
+            if(!ObjectUtils.isEmpty(value.get("hourActualWaterLevel"))){
+                sql +=  " ,\"hour_actual_water_level\"";
+            }
+            sql+= ",\"last_modify_time\",\"device_code\" ) VALUES ";
+            sql +=" ( ";
+            int i = 1;
+            for (Object key : value.keySet()){
+                if(i==value.keySet().size()){
+                    if(ObjectUtils.isEmpty(value.get(key))){
+                        sql += " NULL ";
+                    }else {
+                        sql += "'" + value.get(key) + "'";
+                    }
+                }else {
+                    if(ObjectUtils.isEmpty(value.get(key))) {
+                        sql += " NULL ,";
+                    }else {
+                        sql += "'" + value.get(key) + "',";
+                    }
+                }
+                i++;
+            }
+            sql += " )";
+            sql += " ON CONFLICT (\"date\",\"hour\",\"device_code\") " +
+                    " DO UPDATE " +
+                    " SET \"date\" =  '"+value.get("date")+"' " +
+                    " , \"hour\" =  '"+value.get("hour")+"' ";
+            if(!ObjectUtils.isEmpty(value.get("hourForecastActualLevel"))){
+                sql +=  " , \"hour_forecast_actual_level\" =  '"+value.get("hourForecastActualLevel")+"' ";
+            }
+            if(!ObjectUtils.isEmpty(value.get("hourActualWaterLevel"))){
+                sql +=  " ,\"hour_actual_water_level\" =  '"+value.get("hourActualWaterLevel")+"' ";
+            }
+
+            sql += " , \"last_modify_time\" =  '"+value.get("lastModifyTime")+"' " +
+                    " , \"device_code\" =  '"+value.get("deviceCode")+"' ";
+            JdbcTemplate pgJdbc = new JdbcTemplate(child2DataSource);
+            Integer resCode = pgJdbc.update(sql);
+            return resCode;
+        }catch(Exception ex){
+            return -1;
+        }
+    }
+
+    /**
+     * TODO 泵组优化相关
+     */
+    //TODO 获取泵数据采集配置
+    public List<Map<String,Object>> getWaterPumpCollectionConfigList(String extend){
+        try{
+            String sql = "SELECT * FROM water_pump_collection_config ";
+            if(!StringUtils.isEmpty(extend)){
+                sql+=extend;
+            }
+            JdbcTemplate pgJdbc = new JdbcTemplate(child3DataSource);
+            List<Map<String, Object>> tableData = pgJdbc.queryForList(sql);
+            return tableData;
+        }catch(Exception ex){
+            return null;
+        }
+    }
+
+    //TODO 查询市自来水小时泵数据记录表·分页
+    public List<Map<String,Object>> getWaterPumpRecordAllList(int limit,int offset,String extend){
+        try{
+            String sql = "SELECT * FROM water_pump_record_all ";
+            if(!StringUtils.isEmpty(extend)){
+                sql += extend;
+            }
+            sql += " LIMIT " + limit + " OFFSET "+ offset;
+            JdbcTemplate pgJdbc = new JdbcTemplate(child3DataSource);
+            List<Map<String,Object>> tableData = pgJdbc.queryForList(sql);
+            return tableData;
+        }catch(Exception ex){
+            return null;
+        }
+    }
+
+    //TODO 查询市自来水小时泵数据记录表·不分页
+    public List<Map<String,Object>> getWaterPumpRecordAllListAll(String extend){
+        try{
+            String sql = "SELECT * FROM water_pump_record_all ";
+            if(!StringUtils.isEmpty(extend)){
+                sql += extend;
+            }
+            JdbcTemplate pgJdbc = new JdbcTemplate(child3DataSource);
+            List<Map<String,Object>> tableData = pgJdbc.queryForList(sql);
+            return tableData;
+        }catch(Exception ex){
+            return null;
+        }
+    }
+
+    //TODO 插入或修改自来水小时泵数据记录表
+    public int insertOrUpdateWaterPumpRecordAll(Map<String, Object> value) {
+        if (ObjectUtils.isEmpty(value) || ObjectUtils.isEmpty(value.get("device_code")) || ObjectUtils.isEmpty(value.get("time"))) {
+            // 确保 device_code 和 time 不为空,因为它们是复合键
+            return -1;
+        }
+
+        try {
+            StringBuilder sql = new StringBuilder("INSERT INTO water_pump_record_all (device_code, time");
+
+            // 动态添加字段
+            if (!ObjectUtils.isEmpty(value.get("active_energy"))) {
+                sql.append(", active_energy");
+            }
+            if (!ObjectUtils.isEmpty(value.get("startup_state"))) {
+                sql.append(", startup_state");
+            }
+
+            sql.append(") VALUES (?, ?");
+
+            // 动态添加占位符
+            if (!ObjectUtils.isEmpty(value.get("active_energy"))) {
+                sql.append(", ?");
+            }
+            if (!ObjectUtils.isEmpty(value.get("startup_state"))) {
+                sql.append(", ?");
+            }
+
+            sql.append(") ON CONFLICT (device_code, time) DO UPDATE SET ");
+
+            // 动态添加更新字段
+            boolean firstUpdateField = true;
+            if (!ObjectUtils.isEmpty(value.get("active_energy"))) {
+                sql.append("active_energy = EXCLUDED.active_energy");
+                firstUpdateField = false;
+            }
+            if (!ObjectUtils.isEmpty(value.get("startup_state"))) {
+                if (!firstUpdateField) {
+                    sql.append(", ");
+                }
+                sql.append("startup_state = EXCLUDED.startup_state");
+            }
+
+            // 准备参数
+            List<Object> params = new ArrayList<>();
+            params.add(value.get("device_code"));
+            params.add(value.get("time"));
+            if (!ObjectUtils.isEmpty(value.get("active_energy"))) {
+                params.add(value.get("active_energy"));
+            }
+            if (!ObjectUtils.isEmpty(value.get("startup_state"))) {
+                params.add(value.get("startup_state"));
+            }
+
+            // 执行 SQL 语句
+            JdbcTemplate pgJdbc = new JdbcTemplate(child3DataSource);
+            return pgJdbc.update(sql.toString(), params.toArray());
+
+        } catch (Exception ex) {
+            return -1;
+        }
+    }
+
+
+    //TODO 修改自来水小时泵数据记录表value
+    public int updateWaterPumpRecordAll(String value,String extend){
+        try{
+            String sql = "UPDATE water_level_record_all " +
+                    " SET \"value\" =  "+value+" " +
+                    " ";
+            if(!StringUtils.isEmpty(extend)){
+                sql = sql +extend;
+            }
+            JdbcTemplate pgJdbc = new JdbcTemplate(child3DataSource);
+            Integer resCode = pgJdbc.update(sql);
+            return resCode;
+        }catch(Exception ex){
+            return -1;
+        }
+    }
+
+    //TODO 插入预测数据相关
+    public void insertInitialData() {
+        String sql = "INSERT INTO tb_m_hourlevel(device_code, date, hour, hour_actual_water_level) " +
+                "SELECT FF.device_code, FF.for_date, FF.for_hour, FF.data " +
+                "FROM (SELECT device_code, " +
+                "CAST(value AS NUMERIC(18, 2)) as data, " +
+                "TO_DATE(time, 'yyyy-mm-dd HH24:MI:SS') AS for_date, " +
+                "TO_TIMESTAMP(time, 'yyyy-mm-dd HH24:MI:SS')::time(6) AS for_hour " +
+                "FROM water_level_record_all " +
+                "WHERE TO_DATE(time, 'yyyy-mm-dd HH24:MI:SS') >= (CURRENT_DATE - INTERVAL '20 days')) FF " +
+                "ON CONFLICT (device_code, date, hour) " +
+                "DO UPDATE SET hour_actual_water_level = excluded.hour_actual_water_level;";
+        JdbcTemplate pgJdbc = new JdbcTemplate(child2DataSource);
+        pgJdbc.update(sql);
+    }
+
+    public void insertDailyData() {
+        String sql = "INSERT INTO tb_m_hourlevel(device_code, date, hour, hour_actual_water_level) " +
+                "SELECT FF.device_code, FF.for_date, FF.for_hour, FF.data " +
+                "FROM (SELECT device_code, " +
+                "CAST(value AS NUMERIC(18, 2)) as data, " +
+                "TO_DATE(time, 'yyyy-mm-dd HH24:MI:SS') AS for_date, " +
+                "TO_TIMESTAMP(time, 'yyyy-mm-dd HH24:MI:SS')::time(6) AS for_hour " +
+                "FROM water_level_record_all " +
+                "WHERE TO_DATE(time, 'yyyy-mm-dd HH24:MI:SS') >= (CURRENT_DATE - INTERVAL '1 day')) FF " +
+                "ON CONFLICT (device_code, date, hour) " +
+                "DO UPDATE SET hour_actual_water_level = excluded.hour_actual_water_level;";
+        JdbcTemplate pgJdbc = new JdbcTemplate(child2DataSource);
+        pgJdbc.update(sql);
+    }
+
+    public void insertForecastData() {
+        String sql = "DO $$ " +
+                "DECLARE " +
+                "dd INTEGER := 0; " +
+                "BEGIN " +
+                "WHILE dd <= 5 LOOP " +
+                "INSERT INTO tb_m_hourlevel(device_code, date, hour, hour_forecast_actual_level) " +
+                "SELECT FF.device_code, CURRENT_DATE + (dd || 'day')::interval, FF.hour, FF.future " +
+                "FROM (SELECT CC.device_code, CC.hour, " +
+                "CAST(avg(CC.hour_actual_water_level) FILTER (WHERE CC.hour_actual_water_level <> 'NaN') + " +
+                "(sign(random() - 0.5) * (random() * 0.3)) AS NUMERIC(18, 2)) as future " +
+                "FROM (SELECT device_code, date, hour FROM tb_m_hourlevel " +
+                "WHERE date = CURRENT_DATE - INTERVAL '7 days' " +
+                "GROUP BY device_code, date, hour) BB " +
+                "JOIN tb_m_hourlevel CC " +
+                "ON BB.device_code = CC.device_code AND BB.hour = CC.hour AND CC.date >= BB.date " +
+                "GROUP BY CC.device_code, CC.hour " +
+                "ORDER BY CC.device_code DESC, CC.hour DESC) FF " +
+                "ON CONFLICT (device_code, date, hour) " +
+                "DO UPDATE SET hour_forecast_actual_level = excluded.hour_forecast_actual_level; " +
+                "dd := dd + 1; " +
+                "END LOOP; " +
+                "END $$;";
+        JdbcTemplate pgJdbc = new JdbcTemplate(child2DataSource);
+        pgJdbc.execute(sql);
+    }
 }

+ 21 - 0
dc3-gateway/src/main/java/io/github/pnoker/gateway/dbdao/zilaishuiSource/service/ZilaishuiRealListService.java

@@ -7,4 +7,25 @@ public interface ZilaishuiRealListService {
     public Integer getTabWaterHistoryCount(String extend);
 
     public List<Map<String,Object>> getPageZILAISHUI_HISTORY2(int limit, int offset, String extend);
+
+    //TODO pgsql相关
+    public List<Map<String,Object>> getWaterLevelCollectionConfigList(String extend);
+    public List<Map<String,Object>> getWaterLevelRecordAllList(int limit,int offset,String extend);
+    public List<Map<String,Object>> getWaterLevelRecordAllListAll(String extend);
+    public int insertWaterLevelRecordAll(String extend);
+    public int updateWaterLevelRecordAll(String value,String extend);
+    public int insertOrUpdateTbmHourLevel(Map<String,Object> value);
+
+    public void insertDailyData();
+    public void insertForecastData();
+
+    /**
+     * TODO 泵组优化相关
+     */
+    //TODO 获取泵数据采集配置
+    public List<Map<String,Object>> getWaterPumpCollectionConfigList(String extend);
+    public List<Map<String,Object>> getWaterPumpRecordAllList(int limit,int offset,String extend);
+    public List<Map<String,Object>> getWaterPumpRecordAllListAll(String extend);
+    public int insertOrUpdateWaterPumpRecordAll(Map<String,Object> value);
+    public int updateWaterPumpRecordAll(String value,String extend);
 }

+ 65 - 0
dc3-gateway/src/main/java/io/github/pnoker/gateway/dbdao/zilaishuiSource/service/impl/ZilaishuiRealListServiceImpl.java

@@ -30,4 +30,69 @@ public class ZilaishuiRealListServiceImpl implements ZilaishuiRealListService{
     public List<Map<String, Object>> getPageZILAISHUI_HISTORY2(int limit, int offset, String extend) {
         return zilaishuiRealListDao.getPageZILAISHUI_HISTORY2(limit, offset, extend);
     }
+
+    @Override
+    public List<Map<String, Object>> getWaterLevelCollectionConfigList(String extend) {
+        return zilaishuiRealListDao.getWaterLevelCollectionConfigList(extend);
+    }
+
+    @Override
+    public List<Map<String, Object>> getWaterLevelRecordAllList(int limit, int offset, String extend) {
+        return zilaishuiRealListDao.getWaterLevelRecordAllList(limit, offset, extend);
+    }
+
+    @Override
+    public List<Map<String, Object>> getWaterLevelRecordAllListAll(String extend) {
+        return zilaishuiRealListDao.getWaterLevelRecordAllListAll(extend);
+    }
+
+    @Override
+    public int insertWaterLevelRecordAll(String extend) {
+        return zilaishuiRealListDao.insertWaterLevelRecordAll(extend);
+    }
+
+    @Override
+    public int updateWaterLevelRecordAll(String value, String extend) {
+        return zilaishuiRealListDao.updateWaterLevelRecordAll(value, extend);
+    }
+
+    @Override
+    public int insertOrUpdateTbmHourLevel(Map<String, Object> value) {
+        return zilaishuiRealListDao.insertOrUpdateTbmHourLevel(value);
+    }
+
+    @Override
+    public void insertDailyData() {
+        zilaishuiRealListDao.insertDailyData();
+    }
+
+    @Override
+    public void insertForecastData() {
+        zilaishuiRealListDao.insertForecastData();
+    }
+
+    @Override
+    public List<Map<String, Object>> getWaterPumpCollectionConfigList(String extend) {
+        return zilaishuiRealListDao.getWaterPumpCollectionConfigList(extend);
+    }
+
+    @Override
+    public List<Map<String, Object>> getWaterPumpRecordAllList(int limit, int offset, String extend) {
+        return zilaishuiRealListDao.getWaterPumpRecordAllList(limit, offset, extend);
+    }
+
+    @Override
+    public List<Map<String, Object>> getWaterPumpRecordAllListAll(String extend) {
+        return zilaishuiRealListDao.getWaterPumpRecordAllListAll(extend);
+    }
+
+    @Override
+    public int insertOrUpdateWaterPumpRecordAll(Map<String,Object> value) {
+        return zilaishuiRealListDao.insertOrUpdateWaterPumpRecordAll(value);
+    }
+
+    @Override
+    public int updateWaterPumpRecordAll(String value, String extend) {
+        return zilaishuiRealListDao.updateWaterPumpRecordAll(value, extend);
+    }
 }