Explorar o código

湿球温度数据计算

miaolijing %!s(int64=3) %!d(string=hai) anos
pai
achega
bec9e4cc39

+ 3 - 0
src/main/java/com/persagy/apm/diagnose/feign/client/CenterMiddlewareClient.java

@@ -25,4 +25,7 @@ public interface CenterMiddlewareClient {
     @PostMapping(value = "/hisdata/queryPeriodData")
     public String queryPeriodData(@RequestBody Map<String, Object> requestMap);
 
+    @PostMapping(value = "/mng/project/query")
+    public String queryProject(@RequestBody Map<String, Object> requestMap);
+
 }

+ 9 - 0
src/main/java/com/persagy/apm/diagnose/feign/client/SaasWebClient.java

@@ -24,4 +24,13 @@ public interface SaasWebClient {
 	@PostMapping("/Spring/MVC/entrance/unifier/queryInUseProjectsByIds")
 	@Headers({ "Content-Type: application/x-www-form-urlencoded" })
 	String queryInUseProjectsByIds(@RequestParam("jsonString") String jsonString);
+
+    /**
+     * 根据项目id查询项目信息
+     * @param jsonString
+     * @return
+     */
+    @PostMapping("/Spring/MVC/entrance/unifier/getProjectByIdService")
+    @Headers({ "Content-Type: application/x-www-form-urlencoded" })
+    String getProjectByIdService(@RequestParam("jsonString") String jsonString);
 }

+ 26 - 0
src/main/java/com/persagy/apm/diagnose/maintenance/model/dto/WeatherDTO.java

@@ -0,0 +1,26 @@
+package com.persagy.apm.diagnose.maintenance.model.dto;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 天气信息
+ */
+@Data
+@Builder(toBuilder = true)
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class WeatherDTO {
+    private Date hourTime;
+
+    private Double temperature;
+
+    private Double humidity;
+}

+ 3 - 1
src/main/java/com/persagy/apm/diagnose/maintenance/service/IProjectDataRecordService.java

@@ -1,5 +1,7 @@
 package com.persagy.apm.diagnose.maintenance.service;
 
+import com.persagy.apm.diagnose.service.dto.ProjectDTO;
+
 import java.util.Date;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Future;
@@ -9,7 +11,7 @@ import java.util.concurrent.Future;
  */
 public interface IProjectDataRecordService {
 
-    Future<String> computeMaintenanceData(Date todayDate,String projectId,CountDownLatch latch) throws Exception;
+    Future<String> computeMaintenanceData(Date todayDate, ProjectDTO projectDTO, CountDownLatch latch) throws Exception;
 
     Future<String> sendMaintenanceData(Date todayDate,String projectId, CountDownLatch latch) throws Exception;
 

+ 111 - 31
src/main/java/com/persagy/apm/diagnose/maintenance/service/impl/ProjectDataRecordServiceImpl.java

@@ -11,10 +11,12 @@ import com.persagy.apm.diagnose.indicatorrecord.model.dto.QueryMonitorIndicatorR
 import com.persagy.apm.diagnose.indicatorrecord.service.IMonitorIndicatorRecordService;
 import com.persagy.apm.diagnose.maintenance.constant.*;
 import com.persagy.apm.diagnose.maintenance.model.dto.CalculateMethodDTO;
+import com.persagy.apm.diagnose.maintenance.model.dto.WeatherDTO;
 import com.persagy.apm.diagnose.maintenance.service.IProjectDataRecordService;
 import com.persagy.apm.diagnose.service.CenterDataService;
 import com.persagy.apm.diagnose.service.EnergyAlarmServiceImpl;
 import com.persagy.apm.diagnose.service.SaasService;
+import com.persagy.apm.diagnose.service.WeatherServiceImpl;
 import com.persagy.apm.diagnose.service.dto.AlarmRuleDTO;
 import com.persagy.apm.diagnose.service.dto.ProjectDTO;
 import com.persagy.apm.diagnose.service.dto.TimeDataDTO;
@@ -72,6 +74,7 @@ public class ProjectDataRecordServiceImpl implements IProjectDataRecordService {
     public final static String alarmSplit = "_";
     private final static Long ConfigItemKeyTime = 60 * 60 * 1000L;
     private final static Long SendDataTimeKeyTime = 24 * 60 * 60 * 1000L;
+    private final static Double TwdTemp_Limit = 0.1;
 
     @Autowired
     private AlarmRecordServiceImpl alarmRecordService;
@@ -91,30 +94,35 @@ public class ProjectDataRecordServiceImpl implements IProjectDataRecordService {
     private ComputePropertiesConfig computePropertiesConfig;
     @Autowired
     private EnergyAlarmServiceImpl energyAlarmService;
+    @Autowired
+    private WeatherServiceImpl weatherService;
 
     @Resource(name = "ZillionDao")
     private CoreDao coredao;
 
     @Override
     @Async("asyncComputeMaintenanceDataExecutor")
-    public Future<String> computeMaintenanceData(Date todayDate, String projectId, CountDownLatch latch) throws Exception {
+    public Future<String> computeMaintenanceData(Date todayDate,ProjectDTO projectDTO, CountDownLatch latch) throws Exception {
         long time = System.currentTimeMillis() + (20 * 1000);
         try {
-            if (!lockUtil.lock(projectId + "_computeMaintenance", String.valueOf(time))) {
+            if (!lockUtil.lock(projectDTO.getProjectId() + "_computeMaintenance", String.valueOf(time))) {
                 // 获取不到锁,略过
-                return new AsyncResult<>("【监测维保数据计算线程】项目:" + projectId + "被占用");
+                return new AsyncResult<>("【监测维保数据计算线程】项目:" + projectDTO.getProjectId() + "被占用");
             }
 
+            Date startDate = DateUtils.addDays(todayDate,-5);
+            computerWetBallTempMap(projectDTO,startDate,todayDate);
+
             long start = System.currentTimeMillis();
-            AsyncResult<String> projectDTOBack = computeProjectMaintenanceData(todayDate, projectId);
-            if (projectDTOBack != null) {
-                return projectDTOBack;
-            }
+//            AsyncResult<String> projectDTOBack = computeProjectMaintenanceData(todayDate, projectDTO);
+//            if (projectDTOBack != null) {
+//                return projectDTOBack;
+//            }
             long end = System.currentTimeMillis();
-            return new AsyncResult<>("【监测维保数据计算线程】计算项目指标数据用时:" + projectId + ";" + (end - start));
+            return new AsyncResult<>("【监测维保数据计算线程】计算项目指标数据用时:" + projectDTO.getProjectId() + ";" + (end - start));
         } finally {
             // 释放锁
-            lockUtil.unlock(projectId + "_computeMaintenance", String.valueOf(time));
+            lockUtil.unlock(projectDTO.getProjectId() + "_computeMaintenance", String.valueOf(time));
             latch.countDown();
         }
     }
@@ -383,23 +391,23 @@ public class ProjectDataRecordServiceImpl implements IProjectDataRecordService {
     /**
      * 计算维保数据
      */
-    private AsyncResult<String> computeProjectMaintenanceData(Date todayDate, String projectId) {
+    private AsyncResult<String> computeProjectMaintenanceData(Date todayDate, ProjectDTO projectDTO) {
         try {
             //通过报警服务查询报警规则
             List<String> itemCodeList = new ArrayList<>();
             itemCodeList.add(EnumAlarmItem.CondAbnormal.getCode());
             itemCodeList.add(EnumAlarmItem.EvapAbnormal.getCode());
             itemCodeList.add(EnumAlarmItem.CoolTowerApproachTempAbnormal.getCode());
-            List<AlarmRuleDTO> projectAlarmRules = energyAlarmService.getProjectAlarmRules(projectId,itemCodeList);
+            List<AlarmRuleDTO> projectAlarmRules = energyAlarmService.getProjectAlarmRules(projectDTO.getProjectId(),itemCodeList);
             if (CollectionUtils.isEmpty(projectAlarmRules)) {
-                return new AsyncResult<>("【监测维保数据计算线程】当前项目:" + projectId + "未设置设备维保报警规则");
+                return new AsyncResult<>("【监测维保数据计算线程】当前项目:" + projectDTO.getProjectId() + "未设置设备维保报警规则");
             }
             Set<String> objIdAndIndicatorId = getObjIdAndInfoCodeFromRules(projectAlarmRules);
             if (CollectionUtils.isEmpty(objIdAndIndicatorId)) {
-                return new AsyncResult<>("【监测维保数据计算线程】当前项目:" + projectId + "报警规则未关联对象");
+                return new AsyncResult<>("【监测维保数据计算线程】当前项目:" + projectDTO.getProjectId() + "报警规则未关联对象");
             }
             //Map<objId_monitorIndicatorId, Date>
-            Map<String, Date> objId_indicatorIdAndComputeTime = getObjId_IndicatorIdAndComputeTIme(projectId);
+            Map<String, Date> objId_indicatorIdAndComputeTime = getObjId_IndicatorIdAndComputeTIme(projectDTO.getProjectId());
             //循环计算
             for (AlarmRuleDTO alarmRuleDTO:projectAlarmRules) {
                 String itemCode = alarmRuleDTO.getAlarmItemCode();
@@ -413,7 +421,7 @@ public class ProjectDataRecordServiceImpl implements IProjectDataRecordService {
                     continue;
                 }
                 for (String objId:objIdList) {
-                    List<AlarmCondition> alarmConditionList = energyAlarmService.getProjectAlarmCondition(projectId,objId,enumAlarmItem.getCode());
+                    List<AlarmCondition> alarmConditionList = energyAlarmService.getProjectAlarmCondition(projectDTO.getProjectId(),objId,enumAlarmItem.getCode());
                     if (CollectionUtils.isEmpty(alarmConditionList)){
                         continue;
                     }
@@ -454,15 +462,15 @@ public class ProjectDataRecordServiceImpl implements IProjectDataRecordService {
                         Date computeTime;
                         if (indicatorType == EnumMaintenanceIndicatorType.ACCCOT_DayAvg) {//冷却塔
                             //冷却塔 日均 数据计算
-                            computeTime = computeCoolTowerData(lastComputeTime, todayDate, projectId, objId, indicatorType);
+                            computeTime = computeCoolTowerData(lastComputeTime, todayDate, projectDTO, objId, indicatorType);
                         } else {//冷水机组
                             //冷却水组  日均 数据计算
-                            computeTime = computeCoolWaterData(lastComputeTime, todayDate, projectId, objId, indicatorType);
+                            computeTime = computeCoolWaterData(lastComputeTime, todayDate, projectDTO.getProjectId(), objId, indicatorType);
                         }
                         //计算 运行持续时长
-                        computeAlarmDay(projectId, objId, infoCode, indicatorType, lastComputeTime, todayDate,monitorIndicatorMap);
+                        computeAlarmDay(projectDTO.getProjectId(), objId, infoCode, indicatorType, lastComputeTime, todayDate,monitorIndicatorMap);
                         //更新计算 时间记录
-                        saveOrUpdateComputeTime(projectId, objId, infoCode, computeTime);
+                        saveOrUpdateComputeTime(projectDTO.getProjectId(), objId, infoCode, computeTime);
                     }
                 }
             }
@@ -622,7 +630,7 @@ public class ProjectDataRecordServiceImpl implements IProjectDataRecordService {
     /**
      * 冷却塔 日均计算
      */
-    Date computeCoolTowerData(Date startDate, Date endDate, String projectId, String cTObjId, EnumMaintenanceIndicatorType indicatorType) throws Exception {
+    Date computeCoolTowerData(Date startDate, Date endDate, ProjectDTO projectDTO, String cTObjId, EnumMaintenanceIndicatorType indicatorType) throws Exception {
 //        Date runDate = null;
 //        //获取冷却塔下所有风机运行时时间列表(所有风机运行时间合并为一组时间列表)
 //        Map<Date, List<Date>> allDateRunDataMap = getCoolTowerRunDateMap(projectId, startDate, endDate);
@@ -630,7 +638,7 @@ public class ProjectDataRecordServiceImpl implements IProjectDataRecordService {
 //        Map<Date, List<Date>> dateRunDataMap = getCoolTowerContinuedRunDateMap(allDateRunDataMap);
 
         Date runDate = null;
-        Map<Date, List<TimeDataDTO>> dayTimeDataMap = getServiceDataFromCenterDataService(projectId, cTObjId, EnumCoolWaterPointNameType.RunStatus.getCode(), startDate, endDate);
+        Map<Date, List<TimeDataDTO>> dayTimeDataMap = getServiceDataFromCenterDataService(projectDTO.getProjectId(), cTObjId, EnumCoolWaterPointNameType.RunStatus.getCode(), startDate, endDate);
         //获取日 对应运行时间集合
         Map<Date, List<Date>> dateRunDataMap = getContinuedRunDateMap(dayTimeDataMap);
         //获取冷却水回水干管温度数据集合
@@ -640,19 +648,21 @@ public class ProjectDataRecordServiceImpl implements IProjectDataRecordService {
         //计算日均
         if (dateRunDataMap.size() > 0) {
             //获取中央供冷系统对象
-            List<JSONObject> object2List = getEqObjectList(projectId, "ACCC");
+            List<JSONObject> object2List = getEqObjectList(projectDTO.getProjectId(), "ACCC");
             if (!CollectionUtils.isEmpty(object2List)) {
                 JSONObject object = object2List.get(0);
                 String objId = object.getString("id");
-                dayCoolWaterMainReturnTempMap = getServiceDataFromCenterDataService(projectId, objId, EnumCoolTowerPointNameType.CoolWaterMainReturnTemp.getCode(), startDate, endDate);
+                dayCoolWaterMainReturnTempMap = getServiceDataFromCenterDataService(projectDTO.getProjectId(), objId, EnumCoolTowerPointNameType.CoolWaterMainReturnTemp.getCode(), startDate, endDate);
             }
+            //计算出 湿球温度数据集合
+            dayTwdTempMap = computerWetBallTempMap(projectDTO,startDate,endDate);
             //获取中央供冷系统对象
-            List<JSONObject> object3List = getEqObjectList(projectId, "WEMMMS");
-            if (!CollectionUtils.isEmpty(object3List)) {
-                JSONObject object = object3List.get(0);
-                String objId = object.getString("id");
-                dayTwdTempMap = getServiceDataFromCenterDataService(projectId, objId, EnumCoolTowerPointNameType.Twb.getCode(), startDate, endDate);
-            }
+//            List<JSONObject> object3List = getEqObjectList(projectDTO.getProjectId(), "WEMMMS");
+//            if (!CollectionUtils.isEmpty(object3List)) {
+//                JSONObject object = object3List.get(0);
+//                String objId = object.getString("id");
+//                dayTwdTempMap = getServiceDataFromCenterDataService(projectDTO.getProjectId(), objId, EnumCoolTowerPointNameType.Twb.getCode(), startDate, endDate);
+//            }
         }
         //循环计算日均
         for (Date dayDate = startDate; dayDate.before(endDate); dayDate = DateUtils.addDays(dayDate, 1)) {
@@ -663,7 +673,7 @@ public class ProjectDataRecordServiceImpl implements IProjectDataRecordService {
             monitorIndicatorRecord.setMonitorIndicatorId(indicatorType.getCode());
             monitorIndicatorRecord.setDataTime(dayDate);
             monitorIndicatorRecord.setObjId(cTObjId);
-            monitorIndicatorRecord.setProject(projectId);
+            monitorIndicatorRecord.setProject(projectDTO.getProjectId());
             monitorIndicatorRecord.setDataValue(dayAvg);
             monitorIndicatorRecordService.saveOrUpdateByPk(monitorIndicatorRecord);
             runDate = dayDate;
@@ -990,7 +1000,7 @@ public class ProjectDataRecordServiceImpl implements IProjectDataRecordService {
         List<JSONObject> jsonToList = new ArrayList<>();
         try {
             List<String> classCodeList = new ArrayList<>();
-            classCodeList.add(classCode);//获取冷却塔下所有风机设备
+            classCodeList.add(classCode);
             JSONArray jsonArray = centerDataService.queryObjListByObjType(projectId, classCodeList);
             jsonToList = JSON.parseArray(jsonArray.toJSONString(), JSONObject.class);
         } catch (Exception e) {
@@ -1132,4 +1142,74 @@ public class ProjectDataRecordServiceImpl implements IProjectDataRecordService {
         }
         return objIdAndInfoCode;
     }
+
+    public Map<Date, List<TimeDataDTO>> computerWetBallTempMap(ProjectDTO projectDTO,Date startDate,Date endDate){
+        try {
+            //根据室外天气数据计算出湿球温度数据
+            Map<Date, List<WeatherDTO>> dayWeatherDataMap = getWeatherTemp(projectDTO,startDate,endDate);
+            if (null != dayWeatherDataMap && dayWeatherDataMap.size() > 0){
+                Map<Date, List<TimeDataDTO>> dayTwdTempMap = new HashMap<>();
+                for (Date dayDate:dayWeatherDataMap.keySet()) {
+                    List<WeatherDTO> dtoList = dayWeatherDataMap.get(dayDate);
+                    if (CollectionUtils.isEmpty(dtoList)){
+                        continue;
+                    }
+                    List<TimeDataDTO> timeDataDTOList = new ArrayList<>();
+                    for (WeatherDTO dto:dtoList) {
+                        //根据温度和湿度 计算出湿空气焓值
+                        Double hVal = TwdTempUtil.getHVal(dto.getTemperature(),dto.getHumidity());
+                        //根据允许范围推出Tw值
+                        Double Tw = TwdTempUtil.getTw(dto.getTemperature(),hVal,TwdTemp_Limit);
+                        log.info("温度:"+dto.getTemperature()+"湿度:"+dto.getHumidity()+"湿球温度:"+Tw);
+                        //小时时间
+                        Date hour = dto.getHourTime();
+                        Date nextHour = com.persagy.apm.diagnose.utils.DateUtils.addHours(hour,1);
+                        for (Date starthour = hour; starthour.before(nextHour) ; starthour = com.persagy.apm.diagnose.utils.DateUtils.addMinutes(starthour,15)) {
+                            TimeDataDTO timeDataDTO = new TimeDataDTO();
+                            timeDataDTO.setTime(com.persagy.apm.diagnose.utils.DateUtils.date2Str(starthour, com.persagy.apm.diagnose.utils.DateUtils.SDFSECOND));
+                            timeDataDTO.setData(Tw);
+                            timeDataDTOList.add(timeDataDTO);
+                        }
+                    }
+                    dayTwdTempMap.put(dayDate,timeDataDTOList);
+                }
+                return dayTwdTempMap;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 获取项目 天气数据
+     */
+    public Map<Date, List<WeatherDTO>> getWeatherTemp(ProjectDTO projectDTO,Date startDate,Date endDate){
+        try {
+            String startTime = com.persagy.apm.diagnose.utils.DateUtils.date2Str(startDate, com.persagy.apm.diagnose.utils.DateUtils.SDF_SECOND);
+            String endTime = com.persagy.apm.diagnose.utils.DateUtils.date2Str(endDate, com.persagy.apm.diagnose.utils.DateUtils.SDF_SECOND);
+            List<WeatherDTO> weatherDTOList = weatherService.hourHistoryData(projectDTO.getCity(),startTime,endTime,true,2);
+            if (!CollectionUtils.isEmpty(weatherDTOList)){
+                Map<Date, List<WeatherDTO>> dayTimeWeatherDataMap = new HashMap<>();
+                for (WeatherDTO dto : weatherDTOList) {
+//                    String time = dto.getHourTime();
+//                    Date timeDate = com.persagy.apm.diagnose.utils.DateUtils.str2Date(time, com.persagy.apm.diagnose.utils.DateUtils.SDF_SECOND);
+                    Date dayDate = DateUtils.truncate(dto.getHourTime(), Calendar.DATE);
+                    if (dayTimeWeatherDataMap.containsKey(dayDate)) {
+                        dayTimeWeatherDataMap.get(dayDate).add(dto);
+                    } else {
+                        List<WeatherDTO> dataDTOS = new ArrayList<>();
+                        dataDTOS.add(dto);
+                        dayTimeWeatherDataMap.put(dayDate, dataDTOS);
+                    }
+                }
+                return dayTimeWeatherDataMap;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
 }

+ 56 - 0
src/main/java/com/persagy/apm/diagnose/service/CenterDataService.java

@@ -9,6 +9,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.persagy.apm.diagnose.constant.EnumDataTimeType;
 import com.persagy.apm.diagnose.feign.client.CenterMiddlewareClient;
 import com.persagy.apm.diagnose.service.dto.ObjRelationDataDTO;
+import com.persagy.apm.diagnose.service.dto.ProjectDTO;
 import com.persagy.apm.diagnose.service.dto.TimeDataDTO;
 import com.persagy.apm.diagnose.utils.DataUtils;
 import com.persagy.apm.diagnose.utils.DateUtils;
@@ -33,6 +34,7 @@ public class CenterDataService{
 	private CenterMiddlewareClient centerMiddlewareClient;
 
 
+
 	public JSONArray queryObjListByObjType(String projectId, List<String> classCodeList) throws Exception {
 		JSONArray resultArray = new JSONArray();
 		Map<String, Object> requestMap = new HashMap<>();
@@ -211,4 +213,58 @@ public class CenterDataService{
 		}
 		return resultArray;
 	}
+
+
+    public List<ProjectDTO> queryProjectList() throws Exception {
+        List<ProjectDTO> list = new ArrayList<>();
+        Map<String, Object> requestMap = new HashMap<>();
+        try {
+            Map<String, Object> criteria = new HashMap<>();
+            List<String> typeList = new ArrayList<>();
+            typeList.add("Pj");
+            criteria.put("type",typeList);
+            criteria.put("groupCode", systemCode);
+            requestMap.put("criteria", criteria);
+            String result = centerMiddlewareClient.queryProject(requestMap);
+
+            if (null != result) {
+                JSONObject responseMap = JSONObject.parseObject(result);
+                if (null != responseMap && !responseMap.isEmpty() && SUCCESS.equals(responseMap.get("Result"))) {
+                    List<Map> contentList = (List<Map>) responseMap.get("Content");
+                    if (CollectionUtils.isEmpty(contentList)) {
+                        return list;
+                    }
+                    for (Map map : contentList) {
+                        Map infoMap = (Map)map.get("infos");
+                        if (null == infoMap) {
+                            continue;
+                        }
+                        String projID = (String) infoMap.get("ProjID");
+                        if (StringUtils.isEmpty(projID)) {
+                            continue;
+                        }
+                        String projLocalID = (String) infoMap.get("ProjLocalID");
+                        if (StringUtils.isEmpty(projLocalID)) {
+                            continue;
+                        }
+                        String city = (String) infoMap.get("City");
+                        if (StringUtils.isEmpty(city)) {
+                            continue;
+                        }
+                        ProjectDTO dto = new ProjectDTO();
+                        dto.setProjectId(projID);
+                        dto.setProjectLocalId(projLocalID);
+                        dto.setCity(city);
+                        list.add(dto);
+                    }
+                }
+            }
+        } catch (Exception e) {
+            log.error("获取项目列表错误,错误原因:" + e);
+            log.error("查询数据中台queryObject参数:" + requestMap);
+            throw e;
+        }
+        return list;
+    }
+
 }

+ 4 - 2
src/main/java/com/persagy/apm/diagnose/service/MaintenanceDataService.java

@@ -23,6 +23,8 @@ public class MaintenanceDataService {
     @Autowired
     private SaasWebServiceImpl saasWebServiceImpl;
     @Autowired
+    private CenterDataService centerDataService;
+    @Autowired
     private IProjectDataRecordService projectDataRecordService;
 
     /**
@@ -31,7 +33,7 @@ public class MaintenanceDataService {
     public void computeMaintenanceData() throws Exception {
 
         //查询项目列表
-        List<ProjectDTO> projectDTOList = saasWebServiceImpl.queryProjectDTOList(null);
+        List<ProjectDTO> projectDTOList = centerDataService.queryProjectList();
         if (CollectionUtils.isEmpty(projectDTOList)) {
             return;
         }
@@ -41,7 +43,7 @@ public class MaintenanceDataService {
         List<Future<String>> futureList = new ArrayList<>();
         CountDownLatch latch = new CountDownLatch(projectDTOList.size());
         for (ProjectDTO projectDTO : projectDTOList) {
-            futureList.add(projectDataRecordService.computeMaintenanceData(todayDate,projectDTO.getProjectId(), latch));
+            futureList.add(projectDataRecordService.computeMaintenanceData(todayDate,projectDTO, latch));
         }
         //等待所有任务执行完
         latch.await();

+ 28 - 0
src/main/java/com/persagy/apm/diagnose/service/SaasWebServiceImpl.java

@@ -70,4 +70,32 @@ public class SaasWebServiceImpl {
         return result;
     }
 
+    public List<ProjectDTO> getProjectByIdService(String projectId) throws Exception {
+        JSONObject param = new JSONObject();
+        JSONObject puser = new JSONObject();
+        puser.put("userId", USERID);
+        puser.put("loginDevice", LOGINDEVICE);
+        puser.put("pd", DEFAULT_PD);
+        param.put("puser", puser);
+        param.put("groupCode",systemCode);
+        param.put("projectId", projectId);
+        String resultStr = saasWebClient.getProjectByIdService(param.toJSONString());
+        JSONObject parseObject = JSONObject.parseObject(resultStr);
+        if ("failure".equals(parseObject.getString("result"))) {
+            throw new Exception("查询分区失败:" + parseObject.getString("reson"));
+        }
+        List<ProjectDTO> result = new ArrayList<>();
+        JSONArray jsonArray = parseObject.getJSONArray("content");
+        if (jsonArray == null || jsonArray.isEmpty()) {
+            return result;
+        }
+
+        for (Object object : jsonArray) {
+            JSONObject obj = (JSONObject) object;
+            ProjectDTO projectDTO = ProjectDTO.builder().projectId(obj.getString("projectId")).projectLocalId(obj.getString("projectLocalID")).build();
+            result.add(projectDTO);
+        }
+        return result;
+    }
+
 }

+ 84 - 0
src/main/java/com/persagy/apm/diagnose/service/WeatherServiceImpl.java

@@ -0,0 +1,84 @@
+package com.persagy.apm.diagnose.service;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.persagy.apm.diagnose.maintenance.model.dto.WeatherDTO;
+import com.persagy.apm.diagnose.utils.HttpUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 天气服务
+ */
+@Service
+@Slf4j
+public class WeatherServiceImpl {
+
+    /**
+     * 天气服务
+     */
+    @Value(value = "${weather.server}")
+    public String emsWeatherServer;
+    private static final String SUCCESS = "success";
+    /**
+     * 天气服务系统-获取历史小时天气 最大支持查询7天的数据。
+     */
+    public static final String HOUR_HISTORY_DATA = "/Spring/MVC/entrance/unifier/HourHistoryData";
+
+    public List<WeatherDTO> hourHistoryData(String cityCode, String startTimeStr, String endTimeStr, Boolean minResponse, int reqCount) throws Exception {
+        String requestUrl = emsWeatherServer + HOUR_HISTORY_DATA;
+        JSONObject param = new JSONObject();
+        param.put("cityCode", cityCode);
+        param.put("startTime", startTimeStr);
+        param.put("endTime", endTimeStr);
+        param.put("minResponse", minResponse);
+
+        Map<String, Object> paramMap = new HashMap<>();
+        paramMap.put("jsonString", param);
+
+        try {
+            String result = HttpUtils.httpPostFormUrlencoded(requestUrl, paramMap);
+
+            JSONObject resultObj = JSONObject.parseObject(result, JSONObject.class);
+
+            if (!resultObj.getString("result").equalsIgnoreCase(SUCCESS)) {
+                log.error("查询小时天气历史数据返回结果:{}", result);
+            /*// todo 由于在没有数据情况下接口返回也是失败,但是其实是成功,所以不抛异常
+            if (null != resultObj.get("reason")) {
+                throw new Exception("查询小时天气历史数据请求返回失败");
+            }*/
+                throw new Exception("查询小时天气历史数据请求返回失败");
+            }
+            List<JSONObject> jsonObjectList = JSON.parseArray(JSON.toJSONString(resultObj.get("content")), JSONObject.class);
+            if (!CollectionUtils.isEmpty(jsonObjectList)){
+                List<WeatherDTO> weatherDTOList = new ArrayList<>();
+                for (JSONObject obj:jsonObjectList) {
+                    WeatherDTO dto = new WeatherDTO();
+                    dto.setHourTime(obj.getDate("hourTime"));
+                    dto.setTemperature(obj.getDouble("temperature"));
+                    dto.setHumidity(obj.getDouble("humidity"));
+                    weatherDTOList.add(dto);
+                }
+                return weatherDTOList;
+            }
+        } catch (Exception e) {
+            log.error("---------出错了---------");
+            log.error("出错的请求路径是:{}", requestUrl);
+            log.error("出错的请求参数是:{}", JSON.toJSONString(paramMap));
+            // 重试
+            Thread.sleep(100);
+            if (reqCount < 5) {
+                return hourHistoryData(cityCode, startTimeStr, endTimeStr, minResponse, reqCount + 1);
+            }
+           // throw new Exception("查询小时天气历史数据请求出错");
+        }
+        return new ArrayList<>();
+    }
+}

+ 1 - 0
src/main/java/com/persagy/apm/diagnose/service/dto/ProjectDTO.java

@@ -21,4 +21,5 @@ import lombok.NoArgsConstructor;
 public class ProjectDTO {
 	private String projectId;
 	private String projectLocalId;
+	private String city;
 }

+ 205 - 0
src/main/java/com/persagy/apm/diagnose/utils/HttpUtils.java

@@ -0,0 +1,205 @@
+package com.persagy.apm.diagnose.utils;
+
+import org.apache.http.HttpEntityEnclosingRequest;
+import org.apache.http.HttpRequest;
+import org.apache.http.NameValuePair;
+import org.apache.http.NoHttpResponseException;
+import org.apache.http.client.HttpRequestRetryHandler;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.ConnectTimeoutException;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.entity.FileEntity;
+import org.apache.http.entity.InputStreamEntity;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLHandshakeException;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.net.UnknownHostException;
+import java.util.*;
+
+/**
+ * http工具
+ */
+public class HttpUtils {
+
+    private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);
+    private static final CloseableHttpClient HTTP_CLIENT;
+    private static final String UTF8 = "utf-8";
+
+    static {
+        //加载配置文件
+        InputStream inputStream = HttpUtils.class.getResourceAsStream("/config/system.properties");
+        Properties properties = new Properties();
+        if (inputStream != null) {
+            try {
+                properties.load(inputStream);
+            } catch (Exception e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+
+        String connectTimeoutString = properties.getProperty("httpclient.connect.timeout", "1000");
+        String connectionRequestTimeoutString = properties.getProperty("httpclient.request.timeout", "1000");
+        String socketTimeoutString = properties.getProperty("httpclient.socket.timeout", "3600000");
+
+        String maxTotalString = properties.getProperty("httpclient.pool.total", "1200");
+        String defaultMaxPerRouteString = properties.getProperty("httpclient.pool.per.route", "200");
+
+        ConnectionSocketFactory plainsf = PlainConnectionSocketFactory.getSocketFactory();
+        LayeredConnectionSocketFactory sslsf = SSLConnectionSocketFactory.getSocketFactory();
+        Registry<ConnectionSocketFactory> registry = RegistryBuilder
+                .<ConnectionSocketFactory>create().register("http", plainsf)
+                .register("https", sslsf).build();
+        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
+        // 将最大连接数增加
+        Integer maxTotal = Integer.valueOf(maxTotalString);
+        cm.setMaxTotal(maxTotal);
+        // 将每个路由基础的连接增加
+        Integer defaultMaxPerRoute = Integer.valueOf(defaultMaxPerRouteString);
+        cm.setDefaultMaxPerRoute(defaultMaxPerRoute);
+        //host
+        /*HttpHost httpHost = new HttpHost(hostname, port);
+        // 将目标主机的最大连接数增加
+        cm.setMaxPerRoute(new HttpRoute(httpHost), maxRoute);*/
+
+        // 请求重试处理
+        HttpRequestRetryHandler httpRequestRetryHandler = (exception, executionCount, context) -> {
+            // 如果已经重试了5次,就放弃
+            if (executionCount >= 5) {
+                return false;
+            }
+            // 如果服务器丢掉了连接,那么就重试
+            if (exception instanceof NoHttpResponseException) {
+                return true;
+            }
+            // 不要重试SSL握手异常
+            if (exception instanceof SSLHandshakeException) {
+                return false;
+            }
+            // 连接被拒绝
+            if (exception instanceof ConnectTimeoutException) {
+                return false;
+            }
+            // 超时
+            if (exception instanceof InterruptedIOException) {
+                return false;
+            }
+            // 目标服务器不可达
+            if (exception instanceof UnknownHostException) {
+                return false;
+            }
+            // SSL握手异常
+            if (exception instanceof SSLException) {
+                return false;
+            }
+
+            HttpClientContext clientContext = HttpClientContext
+                    .adapt(context);
+            HttpRequest request = clientContext.getRequest();
+            // 如果请求是幂等的,就再次尝试
+            if (!(request instanceof HttpEntityEnclosingRequest)) {
+                return true;
+            }
+            return false;
+        };
+
+        //requestConfig
+        Integer connectionTimeout = Integer.valueOf(connectTimeoutString);
+        Integer requestTimeout = Integer.valueOf(connectionRequestTimeoutString);
+        Integer socketTimeout = Integer.valueOf(socketTimeoutString);
+        RequestConfig requestConfig = RequestConfig.custom()
+                // 连接建立时间,三次握手完成时间
+                .setConnectTimeout(connectionTimeout)
+                // 数据传输过程中数据包之间间隔的最大时间
+                .setSocketTimeout(socketTimeout)
+                // httpClient使用连接池来管理连接,这个时间就是从连接池获取连接的超时时间
+                .setConnectionRequestTimeout(requestTimeout).build();
+        HTTP_CLIENT = HttpClients.custom()
+                .setConnectionManager(cm)
+                .setRetryHandler(httpRequestRetryHandler)
+                .setDefaultRequestConfig(requestConfig).build();
+    }
+
+    public static String httpGetRequest(String url) throws Exception {
+        HttpGet httpGet = new HttpGet(url);
+        return sendRequest(httpGet);
+    }
+
+    public static String httpPostRequest(String url) throws Exception {
+        HttpPost httpPost = new HttpPost(url);
+        return sendRequest(httpPost);
+    }
+
+    public static String httpPostRequest(String url, Map<String, Object> params) throws IOException {
+        log.info("请求url:" + url);
+        log.info("参数是:{}", params.toString());
+        HttpPost httpPost = new HttpPost(url);
+        httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
+        httpPost.setEntity(new StringEntity(JsonUtils.beanToJson(params), UTF8));
+        String respContent = sendRequest(httpPost);
+        log.info("返回值是:{}", respContent);
+        return respContent;
+    }
+
+    public static String httpPostFormUrlencoded(String url, Map<String, Object> params) throws IOException {
+        log.info("请求url:" + url);
+        log.info("参数是:{}", params.toString());
+        HttpPost httpPost = new HttpPost(url);
+        List<NameValuePair> pairs = new ArrayList<>();
+        Map.Entry entry;
+        for (Iterator var = params.entrySet().iterator(); var.hasNext(); pairs.add(new BasicNameValuePair((String) entry.getKey(), entry.getValue().toString()))) {
+            entry = (Map.Entry) var.next();
+        }
+        httpPost.setEntity(new UrlEncodedFormEntity(pairs, UTF8));
+        String respContent = sendRequest(httpPost);
+        log.info("返回值是:{}", respContent);
+        return respContent;
+    }
+
+    private static String sendRequest(HttpUriRequest request) throws IOException {
+        CloseableHttpResponse response = HTTP_CLIENT.execute(request);
+        return EntityUtils.toString(response.getEntity(), UTF8);
+    }
+
+    public static String httpPostRequest(String url, InputStream is) throws Exception {
+        HttpPost httpPost = new HttpPost(url);
+        httpPost.setEntity(new InputStreamEntity(is));
+        return sendRequest(httpPost);
+    }
+
+    public static String httpPostRequest(String url, File file) throws Exception {
+        HttpPost httpPost = new HttpPost(url);
+        httpPost.setEntity(new FileEntity(file));
+        return sendRequest(httpPost);
+    }
+
+    public static byte[] httpGetFile(String url) throws Exception {
+        HttpGet httpGet = new HttpGet(url);
+        CloseableHttpResponse response = HTTP_CLIENT.execute(httpGet);
+        return EntityUtils.toByteArray(response.getEntity());
+    }
+
+}

+ 143 - 0
src/main/java/com/persagy/apm/diagnose/utils/JsonUtils.java

@@ -0,0 +1,143 @@
+package com.persagy.apm.diagnose.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.TypeReference;
+import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
+import com.alibaba.fastjson.util.TypeUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Type;
+import java.util.List;
+
+/**
+ * @Description json工具类
+ * @Author feng
+ * @Date 2018/7/19 12:17
+ * @Version 1.0
+ */
+public class JsonUtils {
+
+    static {
+        TypeUtils.compatibleWithJavaBean = true;
+    }
+
+    /**
+     * 将json字符串转换成java对象
+     *
+     * @param json 需要转化json字符
+     * @param cls  cls  返回实例对象类型
+     * @return T
+     */
+    public static <T> T jsonToBean(String json, Class<T> cls) {
+        return JSON.parseObject(json, cls);
+    }
+
+    public static <T> T getJsonFromInputStream(InputStream inputStream, Class<T> cls) throws IOException {
+
+        return JSON.parseObject(inputStream, cls);
+    }
+
+    /**
+     * 将json字符串转换成java对象
+     *
+     * @param json 需要转化json字符
+     * @param cls  cls  返回实例对象类型
+     * @return T
+     */
+    public static <T> T jsonToBean(String json, Type cls) {
+        return JSON.parseObject(json, cls);
+    }
+
+    /**
+     * 将json字符串转换成java对象
+     *
+     * @param json 需要转化json字符
+     * @return T
+     */
+    public static <T> T jsonToBean(String json) {
+        TypeReference<T> typeReference = new TypeReference<T>() {
+        };
+        return JSON.parseObject(json, typeReference.getType());
+    }
+
+    /**
+     * 将json字符串转换成java对象
+     *
+     * @param json 需要转化json字符
+     * @param cls  cls  返回实例对象类型
+     * @return T
+     */
+    public static <T> T jsonToBean(byte[] json, Class<T> cls) {
+        return JSON.parseObject(json, cls);
+    }
+
+
+    /**
+     * 将json字符串转换成java对象
+     *
+     * @param json 需要转化json字符
+     * @param cls  cls  返回实例对象类型
+     * @return T     TypeReference typeReference = new TypeReference<JsonBean>() {};
+     */
+    public static <T> T jsonToBean(byte[] json, Type cls) {
+        return JSON.parseObject(json, cls);
+    }
+
+
+    /**
+     * 将json字符串转换成java List对象
+     *
+     * @param json 需要转化json字符
+     * @param cls  cls  返回实例对象类型
+     * @return List<T>
+     */
+    public static <T> List<T> jsonToList(String json, Class<T> cls) {
+        return JSON.parseArray(json, cls);
+    }
+
+    /**
+     * 将bean对象转化成json字符串
+     *
+     * @param obj 转化的对象实例
+     * @return String  JSON 字符
+     */
+    public static String beanToJson(Object obj) {
+        String result = JSON.toJSONString(obj);
+        return result;
+    }
+
+    /**
+     * 将bean对象转化成json字符串
+     *
+     * @param obj    转化的对象实例
+     * @param filter 序列化处理
+     * @return String  JSON 字符
+     */
+    public static String beanToJson(Object obj, SimplePropertyPreFilter filter) {
+        return JSON.toJSONString(obj, filter);
+    }
+
+
+    /**
+     * 价格json字符转换JSONObject
+     *
+     * @param jsonString 需要转换的字符
+     * @return JSONObject
+     */
+    public static JSONObject parseJsonObject(String jsonString) {
+        return JSONObject.parseObject(jsonString);
+    }
+
+    /**
+     * 价格json字符转换JSONObject
+     *
+     * @param jsonString 需要转换的字符
+     * @return JSONObject
+     */
+    public static JSONArray parseJsonArray(String jsonString) {
+        return JSONArray.parseArray(jsonString);
+    }
+}

+ 84 - 0
src/main/java/com/persagy/apm/diagnose/utils/TwdTempUtil.java

@@ -0,0 +1,84 @@
+package com.persagy.apm.diagnose.utils;
+
+/**
+ * 湿球温度计算
+ */
+
+public class TwdTempUtil {
+
+    public static void main(String[] args) {
+        try {
+            //Td干球温度 Hr相对湿度 范围 0~100  允许差值 范围
+            Double Td = 30.0,Hr = 75.0,limit = 0.1;
+            //根据温度和湿度 计算出湿空气焓值
+            Double hVal = getHVal(Td,Hr);
+            //根据允许范围推出Tw值
+            Double newTw = getTw(Td,hVal,limit);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 根据允许范围推出Tw值
+     */
+    public static Double getTw(Double Td, Double hVal, Double limit){
+        Double Tw = Td-3;
+        Double num = 0.0;
+        Boolean isOk = false;
+        Boolean isTrueVal = false;
+        while (!isOk){
+            //湿空气焓值
+            Double hwVal = getHwVal(Tw);
+            //两种湿空气焓值  差值
+            Double hc = DataUtils.subtract(hVal,hwVal);
+            //判断范围
+            if (hc<limit && hc > 0.0){
+                isOk = true;
+                isTrueVal = true;
+            }else if (hc > 0){//hw 小于 h  增加湿球温度数据值
+                Tw = Tw + 0.25;
+            }else if (hc < 0){//hw 大于 h  减小湿球温度数据值
+                Tw = Tw - 0.25;
+            }
+            num++;
+            if (num > 20){
+                isOk = true;
+            }
+        }
+        if (isTrueVal){
+            return Tw;
+        }else {
+            return getTw(Td,hVal,limit+0.5);
+        }
+    }
+
+    /**
+     * 根据湿球温度计算出湿空气焓值
+     */
+    public static double getHwVal(Double Tw){
+        Double eVal = (18.678-Tw/234.5)*Tw/(Tw+257.14);
+        Double ev= Math.exp(eVal);
+        Double Pv = 611.2 * ev; //Td时的水蒸汽饱和压力
+        //含湿量
+        Double dw = 0.6219*(Pv/(101326-Pv));
+        //湿空气焓值
+        Double hw = 1.01*Tw + (2500+1.84*Tw)*dw;
+        return hw;
+    }
+
+    /**
+     * 根据温度和湿度 计算出湿空气焓值
+     */
+    public static double getHVal(Double Td,Double Hr){
+        Double eVal = (18.678-Td/234.5)*Td/(Td+257.14);
+        Double ev= Math.exp(eVal);
+        Double Pv = 611.2*ev; //Td时的水蒸汽饱和压力
+        Double hrPv = 0.01*Hr*Pv;
+        //含湿量
+        Double d = 0.6219*(hrPv/(101326-hrPv));
+        //湿空气焓值
+        Double h = 1.01*Td + (2500+1.84*Td)*d;
+        return h;
+    }
+}